tor-browser

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

audio_device_mac.h (12348B)


      1 /*
      2 *  Copyright (c) 2012 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 #ifndef AUDIO_DEVICE_AUDIO_DEVICE_MAC_H_
     12 #define AUDIO_DEVICE_AUDIO_DEVICE_MAC_H_
     13 
     14 #include <AudioToolbox/AudioConverter.h>
     15 #include <CoreAudio/CoreAudio.h>
     16 #include <mach/semaphore.h>
     17 
     18 #include <atomic>
     19 #include <memory>
     20 
     21 #include "absl/strings/string_view.h"
     22 #include "modules/audio_device/audio_device_generic.h"
     23 #include "modules/audio_device/mac/audio_mixer_manager_mac.h"
     24 #include "rtc_base/event.h"
     25 #include "rtc_base/logging.h"
     26 #include "rtc_base/platform_thread.h"
     27 #include "rtc_base/synchronization/mutex.h"
     28 #include "rtc_base/thread_annotations.h"
     29 
     30 struct PaUtilRingBuffer;
     31 
     32 namespace webrtc {
     33 
     34 const uint32_t N_REC_SAMPLES_PER_SEC = 48000;
     35 const uint32_t N_PLAY_SAMPLES_PER_SEC = 48000;
     36 
     37 const uint32_t N_REC_CHANNELS = 1;   // default is mono recording
     38 const uint32_t N_PLAY_CHANNELS = 2;  // default is stereo playout
     39 const uint32_t N_DEVICE_CHANNELS = 64;
     40 
     41 const int kBufferSizeMs = 10;
     42 
     43 const uint32_t ENGINE_REC_BUF_SIZE_IN_SAMPLES =
     44    N_REC_SAMPLES_PER_SEC * kBufferSizeMs / 1000;
     45 const uint32_t ENGINE_PLAY_BUF_SIZE_IN_SAMPLES =
     46    N_PLAY_SAMPLES_PER_SEC * kBufferSizeMs / 1000;
     47 
     48 const int N_BLOCKS_IO = 2;
     49 const int N_BUFFERS_IN = 2;   // Must be at least N_BLOCKS_IO.
     50 const int N_BUFFERS_OUT = 3;  // Must be at least N_BLOCKS_IO.
     51 
     52 const uint32_t TIMER_PERIOD_MS = 2 * 10 * N_BLOCKS_IO * 1000000;
     53 
     54 const uint32_t REC_BUF_SIZE_IN_SAMPLES =
     55    ENGINE_REC_BUF_SIZE_IN_SAMPLES * N_DEVICE_CHANNELS * N_BUFFERS_IN;
     56 const uint32_t PLAY_BUF_SIZE_IN_SAMPLES =
     57    ENGINE_PLAY_BUF_SIZE_IN_SAMPLES * N_PLAY_CHANNELS * N_BUFFERS_OUT;
     58 
     59 const int kGetMicVolumeIntervalMs = 1000;
     60 
     61 class AudioDeviceMac : public AudioDeviceGeneric {
     62 public:
     63  AudioDeviceMac();
     64  ~AudioDeviceMac();
     65 
     66  // Retrieve the currently utilized audio layer
     67  virtual int32_t ActiveAudioLayer(
     68      AudioDeviceModule::AudioLayer& audioLayer) const;
     69 
     70  // Main initializaton and termination
     71  virtual InitStatus Init() RTC_LOCKS_EXCLUDED(mutex_);
     72  virtual int32_t Terminate() RTC_LOCKS_EXCLUDED(mutex_);
     73  virtual bool Initialized() const;
     74 
     75  // Device enumeration
     76  virtual int16_t PlayoutDevices();
     77  virtual int16_t RecordingDevices();
     78  virtual int32_t PlayoutDeviceName(uint16_t index,
     79                                    char name[kAdmMaxDeviceNameSize],
     80                                    char guid[kAdmMaxGuidSize]);
     81  virtual int32_t RecordingDeviceName(uint16_t index,
     82                                      char name[kAdmMaxDeviceNameSize],
     83                                      char guid[kAdmMaxGuidSize]);
     84 
     85  // Device selection
     86  virtual int32_t SetPlayoutDevice(uint16_t index) RTC_LOCKS_EXCLUDED(mutex_);
     87  virtual int32_t SetPlayoutDevice(AudioDeviceModule::WindowsDeviceType device);
     88  virtual int32_t SetRecordingDevice(uint16_t index);
     89  virtual int32_t SetRecordingDevice(
     90      AudioDeviceModule::WindowsDeviceType device);
     91 
     92  // Audio transport initialization
     93  virtual int32_t PlayoutIsAvailable(bool& available);
     94  virtual int32_t InitPlayout() RTC_LOCKS_EXCLUDED(mutex_);
     95  virtual bool PlayoutIsInitialized() const;
     96  virtual int32_t RecordingIsAvailable(bool& available);
     97  virtual int32_t InitRecording() RTC_LOCKS_EXCLUDED(mutex_);
     98  virtual bool RecordingIsInitialized() const;
     99 
    100  // Audio transport control
    101  virtual int32_t StartPlayout() RTC_LOCKS_EXCLUDED(mutex_);
    102  virtual int32_t StopPlayout() RTC_LOCKS_EXCLUDED(mutex_);
    103  virtual bool Playing() const;
    104  virtual int32_t StartRecording() RTC_LOCKS_EXCLUDED(mutex_);
    105  virtual int32_t StopRecording() RTC_LOCKS_EXCLUDED(mutex_);
    106  virtual bool Recording() const;
    107 
    108  // Audio mixer initialization
    109  virtual int32_t InitSpeaker() RTC_LOCKS_EXCLUDED(mutex_);
    110  virtual bool SpeakerIsInitialized() const;
    111  virtual int32_t InitMicrophone() RTC_LOCKS_EXCLUDED(mutex_);
    112  virtual bool MicrophoneIsInitialized() const;
    113 
    114  // Speaker volume controls
    115  virtual int32_t SpeakerVolumeIsAvailable(bool& available)
    116      RTC_LOCKS_EXCLUDED(mutex_);
    117  virtual int32_t SetSpeakerVolume(uint32_t volume);
    118  virtual int32_t SpeakerVolume(uint32_t& volume) const;
    119  virtual int32_t MaxSpeakerVolume(uint32_t& maxVolume) const;
    120  virtual int32_t MinSpeakerVolume(uint32_t& minVolume) const;
    121 
    122  // Microphone volume controls
    123  virtual int32_t MicrophoneVolumeIsAvailable(bool& available)
    124      RTC_LOCKS_EXCLUDED(mutex_);
    125  virtual int32_t SetMicrophoneVolume(uint32_t volume);
    126  virtual int32_t MicrophoneVolume(uint32_t& volume) const;
    127  virtual int32_t MaxMicrophoneVolume(uint32_t& maxVolume) const;
    128  virtual int32_t MinMicrophoneVolume(uint32_t& minVolume) const;
    129 
    130  // Microphone mute control
    131  virtual int32_t MicrophoneMuteIsAvailable(bool& available)
    132      RTC_LOCKS_EXCLUDED(mutex_);
    133  virtual int32_t SetMicrophoneMute(bool enable);
    134  virtual int32_t MicrophoneMute(bool& enabled) const;
    135 
    136  // Speaker mute control
    137  virtual int32_t SpeakerMuteIsAvailable(bool& available)
    138      RTC_LOCKS_EXCLUDED(mutex_);
    139  virtual int32_t SetSpeakerMute(bool enable);
    140  virtual int32_t SpeakerMute(bool& enabled) const;
    141 
    142  // Stereo support
    143  virtual int32_t StereoPlayoutIsAvailable(bool& available)
    144      RTC_LOCKS_EXCLUDED(mutex_);
    145  virtual int32_t SetStereoPlayout(bool enable);
    146  virtual int32_t StereoPlayout(bool& enabled) const;
    147  virtual int32_t StereoRecordingIsAvailable(bool& available);
    148  virtual int32_t SetStereoRecording(bool enable);
    149  virtual int32_t StereoRecording(bool& enabled) const;
    150 
    151  // Delay information and control
    152  virtual int32_t PlayoutDelay(uint16_t& delayMS) const;
    153 
    154  virtual void AttachAudioBuffer(AudioDeviceBuffer* audioBuffer)
    155      RTC_LOCKS_EXCLUDED(mutex_);
    156 
    157 private:
    158  int32_t InitSpeakerLocked() RTC_EXCLUSIVE_LOCKS_REQUIRED(mutex_);
    159  int32_t InitMicrophoneLocked() RTC_EXCLUSIVE_LOCKS_REQUIRED(mutex_);
    160 
    161  virtual int32_t MicrophoneIsAvailable(bool& available)
    162      RTC_LOCKS_EXCLUDED(mutex_);
    163  virtual int32_t MicrophoneIsAvailableLocked(bool& available)
    164      RTC_EXCLUSIVE_LOCKS_REQUIRED(mutex_);
    165  virtual int32_t SpeakerIsAvailable(bool& available)
    166      RTC_LOCKS_EXCLUDED(mutex_);
    167  virtual int32_t SpeakerIsAvailableLocked(bool& available)
    168      RTC_EXCLUSIVE_LOCKS_REQUIRED(mutex_);
    169 
    170  static void AtomicSet32(int32_t* theValue, int32_t newValue);
    171  static int32_t AtomicGet32(int32_t* theValue);
    172 
    173  static void logCAMsg(LoggingSeverity sev, const char* msg, const char* err);
    174 
    175  int32_t GetNumberDevices(AudioObjectPropertyScope scope,
    176                           AudioDeviceID scopedDeviceIds[],
    177                           uint32_t deviceListLength);
    178 
    179  int32_t GetDeviceName(AudioObjectPropertyScope scope,
    180                        uint16_t index,
    181                        ArrayView<char> name);
    182 
    183  int32_t InitDevice(uint16_t userDeviceIndex,
    184                     AudioDeviceID& deviceId,
    185                     bool isInput);
    186 
    187  // Always work with our preferred playout format inside VoE.
    188  // Then convert the output to the OS setting using an AudioConverter.
    189  OSStatus SetDesiredPlayoutFormat();
    190 
    191  static OSStatus objectListenerProc(
    192      AudioObjectID objectId,
    193      UInt32 numberAddresses,
    194      const AudioObjectPropertyAddress addresses[],
    195      void* clientData);
    196 
    197  OSStatus implObjectListenerProc(AudioObjectID objectId,
    198                                  UInt32 numberAddresses,
    199                                  const AudioObjectPropertyAddress addresses[]);
    200 
    201  int32_t HandleDeviceChange();
    202 
    203  int32_t HandleStreamFormatChange(AudioObjectID objectId,
    204                                   AudioObjectPropertyAddress propertyAddress);
    205 
    206  int32_t HandleDataSourceChange(AudioObjectID objectId,
    207                                 AudioObjectPropertyAddress propertyAddress);
    208 
    209  int32_t HandleProcessorOverload(AudioObjectPropertyAddress propertyAddress);
    210 
    211  static OSStatus deviceIOProc(AudioDeviceID device,
    212                               const AudioTimeStamp* now,
    213                               const AudioBufferList* inputData,
    214                               const AudioTimeStamp* inputTime,
    215                               AudioBufferList* outputData,
    216                               const AudioTimeStamp* outputTime,
    217                               void* clientData);
    218 
    219  static OSStatus outConverterProc(
    220      AudioConverterRef audioConverter,
    221      UInt32* numberDataPackets,
    222      AudioBufferList* data,
    223      AudioStreamPacketDescription** dataPacketDescription,
    224      void* userData);
    225 
    226  static OSStatus inDeviceIOProc(AudioDeviceID device,
    227                                 const AudioTimeStamp* now,
    228                                 const AudioBufferList* inputData,
    229                                 const AudioTimeStamp* inputTime,
    230                                 AudioBufferList* outputData,
    231                                 const AudioTimeStamp* outputTime,
    232                                 void* clientData);
    233 
    234  static OSStatus inConverterProc(
    235      AudioConverterRef audioConverter,
    236      UInt32* numberDataPackets,
    237      AudioBufferList* data,
    238      AudioStreamPacketDescription** dataPacketDescription,
    239      void* inUserData);
    240 
    241  OSStatus implDeviceIOProc(const AudioBufferList* inputData,
    242                            const AudioTimeStamp* inputTime,
    243                            AudioBufferList* outputData,
    244                            const AudioTimeStamp* outputTime)
    245      RTC_LOCKS_EXCLUDED(mutex_);
    246 
    247  OSStatus implOutConverterProc(UInt32* numberDataPackets,
    248                                AudioBufferList* data);
    249 
    250  OSStatus implInDeviceIOProc(const AudioBufferList* inputData,
    251                              const AudioTimeStamp* inputTime)
    252      RTC_LOCKS_EXCLUDED(mutex_);
    253 
    254  OSStatus implInConverterProc(UInt32* numberDataPackets,
    255                               AudioBufferList* data);
    256 
    257  static void RunCapture(void*);
    258  static void RunRender(void*);
    259  bool CaptureWorkerThread();
    260  bool RenderWorkerThread();
    261 
    262  bool KeyPressed();
    263 
    264  AudioDeviceBuffer* _ptrAudioBuffer;
    265 
    266  Mutex mutex_;
    267 
    268  Event _stopEventRec;
    269  Event _stopEvent;
    270 
    271  // Only valid/running between calls to StartRecording and StopRecording.
    272  PlatformThread capture_worker_thread_;
    273 
    274  // Only valid/running between calls to StartPlayout and StopPlayout.
    275  PlatformThread render_worker_thread_;
    276 
    277  AudioMixerManagerMac _mixerManager;
    278 
    279  uint16_t _inputDeviceIndex;
    280  uint16_t _outputDeviceIndex;
    281  AudioDeviceID _inputDeviceID;
    282  AudioDeviceID _outputDeviceID;
    283  AudioDeviceIOProcID _inDeviceIOProcID;
    284  AudioDeviceIOProcID _deviceIOProcID;
    285  bool _inputDeviceIsSpecified;
    286  bool _outputDeviceIsSpecified;
    287 
    288  uint8_t _recChannels;
    289  uint8_t _playChannels;
    290 
    291  Float32* _captureBufData;
    292  SInt16* _renderBufData;
    293 
    294  SInt16 _renderConvertData[PLAY_BUF_SIZE_IN_SAMPLES];
    295 
    296  bool _initialized;
    297  bool _isShutDown;
    298  bool _recording;
    299  bool _playing;
    300  bool _recIsInitialized;
    301  bool _playIsInitialized;
    302 
    303  // Atomically set varaibles
    304  std::atomic<int32_t> _renderDeviceIsAlive;
    305  std::atomic<int32_t> _captureDeviceIsAlive;
    306 
    307  bool _twoDevices;
    308  bool _doStop;  // For play if not shared device or play+rec if shared device
    309  bool _doStopRec;  // For rec if not shared device
    310  bool _macBookPro;
    311  bool _macBookProPanRight;
    312 
    313  AudioConverterRef _captureConverter;
    314  AudioConverterRef _renderConverter;
    315 
    316  AudioStreamBasicDescription _outStreamFormat;
    317  AudioStreamBasicDescription _outDesiredFormat;
    318  AudioStreamBasicDescription _inStreamFormat;
    319  AudioStreamBasicDescription _inDesiredFormat;
    320 
    321  uint32_t _captureLatencyUs;
    322  uint32_t _renderLatencyUs;
    323 
    324  // Atomically set variables
    325  mutable std::atomic<int32_t> _captureDelayUs;
    326  mutable std::atomic<int32_t> _renderDelayUs;
    327 
    328  int32_t _renderDelayOffsetSamples;
    329 
    330  PaUtilRingBuffer* _paCaptureBuffer;
    331  PaUtilRingBuffer* _paRenderBuffer;
    332 
    333  semaphore_t _renderSemaphore;
    334  semaphore_t _captureSemaphore;
    335 
    336  int _captureBufSizeSamples;
    337  int _renderBufSizeSamples;
    338 
    339  // Typing detection
    340  // 0x5c is key "9", after that comes function keys.
    341  bool prev_key_state_[0x5d];
    342 };
    343 
    344 }  // namespace webrtc
    345 
    346 #endif  // MODULES_AUDIO_DEVICE_MAIN_SOURCE_MAC_AUDIO_DEVICE_MAC_H_