Skip to content

Commit

Permalink
feat: 封装一层接口,方便使用
Browse files Browse the repository at this point in the history
  • Loading branch information
lowkey committed Mar 10, 2022
1 parent 951e267 commit d121fd5
Show file tree
Hide file tree
Showing 12 changed files with 245 additions and 25 deletions.
27 changes: 25 additions & 2 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -28,11 +28,34 @@ elseif(CMAKE_SYSTEM_NAME MATCHES Linux)
ADD_DEFINITIONS(-DWEBRTC_LINUX)
endif()


add_subdirectory(third_party/abseil-cpp)
add_subdirectory(api)
add_subdirectory(audio)
add_subdirectory(modules)
add_subdirectory(common_audio)
add_subdirectory(rtc_base)
add_subdirectory(system_wrappers)
add_subdirectory(system_wrappers)

if(BUILD_SHARED)
set(LIBRARY_TYPE SHARED)
else()
set(LIBRARY_TYPE STATIC)
endif(BUILD_DYNAMIC)

add_library(ts_mixer ${LIBRARY_TYPE} MixerImpl.cpp
$<TARGET_OBJECTS:modules_audio_mixer>
$<TARGET_OBJECTS:rtc_base>
$<TARGET_OBJECTS:api>
$<TARGET_OBJECTS:audio>
$<TARGET_OBJECTS:modules_audio_process>
$<TARGET_OBJECTS:system_wrappers>
$<TARGET_OBJECTS:common_audio>
)

target_link_libraries(ts_mixer PRIVATE absl::throw_delegate absl::strings)

target_include_directories(ts_mixer PRIVATE ${CMAKE_CURRENT_SOURCE_DIR})
target_include_directories(ts_mixer PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/third_party/abseil-cpp)

INSTALL ( TARGETS ts_mixer DESTINATION lib )

25 changes: 25 additions & 0 deletions IMixer.h
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;
};

}
119 changes: 119 additions & 0 deletions MixerImpl.cpp
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;
}

}
27 changes: 27 additions & 0 deletions MixerImpl.h
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;
};

}
25 changes: 25 additions & 0 deletions README.md
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;
6 changes: 3 additions & 3 deletions api/CMakeLists.txt
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)

6 changes: 3 additions & 3 deletions audio/CMakeLists.txt
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)

6 changes: 3 additions & 3 deletions common_audio/CMakeLists.txt
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)
9 changes: 5 additions & 4 deletions modules/audio_mixer/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -3,17 +3,18 @@ project(MediaEngine_Modules_AudioMixer)

set(TARGET_NAME modules_audio_mixer)

add_library(${TARGET_NAME} SHARED
add_library(${TARGET_NAME} OBJECT
./audio_frame_manipulator.cc
./audio_mixer_impl.cc
./default_output_rate_calculator.cc
./frame_combiner.cc
)

target_include_directories(${TARGET_NAME} PUBLIC ${CMAKE_SOURCE_DIR})
target_include_directories(${TARGET_NAME} PUBLIC ${CMAKE_SOURCE_DIR}/third_party/abseil-cpp)
target_link_libraries(${TARGET_NAME} PRIVATE rtc_base api audio modules_audio_process system_wrappers common_audio)
target_include_directories(${TARGET_NAME} PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/../../)
target_include_directories(${TARGET_NAME} PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/../../third_party/abseil-cpp)

target_link_libraries(${TARGET_NAME} PRIVATE absl::flags_parse)
target_compile_definitions(${TARGET_NAME} PRIVATE WEBRTC_APM_DEBUG_DUMP=0)

if(ANDROID)
find_library(ANDROID_LOG_LIB log)
Expand Down
6 changes: 3 additions & 3 deletions modules/audio_processing/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
cmake_minimum_required(VERSION 3.10)
project(MediaEngine_Modules_AudioProcess)

add_library(modules_audio_process STATIC
add_library(modules_audio_process OBJECT
logging/apm_data_dumper.cc
agc2/limiter.cc
agc2/interpolated_gain_curve.cc
Expand All @@ -10,6 +10,6 @@ agc2/fixed_digital_level_estimator.cc

target_compile_definitions(modules_audio_process PUBLIC WEBRTC_APM_DEBUG_DUMP=0)

target_include_directories(modules_audio_process PRIVATE ${CMAKE_SOURCE_DIR})
target_include_directories(modules_audio_process PUBLIC ${CMAKE_SOURCE_DIR}/third_party/abseil-cpp)
target_include_directories(modules_audio_process PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/../..)
target_include_directories(modules_audio_process PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/../../third_party/abseil-cpp)

8 changes: 4 additions & 4 deletions rtc_base/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
cmake_minimum_required(VERSION 3.10)
project(MediaEngine_AudioMixer_RtcBase)

add_library(rtc_base STATIC
add_library(rtc_base OBJECT
checks.cc
logging.cc
time_utils.cc
Expand All @@ -14,9 +14,9 @@ strings/string_builder.cc
synchronization/sequence_checker_internal.cc
)

target_include_directories(rtc_base PRIVATE ${CMAKE_SOURCE_DIR})
target_include_directories(rtc_base PUBLIC ${CMAKE_SOURCE_DIR}/third_party/abseil-cpp)
target_link_libraries(rtc_base PRIVATE absl::throw_delegate absl::strings)
target_include_directories(rtc_base PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/..)
target_include_directories(rtc_base PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/../third_party/abseil-cpp)

if(CMAKE_SYSTEM_NAME MATCHES Windows)
target_link_libraries(rtc_base PRIVATE winmm)
endif()
Expand Down
6 changes: 3 additions & 3 deletions system_wrappers/CMakeLists.txt
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)

0 comments on commit d121fd5

Please sign in to comment.