2010-03-08 439 views
0

對於比Java更低級別的任何事物,潛入iPhone音頻以及從所有演員/指針/原始存儲器訪問中實現總noob。將UInt32(音頻幀)拆分爲兩個SInt16(左側和右側)?

我正在與some example code一起從光盤讀取WAV文件並將立體聲樣本作爲單個UInt32值返回。如果我理解正確,這只是返回創建兩個16位採樣所需的32位內存的便捷方式。最終這些數據被寫入一個緩衝區,一個音頻單元將它收集起來。即使數據是用UInt32大小的塊編寫的,它最終也會被解釋爲16位樣本對。

我需要幫助的是將這些UInt32幀分成左和右樣本。我假設我想將每個UInt32轉換爲一個SInt16,因爲音頻採樣是一個有符號值。在我看來,爲了提高效率,我應該能夠簡單地指向內存中的相同塊,並避免任何複製。

所以,在僞代碼,這將是這樣的:

UInt32 myStereoFrame = getFramefromFilePlayer; 

SInt16* leftChannel = getFirst16Bits(myStereoFrame); 
SInt16* rightChannel = getSecond16Bits(myStereoFrame); 

誰能幫我把我的僞成真正的代碼?

編輯:

很大程度上得益於zneak對於這個答案,它的偉大工程:

SInt16* left = (SInt16*)&myUInt32Chunk; 
SInt16* right = left + 1; 

現在,我重新組裝成SInt16s以UInt32(假設我不希望只是用我的原變量,myStereoFrame),我需要做相反的操作:在連續內存插槽中排列我的兩個SInt16,然後將該內存投射到UInt32。

所以我做一個數組:

SInt16 newFrameInMemory[2] = {*left, *right} 

然後該陣列的整個長度複製到一個UInt32的

UInt32 newFrame32 = newFrameInMemory 

這可能沒有什麼工作,但如果我做的這個位醜 - 將數組轉換爲指針,然後解引用指針,它確實有效。

UInt32 newFrame32 = *((UInt32*)&newFrameInMemory) 

有沒有更好的方法來做到這一點?

回答

1

這是很容易:

SInt16* left = (SInt16*)&myUInt32Chunk; 
SInt16* right = left + 1; 

除非iPhone是小端,在這種情況下,你必須反轉rightleft

由於int可以看作是兩個連續的short s,您只需要獲取地址即可,然後確實如同兩個short s一樣。

+0

完美!謝謝! – morgancodes 2010-03-08 22:53:43

0

iPhone是小端:-)