Core Audio AudioFIleReadPackets ...寻找原始音频

时间:2010-09-18 05:23:01

标签: objective-c core-audio pcm sample-data audiounit

我正在尝试从文件中获取原始音频数据(我习惯于看到介于-1和1之间的浮点值)。

我正在尝试将这些数据实时从缓冲区中提取出来,以便我可以为应用程序提供某种类型的计量。

我基本上是使用AudioFileReadPackets将整个文件读入内存。我创建了一个RemoteIO音频单元来进行播放,在playbackCallback内部,我正在向AudioBuffer提供mData,以便将它发送到硬件。

我遇到的一个大问题是从我的数据数组(来自AudioFileReadPackets)发送到缓冲区的数据是UInt32 ......我真的很困惑。它看起来像是32位,我将数据包/帧设置为每个4字节。我是如何得到原始音频数据(从-1到1)的呢?

这是我的格式说明

// Describe format
audioFormat.mSampleRate         = 44100.00;
audioFormat.mFormatID           = kAudioFormatLinearPCM;
audioFormat.mFormatFlags        = kAudioFormatFlagIsSignedInteger | kAudioFormatFlagIsPacked;
audioFormat.mFramesPerPacket    = 1;
audioFormat.mChannelsPerFrame   = 2;
audioFormat.mBitsPerChannel     = 16;
audioFormat.mBytesPerPacket     = 4;
audioFormat.mBytesPerFrame      = 4;

我正在阅读一个wave文件。

谢谢!

2 个答案:

答案 0 :(得分:1)

我不确定你为什么要从这个回调中获取UInt32数据,尽管我怀疑它实际上是两个隔行扫描的UInt16数据包,每个通道一个。无论如何,如果你想从文件中获得浮点数据,它需要转换,我不相信@John Ballinger建议的方式是正确的。我的建议是:

// Get buffer in render/read callback
SInt16 *frames = inBuffer->mAudioData;
for(int i = 0; i < inNumPackets; i++) {
  Float32 currentFrame = frames[i] / 32768.0f;
  // Do stuff with currentFrame (add it to your buffer, etc.)
}

您不能简单地将帧转换为您想要的格式。如果需要浮点数据,则需要除以32768,这是16位采样的最大可能值。这将产生{-1.0 .. 1.0}范围内的正确浮点数据。

答案 1 :(得分:0)

看看这个功能...... 数据是SInt16。

static void recordingCallback (
    void                                *inUserData,
    AudioQueueRef                       inAudioQueue,
    AudioQueueBufferRef                 inBuffer,
    const AudioTimeStamp                *inStartTime,
    UInt32                              inNumPackets,
    const AudioStreamPacketDescription  *inPacketDesc
) {


    // This callback, being outside the implementation block, needs a reference to the AudioRecorder object
    AudioRecorder *recorder = (AudioRecorder *) inUserData;

    // if there is audio data, write it to the file
    if (inNumPackets > 0) {

        SInt16 *frameBuffer = inBuffer->mAudioData;
        //NSLog(@"byte size %i, number of packets %i, starging packetnumber %i", inBuffer->mAudioDataByteSize, inNumPackets,recorder.startingPacketNumber);

        //int totalSlices = 1;
        //int framesPerSlice = inNumPackets/totalSlices;
        float total = 0;
        for (UInt32 frame=0; frame<inNumPackets; frame+=20) {
            total += (float)abs((SInt16)frameBuffer[frame]) ; 
        }