-
Notifications
You must be signed in to change notification settings - Fork 3
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
lowkey
committed
Mar 10, 2022
1 parent
951e267
commit d121fd5
Showing
12 changed files
with
245 additions
and
25 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
#include <iostream> | ||
|
||
namespace ts{ | ||
|
||
class IMixer { | ||
public: | ||
static IMixer* Create(int sampleRate, int channelCount); | ||
static void deleteMixer(IMixer*); | ||
public: | ||
/** | ||
* @brief | ||
* | ||
* @param streamCount 流的数量 | ||
* @param data 混音数据,每个流取一帧 | ||
* @param lineSize 每个音频帧,一共有多少采样 | ||
* @param mixData 混音之后的输出数据,需要外部开辟好内存 | ||
*/ | ||
virtual int Mix(int streamCount, uint16_t* data[], int sampleCount, uint16_t* mixData) = 0; | ||
protected: | ||
IMixer() = default; | ||
virtual ~IMixer() = default; | ||
IMixer(const IMixer&) = default; | ||
}; | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,119 @@ | ||
#include <mutex> | ||
|
||
#include "MixerImpl.h" | ||
|
||
namespace ts{ | ||
|
||
class AudioSourceWrap : public ::webrtc::AudioMixer::Source { | ||
|
||
struct AudioData{ | ||
AudioData(uint16_t* a, int b): data(a),sampleCount(b){} | ||
uint16_t* data{nullptr}; | ||
int sampleCount{0}; | ||
}; | ||
|
||
public: | ||
~AudioSourceWrap() { | ||
} | ||
explicit AudioSourceWrap(int sampleRate, int channelCount) | ||
: sample_rate_hz_(sampleRate) | ||
, samples_per_channel_(sample_rate_hz_ / 50) | ||
, number_of_channels_(channelCount) | ||
{ | ||
} | ||
|
||
AudioFrameInfo GetAudioFrameWithInfo(int target_rate_hz, ::webrtc::AudioFrame* frame) override { | ||
if(dataPool.empty()){ | ||
frame->Mute(); | ||
return AudioFrameInfo::kError; | ||
} | ||
dataLock.lock(); | ||
auto audioData = dataPool.front(); | ||
dataPool.pop_front(); | ||
dataLock.unlock(); | ||
|
||
memcpy(frame->mutable_data(),audioData.data, audioData.sampleCount * sizeof(audioData.data[0])); | ||
frame->samples_per_channel_ = samples_per_channel_; | ||
frame->num_channels_ = number_of_channels_; | ||
frame->sample_rate_hz_ = target_rate_hz; | ||
return AudioFrameInfo::kNormal; | ||
} | ||
|
||
int Ssrc() const override { return 0; } | ||
|
||
int PreferredSampleRate() const override { return sample_rate_hz_; } | ||
|
||
void pushData(uint16_t* data, int sampleCount) { | ||
std::lock_guard<std::mutex> lk(dataLock); | ||
//这里可能需要有一个专门的构造 | ||
dataPool.push_back({data,sampleCount}); | ||
} | ||
|
||
private: | ||
int sample_rate_hz_; | ||
int samples_per_channel_; | ||
int number_of_channels_; | ||
std::mutex dataLock; | ||
//这里也许不需要list | ||
std::list<AudioData> dataPool; | ||
}; | ||
|
||
|
||
IMixer* IMixer::Create(int sampleRate, int channelCount){ | ||
return new MixerImpl(sampleRate, channelCount); | ||
} | ||
|
||
void IMixer::deleteMixer(IMixer* ptr){ | ||
assert(ptr); | ||
if (ptr) { | ||
delete ptr; | ||
} | ||
} | ||
|
||
MixerImpl::MixerImpl(int sampleRate, int channelCount) | ||
: m_sampleRate(sampleRate) | ||
, m_channelCount(channelCount) | ||
{ | ||
m_mixer = ::webrtc::AudioMixerImpl::Create( | ||
std::unique_ptr<::webrtc::OutputRateCalculator>(new ::webrtc::DefaultOutputRateCalculator()), true); | ||
} | ||
|
||
MixerImpl::~MixerImpl(){ | ||
} | ||
|
||
int MixerImpl::Mix(int streamCount ,uint16_t* data[], int sampleCount, uint16_t* mixData){ | ||
int diff = streamCount - m_sources.size(); | ||
//balance source | ||
if(diff > 0){ | ||
for (int i = 0; i < diff; i++) { | ||
auto source = std::make_shared<AudioSourceWrap>(m_sampleRate, m_channelCount); | ||
m_sources.emplace_back(source); | ||
m_mixer->AddSource(source.get()); | ||
} | ||
}else{ | ||
for (int i = diff; i < 0; i++) { | ||
auto source = m_sources.back(); | ||
m_sources.pop_back(); | ||
m_mixer->RemoveSource(source.get()); | ||
} | ||
} | ||
// 填充音频数据 | ||
assert(streamCount == m_sources.size()); | ||
auto it = m_sources.begin(); | ||
for (size_t i = 0; i < streamCount; i++) { | ||
if(it != m_sources.end()){ | ||
(*it)->pushData(data[i],sampleCount); | ||
it++; | ||
} | ||
} | ||
//执行混音 | ||
::webrtc::AudioFrame frame; | ||
m_mixer->Mix(m_channelCount, &frame); | ||
if (frame.muted()) { | ||
return -1; | ||
} | ||
memcpy(mixData, frame.data(), sampleCount * 2); | ||
return 0; | ||
} | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
#include <memory> | ||
#include <list> | ||
#include "IMixer.h" | ||
|
||
#include "modules/audio_mixer/audio_mixer_impl.h" | ||
#include "modules/audio_mixer/default_output_rate_calculator.h" | ||
|
||
namespace ts{ | ||
|
||
class AudioSourceWrap; | ||
|
||
class MixerImpl final: public IMixer{ | ||
public: | ||
MixerImpl(int sampleRate, int channelCount); | ||
~MixerImpl(); | ||
public: | ||
int Mix(int streamCount, uint16_t* data[], int sampleCount, uint16_t* mixData) override; | ||
|
||
private: | ||
int m_sampleRate{0}; | ||
int m_channelCount{0}; | ||
rtc::scoped_refptr<::webrtc::AudioMixerImpl> m_mixer; | ||
using AudioSourcePtr = std::shared_ptr<AudioSourceWrap>; | ||
std::list<AudioSourcePtr> m_sources; | ||
}; | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
# 项目简介 | ||
该项目主要为了将webrtc中的音频处理模块提取成单独的代码库,以独立的库提供。目前,以完成混音模块的提取。后续会继续完成aec、ns、agc等模块的提取。main分之最低要求cpp17,如果需要使用cpp11版本需要切换到cpp11分之。但是,cpp11分之性能会稍稍降低。 | ||
|
||
# 使用方式 | ||
## submodule方式 | ||
``` | ||
cd 'SomeDir' //in your project | ||
git submodule add https://github.com/lowkeywx/webrtc_mixer.git | ||
``` | ||
> 需要主项目也使用cmake方式组织 | ||
## 编译成库 | ||
``` | ||
git clone https://github.com/lowkeywx/webrtc_mixer.git | ||
cd webrtc_mixer | ||
mkdir build && cd build | ||
cmake .. && cmake --build . | ||
or | ||
cmake .. -DBUILD_SHARED=ON && cmake --build . | ||
``` | ||
|
||
> 默认每帧,支持10ms。建议使用单声道、16000hz采样率。 | ||
> 如果需要增大每帧到20ms,需要修改 modules/audio_mixer/audio_mixer_impl.h 中 kFrameDurationInMs = 20; modules/audio_mixer/frame_combiner.cc 中 limiter_(static_cast<size_t>(24000), data_dumper_.get(), "AudioMixer");modules/audio_processing/agc2/agc2_common.h 中 kFrameDurationMs = 20; | ||
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,15 +1,15 @@ | ||
cmake_minimum_required(VERSION 3.10) | ||
project(MediaEngine_Api) | ||
|
||
add_library(api STATIC | ||
add_library(api OBJECT | ||
stats_types.cc | ||
audio/channel_layout.cc | ||
audio/audio_frame.cc | ||
task_queue/task_queue_base.cc | ||
) | ||
|
||
target_include_directories(api PRIVATE ${CMAKE_SOURCE_DIR}) | ||
target_include_directories(api PUBLIC ${CMAKE_SOURCE_DIR}/third_party/abseil-cpp) | ||
target_include_directories(api PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/..) | ||
target_include_directories(api PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/../third_party/abseil-cpp) | ||
|
||
#target_link_libraries(api PRIVATE rtc_base) | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,12 +1,12 @@ | ||
cmake_minimum_required(VERSION 3.10) | ||
project(MediaEngine_Audio) | ||
|
||
add_library(audio STATIC | ||
add_library(audio OBJECT | ||
utility/channel_mixer.cc | ||
utility/audio_frame_operations.cc | ||
utility/channel_mixing_matrix.cc | ||
) | ||
|
||
target_include_directories(audio PRIVATE ${CMAKE_SOURCE_DIR}) | ||
target_include_directories(audio PUBLIC ${CMAKE_SOURCE_DIR}/third_party/abseil-cpp) | ||
target_include_directories(audio PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/../) | ||
target_include_directories(audio PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/../third_party/abseil-cpp) | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,11 +1,11 @@ | ||
cmake_minimum_required(VERSION 3.10) | ||
project(MediaEngine_CommonAudio) | ||
|
||
add_library(common_audio STATIC | ||
add_library(common_audio OBJECT | ||
wav_file.cc | ||
audio_util.cc | ||
wav_header.cc | ||
) | ||
|
||
target_include_directories(common_audio PRIVATE ${CMAKE_SOURCE_DIR}) | ||
target_include_directories(common_audio PUBLIC ${CMAKE_SOURCE_DIR}/third_party/abseil-cpp) | ||
target_include_directories(common_audio PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/../) | ||
target_include_directories(common_audio PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/../third_party/abseil-cpp) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,10 +1,10 @@ | ||
cmake_minimum_required(VERSION 3.10) | ||
project(MediaEngine_SystemWrappers) | ||
|
||
add_library(system_wrappers STATIC | ||
add_library(system_wrappers OBJECT | ||
source/metrics.cc | ||
source/field_trial.cc | ||
) | ||
|
||
target_include_directories(system_wrappers PRIVATE ${CMAKE_SOURCE_DIR}) | ||
target_include_directories(system_wrappers PUBLIC ${CMAKE_SOURCE_DIR}/third_party/abseil-cpp) | ||
target_include_directories(system_wrappers PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/..) | ||
target_include_directories(system_wrappers PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/../third_party/abseil-cpp) |