adding mikmod

Original commit message from CVS:
adding mikmod
This commit is contained in:
Thomas Vander Stichele 2001-12-23 16:13:33 +00:00
parent 754f9a350c
commit 6dfbea5001
7 changed files with 1295 additions and 0 deletions

12
ext/mikmod/Makefile.am Normal file
View file

@ -0,0 +1,12 @@
plugindir = $(libdir)/gst
plugin_LTLIBRARIES = libgstmikmod.la
libgstmikmod_la_SOURCES = gstmikmod.c drv_gst.c mikmod_reader.c mikmod_types.c
libgstmikmod_la_LIBADD = $(MIKMOD_LIBS)
libgstmikmod_la_CFLAGS = $(MIKMOD_CFLAGS) $(GST_CFLAGS)
noinst_HEADERS = gstmikmod.h
EXTRA_DIST = README

86
ext/mikmod/README Normal file
View file

@ -0,0 +1,86 @@
Hi,
This is the gstreamer MikMod plugin. It is able to play the IT, XM, S3M,
MTM, 669, STM, ULT, FAR, MED, AMF, DSM, IMF, GDM, STX, OKT and of course MOD
module formats.
Take a look to : www.mikmod.org
Usage : gstreamer-launch disksrc location=foo.mod ! mikmod ! osssink
or gstmediaplay foo.mod
Properties :
musicvolume :
Volume of the module. Allowed values range from 0 to 128. The default value is 128.
pansep :
Stereo channels separation. Allowed values range from 0 (no separation, thus mono sound)
to 128 (full channel separation). The default value is 128.
reverb :
Amount of sound reverberation. Allowed values range from 0 (no reverberation) to 15
(a rough estimate for chaos...). The default value is 6.
sndfxvolume :
Volume of the sound effects. Allowed values range from 0 to 128. The default value is 128.
volume :
Overall sound volume. Allowed values range from 0 to 128. The default value is 96
interp :
This flag, if set, enables the interpolated mixers. Interpolated mixing gives better
sound but takes a bit more time than standard mixing. If the library is built with the
high quality mixer, interpolated mixing is always enabled, regardless of this flag. The
default value is false.
reverse :
This flag, if set, exchanges the left and right stereo channels. The default value is false.
surround :
This flag, if set, enables the surround mixers. Since surround mixing works only for stereo
sound, this flag has no effect if the sound playback is in mono. The default value is true.
16bit :
This flag, if set, selects 16 bit sound mode. This mode yields better sound quality, but needs
twice more mixing time. The default value is true.
hqmixer :
This flag, if set, selects the high-quality software mixer. This mode yields better sound quality,
but needs more mixing time. Of course, this flag has no effect if no DMODE_SOFT_xx flag is set.
The default value is false.
soft_music :
This flag, if set, selects software mixing of the module. The default value is true.
soft_sndfx :
This flag, if set, selects software mixing of the sound effects. The default value is true.
stereo :
This flag, if set, selects stereo sound. The default value is true.
--
Apoc
/* MikMod sound library
(c) 1998, 1999, 2000 Miodrag Vallat and others - see file AUTHORS
for complete list.
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 program 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 this library; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
02111-1307, USA.
*/

97
ext/mikmod/drv_gst.c Normal file
View file

@ -0,0 +1,97 @@
#include <stdlib.h>
#include "gstmikmod.h"
static int buffer_size;
static SBYTE *audiobuffer = NULL;
extern int need_sync;
static BOOL mikmod_IsThere( void )
{
return 1;
}
static BOOL mikmod_Init( void )
{
buffer_size = 32768;
if (!( audiobuffer = ( SBYTE * ) g_malloc( buffer_size ) ))
return 1;
return VC_Init();
}
static void mikmod_Exit( void )
{
VC_Exit();
if ( audiobuffer )
{
g_free(audiobuffer);
audiobuffer = NULL;
}
}
static void mikmod_Update( void )
{
gint length;
GstBuffer *outdata;
length = VC_WriteBytes((SBYTE *) audiobuffer, buffer_size);
outdata = gst_buffer_new();
GST_BUFFER_DATA( outdata ) = g_memdup( audiobuffer, length );
GST_BUFFER_SIZE( outdata ) = length;
if ( need_sync == 1 )
{
GST_BUFFER_FLAG_SET (outdata, GST_BUFFER_FLUSH);
need_sync = 0 ;
}
gst_pad_push( srcpad, outdata );
}
static BOOL mikmod_Reset( void )
{
VC_Exit();
return VC_Init();
}
MDRIVER drv_gst =
{
NULL,
"mikmod",
"mikmod output driver v1.0",
0, 255,
#if (LIBMIKMOD_VERSION > 0x030106)
"mikmod",
NULL,
#endif
mikmod_IsThere,
VC_SampleLoad,
VC_SampleUnload,
VC_SampleSpace,
VC_SampleLength,
mikmod_Init,
mikmod_Exit,
mikmod_Reset,
VC_SetNumVoices,
VC_PlayStart,
VC_PlayStop,
mikmod_Update,
NULL,
VC_VoiceSetVolume,
VC_VoiceGetVolume,
VC_VoiceSetFrequency,
VC_VoiceGetFrequency,
VC_VoiceSetPanning,
VC_VoiceGetPanning,
VC_VoicePlay,
VC_VoiceStop,
VC_VoiceStopped,
VC_VoiceGetPosition,
VC_VoiceRealVolume
};

