/* GStreamer
* Copyright (C) 2005 Sebastien Moutte <sebastien@moutte.net>
* Copyright (C) 2007 Pioneers of the Inevitable <songbird@songbirdnest.com>
* Copyright (C) 2010 Fluendo S.A. <support@fluendo.com>
*
* gstdirectsoundsink.c:
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this library; if not, write to the
* Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
* Boston, MA 02110-1301, USA.
*
*
* The development of this code was made possible due to the involvement
* of Pioneers of the Inevitable, the creators of the Songbird Music player
*
*/

/**
 * SECTION:element-directsoundsink
 *
 * This element lets you output sound using the DirectSound API.
 *
 * Note that you should almost always use generic audio conversion elements
 * like audioconvert and audioresample in front of an audiosink to make sure
 * your pipeline works under all circumstances (those conversion elements will
 * act in passthrough-mode if no conversion is necessary).
 *
 * <refsect2>
 * <title>Example pipelines</title>
 * |[
 * gst-launch-1.0 -v audiotestsrc ! audioconvert ! volume volume=0.1 ! directsoundsink
 * ]| will output a sine wave (continuous beep sound) to your sound card (with
 * a very low volume as precaution).
 * |[
 * gst-launch-1.0 -v filesrc location=music.ogg ! decodebin ! audioconvert ! audioresample ! directsoundsink
 * ]| will play an Ogg/Vorbis audio file and output it.
 * </refsect2>
 */

#ifdef HAVE_CONFIG_H
#include "config.h"
#endif

#include <gst/base/gstbasesink.h>
#include "gstdirectsoundsink.h"
#include <gst/audio/gstaudioiec61937.h>

#include <math.h>

#ifdef __CYGWIN__
#include <unistd.h>
#ifndef _swab
#define _swab swab
#endif
#endif

#define DEFAULT_MUTE FALSE

GST_DEBUG_CATEGORY_STATIC (directsoundsink_debug);
#define GST_CAT_DEFAULT directsoundsink_debug

static void gst_directsound_sink_finalize (GObject * object);

static void gst_directsound_sink_set_property (GObject * object, guint prop_id,
    const GValue * value, GParamSpec * pspec);
static void gst_directsound_sink_get_property (GObject * object, guint prop_id,
    GValue * value, GParamSpec * pspec);

static GstCaps *gst_directsound_sink_getcaps (GstBaseSink * bsink,
    GstCaps * filter);
static GstBuffer *gst_directsound_sink_payload (GstAudioBaseSink * sink,
    GstBuffer * buf);
static gboolean gst_directsound_sink_prepare (GstAudioSink * asink,
    GstAudioRingBufferSpec * spec);
static gboolean gst_directsound_sink_unprepare (GstAudioSink * asink);
static gboolean gst_directsound_sink_open (GstAudioSink * asink);
static gboolean gst_directsound_sink_close (GstAudioSink * asink);
static gint gst_directsound_sink_write (GstAudioSink * asink,
    gpointer data, guint length);
static guint gst_directsound_sink_delay (GstAudioSink * asink);
static void gst_directsound_sink_reset (GstAudioSink * asink);
static GstCaps *gst_directsound_probe_supported_formats (GstDirectSoundSink *
    dsoundsink, const GstCaps * template_caps);
static gboolean gst_directsound_sink_query (GstBaseSink * pad,
    GstQuery * query);

static void gst_directsound_sink_set_volume (GstDirectSoundSink * sink,
    gdouble volume, gboolean store);
static gdouble gst_directsound_sink_get_volume (GstDirectSoundSink * sink);
static void gst_directsound_sink_set_mute (GstDirectSoundSink * sink,
    gboolean mute);
static gboolean gst_directsound_sink_get_mute (GstDirectSoundSink * sink);
static const gchar *gst_directsound_sink_get_device (GstDirectSoundSink *
    dsoundsink);
static void gst_directsound_sink_set_device (GstDirectSoundSink * dsoundsink,
    const gchar * device_id);

static gboolean gst_directsound_sink_is_spdif_format (GstAudioRingBufferSpec *
    spec);

static gchar *gst_hres_to_string (HRESULT hRes);

static GstStaticPadTemplate directsoundsink_sink_factory =
    GST_STATIC_PAD_TEMPLATE ("sink",
    GST_PAD_SINK,
    GST_PAD_ALWAYS,
    GST_STATIC_CAPS ("audio/x-raw, "
        "format = (string) S16LE, "
        "layout = (string) interleaved, "
        "rate = (int) [ 1, MAX ], " "channels = (int) [ 1, 2 ]; "
        "audio/x-raw, "
        "format = (string) U8, "
        "layout = (string) interleaved, "
        "rate = (int) [ 1, MAX ], " "channels = (int) [ 1, 2 ];"
        "audio/x-ac3, framed = (boolean) true;"
        "audio/x-dts, framed = (boolean) true;"));

enum
{
  PROP_0,
  PROP_VOLUME,
  PROP_MUTE,
  PROP_DEVICE
};

#define gst_directsound_sink_parent_class parent_class
G_DEFINE_TYPE_WITH_CODE (GstDirectSoundSink, gst_directsound_sink,
    GST_TYPE_AUDIO_SINK, G_IMPLEMENT_INTERFACE (GST_TYPE_STREAM_VOLUME, NULL)
    );

