2011-10-24 42 views
12

我正在努力將音頻導入iPhone,並將其傳遞給(C++)分析算法。當然,還有很多選項:AudioQueue教程at trailsinthesand讓事情開始。如何從iOS中的AudioQueueRef獲取浮點數據的數組?

音頻回調,但是,給出了一個AudioQueueRef,我發現Apple的文檔在這方面很薄。內置的方法來寫入文件,但沒有什麼地方你實際上在數據包內部查看數據。

我需要數據。我不想寫任何文件,這是所有教程 - 甚至蘋果的便利I/O對象 - 似乎都瞄準的目標。蘋果公司的AVAudioRecorder(令人生氣)會給你關卡並寫入數據,但實際上並沒有給你訪問它的權限。除非我失去了一些東西...

如何做到這一點?在下面的代碼中有inBuffer->mAudioData這是很接近,但我不能找到關於這個'數據'在什麼格式或如何訪問它的信息。

AudioQueue回調:

void AudioInputCallback(void *inUserData, 
    AudioQueueRef inAQ, 
    AudioQueueBufferRef inBuffer, 
    const AudioTimeStamp *inStartTime, 
    UInt32 inNumberPacketDescriptions, 
    const AudioStreamPacketDescription *inPacketDescs) 
{ 
    static int count = 0; 
    RecordState* recordState = (RecordState*)inUserData;  
    AudioQueueEnqueueBuffer(recordState->queue, inBuffer, 0, NULL); 

    ++count; 
    printf("Got buffer %d\n", count); 
} 

和代碼編寫音頻文件:

OSStatus status = AudioFileWritePackets(recordState->audioFile, 
       false, 
       inBuffer->mAudioDataByteSize, 
       inPacketDescs, 
       recordState->currentPacket, 
       &inNumberPacketDescriptions, 
       inBuffer->mAudioData); // THIS! This is what I want to look inside of. 
if(status == 0) 
{ 
    recordState->currentPacket += inNumberPacketDescriptions; 
} 

回答

10
// so you don't have to hunt them all down when you decide to switch to float: 
    #define AUDIO_DATA_TYPE_FORMAT SInt16 

    // the actual sample-grabbing code: 
    int sampleCount = inBuffer->mAudioDataBytesCapacity/sizeof(AUDIO_DATA_TYPE_FORMAT); 
    AUDIO_DATA_TYPE_FORMAT *samples = (AUDIO_DATA_TYPE_FORMAT*)inBuffer->mAudioData; 

然後你有你的(在這種情況下SInt16)陣列samples,你可以從samples[0]訪問samples[sampleCount-1]。 。

+0

這個「samples」數組,它包含多少秒的採樣? 這是錄製音頻的這種二進制表示形式嗎? –

+0

「樣本」包含一個緩衝區的樣本值。長度爲秒取決於緩衝器大小和採樣率:在44.1kHz的512個採樣是512/44100 = .011609977秒。 – buildsucceeded

0

上述解決方案並沒有爲我工作,我得到了錯誤的樣本數據本身(一個字節序的問題)如果櫃面有人在將來得到錯誤的樣本數據,我希望這可以幫助你:

- ( void)feedSamplesToEngine:(UInt32)audioDataBytesCapacity audioData:(void *)audioData int sampleCount = audioDataBytesCapacity/sizeof(SAMPLE_TYPE);

SAMPLE_TYPE *samples = (SAMPLE_TYPE*)audioData; 
//SAMPLE_TYPE *sample_le = (SAMPLE_TYPE *)malloc(sizeof(SAMPLE_TYPE)*sampleCount);//for swapping endians 

std::string shorts; 
double power = pow(2,10); 
for(int i = 0; i < sampleCount; i++) 
{ 
    SAMPLE_TYPE sample_le = (0xff00 & (samples[i] << 8)) | (0x00ff & (samples[i] >> 8)) ; //Endianess issue 
    char dataInterim[30]; 
    sprintf(dataInterim,"%f ", sample_le/power); // normalize it. 
    shorts.append(dataInterim); 
} 
相關問題