首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使用.caf播放ExtAudioFileRead音频文件不是同步的

使用.caf播放ExtAudioFileRead音频文件不是同步的
EN

Stack Overflow用户
提问于 2015-03-22 19:26:34
回答 1查看 211关注 0票数 0

我的应用程序对来自麦克风输入的音频进行巨大的数据处理。为了获得一个“演示模式”,我想做同样的事情,基于本地的.caf音频文件。我设法得到了音频文件。现在,我尝试使用ExtAudioFileRead读取.caf文件,然后进行数据处理。

代码语言:javascript
复制
void readFile()
{
OSStatus err = noErr;

// Audio file
NSURL *path = [[NSBundle mainBundle] URLForResource:@"output" withExtension:@"caf"];
ExtAudioFileOpenURL((__bridge CFURLRef)path, &audio->audiofile);
assert(audio->audiofile);

// File's format.
AudioStreamBasicDescription fileFormat;
UInt32 size = sizeof(fileFormat);
err = ExtAudioFileGetProperty(audio->audiofile, kExtAudioFileProperty_FileDataFormat, &size, &fileFormat);

// tell the ExtAudioFile API what format we want samples back in
//bzero(&audio->clientFormat, sizeof(audio->clientFormat));
audio->clientFormat.mSampleRate         = SampleRate;
audio->clientFormat.mFormatID           = kAudioFormatLinearPCM;
audio->clientFormat.mFormatFlags        = kAudioFormatFlagIsSignedInteger | kAudioFormatFlagIsPacked;
audio->clientFormat.mFramesPerPacket    = 1;
audio->clientFormat.mChannelsPerFrame   = 1;
audio->clientFormat.mBitsPerChannel     = 16;//sizeof(AudioSampleType) * 8;
audio->clientFormat.mBytesPerPacket     = 2 * audio->clientFormat.mChannelsPerFrame;
audio->clientFormat.mBytesPerFrame      = 2 * audio->clientFormat.mChannelsPerFrame;
err = ExtAudioFileSetProperty(audio->audiofile, kExtAudioFileProperty_ClientDataFormat, sizeof(audio->clientFormat), &audio->clientFormat);

// find out how many frames we need to read
SInt64 numFrames = 0;
size = sizeof(numFrames);
err = ExtAudioFileGetProperty(audio->audiofile, kExtAudioFileProperty_FileLengthFrames, &size, &numFrames);

// create the buffers for reading in data
AudioBufferList *bufferList = malloc(sizeof(AudioBufferList) + sizeof(AudioBuffer) * (audio->clientFormat.mChannelsPerFrame - 1));
bufferList->mNumberBuffers = audio->clientFormat.mChannelsPerFrame;
for (int ii=0; ii < bufferList->mNumberBuffers; ++ii)
{
    bufferList->mBuffers[ii].mDataByteSize = sizeof(float) * (int)numFrames;
    bufferList->mBuffers[ii].mNumberChannels = 1;
    bufferList->mBuffers[ii].mData = malloc(bufferList->mBuffers[ii].mDataByteSize);
}

UInt32 maxReadFrames = 1024;
UInt32 rFrames = (UInt32)numFrames;
while(rFrames > 0)
{
    UInt32 framesToRead = (maxReadFrames > rFrames) ? rFrames : maxReadFrames;
    err = ExtAudioFileRead(audio->audiofile, &framesToRead, bufferList);
    [audio processAudio:bufferList];
    if (rFrames % SampleRate == 0)
        [audio realtimeUpdate:nil];
    rFrames = rFrames - maxReadFrames;
}

// Close the file
ExtAudioFileDispose(audio->audiofile);

// destroy the buffers
for (int ii=0; ii < bufferList->mNumberBuffers; ++ii)
{
    free(bufferList->mBuffers[ii].mData);
}
free(bufferList);
bufferList = NULL;
}

很明显,有些事情我不理解,或者ExtAudioFileRead做错了,因为这段代码根本不起作用。我有两个主要问题:

  1. 该文件立即播放。我的意思是,44'100个样本显然不等于1秒。我的3分钟音频文件处理在几秒钟内完成.
  2. 在处理过程中,我需要更新UI。所以我有一些dispatch_sync在processaudiorealtimeUpdate。这似乎真的没有得到ExtAudioFileRead的赞赏,而且被冻结了。谢谢你的帮助。
EN

回答 1

Stack Overflow用户

发布于 2015-04-02 19:29:24

您编写的代码只是从文件中读取示例,然后调用processAudio。我们将尽快完成这一工作。一旦processAudio完成,就会读取下一批示例,并再次调用processAudio。您不应该假设从音频文件(这是一个低级别和非阻塞的os调用)读取的时间与音频读取所需的时间相同。如果您想按照示例速率处理文件中的音频,您可能应该使用AUFilePlayer音频单元。这可以以正确的速度播放文件,您可以使用回调在真实的音频时间内处理示例,而不是“尽可能快”。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/29198838

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档