static void
gst_directsound_sink_finalize (GObject * object)
{
  GstDirectSoundSink *dsoundsink = GST_DIRECTSOUND_SINK (object);

  g_free (dsoundsink->device_id);
  dsoundsink->device_id = NULL;

  g_mutex_clear (&dsoundsink->dsound_lock);
  gst_object_unref (dsoundsink->system_clock);
  if (dsoundsink->write_wait_clock_id != NULL) {
    gst_clock_id_unref (dsoundsink->write_wait_clock_id);
  }

  G_OBJECT_CLASS (parent_class)->finalize (object);
}

static void
gst_directsound_sink_class_init (GstDirectSoundSinkClass * klass)
{
  GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
  GstBaseSinkClass *gstbasesink_class = GST_BASE_SINK_CLASS (klass);
  GstAudioSinkClass *gstaudiosink_class = GST_AUDIO_SINK_CLASS (klass);
  GstAudioBaseSinkClass *gstaudiobasesink_class =
      GST_AUDIO_BASE_SINK_CLASS (klass);
  GstElementClass *element_class = GST_ELEMENT_CLASS (klass);

  GST_DEBUG_CATEGORY_INIT (directsoundsink_debug, "directsoundsink", 0,
      "DirectSound sink");

  gobject_class->finalize = gst_directsound_sink_finalize;
  gobject_class->set_property = gst_directsound_sink_set_property;
  gobject_class->get_property = gst_directsound_sink_get_property;

  gstbasesink_class->get_caps =
      GST_DEBUG_FUNCPTR (gst_directsound_sink_getcaps);

  gstbasesink_class->query = GST_DEBUG_FUNCPTR (gst_directsound_sink_query);

  gstaudiobasesink_class->payload =
      GST_DEBUG_FUNCPTR (gst_directsound_sink_payload);

  gstaudiosink_class->prepare =
      GST_DEBUG_FUNCPTR (gst_directsound_sink_prepare);
  gstaudiosink_class->unprepare =
      GST_DEBUG_FUNCPTR (gst_directsound_sink_unprepare);
  gstaudiosink_class->open = GST_DEBUG_FUNCPTR (gst_directsound_sink_open);
  gstaudiosink_class->close = GST_DEBUG_FUNCPTR (gst_directsound_sink_close);
  gstaudiosink_class->write = GST_DEBUG_FUNCPTR (gst_directsound_sink_write);
  gstaudiosink_class->delay = GST_DEBUG_FUNCPTR (gst_directsound_sink_delay);
  gstaudiosink_class->reset = GST_DEBUG_FUNCPTR (gst_directsound_sink_reset);

  g_object_class_install_property (gobject_class,
      PROP_VOLUME,
      g_param_spec_double ("volume", "Volume",
          "Volume of this stream", 0.0, 1.0, 1.0,
          G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));

  g_object_class_install_property (gobject_class,
      PROP_MUTE,
      g_param_spec_boolean ("mute", "Mute",
          "Mute state of this stream", DEFAULT_MUTE,
          G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));

  g_object_class_install_property (gobject_class,
      PROP_DEVICE,
      g_param_spec_string ("device", "Device",
          "DirectSound playback device as a GUID string",
          NULL, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));

  gst_element_class_set_static_metadata (element_class,
      "Direct Sound Audio Sink", "Sink/Audio",
      "Output to a sound card via Direct Sound",
      "Sebastien Moutte <sebastien@moutte.net>");

  gst_element_class_add_static_pad_template (element_class,
      &directsoundsink_sink_factory);
}

static void
gst_directsound_sink_init (GstDirectSoundSink * dsoundsink)
{
  dsoundsink->volume = 100;
  dsoundsink->mute = FALSE;
  dsoundsink->device_id = NULL;
  dsoundsink->pDS = NULL;
  dsoundsink->cached_caps = NULL;
  dsoundsink->pDSBSecondary = NULL;
  dsoundsink->current_circular_offset = 0;
  dsoundsink->buffer_size = DSBSIZE_MIN;
  g_mutex_init (&dsoundsink->dsound_lock);
  dsoundsink->system_clock = gst_system_clock_obtain ();
  dsoundsink->write_wait_clock_id = NULL;
  dsoundsink->first_buffer_after_reset = FALSE;
}

static void
gst_directsound_sink_set_property (GObject * object,
    guint prop_id, const GValue * value, GParamSpec * pspec)
{
  GstDirectSoundSink *sink = GST_DIRECTSOUND_SINK (object);

  switch (prop_id) {
    case PROP_VOLUME:
      gst_directsound_sink_set_volume (sink, g_value_get_double (value), TRUE);
      break;
    case PROP_MUTE:
      gst_directsound_sink_set_mute (sink, g_value_get_boolean (value));
      break;
    case PROP_DEVICE:
      gst_directsound_sink_set_device (sink, g_value_get_string (value));
      break;
    default:
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
      break;
  }
}

static void
gst_directsound_sink_get_property (GObject * object,
    guint prop_id, GValue * value, GParamSpec * pspec)
{
  GstDirectSoundSink *sink = GST_DIRECTSOUND_SINK (object);

  switch (prop_id) {
    case PROP_VOLUME:
      g_value_set_double (value, gst_directsound_sink_get_volume (sink));
      break;
    case PROP_MUTE:
      g_value_set_boolean (value, gst_directsound_sink_get_mute (sink));
      break;
    case PROP_DEVICE:
      g_value_set_string (value, gst_directsound_sink_get_device (sink));
      break;
    default:
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
      break;
  }
}

