Mercurial > audlegacy-plugins
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 } |
