gpt4 book ai didi

iOS音频系统。开始&停止还是只是开始?

转载 作者:行者123 更新时间:2023-11-29 12:23:15 24 4
gpt4 key购买 nike

我有一个应用程序,其中录音是主要和最重要的部分。然而,用户可以切换到显示所有记录但不执行记录的 TableView Controller 。

问题是哪种方法更好:“启动和停止音频系统或只启动它”。看起来第一个更正确似乎很明显,例如“在需要时分配,在使用时释放”。我将表达我对这个问题的看法,我希望在技术人员中通过争论找到赞同或不赞成。

当我第一次构建 AudioController.m 时,我实现了打开/关闭 Audio Session 和启动/停止音频单元的方法。我想在录音未激活时停止音频系统。我使用了以下代码:

- (BOOL)startAudioSystem {

// open audio session
AVAudioSession *audioSession = [AVAudioSession sharedInstance];
NSError *err = nil;
if (![audioSession setActive:YES error:&err] ) {
NSLog(@"Couldn't activate audio session: %@", err);
}
// start audio unit
OSStatus status;
status = AudioOutputUnitStart([self audioUnit]);
BOOL noErrors = err == nil && status == noErr;
return noErrors;
}

- (BOOL)stopAudioSystem {
// stop audio unit
BOOL result;
result = AudioOutputUnitStop([self audioUnit]) == noErr;
HANDLE_RESULT(result);
// close audio session
NSError *err;
HANDLE_RESULT([[AVAudioSession sharedInstance] setActive:NO withOptions:AVAudioSessionSetActiveOptionNotifyOthersOnDeactivation error:&err]);
HANDLE_ERROR(err);
BOOL noErrors = err == nil && result;
return noErrors;
}

我发现这种方法有问题,原因如下:

  1. 音频系统延迟启动。这意味着,有一段时间没有调用 recording_callback()。我怀疑是 AudioOutputUnitStart 造成的。我试图用这个函数调用注释掉这一行并将其移至初始化。延迟消失了。
  2. 如果用户非常非常快地在录音 View 和表格 View 之间执行切换(音频系统的启动和停止也非常快),它会导致媒体服务死亡(我知道观察 AVAudioSessionMediaServicesWereResetNotification 可以帮助这里,但它不是点)。

为了解决这些问题,我用我设法发现的其他方法修改了 AudioController.m:当应用程序激活时启动音频系统并且在应用程序终止之前不要停止它在这种情况下有还有几个问题:

  1. CPU 使用率
  2. 如果音频类别设置为仅录音,则当用户浏览 TableView Controller 时不能播放其他音频。

第一个令人惊讶的没什么大不了的,如果像这样取消 recording_callback() 中的任何一种处理:

    static OSStatus recordingCallback(void *inRefCon,
AudioUnitRenderActionFlags *ioActionFlags,
const AudioTimeStamp *inTimeStamp,
UInt32 inBusNumber,
UInt32 inNumberFrames,
AudioBufferList *ioData) {

AudioController *input = (__bridge AudioController*)inRefCon;

if(!input->shouldPerformProcessing)
return noErr;

// processing
// ...
//

return noErr;
}

通过执行此操作,当不需要录制且不执行其他操作时,真实设备上的 CPU 使用率等于 0%。

第二个问题可以通过将音频类别切换到 RecordAndPlay 并启用混音或忽略该问题来解决。例如在我的案例中,应用程序需要外部设备使用迷你插孔,因此不能并行使用耳机。

尽管如此,第一种方法更接近我,因为我喜欢在不再需要时关闭/清理每个流/资源。而且我想确定除了启动音频系统之外确实没有其他选择。请确保我不是唯一找到此解决方案的人,而且它是正确的。

最佳答案

解决这个问题的关键是要注意音频系统实际上是在另一个(实时)线程中运行的。当你(或应用程序的主 UI 线程)“不需要它”时,你不能真正停止并释放在另一个线程中运行的东西,但必须延迟才能让另一个线程意识到它需要做一些东西,然后完成并清理自己。对于音频,这可能需要多达 100 毫秒。

鉴于此,策略 2(刚开始)更安全、更现实。

或者在尝试停止音频之前设置许多秒的不使用延迟,并可能在此之后再尝试任何重新启动之前设置另一个短暂的延迟。

关于iOS音频系统。开始&停止还是只是开始?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29967394/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com