2 * audio - audio resource for zavai
4 * Copyright (C) 2009--2010 Enrico Zini <enrico@enricozini.org>
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
26 public class Audio: zavai.Service
29 protected dynamic DBus.Object audiodev;
30 protected dynamic DBus.Object vibdev;
35 Object(name: "audio");
38 audiodev = zavai.registry.sbus.get_object(
39 "org.freesmartphone.odeviced",
40 "/org/freesmartphone/Device/Audio",
41 "org.freesmartphone.Device.Audio");
42 vibdev = zavai.registry.sbus.get_object(
43 "org.freesmartphone.odeviced",
44 "/org/freesmartphone/Device/LED/neo1973_vibrator",
45 "org.freesmartphone.Device.LED");
50 public class PlayerState : Object
52 protected SoundPlayer soundplayer;
53 protected Gst.Element player;
58 public PlayerState(string owner, string uri, bool loop=false)
66 player = Gst.ElementFactory.make("playbin", null);
67 var bus = player.get_bus();
68 bus.add_signal_watch();
69 bus.message += on_message;
71 player.set_property("uri", uri);
72 player.set_state(Gst.State.PAUSED);
75 public void register(SoundPlayer sp)
82 player.set_state(Gst.State.NULL);
87 player.set_state(Gst.State.PAUSED);
92 player.set_state(Gst.State.PLAYING);
95 protected void on_message(Gst.Message message)
97 if (message.type == Gst.MessageType.EOS)
101 player.seek_simple(Gst.Format.TIME, Gst.SeekFlags.FLUSH | Gst.SeekFlags.KEY_UNIT, 0);
102 player.set_state(Gst.State.PLAYING);
104 else if (soundplayer != null)
105 soundplayer.pop_state(owner);
110 public class SoundPlayer : zavai.Resource, Object
112 protected List<PlayerState> states;
113 protected MusicPlayer slave;
114 protected bool slave_was_playing;
118 states = new List<PlayerState>();
121 public void set_slave(MusicPlayer player)
127 public bool playing()
129 return states != null;
132 protected void stop_playing()
134 if (slave_was_playing)
138 public void push_state(PlayerState state)
140 // Save current playing position
143 // We start playing: see about preempting slave
144 slave_was_playing = (slave != null && slave.playing);
145 if (slave_was_playing)
148 // We were playing: pause previous sound
150 state.register(this);
151 states.prepend(state);
152 states.data.resume();
155 public void pop_state(string owner)
158 if (states == null) return;
160 // Track if the list head changed
161 weak List<PlayerState> old_top = states;
163 // Remove state "name" from the stack
164 for (weak List<PlayerState> i = states; i != null; i = i.next)
165 if (i.data.owner == owner)
168 states.delete_link(i);
172 // If the list head changed, put into action the new top state
173 if (states != old_top)
178 states.data.resume();
182 public void shutdown()
184 while (states != null)
187 states.delete_link(states);
193 public class MusicPlayer: zavai.Resource, Object
195 protected Gst.Element player;
196 public SoundPlayer master;
197 public signal void state_changed(Gst.State new_state);
206 player = Gst.ElementFactory.make("playbin", null);
207 var bus = player.get_bus();
208 bus.add_signal_watch();
209 bus.message += on_message;
212 public void play(string uri)
216 player.set_property("uri", uri);
217 player.set_state(master != null && master.playing() ? Gst.State.PAUSED : Gst.State.PLAYING);
220 protected void stop_playing()
222 player.set_state(Gst.State.NULL);
223 state_changed(Gst.State.NULL);
226 public Gst.State get_state()
228 return player.current_state;
234 player.set_state(Gst.State.PAUSED);
235 state_changed(Gst.State.PAUSED);
241 if (master == null || !master.playing())
243 player.set_state(Gst.State.PLAYING);
244 state_changed(Gst.State.PLAYING);
248 public void restart()
250 player.seek_simple(Gst.Format.TIME, Gst.SeekFlags.FLUSH | Gst.SeekFlags.KEY_UNIT, 0);
251 player.set_state(Gst.State.PLAYING);
252 state_changed(Gst.State.PLAYING);
255 protected void on_message(Gst.Message message)
257 if (message.type == Gst.MessageType.EOS)
264 public void shutdown()
270 public Audio audio = null;
271 public SoundPlayer soundplayer = null;
272 public MusicPlayer musicplayer = null;
277 musicplayer = new MusicPlayer();
278 soundplayer = new SoundPlayer();
279 soundplayer.set_slave(musicplayer);
280 zavai.registry.register(musicplayer);
281 zavai.registry.register(soundplayer);