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