如何判断IOS设备在硬件上是否仅支持48kHz

如何判断IOS设备在硬件上是否仅支持48kHz,ios,core-audio,Ios,Core Audio,较新的IOS设备(如6S)仅支持本机48kHz播放。因为标准的CoreAudio图可以很好地重新采样,所以问题不大。问题是,如果您正在使用语音处理单元执行VOIP类型的应用程序,则无法将手机设置为44.1kHz;它创造了一个很好的达斯维德式的体验 以前,我经常检查设备的型号,然后简单地说‘如果是6S或更高,那么我必须重新采样44.1到48kHz),这样效果很好。我不喜欢此修复,因此我尝试了以下代码: session = [AVAudioSession sharedInstance]; [ses

较新的IOS设备(如6S)仅支持本机48kHz播放。因为标准的CoreAudio图可以很好地重新采样,所以问题不大。问题是,如果您正在使用语音处理单元执行VOIP类型的应用程序,则无法将手机设置为44.1kHz;它创造了一个很好的达斯维德式的体验

以前,我经常检查设备的型号,然后简单地说‘如果是6S或更高,那么我必须重新采样44.1到48kHz),这样效果很好。我不喜欢此修复,因此我尝试了以下代码:

session = [AVAudioSession sharedInstance];

[session setActive:YES error:&nsError];

if (systemSampleRate == 44100)      // We may need to resample if it's a phone that only supports 48kHz like the 6S or 6SPlus
{
    [session setCategory:AVAudioSessionCategoryPlayback
             withOptions:0
                   error:&nsError];

    result = [session setPreferredSampleRate:systemSampleRate error:&nsError];

    hardwareSampleRate = [session sampleRate];

    NSLog (@"Phone reports sample rate of %f", hardwareSampleRate);

    if (hardwareSampleRate != (double)systemSampleRate)     // We can't set it!!!!
        needsResampling = YES;
    else
    {
        [session setCategory:AVAudioSessionCategoryRecord
                 withOptions:AVAudioSessionCategoryOptionAllowBluetooth
                       error:&nsError];

        result = [session setPreferredSampleRate:systemSampleRate error:&nsError];

        hardwareSampleRate = [session sampleRate];

        if (hardwareSampleRate != (double)systemSampleRate)     // We can't set it!!!!
            needsResampling = YES;
        else
            needsResampling = NO;
    }
}
大多数情况下,这是可行的。6S设备将报告48kHz,所有其他设备将报告44.1kHz。但是,如果它被绑定到只支持8kHz麦克风音频和44.1kHz播放的蓝牙耳机类型的系统,第一个硬件采样率值报告为44.1!!!!所以我继续认为该设备本机支持44.1,但一切都搞砸了


所以问题是:我如何确定IOS上的本机播放设备物理上只支持48kHz,还是可以同时支持44.1和48kHz?苹果公司关于这一点的公开文件毫无价值,它只是指责人们假设一台设备同时支持这两种功能,而不告诉你如何解决它。

你真的需要假设采样率可以改变。如果systemSampleRate是一个外部需求,请尝试将采样率设置为该值,然后使用您得到的结果。问题是,每次音频渲染链启动或在采样率发生变化时中断时,都必须执行此检查

我使用两种不同的方法来处理这个问题,如果采样率发生变化,这两种方法都涉及拆除和重新初始化我的音频单元链

一种简单的方法是将我的音频单元的所有采样率设置为系统采样率(由活动音频会话上的采样率属性提供)。我假设这是最高质量的方法,因为没有采样率转换

如果我有一个采样率的要求,我将创建我的链与我所需的采样率。然后检查系统采样率是否与我的要求不同。如果不同,我将把转换器单元放在系统单元(远程io)和链末端之间


底线是,最重要的信息是系统采样率是否与您的要求不同,而不是它是否可以更改。这完全是一种痛苦,当6S问世时,一堆音频应用程序都坏了,但这是正确的处理方法。

你从哪里得到systemSampleRate?啊,应该提到。这是系统“想要”运行的理想采样率。它只是被传递到这个例程中,并在其他地方定义。它的值只有44100或48000。它在哪里定义?同样,在这一点之上。像这样:int-systemSampleRate;它只是由一条网络消息触发的,只包含44100或48000条消息。如果您尝试在6秒或6秒以上的时间内使用44100的kAudioUnitSubType_VoiceProcessingIO,系统将很容易接受它(甚至说它在44100运行),但会产生可怕的音频伪影。这些手机必须以48000的速度运行,并在CoreAudio之外执行外部重采样。很容易判断手机的型号,但我不愿意假设未来的所有设备都必须以48000运行。