#ifndef MEDIA_AUDIO_MAC_AUDIO_MANAGER_MAC_H_
#define MEDIA_AUDIO_MAC_AUDIO_MANAGER_MAC_H_
#include <AudioUnit/AudioUnit.h>
#include <CoreAudio/AudioHardware.h>
#include <stddef.h>
#include <list>
#include <map>
#include <memory>
#include <string>
#include "base/compiler_specific.h"
#include "base/memory/weak_ptr.h"
#include "media/audio/apple/audio_auhal.h"
#include "media/audio/apple/audio_manager_apple.h"
#include "media/audio/audio_manager_base.h"
#include "media/audio/mac/audio_device_listener_mac.h"
#include "third_party/abseil-cpp/absl/container/flat_hash_set.h"
namespace base {
namespace apple {
class ScopedObjCClassSwizzler;
}
}
namespace media {
class AUAudioInputStream;
class AUHALStream;
class MEDIA_EXPORT AudioManagerMac : public AudioManagerApple {
public:
AudioManagerMac(std::unique_ptr<AudioThread> audio_thread,
AudioLogFactory* audio_log_factory);
AudioManagerMac(const AudioManagerMac&) = delete;
AudioManagerMac& operator=(const AudioManagerMac&) = delete;
~AudioManagerMac() override;
bool HasAudioOutputDevices() override;
bool HasAudioInputDevices() override;
void GetAudioInputDeviceNames(AudioDeviceNames* device_names) override;
void GetAudioOutputDeviceNames(AudioDeviceNames* device_names) override;
AudioParameters GetInputStreamParameters(
const std::string& device_id) override;
std::string GetAssociatedOutputDeviceID(
const std::string& input_device_id) override;
const std::string_view GetName() override;
AudioOutputStream* MakeLinearOutputStream(
const AudioParameters& params,
const LogCallback& log_callback) override;
AudioOutputStream* MakeLowLatencyOutputStream(
const AudioParameters& params,
const std::string& device_id,
const LogCallback& log_callback) override;
AudioInputStream* MakeLinearInputStream(
const AudioParameters& params,
const std::string& device_id,
const LogCallback& log_callback) override;
AudioInputStream* MakeLowLatencyInputStream(
const AudioParameters& params,
const std::string& device_id,
const LogCallback& log_callback) override;
std::string GetDefaultInputDeviceID() override;
std::string GetDefaultOutputDeviceID() override;
void ReleaseOutputStream(AudioOutputStream* stream) override;
void ReleaseInputStream(AudioInputStream* stream) override;
bool MaybeChangeBufferSize(AudioDeviceID device_id,
AudioUnit audio_unit,
AudioUnitElement element,
size_t desired_buffer_size) override;
base::TimeDelta GetDeferStreamStartTimeout() const override;
void StopAmplitudePeakTrace() override;
double GetMaxInputVolume(AudioDeviceID device_id) override;
void SetInputVolume(AudioDeviceID device_id, double volume) override;
double GetInputVolume(AudioDeviceID device_id) override;
bool IsInputMuted(AudioDeviceID device_id) override;
int HardwareSampleRateForDevice(AudioDeviceID device_id) override;
OSStatus GetInputDeviceStreamFormat(
AudioUnit audio_unit,
AudioStreamBasicDescription* input_format) override;
static bool GetDefaultInputDevice(AudioDeviceID* input_device);
static bool GetDefaultOutputDevice(AudioDeviceID* output_device);
static AudioDeviceID GetAudioDeviceIdByUId(bool is_input,
const std::string& device_id);
static AudioDeviceID FindFirstOutputSubdevice(
AudioDeviceID aggregate_device_id);
static int GetMinAudioBufferSizeMacOS(int min_buffer_size, int sample_rate);
std::vector<AudioObjectID> GetRelatedDeviceIDs(AudioObjectID device_id);
enum { kStartDelayInSecsForPowerEvents = 5 };
bool ShouldDeferStreamStart() const override;
bool IsOnBatteryPower() const;
size_t GetNumberOfResumeNotifications() const;
bool IsSuspending() const;
size_t output_streams() const { return output_streams_.size(); }
size_t low_latency_input_streams() const {
return low_latency_input_streams_.size();
}
size_t basic_input_streams() const { return basic_input_streams_.size(); }
bool DeviceSupportsAmbientNoiseReduction(AudioDeviceID device_id) override;
bool SuppressNoiseReduction(AudioDeviceID device_id) override;
void UnsuppressNoiseReduction(AudioDeviceID device_id) override;
protected:
AudioParameters GetPreferredOutputStreamParameters(
const std::string& output_device_id,
const AudioParameters& input_params) override;
std::vector<AudioObjectID> GetRelatedBluetoothDeviceIDs(
AudioObjectID device_id);
virtual std::vector<AudioObjectID> GetAllAudioDeviceIDs();
virtual std::vector<AudioObjectID> GetRelatedNonBluetoothDeviceIDs(
AudioObjectID device_id);
virtual std::optional<std::string> GetDeviceUniqueID(AudioObjectID device_id);
virtual std::optional<uint32_t> GetDeviceTransportType(
AudioObjectID device_id);
void ShutdownOnAudioThread() override;
private:
void InitializeOnAudioThread();
int ChooseBufferSize(bool is_input, int sample_rate);
void HandleDeviceChanges();
static bool IsVolumeSettableOnChannel(AudioDeviceID device_id, int channel);
static int GetNumberOfChannelsForDevice(AudioDeviceID device_id);
std::string GetDefaultDeviceID(bool is_input);
std::unique_ptr<AudioDeviceListenerMac> output_device_listener_;
int current_sample_rate_;
AudioDeviceID current_output_device_;
class AudioPowerObserver;
std::unique_ptr<AudioPowerObserver> power_observer_;
absl::flat_hash_set<AudioInputStream*> basic_input_streams_;
absl::flat_hash_set<AUAudioInputStream*> low_latency_input_streams_;
absl::flat_hash_set<AUHALStream*> output_streams_;
std::unique_ptr<base::apple::ScopedObjCClassSwizzler>
screen_capture_kit_swizzler_;
bool in_shutdown_;
struct NoiseReductionState {
enum State { DISABLED, ENABLED };
State initial_state = DISABLED;
int suppression_count = 0;
};
std::map<AudioDeviceID, NoiseReductionState> device_noise_reduction_states_;
base::WeakPtrFactory<AudioManagerMac> weak_ptr_factory_;
};
}
#endif