13

我正在努力以一种可以将音频传递给(C++)分析算法的形式将音频输入 iPhone。当然,有很多选择:trailsinthes 上的 AudioQueue 教程事情开始。

但是,音频回调给出了AudioQueueRef,我发现 Apple 的文档在这方面很薄。写入文件的内置方法,但没有在数据包内部实际查看数据的地方。

我需要数据。我不想将任何内容写入文件,这似乎是所有教程——甚至是 Apple 的便利 I/O 对象——的目标。Apple AVAudioRecorder(令人愤怒)会给你关卡并写入数据,但实际上并没有让你访问它。除非我错过了什么...

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

音频队列回调:

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

2 回答 2

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]to访问samples[sampleCount-1]

于 2011-11-01T14:10:34.830 回答
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);
}
于 2017-06-22T13:45:44.283 回答