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