static GstCaps *
gst_directsound_sink_getcaps (GstBaseSink * bsink, GstCaps * filter)
{
  GstElementClass *element_class;
  GstPadTemplate *pad_template;
  GstDirectSoundSink *dsoundsink = GST_DIRECTSOUND_SINK (bsink);
  GstCaps *caps;

  if (dsoundsink->pDS == NULL) {
    GST_DEBUG_OBJECT (dsoundsink, "device not open, using template caps");
    return NULL;                /* base class will get template caps for us */
  }

  if (dsoundsink->cached_caps) {
    caps = gst_caps_ref (dsoundsink->cached_caps);
  } else {
    element_class = GST_ELEMENT_GET_CLASS (dsoundsink);
    pad_template = gst_element_class_get_pad_template (element_class, "sink");
    g_return_val_if_fail (pad_template != NULL, NULL);

    caps = gst_directsound_probe_supported_formats (dsoundsink,
        gst_pad_template_get_caps (pad_template));
    if (caps)
      dsoundsink->cached_caps = gst_caps_ref (caps);
  }

  if (caps && filter) {
    GstCaps *tmp =
        gst_caps_intersect_full (filter, caps, GST_CAPS_INTERSECT_FIRST);
    gst_caps_unref (caps);
    caps = tmp;
  }

  if (caps) {
    gchar *caps_string = gst_caps_to_string (caps);
    GST_DEBUG_OBJECT (dsoundsink, "returning caps %s", caps_string);
    g_free (caps_string);
  }

  return caps;
}

static gboolean
gst_directsound_sink_acceptcaps (GstBaseSink * sink, GstQuery * query)
{
  GstDirectSoundSink *dsink = GST_DIRECTSOUND_SINK (sink);
  GstPad *pad;
  GstCaps *caps;
  GstCaps *pad_caps;
  GstStructure *st;
  gboolean ret = FALSE;
  GstAudioRingBufferSpec spec = { 0 };

  if (G_UNLIKELY (dsink == NULL))
    return FALSE;

  pad = sink->sinkpad;

  gst_query_parse_accept_caps (query, &caps);
  GST_DEBUG_OBJECT (pad, "caps %" GST_PTR_FORMAT, caps);

  pad_caps = gst_pad_query_caps (pad, NULL);
  if (pad_caps) {
    gboolean cret = gst_caps_is_subset (caps, pad_caps);
    gst_caps_unref (pad_caps);
    if (!cret) {
      GST_DEBUG_OBJECT (dsink,
          "Caps are not a subset of the pad caps, not accepting caps");
      goto done;
    }
  }

  /* If we've not got fixed caps, creating a stream might fail, so let's just
   * return from here with default acceptcaps behaviour */
  if (!gst_caps_is_fixed (caps)) {
    GST_DEBUG_OBJECT (dsink, "Caps are not fixed, not accepting caps");
    goto done;
  }

  spec.latency_time = GST_SECOND;
  if (!gst_audio_ring_buffer_parse_caps (&spec, caps)) {
    GST_DEBUG_OBJECT (dsink, "Failed to parse caps, not accepting");
    goto done;
  }

  /* Make sure input is framed (one frame per buffer) and can be payloaded */
  switch (spec.type) {
    case GST_AUDIO_RING_BUFFER_FORMAT_TYPE_AC3:
    case GST_AUDIO_RING_BUFFER_FORMAT_TYPE_DTS:
    {
      gboolean framed = FALSE, parsed = FALSE;
      st = gst_caps_get_structure (caps, 0);

      gst_structure_get_boolean (st, "framed", &framed);
      gst_structure_get_boolean (st, "parsed", &parsed);
      if ((!framed && !parsed) || gst_audio_iec61937_frame_size (&spec) <= 0) {
        GST_DEBUG_OBJECT (dsink, "Wrong AC3/DTS caps, not accepting");
        goto done;
      }
    }
    default:
      break;
  }
  ret = TRUE;
  GST_DEBUG_OBJECT (dsink, "Accepting caps");

done:
  gst_query_set_accept_caps_result (query, ret);
  return TRUE;
}

static gboolean
gst_directsound_sink_query (GstBaseSink * sink, GstQuery * query)
{
  gboolean res = TRUE;

  switch (GST_QUERY_TYPE (query)) {
    case GST_QUERY_ACCEPT_CAPS:
      res = gst_directsound_sink_acceptcaps (sink, query);
      break;
    default:
      res = GST_BASE_SINK_CLASS (parent_class)->query (sink, query);
  }

  return res;
}

static LPGUID
string_to_guid (const gchar * str)
{
  HRESULT ret;
  gunichar2 *wstr;
  LPGUID out;

  wstr = g_utf8_to_utf16 (str, -1, NULL, NULL, NULL);
  if (!wstr)
    return NULL;

  out = g_new (GUID, 1);
  ret = CLSIDFromString ((LPOLESTR) wstr, out);
  g_free (wstr);
  if (ret != NOERROR) {
    g_free (out);
    return NULL;
  }

  return out;
}

