/* GStreamer libsndfile plugin
 * Copyright (C) 1999,2000 Erik Walthinsen <omega@cse.ogi.edu>
 *               2000,2005 Wim Taymans <wim@fluendo.com>
 *               2003,2007 Andy Wingo <wingo@pobox.com>
 *
 * gstsfsrc.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.
 */

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

#include <gst/gst-i18n-plugin.h>

#include "gstsfsrc.h"

enum
{
  PROP_0,
  PROP_LOCATION
};

static GstStaticPadTemplate sf_src_factory = GST_STATIC_PAD_TEMPLATE ("src",
    GST_PAD_SRC,
    GST_PAD_ALWAYS,
    GST_STATIC_CAPS ("audio/x-raw-float, "
        "rate = (int) [ 1, MAX ], "
        "channels = (int) [ 1, MAX ], "
        "endianness = (int) BYTE_ORDER, "
        "width = (int) 32; "
        "audio/x-raw-int, "
        "rate = (int) [ 1, MAX ], "
        "channels = (int) [ 1, MAX ], "
        "endianness = (int) BYTE_ORDER, "
        "width = (int) {16, 32}, "
        "depth = (int) {16, 32}, " "signed = (boolean) true")
    );


GST_DEBUG_CATEGORY_STATIC (gst_sf_src_debug);
#define GST_CAT_DEFAULT gst_sf_src_debug


#define DEFAULT_BUFFER_FRAMES	(256)


static void gst_sf_src_finalize (GObject * object);
static void gst_sf_src_set_property (GObject * object, guint prop_id,
    const GValue * value, GParamSpec * pspec);
static void gst_sf_src_get_property (GObject * object, guint prop_id,
    GValue * value, GParamSpec * pspec);

static gboolean gst_sf_src_start (GstBaseSrc * bsrc);
static gboolean gst_sf_src_stop (GstBaseSrc * bsrc);
static gboolean gst_sf_src_is_seekable (GstBaseSrc * bsrc);
static gboolean gst_sf_src_get_size (GstBaseSrc * bsrc, guint64 * size);
static GstFlowReturn gst_sf_src_create (GstBaseSrc * bsrc, guint64 offset,
    guint length, GstBuffer ** buffer);
static GstCaps *gst_sf_src_get_caps (GstBaseSrc * bsrc);
static gboolean gst_sf_src_set_caps (GstBaseSrc * bsrc, GstCaps * caps);
static gboolean gst_sf_src_check_get_range (GstBaseSrc * bsrc);
static void gst_sf_src_fixate (GstBaseSrc * bsrc, GstCaps * caps);

GST_BOILERPLATE (GstSFSrc, gst_sf_src, GstBaseSrc, GST_TYPE_BASE_SRC);

static void
gst_sf_src_base_init (gpointer g_class)
{
  GstElementClass *gstelement_class = GST_ELEMENT_CLASS (g_class);

  gst_element_class_add_pad_template (gstelement_class,
      gst_static_pad_template_get (&sf_src_factory));

  gst_element_class_set_metadata (gstelement_class, "Sndfile source",
      "Source/Audio",
      "Read audio streams from disk using libsndfile",
      "Andy Wingo <wingo at pobox dot com>");
  GST_DEBUG_CATEGORY_INIT (gst_sf_src_debug, "sfsrc", 0, "sfsrc element");
}

static void
gst_sf_src_class_init (GstSFSrcClass * klass)
{
  GObjectClass *gobject_class;
  GstBaseSrcClass *gstbasesrc_class;

  gobject_class = G_OBJECT_CLASS (klass);
  gstbasesrc_class = GST_BASE_SRC_CLASS (klass);

  gobject_class->set_property = gst_sf_src_set_property;
  gobject_class->get_property = gst_sf_src_get_property;

  g_object_class_install_property (gobject_class, PROP_LOCATION,
      g_param_spec_string ("location", "File Location",
          "Location of the file to read", NULL, G_PARAM_READWRITE));

  gobject_class->finalize = GST_DEBUG_FUNCPTR (gst_sf_src_finalize);

  gstbasesrc_class->start = GST_DEBUG_FUNCPTR (gst_sf_src_start);
  gstbasesrc_class->stop = GST_DEBUG_FUNCPTR (gst_sf_src_stop);
  gstbasesrc_class->is_seekable = GST_DEBUG_FUNCPTR (gst_sf_src_is_seekable);
  gstbasesrc_class->get_size = GST_DEBUG_FUNCPTR (gst_sf_src_get_size);
  gstbasesrc_class->create = GST_DEBUG_FUNCPTR (gst_sf_src_create);
  gstbasesrc_class->get_caps = GST_DEBUG_FUNCPTR (gst_sf_src_get_caps);
  gstbasesrc_class->set_caps = GST_DEBUG_FUNCPTR (gst_sf_src_set_caps);
  gstbasesrc_class->check_get_range =
      GST_DEBUG_FUNCPTR (gst_sf_src_check_get_range);
  gstbasesrc_class->fixate = GST_DEBUG_FUNCPTR (gst_sf_src_fixate);
}

