13c3902f0ac13428394f14f78f0fab05ef3468d69tlegrand@google.com/* Copyright (c) 2013 Jean-Marc Valin */ 23c3902f0ac13428394f14f78f0fab05ef3468d69tlegrand@google.com/* 33c3902f0ac13428394f14f78f0fab05ef3468d69tlegrand@google.com Redistribution and use in source and binary forms, with or without 43c3902f0ac13428394f14f78f0fab05ef3468d69tlegrand@google.com modification, are permitted provided that the following conditions 53c3902f0ac13428394f14f78f0fab05ef3468d69tlegrand@google.com are met: 63c3902f0ac13428394f14f78f0fab05ef3468d69tlegrand@google.com 73c3902f0ac13428394f14f78f0fab05ef3468d69tlegrand@google.com - Redistributions of source code must retain the above copyright 83c3902f0ac13428394f14f78f0fab05ef3468d69tlegrand@google.com notice, this list of conditions and the following disclaimer. 93c3902f0ac13428394f14f78f0fab05ef3468d69tlegrand@google.com 103c3902f0ac13428394f14f78f0fab05ef3468d69tlegrand@google.com - Redistributions in binary form must reproduce the above copyright 113c3902f0ac13428394f14f78f0fab05ef3468d69tlegrand@google.com notice, this list of conditions and the following disclaimer in the 123c3902f0ac13428394f14f78f0fab05ef3468d69tlegrand@google.com documentation and/or other materials provided with the distribution. 133c3902f0ac13428394f14f78f0fab05ef3468d69tlegrand@google.com 143c3902f0ac13428394f14f78f0fab05ef3468d69tlegrand@google.com THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 153c3902f0ac13428394f14f78f0fab05ef3468d69tlegrand@google.com ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 163c3902f0ac13428394f14f78f0fab05ef3468d69tlegrand@google.com LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 173c3902f0ac13428394f14f78f0fab05ef3468d69tlegrand@google.com A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER 183c3902f0ac13428394f14f78f0fab05ef3468d69tlegrand@google.com OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 193c3902f0ac13428394f14f78f0fab05ef3468d69tlegrand@google.com EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 203c3902f0ac13428394f14f78f0fab05ef3468d69tlegrand@google.com PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 213c3902f0ac13428394f14f78f0fab05ef3468d69tlegrand@google.com PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 223c3902f0ac13428394f14f78f0fab05ef3468d69tlegrand@google.com LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 233c3902f0ac13428394f14f78f0fab05ef3468d69tlegrand@google.com NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 243c3902f0ac13428394f14f78f0fab05ef3468d69tlegrand@google.com SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 253c3902f0ac13428394f14f78f0fab05ef3468d69tlegrand@google.com*/ 263c3902f0ac13428394f14f78f0fab05ef3468d69tlegrand@google.com 273c3902f0ac13428394f14f78f0fab05ef3468d69tlegrand@google.com/* This is meant to be a simple example of encoding and decoding audio 283c3902f0ac13428394f14f78f0fab05ef3468d69tlegrand@google.com using Opus. It should make it easy to understand how the Opus API 293c3902f0ac13428394f14f78f0fab05ef3468d69tlegrand@google.com works. For more information, see the full API documentation at: 303c3902f0ac13428394f14f78f0fab05ef3468d69tlegrand@google.com http://www.opus-codec.org/docs/ */ 313c3902f0ac13428394f14f78f0fab05ef3468d69tlegrand@google.com 323c3902f0ac13428394f14f78f0fab05ef3468d69tlegrand@google.com#include <stdlib.h> 333c3902f0ac13428394f14f78f0fab05ef3468d69tlegrand@google.com#include <errno.h> 343c3902f0ac13428394f14f78f0fab05ef3468d69tlegrand@google.com#include <string.h> 353c3902f0ac13428394f14f78f0fab05ef3468d69tlegrand@google.com#include <opus.h> 363c3902f0ac13428394f14f78f0fab05ef3468d69tlegrand@google.com#include <stdio.h> 373c3902f0ac13428394f14f78f0fab05ef3468d69tlegrand@google.com 383c3902f0ac13428394f14f78f0fab05ef3468d69tlegrand@google.com/*The frame size is hardcoded for this sample code but it doesn't have to be*/ 393c3902f0ac13428394f14f78f0fab05ef3468d69tlegrand@google.com#define FRAME_SIZE 960 403c3902f0ac13428394f14f78f0fab05ef3468d69tlegrand@google.com#define SAMPLE_RATE 48000 413c3902f0ac13428394f14f78f0fab05ef3468d69tlegrand@google.com#define CHANNELS 2 423c3902f0ac13428394f14f78f0fab05ef3468d69tlegrand@google.com#define APPLICATION OPUS_APPLICATION_AUDIO 433c3902f0ac13428394f14f78f0fab05ef3468d69tlegrand@google.com#define BITRATE 64000 443c3902f0ac13428394f14f78f0fab05ef3468d69tlegrand@google.com 453c3902f0ac13428394f14f78f0fab05ef3468d69tlegrand@google.com#define MAX_FRAME_SIZE 6*960 463c3902f0ac13428394f14f78f0fab05ef3468d69tlegrand@google.com#define MAX_PACKET_SIZE (3*1276) 473c3902f0ac13428394f14f78f0fab05ef3468d69tlegrand@google.com 483c3902f0ac13428394f14f78f0fab05ef3468d69tlegrand@google.comint main(int argc, char **argv) 493c3902f0ac13428394f14f78f0fab05ef3468d69tlegrand@google.com{ 503c3902f0ac13428394f14f78f0fab05ef3468d69tlegrand@google.com char *inFile; 513c3902f0ac13428394f14f78f0fab05ef3468d69tlegrand@google.com FILE *fin; 523c3902f0ac13428394f14f78f0fab05ef3468d69tlegrand@google.com char *outFile; 533c3902f0ac13428394f14f78f0fab05ef3468d69tlegrand@google.com FILE *fout; 543c3902f0ac13428394f14f78f0fab05ef3468d69tlegrand@google.com opus_int16 in[FRAME_SIZE*CHANNELS]; 553c3902f0ac13428394f14f78f0fab05ef3468d69tlegrand@google.com opus_int16 out[MAX_FRAME_SIZE*CHANNELS]; 563c3902f0ac13428394f14f78f0fab05ef3468d69tlegrand@google.com unsigned char cbits[MAX_PACKET_SIZE]; 573c3902f0ac13428394f14f78f0fab05ef3468d69tlegrand@google.com int nbBytes; 583c3902f0ac13428394f14f78f0fab05ef3468d69tlegrand@google.com /*Holds the state of the encoder and decoder */ 593c3902f0ac13428394f14f78f0fab05ef3468d69tlegrand@google.com OpusEncoder *encoder; 603c3902f0ac13428394f14f78f0fab05ef3468d69tlegrand@google.com OpusDecoder *decoder; 613c3902f0ac13428394f14f78f0fab05ef3468d69tlegrand@google.com int err; 623c3902f0ac13428394f14f78f0fab05ef3468d69tlegrand@google.com 633c3902f0ac13428394f14f78f0fab05ef3468d69tlegrand@google.com if (argc != 3) 643c3902f0ac13428394f14f78f0fab05ef3468d69tlegrand@google.com { 653c3902f0ac13428394f14f78f0fab05ef3468d69tlegrand@google.com fprintf(stderr, "usage: trivial_example input.pcm output.pcm\n"); 663c3902f0ac13428394f14f78f0fab05ef3468d69tlegrand@google.com fprintf(stderr, "input and output are 16-bit little-endian raw files\n"); 673c3902f0ac13428394f14f78f0fab05ef3468d69tlegrand@google.com return EXIT_FAILURE; 683c3902f0ac13428394f14f78f0fab05ef3468d69tlegrand@google.com } 693c3902f0ac13428394f14f78f0fab05ef3468d69tlegrand@google.com 703c3902f0ac13428394f14f78f0fab05ef3468d69tlegrand@google.com /*Create a new encoder state */ 713c3902f0ac13428394f14f78f0fab05ef3468d69tlegrand@google.com encoder = opus_encoder_create(SAMPLE_RATE, CHANNELS, APPLICATION, &err); 723c3902f0ac13428394f14f78f0fab05ef3468d69tlegrand@google.com if (err<0) 733c3902f0ac13428394f14f78f0fab05ef3468d69tlegrand@google.com { 743c3902f0ac13428394f14f78f0fab05ef3468d69tlegrand@google.com fprintf(stderr, "failed to create an encoder: %s\n", opus_strerror(err)); 753c3902f0ac13428394f14f78f0fab05ef3468d69tlegrand@google.com return EXIT_FAILURE; 763c3902f0ac13428394f14f78f0fab05ef3468d69tlegrand@google.com } 773c3902f0ac13428394f14f78f0fab05ef3468d69tlegrand@google.com /* Set the desired bit-rate. You can also set other parameters if needed. 783c3902f0ac13428394f14f78f0fab05ef3468d69tlegrand@google.com The Opus library is designed to have good defaults, so only set 793c3902f0ac13428394f14f78f0fab05ef3468d69tlegrand@google.com parameters you know you need. Doing otherwise is likely to result 803c3902f0ac13428394f14f78f0fab05ef3468d69tlegrand@google.com in worse quality, but better. */ 813c3902f0ac13428394f14f78f0fab05ef3468d69tlegrand@google.com err = opus_encoder_ctl(encoder, OPUS_SET_BITRATE(BITRATE)); 823c3902f0ac13428394f14f78f0fab05ef3468d69tlegrand@google.com if (err<0) 833c3902f0ac13428394f14f78f0fab05ef3468d69tlegrand@google.com { 843c3902f0ac13428394f14f78f0fab05ef3468d69tlegrand@google.com fprintf(stderr, "failed to set bitrate: %s\n", opus_strerror(err)); 853c3902f0ac13428394f14f78f0fab05ef3468d69tlegrand@google.com return EXIT_FAILURE; 863c3902f0ac13428394f14f78f0fab05ef3468d69tlegrand@google.com } 873c3902f0ac13428394f14f78f0fab05ef3468d69tlegrand@google.com inFile = argv[1]; 883c3902f0ac13428394f14f78f0fab05ef3468d69tlegrand@google.com fin = fopen(inFile, "r"); 893c3902f0ac13428394f14f78f0fab05ef3468d69tlegrand@google.com if (fin==NULL) 903c3902f0ac13428394f14f78f0fab05ef3468d69tlegrand@google.com { 913c3902f0ac13428394f14f78f0fab05ef3468d69tlegrand@google.com fprintf(stderr, "failed to open file: %s\n", strerror(errno)); 923c3902f0ac13428394f14f78f0fab05ef3468d69tlegrand@google.com return EXIT_FAILURE; 933c3902f0ac13428394f14f78f0fab05ef3468d69tlegrand@google.com } 943c3902f0ac13428394f14f78f0fab05ef3468d69tlegrand@google.com 953c3902f0ac13428394f14f78f0fab05ef3468d69tlegrand@google.com 963c3902f0ac13428394f14f78f0fab05ef3468d69tlegrand@google.com /* Create a new decoder state. */ 973c3902f0ac13428394f14f78f0fab05ef3468d69tlegrand@google.com decoder = opus_decoder_create(SAMPLE_RATE, CHANNELS, &err); 983c3902f0ac13428394f14f78f0fab05ef3468d69tlegrand@google.com if (err<0) 993c3902f0ac13428394f14f78f0fab05ef3468d69tlegrand@google.com { 1003c3902f0ac13428394f14f78f0fab05ef3468d69tlegrand@google.com fprintf(stderr, "failed to create decoder: %s\n", opus_strerror(err)); 1013c3902f0ac13428394f14f78f0fab05ef3468d69tlegrand@google.com return EXIT_FAILURE; 1023c3902f0ac13428394f14f78f0fab05ef3468d69tlegrand@google.com } 1033c3902f0ac13428394f14f78f0fab05ef3468d69tlegrand@google.com outFile = argv[2]; 1043c3902f0ac13428394f14f78f0fab05ef3468d69tlegrand@google.com fout = fopen(outFile, "w"); 1053c3902f0ac13428394f14f78f0fab05ef3468d69tlegrand@google.com if (fout==NULL) 1063c3902f0ac13428394f14f78f0fab05ef3468d69tlegrand@google.com { 1073c3902f0ac13428394f14f78f0fab05ef3468d69tlegrand@google.com fprintf(stderr, "failed to open file: %s\n", strerror(errno)); 1083c3902f0ac13428394f14f78f0fab05ef3468d69tlegrand@google.com return EXIT_FAILURE; 1093c3902f0ac13428394f14f78f0fab05ef3468d69tlegrand@google.com } 1103c3902f0ac13428394f14f78f0fab05ef3468d69tlegrand@google.com 1113c3902f0ac13428394f14f78f0fab05ef3468d69tlegrand@google.com while (1) 1123c3902f0ac13428394f14f78f0fab05ef3468d69tlegrand@google.com { 1133c3902f0ac13428394f14f78f0fab05ef3468d69tlegrand@google.com int i; 1143c3902f0ac13428394f14f78f0fab05ef3468d69tlegrand@google.com unsigned char pcm_bytes[MAX_FRAME_SIZE*CHANNELS*2]; 1153c3902f0ac13428394f14f78f0fab05ef3468d69tlegrand@google.com int frame_size; 1163c3902f0ac13428394f14f78f0fab05ef3468d69tlegrand@google.com 1173c3902f0ac13428394f14f78f0fab05ef3468d69tlegrand@google.com /* Read a 16 bits/sample audio frame. */ 1183c3902f0ac13428394f14f78f0fab05ef3468d69tlegrand@google.com fread(pcm_bytes, sizeof(short)*CHANNELS, FRAME_SIZE, fin); 1193c3902f0ac13428394f14f78f0fab05ef3468d69tlegrand@google.com if (feof(fin)) 1203c3902f0ac13428394f14f78f0fab05ef3468d69tlegrand@google.com break; 1213c3902f0ac13428394f14f78f0fab05ef3468d69tlegrand@google.com /* Convert from little-endian ordering. */ 1223c3902f0ac13428394f14f78f0fab05ef3468d69tlegrand@google.com for (i=0;i<CHANNELS*FRAME_SIZE;i++) 1233c3902f0ac13428394f14f78f0fab05ef3468d69tlegrand@google.com in[i]=pcm_bytes[2*i+1]<<8|pcm_bytes[2*i]; 1243c3902f0ac13428394f14f78f0fab05ef3468d69tlegrand@google.com 1253c3902f0ac13428394f14f78f0fab05ef3468d69tlegrand@google.com /* Encode the frame. */ 1263c3902f0ac13428394f14f78f0fab05ef3468d69tlegrand@google.com nbBytes = opus_encode(encoder, in, FRAME_SIZE, cbits, MAX_PACKET_SIZE); 1273c3902f0ac13428394f14f78f0fab05ef3468d69tlegrand@google.com if (nbBytes<0) 1283c3902f0ac13428394f14f78f0fab05ef3468d69tlegrand@google.com { 1293c3902f0ac13428394f14f78f0fab05ef3468d69tlegrand@google.com fprintf(stderr, "encode failed: %s\n", opus_strerror(nbBytes)); 1303c3902f0ac13428394f14f78f0fab05ef3468d69tlegrand@google.com return EXIT_FAILURE; 1313c3902f0ac13428394f14f78f0fab05ef3468d69tlegrand@google.com } 1323c3902f0ac13428394f14f78f0fab05ef3468d69tlegrand@google.com 1333c3902f0ac13428394f14f78f0fab05ef3468d69tlegrand@google.com 1343c3902f0ac13428394f14f78f0fab05ef3468d69tlegrand@google.com /* Decode the data. In this example, frame_size will be constant because 1353c3902f0ac13428394f14f78f0fab05ef3468d69tlegrand@google.com the encoder is using a constant frame size. However, that may not 1363c3902f0ac13428394f14f78f0fab05ef3468d69tlegrand@google.com be the case for all encoders, so the decoder must always check 1373c3902f0ac13428394f14f78f0fab05ef3468d69tlegrand@google.com the frame size returned. */ 1383c3902f0ac13428394f14f78f0fab05ef3468d69tlegrand@google.com frame_size = opus_decode(decoder, cbits, nbBytes, out, MAX_FRAME_SIZE, 0); 1393c3902f0ac13428394f14f78f0fab05ef3468d69tlegrand@google.com if (frame_size<0) 1403c3902f0ac13428394f14f78f0fab05ef3468d69tlegrand@google.com { 1413c3902f0ac13428394f14f78f0fab05ef3468d69tlegrand@google.com fprintf(stderr, "decoder failed: %s\n", opus_strerror(err)); 1423c3902f0ac13428394f14f78f0fab05ef3468d69tlegrand@google.com return EXIT_FAILURE; 1433c3902f0ac13428394f14f78f0fab05ef3468d69tlegrand@google.com } 1443c3902f0ac13428394f14f78f0fab05ef3468d69tlegrand@google.com 1453c3902f0ac13428394f14f78f0fab05ef3468d69tlegrand@google.com /* Convert to little-endian ordering. */ 1463c3902f0ac13428394f14f78f0fab05ef3468d69tlegrand@google.com for(i=0;i<CHANNELS*frame_size;i++) 1473c3902f0ac13428394f14f78f0fab05ef3468d69tlegrand@google.com { 1483c3902f0ac13428394f14f78f0fab05ef3468d69tlegrand@google.com pcm_bytes[2*i]=out[i]&0xFF; 1493c3902f0ac13428394f14f78f0fab05ef3468d69tlegrand@google.com pcm_bytes[2*i+1]=(out[i]>>8)&0xFF; 1503c3902f0ac13428394f14f78f0fab05ef3468d69tlegrand@google.com } 1513c3902f0ac13428394f14f78f0fab05ef3468d69tlegrand@google.com /* Write the decoded audio to file. */ 1523c3902f0ac13428394f14f78f0fab05ef3468d69tlegrand@google.com fwrite(pcm_bytes, sizeof(short), frame_size*CHANNELS, fout); 1533c3902f0ac13428394f14f78f0fab05ef3468d69tlegrand@google.com } 1543c3902f0ac13428394f14f78f0fab05ef3468d69tlegrand@google.com /*Destroy the encoder state*/ 1553c3902f0ac13428394f14f78f0fab05ef3468d69tlegrand@google.com opus_encoder_destroy(encoder); 1563c3902f0ac13428394f14f78f0fab05ef3468d69tlegrand@google.com opus_decoder_destroy(decoder); 1573c3902f0ac13428394f14f78f0fab05ef3468d69tlegrand@google.com fclose(fin); 1583c3902f0ac13428394f14f78f0fab05ef3468d69tlegrand@google.com fclose(fout); 1593c3902f0ac13428394f14f78f0fab05ef3468d69tlegrand@google.com return EXIT_SUCCESS; 1603c3902f0ac13428394f14f78f0fab05ef3468d69tlegrand@google.com} 161