comparison src/null/null.c @ 144:5dfc0e491ad3 trunk

[svn] Null output plugin added; original code by Christian Birchinger <joker -at- gentoo.org>
author kiyoshi
date Mon, 30 Oct 2006 17:40:00 -0800
parents
children 7385182ae4b8
comparison
equal deleted inserted replaced
143:e8f34254bc18 144:5dfc0e491ad3
1 /*
2 * Copyright 2006 Christian Birchinger <joker@netswarm.net>
3 *
4 * Based on the XMMS plugin:
5 * Copyright 2000 Håvard Kvålen <havardk@sol.no>
6 *
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
21 */
22
23 #include <glib.h>
24 #include <glib/gi18n.h>
25 #include <gtk/gtk.h>
26 #include <audacious/plugin.h>
27 #include <audacious/util.h>
28 #include <audacious/configdb.h>
29
30 static GTimer *timer;
31 static gulong offset_time, written;
32 static gint bps;
33 static gboolean real_time = TRUE;
34 static gboolean paused, started;
35 static GtkWidget *configurewin;
36 static struct {
37 AFormat format;
38 gint frequency;
39 gint channels;
40 } input_format;
41
42 #define ELAPSED_TIME (offset_time + g_timer_elapsed(timer, NULL) * 1000)
43
44 static void null_init(void)
45 {
46 ConfigDb *db;
47 db = bmp_cfg_db_open();
48 bmp_cfg_db_get_bool(db, "null", "real_time", &real_time);
49 bmp_cfg_db_close(db);
50 }
51
52 static void null_about(void)
53 {
54 static GtkWidget *about;
55
56 if (about)
57 return;
58 about = xmms_show_message(_("About Null Output"),
59 _("Null output plugin " VERSION
60 " by Christian Birchinger <joker@netswarm.net>\n"
61 " based on the XMMS plugin by Håvard Kvål <havardk@xmms.org>"),
62 _("Ok"), FALSE, NULL, NULL);
63
64 g_signal_connect(G_OBJECT(about), "destroy",
65 G_CALLBACK(gtk_widget_destroyed), &about);
66 }
67
68 static void null_configure_ok_cb(GtkButton *w, gpointer data)
69 {
70 ConfigDb *db;
71
72 db = bmp_cfg_db_open();
73 real_time = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(data));
74 bmp_cfg_db_set_bool(db, "null", "real_time", real_time);
75 bmp_cfg_db_close(db);
76 gtk_widget_destroy(configurewin);
77 }
78
79
80 static void null_configure(void)
81 {
82 GtkWidget *rt_btn, *ok_button, *cancel_button, *vbox, *bbox;
83
84 if (configurewin)
85 return;
86
87 configurewin = gtk_window_new(GTK_WINDOW_TOPLEVEL);
88 gtk_window_set_title(GTK_WINDOW(configurewin), "Null output preferences");
89 gtk_window_set_policy(GTK_WINDOW(configurewin), FALSE, FALSE, FALSE);
90 gtk_container_set_border_width(GTK_CONTAINER(configurewin), 10);
91 gtk_signal_connect(GTK_OBJECT(configurewin), "destroy",
92 GTK_SIGNAL_FUNC(gtk_widget_destroyed), &configurewin);
93
94 vbox = gtk_vbox_new(FALSE, 10);
95 gtk_container_add(GTK_CONTAINER(configurewin), vbox);
96
97 rt_btn = gtk_check_button_new_with_label("Run in real time");
98 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(rt_btn), real_time);
99 gtk_box_pack_start(GTK_BOX(vbox), rt_btn, FALSE, FALSE, 0);
100 bbox = gtk_hbutton_box_new();
101 gtk_button_box_set_layout(GTK_BUTTON_BOX(bbox), GTK_BUTTONBOX_END);
102 gtk_button_box_set_spacing(GTK_BUTTON_BOX(bbox), 5);
103 gtk_box_pack_start(GTK_BOX(vbox), bbox, FALSE, FALSE, 0);
104 ok_button = gtk_button_new_with_label("Ok");
105 cancel_button = gtk_button_new_with_label("Cancel");
106 GTK_WIDGET_SET_FLAGS(ok_button, GTK_CAN_DEFAULT);
107 GTK_WIDGET_SET_FLAGS(cancel_button, GTK_CAN_DEFAULT);
108 gtk_widget_grab_default(ok_button);
109 gtk_signal_connect_object(GTK_OBJECT(cancel_button), "clicked",
110 GTK_SIGNAL_FUNC(gtk_widget_destroy),
111 GTK_OBJECT(configurewin));
112 gtk_signal_connect(GTK_OBJECT(ok_button), "clicked",
113 GTK_SIGNAL_FUNC(null_configure_ok_cb), rt_btn);
114 gtk_box_pack_start_defaults(GTK_BOX(bbox), ok_button);
115 gtk_box_pack_start_defaults(GTK_BOX(bbox), cancel_button);
116
117 gtk_widget_show_all(configurewin);
118 }
119
120 static int null_open(AFormat fmt, int rate, int nch)
121 {
122 offset_time = 0;
123 written = 0;
124 started = FALSE;
125 paused = FALSE;
126 input_format.format = fmt;
127 input_format.frequency = rate;
128 input_format.channels = nch;
129 bps = rate * nch;
130 switch (fmt)
131 {
132 case FMT_U8:
133 case FMT_S8:
134 break;
135 default:
136 bps <<= 1;
137 break;
138 }
139 if (real_time)
140 timer = g_timer_new();
141 return 1;
142 }
143
144 static void null_write(void *ptr, int length)
145 {
146 EffectPlugin *ep;
147 if (timer && !started)
148 {
149 g_timer_start(timer);
150 started = TRUE;
151 }
152
153 if ((ep = get_current_effect_plugin()) != NULL &&
154 effects_enabled() && ep->mod_samples)
155 ep->mod_samples(&ptr, length, input_format.format,
156 input_format.frequency, input_format.channels);
157
158 written += length;
159 }
160
161 static void null_close(void)
162 {
163 if (timer)
164 g_timer_destroy(timer);
165 timer = NULL;
166 }
167
168 static void null_flush(int time)
169 {
170 offset_time = time;
171 written = ((double)time * bps) / 1000;
172 if (timer)
173 g_timer_reset(timer);
174 }
175
176 static void null_pause(short p)
177 {
178 paused = p;
179 if (!timer)
180 return;
181
182 if (paused)
183 g_timer_stop(timer);
184 else
185 {
186 offset_time += g_timer_elapsed(timer, NULL) * 1000;
187 g_timer_start(timer);
188 }
189 }
190
191 static int null_buffer_free(void)
192 {
193 if (timer)
194 {
195 return 10240 - (written - (ELAPSED_TIME * bps) / 1000);
196 }
197 else
198 {
199 if (!paused)
200 return 10000;
201 else
202 return 0;
203 }
204 }
205
206 static int null_playing(void)
207 {
208 if (!timer)
209 return FALSE;
210
211 if ((gdouble)(written * 1000) / bps > ELAPSED_TIME)
212 return TRUE;
213 return FALSE;
214 }
215
216 static int null_get_written_time(void)
217 {
218 if (!bps)
219 return 0;
220 return ((gint64)written * 1000) / bps;
221 }
222
223 static int null_get_output_time(void)
224 {
225 if (!timer)
226 return null_get_written_time();
227
228 return ELAPSED_TIME;
229 }
230
231 OutputPlugin null_op =
232 {
233 NULL,
234 NULL,
235 "Null output " VERSION,
236 null_init,
237 NULL, /* cleanup */
238 null_about,
239 null_configure,
240 NULL, /* Get volume */
241 NULL, /* Set volume */
242 null_open,
243 null_write,
244 null_close,
245 null_flush,
246 null_pause,
247 null_buffer_free,
248 null_playing,
249 null_get_output_time,
250 null_get_written_time,
251 NULL /* tell */
252 };
253
254 OutputPlugin *get_oplugin_info(void)
255 {
256 return &null_op;
257 }