0a3967c8095e6c21639e1c86a46b3e2104c6f56a
[gregoa/zavai.git] / src / audio.vala
1 /*
2  * audio - audio resource for zavai
3  *
4  * Copyright (C) 2009--2010  Enrico Zini <enrico@enricozini.org>
5  *
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.
10  *
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.
15  *
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
19  */
20
21 using GLib;
22
23 namespace zavai {
24 namespace audio {
25
26 public class Audio: zavai.Service
27 {
28     /*
29        protected dynamic DBus.Object audiodev;
30        protected dynamic DBus.Object vibdev;
31    */
32
33     public Audio()
34     {
35         Object(name: "audio");
36
37 /*
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");
46 */
47         clock.alarm_trigger_queue.triggered += on_alarm_trigger;
48         clock.alarm_trigger_queue.acked += on_alarm_done;
49         clock.alarm_trigger_queue.canceled += on_alarm_done;
50     }
51
52     public void on_alarm_trigger(clock.AlarmTriggerInfo info)
53     {
54         zavai.log.debug("Make noise for alarm");
55         if (zavai.led.vibrator != null)
56         {
57             var state = new zavai.led.LedState("alarm");
58             state.set_blink(255);
59             zavai.led.vibrator.push_state(state);
60         }
61         soundplayer.play(config.ringtone_alarm, true);
62     }
63
64     public void on_alarm_done(clock.AlarmTriggerInfo info)
65     {
66         zavai.log.debug("Stop noise for alarm");
67         if (zavai.led.vibrator != null)
68             zavai.led.vibrator.pop_state("alarm");
69         soundplayer.stop();
70     }
71 }
72
73 public class Player: zavai.Resource, Object
74 {
75     protected Gst.Element player;
76     protected bool playing;
77     protected Player slave;
78     protected Player master;
79     protected bool loop;
80     protected string uri;
81     public signal void state_changed(Gst.State new_state);
82
83     public Player()
84     {
85         slave = null;
86         master = null;
87         player = Gst.ElementFactory.make("playbin", null);
88         playing = false;
89         loop = false;
90         var bus = player.get_bus();
91         bus.add_signal_watch();
92         bus.message += on_message;
93     }
94
95     public void set_slave(Player player)
96     {
97         slave = player;
98         slave.master = this;
99     }
100
101     public void play(string uri, bool loop = false)
102     {
103 stderr.printf("Playing %s\n", uri);
104         this.uri = uri;
105
106         if (slave != null && slave.playing)
107             slave.pause();
108
109         player.set_property("uri", uri);
110         player.set_state(master != null && master.playing ? Gst.State.PAUSED : Gst.State.PLAYING);
111         playing = true;
112         this.loop = loop;
113     }
114
115     public Gst.State get_state()
116     {
117         Gst.State state;
118         Gst.State pending;
119
120         player.get_state(out state, out pending, (Gst.ClockType)Gst.CLOCK_TIME_NONE);
121
122         return state;
123     }
124
125     public void pause()
126     {
127         player.set_state(Gst.State.PAUSED);
128         state_changed(Gst.State.PAUSED);
129     }
130
131     public void resume()
132     {
133         player.set_state(Gst.State.PLAYING);
134         state_changed(Gst.State.PLAYING);
135     }
136
137     public void restart()
138     {
139         player.seek_simple(Gst.Format.TIME, Gst.SeekFlags.FLUSH | Gst.SeekFlags.KEY_UNIT, 0);
140         player.set_state(Gst.State.PLAYING);
141         state_changed(Gst.State.PLAYING);
142     }
143
144     public void stop()
145     {
146         playing = false;
147         player.set_state(Gst.State.NULL);
148         state_changed(Gst.State.NULL);
149
150         // Resume slave after we are done
151         if (slave != null && slave.playing)
152             slave.resume();
153     }
154
155     protected void on_message(Gst.Message message)
156     {
157         if (message.type == Gst.MessageType.EOS)
158         {
159             if (loop)
160                 restart();
161             else
162                 stop();
163         }
164     }
165
166     public void shutdown()
167     {
168         stop();
169     }
170 }
171
172 public Audio audio = null;
173 public Player musicplayer = null;
174 public Player soundplayer = null;
175
176 public void init()
177 {
178     audio = new Audio();
179     musicplayer = new Player();
180     soundplayer = new Player();
181     soundplayer.set_slave(musicplayer);
182     zavai.registry.register(musicplayer);
183     zavai.registry.register(soundplayer);
184 }
185
186 }
187 }