ReformatBufferProvider和ClampFloatBufferProvider
简介
ReformatBufferProvider就是用于转换输入和输出的数据format不一致,比如输入是float、输出是int32_t;
ClampFloatBufferProvider则是将float类型的音频数据其能量限制在[-3dB,3dB]中
ReformatBufferProvider转换规则
转换规则大致如下:
void ReformatBufferProvider::copyFrames(void *dst, const void *src, size_t frames)
{memcpy_by_audio_format(dst, mOutputFormat, src, mInputFormat, frames * mChannelCount);//float >> int16: float * (1 << 15) 等比例缩放,并在限制在-32768,32767范围//int16_t >> float: int16_t * (1/(1<<15)),也就是int16_t/16bit的max值//uint8_t >> int16_t: (uint8_t-0x80) << 8;1. -0x80将0~256转换到-128~127,左移8缩放//int16_t >> uint8_t: (int16_t >> 8)+0x80//int16_t >> int32_t: int16_t << 16,这个移位操作实质也是等比例放大,//16_max=2^15 32_max=2^31,设16bit内的值为32000,通过等比例换算//16_max/32_max=32000/x,计算x=2097152000=32000<<16//int32_t >> int16_t: int32_t >> 16
}
精华在注释当中,其具体实现在./system/media/audio_utils/format.c,有兴趣的可自行去查阅,本篇文章不在具体介绍
ClampFloatBufferProvider限制规则
void ClampFloatBufferProvider::copyFrames(void *dst, const void *src, size_t frames)
{//src没有作任何操作,只是将src限制在[-x, x]之间memcpy_to_float_from_float_with_clamping((float*)dst, (const float*)src,frames * mChannelCount,FLOAT_NOMINAL_RANGE_HEADROOM);//3dB的衰减因子,3=20lgx,x=1.412538
}
FLOAT_NOMINAL_RANGE_HEADROOM就是3dB的衰减因子, 3 d B = 20 l g x 3dB=20lg x 3dB=20lgx计算 x = 1.412538 x=1.412538 x=1.412538
进入memcpy_to_float_from_float_with_clamping看看:
/**
* 将dst限制在[-absMx, absMax]
**/
void memcpy_to_float_from_float_with_clamping(float *dst, const float *src, size_t count,float absMax) {// Note: using NEON intrinsics (vminq_f32, vld1q_f32...) did NOT accelerate// the function when benchmarked. The compiler already vectorize using FMINNM f32x4 & similar.// Note: clamping induce a ~20% overhead compared to memcpy for count in [64, 512]// See primitives_benchmarkfor (; count > 0; --count) {const float sample = *src++;*dst++ = fmax(-absMax, fmin(absMax, sample));}
}
将dst限制在[-absMx, absMax],可以把音频数据当作是一个能量值;