OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 // | 4 // |
5 // Implementation of AudioOutputStream for Windows using Windows Core Audio | 5 // Implementation of AudioOutputStream for Windows using Windows Core Audio |
6 // WASAPI for low latency rendering. | 6 // WASAPI for low latency rendering. |
7 // | 7 // |
8 // Overview of operation and performance: | 8 // Overview of operation and performance: |
9 // | 9 // |
10 // - An object of WASAPIAudioOutputStream is created by the AudioManager | 10 // - An object of WASAPIAudioOutputStream is created by the AudioManager |
(...skipping 164 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
175 virtual ~WASAPIAudioOutputStream(); | 175 virtual ~WASAPIAudioOutputStream(); |
176 | 176 |
177 // Implementation of AudioOutputStream. | 177 // Implementation of AudioOutputStream. |
178 virtual bool Open() OVERRIDE; | 178 virtual bool Open() OVERRIDE; |
179 virtual void Start(AudioSourceCallback* callback) OVERRIDE; | 179 virtual void Start(AudioSourceCallback* callback) OVERRIDE; |
180 virtual void Stop() OVERRIDE; | 180 virtual void Stop() OVERRIDE; |
181 virtual void Close() OVERRIDE; | 181 virtual void Close() OVERRIDE; |
182 virtual void SetVolume(double volume) OVERRIDE; | 182 virtual void SetVolume(double volume) OVERRIDE; |
183 virtual void GetVolume(double* volume) OVERRIDE; | 183 virtual void GetVolume(double* volume) OVERRIDE; |
184 | 184 |
185 // Retrieves the stream format that the audio engine uses for its internal | 185 // Retrieves the number of channels the audio engine uses for its internal |
186 // processing/mixing of shared-mode streams. | 186 // processing/mixing of shared-mode streams for the default endpoint device. |
187 // This method should not be used in combination with exclusive-mode streams. | 187 static int HardwareChannelCount(); |
| 188 |
| 189 // Retrieves the channel layout the audio engine uses for its internal |
| 190 // processing/mixing of shared-mode streams for the default endpoint device. |
| 191 // Note that we convert an internal channel layout mask (see ChannelMask()) |
| 192 // into a Chrome-specific channel layout enumerator in this method, hence |
| 193 // the match might not be perfect. |
| 194 static ChannelLayout HardwareChannelLayout(); |
| 195 |
| 196 // Retrieves the sample rate the audio engine uses for its internal |
| 197 // processing/mixing of shared-mode streams for the default endpoint device. |
188 static int HardwareSampleRate(ERole device_role); | 198 static int HardwareSampleRate(ERole device_role); |
189 | 199 |
190 // Returns AUDCLNT_SHAREMODE_EXCLUSIVE if --enable-exclusive-mode is used | 200 // Returns AUDCLNT_SHAREMODE_EXCLUSIVE if --enable-exclusive-mode is used |
191 // as command-line flag and AUDCLNT_SHAREMODE_SHARED otherwise (default). | 201 // as command-line flag and AUDCLNT_SHAREMODE_SHARED otherwise (default). |
192 static AUDCLNT_SHAREMODE GetShareMode(); | 202 static AUDCLNT_SHAREMODE GetShareMode(); |
193 | 203 |
194 bool started() const { return started_; } | 204 bool started() const { return started_; } |
195 | 205 |
196 private: | 206 private: |
197 // Implementation of IUnknown (trivial in this case). See | 207 // Implementation of IUnknown (trivial in this case). See |
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
248 // Converts unique endpoint ID to user-friendly device name. | 258 // Converts unique endpoint ID to user-friendly device name. |
249 std::string GetDeviceName(LPCWSTR device_id) const; | 259 std::string GetDeviceName(LPCWSTR device_id) const; |
250 | 260 |
251 // Called on the audio render thread when the current audio stream must | 261 // Called on the audio render thread when the current audio stream must |
252 // be re-initialized because the default audio device has changed. This | 262 // be re-initialized because the default audio device has changed. This |
253 // method: stops the current renderer, releases and re-creates all WASAPI | 263 // method: stops the current renderer, releases and re-creates all WASAPI |
254 // interfaces, creates a new IMMDevice and re-starts rendering using the | 264 // interfaces, creates a new IMMDevice and re-starts rendering using the |
255 // new default audio device. | 265 // new default audio device. |
256 bool RestartRenderingUsingNewDefaultDevice(); | 266 bool RestartRenderingUsingNewDefaultDevice(); |
257 | 267 |
258 AUDCLNT_SHAREMODE share_mode() const { return share_mode_; } | 268 // Returns the number of channels the audio engine uses for its internal |
| 269 // processing/mixing of shared-mode streams for the default endpoint device. |
| 270 int endpoint_channel_count() { return format_.Format.nChannels; } |
| 271 |
| 272 // TODO(henrika): add comments... |
| 273 int channel_factor() const { |
| 274 return (format_.Format.nChannels / client_channel_count_); |
| 275 } |
259 | 276 |
260 // Initializes the COM library for use by the calling thread and sets the | 277 // Initializes the COM library for use by the calling thread and sets the |
261 // thread's concurrency model to multi-threaded. | 278 // thread's concurrency model to multi-threaded. |
262 base::win::ScopedCOMInitializer com_init_; | 279 base::win::ScopedCOMInitializer com_init_; |
263 | 280 |
264 // Contains the thread ID of the creating thread. | 281 // Contains the thread ID of the creating thread. |
265 base::PlatformThreadId creating_thread_id_; | 282 base::PlatformThreadId creating_thread_id_; |
266 | 283 |
267 // Our creator, the audio manager needs to be notified when we close. | 284 // Our creator, the audio manager needs to be notified when we close. |
268 AudioManagerWin* manager_; | 285 AudioManagerWin* manager_; |
269 | 286 |
270 // Rendering is driven by this thread (which has no message loop). | 287 // Rendering is driven by this thread (which has no message loop). |
271 // All OnMoreData() callbacks will be called from this thread. | 288 // All OnMoreData() callbacks will be called from this thread. |
272 base::DelegateSimpleThread* render_thread_; | 289 base::DelegateSimpleThread* render_thread_; |
273 | 290 |
274 // Contains the desired audio format which is set up at construction. | 291 // Contains the desired audio format which is set up at construction. |
275 WAVEFORMATEX format_; | 292 // Extended PCM waveform format structure based on WAVEFORMATEXTENSIBLE. |
| 293 // Use this for multiple channel and hi-resolution PCM data. |
| 294 WAVEFORMATPCMEX format_; |
276 | 295 |
277 // Copy of the audio format which we know the audio engine supports. | 296 // Copy of the audio format which we know the audio engine supports. |
278 // It is recommended to ensure that the sample rate in |format_| is identical | 297 // It is recommended to ensure that the sample rate in |format_| is identical |
279 // to the sample rate in |audio_engine_mix_format_|. | 298 // to the sample rate in |audio_engine_mix_format_|. |
280 base::win::ScopedCoMem<WAVEFORMATEX> audio_engine_mix_format_; | 299 base::win::ScopedCoMem<WAVEFORMATPCMEX> audio_engine_mix_format_; |
281 | 300 |
282 bool opened_; | 301 bool opened_; |
283 bool started_; | 302 bool started_; |
284 | 303 |
285 // Set to true as soon as a new default device is detected, and cleared when | 304 // Set to true as soon as a new default device is detected, and cleared when |
286 // the streaming has switched from using the old device to the new device. | 305 // the streaming has switched from using the old device to the new device. |
287 // All additional device detections during an active state are ignored to | 306 // All additional device detections during an active state are ignored to |
288 // ensure that the ongoing switch can finalize without disruptions. | 307 // ensure that the ongoing switch can finalize without disruptions. |
289 bool restart_rendering_mode_; | 308 bool restart_rendering_mode_; |
290 | 309 |
(...skipping 18 matching lines...) Expand all Loading... |
309 size_t endpoint_buffer_size_frames_; | 328 size_t endpoint_buffer_size_frames_; |
310 | 329 |
311 // Defines the role that the system has assigned to an audio endpoint device. | 330 // Defines the role that the system has assigned to an audio endpoint device. |
312 ERole device_role_; | 331 ERole device_role_; |
313 | 332 |
314 // The sharing mode for the connection. | 333 // The sharing mode for the connection. |
315 // Valid values are AUDCLNT_SHAREMODE_SHARED and AUDCLNT_SHAREMODE_EXCLUSIVE | 334 // Valid values are AUDCLNT_SHAREMODE_SHARED and AUDCLNT_SHAREMODE_EXCLUSIVE |
316 // where AUDCLNT_SHAREMODE_SHARED is the default. | 335 // where AUDCLNT_SHAREMODE_SHARED is the default. |
317 AUDCLNT_SHAREMODE share_mode_; | 336 AUDCLNT_SHAREMODE share_mode_; |
318 | 337 |
| 338 // TODO(henrika): add comments... |
| 339 int client_channel_count_; |
| 340 |
319 // Counts the number of audio frames written to the endpoint buffer. | 341 // Counts the number of audio frames written to the endpoint buffer. |
320 UINT64 num_written_frames_; | 342 UINT64 num_written_frames_; |
321 | 343 |
322 // Pointer to the client that will deliver audio samples to be played out. | 344 // Pointer to the client that will deliver audio samples to be played out. |
323 AudioSourceCallback* source_; | 345 AudioSourceCallback* source_; |
324 | 346 |
325 // An IMMDeviceEnumerator interface which represents a device enumerator. | 347 // An IMMDeviceEnumerator interface which represents a device enumerator. |
326 base::win::ScopedComPtr<IMMDeviceEnumerator> device_enumerator_; | 348 base::win::ScopedComPtr<IMMDeviceEnumerator> device_enumerator_; |
327 | 349 |
328 // An IMMDevice interface which represents an audio endpoint device. | 350 // An IMMDevice interface which represents an audio endpoint device. |
(...skipping 16 matching lines...) Expand all Loading... |
345 | 367 |
346 // This event will be signaled when stream switching shall take place. | 368 // This event will be signaled when stream switching shall take place. |
347 base::win::ScopedHandle stream_switch_event_; | 369 base::win::ScopedHandle stream_switch_event_; |
348 | 370 |
349 DISALLOW_COPY_AND_ASSIGN(WASAPIAudioOutputStream); | 371 DISALLOW_COPY_AND_ASSIGN(WASAPIAudioOutputStream); |
350 }; | 372 }; |
351 | 373 |
352 } // namespace media | 374 } // namespace media |
353 | 375 |
354 #endif // MEDIA_AUDIO_WIN_AUDIO_LOW_LATENCY_OUTPUT_WIN_H_ | 376 #endif // MEDIA_AUDIO_WIN_AUDIO_LOW_LATENCY_OUTPUT_WIN_H_ |
OLD | NEW |