1

I'm trying to get raw audio data from a file (i'm used to seeing floating point values between -1 and 1).

I'm trying to pull this data out of the buffers in real time so that I can provide some type of metering for the app.

I'm basically reading the whole file into memory using AudioFileReadPackets. I've create a RemoteIO audio unit to do playback and inside of the playbackCallback, i'm supplying the mData to the AudioBuffer so that it can be sent to hardware.

The big problem I'm having is that the data being sent to the buffers from my array of data (from AudioFileReadPackets) is UInt32... I'm really confused. It looks like it's 32-bits and I've set the packets/frames to be 4bytes each. How the heck to I get my raw audio data (from -1 to 1) out of this?

This is my Format description

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

I am reading a wave file currently.

Thanks!

4

2 回答 2

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} 范围内产生正确的浮点数据。

于 2010-09-20T07:57:17.127 回答
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]) ; 
        }
于 2010-09-18T06:10:07.257 回答