/* GStreamer libsndfile plugin
 * Copyright (C) 2013 Stefan Sauer <ensonic@users.sf.net>
 *
 * 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 self library; if not, write to the
 * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
 * Boston, MA 02110-1301, USA.
 */

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

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

#include "gstsfdec.h"

#define FORMATS \
    "{ "GST_AUDIO_NE (F32)", "GST_AUDIO_NE (S32)", "GST_AUDIO_NE (S16)" }"

static GstStaticPadTemplate sf_dec_src_factory = GST_STATIC_PAD_TEMPLATE ("src",
    GST_PAD_SRC,
    GST_PAD_ALWAYS,
    GST_STATIC_CAPS ("audio/x-raw, "
        "format = (string) " FORMATS ", "
        "layout = (string) interleaved, "
        "rate = (int) [ 1, MAX ], " "channels = (int) [ 1, MAX ]"));

GST_DEBUG_CATEGORY_STATIC (gst_sf_dec_debug);
#define GST_CAT_DEFAULT gst_sf_dec_debug

#define DEFAULT_BUFFER_FRAMES	(256)

static gboolean gst_sf_dec_src_event (GstPad * pad, GstObject * parent,
    GstEvent * event);
static gboolean gst_sf_dec_src_query (GstPad * pad, GstObject * parent,
    GstQuery * query);
static GstStateChangeReturn gst_sf_dec_change_state (GstElement * element,
    GstStateChange transition);

static gboolean gst_sf_dec_sink_activate (GstPad * pad, GstObject * parent);
static gboolean gst_sf_dec_sink_activate_mode (GstPad * sinkpad,
    GstObject * parent, GstPadMode mode, gboolean active);
static void gst_sf_dec_loop (GstPad * pad);

static gboolean gst_sf_dec_start (GstSFDec * bsrc);
static gboolean gst_sf_dec_stop (GstSFDec * bsrc);

#define _do_init \
    GST_DEBUG_CATEGORY_INIT (gst_sf_dec_debug, "sfdec", 0, "sfdec element");
#define gst_sf_dec_parent_class parent_class
G_DEFINE_TYPE_WITH_CODE (GstSFDec, gst_sf_dec, GST_TYPE_ELEMENT, _do_init);

/* sf virtual io */

static sf_count_t
gst_sf_vio_get_filelen (void *user_data)
{
  GstSFDec *self = GST_SF_DEC (user_data);
  gint64 dur;

  if (gst_pad_peer_query_duration (self->sinkpad, GST_FORMAT_BYTES, &dur)) {
    return (sf_count_t) dur;
  }
  GST_WARNING_OBJECT (self, "query_duration failed");
  return -1;
}

static sf_count_t
gst_sf_vio_tell (void *user_data)
{
  GstSFDec *self = GST_SF_DEC (user_data);
  return self->pos;
}

static sf_count_t
gst_sf_vio_seek (sf_count_t offset, int whence, void *user_data)
{
  GstSFDec *self = GST_SF_DEC (user_data);

  switch (whence) {
    case SEEK_CUR:
      self->pos += offset;
      break;
    case SEEK_SET:
      self->pos = offset;
      break;
    case SEEK_END:
      self->pos = gst_sf_vio_get_filelen (user_data) - offset;
      break;
  }
  return (sf_count_t) self->pos;
}

static sf_count_t
gst_sf_vio_read (void *ptr, sf_count_t count, void *user_data)
{
  GstSFDec *self = GST_SF_DEC (user_data);
  GstBuffer *buffer = gst_buffer_new_wrapped_full (0, ptr, count, 0, count,
      ptr, NULL);

  if (gst_pad_pull_range (self->sinkpad, self->pos, count, &buffer) ==
      GST_FLOW_OK) {
    GST_DEBUG_OBJECT (self, "read %d bytes @ pos %" G_GUINT64_FORMAT,
        (gint) count, self->pos);
    self->pos += count;
    return count;
  }
  GST_WARNING_OBJECT (self, "read failed");
  return 0;
}

static sf_count_t
gst_sf_vio_write (const void *ptr, sf_count_t count, void *user_data)
{
  GstSFDec *self = GST_SF_DEC (user_data);
  GstBuffer *buffer = gst_buffer_new_wrapped (g_memdup (ptr, count), count);

  if (gst_pad_push (self->srcpad, buffer) == GST_FLOW_OK) {
    return count;
  }
  GST_WARNING_OBJECT (self, "write failed");
  return 0;
}

