summaryrefslogtreecommitdiffstats
path: root/media
diff options
context:
space:
mode:
authorfbarchard@chromium.org <fbarchard@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-10-18 18:25:07 +0000
committerfbarchard@chromium.org <fbarchard@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-10-18 18:25:07 +0000
commit5cc00db3c77d58478ed1d2e96c226dfbfdd0d0a2 (patch)
tree893485e8e4d8b2a433cae5043a52cb5640b5a9a9 /media
parent4244aaa63f14fbfbc4fb9df6a9d3703f00ecef77 (diff)
downloadchromium_src-5cc00db3c77d58478ed1d2e96c226dfbfdd0d0a2.zip
chromium_src-5cc00db3c77d58478ed1d2e96c226dfbfdd0d0a2.tar.gz
chromium_src-5cc00db3c77d58478ed1d2e96c226dfbfdd0d0a2.tar.bz2
add wave out extensible support for 5.1 surround sound
BUG=25315 TEST=play 5.1 audio and it should come out all 6 speakers, not downmixed to stereo. Review URL: http://codereview.chromium.org/3772009 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@62954 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'media')
-rw-r--r--media/audio/win/waveout_output_win.cc49
-rw-r--r--media/audio/win/waveout_output_win.h5
2 files changed, 36 insertions, 18 deletions
diff --git a/media/audio/win/waveout_output_win.cc b/media/audio/win/waveout_output_win.cc
index 03da37d..0865477 100644
--- a/media/audio/win/waveout_output_win.cc
+++ b/media/audio/win/waveout_output_win.cc
@@ -55,14 +55,28 @@ PCMWaveOutAudioOutputStream::PCMWaveOutAudioOutputStream(
volume_(1),
channels_(params.channels),
pending_bytes_(0) {
- format_.wFormatTag = WAVE_FORMAT_PCM;
- format_.nChannels = params.channels > 2 ? 2 : params.channels;
- format_.nSamplesPerSec = params.sample_rate;
- format_.wBitsPerSample = params.bits_per_sample;
- format_.cbSize = 0;
+ format_.Format.wFormatTag = WAVE_FORMAT_EXTENSIBLE;
+ format_.Format.nChannels = params.channels;
+ format_.Format.nSamplesPerSec = params.sample_rate;
+ format_.Format.wBitsPerSample = params.bits_per_sample;
+ format_.Format.cbSize = sizeof(format_) - sizeof(WAVEFORMATEX);
// The next are computed from above.
- format_.nBlockAlign = (format_.nChannels * format_.wBitsPerSample) / 8;
- format_.nAvgBytesPerSec = format_.nBlockAlign * format_.nSamplesPerSec;
+ format_.Format.nBlockAlign = (format_.Format.nChannels *
+ format_.Format.wBitsPerSample) / 8;
+ format_.Format.nAvgBytesPerSec = format_.Format.nBlockAlign *
+ format_.Format.nSamplesPerSec;
+ // This mask handles Stereo, 5.1 and 7.1.
+ // TODO(fbarchard): Support masks for other channel layouts.
+ format_.dwChannelMask = SPEAKER_FRONT_LEFT |
+ SPEAKER_FRONT_RIGHT |
+ SPEAKER_FRONT_CENTER |
+ SPEAKER_LOW_FREQUENCY |
+ SPEAKER_BACK_LEFT |
+ SPEAKER_BACK_RIGHT |
+ SPEAKER_SIDE_LEFT |
+ SPEAKER_SIDE_RIGHT;
+ format_.SubFormat = KSDATAFORMAT_SUBTYPE_PCM;
+ format_.Samples.wValidBitsPerSample = params.bits_per_sample;
// The event is auto-reset.
stopped_event_.Set(::CreateEventW(NULL, FALSE, FALSE, NULL));
}
@@ -78,9 +92,10 @@ bool PCMWaveOutAudioOutputStream::Open(uint32 buffer_size) {
return false;
if (num_buffers_ < 2 || num_buffers_ > 5)
return false;
- // Open the device. We'll be getting callback in WaveCallback function. They
- // occur in a magic, time-critical thread that windows creates.
- MMRESULT result = ::waveOutOpen(&waveout_, device_id_, &format_,
+ // Open the device. We'll be getting callback in WaveCallback function.
+ // They occur in a magic, time-critical thread that windows creates.
+ MMRESULT result = ::waveOutOpen(&waveout_, device_id_,
+ reinterpret_cast<LPCWAVEFORMATEX>(&format_),
reinterpret_cast<DWORD_PTR>(WaveCallback),
reinterpret_cast<DWORD_PTR>(this),
CALLBACK_FUNCTION);
@@ -88,7 +103,7 @@ bool PCMWaveOutAudioOutputStream::Open(uint32 buffer_size) {
return false;
// If we don't have a packet size we use 100ms.
if (!buffer_size)
- buffer_size = format_.nAvgBytesPerSec / 10;
+ buffer_size = format_.Format.nAvgBytesPerSec / 10;
SetupBuffers(buffer_size);
buffer_size_ = buffer_size;
@@ -235,20 +250,22 @@ void PCMWaveOutAudioOutputStream::QueueNextPacket(WAVEHDR *buffer) {
// If we are down sampling to a smaller number of channels, we need to
// scale up the amount of pending bytes.
// TODO(fbarchard): Handle used 0 by queueing more.
- uint32 scaled_pending_bytes = pending_bytes_ * channels_ / format_.nChannels;
+ uint32 scaled_pending_bytes = pending_bytes_ * channels_ /
+ format_.Format.nChannels;
// TODO(sergeyu): Specify correct hardware delay for AudioBuffersState.
uint32 used = callback_->OnMoreData(
this, reinterpret_cast<uint8*>(buffer->lpData), buffer_size_,
AudioBuffersState(scaled_pending_bytes, 0));
if (used <= buffer_size_) {
- buffer->dwBufferLength = used * format_.nChannels / channels_;
- if (channels_ > 2 && format_.nChannels == 2) {
+ buffer->dwBufferLength = used * format_.Format.nChannels / channels_;
+ if (channels_ > 2 && format_.Format.nChannels == 2) {
media::FoldChannels(buffer->lpData, used,
- channels_, format_.wBitsPerSample >> 3,
+ channels_, format_.Format.wBitsPerSample >> 3,
volume_);
} else {
media::AdjustVolume(buffer->lpData, used,
- format_.nChannels, format_.wBitsPerSample >> 3,
+ format_.Format.nChannels,
+ format_.Format.wBitsPerSample >> 3,
volume_);
}
} else {
diff --git a/media/audio/win/waveout_output_win.h b/media/audio/win/waveout_output_win.h
index 7bee81e..7437416 100644
--- a/media/audio/win/waveout_output_win.h
+++ b/media/audio/win/waveout_output_win.h
@@ -7,6 +7,7 @@
#include <windows.h>
#include <mmsystem.h>
+#include <mmreg.h>
#include "base/basictypes.h"
#include "base/scoped_handle_win.h"
@@ -100,13 +101,13 @@ class PCMWaveOutAudioOutputStream : public AudioOutputStream {
UINT device_id_;
// Windows native structure to encode the format parameters.
- WAVEFORMATEX format_;
+ WAVEFORMATPCMEX format_;
// Handle to the instance of the wave device.
HWAVEOUT waveout_;
// Pointer to the first allocated audio buffer. This object owns it.
- WAVEHDR* buffer_;
+ WAVEHDR* buffer_;
// An event that is signaled when the callback thread is ready to stop.
ScopedHandle stopped_event_;