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