我从 wav 文件中获取 AudioBufferList(采样率为 44100HZ,长时间为 2 秒)。但我无法获得 44100*2=88200 个样本。实际上,我得到了一个包含 512 个 nNumberBuffers 的 AudiobufferList。如何从 AudioBufferList 中获取样本?
问问题
1042 次
3 回答
2
这是我从 wav 文件中获取样本的方法
-(float *) GetSoundFile:(NSString *)fileName
{
NSBundle *bundle = [NSBundle mainBundle];
NSString *path = [bundle pathForResource:[fileName stringByDeletingPathExtension]
ofType:[fileName pathExtension]];
NSURL *audioURL = [NSURL fileURLWithPath:path];
if (!audioURL)
{
NSLog(@"file: %@ not found.", fileName);
}
OSStatus err = 0;
theFileLengthInFrames = 0; //this is global
AudioStreamBasicDescription theFileFormat;
UInt32 thePropertySize = sizeof(theFileFormat);
ExtAudioFileRef extRef = NULL;
void* theData = NULL;
AudioStreamBasicDescription theOutputFormat;
// Open a file with ExtAudioFileOpen()
err = ExtAudioFileOpenURL((__bridge CFURLRef)(audioURL), &extRef);
// Get the audio data format
err = ExtAudioFileGetProperty(extRef, kExtAudioFileProperty_FileDataFormat, &thePropertySize, &theFileFormat);
theOutputFormat.mSampleRate = samplingRate = theFileFormat.mSampleRate;
theOutputFormat.mChannelsPerFrame = numChannels = 1;
theOutputFormat.mFormatID = kAudioFormatLinearPCM;
theOutputFormat.mBytesPerFrame = sizeof(Float32) * theOutputFormat.mChannelsPerFrame ;
theOutputFormat.mFramesPerPacket = theFileFormat.mFramesPerPacket;
theOutputFormat.mBytesPerPacket = theOutputFormat.mFramesPerPacket * theOutputFormat.mBytesPerFrame;
theOutputFormat.mBitsPerChannel = sizeof(Float32) * 8 ;
theOutputFormat.mFormatFlags = 9 | 12;
//set the output property
err = ExtAudioFileSetProperty(extRef, kExtAudioFileProperty_ClientDataFormat, sizeof(AudioStreamBasicDescription), &theOutputFormat);
// Here I Get the total frame count and write it into gloabal variable
thePropertySize = sizeof(theFileLengthInFrames);
err = ExtAudioFileGetProperty(extRef, kExtAudioFileProperty_FileLengthFrames, &thePropertySize, &theFileLengthInFrames);
UInt32 dataSize = (UInt32)(theFileLengthInFrames * theOutputFormat.mBytesPerFrame);
theData = malloc(dataSize);
AudioBufferList theDataBuffer;
if (theData)
{
theDataBuffer.mNumberBuffers = 1;
theDataBuffer.mBuffers[0].mDataByteSize = dataSize;
theDataBuffer.mBuffers[0].mNumberChannels = theOutputFormat.mChannelsPerFrame;
theDataBuffer.mBuffers[0].mData = theData;
// Read the data into an AudioBufferList
err = ExtAudioFileRead(extRef, (UInt32*)&theFileLengthInFrames, &theDataBuffer);
}
return (float*)theDataBuffer.mBuffers[0].mData;
//here is the data that has thefilelengthInframes amount frames
}
于 2014-11-06T07:13:00.150 回答
1
AudioBufferList 不应设置为固定大小,因为它是一个临时缓冲区,取决于硬件。大小是不可预测的,您只能设置一个更可取的大小,而且在 2 次读取调用之间不被授予相同的大小。要获得 88200 个样本(或您喜欢的样本),您必须使用 AudioBufferList 中的样本逐步填充新缓冲区。我建议使用为此目的制作的这个循环缓冲区https://github.com/michaeltyson/TPCircularBuffer 。希望这有帮助
于 2013-02-11T10:29:51.093 回答
0
据我所知,AudioBufferList 必须由您配置以接收数据,然后必须由一些读取函数(例如 ExtAudioFileRead())填充。因此,您应该通过分配所需的缓冲区(通常为 1 或 2)来准备它,将 nNumberBuffers 设置为该数字并将音频数据读取给它们。AudioBufferList 仅存储该缓冲区,它们将包含帧值。
于 2012-09-17T16:18:57.773 回答