在创建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。