656
ext/mikmod/gstmikmod.c Normal file
View file

@ -0,0 +1,656 @@
/* Gnome-Streamer
* Copyright (C) <1999> Erik Walthinsen <omega@cse.ogi.edu>
*
* 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 this library; if not, write to the
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*/
#include "gstmikmod.h"
#include <libs/audio/gstaudio.h>
#include <stdlib.h>
GstElementDetails mikmod_details = {
"MikMod",
"Audio/Module",
"Module decoder based on libmikmod",
VERSION,
"Jeremy SIMON <jsimon13@yahoo.fr>",
"(C) 2001",
};
/* Filter signals and args */
enum {
/* FILL ME */
LAST_SIGNAL
};
enum {
ARG_0,
ARG_SONGNAME,
ARG_MODTYPE,
ARG_MUSICVOLUME,
ARG_PANSEP,
ARG_REVERB,
ARG_SNDFXVOLUME,
ARG_VOLUME,
ARG_FIXFREQ,
ARG_INTERP,
ARG_REVERSE,
ARG_SURROUND,
ARG_16BIT,
ARG_HQMIXER,
ARG_SOFT_MUSIC,
ARG_SOFT_SNDFX,
ARG_STEREO
};
static GstPadTemplate*
mikmod_src_factory (void)
{
static GstPadTemplate *template = NULL;
if (!template) {
template = gst_padtemplate_new (
"src",
GST_PAD_SRC,
GST_PAD_ALWAYS,
gst_caps_new (
"mikmod_src",
"audio/raw",
gst_props_new (
"format", GST_PROPS_STRING ("int"),
"law", GST_PROPS_INT (0),
"endianness", GST_PROPS_INT (G_BYTE_ORDER),
"signed", GST_PROPS_BOOLEAN (TRUE),
"width", GST_PROPS_INT (16),
"depth", GST_PROPS_INT (16),
"rate", GST_PROPS_INT_RANGE (8000, 48000),
"channels", GST_PROPS_INT_RANGE (1, 2),
NULL)),NULL);
}
return template;
}
static GstPadTemplate*
mikmod_sink_factory (void)
{
static GstPadTemplate *template = NULL;
if (!template) {
template = gst_padtemplate_new (
"sink",
GST_PAD_SINK,
GST_PAD_ALWAYS,
gst_caps_new (
"mikmod_sink",
"audio/mod",
NULL),NULL
);
}
return template;
}
static GstCaps*
mikmod_typefind (GstBuffer *buf, gpointer private)
{
if ( MOD_CheckType( buf ) )
return gst_caps_new ("mikmod_typefind", "audio/mod", NULL);
if ( Mod_669_CheckType( buf ) )
return gst_caps_new ("mikmod_typefind", "audio/mod", NULL);
if ( Amf_CheckType( buf ) )
return gst_caps_new ("mikmod_typefind", "audio/mod", NULL);
if ( Dsm_CheckType( buf ) )
return gst_caps_new ("mikmod_typefind", "audio/mod", NULL);
if ( Fam_CheckType( buf ) )
return gst_caps_new ("mikmod_typefind", "audio/mod", NULL);
if ( Gdm_CheckType( buf ) )
return gst_caps_new ("mikmod_typefind", "audio/mod", NULL);
if ( Imf_CheckType( buf ) )
return gst_caps_new ("mikmod_typefind", "audio/mod", NULL);
if ( It_CheckType( buf ) )
return gst_caps_new ("mikmod_typefind", "audio/mod", NULL);
if ( M15_CheckType( buf ) )
return gst_caps_new ("mikmod_typefind", "audio/mod", NULL);
/* FIXME
if ( Med_CheckType( buf ) )
return gst_caps_new ("mikmod_typefind", "audio/mod", NULL);
*/
if ( Mtm_CheckType( buf ) )
return gst_caps_new ("mikmod_typefind", "audio/mod", NULL);
if ( Okt_CheckType( buf ) )
return gst_caps_new ("mikmod_typefind", "audio/mod", NULL);
if ( S3m_CheckType( buf ) )
return gst_caps_new ("mikmod_typefind", "audio/mod", NULL);
if ( Xm_CheckType( buf ) )
return gst_caps_new ("mikmod_typefind", "audio/mod", NULL);
return NULL;
}
static GstTypeDefinition mikmoddefinition = {
"mikmod_audio/mod", "audio/mod", ".mod .sam .med .s3m .it .xm .stm .mtm .669 .ult .far .amf .dsm .imf .gdm .stx .okt", mikmod_typefind
};
static void gst_mikmod_class_init (GstMikModClass *klass);
static void gst_mikmod_init (GstMikMod *filter);
static void gst_mikmod_set_property (GObject *object, guint id, const GValue *value, GParamSpec *pspec );
static void gst_mikmod_get_property (GObject *object, guint id, GValue *value, GParamSpec *pspec );
static void gst_mikmod_loop (GstElement *element);
static gboolean gst_mikmod_setup (GstMikMod *mikmod);
static GstElementStateReturn gst_mikmod_change_state (GstElement *element);
static GstPadNegotiateReturn mikmod_negotiate_sink (GstPad *pad, GstCaps **caps, gpointer *data);
static GstPadNegotiateReturn mikmod_negotiate_sink (GstPad *pad, GstCaps **caps, gpointer *data);
static GstElementClass *parent_class = NULL;
#define GST_TYPE_MIKMOD_MIXFREQ (gst_mikmod_mixfreq_get_type())
static GType
gst_mikmod_mixfreq_get_type (void)
{
static GType mikmod_mixfreq_type = 0;
static GEnumValue mikmod_mixfreq[] = {
{ 0, "8000", "8000 Hz" },
{ 1, "11025", "11025 Hz" },
{ 2, "22100", "22100 Hz" },
{ 3, "44100", "44100 Hz" },
{ 0, NULL, NULL },
};
if (! mikmod_mixfreq_type ) {
mikmod_mixfreq_type = g_enum_register_static ("GstMikmodmixfreq", mikmod_mixfreq);
}
return mikmod_mixfreq_type;
}
static GstPadNegotiateReturn
mikmod_negotiate_src (GstPad *pad, GstCaps **caps, gpointer *data)
{
GstMikMod* filter = GST_MIKMOD (gst_pad_get_parent (pad));
if (*caps==NULL)
return GST_PAD_NEGOTIATE_FAIL;
return gst_pad_negotiate_proxy(pad,filter->sinkpad,caps);
}
static GstPadNegotiateReturn
mikmod_negotiate_sink (GstPad *pad, GstCaps **caps, gpointer *data)
{
GstMikMod* filter = GST_MIKMOD (gst_pad_get_parent (pad));
if (*caps==NULL)
return GST_PAD_NEGOTIATE_FAIL;
return gst_pad_negotiate_proxy(pad,filter->srcpad,caps);
}
GType
gst_mikmod_get_type(void) {
static GType mikmod_type = 0;
if (!mikmod_type) {
static const GTypeInfo mikmod_info = {
sizeof(GstMikModClass),
NULL,
NULL,
(GClassInitFunc)gst_mikmod_class_init,
NULL,
NULL,
sizeof(GstMikMod),
0,
(GInstanceInitFunc)gst_mikmod_init,
};
mikmod_type = g_type_register_static(GST_TYPE_ELEMENT, "GstMikmod", &mikmod_info, 0);
}
return mikmod_type;
}
static void
gst_mikmod_class_init (GstMikModClass *klass)
{
GObjectClass *gobject_class;
GstElementClass *gstelement_class;
gobject_class = (GObjectClass*)klass;
gstelement_class = (GstElementClass*)klass;
parent_class = g_type_class_ref(GST_TYPE_ELEMENT);
g_object_class_install_property(G_OBJECT_CLASS(klass), ARG_SONGNAME,
g_param_spec_string("songname","songname","songname",
"", G_PARAM_READABLE));
g_object_class_install_property(G_OBJECT_CLASS(klass), ARG_MODTYPE,
g_param_spec_string("modtype", "modtype", "modtype",
"", G_PARAM_READABLE ));
g_object_class_install_property(G_OBJECT_CLASS(klass), ARG_MUSICVOLUME,
g_param_spec_int("musicvolume", "musivolume", "musicvolume",
0, 128, 128, G_PARAM_READWRITE ));
g_object_class_install_property(G_OBJECT_CLASS(klass), ARG_PANSEP,
g_param_spec_int("pansep", "pansep", "pansep",
0, 128, 128, G_PARAM_READWRITE ));
g_object_class_install_property(G_OBJECT_CLASS(klass), ARG_REVERB,
g_param_spec_int("reverb", "reverb", "reverb",
0, 15, 0, G_PARAM_READWRITE ));
g_object_class_install_property(G_OBJECT_CLASS(klass), ARG_SNDFXVOLUME,
g_param_spec_int("sndfxvolume", "sndfxvolume", "sndfxvolume",
0, 128, 128, G_PARAM_READWRITE ));
g_object_class_install_property(G_OBJECT_CLASS(klass), ARG_VOLUME,
g_param_spec_int("volume", "volume", "volume",
0, 128, 96, G_PARAM_READWRITE ));
g_object_class_install_property(G_OBJECT_CLASS(klass), ARG_FIXFREQ,
g_param_spec_enum("mixfreq", "mixfreq", "mixfreq",
GST_TYPE_MIKMOD_MIXFREQ, 3,G_PARAM_READWRITE ));
g_object_class_install_property(G_OBJECT_CLASS(klass), ARG_INTERP,
g_param_spec_boolean("interp", "interp", "interp",
FALSE, G_PARAM_READWRITE ));
g_object_class_install_property(G_OBJECT_CLASS(klass), ARG_REVERSE,
g_param_spec_boolean("reverse", "reverse", "reverse",
FALSE, G_PARAM_READWRITE ));
g_object_class_install_property(G_OBJECT_CLASS(klass), ARG_SURROUND,
g_param_spec_boolean("surround", "surround", "surround",
TRUE, G_PARAM_READWRITE ));
g_object_class_install_property(G_OBJECT_CLASS(klass), ARG_16BIT,
g_param_spec_boolean("use16bit", "use16bit", "use16bit",
TRUE, G_PARAM_READWRITE ));
g_object_class_install_property(G_OBJECT_CLASS(klass), ARG_HQMIXER,
g_param_spec_boolean("hqmixer", "hqmixer", "hqmixer",
FALSE, G_PARAM_READWRITE ));
g_object_class_install_property(G_OBJECT_CLASS(klass), ARG_SOFT_MUSIC,
g_param_spec_boolean("soft_music", "soft_music", "soft_music",
TRUE, G_PARAM_READWRITE ));
g_object_class_install_property(G_OBJECT_CLASS(klass), ARG_SOFT_SNDFX,
g_param_spec_boolean("soft_sndfx", "soft_sndfx", "soft_sndfx",
TRUE, G_PARAM_READWRITE ));
g_object_class_install_property(G_OBJECT_CLASS(klass), ARG_STEREO,
g_param_spec_boolean("stereo", "stereo", "stereo",
TRUE, G_PARAM_READWRITE ));
gobject_class->set_property = gst_mikmod_set_property;
gobject_class->get_property = gst_mikmod_get_property;
gstelement_class->change_state = gst_mikmod_change_state;
}
static void
gst_mikmod_init (GstMikMod *filter)
{
filter->sinkpad = gst_pad_new_from_template(mikmod_sink_factory (),"sink");
filter->srcpad = gst_pad_new_from_template(mikmod_src_factory (),"src");
/*gst_pad_set_negotiate_function(filter->sinkpad,mikmod_negotiate_sink);
gst_pad_set_negotiate_function(filter->srcpad,mikmod_negotiate_src);*/
gst_element_add_pad(GST_ELEMENT(filter),filter->sinkpad);
gst_element_add_pad(GST_ELEMENT(filter),filter->srcpad);
gst_element_set_loop_function (GST_ELEMENT (filter), gst_mikmod_loop);
filter->Buffer = gst_buffer_new();
filter->stereo = TRUE;
filter->surround = TRUE;
filter->_16bit = TRUE;
filter->soft_music = TRUE;
filter->soft_sndfx = TRUE;
filter->mixfreq = 44100;
filter->reverb = 0;
filter->pansep = 128;
filter->musicvolume = 128;
filter->volume = 96;
filter->sndfxvolume = 128;
}
static void
gst_mikmod_loop (GstElement *element)
{
GstMikMod *mikmod;
GstBuffer *buffer_in;
gint mode16bits;
gint first = 0;
g_return_if_fail (element != NULL);
g_return_if_fail (GST_IS_MIKMOD (element));
mikmod = GST_MIKMOD (element);
srcpad = mikmod->srcpad;
mikmod->Buffer = NULL;
while ((buffer_in = gst_pad_pull( mikmod->sinkpad ))) /*&& GST_BUFFER_SIZE(buffer_tmp) != 0 && GST_BUFFER_SIZE(buffer_tmp) != -1 ) */
{
if ( GST_IS_EVENT (buffer_in) )
{
GstEvent *event = GST_EVENT (buffer_in);
if (GST_EVENT_TYPE (event) == GST_EVENT_EOS)
break;
}
/*if ( GST_BUFFER_SIZE(buffer_in) != 0 && GST_BUFFER_SIZE(buffer_in) != -1 )
{*/
if ( mikmod->Buffer )
{
mikmod->Buffer = gst_buffer_append( mikmod->Buffer, buffer_in );
gst_buffer_unref( buffer_in );
}
else
mikmod->Buffer = buffer_in;
/* }*/
}
if ( mikmod->_16bit )
mode16bits = 16;
else
mode16bits = 8;
MikMod_RegisterDriver(&drv_gst);
MikMod_RegisterAllLoaders();
MikMod_Init("");
reader = GST_READER_new( mikmod );
module = Player_LoadGeneric ( reader, 64, 0 );
if ( ! Player_Active() )
Player_Start(module);
gst_pad_set_caps (mikmod->srcpad, gst_caps_new (
"mikmod_src",
"audio/raw",
gst_props_new (
"format", GST_PROPS_STRING ("int"),
"law", GST_PROPS_INT (0),
"endianness", GST_PROPS_INT (G_BYTE_ORDER),
"signed", GST_PROPS_BOOLEAN (TRUE),
"width", GST_PROPS_INT (mode16bits),
"depth", GST_PROPS_INT (mode16bits),
"rate", GST_PROPS_INT (mikmod->mixfreq),
"channels", GST_PROPS_INT (2),
NULL
)
));
do {
if ( Player_Active() )
drv_gst.Update();
if (GST_ELEMENT_IS_COTHREAD_STOPPING (element))
cothread_switch(cothread_current_main());
}
while ( 1 );
}
static gboolean
gst_mikmod_setup (GstMikMod *mikmod)
{
md_musicvolume = mikmod->musicvolume;
md_pansep = mikmod->pansep;
md_reverb = mikmod->reverb;
md_sndfxvolume = mikmod->sndfxvolume;
md_volume = mikmod->volume;
md_mixfreq = mikmod->mixfreq;
md_mode = 0;
if ( mikmod->interp )
md_mode = md_mode | DMODE_INTERP;
if ( mikmod->reverse )
md_mode = md_mode | DMODE_REVERSE;
if ( mikmod->surround )
md_mode = md_mode | DMODE_SURROUND;
if ( mikmod->_16bit )
md_mode = md_mode | DMODE_16BITS;
if ( mikmod->hqmixer )
md_mode = md_mode | DMODE_HQMIXER;
if ( mikmod->soft_music )
md_mode = md_mode | DMODE_SOFT_MUSIC;
if ( mikmod->soft_sndfx )
md_mode = md_mode | DMODE_SOFT_SNDFX;
if ( mikmod->stereo )
md_mode = md_mode | DMODE_STEREO;
return TRUE;
}
static GstElementStateReturn
gst_mikmod_change_state (GstElement *element)
{
GstMikMod *mikmod;
g_return_val_if_fail (GST_IS_MIKMOD (element), GST_STATE_FAILURE);
mikmod = GST_MIKMOD (element);
GST_DEBUG (0,"state pending %d\n", GST_STATE_PENDING (element));
/* if going down into NULL state, close the file if it's open */
if (GST_STATE_PENDING (element) == GST_STATE_READY)
{
gst_mikmod_setup(mikmod);
if ( Player_Active() )
{
Player_TogglePause();
Player_SetPosition( 0 );
}
}
if (GST_STATE_PENDING (element) == GST_STATE_PLAYING)
{
if ( Player_Active() && Player_Paused() )
Player_TogglePause();
else
if ( ! Player_Active() )
Player_Start(module);
}
if (GST_STATE_PENDING (element) == GST_STATE_PAUSED)
if ( Player_Active() && ! Player_Paused() )
Player_TogglePause();
if (GST_STATE_PENDING (element) == GST_STATE_NULL)
MikMod_Exit();
/* if we haven't failed already, give the parent class a chance to ;-) */
if (GST_ELEMENT_CLASS (parent_class)->change_state)
return GST_ELEMENT_CLASS (parent_class)->change_state (element);
return GST_STATE_SUCCESS;
}
static void
gst_mikmod_set_property (GObject *object, guint id, const GValue *value, GParamSpec *pspec )
{
GstMikMod *filter;
/* it's not null if we got it, but it might not be ours */
g_return_if_fail(GST_IS_MIKMOD(object));
filter = GST_MIKMOD(object);
switch (id) {
case ARG_SONGNAME:
filter->songname = g_value_get_string (value);
break;
case ARG_MODTYPE:
filter->modtype = g_value_get_string (value);
break;
case ARG_MUSICVOLUME:
filter->musicvolume = g_value_get_int (value);
break;
case ARG_PANSEP:
filter->pansep = g_value_get_int (value);
break;
case ARG_REVERB:
filter->reverb = g_value_get_int (value);
break;
case ARG_SNDFXVOLUME:
filter->sndfxvolume = g_value_get_int (value);
break;
case ARG_VOLUME:
filter->volume = g_value_get_int (value);
break;
case ARG_FIXFREQ:
filter->mixfreq = g_value_get_enum (value);
break;
case ARG_INTERP:
filter->interp = g_value_get_boolean (value);
break;
case ARG_REVERSE:
filter->reverse = g_value_get_boolean (value);
break;
case ARG_SURROUND:
filter->surround = g_value_get_boolean (value);
break;
case ARG_16BIT:
filter->_16bit = g_value_get_boolean (value);
break;
case ARG_HQMIXER:
filter->hqmixer = g_value_get_boolean (value);
break;
case ARG_SOFT_MUSIC:
filter->soft_music = g_value_get_boolean (value);
break;
case ARG_SOFT_SNDFX:
filter->soft_sndfx = g_value_get_boolean (value);
break;
case ARG_STEREO:
filter->stereo = g_value_get_boolean (value);
break;
default:
// G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
}
}
static void
gst_mikmod_get_property (GObject *object, guint id, GValue *value, GParamSpec *pspec )
{
GstMikMod *filter;
/* it's not null if we got it, but it might not be ours */
g_return_if_fail(GST_IS_MIKMOD(object));
filter = GST_MIKMOD(object);
switch (id) {
case ARG_MUSICVOLUME:
g_value_set_int (value, filter->musicvolume);
break;
case ARG_PANSEP:
g_value_set_int (value, filter->pansep);
break;
case ARG_REVERB:
g_value_set_int (value, filter->reverb);
break;
case ARG_SNDFXVOLUME:
g_value_set_int (value, filter->sndfxvolume);
break;
case ARG_VOLUME:
g_value_set_int (value, filter->volume);
break;
case ARG_FIXFREQ:
g_value_set_int (value, filter->mixfreq);
break;
case ARG_INTERP:
g_value_set_boolean (value, filter->interp);
break;
case ARG_REVERSE:
g_value_set_boolean (value, filter->reverse);
break;
case ARG_SURROUND:
g_value_set_boolean (value, filter->surround);
break;
case ARG_16BIT:
g_value_set_boolean (value, filter->_16bit);
break;
case ARG_HQMIXER:
g_value_set_boolean (value, filter->hqmixer);
break;
case ARG_SOFT_MUSIC:
g_value_set_boolean (value, filter->soft_music);
break;
case ARG_SOFT_SNDFX:
g_value_set_boolean (value, filter->soft_sndfx);
break;
case ARG_STEREO:
g_value_set_boolean (value, filter->stereo);
break;
default:
// G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
}
}
static gboolean
plugin_init (GModule *module, GstPlugin *plugin)
{
GstElementFactory *factory;
GstTypeFactory *type;
factory = gst_elementfactory_new("mikmod",GST_TYPE_MIKMOD,
&mikmod_details);
g_return_val_if_fail(factory != NULL, FALSE);
gst_elementfactory_add_padtemplate (factory, mikmod_src_factory ());
gst_elementfactory_add_padtemplate (factory, mikmod_sink_factory ());
type = gst_typefactory_new (&mikmoddefinition);
gst_plugin_add_feature (plugin, GST_PLUGIN_FEATURE (type));
gst_plugin_add_feature (plugin, GST_PLUGIN_FEATURE (factory));
return TRUE;
}
GstPluginDesc plugin_desc = {
GST_VERSION_MAJOR,
GST_VERSION_MINOR,
"mikmod",
plugin_init
};

