/* * Copyright (c) 2020 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.
*/
// For Windows, use specific enum type to initialize default audio device as // defined in AudioDeviceModule::WindowsDeviceType. #ifdefined(WEBRTC_WIN)
constexpr AudioDeviceModule::WindowsDeviceType kAudioDeviceId =
AudioDeviceModule::WindowsDeviceType::kDefaultCommunicationDevice; #else
constexpr uint16_t kAudioDeviceId = 0; #endif// defined(WEBRTC_WIN)
// Maximum value range limit on ChannelId. This can be increased without any // side effect and only set at this moderate value for better readability for // logging. static constexpr int kMaxChannelId = 100000;
// AudioTransportImpl depends on audio mixer and audio processing instances.
audio_transport_ = std::make_unique<AudioTransportImpl>(
audio_mixer_.get(), audio_processing_.get(), nullptr);
}
bool VoipCore::InitializeIfNeeded() { // `audio_device_module_` internally owns a lock and the whole logic here // needs to be executed atomically once using another lock in VoipCore. // Further changes in this method will need to make sure that no deadlock is // introduced in the future.
MutexLock lock(&lock_);
if (initialized_) { returntrue;
}
// Initialize ADM. if (audio_device_module_->Init() != 0) {
RTC_LOG(LS_ERROR) << "Failed to initialize the ADM."; returnfalse;
}
// Note that failures on initializing default recording/speaker devices are // not considered to be fatal here. In certain case, caller may not care about // recording device functioning (e.g webinar where only speaker is available). // It's also possible that there are other audio devices available that may // work.
// Initialize default speaker device. if (audio_device_module_->SetPlayoutDevice(kAudioDeviceId) != 0) {
RTC_LOG(LS_WARNING) << "Unable to set playout device.";
} if (audio_device_module_->InitSpeaker() != 0) {
RTC_LOG(LS_WARNING) << "Unable to access speaker.";
}
// Initialize default recording device. if (audio_device_module_->SetRecordingDevice(kAudioDeviceId) != 0) {
RTC_LOG(LS_WARNING) << "Unable to set recording device.";
} if (audio_device_module_->InitMicrophone() != 0) {
RTC_LOG(LS_WARNING) << "Unable to access microphone.";
}
// Set number of channels on speaker device. bool available = false; if (audio_device_module_->StereoPlayoutIsAvailable(&available) != 0) {
RTC_LOG(LS_WARNING) << "Unable to query stereo playout.";
} if (audio_device_module_->SetStereoPlayout(available) != 0) {
RTC_LOG(LS_WARNING) << "Unable to set mono/stereo playout mode.";
}
// Set number of channels on recording device.
available = false; if (audio_device_module_->StereoRecordingIsAvailable(&available) != 0) {
RTC_LOG(LS_WARNING) << "Unable to query stereo recording.";
} if (audio_device_module_->SetStereoRecording(available) != 0) {
RTC_LOG(LS_WARNING) << "Unable to set stereo recording mode.";
}
if (audio_device_module_->RegisterAudioCallback(audio_transport_.get()) !=
0) {
RTC_LOG(LS_WARNING) << "Unable to register audio callback.";
}
if (no_channels_after_release) { // TODO(bugs.webrtc.org/11581): unclear if we still need to clear `channel` // here.
channel = nullptr;
// Make sure to stop playout on ADM if it is playing. if (audio_device_module_->Playing()) { if (audio_device_module_->StopPlayout() != 0) {
RTC_LOG(LS_WARNING) << "StopPlayout failed";
status_code = VoipResult::kInternal;
}
}
}
return status_code;
}
rtc::scoped_refptr<AudioChannel> VoipCore::GetChannel(ChannelId channel_id) {
rtc::scoped_refptr<AudioChannel> channel;
{
MutexLock lock(&lock_); auto iter = channels_.find(channel_id); if (iter != channels_.end()) {
channel = iter->second;
}
} if (!channel) {
RTC_LOG(LS_ERROR) << "Channel " << channel_id << " not found";
} return channel;
}
// Gather a list of audio channel that are currently sending along with // highest sampling rate and channel numbers to configure into audio // transport. int max_sampling_rate = 8000;
size_t max_num_channels = 1;
{
MutexLock lock(&lock_); // Reserve to prevent run time vector re-allocation.
audio_senders.reserve(channels_.size()); for (auto kv : channels_) {
rtc::scoped_refptr<AudioChannel>& channel = kv.second; if (channel->IsSendingMedia()) { auto encoder_format = channel->GetEncoderFormat(); if (!encoder_format) {
RTC_LOG(LS_ERROR)
<< "channel " << channel->GetId() << " encoder is not set"; continue;
}
audio_senders.push_back(channel->GetAudioSender());
max_sampling_rate =
std::max(max_sampling_rate, encoder_format->clockrate_hz);
max_num_channels =
std::max(max_num_channels, encoder_format->num_channels);
}
}
}
// Depending on availability of senders, turn on or off ADM recording. if (!audio_senders.empty()) { // Initialize audio device module and default device if needed. if (!InitializeIfNeeded()) { returnfalse;
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.