X-Git-Url: https://git.toastfreeware.priv.at/gregoa/zavai.git/blobdiff_plain/d36b7e6b30388f03e1e99843ee7e9fdb779bbffb..4ab1def9651af8f5405f2dce85374382f4a01d9b:/src/audio.vala?ds=sidebyside diff --git a/src/audio.vala b/src/audio.vala index 4cc37f4..51790d0 100644 --- a/src/audio.vala +++ b/src/audio.vala @@ -1,7 +1,7 @@ /* * audio - audio resource for zavai * - * Copyright (C) 2009 Enrico Zini + * Copyright (C) 2009--2010 Enrico Zini * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -25,41 +25,260 @@ namespace audio { public class Audio: zavai.Service { - protected dynamic DBus.Object audiodev; - protected dynamic DBus.Object vibdev; - - public Audio() - { - name = "audio"; - audiodev = zavai.registry.sbus.get_object( - "org.freesmartphone.odeviced", - "/org/freesmartphone/Device/Audio", - "org.freesmartphone.Device.Audio"); + /* + protected dynamic DBus.Object audiodev; + protected dynamic DBus.Object vibdev; + */ + + public Audio() + { + Object(name: "audio"); + +/* + audiodev = zavai.registry.sbus.get_object( + "org.freesmartphone.odeviced", + "/org/freesmartphone/Device/Audio", + "org.freesmartphone.Device.Audio"); vibdev = zavai.registry.sbus.get_object( - "org.freesmartphone.odeviced", - "/org/freesmartphone/Device/LED/neo1973_vibrator", - "org.freesmartphone.Device.LED"); - } - - public void notify_alarm(zavai.clock.Alarm a) - { - // Wiggle screen to turn on backlight - zavai.ui.power.backlight.wiggle(); - try { - vibdev.BlinkSeconds(2, 500, 200); - } catch (Error e) { - zavai.log.error("Cannot blink vibrator: " + e.message); + "org.freesmartphone.odeviced", + "/org/freesmartphone/Device/LED/neo1973_vibrator", + "org.freesmartphone.Device.LED"); +*/ + } +} + +public class PlayerState : Object +{ + protected SoundPlayer soundplayer; + protected Gst.Element player; + public string owner; + public string uri; + public bool loop; + + public PlayerState(string owner, string uri, bool loop=false) + { + soundplayer = null; + + this.owner = owner; + this.uri = uri; + this.loop = loop; + + player = Gst.ElementFactory.make("playbin", null); + var bus = player.get_bus(); + bus.add_signal_watch(); + bus.message += on_message; + + player.set_property("uri", uri); + player.set_state(Gst.State.PAUSED); + } + + public void register(SoundPlayer sp) + { + soundplayer = sp; + } + + public void stop() + { + player.set_state(Gst.State.NULL); + } + + public void pause() + { + player.set_state(Gst.State.PAUSED); + } + + public void resume() + { + player.set_state(Gst.State.PLAYING); + } + + protected void on_message(Gst.Message message) + { + if (message.type == Gst.MessageType.EOS) + { + if (loop) + { + player.seek_simple(Gst.Format.TIME, Gst.SeekFlags.FLUSH | Gst.SeekFlags.KEY_UNIT, 0); + player.set_state(Gst.State.PLAYING); + } + else if (soundplayer != null) + soundplayer.pop_state(owner); + } + } +} + +public class SoundPlayer : zavai.Resource, Object +{ + protected List states; + protected MusicPlayer slave; + protected bool slave_was_playing; + + public SoundPlayer() + { + states = new List(); + } + + public void set_slave(MusicPlayer player) + { + slave = player; + slave.master = this; + } + + public bool playing() + { + return states != null; + } + + protected void stop_playing() + { + if (slave_was_playing) + slave.resume(); + } + + public void push_state(PlayerState state) + { + // Save current playing position + if (states == null) + { + // We start playing: see about preempting slave + slave_was_playing = (slave != null && slave.playing); + if (slave_was_playing) + slave.pause(); + } else + // We were playing: pause previous sound + states.data.pause(); + state.register(this); + states.prepend(state); + states.data.resume(); + } + + public void pop_state(string owner) + { + // Handle empty list + if (states == null) return; + + // Track if the list head changed + weak List old_top = states; + + // Remove state "name" from the stack + for (weak List i = states; i != null; i = i.next) + if (i.data.owner == owner) + { + i.data.stop(); + states.delete_link(i); + break; + } + + // If the list head changed, put into action the new top state + if (states != old_top) + { + if (states == null) + stop_playing(); + else + states.data.resume(); + } + } + + public void shutdown() + { + while (states != null) + { + states.data.stop(); + states.delete_link(states); } + stop_playing(); + } +} + +public class MusicPlayer: zavai.Resource, Object +{ + protected Gst.Element player; + public SoundPlayer master; + public signal void state_changed(Gst.State new_state); + public string uri; + public bool playing; + + public MusicPlayer() + { + master = null; + uri = null; + playing = false; + player = Gst.ElementFactory.make("playbin", null); + var bus = player.get_bus(); + bus.add_signal_watch(); + bus.message += on_message; + } + + public void play(string uri) + { + this.uri = uri; + playing = true; + player.set_property("uri", uri); + player.set_state(master != null && master.playing() ? Gst.State.PAUSED : Gst.State.PLAYING); + } + + protected void stop_playing() + { + player.set_state(Gst.State.NULL); + state_changed(Gst.State.NULL); + } + + public Gst.State get_state() + { + return player.current_state; + } + + public void pause() + { + playing = false; + player.set_state(Gst.State.PAUSED); + state_changed(Gst.State.PAUSED); + } + + public void resume() + { + playing = true; + if (master == null || !master.playing()) + { + player.set_state(Gst.State.PLAYING); + state_changed(Gst.State.PLAYING); + } + } + + public void restart() + { + player.seek_simple(Gst.Format.TIME, Gst.SeekFlags.FLUSH | Gst.SeekFlags.KEY_UNIT, 0); + player.set_state(Gst.State.PLAYING); + state_changed(Gst.State.PLAYING); + } + + protected void on_message(Gst.Message message) + { + if (message.type == Gst.MessageType.EOS) + { + playing = false; + stop_playing(); + } + } + + public void shutdown() + { + stop_playing(); } } public Audio audio = null; +public SoundPlayer soundplayer = null; +public MusicPlayer musicplayer = null; public void init() { audio = new Audio(); - - zavai.registry.register_service(audio); + musicplayer = new MusicPlayer(); + soundplayer = new SoundPlayer(); + soundplayer.set_slave(musicplayer); + zavai.registry.register(musicplayer); + zavai.registry.register(soundplayer); } }