SF_VIRTUAL_IO gst_sf_vio = {
  &gst_sf_vio_get_filelen,
  &gst_sf_vio_seek,
  &gst_sf_vio_read,
  &gst_sf_vio_write,
  &gst_sf_vio_tell,
};


static void
gst_sf_dec_class_init (GstSFDecClass * klass)
{
  GstElementClass *gstelement_class;

  gstelement_class = GST_ELEMENT_CLASS (klass);
  gstelement_class->change_state = GST_DEBUG_FUNCPTR (gst_sf_dec_change_state);

  gst_element_class_set_static_metadata (gstelement_class, "Sndfile decoder",
      "Decoder/Audio",
      "Read audio streams using libsndfile",
      "Stefan Sauer <ensonic@user.sf.net>");

  gst_element_class_add_pad_template (gstelement_class,
      gst_static_pad_template_get (&sf_dec_src_factory));

  gst_element_class_add_pad_template (gstelement_class,
      gst_pad_template_new ("sink", GST_PAD_SINK, GST_PAD_ALWAYS,
          gst_sf_create_audio_template_caps ()));

}

static void
gst_sf_dec_init (GstSFDec * self)
{
  self->sinkpad = gst_pad_new_from_template (gst_element_class_get_pad_template
      (GST_ELEMENT_GET_CLASS (self), "sink"), "sink");
  gst_pad_set_activate_function (self->sinkpad,
      GST_DEBUG_FUNCPTR (gst_sf_dec_sink_activate));
  gst_pad_set_activatemode_function (self->sinkpad,
      GST_DEBUG_FUNCPTR (gst_sf_dec_sink_activate_mode));
  gst_element_add_pad (GST_ELEMENT (self), self->sinkpad);

  self->srcpad = gst_pad_new_from_static_template (&sf_dec_src_factory, "src");
  gst_pad_set_event_function (self->srcpad,
      GST_DEBUG_FUNCPTR (gst_sf_dec_src_event));
  gst_pad_set_query_function (self->srcpad,
      GST_DEBUG_FUNCPTR (gst_sf_dec_src_query));
  gst_element_add_pad (GST_ELEMENT (self), self->srcpad);
}

static gboolean
gst_sf_dec_do_seek (GstSFDec * self, GstEvent * event)
{
  gdouble rate;
  GstFormat format;
  GstSeekFlags flags;
  GstSeekType cur_type, stop_type;
  gboolean flush;
  gint64 cur, stop, pos;
  GstSegment seg;
  guint64 song_length = gst_util_uint64_scale_int (self->duration, GST_SECOND,
      self->rate);

  gst_event_parse_seek (event, &rate, &format, &flags, &cur_type, &cur,
      &stop_type, &stop);

  if (format != GST_FORMAT_TIME)
    goto unsupported_format;

  /* FIXME: we should be using GstSegment for all this */
  if (cur_type != GST_SEEK_TYPE_SET || stop_type != GST_SEEK_TYPE_NONE)
    goto unsuported_type;

  if (stop_type == GST_SEEK_TYPE_NONE)
    stop = GST_CLOCK_TIME_NONE;
  if (!GST_CLOCK_TIME_IS_VALID (stop) && song_length > 0)
    stop = song_length;

  cur = CLAMP (cur, -1, song_length);

  /* cur -> pos */
  pos = gst_util_uint64_scale_int (cur, self->rate, GST_SECOND);
  if ((pos = sf_seek (self->file, pos, SEEK_SET) == -1))
    goto seek_failed;

  /* pos -> cur */
  cur = gst_util_uint64_scale_int (pos, GST_SECOND, self->rate);

  GST_DEBUG_OBJECT (self, "seek to %" GST_TIME_FORMAT,
      GST_TIME_ARGS ((guint64) cur));

  flush = ((flags & GST_SEEK_FLAG_FLUSH) == GST_SEEK_FLAG_FLUSH);

  if (flush) {
    gst_pad_push_event (self->srcpad, gst_event_new_flush_start ());
  } else {
    gst_pad_stop_task (self->sinkpad);
  }

  GST_PAD_STREAM_LOCK (self->sinkpad);

  if (flags & GST_SEEK_FLAG_SEGMENT) {
    gst_element_post_message (GST_ELEMENT (self),
        gst_message_new_segment_start (GST_OBJECT (self), format, cur));
  }

  if (flush) {
    gst_pad_push_event (self->srcpad, gst_event_new_flush_stop (TRUE));
  }

  GST_LOG_OBJECT (self, "sending newsegment from %" GST_TIME_FORMAT "-%"
      GST_TIME_FORMAT ", pos=%" GST_TIME_FORMAT,
      GST_TIME_ARGS ((guint64) cur), GST_TIME_ARGS ((guint64) stop),
      GST_TIME_ARGS ((guint64) cur));

  gst_segment_init (&seg, GST_FORMAT_TIME);
  seg.rate = rate;
  seg.start = cur;
  seg.stop = stop;
  seg.time = cur;
  gst_pad_push_event (self->srcpad, gst_event_new_segment (&seg));

  gst_pad_start_task (self->sinkpad,
      (GstTaskFunction) gst_sf_dec_loop, self, NULL);

  GST_PAD_STREAM_UNLOCK (self->sinkpad);

  return TRUE;

  /* ERROR */
unsupported_format:
  {
    GST_DEBUG_OBJECT (self, "seeking is only supported in TIME format");
    return FALSE;
  }
unsuported_type:
  {
    GST_DEBUG_OBJECT (self, "unsupported seek type");
    return FALSE;
  }
seek_failed:
  {
    GST_DEBUG_OBJECT (self, "seek failed");
    return FALSE;
  }
}