static gboolean
gst_directsound_sink_open (GstAudioSink * asink)
{
  GstDirectSoundSink *dsoundsink;
  HRESULT hRes;
  LPGUID lpGuid = NULL;

  dsoundsink = GST_DIRECTSOUND_SINK (asink);

  if (dsoundsink->device_id) {
    lpGuid = string_to_guid (dsoundsink->device_id);
    if (lpGuid == NULL) {
      GST_ELEMENT_ERROR (dsoundsink, RESOURCE, OPEN_READ,
          ("device set but guid not found: %s", dsoundsink->device_id), (NULL));
      return FALSE;
    }
  }

  /* create and initialize a DirectSound object */
  if (FAILED (hRes = DirectSoundCreate (lpGuid, &dsoundsink->pDS, NULL))) {
    gchar *error_text = gst_hres_to_string (hRes);
    GST_ELEMENT_ERROR (dsoundsink, RESOURCE, OPEN_READ,
        ("DirectSoundCreate: %s", error_text), (NULL));
    g_free (lpGuid);
    g_free (error_text);
    return FALSE;
  }

  g_free (lpGuid);

  if (FAILED (hRes = IDirectSound_SetCooperativeLevel (dsoundsink->pDS,
              GetDesktopWindow (), DSSCL_PRIORITY))) {
    gchar *error_text = gst_hres_to_string (hRes);
    GST_ELEMENT_ERROR (dsoundsink, RESOURCE, OPEN_READ,
        ("IDirectSound_SetCooperativeLevel: %s", error_text), (NULL));
    g_free (error_text);
    return FALSE;
  }

  return TRUE;
}

static gboolean
gst_directsound_sink_is_spdif_format (GstAudioRingBufferSpec * spec)
{
  return spec->type == GST_AUDIO_RING_BUFFER_FORMAT_TYPE_AC3 ||
      spec->type == GST_AUDIO_RING_BUFFER_FORMAT_TYPE_DTS;
}

static gboolean
gst_directsound_sink_prepare (GstAudioSink * asink,
    GstAudioRingBufferSpec * spec)
{
  GstDirectSoundSink *dsoundsink;
  HRESULT hRes;
  DSBUFFERDESC descSecondary;
  WAVEFORMATEX wfx;

  dsoundsink = GST_DIRECTSOUND_SINK (asink);

  /*save number of bytes per sample and buffer format */
  dsoundsink->bytes_per_sample = spec->info.bpf;
  dsoundsink->type = spec->type;

  /* fill the WAVEFORMATEX structure with spec params */
  memset (&wfx, 0, sizeof (wfx));
  if (!gst_directsound_sink_is_spdif_format (spec)) {
    wfx.cbSize = sizeof (wfx);
    wfx.wFormatTag = WAVE_FORMAT_PCM;
    wfx.nChannels = spec->info.channels;
    wfx.nSamplesPerSec = spec->info.rate;
    wfx.wBitsPerSample = (spec->info.bpf * 8) / wfx.nChannels;
    wfx.nBlockAlign = spec->info.bpf;
    wfx.nAvgBytesPerSec = wfx.nSamplesPerSec * wfx.nBlockAlign;

    /* Create directsound buffer with size based on our configured
     * buffer_size (which is 200 ms by default) */
    dsoundsink->buffer_size =
        gst_util_uint64_scale_int (wfx.nAvgBytesPerSec, spec->buffer_time,
        GST_MSECOND);
    /* Make sure we make those numbers multiple of our sample size in bytes */
    dsoundsink->buffer_size -= dsoundsink->buffer_size % spec->info.bpf;

    spec->segsize =
        gst_util_uint64_scale_int (wfx.nAvgBytesPerSec, spec->latency_time,
        GST_MSECOND);
    spec->segsize -= spec->segsize % spec->info.bpf;
    spec->segtotal = dsoundsink->buffer_size / spec->segsize;
  } else {
#ifdef WAVE_FORMAT_DOLBY_AC3_SPDIF
    wfx.cbSize = 0;
    wfx.wFormatTag = WAVE_FORMAT_DOLBY_AC3_SPDIF;
    wfx.nChannels = 2;
    wfx.nSamplesPerSec = 48000;
    wfx.wBitsPerSample = 16;
    wfx.nBlockAlign = wfx.wBitsPerSample / 8 * wfx.nChannels;
    wfx.nAvgBytesPerSec = wfx.nSamplesPerSec * wfx.nBlockAlign;

    spec->segsize = 6144;
    spec->segtotal = 10;
#else
    g_assert_not_reached ();
#endif
  }

  // Make the final buffer size be an integer number of segments
  dsoundsink->buffer_size = spec->segsize * spec->segtotal;

  GST_INFO_OBJECT (dsoundsink, "channels: %d, rate: %d, bytes_per_sample: %d"
      " WAVEFORMATEX.nSamplesPerSec: %ld, WAVEFORMATEX.wBitsPerSample: %d,"
      " WAVEFORMATEX.nBlockAlign: %d, WAVEFORMATEX.nAvgBytesPerSec: %ld\n"
      "Size of dsound circular buffer=>%d\n",
      GST_AUDIO_INFO_CHANNELS (&spec->info), GST_AUDIO_INFO_RATE (&spec->info),
      GST_AUDIO_INFO_BPF (&spec->info), wfx.nSamplesPerSec, wfx.wBitsPerSample,
      wfx.nBlockAlign, wfx.nAvgBytesPerSec, dsoundsink->buffer_size);

  /* create a secondary directsound buffer */
  memset (&descSecondary, 0, sizeof (DSBUFFERDESC));
  descSecondary.dwSize = sizeof (DSBUFFERDESC);
  descSecondary.dwFlags = DSBCAPS_GETCURRENTPOSITION2 | DSBCAPS_GLOBALFOCUS;
  if (!gst_directsound_sink_is_spdif_format (spec))
    descSecondary.dwFlags |= DSBCAPS_CTRLVOLUME;

  descSecondary.dwBufferBytes = dsoundsink->buffer_size;
  descSecondary.lpwfxFormat = (WAVEFORMATEX *) & wfx;

  hRes = IDirectSound_CreateSoundBuffer (dsoundsink->pDS, &descSecondary,
      &dsoundsink->pDSBSecondary, NULL);
  if (FAILED (hRes)) {
    gchar *error_text = gst_hres_to_string (hRes);
    GST_ELEMENT_ERROR (dsoundsink, RESOURCE, OPEN_READ,
        ("IDirectSound_CreateSoundBuffer: %s", error_text), (NULL));
    g_free (error_text);
    return FALSE;
  }

  gst_directsound_sink_set_volume (dsoundsink,
      gst_directsound_sink_get_volume (dsoundsink), FALSE);
  gst_directsound_sink_set_mute (dsoundsink, dsoundsink->mute);

  return TRUE;
}

