Share code among players
[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     protected Omhacks.Led vibrator;
29     protected bool has_vibrator;
30
31     /*
32        protected dynamic DBus.Object audiodev;
33        protected dynamic DBus.Object vibdev;
34    */
35
36     public Audio()
37     {
38         Object(name: "audio");
39
40         has_vibrator = (vibrator.init("neo1973:vibrator") == 0);
41
42 /*
43         audiodev = zavai.registry.sbus.get_object(
44                 "org.freesmartphone.odeviced",
45                 "/org/freesmartphone/Device/Audio",
46                 "org.freesmartphone.Device.Audio");
47         vibdev = zavai.registry.sbus.get_object(
48                 "org.freesmartphone.odeviced",
49                 "/org/freesmartphone/Device/LED/neo1973_vibrator",
50                 "org.freesmartphone.Device.LED");
51 */
52         if (has_vibrator)
53         {
54             zavai.log.warning("audio: can notify alarm triggers");
55             clock.alarm_trigger_queue.triggered += on_alarm_trigger;
56             clock.alarm_trigger_queue.acked += on_alarm_done;
57             clock.alarm_trigger_queue.canceled += on_alarm_done;
58         } else {
59             zavai.log.warning("audio: no way to notify alarm triggers");
60         }
61     }
62
63     public void on_alarm_trigger(clock.AlarmTriggerInfo info)
64     {
65         zavai.log.debug("Start vibrator");
66         vibrator.brightness = 256;
67         // FIXME: is there a better way? I hope there is a better way. Please
68         // tell me there is a better way.
69         var trig = "timer";
70         for (int i = 0; ; ++i)
71         {
72             vibrator.trigger[i] = (char)trig[i];
73             if (trig[i] == 0) break;
74         }
75         vibrator.delay_on = 200;
76         vibrator.delay_off = 300;
77         vibrator.set();
78     }
79
80     public void on_alarm_done(clock.AlarmTriggerInfo info)
81     {
82         zavai.log.debug("Stop vibrator");
83         var trig = "none";
84         for (int i = 0; ; ++i)
85         {
86             vibrator.trigger[i] = (char)trig[i];
87             if (trig[i] == 0) break;
88         }
89         vibrator.brightness = 0;
90         vibrator.set();
91     }
92
93 /*
94     public void notify_alarm(zavai.clock.Alarm a)
95     {
96         // Wiggle screen to turn on backlight
97         zavai.ui.power.backlight.wiggle();
98         try {
99             // Method does not exist in this frameworkd
100             vibdev.BlinkSeconds(5, 500, 200);
101         } catch (Error e) {
102             zavai.log.error("Cannot blink vibrator: " + e.message);
103         }
104         // TODO: play music?
105     }
106 */
107 }
108
109 public class Player: zavai.Resource, Object
110 {
111     protected Gst.Element player;
112     protected bool playing;
113     protected Player slave;
114     protected Player master;
115
116     public Player()
117     {
118         slave = null;
119         master = null;
120         player = Gst.ElementFactory.make("playbin", null);
121         playing = false;
122         var bus = player.get_bus();
123         bus.add_signal_watch();
124         bus.message += on_message;
125     }
126
127     public void set_slave(Player player)
128     {
129         slave = player;
130         slave.master = this;
131     }
132
133     public void play(string uri)
134     {
135         if (slave != null && slave.playing)
136             slave.pause();
137
138         player.set_property("uri", uri);
139         player.set_state(master != null && master.playing ? Gst.State.PAUSED : Gst.State.PLAYING);
140         playing = true;
141     }
142
143     public void pause()
144     {
145         player.set_state(Gst.State.PAUSED);
146     }
147
148     public void resume()
149     {
150         player.set_state(Gst.State.PLAYING);
151     }
152
153     public void stop()
154     {
155         playing = false;
156         player.set_state(Gst.State.NULL);
157
158         // Resume slave after we are done
159         if (slave != null && slave.playing)
160             slave.resume();
161     }
162
163     protected void on_message(Gst.Message message)
164     {
165         if (message.type == Gst.MessageType.EOS)
166             stop();
167     }
168
169     public void shutdown()
170     {
171         stop();
172     }
173 }
174
175 public Audio audio = null;
176 public Player musicplayer = null;
177 public Player soundplayer = null;
178
179 public void init()
180 {
181     audio = new Audio();
182     musicplayer = new Player();
183     soundplayer = new Player();
184     soundplayer.set_slave(musicplayer);
185     zavai.registry.register(musicplayer);
186     zavai.registry.register(soundplayer);
187 }
188
189 }
190 }