static gboolean
gst_sf_dec_src_event (GstPad * pad, GstObject * parent, GstEvent * event)
{
  GstSFDec *self = GST_SF_DEC (parent);
  gboolean res = FALSE;

  GST_DEBUG_OBJECT (self, "event %s, %" GST_PTR_FORMAT,
      GST_EVENT_TYPE_NAME (event), event);

  switch (GST_EVENT_TYPE (event)) {
    case GST_EVENT_SEEK:
      if (!self->file || !self->seekable)
        goto done;
      res = gst_sf_dec_do_seek (self, event);
      break;
    default:
      res = gst_pad_event_default (pad, parent, event);
      break;
  }
done:
  GST_DEBUG_OBJECT (self, "event %s: %d", GST_EVENT_TYPE_NAME (event), res);
  return res;
}

static gboolean
gst_sf_dec_src_query (GstPad * pad, GstObject * parent, GstQuery * query)
{
  GstSFDec *self = GST_SF_DEC (parent);
  GstFormat format;
  gboolean res = FALSE;

  GST_DEBUG_OBJECT (self, "query %s, %" GST_PTR_FORMAT,
      GST_QUERY_TYPE_NAME (query), query);

  switch (GST_QUERY_TYPE (query)) {
    case GST_QUERY_DURATION:
      if (!self->file)
        goto done;
      gst_query_parse_duration (query, &format, NULL);
      if (format == GST_FORMAT_TIME) {
        gst_query_set_duration (query, format,
            gst_util_uint64_scale_int (self->duration, GST_SECOND, self->rate));
        res = TRUE;
      }
      break;
    case GST_QUERY_POSITION:
      if (!self->file)
        goto done;
      gst_query_parse_position (query, &format, NULL);
      if (format == GST_FORMAT_TIME) {
        gst_query_set_position (query, format,
            gst_util_uint64_scale_int (self->pos, GST_SECOND, self->rate));
        res = TRUE;
      }
      break;
    default:
      res = gst_pad_query_default (pad, parent, query);
      break;
  }

done:
  GST_DEBUG_OBJECT (self, "query %s: %d", GST_QUERY_TYPE_NAME (query), res);
  return res;
}

static GstStateChangeReturn
gst_sf_dec_change_state (GstElement * element, GstStateChange transition)
{
  GstStateChangeReturn ret;
  GstSFDec *self = GST_SF_DEC (element);

  GST_INFO_OBJECT (self, "transition: %s -> %s",
      gst_element_state_get_name (GST_STATE_TRANSITION_CURRENT (transition)),
      gst_element_state_get_name (GST_STATE_TRANSITION_NEXT (transition)));

  switch (transition) {
    case GST_STATE_CHANGE_READY_TO_PAUSED:
      gst_sf_dec_start (self);
      break;
    default:
      break;
  }

  ret = GST_ELEMENT_CLASS (parent_class)->change_state (element, transition);

  switch (transition) {
    case GST_STATE_CHANGE_PAUSED_TO_READY:
      gst_sf_dec_stop (self);
      break;
    default:
      break;
  }
  return ret;
}