static gboolean
gst_directsound_sink_unprepare (GstAudioSink * asink)
{
  GstDirectSoundSink *dsoundsink;

  dsoundsink = GST_DIRECTSOUND_SINK (asink);

  /* release secondary DirectSound buffer */
  if (dsoundsink->pDSBSecondary) {
    IDirectSoundBuffer_Release (dsoundsink->pDSBSecondary);
    dsoundsink->pDSBSecondary = NULL;
  }

  return TRUE;
}

static gboolean
gst_directsound_sink_close (GstAudioSink * asink)
{
  GstDirectSoundSink *dsoundsink = NULL;

  dsoundsink = GST_DIRECTSOUND_SINK (asink);

  /* release DirectSound object */
  g_return_val_if_fail (dsoundsink->pDS != NULL, FALSE);
  IDirectSound_Release (dsoundsink->pDS);
  dsoundsink->pDS = NULL;

  gst_caps_replace (&dsoundsink->cached_caps, NULL);

  return TRUE;
}

static gint
gst_directsound_sink_write (GstAudioSink * asink, gpointer data, guint length)
{
  GstDirectSoundSink *dsoundsink;
  DWORD dwStatus = 0;
  HRESULT hRes, hRes2;
  LPVOID pLockedBuffer1 = NULL, pLockedBuffer2 = NULL;
  DWORD dwSizeBuffer1, dwSizeBuffer2;
  DWORD dwCurrentPlayCursor;

  dsoundsink = GST_DIRECTSOUND_SINK (asink);

  GST_DSOUND_LOCK (dsoundsink);

  /* get current buffer status */
  hRes = IDirectSoundBuffer_GetStatus (dsoundsink->pDSBSecondary, &dwStatus);

  /* get current play cursor position */
  hRes2 = IDirectSoundBuffer_GetCurrentPosition (dsoundsink->pDSBSecondary,
      &dwCurrentPlayCursor, NULL);

  if (SUCCEEDED (hRes) && SUCCEEDED (hRes2) && (dwStatus & DSBSTATUS_PLAYING)) {
    DWORD dwFreeBufferSize = 0;
    GstClockTime sleep_time_ms = 0, sleep_until;
    GstClockID clock_id;

  calculate_freesize:
    /* Calculate the free space in the circular buffer */
    if (dwCurrentPlayCursor < dsoundsink->current_circular_offset)
      dwFreeBufferSize =
          dsoundsink->buffer_size - (dsoundsink->current_circular_offset -
          dwCurrentPlayCursor);
    else
      dwFreeBufferSize =
          dwCurrentPlayCursor - dsoundsink->current_circular_offset;

    /* Not enough free space, wait for some samples to be played out. We could
     * write out partial data, but that will result in a tight loop in the
     * audioringbuffer write thread, and lead to high CPU usage. */
    if (length > dwFreeBufferSize) {
      gint rate = GST_AUDIO_BASE_SINK (asink)->ringbuffer->spec.info.rate;
      /* Wait for a time proportional to the space needed. In reality, the
       * directsound sink's position does not update frequently enough, so we
       * will end up waiting for much longer. Note that Sleep() has millisecond
       * resolution at best. */
      sleep_time_ms = gst_util_uint64_scale_int ((length - dwFreeBufferSize),
          1000, dsoundsink->bytes_per_sample * rate);
      /* Make sure we don't run in a tight loop unnecessarily */
      sleep_time_ms = MAX (sleep_time_ms, 10);
      sleep_until = gst_clock_get_time (dsoundsink->system_clock) +
          sleep_time_ms * GST_MSECOND;

      GST_DEBUG_OBJECT (dsoundsink,
          "length: %u, FreeBufSiz: %ld, sleep_time_ms: %" G_GUINT64_FORMAT
          ", bps: %i, rate: %i", length, dwFreeBufferSize, sleep_time_ms,
          dsoundsink->bytes_per_sample, rate);

      if (G_UNLIKELY (dsoundsink->write_wait_clock_id == NULL ||
              gst_clock_single_shot_id_reinit (dsoundsink->system_clock,
                  dsoundsink->write_wait_clock_id, sleep_until) == FALSE)) {

        if (dsoundsink->write_wait_clock_id != NULL) {
          gst_clock_id_unref (dsoundsink->write_wait_clock_id);
        }

        dsoundsink->write_wait_clock_id =
            gst_clock_new_single_shot_id (dsoundsink->system_clock,
            sleep_until);
      }

      clock_id = dsoundsink->write_wait_clock_id;
      dsoundsink->reset_while_sleeping = FALSE;

      GST_DSOUND_UNLOCK (dsoundsink);

      /* don't bother with the return value as we'll detect reset separately,
         as reset could happen between when this returns and we obtain the lock
         again -- so we can't use UNSCHEDULED here */
      gst_clock_id_wait (clock_id, NULL);

      GST_DSOUND_LOCK (dsoundsink);

      /* if a reset occurs, exit now */
      if (dsoundsink->reset_while_sleeping == TRUE) {
        GST_DSOUND_UNLOCK (dsoundsink);
        return -1;
      }

      /* May we send out? */
      hRes = IDirectSoundBuffer_GetCurrentPosition (dsoundsink->pDSBSecondary,
          &dwCurrentPlayCursor, NULL);
      hRes2 =
          IDirectSoundBuffer_GetStatus (dsoundsink->pDSBSecondary, &dwStatus);
      if (SUCCEEDED (hRes) && SUCCEEDED (hRes2)
          && (dwStatus & DSBSTATUS_PLAYING))
        goto calculate_freesize;
      else {
        gchar *err1, *err2;

        dsoundsink->first_buffer_after_reset = FALSE;
        GST_DSOUND_UNLOCK (dsoundsink);

        err1 = gst_hres_to_string (hRes);
        err2 = gst_hres_to_string (hRes2);
        GST_ELEMENT_ERROR (dsoundsink, RESOURCE, OPEN_WRITE,
            ("IDirectSoundBuffer_GetStatus %s, "
                "IDirectSoundBuffer_GetCurrentPosition: %s, dwStatus: %lu",
                err2, err1, dwStatus), (NULL));
        g_free (err1);
        g_free (err2);
        return -1;
      }
    }
  }

  if (dwStatus & DSBSTATUS_BUFFERLOST) {
    hRes = IDirectSoundBuffer_Restore (dsoundsink->pDSBSecondary);      /*need a loop waiting the buffer is restored?? */
    dsoundsink->current_circular_offset = 0;
  }

  /* Lock a buffer of length @length for writing */
  hRes = IDirectSoundBuffer_Lock (dsoundsink->pDSBSecondary,
      dsoundsink->current_circular_offset, length, &pLockedBuffer1,
      &dwSizeBuffer1, &pLockedBuffer2, &dwSizeBuffer2, 0L);

  if (SUCCEEDED (hRes)) {
    // Write to pointers without reordering.
    memcpy (pLockedBuffer1, data, dwSizeBuffer1);
    if (pLockedBuffer2 != NULL)
      memcpy (pLockedBuffer2, (LPBYTE) data + dwSizeBuffer1, dwSizeBuffer2);

    hRes = IDirectSoundBuffer_Unlock (dsoundsink->pDSBSecondary, pLockedBuffer1,
        dwSizeBuffer1, pLockedBuffer2, dwSizeBuffer2);

    // Update where the buffer will lock (for next time)
    dsoundsink->current_circular_offset += dwSizeBuffer1 + dwSizeBuffer2;
    dsoundsink->current_circular_offset %= dsoundsink->buffer_size;     /* Circular buffer */
  }

  /* if the buffer was not in playing state yet, call play on the buffer 
     except if this buffer is the fist after a reset (base class call reset and write a buffer when setting the sink to pause) */
  if (!(dwStatus & DSBSTATUS_PLAYING) &&
      dsoundsink->first_buffer_after_reset == FALSE) {
    hRes = IDirectSoundBuffer_Play (dsoundsink->pDSBSecondary, 0, 0,
        DSBPLAY_LOOPING);
  }

  dsoundsink->first_buffer_after_reset = FALSE;

  GST_DSOUND_UNLOCK (dsoundsink);

  return length;
}

