iphone - 如何阻止音频文件在 Apple 的 MixerHost 核心音频示例中循环播放

标签 iphone c core-audio

我有一个应用程序允许用户使用音频单元录制节拍。为此,我修改了 Apple 的 MixerHost 示例代码中的 Mixer 类。

目前我的声音文件在循环,我想停止它。我希望用户能够在声音文件完成后保存混音。

循环的原因是 inputrendercallback 函数的以下部分的最后一行中的 for 循环:

for (UInt32 frameNumber = 0; frameNumber < inNumberFrames; ++frameNumber) {

        outSamplesChannelLeft[frameNumber]                 = dataInLeft[sampleNumber];
        if (isStereo) outSamplesChannelRight[frameNumber]  = dataInRight[sampleNumber];

        sampleNumber++;

        // After reaching the end of the sound stored in memory--that is, after
        //    (frameTotalForSound / inNumberFrames) invocations of this callback--loop back to the 
        //    start of the sound so playback resumes from there.
        if (sampleNumber >= frameTotalForSound) sampleNumber = 0;
    }

我意识到我需要更改 if (sampleNumber >= frameTotalForSound) sampleNumber = 0; 以便告诉回调在样本用完后停止请求样本,但我会在 objective-c 中调用方法比我操纵这个 C 结构要舒服得多。

有没有人知道如何做到这一点?

谢谢。

最佳答案

我只能想象很多人一定遇到过这个音频文件循环问题,因为 MixerHost 是 Apple 提供的为数不多的 Core Audio 示例之一。

我使用 NSNotificationCenter 解决了这个问题。在谴责在 C 函数内部使用 Objective C 之前,请认识到我通过在 MixerHost 示例本身中模仿 Apple 代码的其他部分找到了这个解决方案。例如,要暂停程序并指示耳机已拔下,或者设备已从底座连接器上取下,Apple 使用了 MixerHostAudio 类的 audioRouteChangeListenerCallback 中的通知中心:

 if (routeChangeReason == kAudioSessionRouteChangeReason_OldDeviceUnavailable) {

            NSLog (@"Audio output device was removed; stopping audio playback.");
            NSString *MixerObjectPlaybackStateDidChangeNotification = @"MixerObjectPlaybackStateDidChangeNotification";
            [[NSNotificationCenter defaultCenter] postNotificationName: MixerObjectPlaybackStateDidChangeNotification object: audioObject]; 

我还决定从 inputrendercallback 函数中发布一个通知:

for (UInt32 frameNumber = 0; frameNumber < inNumberFrames; ++frameNumber) {

        if (sampleNumber == frameTotalForSound) {

            NSString *AudioFileFinishedPlaying = @"AudioFileFinishedPlaying";
            [[NSNotificationCenter defaultCenter] postNotificationName: AudioFileFinishedPlaying object: nil];
        }

        outSamplesChannelLeft[frameNumber]                 = dataInLeft[sampleNumber];
        if (isStereo) outSamplesChannelRight[frameNumber]  = dataInRight[sampleNumber];

        sampleNumber++;

...

然后我在程序的另一部分使用 addObserver:selector:name:object: 方法来停止循环并执行与我的应用程序相关的其他任务。

希望对您有所帮助。如果有人有更好的解决方案,那么我愿意接受它。谢谢。

关于iphone - 如何阻止音频文件在 Apple 的 MixerHost 核心音频示例中循环播放,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10242057/

相关文章:

macos - AudioObjectGetPropertyData 获取输入设备列表

iphone - 无法摆脱 UITableView 的 tableFooterView 中的颜色

iphone - 添加本地化时,Appstore 提示名称已存在?

未调用 Objective-C 方法

ios - 在 iPhone 4S 上,ViewController 上的更改不会从 didSelectRowAtIndexPath 持续到 cellForRowAtIndexPath

ios - 从 NSData 解码 MP3 文件

c - 可移植地将二进制补码整数写入内存的算法

c - 在 C 目标中用 antlr3 解析一些特定的语句

c - 错误 : Misplace Else

ios - 为什么插入耳机时 iPhone 底部麦克风的音量与不插入时不同?