2013-08-25 80 views
0

如在標題我需要從一個字符緩衝器如何讀取短(16位)從一個無符號字符整數(8比特)緩衝器

緩衝

uint8_t *data[AV_NUM_DATA_POINTERS] 

這是一個字段讀短整數該AVFrame frame結構,是通過調用填充FFmpeg的功能

avcodec_decode_audio4(avctx,frame,got_frame_ptr,avpkt) 

但是,我需要閱讀該緩衝區簽署16位整數的緩衝區,因爲這是樣本格式INDI由編解碼器上下文 avctx-> sample_fmt == cated AV_SAMPLE_FMT_S16

我試圖做到這一點使用的memcpy,但我還沒有成功獲得合理的值,所以後來我試圖用一個工會結構上的一些相關問題的建議在這裏在StackOverflow中。我的代碼如下: union CharToStruct {0} {0} {0} {0} {0} uint8_t myCharArray [2]; 空頭值; } presentSound;

audioRet=avcodec_decode_audio4(avctx,frame,got_frame_ptr,avpkt); 
if(got_frame_ptr){ 
    audioRet=audioRet/2; 
    int b=0; 
    for(int i=0;i<audioRet;i++){ 
     presentSound.myCharArray[0]=frame->data[0][2*i+1]; 
     presentSound.myCharArray[1]=frame->data[0][2*i] 
     dbuf[((i-b)/2)*8+info->mLeft+b]=info->presentSound.value;//the reason of the offset by 8 here is because I will be writing the result to a multichannel device 
} 

因此,這些值是合理的,但是當我使用portaudio將其寫入設備時,我只是點擊噪聲。我是否以錯誤的方式進行轉換?你能幫助我以更好的方式來做這個閱讀嗎?

非常感謝您的幫助

阿爾巴

回答

0

只要將uint8_t數組看作原始字節數組即可。在C/C++中,無符號字符(uint8_t)與您所能獲得的「無類型」數組非常接近。任何類型的數據都可以作爲原始字節寫入任何類型的數組,但是與unsigned char數組交互是最容易的,因爲每個元素的值都是從0x00到0xFF(一個字節),用戶可以解釋這些字節,但是他們選擇。

如果您只是簡單地將數據從ffmpeg傳遞到PortAudio,您可能不需要對數據進行任何解釋。 PortAudio的回調(或使用阻塞API的寫入方法)要求用戶設置一個void指針指向正在播放的數據緩衝區的開始位置。只要按順序讀取時的字節可以解釋爲預期的樣本格式,那麼該緩衝區的類型無關緊要。實際上,只要能夠將緩衝區指針傳遞給回調函數,並且緩衝區在被回調處理之前不會被釋放,您甚至可能甚至不需要複製數據。注意其他問題,如讀取單聲道流和寫入立體聲流。如果輸出流期望交錯立體聲音頻,則必須將每個採樣寫入輸出緩衝區兩次(或者對於每個預期的通道一次)。另一方面,如果你希望操作緩衝區中的樣本,你可能希望將uint8_t *重新編譯爲short *。由於緩衝區中的數據已經是帶符號的16位樣本,因此一旦您投射,數組中的每個元素將成爲一個數據樣本。請記住,數組的大小隻有原始緩衝區的一半,因爲元素的大小是其兩倍。

這應該是完全安全的,只要您在單個系統上工作,您不應該在ffmpeg和PortAudio之間移動示例時存在任何字節順序問題。如果系統是big endian,則樣本將是big endian(最低地址Motorolla中的高位字節),如果系統是little endian(最低地址中的低位字節,Intel),則樣本將是小尾數。

0

對我來說,這看起來錯誤:

 presentSound.myCharArray[0]=frame->data[0][2*i+1]; 
    presentSound.myCharArray[1]=frame->data[0][2*i] 

我希望看到:

 presentSound.myCharArray[0]=frame->data[0][2*i] 
    presentSound.myCharArray[1]=frame->data[0][2*i+1]; 

可能值得將數據寫入文件,並附加一個WAV頭(從現有文件o中取前40個字節) f格式正確[每樣本位數,每秒樣本數],然後是輸出樣本數,以及之後的樣本數)。

+0

噢,謝謝,把結果寫到一個wav文件是一個好主意,這樣我就可以看到播放的聲音是否如預期那樣。 –

+0

這個相關問題的回答[鏈接](http://stackoverflow.com/a/16673014/2716163)建議首先放第二個字節,告訴最短的最重要的位是最後一個字節。但我也嘗試了另一種方式,先把[2 * i]然後再把[2 * i + 1]和我得到的數字放在那麼小,我什麼都聽不到。 –

相關問題