diff --git a/src/dummy_audio_mixer.cpp b/src/dummy_audio_mixer.cpp index b7c69bdb..d8413fd8 100644 --- a/src/dummy_audio_mixer.cpp +++ b/src/dummy_audio_mixer.cpp @@ -16,8 +16,14 @@ void DummyAudioMixer::Mix(size_t number_of_channels, webrtc::AudioFrame* audio_frame_for_mixing) { webrtc::MutexLock lock(&mutex_); for (auto& source_and_status : audio_source_list_) { - // 第一引数の設定値にサンプリングレートがリサンプリングされる - // -1 を指定するとリサンプリングされなくなる + /** + * webrtc::AudioTrackSinkInterface の OnData はこの関数内で呼ばれる + * + * 第一引数の設定値にサンプリングレートがリサンプリングされるが、 + * -1 を指定するとリサンプリングされなくなる。 + * SoraAudioSinkImpl の OnData 内でリサンプリングするため、 + * ここでは -1 を指定している。 + */ source_and_status->audio_source->GetAudioFrameWithInfo( -1, &source_and_status->audio_frame); } @@ -41,6 +47,11 @@ void DummyAudioMixer::RemoveSource(Source* audio_source) { DummyAudioMixer::DummyAudioMixer(webrtc::TaskQueueFactory* task_queue_factory) : task_queue_factory_(task_queue_factory) { + /** + * 通常 webrtc::AudioMixer の Mix は音声出力デバイスのループで呼ばれるが、 + * sora::SoraClientContextConfig::use_audio_device を false にした際に設定される、 + * webrtc::AudioDeviceDummy はループを回さないため、ここでループを作ることとした。 + */ task_queue_ = std::make_unique(task_queue_factory_->CreateTaskQueue( "TestAudioDeviceModuleImpl", diff --git a/src/dummy_audio_mixer.h b/src/dummy_audio_mixer.h index b3bc2b05..6d2e0b0d 100644 --- a/src/dummy_audio_mixer.h +++ b/src/dummy_audio_mixer.h @@ -12,6 +12,18 @@ #include #include +/** + * webrtc::AudioMixer を継承した DummyAudioMixer です。 + * + * PeerConnectionFactory 生成時に渡す cricket::MediaEngineDependencies の + * audio_mixer を指定しない場合 webrtc::AudioMixerImpl が使用されます。 + * これはすべての AudioTrack の出力データのサンプリングレートとチャネル数を揃え、 + * ミキシングした上で音声出力デバイスに渡す役割を担います。 + * しかし、 Python SDK では音声をデバイスに出力することはありません。 + * ですが、 AudioTrack からデータを受け取る AudioSinkInterface::OnData は + * AudioMixer により駆動されているため、 AudioSinkInterface::OnData を呼び出す仕組みだけを持つ + * シンプルな webrtc::AudioMixer になっています。 + */ class DummyAudioMixer : public webrtc::AudioMixer { public: struct SourceStatus; diff --git a/src/sora_factory.cpp b/src/sora_factory.cpp index 4d4d0ab4..0a64829c 100644 --- a/src/sora_factory.cpp +++ b/src/sora_factory.cpp @@ -36,6 +36,7 @@ SoraFactory::SoraFactory(std::optional use_hardware_encoder, #endif sora::SoraClientContextConfig context_config; + // Audio デバイスは使わない、 use_audio_device を true にしただけでデバイスを掴んでしまうので常に false context_config.use_audio_device = false; if (use_hardware_encoder) { context_config.use_hardware_encoder = *use_hardware_encoder; @@ -44,8 +45,10 @@ SoraFactory::SoraFactory(std::optional use_hardware_encoder, [use_hardware_encoder = context_config.use_hardware_encoder, openh264]( const webrtc::PeerConnectionFactoryDependencies& dependencies, cricket::MediaEngineDependencies& media_dependencies) { + // 通常の AudioMixer を使うと use_audio_device が false のとき、音声のループは全て止まってしまうので自前の AudioMixer を使う media_dependencies.audio_mixer = DummyAudioMixer::Create(media_dependencies.task_queue_factory); + // アンチエコーやゲインコントロール、ノイズサプレッションが必要になる用途は想定していないため nullptr media_dependencies.audio_processing = nullptr; #ifndef _WIN32