/*
 * GStreamer
 * Copyright 2005 Thomas Vander Stichele <thomas@apestaart.org>
 * Copyright 2005 Ronald S. Bultje <rbultje@ronald.bitfreak.net>
 * Copyright 2005 S�bastien Moutte <sebastien@moutte.net>
 * Copyright 2006 Joni Valtanen <joni.valtanen@movial.fi>
 * 
 * Permission is hereby granted, free of charge, to any person obtaining a
 * copy of this software and associated documentation files (the "Software"),
 * to deal in the Software without restriction, including without limitation
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
 * and/or sell copies of the Software, and to permit persons to whom the
 * Software is furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
 * DEALINGS IN THE SOFTWARE.
 *
 * Alternatively, the contents of this file may be used under the
 * GNU Lesser General Public License Version 2.1 (the "LGPL"), in
 * which case the following provisions apply instead of the ones
 * mentioned above:
 *
 * 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.
 */

/*
  TODO: add mixer device init for selection by device-guid
*/

/**
 * SECTION:element-directsoundsrc
 * @title: directsoundsrc
 *
 * Reads audio data using the DirectSound API.
 *
 * ## Example pipelines
 * |[
 * gst-launch-1.0 -v directsoundsrc ! audioconvert ! vorbisenc ! oggmux ! filesink location=dsound.ogg
 * ]| Record from DirectSound and encode to Ogg/Vorbis.
 *
 */

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

#include <gst/gst.h>
#include <gst/audio/audio.h>
#include <gst/audio/gstaudiobasesrc.h>

#include "gstdirectsoundsrc.h"

#include <windows.h>
#include <dsound.h>
#include <mmsystem.h>
#include <stdio.h>

GST_DEBUG_CATEGORY_STATIC (directsoundsrc_debug);
#define GST_CAT_DEFAULT directsoundsrc_debug

/* defaults here */
#define DEFAULT_DEVICE 0
#define DEFAULT_MUTE FALSE

/* properties */
enum
{
  PROP_0,
  PROP_DEVICE_NAME,
  PROP_DEVICE,
  PROP_VOLUME,
  PROP_MUTE
};

static HRESULT (WINAPI * pDSoundCaptureCreate) (LPGUID,
    LPDIRECTSOUNDCAPTURE *, LPUNKNOWN);

static void gst_directsound_src_finalize (GObject * object);

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

static void gst_directsound_src_get_property (GObject * object,
    guint prop_id, GValue * value, GParamSpec * pspec);

static gboolean gst_directsound_src_open (GstAudioSrc * asrc);
static gboolean gst_directsound_src_close (GstAudioSrc * asrc);
static gboolean gst_directsound_src_prepare (GstAudioSrc * asrc,
    GstAudioRingBufferSpec * spec);
static gboolean gst_directsound_src_unprepare (GstAudioSrc * asrc);
static void gst_directsound_src_reset (GstAudioSrc * asrc);
static GstCaps *gst_directsound_src_getcaps (GstBaseSrc * bsrc,
    GstCaps * filter);

static guint gst_directsound_src_read (GstAudioSrc * asrc,
    gpointer data, guint length, GstClockTime * timestamp);

static void gst_directsound_src_dispose (GObject * object);

static guint gst_directsound_src_delay (GstAudioSrc * asrc);

static gboolean gst_directsound_src_mixer_find (GstDirectSoundSrc * dsoundsrc,
    MIXERCAPS * mixer_caps);
static void gst_directsound_src_mixer_init (GstDirectSoundSrc * dsoundsrc);

static gdouble gst_directsound_src_get_volume (GstDirectSoundSrc * dsoundsrc);
static void gst_directsound_src_set_volume (GstDirectSoundSrc * dsoundsrc,
    gdouble volume);

static gboolean gst_directsound_src_get_mute (GstDirectSoundSrc * dsoundsrc);
static void gst_directsound_src_set_mute (GstDirectSoundSrc * dsoundsrc,
    gboolean mute);

static const gchar *gst_directsound_src_get_device (GstDirectSoundSrc *
    dsoundsrc);
static void gst_directsound_src_set_device (GstDirectSoundSrc * dsoundsrc,
    const gchar * device_id);

static GstStaticPadTemplate directsound_src_src_factory =
GST_STATIC_PAD_TEMPLATE ("src",
    GST_PAD_SRC,
    GST_PAD_ALWAYS,
    GST_STATIC_CAPS ("audio/x-raw, "
        "format = (string) { S16LE, S8 }, "
        "layout = (string) interleaved, "
        "rate = (int) [ 1, MAX ], " "channels = (int) [ 1, 2 ]"));

#define gst_directsound_src_parent_class parent_class
G_DEFINE_TYPE_WITH_CODE (GstDirectSoundSrc, gst_directsound_src,
    GST_TYPE_AUDIO_SRC, G_IMPLEMENT_INTERFACE (GST_TYPE_STREAM_VOLUME, NULL)
    );

static void
gst_directsound_src_dispose (GObject * object)
{
  G_OBJECT_CLASS (parent_class)->dispose (object);
}

