/* * Copyright (c) 2017 The WebRTC project authors. All Rights Reserved. * * Use of this source code is governed by a BSD-style license * that can be found in the LICENSE file in the root of the source * tree. An additional intellectual property rights grant can be found * in the file PATENTS. All contributing project authors may * be found in the AUTHORS file in the root of the source tree. */ #include "modules/audio_device/include/audio_device_data_observer.h" #include "rtc_base/checks.h" #include "rtc_base/refcountedobject.h" namespace webrtc { namespace { // A wrapper over AudioDeviceModule that registers itself as AudioTransport // callback and redirects the PCM data to AudioDeviceDataObserver callback. class ADMWrapper : public AudioDeviceModule, public AudioTransport { public: ADMWrapper(const int32_t id, const AudioLayer audio_layer, AudioDeviceDataObserver* observer) : impl_(AudioDeviceModule::Create(id, audio_layer)), observer_(observer) { // Register self as the audio transport callback for underlying ADM impl. auto res = impl_->RegisterAudioCallback(this); is_valid_ = (impl_.get() != nullptr) && (res == 0); } virtual ~ADMWrapper() { audio_transport_ = nullptr; observer_ = nullptr; } // Make sure we have a valid ADM before returning it to user. bool IsValid() { return is_valid_; } // AudioTransport methods overrides. int32_t RecordedDataIsAvailable(const void* audioSamples, const size_t nSamples, const size_t nBytesPerSample, const size_t nChannels, const uint32_t samples_per_sec, const uint32_t total_delay_ms, const int32_t clockDrift, const uint32_t currentMicLevel, const bool keyPressed, uint32_t& newMicLevel) override { int32_t res = 0; // Capture PCM data of locally captured audio. if (observer_) { observer_->OnCaptureData(audioSamples, nSamples, nBytesPerSample, nChannels, samples_per_sec); } // Send to the actual audio transport. if (audio_transport_) { res = audio_transport_->RecordedDataIsAvailable( audioSamples, nSamples, nBytesPerSample, nChannels, samples_per_sec, total_delay_ms, clockDrift, currentMicLevel, keyPressed, newMicLevel); } return res; } int32_t NeedMorePlayData(const size_t nSamples, const size_t nBytesPerSample, const size_t nChannels, const uint32_t samples_per_sec, void* audioSamples, size_t& nSamplesOut, int64_t* elapsed_time_ms, int64_t* ntp_time_ms) override { int32_t res = 0; // Request data from audio transport. if (audio_transport_) { res = audio_transport_->NeedMorePlayData( nSamples, nBytesPerSample, nChannels, samples_per_sec, audioSamples, nSamplesOut, elapsed_time_ms, ntp_time_ms); } // Capture rendered data. if (observer_) { observer_->OnRenderData(audioSamples, nSamples, nBytesPerSample, nChannels, samples_per_sec); } return res; } void PushCaptureData(int voe_channel, const void* audio_data, int bits_per_sample, int sample_rate, size_t number_of_channels, size_t number_of_frames) override { RTC_NOTREACHED(); } void PullRenderData(int bits_per_sample, int sample_rate, size_t number_of_channels, size_t number_of_frames, void* audio_data, int64_t* elapsed_time_ms, int64_t* ntp_time_ms) override { RTC_NOTREACHED(); } // Override AudioDeviceModule's RegisterAudioCallback method to remember the // actual audio transport (e.g.: voice engine). int32_t RegisterAudioCallback(AudioTransport* audio_callback) override { // Remember the audio callback to forward PCM data audio_transport_ = audio_callback; return 0; } // AudioDeviceModule pass through method overrides. int32_t ActiveAudioLayer(AudioLayer* audio_layer) const override { return impl_->ActiveAudioLayer(audio_layer); } ErrorCode LastError() const override { return impl_->LastError(); } int32_t Init() override { return impl_->Init(); } int32_t Terminate() override { return impl_->Terminate(); } bool Initialized() const override { return impl_->Initialized(); } int16_t PlayoutDevices() override { return impl_->PlayoutDevices(); } int16_t RecordingDevices() override { return impl_->RecordingDevices(); } int32_t PlayoutDeviceName(uint16_t index, char name[kAdmMaxDeviceNameSize], char guid[kAdmMaxGuidSize]) override { return impl_->PlayoutDeviceName(index, name, guid); } int32_t RecordingDeviceName(uint16_t index, char name[kAdmMaxDeviceNameSize], char guid[kAdmMaxGuidSize]) override { return impl_->RecordingDeviceName(index, name, guid); } int32_t SetPlayoutDevice(uint16_t index) override { return impl_->SetPlayoutDevice(index); } int32_t SetPlayoutDevice(WindowsDeviceType device) override { return impl_->SetPlayoutDevice(device); } int32_t SetRecordingDevice(uint16_t index) override { return impl_->SetRecordingDevice(index); } int32_t SetRecordingDevice(WindowsDeviceType device) override { return impl_->SetRecordingDevice(device); } int32_t PlayoutIsAvailable(bool* available) override { return impl_->PlayoutIsAvailable(available); } int32_t InitPlayout() override { return impl_->InitPlayout(); } bool PlayoutIsInitialized() const override { return impl_->PlayoutIsInitialized(); } int32_t RecordingIsAvailable(bool* available) override { return impl_->RecordingIsAvailable(available); } int32_t InitRecording() override { return impl_->InitRecording(); } bool RecordingIsInitialized() const override { return impl_->RecordingIsInitialized(); } int32_t StartPlayout() override { return impl_->StartPlayout(); } int32_t StopPlayout() override { return impl_->StopPlayout(); } bool Playing() const override { return impl_->Playing(); } int32_t StartRecording() override { return impl_->StartRecording(); } int32_t StopRecording() override { return impl_->StopRecording(); } bool Recording() const override { return impl_->Recording(); } int32_t SetAGC(bool enable) override { return impl_->SetAGC(enable); } bool AGC() const override { return impl_->AGC(); } int32_t InitSpeaker() override { return impl_->InitSpeaker(); } bool SpeakerIsInitialized() const override { return impl_->SpeakerIsInitialized(); } int32_t InitMicrophone() override { return impl_->InitMicrophone(); } bool MicrophoneIsInitialized() const override { return impl_->MicrophoneIsInitialized(); } int32_t SpeakerVolumeIsAvailable(bool* available) override { return impl_->SpeakerVolumeIsAvailable(available); } int32_t SetSpeakerVolume(uint32_t volume) override { return impl_->SetSpeakerVolume(volume); } int32_t SpeakerVolume(uint32_t* volume) const override { return impl_->SpeakerVolume(volume); } int32_t MaxSpeakerVolume(uint32_t* max_volume) const override { return impl_->MaxSpeakerVolume(max_volume); } int32_t MinSpeakerVolume(uint32_t* min_volume) const override { return impl_->MinSpeakerVolume(min_volume); } int32_t MicrophoneVolumeIsAvailable(bool* available) override { return impl_->MicrophoneVolumeIsAvailable(available); } int32_t SetMicrophoneVolume(uint32_t volume) override { return impl_->SetMicrophoneVolume(volume); } int32_t MicrophoneVolume(uint32_t* volume) const override { return impl_->MicrophoneVolume(volume); } int32_t MaxMicrophoneVolume(uint32_t* max_volume) const override { return impl_->MaxMicrophoneVolume(max_volume); } int32_t MinMicrophoneVolume(uint32_t* min_volume) const override { return impl_->MinMicrophoneVolume(min_volume); } int32_t SpeakerMuteIsAvailable(bool* available) override { return impl_->SpeakerMuteIsAvailable(available); } int32_t SetSpeakerMute(bool enable) override { return impl_->SetSpeakerMute(enable); } int32_t SpeakerMute(bool* enabled) const override { return impl_->SpeakerMute(enabled); } int32_t MicrophoneMuteIsAvailable(bool* available) override { return impl_->MicrophoneMuteIsAvailable(available); } int32_t SetMicrophoneMute(bool enable) override { return impl_->SetMicrophoneMute(enable); } int32_t MicrophoneMute(bool* enabled) const override { return impl_->MicrophoneMute(enabled); } int32_t StereoPlayoutIsAvailable(bool* available) const override { return impl_->StereoPlayoutIsAvailable(available); } int32_t SetStereoPlayout(bool enable) override { return impl_->SetStereoPlayout(enable); } int32_t StereoPlayout(bool* enabled) const override { return impl_->StereoPlayout(enabled); } int32_t StereoRecordingIsAvailable(bool* available) const override { return impl_->StereoRecordingIsAvailable(available); } int32_t SetStereoRecording(bool enable) override { return impl_->SetStereoRecording(enable); } int32_t StereoRecording(bool* enabled) const override { return impl_->StereoRecording(enabled); } int32_t SetRecordingChannel(const ChannelType channel) override { return impl_->SetRecordingChannel(channel); } int32_t RecordingChannel(ChannelType* channel) const override { return impl_->RecordingChannel(channel); } int32_t PlayoutDelay(uint16_t* delay_ms) const override { return impl_->PlayoutDelay(delay_ms); } int32_t RecordingDelay(uint16_t* delay_ms) const override { return impl_->RecordingDelay(delay_ms); } int32_t SetRecordingSampleRate(const uint32_t samples_per_sec) override { return impl_->SetRecordingSampleRate(samples_per_sec); } int32_t RecordingSampleRate(uint32_t* samples_per_sec) const override { return impl_->RecordingSampleRate(samples_per_sec); } int32_t SetPlayoutSampleRate(const uint32_t samples_per_sec) override { return impl_->SetPlayoutSampleRate(samples_per_sec); } int32_t PlayoutSampleRate(uint32_t* samples_per_sec) const override { return impl_->PlayoutSampleRate(samples_per_sec); } int32_t SetLoudspeakerStatus(bool enable) override { return impl_->SetLoudspeakerStatus(enable); } int32_t GetLoudspeakerStatus(bool* enabled) const override { return impl_->GetLoudspeakerStatus(enabled); } bool BuiltInAECIsAvailable() const override { return impl_->BuiltInAECIsAvailable(); } bool BuiltInAGCIsAvailable() const override { return impl_->BuiltInAGCIsAvailable(); } bool BuiltInNSIsAvailable() const override { return impl_->BuiltInNSIsAvailable(); } int32_t EnableBuiltInAEC(bool enable) override { return impl_->EnableBuiltInAEC(enable); } int32_t EnableBuiltInAGC(bool enable) override { return impl_->EnableBuiltInAGC(enable); } int32_t EnableBuiltInNS(bool enable) override { return impl_->EnableBuiltInNS(enable); } // Only supported on iOS. #if defined(WEBRTC_IOS) int GetPlayoutAudioParameters(AudioParameters* params) const override { return impl_->GetPlayoutAudioParameters(params); } int GetRecordAudioParameters(AudioParameters* params) const override { return impl_->GetRecordAudioParameters(params); } #endif // WEBRTC_IOS protected: rtc::scoped_refptr impl_; AudioDeviceDataObserver* observer_ = nullptr; AudioTransport* audio_transport_ = nullptr; bool is_valid_ = false; }; } // namespace rtc::scoped_refptr CreateAudioDeviceWithDataObserver( const int32_t id, const AudioDeviceModule::AudioLayer audio_layer, AudioDeviceDataObserver* observer) { rtc::scoped_refptr audio_device( new rtc::RefCountedObject(id, audio_layer, observer)); if (!audio_device->IsValid()) { return nullptr; } return audio_device; } } // namespace webrtc