PCM 音频 AV_SAMPLE_FMT_S32 转 AV_SAMPLE_FMT_S16

以 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);

}

你可能感兴趣的:(FFmpeg,WebRTC)