static void
gst_directsound_src_finalize (GObject * object)
{
  GstDirectSoundSrc *dsoundsrc = GST_DIRECTSOUND_SRC (object);

  g_mutex_clear (&dsoundsrc->dsound_lock);
  gst_object_unref (dsoundsrc->system_clock);
  if (dsoundsrc->read_wait_clock_id != NULL)
    gst_clock_id_unref (dsoundsrc->read_wait_clock_id);

  g_free (dsoundsrc->device_name);

  g_free (dsoundsrc->device_id);

  g_free (dsoundsrc->device_guid);

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

static void
gst_directsound_src_class_init (GstDirectSoundSrcClass * klass)
{
  GObjectClass *gobject_class;
  GstElementClass *gstelement_class;
  GstBaseSrcClass *gstbasesrc_class;
  GstAudioSrcClass *gstaudiosrc_class;

  gobject_class = (GObjectClass *) klass;
  gstelement_class = (GstElementClass *) klass;
  gstbasesrc_class = (GstBaseSrcClass *) klass;
  gstaudiosrc_class = (GstAudioSrcClass *) klass;

  GST_DEBUG_CATEGORY_INIT (directsoundsrc_debug, "directsoundsrc", 0,
      "DirectSound Src");

  GST_DEBUG ("initializing directsoundsrc class");

  gobject_class->finalize = GST_DEBUG_FUNCPTR (gst_directsound_src_finalize);
  gobject_class->dispose = GST_DEBUG_FUNCPTR (gst_directsound_src_dispose);
  gobject_class->get_property =
      GST_DEBUG_FUNCPTR (gst_directsound_src_get_property);
  gobject_class->set_property =
      GST_DEBUG_FUNCPTR (gst_directsound_src_set_property);

  gstbasesrc_class->get_caps = GST_DEBUG_FUNCPTR (gst_directsound_src_getcaps);

  gstaudiosrc_class->open = GST_DEBUG_FUNCPTR (gst_directsound_src_open);
  gstaudiosrc_class->close = GST_DEBUG_FUNCPTR (gst_directsound_src_close);
  gstaudiosrc_class->read = GST_DEBUG_FUNCPTR (gst_directsound_src_read);
  gstaudiosrc_class->prepare = GST_DEBUG_FUNCPTR (gst_directsound_src_prepare);
  gstaudiosrc_class->unprepare =
      GST_DEBUG_FUNCPTR (gst_directsound_src_unprepare);
  gstaudiosrc_class->delay = GST_DEBUG_FUNCPTR (gst_directsound_src_delay);
  gstaudiosrc_class->reset = GST_DEBUG_FUNCPTR (gst_directsound_src_reset);

  gst_element_class_set_static_metadata (gstelement_class,
      "DirectSound audio source", "Source/Audio",
      "Capture from a soundcard via DirectSound",
      "Joni Valtanen <joni.valtanen@movial.fi>");

  gst_element_class_add_static_pad_template (gstelement_class,
      &directsound_src_src_factory);

  g_object_class_install_property
      (gobject_class, PROP_DEVICE_NAME,
      g_param_spec_string ("device-name", "Device name",
          "Human-readable name of the sound device", NULL, G_PARAM_READWRITE));

  g_object_class_install_property (gobject_class,
      PROP_DEVICE,
      g_param_spec_string ("device", "Device",
          "DirectSound playback device as a GUID string (volume and mute will not work!)",
          NULL, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));

  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));
}

static GstCaps *
gst_directsound_src_getcaps (GstBaseSrc * bsrc, GstCaps * filter)
{
  GstCaps *caps = NULL;
  GST_DEBUG_OBJECT (bsrc, "get caps");

  caps = gst_pad_get_pad_template_caps (GST_BASE_SRC_PAD (bsrc));
  return caps;
}

static void
gst_directsound_src_set_property (GObject * object, guint prop_id,
    const GValue * value, GParamSpec * pspec)
{
  GstDirectSoundSrc *src = GST_DIRECTSOUND_SRC (object);
  GST_DEBUG ("set property");

  switch (prop_id) {
    case PROP_DEVICE_NAME:
      if (src->device_name) {
        g_free (src->device_name);
        src->device_name = NULL;
      }
      if (g_value_get_string (value)) {
        src->device_name = g_strdup (g_value_get_string (value));
      }
      break;
    case PROP_VOLUME:
      gst_directsound_src_set_volume (src, g_value_get_double (value));
      break;
    case PROP_MUTE:
      gst_directsound_src_set_mute (src, g_value_get_boolean (value));
      break;
    case PROP_DEVICE:
      gst_directsound_src_set_device (src, g_value_get_string (value));
      break;
    default:
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
      break;
  }
}

static void
gst_directsound_src_get_property (GObject * object, guint prop_id,
    GValue * value, GParamSpec * pspec)
{
  GstDirectSoundSrc *src = GST_DIRECTSOUND_SRC (object);

  GST_DEBUG ("get property");

  switch (prop_id) {
    case PROP_DEVICE_NAME:
      g_value_set_string (value, src->device_name);
      break;
    case PROP_DEVICE:
      g_value_set_string (value, gst_directsound_src_get_device (src));
      break;
    case PROP_VOLUME:
      g_value_set_double (value, gst_directsound_src_get_volume (src));
      break;
    case PROP_MUTE:
      g_value_set_boolean (value, gst_directsound_src_get_mute (src));
      break;
    default:
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
      break;
  }
}


