【问题标题】:How to get array of float audio data from AudioQueueRef in iOS?如何从 iOS 中的 AudioQueueRef 获取浮点音频数据数组?
【发布时间】:2011-12-14 09:46:48
【问题描述】:

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

不过,音频回调给出了AudioQueueRef,我发现 Apple 的文档在这方面很薄弱。用于写入文件的内置方法,但在您实际查看数据包内部以查看数据的位置没有任何内容。

我需要数据。我不想将任何内容写入文件,这似乎是所有教程——甚至是 Apple 的便捷 I/O 对象——的目标。 Apple 的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;
}

【问题讨论】:

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


    【解决方案1】:

    上述解决方案对我不起作用,我自己得到了错误的样本数据。(一个字节序问题)如果将来有人得到错误的样本数据,我希望这对你有帮助:

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

    【讨论】:

      【解决方案2】:
        // 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] 访问它。

      【讨论】:

      • 这个“samples”数组,它包含多少秒的采样?这是录制音频的二进制表示吗?
      • "samples" 包含一个缓冲区的样本。长度为秒取决于缓冲区大小和采样率:44.1kHz 的 512 个样本为 512/44100 = .011609977 秒。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2018-09-25
      • 2016-04-17
      • 1970-01-01
      • 1970-01-01
      • 2020-12-19
      • 2010-10-30
      • 1970-01-01
      相关资源
      最近更新 更多