static gboolean
gst_sf_dec_start (GstSFDec * self)
{
  return TRUE;
}

static gboolean
gst_sf_dec_stop (GstSFDec * self)
{
  int err = 0;

  GST_INFO_OBJECT (self, "Closing sndfile stream");

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

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

  self->pos = 0;
  self->duration = 0;

  return TRUE;

close_failed:
  {
    GST_ELEMENT_ERROR (self, RESOURCE, CLOSE,
        ("Could not close sndfile stream."),
        ("soundfile error: %s", sf_error_number (err)));
    return FALSE;
  }
}

static gboolean
gst_sf_dec_sink_activate (GstPad * sinkpad, GstObject * parent)
{
  GstQuery *query;
  gboolean pull_mode;

  query = gst_query_new_scheduling ();

  if (!gst_pad_peer_query (sinkpad, query)) {
    gst_query_unref (query);
    goto activate_push;
  }

  pull_mode = gst_query_has_scheduling_mode_with_flags (query,
      GST_PAD_MODE_PULL, GST_SCHEDULING_FLAG_SEEKABLE);
  gst_query_unref (query);

  if (!pull_mode)
    goto activate_push;

  GST_DEBUG_OBJECT (sinkpad, "activating pull");
  return gst_pad_activate_mode (sinkpad, GST_PAD_MODE_PULL, TRUE);

activate_push:
  {
    GST_DEBUG_OBJECT (sinkpad, "activating push");
    return gst_pad_activate_mode (sinkpad, GST_PAD_MODE_PUSH, TRUE);
  }
}

static gboolean
gst_sf_dec_sink_activate_mode (GstPad * sinkpad, GstObject * parent,
    GstPadMode mode, gboolean active)
{
  gboolean res;

  switch (mode) {
    case GST_PAD_MODE_PUSH:
      res = FALSE;              /* no push support */
      break;
    case GST_PAD_MODE_PULL:
      if (active) {
        /* if we have a scheduler we can start the task */
        GST_DEBUG_OBJECT (sinkpad, "start task");
        res = gst_pad_start_task (sinkpad, (GstTaskFunction) gst_sf_dec_loop,
            sinkpad, NULL);
      } else {
        res = gst_pad_stop_task (sinkpad);
      }
      break;
    default:
      res = FALSE;
      break;
  }
  return res;
}

