Web   ·   Wiki   ·   Activities   ·   Blog   ·   Lists   ·   Chat   ·   Meeting   ·   Bugs   ·   Git   ·   Translate   ·   Archive   ·   People   ·   Donate
summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorYves 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)
commit55fe11f8ccbaba4e907264bd904469b696b0aeac (patch)
tree4e9f11bfe5907a577bfa1d34f9a6785b2dbd1616
parentc2b2132258f718fee7d718ac512a91748a98bba3 (diff)
gc_sound: play groups of item
-rw-r--r--ChangeLog35
-rw-r--r--src/Makefile.am2
-rw-r--r--src/gc_sound/ChangeLog9
-rw-r--r--src/gc_sound/src/gc-sound-channel.gob46
-rw-r--r--src/gc_sound/src/gc-sound-item.gob122
-rw-r--r--src/gc_sound/src/gc-sound-mixer.gob7
-rw-r--r--src/gc_sound/src/test_gc_sound.c54
7 files changed, 232 insertions, 43 deletions
diff --git a/ChangeLog b/ChangeLog
index c37afbc..bc1afa9 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -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));
}