X-Git-Url: https://git.toastfreeware.priv.at/gregoa/zavai.git/blobdiff_plain/a485a16f789a767c378844efefed40fb05f2a554..4ab1def9651af8f5405f2dce85374382f4a01d9b:/src/audio.vala?ds=sidebyside diff --git a/src/audio.vala b/src/audio.vala index 4d4df38..51790d0 100644 --- a/src/audio.vala +++ b/src/audio.vala @@ -25,9 +25,6 @@ namespace audio { public class Audio: zavai.Service { - protected Omhacks.Led vibrator; - protected bool has_vibrator; - /* protected dynamic DBus.Object audiodev; protected dynamic DBus.Object vibdev; @@ -37,8 +34,6 @@ public class Audio: zavai.Service { Object(name: "audio"); - has_vibrator = (vibrator.init("neo1973:vibrator") == 0); - /* audiodev = zavai.registry.sbus.get_object( "org.freesmartphone.odeviced", @@ -49,138 +44,241 @@ public class Audio: zavai.Service "/org/freesmartphone/Device/LED/neo1973_vibrator", "org.freesmartphone.Device.LED"); */ - if (has_vibrator) + } +} + +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) { - zavai.log.warning("audio: can notify alarm triggers"); - clock.alarm_trigger_queue.triggered += on_alarm_trigger; - clock.alarm_trigger_queue.acked += on_alarm_done; - clock.alarm_trigger_queue.canceled += on_alarm_done; - } else { - zavai.log.warning("audio: no way to notify alarm triggers"); + 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 void on_alarm_trigger(clock.AlarmTriggerInfo info) +public class SoundPlayer : zavai.Resource, Object +{ + protected List states; + protected MusicPlayer slave; + protected bool slave_was_playing; + + public SoundPlayer() { - zavai.log.debug("Start vibrator"); - vibrator.brightness = 256; - // FIXME: is there a better way? I hope there is a better way. Please - // tell me there is a better way. - var trig = "timer"; - for (int i = 0; ; ++i) + 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) { - vibrator.trigger[i] = (char)trig[i]; - if (trig[i] == 0) break; - } - vibrator.delay_on = 200; - vibrator.delay_off = 300; - vibrator.set(); + // 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 on_alarm_done(clock.AlarmTriggerInfo info) + public void pop_state(string owner) { - zavai.log.debug("Stop vibrator"); - var trig = "none"; - for (int i = 0; ; ++i) + // 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) { - vibrator.trigger[i] = (char)trig[i]; - if (trig[i] == 0) break; + if (states == null) + stop_playing(); + else + states.data.resume(); } - vibrator.brightness = 0; - vibrator.set(); } -/* - public void notify_alarm(zavai.clock.Alarm a) - { - // Wiggle screen to turn on backlight - zavai.ui.power.backlight.wiggle(); - try { - // Method does not exist in this frameworkd - vibdev.BlinkSeconds(5, 500, 200); - } catch (Error e) { - zavai.log.error("Cannot blink vibrator: " + e.message); + public void shutdown() + { + while (states != null) + { + states.data.stop(); + states.delete_link(states); } - // TODO: play music? + stop_playing(); } -*/ } -public class Player: zavai.Service +public class MusicPlayer: zavai.Resource, Object { - protected Gst.Element music_player; - protected bool music_playing; - protected Gst.Element sound_player; - protected bool sound_playing; + protected Gst.Element player; + public SoundPlayer master; + public signal void state_changed(Gst.State new_state); + public string uri; + public bool playing; - public Player() + public MusicPlayer() { - Object(name: "audio.player"); + 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; + } - music_player = Gst.ElementFactory.make("playbin", null); - music_playing = false; - var music_bus = music_player.get_bus(); - music_bus.add_signal_watch(); - music_bus.message += on_music_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); + } - sound_player = Gst.ElementFactory.make("playbin", null); - sound_playing = false; - var sound_bus = sound_player.get_bus(); - sound_bus.add_signal_watch(); - sound_bus.message += on_sound_message; + protected void stop_playing() + { + player.set_state(Gst.State.NULL); + state_changed(Gst.State.NULL); } - public void play_music(string uri) + public Gst.State get_state() { -stderr.printf("Music starts %s\n", uri); - music_player.set_property("uri", uri); - music_player.set_state(sound_playing ? Gst.State.PAUSED : Gst.State.PLAYING); - music_playing = true; + return player.current_state; } - public void play_sound(string uri) + public void pause() { -stderr.printf("Sound starts %s\n", uri); - // Pause music - if (music_playing) music_player.set_state(Gst.State.PAUSED); - // Play sound - sound_player.set_property("uri", uri); - sound_player.set_state(Gst.State.PLAYING); - music_playing = true; + playing = false; + player.set_state(Gst.State.PAUSED); + state_changed(Gst.State.PAUSED); } - protected void on_music_message(Gst.Message message) + public void resume() { - if (message.type == Gst.MessageType.EOS) + playing = true; + if (master == null || !master.playing()) { -stderr.printf("Music ends\n"); - music_playing = false; - music_player.set_state(Gst.State.NULL); + player.set_state(Gst.State.PLAYING); + state_changed(Gst.State.PLAYING); } } - protected void on_sound_message(Gst.Message message) + 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) { -stderr.printf("Sound ends\n"); - sound_playing = false; - sound_player.set_state(Gst.State.NULL); - - // Resume music after playing alarm - if (music_playing) music_player.set_state(Gst.State.PLAYING); + playing = false; + stop_playing(); } } + public void shutdown() + { + stop_playing(); + } } public Audio audio = null; -public Player player = null; +public SoundPlayer soundplayer = null; +public MusicPlayer musicplayer = null; public void init() { audio = new Audio(); - player = new Player(); + musicplayer = new MusicPlayer(); + soundplayer = new SoundPlayer(); + soundplayer.set_slave(musicplayer); + zavai.registry.register(musicplayer); + zavai.registry.register(soundplayer); } }