/* initialize the new element
 * instantiate pads and add them to element
 * set functions
 * initialize structure
 */
static void
gst_directsound_src_init (GstDirectSoundSrc * src)
{
  GST_DEBUG_OBJECT (src, "initializing directsoundsrc");
  g_mutex_init (&src->dsound_lock);
  src->system_clock = gst_system_clock_obtain ();
  src->read_wait_clock_id = NULL;
  src->reset_while_sleeping = FALSE;
  src->device_guid = NULL;
  src->device_id = NULL;
  src->device_name = NULL;
  src->mixer = NULL;
  src->control_id_mute = -1;
  src->control_id_volume = -1;
  src->volume = 100;
  src->mute = FALSE;
}


/* Enumeration callback called by DirectSoundCaptureEnumerate.
 * Gets the GUID of request audio device
 */
static BOOL CALLBACK
gst_directsound_enum_callback (GUID * pGUID, TCHAR * strDesc,
    TCHAR * strDrvName, VOID * pContext)
{
  GstDirectSoundSrc *dsoundsrc = GST_DIRECTSOUND_SRC (pContext);
  gchar *driver, *description;

  description = g_locale_to_utf8 (strDesc, -1, NULL, NULL, NULL);
  if (!description) {
    GST_ERROR_OBJECT (dsoundsrc,
        "Failed to convert description from locale encoding to UTF8");
    return TRUE;
  }

  driver = g_locale_to_utf8 (strDrvName, -1, NULL, NULL, NULL);

  if (pGUID && dsoundsrc && dsoundsrc->device_name &&
      !g_strcmp0 (dsoundsrc->device_name, description)) {
    g_free (dsoundsrc->device_guid);
    dsoundsrc->device_guid = (GUID *) g_malloc0 (sizeof (GUID));
    memcpy (dsoundsrc->device_guid, pGUID, sizeof (GUID));
    GST_INFO_OBJECT (dsoundsrc, "found the requested audio device :%s",
        dsoundsrc->device_name);
    g_free (description);
    g_free (driver);
    return FALSE;
  }

  GST_INFO_OBJECT (dsoundsrc, "sound device names: %s, %s, requested device:%s",
      description, driver, dsoundsrc->device_name);

  g_free (description);
  g_free (driver);

  return TRUE;
}

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_src_open (GstAudioSrc * asrc)
{
  GstDirectSoundSrc *dsoundsrc;
  HRESULT hRes;                 /* Result for windows functions */

  GST_DEBUG_OBJECT (asrc, "opening directsoundsrc");

  dsoundsrc = GST_DIRECTSOUND_SRC (asrc);

  /* Open dsound.dll */
  dsoundsrc->DSoundDLL = LoadLibrary ("dsound.dll");
  if (!dsoundsrc->DSoundDLL) {
    goto dsound_open;
  }

  /* Building the DLL Calls */
  pDSoundCaptureCreate =
      (void *) GetProcAddress (dsoundsrc->DSoundDLL,
      TEXT ("DirectSoundCaptureCreate"));

  /* If everything is not ok */
  if (!pDSoundCaptureCreate) {
    goto capture_function;
  }

  if (dsoundsrc->device_id) {
    GST_DEBUG_OBJECT (asrc, "device id set to: %s ", dsoundsrc->device_id);
    dsoundsrc->device_guid = string_to_guid (dsoundsrc->device_id);
    if (dsoundsrc->device_guid == NULL) {
      GST_ELEMENT_ERROR (dsoundsrc, RESOURCE, OPEN_READ,
          ("gst_directsound_src_open: device set, but guid not found: %s",
              dsoundsrc->device_id), (NULL));
      g_free (dsoundsrc->device_guid);
      return FALSE;
    }
  } else {

    hRes = DirectSoundCaptureEnumerate ((LPDSENUMCALLBACK)
        gst_directsound_enum_callback, (VOID *) dsoundsrc);

    if (FAILED (hRes)) {
      goto capture_enumerate;
    }
  }
  /* Create capture object */
  hRes = pDSoundCaptureCreate (dsoundsrc->device_guid, &dsoundsrc->pDSC, NULL);


  if (FAILED (hRes)) {
    goto capture_object;
  }
  // mixer is only supported when device-id is not set
  if (!dsoundsrc->device_id) {
    gst_directsound_src_mixer_init (dsoundsrc);
  }

  return TRUE;

capture_function:
  {
    FreeLibrary (dsoundsrc->DSoundDLL);
    GST_ELEMENT_ERROR (dsoundsrc, RESOURCE, OPEN_READ,
        ("Unable to get capturecreate function"), (NULL));
    return FALSE;
  }
capture_enumerate:
  {
    FreeLibrary (dsoundsrc->DSoundDLL);
    GST_ELEMENT_ERROR (dsoundsrc, RESOURCE, OPEN_READ,
        ("Unable to enumerate audio capture devices"), (NULL));
    return FALSE;
  }
capture_object:
  {
    FreeLibrary (dsoundsrc->DSoundDLL);
    GST_ELEMENT_ERROR (dsoundsrc, RESOURCE, OPEN_READ,
        ("Unable to create capture object"), (NULL));
    return FALSE;
  }
dsound_open:
  {
    DWORD err = GetLastError ();
    GST_ELEMENT_ERROR (dsoundsrc, RESOURCE, OPEN_READ,
        ("Unable to open dsound.dll"), (NULL));
    g_print ("0x%lx\n", HRESULT_FROM_WIN32 (err));
    return FALSE;
  }
}

