Home | History | Annotate | Download | only in mac
      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 WEBRTC_AUDIO_DEVICE_AUDIO_DEVICE_MAC_H
     12 #define WEBRTC_AUDIO_DEVICE_AUDIO_DEVICE_MAC_H
     13 
     14 #include "webrtc/modules/audio_device/audio_device_generic.h"
     15 #include "webrtc/modules/audio_device/mac/audio_mixer_manager_mac.h"
     16 #include "webrtc/system_wrappers/interface/critical_section_wrapper.h"
     17 
     18 #include <AudioToolbox/AudioConverter.h>
     19 #include <CoreAudio/CoreAudio.h>
     20 #include <mach/semaphore.h>
     21 
     22 struct PaUtilRingBuffer;
     23 
     24 namespace webrtc
     25 {
     26 class EventWrapper;
     27 class ThreadWrapper;
     28 
     29 const uint32_t N_REC_SAMPLES_PER_SEC = 48000;
     30 const uint32_t N_PLAY_SAMPLES_PER_SEC = 48000;
     31 
     32 const uint32_t N_REC_CHANNELS = 1; // default is mono recording
     33 const uint32_t N_PLAY_CHANNELS = 2; // default is stereo playout
     34 const uint32_t N_DEVICE_CHANNELS = 64;
     35 
     36 const uint32_t ENGINE_REC_BUF_SIZE_IN_SAMPLES = (N_REC_SAMPLES_PER_SEC / 100);
     37 const uint32_t ENGINE_PLAY_BUF_SIZE_IN_SAMPLES = (N_PLAY_SAMPLES_PER_SEC / 100);
     38 
     39 const int N_BLOCKS_IO = 2;
     40 const int N_BUFFERS_IN = 2;  // Must be at least N_BLOCKS_IO.
     41 const int N_BUFFERS_OUT = 3;  // Must be at least N_BLOCKS_IO.
     42 
     43 const uint32_t TIMER_PERIOD_MS = (2 * 10 * N_BLOCKS_IO * 1000000);
     44 
     45 const uint32_t REC_BUF_SIZE_IN_SAMPLES =
     46     ENGINE_REC_BUF_SIZE_IN_SAMPLES * N_DEVICE_CHANNELS * N_BUFFERS_IN;
     47 const uint32_t PLAY_BUF_SIZE_IN_SAMPLES =
     48     ENGINE_PLAY_BUF_SIZE_IN_SAMPLES * N_PLAY_CHANNELS * N_BUFFERS_OUT;
     49 
     50 class AudioDeviceMac: public AudioDeviceGeneric
     51 {
     52 public:
     53     AudioDeviceMac(const int32_t id);
     54     ~AudioDeviceMac();
     55 
     56     // Retrieve the currently utilized audio layer
     57     virtual int32_t
     58         ActiveAudioLayer(AudioDeviceModule::AudioLayer& audioLayer) const;
     59 
     60     // Main initializaton and termination
     61     virtual int32_t Init();
     62     virtual int32_t Terminate();
     63     virtual bool Initialized() const;
     64 
     65     // Device enumeration
     66     virtual int16_t PlayoutDevices();
     67     virtual int16_t RecordingDevices();
     68     virtual int32_t PlayoutDeviceName(
     69         uint16_t index,
     70         char name[kAdmMaxDeviceNameSize],
     71         char guid[kAdmMaxGuidSize]);
     72     virtual int32_t RecordingDeviceName(
     73         uint16_t index,
     74         char name[kAdmMaxDeviceNameSize],
     75         char guid[kAdmMaxGuidSize]);
     76 
     77     // Device selection
     78     virtual int32_t SetPlayoutDevice(uint16_t index);
     79     virtual int32_t SetPlayoutDevice(
     80         AudioDeviceModule::WindowsDeviceType device);
     81     virtual int32_t SetRecordingDevice(uint16_t index);
     82     virtual int32_t SetRecordingDevice(
     83         AudioDeviceModule::WindowsDeviceType device);
     84 
     85     // Audio transport initialization
     86     virtual int32_t PlayoutIsAvailable(bool& available);
     87     virtual int32_t InitPlayout();
     88     virtual bool PlayoutIsInitialized() const;
     89     virtual int32_t RecordingIsAvailable(bool& available);
     90     virtual int32_t InitRecording();
     91     virtual bool RecordingIsInitialized() const;
     92 
     93     // Audio transport control
     94     virtual int32_t StartPlayout();
     95     virtual int32_t StopPlayout();
     96     virtual bool Playing() const;
     97     virtual int32_t StartRecording();
     98     virtual int32_t StopRecording();
     99     virtual bool Recording() const;
    100 
    101     // Microphone Automatic Gain Control (AGC)
    102     virtual int32_t SetAGC(bool enable);
    103     virtual bool AGC() const;
    104 
    105     // Volume control based on the Windows Wave API (Windows only)
    106     virtual int32_t SetWaveOutVolume(uint16_t volumeLeft, uint16_t volumeRight);
    107     virtual int32_t WaveOutVolume(uint16_t& volumeLeft,
    108                                   uint16_t& volumeRight) const;
    109 
    110     // Audio mixer initialization
    111     virtual int32_t InitSpeaker();
    112     virtual bool SpeakerIsInitialized() const;
    113     virtual int32_t InitMicrophone();
    114     virtual bool MicrophoneIsInitialized() const;
    115 
    116     // Speaker volume controls
    117     virtual int32_t SpeakerVolumeIsAvailable(bool& available);
    118     virtual int32_t SetSpeakerVolume(uint32_t volume);
    119     virtual int32_t SpeakerVolume(uint32_t& volume) const;
    120     virtual int32_t MaxSpeakerVolume(uint32_t& maxVolume) const;
    121     virtual int32_t MinSpeakerVolume(uint32_t& minVolume) const;
    122     virtual int32_t SpeakerVolumeStepSize(uint16_t& stepSize) const;
    123 
    124     // Microphone volume controls
    125     virtual int32_t MicrophoneVolumeIsAvailable(bool& available);
    126     virtual int32_t SetMicrophoneVolume(uint32_t volume);
    127     virtual int32_t MicrophoneVolume(uint32_t& volume) const;
    128     virtual int32_t MaxMicrophoneVolume(uint32_t& maxVolume) const;
    129     virtual int32_t MinMicrophoneVolume(uint32_t& minVolume) const;
    130     virtual int32_t
    131         MicrophoneVolumeStepSize(uint16_t& stepSize) const;
    132 
    133     // Microphone mute control
    134     virtual int32_t MicrophoneMuteIsAvailable(bool& available);
    135     virtual int32_t SetMicrophoneMute(bool enable);
    136     virtual int32_t MicrophoneMute(bool& enabled) const;
    137 
    138     // Speaker mute control
    139     virtual int32_t SpeakerMuteIsAvailable(bool& available);
    140     virtual int32_t SetSpeakerMute(bool enable);
    141     virtual int32_t SpeakerMute(bool& enabled) const;
    142 
    143     // Microphone boost control
    144     virtual int32_t MicrophoneBoostIsAvailable(bool& available);
    145     virtual int32_t SetMicrophoneBoost(bool enable);
    146     virtual int32_t MicrophoneBoost(bool& enabled) const;
    147 
    148     // Stereo support
    149     virtual int32_t StereoPlayoutIsAvailable(bool& available);
    150     virtual int32_t SetStereoPlayout(bool enable);
    151     virtual int32_t StereoPlayout(bool& enabled) const;
    152     virtual int32_t StereoRecordingIsAvailable(bool& available);
    153     virtual int32_t SetStereoRecording(bool enable);
    154     virtual int32_t StereoRecording(bool& enabled) const;
    155 
    156     // Delay information and control
    157     virtual int32_t
    158         SetPlayoutBuffer(const AudioDeviceModule::BufferType type,
    159                          uint16_t sizeMS);
    160     virtual int32_t PlayoutBuffer(AudioDeviceModule::BufferType& type,
    161                                   uint16_t& sizeMS) const;
    162     virtual int32_t PlayoutDelay(uint16_t& delayMS) const;
    163     virtual int32_t RecordingDelay(uint16_t& delayMS) const;
    164 
    165     // CPU load
    166     virtual int32_t CPULoad(uint16_t& load) const;
    167 
    168     virtual bool PlayoutWarning() const;
    169     virtual bool PlayoutError() const;
    170     virtual bool RecordingWarning() const;
    171     virtual bool RecordingError() const;
    172     virtual void ClearPlayoutWarning();
    173     virtual void ClearPlayoutError();
    174     virtual void ClearRecordingWarning();
    175     virtual void ClearRecordingError();
    176 
    177     virtual void AttachAudioBuffer(AudioDeviceBuffer* audioBuffer);
    178 
    179 private:
    180     virtual int32_t MicrophoneIsAvailable(bool& available);
    181     virtual int32_t SpeakerIsAvailable(bool& available);
    182 
    183     void Lock()
    184     {
    185         _critSect.Enter();
    186     }
    187     ;
    188     void UnLock()
    189     {
    190         _critSect.Leave();
    191     }
    192     ;
    193     int32_t Id()
    194     {
    195         return _id;
    196     }
    197 
    198     static void AtomicSet32(int32_t* theValue, int32_t newValue);
    199     static int32_t AtomicGet32(int32_t* theValue);
    200 
    201     static void logCAMsg(const TraceLevel level,
    202                          const TraceModule module,
    203                          const int32_t id, const char *msg,
    204                          const char *err);
    205 
    206     int32_t GetNumberDevices(const AudioObjectPropertyScope scope,
    207                              AudioDeviceID scopedDeviceIds[],
    208                              const uint32_t deviceListLength);
    209 
    210     int32_t GetDeviceName(const AudioObjectPropertyScope scope,
    211                           const uint16_t index, char* name);
    212 
    213     int32_t InitDevice(uint16_t userDeviceIndex,
    214                        AudioDeviceID& deviceId, bool isInput);
    215 
    216     static OSStatus
    217         objectListenerProc(AudioObjectID objectId, UInt32 numberAddresses,
    218                            const AudioObjectPropertyAddress addresses[],
    219                            void* clientData);
    220 
    221     OSStatus
    222         implObjectListenerProc(AudioObjectID objectId, UInt32 numberAddresses,
    223                                const AudioObjectPropertyAddress addresses[]);
    224 
    225     int32_t HandleDeviceChange();
    226 
    227     int32_t
    228         HandleStreamFormatChange(AudioObjectID objectId,
    229                                  AudioObjectPropertyAddress propertyAddress);
    230 
    231     int32_t
    232         HandleDataSourceChange(AudioObjectID objectId,
    233                                AudioObjectPropertyAddress propertyAddress);
    234 
    235     int32_t
    236         HandleProcessorOverload(AudioObjectPropertyAddress propertyAddress);
    237 
    238     static OSStatus deviceIOProc(AudioDeviceID device,
    239                                  const AudioTimeStamp *now,
    240                                  const AudioBufferList *inputData,
    241                                  const AudioTimeStamp *inputTime,
    242                                  AudioBufferList *outputData,
    243                                  const AudioTimeStamp* outputTime,
    244                                  void *clientData);
    245 
    246     static OSStatus
    247         outConverterProc(AudioConverterRef audioConverter,
    248                          UInt32 *numberDataPackets, AudioBufferList *data,
    249                          AudioStreamPacketDescription **dataPacketDescription,
    250                          void *userData);
    251 
    252     static OSStatus inDeviceIOProc(AudioDeviceID device,
    253                                    const AudioTimeStamp *now,
    254                                    const AudioBufferList *inputData,
    255                                    const AudioTimeStamp *inputTime,
    256                                    AudioBufferList *outputData,
    257                                    const AudioTimeStamp *outputTime,
    258                                    void *clientData);
    259 
    260     static OSStatus
    261         inConverterProc(AudioConverterRef audioConverter,
    262                         UInt32 *numberDataPackets, AudioBufferList *data,
    263                         AudioStreamPacketDescription **dataPacketDescription,
    264                         void *inUserData);
    265 
    266     OSStatus implDeviceIOProc(const AudioBufferList *inputData,
    267                               const AudioTimeStamp *inputTime,
    268                               AudioBufferList *outputData,
    269                               const AudioTimeStamp *outputTime);
    270 
    271     OSStatus implOutConverterProc(UInt32 *numberDataPackets,
    272                                   AudioBufferList *data);
    273 
    274     OSStatus implInDeviceIOProc(const AudioBufferList *inputData,
    275                                 const AudioTimeStamp *inputTime);
    276 
    277     OSStatus implInConverterProc(UInt32 *numberDataPackets,
    278                                  AudioBufferList *data);
    279 
    280     static bool RunCapture(void*);
    281     static bool RunRender(void*);
    282     bool CaptureWorkerThread();
    283     bool RenderWorkerThread();
    284 
    285     bool KeyPressed();
    286 
    287     AudioDeviceBuffer* _ptrAudioBuffer;
    288 
    289     CriticalSectionWrapper& _critSect;
    290 
    291     EventWrapper& _stopEventRec;
    292     EventWrapper& _stopEvent;
    293 
    294     ThreadWrapper* _captureWorkerThread;
    295     ThreadWrapper* _renderWorkerThread;
    296     uint32_t _captureWorkerThreadId;
    297     uint32_t _renderWorkerThreadId;
    298 
    299     int32_t _id;
    300 
    301     AudioMixerManagerMac _mixerManager;
    302 
    303     uint16_t _inputDeviceIndex;
    304     uint16_t _outputDeviceIndex;
    305     AudioDeviceID _inputDeviceID;
    306     AudioDeviceID _outputDeviceID;
    307 #if __MAC_OS_X_VERSION_MAX_ALLOWED >= 1050
    308     AudioDeviceIOProcID _inDeviceIOProcID;
    309     AudioDeviceIOProcID _deviceIOProcID;
    310 #endif
    311     bool _inputDeviceIsSpecified;
    312     bool _outputDeviceIsSpecified;
    313 
    314     uint8_t _recChannels;
    315     uint8_t _playChannels;
    316 
    317     Float32* _captureBufData;
    318     SInt16* _renderBufData;
    319 
    320     SInt16 _renderConvertData[PLAY_BUF_SIZE_IN_SAMPLES];
    321 
    322     AudioDeviceModule::BufferType _playBufType;
    323 
    324     bool _initialized;
    325     bool _isShutDown;
    326     bool _recording;
    327     bool _playing;
    328     bool _recIsInitialized;
    329     bool _playIsInitialized;
    330     bool _AGC;
    331 
    332     // Atomically set varaibles
    333     int32_t _renderDeviceIsAlive;
    334     int32_t _captureDeviceIsAlive;
    335 
    336     bool _twoDevices;
    337     bool _doStop; // For play if not shared device or play+rec if shared device
    338     bool _doStopRec; // For rec if not shared device
    339     bool _macBookPro;
    340     bool _macBookProPanRight;
    341 
    342     AudioConverterRef _captureConverter;
    343     AudioConverterRef _renderConverter;
    344 
    345     AudioStreamBasicDescription _outStreamFormat;
    346     AudioStreamBasicDescription _outDesiredFormat;
    347     AudioStreamBasicDescription _inStreamFormat;
    348     AudioStreamBasicDescription _inDesiredFormat;
    349 
    350     uint32_t _captureLatencyUs;
    351     uint32_t _renderLatencyUs;
    352 
    353     // Atomically set variables
    354     mutable int32_t _captureDelayUs;
    355     mutable int32_t _renderDelayUs;
    356 
    357     int32_t _renderDelayOffsetSamples;
    358 
    359     uint16_t _playBufDelayFixed; // fixed playback delay
    360 
    361     uint16_t _playWarning;
    362     uint16_t _playError;
    363     uint16_t _recWarning;
    364     uint16_t _recError;
    365 
    366     PaUtilRingBuffer* _paCaptureBuffer;
    367     PaUtilRingBuffer* _paRenderBuffer;
    368 
    369     semaphore_t _renderSemaphore;
    370     semaphore_t _captureSemaphore;
    371 
    372     int _captureBufSizeSamples;
    373     int _renderBufSizeSamples;
    374 
    375     // Typing detection
    376     // 0x5c is key "9", after that comes function keys.
    377     bool prev_key_state_[0x5d];
    378 };
    379 
    380 }  // namespace webrtc
    381 
    382 #endif  // MODULES_AUDIO_DEVICE_MAIN_SOURCE_MAC_AUDIO_DEVICE_MAC_H_
    383