static guint
gst_directsound_sink_delay (GstAudioSink * asink)
{
  GstDirectSoundSink *dsoundsink;
  HRESULT hRes;
  DWORD dwCurrentPlayCursor;
  DWORD dwBytesInQueue = 0;
  gint nNbSamplesInQueue = 0;
  DWORD dwStatus;

  dsoundsink = GST_DIRECTSOUND_SINK (asink);

  /* get current buffer status */
  hRes = IDirectSoundBuffer_GetStatus (dsoundsink->pDSBSecondary, &dwStatus);

  if (SUCCEEDED (hRes) && (dwStatus & DSBSTATUS_PLAYING)) {
    /*evaluate the number of samples in queue in the circular buffer */
    hRes = IDirectSoundBuffer_GetCurrentPosition (dsoundsink->pDSBSecondary,
        &dwCurrentPlayCursor, NULL);

    if (hRes == S_OK) {
      if (dwCurrentPlayCursor < dsoundsink->current_circular_offset)
        dwBytesInQueue =
            dsoundsink->current_circular_offset - dwCurrentPlayCursor;
      else
        dwBytesInQueue =
            dsoundsink->current_circular_offset + (dsoundsink->buffer_size -
            dwCurrentPlayCursor);

      nNbSamplesInQueue = dwBytesInQueue / dsoundsink->bytes_per_sample;
    }
  }

  return nNbSamplesInQueue;
}

