From f106d808e51077cb5428dd7657da4c9beca7baa8 Mon Sep 17 00:00:00 2001 From: Yves Combe Date: Mon, 18 Dec 2006 23:42:31 +0000 Subject: GC_SOUND: Add a property for policy. Fix bug if played item is destroyed GC_SOUND: Add a property for policy. Fix bug if played item is destroyed at end before it's "play_end" callback. TODO: fix bug if item is destroyed when it's playing. GCOMPRIS fix memory and bar.c TODO: python binding for gc_sound_from_gc_filename --- diff --git a/ChangeLog b/ChangeLog index 7c33451..c4da2e1 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,30 @@ +2006-12-19 Yves Combe + + GC_SOUND: + Add a property for policy. + Fix bug if played item is destroyed at end before it's "play_end" callback. + TODO: fix bug if item is destroyed when it's playing. + GCOMPRIS + fix memory and bar.c + TODO: python binding for gc_sound_from_gc_filename + + * src/boards/memory.c: (start_board), (end_board), (create_item), + (check_win), (sound_callback), (start_callback): + * src/gc_sound/ChangeLog: + * src/gc_sound/src/gc-sound-channel.c: + (gc_sound_channel_play_item), (gc_sound_channel_play), + (gc_sound_channel_init), (gc_sound_channel_signal_chunk_end), + (running_root_destroy), (running_root_end), + (gc_sound_channel_signal_run): + * src/gc_sound/src/gc-sound-channel.h: + * src/gc_sound/src/gc-sound-item.c: (gc_sound_item_get_property), + (gc_sound_item_set_property), (gc_sound_item_class_init): + * src/gc_sound/src/gc-sound-mixer-SDL.c: (gc_sound_mixer_sdl_halt), + (gc_sound_mixer_sdl_halt_channel), (gc_sound_mixer_sdl_play_item), + (channel_finished_cb): + * src/gc_sound/src/test_gc_sound.c: (main): + * src/gcompris/bar.c: (item_event_bar): + 2006-12-15 Yves Combe GC_SOUND diff --git a/src/boards/memory.c b/src/boards/memory.c index f69a162..15af81a 100644 --- a/src/boards/memory.c +++ b/src/boards/memory.c @@ -247,7 +247,6 @@ static gchar *soundList[] = "sounds/LuneRouge/sf/LRWeird_3_by_Lionel_Allorge.ogg", "sounds/LuneRouge/sf/LRWeird_5_by_Lionel_Allorge.ogg", "sounds/LuneRouge/sf/LRWeird_6_by_Lionel_Allorge.ogg", - "sounds/LuneRouge/sf/LRET_phone_home_01_by_Lionel_Allorge_cut.ogg", "sounds/LuneRouge/usine/LRFactory_noise_02_by_Lionel_Allorge.ogg", "sounds/LuneRouge/usine/LRFactory_noise_03_by_Lionel_Allorge.ogg", "sounds/LuneRouge/usine/LRFactory_noise_04_by_Lionel_Allorge.ogg", @@ -424,6 +423,7 @@ static GnomeCanvasItem *player_score; static GnomeCanvasItem *tux_score_s; static GnomeCanvasItem *player_score_s; +static GcSoundItem *flip = NULL; /* set the type of the token returned in string in returned_type */ void get_random_token(int token_type, gint *returned_type, gchar **string, gchar **second_value) { @@ -821,7 +821,7 @@ static void start_board (GcomprisBoard *agcomprisBoard) /* initial state to restore */ sound_policy = gc_sound_policy_get(); - gc_sound_policy_set(INTERRUPT_AND_PLAY); + //gc_sound_policy_set(INTERRUPT_AND_PLAY); gc_set_background(gnome_canvas_root(gcomprisBoard->canvas), "images/gcompris_band.png"); base_x1 = BASE_SOUND_X1; @@ -893,10 +893,11 @@ static void start_board (GcomprisBoard *agcomprisBoard) to_tux = FALSE; if (currentUiMode == UIMODE_SOUND){ playing_sound = TRUE; - item = gc_sound_item_from_gc_filename("sounds/LuneRouge/musique/LRBuddhist_gong_05_by_Lionel_Allorge.ogg", NULL); + item = gc_sound_item_from_gc_filename("sounds/LuneRouge/musique/LRBuddhist_gong_05_by_Lionel_Allorge.ogg", "destroy_after_play", TRUE, NULL); - g_object_connect(G_OBJECT(item), "play_end",(GCallback) start_callback, NULL); + g_signal_connect(G_OBJECT(item), "play_end",(GCallback) start_callback, NULL); gc_sound_item_play(item); + flip = gc_sound_item_from_gc_filename("sounds/flip.wav", "policy",INTERRUPT_AND_PLAY, NULL); } else playing_sound = FALSE; @@ -908,7 +909,7 @@ static void end_board () { if (currentUiMode == UIMODE_SOUND) { - gc_sound_policy_set(sound_policy); + //gc_sound_policy_set(sound_policy); gc_sound_object_destroy(GC_SOUND_OBJECT(gc_sound_channel_get_root(gc_prop_get()->fx_chan))); gc_sound_resume(); } @@ -1348,8 +1349,11 @@ static void create_item(GnomeCanvasGroup *parent) gdk_pixbuf_unref(pixmap); memoryItem->sound_item = \ - gc_sound_item_from_gc_filename( memoryItem->data, NULL); - g_object_connect(memoryItem->sound_item, "play_end", (GCallback) sound_callback, NULL); + gc_sound_item_from_gc_filename( memoryItem->data, "policy", INTERRUPT_AND_PLAY, NULL); + + if (!memoryItem->sound_item) + g_error ("Cannot get gc_filename for %s", memoryItem->data); + g_signal_connect(G_OBJECT(memoryItem->sound_item), "play_end", (GCallback) sound_callback, NULL); } else { if(memoryItem->type == TYPE_IMAGE) { @@ -1553,7 +1557,7 @@ static void check_win() // Check win if (compare_card((gpointer) firstCard, (gpointer) secondCard) == 0) { - gc_sound_play_ogg ("sounds/flip.wav", NULL); + gc_sound_item_play (flip); win_id = g_timeout_add (timeout, (GSourceFunc) hide_card, NULL); return; @@ -1821,6 +1825,8 @@ static void sound_callback(GcSoundItem *item, gboolean stopped, gpointer data) if (! gcomprisBoard) return; + g_warning("sound_callback"); + playing_sound = FALSE; if (currentMode == MODE_TUX){ if (to_tux) { @@ -1857,6 +1863,7 @@ static void start_callback(GcSoundItem *item, gboolean stopped, gpointer data) if (currentUiMode != UIMODE_SOUND) return; - playing_sound = FALSE; gc_sound_object_destroy(GC_SOUND_OBJECT(item)); + + playing_sound = FALSE; } diff --git a/src/gc_sound/ChangeLog b/src/gc_sound/ChangeLog index d2f9a76..af5363c 100644 --- a/src/gc_sound/ChangeLog +++ b/src/gc_sound/ChangeLog @@ -1,3 +1,21 @@ +2006-12-19 Yves Combe + + Add a property for policy. + Fix bug if played item is destroyed at end before it's "play_end" callback. + TODO: fix bug if item is destroyed when it's playing. + + * src/gc-sound-channel.c: (gc_sound_channel_play_item), + (gc_sound_channel_play), (gc_sound_channel_init), + (gc_sound_channel_signal_chunk_end), (running_root_destroy), + (running_root_end), (gc_sound_channel_signal_run): + * src/gc-sound-channel.h: + * src/gc-sound-item.c: (gc_sound_item_get_property), + (gc_sound_item_set_property), (gc_sound_item_class_init): + * src/gc-sound-mixer-SDL.c: (gc_sound_mixer_sdl_halt), + (gc_sound_mixer_sdl_halt_channel), (gc_sound_mixer_sdl_play_item), + (channel_finished_cb): + * src/test_gc_sound.c: (main): + 2006-12-15 Yves Combe gc_sound_append_child now accepts varargs for item properties. diff --git a/src/gc_sound/src/gc-sound-channel.c b/src/gc_sound/src/gc-sound-channel.c index 28fe33c..d129b4c 100644 --- a/src/gc_sound/src/gc-sound-channel.c +++ b/src/gc_sound/src/gc-sound-channel.c @@ -40,7 +40,10 @@ static GcSoundObjectClass *parent_class; gboolean gc_sound_channel_play_item (GcSoundChannel * self, GcSoundItem *item) { + g_return_val_if_fail(self->running_sample == NULL, FALSE); + self->running_sample = item; + g_object_ref(self->running_sample); self->stopped = FALSE; return gc_sound_mixer_play_item (GC_SOUND_MIXER(GC_SOUND_OBJECT(self)->parent), self, item); @@ -88,32 +91,33 @@ gboolean gc_sound_channel_play (GcSoundChannel *self, else policy = gc_sound_item_get_policy(item); + g_warning("Playing item %s with policy %d", item->filename, policy); + switch (policy) { case PLAY_ONLY_IF_IDLE: - if (self->running_sample || g_list_length (self->playlist)>0) + if (self->running_root || g_list_length (self->playlist)>0) return FALSE; self->playlist = g_list_append (self->playlist, item); - // TODO send a signal to run !!! - g_signal_emit(self, gc_sound_channel_signals[RUN], 0); break; case INTERRUPT_AND_PLAY: - g_list_free (self->playlist); - self->playlist = NULL; - self->playlist = g_list_append (self->playlist, item); - if (self->running_sample){ + if (self->running_sample) { self->stopped = TRUE; gc_sound_channel_halt(self); } - g_signal_emit(self, gc_sound_channel_signals[RUN], 0); + g_list_free (self->playlist); + self->playlist = NULL; + self->playlist = g_list_append (self->playlist, item); break; default: self->playlist = g_list_append (self->playlist, item); - if (!self->running_sample) - g_signal_emit(self, gc_sound_channel_signals[RUN], 0); break; } + + if (!self->running_root) { + g_signal_emit(self, gc_sound_channel_signals[RUN], 0); + } return TRUE; } @@ -152,9 +156,6 @@ gc_sound_channel_destroy (GcSoundObject *self){ static void gc_sound_channel_init(GcSoundChannel* self) { - // initialisation des variables. - //g_warning("gc_sound_channel_init"); - self->volume = 1.0; self->policy = PLAY_AFTER_CURRENT; @@ -200,13 +201,51 @@ gc_sound_channel_set_property(GObject* object, guint prop_id, GValue const* valu static void gc_sound_channel_signal_chunk_end (GcSoundChannel *self) { + g_return_if_fail(GC_IS_SOUND_ITEM(self->running_sample)); + GcSoundItem *chunk = self->running_sample; + if ( self->running_sample == self->running_root->data){ + if (!g_signal_handler_is_connected (G_OBJECT(self->running_root->data), self->running_handler_end)) + g_error ("RUNNING ROOT NOT CONNECTED"); + } + g_object_unref(self->running_sample); self->running_sample = NULL; - g_return_if_fail(GC_IS_SOUND_ITEM(chunk)); - g_signal_emit_by_name (chunk, "chunk_end", 0, self->stopped); + +} + +void running_root_destroy(GcSoundItem *item, gpointer data) +{ + GcSoundChannel *self = GC_SOUND_CHANNEL(data); + + g_warning("callback running_root_destroy %s", item->filename); + + g_signal_handler_disconnect(item, self->running_handler_end); + g_signal_handler_disconnect(item, self->running_handler_destroy); + + g_object_unref(G_OBJECT(self->running_root->data)); + self->running_root = NULL; + + g_signal_emit(self, gc_sound_channel_signals[RUN], 0); + +} + +void running_root_end(GcSoundItem *item, gboolean stopped, gpointer data) +{ + GcSoundChannel *self = GC_SOUND_CHANNEL(data); + + g_warning("callback running_root_end %s", item->filename); + + g_signal_handler_disconnect(item, self->running_handler_end); + g_signal_handler_disconnect(item, self->running_handler_destroy); + + g_object_unref(G_OBJECT(self->running_root->data)); + self->running_root = NULL; + + g_signal_emit(self, gc_sound_channel_signals[RUN], 0); + } static void @@ -218,10 +257,15 @@ gc_sound_channel_signal_run (GcSoundChannel *self) { self->running_root = g_list_first (self->playlist); self->playlist = g_list_remove_link (self->playlist, self->running_root); - + self->running_handler_end = g_signal_connect( G_OBJECT(self->running_root->data), "play_end", (GCallback) running_root_end, self); + self->running_handler_destroy = g_signal_connect( G_OBJECT(self->running_root->data), "destroy", (GCallback) running_root_destroy, self); + g_object_ref(G_OBJECT(self->running_root->data)); ret = gc_sound_item_run_next (GC_SOUND_ITEM(self->running_root->data), FALSE); if (ret) - return ; + break; + g_object_unref(G_OBJECT(self->running_root->data)); + g_signal_handler_disconnect ( G_OBJECT(self->running_root->data), self->running_handler_end); + g_signal_handler_disconnect ( G_OBJECT(self->running_root->data), self->running_handler_destroy); } } diff --git a/src/gc_sound/src/gc-sound-channel.h b/src/gc_sound/src/gc-sound-channel.h index 05fc76e..f572931 100644 --- a/src/gc_sound/src/gc-sound-channel.h +++ b/src/gc_sound/src/gc-sound-channel.h @@ -69,6 +69,8 @@ struct _GcSoundChannel { GcSoundItem* running_sample; // this one is the group playing GList* running_root; + gulong running_handler_end; + gulong running_handler_destroy; gint channel_number; }; diff --git a/src/gc_sound/src/gc-sound-item.c b/src/gc_sound/src/gc-sound-item.c index e8b5a35..d333249 100644 --- a/src/gc_sound/src/gc-sound-item.c +++ b/src/gc_sound/src/gc-sound-item.c @@ -18,6 +18,7 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include +#include #include @@ -240,6 +241,7 @@ enum { PROP_0, PROP_CHANNEL, PROP_FILENAME, + PROP_POLICY, PROP_DESTROY_AFTER_PLAY }; @@ -288,6 +290,9 @@ gc_sound_item_get_property(GObject* object, guint prop_id, GValue* value, GParam case PROP_FILENAME: g_value_set_string(value, g_strdup(self->filename)); break; + case PROP_POLICY: + g_value_set_enum(value, self->policy); + break; case PROP_DESTROY_AFTER_PLAY: g_value_set_boolean(value, self->destroy_after_play); break; @@ -309,6 +314,9 @@ gc_sound_item_set_property(GObject* object, guint prop_id, GValue const* value, case PROP_FILENAME: gc_sound_item_set_filename( self, (gchar *)g_value_get_string(value)); break; + case PROP_POLICY: + gc_sound_item_set_policy( self, (GcSoundPolicy) g_value_get_enum(value)); + break; case PROP_DESTROY_AFTER_PLAY: self->destroy_after_play = g_value_get_boolean(value); break; @@ -346,6 +354,14 @@ gc_sound_item_class_init(GcSoundItemClass* self_class) NULL, G_PARAM_READWRITE)); g_object_class_install_property(go_class, + PROP_POLICY, + g_param_spec_enum ("policy", + "gc sound policy", + "Set/Get the sound Policy", + GC_TYPE_SOUND_POLICY, + POLICY_NONE, + G_PARAM_READWRITE)); + g_object_class_install_property(go_class, PROP_DESTROY_AFTER_PLAY, g_param_spec_boolean ("destroy_after_play", "destroy the item when played", diff --git a/src/gc_sound/src/gc-sound-mixer-SDL.c b/src/gc_sound/src/gc-sound-mixer-SDL.c index 6c06c06..ba641a6 100644 --- a/src/gc_sound/src/gc-sound-mixer-SDL.c +++ b/src/gc_sound/src/gc-sound-mixer-SDL.c @@ -229,7 +229,9 @@ gc_sound_mixer_sdl_halt (GcSoundMixer * mixer) self = GC_SOUND_MIXER_SDL(mixer); - Mix_HaltChannel(-1); + //Mix_HaltChannel(-1); + // use Expire channel to let another threaded stop them. + Mix_ExpireChannel( -1, 1); return TRUE; } @@ -262,7 +264,9 @@ gc_sound_mixer_sdl_halt_channel (GcSoundMixer * mixer, GcSoundChannel * cha g_return_val_if_fail(GC_IS_SOUND_MIXER_SDL(mixer), FALSE); g_return_val_if_fail(GC_IS_SOUND_CHANNEL(channel), FALSE); - Mix_HaltChannel (channel->channel_number); + //Mix_HaltChannel (channel->channel_number); + // use Expire channel to let another threaded stop them. + Mix_ExpireChannel( channel->channel_number, 1); return TRUE; } @@ -298,18 +302,19 @@ gc_sound_mixer_sdl_play_item (GcSoundMixer * mixer, GcSoundChannel * channel, G if ((item->volume == -1.0) || (item->volume > channel->volume)) Mix_VolumeChunk(sample, (int ) channel->volume * MIX_MAX_VOLUME); - else + else { Mix_VolumeChunk(sample, (int) item->volume * MIX_MAX_VOLUME); + } - if (Mix_PlayChannel(channel->channel_number, sample, 0)==-1) { - g_warning("Channel cannot play music %s", item->filename); - Mix_FreeChunk (sample); - return FALSE; - } + if (Mix_PlayChannel(channel->channel_number, sample, 0)==-1) { + g_warning("Channel cannot play music %s", item->filename); + Mix_FreeChunk (sample); + return FALSE; + } g_hash_table_insert( self->samples, channel, sample); - g_warning("Playing %s on channel #%d", item->filename, channel->channel_number); + g_warning("Playing %s volume on channel #%d", item->filename, channel->channel_number); return TRUE; } @@ -324,6 +329,8 @@ void channel_finished_cb (int channel_number) g_return_if_fail(GC_IS_SOUND_MIXER_SDL(self)); g_return_if_fail(GC_IS_SOUND_CHANNEL(channel)); + g_warning("Oh My Goodness, an error : %s", Mix_GetError()); + g_signal_emit(self, gc_sound_mixer_sdl_signals[CHANNEL_FINISHED], 0, channel, NULL); } diff --git a/src/gc_sound/src/test_gc_sound.c b/src/gc_sound/src/test_gc_sound.c index 745cfff..a58060c 100644 --- a/src/gc_sound/src/test_gc_sound.c +++ b/src/gc_sound/src/test_gc_sound.c @@ -12,7 +12,7 @@ void start(GcSoundItem *item, gpointer data) g_warning("Return of start callback %s", GC_SOUND_OBJECT(item)->nick); } -main (int argc, char *argv) +int main (int argc, char **argv) { GcSoundMixer *gcmix; GcSoundChannel* gcchan1, *gcchan2; @@ -122,4 +122,5 @@ main (int argc, char *argv) g_warning("loop now"); g_main_loop_run(g_main_loop_new (NULL, FALSE)); + return 0; } diff --git a/src/gcompris/bar.c b/src/gcompris/bar.c index bb5ac5b..759999e 100644 --- a/src/gcompris/bar.c +++ b/src/gcompris/bar.c @@ -536,13 +536,13 @@ item_event_bar(GnomeCanvasItem *item, GdkEvent *event, gchar *data) } else if(!strcmp((char *)data, "back")) { - gc_sound_play_ogg ("gobble", NULL); + gc_sound_play_ogg ("sounds/gobble.ogg", NULL); gc_bar_hide (TRUE); gc_board_stop(); } else if(!strcmp((char *)data, "help")) { - gc_sound_play_ogg ("gobble", NULL); + gc_sound_play_ogg ("sounds/gobble.ogg", NULL); gc_help_start(gcomprisBoard); } else if(!strcmp((char *)data, "repeat")) -- cgit v0.9.1