/* GStreamer
* Copyright (C) 2005 Sebastien Moutte <sebastien@moutte.net>
*
* gstwaveformsink.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., 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*/

/**
 * SECTION:element-waveformsink
 *
 * This element lets you output sound using the Windows WaveForm 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 -v audiotestsrc ! audioconvert ! volume volume=0.1 ! waveformsink
 * ]| will output a sine wave (continuous beep sound) to your sound card (with
 * a very low volume as precaution).
 * |[
 * gst-launch -v filesrc location=music.ogg ! decodebin ! audioconvert ! audioresample ! waveformsink
 * ]| will play an Ogg/Vorbis audio file and output it.
 * </refsect2>
 */

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

#include "gstwaveformsink.h"

GST_DEBUG_CATEGORY_STATIC (waveformsink_debug);

static void gst_waveform_sink_finalise (GObject * object);
static void gst_waveform_sink_set_property (GObject * object,
    guint prop_id, const GValue * value, GParamSpec * pspec);
static void gst_waveform_sink_get_property (GObject * object,
    guint prop_id, GValue * value, GParamSpec * pspec);
static GstCaps *gst_waveform_sink_getcaps (GstBaseSink * bsink,
    GstCaps * filter);

/************************************************************************/
/* GstAudioSink functions                                               */
/************************************************************************/
static gboolean gst_waveform_sink_prepare (GstAudioSink * asink,
    GstAudioRingBufferSpec * spec);
static gboolean gst_waveform_sink_unprepare (GstAudioSink * asink);
static gboolean gst_waveform_sink_open (GstAudioSink * asink);
static gboolean gst_waveform_sink_close (GstAudioSink * asink);
static gint gst_waveform_sink_write (GstAudioSink * asink, gpointer data,
    guint length);
static guint gst_waveform_sink_delay (GstAudioSink * asink);
static void gst_waveform_sink_reset (GstAudioSink * asink);

/************************************************************************/
/* Utils                                                                */
/************************************************************************/
GstCaps *gst_waveform_sink_create_caps (gint rate, gint channels,
    const gchar * format);
WAVEHDR *bufferpool_get_buffer (GstWaveFormSink * wfsink, gpointer data,
    guint length);
void CALLBACK waveOutProc (HWAVEOUT hwo, UINT uMsg, DWORD_PTR dwInstance,
    DWORD_PTR dwParam1, DWORD_PTR dwParam2);

static GstStaticPadTemplate waveformsink_sink_factory =
GST_STATIC_PAD_TEMPLATE ("sink",
    GST_PAD_SINK,
    GST_PAD_ALWAYS,
    GST_STATIC_CAPS ("audio/x-raw, "
        "format = (string) { " GST_AUDIO_NE (S16) ", S8 }, "
        "layout = (string) interleaved, "
        "rate = (int) [ 1, MAX ], " "channels = (int) [ 1, 2 ]"));

#define gst_waveform_sink_parent_class parent_class
G_DEFINE_TYPE (GstWaveFormSink, gst_waveform_sink, GST_TYPE_AUDIO_SINK);

static void
gst_waveform_sink_class_init (GstWaveFormSinkClass * klass)
{
  GObjectClass *gobject_class;
  GstBaseSinkClass *gstbasesink_class;
  GstAudioSinkClass *gstaudiosink_class;
  GstElementClass *element_class;

  gobject_class = (GObjectClass *) klass;
  gstbasesink_class = (GstBaseSinkClass *) klass;
  gstaudiosink_class = (GstAudioSinkClass *) klass;
  element_class = GST_ELEMENT_CLASS (klass);

  parent_class = g_type_class_peek_parent (klass);

  gobject_class->finalize = gst_waveform_sink_finalise;
  gobject_class->get_property = gst_waveform_sink_get_property;
  gobject_class->set_property = gst_waveform_sink_set_property;

  gstbasesink_class->get_caps = GST_DEBUG_FUNCPTR (gst_waveform_sink_getcaps);

  gstaudiosink_class->prepare = GST_DEBUG_FUNCPTR (gst_waveform_sink_prepare);
  gstaudiosink_class->unprepare =
      GST_DEBUG_FUNCPTR (gst_waveform_sink_unprepare);
  gstaudiosink_class->open = GST_DEBUG_FUNCPTR (gst_waveform_sink_open);
  gstaudiosink_class->close = GST_DEBUG_FUNCPTR (gst_waveform_sink_close);
  gstaudiosink_class->write = GST_DEBUG_FUNCPTR (gst_waveform_sink_write);
  gstaudiosink_class->delay = GST_DEBUG_FUNCPTR (gst_waveform_sink_delay);
  gstaudiosink_class->reset = GST_DEBUG_FUNCPTR (gst_waveform_sink_reset);

  GST_DEBUG_CATEGORY_INIT (waveformsink_debug, "waveformsink", 0,
      "Waveform sink");

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

  gst_element_class_add_pad_template (element_class,
      gst_static_pad_template_get (&waveformsink_sink_factory));
}