105
ext/mikmod/gstmikmod.h Normal file
View file

@ -0,0 +1,105 @@
/* Gnome-Streamer
* Copyright (C) <1999> Erik Walthinsen <omega@cse.ogi.edu>
*
* 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 this library; if not, write to the
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*/
#ifndef __GST_MIKMOD_H__
#define __GST_MIKMOD_H__
#include <config.h>
#include <mikmod.h>
#include <gst/gst.h>
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
#define GST_TYPE_MIKMOD \
(gst_mikmod_get_type())
#define GST_MIKMOD(obj) \
(G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_MIKMOD,GstMikMod))
#define GST_MIKMOD_CLASS(klass) \
(G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_ULAW,GstMikMod))
#define GST_IS_MIKMOD(obj) \
(G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_MIKMOD))
#define GST_IS_MIKMOD_CLASS(obj) \
(G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_MIKMOD))
struct _GstMikMod {
GstElement element;
GstPad *sinkpad, *srcpad;
GstBuffer *Buffer;
gchar *songname;
gchar *modtype;
gint musicvolume;
gint pansep;
gint reverb;
gint sndfxvolume;
gint volume;
gint mixfreq;
gint mode;
gboolean interp;
gboolean reverse;
gboolean surround;
gboolean _16bit;
gboolean hqmixer;
gboolean soft_music;
gboolean soft_sndfx;
gboolean stereo;
};
struct _GstMikModClass {
GstElementClass parent_class;
};
typedef struct _GstMikMod GstMikMod;
typedef struct _GstMikModClass GstMikModClass;
MODULE *module;
MREADER *reader;
GstPad *srcpad;
int need_sync;
GType gst_mikmod_get_type(void);
// symbols for mikmod_reader.h
struct _GST_READER
{
MREADER core;
GstMikMod *mik;
guint64 offset;
gshort eof;
};
typedef struct _GST_READER GST_READER;
MREADER *GST_READER_new( GstMikMod *mik );
// symbols for drv_gst.c
extern MDRIVER drv_gst;
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif /* __GST_MIKMOD_H__ */

