diff options
author | Yves Combe <ycombe@src.gnome.org> | 2006-11-14 21:59:18 (GMT) |
---|---|---|
committer | Yves Combe <ycombe@src.gnome.org> | 2006-11-14 21:59:18 (GMT) |
commit | 55fe11f8ccbaba4e907264bd904469b696b0aeac (patch) | |
tree | 4e9f11bfe5907a577bfa1d34f9a6785b2dbd1616 | |
parent | c2b2132258f718fee7d718ac512a91748a98bba3 (diff) |
gc_sound: play groups of item
-rw-r--r-- | ChangeLog | 35 | ||||
-rw-r--r-- | src/Makefile.am | 2 | ||||
-rw-r--r-- | src/gc_sound/ChangeLog | 9 | ||||
-rw-r--r-- | src/gc_sound/src/gc-sound-channel.gob | 46 | ||||
-rw-r--r-- | src/gc_sound/src/gc-sound-item.gob | 122 | ||||
-rw-r--r-- | src/gc_sound/src/gc-sound-mixer.gob | 7 | ||||
-rw-r--r-- | src/gc_sound/src/test_gc_sound.c | 54 |
7 files changed, 232 insertions, 43 deletions
@@ -1,3 +1,38 @@ +2006-11-14 Yves Combe <yves@ycombe.net> + + Play groups of music. + + * src/Makefile.am: + * src/gc_sound/ChangeLog: + * src/gc_sound/src/gc-sound-channel.gob: + * src/gc_sound/src/gc-sound-item.gob: + * src/gc_sound/src/gc-sound-mixer.gob: + * src/gc_sound/src/test_gc_sound.c: (finish), (start), (main): + +2006-11-14 Yves Combe <yves@ycombe.net> + + initial import of library for sound object gc_sound. Not yet integrated. + + * src/Makefile.am: + * src/gc_sound/COPYING: + * src/gc_sound/ChangeLog: + * src/gc_sound/INSTALL: + * src/gc_sound/Makefile.am: + * src/gc_sound/aclocal.m4: + * src/gc_sound/compile: + * src/gc_sound/config.guess: + * src/gc_sound/config.sub: + * src/gc_sound/configure.in: + * src/gc_sound/install-sh: + * src/gc_sound/ltmain.sh: + * src/gc_sound/missing: + * src/gc_sound/src/Makefile.am: + * src/gc_sound/src/gc-sound-channel.gob: + * src/gc_sound/src/gc-sound-item.gob: + * src/gc_sound/src/gc-sound-mixer.gob: + * src/gc_sound/src/gc-sound.h: + * src/gc_sound/src/test_gc_sound.c: (finish), (main): + 2006-11-13 Bruno coudoin <bruno.coudoin@free.fr> * src/gcompris/properties.c: (gc_prop_config_file_get), diff --git a/src/Makefile.am b/src/Makefile.am index cbc22fb..2839949 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -1,3 +1,3 @@ ## Process this file with automake to produce Makefile.in -SUBDIRS = gcompris boards +SUBDIRS = gc_sound gcompris boards diff --git a/src/gc_sound/ChangeLog b/src/gc_sound/ChangeLog index 8fc0356..e06a4c1 100644 --- a/src/gc_sound/ChangeLog +++ b/src/gc_sound/ChangeLog @@ -1,5 +1,14 @@ 2006-11-14 Yves Combe <yves@ycombe.net> + Play music with groups of sound items. + + * src/gc-sound-channel.gob: + * src/gc-sound-item.gob: + * src/gc-sound-mixer.gob: + * src/test_gc_sound.c: (finish), (start), (main): + +2006-11-14 Yves Combe <yves@ycombe.net> + initial import of gc_sound objects library. Works, without grouping. * COPYING: diff --git a/src/gc_sound/src/gc-sound-channel.gob b/src/gc_sound/src/gc-sound-channel.gob index 09e19db..55a2776 100644 --- a/src/gc_sound/src/gc-sound-channel.gob +++ b/src/gc_sound/src/gc-sound-channel.gob @@ -49,6 +49,7 @@ requires 2.0.0 static GHashTable *channels_table = NULL; %} class GC:Sound:Channel from G:Object { + public gchar *nick = {NULL}; private int channel destroy { g_hash_table_remove(channels_table, GINT_TO_POINTER(channel)); @@ -67,7 +68,10 @@ class GC:Sound:Channel from G:Object { private gboolean initialised = {FALSE}; private Mix_Chunk *sample; - private GC:Sound:Item *playing_item = { NULL }; + private GC:Sound:Item *playing_item = { NULL }; + private G:List *playing_root = { NULL }; + private G:List *play_list = { NULL }; + private gulong signal_id_child = { 0 }; private int volume = { MIX_MAX_VOLUME }; @@ -145,11 +149,10 @@ class GC:Sound:Channel from G:Object { return; } self_play_finished (self, self->_priv->playing_item); - self->_priv->playing_item = NULL; } public gboolean - real_play (self, GC:Sound:Item *item (check null type), int volume) + real_play (self, GC:Sound:Item *item (check null type)) { gchar * filename = gc_sound_item_get_filename(item); @@ -162,10 +165,10 @@ class GC:Sound:Channel from G:Object { return FALSE; } - if ((volume == -1) || (volume > self->_priv->volume)) + if ((item->volume == -1) || (item->volume > self->_priv->volume)) Mix_VolumeChunk(self->_priv->sample, self->_priv->volume); else - Mix_VolumeChunk(self->_priv->sample, volume); + Mix_VolumeChunk(self->_priv->sample, item->volume); if(Mix_PlayChannel(self->_priv->channel, self->_priv->sample, 0)==-1) { g_warning("Channel cannot play music %s", filename); @@ -181,11 +184,38 @@ class GC:Sound:Channel from G:Object { signal first NONE (POINTER) void play_finished (self, GC:Sound:Item *item (check null type)) { - g_warning ("Channel %d emitted signal play-finished %d", self->_priv->channel); Mix_FreeChunk(self->_priv->sample); self->_priv->sample = NULL; - gc_sound_item_play_finished(item); + gc_sound_item_play_next(item); } - + + protected void play_item (self, GC:Sound:Item *item) + { + self->_priv->play_list = g_list_append (self->_priv->play_list, item); + + self_play_first_item(self); + } + + protected void play_first_item(self) + { + if (g_list_length(self->_priv->play_list)>0) + { + self->_priv->playing_root = g_list_first (self->_priv->play_list); + self->_priv->play_list = g_list_remove_link (self->_priv->play_list, self->_priv->playing_root); + } + else + return; + + self->_priv->signal_id_child = gc_sound_item_connect__play_finished (GC_SOUND_ITEM(self->_priv->playing_root->data), self_item_play_finished, self); + gc_sound_item_play_next(GC_SOUND_ITEM(self->_priv->playing_root->data)); + } + + private void item_play_finished (GC:Sound:Item *item, gpointer data) + { + + g_signal_handler_disconnect ( item, GC_SOUND_CHANNEL(data)->_priv->signal_id_child); + + self_play_first_item(GC_SOUND_CHANNEL(data)); + } } diff --git a/src/gc_sound/src/gc-sound-item.gob b/src/gc_sound/src/gc-sound-item.gob index eefb238..fa738f7 100644 --- a/src/gc_sound/src/gc-sound-item.gob +++ b/src/gc_sound/src/gc-sound-item.gob @@ -48,6 +48,8 @@ typedef struct _GCSoundChannel GCSoundChannel; %} class GC:Sound:Item from G:Object { + public gchar *nick = {NULL}; + private GC:Sound:Channel *channel = { NULL } destroywith g_object_unref ; @@ -64,18 +66,43 @@ class GC:Sound:Item from G:Object { ( nick=_("Channel playing for us"), blurb=_("Numero of channel"), object_type=GC:Sound:Item, - export, link ); + export) + set { self->_priv->parent = GC_SOUND_ITEM(g_value_get_object +(VAL)); + } + get { g_value_set_object (VAL, G_OBJECT(self->_priv->parent)); } + ; private gchar *filename = { NULL } destroywith g_free; + public int volume = { -1 }; + + /* mark if item or one child is playing */ + private gboolean started = { FALSE }; + + /* mark if is playing or not */ + private gboolean has_played = { FALSE }; + property STRING filename ( nick=_("Filename of sound"), blurb=_("sound file to play"), - export, link ); + export ) + set { + if (self->_priv->filename==NULL) + g_free(self->_priv->filename); - public GC:Sound:Item *playing = { NULL } - unrefwith g_object_unref; + self->_priv->filename = g_strdup(g_value_get_string(VAL)); + self->_priv->PlayList = g_list_remove ( self->_priv->PlayList, self); + + if (self->_priv->filename) + self->_priv->PlayList = g_list_insert ( self->_priv->PlayList, self, 0); + + } + get { g_value_set_string(VAL, g_strdup(self->_priv->filename));}; + + + private G:List *playing = { NULL }; private G:List *SoundItems = { NULL } destroy { @@ -89,11 +116,6 @@ class GC:Sound:Item from G:Object { private GList *PlayList = { NULL } destroy { - GList *list; - - for (list = PlayList; list != NULL; list = list->next) - g_object_unref(G_OBJECT(list->data)); - g_list_free (PlayList); }; @@ -107,23 +129,87 @@ class GC:Sound:Item from G:Object { } public GC:Sound:Item * - new (GC:Sound:Item *parent) + new (self) { - return GC_SOUND_ITEM(g_object_new(gc_sound_item_get_type(), "parent", parent, "channel", parent->_priv->channel, NULL)); + GCSoundItem *child; + + child = GC_SOUND_ITEM(g_object_new(gc_sound_item_get_type(), "parent", self, "channel", self->_priv->channel, NULL)); + + self->_priv->SoundItems = g_list_append (self->_priv->SoundItems, child); + self->_priv->PlayList = g_list_append (self->_priv->PlayList, child); + + g_object_ref (G_OBJECT(child)); + + self_connect__play_finished ( child, self_child_play_finished, self); + self_connect__play_started ( child, self_child_play_started, self); + + return child; } - public gboolean - play (self, int volume) + public void + play (self) { - if (self->_priv->filename != NULL) { - gc_sound_channel_real_play(self->_priv->channel, self, volume); + /* Change that with policy */ + self->_priv->has_played = TRUE; + gc_sound_channel_play_item(self->_priv->channel, self); + } + + + protected void + play_next (self) + { + self->_priv->has_played = TRUE; + + if (g_list_length(self->_priv->PlayList) > 0) { + if (self->_priv->playing == NULL) { + self->_priv->playing = g_list_first(self->_priv->PlayList); + } else + self->_priv->playing = g_list_next (self->_priv->playing ); + + if ( self->_priv->playing == NULL ) + self_play_finished(self); + else { + if ( GC_SOUND_ITEM(self->_priv->playing->data) == self){ + self_play_started(self); + gc_sound_channel_real_play(self->_priv->channel, self); + } + else + gc_sound_item_play_next ( GC_SOUND_ITEM(self->_priv->playing->data)); + } } + } - signal first NONE (NONE) + /* play */ + signal last NONE (NONE) void play_finished (self) { - g_warning ("Item sound %s has emit play_finished signal", self->_priv->filename); + //g_warning("play_finished %s", self->nick); + + if (self->_priv->has_played && self->_priv->playing) { + self_play_next(self); + } + else { + self->_priv->started = FALSE; + self->_priv->has_played = FALSE; + } } - + signal last NONE (NONE) + void play_started (self) + { + //g_warning("play_started %s", self->nick); + self->_priv->started = TRUE; + } + + private void child_play_finished (GC:Sound:Item *item, gpointer data) + { + if ( GC_SOUND_ITEM(data)->_priv->has_played ) + self_play_next(GC_SOUND_ITEM(data)); + } + + private void child_play_started (GC:Sound:Item *item, gpointer data) + { + if (! GC_SOUND_ITEM(data)->_priv->started) + self_play_started(GC_SOUND_ITEM(data)); + } } diff --git a/src/gc_sound/src/gc-sound-mixer.gob b/src/gc_sound/src/gc-sound-mixer.gob index 7035c5f..adb4340 100644 --- a/src/gc_sound/src/gc-sound-mixer.gob +++ b/src/gc_sound/src/gc-sound-mixer.gob @@ -46,6 +46,7 @@ typedef struct _GCSoundChannel GCSoundChannel; #endif %} class GC:Sound:Mixer from G:Object { + public gchar *nick = {NULL}; protected int channels = { 0 }; private int audio_buffers=2048; @@ -106,7 +107,7 @@ class GC:Sound:Mixer from G:Object { private gboolean sdl_ok = { FALSE }; - init (self) { + init (self) { g_warning("gc mixer init"); // initialize SDL for audio @@ -124,10 +125,10 @@ class GC:Sound:Mixer from G:Object { } - public G:Object * + public GC:Sound:Mixer * new (void) { - return (GObject *)GET_NEW; + return (GCSoundMixer *)GET_NEW; } public void close_audio(self) diff --git a/src/gc_sound/src/test_gc_sound.c b/src/gc_sound/src/test_gc_sound.c index 68da533..29e09f3 100644 --- a/src/gc_sound/src/test_gc_sound.c +++ b/src/gc_sound/src/test_gc_sound.c @@ -4,42 +4,70 @@ void finish(GCSoundItem *item, gpointer data) { - g_warning("Return of finish callback %s", gc_sound_item_get_filename(item)); + g_warning("Return of finish callback %s", item->nick); +} + +void start(GCSoundItem *item, gpointer data) +{ + g_warning("Return of start callback %s", item->nick); } main (int argc, char *argv) { GCSoundMixer *gcmix; GCSoundChannel* gcchan1, *gcchan2; - GCSoundItem *item1, *item2, *root1, *root2; + GCSoundItem *item1, *item2, *root1, *root2, *item1_1, *item1_2; g_type_init (); - gcmix = GC_SOUND_MIXER(gc_sound_mixer_new()); + /* Sound mixer opens SDL and audio device */ + gcmix = gc_sound_mixer_new(); + gcmix->nick = "gcmix"; + /* We open two chans to play simultaneously */ gcchan1 = gc_sound_mixer_new_channel(gcmix); gcchan2 = gc_sound_mixer_new_channel(gcmix); + gcchan1->nick = "gcchan1"; + gcchan2->nick = "gcchan2"; - printf ("gcchan1 %d gcchan2 %d\n", gcchan1, gcchan2); + /* Each chan has a root item, where we group the sounds to play in that channel*/ root1 = GC_SOUND_ITEM(gc_sound_channel_get_rootItem(gcchan1)); root2 = GC_SOUND_ITEM(gc_sound_channel_get_rootItem(gcchan2)); + root1->nick="root1"; + root2->nick="root2"; - printf ("root1 %d root2 %d\n", root1, root2); + /* create new item for our sounds */ + item1 = gc_sound_item_new (root1); + item2 = gc_sound_item_new (root2); + item1_1 = gc_sound_item_new (item1); - item1 = GC_SOUND_ITEM(gc_sound_item_new (root1)); - item2 = GC_SOUND_ITEM(gc_sound_item_new (root2)); + item1_2 = gc_sound_item_new (item1); + item1->nick = "item1"; + item2->nick = "item2"; + item1_1->nick = "item1_1"; + item1_2->nick = "item1_2"; - printf ("item1 %d item2 %d\n", item1, item2); + /* set file sound name */ + gc_sound_item_set_filename(item1_1, "../../../boards/sounds/wahoo.ogg"); + gc_sound_item_set_filename(item1_2, "../../../boards/sounds/wahoo.ogg"); + gc_sound_item_set_filename(item2, "../../../boards/music/background/LRLaPause.ogg"); - gc_sound_item_set_filename(item1, "wahoo.ogg"); - gc_sound_item_set_filename(item2, "LRLaPause.ogg"); - - gc_sound_item_play(item2, -1); - gc_sound_item_play(item1, -1); + // test + gc_sound_item_set_filename(item1_1, NULL); + gc_sound_item_set_filename(item1_1, "../../../boards/sounds/wahoo.ogg"); + // callback connection gc_sound_item_connect__play_finished(item1, finish, NULL); gc_sound_item_connect__play_finished(item2, finish, NULL); + gc_sound_item_connect__play_started(item1_1, start, NULL); + gc_sound_item_connect__play_started(item1_2, start, NULL); + + //play + gc_sound_item_play(item2); + g_usleep(1000000); + gc_sound_item_play(item1); + /* infinite loop */ g_main_loop_run(g_main_loop_new (NULL, FALSE)); } |