以 pc 为例:
设: 转换 的值为 X_short_sample;
因为: n_int_sample / int_Max = X_short_sample / short_Max;
所以: X_short_sample = ( n_int_sample * short_Max ) / int_Max ;
其它相关格式转换,原理应该一样;
float 转换稍微麻烦,可以简化,如: float to short :
> 0 : 取整;
<0 : 取0;
如果想要精确参考如下:
webrtc 提供的 short 和 float 的转换:
// The conversion functions use the following naming convention:
// S16: int16_t [-32768, 32767]
// Float: float [-1.0, 1.0]
// FloatS16: float [-32768.0, 32767.0]
// Dbfs: float [-20.0*log(10, 32768), 0] = [-90.3, 0]
// The ratio conversion functions use this naming convention:
// Ratio: float (0, +inf)
// Db: float (-inf, +inf)
static inline int16_t FloatToS16(float v) {
if (v > 0)
return v >= 1 ? limits_int16::max()
: static_cast<int16_t>(v * limits_int16::max() + 0.5f);
return v <= -1 ? limits_int16::min()
: static_cast<int16_t>(-v * limits_int16::min() - 0.5f);
}
static inline float S16ToFloat(int16_t v) {
static const float kMaxInt16Inverse = 1.f / limits_int16::max();
static const float kMinInt16Inverse = 1.f / limits_int16::min();
return v * (v > 0 ? kMaxInt16Inverse : -kMinInt16Inverse);
}
static inline int16_t FloatS16ToS16(float v) {
static const float kMaxRound = limits_int16::max() - 0.5f;
static const float kMinRound = limits_int16::min() + 0.5f;
if (v > 0)
return v >= kMaxRound ? limits_int16::max()
: static_cast<int16_t>(v + 0.5f);
return v <= kMinRound ? limits_int16::min() : static_cast<int16_t>(v - 0.5f);
}
static inline float FloatToFloatS16(float v) {
return v * (v > 0 ? limits_int16::max() : -limits_int16::min());
}
static inline float FloatS16ToFloat(float v) {
static const float kMaxInt16Inverse = 1.f / limits_int16::max();
static const float kMinInt16Inverse = 1.f / limits_int16::min();
return v * (v > 0 ? kMaxInt16Inverse : -kMinInt16Inverse);
}