122
ext/mikmod/mikmod_reader.c Normal file
View file

@ -0,0 +1,122 @@
#include <unistd.h>
#include <string.h>
#include "gstmikmod.h"
extern int need_sync;
static BOOL GST_READER_Eof ( MREADER *reader );
static BOOL GST_READER_Read( MREADER *reader, void *ptr, size_t size );
static int GST_READER_Get ( MREADER *reader );
static BOOL GST_READER_Seek( MREADER* reader,long offset,int whence );
static long GST_READER_Tell( MREADER* reader );
static BOOL GST_READER_Eof( MREADER *reader )
{
GST_READER *gst_reader;
gst_reader = ( GST_READER * ) reader;
return gst_reader->eof;
}
static BOOL GST_READER_Read( MREADER *reader, void *ptr, size_t size )
{
GST_READER *gst_reader;
gst_reader = ( GST_READER * ) reader;
/*tmp->mik->Buffer = gst_pad_pullregion( tmp->mik->sinkpad, GST_REGION_OFFSET_LEN, tmp->offset, size );*/
memcpy( ptr, GST_BUFFER_DATA( gst_reader->mik->Buffer ) + gst_reader->offset, size);
gst_reader->offset = gst_reader->offset + size;
/* if ( GST_BUFFER_SIZE( tmp->mik->Buffer ) != size )
tmp->eof = 1;
else
tmp->eof = 0;
if (GST_BUFFER_FLAG_IS_SET (tmp->mik->Buffer, GST_BUFFER_FLUSH))
need_sync = 1;
gst_buffer_unref( tmp->mik->Buffer );*/
return 1;
}
static int GST_READER_Get ( MREADER *reader )
{
GST_READER *gst_reader;
int res;
gst_reader = ( GST_READER * ) reader;
/*tmp->mik->Buffer = gst_pad_pullregion( tmp->mik->sinkpad, GST_REGION_OFFSET_LEN, tmp->offset, 1 );*/
res = *( GST_BUFFER_DATA( gst_reader->mik->Buffer ) + gst_reader->offset );
gst_reader->offset += 1;
/* if ( GST_BUFFER_SIZE( tmp->mik->Buffer ) != 1 )
tmp->eof = 1;
else
tmp->eof = 0;
gst_buffer_unref( tmp->mik->Buffer );*/
return res;
}
static BOOL GST_READER_Seek( MREADER *reader, long offset, int whence )
{
GST_READER *gst_reader;
gst_reader = ( GST_READER * ) reader;
if ( whence == SEEK_SET )
gst_reader->offset = offset;
else
gst_reader->offset += offset;
return 1;
}
static long GST_READER_Tell( MREADER *reader )
{
GST_READER *gst_reader;
gst_reader = ( GST_READER * ) reader;
return gst_reader->offset;
}
MREADER *GST_READER_new( GstMikMod *mik )
{
GST_READER *gst_reader;
gst_reader = ( GST_READER * ) g_malloc( sizeof( GST_READER ));
gst_reader->offset = 0;
gst_reader->eof = 0;
gst_reader->mik = mik;
if ( gst_reader )
{
gst_reader->core.Eof = &GST_READER_Eof;
gst_reader->core.Read = &GST_READER_Read;
gst_reader->core.Get = &GST_READER_Get;
gst_reader->core.Seek = &GST_READER_Seek;
gst_reader->core.Tell = &GST_READER_Tell;
}
return ( MREADER *)gst_reader;
}
void GST_READER_free ( MREADER *reader )
{
if ( reader )
g_free( reader );
}

