// Copyright (c) 2011 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. #ifndef MEDIA_AUDIO_MAC_AUDIO_OUTPUT_MAC_H_ #define MEDIA_AUDIO_MAC_AUDIO_OUTPUT_MAC_H_ #include <AudioToolbox/AudioFormat.h> #include <AudioToolbox/AudioQueue.h> #include <AudioUnit/AudioUnit.h> #include "base/synchronization/lock.h" #include "media/audio/audio_io.h" #include "media/audio/audio_parameters.h" class AudioManagerMac; // Implementation of AudioOuputStream for Mac OS X using the audio queue service // present in OS 10.5 and later. Audioqueue is the successor to the SoundManager // services but it is supported in 64 bits. class PCMQueueOutAudioOutputStream : public AudioOutputStream { public: // The ctor takes all the usual parameters, plus |manager| which is the // the audio manager who is creating this object. PCMQueueOutAudioOutputStream(AudioManagerMac* manager, const AudioParameters& params); // The dtor is typically called by the AudioManager only and it is usually // triggered by calling AudioOutputStream::Close(). virtual ~PCMQueueOutAudioOutputStream(); // Implementation of AudioOutputStream. virtual bool Open(); virtual void Close(); virtual void Start(AudioSourceCallback* callback); virtual void Stop(); virtual void SetVolume(double volume); virtual void GetVolume(double* volume); private: // The audio is double buffered. static const uint32 kNumBuffers = 2; static const int kEmptyChannel = -1; // Reorder PCM from source layout to device layout found in Core Audio. template<class Format> void SwizzleLayout(Format* b, uint32 filled); // Check and move channels if surround sound layout needs adjusted. bool CheckForAdjustedLayout(Channels input_channel, Channels output_channel); // The OS calls back here when an audio buffer has been processed. static void RenderCallback(void* p_this, AudioQueueRef queue, AudioQueueBufferRef buffer); // Called when an error occurs. void HandleError(OSStatus err); // Atomic operations for setting/getting the source callback. void SetSource(AudioSourceCallback* source); AudioSourceCallback* GetSource(); // Structure that holds the stream format details such as bitrate. AudioStreamBasicDescription format_; // Handle to the OS audio queue object. AudioQueueRef audio_queue_; // Array of pointers to the OS managed audio buffers. AudioQueueBufferRef buffer_[kNumBuffers]; // Mutex for the |source_| to implment atomic set and get. // It is important to NOT wait on any other locks while this is held. base::Lock source_lock_; // Pointer to the object that will provide the audio samples. AudioSourceCallback* source_; // Our creator, the audio manager needs to be notified when we close. AudioManagerMac* manager_; // Packet size in bytes. uint32 packet_size_; // Number of bytes for making a silence buffer. int silence_bytes_; // Volume level from 0 to 1. float volume_; // Number of bytes yet to be played in audio buffer. uint32 pending_bytes_; // Number of channels in the source audio. int num_source_channels_; // Source's channel layout for surround sound channels. ChannelLayout source_layout_; // Device's channel layout. int core_channel_orderings_[CHANNELS_MAX]; // An array for remapping source to device channel layouts during a swizzle. int channel_remap_[CHANNELS_MAX]; // Number of channels in device layout. int num_core_channels_; // A flag to determine if swizzle is needed from source to device layouts. bool should_swizzle_; // A flag to determine if downmix is needed from source to device layouts. bool should_down_mix_; DISALLOW_COPY_AND_ASSIGN(PCMQueueOutAudioOutputStream); }; #endif // MEDIA_AUDIO_MAC_AUDIO_OUTPUT_MAC_H_