static void
create_and_send_tags (GstSFDec * self, SF_INFO * info, SF_LOOP_INFO * loop_info,
    SF_INSTRUMENT * instrument)
{
  GstTagList *tags;
  const gchar *tag;
  const gchar *codec_name;

  /* send tags */
  tags = gst_tag_list_new_empty ();
  if ((tag = sf_get_string (self->file, SF_STR_TITLE)) && *tag) {
    gst_tag_list_add (tags, GST_TAG_MERGE_APPEND, GST_TAG_TITLE, tag, NULL);
  }
  if ((tag = sf_get_string (self->file, SF_STR_COMMENT)) && *tag) {
    gst_tag_list_add (tags, GST_TAG_MERGE_APPEND, GST_TAG_COMMENT, tag, NULL);
  }
  if ((tag = sf_get_string (self->file, SF_STR_ARTIST)) && *tag) {
    gst_tag_list_add (tags, GST_TAG_MERGE_APPEND, GST_TAG_ARTIST, tag, NULL);
  }
  if ((tag = sf_get_string (self->file, SF_STR_ALBUM)) && *tag) {
    gst_tag_list_add (tags, GST_TAG_MERGE_APPEND, GST_TAG_ALBUM, tag, NULL);
  }
  if ((tag = sf_get_string (self->file, SF_STR_GENRE)) && *tag) {
    gst_tag_list_add (tags, GST_TAG_MERGE_APPEND, GST_TAG_GENRE, tag, NULL);
  }
  if ((tag = sf_get_string (self->file, SF_STR_COPYRIGHT)) && *tag) {
    gst_tag_list_add (tags, GST_TAG_MERGE_APPEND, GST_TAG_COPYRIGHT, tag, NULL);
  }
  if ((tag = sf_get_string (self->file, SF_STR_LICENSE)) && *tag) {
    gst_tag_list_add (tags, GST_TAG_MERGE_APPEND, GST_TAG_LICENSE, tag, NULL);
  }
  if ((tag = sf_get_string (self->file, SF_STR_SOFTWARE)) && *tag) {
    gst_tag_list_add (tags, GST_TAG_MERGE_APPEND, GST_TAG_APPLICATION_NAME, tag,
        NULL);
  }
  if ((tag = sf_get_string (self->file, SF_STR_TRACKNUMBER)) && *tag) {
    guint track = atoi (tag);
    gst_tag_list_add (tags, GST_TAG_MERGE_REPLACE, GST_TAG_TRACK_NUMBER, track,
        NULL);
  }
  if ((tag = sf_get_string (self->file, SF_STR_DATE)) && *tag) {
    GValue tag_val = { 0, };
    GType tag_type = gst_tag_get_type (GST_TAG_DATE_TIME);

    g_value_init (&tag_val, tag_type);
    if (gst_value_deserialize (&tag_val, tag)) {
      gst_tag_list_add_value (tags, GST_TAG_MERGE_APPEND, GST_TAG_DATE_TIME,
          &tag_val);
    } else {
      GST_WARNING_OBJECT (self, "could not deserialize '%s' into a "
          "tag %s of type %s", tag, GST_TAG_DATE_TIME, g_type_name (tag_type));
    }
    g_value_unset (&tag_val);
  }
  if (loop_info) {
    if (loop_info->bpm != 0.0) {
      gst_tag_list_add (tags, GST_TAG_MERGE_REPLACE, GST_TAG_BEATS_PER_MINUTE,
          (gdouble) loop_info->bpm, NULL);
    }
    if (loop_info->root_key != -1) {
      gst_tag_list_add (tags, GST_TAG_MERGE_REPLACE, GST_TAG_MIDI_BASE_NOTE,
          (guint) loop_info->root_key, NULL);
    }
  }
  if (instrument) {
    gst_tag_list_add (tags, GST_TAG_MERGE_REPLACE, GST_TAG_MIDI_BASE_NOTE,
        (guint) instrument->basenote, NULL);
  }
  /* TODO: calculate bitrate: GST_TAG_BITRATE */
  switch (info->format & SF_FORMAT_SUBMASK) {
    case SF_FORMAT_PCM_S8:
    case SF_FORMAT_PCM_16:
    case SF_FORMAT_PCM_24:
    case SF_FORMAT_PCM_32:
    case SF_FORMAT_PCM_U8:
      codec_name = "Uncompressed PCM audio";
      break;
    case SF_FORMAT_FLOAT:
    case SF_FORMAT_DOUBLE:
      codec_name = "Uncompressed IEEE float audio";
      break;
    case SF_FORMAT_ULAW:
      codec_name = "µ-law audio";
      break;
    case SF_FORMAT_ALAW:
      codec_name = "A-law audio";
      break;
    case SF_FORMAT_IMA_ADPCM:
    case SF_FORMAT_MS_ADPCM:
    case SF_FORMAT_VOX_ADPCM:
    case SF_FORMAT_G721_32:
    case SF_FORMAT_G723_24:
    case SF_FORMAT_G723_40:
      codec_name = "ADPCM audio";
      break;
    case SF_FORMAT_GSM610:
      codec_name = "MS GSM audio";
      break;
    case SF_FORMAT_DWVW_12:
    case SF_FORMAT_DWVW_16:
    case SF_FORMAT_DWVW_24:
    case SF_FORMAT_DWVW_N:
      codec_name = "Delta Width Variable Word encoded audio";
      break;
    case SF_FORMAT_DPCM_8:
    case SF_FORMAT_DPCM_16:
      codec_name = "differential PCM audio";
      break;
    case SF_FORMAT_VORBIS:
      codec_name = "Vorbis";
      break;
    default:
      codec_name = NULL;
      GST_WARNING_OBJECT (self, "unmapped codec_type: %d",
          info->format & SF_FORMAT_SUBMASK);
      break;
  }
  if (codec_name) {
    gst_tag_list_add (tags, GST_TAG_MERGE_APPEND, GST_TAG_AUDIO_CODEC,
        codec_name, NULL);
  }

  if (!gst_tag_list_is_empty (tags)) {
    GST_DEBUG_OBJECT (self, "have tags");
    gst_pad_push_event (self->srcpad, gst_event_new_tag (tags));
  } else {
    gst_tag_list_unref (tags);
  }
}

static gboolean
is_valid_loop (gint mode, guint start, guint end)
{
  if (!end)
    return FALSE;
  if (start >= end)
    return FALSE;
  if (!mode)
    return FALSE;

  return TRUE;
}

