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