2015-09-08 2 views
1

У меня есть .wav-файлы, и я бы хотел их закодировать с помощью opus, написать все в файле .opus, а затем прочитать его с помощью vlc. Я сделал некоторый код, используя простой опус, но качество очень плохое. На самом деле, есть проблема, я никогда не пишу никакого заголовка, это нормально? Что я забыл?Как получить хорошо сформированный файл opus с libopus?

#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; 
} 

Я думаю, что существует реальная проблема, как я пишу файл, но я dont't, откуда приходит, пожалуйста, вы можете мне помочь?

ответ

1

Для создания воспроизводимого файла .opus вам необходимо создать заголовки и инкапсулировать их в последовательности страниц Ogg, прежде чем писать поток. См. https://git.xiph.org/?p=opus-tools.git;a=blob;f=src/opusenc.c для реализации с открытым исходным кодом.

Обратите внимание, что вы получите лучшие результаты, если вы используете 960 образцов для MAX_FRAME_SIZE. Наклонение битрейта до максимума не приведет к значительному различию в звуке.

Смежные вопросы