waveout_output_win.cc revision 2a99a7e74a7f215066514fe81d2bfa6639d9eddd
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. 4 5#include "media/audio/win/waveout_output_win.h" 6 7#include <windows.h> 8#include <mmsystem.h> 9#pragma comment(lib, "winmm.lib") 10 11#include "base/atomicops.h" 12#include "base/basictypes.h" 13#include "base/debug/trace_event.h" 14#include "base/logging.h" 15#include "media/audio/audio_io.h" 16#include "media/audio/audio_util.h" 17#include "media/audio/win/audio_manager_win.h" 18 19namespace media { 20 21// Some general thoughts about the waveOut API which is badly documented : 22// - We use CALLBACK_EVENT mode in which XP signals events such as buffer 23// releases. 24// - We use RegisterWaitForSingleObject() so one of threads in thread pool 25// automatically calls our callback that feeds more data to Windows. 26// - Windows does not provide a way to query if the device is playing or paused 27// thus it forces you to maintain state, which naturally is not exactly 28// synchronized to the actual device state. 29 30// Sixty four MB is the maximum buffer size per AudioOutputStream. 31static const uint32 kMaxOpenBufferSize = 1024 * 1024 * 64; 32 33// See Also 34// http://www.thx.com/consumer/home-entertainment/home-theater/surround-sound-speaker-set-up/ 35// http://en.wikipedia.org/wiki/Surround_sound 36 37static const int kMaxChannelsToMask = 8; 38static const unsigned int kChannelsToMask[kMaxChannelsToMask + 1] = { 39 0, 40 // 1 = Mono 41 SPEAKER_FRONT_CENTER, 42 // 2 = Stereo 43 SPEAKER_FRONT_LEFT | SPEAKER_FRONT_RIGHT, 44 // 3 = Stereo + Center 45 SPEAKER_FRONT_LEFT | SPEAKER_FRONT_RIGHT | SPEAKER_FRONT_CENTER, 46 // 4 = Quad 47 SPEAKER_FRONT_LEFT | SPEAKER_FRONT_RIGHT | 48 SPEAKER_BACK_LEFT | SPEAKER_BACK_RIGHT, 49 // 5 = 5.0 50 SPEAKER_FRONT_LEFT | SPEAKER_FRONT_RIGHT | SPEAKER_FRONT_CENTER | 51 SPEAKER_BACK_LEFT | SPEAKER_BACK_RIGHT, 52 // 6 = 5.1 53 SPEAKER_FRONT_LEFT | SPEAKER_FRONT_RIGHT | 54 SPEAKER_FRONT_CENTER | SPEAKER_LOW_FREQUENCY | 55 SPEAKER_BACK_LEFT | SPEAKER_BACK_RIGHT, 56 // 7 = 6.1 57 SPEAKER_FRONT_LEFT | SPEAKER_FRONT_RIGHT | 58 SPEAKER_FRONT_CENTER | SPEAKER_LOW_FREQUENCY | 59 SPEAKER_BACK_LEFT | SPEAKER_BACK_RIGHT | 60 SPEAKER_BACK_CENTER, 61 // 8 = 7.1 62 SPEAKER_FRONT_LEFT | SPEAKER_FRONT_RIGHT | 63 SPEAKER_FRONT_CENTER | SPEAKER_LOW_FREQUENCY | 64 SPEAKER_BACK_LEFT | SPEAKER_BACK_RIGHT | 65 SPEAKER_SIDE_LEFT | SPEAKER_SIDE_RIGHT 66 // TODO(fbarchard): Add additional masks for 7.2 and beyond. 67}; 68 69inline size_t PCMWaveOutAudioOutputStream::BufferSize() const { 70 // Round size of buffer up to the nearest 16 bytes. 71 return (sizeof(WAVEHDR) + buffer_size_ + 15u) & static_cast<size_t>(~15); 72} 73 74inline WAVEHDR* PCMWaveOutAudioOutputStream::GetBuffer(int n) const { 75 DCHECK_GE(n, 0); 76 DCHECK_LT(n, num_buffers_); 77 return reinterpret_cast<WAVEHDR*>(&buffers_[n * BufferSize()]); 78} 79 80PCMWaveOutAudioOutputStream::PCMWaveOutAudioOutputStream( 81 AudioManagerWin* manager, const AudioParameters& params, int num_buffers, 82 UINT device_id) 83 : state_(PCMA_BRAND_NEW), 84 manager_(manager), 85 device_id_(device_id), 86 waveout_(NULL), 87 callback_(NULL), 88 num_buffers_(num_buffers), 89 buffer_size_(params.GetBytesPerBuffer()), 90 volume_(1), 91 channels_(params.channels()), 92 pending_bytes_(0), 93 waiting_handle_(NULL), 94 audio_bus_(AudioBus::Create(params)) { 95 format_.Format.wFormatTag = WAVE_FORMAT_EXTENSIBLE; 96 format_.Format.nChannels = params.channels(); 97 format_.Format.nSamplesPerSec = params.sample_rate(); 98 format_.Format.wBitsPerSample = params.bits_per_sample(); 99 format_.Format.cbSize = sizeof(format_) - sizeof(WAVEFORMATEX); 100 // The next are computed from above. 101 format_.Format.nBlockAlign = (format_.Format.nChannels * 102 format_.Format.wBitsPerSample) / 8; 103 format_.Format.nAvgBytesPerSec = format_.Format.nBlockAlign * 104 format_.Format.nSamplesPerSec; 105 if (params.channels() > kMaxChannelsToMask) { 106 format_.dwChannelMask = kChannelsToMask[kMaxChannelsToMask]; 107 } else { 108 format_.dwChannelMask = kChannelsToMask[params.channels()]; 109 } 110 format_.SubFormat = KSDATAFORMAT_SUBTYPE_PCM; 111 format_.Samples.wValidBitsPerSample = params.bits_per_sample(); 112} 113 114PCMWaveOutAudioOutputStream::~PCMWaveOutAudioOutputStream() { 115 DCHECK(NULL == waveout_); 116} 117 118bool PCMWaveOutAudioOutputStream::Open() { 119 if (state_ != PCMA_BRAND_NEW) 120 return false; 121 if (BufferSize() * num_buffers_ > kMaxOpenBufferSize) 122 return false; 123 if (num_buffers_ < 2 || num_buffers_ > 5) 124 return false; 125 126 // Create buffer event. 127 buffer_event_.Set(::CreateEvent(NULL, // Security attributes. 128 FALSE, // It will auto-reset. 129 FALSE, // Initial state. 130 NULL)); // No name. 131 if (!buffer_event_.Get()) 132 return false; 133 134 // Open the device. 135 // We'll be getting buffer_event_ events when it's time to refill the buffer. 136 MMRESULT result = ::waveOutOpen( 137 &waveout_, 138 device_id_, 139 reinterpret_cast<LPCWAVEFORMATEX>(&format_), 140 reinterpret_cast<DWORD_PTR>(buffer_event_.Get()), 141 NULL, 142 CALLBACK_EVENT); 143 if (result != MMSYSERR_NOERROR) 144 return false; 145 146 SetupBuffers(); 147 state_ = PCMA_READY; 148 return true; 149} 150 151void PCMWaveOutAudioOutputStream::SetupBuffers() { 152 buffers_.reset(new char[BufferSize() * num_buffers_]); 153 for (int ix = 0; ix != num_buffers_; ++ix) { 154 WAVEHDR* buffer = GetBuffer(ix); 155 buffer->lpData = reinterpret_cast<char*>(buffer) + sizeof(WAVEHDR); 156 buffer->dwBufferLength = buffer_size_; 157 buffer->dwBytesRecorded = 0; 158 buffer->dwFlags = WHDR_DONE; 159 buffer->dwLoops = 0; 160 // Tell windows sound drivers about our buffers. Not documented what 161 // this does but we can guess that causes the OS to keep a reference to 162 // the memory pages so the driver can use them without worries. 163 ::waveOutPrepareHeader(waveout_, buffer, sizeof(WAVEHDR)); 164 } 165} 166 167void PCMWaveOutAudioOutputStream::FreeBuffers() { 168 for (int ix = 0; ix != num_buffers_; ++ix) { 169 ::waveOutUnprepareHeader(waveout_, GetBuffer(ix), sizeof(WAVEHDR)); 170 } 171 buffers_.reset(NULL); 172} 173 174// Initially we ask the source to fill up all audio buffers. If we don't do 175// this then we would always get the driver callback when it is about to run 176// samples and that would leave too little time to react. 177void PCMWaveOutAudioOutputStream::Start(AudioSourceCallback* callback) { 178 if (state_ != PCMA_READY) 179 return; 180 callback_ = callback; 181 182 // Reset buffer event, it can be left in the arbitrary state if we 183 // previously stopped the stream. Can happen because we are stopping 184 // callbacks before stopping playback itself. 185 if (!::ResetEvent(buffer_event_.Get())) { 186 HandleError(MMSYSERR_ERROR); 187 return; 188 } 189 190 // Start watching for buffer events. 191 if (!::RegisterWaitForSingleObject(&waiting_handle_, 192 buffer_event_.Get(), 193 &BufferCallback, 194 this, 195 INFINITE, 196 WT_EXECUTEDEFAULT)) { 197 HandleError(MMSYSERR_ERROR); 198 waiting_handle_ = NULL; 199 return; 200 } 201 202 state_ = PCMA_PLAYING; 203 204 // Queue the buffers. 205 pending_bytes_ = 0; 206 for (int ix = 0; ix != num_buffers_; ++ix) { 207 WAVEHDR* buffer = GetBuffer(ix); 208 // Caller waits for 1st packet to become available, but not for others, 209 // so we wait for them here. 210 if (ix != 0) 211 callback_->WaitTillDataReady(); 212 QueueNextPacket(buffer); // Read more data. 213 pending_bytes_ += buffer->dwBufferLength; 214 } 215 216 // From now on |pending_bytes_| would be accessed by callback thread. 217 // Most likely waveOutPause() or waveOutRestart() has its own memory barrier, 218 // but issuing our own is safer. 219 base::subtle::MemoryBarrier(); 220 221 MMRESULT result = ::waveOutPause(waveout_); 222 if (result != MMSYSERR_NOERROR) { 223 HandleError(result); 224 return; 225 } 226 227 // Send the buffers to the audio driver. Note that the device is paused 228 // so we avoid entering the callback method while still here. 229 for (int ix = 0; ix != num_buffers_; ++ix) { 230 result = ::waveOutWrite(waveout_, GetBuffer(ix), sizeof(WAVEHDR)); 231 if (result != MMSYSERR_NOERROR) { 232 HandleError(result); 233 break; 234 } 235 } 236 result = ::waveOutRestart(waveout_); 237 if (result != MMSYSERR_NOERROR) { 238 HandleError(result); 239 return; 240 } 241} 242 243// Stopping is tricky if we want it be fast. 244// For now just do it synchronously and avoid all the complexities. 245// TODO(enal): if we want faster Stop() we can create singleton that keeps track 246// of all currently playing streams. Then you don't have to wait 247// till all callbacks are completed. Of course access to singleton 248// should be under its own lock, and checking the liveness and 249// acquiring the lock on stream should be done atomically. 250void PCMWaveOutAudioOutputStream::Stop() { 251 if (state_ != PCMA_PLAYING) 252 return; 253 state_ = PCMA_STOPPING; 254 base::subtle::MemoryBarrier(); 255 256 // Stop watching for buffer event, wait till all the callbacks are complete. 257 // Should be done before ::waveOutReset() call to avoid race condition when 258 // callback that is currently active and already checked that stream is still 259 // being played calls ::waveOutWrite() after ::waveOutReset() returns, later 260 // causing ::waveOutClose() to fail with WAVERR_STILLPLAYING. 261 // TODO(enal): that delays actual stopping of playback. Alternative can be 262 // to call ::waveOutReset() twice, once before 263 // ::UnregisterWaitEx() and once after. 264 if (waiting_handle_) { 265 if (!::UnregisterWaitEx(waiting_handle_, INVALID_HANDLE_VALUE)) { 266 state_ = PCMA_PLAYING; 267 HandleError(MMSYSERR_ERROR); 268 return; 269 } 270 waiting_handle_ = NULL; 271 } 272 273 // Stop playback. 274 MMRESULT res = ::waveOutReset(waveout_); 275 if (res != MMSYSERR_NOERROR) { 276 state_ = PCMA_PLAYING; 277 HandleError(res); 278 return; 279 } 280 281 // Wait for lock to ensure all outstanding callbacks have completed. 282 base::AutoLock auto_lock(lock_); 283 284 // waveOutReset() leaves buffers in the unpredictable state, causing 285 // problems if we want to close, release, or reuse them. Fix the states. 286 for (int ix = 0; ix != num_buffers_; ++ix) { 287 GetBuffer(ix)->dwFlags = WHDR_PREPARED; 288 } 289 290 // Don't use callback after Stop(). 291 callback_ = NULL; 292 293 state_ = PCMA_READY; 294} 295 296// We can Close in any state except that trying to close a stream that is 297// playing Windows generates an error. We cannot propagate it to the source, 298// as callback_ is set to NULL. Just print it and hope somebody somehow 299// will find it... 300void PCMWaveOutAudioOutputStream::Close() { 301 // Force Stop() to ensure it's safe to release buffers and free the stream. 302 Stop(); 303 304 if (waveout_) { 305 FreeBuffers(); 306 307 // waveOutClose() generates a WIM_CLOSE callback. In case Start() was never 308 // called, force a reset to ensure close succeeds. 309 MMRESULT res = ::waveOutReset(waveout_); 310 DCHECK_EQ(res, static_cast<MMRESULT>(MMSYSERR_NOERROR)); 311 res = ::waveOutClose(waveout_); 312 DCHECK_EQ(res, static_cast<MMRESULT>(MMSYSERR_NOERROR)); 313 state_ = PCMA_CLOSED; 314 waveout_ = NULL; 315 } 316 317 // Tell the audio manager that we have been released. This can result in 318 // the manager destroying us in-place so this needs to be the last thing 319 // we do on this function. 320 manager_->ReleaseOutputStream(this); 321} 322 323void PCMWaveOutAudioOutputStream::SetVolume(double volume) { 324 if (!waveout_) 325 return; 326 volume_ = static_cast<float>(volume); 327} 328 329void PCMWaveOutAudioOutputStream::GetVolume(double* volume) { 330 if (!waveout_) 331 return; 332 *volume = volume_; 333} 334 335void PCMWaveOutAudioOutputStream::HandleError(MMRESULT error) { 336 DLOG(WARNING) << "PCMWaveOutAudio error " << error; 337 if (callback_) 338 callback_->OnError(this); 339} 340 341void PCMWaveOutAudioOutputStream::QueueNextPacket(WAVEHDR *buffer) { 342 DCHECK_EQ(channels_, format_.Format.nChannels); 343 // Call the source which will fill our buffer with pleasant sounds and 344 // return to us how many bytes were used. 345 // TODO(fbarchard): Handle used 0 by queueing more. 346 347 // HACK: Yield if Read() is called too often. On older platforms which are 348 // still using the WaveOut backend, we run into synchronization issues where 349 // the renderer has not finished filling the shared memory when Read() is 350 // called. Reading too early will lead to clicks and pops. See issues: 351 // http://crbug.com/161307 and http://crbug.com/61022 352 callback_->WaitTillDataReady(); 353 354 // TODO(sergeyu): Specify correct hardware delay for AudioBuffersState. 355 int frames_filled = callback_->OnMoreData( 356 audio_bus_.get(), AudioBuffersState(pending_bytes_, 0)); 357 uint32 used = frames_filled * audio_bus_->channels() * 358 format_.Format.wBitsPerSample / 8; 359 360 if (used <= buffer_size_) { 361 // Note: If this ever changes to output raw float the data must be clipped 362 // and sanitized since it may come from an untrusted source such as NaCl. 363 audio_bus_->ToInterleaved( 364 frames_filled, format_.Format.wBitsPerSample / 8, buffer->lpData); 365 366 buffer->dwBufferLength = used * format_.Format.nChannels / channels_; 367 media::AdjustVolume(buffer->lpData, used, 368 format_.Format.nChannels, 369 format_.Format.wBitsPerSample >> 3, 370 volume_); 371 } else { 372 HandleError(0); 373 return; 374 } 375 buffer->dwFlags = WHDR_PREPARED; 376} 377 378// One of the threads in our thread pool asynchronously calls this function when 379// buffer_event_ is signalled. Search through all the buffers looking for freed 380// ones, fills them with data, and "feed" the Windows. 381// Note: by searching through all the buffers we guarantee that we fill all the 382// buffers, even when "event loss" happens, i.e. if Windows signals event 383// when it did not flip into unsignaled state from the previous signal. 384void NTAPI PCMWaveOutAudioOutputStream::BufferCallback(PVOID lpParameter, 385 BOOLEAN timer_fired) { 386 TRACE_EVENT0("audio", "PCMWaveOutAudioOutputStream::BufferCallback"); 387 388 DCHECK(!timer_fired); 389 PCMWaveOutAudioOutputStream* stream = 390 reinterpret_cast<PCMWaveOutAudioOutputStream*>(lpParameter); 391 392 // Lock the stream so callbacks do not interfere with each other. 393 // Several callbacks can be called simultaneously by different threads in the 394 // thread pool if some of the callbacks are slow, or system is very busy and 395 // scheduled callbacks are not called on time. 396 base::AutoLock auto_lock(stream->lock_); 397 if (stream->state_ != PCMA_PLAYING) 398 return; 399 400 for (int ix = 0; ix != stream->num_buffers_; ++ix) { 401 WAVEHDR* buffer = stream->GetBuffer(ix); 402 if (buffer->dwFlags & WHDR_DONE) { 403 // Before we queue the next packet, we need to adjust the number of 404 // pending bytes since the last write to hardware. 405 stream->pending_bytes_ -= buffer->dwBufferLength; 406 stream->QueueNextPacket(buffer); 407 408 // QueueNextPacket() can take a long time, especially if several of them 409 // were called back-to-back. Check if we are stopping now. 410 if (stream->state_ != PCMA_PLAYING) 411 return; 412 413 // Time to send the buffer to the audio driver. Since we are reusing 414 // the same buffers we can get away without calling waveOutPrepareHeader. 415 MMRESULT result = ::waveOutWrite(stream->waveout_, 416 buffer, 417 sizeof(WAVEHDR)); 418 if (result != MMSYSERR_NOERROR) 419 stream->HandleError(result); 420 stream->pending_bytes_ += buffer->dwBufferLength; 421 } 422 } 423} 424 425} // namespace media 426