本文简要说明最新版WebRtc AudioMixer混音流程。
本程序使用4个16KHz 单声道时长均大于10秒的Wav文件作为混音源,只合成前10秒的音频,输出也是16KHz单声道音频。
输入和输出的采样率都是16000,每10ms音频长度采样点数为160,每个采样点为16bit,两字节大小。
使用的WebRTC代码日期为2019-05-08。
代码如下:
1 #include "stdafx.h" 2 #include <string> 3 #include <iostream> 4 #include <memory> 5 #include <thread> 6 #include <chrono> 7 #include "webrtc\modules\audio_mixer\audio_mixer_impl.h" 8 #include "webrtc\api\audio\audio_frame.h" 9 #include "webrtc\modules\audio_mixer\output_rate_calculator.h" 10 11 using namespace std::literals::chrono_literals; 12 13 #define WAV_HEADER_SIZE 44 14 #define SAMPLE_RATE 16000 15 16 int16_t s_buf[160] = { 0 }; 17 18 class AudioSrc : public webrtc::AudioMixer::Source 19 { 20 public: 21 AudioSrc(int ssrc, int sample, const std::string& file) 22 : mSsrc(ssrc) 23 , mSample(sample) 24 , mFile(nullptr) 25 { 26 fopen_s(&mFile, file.c_str(), "rb"); 27 28 if (mFile) 29 { 30 fseek(mFile, 44, SEEK_SET); 31 } 32 } 33 34 virtual ~AudioSrc() 35 { 36 if (mFile) 37 { 38 fclose(mFile); 39 mFile = nullptr; 40 } 41 } 42 43 virtual AudioFrameInfo GetAudioFrameWithInfo(int sample_rate_hz, 44 webrtc::AudioFrame* audio_frame) 45 { 46 if (mFile) 47 { 48 fread(s_buf, 160 * 2, 1, mFile);//16KHz, 10ms buf 49 } 50 51 std::thread::id tid = std::this_thread::get_id(); 52 std::cout << "thread id "; 53 tid._To_text(std::cout); 54 55 //copy s_buf to audio_frame inner buf 56 audio_frame->UpdateFrame(0, s_buf, 160, SAMPLE_RATE, webrtc::AudioFrame::SpeechType::kNormalSpeech, webrtc::AudioFrame::VADActivity::kVadUnknown, 1); 57 printf(",ssrc %d get audio frame, muted: %d, n %d, s %d\n", mSsrc, int(audio_frame->muted()), audio_frame->num_channels_, audio_frame->sample_rate_hz_); 58 59 return AudioFrameInfo::kNormal; 60 } 61 62 // A way for a mixer implementation to distinguish participants. 63 virtual int Ssrc() const 64 { 65 return mSsrc; 66 } 67 68 // A way for this source to say that GetAudioFrameWithInfo called 69 // with this sample rate or higher will not cause quality loss. 70 virtual int PreferredSampleRate() const 71 { 72 return mSample; 73 } 74 75 private: 76 int mSsrc; 77 int mSample; 78 FILE* mFile; 79 }; 80 81 82 class AudioOutput : public webrtc::OutputRateCalculator 83 { 84 virtual int CalculateOutputRate( 85 const std::vector<int>& preferred_sample_rates) 86 { 87 return SAMPLE_RATE; 88 } 89 90 }; 91 92 int MixText() 93 { 94 auto mixptr = webrtc::AudioMixerImpl::Create(std::make_unique<AudioOutput>(), true); 95 AudioSrc src1(1, SAMPLE_RATE, "e:\\Media\\Audio\\16k_1.wav"); 96 AudioSrc src2(2, SAMPLE_RATE, "e:\\Media\\Audio\\16k_2.wav"); 97 AudioSrc src3(3, SAMPLE_RATE, "e:\\Media\\Audio\\16k_3.wav"); 98 AudioSrc src4(4, SAMPLE_RATE, "e:\\Media\\Audio\\16k_4.wav"); 99 100 mixptr->AddSource(&src1); 101 mixptr->AddSource(&src2); 102 mixptr->AddSource(&src3); 103 mixptr->AddSource(&src4); 104 105 std::thread::id tid = std::this_thread::get_id(); 106 std::cout << "main thread id: "; 107 ti