2010-10-30 138 views
0

我想從使用核心音頻的PCM音頻文件中提取電平數據。我已經得到儘可能(我相信)原始數據到一個字節數組(UInt8),但它是16位PCM數據,我無法讀取數據。輸入來自iPhone麥克風,我設置爲:使用核心音頻從PCM原始數據獲取電平值

[recordSetting setValue:[NSNumber numberWithInt:kAudioFormatLinearPCM] forKey:AVFormatIDKey]; 
[recordSetting setValue:[NSNumber numberWithFloat:44100.0] forKey:AVSampleRateKey]; 
[recordSetting setValue:[NSNumber numberWithInt:1] forKey:AVNumberOfChannelsKey]; 

[recordSetting setValue:[NSNumber numberWithInt:16] forKey:AVLinearPCMBitDepthKey]; 
[recordSetting setValue:[NSNumber numberWithBool:NO] forKey:AVLinearPCMIsBigEndianKey]; 
[recordSetting setValue:[NSNumber numberWithBool:NO] forKey:AVLinearPCMIsFloatKey]; 

這顯然是16位。然後我試圖打印出幾個值,看看它們是否適合下面的調試目的,而且看起來不合理(很多爲0)。

ExtAudioFileRef inputFile = NULL; ExtAudioFileOpenURL(track.location,& inputFile);

AudioStreamBasicDescription inputFileFormat; 
UInt32 dataSize = (UInt32)sizeof(inputFileFormat); 
ExtAudioFileGetProperty(inputFile, kExtAudioFileProperty_FileDataFormat, &dataSize, &inputFileFormat); 

UInt8 *buffer = malloc(BUFFER_SIZE); 
AudioBufferList bufferList; 
bufferList.mNumberBuffers = 1; 
bufferList.mBuffers[0].mNumberChannels = 1; 
bufferList.mBuffers[0].mData = buffer; //pointer to buffer of audio data 
bufferList.mBuffers[0].mDataByteSize = BUFFER_SIZE; //number of bytes in the buffer 

while(true) { 

    UInt32 frameCount = (bufferList.mBuffers[0].mDataByteSize/inputFileFormat.mBytesPerFrame); 

    // Read a chunk of input 
    OSStatus status = ExtAudioFileRead(inputFile, &frameCount, &bufferList); 

    // If no frames were returned, conversion is finished 
    if(0 == frameCount) 
     break; 

    NSLog(@"---"); 

    int16_t *bufferl = &buffer; 
    for(int i=0;i<100;i++){ 
     //const int16_t *bufferl = bufferl[i]; 
     NSLog(@"%d",bufferl[i]); 
    } 

} 

不知道我在做什麼錯,我認爲它與讀取字節數組有關。對不起,長碼後...

+0

我發現這個:http://stackoverflow.com/questions/3833356/extracting-amplitude-data-from-linear-pcm-on-the-iphone但我仍然沒有看到我做錯了什麼。 – John 2010-10-30 05:11:46

+0

我還應該添加track.location是一個帶有pcm caf文件的NSURL,以及BUFFER_SIZE =((4096 * 4)* 8),它應該是32K。 – John 2010-10-30 05:13:15

回答

1

您選擇分配的緩衝區無符號8位整數,然後將其地址轉換爲無符號16位整數。 KA-熱潮。

你想要在for循環中執行的操作是將bufferList.mBuffers [0] .mData強制轉換爲SInt16 *,然後通過迭代打印出您的值。

你不需要你的緩衝區var。 (爲此)

0

你可以簡化很多事情。我相信你可以讓API爲你分配緩衝區。

bufferList.mBuffers[0].mData = nil; 
bufferList.mBuffers[0].mDataByteSize = 0; 

你也應該在讀呼叫,而不是假設他們是你在通過相同的人後bufferList使用的值。所以你看後,

SInt16 *buffer = (SInt16 *)bufferList.mBuffers[0].mData; 
for (UInt32 i=0; i< frameCount; i++) { 
    NSLog (@"%d", buffer[i]); 
}