精华内容
下载资源
问答
  • webRTC混音流程

    2019-09-12 17:25:51
    原因:由于目前开始调研混音算法,故在此分析一下webRTC的实现流程,其他实现流程在另外一个博客有记录. 概况:目前调研的混音算法在多路混音时只有webRtc的原理符合基本流程。webRtc充分考虑了人耳在同一时间内...

    原因:由于目前开始调研混音算法,故在此分析一下webRTC的实现流程,其他实现流程在另外一个博客有记录.

    概况:目前调研的混音算法在多路混音时只有webRtc的原理符合基本流程。webRtc充分考虑了人耳在同一时间内最多只能感知3路音频的特性,故在多路混音时选择三路能力值最大的作为主要混音,其余参与者判断是否上一帧参与过混音,如果参与过则当前帧进行淡出特性,然后一起进行混音.而最终的混音算法就是简单的线性叠加做饱和运算.

    代码分析:

    主要实现文件在webrtc/modules/audio_conference_mixer目录.依赖的头文件主要有audio_conference_mixer_defines.h,该文件中主要定义了MixerParticipan和AudioMixerOutputRecevier两个类,该两个类主要定义了混音数据的对象来源和混音后数据的接收.调用逻辑通过TimeUnitNextProcess和Process方法进行调用,所以重点实现在process方法中.主要方法伪代码如下:

    void AudioConferenceMixerImpl::Process() {
    
      UpdateToMix(&mixList, &rampOutList, &mixedParticipantsMap,
                        &remainingParticipantsAllowedToMix);
    
        MixFromList(mixedAudio, mixList);
        MixAnonomouslyFromList(mixedAudio, additionalFramesList);
        MixAnonomouslyFromList(mixedAudio, rampOutList);
    
    
    }

    UpdateToMix是为了将参与会话成员按需求分配到mixList,rampOutList,mixList就是重点需要进行mix的会话成员,而rampOutList是上一帧参与会话,当前帧将该会话进行淡出处理,所以重点分析UpdateToMix方法代码如下:通过代码可以看出首先进行判断当前会话上一帧是否参与了mix,如果没有则将进行RampIn特效处理,然后加入activeList队列,在加入过程前判断队列是否达到了限制的最大值,如果达到则将移除能量值最小的会话成员,而在移除过程中也要判断移除的会话成员上一帧是否参与了mix,如果参与了则将该会话当前帧做RampOut处理.

    void AudioConferenceMixerImpl::UpdateToMix(
        AudioFrameList* mixList,
        AudioFrameList* rampOutList,
        std::map<int, MixerParticipant*>* mixParticipantList,
        size_t* maxAudioFrameCounter) const {
    
    
     for (MixerParticipantList::const_iterator participant =
            _participantList.begin(); participant != _participantList.end();
             ++participant) {
    
    
       if(audioFrame->vad_activity_ == AudioFrame::kVadActive) {
                if(!wasMixed && !muted) {
                    RampIn(*audioFrame);
                }
    
            if(activeList.size() >= *maxAudioFrameCounter) {
            
               if (replaceWasMixed) {
                          if (!replaceFrame.muted) {
                            RampOut(*replaceFrame.frame);
                          }
                          rampOutList->push_back(replaceFrame);
    
            }
                
        }
    
    
    }

    最后将当前两个队列成员进行mix处理.主要代码如下:可以看出进行了简单的合并.

    void MixFrames(AudioFrame* mixed_frame, AudioFrame* frame, bool use_limiter) {
    
    
      if (use_limiter) {
        // This is to avoid saturation in the mixing. It is only
        // meaningful if the limiter will be used.
        AudioFrameOperations::ApplyHalfGain(frame);
      }
      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);
      }
    
    }
    
    void AudioFrameOperations::Add(const AudioFrame& frame_to_add,
                                   AudioFrame* result_frame) {
    for (size_t i = 0;
             i < result_frame->samples_per_channel_ * result_frame->num_channels_;
             i++) {
          const int32_t wrap_guard = static_cast<int32_t>(result_frame->data_[i]) +
                               static_cast<int32_t>(frame_to_add.data_[i]);
          result_frame->data_[i] = rtc::saturated_cast<int16_t>(wrap_guard);
    
    }

    按照webRTC混音原理通过简单代码实现,4路进行混音最终生成的波形如下

    利用FFmpeg命令行生成如下:可以明显看出波形衰减严重。

    总结:webRTC混音原理通过代码可以大体分析出,可以根据原理自己实现一个混音算法。

    展开全文
  • WebRTC 混音分析

    2018-05-04 21:12:51
    webrtc网站被和谐, 直接上github查找有没有人fork, 然后找到一个比较新的版本 ...没有下载代码, 直接用手机在网页上查看代码, 虽然不方便,但也找到混音处理代码. 简单写一下大概过程, 详细的在以后有用到...

    webrtc网站被和谐, 直接上github查找有没有人fork, 然后找到一个比较新的版本
    https://github.com/JumpingYang001/webrtc
    https://github.com/ibaoger/webrtc (这个好像每天都更新)

    没有下载代码, 直接用手机在网页上查看代码, 虽然不方便,但也找到混音处理代码.
    简单写一下大概过程, 详细的在以后有用到时再研究吧。
    因为是在手机上看的代码,可能理解有误,等有空再仔细在电脑上深入研究。

    混音对象:

    media/engie/webrtcvoiceengine.cc
    void WebRtcVoiceEngine::Init() {
    ...
    config.audio_mixer = webrtc::AudioMixerImpl::Create();
    ...
    }

    混音类:

    modules/audio_mixer/audio_mixer_impl.cc
    AudioMixerImpl::Mix()

    Mix方法调用:

    modules/audio_mixer/frame_combiner.cc
    FrameCombiner::Combine()

    Combine方法:
    调用MixToFloatFrame进行合并, MixToFloatFrame只是简单的把数据相加, 然后调用RunApmAgcLimiter或RunApmAgc2Limiter对混音结果进行增益处理, 同时应该可以防止溢出.
    调用InterleaveToAudioFrame根据音频声道交织处理混音结果.
    最后混音的结果在audio_frame_for_mixing中.

    展开全文
  • WebRTC混音流程分析

    千次阅读 2017-09-13 16:48:29
    混音分为服务端混音和客户端混音两种,服务端混音是为了节省带宽。哪为什么客户端也要混音呢?...WebRTC中目前只有客户端混音混音具体实现在webrtc/modules/audio_conference_mixer目录中 想知道一个C++模块如何使用
    混音分为服务端混音和客户端混音两种,服务端混音是为了节省带宽。哪为什么客户端也要混音呢?哪是国为声卡同一时刻只能播放一路
    
    语音,当你的客户端有多路接收语音时,如果你不先混音,而是每一路都直接住声卡送的话,容易会造成声音越来越延时。

    WebRTC中目前只有客户端混音,混音具体实现在webrtc/modules/audio_conference_mixer目录中
    想知道一个C++模块如何使用,我们一般会先看看这个模块的头文件,在audio_conference_mixer模块的include目录下有两个头文件
    audio_conference_mixer.h 和 audio_conference_mixer_defines.h,我们先来看看audio_conference_mixer_defines.h,在这个文件
    中定义了两个类
    MixerParticipant:被混音方,负责给混音器提供原始语音数据
    AudioMixerOutputReceiver :混音后的语音接收方

    在audio_conference_mixer.h文件中定义了 AudioConferenceMixer 类,它继承于Module类,说明这个类的对象可以被WebRTC的工作线
    程周期性的调用。在这个类定义中,

    被混音方的添加和删除用SetMixabilityStatus(MixerParticipant* participant, bool  mixable)方法来实现,这个方法中
    第一个参数是被混音对象指针,第二个参数是是否能被混音。

    添加接收方使用RegisterMixedStreamCallback(AudioMixerOutputReceiver* receiver),参数代表接收者对象
    另外我们还发现这两个方法
    // Module functions
    int64_t TimeUntilNextProcess() override = 0;
    void  Process() override = 0;

    从上面几个方法,我们就可能想象出这个混音模块大概的工作流程,WebRTC工作线程先调用混音模块的TimeUntilNextProcess方法,先确认是否到了处理
    这个模块的时间,如果还没有到时间,就直接处理下一个模块 ,如果到了时间,就调用这个模块的Process方法,在Process方法中,会从所有的等待混音对象
    中分别取出一个音频帧,再把所有的音频帧叠加起来,合成一个音频帧,再送给混音接收对象。

    为了验证我们的想法,我们先在模块中搜索TimeUntilNextProcess和Process方法,发现这两个方法的具体实现在 AudioConferenceMixerImpl 类中
    AudioConferenceMixerImpl .cc 182行AudioConferenceMixerImpl:: TimeUntilNextProcess 方法中,我们可以知道这这个模块以10ms的周期被
    调用,这和WebRTC的音频采样周期刚好符合。

    我们先来分析一下AudioConferenceMixerImpl:: Process :下面我会以中文的方式把Process的流程写出来,大家再对照代码自己再体会一下。
    void  AudioConferenceMixerImpl: rocess() {
    1,更新 _timeScheduler ,作用是确保以近似10ms的间隔去音频缓冲队列取数据来混音
    2,定义了三个 AudioFrameList 音频帧队列, mixList rampOutList additionalFramesList ,这三个队列分别是当前需要混音的音频队列,上次已经被混音,
          这次需要被移除队列,附加的音频队列(在WebRTC中,主要用于文件播放器)
    3,分别取数据填充这三个队列,
    UpdateToMix(&mixList, &rampOutList, &mixedParticipantsMap,&remainingParticipantsAllowedToMix);
    GetAdditionalAudio(&additionalFramesList);
    4,把这三个队列混音
          MixFromList(mixedAudio, mixList);
          MixAnonomouslyFromList(mixedAudio, additionalFramesList);
                   MixAnonomouslyFromList(mixedAudio, rampOutList);
            5,  调用WebRTC中的AudioProcessing模块处理混音后的音频帧,调整音量 LimitMixedAudio(mixedAudio);
            6,通知混音接收方 _mixReceiver->NewMixedAudio
            7,清除数据
    }

    Process()方法结构还比较清晰,理解起来不太难。UpdateToMix方法主要作用是从众多候选者中选出声音最大的三个,从这三个候选者中取出音频,再混音。
    因为同时混太多路,容易发生重叠,造成语音不清楚。下面我们来分析UpdateToMix方法,UpdateToMix方法代码比较长,第一次看有点费力。

    void  AudioConferenceMixerImpl::UpdateToMix(
        AudioFrameList* mixList,
        AudioFrameList* rampOutList,
        std::map< int , MixerParticipant*>* mixParticipantList,
        size_t* maxAudioFrameCounter)  const  {
    const  size_t mixListStartSize = mixList->size();  //一直为0,不知道是不是bug
    AudioFrameList activeList;   //声音最大的用户,最多三个
    ParticipantFrameStructList passiveWasNotMixedList; //虽然没有说话,但是因为当前用户少于3,也要被混音
    ParticipantFrameStructList passiveWasMixedList; //上一次已经被混音了,这一次没有说话的用户
    for{
    1,循环从候选用户取出音频帧
    2,如果当前总用户数少于3,设置标志位 mustAddToPassiveList ,即使这个音频帧不是活动的,也可以被混音
    3,检测上一次是不是已经被混音,设置标志位 wasMixed
    if(音频帧是活动的){
    下面代码是检测出最大的三个用户出来
    }else{
    if(上次被混音过){
    添加到 passiveWasMixedList
    }else if(用户总数小于3,必需要被混音){
    添加 RampIn ,类似图片切换淡入淡出效果
    添加到 passiveWasNotMixedList
    }else{
    直接释放不处理
    }
    }
    }
    }

    这里需要单独说明的是,WebRTC处理被混音用户进入和退出时加了特效,要不然就会太生硬了,具体实现在 audio_frame_manipulator .cc文件中。当用户第一次进入时,会添加RampIn效果,当用户退出时,会加入RampOut效果。为了避免混音后的音量忽大忽小,调用了AudioProcessing模块的AGC功能,这样就可能保证音频的音量保持稳定。

    两个音频帧的混音具体实现在
    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_  ==  &&
               frame-> num_channels_  ==  1 );
         AudioFrameOperations ::MonoToStereo(frame);
      }

      *mixed_frame  +=  *frame;
    }
    从*mixed_frame  +=  *frame;这一行我们可以看出AudioFrame类重定义了+=运算符,我们转到AudioFrame类去看看两个音频帧是如何混合在一起的

    inline  AudioFrame& AudioFrame:: operator +=( const  AudioFrame& rhs) {
    ...

    for  (size_t i =  0 ; i < samples_per_channel_ * num_channels_; i++) {
                     int32_t wrap_guard =
                                   static_cast <int32_t>(data_) +  static_cast<int32_t>(rhs.data_);
                              data_ = ClampToInt16(wrap_guard);
    }
    }

    从上面可以看出,两个音频帧的混合非常简单,只要把对应的音频数据相加就行。
    ClampToInt16这个方法是为了防止两个short类型数据相加的结果溢出。我们转到这个方法看看是如何实现的。
    inline int16_t ClampToInt16(int32_t input) {
      if (input < -0x00008000) {
        return -0x8000;
      } else if (input > 0x00007FFF) {
        return 0x7FFF;
      } else {
        return static_cast<int16_t>(input);
      }
    }
    这个算法也很简单,一目了然

    到此,WebRTC中的混音模块算是分析完了,本文是根据WebRTC56版本代码写的,其它版本可能会有不同的地方。


    原文:http://www.rtc8.com/forum.php?mod=viewthread&tid=33&extra=page%3D1

    展开全文
  • webrtc混音混流

    2020-11-28 10:29:13
    webRTC混音流程 https://blog.csdn.net/u013692429/article/details/100778297 原因:由于目前开始调研混音算法,故在此分析一下webRTC的实现流程,其他实现流程在另外一个博客有记录. 概况:目前调研的混音...

    webRTC混音流程

    https://blog.csdn.net/u013692429/article/details/100778297

     

    原因:由于目前开始调研混音算法,故在此分析一下webRTC的实现流程,其他实现流程在另外一个博客有记录.

    概况:目前调研的混音算法在多路混音时只有webRtc的原理符合基本流程。webRtc充分考虑了人耳在同一时间内最多只能感知3路音频的特性,故在多路混音时选择三路能力值最大的作为主要混音,其余参与者判断是否上一帧参与过混音,如果参与过则当前帧进行淡出特性,然后一起进行混音.而最终的混音算法就是简单的线性叠加做饱和运算.

    代码分析:

    主要实现文件在webrtc/modules/audio_conference_mixer目录.依赖的头文件主要有audio_conference_mixer_defines.h,该文件中主要定义了MixerParticipan和AudioMixerOutputRecevier两个类,该两个类主要定义了混音数据的对象来源和混音后数据的接收.调用逻辑通过TimeUnitNextProcess和Process方法进行调用,所以重点实现在process方法中.主要方法伪代码如下:

     

     

    https://www.cnblogs.com/Yinkaisheng/p/11105005.html

    展开全文
  • WebRTC中的混音算法

    千次阅读 2018-11-28 20:15:02
    webrtc混音算法在modules/audio_mixer/frame_combiner.cc文件的FrameCombiner::Combine()函数里 主干程序: void FrameCombiner::Combine(const std::vector&lt;AudioFrame*&gt;&amp; mix_list, ...
  • WebRTC功能强大,集成了能分别处理音视频的API功能模块。并对音视频处理过程中的多种问题进行了集成优化,使得开发者可以更好地使用各种功能! 一、视频处理 WebRTC的视频部分,包含采集、编解码(I420/VP8)、...
  • WebRTC由语音引擎,视频引擎和网络传输三大模块组成,其中语音引擎是WebRTC中最具价值的技术之一,实现了音频数据的采集、前处理、编码、发送、接受、解码、混音、后处理、播放等一系列处理流程。 音频引擎主要...
  • WebRTC 中的基本音频处理操作

    千次阅读 2019-12-13 13:56:26
    WebRTC 的 AudioMixer 将 0 个、1 个或多个 Mixer Source 混音为特定通道数的单路音频帧。输出的音频帧的采样率,由 AudioMixer 的具体实现根据一定的规则确定。 Mixer Source 为 AudioMixer 提供特定采样率的单...
  • 本文简要说明最新版WebRtc AudioMixer混音流程。 本程序使用4个16KHz 单声道时长均大于10秒的Wav文件作为混音源,只合成前10秒的音频,输出也是16KHz单声道音频。 输入和输出的采样率都是16000,每10ms音频长度...
  • 该文章面向对WebRTC有一定基础的码农,如果完全没了解过WebRTC的朋友,可以点赞并私信我进行一对一辅导哦。 因为项目需要直播功能,所以用到了WebRTC,但是由于项目本身有一个特殊功能需要一直使用麦克风,而此时...
  • webrtc封装sdk(一)思路

    千次阅读 2019-01-05 16:28:57
    很多公司使用webrtc来做音视频sdk,但是大部分公司在使用上层的api,使用起来很繁琐,需要了解很多会话协议,《webrtc封装sdk》系列文章为大家讲述一种更简单的封装方法,只需几天,就可以封装出一个sdk。...
  • WebRTC源码分析二:音频模块结构

    万次阅读 2014-02-17 17:44:30
    本文介绍WebRTC音频模块组成和结构,详细介绍音频引擎的配置和启动,相信看完本文后,很多人可以利用webRTC完成一个音频通话程序开发。 一、对外接口  音频部分的对外主要接口如下,各个接口之间的关系如图1所示。 ...
  • 一个跨平台的音频混音器,支持android、ios、macos和windows。由WebRTC、FFMPEG和吉尼提供支持。
  • WebRTC 架构

    千次阅读 多人点赞 2020-04-30 17:04:12
    WebRTC Native框架 我的书: 购买链接: 京东购买链接 淘宝购买链接 当当购买链接 WebRTC还是比较庞大的,咋一看无从下手,本篇以WebRTC自带的例子,阐述WebRTC Native核心的音频、视频和信令三个部分,...
  • 混音 混音的意义就是将多个音频流混成一路音频,在Conference 的实现中有分为终端实现和服务器实现。 1. 终端混音实现: 终端接受到多路(一般是多个用户)的音频流之后,在终端本地将多路音频流混成一路音频送给扬...
  • 做录音时首先需要获取本地采集的pcm数据和所有远端用户合成后的pcm数据,也就是播放时投递给扬声器的pcm数据,本文讲解一下如何获取webrtc的原始音频数据。 ##webrtc版本说明 本文使用的webrtc api依赖于webrtc分支...
  • 1.2 混音及数据获取 2 音频录制数据 2.1 初始化音频帧及设置相关属性 2.2 混音及重采样 2.3 处理音视频数据 2.4 拷贝音频帧及分配到多个发送通道 2.6 WebRTC实际调用日志 IOS ADM 类图 1. 播放数据 1.1 数据流的...
  • WebRTC协议学习之一(WebRTC简介)

    万次阅读 2019-08-07 21:00:49
    WebRTC协议学习之一(WebRTC简介)
  • webrtc

    2019-11-15 23:19:10
    WebRTC(Web Real-Time Communication)项目的最终目的主要是让Web开发者能够基于浏览器(Chrome\FireFox...)轻易快捷开发出丰富的实时多媒体应用,而无需下载安装任何插件,Web开发者也无需关注多媒体的数字信号...
  • 公司的项目是通过WebRTC的APM(Audio Processing Module)模块进行的声音处理(降噪,增益,回声消除等),通过调用audio_device获取设备音频硬件。整套音频处理都是基于WebRTC来实现的。 但是这让我走了很多“路...
  • H5端之WebRTC笔记

    千次阅读 2020-03-25 18:29:39
    文章目录WebRTC介绍概要WebRTC标准名词解释WebRTC功能特性WebRTC中的媒体轨道(MediaStreamTrack)流(MediaStream)媒体流实例 在有道云笔记中上传本地图片太重要啦 WebRTC介绍 概要 WebRTC是一个基于标准化技术...
  • WebRTC源码研究(1)WebRTC架构

    千次阅读 多人点赞 2020-06-09 08:02:05
    文章目录WebRTC源码研究(一)webrtc架构 WebRTC源码研究(一)webrtc架构
  • WebRTC音频

    千次阅读 2017-02-08 19:03:35
    webrtc整个的音频,采集,编码,打包,发送,到接收,解包,解码,播放,整个过程做了详细的描述

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 692
精华内容 276
关键字:

webrtc混音