static void
create_and_send_toc (GstSFDec * self, SF_INFO * info, SF_LOOP_INFO * loop_info,
    SF_INSTRUMENT * instrument)
{
  GstToc *toc;
  GstTocEntry *entry = NULL, *subentry = NULL;
  gint64 start, stop;
  gchar *id;
  gint i;
  gboolean have_loops = FALSE;

  if (!instrument)
    return;

  for (i = 0; i < 16; i++) {
    if (is_valid_loop (instrument->loops[i].mode, instrument->loops[i].start,
            instrument->loops[i].end)) {
      have_loops = TRUE;
      break;
    }
  }
  if (!have_loops) {
    GST_INFO_OBJECT (self, "Have no loops");
    return;
  }


  toc = gst_toc_new (GST_TOC_SCOPE_GLOBAL);
  GST_DEBUG_OBJECT (self, "have toc");

  /* add cue edition */
  entry = gst_toc_entry_new (GST_TOC_ENTRY_TYPE_EDITION, "loops");
  stop = gst_util_uint64_scale_int (self->duration, GST_SECOND, self->rate);
  gst_toc_entry_set_start_stop_times (entry, 0, stop);
  gst_toc_append_entry (toc, entry);

  for (i = 0; i < 16; i++) {
    GST_DEBUG_OBJECT (self,
        "loop[%2d]: mode=%d, start=%u, end=%u, count=%u", i,
        instrument->loops[i].mode, instrument->loops[i].start,
        instrument->loops[i].end, instrument->loops[i].count);
    if (is_valid_loop (instrument->loops[i].mode, instrument->loops[i].start,
            instrument->loops[i].end)) {
      id = g_strdup_printf ("%08x", i);
      subentry = gst_toc_entry_new (GST_TOC_ENTRY_TYPE_CHAPTER, id);
      g_free (id);
      start = gst_util_uint64_scale_int (instrument->loops[i].start,
          GST_SECOND, self->rate);
      stop = gst_util_uint64_scale_int (instrument->loops[i].end,
          GST_SECOND, self->rate);
      gst_toc_entry_set_start_stop_times (subentry, start, stop);
      gst_toc_entry_append_sub_entry (entry, subentry);
    }
  }

  gst_pad_push_event (self->srcpad, gst_event_new_toc (toc, FALSE));
}

