我正在尝试从文件中获取原始音频数据(我习惯于看到介于-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文件。
谢谢!
答案 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]) ;
}