]> Gitweb @ Texas Instruments - Open Source Git Repositories - git.TI.com/gitweb - glsdk/gst-plugins-ugly0-10.git/blob - ext/sidplay/gstsiddec.cc
configure.ac: rework similarly to other modules
[glsdk/gst-plugins-ugly0-10.git] / ext / sidplay / gstsiddec.cc
1 /* GStreamer
2  * Copyright (C) <1999> Erik Walthinsen <omega@cse.ogi.edu>
3  *
4  * This library is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Library General Public
6  * License as published by the Free Software Foundation; either
7  * version 2 of the License, or (at your option) any later version.
8  *
9  * This library is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12  * Library General Public License for more details.
13  *
14  * You should have received a copy of the GNU Library General Public
15  * License along with this library; if not, write to the
16  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
17  * Boston, MA 02111-1307, USA.
18  */
20 #ifdef HAVE_CONFIG_H
21 #include "config.h"
22 #endif
24 #include <string.h>
25 #include "gstsiddec.h"
27 /* Sidec signals and args */
28 enum
29 {
30   /* FILL ME */
31   LAST_SIGNAL
32 };
34 #define DEFAULT_BLOCKSIZE       4096
36 enum
37 {
38   ARG_0,
39   ARG_TUNE,
40   ARG_CLOCK,
41   ARG_MEMORY,
42   ARG_FILTER,
43   ARG_MEASURED_VOLUME,
44   ARG_MOS8580,
45   ARG_FORCE_SPEED,
46   ARG_BLOCKSIZE,
47   ARG_METADATA
48       /* FILL ME */
49 };
51 static GstStaticPadTemplate sink_templ = GST_STATIC_PAD_TEMPLATE ("sink",
52     GST_PAD_SINK,
53     GST_PAD_ALWAYS,
54     GST_STATIC_CAPS ("audio/x-sid")
55     );
57 static GstStaticPadTemplate src_templ = GST_STATIC_PAD_TEMPLATE ("src",
58     GST_PAD_SRC,
59     GST_PAD_ALWAYS,
60     GST_STATIC_CAPS ("audio/x-raw-int, "
61         "endianness = (int) BYTE_ORDER, "
62         "signed = (boolean) { true, false }, "
63         "width = (int) { 8, 16 }, "
64         "depth = (int) { 8, 16 }, "
65         "rate = (int) [ 8000, 48000 ], " "channels = (int) [ 1, 2 ]")
66     );
69 #define GST_TYPE_SID_CLOCK (gst_sid_clock_get_type())
70 static GType
71 gst_sid_clock_get_type (void)
72 {
73   static GType sid_clock_type = 0;
74   static GEnumValue sid_clock[] = {
75     {SIDTUNE_CLOCK_PAL, "PAL", "pal"},
76     {SIDTUNE_CLOCK_NTSC, "NTSC", "ntsc"},
77     {0, NULL, NULL},
78   };
80   if (!sid_clock_type) {
81     sid_clock_type = g_enum_register_static ("GstSidClock", sid_clock);
82   }
83   return sid_clock_type;
84 }
86 #define GST_TYPE_SID_MEMORY (gst_sid_memory_get_type())
87 static GType
88 gst_sid_memory_get_type (void)
89 {
90   static GType sid_memory_type = 0;
91   static GEnumValue sid_memory[] = {
92     {MPU_BANK_SWITCHING, "Bank Switching", "bank-switching"},
93     {MPU_TRANSPARENT_ROM, "Transparent ROM", "transparent-rom"},
94     {MPU_PLAYSID_ENVIRONMENT, "Playsid Environment", "playsid-environment"},
95     {0, NULL, NULL},
96   };
98   if (!sid_memory_type) {
99     sid_memory_type = g_enum_register_static ("GstSidMemory", sid_memory);
100   }
101   return sid_memory_type;
104 static void gst_siddec_base_init (gpointer g_class);
105 static void gst_siddec_class_init (GstSidDec * klass);
106 static void gst_siddec_init (GstSidDec * siddec);
108 static GstFlowReturn gst_siddec_chain (GstPad * pad, GstBuffer * buffer);
109 static gboolean gst_siddec_sink_event (GstPad * pad, GstEvent * event);
111 static gboolean gst_siddec_src_convert (GstPad * pad, GstFormat src_format,
112     gint64 src_value, GstFormat * dest_format, gint64 * dest_value);
113 static gboolean gst_siddec_src_query (GstPad * pad, GstQuery * query);
115 static void gst_siddec_get_property (GObject * object, guint prop_id,
116     GValue * value, GParamSpec * pspec);
117 static void gst_siddec_set_property (GObject * object, guint prop_id,
118     const GValue * value, GParamSpec * pspec);
120 static GstElementClass *parent_class = NULL;
122 //static guint gst_siddec_signals[LAST_SIGNAL] = { 0 };
124 GType
125 gst_siddec_get_type (void)
127   static GType siddec_type = 0;
129   if (!siddec_type) {
130     static const GTypeInfo siddec_info = {
131       sizeof (GstSidDecClass),
132       gst_siddec_base_init,
133       NULL,
134       (GClassInitFunc) gst_siddec_class_init,
135       NULL,
136       NULL,
137       sizeof (GstSidDec),
138       0,
139       (GInstanceInitFunc) gst_siddec_init,
140       NULL
141     };
143     siddec_type =
144         g_type_register_static (GST_TYPE_ELEMENT, "GstSidDec", &siddec_info,
145         (GTypeFlags) 0);
146   }
148   return siddec_type;
151 static void
152 gst_siddec_base_init (gpointer g_class)
154   static GstElementDetails gst_siddec_details =
155       GST_ELEMENT_DETAILS ("Sid decoder",
156       "Codec/Decoder/Audio",
157       "Use sidplay to decode SID audio tunes",
158       "Wim Taymans <wim.taymans@chello.be> ");
159   GstElementClass *element_class = GST_ELEMENT_CLASS (g_class);
161   gst_element_class_set_details (element_class, &gst_siddec_details);
163   gst_element_class_add_pad_template (element_class,
164       gst_static_pad_template_get (&src_templ));
165   gst_element_class_add_pad_template (element_class,
166       gst_static_pad_template_get (&sink_templ));
170 static void
171 gst_siddec_class_init (GstSidDec * klass)
173   GObjectClass *gobject_class;
174   GstElementClass *gstelement_class;
176   gobject_class = (GObjectClass *) klass;
177   gstelement_class = (GstElementClass *) klass;
179   parent_class = GST_ELEMENT_CLASS (g_type_class_ref (GST_TYPE_ELEMENT));
181   gobject_class->set_property = gst_siddec_set_property;
182   gobject_class->get_property = gst_siddec_get_property;
184   g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_TUNE,
185       g_param_spec_int ("tune", "tune", "tune",
186           1, 100, 1, (GParamFlags) G_PARAM_READWRITE));
187   g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_CLOCK,
188       g_param_spec_enum ("clock", "clock", "clock",
189           GST_TYPE_SID_CLOCK, SIDTUNE_CLOCK_PAL,
190           (GParamFlags) G_PARAM_READWRITE));
191   g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_MEMORY,
192       g_param_spec_enum ("memory", "memory", "memory", GST_TYPE_SID_MEMORY,
193           MPU_PLAYSID_ENVIRONMENT, (GParamFlags) G_PARAM_READWRITE));
194   g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_FILTER,
195       g_param_spec_boolean ("filter", "filter", "filter", TRUE,
196           (GParamFlags) G_PARAM_READWRITE));
197   g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_MEASURED_VOLUME,
198       g_param_spec_boolean ("measured_volume", "measured_volume",
199           "measured_volume", TRUE, (GParamFlags) G_PARAM_READWRITE));
200   g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_MOS8580,
201       g_param_spec_boolean ("mos8580", "mos8580", "mos8580", TRUE,
202           (GParamFlags) G_PARAM_READWRITE));
203   g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_FORCE_SPEED,
204       g_param_spec_boolean ("force_speed", "force_speed", "force_speed", TRUE,
205           (GParamFlags) G_PARAM_READWRITE));
206   g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_BLOCKSIZE,
207       g_param_spec_ulong ("blocksize", "Block size",
208           "Size in bytes to output per buffer", 1, G_MAXULONG,
209           DEFAULT_BLOCKSIZE, (GParamFlags) G_PARAM_READWRITE));
210   g_object_class_install_property (gobject_class, ARG_METADATA,
211       g_param_spec_boxed ("metadata", "Metadata", "Metadata", GST_TYPE_CAPS,
212           (GParamFlags) G_PARAM_READABLE));
215 static void
216 gst_siddec_init (GstSidDec * siddec)
218   siddec->sinkpad =
219       gst_pad_new_from_template (gst_static_pad_template_get (&sink_templ),
220       "sink");
221   gst_pad_set_query_function (siddec->sinkpad, NULL);
222   gst_pad_set_event_function (siddec->sinkpad, gst_siddec_sink_event);
223   gst_pad_set_chain_function (siddec->sinkpad, gst_siddec_chain);
224   gst_element_add_pad (GST_ELEMENT (siddec), siddec->sinkpad);
226   siddec->srcpad =
227       gst_pad_new_from_template (gst_static_pad_template_get (&src_templ),
228       "src");
229   gst_pad_set_event_function (siddec->srcpad, NULL);
230   gst_pad_set_query_function (siddec->srcpad, gst_siddec_src_query);
231   gst_element_add_pad (GST_ELEMENT (siddec), siddec->srcpad);
233   siddec->engine = new emuEngine ();
234   siddec->tune = new sidTune (0);
235   siddec->config = (emuConfig *) g_malloc (sizeof (emuConfig));
237   siddec->config->frequency = 44100;    // frequency
238   siddec->config->bitsPerSample = SIDEMU_16BIT; // bits per sample
239   siddec->config->sampleFormat = SIDEMU_SIGNED_PCM;     // sample fomat
240   siddec->config->channels = SIDEMU_STEREO;     // channels
242   siddec->config->sidChips = 0; // -
243   siddec->config->volumeControl = SIDEMU_NONE;  // volume control
244   siddec->config->mos8580 = TRUE;       // mos8580
245   siddec->config->measuredVolume = TRUE;        // measure volume
246   siddec->config->emulateFilter = TRUE; // emulate filter
247   siddec->config->filterFs = SIDEMU_DEFAULTFILTERFS;    // filter Fs
248   siddec->config->filterFm = SIDEMU_DEFAULTFILTERFM;    // filter Fm
249   siddec->config->filterFt = SIDEMU_DEFAULTFILTERFT;    // filter Ft
250   siddec->config->memoryMode = MPU_PLAYSID_ENVIRONMENT; // memory mode
251   siddec->config->clockSpeed = SIDTUNE_CLOCK_PAL;       // clock speed
252   siddec->config->forceSongSpeed = TRUE;        // force song speed
253   siddec->config->digiPlayerScans = 0;  // digi player scans
254   siddec->config->autoPanning = SIDEMU_NONE;    // auto panning
256   siddec->engine->setConfig (*siddec->config);
257   siddec->engine->setDefaultFilterStrength ();
259   siddec->tune_buffer = (guchar *) g_malloc (maxSidtuneFileLen);
260   siddec->tune_len = 0;
261   siddec->tune_number = 1;
262   siddec->total_bytes = 0;
263   siddec->blocksize = DEFAULT_BLOCKSIZE;
266 #if 0
267 static void
268 update_metadata (GstSidDec * siddec)
270   sidTuneInfo info;
271   GstProps *props;
272   GstPropsEntry *entry;
274   if (siddec->tune->getInfo (info)) {
275     props = gst_props_empty_new ();
277     if (info.nameString) {
278       entry = gst_props_entry_new ("Title", G_TYPE_STRING (info.nameString));
279       gst_props_add_entry (props, entry);
280     }
281     if (info.authorString) {
282       entry =
283           gst_props_entry_new ("Composer", G_TYPE_STRING (info.authorString));
284       gst_props_add_entry (props, entry);
285     }
286     if (info.copyrightString) {
287       entry =
288           gst_props_entry_new ("Copyright",
289           G_TYPE_STRING (info.copyrightString));
290       gst_props_add_entry (props, entry);
291     }
293     siddec->metadata = gst_caps_new ("sid_metadata",
294         "application/x-gst-metadata", props);
296     g_object_notify (G_OBJECT (siddec), "metadata");
297   }
299 #endif
301 #define GET_FIXED_INT(caps, name, dest)         \
302 G_STMT_START {                                  \
303   if (gst_caps_has_fixed_property (caps, name)) \
304     gst_structure_get_int  (structure, name, (gint*)dest);  \
305 } G_STMT_END
306 #define GET_FIXED_BOOLEAN(caps, name, dest)     \
307 G_STMT_START {                                  \
308   if (gst_caps_has_fixed_property (caps, name)) \
309     gst_structure_get_boolean  (structure, name, dest);    \
310 } G_STMT_END
312 static gboolean
313 siddec_negotiate (GstSidDec * siddec)
315   GstCaps *allowed;
316   gboolean sign = TRUE;
317   gint width = 16, depth = 16;
318   GstStructure *structure;
319   int rate = 22050;
320   int channels = 2;
322   allowed = gst_pad_get_allowed_caps (siddec->srcpad);
323   if (!allowed) {
324     GST_DEBUG_OBJECT (siddec, "could not get allowed caps");
325     return FALSE;
326   }
327   GST_DEBUG_OBJECT (siddec, "allowed caps: " GST_PTR_FORMAT, allowed);
329   structure = gst_caps_get_structure (allowed, 0);
331   gst_structure_get_int (structure, "width", &width);
332   gst_structure_get_int (structure, "depth", &depth);
334   if (width && depth && width != depth) {
335     GST_DEBUG_OBJECT (siddec, "width %d and depth %d are different",
336         width, depth);
337     return FALSE;
338   }
339   width = width | depth;
341   if (width) {
342     siddec->config->bitsPerSample = width;
343   }
345   gst_structure_get_boolean (structure, "signed", &sign);
346   gst_structure_get_int (structure, "rate", &rate);
347   siddec->config->frequency = rate;
348   gst_structure_get_int (structure, "channels", &channels);
349   siddec->config->channels = channels;
351   siddec->config->sampleFormat =
352       (sign ? SIDEMU_SIGNED_PCM : SIDEMU_UNSIGNED_PCM);
354   gst_pad_set_caps (siddec->srcpad,
355       gst_caps_new_simple ("audio/x-raw-int",
356           "endianness", G_TYPE_INT, G_BYTE_ORDER,
357           "signed", G_TYPE_BOOLEAN, sign,
358           "width", G_TYPE_INT, siddec->config->bitsPerSample,
359           "depth", G_TYPE_INT, siddec->config->bitsPerSample,
360           "rate", G_TYPE_INT, siddec->config->frequency,
361           "channels", G_TYPE_INT, siddec->config->channels, NULL));
363   siddec->engine->setConfig (*siddec->config);
365   return TRUE;
368 static void
369 play_loop (GstPad * pad)
371   GstFlowReturn ret;
372   GstSidDec *siddec;
373   GstBuffer *out;
374   gint64 value, offset, time;
375   GstFormat format;
377   siddec = GST_SIDDEC (GST_PAD_PARENT (pad));
379   out = gst_buffer_new_and_alloc (siddec->blocksize);
380   gst_buffer_set_caps (out, GST_PAD_CAPS (pad));
382   sidEmuFillBuffer (*siddec->engine, *siddec->tune,
383       GST_BUFFER_DATA (out), GST_BUFFER_SIZE (out));
385   /* get offset in samples */
386   format = GST_FORMAT_DEFAULT;
387   gst_siddec_src_convert (siddec->srcpad,
388       GST_FORMAT_BYTES, siddec->total_bytes, &format, &offset);
389   GST_BUFFER_OFFSET (out) = offset;
391   /* get current timestamp */
392   format = GST_FORMAT_TIME;
393   gst_siddec_src_convert (siddec->srcpad,
394       GST_FORMAT_BYTES, siddec->total_bytes, &format, &time);
395   GST_BUFFER_TIMESTAMP (out) = time;
397   /* update position and get new timestamp to calculate duration */
398   siddec->total_bytes += siddec->blocksize;
400   /* get offset in samples */
401   format = GST_FORMAT_DEFAULT;
402   gst_siddec_src_convert (siddec->srcpad,
403       GST_FORMAT_BYTES, siddec->total_bytes, &format, &value);
404   GST_BUFFER_OFFSET_END (out) = value;
406   format = GST_FORMAT_TIME;
407   gst_siddec_src_convert (siddec->srcpad,
408       GST_FORMAT_BYTES, siddec->total_bytes, &format, &value);
409   GST_BUFFER_DURATION (out) = value - time;
411   if ((ret = gst_pad_push (siddec->srcpad, out)) != GST_FLOW_OK)
412     goto pause;
414   return;
416 pause:
417   {
418     gst_pad_pause_task (pad);
419   }
422 static gboolean
423 start_play_tune (GstSidDec * siddec)
425   gboolean res;
427   if (!siddec->tune->load (siddec->tune_buffer, siddec->tune_len))
428     goto could_not_load;
430   //update_metadata (siddec);
432   if (!siddec_negotiate (siddec))
433     goto could_not_negotiate;
435   if (!sidEmuInitializeSong (*siddec->engine, *siddec->tune,
436           siddec->tune_number))
437     goto could_not_init;
439   gst_pad_push_event (siddec->srcpad,
440       gst_event_new_new_segment (FALSE, 1.0, GST_FORMAT_TIME, 0, -1, 0));
442   res = gst_pad_start_task (siddec->srcpad,
443       (GstTaskFunction) play_loop, siddec->srcpad);
444   return res;
446   /* ERRORS */
447 could_not_load:
448   {
449     GST_ELEMENT_ERROR (siddec, LIBRARY, INIT,
450         ("Could not load tune"), ("Could not load tune"));
451     return FALSE;
452   }
453 could_not_negotiate:
454   {
455     GST_ELEMENT_ERROR (siddec, CORE, NEGOTIATION,
456         ("Could not negotiate format"), ("Could not negotiate format"));
457     return FALSE;
458   }
459 could_not_init:
460   {
461     GST_ELEMENT_ERROR (siddec, LIBRARY, INIT,
462         ("Could not initialize song"), ("Could not initialize song"));
463     return FALSE;
464   }
467 static gboolean
468 gst_siddec_sink_event (GstPad * pad, GstEvent * event)
470   GstSidDec *siddec;
471   gboolean res;
473   siddec = GST_SIDDEC (GST_PAD_PARENT (pad));
475   switch (GST_EVENT_TYPE (event)) {
476     case GST_EVENT_EOS:
477       res = start_play_tune (siddec);
478       break;
479     case GST_EVENT_NEWSEGMENT:
480       res = FALSE;
481       break;
482     default:
483       res = FALSE;
484       break;
485   }
486   gst_event_unref (event);
488   return res;
491 static GstFlowReturn
492 gst_siddec_chain (GstPad * pad, GstBuffer * buffer)
494   GstSidDec *siddec;
495   guint64 size;
497   siddec = GST_SIDDEC (GST_PAD_PARENT (pad));
499   size = GST_BUFFER_SIZE (buffer);
500   if (siddec->tune_len + size > maxSidtuneFileLen)
501     goto overflow;
503   memcpy (siddec->tune_buffer + siddec->tune_len, GST_BUFFER_DATA (buffer),
504       size);
505   siddec->tune_len += size;
507   gst_buffer_unref (buffer);
509   return GST_FLOW_OK;
511 overflow:
512   {
513     return GST_FLOW_ERROR;
514   }
517 static gboolean
518 gst_siddec_src_convert (GstPad * pad, GstFormat src_format, gint64 src_value,
519     GstFormat * dest_format, gint64 * dest_value)
521   gboolean res = TRUE;
522   guint scale = 1;
523   GstSidDec *siddec;
524   gint bytes_per_sample;
526   siddec = GST_SIDDEC (GST_PAD_PARENT (pad));
528   if (src_format == *dest_format) {
529     *dest_value = src_value;
530     return TRUE;
531   }
533   bytes_per_sample =
534       (siddec->config->bitsPerSample >> 3) * siddec->config->channels;
536   switch (src_format) {
537     case GST_FORMAT_BYTES:
538       switch (*dest_format) {
539         case GST_FORMAT_DEFAULT:
540           if (bytes_per_sample == 0)
541             return FALSE;
542           *dest_value = src_value / bytes_per_sample;
543           break;
544         case GST_FORMAT_TIME:
545         {
546           gint byterate = bytes_per_sample * siddec->config->frequency;
548           if (byterate == 0)
549             return FALSE;
550           *dest_value = src_value * GST_SECOND / byterate;
551           break;
552         }
553         default:
554           res = FALSE;
555       }
556       break;
557     case GST_FORMAT_DEFAULT:
558       switch (*dest_format) {
559         case GST_FORMAT_BYTES:
560           *dest_value = src_value * bytes_per_sample;
561           break;
562         case GST_FORMAT_TIME:
563           if (siddec->config->frequency == 0)
564             return FALSE;
565           *dest_value = src_value * GST_SECOND / siddec->config->frequency;
566           break;
567         default:
568           res = FALSE;
569       }
570       break;
571     case GST_FORMAT_TIME:
572       switch (*dest_format) {
573         case GST_FORMAT_BYTES:
574           scale = bytes_per_sample;
575           /* fallthrough */
576         case GST_FORMAT_DEFAULT:
577           *dest_value =
578               src_value * scale * siddec->config->frequency / GST_SECOND;
579           break;
580         default:
581           res = FALSE;
582       }
583       break;
584     default:
585       res = FALSE;
586   }
588   return res;
591 static gboolean
592 gst_siddec_src_query (GstPad * pad, GstQuery * query)
594   gboolean res = TRUE;
595   GstSidDec *siddec;
597   siddec = GST_SIDDEC (GST_PAD_PARENT (pad));
599   switch (GST_QUERY_TYPE (query)) {
600     case GST_QUERY_POSITION:
601     {
602       GstFormat format;
603       gint64 current;
605       gst_query_parse_position (query, &format, NULL);
607       /* we only know about our bytes, convert to requested format */
608       res &= gst_siddec_src_convert (pad,
609           GST_FORMAT_BYTES, siddec->total_bytes, &format, &current);
610       if (res) {
611         gst_query_set_position (query, format, current);
612       }
613       break;
614     }
615     default:
616       res = gst_pad_query_default (pad, query);
617       break;
618   }
619   return res;
622 static void
623 gst_siddec_set_property (GObject * object, guint prop_id, const GValue * value,
624     GParamSpec * pspec)
626   GstSidDec *siddec;
628   /* it's not null if we got it, but it might not be ours */
629   g_return_if_fail (GST_IS_SIDDEC (object));
630   siddec = GST_SIDDEC (object);
632   switch (prop_id) {
633     case ARG_TUNE:
634       siddec->tune_number = g_value_get_int (value);
635       break;
636     case ARG_CLOCK:
637       siddec->config->clockSpeed = g_value_get_enum (value);
638       break;
639     case ARG_MEMORY:
640       siddec->config->memoryMode = g_value_get_enum (value);
641       break;
642     case ARG_FILTER:
643       siddec->config->emulateFilter = g_value_get_boolean (value);
644       break;
645     case ARG_MEASURED_VOLUME:
646       siddec->config->measuredVolume = g_value_get_boolean (value);
647       break;
648     case ARG_MOS8580:
649       siddec->config->mos8580 = g_value_get_boolean (value);
650       break;
651     case ARG_BLOCKSIZE:
652       siddec->blocksize = g_value_get_ulong (value);
653       break;
654     case ARG_FORCE_SPEED:
655       siddec->config->forceSongSpeed = g_value_get_boolean (value);
656       break;
657     default:
658       /* G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); */
659       return;
660   }
661   siddec->engine->setConfig (*siddec->config);
664 static void
665 gst_siddec_get_property (GObject * object, guint prop_id, GValue * value,
666     GParamSpec * pspec)
668   GstSidDec *siddec;
670   /* it's not null if we got it, but it might not be ours */
671   g_return_if_fail (GST_IS_SIDDEC (object));
672   siddec = GST_SIDDEC (object);
674   switch (prop_id) {
675     case ARG_TUNE:
676       g_value_set_int (value, siddec->tune_number);
677       break;
678     case ARG_CLOCK:
679       g_value_set_enum (value, siddec->config->clockSpeed);
680       break;
681     case ARG_MEMORY:
682       g_value_set_enum (value, siddec->config->memoryMode);
683       break;
684     case ARG_FILTER:
685       g_value_set_boolean (value, siddec->config->emulateFilter);
686       break;
687     case ARG_MEASURED_VOLUME:
688       g_value_set_boolean (value, siddec->config->measuredVolume);
689       break;
690     case ARG_MOS8580:
691       g_value_set_boolean (value, siddec->config->mos8580);
692       break;
693     case ARG_FORCE_SPEED:
694       g_value_set_boolean (value, siddec->config->forceSongSpeed);
695       break;
696     case ARG_BLOCKSIZE:
697       g_value_set_ulong (value, siddec->blocksize);
698       break;
699     case ARG_METADATA:
700       g_value_set_boxed (value, siddec->metadata);
701       break;
702     default:
703       /* G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); */
704       break;
705   }
708 static gboolean
709 plugin_init (GstPlugin * plugin)
711   return gst_element_register (plugin, "siddec", GST_RANK_PRIMARY,
712       GST_TYPE_SIDDEC);
715 GST_PLUGIN_DEFINE (GST_VERSION_MAJOR,
716     GST_VERSION_MINOR,
717     "siddec",
718     "Uses libsid to decode .sid files",
719     plugin_init, VERSION, "GPL", GST_PACKAGE_NAME, GST_PACKAGE_ORIGIN);