static gboolean
gst_sf_dec_open_file (GstSFDec * self)
{
  SF_INFO info = { 0, };
  SF_LOOP_INFO loop_info = { 0, };
  SF_INSTRUMENT instrument = { 0, };
  GstCaps *caps;
  GstStructure *s;
  GstSegment seg;
  gint width;
  const gchar *format;
  gchar *stream_id;
  gboolean have_loop_info = FALSE;
  gboolean have_instrument = FALSE;

  GST_DEBUG_OBJECT (self, "opening the stream");
  if (!(self->file = sf_open_virtual (&gst_sf_vio, SFM_READ, &info, self)))
    goto open_failed;

  stream_id =
      gst_pad_create_stream_id (self->srcpad, GST_ELEMENT_CAST (self), NULL);
  gst_pad_push_event (self->srcpad, gst_event_new_stream_start (stream_id));
  g_free (stream_id);

  self->channels = info.channels;
  self->rate = info.samplerate;
  self->duration = info.frames;
  self->seekable = info.seekable;
  GST_DEBUG_OBJECT (self, "stream openend: channels=%d, rate=%d, seekable=%d",
      info.channels, info.samplerate, info.seekable);

  /* negotiate srcpad caps */
  if ((caps = gst_pad_get_allowed_caps (self->srcpad)) == NULL) {
    caps = gst_pad_get_pad_template_caps (self->srcpad);
  }
  caps = gst_caps_make_writable (caps);
  GST_DEBUG_OBJECT (self, "allowed caps %" GST_PTR_FORMAT, caps);

  s = gst_caps_get_structure (caps, 0);
  gst_structure_set (s,
      "channels", G_TYPE_INT, self->channels,
      "rate", G_TYPE_INT, self->rate, NULL);

  if (!gst_structure_fixate_field_string (s, "format", GST_AUDIO_NE (S16)))
    GST_WARNING_OBJECT (self, "Failed to fixate format to S16NE");

  caps = gst_caps_fixate (caps);

  GST_DEBUG_OBJECT (self, "fixated caps %" GST_PTR_FORMAT, caps);

  /* configure to output the negotiated format */
  s = gst_caps_get_structure (caps, 0);
  format = gst_structure_get_string (s, "format");
  if (g_str_equal (format, GST_AUDIO_NE (S32))) {
    self->reader = (GstSFReader) sf_readf_int;
    width = 32;
  } else if (g_str_equal (format, GST_AUDIO_NE (S16))) {
    self->reader = (GstSFReader) sf_readf_short;
    width = 16;
  } else {
    self->reader = (GstSFReader) sf_readf_float;
    width = 32;
  }
  self->bytes_per_frame = width * self->channels / 8;

  gst_pad_set_caps (self->srcpad, caps);
  gst_caps_unref (caps);

  /* push initial segment */
  gst_segment_init (&seg, GST_FORMAT_TIME);
  seg.stop = gst_util_uint64_scale_int (self->duration, GST_SECOND, self->rate);
  gst_pad_push_event (self->srcpad, gst_event_new_segment (&seg));

  /* get extra details */
  if (sf_command (self->file, SFC_GET_LOOP_INFO, &loop_info,
          sizeof (loop_info))) {
    GST_DEBUG_OBJECT (self, "have loop info");
    have_loop_info = TRUE;
  }
  if (sf_command (self->file, SFC_GET_INSTRUMENT, &instrument,
          sizeof (instrument))) {
    GST_DEBUG_OBJECT (self, "have instrument");
    have_instrument = TRUE;
  }

  create_and_send_tags (self, &info, (have_loop_info ? &loop_info : NULL),
      (have_instrument ? &instrument : NULL));

  create_and_send_toc (self, &info, (have_loop_info ? &loop_info : NULL),
      (have_instrument ? &instrument : NULL));

  return TRUE;

open_failed:
  {
    GST_ELEMENT_ERROR (self, RESOURCE, OPEN_READ,
        (_("Could not open sndfile stream for reading.")),
        ("soundfile error: %s", sf_strerror (NULL)));
    return FALSE;
  }
}

static void
gst_sf_dec_loop (GstPad * pad)
{
  GstSFDec *self = GST_SF_DEC (GST_PAD_PARENT (pad));
  GstBuffer *buf;
  GstMapInfo map;
  GstFlowReturn flow;
  sf_count_t frames_read;
  guint num_frames = 1024;      /* arbitrary */

  if (G_UNLIKELY (!self->file)) {
    /* not started yet */
    if (!gst_sf_dec_open_file (self))
      goto pause;
  }

  buf = gst_buffer_new_and_alloc (self->bytes_per_frame * num_frames);
  gst_buffer_map (buf, &map, GST_MAP_WRITE);
  frames_read = self->reader (self->file, map.data, num_frames);
  GST_LOG_OBJECT (self, "read %d / %d bytes = %d frames of audio",
      (gint) frames_read, (gint) map.size, num_frames);
  gst_buffer_unmap (buf, &map);

  if (G_UNLIKELY (frames_read < 0))
    goto could_not_read;

  if (G_UNLIKELY (frames_read == 0))
    goto eos;

  GST_BUFFER_OFFSET (buf) = self->offset;
  GST_BUFFER_TIMESTAMP (buf) = gst_util_uint64_scale_int (self->offset,
      GST_SECOND, self->rate);
  self->offset += frames_read;
  GST_BUFFER_DURATION (buf) = gst_util_uint64_scale_int (self->offset,
      GST_SECOND, self->rate) - GST_BUFFER_TIMESTAMP (buf);

  flow = gst_pad_push (self->srcpad, buf);
  if (flow != GST_FLOW_OK) {
    GST_LOG_OBJECT (self, "pad push flow: %s", gst_flow_get_name (flow));
    goto pause;
  }

  return;

  /* ERROR */
could_not_read:
  {
    GST_ELEMENT_ERROR (self, RESOURCE, READ, (NULL), GST_ERROR_SYSTEM);
    gst_buffer_unref (buf);
    goto pause;
  }
eos:
  {
    GST_DEBUG_OBJECT (self, "EOS");
    gst_buffer_unref (buf);
    gst_pad_push_event (self->srcpad, gst_event_new_eos ());
    goto pause;
  }
pause:
  {
    GST_INFO_OBJECT (self, "Pausing");
    gst_pad_pause_task (self->sinkpad);
  }
}