217
ext/mikmod/mikmod_types.c Normal file
View file

@ -0,0 +1,217 @@
/* Gnome-Streamer
* Copyright (C) <1999> Erik Walthinsen <omega@cse.ogi.edu>
*
* 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 this library; if not, write to the
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*/
#include <gst/gst.h>
#define MODULEHEADERSIZE 0x438
gboolean MOD_CheckType( GstBuffer *buf )
{
gchar *data;
data = GST_BUFFER_DATA( buf ) + MODULEHEADERSIZE;
/* Protracker and variants */
if (( ! memcmp( data, "M.K.", 4 )) || ( ! memcmp( data, "M!K!", 4 )))
return TRUE;
/* Star Tracker */
if ((( ! memcmp( data, "FLT", 3 )) || ( ! memcmp( data, "EXO", 3 ))) && ( isdigit( data[3] )))
return TRUE;
/* Oktalyzer (Amiga) */
if (! memcmp( data, "OKTA", 4 ))
return TRUE;
/* Oktalyser (Atari) */
if ( ! memcmp( data, "CD81", 4 ))
return TRUE;
/* Fasttracker */
if (( ! memcmp( data + 1, "CHN", 3 )) && ( isdigit( data[0] )))
return TRUE;
/* Fasttracker or Taketracker */
if ((( ! memcmp( data + 2, "CH", 2 )) || ( ! memcmp( data + 2, "CN", 2 ))) && ( isdigit( data[0] )) && ( isdigit( data[1] )))
return TRUE;
return FALSE;
}
gboolean Mod_669_CheckType( GstBuffer *buf )
{
gchar *data;
data = GST_BUFFER_DATA( buf );
if( ! memcmp( data, "if", 2 ) || ! memcmp( data, "JN", 2 ))
return TRUE;
return FALSE;
}
gboolean Amf_CheckType( GstBuffer *buf )
{
gchar *data;
data = GST_BUFFER_DATA( buf );
if( memcmp( data, "AMF", 3) )
return FALSE;
data = GST_BUFFER_DATA( buf ) + 3;
if (( (gint)*data >= 10 ) && ( (gint)*data <= 14 ))
return TRUE;
return FALSE;
}
gboolean Dsm_CheckType( GstBuffer *buf )
{
gchar *data;
data = GST_BUFFER_DATA( buf );
if( ! memcmp( data, "RIFF", 4 ) && ! memcmp( data + 8, "DSMF", 4 ))
return TRUE;
return FALSE;
}
gboolean Fam_CheckType( GstBuffer *buf )
{
gchar *data;
static unsigned char FARSIG[4+3]={'F','A','R',0xfe,13,10,26};
data = GST_BUFFER_DATA( buf );
if(( memcmp( data, FARSIG, 4 )) || ( memcmp( data + 44, FARSIG + 4, 3 )))
return FALSE;
return 1;
}
gboolean Gdm_CheckType( GstBuffer *buf )
{
gchar *data;
data = GST_BUFFER_DATA( buf );
if ( ! memcmp( data, "GDM\xfe", 4 ) && ! memcmp( data + 71, "GMFS", 4 ))
return TRUE;
return FALSE;
}
gboolean Imf_CheckType( GstBuffer *buf )
{
gchar *data;
data = GST_BUFFER_DATA( buf ) + 0x3c;
if( ! memcmp( data, "IM10", 4))
return TRUE;
return FALSE;
}
gboolean It_CheckType( GstBuffer *buf )
{
gchar *data;
data = GST_BUFFER_DATA( buf );
if( ! memcmp( data, "IMPM", 4 ))
return TRUE ;
return FALSE;
}
gboolean M15_CheckType( GstBuffer *buf )
{
return FALSE;
#warning M15 CheckType to do
}
gboolean Med_CheckType( GstBuffer *buf )
{
gchar *data;
data = GST_BUFFER_DATA( buf );
if(( ! memcmp(data, "MMD0", 4 )) || ( memcmp( data, "MMD1", 4 )))
return TRUE;
return FALSE;
}
gboolean Mtm_CheckType( GstBuffer *buf )
{
gchar *data;
data = GST_BUFFER_DATA( buf );
if( ! memcmp( data, "MTM", 3 ))
return TRUE;
return FALSE;
}
gboolean Okt_CheckType( GstBuffer *buf )
{
gchar *data;
data = GST_BUFFER_DATA( buf );
if( ! memcmp( data, "OKTSONG", 8 ))
return TRUE;
return FALSE;
}
gboolean S3m_CheckType( GstBuffer *buf )
{
gchar *data;
data = GST_BUFFER_DATA( buf ) + 0x2c;
if( ! memcmp( data, "SCRM", 4 ))
return TRUE;
return FALSE;
}
gboolean Xm_CheckType( GstBuffer *buf )
{
gchar *data;
data = GST_BUFFER_DATA( buf ) + 0x2c;
if( memcmp( data, "Extended Module: ", 17 ))
return FALSE;
if( data[ 37 ] == 0x1a )
return TRUE;
return FALSE;
}