PCM混音
来源:互联网 发布:叶英捏脸数据 编辑:程序博客网 时间:2024/04/29 05:00
混音
pcm混音的原理是把两组数据相加,相加后的数据范围不能超过pcm位宽的表示范围,MixFrames
写死是int16_t类型(具体查看AudioFrame),所以可以看出webrtc内混音处理是不支持16bit之外的pcm音频。
PCM操作,包括单声道转立体声、立体声转单声道、哑音、音量调整。
音频术语
webrtc中的混音函数在webrtc/modules/audio_conference_mixer/source/audio_conference_mixer_impl.cc
,也就是下面这个函数。
// Mix |frame| into |mixed_frame|, with saturation protection and upmixing.// These effects are applied to |frame| itself prior to mixing. Assumes that// |mixed_frame| always has at least as many channels as |frame|. Supports// stereo at most.//// TODO(andrew): consider not modifying |frame| here.void MixFrames(AudioFrame* mixed_frame, AudioFrame* frame, bool use_limiter) { assert(mixed_frame->num_channels_ >= frame->num_channels_); if (use_limiter) { // Divide by two to avoid saturation in the mixing. // This is only meaningful if the limiter will be used. *frame >>= 1; } if (mixed_frame->num_channels_ > frame->num_channels_) { // We only support mono-to-stereo. assert(mixed_frame->num_channels_ == 2 && frame->num_channels_ == 1); AudioFrameOperations::MonoToStereo(frame); } *mixed_frame += *frame;}
最后一句代码才是混合的关键所在,它调用了AudioFrame的重载函数+=
,也就是进行了下面的操作。也就是把相加后的数据控制在int16_t范围。
文件路径是:webrtc/modules/interface/module_common_types.h
inline AudioFrame& AudioFrame::operator+=(const AudioFrame& rhs) { ... if (speech_type_ != rhs.speech_type_) speech_type_ = kUndefined; if (noPrevData) { memcpy(data_, rhs.data_, sizeof(int16_t) * rhs.samples_per_channel_ * num_channels_); } else { // IMPROVEMENT this can be done very fast in assembly for (int i = 0; i < samples_per_channel_ * num_channels_; i++) { int32_t wrapGuard = static_cast<int32_t>(data_[i]) + static_cast<int32_t>(rhs.data_[i]); if (wrapGuard < -32768) { data_[i] = -32768; } else if (wrapGuard > 32767) { data_[i] = 32767; } else { data_[i] = (int16_t)wrapGuard; } } } energy_ = 0xffffffff; return *this;}
最后的判断可以用宏来写
#define MIXER_MAX(x,y) ((x)>(y)? (x):(y))#define MIXER_MIN(x,y) ((x)<(y)? (x):(y))#define MIXER_CLIP3(a,b,x) (MIXER_MAX(a,MIXER_MIN(x,b))) /* clip x between a and b */#define MIXER_CLIP(x) MIXER_CLIP3(-32768,32767,x)for (int i = 0; i < samples_per_channel_ * num_channels_; i++) { int32_t wrapGuard = static_cast<int32_t>(data_[i]) + static_cast<int32_t>(rhs.data_[i]); data_[i] = (int16_t)MIXER_CLIP(wrapGuard);}
Android源码里面是这样写的,用位移的效率要高一些,我仅仅是根据理论知识推测效率要比判断要高,没有进行过对比。
static inline int16_t clamp16(int32_t sample){ if ((sample>>15) ^ (sample>>31)) sample = 0x7FFF ^ (sample>>31); return sample;}
0 0
- PCM混音
- pcm混音
- PCM
- PCM
- PCM
- PCM
- PCM
- PCM
- 通过DirectSound实时播放PCM+混音
- WAV && PCM
- 什么是PCM?
- PCM总结
- PCM格式
- PCM 概念
- PCM数据格式
- Audio PCM
- PCM音频
- PCM数据格式
- java.security.cert.CertificateException: Certificates does not conform to algorithm constraints
- C#源代码—猴子第一天摘下若干个桃子,当即吃了一半,还不过瘾就多吃了一个。第二天早上又将剩下的桃子吃了一半,还是不过瘾又多 吃了一个。以后每天都吃前一天剩下的一半再加一个。到第10天刚好剩一个。
- NSURLConnection 的使用
- 怎么做好互联网产品运营?
- 实现QT与HTML页面通信
- PCM混音
- 推荐几个机器学习算法及应用领域相关的中国大牛
- Java中的static关键字解析
- 点扩散函数point spread function (PSF)
- 劳逸结合
- android 创建快捷方式
- VMWare 虚拟网络连接设置与主机设置不一致导致虚拟机无法连接网络的解决办法
- 目前机器学习最热门的领域有哪些
- Cocoapod快速使用