static void
gst_directsound_sink_reset (GstAudioSink * asink)
{
  GstDirectSoundSink *dsoundsink;
  LPVOID pLockedBuffer = NULL;
  DWORD dwSizeBuffer = 0;

  dsoundsink = GST_DIRECTSOUND_SINK (asink);

  GST_DSOUND_LOCK (dsoundsink);

  if (dsoundsink->pDSBSecondary) {
    /*stop playing */
    HRESULT hRes = IDirectSoundBuffer_Stop (dsoundsink->pDSBSecondary);

    /*reset position */
    hRes = IDirectSoundBuffer_SetCurrentPosition (dsoundsink->pDSBSecondary, 0);
    dsoundsink->current_circular_offset = 0;

    /*reset the buffer */
    hRes = IDirectSoundBuffer_Lock (dsoundsink->pDSBSecondary,
        0, dsoundsink->buffer_size,
        &pLockedBuffer, &dwSizeBuffer, NULL, NULL, 0L);

    if (SUCCEEDED (hRes)) {
      memset (pLockedBuffer, 0, dwSizeBuffer);

      hRes =
          IDirectSoundBuffer_Unlock (dsoundsink->pDSBSecondary, pLockedBuffer,
          dwSizeBuffer, NULL, 0);
    }
  }

  dsoundsink->reset_while_sleeping = TRUE;
  dsoundsink->first_buffer_after_reset = TRUE;
  if (dsoundsink->write_wait_clock_id != NULL) {
    gst_clock_id_unschedule (dsoundsink->write_wait_clock_id);
  }

  GST_DSOUND_UNLOCK (dsoundsink);
}

/*
 * gst_directsound_probe_supported_formats:
 *
 * Takes the template caps and returns the subset which is actually
 * supported by this device.
 *
 */

static GstCaps *
gst_directsound_probe_supported_formats (GstDirectSoundSink * dsoundsink,
    const GstCaps * template_caps)
{
  HRESULT hRes;
  DSBUFFERDESC descSecondary;
  WAVEFORMATEX wfx;
  GstCaps *caps;
  GstCaps *tmp, *tmp2;
  LPDIRECTSOUNDBUFFER tmpBuffer;

  caps = gst_caps_copy (template_caps);

  /*
   * Check availability of digital output by trying to create an SPDIF buffer
   */

#ifdef WAVE_FORMAT_DOLBY_AC3_SPDIF
  /* fill the WAVEFORMATEX structure with some standard AC3 over SPDIF params */
  memset (&wfx, 0, sizeof (wfx));
  wfx.cbSize = 0;
  wfx.wFormatTag = WAVE_FORMAT_DOLBY_AC3_SPDIF;
  wfx.nChannels = 2;
  wfx.nSamplesPerSec = 48000;
  wfx.wBitsPerSample = 16;
  wfx.nBlockAlign = 4;
  wfx.nAvgBytesPerSec = wfx.nSamplesPerSec * wfx.nBlockAlign;

  // create a secondary directsound buffer
  memset (&descSecondary, 0, sizeof (DSBUFFERDESC));
  descSecondary.dwSize = sizeof (DSBUFFERDESC);
  descSecondary.dwFlags = DSBCAPS_GETCURRENTPOSITION2 | DSBCAPS_GLOBALFOCUS;
  descSecondary.dwBufferBytes = 6144;
  descSecondary.lpwfxFormat = &wfx;

  hRes = IDirectSound_CreateSoundBuffer (dsoundsink->pDS, &descSecondary,
      &tmpBuffer, NULL);
  if (FAILED (hRes)) {
    gchar *error_text = gst_hres_to_string (hRes);
    GST_INFO_OBJECT (dsoundsink, "AC3 passthrough not supported "
        "(IDirectSound_CreateSoundBuffer returned: %s)\n", error_text);
    g_free (error_text);
    tmp = gst_caps_new_empty_simple ("audio/x-ac3");
    tmp2 = gst_caps_subtract (caps, tmp);
    gst_caps_unref (tmp);
    gst_caps_unref (caps);
    caps = tmp2;
    tmp = gst_caps_new_empty_simple ("audio/x-dts");
    tmp2 = gst_caps_subtract (caps, tmp);
    gst_caps_unref (tmp);
    gst_caps_unref (caps);
    caps = tmp2;
  } else {
    GST_INFO_OBJECT (dsoundsink, "AC3 passthrough supported");
    hRes = IDirectSoundBuffer_Release (tmpBuffer);
    if (FAILED (hRes)) {
      gchar *error_text = gst_hres_to_string (hRes);
      GST_DEBUG_OBJECT (dsoundsink,
          "(IDirectSoundBuffer_Release returned: %s)\n", error_text);
      g_free (error_text);
    }
  }
#else
  tmp = gst_caps_new_empty_simple ("audio/x-ac3");
  tmp2 = gst_caps_subtract (caps, tmp);
  gst_caps_unref (tmp);
  gst_caps_unref (caps);
  caps = tmp2;
  tmp = gst_caps_new_empty_simple ("audio/x-dts");
  tmp2 = gst_caps_subtract (caps, tmp);
  gst_caps_unref (tmp);
  gst_caps_unref (caps);
  caps = tmp2;
#endif

  return caps;
}