static void
gst_sf_src_init (GstSFSrc * src, GstSFSrcClass * g_class)
{
}

static void
gst_sf_src_finalize (GObject * object)
{
  GstSFSrc *src;

  src = GST_SF_SRC (object);

  g_free (src->location);

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

static void
gst_sf_src_set_location (GstSFSrc * this, const gchar * location)
{
  if (this->file)
    goto was_open;

  if (this->location)
    g_free (this->location);

  this->location = location ? g_strdup (location) : NULL;

  return;

was_open:
  {
    g_warning ("Changing the `location' property on sfsrc when "
        "a file is open not supported.");
    return;
  }
}

static void
gst_sf_src_set_property (GObject * object, guint prop_id, const GValue * value,
    GParamSpec * pspec)
{
  GstSFSrc *this = GST_SF_SRC (object);

  switch (prop_id) {
    case PROP_LOCATION:
      gst_sf_src_set_location (this, g_value_get_string (value));
      break;

    default:
      break;
  }
}

static void
gst_sf_src_get_property (GObject * object, guint prop_id, GValue * value,
    GParamSpec * pspec)
{
  GstSFSrc *this = GST_SF_SRC (object);

  switch (prop_id) {
    case PROP_LOCATION:
      g_value_set_string (value, this->location);
      break;

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

static GstFlowReturn
gst_sf_src_create (GstBaseSrc * bsrc, guint64 offset, guint length,
    GstBuffer ** buffer)
{
  GstSFSrc *this;
  GstBuffer *buf;
/* FIXME discont is set but not used */
#if 0
  gboolean discont = FALSE;
#endif
  sf_count_t bytes_read;

  this = GST_SF_SRC (bsrc);

  if (G_UNLIKELY (offset % this->bytes_per_frame))
    goto bad_offset;
  if (G_UNLIKELY (length % this->bytes_per_frame))
    goto bad_length;

  offset /= this->bytes_per_frame;

  if (G_UNLIKELY (this->offset != offset)) {
    sf_count_t pos;

    pos = sf_seek (this->file, offset, SEEK_SET);

    if (G_UNLIKELY (pos < 0 || pos != offset))
      goto seek_failed;

    this->offset = offset;
#if 0
    discont = TRUE;
#endif
  }

  buf = gst_buffer_new_and_alloc (length);

  /* now make length in frames */
  length /= this->bytes_per_frame;

  bytes_read = this->reader (this->file, GST_BUFFER_DATA (buf), length);
  if (G_UNLIKELY (bytes_read < 0))
    goto could_not_read;

  if (G_UNLIKELY (bytes_read == 0 && length > 0))
    goto eos;

  GST_BUFFER_SIZE (buf) = bytes_read * this->bytes_per_frame;

  GST_BUFFER_OFFSET (buf) = offset;
  GST_BUFFER_OFFSET_END (buf) = offset + length;
  GST_BUFFER_TIMESTAMP (buf) = gst_util_uint64_scale_int (offset,
      GST_SECOND, this->rate);
  GST_BUFFER_DURATION (buf) = gst_util_uint64_scale_int (offset + length,
      GST_SECOND, this->rate) - GST_BUFFER_TIMESTAMP (buf);

  gst_buffer_set_caps (buf, GST_PAD_CAPS (GST_BASE_SRC_PAD (bsrc)));

  *buffer = buf;

  this->offset += length;

  return GST_FLOW_OK;

  /* ERROR */
bad_offset:
  {
    GST_ELEMENT_ERROR (this, RESOURCE, SEEK,
        (NULL), ("offset %" G_GUINT64_FORMAT " not divisible by %d bytes per "
            "frame", offset, this->bytes_per_frame));
    return GST_FLOW_ERROR;
  }
bad_length:
  {
    GST_ELEMENT_ERROR (this, RESOURCE, SEEK, (NULL),
        ("length %u not divisible by %d bytes per frame", length,
            this->bytes_per_frame));
    return GST_FLOW_ERROR;
  }
seek_failed:
  {
    GST_ELEMENT_ERROR (this, RESOURCE, READ, (NULL), GST_ERROR_SYSTEM);
    return GST_FLOW_ERROR;
  }
could_not_read:
  {
    GST_ELEMENT_ERROR (this, RESOURCE, READ, (NULL), GST_ERROR_SYSTEM);
    gst_buffer_unref (buf);
    return GST_FLOW_ERROR;
  }
eos:
  {
    GST_DEBUG ("EOS, baby");
    gst_buffer_unref (buf);
    return GST_FLOW_UNEXPECTED;
  }
}

static gboolean
gst_sf_src_is_seekable (GstBaseSrc * basesrc)
{
  return TRUE;
}

static gboolean
gst_sf_src_get_size (GstBaseSrc * basesrc, guint64 * size)
{
  GstSFSrc *this;
  sf_count_t end;

  this = GST_SF_SRC (basesrc);

  end = sf_seek (this->file, 0, SEEK_END);

  sf_seek (this->file, this->offset, SEEK_SET);

  *size = end * this->bytes_per_frame;

  return TRUE;
}

static gboolean
gst_sf_src_open_file (GstSFSrc * this)
{
  int mode;
  SF_INFO info;

  g_return_val_if_fail (this->file == NULL, FALSE);

  if (!this->location)
    goto no_filename;

  mode = SFM_READ;
  info.format = 0;

  this->file = sf_open (this->location, mode, &info);

  if (!this->file)
    goto open_failed;

  this->channels = info.channels;
  this->rate = info.samplerate;
  /* do something with info.seekable? */

  return TRUE;

no_filename:
  {
    GST_ELEMENT_ERROR (this, RESOURCE, NOT_FOUND,
        (_("No file name specified for writing.")), (NULL));
    return FALSE;
  }
open_failed:
  {
    GST_ELEMENT_ERROR (this, RESOURCE, OPEN_WRITE,
        (_("Could not open file \"%s\" for writing."), this->location),
        ("soundfile error: %s", sf_strerror (NULL)));
    return FALSE;
  }
}

static void
gst_sf_src_close_file (GstSFSrc * this)
{
  int err = 0;

  g_return_if_fail (this->file != NULL);

  GST_INFO_OBJECT (this, "Closing file %s", this->location);

  if ((err = sf_close (this->file)))
    goto close_failed;

  this->file = NULL;
  this->offset = 0;
  this->channels = 0;
  this->rate = 0;

  return;

close_failed:
  {
    GST_ELEMENT_ERROR (this, RESOURCE, CLOSE,
        ("Could not close file file \"%s\".", this->location),
        ("soundfile error: %s", sf_error_number (err)));
    return;
  }
}

static gboolean
gst_sf_src_start (GstBaseSrc * basesrc)
{
  GstSFSrc *this = GST_SF_SRC (basesrc);

  return gst_sf_src_open_file (this);
}

/* unmap and close the file */
static gboolean
gst_sf_src_stop (GstBaseSrc * basesrc)
{
  GstSFSrc *this = GST_SF_SRC (basesrc);

  gst_sf_src_close_file (this);

  return TRUE;
}

static GstCaps *
gst_sf_src_get_caps (GstBaseSrc * bsrc)
{
  GstSFSrc *this;
  GstCaps *ret;

  this = GST_SF_SRC (bsrc);

  ret = gst_caps_copy (gst_pad_get_pad_template_caps (bsrc->srcpad));

  if (this->file) {
    GstStructure *s;
    gint i;

    for (i = 0; i < gst_caps_get_size (ret); i++) {
      s = gst_caps_get_structure (ret, i);
      gst_structure_set (s, "channels", G_TYPE_INT, this->channels,
          "rate", G_TYPE_INT, this->rate, NULL);
    }
  }

  return ret;
}

static gboolean
gst_sf_src_set_caps (GstBaseSrc * bsrc, GstCaps * caps)
{
  GstSFSrc *this = (GstSFSrc *) bsrc;
  GstStructure *structure;
  gint width;

  structure = gst_caps_get_structure (caps, 0);

  if (!this->file)
    goto file_not_open;

  if (!gst_structure_get_int (structure, "width", &width))
    goto impossible;

  if (gst_structure_has_name (structure, "audio/x-raw-int")) {
    switch (width) {
      case 16:
        this->reader = (GstSFReader) sf_readf_short;
        break;
      case 32:
        this->reader = (GstSFReader) sf_readf_int;
        break;
      default:
        goto impossible;
    }
  } else {
    switch (width) {
      case 32:
        this->reader = (GstSFReader) sf_readf_float;
        break;
      default:
        goto impossible;
    }
  }

  this->bytes_per_frame = width * this->channels / 8;

  return TRUE;

impossible:
  {
    g_warning ("something impossible happened");
    return FALSE;
  }
file_not_open:
  {
    GST_WARNING_OBJECT (this, "file has to be open in order to set caps");
    return FALSE;
  }
}

static gboolean
gst_sf_src_check_get_range (GstBaseSrc * bsrc)
{
  return TRUE;
}

static void
gst_sf_src_fixate (GstBaseSrc * bsrc, GstCaps * caps)
{
  GstStructure *s;
  gint width, depth;

  s = gst_caps_get_structure (caps, 0);

  gst_structure_fixate_field_nearest_int (s, "width", 16);

  /* fields for int */
  if (gst_structure_has_field (s, "depth")) {
    gst_structure_get_int (s, "width", &width);
    /* round width to nearest multiple of 8 for the depth */
    depth = GST_ROUND_UP_8 (width);
    gst_structure_fixate_field_nearest_int (s, "depth", depth);
  }
  if (gst_structure_has_field (s, "signed"))
    gst_structure_fixate_field_boolean (s, "signed", TRUE);
  if (gst_structure_has_field (s, "endianness"))
    gst_structure_fixate_field_nearest_int (s, "endianness", G_BYTE_ORDER);
}
