- add sources.
[platform/framework/web/crosswalk.git] / src / media / audio / mac / audio_auhal_mac.h
1 // Copyright 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 //
5 // Implementation notes:
6 //
7 // - It is recommended to first acquire the native sample rate of the default
8 //   output device and then use the same rate when creating this object.
9 //   Use AudioManagerMac::HardwareSampleRate() to retrieve the sample rate.
10 // - Calling Close() also leads to self destruction.
11 // - The latency consists of two parts:
12 //   1) Hardware latency, which includes Audio Unit latency, audio device
13 //      latency;
14 //   2) The delay between the moment getting the callback and the scheduled time
15 //      stamp that tells when the data is going to be played out.
16 //
17 #ifndef MEDIA_AUDIO_MAC_AUDIO_AUHAL_MAC_H_
18 #define MEDIA_AUDIO_MAC_AUDIO_AUHAL_MAC_H_
19
20 #include <AudioUnit/AudioUnit.h>
21 #include <CoreAudio/CoreAudio.h>
22
23 #include "base/compiler_specific.h"
24 #include "base/synchronization/lock.h"
25 #include "media/audio/audio_io.h"
26 #include "media/audio/audio_parameters.h"
27
28 namespace media {
29
30 class AudioManagerMac;
31
32 // Implementation of AudioOuputStream for Mac OS X using the
33 // AUHAL Audio Unit present in OS 10.4 and later.
34 // It is useful for low-latency output with optional synchronized
35 // input.
36 //
37 // Overview of operation:
38 // 1) An object of AUHALStream is created by the AudioManager
39 // factory: audio_man->MakeAudioStream().
40 // 2) Next some thread will call Open(), at that point the underlying
41 // AUHAL Audio Unit is created and configured to use the |device|.
42 // 3) Then some thread will call Start(source).
43 // Then the AUHAL is started which creates its own thread which
44 // periodically will call the source for more data as buffers are being
45 // consumed.
46 // 4) At some point some thread will call Stop(), which we handle by directly
47 // stopping the default output Audio Unit.
48 // 6) The same thread that called stop will call Close() where we cleanup
49 // and notify the audio manager, which likely will destroy this object.
50
51 class AUHALStream : public AudioOutputStream {
52  public:
53   // |manager| creates this object.
54   // |device| is the CoreAudio device to use for the stream.
55   // It will often be the default output device.
56   AUHALStream(AudioManagerMac* manager,
57               const AudioParameters& params,
58               AudioDeviceID device);
59   // The dtor is typically called by the AudioManager only and it is usually
60   // triggered by calling AudioOutputStream::Close().
61   virtual ~AUHALStream();
62
63   // Implementation of AudioOutputStream.
64   virtual bool Open() OVERRIDE;
65   virtual void Close() OVERRIDE;
66   virtual void Start(AudioSourceCallback* callback) OVERRIDE;
67   virtual void Stop() OVERRIDE;
68   virtual void SetVolume(double volume) OVERRIDE;
69   virtual void GetVolume(double* volume) OVERRIDE;
70
71  private:
72   // AUHAL callback.
73   static OSStatus InputProc(void* user_data,
74                             AudioUnitRenderActionFlags* flags,
75                             const AudioTimeStamp* time_stamp,
76                             UInt32 bus_number,
77                             UInt32 number_of_frames,
78                             AudioBufferList* io_data);
79
80   OSStatus Render(AudioUnitRenderActionFlags* flags,
81                   const AudioTimeStamp* output_time_stamp,
82                   UInt32 bus_number,
83                   UInt32 number_of_frames,
84                   AudioBufferList* io_data);
85
86   // Helper method to enable input and output.
87   bool EnableIO(bool enable, UInt32 scope);
88
89   // Sets the stream format on the AUHAL to PCM Float32 non-interleaved
90   // for the given number of channels on the given scope and element.
91   // The created stream description will be stored in |desc|.
92   bool SetStreamFormat(AudioStreamBasicDescription* desc,
93                        int channels,
94                        UInt32 scope,
95                        UInt32 element);
96
97   // Creates the AUHAL, sets its stream format, buffer-size, etc.
98   bool ConfigureAUHAL();
99
100   // Creates the input and output busses.
101   void CreateIOBusses();
102
103   // Gets the fixed playout device hardware latency and stores it. Returns 0
104   // if not available.
105   double GetHardwareLatency();
106
107   // Gets the current playout latency value.
108   double GetPlayoutLatency(const AudioTimeStamp* output_time_stamp);
109
110   // Our creator, the audio manager needs to be notified when we close.
111   AudioManagerMac* manager_;
112
113   AudioParameters params_;
114   // For convenience - same as in params_.
115   int input_channels_;
116   int output_channels_;
117
118   // Buffer-size.
119   size_t number_of_frames_;
120
121   // Pointer to the object that will provide the audio samples.
122   AudioSourceCallback* source_;
123
124   // Protects |source_|.  Necessary since Render() calls seem to be in flight
125   // when |audio_unit_| is supposedly stopped.  See http://crbug.com/178765.
126   base::Lock source_lock_;
127
128   // Holds the stream format details such as bitrate.
129   AudioStreamBasicDescription input_format_;
130   AudioStreamBasicDescription output_format_;
131
132   // The audio device to use with the AUHAL.
133   // We can potentially handle both input and output with this device.
134   AudioDeviceID device_;
135
136   // The AUHAL Audio Unit which talks to |device_|.
137   AudioUnit audio_unit_;
138
139   // Volume level from 0 to 1.
140   float volume_;
141
142   // Fixed playout hardware latency in frames.
143   double hardware_latency_frames_;
144
145   // The flag used to stop the streaming.
146   bool stopped_;
147
148   // The flag used to indicate if the AudioManager has been notified of a
149   // potential device change.  Reset to false during Start().
150   bool notified_for_possible_device_change_;
151
152   // The input AudioUnit renders its data here.
153   scoped_ptr<uint8[]> input_buffer_list_storage_;
154   AudioBufferList* input_buffer_list_;
155
156   // Holds the actual data for |input_buffer_list_|.
157   scoped_ptr<AudioBus> input_bus_;
158
159   // Container for retrieving data from AudioSourceCallback::OnMoreIOData().
160   scoped_ptr<AudioBus> output_bus_;
161
162   DISALLOW_COPY_AND_ASSIGN(AUHALStream);
163 };
164
165 }  // namespace media
166
167 #endif  // MEDIA_AUDIO_MAC_AUDIO_AUHAL_MAC_H_