Make noise for alarms
[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         clock.alarm_trigger_queue.triggered += on_alarm_trigger;
53         clock.alarm_trigger_queue.acked += on_alarm_done;
54         clock.alarm_trigger_queue.canceled += on_alarm_done;
55     }
56
57     public void on_alarm_trigger(clock.AlarmTriggerInfo info)
58     {
59         zavai.log.debug("Make noise for alarm");
60         if (has_vibrator)
61         {
62             vibrator.brightness = 256;
63             // FIXME: is there a better way? I hope there is a better way. Please
64             // tell me there is a better way.
65             var trig = "timer";
66             for (int i = 0; ; ++i)
67             {
68                 vibrator.trigger[i] = (char)trig[i];
69                 if (trig[i] == 0) break;
70             }
71             vibrator.delay_on = 200;
72             vibrator.delay_off = 300;
73             vibrator.set();
74         }
75         soundplayer.play(config.ringtone_alarm, true);
76     }
77
78     public void on_alarm_done(clock.AlarmTriggerInfo info)
79     {
80         zavai.log.debug("Stop noise for alarm");
81         if (has_vibrator)
82         {
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         soundplayer.stop();
93     }
94
95 /*
96     public void notify_alarm(zavai.clock.Alarm a)
97     {
98         // Wiggle screen to turn on backlight
99         zavai.ui.power.backlight.wiggle();
100         try {
101             // Method does not exist in this frameworkd
102             vibdev.BlinkSeconds(5, 500, 200);
103         } catch (Error e) {
104             zavai.log.error("Cannot blink vibrator: " + e.message);
105         }
106         // TODO: play music?
107     }
108 */
109 }
110
111 public class Player: zavai.Resource, Object
112 {
113     protected Gst.Element player;
114     protected bool playing;
115     protected Player slave;
116     protected Player master;
117     protected bool loop;
118     protected string uri;
119
120     public Player()
121     {
122         slave = null;
123         master = null;
124         player = Gst.ElementFactory.make("playbin", null);
125         playing = false;
126         loop = false;
127         var bus = player.get_bus();
128         bus.add_signal_watch();
129         bus.message += on_message;
130     }
131
132     public void set_slave(Player player)
133     {
134         slave = player;
135         slave.master = this;
136     }
137
138     public void play(string uri, bool loop = false)
139     {
140 stderr.printf("Playing %s\n", uri);
141         this.uri = uri;
142
143         if (slave != null && slave.playing)
144             slave.pause();
145
146         player.set_property("uri", uri);
147         player.set_state(master != null && master.playing ? Gst.State.PAUSED : Gst.State.PLAYING);
148         playing = true;
149         this.loop = loop;
150     }
151
152     public void pause()
153     {
154         player.set_state(Gst.State.PAUSED);
155     }
156
157     public void resume()
158     {
159         player.set_state(Gst.State.PLAYING);
160     }
161
162     public void restart()
163     {
164         player.seek_simple(Gst.Format.TIME, Gst.SeekFlags.FLUSH | Gst.SeekFlags.KEY_UNIT, 0);
165         player.set_state(Gst.State.PLAYING);
166     }
167
168     public void stop()
169     {
170         playing = false;
171         player.set_state(Gst.State.NULL);
172
173         // Resume slave after we are done
174         if (slave != null && slave.playing)
175             slave.resume();
176     }
177
178     protected void on_message(Gst.Message message)
179     {
180         if (message.type == Gst.MessageType.EOS)
181         {
182             if (loop)
183                 restart();
184             else
185                 stop();
186         }
187     }
188
189     public void shutdown()
190     {
191         stop();
192     }
193 }
194
195 public Audio audio = null;
196 public Player musicplayer = null;
197 public Player soundplayer = null;
198
199 public void init()
200 {
201     audio = new Audio();
202     musicplayer = new Player();
203     soundplayer = new Player();
204     soundplayer.set_slave(musicplayer);
205     zavai.registry.register(musicplayer);
206     zavai.registry.register(soundplayer);
207 }
208
209 }
210 }