Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(41)

Side by Side Diff: media/audio/win/audio_low_latency_output_win.h

Issue 10823100: Adds support for multi-channel output audio for the low-latency path in Windows. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 8 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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
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 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
230 240
231 // Issues the OnError() callback to the |sink_|. 241 // Issues the OnError() callback to the |sink_|.
232 void HandleError(HRESULT err); 242 void HandleError(HRESULT err);
233 243
234 // The Open() method is divided into these sub methods. 244 // The Open() method is divided into these sub methods.
235 HRESULT SetRenderDevice(); 245 HRESULT SetRenderDevice();
236 HRESULT ActivateRenderDevice(); 246 HRESULT ActivateRenderDevice();
237 bool DesiredFormatIsSupported(); 247 bool DesiredFormatIsSupported();
238 HRESULT InitializeAudioEngine(); 248 HRESULT InitializeAudioEngine();
239 249
250 // Retrieves the stream format that the audio engine uses for its internal
251 // processing/mixing of shared-mode streams.
252 static HRESULT GetMixFormat(ERole device_role, WAVEFORMATEX** device_format);
scherkus (not reviewing) 2012/08/01 00:14:05 any reason static private methods need to be here?
henrika (OOO until Aug 14) 2012/08/01 16:11:09 Great input, thanks. I actually did use private me
scherkus (not reviewing) 2012/08/02 00:41:57 Above the function.
253
240 // Called when the device will be opened in shared mode and use the 254 // Called when the device will be opened in shared mode and use the
241 // internal audio engine's mix format. 255 // internal audio engine's mix format.
242 HRESULT SharedModeInitialization(); 256 HRESULT SharedModeInitialization();
243 257
244 // Called when the device will be opened in exclusive mode and use the 258 // Called when the device will be opened in exclusive mode and use the
245 // application specified format. 259 // application specified format.
246 HRESULT ExclusiveModeInitialization(); 260 HRESULT ExclusiveModeInitialization();
247 261
248 // Converts unique endpoint ID to user-friendly device name. 262 // Converts unique endpoint ID to user-friendly device name.
249 std::string GetDeviceName(LPCWSTR device_id) const; 263 std::string GetDeviceName(LPCWSTR device_id) const;
250 264
251 // Called on the audio render thread when the current audio stream must 265 // Called on the audio render thread when the current audio stream must
252 // be re-initialized because the default audio device has changed. This 266 // be re-initialized because the default audio device has changed. This
253 // method: stops the current renderer, releases and re-creates all WASAPI 267 // method: stops the current renderer, releases and re-creates all WASAPI
254 // interfaces, creates a new IMMDevice and re-starts rendering using the 268 // interfaces, creates a new IMMDevice and re-starts rendering using the
255 // new default audio device. 269 // new default audio device.
256 bool RestartRenderingUsingNewDefaultDevice(); 270 bool RestartRenderingUsingNewDefaultDevice();
257 271
272 // Retrieves an integer mask which corresponds to the channel layout the
273 // audio engine uses for its internal processing/mixing of shared-mode
274 // streams. This mask indicates which channels are present in the multi-
275 // channel stream. The least significant bit corresponds with the Front Left
276 // speaker, the next least significant bit corresponds to the Front Right
277 // speaker, and so on, continuing in the order defined in KsMedia.h.
278 // See http://msdn.microsoft.com/en-us/library/windows/hardware/ff537083(v=vs. 85).aspx
279 // for more details.
280 static uint32 ChannelConfig();
tommi (sloooow) - chröme 2012/07/31 21:39:30 Maybe we could define our own type for channel con
henrika (OOO until Aug 14) 2012/08/01 16:11:09 Added typedef ChannelConfigMask in media. Got conf
281
282 // Converts Microsoft's channel configuration to Chrome's ChannelLayout.
283 // This mapping is not perfect but the best we can do given the current
284 // ChannelLayout enumerator and the Windows-specific speaker configurations
285 // defined in ksmedia.h. Don't assume that the channel ordering in
286 // ChannelLayout is exactly the same as the Windows specific configuration.
287 // As an example: KSAUDIO_SPEAKER_7POINT1_SURROUND is mapped to
288 // CHANNEL_LAYOUT_7_1 but the positions of Back L, Back R and Side L, Side R
289 // speakers are different in these two definitions.
290 static ChannelLayout ChannelConfigToChromeChannelLayout(uint32 layout);
291
258 AUDCLNT_SHAREMODE share_mode() const { return share_mode_; } 292 AUDCLNT_SHAREMODE share_mode() const { return share_mode_; }
293 int endpoint_channel_count() const { return endpoint_channel_count_; }
scherkus (not reviewing) 2012/08/01 00:14:05 huh? these are all private methods -- why the acce
henrika (OOO until Aug 14) 2012/08/01 16:11:09 Got it. Will clean up.
294 uint32 endpoint_channel_config() const { return endpoint_channel_config_; }
295 int client_channel_count() const {
296 return client_audio_parameters_.channels();
297 }
259 298
260 // Initializes the COM library for use by the calling thread and sets the 299 // Initializes the COM library for use by the calling thread and sets the
261 // thread's concurrency model to multi-threaded. 300 // thread's concurrency model to multi-threaded.
262 base::win::ScopedCOMInitializer com_init_; 301 base::win::ScopedCOMInitializer com_init_;
263 302
264 // Contains the thread ID of the creating thread. 303 // Contains the thread ID of the creating thread.
265 base::PlatformThreadId creating_thread_id_; 304 base::PlatformThreadId creating_thread_id_;
266 305
267 // Our creator, the audio manager needs to be notified when we close. 306 // Our creator, the audio manager needs to be notified when we close.
268 AudioManagerWin* manager_; 307 AudioManagerWin* manager_;
269 308
309 AudioParameters client_audio_parameters_;
tommi (sloooow) - chröme 2012/07/31 21:39:30 are there any other audio parameters that this cla
henrika (OOO until Aug 14) 2012/08/01 16:11:09 I store this one to keep track of the parameters s
310
270 // Rendering is driven by this thread (which has no message loop). 311 // Rendering is driven by this thread (which has no message loop).
271 // All OnMoreData() callbacks will be called from this thread. 312 // All OnMoreData() callbacks will be called from this thread.
272 base::DelegateSimpleThread* render_thread_; 313 base::DelegateSimpleThread* render_thread_;
273 314
274 // Contains the desired audio format which is set up at construction. 315 // Contains the desired audio format which is set up at construction.
275 WAVEFORMATEX format_; 316 // Extended PCM waveform format structure based on WAVEFORMATEXTENSIBLE.
317 // Use this for multiple channel and hi-resolution PCM data.
318 WAVEFORMATPCMEX format_;
276 319
277 // Copy of the audio format which we know the audio engine supports. 320 // 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 321 // It is recommended to ensure that the sample rate in |format_| is identical
279 // to the sample rate in |audio_engine_mix_format_|. 322 // to the sample rate in |audio_engine_mix_format_|.
280 base::win::ScopedCoMem<WAVEFORMATEX> audio_engine_mix_format_; 323 base::win::ScopedCoMem<WAVEFORMATPCMEX> audio_engine_mix_format_;
281 324
282 bool opened_; 325 bool opened_;
283 bool started_; 326 bool started_;
284 327
285 // Set to true as soon as a new default device is detected, and cleared when 328 // 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. 329 // 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 330 // All additional device detections during an active state are ignored to
288 // ensure that the ongoing switch can finalize without disruptions. 331 // ensure that the ongoing switch can finalize without disruptions.
289 bool restart_rendering_mode_; 332 bool restart_rendering_mode_;
290 333
(...skipping 18 matching lines...) Expand all
309 size_t endpoint_buffer_size_frames_; 352 size_t endpoint_buffer_size_frames_;
310 353
311 // Defines the role that the system has assigned to an audio endpoint device. 354 // Defines the role that the system has assigned to an audio endpoint device.
312 ERole device_role_; 355 ERole device_role_;
313 356
314 // The sharing mode for the connection. 357 // The sharing mode for the connection.
315 // Valid values are AUDCLNT_SHAREMODE_SHARED and AUDCLNT_SHAREMODE_EXCLUSIVE 358 // Valid values are AUDCLNT_SHAREMODE_SHARED and AUDCLNT_SHAREMODE_EXCLUSIVE
316 // where AUDCLNT_SHAREMODE_SHARED is the default. 359 // where AUDCLNT_SHAREMODE_SHARED is the default.
317 AUDCLNT_SHAREMODE share_mode_; 360 AUDCLNT_SHAREMODE share_mode_;
318 361
362 // Contains the number of channels the audio engine uses for its internal
363 // processing/mixing of shared-mode streams for the default endpoint device.
364 const int endpoint_channel_count_;
365
366 // Contains the channel configuration the audio engine uses for its internal
367 // processing/mixing of shared-mode streams for the default endpoint
368 // device.
369 const uint32 endpoint_channel_config_;
370
371 // TODO(henrika): add comments....
372 int channel_factor_;
373
319 // Counts the number of audio frames written to the endpoint buffer. 374 // Counts the number of audio frames written to the endpoint buffer.
320 UINT64 num_written_frames_; 375 UINT64 num_written_frames_;
321 376
322 // Pointer to the client that will deliver audio samples to be played out. 377 // Pointer to the client that will deliver audio samples to be played out.
323 AudioSourceCallback* source_; 378 AudioSourceCallback* source_;
324 379
325 // An IMMDeviceEnumerator interface which represents a device enumerator. 380 // An IMMDeviceEnumerator interface which represents a device enumerator.
326 base::win::ScopedComPtr<IMMDeviceEnumerator> device_enumerator_; 381 base::win::ScopedComPtr<IMMDeviceEnumerator> device_enumerator_;
327 382
328 // An IMMDevice interface which represents an audio endpoint device. 383 // An IMMDevice interface which represents an audio endpoint device.
(...skipping 16 matching lines...) Expand all
345 400
346 // This event will be signaled when stream switching shall take place. 401 // This event will be signaled when stream switching shall take place.
347 base::win::ScopedHandle stream_switch_event_; 402 base::win::ScopedHandle stream_switch_event_;
348 403
349 DISALLOW_COPY_AND_ASSIGN(WASAPIAudioOutputStream); 404 DISALLOW_COPY_AND_ASSIGN(WASAPIAudioOutputStream);
350 }; 405 };
351 406
352 } // namespace media 407 } // namespace media
353 408
354 #endif // MEDIA_AUDIO_WIN_AUDIO_LOW_LATENCY_OUTPUT_WIN_H_ 409 #endif // MEDIA_AUDIO_WIN_AUDIO_LOW_LATENCY_OUTPUT_WIN_H_
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698