2015-09-08 86 views
1

我有.wav文件,我會使用opus對它們進行編碼,將所有內容寫入.opus文件,然後使用vlc讀取它。我用一些簡單的例子做了一些代碼,但質量很差。事實上,有一個問題,我從來沒有寫過任何標題,這是正常的嗎?我什麼都忘記了?如何用libopus獲得一個合適的opus文件?

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

我覺得有一個真正的問題,我怎麼寫文件,但我不知道它來自哪裏,你能幫我嗎?

回答

1

要製作可播放的.opus文件,您需要構建標題並將其封裝在Ogg頁面的序列中,然後再寫入流。有關開源實現請參見https://git.xiph.org/?p=opus-tools.git;a=blob;f=src/opusenc.c

注意,如果您使用MAX_FRAME_SIZE的960個樣本,則會得到更好的結果。將比特率顛簸至最大也不會產生太大的可聽差異。