static gboolean
gst_directsound_src_close (GstAudioSrc * asrc)
{
  GstDirectSoundSrc *dsoundsrc;

  GST_DEBUG_OBJECT (asrc, "closing directsoundsrc");

  dsoundsrc = GST_DIRECTSOUND_SRC (asrc);

  /* Release capture handler  */
  IDirectSoundCapture_Release (dsoundsrc->pDSC);

  /* Close library */
  FreeLibrary (dsoundsrc->DSoundDLL);

  if (dsoundsrc->mixer)
    mixerClose (dsoundsrc->mixer);

  return TRUE;
}

static gboolean
gst_directsound_src_prepare (GstAudioSrc * asrc, GstAudioRingBufferSpec * spec)
{
  GstDirectSoundSrc *dsoundsrc;
  WAVEFORMATEX wfx;             /* Wave format structure */
  HRESULT hRes;                 /* Result for windows functions */
  DSCBUFFERDESC descSecondary;  /* Capturebuffer description */

  dsoundsrc = GST_DIRECTSOUND_SRC (asrc);

  GST_DEBUG_OBJECT (asrc, "preparing directsoundsrc");

  /* Define buffer */
  memset (&wfx, 0, sizeof (WAVEFORMATEX));
  wfx.wFormatTag = WAVE_FORMAT_PCM;
  wfx.nChannels = GST_AUDIO_INFO_CHANNELS (&spec->info);
  wfx.nSamplesPerSec = GST_AUDIO_INFO_RATE (&spec->info);
  wfx.wBitsPerSample = GST_AUDIO_INFO_BPF (&spec->info) * 8 / wfx.nChannels;
  wfx.nBlockAlign = GST_AUDIO_INFO_BPF (&spec->info);
  wfx.nAvgBytesPerSec = wfx.nSamplesPerSec * wfx.nBlockAlign;
  /* Ignored for WAVE_FORMAT_PCM. */
  wfx.cbSize = 0;

  if (wfx.wBitsPerSample != 16 && wfx.wBitsPerSample != 8)
    goto dodgy_width;

  GST_INFO_OBJECT (asrc, "latency time: %" G_GUINT64_FORMAT " - buffer time: %"
      G_GUINT64_FORMAT, spec->latency_time, spec->buffer_time);

  /* Buffer-time should always be >= 2*latency */
  if (spec->buffer_time < spec->latency_time * 2) {
    spec->buffer_time = spec->latency_time * 2;
    GST_WARNING ("buffer-time was less than 2*latency-time, clamping");
  }

  /* Set the buffer size from our configured buffer time (in microsecs) */
  dsoundsrc->buffer_size =
      gst_util_uint64_scale_int (spec->buffer_time, wfx.nAvgBytesPerSec,
      GST_SECOND / GST_USECOND);

  GST_INFO_OBJECT (asrc, "Buffer size: %d", dsoundsrc->buffer_size);

  spec->segsize =
      gst_util_uint64_scale (spec->latency_time, wfx.nAvgBytesPerSec,
      GST_SECOND / GST_USECOND);

  /* Sanitized segsize */
  if (spec->segsize < GST_AUDIO_INFO_BPF (&spec->info))
    spec->segsize = GST_AUDIO_INFO_BPF (&spec->info);
  else if (spec->segsize % GST_AUDIO_INFO_BPF (&spec->info) != 0)
    spec->segsize =
        ((spec->segsize + GST_AUDIO_INFO_BPF (&spec->info) -
            1) / GST_AUDIO_INFO_BPF (&spec->info)) *
        GST_AUDIO_INFO_BPF (&spec->info);
  spec->segtotal = dsoundsrc->buffer_size / spec->segsize;
  /* The device usually takes time = 1-2 segments to start producing buffers */
  spec->seglatency = spec->segtotal + 2;

  /* Fetch and set the actual latency time that will be used */
  dsoundsrc->latency_time =
      gst_util_uint64_scale (spec->segsize, GST_SECOND / GST_USECOND,
      GST_AUDIO_INFO_BPF (&spec->info) * GST_AUDIO_INFO_RATE (&spec->info));

  GST_INFO_OBJECT (asrc, "actual latency time: %" G_GUINT64_FORMAT,
      spec->latency_time);

  /* Init secondary buffer desciption */
  memset (&descSecondary, 0, sizeof (DSCBUFFERDESC));
  descSecondary.dwSize = sizeof (DSCBUFFERDESC);
  descSecondary.dwFlags = 0;
  descSecondary.dwReserved = 0;

  /* This is not primary buffer so have to set size  */
  descSecondary.dwBufferBytes = dsoundsrc->buffer_size;
  descSecondary.lpwfxFormat = &wfx;

  /* Create buffer */
  hRes = IDirectSoundCapture_CreateCaptureBuffer (dsoundsrc->pDSC,
      &descSecondary, &dsoundsrc->pDSBSecondary, NULL);
  if (hRes != DS_OK)
    goto capture_buffer;

  dsoundsrc->bytes_per_sample = GST_AUDIO_INFO_BPF (&spec->info);

  GST_INFO_OBJECT (asrc,
      "bytes/sec: %lu, buffer size: %d, segsize: %d, segtotal: %d",
      wfx.nAvgBytesPerSec, dsoundsrc->buffer_size, spec->segsize,
      spec->segtotal);

  /* Not read anything yet */
  dsoundsrc->current_circular_offset = 0;

  GST_INFO_OBJECT (asrc, "channels: %d, rate: %d, bytes_per_sample: %d"
      " WAVEFORMATEX.nSamplesPerSec: %ld, WAVEFORMATEX.wBitsPerSample: %d,"
      " WAVEFORMATEX.nBlockAlign: %d, WAVEFORMATEX.nAvgBytesPerSec: %ld",
      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);

  return TRUE;

capture_buffer:
  {
    GST_ELEMENT_ERROR (dsoundsrc, RESOURCE, OPEN_READ,
        ("Unable to create capturebuffer"), (NULL));
    return FALSE;
  }
dodgy_width:
  {
    GST_ELEMENT_ERROR (dsoundsrc, RESOURCE, OPEN_READ,
        ("Unexpected width %d", wfx.wBitsPerSample), (NULL));
    return FALSE;
  }
}

