tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

audio_device_module_win.cc (16915B)


      1 /*
      2 *  Copyright (c) 2018 The WebRTC project authors. All Rights Reserved.
      3 *
      4 *  Use of this source code is governed by a BSD-style license
      5 *  that can be found in the LICENSE file in the root of the source
      6 *  tree. An additional intellectual property rights grant can be found
      7 *  in the file PATENTS.  All contributing project authors may
      8 *  be found in the AUTHORS file in the root of the source tree.
      9 */
     10 
     11 #include "modules/audio_device/win/audio_device_module_win.h"
     12 
     13 #include <memory>
     14 #include <utility>
     15 
     16 #include "api/audio/audio_device.h"
     17 #include "api/environment/environment.h"
     18 #include "api/make_ref_counted.h"
     19 #include "api/sequence_checker.h"
     20 #include "modules/audio_device/audio_device_buffer.h"
     21 #include "rtc_base/checks.h"
     22 #include "rtc_base/logging.h"
     23 #include "rtc_base/string_utils.h"
     24 
     25 namespace webrtc {
     26 namespace webrtc_win {
     27 namespace {
     28 
     29 #define RETURN_IF_OUTPUT_RESTARTS(...) \
     30  do {                                 \
     31    if (output_->Restarting()) {       \
     32      return __VA_ARGS__;              \
     33    }                                  \
     34  } while (0)
     35 
     36 #define RETURN_IF_INPUT_RESTARTS(...) \
     37  do {                                \
     38    if (input_->Restarting()) {       \
     39      return __VA_ARGS__;             \
     40    }                                 \
     41  } while (0)
     42 
     43 #define RETURN_IF_OUTPUT_IS_INITIALIZED(...) \
     44  do {                                       \
     45    if (output_->PlayoutIsInitialized()) {   \
     46      return __VA_ARGS__;                    \
     47    }                                        \
     48  } while (0)
     49 
     50 #define RETURN_IF_INPUT_IS_INITIALIZED(...) \
     51  do {                                      \
     52    if (input_->RecordingIsInitialized()) { \
     53      return __VA_ARGS__;                   \
     54    }                                       \
     55  } while (0)
     56 
     57 #define RETURN_IF_OUTPUT_IS_ACTIVE(...) \
     58  do {                                  \
     59    if (output_->Playing()) {           \
     60      return __VA_ARGS__;               \
     61    }                                   \
     62  } while (0)
     63 
     64 #define RETURN_IF_INPUT_IS_ACTIVE(...) \
     65  do {                                 \
     66    if (input_->Recording()) {         \
     67      return __VA_ARGS__;              \
     68    }                                  \
     69  } while (0)
     70 
     71 // This class combines a generic instance of an AudioInput and a generic
     72 // instance of an AudioOutput to create an AudioDeviceModule. This is mostly
     73 // done by delegating to the audio input/output with some glue code. This class
     74 // also directly implements some of the AudioDeviceModule methods with dummy
     75 // implementations.
     76 //
     77 // An instance must be created, destroyed and used on one and the same thread,
     78 // i.e., all public methods must also be called on the same thread. A thread
     79 // checker will RTC_DCHECK if any method is called on an invalid thread.
     80 // TODO(henrika): is thread checking needed in AudioInput and AudioOutput?
     81 class WindowsAudioDeviceModule : public AudioDeviceModuleForTest {
     82 public:
     83  enum class InitStatus {
     84    OK = 0,
     85    PLAYOUT_ERROR = 1,
     86    RECORDING_ERROR = 2,
     87    OTHER_ERROR = 3,
     88    NUM_STATUSES = 4
     89  };
     90 
     91  WindowsAudioDeviceModule(const Environment& env,
     92                           std::unique_ptr<AudioInput> audio_input,
     93                           std::unique_ptr<AudioOutput> audio_output)
     94      : env_(env),
     95        input_(std::move(audio_input)),
     96        output_(std::move(audio_output)) {
     97    RTC_CHECK(input_);
     98    RTC_CHECK(output_);
     99    RTC_DLOG(LS_INFO) << __FUNCTION__;
    100    RTC_DCHECK_RUN_ON(&thread_checker_);
    101  }
    102 
    103  ~WindowsAudioDeviceModule() override {
    104    RTC_DLOG(LS_INFO) << __FUNCTION__;
    105    RTC_DCHECK_RUN_ON(&thread_checker_);
    106    Terminate();
    107  }
    108 
    109  WindowsAudioDeviceModule(const WindowsAudioDeviceModule&) = delete;
    110  WindowsAudioDeviceModule& operator=(const WindowsAudioDeviceModule&) = delete;
    111 
    112  int32_t ActiveAudioLayer(
    113      AudioDeviceModule::AudioLayer* audioLayer) const override {
    114    RTC_DLOG(LS_INFO) << __FUNCTION__;
    115    RTC_DCHECK_RUN_ON(&thread_checker_);
    116    // TODO(henrika): it might be possible to remove this unique signature.
    117    *audioLayer = AudioDeviceModule::kWindowsCoreAudio2;
    118    return 0;
    119  }
    120 
    121  int32_t RegisterAudioCallback(AudioTransport* audioCallback) override {
    122    RTC_DLOG(LS_INFO) << __FUNCTION__;
    123    RTC_DCHECK(audio_device_buffer_);
    124    RTC_DCHECK_RUN_ON(&thread_checker_);
    125    return audio_device_buffer_->RegisterAudioCallback(audioCallback);
    126  }
    127 
    128  int32_t Init() override {
    129    RTC_DLOG(LS_INFO) << __FUNCTION__;
    130    RTC_DCHECK_RUN_ON(&thread_checker_);
    131    RETURN_IF_OUTPUT_RESTARTS(0);
    132    RETURN_IF_INPUT_RESTARTS(0);
    133    if (initialized_) {
    134      return 0;
    135    }
    136    audio_device_buffer_ = std::make_unique<AudioDeviceBuffer>(env_);
    137    AttachAudioBuffer();
    138    InitStatus status;
    139    if (output_->Init() != 0) {
    140      status = InitStatus::PLAYOUT_ERROR;
    141    } else if (input_->Init() != 0) {
    142      output_->Terminate();
    143      status = InitStatus::RECORDING_ERROR;
    144    } else {
    145      initialized_ = true;
    146      status = InitStatus::OK;
    147    }
    148    if (status != InitStatus::OK) {
    149      RTC_LOG(LS_ERROR) << "Audio device initialization failed";
    150      return -1;
    151    }
    152    return 0;
    153  }
    154 
    155  int32_t Terminate() override {
    156    RTC_DLOG(LS_INFO) << __FUNCTION__;
    157    RTC_DCHECK_RUN_ON(&thread_checker_);
    158    RETURN_IF_OUTPUT_RESTARTS(0);
    159    RETURN_IF_INPUT_RESTARTS(0);
    160    if (!initialized_)
    161      return 0;
    162    int32_t err = input_->Terminate();
    163    err |= output_->Terminate();
    164    initialized_ = false;
    165    RTC_DCHECK_EQ(err, 0);
    166    return err;
    167  }
    168 
    169  bool Initialized() const override {
    170    RTC_DCHECK_RUN_ON(&thread_checker_);
    171    return initialized_;
    172  }
    173 
    174  int16_t PlayoutDevices() override {
    175    RTC_DLOG(LS_INFO) << __FUNCTION__;
    176    RTC_DCHECK_RUN_ON(&thread_checker_);
    177    RETURN_IF_OUTPUT_RESTARTS(0);
    178    return output_->NumDevices();
    179  }
    180 
    181  int16_t RecordingDevices() override {
    182    RTC_DLOG(LS_INFO) << __FUNCTION__;
    183    RTC_DCHECK_RUN_ON(&thread_checker_);
    184    RETURN_IF_INPUT_RESTARTS(0);
    185    return input_->NumDevices();
    186  }
    187 
    188  int32_t PlayoutDeviceName(uint16_t index,
    189                            char name[kAdmMaxDeviceNameSize],
    190                            char guid[kAdmMaxGuidSize]) override {
    191    RTC_DLOG(LS_INFO) << __FUNCTION__;
    192    RTC_DCHECK_RUN_ON(&thread_checker_);
    193    RETURN_IF_OUTPUT_RESTARTS(0);
    194    std::string name_str, guid_str;
    195    int ret = -1;
    196    if (guid != nullptr) {
    197      ret = output_->DeviceName(index, &name_str, &guid_str);
    198      webrtc::strcpyn(guid, kAdmMaxGuidSize, guid_str.c_str());
    199    } else {
    200      ret = output_->DeviceName(index, &name_str, nullptr);
    201    }
    202    webrtc::strcpyn(name, kAdmMaxDeviceNameSize, name_str.c_str());
    203    return ret;
    204  }
    205  int32_t RecordingDeviceName(uint16_t index,
    206                              char name[kAdmMaxDeviceNameSize],
    207                              char guid[kAdmMaxGuidSize]) override {
    208    RTC_DLOG(LS_INFO) << __FUNCTION__;
    209    RTC_DCHECK_RUN_ON(&thread_checker_);
    210    RETURN_IF_INPUT_RESTARTS(0);
    211    std::string name_str, guid_str;
    212    int ret = -1;
    213    if (guid != nullptr) {
    214      ret = input_->DeviceName(index, &name_str, &guid_str);
    215      webrtc::strcpyn(guid, kAdmMaxGuidSize, guid_str.c_str());
    216    } else {
    217      ret = input_->DeviceName(index, &name_str, nullptr);
    218    }
    219    webrtc::strcpyn(name, kAdmMaxDeviceNameSize, name_str.c_str());
    220    return ret;
    221  }
    222 
    223  int32_t SetPlayoutDevice(uint16_t index) override {
    224    RTC_DLOG(LS_INFO) << __FUNCTION__;
    225    RTC_DCHECK_RUN_ON(&thread_checker_);
    226    RETURN_IF_OUTPUT_RESTARTS(0);
    227    return output_->SetDevice(index);
    228  }
    229 
    230  int32_t SetPlayoutDevice(
    231      AudioDeviceModule::WindowsDeviceType device) override {
    232    RTC_DLOG(LS_INFO) << __FUNCTION__;
    233    RTC_DCHECK_RUN_ON(&thread_checker_);
    234    RETURN_IF_OUTPUT_RESTARTS(0);
    235    return output_->SetDevice(device);
    236  }
    237  int32_t SetRecordingDevice(uint16_t index) override {
    238    RTC_DLOG(LS_INFO) << __FUNCTION__;
    239    RTC_DCHECK_RUN_ON(&thread_checker_);
    240    return input_->SetDevice(index);
    241  }
    242 
    243  int32_t SetRecordingDevice(
    244      AudioDeviceModule::WindowsDeviceType device) override {
    245    RTC_DLOG(LS_INFO) << __FUNCTION__;
    246    RTC_DCHECK_RUN_ON(&thread_checker_);
    247    return input_->SetDevice(device);
    248  }
    249 
    250  int32_t PlayoutIsAvailable(bool* available) override {
    251    RTC_DLOG(LS_INFO) << __FUNCTION__;
    252    RTC_DCHECK_RUN_ON(&thread_checker_);
    253    *available = true;
    254    return 0;
    255  }
    256 
    257  int32_t InitPlayout() override {
    258    RTC_DLOG(LS_INFO) << __FUNCTION__;
    259    RTC_DCHECK_RUN_ON(&thread_checker_);
    260    RETURN_IF_OUTPUT_RESTARTS(0);
    261    RETURN_IF_OUTPUT_IS_INITIALIZED(0);
    262    return output_->InitPlayout();
    263  }
    264 
    265  bool PlayoutIsInitialized() const override {
    266    RTC_DLOG(LS_INFO) << __FUNCTION__;
    267    RTC_DCHECK_RUN_ON(&thread_checker_);
    268    RETURN_IF_OUTPUT_RESTARTS(true);
    269    return output_->PlayoutIsInitialized();
    270  }
    271 
    272  int32_t RecordingIsAvailable(bool* available) override {
    273    RTC_DLOG(LS_INFO) << __FUNCTION__;
    274    RTC_DCHECK_RUN_ON(&thread_checker_);
    275    *available = true;
    276    return 0;
    277  }
    278 
    279  int32_t InitRecording() override {
    280    RTC_DLOG(LS_INFO) << __FUNCTION__;
    281    RTC_DCHECK_RUN_ON(&thread_checker_);
    282    RETURN_IF_INPUT_RESTARTS(0);
    283    RETURN_IF_INPUT_IS_INITIALIZED(0);
    284    return input_->InitRecording();
    285  }
    286 
    287  bool RecordingIsInitialized() const override {
    288    RTC_DLOG(LS_INFO) << __FUNCTION__;
    289    RTC_DCHECK_RUN_ON(&thread_checker_);
    290    RETURN_IF_INPUT_RESTARTS(true);
    291    return input_->RecordingIsInitialized();
    292  }
    293 
    294  int32_t StartPlayout() override {
    295    RTC_DLOG(LS_INFO) << __FUNCTION__;
    296    RTC_DCHECK_RUN_ON(&thread_checker_);
    297    RETURN_IF_OUTPUT_RESTARTS(0);
    298    RETURN_IF_OUTPUT_IS_ACTIVE(0);
    299    return output_->StartPlayout();
    300  }
    301 
    302  int32_t StopPlayout() override {
    303    RTC_DLOG(LS_INFO) << __FUNCTION__;
    304    RTC_DCHECK_RUN_ON(&thread_checker_);
    305    RETURN_IF_OUTPUT_RESTARTS(-1);
    306    return output_->StopPlayout();
    307  }
    308 
    309  bool Playing() const override {
    310    RTC_DLOG(LS_INFO) << __FUNCTION__;
    311    RTC_DCHECK_RUN_ON(&thread_checker_);
    312    RETURN_IF_OUTPUT_RESTARTS(true);
    313    return output_->Playing();
    314  }
    315 
    316  int32_t StartRecording() override {
    317    RTC_DLOG(LS_INFO) << __FUNCTION__;
    318    RTC_DCHECK_RUN_ON(&thread_checker_);
    319    RETURN_IF_INPUT_RESTARTS(0);
    320    RETURN_IF_INPUT_IS_ACTIVE(0);
    321    return input_->StartRecording();
    322  }
    323 
    324  int32_t StopRecording() override {
    325    RTC_DLOG(LS_INFO) << __FUNCTION__;
    326    RTC_DCHECK_RUN_ON(&thread_checker_);
    327    RETURN_IF_INPUT_RESTARTS(-1);
    328    return input_->StopRecording();
    329  }
    330 
    331  bool Recording() const override {
    332    RTC_DLOG(LS_INFO) << __FUNCTION__;
    333    RETURN_IF_INPUT_RESTARTS(true);
    334    return input_->Recording();
    335  }
    336 
    337  int32_t InitSpeaker() override {
    338    RTC_DLOG(LS_INFO) << __FUNCTION__;
    339    RTC_DCHECK_RUN_ON(&thread_checker_);
    340    RTC_DLOG(LS_WARNING) << "This method has no effect";
    341    return initialized_ ? 0 : -1;
    342  }
    343 
    344  bool SpeakerIsInitialized() const override {
    345    RTC_DLOG(LS_INFO) << __FUNCTION__;
    346    RTC_DCHECK_RUN_ON(&thread_checker_);
    347    RTC_DLOG(LS_WARNING) << "This method has no effect";
    348    return initialized_;
    349  }
    350 
    351  int32_t InitMicrophone() override {
    352    RTC_DLOG(LS_INFO) << __FUNCTION__;
    353    RTC_DCHECK_RUN_ON(&thread_checker_);
    354    RTC_DLOG(LS_WARNING) << "This method has no effect";
    355    return initialized_ ? 0 : -1;
    356  }
    357 
    358  bool MicrophoneIsInitialized() const override {
    359    RTC_DLOG(LS_INFO) << __FUNCTION__;
    360    RTC_DCHECK_RUN_ON(&thread_checker_);
    361    RTC_DLOG(LS_WARNING) << "This method has no effect";
    362    return initialized_;
    363  }
    364 
    365  int32_t SpeakerVolumeIsAvailable(bool* available) override {
    366    // TODO(henrika): improve support.
    367    RTC_DLOG(LS_INFO) << __FUNCTION__;
    368    RTC_DCHECK_RUN_ON(&thread_checker_);
    369    *available = false;
    370    return 0;
    371  }
    372 
    373  int32_t SetSpeakerVolume(uint32_t volume) override { return 0; }
    374  int32_t SpeakerVolume(uint32_t* volume) const override { return 0; }
    375  int32_t MaxSpeakerVolume(uint32_t* maxVolume) const override { return 0; }
    376  int32_t MinSpeakerVolume(uint32_t* minVolume) const override { return 0; }
    377 
    378  int32_t MicrophoneVolumeIsAvailable(bool* available) override {
    379    // TODO(henrika): improve support.
    380    RTC_DLOG(LS_INFO) << __FUNCTION__;
    381    RTC_DCHECK_RUN_ON(&thread_checker_);
    382    *available = false;
    383    return 0;
    384  }
    385 
    386  int32_t SetMicrophoneVolume(uint32_t volume) override { return 0; }
    387  int32_t MicrophoneVolume(uint32_t* volume) const override { return 0; }
    388  int32_t MaxMicrophoneVolume(uint32_t* maxVolume) const override { return 0; }
    389  int32_t MinMicrophoneVolume(uint32_t* minVolume) const override { return 0; }
    390 
    391  int32_t SpeakerMuteIsAvailable(bool* available) override { return 0; }
    392  int32_t SetSpeakerMute(bool enable) override { return 0; }
    393  int32_t SpeakerMute(bool* enabled) const override { return 0; }
    394 
    395  int32_t MicrophoneMuteIsAvailable(bool* available) override { return 0; }
    396  int32_t SetMicrophoneMute(bool enable) override { return 0; }
    397  int32_t MicrophoneMute(bool* enabled) const override { return 0; }
    398 
    399  int32_t StereoPlayoutIsAvailable(bool* available) const override {
    400    // TODO(henrika): improve support.
    401    RTC_DLOG(LS_INFO) << __FUNCTION__;
    402    RTC_DCHECK_RUN_ON(&thread_checker_);
    403    *available = true;
    404    return 0;
    405  }
    406 
    407  int32_t SetStereoPlayout(bool enable) override {
    408    // TODO(henrika): improve support.
    409    RTC_DLOG(LS_INFO) << __FUNCTION__;
    410    RTC_DCHECK_RUN_ON(&thread_checker_);
    411    return 0;
    412  }
    413 
    414  int32_t StereoPlayout(bool* enabled) const override {
    415    // TODO(henrika): improve support.
    416    RTC_DLOG(LS_INFO) << __FUNCTION__;
    417    RTC_DCHECK_RUN_ON(&thread_checker_);
    418    *enabled = true;
    419    return 0;
    420  }
    421 
    422  int32_t StereoRecordingIsAvailable(bool* available) const override {
    423    // TODO(henrika): improve support.
    424    RTC_DLOG(LS_INFO) << __FUNCTION__;
    425    RTC_DCHECK_RUN_ON(&thread_checker_);
    426    *available = true;
    427    return 0;
    428  }
    429 
    430  int32_t SetStereoRecording(bool enable) override {
    431    // TODO(henrika): improve support.
    432    RTC_DLOG(LS_INFO) << __FUNCTION__;
    433    RTC_DCHECK_RUN_ON(&thread_checker_);
    434    return 0;
    435  }
    436 
    437  int32_t StereoRecording(bool* enabled) const override {
    438    // TODO(henrika): improve support.
    439    RTC_DLOG(LS_INFO) << __FUNCTION__;
    440    RTC_DCHECK_RUN_ON(&thread_checker_);
    441    *enabled = true;
    442    return 0;
    443  }
    444 
    445  int32_t PlayoutDelay(uint16_t* delayMS) const override { return 0; }
    446 
    447  bool BuiltInAECIsAvailable() const override { return false; }
    448  bool BuiltInAGCIsAvailable() const override { return false; }
    449  bool BuiltInNSIsAvailable() const override { return false; }
    450 
    451  int32_t EnableBuiltInAEC(bool enable) override { return 0; }
    452  int32_t EnableBuiltInAGC(bool enable) override { return 0; }
    453  int32_t EnableBuiltInNS(bool enable) override { return 0; }
    454 
    455  int32_t AttachAudioBuffer() {
    456    RTC_DLOG(LS_INFO) << __FUNCTION__;
    457    output_->AttachAudioBuffer(audio_device_buffer_.get());
    458    input_->AttachAudioBuffer(audio_device_buffer_.get());
    459    return 0;
    460  }
    461 
    462  int RestartPlayoutInternally() override {
    463    RTC_DLOG(LS_INFO) << __FUNCTION__;
    464    RTC_DCHECK_RUN_ON(&thread_checker_);
    465    RETURN_IF_OUTPUT_RESTARTS(0);
    466    return output_->RestartPlayout();
    467  }
    468 
    469  int RestartRecordingInternally() override {
    470    RTC_DLOG(LS_INFO) << __FUNCTION__;
    471    RTC_DCHECK_RUN_ON(&thread_checker_);
    472    return input_->RestartRecording();
    473  }
    474 
    475  int SetPlayoutSampleRate(uint32_t sample_rate) override {
    476    RTC_DLOG(LS_INFO) << __FUNCTION__;
    477    RTC_DCHECK_RUN_ON(&thread_checker_);
    478    return output_->SetSampleRate(sample_rate);
    479  }
    480 
    481  int SetRecordingSampleRate(uint32_t sample_rate) override {
    482    RTC_DLOG(LS_INFO) << __FUNCTION__;
    483    RTC_DCHECK_RUN_ON(&thread_checker_);
    484    return input_->SetSampleRate(sample_rate);
    485  }
    486 
    487 private:
    488  const Environment env_;
    489 
    490  // Ensures that the class is used on the same thread as it is constructed
    491  // and destroyed on.
    492  SequenceChecker thread_checker_;
    493 
    494  // Implements the AudioInput interface and deals with audio capturing parts.
    495  const std::unique_ptr<AudioInput> input_;
    496 
    497  // Implements the AudioOutput interface and deals with audio rendering parts.
    498  const std::unique_ptr<AudioOutput> output_;
    499 
    500  // The AudioDeviceBuffer (ADB) instance is needed for sending/receiving audio
    501  // to/from the WebRTC layer. Created and owned by this object. Used by
    502  // both `input_` and `output_` but they use orthogonal parts of the ADB.
    503  std::unique_ptr<AudioDeviceBuffer> audio_device_buffer_;
    504 
    505  // Set to true after a successful call to Init(). Cleared by Terminate().
    506  bool initialized_ = false;
    507 };
    508 
    509 }  // namespace
    510 
    511 webrtc::scoped_refptr<AudioDeviceModuleForTest>
    512 CreateWindowsCoreAudioAudioDeviceModuleFromInputAndOutput(
    513    const Environment& env,
    514    std::unique_ptr<AudioInput> audio_input,
    515    std::unique_ptr<AudioOutput> audio_output) {
    516  RTC_DLOG(LS_INFO) << __FUNCTION__;
    517  return make_ref_counted<WindowsAudioDeviceModule>(env, std::move(audio_input),
    518                                                    std::move(audio_output));
    519 }
    520 
    521 }  // namespace webrtc_win
    522 }  // namespace webrtc