static GstBuffer *
gst_directsound_sink_payload (GstAudioBaseSink * sink, GstBuffer * buf)
{
  if (gst_directsound_sink_is_spdif_format (&sink->ringbuffer->spec)) {
    gint framesize = gst_audio_iec61937_frame_size (&sink->ringbuffer->spec);
    GstBuffer *out;
    GstMapInfo infobuf, infoout;
    gboolean success;

    if (framesize <= 0)
      return NULL;

    out = gst_buffer_new_and_alloc (framesize);

    if (!gst_buffer_map (buf, &infobuf, GST_MAP_READWRITE)) {
      gst_buffer_unref (out);
      return NULL;
    }
    if (!gst_buffer_map (out, &infoout, GST_MAP_READWRITE)) {
      gst_buffer_unmap (buf, &infobuf);
      gst_buffer_unref (out);
      return NULL;
    }
    success = gst_audio_iec61937_payload (infobuf.data, infobuf.size,
        infoout.data, infoout.size, &sink->ringbuffer->spec, G_BYTE_ORDER);
    if (!success) {
      gst_buffer_unmap (out, &infoout);
      gst_buffer_unmap (buf, &infobuf);
      gst_buffer_unref (out);
      return NULL;
    }

    gst_buffer_copy_into (out, buf, GST_BUFFER_COPY_ALL, 0, -1);
    /* Fix endianness */
    _swab ((gchar *) infoout.data, (gchar *) infoout.data, infobuf.size);
    gst_buffer_unmap (out, &infoout);
    gst_buffer_unmap (buf, &infobuf);
    return out;
  } else
    return gst_buffer_ref (buf);
}

static void
gst_directsound_sink_set_volume (GstDirectSoundSink * dsoundsink,
    gdouble dvolume, gboolean store)
{
  glong volume;

  volume = dvolume * 100;
  if (store)
    dsoundsink->volume = volume;

  if (dsoundsink->pDSBSecondary) {
    /* DirectSound controls volume using units of 100th of a decibel,
     * ranging from -10000 to 0. We use a linear scale of 0 - 100
     * here, so remap.
     */
    long dsVolume;
    if (volume == 0 || dsoundsink->mute)
      dsVolume = -10000;
    else
      dsVolume = 100 * (long) (20 * log10 ((double) volume / 100.));
    dsVolume = CLAMP (dsVolume, -10000, 0);

    GST_DEBUG_OBJECT (dsoundsink,
        "Setting volume on secondary buffer to %d from %d", (int) dsVolume,
        (int) volume);
    IDirectSoundBuffer_SetVolume (dsoundsink->pDSBSecondary, dsVolume);
  }
}

gdouble
gst_directsound_sink_get_volume (GstDirectSoundSink * dsoundsink)
{
  return (gdouble) dsoundsink->volume / 100;
}

static void
gst_directsound_sink_set_mute (GstDirectSoundSink * dsoundsink, gboolean mute)
{
  if (mute) {
    gst_directsound_sink_set_volume (dsoundsink, 0, FALSE);
    dsoundsink->mute = TRUE;
  } else {
    gst_directsound_sink_set_volume (dsoundsink,
        gst_directsound_sink_get_volume (dsoundsink), FALSE);
    dsoundsink->mute = FALSE;
  }

}

static gboolean
gst_directsound_sink_get_mute (GstDirectSoundSink * dsoundsink)
{
  return dsoundsink->mute;
}

static const gchar *
gst_directsound_sink_get_device (GstDirectSoundSink * dsoundsink)
{
  return dsoundsink->device_id;
}

static void
gst_directsound_sink_set_device (GstDirectSoundSink * dsoundsink,
    const gchar * device_id)
{
  g_free (dsoundsink->device_id);
  dsoundsink->device_id = g_strdup (device_id);
}

/* Converts a HRESULT error to a text string
 * LPTSTR is either a */
static gchar *
gst_hres_to_string (HRESULT hRes)
{
  DWORD flags;
  gchar *ret_text;
  LPTSTR error_text = NULL;

  flags = FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_ALLOCATE_BUFFER
      | FORMAT_MESSAGE_IGNORE_INSERTS;
  FormatMessage (flags, NULL, hRes, MAKELANGID (LANG_NEUTRAL, SUBLANG_DEFAULT),
      (LPTSTR) & error_text, 0, NULL);

#ifdef UNICODE
  /* If UNICODE is defined, LPTSTR is LPWSTR which is UTF-16 */
  ret_text = g_utf16_to_utf8 (error_text, 0, NULL, NULL, NULL);
#else
  ret_text = g_strdup (error_text);
#endif

  LocalFree (error_text);
  return ret_text;
}