static gboolean
gst_directsound_src_unprepare (GstAudioSrc * asrc)
{
  GstDirectSoundSrc *dsoundsrc;

  GST_DEBUG_OBJECT (asrc, "unpreparing directsoundsrc");

  dsoundsrc = GST_DIRECTSOUND_SRC (asrc);

  GST_DSOUND_LOCK (dsoundsrc);

  /* Stop capturing */
  IDirectSoundCaptureBuffer_Stop (dsoundsrc->pDSBSecondary);

  /* Release buffer  */
  IDirectSoundCaptureBuffer_Release (dsoundsrc->pDSBSecondary);
  GST_DSOUND_UNLOCK (dsoundsrc);
  return TRUE;
}

/* 
return number of readed bytes */
static guint
gst_directsound_src_read (GstAudioSrc * asrc, gpointer data, guint length,
    GstClockTime * timestamp)
{
  GstDirectSoundSrc *dsoundsrc;
  guint64 sleep_time_ms, sleep_until;
  GstClockID clock_id;

  HRESULT hRes;                 /* Result for windows functions */
  DWORD dwCurrentCaptureCursor = 0;
  DWORD dwBufferSize = 0;

  LPVOID pLockedBuffer1 = NULL;
  LPVOID pLockedBuffer2 = NULL;
  DWORD dwSizeBuffer1 = 0;
  DWORD dwSizeBuffer2 = 0;

  DWORD dwStatus = 0;

  GST_DEBUG_OBJECT (asrc, "reading directsoundsrc");

  dsoundsrc = GST_DIRECTSOUND_SRC (asrc);

  GST_DSOUND_LOCK (dsoundsrc);

  /* Get current buffer status */
  hRes = IDirectSoundCaptureBuffer_GetStatus (dsoundsrc->pDSBSecondary,
      &dwStatus);

  if (FAILED (hRes)) {
    GST_DSOUND_UNLOCK (dsoundsrc);
    return -1;
  }

  /* Starting capturing if not already */
  if (!(dwStatus & DSCBSTATUS_CAPTURING)) {
    hRes = IDirectSoundCaptureBuffer_Start (dsoundsrc->pDSBSecondary,
        DSCBSTART_LOOPING);
    GST_INFO_OBJECT (asrc, "capture started");
  }

  /* Loop till the source has produced bytes equal to or greater than @length.
   *
   * DirectSound has a notification-based API that uses Windows CreateEvent()
   * + WaitForSingleObject(), but it is completely useless for live streams.
   *
   *  1. You must schedule all events before starting capture
   *  2. The events are all fired exactly once
   *  3. You cannot schedule new events while a capture is running
   *  4. You cannot stop/schedule/start either
   *
   * This means you cannot use the API while doing live looped capture and we
   * must resort to this.
   *
   * However, this is almost as efficient as event-based capture since it's ok
   * to consistently overwait by a fixed amount; the extra bytes will just end
   * up being used in the next call, and the extra latency will be constant. */
  while (TRUE) {
    hRes =
        IDirectSoundCaptureBuffer_GetCurrentPosition (dsoundsrc->pDSBSecondary,
        &dwCurrentCaptureCursor, NULL);

    if (FAILED (hRes)) {
      GST_DSOUND_UNLOCK (dsoundsrc);
      return -1;
    }

    /* calculate the size of the buffer that's been captured while accounting
     * for wrap-arounds */
    if (dwCurrentCaptureCursor < dsoundsrc->current_circular_offset) {
      dwBufferSize = dsoundsrc->buffer_size -
          (dsoundsrc->current_circular_offset - dwCurrentCaptureCursor);
    } else {
      dwBufferSize =
          dwCurrentCaptureCursor - dsoundsrc->current_circular_offset;
    }

    if (dwBufferSize >= length) {
      /* Yay, we got all the data we need */
      break;
    } else {
      GST_DEBUG_OBJECT (asrc, "not enough data, got %lu (want at least %u)",
          dwBufferSize, length);
      /* If we didn't get enough data, sleep for a proportionate time */
      sleep_time_ms = gst_util_uint64_scale (dsoundsrc->latency_time,
          length - dwBufferSize, length * 1000);
      /* Make sure we don't run in a tight loop unnecessarily */
      sleep_time_ms = MAX (sleep_time_ms, 10);
      /* Sleep using gst_clock_id_wait() so that we can be interrupted */
      sleep_until = gst_clock_get_time (dsoundsrc->system_clock) +
          sleep_time_ms * GST_MSECOND;
      /* Setup the clock id wait */
      if (G_UNLIKELY (dsoundsrc->read_wait_clock_id == NULL ||
              gst_clock_single_shot_id_reinit (dsoundsrc->system_clock,
                  dsoundsrc->read_wait_clock_id, sleep_until) == FALSE)) {
        if (dsoundsrc->read_wait_clock_id != NULL)
          gst_clock_id_unref (dsoundsrc->read_wait_clock_id);
        dsoundsrc->read_wait_clock_id =
            gst_clock_new_single_shot_id (dsoundsrc->system_clock, sleep_until);
      }

      clock_id = dsoundsrc->read_wait_clock_id;
      dsoundsrc->reset_while_sleeping = FALSE;

      GST_DEBUG_OBJECT (asrc, "waiting %" G_GUINT64_FORMAT "ms for more data",
          sleep_time_ms);
      GST_DSOUND_UNLOCK (dsoundsrc);

      gst_clock_id_wait (clock_id, NULL);

      GST_DSOUND_LOCK (dsoundsrc);

      if (dsoundsrc->reset_while_sleeping == TRUE) {
        GST_DEBUG_OBJECT (asrc, "reset while sleeping, cancelled read");
        GST_DSOUND_UNLOCK (dsoundsrc);
        return -1;
      }
    }
  }

  GST_DEBUG_OBJECT (asrc, "Got enough data: %lu bytes (wanted at least %u)",
      dwBufferSize, length);

  /* Lock the buffer and read only the first @length bytes. Keep the rest in
   * the capture buffer for the next read. */
  hRes = IDirectSoundCaptureBuffer_Lock (dsoundsrc->pDSBSecondary,
      dsoundsrc->current_circular_offset,
      length,
      &pLockedBuffer1, &dwSizeBuffer1, &pLockedBuffer2, &dwSizeBuffer2, 0L);

  /* NOTE: We now assume that dwSizeBuffer1 + dwSizeBuffer2 == length since the
   * API is supposed to guarantee that */

  /* Copy buffer data to another buffer */
  if (hRes == DS_OK) {
    memcpy (data, pLockedBuffer1, dwSizeBuffer1);
  }

  /* ...and if something is in another buffer */
  if (pLockedBuffer2 != NULL) {
    memcpy (((guchar *) data + dwSizeBuffer1), pLockedBuffer2, dwSizeBuffer2);
  }

  dsoundsrc->current_circular_offset += dwSizeBuffer1 + dwSizeBuffer2;
  dsoundsrc->current_circular_offset %= dsoundsrc->buffer_size;

  IDirectSoundCaptureBuffer_Unlock (dsoundsrc->pDSBSecondary,
      pLockedBuffer1, dwSizeBuffer1, pLockedBuffer2, dwSizeBuffer2);

  GST_DSOUND_UNLOCK (dsoundsrc);

  /* We always read exactly @length data */
  return length;
}

