1

我从 wav 文件中获取 AudioBufferList(采样率为 44100HZ,长时间为 2 秒)。但我无法获得 44100*2=88200 个样本。实际上,我得到了一个包含 512 个 nNumberBuffers 的 AudiobufferList。如何从 AudioBufferList 中获取样本?

4

3 回答 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 回答