2

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

结果是一场演出。

o 当我在 iPhone 上安装应用程序并在调试器中运行时,或在 iPhone 关机后启动应用程序时,应用程序运行良好 - 当我按下按钮时播放音频,或从保存的“状态”重新启动音频上次运行应用程序的时间。

o 如果我尝试按下 Home 按钮,然后从后台重新启动应用程序,音频(a 和 1-n 音频流的混合)会发出只有我能识别的断断续续的声音。

o 如果 - 在音频清晰的情况下 - 我拨打 iPhone,我可以接听或拒绝接听电话。在这两种情况下,应用程序都会干净利落地恢复正常运行。

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

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

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

主视图控制器:

o viewDidLoad - 没什么特别的

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

o willResignActive 保存正在播放的状态;停止所有声音;停止播放器;将音频会话设置为非活动状态;

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

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

Player 概述 - 我的班级:Player 是一个单身人士。我确保单例实例被销毁,并在 didBecomeActive 中创建了一个新实例。实例化单例实际上会启动 AudioUnit。

构造函数setupRemoteIO;启动音频输出单元开始;停止音频输出单元停止;播放器回调通常的东西;

>

以下是我的 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 上的文档说它会阻塞,直到所有活动完成。

4

3 回答 3

0

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

通过从不取消初始化 AudioUnits,我能够在我的应用程序中解决这个问题。

有关我的问题和我的 AudioUnit 代码的更多信息。

于 2011-05-25T23:33:51.077 回答
0

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

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

经过几个小时的跟踪,我找到了一种无需音频单元即可完成任务的方法,并将它们从我的应用程序中取出。所以恐怕我没有完整的答案。但希望这些线索能对某人有所帮助。将来我可能需要再次执行此操作,因此我将返回此处查看其他人是否已解决此问题。

于 2011-08-05T01:40:36.657 回答
0

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

于 2010-09-12T16:47:50.077 回答