// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include <windows.h>
#include <mmsystem.h>
#pragma comment(lib, "winmm.lib")

#include "media/audio/win/waveout_output_win.h"

#include "base/basictypes.h"
#include "base/logging.h"
#include "media/audio/audio_output.h"
#include "media/audio/win/audio_manager_win.h"

// Some general thoughts about the waveOut API which is badly documented :
// - We use CALLBACK_FUNCTION mode in which XP secretly creates two threads
//   named _MixerCallbackThread and _waveThread which have real-time priority.
//   The callbacks occur in _waveThread.
// - Windows does not provide a way to query if the device is playing or paused
//   thus it forces you to maintain state, which naturally is not exactly
//   synchronized to the actual device state.
// - Some functions, like waveOutReset cannot be called in the callback thread
//   or called in any random state because they deadlock. This results in a
//   non- instantaneous Stop() method. waveOutPrepareHeader seems to be in the
//   same boat.
// - waveOutReset() will forcefully kill the _waveThread so it is important
//   to make sure we are not executing inside the audio source's OnMoreData()
//   or that we take locks inside WaveCallback() or QueueNextPacket().

namespace {

// We settled for a double buffering scheme. It seems to strike a good balance
// between how fast data needs to be provided versus memory usage.
const size_t kNumBuffers = 2;

// Our sound buffers are allocated once and kept in a linked list using the
// the WAVEHDR::dwUser variable. The last buffer points to the first buffer.
WAVEHDR* GetNextBuffer(WAVEHDR* current) {
  return reinterpret_cast<WAVEHDR*>(current->dwUser);
}

}  // namespace

PCMWaveOutAudioOutputStream::PCMWaveOutAudioOutputStream(
    AudioManagerWin* manager, int channels, int sampling_rate,
    char bits_per_sample, UINT device_id)
    : state_(PCMA_BRAND_NEW),
      manager_(manager),
      device_id_(device_id),
      waveout_(NULL),
      callback_(NULL),
      buffer_(NULL),
      buffer_size_(0) {
  format_.wFormatTag = WAVE_FORMAT_PCM;
  format_.nChannels = channels;
  format_.nSamplesPerSec = sampling_rate;
  format_.wBitsPerSample = bits_per_sample;
  format_.cbSize = 0;
  // The next are computed from above.
  format_.nBlockAlign = (format_.nChannels * format_.wBitsPerSample) / 8;
  format_.nAvgBytesPerSec = format_.nBlockAlign * format_.nSamplesPerSec;
  // The event is auto-reset.
  stopped_event_.Set(::CreateEventW(NULL, FALSE, FALSE, NULL));
}

PCMWaveOutAudioOutputStream::~PCMWaveOutAudioOutputStream() {
  DCHECK(NULL == waveout_);
}

bool PCMWaveOutAudioOutputStream::Open(size_t buffer_size) {
  if (state_ != PCMA_BRAND_NEW)
    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_,
                                  reinterpret_cast<DWORD_PTR>(WaveCallback),
                                  reinterpret_cast<DWORD_PTR>(this),
                                  CALLBACK_FUNCTION);
  if (result != MMSYSERR_NOERROR)
    return false;
  // If we don't have a packet size we use 100ms.
  if (!buffer_size)
    buffer_size = format_.nAvgBytesPerSec / 10;

  SetupBuffers(buffer_size);
  buffer_size_ = buffer_size;
  state_ = PCMA_READY;
  return true;
}

void PCMWaveOutAudioOutputStream::SetupBuffers(size_t rq_size) {
  WAVEHDR* last = NULL;
  WAVEHDR* first = NULL;
  for (int ix = 0; ix != kNumBuffers; ++ix) {
    size_t sz = sizeof(WAVEHDR) + rq_size;
    buffer_ =  reinterpret_cast<WAVEHDR*>(new char[sz]);
    buffer_->lpData = reinterpret_cast<char*>(buffer_) + sizeof(WAVEHDR);
    buffer_->dwBufferLength = rq_size;
    buffer_->dwBytesRecorded = 0;
    buffer_->dwUser = reinterpret_cast<DWORD_PTR>(last);
    buffer_->dwFlags = WHDR_DONE;
    buffer_->dwLoops = 0;
    if (ix == 0)
      first = buffer_;
    last = buffer_;
    // Tell windows sound drivers about our buffers. Not documented what
    // this does but we can guess that causes the OS to keep a reference to
    // the memory pages so the driver can use them without worries.
    ::waveOutPrepareHeader(waveout_, buffer_, sizeof(WAVEHDR));
  }
  // Fix the first buffer to point to the last one.
  first->dwUser = reinterpret_cast<DWORD_PTR>(last);
}

void PCMWaveOutAudioOutputStream::FreeBuffers() {
  WAVEHDR* current = buffer_;
  for (int ix = 0; ix != kNumBuffers; ++ix) {
    WAVEHDR* next = GetNextBuffer(current);
    ::waveOutUnprepareHeader(waveout_, current, sizeof(WAVEHDR));
    delete[] reinterpret_cast<char*>(current);
    current = next;
  }
  buffer_ = NULL;
}

