New volume change interrupts old one
[projects/chimara/chimara.git] / libchimara / schannel.c
index 71c2727dc8100a43885dec87abdae443d01365af..d176d7d87caf7ef04aa878340aea32943863b2a1 100644 (file)
@@ -680,22 +680,6 @@ glk_schannel_unpause(schanid_t chan)
        }
 }
 
-static double
-volume_glk_to_gstreamer(glui32 volume_glk)
-{
-       return CLAMP(((double)volume_glk / 0x10000), 0.0, 10.0);
-}
-
-static void
-channel_set_volume_immediately(schanid_t chan, double volume, glui32 notify)
-{
-       g_object_set(chan->filter, "volume", volume, NULL);
-
-       if(notify != 0) {
-               /* Send a notification */
-       }
-}
-
 /**
  * glk_schannel_set_volume:
  * @chan: Channel to set the volume of.
@@ -728,15 +712,16 @@ channel_set_volume_immediately(schanid_t chan, double volume, glui32 notify)
 void 
 glk_schannel_set_volume(schanid_t chan, glui32 vol)
 {
-       VALID_SCHANNEL(chan, return);
-       /* Silently ignore out-of-range volume values */
+       glk_schannel_set_volume_ext(chan, vol, 0, 0);
+}
 
-#ifdef GSTREAMER_SOUND
-       double volume = volume_glk_to_gstreamer(vol);
-       channel_set_volume_immediately(chan, volume, 0);
-#endif
+static double
+volume_glk_to_gstreamer(glui32 volume_glk)
+{
+       return CLAMP(((double)volume_glk / 0x10000), 0.0, 10.0);
 }
 
+#ifdef GSTREAMER_SOUND
 static gboolean
 volume_change_timeout(schanid_t chan)
 {
@@ -747,9 +732,10 @@ volume_change_timeout(schanid_t chan)
                /* We're done - make sure the volume is at the requested level */
                g_object_set(chan->filter, "volume", chan->target_volume, NULL);
 
-               if(chan->volume_notify) {
-                       /* Send a notification */
-               }
+               if(chan->volume_notify)
+                       event_throw(chan->glk, evtype_VolumeNotify, NULL, 0, chan->volume_notify);
+
+               chan->volume_timer_id = 0;
                return FALSE;
        }
 
@@ -762,13 +748,11 @@ volume_change_timeout(schanid_t chan)
        g_object_get(chan->filter, "volume", &current_volume, NULL);
        double volume_step = (chan->target_volume - current_volume) / steps_left;
 
-       g_printerr("Time left: %.2f ms\nVolume difference: %.2f\nVolume step: %.4f\n",
-               time_left_msec, chan->target_volume - current_volume, volume_step);
-
        g_object_set(chan->filter, "volume", current_volume + volume_step, NULL);
 
        return TRUE;
 }
+#endif /* GSTREAMER_SOUND */
 
 /**
  * glk_schannel_set_volume_ext:
@@ -813,12 +797,20 @@ glk_schannel_set_volume_ext(schanid_t chan, glui32 vol, glui32 duration, glui32
 {
        VALID_SCHANNEL(chan, return);
        /* Silently ignore out-of-range volume values */
-       
+
 #ifdef GSTREAMER_SOUND
+       /* Interrupt a previous volume change */
+       if(chan->volume_timer_id > 0)
+               g_source_remove(chan->volume_timer_id);
+       
        double target_volume = volume_glk_to_gstreamer(vol);
 
        if(duration == 0) {
-               channel_set_volume_immediately(chan, target_volume, notify);
+               g_object_set(chan->filter, "volume", target_volume, NULL);
+
+               if(notify != 0)
+                       event_throw(chan->glk, evtype_VolumeNotify, NULL, 0, notify);
+
                return;
        }
 
@@ -832,7 +824,7 @@ glk_schannel_set_volume_ext(schanid_t chan, glui32 vol, glui32 duration, glui32
        chan->volume_notify = notify;
 
        /* Set up a timer for the volume */
-       g_timeout_add(VOLUME_TIMER_RESOLUTION, (GSourceFunc)volume_change_timeout, chan);
+       chan->volume_timer_id = g_timeout_add(VOLUME_TIMER_RESOLUTION, (GSourceFunc)volume_change_timeout, chan);
 #endif
 }