/* 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., 51 Franklin St, Fifth Floor,
* Boston, MA 02110-1301, 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-1.0 -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-1.0 -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_static_pad_template (element_class,
      &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 %" GST_PTR_FORMAT, 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);
  }
}
