I have .wav files and I would to encode them using opus, write everything in an .opus file then read it with vlc for example. I have done some code using the opus trivial example but the quality is very poor. In fact, there is a problem, I never write any header, is that normal ? What do I have forgotten ?
#define FRAME_SIZE 960
#define SAMPLE_RATE 48000 //frequence
#define CHANNELS 1 // up to 255
#define APPLICATION OPUS_APPLICATION_AUDIO
#define MAX_FRAME_SIZE 6*960
#define MAX_PACKET_SIZE (3*1276)
#define BUFFER_LEN 1024
int main(int argc, char **argv)
{
char *inFile;
FILE *fin;
char *outFile;
FILE *fout;
opus_int16 in[FRAME_SIZE*CHANNELS];
unsigned char cbits[MAX_PACKET_SIZE];
OpusEncoder *encoder;
int err;
/*Create a new encoder state */
encoder = opus_encoder_create(SAMPLE_RATE, CHANNELS, APPLICATION, &err);
if (err<0)
{
fprintf(stderr, "failed to create an encoder: %s\n", opus_strerror(err));
return EXIT_FAILURE;
}
opus_encoder_ctl(encoder, OPUS_SET_BITRATE(512000)); //500 to 512 000 // 350 000 pas trop mal
if (err<0)
{
fprintf(stderr, "failed to set bitrate: %s\n", opus_strerror(err));
return EXIT_FAILURE;
}
inFile = "toencode.wav";
fin = fopen(inFile, "r");
if (fin==NULL)
{
fprintf(stderr, "in: failed to open file: %s\n", strerror(errno));
return EXIT_FAILURE;
}
if (err<0)
{
fprintf(stderr, "failed to create decoder: %s\n", opus_strerror(err));
return EXIT_FAILURE;
}
outFile = "encoded.opus";
fout = fopen(outFile, "w");
if (fout==NULL)
{
fprintf(stderr, "failed to open file: %s\n", strerror(errno));
return EXIT_FAILURE;
}
while (1)
{
int i;
unsigned char pcm_bytes[MAX_FRAME_SIZE*CHANNELS*2];
/* Read a 16 bits/sample audio frame. */
fread(pcm_bytes, sizeof(short)*CHANNELS, FRAME_SIZE, fin);
if (feof(fin))
break;
/* Convert from little-endian ordering. */
for (i=0;i<CHANNELS*FRAME_SIZE;i++)
in[i]=pcm_bytes[2*i+1]<<8|pcm_bytes[2*i];
/* Encode the frame. */
if (opus_encode(encoder, in, FRAME_SIZE, cbits, MAX_PACKET_SIZE)<0)
{
// fprintf(stderr, "encode failed: %s\n", opus_strerror(nbBytes));
return EXIT_FAILURE;
}
fwrite(in,sizeof(short),sizeof(in),fout);
}
/*Destroy the encoder state*/
opus_encoder_destroy(encoder);
fclose(fin);
fclose(fout);
return EXIT_SUCCESS;
}
I think there is a real problem of how I write the file but I dont't where it comes from, can you please help me ?
To make a playable .opus file you need to construct headers and encapsulate them in a sequence of Ogg pages before writing the stream out. See https://git.xiph.org/?p=opus-tools.git;a=blob;f=src/opusenc.c for an open source implementation.
Note you'll get better results if you use 960 samples for MAX_FRAME_SIZE. Bumping the bitrate to the maximum won't make much of a audible difference either.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With