static void
gst_waveform_sink_set_property (GObject * object, guint prop_id,
    const GValue * value, GParamSpec * pspec)
{
  /* GstWaveFormSink *wfsink = GST_WAVEFORM_SINK (object); */

  switch (prop_id) {
    default:
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
      break;
  }
}

static void
gst_waveform_sink_get_property (GObject * object, guint prop_id,
    GValue * value, GParamSpec * pspec)
{
  /* GstWaveFormSink *wfsink = GST_WAVEFORM_SINK (object); */

  switch (prop_id) {
    default:
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
      break;
  }
}

static void
gst_waveform_sink_init (GstWaveFormSink * wfsink)
{
  /* initialize members */
  wfsink->hwaveout = NULL;
  wfsink->cached_caps = NULL;
  wfsink->wave_buffers = NULL;
  wfsink->write_buffer = 0;
  wfsink->buffer_count = BUFFER_COUNT;
  wfsink->buffer_size = BUFFER_SIZE;
  wfsink->free_buffers_count = wfsink->buffer_count;
  wfsink->bytes_in_queue = 0;

  InitializeCriticalSection (&wfsink->critic_wave);
}

static void
gst_waveform_sink_finalise (GObject * object)
{
  GstWaveFormSink *wfsink = GST_WAVEFORM_SINK (object);

  if (wfsink->cached_caps) {
    gst_caps_unref (wfsink->cached_caps);
    wfsink->cached_caps = NULL;
  }

  DeleteCriticalSection (&wfsink->critic_wave);

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

static GstCaps *
gst_waveform_sink_getcaps (GstBaseSink * bsink, GstCaps * filter)
{
  GstWaveFormSink *wfsink = GST_WAVEFORM_SINK (bsink);
  MMRESULT mmresult;
  WAVEOUTCAPS wocaps;
  GstCaps *caps, *caps_temp;

  /* return the cached caps if already defined */
  if (wfsink->cached_caps) {
    return gst_caps_ref (wfsink->cached_caps);
  }

  /* get the default device caps */
  mmresult = waveOutGetDevCaps (WAVE_MAPPER, &wocaps, sizeof (wocaps));
  if (mmresult != MMSYSERR_NOERROR) {
    waveOutGetErrorText (mmresult, wfsink->error_string, ERROR_LENGTH - 1);
    GST_ELEMENT_ERROR (wfsink, RESOURCE, SETTINGS,
        ("gst_waveform_sink_getcaps: waveOutGetDevCaps failed error=>%s",
            wfsink->error_string), (NULL));
    return NULL;
  }

  caps = gst_caps_new_empty ();

  /* create a caps for all wave formats supported by the device 
     starting by the best quality format */
  if (wocaps.dwFormats & WAVE_FORMAT_96S16) {
    caps_temp = gst_waveform_sink_create_caps (96000, 2, GST_AUDIO_NE (S16));
    if (caps_temp) {
      gst_caps_append (caps, caps_temp);
    }
  }
  if (wocaps.dwFormats & WAVE_FORMAT_96S08) {
    caps_temp = gst_waveform_sink_create_caps (96000, 2, "S8");
    if (caps_temp) {
      gst_caps_append (caps, caps_temp);
    }
  }
  if (wocaps.dwFormats & WAVE_FORMAT_96M16) {
    caps_temp = gst_waveform_sink_create_caps (96000, 1, GST_AUDIO_NE (S16));
    if (caps_temp) {
      gst_caps_append (caps, caps_temp);
    }
  }
  if (wocaps.dwFormats & WAVE_FORMAT_96M08) {
    caps_temp = gst_waveform_sink_create_caps (96000, 1, "S8");
    if (caps_temp) {
      gst_caps_append (caps, caps_temp);
    }
  }
  if (wocaps.dwFormats & WAVE_FORMAT_4S16) {
    caps_temp = gst_waveform_sink_create_caps (44100, 2, GST_AUDIO_NE (S16));
    if (caps_temp) {
      gst_caps_append (caps, caps_temp);
    }
  }
  if (wocaps.dwFormats & WAVE_FORMAT_4S08) {
    caps_temp = gst_waveform_sink_create_caps (44100, 2, "S8");
    if (caps_temp) {
      gst_caps_append (caps, caps_temp);
    }
  }
  if (wocaps.dwFormats & WAVE_FORMAT_4M16) {
    caps_temp = gst_waveform_sink_create_caps (44100, 1, GST_AUDIO_NE (S16));
    if (caps_temp) {
      gst_caps_append (caps, caps_temp);
    }
  }
  if (wocaps.dwFormats & WAVE_FORMAT_4M08) {
    caps_temp = gst_waveform_sink_create_caps (44100, 1, "S8");
    if (caps_temp) {
      gst_caps_append (caps, caps_temp);
    }
  }
  if (wocaps.dwFormats & WAVE_FORMAT_2S16) {
    caps_temp = gst_waveform_sink_create_caps (22050, 2, GST_AUDIO_NE (S16));
    if (caps_temp) {
      gst_caps_append (caps, caps_temp);
    }
  }
  if (wocaps.dwFormats & WAVE_FORMAT_2S08) {
    caps_temp = gst_waveform_sink_create_caps (22050, 2, "S8");
    if (caps_temp) {
      gst_caps_append (caps, caps_temp);
    }
  }
  if (wocaps.dwFormats & WAVE_FORMAT_2M16) {
    caps_temp = gst_waveform_sink_create_caps (22050, 1, GST_AUDIO_NE (S16));
    if (caps_temp) {
      gst_caps_append (caps, caps_temp);
    }
  }
  if (wocaps.dwFormats & WAVE_FORMAT_2M08) {
    caps_temp = gst_waveform_sink_create_caps (22050, 1, "S8");
    if (caps_temp) {
      gst_caps_append (caps, caps_temp);
    }
  }
  if (wocaps.dwFormats & WAVE_FORMAT_1S16) {
    caps_temp = gst_waveform_sink_create_caps (11025, 2, GST_AUDIO_NE (S16));
    if (caps_temp) {
      gst_caps_append (caps, caps_temp);
    }
  }
  if (wocaps.dwFormats & WAVE_FORMAT_1S08) {
    caps_temp = gst_waveform_sink_create_caps (11025, 2, "S8");
    if (caps_temp) {
      gst_caps_append (caps, caps_temp);
    }
  }
  if (wocaps.dwFormats & WAVE_FORMAT_1M16) {
    caps_temp = gst_waveform_sink_create_caps (11025, 1, GST_AUDIO_NE (S16));
    if (caps_temp) {
      gst_caps_append (caps, caps_temp);
    }
  }
  if (wocaps.dwFormats & WAVE_FORMAT_1M08) {
    caps_temp = gst_waveform_sink_create_caps (11025, 1, "S8");
    if (caps_temp) {
      gst_caps_append (caps, caps_temp);
    }
  }

  if (gst_caps_is_empty (caps)) {
    gst_caps_unref (caps);
    caps = NULL;
  } else {
    wfsink->cached_caps = gst_caps_ref (caps);
  }

  GST_CAT_LOG_OBJECT (waveformsink_debug, wfsink, "Returning caps %s",
      gst_caps_to_string (caps));

  return caps;
}

static gboolean
gst_waveform_sink_open (GstAudioSink * asink)
{
  /* GstWaveFormSink *wfsink = GST_WAVEFORM_SINK (asink); */

  /* nothing to do here as the device needs to be opened with the format we will use */

  return TRUE;
}

static gboolean
gst_waveform_sink_prepare (GstAudioSink * asink, GstAudioRingBufferSpec * spec)
{
  GstWaveFormSink *wfsink = GST_WAVEFORM_SINK (asink);
  WAVEFORMATEX wfx;
  MMRESULT mmresult;
  guint index;

  /* setup waveformex struture with the input ringbuffer specs */
  memset (&wfx, 0, sizeof (wfx));
  wfx.cbSize = 0;
  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;

  /* save bytes per sample to use it in delay */
  wfsink->bytes_per_sample = spec->info.bpf;

  /* open the default audio device with the given caps */
  mmresult = waveOutOpen (&wfsink->hwaveout, WAVE_MAPPER,
      &wfx, (DWORD_PTR) waveOutProc, (DWORD_PTR) wfsink, CALLBACK_FUNCTION);
  if (mmresult != MMSYSERR_NOERROR) {
    waveOutGetErrorText (mmresult, wfsink->error_string, ERROR_LENGTH - 1);
    GST_ELEMENT_ERROR (wfsink, RESOURCE, OPEN_WRITE,
        ("gst_waveform_sink_prepare: waveOutOpen failed error=>%s",
            wfsink->error_string), (NULL));
    return FALSE;
  }

  /* evaluate the buffer size and the number of buffers needed */
  wfsink->free_buffers_count = wfsink->buffer_count;

  /* allocate wave buffers */
  wfsink->wave_buffers = (WAVEHDR *) g_new0 (WAVEHDR, wfsink->buffer_count);
  if (!wfsink->wave_buffers) {
    GST_ELEMENT_ERROR (wfsink, RESOURCE, OPEN_WRITE,
        ("gst_waveform_sink_prepare: Failed to allocate wave buffer headers (buffer count=%d)",
            wfsink->buffer_count), (NULL));
    return FALSE;
  }
  memset (wfsink->wave_buffers, 0, sizeof (WAVEHDR) * wfsink->buffer_count);

  /* setup headers */
  for (index = 0; index < wfsink->buffer_count; index++) {
    wfsink->wave_buffers[index].dwBufferLength = wfsink->buffer_size;
    wfsink->wave_buffers[index].lpData = g_new0 (gchar, wfsink->buffer_size);
  }

  return TRUE;
}

static gboolean
gst_waveform_sink_unprepare (GstAudioSink * asink)
{
  GstWaveFormSink *wfsink = GST_WAVEFORM_SINK (asink);

  /* free wave buffers */
  if (wfsink->wave_buffers) {
    guint index;

    for (index = 0; index < wfsink->buffer_count; index++) {
      if (wfsink->wave_buffers[index].dwFlags & WHDR_PREPARED) {
        MMRESULT mmresult = waveOutUnprepareHeader (wfsink->hwaveout,
            &wfsink->wave_buffers[index], sizeof (WAVEHDR));
        if (mmresult != MMSYSERR_NOERROR) {
          waveOutGetErrorText (mmresult, wfsink->error_string,
              ERROR_LENGTH - 1);
          GST_CAT_WARNING_OBJECT (waveformsink_debug, wfsink,
              "gst_waveform_sink_unprepare: Error unpreparing buffer => %s",
              wfsink->error_string);
        }
      }
      g_free (wfsink->wave_buffers[index].lpData);
    }
    g_free (wfsink->wave_buffers);
    wfsink->wave_buffers = NULL;
  }

  /* close waveform-audio output device */
  if (wfsink->hwaveout) {
    waveOutClose (wfsink->hwaveout);
    wfsink->hwaveout = NULL;
  }

  return TRUE;
}

static gboolean
gst_waveform_sink_close (GstAudioSink * asink)
{
  /* GstWaveFormSink *wfsink = GST_WAVEFORM_SINK (asink); */

  return TRUE;
}

static gint
gst_waveform_sink_write (GstAudioSink * asink, gpointer data, guint length)
{
  GstWaveFormSink *wfsink = GST_WAVEFORM_SINK (asink);
  WAVEHDR *waveheader;
  MMRESULT mmresult;
  guint bytes_to_write = length;
  guint remaining_length = length;

  wfsink->bytes_in_queue += length;

  while (remaining_length > 0) {
    if (wfsink->free_buffers_count == 0) {
      /* no free buffer available, wait for one */
      Sleep (10);
      continue;
    }

    /* get the current write buffer header */
    waveheader = &wfsink->wave_buffers[wfsink->write_buffer];

    /* unprepare the header if needed */
    if (waveheader->dwFlags & WHDR_PREPARED) {
      mmresult =
          waveOutUnprepareHeader (wfsink->hwaveout, waveheader,
          sizeof (WAVEHDR));
      if (mmresult != MMSYSERR_NOERROR) {
        waveOutGetErrorText (mmresult, wfsink->error_string, ERROR_LENGTH - 1);
        GST_CAT_WARNING_OBJECT (waveformsink_debug, wfsink,
            "Error unpreparing buffer => %s", wfsink->error_string);
      }
    }

    if (wfsink->buffer_size - waveheader->dwUser >= remaining_length)
      bytes_to_write = remaining_length;
    else
      bytes_to_write = wfsink->buffer_size - waveheader->dwUser;

    memcpy (waveheader->lpData + waveheader->dwUser, data, bytes_to_write);
    waveheader->dwUser += bytes_to_write;
    remaining_length -= bytes_to_write;
    data = (guint8 *) data + bytes_to_write;

    if (waveheader->dwUser == wfsink->buffer_size) {
      /* we have filled a buffer, let's prepare it and next write it to the device */
      mmresult =
          waveOutPrepareHeader (wfsink->hwaveout, waveheader, sizeof (WAVEHDR));
      if (mmresult != MMSYSERR_NOERROR) {
        waveOutGetErrorText (mmresult, wfsink->error_string, ERROR_LENGTH - 1);
        GST_CAT_WARNING_OBJECT (waveformsink_debug, wfsink,
            "gst_waveform_sink_write: Error preparing header => %s",
            wfsink->error_string);
      }
      mmresult = waveOutWrite (wfsink->hwaveout, waveheader, sizeof (WAVEHDR));
      if (mmresult != MMSYSERR_NOERROR) {
        waveOutGetErrorText (mmresult, wfsink->error_string, ERROR_LENGTH - 1);
        GST_CAT_WARNING_OBJECT (waveformsink_debug, wfsink,
            "gst_waveform_sink_write: Error writting buffer to the device => %s",
            wfsink->error_string);
      }

      EnterCriticalSection (&wfsink->critic_wave);
      wfsink->free_buffers_count--;
      LeaveCriticalSection (&wfsink->critic_wave);

      wfsink->write_buffer++;
      wfsink->write_buffer %= wfsink->buffer_count;
      waveheader->dwUser = 0;
      wfsink->bytes_in_queue = 0;
      GST_CAT_LOG_OBJECT (waveformsink_debug, wfsink,
          "gst_waveform_sink_write: Writting a buffer to the device (free buffers remaining=%d, write buffer=%d)",
          wfsink->free_buffers_count, wfsink->write_buffer);
    }
  }

  return length;
}

static guint
gst_waveform_sink_delay (GstAudioSink * asink)
{
  /* return the number of samples in queue (device+internal queue) */
  GstWaveFormSink *wfsink = GST_WAVEFORM_SINK (asink);
  guint bytes_in_device =
      (wfsink->buffer_count - wfsink->free_buffers_count) * wfsink->buffer_size;
  guint delay =
      (bytes_in_device + wfsink->bytes_in_queue) / wfsink->bytes_per_sample;
  return delay;
}

static void
gst_waveform_sink_reset (GstAudioSink * asink)
{
  GstWaveFormSink *wfsink = GST_WAVEFORM_SINK (asink);
  MMRESULT mmresult = waveOutReset (wfsink->hwaveout);

  if (mmresult != MMSYSERR_NOERROR) {
    waveOutGetErrorText (mmresult, wfsink->error_string, ERROR_LENGTH - 1);
    GST_CAT_WARNING_OBJECT (waveformsink_debug, wfsink,
        "gst_waveform_sink_reset: Error reseting waveform-audio device => %s",
        wfsink->error_string);
  }
}

GstCaps *
gst_waveform_sink_create_caps (gint rate, gint channels, const gchar * format)
{
  GstCaps *caps = NULL;

  caps = gst_caps_new_simple ("audio/x-raw",
      "format", G_TYPE_STRING, format,
      "layout", G_TYPE_STRING, "interleaved",
      "channels", G_TYPE_INT, channels, "rate", G_TYPE_INT, rate, NULL);
  return caps;
}

void CALLBACK
waveOutProc (HWAVEOUT hwo,
    UINT uMsg, DWORD_PTR dwInstance, DWORD_PTR dwParam1, DWORD_PTR dwParam2)
{
  GstWaveFormSink *wfsink = (GstWaveFormSink *) dwInstance;

  if (uMsg == WOM_DONE) {
    EnterCriticalSection (&wfsink->critic_wave);
    wfsink->free_buffers_count++;
    LeaveCriticalSection (&wfsink->critic_wave);
  }
}