// Initially we ask the source to fill up both audio buffers. If we don't do
// this then we would always get the driver callback when it is about to run
// samples and that would leave too little time to react.
void PCMWaveOutAudioOutputStream::Start(AudioSourceCallback* callback) {
  if (state_ != PCMA_READY)
    return;
  callback_ = callback;
  state_ = PCMA_PLAYING;
  WAVEHDR* buffer = buffer_;
  for (int ix = 0; ix != kNumBuffers; ++ix) {
    QueueNextPacket(buffer);
    buffer = GetNextBuffer(buffer);
  }
}

// Stopping is tricky. First, no buffer should be locked by the audio driver
// or else the waveOutReset will deadlock and secondly, the callback should not
// be inside the AudioSource's OnMoreData because waveOutReset() forcefully
// kills the callback thread.
void PCMWaveOutAudioOutputStream::Stop() {
  if (state_ != PCMA_PLAYING)
    return;
  state_ = PCMA_STOPPING;
  // Wait for the callback to finish, it will signal us when ready to be reset.
  if (WAIT_OBJECT_0 != ::WaitForSingleObject(stopped_event_, INFINITE)) {
    HandleError(::GetLastError());
    return;
  }
  state_ = PCMA_STOPPED;
  MMRESULT res = ::waveOutReset(waveout_);
  if (res != MMSYSERR_NOERROR) {
    state_ = PCMA_PLAYING;
    HandleError(res);
  }
}

// We can Close in any state except that trying to close a stream that is
// playing Windows generates an error, which we propagate to the source.
void PCMWaveOutAudioOutputStream::Close() {
  if (waveout_) {
    // waveOutClose generates a callback with WOM_CLOSE id in the same thread.
    MMRESULT res = ::waveOutClose(waveout_);
    if (res != MMSYSERR_NOERROR) {
      HandleError(res);
      return;
    }
    state_ = PCMA_CLOSED;
    waveout_ = NULL;
    FreeBuffers();
  }
  // Tell the audio manager that we have been released. This can result in
  // the manager destroying us in-place so this needs to be the last thing
  // we do on this function.
  manager_->ReleaseStream(this);
}

// TODO(cpu): Implement SetVolume and GetVolume.
void PCMWaveOutAudioOutputStream::SetVolume(double left_level,
                                            double right_level) {
  if (state_ != PCMA_READY)
    return;
}

void PCMWaveOutAudioOutputStream::GetVolume(double* left_level,
                                            double* right_level) {
  if (state_ != PCMA_READY)
    return;
}

void PCMWaveOutAudioOutputStream::HandleError(MMRESULT error) {
  DLOG(WARNING) << "PCMWaveOutAudio error " << error;
  callback_->OnError(this, error);
}

void PCMWaveOutAudioOutputStream::QueueNextPacket(WAVEHDR *buffer) {
  // Call the source which will fill our buffer with pleasant sounds and
  // return to us how many bytes were used.
  size_t used = callback_->OnMoreData(this, buffer->lpData, buffer_size_);

  if (used <= buffer_size_) {
    buffer->dwBufferLength = used;
  } else {
    HandleError(0);
    return;
  }
  // Time to queue the buffer to the audio driver. Since we are reusing
  // the same buffers we can get away without calling waveOutPrepareHeader.
  buffer->dwFlags = WHDR_PREPARED;
  MMRESULT result = ::waveOutWrite(waveout_, buffer, sizeof(WAVEHDR));
  if (result != MMSYSERR_NOERROR)
    HandleError(result);
}

// Windows call us back in this function when some events happen. Most notably
// when it is done playing a buffer. Since we use double buffering it is
// convenient to think of |buffer| as free and GetNextBuffer(buffer) as in
// use by the driver.
void PCMWaveOutAudioOutputStream::WaveCallback(HWAVEOUT hwo, UINT msg,
                                               DWORD_PTR instance,
                                               DWORD_PTR param1, DWORD_PTR) {
  PCMWaveOutAudioOutputStream* obj =
      reinterpret_cast<PCMWaveOutAudioOutputStream*>(instance);

  if (msg == WOM_DONE) {
    // WOM_DONE indicates that the driver is done with our buffer, we can
    // either ask the source for more data or check if we need to stop playing.
    WAVEHDR* buffer = reinterpret_cast<WAVEHDR*>(param1);
    buffer->dwFlags = WHDR_DONE;

    if (obj->state_ == PCMA_STOPPING) {
      // The main thread has called Stop() and is waiting to issue waveOutReset
      // which will kill this thread. We should not enter AudioSourceCallback
      // code anymore.
      ::SetEvent(obj->stopped_event_);
      return;
    } else if (obj->state_ == PCMA_STOPPED) {
      // Not sure if ever hit this but just in case.
      return;
    }
    obj->QueueNextPacket(buffer);
  } else if (msg == WOM_CLOSE) {
    // We can be closed before calling Start, so it is possible to have a
    // null callback at this point.
    if (obj->callback_)
      obj->callback_->OnClose(obj);
  }
}

