如何从iOS中的AudioQueueRef获取浮点音频数据数组?

时间:2011-10-24 19:18:10

标签: objective-c ios core-audio avaudiorecorder audioqueue

我正致力于将音频传输到iPhone,我可以将其传递给(C ++)分析算法。当然,有很多选择:AudioQueue教程at trailsinthesand开始了。

音频回调虽然提供了AudioQueueRef,但我发现Apple的文档在这方面很薄弱。内置的方法可以写入文件,但实际上你没有在数据包内查找数据。

我需要数据。我不想在文件中写任何内容,这就是所有教程 - 甚至Apple的便利I / O对象 - 似乎都是针对的。 Apple的AVAudioRecorder(令人愤怒地)将为您提供级别并写入数据,但实际上并不允许您访问它。除非我遗漏了什么......

怎么做?在下面的代码中,inBuffer->mAudioData非常接近,但我找不到有关此“数据”的格式或访问方式的信息。

AudioQueue Callback:

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;
}

2 个答案:

答案 0 :(得分: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]

答案 1 :(得分:0)

上述解决方案对我不起作用,我本身得到了错误的示例数据。(一个endian问题)如果将来有人拿错了样本数据,我希望这可以帮助你:

- (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);
}