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

Side by Side Diff: media/audio/win/waveout_output_win.cc

Issue 155894: Surround Sound handling by folding 5 channels down to stereo. (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: '' Created 11 years, 5 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
« no previous file with comments | « media/audio/win/waveout_output_win.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2006-2008 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 #include <windows.h> 5 #include <windows.h>
6 #include <mmsystem.h> 6 #include <mmsystem.h>
7 #pragma comment(lib, "winmm.lib") 7 #pragma comment(lib, "winmm.lib")
8 8
9 #include "media/audio/win/waveout_output_win.h" 9 #include "media/audio/win/waveout_output_win.h"
10 10
(...skipping 11 matching lines...) Expand all
22 // thus it forces you to maintain state, which naturally is not exactly 22 // thus it forces you to maintain state, which naturally is not exactly
23 // synchronized to the actual device state. 23 // synchronized to the actual device state.
24 // - Some functions, like waveOutReset cannot be called in the callback thread 24 // - Some functions, like waveOutReset cannot be called in the callback thread
25 // or called in any random state because they deadlock. This results in a 25 // or called in any random state because they deadlock. This results in a
26 // non- instantaneous Stop() method. waveOutPrepareHeader seems to be in the 26 // non- instantaneous Stop() method. waveOutPrepareHeader seems to be in the
27 // same boat. 27 // same boat.
28 // - waveOutReset() will forcefully kill the _waveThread so it is important 28 // - waveOutReset() will forcefully kill the _waveThread so it is important
29 // to make sure we are not executing inside the audio source's OnMoreData() 29 // to make sure we are not executing inside the audio source's OnMoreData()
30 // or that we take locks inside WaveCallback() or QueueNextPacket(). 30 // or that we take locks inside WaveCallback() or QueueNextPacket().
31 31
32 // Enable or disable software folding
33 #define FOLDING 1
34
32 namespace { 35 namespace {
33 36
34 // We settled for a double buffering scheme. It seems to strike a good balance 37 // We settled for a double buffering scheme. It seems to strike a good balance
35 // between how fast data needs to be provided versus memory usage. 38 // between how fast data needs to be provided versus memory usage.
36 const size_t kNumBuffers = 2; 39 const size_t kNumBuffers = 2;
37 40
38 // Sixty four MB is the maximum buffer size per AudioOutputStream. 41 // Sixty four MB is the maximum buffer size per AudioOutputStream.
39 const size_t kMaxOpenBufferSize = 1024 * 1024 * 64; 42 const size_t kMaxOpenBufferSize = 1024 * 1024 * 64;
40 43
41 // Our sound buffers are allocated once and kept in a linked list using the 44 // Our sound buffers are allocated once and kept in a linked list using the
42 // the WAVEHDR::dwUser variable. The last buffer points to the first buffer. 45 // the WAVEHDR::dwUser variable. The last buffer points to the first buffer.
43 WAVEHDR* GetNextBuffer(WAVEHDR* current) { 46 WAVEHDR* GetNextBuffer(WAVEHDR* current) {
44 return reinterpret_cast<WAVEHDR*>(current->dwUser); 47 return reinterpret_cast<WAVEHDR*>(current->dwUser);
45 } 48 }
46 49
47 } // namespace 50 } // namespace
48 51
49 PCMWaveOutAudioOutputStream::PCMWaveOutAudioOutputStream( 52 PCMWaveOutAudioOutputStream::PCMWaveOutAudioOutputStream(
50 AudioManagerWin* manager, int channels, int sampling_rate, 53 AudioManagerWin* manager, int channels, int sampling_rate,
51 char bits_per_sample, UINT device_id) 54 char bits_per_sample, UINT device_id)
52 : state_(PCMA_BRAND_NEW), 55 : state_(PCMA_BRAND_NEW),
53 manager_(manager), 56 manager_(manager),
54 device_id_(device_id), 57 device_id_(device_id),
55 waveout_(NULL), 58 waveout_(NULL),
56 callback_(NULL), 59 callback_(NULL),
57 buffer_(NULL), 60 buffer_(NULL),
58 buffer_size_(0), 61 buffer_size_(0),
59 volume_(1) { 62 volume_(1),
63 channels_(channels) {
60 format_.wFormatTag = WAVE_FORMAT_PCM; 64 format_.wFormatTag = WAVE_FORMAT_PCM;
65 #ifdef FOLDING
66 format_.nChannels = channels > 2 ? 2 : channels;
67 #else
61 format_.nChannels = channels; 68 format_.nChannels = channels;
69 #endif
62 format_.nSamplesPerSec = sampling_rate; 70 format_.nSamplesPerSec = sampling_rate;
63 format_.wBitsPerSample = bits_per_sample; 71 format_.wBitsPerSample = bits_per_sample;
64 format_.cbSize = 0; 72 format_.cbSize = 0;
65 // The next are computed from above. 73 // The next are computed from above.
66 format_.nBlockAlign = (format_.nChannels * format_.wBitsPerSample) / 8; 74 format_.nBlockAlign = (format_.nChannels * format_.wBitsPerSample) / 8;
67 format_.nAvgBytesPerSec = format_.nBlockAlign * format_.nSamplesPerSec; 75 format_.nAvgBytesPerSec = format_.nBlockAlign * format_.nSamplesPerSec;
68 // The event is auto-reset. 76 // The event is auto-reset.
69 stopped_event_.Set(::CreateEventW(NULL, FALSE, FALSE, NULL)); 77 stopped_event_.Set(::CreateEventW(NULL, FALSE, FALSE, NULL));
70 } 78 }
71 79
(...skipping 147 matching lines...) Expand 10 before | Expand all | Expand 10 after
219 DLOG(WARNING) << "PCMWaveOutAudio error " << error; 227 DLOG(WARNING) << "PCMWaveOutAudio error " << error;
220 callback_->OnError(this, error); 228 callback_->OnError(this, error);
221 } 229 }
222 230
223 void PCMWaveOutAudioOutputStream::QueueNextPacket(WAVEHDR *buffer) { 231 void PCMWaveOutAudioOutputStream::QueueNextPacket(WAVEHDR *buffer) {
224 // Call the source which will fill our buffer with pleasant sounds and 232 // Call the source which will fill our buffer with pleasant sounds and
225 // return to us how many bytes were used. 233 // return to us how many bytes were used.
226 // TODO(fbarchard): Handle used 0 by queueing more. 234 // TODO(fbarchard): Handle used 0 by queueing more.
227 size_t used = callback_->OnMoreData(this, buffer->lpData, buffer_size_); 235 size_t used = callback_->OnMoreData(this, buffer->lpData, buffer_size_);
228 if (used <= buffer_size_) { 236 if (used <= buffer_size_) {
229 buffer->dwBufferLength = used; 237 buffer->dwBufferLength = used * format_.nChannels / channels_;
230 media::AdjustVolume(buffer->lpData, buffer->dwBufferLength, 238 if (channels_ > 2 && format_.nChannels == 2) {
231 format_.nChannels, format_.wBitsPerSample >> 3, 239 media::FoldChannels(buffer->lpData, used,
232 volume_); 240 channels_, format_.wBitsPerSample >> 3,
241 volume_);
242 } else {
243 media::AdjustVolume(buffer->lpData, used,
244 format_.nChannels, format_.wBitsPerSample >> 3,
245 volume_);
246 }
247
233 } else { 248 } else {
234 HandleError(0); 249 HandleError(0);
235 return; 250 return;
236 } 251 }
237 buffer->dwFlags = WHDR_PREPARED; 252 buffer->dwFlags = WHDR_PREPARED;
238 } 253 }
239 254
240 // Windows call us back in this function when some events happen. Most notably 255 // Windows call us back in this function when some events happen. Most notably
241 // when it is done playing a buffer. Since we use double buffering it is 256 // when it is done playing a buffer. Since we use double buffering it is
242 // convenient to think of |buffer| as free and GetNextBuffer(buffer) as in 257 // convenient to think of |buffer| as free and GetNextBuffer(buffer) as in
(...skipping 28 matching lines...) Expand all
271 if (result != MMSYSERR_NOERROR) 286 if (result != MMSYSERR_NOERROR)
272 obj->HandleError(result); 287 obj->HandleError(result);
273 288
274 } else if (msg == WOM_CLOSE) { 289 } else if (msg == WOM_CLOSE) {
275 // We can be closed before calling Start, so it is possible to have a 290 // We can be closed before calling Start, so it is possible to have a
276 // null callback at this point. 291 // null callback at this point.
277 if (obj->callback_) 292 if (obj->callback_)
278 obj->callback_->OnClose(obj); 293 obj->callback_->OnClose(obj);
279 } 294 }
280 } 295 }
OLDNEW
« no previous file with comments | « media/audio/win/waveout_output_win.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698