ios - 停止 AUGraph 的卡顿

标签 ios objective-c cocoa audio core-audio

当我第一次启动 AUGraph 并使用 kAudioUnitSubType_AudioFilePlayer 组件播放歌曲时,我收到了断断续续的声音。卡顿时间大约为 3 秒,但这足以打扰我,而且我注意到有时在播放时音乐会停顿一秒钟(我猜是为了缓冲?)。我尝试将 kAudioUnitProperty_ScheduledFilePrime 更改为随机值,但没有发现任何变化。

我应该更改哪些变量或值以消除此缺陷?这是流格式的问题吗?

我正在使用来自 https://github.com/ronaldmannak/YBAudioFramework/tree/master/YBAudioUnit 的 YBAudioUnit

代码:

YBAudioFilePlayer:

- (void)setFileURL:(NSURL *)fileURL typeHint:(AudioFileTypeID)typeHint {
    if (_fileURL) {
        // Release old file:
        AudioFileClose(_audioFileID);
    }

    _fileURL = fileURL;

    if (_fileURL) {
        YBAudioThrowIfErr(AudioFileOpenURL((__bridge CFURLRef)fileURL, kAudioFileReadPermission, typeHint, &_audioFileID));
        YBAudioThrowIfErr(AudioUnitSetProperty(_auAudioUnit, kAudioUnitProperty_ScheduledFileIDs, kAudioUnitScope_Global, 0, &_audioFileID, sizeof(AudioFileID)));

        // Get number of audio packets in the file:
        UInt32 propsize = sizeof(_filePacketsCount);
        YBAudioThrowIfErr(AudioFileGetProperty(_audioFileID, kAudioFilePropertyAudioDataPacketCount, &propsize, &_filePacketsCount));

        // Get file's asbd:
        propsize = sizeof(_fileASBD);
        YBAudioThrowIfErr(AudioFileGetProperty(_audioFileID, kAudioFilePropertyDataFormat, &propsize, &_fileASBD));

        // Get unit's asbd:
        propsize = sizeof(_fileASBD);
        AudioUnitGetProperty(_auAudioUnit, kAudioUnitProperty_StreamFormat, kAudioUnitScope_Output, 0, &_unitASBD, &propsize);

        if (_fileASBD.mSampleRate > 0 && _unitASBD.mSampleRate > 0) {
            _sampleRateRatio = _unitASBD.mSampleRate / _fileASBD.mSampleRate;
        } else {
            _sampleRateRatio = 1.;
        }
    }
}

为了播放,我在 YBAudioFilePlayer 上调用了这些方法:

[player1 setFileURL:item.url typeHint:0];
[player1 scheduleEntireFilePrimeAndStartImmediately];
[graph start];//On a YBAudioUnitGraph which is really just a basic AUGraph

最佳答案

这不仅仅是一个答案,这是一个评论,但它相当大,所以我会在这里发布。

我没有时间和耐心研究YB.. API里面的代码。但是我想到了一些事情。

我记得首先尝试使用 Audio Units(使用 Apple 的 API)并且我遇到了很多口吃。我解决了这个问题,删除了将数据提供给我的 AUGraph 的回调中的所有 objective-C 调用(好吧,除了我无法删除的一个,我删除了所有调用)。我用纯 C 和 C++ 调用替换了所有 Objective-c 调用。示例:

... this is the render callback
int i = [myClass someProperty];  // obj-c
int i = myClass->someVarialbe;  // c, c++

这只是一个例子,但它得到了显着改善,我摆脱了口吃。或许你可以看看YBXX API的实现,看看回调中是否有很多obj-c调用,如果有,我不会使用该API。

第二次观察。看起来您只是想播放一个音频文件,拥有 AudioGraph 的开销很大,您可以使用没有 Graph 的单个 IO 音频单元。

关于ios - 停止 AUGraph 的卡顿,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21808286/

相关文章:

macos - 奇数尺寸的 CALayer 模糊

iphone - View Controller 的全局实例是否应该由应用程序委托(delegate)拥有

iphone - UITabBarController 在内存警告后释放 View

objective-c - Objective C 架构问题

ios - 按下时突出显示的UIButton不会在第一次按下时突出显示

iphone - 使用 openssl 加密并使用 AES 128、ecb 模式在 iPhone 上解密

ios - 是否可以在 TestFlight 中同时激活内部和外部构建?

ios - 如何从 Swift 4.2 上的 map (对象)Cloud Firestore 文档中获取数据?

ios - 哪个是显示链接,UITextView/UILabel中的热词的最佳解决方案?

java - Objective-C 委托(delegate)与 Java 监听器