概要
webrtcの内部には魅力的な動作がいくつかある。
個別に取り出して自作のアプリとかに入れることができると、高いクオリティのアプリを作ることができる。
(と思ってる)
今回はaudioProcessingの部分を取り出して利用してみようと思う。
ちょうどいい具合のプロジェクトがあった。
https://github.com/freedesktop/pulseaudio-webrtc-audio-processing
ただ、linuxでのbuildはできるみたいですが、僕が使ってるOSXではうまくbuildできないみたいなので
改良してみた
https://github.com/taktod/pulseaudio-webrtc-audio-processing
autogen.shの中身変更しただけ。
c++で利用してみる
cで利用してもいいんですが、webrtcのコードは基本c++で書かれていて、namespaceとか使っているため、c++で書くほうが作りやすいため、c++で書いてみることにする。
できたコードはこんな感じ。
使い方は・・・
$ git clone https://github.com/taktod/pulseaudio-webrtc-audio-processing.git
$ cd pulseaudio-webrtc-audio-processing
$ ./autogen.sh
$ make
$ cd test
$ mkdir build
$ cd build
$ cmake ..
$ make
$ ./webrtcInitializeTest
pulseaudio-webrtc-audio-processingを作ってから
testのディレクトリに移動してtestのコードをmakeして利用
コードはこんな感じ
#include <iostream>
#include <modules/audio_processing/include/audio_processing.h>
#include <modules/interface/module_common_types.h>
using namespace std;
using namespace webrtc;
int main() {
cout << "try to use webrtc audio processing." << endl;
AudioFrame frame;
int16_t buf[480];
for(int i = 0;i < 480;++ i) {
buf[i] = i;
}
frame.UpdateFrame(
0, // id
0, // timestamp
buf, // data
480, // sample per channel
48000, // sample_rate
AudioFrame::kNormalSpeech, // speech type
AudioFrame::kVadActive); // vad activity
AudioProcessing* apm = AudioProcessing::Create();
apm->Initialize(
48000, // input samplerate
48000, // output samplerate
48000, // reverse samplerate
AudioProcessing::ChannelLayout::kMono, // input channel layout
AudioProcessing::ChannelLayout::kMono, // output channel layout
AudioProcessing::ChannelLayout::kMono // reverse channel layout
);
apm->high_pass_filter()->Enable(true);
apm->echo_cancellation()->enable_drift_compensation(false);
apm->echo_cancellation()->Enable(true);
apm->noise_suppression()->set_level(NoiseSuppression::Level::kHigh);
apm->noise_suppression()->Enable(true);
apm->gain_control()->set_analog_level_limits(0, 255);
apm->gain_control()->set_mode(GainControl::Mode::kAdaptiveDigital);
apm->gain_control()->Enable(true);
for(int i = 0;i < 4;++ i) {
apm->ProcessReverseStream(&frame);
apm->set_stream_delay_ms(10);
int err = apm->ProcessStream(&frame);
cout << "result:" << err << endl;
int16_t *buf = (int16_t *)frame.data_;
for(int i = 0;i < 16;++ i) {
cout << buf[i] << endl;
}
}
delete apm;
return 0;
}
とりあえず使えてはいるみたいですね。
- 適当にAudioFrameオブジェクトを作る UpdateFrameでpcmデータを登録する。16bit整数で入れれば良い模様
- AudioProcessingのオブジェクト作って初期化
- ProcessReverseStreamで外からやってきた音(スピーカーから鳴らしたい音)をapmに入れる
- stream delayを適当に設定する
- ProcessStreamでマイクで録音したデータをapmに入れると入れたframeの内容が結果に書き換えられる
という動作な模様
AudioProcessingはCreateすると内部でnewしているみたいなので、最後にdeleteで解放しておく必要がある模様
コンパイル方法
使い方は簡単、コンパイルするのが面倒だった。
cmake_minimum_required(VERSION 2.8)
add_definitions("-Wall -std=c++11")
add_definitions(-D__DIR__="${PROJECT_SOURCE_DIR}")
add_definitions(-DWEBRTC_POSIX)
add_definitions(-DWEBRTC_AUDIO_PROCESSING_ONLY_BUILD)
include_directories(${PROJECT_SOURCE_DIR}/../webrtc)
include_directories(${PROJECT_SOURCE_DIR}/../)
link_directories(${PROJECT_SOURCE_DIR}/../webrtc/modules/audio_processing/.libs/)
add_executable(webrtcInitializeTest initializeTest.cpp)
target_link_libraries(webrtcInitializeTest
webrtc_audio_processing
)
c++11を使わないとwebrtcの定義周りがうまく使えない模様
WEBRTC_POSIXを定義しないとwebrtcで利用する環境の指定が入らず、エラーになる。
WEBRTC_AUDIO_PROCESSING_ONLY_BUILDを定義しないとvideo周りのコードが存在しないためエラーになる。
(このライブラリはaudioの部分だけ抜き出してある)
妙なところにありますがpulseaudio-webrtc-audio-processing/webrtc/modules/audio_processing/.libs/に目的のライブラリが出来上がるみたいですね。
今後学習していきたい
c++で実装利用できたので、iOSやandroidでも利用可能みたいですね。
まだ勉強不足で動作の効果がよくわかってないです。