summaryrefslogtreecommitdiff
path: root/ext/sndfile/gstsfdec.c
diff options
context:
space:
mode:
authorStefan Sauer <ensonic@users.sf.net>2013-12-18 08:12:07 +0100
committerStefan Sauer <ensonic@users.sf.net>2013-12-20 20:00:55 +0100
commitbf956c487f4d8c6995a43ec635fe59f8e7b8b092 (patch)
tree6f36e578766d5db2ab788924456bb4d50bf3e0d3 /ext/sndfile/gstsfdec.c
parentb884eac02ca2f81b6331c1b1929aef23207cd3b9 (diff)
sfdec: add taglist support
Map the metadata strings and a bunch of info-fields to GStreamer tags.
Diffstat (limited to 'ext/sndfile/gstsfdec.c')
-rw-r--r--ext/sndfile/gstsfdec.c112
1 files changed, 111 insertions, 1 deletions
diff --git a/ext/sndfile/gstsfdec.c b/ext/sndfile/gstsfdec.c
index ba8b49683..31a84a983 100644
--- a/ext/sndfile/gstsfdec.c
+++ b/ext/sndfile/gstsfdec.c
@@ -21,10 +21,11 @@
# include "config.h"
#endif
+#include <stdlib.h>
#include <gst/gst-i18n-plugin.h>
+#include <gst/audio/audio.h>
#include "gstsfdec.h"
-#include <gst/audio/audio.h>
enum
{
@@ -355,11 +356,15 @@ static gboolean
gst_sf_dec_open_file (GstSFDec * self)
{
SF_INFO info = { 0, };
+ SF_LOOP_INFO loop_info = { 0, };
GstCaps *caps;
GstStructure *s;
GstSegment seg;
+ GstTagList *tags;
gint width;
const gchar *format;
+ const gchar *tag;
+ const gchar *codec_name;
gchar *stream_id;
GST_DEBUG_OBJECT (self, "opening the stream");
@@ -413,10 +418,115 @@ gst_sf_dec_open_file (GstSFDec * self)
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");
+ }
+
+ /* send tags */
+ tags = gst_tag_list_new_empty ();
+ if ((tag = sf_get_string (self->file, SF_STR_TITLE))) {
+ gst_tag_list_add (tags, GST_TAG_MERGE_APPEND, GST_TAG_TITLE, tag, NULL);
+ }
+ if ((tag = sf_get_string (self->file, SF_STR_COMMENT))) {
+ gst_tag_list_add (tags, GST_TAG_MERGE_APPEND, GST_TAG_COMMENT, tag, NULL);
+ }
+ if ((tag = sf_get_string (self->file, SF_STR_ARTIST))) {
+ gst_tag_list_add (tags, GST_TAG_MERGE_APPEND, GST_TAG_ARTIST, tag, NULL);
+ }
+ if ((tag = sf_get_string (self->file, SF_STR_ALBUM))) {
+ gst_tag_list_add (tags, GST_TAG_MERGE_APPEND, GST_TAG_ALBUM, tag, NULL);
+ }
+ if ((tag = sf_get_string (self->file, SF_STR_GENRE))) {
+ gst_tag_list_add (tags, GST_TAG_MERGE_APPEND, GST_TAG_GENRE, tag, NULL);
+ }
+ if ((tag = sf_get_string (self->file, SF_STR_COPYRIGHT))) {
+ gst_tag_list_add (tags, GST_TAG_MERGE_APPEND, GST_TAG_COPYRIGHT, tag, NULL);
+ }
+ if ((tag = sf_get_string (self->file, SF_STR_LICENSE))) {
+ gst_tag_list_add (tags, GST_TAG_MERGE_APPEND, GST_TAG_LICENSE, tag, NULL);
+ }
+ if ((tag = sf_get_string (self->file, SF_STR_SOFTWARE))) {
+ 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))) {
+ guint track = atoi (tag);
+ gst_tag_list_add (tags, GST_TAG_MERGE_APPEND, GST_TAG_TRACK_NUMBER, track,
+ NULL);
+ }
+ if (loop_info.bpm != 0.0) {
+ gst_tag_list_add (tags, GST_TAG_MERGE_APPEND, GST_TAG_BEATS_PER_MINUTE,
+ (gdouble) loop_info.bpm, NULL);
+ }
+ /* TODO: SF_STR_DATE: GST_TAG_DATE / GST_TAG_DATE_TIME */
+ /* 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);
+ }
+
return TRUE;
open_failed: