尝试识别核心音频与iPhone后台执行的问题

时间:2010-09-12 16:09:47

标签: iphone core-audio multitasking

我在商店里有一个音频应用程序。它适用于iOS 4.0之前的iPhone OS版本。我正在开发一个新版本,首先要使应用程序符合新的iOS多任务处理功能。 (我的iPhone上有iOS 4.0,并已升级到最新的xCode和SDK。)

结果是一个显示阻止。

o当我在iPhone上安装应用程序并在调试器中运行,或者在iPhone关闭后启动应用程序时,应用程序就可以正常工作 - 按下按钮时播放音频,或者从“状态”重启音频上次应用程序运行时保存了。

o如果我尝试按下主页按钮,然后从后台重新启动应用程序,那么音频 - 和1-n音频流的混合 - 会发出只有我能识别的口吃声。

o如果 - 虽然音频很干净 - 我打电话给iPhone,我可以接听或拒绝接听电话。在这两种情况下,应用程序都会干净利落地进行播放。

请注意,在后台模式下,我不想尝试播放任何内容。我只想关闭一些东西并在被问到时将它们带回来。

技术:所有音频逻辑都使用RemoteIO。 (我有一天计划做一些相当复杂的信号处理。)

请原谅伪代码叙述 - 一些真正的代码非常广泛。

MainViewController:

o viewDidLoad - 没什么特别的

o didBecomeActive     将self设置为音频会话代理;     将AudioSessionCategory设置为MediaPlayback;     设置AudioSessionActive;     创建一个播放器(见下文);     重新启动之前播放的任何声音;

o willResignActive     保存播放的状态;     调用stopAllSounds;     阻止玩家;     设置音频会话无效;

o didEnterBackground - 没有(方法已注册,但没有内容。)

o willEnterForeground - 没有(方法已注册,但没有内容。)

播放器概述 - 我的课程: 玩家是单身人士。我确保在didBecomeActive中销毁单例实例,并创建一个新实例。实例化单例实际上启动了AudioUnit。

构造     setupRemoteIO; 开始     AudioOutputUnitStart; 停     AudioOutputUnitStop; 球员回调     通常的东西;

  
    

>

  

以下是我的MainViewController中的一些方法:

(void)willResignActive:(NSNotification *)note {
    [ self saveState ];
    [ [ NaturePlayer getInstance ] stopAllSounds ];
    [ [ NaturePlayer getInstance ] stop ];
    NSError *activationError = nil;
    [[AVAudioSession sharedInstance] setActive: NO error: &activationError]; 
    [NaturePlayer destroy];

}

- (void)didBecomeActive:(NSNotification *)note {
    [ self setupAudioSession ];

    NSError *activationError = nil;
    [[AVAudioSession sharedInstance] setActive: YES error: &activationError]; 
    [ self restartSounds ];
    [ self setViewState ];
}

- (void)didEnterBackground:(NSNotification *)note {
    int xxx = 1;
}

- (void)willEnterForeground:(NSNotification *)note {
    int xxx = 1;
}

- (void) applicationWillTerminate: (NSNotification*) notification {
    int xxx = 1;
}

以下是NaturePlayer的方法:

/**
 * Stop the playback process.
 */
void NaturePlayerDelegate::stop() {
    if (isPlaying_) {
        AudioOutputUnitStop(outputUnit_);
        isPlaying_ = FALSE ;        
    }

}

我检查过:正在调用stop(),然后调用AudioOutputUnitStop(); 同时检查:AudioOutputUnitStop上的文档说它会阻塞,直到所有活动都完成。

3 个答案:

答案 0 :(得分:0)

很难说没有关于音频代码的更多细节。但我建议您可能需要检查您的Player对象拆解代码,以确保在释放内容之前完全停止音频单元和音频会话(缓冲区回调线程耗尽)。

答案 1 :(得分:0)

您是否在代码中初始化和取消初始化AudioUnits?我最近发现一个问题,即创建和销毁AudioUnit然后离开并返回到您的应用程序将导致口吃。

我能够通过永不取消初始化AudioUnits来解决这个问题。

More info关于我的问题和我的AudioUnit代码。

答案 2 :(得分:0)

我在我的一个项目中遇到了同样的问题。我发现如果在挂起应用程序之前从按钮单击调用AudioOutputUnitStop(),然后在应用程序恢复时调用AudioOutputUnitStart(),我没有遇到任何问题。但是如果我从viewDidUnload处理程序中自动调用AudioOutputUnitStop()或者作为对UIApplicationWillResignActiveNotification的响应,我就会听到上面描述的口吃,类似反馈的声音。

我还注意到,如果我手动停止音频设备,然后暂停应用程序,则会调用中断监听器。但是,如果我在音频设备仍在运行时暂停应用程序,则不会调用中断侦听器。中断监听器应该停止音频单元,所以这对我没有好处。

经过几个小时的追踪,我找到了一种方法来完成没有音频单元的任务,并将它们从我的应用程序中取出。所以我担心我没有完整的答案。但希望这些线索可以帮助某些人。我可能需要在将来再次这样做,所以我会在这里查看是否有其他人已经弄清楚了。