static guint
gst_directsound_src_delay (GstAudioSrc * asrc)
{
  GstDirectSoundSrc *dsoundsrc;
  HRESULT hRes;
  DWORD dwCurrentCaptureCursor;
  DWORD dwBytesInQueue = 0;
  gint nNbSamplesInQueue = 0;

  GST_INFO_OBJECT (asrc, "Delay");

  dsoundsrc = GST_DIRECTSOUND_SRC (asrc);

  /* evaluate the number of samples in queue in the circular buffer */
  hRes =
      IDirectSoundCaptureBuffer_GetCurrentPosition (dsoundsrc->pDSBSecondary,
      &dwCurrentCaptureCursor, NULL);
  /* FIXME: Check is this calculated right */
  if (hRes == S_OK) {
    if (dwCurrentCaptureCursor < dsoundsrc->current_circular_offset) {
      dwBytesInQueue =
          dsoundsrc->buffer_size - (dsoundsrc->current_circular_offset -
          dwCurrentCaptureCursor);
    } else {
      dwBytesInQueue =
          dwCurrentCaptureCursor - dsoundsrc->current_circular_offset;
    }

    nNbSamplesInQueue = dwBytesInQueue / dsoundsrc->bytes_per_sample;
  }

  GST_INFO_OBJECT (asrc, "Delay is %d samples", nNbSamplesInQueue);

  return nNbSamplesInQueue;
}

