Mailbox support for texture layers.
[chromium-blink-merge.git] / media / audio / mac / audio_synchronized_mac.h
blobe99d9c8dc469fa6e066b53dbed277d0199a3e8cf
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;
23 // AudioSynchronizedStream allows arbitrary combinations of input and output
24 // devices running off different clocks and using different drivers, with
25 // potentially differing sample-rates. It implements AudioOutputStream
26 // and shuttles its synchronized I/O data using AudioSourceCallback.
28 // It is required to first acquire the native sample rate of the selected
29 // output device and then use the same rate when creating this object.
31 // ............................................................................
32 // Theory of Operation:
33 // .
34 // INPUT THREAD . OUTPUT THREAD
35 // +-----------------+ +------+ .
36 // | Input AudioUnit | --> | | .
37 // +-----------------+ | | .
38 // | FIFO | .
39 // | | +-----------+
40 // | | -----> | Varispeed |
41 // | | +-----------+
42 // +------+ . |
43 // . | +-----------+
44 // . OnMoreIOData() --> | Output AU |
45 // . +-----------+
47 // The input AudioUnit's InputProc is called on one thread which feeds the
48 // FIFO. The output AudioUnit's OutputProc is called on a second thread
49 // which pulls on the varispeed to get the current input data. The varispeed
50 // handles mismatches between input and output sample-rate and also clock drift
51 // between the input and output drivers. The varispeed consumes its data from
52 // the FIFO and adjusts its rate dynamically according to the amount
53 // of data buffered in the FIFO. If the FIFO starts getting too much data
54 // buffered then the varispeed will speed up slightly to compensate
55 // and similarly if the FIFO doesn't have enough data buffered then the
56 // varispeed will slow down slightly.
58 // Finally, once the input data is available then OnMoreIOData() is called
59 // which is given this input, and renders the output which is finally sent
60 // to the Output AudioUnit.
61 class AudioSynchronizedStream : public AudioOutputStream {
62 public:
63 // The ctor takes all the usual parameters, plus |manager| which is the
64 // the audio manager who is creating this object.
65 AudioSynchronizedStream(AudioManagerMac* manager,
66 const AudioParameters& params,
67 AudioDeviceID input_id,
68 AudioDeviceID output_id);
70 virtual ~AudioSynchronizedStream();
72 // Implementation of AudioOutputStream.
73 virtual bool Open() OVERRIDE;
74 virtual void Close() OVERRIDE;
75 virtual void Start(AudioSourceCallback* callback) OVERRIDE;
76 virtual void Stop() OVERRIDE;
78 virtual void SetVolume(double volume) OVERRIDE;
79 virtual void GetVolume(double* volume) OVERRIDE;
81 OSStatus SetInputDeviceAsCurrent(AudioDeviceID input_id);
82 OSStatus SetOutputDeviceAsCurrent(AudioDeviceID output_id);
83 AudioDeviceID GetInputDeviceID() { return input_info_.id_; }
84 AudioDeviceID GetOutputDeviceID() { return output_info_.id_; }
86 bool IsRunning();
88 private:
89 // Initialization.
90 OSStatus CreateAudioUnits();
91 OSStatus SetupInput(AudioDeviceID input_id);
92 OSStatus EnableIO();
93 OSStatus SetupOutput(AudioDeviceID output_id);
94 OSStatus SetupCallbacks();
95 OSStatus SetupStreamFormats();
96 void AllocateInputData();
98 // Handlers for the AudioUnit callbacks.
99 OSStatus HandleInputCallback(AudioUnitRenderActionFlags* io_action_flags,
100 const AudioTimeStamp* time_stamp,
101 UInt32 bus_number,
102 UInt32 number_of_frames,
103 AudioBufferList* io_data);
105 OSStatus HandleVarispeedCallback(AudioUnitRenderActionFlags* io_action_flags,
106 const AudioTimeStamp* time_stamp,
107 UInt32 bus_number,
108 UInt32 number_of_frames,
109 AudioBufferList* io_data);
111 OSStatus HandleOutputCallback(AudioUnitRenderActionFlags* io_action_flags,
112 const AudioTimeStamp* time_stamp,
113 UInt32 bus_number,
114 UInt32 number_of_frames,
115 AudioBufferList* io_data);
117 // AudioUnit callbacks.
118 static OSStatus InputProc(void* user_data,
119 AudioUnitRenderActionFlags* io_action_flags,
120 const AudioTimeStamp* time_stamp,
121 UInt32 bus_number,
122 UInt32 number_of_frames,
123 AudioBufferList* io_data);
125 static OSStatus VarispeedProc(void* user_data,
126 AudioUnitRenderActionFlags* io_action_flags,
127 const AudioTimeStamp* time_stamp,
128 UInt32 bus_number,
129 UInt32 number_of_frames,
130 AudioBufferList* io_data);
132 static OSStatus OutputProc(void* user_data,
133 AudioUnitRenderActionFlags* io_action_flags,
134 const AudioTimeStamp* time_stamp,
135 UInt32 bus_number,
136 UInt32 number_of_frames,
137 AudioBufferList* io_data);
139 // Our creator.
140 AudioManagerMac* manager_;
142 // Client parameters.
143 AudioParameters params_;
145 double input_sample_rate_;
146 double output_sample_rate_;
148 // Pointer to the object that will provide the audio samples.
149 AudioSourceCallback* source_;
151 // Values used in Open().
152 AudioDeviceID input_id_;
153 AudioDeviceID output_id_;
155 // The input AudioUnit renders its data here.
156 AudioBufferList* input_buffer_list_;
158 // Holds the actual data for |input_buffer_list_|.
159 scoped_ptr<AudioBus> input_bus_;
161 // Used to overlay AudioBufferLists.
162 scoped_ptr<AudioBus> wrapper_bus_;
164 class AudioDeviceInfo {
165 public:
166 AudioDeviceInfo()
167 : id_(kAudioDeviceUnknown),
168 is_input_(false),
169 buffer_size_frames_(0) {}
170 void Initialize(AudioDeviceID inID, bool isInput);
171 bool IsInitialized() const { return id_ != kAudioDeviceUnknown; }
173 AudioDeviceID id_;
174 bool is_input_;
175 UInt32 buffer_size_frames_;
178 AudioDeviceInfo input_info_;
179 AudioDeviceInfo output_info_;
181 // Used for input to output buffering.
182 AudioFifo fifo_;
184 // The optimal number of frames we'd like to keep in the FIFO at all times.
185 int target_fifo_frames_;
187 // A running average of the measured delta between actual number of frames
188 // in the FIFO versus |target_fifo_frames_|.
189 double average_delta_;
191 // A varispeed rate scalar which is calculated based on FIFO drift.
192 double fifo_rate_compensation_;
194 // AudioUnits.
195 AudioUnit input_unit_;
196 AudioUnit varispeed_unit_;
197 AudioUnit output_unit_;
199 double first_input_time_;
201 bool is_running_;
202 int hardware_buffer_size_;
203 int channels_;
205 DISALLOW_COPY_AND_ASSIGN(AudioSynchronizedStream);
208 } // namespace media
210 #endif // MEDIA_AUDIO_MAC_AUDIO_SYNCHRONIZED_MAC_H_