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, "0", "PAL"},
76 {SIDTUNE_CLOCK_NTSC, "1", "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, "32", "Bank Switching"},
93 {MPU_TRANSPARENT_ROM, "33", "Transparent ROM"},
94 {MPU_PLAYSID_ENVIRONMENT, "34", "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;
102 }
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)
126 {
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;
149 }
151 static void
152 gst_siddec_base_init (gpointer g_class)
153 {
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));
168 }
170 static void
171 gst_siddec_class_init (GstSidDec * klass)
172 {
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));
213 }
215 static void
216 gst_siddec_init (GstSidDec * siddec)
217 {
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;
264 }
266 #if 0
267 static void
268 update_metadata (GstSidDec * siddec)
269 {
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 }
298 }
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)
314 {
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;
366 }
368 static void
369 play_loop (GstPad * pad)
370 {
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 }
420 }
422 static gboolean
423 start_play_tune (GstSidDec * siddec)
424 {
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 }
465 }
467 static gboolean
468 gst_siddec_sink_event (GstPad * pad, GstEvent * event)
469 {
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;
489 }
491 static GstFlowReturn
492 gst_siddec_chain (GstPad * pad, GstBuffer * buffer)
493 {
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 }
515 }
517 static gboolean
518 gst_siddec_src_convert (GstPad * pad, GstFormat src_format, gint64 src_value,
519 GstFormat * dest_format, gint64 * dest_value)
520 {
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;
589 }
591 static gboolean
592 gst_siddec_src_query (GstPad * pad, GstQuery * query)
593 {
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, ¤t);
610 if (res) {
611 gst_query_set_position (query, format, current);
612 }
613 break;
614 }
615 default:
616 res = FALSE;
617 break;
618 }
619 return res;
620 }
622 static void
623 gst_siddec_set_property (GObject * object, guint prop_id, const GValue * value,
624 GParamSpec * pspec)
625 {
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);
662 }
664 static void
665 gst_siddec_get_property (GObject * object, guint prop_id, GValue * value,
666 GParamSpec * pspec)
667 {
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 }
706 }
708 static gboolean
709 plugin_init (GstPlugin * plugin)
710 {
711 return gst_element_register (plugin, "siddec", GST_RANK_PRIMARY,
712 GST_TYPE_SIDDEC);
713 }
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, GST_ORIGIN)