Core Audio AudioFIleReadPackets… looking for raw audio

白昼怎懂夜的黑 提交于 2019-12-06 12:41:53

问题


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!


回答1:


I'm not sure exactly why you are getting UInt32 data back from this callback, though I suspect that it is actually two interlaced UInt16 packets, one per each channel. Anyways, if you want floating point data from the file, it needs to be converted, and I'm not convinced that the way @John Ballinger recommends is the correct way. My suggestion would be:

// 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.)
}

You can't simply cast the frames to the format you want. If you need floating point data, you will need to divide by 32768, which is the maximum possible value for 16-bit samples. This will yield correct floating point data in the {-1.0 .. 1.0} range.




回答2:


Have a look at this function... The data is 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]) ; 
        }


来源:https://stackoverflow.com/questions/3740499/core-audio-audiofilereadpackets-looking-for-raw-audio

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!