/*
 * 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 device selection and check rate etc.
*/

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

#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>

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

  g_free (dsoundsrc->device_name);
  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_pad_template (gstelement_class,
      gst_static_pad_template_get (&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_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;
    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_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->device_guid = 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);

  if (pGUID && dsoundsrc && dsoundsrc->device_name &&
      !g_strcmp0 (dsoundsrc->device_name, strDesc)) {
    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);
    return FALSE;
  }

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

  return TRUE;
}

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

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

  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;

  /* Set the buffer size to two seconds. 
     This should never reached. 
   */
  dsoundsrc->buffer_size = wfx.nAvgBytesPerSec * 2;

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

  /* 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_DEBUG ("latency time: %" G_GUINT64_FORMAT " - buffer time: %"
      G_GUINT64_FORMAT, spec->latency_time, spec->buffer_time);

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

  /* Save the times */
  dsoundsrc->buffer_time = spec->buffer_time;
  dsoundsrc->latency_time = spec->latency_time;

  dsoundsrc->latency_size = (gint) wfx.nAvgBytesPerSec *
      dsoundsrc->latency_time / 1000000.0;

  spec->segsize = (guint) (((double) spec->buffer_time / 1000000.0) *
      wfx.nAvgBytesPerSec);

  /* just in case */
  if (spec->segsize < 1)
    spec->segsize = 1;

  spec->segtotal = GST_AUDIO_INFO_BPF (&spec->info) * 8 *
      (wfx.nAvgBytesPerSec / spec->segsize);

  GST_DEBUG_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_DEBUG_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;

  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);
    //    Sleep (dsoundsrc->latency_time/1000);
    GST_DEBUG_OBJECT (asrc, "capture started");
  }
  //  calculate_buffersize:
  while (length > dwBufferSize) {
    Sleep (dsoundsrc->latency_time / 1000);

    hRes =
        IDirectSoundCaptureBuffer_GetCurrentPosition (dsoundsrc->pDSBSecondary,
        &dwCurrentCaptureCursor, NULL);

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

    /* calculate the buffer */
    if (dwCurrentCaptureCursor < dsoundsrc->current_circular_offset) {
      dwBufferSize = dsoundsrc->buffer_size -
          (dsoundsrc->current_circular_offset - dwCurrentCaptureCursor);
    } else {
      dwBufferSize =
          dwCurrentCaptureCursor - dsoundsrc->current_circular_offset;
    }
  }                             // while (...

  /* Lock the buffer */
  hRes = IDirectSoundCaptureBuffer_Lock (dsoundsrc->pDSBSecondary,
      dsoundsrc->current_circular_offset,
      length,
      &pLockedBuffer1, &dwSizeBuffer1, &pLockedBuffer2, &dwSizeBuffer2, 0L);

  /* 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);

  /* return length (readed data size in bytes) */
  return length;
}

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

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

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

#if 0
  IDirectSoundCaptureBuffer_Stop (dsoundsrc->pDSBSecondary);
#endif

  GST_DSOUND_LOCK (dsoundsrc);

  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 (GPOINTER_TO_UINT (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;
}