static void
gst_directsound_src_reset (GstAudioSrc * asrc)
{
  GstDirectSoundSrc *dsoundsrc;
  LPVOID pLockedBuffer = NULL;
  DWORD dwSizeBuffer = 0;

  GST_DEBUG_OBJECT (asrc, "reset directsoundsrc");

  dsoundsrc = GST_DIRECTSOUND_SRC (asrc);

  GST_DSOUND_LOCK (dsoundsrc);

  dsoundsrc->reset_while_sleeping = TRUE;
  /* Interrupt read sleep if required */
  if (dsoundsrc->read_wait_clock_id != NULL)
    gst_clock_id_unschedule (dsoundsrc->read_wait_clock_id);

  if (dsoundsrc->pDSBSecondary) {
    /*stop capturing */
    HRESULT hRes = IDirectSoundCaptureBuffer_Stop (dsoundsrc->pDSBSecondary);

    /*reset position */
    /*    hRes = IDirectSoundCaptureBuffer_SetCurrentPosition (dsoundsrc->pDSBSecondary, 0); */

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

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

      hRes =
          IDirectSoundCaptureBuffer_Unlock (dsoundsrc->pDSBSecondary,
          pLockedBuffer, dwSizeBuffer, NULL, 0);
    }
    dsoundsrc->current_circular_offset = 0;

  }

  GST_DSOUND_UNLOCK (dsoundsrc);
}

/* If the PROP_DEVICE_NAME is set, find the mixer related to device;
 * otherwise we get the default input mixer. */
static gboolean
gst_directsound_src_mixer_find (GstDirectSoundSrc * dsoundsrc,
    MIXERCAPS * mixer_caps)
{
  MMRESULT mmres;
  guint i, num_mixers;

  num_mixers = mixerGetNumDevs ();
  for (i = 0; i < num_mixers; i++) {
    mmres = mixerOpen (&dsoundsrc->mixer, i, 0L, 0L,
        MIXER_OBJECTF_MIXER | MIXER_OBJECTF_WAVEIN);

    if (mmres != MMSYSERR_NOERROR)
      continue;

    mmres = mixerGetDevCaps ((UINT_PTR) dsoundsrc->mixer,
        mixer_caps, sizeof (MIXERCAPS));

    if (mmres != MMSYSERR_NOERROR) {
      mixerClose (dsoundsrc->mixer);
      continue;
    }

    /* Get default mixer */
    if (dsoundsrc->device_name == NULL) {
      GST_DEBUG ("Got default input mixer: %s", mixer_caps->szPname);
      return TRUE;
    }

    if (g_strstr_len (dsoundsrc->device_name, -1, mixer_caps->szPname) != NULL) {
      GST_DEBUG ("Got requested input mixer: %s", mixer_caps->szPname);
      return TRUE;
    }

    /* Wrong mixer */
    mixerClose (dsoundsrc->mixer);
  }

  GST_DEBUG ("Can't find input mixer");
  return FALSE;
}

static void
gst_directsound_src_mixer_init (GstDirectSoundSrc * dsoundsrc)
{
  gint i, k;
  gboolean found_mic;
  MMRESULT mmres;
  MIXERCAPS mixer_caps;
  MIXERLINE mixer_line;
  MIXERLINECONTROLS ml_ctrl;
  PMIXERCONTROL pamixer_ctrls;

  if (!gst_directsound_src_mixer_find (dsoundsrc, &mixer_caps))
    goto mixer_init_fail;

  /* Find the MIXERLINE related to MICROPHONE */
  found_mic = FALSE;
  for (i = 0; i < mixer_caps.cDestinations && !found_mic; i++) {
    gint j, num_connections;

    mixer_line.cbStruct = sizeof (mixer_line);
    mixer_line.dwDestination = i;
    mmres = mixerGetLineInfo ((HMIXEROBJ) dsoundsrc->mixer,
        &mixer_line, MIXER_GETLINEINFOF_DESTINATION);

    if (mmres != MMSYSERR_NOERROR)
      goto mixer_init_fail;

    num_connections = mixer_line.cConnections;
    for (j = 0; j < num_connections && !found_mic; j++) {
      mixer_line.cbStruct = sizeof (mixer_line);
      mixer_line.dwDestination = i;
      mixer_line.dwSource = j;
      mmres = mixerGetLineInfo ((HMIXEROBJ) dsoundsrc->mixer,
          &mixer_line, MIXER_GETLINEINFOF_SOURCE);

      if (mmres != MMSYSERR_NOERROR)
        goto mixer_init_fail;

      if (mixer_line.dwComponentType == MIXERLINE_COMPONENTTYPE_SRC_MICROPHONE
          || mixer_line.dwComponentType == MIXERLINE_COMPONENTTYPE_SRC_LINE)
        found_mic = TRUE;
    }
  }

  if (found_mic == FALSE) {
    GST_DEBUG ("Can't find mixer line related to input");
    goto mixer_init_fail;
  }

  /* Get control associated with microphone audio line */
  pamixer_ctrls = g_malloc (sizeof (MIXERCONTROL) * mixer_line.cControls);
  ml_ctrl.cbStruct = sizeof (ml_ctrl);
  ml_ctrl.dwLineID = mixer_line.dwLineID;
  ml_ctrl.cControls = mixer_line.cControls;
  ml_ctrl.cbmxctrl = sizeof (MIXERCONTROL);
  ml_ctrl.pamxctrl = pamixer_ctrls;
  mmres = mixerGetLineControls ((HMIXEROBJ) dsoundsrc->mixer,
      &ml_ctrl, MIXER_GETLINECONTROLSF_ALL);

  /* Find control associated with volume and mute */
  for (k = 0; k < mixer_line.cControls; k++) {
    if (strstr (pamixer_ctrls[k].szName, "Volume") != NULL) {
      dsoundsrc->control_id_volume = pamixer_ctrls[k].dwControlID;
      dsoundsrc->dw_vol_max = pamixer_ctrls[k].Bounds.dwMaximum;
      dsoundsrc->dw_vol_min = pamixer_ctrls[k].Bounds.dwMinimum;
    } else if (strstr (pamixer_ctrls[k].szName, "Mute") != NULL) {
      dsoundsrc->control_id_mute = pamixer_ctrls[k].dwControlID;
    } else {
      GST_DEBUG ("Control not handled: %s", pamixer_ctrls[k].szName);
    }
  }
  g_free (pamixer_ctrls);

  if (dsoundsrc->control_id_volume < 0 && dsoundsrc->control_id_mute < 0)
    goto mixer_init_fail;

  /* Save cChannels information to properly changes in volume */
  dsoundsrc->mixerline_cchannels = mixer_line.cChannels;
  return;

mixer_init_fail:
  GST_WARNING ("Failed to get Volume and Mute controls");
  if (dsoundsrc->mixer != NULL) {
    mixerClose (dsoundsrc->mixer);
    dsoundsrc->mixer = NULL;
  }
}

