Report errors from ChromiumEnv::GetChildren in Posix.
[chromium-blink-merge.git] / media / audio / mac / audio_synchronized_mac.h
bloba6db48e3037d8ee53e72106cdba96adad0018047
1 // Copyright (c) 2012 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.
5 #ifndef MEDIA_AUDIO_MAC_AUDIO_SYNCHRONIZED_MAC_H_
6 #define MEDIA_AUDIO_MAC_AUDIO_SYNCHRONIZED_MAC_H_
8 #include <AudioToolbox/AudioToolbox.h>
9 #include <AudioUnit/AudioUnit.h>
10 #include <CoreAudio/CoreAudio.h>
12 #include "base/compiler_specific.h"
13 #include "base/synchronization/lock.h"
14 #include "media/audio/audio_io.h"
15 #include "media/audio/audio_parameters.h"
16 #include "media/base/audio_bus.h"
17 #include "media/base/audio_fifo.h"
19 namespace media {
21 class AudioManagerMac;
22 class ChannelMixer;
24 // AudioSynchronizedStream allows arbitrary combinations of input and output
25 // devices running off different clocks and using different drivers, with
26 // potentially differing sample-rates. It implements AudioOutputStream
27 // and shuttles its synchronized I/O data using AudioSourceCallback.
29 // It is required to first acquire the native sample rate of the selected
30 // output device and then use the same rate when creating this object.
32 // ............................................................................
33 // Theory of Operation:
34 // .
35 // INPUT THREAD . OUTPUT THREAD
36 // +-----------------+ +------+ .
37 // | Input AudioUnit | --> | | .
38 // +-----------------+ | | .
39 // | FIFO | .
40 // | | +-----------+
41 // | | -----> | Varispeed |
42 // | | +-----------+
43 // +------+ . |
44 // . | +-----------+
45 // . OnMoreIOData() --> | Output AU |
46 // . +-----------+
48 // The input AudioUnit's InputProc is called on one thread which feeds the
49 // FIFO. The output AudioUnit's OutputProc is called on a second thread
50 // which pulls on the varispeed to get the current input data. The varispeed
51 // handles mismatches between input and output sample-rate and also clock drift
52 // between the input and output drivers. The varispeed consumes its data from
53 // the FIFO and adjusts its rate dynamically according to the amount
54 // of data buffered in the FIFO. If the FIFO starts getting too much data
55 // buffered then the varispeed will speed up slightly to compensate
56 // and similarly if the FIFO doesn't have enough data buffered then the
57 // varispeed will slow down slightly.
59 // Finally, once the input data is available then OnMoreIOData() is called
60 // which is given this input, and renders the output which is finally sent
61 // to the Output AudioUnit.
62 class AudioSynchronizedStream : public AudioOutputStream {
63 public:
64 // The ctor takes all the usual parameters, plus |manager| which is the
65 // the audio manager who is creating this object.
66 AudioSynchronizedStream(AudioManagerMac* manager,
67 const AudioParameters& params,
68 AudioDeviceID input_id,
69 AudioDeviceID output_id);
71 virtual ~AudioSynchronizedStream();
73 // Implementation of AudioOutputStream.
74 virtual bool Open() OVERRIDE;
75 virtual void Close() OVERRIDE;
76 virtual void Start(AudioSourceCallback* callback) OVERRIDE;
77 virtual void Stop() OVERRIDE;
79 virtual void SetVolume(double volume) OVERRIDE;
80 virtual void GetVolume(double* volume) OVERRIDE;
82 OSStatus SetInputDeviceAsCurrent(AudioDeviceID input_id);
83 OSStatus SetOutputDeviceAsCurrent(AudioDeviceID output_id);
84 AudioDeviceID GetInputDeviceID() { return input_info_.id_; }
85 AudioDeviceID GetOutputDeviceID() { return output_info_.id_; }
87 bool IsRunning();
89 private:
90 // Initialization.
91 OSStatus CreateAudioUnits();
92 OSStatus SetupInput(AudioDeviceID input_id);
93 OSStatus EnableIO();
94 OSStatus SetupOutput(AudioDeviceID output_id);
95 OSStatus SetupCallbacks();
96 OSStatus SetupStreamFormats();
97 void AllocateInputData();
99 // Handlers for the AudioUnit callbacks.
100 OSStatus HandleInputCallback(AudioUnitRenderActionFlags* io_action_flags,
101 const AudioTimeStamp* time_stamp,
102 UInt32 bus_number,
103 UInt32 number_of_frames,
104 AudioBufferList* io_data);
106 OSStatus HandleVarispeedCallback(AudioUnitRenderActionFlags* io_action_flags,
107 const AudioTimeStamp* time_stamp,
108 UInt32 bus_number,
109 UInt32 number_of_frames,
110 AudioBufferList* io_data);
112 OSStatus HandleOutputCallback(AudioUnitRenderActionFlags* io_action_flags,
113 const AudioTimeStamp* time_stamp,
114 UInt32 bus_number,
115 UInt32 number_of_frames,
116 AudioBufferList* io_data);
118 // AudioUnit callbacks.
119 static OSStatus InputProc(void* user_data,
120 AudioUnitRenderActionFlags* io_action_flags,
121 const AudioTimeStamp* time_stamp,
122 UInt32 bus_number,
123 UInt32 number_of_frames,
124 AudioBufferList* io_data);
126 static OSStatus VarispeedProc(void* user_data,
127 AudioUnitRenderActionFlags* io_action_flags,
128 const AudioTimeStamp* time_stamp,
129 UInt32 bus_number,
130 UInt32 number_of_frames,
131 AudioBufferList* io_data);
133 static OSStatus OutputProc(void* user_data,
134 AudioUnitRenderActionFlags* io_action_flags,
135 const AudioTimeStamp* time_stamp,
136 UInt32 bus_number,
137 UInt32 number_of_frames,
138 AudioBufferList* io_data);
140 // Our creator.
141 AudioManagerMac* manager_;
143 // Client parameters.
144 AudioParameters params_;
146 double input_sample_rate_;
147 double output_sample_rate_;
149 // Pointer to the object that will provide the audio samples.
150 AudioSourceCallback* source_;
152 // Values used in Open().
153 AudioDeviceID input_id_;
154 AudioDeviceID output_id_;
156 // The input AudioUnit renders its data here.
157 AudioBufferList* input_buffer_list_;
159 // Holds the actual data for |input_buffer_list_|.
160 scoped_ptr<AudioBus> input_bus_;
162 // Used to overlay AudioBufferLists.
163 scoped_ptr<AudioBus> wrapper_bus_;
165 class AudioDeviceInfo {
166 public:
167 AudioDeviceInfo()
168 : id_(kAudioDeviceUnknown),
169 is_input_(false),
170 buffer_size_frames_(0) {}
171 void Initialize(AudioDeviceID inID, bool isInput);
172 bool IsInitialized() const { return id_ != kAudioDeviceUnknown; }
174 AudioDeviceID id_;
175 bool is_input_;
176 UInt32 buffer_size_frames_;
179 AudioDeviceInfo input_info_;
180 AudioDeviceInfo output_info_;
182 // Used for input to output buffering.
183 AudioFifo fifo_;
185 // The optimal number of frames we'd like to keep in the FIFO at all times.
186 int target_fifo_frames_;
188 // A running average of the measured delta between actual number of frames
189 // in the FIFO versus |target_fifo_frames_|.
190 double average_delta_;
192 // A varispeed rate scalar which is calculated based on FIFO drift.
193 double fifo_rate_compensation_;
195 // AudioUnits.
196 AudioUnit input_unit_;
197 AudioUnit varispeed_unit_;
198 AudioUnit output_unit_;
200 double first_input_time_;
202 bool is_running_;
203 int hardware_buffer_size_;
204 int channels_;
206 // Channel mixer used to transform mono to stereo data. It is only created
207 // if the input_hardware_channels is mono.
208 scoped_ptr<ChannelMixer> channel_mixer_;
209 scoped_ptr<AudioBus> mixer_bus_;
211 DISALLOW_COPY_AND_ASSIGN(AudioSynchronizedStream);
214 } // namespace media
216 #endif // MEDIA_AUDIO_MAC_AUDIO_SYNCHRONIZED_MAC_H_