2014-08-27 15 views
0

我想了好幾個月來弄清楚它是如何工作的。我有一個我正在開發的程序,我有一個mp3文件進出我有pcm到「alsa」播放。使用庫mpg123的,其中主要的代碼是這樣的:管理MP3的播放速度和位置

while (mpg123_read (mh, buffer, buffer_size, & done) == MPG123_OK) 
    sendoutput (dev, buffer, done); 

現在,我已經嘗試基於在緩衝區上使用庫avutil/avcodec中的減少/增加一秒的樣本數量。結果很糟糕,而且不可聽。在之前的問題中,有人建議我增加我的電腦性能,但如果像「VLC」這樣的簡單程序可以在舊電腦上做到這一點,爲什麼我不能?

而對於音頻文件中的位置問題,我該如何實現?

編輯 我添加一段代碼試圖解釋。

SampleConversion.c

#define LENGTH_MS 1000  // how many milliseconds of speech to store 0,5s:x=1:44100 x=22050 sample da memorizzare 
#define RATE 44100  // the sampling rate (input) 
struct AVResampleContext* audio_cntx = 0; 
//(LENGTH_MS*RATE*16*CHANNELS)/8000 
void inizializeResample(int inRate, int outRate) 
{ 
    audio_cntx = av_resample_init(outRate, //out rate 
     inRate, //in rate 
     16, //filter length 
     10, //phase count 
     0, //linear FIR filter 
     0.8); //cutoff frequency 
    assert(audio_cntx && "Failed to create resampling context!"); 
} 
void resample(char dataIn[],char dataOut[],int nsamples) 
{ 
    int samples_consumed; 
    int samples_output = av_resample(audio_cntx, //resample context 
    (short*)dataOut, //buffout 
    (short*)dataIn,  //buffin 
    &samples_consumed, //&consumed 
    nsamples,  //nb_samples 
    sizeof(dataOut)/2,//lenout sizeof(out_buffer)/2 (Right?) 
    0);//is_last 
    assert(samples_output > 0 && "Error calling av_resample()!"); 
} 

void endResample() 
{ 
    av_resample_close(audio_cntx);  
} 

我的編輯播放功能(Mpg123.c

if (isPaused==0 && mpg123_read(mh, buffer, buffer_size, &done) == MPG123_OK) 
{ 
    int i=0; char * resBuffer=malloc(sizeof(buffer)); 
    //resBuffer=&buffer[0]; 
    resample(buffer,resBuffer,44100); 
    if((ao_play(dev, (char*)resBuffer, done)==0)){ 
    return 1; 
    } 
} 

兩個代碼我做的,所以我不能讓任何人曾經建議作爲改進在前面的問題中(儘管我不知道他們是否正確,感嘆) 編輯2:更新了chan ges

+1

「如果像」VLC「這樣的簡單程序可以在舊電腦上做到這一點,爲什麼我不能?你有沒有看過VLC的源代碼? – TerryG 2014-08-27 17:59:34

+0

如果你不解釋你是如何使用'avutil/avcodec'的,期望任何人都能提供幫助?至於在音頻文件中的重新定位,這將取決於你正在使用的庫的功能 - 如果它不能這樣做,你將不得不將整個文件讀入內存。 – 2014-08-27 18:09:17

+0

Avcodec具有稱爲「av_resample」的重採樣的特定功能。 – Delayer 2014-08-27 18:18:46

回答

1

av_resample的調用中,samples_consumed從不讀取,所以任何未消耗的幀都將被跳過。 此外,nsamples是恆定值44100而不是實際讀取的幀數(donempg123_read)。 sizeof(dataOut)是錯的;這是一個指針的大小。 is_last在輸入結束時出錯。

在播放功能中,sizeof(buffer)可能是錯誤的,具體取決於buffer的定義。