static gdouble
gst_directsound_src_get_volume (GstDirectSoundSrc * dsoundsrc)
{
  return (gdouble) dsoundsrc->volume / 100;
}

static gboolean
gst_directsound_src_get_mute (GstDirectSoundSrc * dsoundsrc)
{
  return dsoundsrc->mute;
}

static void
gst_directsound_src_set_volume (GstDirectSoundSrc * dsoundsrc, gdouble volume)
{
  MMRESULT mmres;
  MIXERCONTROLDETAILS details;
  MIXERCONTROLDETAILS_UNSIGNED details_unsigned;
  glong dwvolume;

  if (dsoundsrc->mixer == NULL || dsoundsrc->control_id_volume < 0) {
    GST_WARNING ("mixer not initialized");
    return;
  }

  dwvolume = volume * dsoundsrc->dw_vol_max;
  dwvolume = CLAMP (dwvolume, dsoundsrc->dw_vol_min, dsoundsrc->dw_vol_max);

  GST_DEBUG ("max volume %ld | min volume %ld",
      dsoundsrc->dw_vol_max, dsoundsrc->dw_vol_min);
  GST_DEBUG ("set volume to %f (%ld)", volume, dwvolume);

  details.cbStruct = sizeof (details);
  details.dwControlID = dsoundsrc->control_id_volume;
  details.cChannels = dsoundsrc->mixerline_cchannels;
  details.cMultipleItems = 0;

  details_unsigned.dwValue = dwvolume;
  details.cbDetails = sizeof (MIXERCONTROLDETAILS_UNSIGNED);
  details.paDetails = &details_unsigned;

  mmres = mixerSetControlDetails ((HMIXEROBJ) dsoundsrc->mixer,
      &details, MIXER_OBJECTF_HMIXER | MIXER_SETCONTROLDETAILSF_VALUE);

  if (mmres != MMSYSERR_NOERROR)
    GST_WARNING ("Failed to set volume");
  else
    dsoundsrc->volume = volume * 100;
}

static void
gst_directsound_src_set_mute (GstDirectSoundSrc * dsoundsrc, gboolean mute)
{
  MMRESULT mmres;
  MIXERCONTROLDETAILS details;
  MIXERCONTROLDETAILS_BOOLEAN details_boolean;

  if (dsoundsrc->mixer == NULL || dsoundsrc->control_id_mute < 0) {
    GST_WARNING ("mixer not initialized");
    return;
  }

  details.cbStruct = sizeof (details);
  details.dwControlID = dsoundsrc->control_id_mute;
  details.cChannels = dsoundsrc->mixerline_cchannels;
  details.cMultipleItems = 0;

  details_boolean.fValue = mute;
  details.cbDetails = sizeof (MIXERCONTROLDETAILS_BOOLEAN);
  details.paDetails = &details_boolean;

  mmres = mixerSetControlDetails ((HMIXEROBJ) dsoundsrc->mixer,
      &details, MIXER_OBJECTF_HMIXER | MIXER_SETCONTROLDETAILSF_VALUE);

  if (mmres != MMSYSERR_NOERROR)
    GST_WARNING ("Failed to set mute");
  else
    dsoundsrc->mute = mute;
}

static const gchar *
gst_directsound_src_get_device (GstDirectSoundSrc * dsoundsrc)
{
  return dsoundsrc->device_id;
}

static void
gst_directsound_src_set_device (GstDirectSoundSrc * dsoundsrc,
    const gchar * device_id)
{
  g_free (dsoundsrc->device_id);
  dsoundsrc->device_id = g_strdup (device_id);
}
