从源码中看AudioTrack对采样率,通道数和AudioFormat的限制

转载:https://www.jianshu.com/p/963fea6e4a0d

新泾镇刀客关注

0.0342016.08.25 12:08:51字数 443阅读 5,068

在创建audiotrack中传入的采样率通道和audioFormat,会共同决定minBufferSize。同样会在getMinBufferSize()方法中check,源码API23.AudioTrack的构造函数中也会对相应参数校验,但这里只看getMinBufferSize()方法。

    static public int getMinBufferSize(int sampleRateInHz, int channelConfig, int audioFormat) {
    int channelCount = 0;
    switch(channelConfig) {
    case AudioFormat.CHANNEL_OUT_MONO:
    case AudioFormat.CHANNEL_CONFIGURATION_MONO:
        channelCount = 1;
        break;
    case AudioFormat.CHANNEL_OUT_STEREO:
    case AudioFormat.CHANNEL_CONFIGURATION_STEREO:
        channelCount = 2;
        break;
    default:
        if (!isMultichannelConfigSupported(channelConfig)) {
            loge("getMinBufferSize(): Invalid channel configuration.");
            return ERROR_BAD_VALUE;
        } else {
            channelCount = AudioFormat.channelCountFromOutChannelMask(channelConfig);
        }
    }

    if (!AudioFormat.isPublicEncoding(audioFormat)) {
        loge("getMinBufferSize(): Invalid audio format.");
        return ERROR_BAD_VALUE;
    }

    // sample rate, note these values are subject to change
    if ( (sampleRateInHz < SAMPLE_RATE_HZ_MIN) || (sampleRateInHz > SAMPLE_RATE_HZ_MAX) ) {
        loge("getMinBufferSize(): " + sampleRateInHz + " Hz is not a supported sample rate.");
        return ERROR_BAD_VALUE;
    }

    int size = native_get_min_buff_size(sampleRateInHz, channelCount, audioFormat);
    if (size <= 0) {
        loge("getMinBufferSize(): error querying hardware");
        return ERROR;
    }
    else {
        return size;
    }
}

通道数

除了单声道,就是立体声了,channelCount不是1就是2。
此外还有多声道的支持判断支持新设备,目前还没有详细学习。使用其他的channelConfig有什么用处还不了解。通过比对发现,其他channelConfig应该算是新特性,至少在api15里面是没有的。所以至少使用其中的一种CHANNEL_OUT_MONO,CHANNEL_CONFIGURATION_MONO,CHANNEL_OUT_STEREO,CHANNEL_CONFIGURATION_STEREO。

sampleRateInHz

一个范围限制。 api23里显示的是从4000到192000。老sdk中没有这么宽的支持,api15中,是4000到48000,。考虑到兼容性,采样率还是尽量在4000-48000.具体选择什么样的采样率还要看需求,如果处理的是人声,人耳可以听见的范围在20-20k,根据耐奎斯特定律,至少也得是40k。如果多音轨合成,尽量还是相同的采样率,目前对android上重采样的实现还没有细研究。

/** Minimum value for sample rate */
private static final int SAMPLE_RATE_HZ_MIN = 4000;
/** Maximum value for sample rate */
private static final int SAMPLE_RATE_HZ_MAX = 192000;

audioFormate

这里调用了isPublicEncoding()方法,里面做了相应判断,但是要注意这里引用的是API23的代码。

public static boolean isPublicEncoding(int audioFormat)
{
    switch (audioFormat) {
    case ENCODING_PCM_8BIT:
    case ENCODING_PCM_16BIT:
    case ENCODING_PCM_FLOAT:
    case ENCODING_AC3:
    case ENCODING_E_AC3:
    case ENCODING_DTS:
    case ENCODING_DTS_HD:
        return true;
    default:
        return false;
    }
}

虽然AudioFormate中定义了很多 ENCODING类型,允许的类型有限。目前看到的类型中,除了PCM_8BIT和PCM_16BIT,还有其他。但是老的sdk中仅允许PCM_8BIT和PCM_16BIT,而且。。。。
多看一眼注释

 // These values must be kept in sync with core/jni/android_media_AudioFormat.h
// Also sync av/services/audiopolicy/managerdefault/ConfigParsingUtils.h
/** Audio data format: PCM 16 bit per sample. Guaranteed to be supported by devices. */
public static final int ENCODING_PCM_16BIT = 2;
/** Audio data format: PCM 8 bit per sample. Not guaranteed to be supported by devices. */
public static final int ENCODING_PCM_8BIT = 3;

ENCODING_PCM_8BIT 并不保证支持,所以还是优选PCM_16BIT。

发布了56 篇原创文章 · 获赞 53 · 访问量 10万+

猜你喜欢

转载自blog.csdn.net/weixin_42082222/article/details/104007091