Mercurial > audlegacy
comparison Plugins/Output/crossfade/configure.c @ 261:5fd398406cf7 trunk
[svn] Still need to pry internal OSS from clenched fingers. In need of anti-warning love too, but it compiles.
author | chainsaw |
---|---|
date | Tue, 06 Dec 2005 16:09:32 -0800 |
parents | |
children | 5410de731c3c |
comparison
equal
deleted
inserted
replaced
260:4b1c9d1a469b | 261:5fd398406cf7 |
---|---|
1 | |
2 /* | |
3 * XMMS Crossfade Plugin | |
4 * Copyright (C) 2000-2004 Peter Eisenlohr <peter@eisenlohr.org> | |
5 * | |
6 * based on the original OSS Output Plugin | |
7 * Copyright (C) 1998-2000 Peter Alm, Mikael Alm, Olle Hallnas, Thomas Nilsson and 4Front Technologies | |
8 * | |
9 * This program is free software; you can redistribute it and/or modify | |
10 * it under the terms of the GNU General Public License as published by | |
11 * the Free Software Foundation; either version 2 of the License, or | |
12 * (at your option) any later version. | |
13 * | |
14 * This program is distributed in the hope that it will be useful, | |
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
17 * GNU General Public License for more details. | |
18 * | |
19 * You should have received a copy of the GNU General Public License | |
20 * along with this program; if not, write to the Free Software | |
21 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, | |
22 * USA. | |
23 */ | |
24 | |
25 #ifdef HAVE_CONFIG_H | |
26 # include "config.h" | |
27 #endif | |
28 | |
29 #undef PRESET_SUPPORT | |
30 | |
31 #include "crossfade.h" | |
32 #include "configure.h" | |
33 #include "interface.h" | |
34 #include "monitor.h" | |
35 #include "support.h" | |
36 #ifdef HAVE_OSS | |
37 # include "oss.h" | |
38 #endif | |
39 | |
40 #include <stdio.h> | |
41 #include <string.h> | |
42 #include <stdlib.h> | |
43 #include <ctype.h> | |
44 | |
45 #include <fcntl.h> | |
46 #include <unistd.h> | |
47 #include <sys/ioctl.h> | |
48 #include <sys/stat.h> | |
49 | |
50 #ifdef HAVE_OSS | |
51 # ifdef HAVE_SYS_SOUNDCARD_H | |
52 # include <sys/soundcard.h> | |
53 # elif defined(HAVE_MACHINE_SOUNDCARD_H) | |
54 # include <machine/soundcard.h> | |
55 # endif | |
56 #endif | |
57 | |
58 #ifdef HAVE_LIBSAMPLERATE | |
59 # include <samplerate.h> | |
60 #endif | |
61 | |
62 | |
63 #define HIDE(name) \ | |
64 { if((set_wgt = lookup_widget(config_win, name))) \ | |
65 gtk_widget_hide(set_wgt); } | |
66 | |
67 #define SHOW(name) \ | |
68 { if((set_wgt = lookup_widget(config_win, name))) \ | |
69 gtk_widget_show(set_wgt); } | |
70 | |
71 | |
72 #define SETW_SENSITIVE(wgt, sensitive) \ | |
73 gtk_widget_set_sensitive(wgt, sensitive) | |
74 | |
75 #define SETW_TOGGLE(wgt, active) \ | |
76 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(wgt), active) | |
77 | |
78 #define SETW_SPIN(wgt, value) \ | |
79 gtk_spin_button_set_value(GTK_SPIN_BUTTON(wgt), value) | |
80 | |
81 | |
82 #define SET_SENSITIVE(name, sensitive) \ | |
83 { if((set_wgt = lookup_widget(config_win, name))) \ | |
84 gtk_widget_set_sensitive(set_wgt, sensitive); } | |
85 | |
86 #define SET_TOGGLE(name, active) \ | |
87 { if((set_wgt = lookup_widget(config_win, name))) \ | |
88 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(set_wgt), active); } | |
89 | |
90 #define SET_SPIN(name, value) \ | |
91 { if((set_wgt = lookup_widget(config_win, name))) \ | |
92 gtk_spin_button_set_value(GTK_SPIN_BUTTON(set_wgt), value); } | |
93 | |
94 #define SET_PAGE(name, index) \ | |
95 { if((set_wgt = lookup_widget(config_win, name))) \ | |
96 gtk_notebook_set_page(GTK_NOTEBOOK(set_wgt), index); } | |
97 | |
98 #define SET_HISTORY(name, index) \ | |
99 { if((set_wgt = lookup_widget(config_win, name))) \ | |
100 gtk_option_menu_set_history(GTK_OPTION_MENU(set_wgt), index); } | |
101 | |
102 | |
103 #define GET_SENSITIVE(name) \ | |
104 ((get_wgt = lookup_widget(config_win, name)) \ | |
105 && GTK_WIDGET_SENSITIVE(get_wgt)) \ | |
106 | |
107 #define GET_TOGGLE(name) \ | |
108 ((get_wgt = lookup_widget(config_win, name)) \ | |
109 && gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(get_wgt))) | |
110 | |
111 #define GET_SPIN(name) \ | |
112 ((get_wgt = lookup_widget(config_win, name)) \ | |
113 ? gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(get_wgt)) : 0) | |
114 | |
115 | |
116 static GtkWidget *config_win = NULL; | |
117 static GtkWidget *about_win = NULL; | |
118 static GtkWidget *set_wgt; | |
119 static GtkWidget *get_wgt; | |
120 | |
121 /* init with DEFAULT_CFG to make sure all string pointers are set to NULL */ | |
122 static config_t _cfg = CONFIG_DEFAULT; | |
123 static config_t *cfg = &_cfg; | |
124 | |
125 /* some helpers to keep track of the GUI's state */ | |
126 static gboolean checking = FALSE; | |
127 static gint op_index; | |
128 static plugin_config_t op_config; | |
129 static gint ep_index; | |
130 | |
131 | |
132 static void update_plugin_config(gchar **config_string, gchar *name, | |
133 plugin_config_t *pc, gboolean save); | |
134 | |
135 /*****************************************************************************/ | |
136 | |
137 void g_free_f(gpointer data, gpointer user_data) | |
138 { | |
139 g_free(data); | |
140 } | |
141 | |
142 /*****************************************************************************/ | |
143 | |
144 #ifdef PRESET_SUPPORT | |
145 static void | |
146 scan_presets(gchar *filename) | |
147 { | |
148 struct stat stats; | |
149 FILE *fh; | |
150 gchar *data, **lines, *tmp, *name; | |
151 int i; | |
152 | |
153 if(lstat(filename, &stats)) { | |
154 DEBUG(("[crossfade] scan_presets: \"%s\":\n", filename)); | |
155 PERROR("[crossfade] scan_presets: lstat"); | |
156 return; | |
157 } | |
158 if(stats.st_size <= 0) return; | |
159 | |
160 if(!(data = g_malloc(stats.st_size + 1))) { | |
161 DEBUG(("[crossfade] scan_presets: g_malloc(%ld) failed!\n", stats.st_size)); | |
162 return; | |
163 } | |
164 | |
165 if(!(fh = fopen(filename, "r"))) { | |
166 PERROR("[crossfade] scan_presets: fopen"); | |
167 g_free(data); | |
168 return; | |
169 } | |
170 | |
171 if(fread(data, stats.st_size, 1, fh) != 1) { | |
172 DEBUG(("[crossfade] scan_presets: fread() failed!\n")); | |
173 g_free(data); | |
174 fclose(fh); | |
175 return; | |
176 } | |
177 fclose(fh); | |
178 data[stats.st_size] = 0; | |
179 | |
180 lines = g_strsplit(data, "\n", 0); | |
181 g_free(data); | |
182 | |
183 if(!lines) { | |
184 DEBUG(("[crossfade] scan_presets: g_strsplit() failed!\n")); | |
185 return; | |
186 } | |
187 | |
188 g_list_foreach(config->presets, g_free_f, NULL); | |
189 g_list_free(config->presets); | |
190 config->presets = NULL; | |
191 | |
192 for(i=0; lines[i]; i++) { | |
193 if(lines[i][0] == '[') { | |
194 if((tmp = strchr(lines[i], ']'))) { | |
195 *tmp = 0; | |
196 if((name = g_strdup(lines[i]+1))) | |
197 config->presets = g_list_append(config->presets, name); | |
198 } | |
199 } | |
200 } | |
201 | |
202 g_strfreev(lines); | |
203 } | |
204 #endif | |
205 | |
206 static void | |
207 read_fade_config(ConfigFile *cfgfile, gchar *section, gchar *key, fade_config_t *fc) | |
208 { | |
209 gchar *s = NULL; | |
210 gint n; | |
211 | |
212 if(!cfgfile || !section || !key || !fc) return; | |
213 | |
214 xmms_cfg_read_string(cfgfile, section, key, &s); | |
215 if(!s) return; | |
216 | |
217 n = sscanf(s, | |
218 "%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d", | |
219 &fc->type, | |
220 &fc->pause_len_ms, | |
221 &fc->simple_len_ms, | |
222 &fc->out_enable, | |
223 &fc->out_len_ms, | |
224 &fc->out_volume, | |
225 &fc->ofs_type, | |
226 &fc->ofs_type_wanted, | |
227 &fc->ofs_custom_ms, | |
228 &fc->in_locked, | |
229 &fc->in_enable, | |
230 &fc->in_len_ms, | |
231 &fc->in_volume, | |
232 &fc->flush_pause_enable, | |
233 &fc->flush_pause_len_ms, | |
234 &fc->flush_in_enable, | |
235 &fc->flush_in_len_ms, | |
236 &fc->flush_in_volume); | |
237 | |
238 g_free(s); | |
239 } | |
240 | |
241 static void | |
242 write_fade_config(ConfigFile *cfgfile, gchar *section, gchar *key, fade_config_t *fc) | |
243 { | |
244 gchar *s; | |
245 | |
246 if(!cfgfile || !section || !key || !fc) return; | |
247 | |
248 s = g_strdup_printf("%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d", | |
249 fc->type, | |
250 fc->pause_len_ms, | |
251 fc->simple_len_ms, | |
252 fc->out_enable, | |
253 fc->out_len_ms, | |
254 fc->out_volume, | |
255 fc->ofs_type, | |
256 fc->ofs_type_wanted, | |
257 fc->ofs_custom_ms, | |
258 fc->in_locked, | |
259 fc->in_enable, | |
260 fc->in_len_ms, | |
261 fc->in_volume, | |
262 fc->flush_pause_enable, | |
263 fc->flush_pause_len_ms, | |
264 fc->flush_in_enable, | |
265 fc->flush_in_len_ms, | |
266 fc->flush_in_volume); | |
267 | |
268 if(!s) return; | |
269 | |
270 xmms_cfg_write_string(cfgfile, section, key, s); | |
271 g_free(s); | |
272 } | |
273 | |
274 void | |
275 xfade_load_config() | |
276 { | |
277 #ifdef PRESET_SUPPORT | |
278 gchar *filename; | |
279 #endif | |
280 gchar *section = "Crossfade"; | |
281 ConfigFile *cfgfile; | |
282 | |
283 if((cfgfile = xmms_cfg_open_default_file())) { | |
284 /* config items used in v0.1 */ | |
285 xmms_cfg_read_int (cfgfile, section, "output_method", &config->output_method); | |
286 xmms_cfg_read_int (cfgfile, section, "audio_device", &config->oss_audio_device); | |
287 xmms_cfg_read_boolean(cfgfile, section, "use_alt_audio_device", &config->oss_use_alt_audio_device); | |
288 xmms_cfg_read_string (cfgfile, section, "alt_audio_device", &config->oss_alt_audio_device); | |
289 xmms_cfg_read_int (cfgfile, section, "mixer_device", &config->oss_mixer_device); | |
290 xmms_cfg_read_string (cfgfile, section, "output_plugin", &config->op_name); | |
291 xmms_cfg_read_string (cfgfile, section, "op_config_string", &config->op_config_string); | |
292 xmms_cfg_read_int (cfgfile, section, "buffer_size", &config->mix_size_ms); | |
293 xmms_cfg_read_int (cfgfile, section, "sync_size", &config->sync_size_ms); | |
294 xmms_cfg_read_int (cfgfile, section, "preload_size", &config->preload_size_ms); | |
295 xmms_cfg_read_int (cfgfile, section, "songchange_timeout", &config->songchange_timeout); | |
296 xmms_cfg_read_boolean(cfgfile, section, "enable_mixer", &config->enable_mixer); | |
297 xmms_cfg_read_boolean(cfgfile, section, "mixer_reverse", &config->mixer_reverse); | |
298 xmms_cfg_read_boolean(cfgfile, section, "enable_debug", &config->enable_debug); | |
299 xmms_cfg_read_boolean(cfgfile, section, "enable_monitor", &config->enable_monitor); | |
300 | |
301 /* config items introduced by v0.2 */ | |
302 xmms_cfg_read_int (cfgfile, section, "oss_buffer_size", &config->oss_buffer_size_ms); | |
303 xmms_cfg_read_int (cfgfile, section, "oss_preload_size", &config->oss_preload_size_ms); | |
304 xmms_cfg_read_boolean(cfgfile, section, "oss_mixer_use_master", &config->oss_mixer_use_master); | |
305 xmms_cfg_read_boolean(cfgfile, section, "gap_lead_enable", &config->gap_lead_enable); | |
306 xmms_cfg_read_int (cfgfile, section, "gap_lead_len_ms", &config->gap_lead_len_ms); | |
307 xmms_cfg_read_int (cfgfile, section, "gap_lead_level", &config->gap_lead_level); | |
308 xmms_cfg_read_boolean(cfgfile, section, "gap_trail_enable", &config->gap_trail_enable); | |
309 xmms_cfg_read_int (cfgfile, section, "gap_trail_len_ms", &config->gap_trail_len_ms); | |
310 xmms_cfg_read_int (cfgfile, section, "gap_trail_level", &config->gap_trail_level); | |
311 xmms_cfg_read_int (cfgfile, section, "gap_trail_locked", &config->gap_trail_locked); | |
312 | |
313 /* config items introduced by v0.2.1 */ | |
314 xmms_cfg_read_boolean(cfgfile, section, "buffer_size_auto", &config->mix_size_auto); | |
315 | |
316 /* config items introduced by v0.2.3 */ | |
317 xmms_cfg_read_boolean(cfgfile, section, "album_detection", &config->album_detection); | |
318 | |
319 /* config items introduced by v0.2.4 */ | |
320 xmms_cfg_read_boolean(cfgfile, section, "http_workaround", &config->enable_http_workaround); | |
321 xmms_cfg_read_boolean(cfgfile, section, "enable_op_max_used", &config->enable_op_max_used); | |
322 xmms_cfg_read_int (cfgfile, section, "op_max_used_ms", &config->op_max_used_ms); | |
323 | |
324 /* config items introduced by v0.2.6 */ | |
325 xmms_cfg_read_string (cfgfile, section, "effect_plugin", &config->ep_name); | |
326 xmms_cfg_read_boolean(cfgfile, section, "effect_enable", &config->ep_enable); | |
327 xmms_cfg_read_int (cfgfile, section, "output_rate", &config->output_rate); | |
328 | |
329 /* config items introduced by v0.2.7 */ | |
330 xmms_cfg_read_boolean(cfgfile, section, "oss_maxbuf_enable", &config->oss_maxbuf_enable); | |
331 | |
332 /* config items introduced by v0.3.0 */ | |
333 xmms_cfg_read_boolean(cfgfile, section, "use_alt_mixer_device", &config->oss_use_alt_mixer_device); | |
334 xmms_cfg_read_int (cfgfile, section, "oss_fragments", &config->oss_fragments); | |
335 xmms_cfg_read_int (cfgfile, section, "oss_fragment_size", &config->oss_fragment_size); | |
336 xmms_cfg_read_boolean(cfgfile, section, "volnorm_enable", &config->volnorm_enable); | |
337 xmms_cfg_read_boolean(cfgfile, section, "volnorm_use_qa", &config->volnorm_use_qa); | |
338 xmms_cfg_read_int (cfgfile, section, "volnorm_target", &config->volnorm_target); | |
339 xmms_cfg_read_boolean(cfgfile, section, "output_keep_opened", &config->output_keep_opened); | |
340 xmms_cfg_read_boolean(cfgfile, section, "mixer_software", &config->mixer_software); | |
341 xmms_cfg_read_int (cfgfile, section, "mixer_vol_left", &config->mixer_vol_left); | |
342 xmms_cfg_read_int (cfgfile, section, "mixer_vol_right", &config->mixer_vol_right); | |
343 | |
344 /* config items introduced by v0.3.2 */ | |
345 xmms_cfg_read_boolean(cfgfile, section, "no_xfade_if_same_file",&config->no_xfade_if_same_file); | |
346 | |
347 /* config items introduced by v0.3.3 */ | |
348 xmms_cfg_read_string (cfgfile, section, "alt_mixer_device", &config->oss_alt_mixer_device); | |
349 xmms_cfg_read_boolean(cfgfile, section, "gap_crossing", &config->gap_crossing); | |
350 | |
351 /* config items introduced by v0.3.6 */ | |
352 xmms_cfg_read_int (cfgfile, section, "output_quality", &config->output_quality); | |
353 | |
354 /* fade configs */ | |
355 read_fade_config(cfgfile, section, "fc_xfade", &config->fc[FADE_CONFIG_XFADE]); | |
356 read_fade_config(cfgfile, section, "fc_manual", &config->fc[FADE_CONFIG_MANUAL]); | |
357 read_fade_config(cfgfile, section, "fc_album", &config->fc[FADE_CONFIG_ALBUM]); | |
358 read_fade_config(cfgfile, section, "fc_start", &config->fc[FADE_CONFIG_START]); | |
359 read_fade_config(cfgfile, section, "fc_stop", &config->fc[FADE_CONFIG_STOP]); | |
360 read_fade_config(cfgfile, section, "fc_eop", &config->fc[FADE_CONFIG_EOP]); | |
361 read_fade_config(cfgfile, section, "fc_seek", &config->fc[FADE_CONFIG_SEEK]); | |
362 read_fade_config(cfgfile, section, "fc_pause", &config->fc[FADE_CONFIG_PAUSE]); | |
363 | |
364 xmms_cfg_free(cfgfile); | |
365 DEBUG(("[crossfade] load_config: configuration loaded\n")); | |
366 } | |
367 else | |
368 DEBUG(("[crossfade] load_config: error loading config, using defaults\n")); | |
369 | |
370 #ifdef PRESET_SUPPORT | |
371 filename = g_strconcat(g_get_home_dir(), "/.xmms/xmms-crossfade-presets", NULL); | |
372 scan_presets(filename); | |
373 g_free(filename); | |
374 #endif | |
375 } | |
376 | |
377 void | |
378 xfade_save_config() | |
379 { | |
380 gchar *section = "Crossfade"; | |
381 ConfigFile *cfgfile; | |
382 | |
383 if((cfgfile = xmms_cfg_open_default_file())) { | |
384 /* obsolete config items */ | |
385 xmms_cfg_remove_key(cfgfile, section, "underrun_pct"); | |
386 xmms_cfg_remove_key(cfgfile, section, "enable_crossfade"); | |
387 xmms_cfg_remove_key(cfgfile, section, "enable_gapkiller"); | |
388 xmms_cfg_remove_key(cfgfile, section, "mixer_use_master"); | |
389 xmms_cfg_remove_key(cfgfile, section, "late_effect"); | |
390 xmms_cfg_remove_key(cfgfile, section, "gap_lead_length"); | |
391 | |
392 /* config items used in v0.1 */ | |
393 xmms_cfg_write_int (cfgfile, section, "output_method", config->output_method); | |
394 xmms_cfg_write_int (cfgfile, section, "audio_device", config->oss_audio_device); | |
395 xmms_cfg_write_boolean(cfgfile, section, "use_alt_audio_device", config->oss_use_alt_audio_device); | |
396 xmms_cfg_write_string (cfgfile, section, "alt_audio_device", config->oss_alt_audio_device ? config->oss_alt_audio_device : DEFAULT_OSS_ALT_AUDIO_DEVICE); | |
397 xmms_cfg_write_int (cfgfile, section, "mixer_device", config->oss_mixer_device); | |
398 xmms_cfg_write_string (cfgfile, section, "output_plugin", config->op_name ? config->op_name : DEFAULT_OP_NAME); | |
399 xmms_cfg_write_string (cfgfile, section, "op_config_string", config->op_config_string ? config->op_config_string : DEFAULT_OP_CONFIG_STRING); | |
400 xmms_cfg_write_int (cfgfile, section, "buffer_size", config->mix_size_ms); | |
401 xmms_cfg_write_int (cfgfile, section, "sync_size", config->sync_size_ms); | |
402 xmms_cfg_write_int (cfgfile, section, "preload_size", config->preload_size_ms); | |
403 xmms_cfg_write_int (cfgfile, section, "songchange_timeout", config->songchange_timeout); | |
404 xmms_cfg_write_boolean(cfgfile, section, "enable_mixer", config->enable_mixer); | |
405 xmms_cfg_write_boolean(cfgfile, section, "mixer_reverse", config->mixer_reverse); | |
406 xmms_cfg_write_boolean(cfgfile, section, "enable_debug", config->enable_debug); | |
407 xmms_cfg_write_boolean(cfgfile, section, "enable_monitor", config->enable_monitor); | |
408 | |
409 /* config items introduced by v0.2 */ | |
410 xmms_cfg_write_int (cfgfile, section, "oss_buffer_size", config->oss_buffer_size_ms); | |
411 xmms_cfg_write_int (cfgfile, section, "oss_preload_size", config->oss_preload_size_ms); | |
412 xmms_cfg_write_boolean(cfgfile, section, "oss_mixer_use_master", config->oss_mixer_use_master); | |
413 xmms_cfg_write_boolean(cfgfile, section, "gap_lead_enable", config->gap_lead_enable); | |
414 xmms_cfg_write_int (cfgfile, section, "gap_lead_len_ms", config->gap_lead_len_ms); | |
415 xmms_cfg_write_int (cfgfile, section, "gap_lead_level", config->gap_lead_level); | |
416 xmms_cfg_write_boolean(cfgfile, section, "gap_trail_enable", config->gap_trail_enable); | |
417 xmms_cfg_write_int (cfgfile, section, "gap_trail_len_ms", config->gap_trail_len_ms); | |
418 xmms_cfg_write_int (cfgfile, section, "gap_trail_level", config->gap_trail_level); | |
419 xmms_cfg_write_int (cfgfile, section, "gap_trail_locked", config->gap_trail_locked); | |
420 | |
421 /* config items introduced by v0.2.1 */ | |
422 xmms_cfg_write_boolean(cfgfile, section, "buffer_size_auto", config->mix_size_auto); | |
423 | |
424 /* config items introduced by v0.2.3 */ | |
425 xmms_cfg_write_boolean(cfgfile, section, "album_detection", config->album_detection); | |
426 | |
427 /* config items introduced by v0.2.4 */ | |
428 xmms_cfg_write_boolean(cfgfile, section, "http_workaround", config->enable_http_workaround); | |
429 xmms_cfg_write_boolean(cfgfile, section, "enable_op_max_used", config->enable_op_max_used); | |
430 xmms_cfg_write_int (cfgfile, section, "op_max_used_ms", config->op_max_used_ms); | |
431 | |
432 /* config items introduced by v0.2.6 */ | |
433 xmms_cfg_write_string (cfgfile, section, "effect_plugin", config->ep_name ? config->ep_name : DEFAULT_EP_NAME); | |
434 xmms_cfg_write_boolean(cfgfile, section, "effect_enable", config->ep_enable); | |
435 xmms_cfg_write_int (cfgfile, section, "output_rate", config->output_rate); | |
436 | |
437 /* config items introduced by v0.2.7 */ | |
438 xmms_cfg_write_boolean(cfgfile, section, "oss_maxbuf_enable", config->oss_maxbuf_enable); | |
439 | |
440 /* config items introduced by v0.3.0 */ | |
441 xmms_cfg_write_boolean(cfgfile, section, "use_alt_mixer_device", config->oss_use_alt_mixer_device); | |
442 xmms_cfg_write_int (cfgfile, section, "oss_fragments", config->oss_fragments); | |
443 xmms_cfg_write_int (cfgfile, section, "oss_fragment_size", config->oss_fragment_size); | |
444 #ifdef VOLUME_NORMALIZER | |
445 xmms_cfg_write_boolean(cfgfile, section, "volnorm_enable", config->volnorm_enable); | |
446 xmms_cfg_write_boolean(cfgfile, section, "volnorm_use_qa", config->volnorm_use_qa); | |
447 xmms_cfg_write_int (cfgfile, section, "volnorm_target", config->volnorm_target); | |
448 #endif | |
449 xmms_cfg_write_boolean(cfgfile, section, "output_keep_opened", config->output_keep_opened); | |
450 xmms_cfg_write_boolean(cfgfile, section, "mixer_software", config->mixer_software); | |
451 xmms_cfg_write_int (cfgfile, section, "mixer_vol_left", config->mixer_vol_left); | |
452 xmms_cfg_write_int (cfgfile, section, "mixer_vol_right", config->mixer_vol_right); | |
453 | |
454 /* config items introduced by v0.3.2 */ | |
455 xmms_cfg_write_boolean(cfgfile, section, "no_xfade_if_same_file",config->no_xfade_if_same_file); | |
456 | |
457 /* config items introduced by v0.3.2 */ | |
458 xmms_cfg_write_string (cfgfile, section, "alt_mixer_device", config->oss_alt_mixer_device ? config->oss_alt_mixer_device : DEFAULT_OSS_ALT_MIXER_DEVICE); | |
459 xmms_cfg_write_boolean(cfgfile, section, "gap_crossing", config->gap_crossing); | |
460 | |
461 /* config items introduced by v0.3.6 */ | |
462 xmms_cfg_write_int (cfgfile, section, "output_quality", config->output_quality); | |
463 | |
464 /* fade configs */ | |
465 write_fade_config(cfgfile, section, "fc_xfade", &config->fc[FADE_CONFIG_XFADE]); | |
466 write_fade_config(cfgfile, section, "fc_manual", &config->fc[FADE_CONFIG_MANUAL]); | |
467 write_fade_config(cfgfile, section, "fc_album", &config->fc[FADE_CONFIG_ALBUM]); | |
468 write_fade_config(cfgfile, section, "fc_start", &config->fc[FADE_CONFIG_START]); | |
469 write_fade_config(cfgfile, section, "fc_stop", &config->fc[FADE_CONFIG_STOP]); | |
470 write_fade_config(cfgfile, section, "fc_eop", &config->fc[FADE_CONFIG_EOP]); | |
471 write_fade_config(cfgfile, section, "fc_seek", &config->fc[FADE_CONFIG_SEEK]); | |
472 write_fade_config(cfgfile, section, "fc_pause", &config->fc[FADE_CONFIG_PAUSE]); | |
473 | |
474 xmms_cfg_write_default_file(cfgfile); | |
475 xmms_cfg_free (cfgfile); | |
476 DEBUG(("[crossfade] save_config: configuration saved\n")); | |
477 } | |
478 else | |
479 DEBUG(("[crossfade] save_config: error saving configuration!\n")); | |
480 } | |
481 | |
482 #define SAFE_FREE(x) if(x) { g_free(x); x = NULL; } | |
483 void | |
484 xfade_free_config() | |
485 { | |
486 SAFE_FREE(cfg->oss_alt_audio_device); | |
487 SAFE_FREE(cfg->oss_alt_mixer_device); | |
488 SAFE_FREE(cfg->op_config_string); | |
489 SAFE_FREE(cfg->op_name); | |
490 | |
491 g_list_foreach(config->presets, g_free_f, NULL); | |
492 g_list_free(config->presets); | |
493 config->presets = NULL; | |
494 } | |
495 | |
496 void | |
497 xfade_load_plugin_config(gchar *config_string, | |
498 gchar *plugin_name, | |
499 plugin_config_t *plugin_config) | |
500 { | |
501 update_plugin_config(&config_string, plugin_name, plugin_config, FALSE); | |
502 } | |
503 | |
504 void | |
505 xfade_save_plugin_config(gchar **config_string, | |
506 gchar *plugin_name, | |
507 plugin_config_t *plugin_config) | |
508 { | |
509 update_plugin_config(config_string, plugin_name, plugin_config, TRUE); | |
510 } | |
511 | |
512 /*** helpers *****************************************************************/ | |
513 | |
514 gint | |
515 xfade_cfg_fadeout_len(fade_config_t *fc) | |
516 { | |
517 if(!fc) return 0; | |
518 switch(fc->type) { | |
519 case FADE_TYPE_SIMPLE_XF: | |
520 return fc->simple_len_ms; | |
521 case FADE_TYPE_ADVANCED_XF: | |
522 return fc->out_enable ? fc->out_len_ms : 0; | |
523 case FADE_TYPE_FADEOUT: | |
524 case FADE_TYPE_PAUSE_ADV: | |
525 return fc->out_len_ms; | |
526 } | |
527 return 0; | |
528 } | |
529 | |
530 gint | |
531 xfade_cfg_fadeout_volume(fade_config_t *fc) | |
532 { | |
533 gint volume; | |
534 if(!fc) return 0; | |
535 switch(fc->type) { | |
536 case FADE_TYPE_ADVANCED_XF: | |
537 case FADE_TYPE_FADEOUT: | |
538 volume = fc->out_volume; | |
539 if(volume < 0) volume = 0; | |
540 if(volume > 100) volume = 100; | |
541 return volume; | |
542 } | |
543 return 0; | |
544 } | |
545 | |
546 gint | |
547 xfade_cfg_offset(fade_config_t *fc) | |
548 { | |
549 if(!fc) return 0; | |
550 switch(fc->type) { | |
551 case FADE_TYPE_FLUSH: | |
552 return fc->flush_pause_enable ? fc->flush_pause_len_ms : 0; | |
553 case FADE_TYPE_PAUSE: | |
554 return fc->pause_len_ms; | |
555 case FADE_TYPE_SIMPLE_XF: | |
556 return -fc->simple_len_ms; | |
557 case FADE_TYPE_ADVANCED_XF: | |
558 switch(fc->ofs_type) { | |
559 case FC_OFFSET_LOCK_OUT: | |
560 return -fc->out_len_ms; | |
561 case FC_OFFSET_LOCK_IN: | |
562 return -fc->in_len_ms; | |
563 case FC_OFFSET_CUSTOM: | |
564 return fc->ofs_custom_ms; | |
565 } | |
566 return 0; | |
567 case FADE_TYPE_FADEOUT: | |
568 case FADE_TYPE_PAUSE_ADV: | |
569 return fc->ofs_custom_ms; | |
570 } | |
571 return 0; | |
572 } | |
573 | |
574 gint | |
575 xfade_cfg_fadein_len(fade_config_t *fc) | |
576 { | |
577 if(!fc) return 0; | |
578 switch(fc->type) { | |
579 case FADE_TYPE_FLUSH: | |
580 return fc->flush_in_enable ? fc->flush_in_len_ms : 0; | |
581 case FADE_TYPE_SIMPLE_XF: | |
582 return fc->simple_len_ms; | |
583 case FADE_TYPE_ADVANCED_XF: | |
584 return | |
585 fc->in_locked | |
586 ? (fc->out_enable ? fc->out_len_ms : 0) | |
587 : (fc->in_enable ? fc->in_len_ms : 0); | |
588 case FADE_TYPE_FADEIN: | |
589 case FADE_TYPE_PAUSE_ADV: | |
590 return fc->in_len_ms; | |
591 } | |
592 return 0; | |
593 } | |
594 | |
595 gint | |
596 xfade_cfg_fadein_volume(fade_config_t *fc) | |
597 { | |
598 gint volume; | |
599 if(!fc) return 0; | |
600 switch(fc->type) { | |
601 case FADE_TYPE_FLUSH: | |
602 volume = fc->flush_in_volume; | |
603 break; | |
604 case FADE_TYPE_ADVANCED_XF: | |
605 volume = fc->in_locked ? fc->out_volume : fc->in_volume; | |
606 break; | |
607 case FADE_TYPE_FADEIN: | |
608 volume = fc->in_volume; | |
609 break; | |
610 default: | |
611 volume = 0; | |
612 } | |
613 if(volume < 0) volume = 0; | |
614 if(volume > 100) volume = 100; | |
615 return volume; | |
616 } | |
617 | |
618 gboolean | |
619 xfade_cfg_gap_trail_enable(config_t *cfg) | |
620 { | |
621 return cfg->gap_trail_locked | |
622 ? cfg->gap_lead_enable | |
623 : cfg->gap_trail_enable; | |
624 } | |
625 | |
626 gint | |
627 xfade_cfg_gap_trail_len(config_t *cfg) | |
628 { | |
629 if(!xfade_cfg_gap_trail_enable(cfg)) return 0; | |
630 return cfg->gap_trail_locked | |
631 ? cfg->gap_lead_len_ms | |
632 : cfg->gap_trail_len_ms; | |
633 } | |
634 | |
635 gint | |
636 xfade_cfg_gap_trail_level(config_t *cfg) | |
637 { | |
638 return cfg->gap_trail_locked | |
639 ? cfg->gap_lead_level | |
640 : cfg->gap_trail_level; | |
641 } | |
642 | |
643 gint | |
644 xfade_mix_size_ms(config_t *cfg) | |
645 { | |
646 if(cfg->mix_size_auto) { | |
647 gint i, min_size = 0; | |
648 | |
649 for(i=0; i<MAX_FADE_CONFIGS; i++) { | |
650 gint size = xfade_cfg_fadeout_len(&cfg->fc[i]); | |
651 gint offset = xfade_cfg_offset(&cfg->fc[i]); | |
652 | |
653 if(cfg->fc[i].type == FADE_TYPE_PAUSE_ADV) | |
654 size += xfade_cfg_fadein_len(&cfg->fc[i]); | |
655 | |
656 if(size < -offset) | |
657 size = -offset; | |
658 | |
659 if(size > min_size) | |
660 min_size = size; | |
661 } | |
662 return min_size += xfade_cfg_gap_trail_len(cfg) | |
663 + cfg->songchange_timeout; | |
664 } | |
665 else | |
666 return cfg->mix_size_ms; | |
667 } | |
668 | |
669 /*** internal helpers ********************************************************/ | |
670 | |
671 static void | |
672 add_menu_item(GtkWidget *menu, gchar *title, GtkSignalFunc func, gint index, gint **imap) | |
673 { | |
674 GtkWidget *item; | |
675 if(!menu || !title || !func) return; | |
676 item = gtk_menu_item_new_with_label(title); | |
677 gtk_signal_connect(GTK_OBJECT(item), "activate", GTK_SIGNAL_FUNC(func), (gpointer)index); | |
678 gtk_widget_show(item); | |
679 gtk_menu_append(GTK_MENU(menu), item); | |
680 | |
681 if(imap) *((*imap)++) = index; | |
682 } | |
683 | |
684 /*** output method ***********************************************************/ | |
685 | |
686 /*-- callbacks --------------------------------------------------------------*/ | |
687 | |
688 void on_output_oss_radio_toggled(GtkToggleButton *togglebutton, gpointer user_data) | |
689 { | |
690 SET_PAGE("output_notebook", 0); | |
691 cfg->output_method = OUTPUT_METHOD_BUILTIN_OSS; | |
692 } | |
693 | |
694 void on_output_plugin_radio_toggled(GtkToggleButton *togglebutton, gpointer user_data) | |
695 { | |
696 SET_PAGE("output_notebook", 1); | |
697 cfg->output_method = OUTPUT_METHOD_PLUGIN; | |
698 } | |
699 | |
700 void on_output_none_radio_toggled(GtkToggleButton *togglebutton, gpointer user_data) | |
701 { | |
702 SET_PAGE("output_notebook", 2); | |
703 cfg->output_method = OUTPUT_METHOD_BUILTIN_NULL; | |
704 } | |
705 | |
706 static void resampling_rate_cb(GtkWidget *widget, gint index) | |
707 { | |
708 cfg->output_rate = index; | |
709 } | |
710 | |
711 #ifdef HAVE_LIBSAMPLERATE | |
712 static void resampling_quality_cb(GtkWidget *widget, gint index) | |
713 { | |
714 cfg->output_quality = index; | |
715 } | |
716 #endif | |
717 | |
718 /*** oss output **************************************************************/ | |
719 | |
720 static void | |
721 scan_devices(gchar *type, GtkWidget *option_menu, GtkSignalFunc signal_f) | |
722 { | |
723 #ifdef HAVE_OSS | |
724 gchar buffer[256]; | |
725 FILE *file; | |
726 | |
727 GtkWidget *item; | |
728 gboolean found = FALSE; | |
729 gint type_len = strlen(type); | |
730 #endif | |
731 | |
732 GtkWidget *menu; | |
733 gint index = 0; | |
734 gint mixer = 0; | |
735 | |
736 menu = gtk_menu_new(); | |
737 | |
738 #ifdef HAVE_OSS | |
739 /* look for devices in /dev/sndstat or /proc/asound/sndstat (OSS style) */ | |
740 if((file = fopen("/dev/sndstat", "r")) || | |
741 (file = fopen("/proc/asound/sndstat", "r")) || | |
742 (file = fopen("/proc/asound/oss/sndstat", "r"))) { | |
743 while(fgets(buffer, sizeof(buffer), file)) { | |
744 gint i = strlen(buffer)-1; | |
745 while((i >= 0) && isspace(buffer[i])) buffer[i--] = 0; | |
746 if(found) { | |
747 if(!buffer[0] || !isdigit(buffer[0])) break; | |
748 if(index == 0) { | |
749 gchar *label, *p = strchr(buffer, ':'); | |
750 if(p) do p++; while(*p == ' '); | |
751 else p = buffer; | |
752 label = g_strdup_printf("Default (%s)", p); | |
753 item = gtk_menu_item_new_with_label(label); | |
754 g_free(label); | |
755 } | |
756 else item = gtk_menu_item_new_with_label(buffer); | |
757 | |
758 gtk_signal_connect(GTK_OBJECT(item), "activate", GTK_SIGNAL_FUNC(signal_f), | |
759 (gpointer)index); | |
760 gtk_widget_show(item); | |
761 gtk_menu_append(GTK_MENU(menu), item); | |
762 index++; | |
763 } | |
764 else if(!strcmp(buffer, type)) | |
765 found = TRUE; | |
766 else if(!strncmp(buffer, type, type_len)) | |
767 DEBUG(("[crossfade] scan_devices: %s\n", buffer)); | |
768 } | |
769 fclose(file); | |
770 | |
771 if(!found) | |
772 DEBUG(("[crossfade] scan_devices: section \"%s\" not found!\n", type)); | |
773 } | |
774 else { | |
775 DEBUG(("[crossfade] scan_devices: no sndstat found!\n")); | |
776 #ifdef SOUND_MIXER_INFO | |
777 /* from xmms-3dse7 by Frank Cornelis */ | |
778 DEBUG(("[crossfade] scan_devices: using alternate method...\n")); | |
779 for(;;) { | |
780 gchar dev_name[32]; | |
781 int fd; | |
782 mixer_info info; | |
783 gchar *label; | |
784 | |
785 if(mixer != 0) | |
786 sprintf(dev_name, "/dev/mixer%d", mixer); | |
787 else | |
788 strcpy(dev_name, "/dev/mixer"); | |
789 | |
790 if((fd = open(dev_name, O_RDONLY)) != -1) { | |
791 if(ioctl(fd, SOUND_MIXER_INFO, &info) != -1) { | |
792 label = g_strdup_printf(index ? "%s" : "Default (%s)", info.name); | |
793 add_menu_item(menu, label, signal_f, index, NULL); | |
794 g_free(label); | |
795 index++; | |
796 } | |
797 close(fd); | |
798 } | |
799 else break; | |
800 mixer++; | |
801 } | |
802 #endif | |
803 } | |
804 #endif /* HAVE_OSS */ | |
805 | |
806 /* create default entry if no device(s) could be found */ | |
807 if(index == 0) add_menu_item(menu, "Default", signal_f, 0, NULL); | |
808 | |
809 /* attach menu */ | |
810 gtk_option_menu_set_menu(GTK_OPTION_MENU(option_menu), menu); | |
811 } | |
812 | |
813 /*-- oss output callbacks ---------------------------------------------------*/ | |
814 | |
815 void check_oss_dependencies() | |
816 { | |
817 if(checking) return; | |
818 checking = TRUE; | |
819 | |
820 SET_SENSITIVE("oss_adevice_optionmenu", !cfg->oss_use_alt_audio_device); | |
821 SET_SENSITIVE("oss_adevice_alt_entry", cfg->oss_use_alt_audio_device); | |
822 | |
823 SET_SENSITIVE("oss_mdevice_optionmenu", !cfg->oss_use_alt_mixer_device); | |
824 SET_SENSITIVE("oss_mdevice_alt_entry", cfg->oss_use_alt_mixer_device); | |
825 | |
826 SET_SENSITIVE("osshwb_fragments_label", !cfg->oss_maxbuf_enable); | |
827 SET_SENSITIVE("osshwb_fragments_spin", !cfg->oss_maxbuf_enable); | |
828 SET_SENSITIVE("osshwb_fragsize_label", !cfg->oss_maxbuf_enable); | |
829 SET_SENSITIVE("osshwb_fragsize_spin", !cfg->oss_maxbuf_enable); | |
830 | |
831 checking = FALSE; | |
832 } | |
833 | |
834 void config_adevice_cb(GtkWidget *widget, gint device) | |
835 { | |
836 cfg->oss_audio_device = device; | |
837 } | |
838 | |
839 void config_mdevice_cb(GtkWidget *widget, gint device) | |
840 { | |
841 cfg->oss_mixer_device = device; | |
842 } | |
843 | |
844 void on_config_adevice_alt_check_toggled(GtkToggleButton *togglebutton, gpointer user_data) | |
845 { | |
846 if(checking) return; | |
847 cfg->oss_use_alt_audio_device = gtk_toggle_button_get_active(togglebutton); | |
848 check_oss_dependencies(); | |
849 } | |
850 | |
851 void on_config_mdevice_alt_check_toggled(GtkToggleButton *togglebutton, gpointer user_data) | |
852 { | |
853 if(checking) return; | |
854 cfg->oss_use_alt_mixer_device = gtk_toggle_button_get_active(togglebutton); | |
855 check_oss_dependencies(); | |
856 } | |
857 | |
858 void on_osshwb_maxbuf_check_toggled(GtkToggleButton *togglebutton, gpointer user_data) | |
859 { | |
860 if(checking) return; | |
861 cfg->oss_maxbuf_enable = gtk_toggle_button_get_active(togglebutton); | |
862 check_oss_dependencies(); | |
863 } | |
864 | |
865 /*** plugin output ***********************************************************/ | |
866 | |
867 static gchar * | |
868 strip(gchar *s) | |
869 { | |
870 gchar *p; | |
871 if(!s) return NULL; | |
872 for(; *s == ' '; s++); | |
873 if(!*s) return s; | |
874 for(p = s+strlen(s)-1; *p == ' '; p--); | |
875 *++p = 0; | |
876 return s; | |
877 } | |
878 | |
879 static void | |
880 update_plugin_config(gchar **config_string, gchar *name, | |
881 plugin_config_t *pc, gboolean save) | |
882 { | |
883 plugin_config_t default_pc = DEFAULT_OP_CONFIG; | |
884 | |
885 gchar *buffer = NULL; | |
886 gchar out[1024]; | |
887 | |
888 gboolean plugin_found = FALSE; | |
889 gchar *plugin, *next_plugin; | |
890 gchar *args; | |
891 | |
892 if(pc && !save) *pc = default_pc; | |
893 if(!config_string || !*config_string || !name || !pc) { | |
894 DEBUG(("[crossfade] update_plugin_config: missing arg!\n")); | |
895 return; | |
896 } | |
897 | |
898 buffer = g_strdup(*config_string); | |
899 out[0] = 0; | |
900 | |
901 for(plugin = buffer; plugin; plugin = next_plugin) { | |
902 if((next_plugin = strchr(plugin, ';'))) *next_plugin++ = 0; | |
903 if((args = strchr(plugin, '='))) *args++ = 0; | |
904 plugin = strip(plugin); | |
905 if(!*plugin || !args || !*args) continue; | |
906 | |
907 if(save) { | |
908 if(0 == strcmp(plugin, name)) continue; | |
909 if(*out) strcat(out, "; "); | |
910 strcat(out, plugin); | |
911 strcat(out, "="); | |
912 strcat(out, args); | |
913 continue; | |
914 } | |
915 else if(strcmp(plugin, name)) continue; | |
916 | |
917 args = strip(args); | |
918 sscanf(args, "%d,%d,%d,%d", | |
919 &pc->throttle_enable, | |
920 &pc->max_write_enable, | |
921 &pc->max_write_len, | |
922 &pc->force_reopen); | |
923 pc->max_write_len &= -4; | |
924 plugin_found = TRUE; | |
925 } | |
926 | |
927 if(save) { | |
928 /* only save if settings differ from defaults */ | |
929 if(( pc->throttle_enable != default_pc.throttle_enable) | |
930 ||(pc->max_write_enable != default_pc.max_write_enable) | |
931 ||(pc->max_write_len != default_pc.max_write_len) | |
932 ||(pc->force_reopen != default_pc.force_reopen)) { | |
933 if(*out) strcat(out, "; "); | |
934 sprintf(out + strlen(out), "%s=%d,%d,%d,%d", name, | |
935 pc->throttle_enable ? 1 : 0, | |
936 pc->max_write_enable ? 1 : 0, | |
937 pc->max_write_len, | |
938 pc->force_reopen); | |
939 } | |
940 if(*config_string) g_free(*config_string); | |
941 *config_string = g_strdup(out); | |
942 } | |
943 | |
944 g_free(buffer); | |
945 } | |
946 | |
947 static void | |
948 config_plugin_cb(GtkWidget *widget, gint index); | |
949 | |
950 static gint | |
951 scan_plugins(GtkWidget *option_menu, gchar *selected) | |
952 { | |
953 GtkWidget *menu = gtk_menu_new(); | |
954 GList *list = g_list_first(get_output_list()); /* XMMS */ | |
955 gint index = 0; | |
956 gint sel_index = -1; | |
957 gint def_index = -1; | |
958 | |
959 /* sanity check */ | |
960 if(selected == NULL) selected = ""; | |
961 | |
962 /* parse module list */ | |
963 while(list) { | |
964 OutputPlugin *op = (OutputPlugin *)list->data; | |
965 GtkWidget *item = gtk_menu_item_new_with_label(op->description); | |
966 | |
967 if(op == get_crossfade_oplugin_info()) /* disable selecting ourselves */ | |
968 gtk_widget_set_sensitive(item, FALSE); | |
969 else { | |
970 if(def_index == -1) def_index = index; | |
971 if(selected && !strcmp(g_basename(op->filename), selected)) | |
972 sel_index = index; | |
973 } | |
974 | |
975 /* create menu item */ | |
976 gtk_signal_connect(GTK_OBJECT(item), "activate", | |
977 GTK_SIGNAL_FUNC(config_plugin_cb), (gpointer)index++); | |
978 gtk_widget_show(item); | |
979 gtk_menu_append(GTK_MENU(menu), item); | |
980 | |
981 /* advance to next module */ | |
982 list = g_list_next(list); | |
983 } | |
984 | |
985 /* attach menu */ | |
986 gtk_option_menu_set_menu(GTK_OPTION_MENU(option_menu), menu); | |
987 | |
988 if(sel_index == -1) { | |
989 DEBUG(("[crossfade] scan_plugins: plugin not found (\"%s\")\n", selected)); | |
990 return def_index; /* use default (first entry) */ | |
991 } | |
992 return sel_index; | |
993 } | |
994 | |
995 /*-- plugin output callbacks ------------------------------------------------*/ | |
996 | |
997 static void | |
998 config_plugin_cb(GtkWidget *widget, gint index) | |
999 { | |
1000 OutputPlugin *op = g_list_nth_data(get_output_list(), index); /* XMMS */ | |
1001 | |
1002 /* get plugin options from gui */ | |
1003 op_config.throttle_enable = GET_TOGGLE("op_throttle_check"); | |
1004 op_config.max_write_enable = GET_TOGGLE("op_maxblock_check"); | |
1005 op_config.max_write_len = GET_SPIN ("op_maxblock_spin"); | |
1006 op_config.force_reopen = GET_TOGGLE("op_forcereopen_check"); | |
1007 | |
1008 /* config -> string */ | |
1009 xfade_save_plugin_config(&cfg->op_config_string, cfg->op_name, &op_config); | |
1010 | |
1011 /* select new plugin */ | |
1012 op_index = index; | |
1013 | |
1014 /* get new plugin's name */ | |
1015 if(cfg->op_name) g_free(cfg->op_name); | |
1016 cfg->op_name = (op && op->filename) | |
1017 ? g_strdup(g_basename(op->filename)) : NULL; | |
1018 | |
1019 /* string -> config */ | |
1020 xfade_load_plugin_config(cfg->op_config_string, cfg->op_name, &op_config); | |
1021 | |
1022 /* update gui */ | |
1023 SET_SENSITIVE("op_configure_button", op && (op->configure != NULL)); | |
1024 SET_SENSITIVE("op_about_button", op && (op->about != NULL)); | |
1025 SET_TOGGLE ("op_throttle_check", op_config.throttle_enable); | |
1026 SET_TOGGLE ("op_maxblock_check", op_config.max_write_enable); | |
1027 SET_SPIN ("op_maxblock_spin", op_config.max_write_len); | |
1028 SET_SENSITIVE("op_maxblock_spin", op_config.max_write_enable); | |
1029 SET_TOGGLE ("op_forcereopen_check", op_config.force_reopen); | |
1030 } | |
1031 | |
1032 void on_output_plugin_configure_button_clicked (GtkButton *button, gpointer user_data) | |
1033 { | |
1034 OutputPlugin *op = g_list_nth_data(get_output_list(), op_index); /* XMMS */ | |
1035 if((op == NULL) || (op->configure == NULL)) return; | |
1036 op->configure(); | |
1037 } | |
1038 | |
1039 void on_output_plugin_about_button_clicked(GtkButton *button, gpointer user_data) | |
1040 { | |
1041 OutputPlugin *op = g_list_nth_data(get_output_list(), op_index); /* XMMS */ | |
1042 if((op == NULL) || (op->about == NULL)) return; | |
1043 op->about(); | |
1044 } | |
1045 | |
1046 void on_op_throttle_check_toggled(GtkToggleButton *togglebutton, gpointer user_data) | |
1047 { | |
1048 op_config.throttle_enable = gtk_toggle_button_get_active(togglebutton); | |
1049 } | |
1050 | |
1051 void on_op_maxblock_check_toggled(GtkToggleButton *togglebutton, gpointer user_data) | |
1052 { | |
1053 op_config.max_write_enable = gtk_toggle_button_get_active(togglebutton); | |
1054 SET_SENSITIVE("op_maxblock_spin", op_config.max_write_enable); | |
1055 } | |
1056 | |
1057 void on_op_maxblock_spin_changed(GtkEditable *editable, gpointer user_data) | |
1058 { | |
1059 op_config.max_write_len = gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(editable)); | |
1060 } | |
1061 | |
1062 void on_op_forcereopen_check_toggled(GtkToggleButton *togglebutton, gpointer user_data) | |
1063 { | |
1064 op_config.max_write_enable = gtk_toggle_button_get_active(togglebutton); | |
1065 } | |
1066 | |
1067 /*** effects *****************************************************************/ | |
1068 | |
1069 static void | |
1070 config_effect_plugin_cb(GtkWidget *widget, gint index); | |
1071 | |
1072 static gint | |
1073 scan_effect_plugins(GtkWidget *option_menu, gchar *selected) | |
1074 { | |
1075 GtkWidget *menu = gtk_menu_new(); | |
1076 GList *list = g_list_first(get_effect_list()); /* XMMS */ | |
1077 gint index = 0; | |
1078 gint sel_index = -1; | |
1079 gint def_index = -1; | |
1080 | |
1081 /* sanity check */ | |
1082 if(selected == NULL) selected = ""; | |
1083 | |
1084 /* parse module list */ | |
1085 while(list) { | |
1086 EffectPlugin *ep = (EffectPlugin *)list->data; | |
1087 GtkWidget *item = gtk_menu_item_new_with_label(ep->description); | |
1088 | |
1089 if(def_index == -1) def_index = index; | |
1090 if(selected && !strcmp(g_basename(ep->filename), selected)) | |
1091 sel_index = index; | |
1092 | |
1093 /* create menu item */ | |
1094 gtk_signal_connect(GTK_OBJECT(item), "activate", | |
1095 GTK_SIGNAL_FUNC(config_effect_plugin_cb), (gpointer)index++); | |
1096 gtk_widget_show(item); | |
1097 gtk_menu_append(GTK_MENU(menu), item); | |
1098 | |
1099 /* advance to next module */ | |
1100 list = g_list_next(list); | |
1101 } | |
1102 | |
1103 /* attach menu */ | |
1104 gtk_option_menu_set_menu(GTK_OPTION_MENU(option_menu), menu); | |
1105 | |
1106 if(sel_index == -1) { | |
1107 DEBUG(("[crossfade] scan_effect_plugins: plugin not found (\"%s\")\n", selected)); | |
1108 return def_index; /* use default (first entry) */ | |
1109 } | |
1110 return sel_index; | |
1111 } | |
1112 | |
1113 /*-- plugin output callbacks ------------------------------------------------*/ | |
1114 | |
1115 static void | |
1116 config_effect_plugin_cb(GtkWidget *widget, gint index) | |
1117 { | |
1118 EffectPlugin *ep = g_list_nth_data(get_effect_list(), index); /* XMMS */ | |
1119 | |
1120 /* select new plugin */ | |
1121 ep_index = index; | |
1122 | |
1123 /* get new plugin's name */ | |
1124 if(cfg->ep_name) g_free(cfg->ep_name); | |
1125 cfg->ep_name = (ep && ep->filename) | |
1126 ? g_strdup(g_basename(ep->filename)) : NULL; | |
1127 | |
1128 /* update gui */ | |
1129 SET_SENSITIVE("ep_configure_button", ep && (ep->configure != NULL)); | |
1130 SET_SENSITIVE("ep_about_button", ep && (ep->about != NULL)); | |
1131 | |
1132 /* 0.3.5: apply effect config immediatelly */ | |
1133 if(config->ep_name) g_free(config->ep_name); | |
1134 config->ep_name = g_strdup(cfg->ep_name); | |
1135 xfade_realize_ep_config(); | |
1136 } | |
1137 | |
1138 void on_ep_configure_button_clicked(GtkButton *button, gpointer user_data) | |
1139 { | |
1140 EffectPlugin *ep = g_list_nth_data(get_effect_list(), ep_index); /* XMMS */ | |
1141 if((ep == NULL) || (ep->configure == NULL)) return; | |
1142 ep->configure(); | |
1143 } | |
1144 | |
1145 void on_ep_about_button_clicked(GtkButton *button, gpointer user_data) | |
1146 { | |
1147 EffectPlugin *ep = g_list_nth_data(get_effect_list(), ep_index); /* XMMS */ | |
1148 if((ep == NULL) || (ep->about == NULL)) return; | |
1149 ep->about(); | |
1150 } | |
1151 | |
1152 void on_ep_enable_check_toggled(GtkToggleButton *togglebutton, gpointer user_data) | |
1153 { | |
1154 /* 0.3.5: apply effect config immediatelly */ | |
1155 config->ep_enable = cfg->ep_enable = GET_TOGGLE("ep_enable_check"); | |
1156 xfade_realize_ep_config(); | |
1157 } | |
1158 | |
1159 /*-- volume normalizer ------------------------------------------------------*/ | |
1160 | |
1161 void check_effects_dependencies() | |
1162 { | |
1163 if(checking) return; | |
1164 checking = TRUE; | |
1165 | |
1166 SET_SENSITIVE("volnorm_target_spin", cfg->volnorm_enable); | |
1167 SET_SENSITIVE("volnorm_target_label", cfg->volnorm_enable); | |
1168 SET_SENSITIVE("volnorm_quantaudio_check", cfg->volnorm_enable); | |
1169 SET_SENSITIVE("volnorm_target_spin", cfg->volnorm_enable); | |
1170 | |
1171 checking = FALSE; | |
1172 } | |
1173 | |
1174 void on_volnorm_enable_check_toggled(GtkToggleButton *togglebutton, gpointer user_data) | |
1175 { | |
1176 if(checking) return; | |
1177 cfg->volnorm_enable = gtk_toggle_button_get_active(togglebutton); | |
1178 check_effects_dependencies(); | |
1179 } | |
1180 | |
1181 /*** crossfader **************************************************************/ | |
1182 | |
1183 static void xf_config_cb(GtkWidget *widget, gint index); | |
1184 static void xf_type_cb (GtkWidget *widget, gint index); | |
1185 | |
1186 /* crude hack to keep track of menu items */ | |
1187 static gint xf_config_index_map[MAX_FADE_CONFIGS]; | |
1188 static gint xf_type_index_map [MAX_FADE_TYPES]; | |
1189 | |
1190 static void | |
1191 create_crossfader_config_menu() | |
1192 { | |
1193 GtkWidget *optionmenu, *menu; | |
1194 gint i, *imap; | |
1195 | |
1196 if((optionmenu = lookup_widget(config_win, "xf_config_optionmenu"))) { | |
1197 for(i=0; i<MAX_FADE_CONFIGS; i++) xf_config_index_map[i] = -1; | |
1198 imap = xf_config_index_map; | |
1199 menu = gtk_menu_new(); | |
1200 add_menu_item(menu, "Start of playback", xf_config_cb, FADE_CONFIG_START, &imap); | |
1201 add_menu_item(menu, "Automatic songchange", xf_config_cb, FADE_CONFIG_XFADE, &imap); | |
1202 #if 0 | |
1203 /* this should be FADE_TYPE_NONE all the time, anyway, | |
1204 so no need to make it configureable by the user */ | |
1205 add_menu_item(menu, "Automatic (gapless)", xf_config_cb, FADE_CONFIG_ALBUM, &imap); | |
1206 #endif | |
1207 add_menu_item(menu, "Manual songchange", xf_config_cb, FADE_CONFIG_MANUAL, &imap); | |
1208 add_menu_item(menu, "Manual stop", xf_config_cb, FADE_CONFIG_STOP, &imap); | |
1209 add_menu_item(menu, "End of playlist", xf_config_cb, FADE_CONFIG_EOP, &imap); | |
1210 add_menu_item(menu, "Seeking", xf_config_cb, FADE_CONFIG_SEEK, &imap); | |
1211 add_menu_item(menu, "Pause", xf_config_cb, FADE_CONFIG_PAUSE, &imap); | |
1212 gtk_option_menu_set_menu(GTK_OPTION_MENU(optionmenu), menu); | |
1213 } | |
1214 | |
1215 } | |
1216 | |
1217 static void | |
1218 create_crossfader_type_menu() | |
1219 { | |
1220 GtkWidget *optionmenu, *menu; | |
1221 gint i, *imap; | |
1222 guint32 mask; | |
1223 | |
1224 if((optionmenu = lookup_widget(config_win, "xf_type_optionmenu"))) { | |
1225 for(i=0; i<MAX_FADE_TYPES; i++) xf_type_index_map[i] = -1; | |
1226 imap = xf_type_index_map; | |
1227 menu = gtk_menu_new(); | |
1228 mask = cfg->fc[cfg->xf_index].type_mask; | |
1229 if(mask & (1 << FADE_TYPE_REOPEN)) add_menu_item(menu, "Reopen output device", xf_type_cb, FADE_TYPE_REOPEN, &imap); | |
1230 if(mask & (1 << FADE_TYPE_FLUSH)) add_menu_item(menu, "Flush output device", xf_type_cb, FADE_TYPE_FLUSH, &imap); | |
1231 if(mask & (1 << FADE_TYPE_NONE)) add_menu_item(menu, "None (gapless/off)", xf_type_cb, FADE_TYPE_NONE, &imap); | |
1232 if(mask & (1 << FADE_TYPE_PAUSE)) add_menu_item(menu, "Pause", xf_type_cb, FADE_TYPE_PAUSE, &imap); | |
1233 if(mask & (1 << FADE_TYPE_SIMPLE_XF)) add_menu_item(menu, "Simple crossfade", xf_type_cb, FADE_TYPE_SIMPLE_XF, &imap); | |
1234 if(mask & (1 << FADE_TYPE_ADVANCED_XF)) add_menu_item(menu, "Advanced crossfade", xf_type_cb, FADE_TYPE_ADVANCED_XF, &imap); | |
1235 if(mask & (1 << FADE_TYPE_FADEIN)) add_menu_item(menu, "Fadein", xf_type_cb, FADE_TYPE_FADEIN, &imap); | |
1236 if(mask & (1 << FADE_TYPE_FADEOUT)) add_menu_item(menu, "Fadeout", xf_type_cb, FADE_TYPE_FADEOUT, &imap); | |
1237 if(mask & (1 << FADE_TYPE_PAUSE_NONE)) add_menu_item(menu, "None", xf_type_cb, FADE_TYPE_PAUSE_NONE, &imap); | |
1238 if(mask & (1 << FADE_TYPE_PAUSE_ADV)) add_menu_item(menu, "Fadeout/Fadein", xf_type_cb, FADE_TYPE_PAUSE_ADV, &imap); | |
1239 gtk_option_menu_set_menu(GTK_OPTION_MENU(optionmenu), menu); | |
1240 } | |
1241 } | |
1242 | |
1243 #define NONE 0x00000000L | |
1244 #define XF_CONFIG 0x00000001L | |
1245 #define XF_TYPE 0x00000002L | |
1246 #define XF_MIX_SIZE 0x00000004L | |
1247 #define XF_FADEOUT 0x00000008L | |
1248 #define XF_OFFSET 0x00000010L | |
1249 #define XF_FADEIN 0x00000020L | |
1250 #define XF_PAGE 0x00000040L | |
1251 #define XF_FLUSH 0x00000080L | |
1252 #define ANY 0xffffffffL | |
1253 | |
1254 static void | |
1255 check_crossfader_dependencies(guint32 mask) | |
1256 { | |
1257 fade_config_t *fc = &cfg->fc[cfg->xf_index]; | |
1258 gint i; | |
1259 | |
1260 /* HACK: avoid endless recursion */ | |
1261 if(checking) return; | |
1262 checking = TRUE; | |
1263 | |
1264 if(mask & XF_FLUSH) { | |
1265 SET_TOGGLE ("xftfp_enable_check", fc->flush_pause_enable); | |
1266 SET_SENSITIVE("xftfp_length_label", fc->flush_pause_enable); | |
1267 SET_SENSITIVE("xftfp_length_spin", fc->flush_pause_enable); | |
1268 SET_TOGGLE ("xftffi_enable_check", fc->flush_in_enable); | |
1269 SET_SENSITIVE("xftffi_length_label", fc->flush_in_enable); | |
1270 SET_SENSITIVE("xftffi_length_spin", fc->flush_in_enable); | |
1271 SET_SENSITIVE("xftffi_volume_label", fc->flush_in_enable); | |
1272 SET_SENSITIVE("xftffi_volume_spin", fc->flush_in_enable); | |
1273 } | |
1274 | |
1275 if(mask & XF_MIX_SIZE) { | |
1276 SET_TOGGLE ("xf_autobuf_check", cfg->mix_size_auto); | |
1277 SET_SENSITIVE("xf_buffer_spin", !cfg->mix_size_auto); | |
1278 SET_SPIN ("xf_buffer_spin", xfade_mix_size_ms(cfg)); | |
1279 } | |
1280 | |
1281 if(mask & XF_CONFIG) { | |
1282 for(i=0; i<MAX_FADE_CONFIGS && (xf_config_index_map[i] != cfg->xf_index); i++); | |
1283 if(i == MAX_FADE_CONFIGS) i=0; | |
1284 SET_HISTORY("xf_config_optionmenu", i); | |
1285 } | |
1286 | |
1287 if(mask & XF_TYPE) { | |
1288 create_crossfader_type_menu(); | |
1289 for(i=0; i<MAX_FADE_TYPES && (xf_type_index_map[i] != fc->type); i++); | |
1290 if(i == MAX_FADE_TYPES) { | |
1291 fc->type = FADE_TYPE_NONE; | |
1292 for(i=0; i<MAX_FADE_TYPES && (xf_type_index_map[i] != fc->type); i++); | |
1293 if(i == MAX_FADE_CONFIGS) i=0; | |
1294 } | |
1295 SET_HISTORY("xf_type_optionmenu", i); | |
1296 } | |
1297 | |
1298 if(mask & XF_PAGE) { | |
1299 SET_PAGE("xf_type_notebook", fc->type); | |
1300 SET_SPIN("pause_length_spin", fc->pause_len_ms); | |
1301 SET_SPIN("simple_length_spin", fc->simple_len_ms); | |
1302 if(fc->config == FADE_CONFIG_SEEK) { | |
1303 HIDE("xftf_pause_frame"); | |
1304 HIDE("xftf_fadein_frame"); | |
1305 } | |
1306 else { | |
1307 SHOW("xftf_pause_frame"); | |
1308 SHOW("xftf_fadein_frame"); | |
1309 } | |
1310 } | |
1311 | |
1312 if(mask & XF_FADEOUT) { | |
1313 SET_TOGGLE ("fadeout_enable_check", fc->out_enable); | |
1314 SET_SENSITIVE("fadeout_length_label", fc->out_enable); | |
1315 SET_SENSITIVE("fadeout_length_spin", fc->out_enable); | |
1316 SET_SPIN ("fadeout_length_spin", fc->out_len_ms); | |
1317 SET_SENSITIVE("fadeout_volume_label", fc->out_enable); | |
1318 SET_SENSITIVE("fadeout_volume_spin", fc->out_enable); | |
1319 SET_SPIN ("fadeout_volume_spin", fc->out_volume); | |
1320 SET_SPIN ("xftfo_length_spin", fc->out_len_ms); | |
1321 SET_SPIN ("xftfo_volume_spin", fc->out_volume); | |
1322 SET_SPIN ("xftfoi_fadeout_spin", fc->out_len_ms); | |
1323 } | |
1324 | |
1325 if(mask & XF_FADEIN) { | |
1326 SET_TOGGLE ("fadein_lock_check", fc->in_locked); | |
1327 SET_SENSITIVE("fadein_enable_check", !fc->in_locked); | |
1328 SET_TOGGLE ("fadein_enable_check", fc->in_locked ? fc->out_enable : fc->in_enable); | |
1329 SET_SENSITIVE("fadein_length_label", !fc->in_locked && fc->in_enable); | |
1330 SET_SENSITIVE("fadein_length_spin", !fc->in_locked && fc->in_enable); | |
1331 SET_SPIN ("fadein_length_spin", fc->in_locked ? fc->out_len_ms : fc->in_len_ms); | |
1332 SET_SENSITIVE("fadein_volume_label", !fc->in_locked && fc->in_enable); | |
1333 SET_SENSITIVE("fadein_volume_spin", !fc->in_locked && fc->in_enable); | |
1334 SET_SPIN ("fadein_volume_spin", fc->in_locked ? fc->out_volume : fc->in_volume); | |
1335 SET_SPIN ("xftfi_length_spin", fc->in_len_ms); | |
1336 SET_SPIN ("xftfi_volume_spin", fc->in_volume); | |
1337 SET_SPIN ("xftfoi_fadein_spin", fc->in_len_ms); | |
1338 } | |
1339 | |
1340 if(mask & XF_OFFSET) { | |
1341 if(fc->out_enable) | |
1342 SET_SENSITIVE("xfofs_lockout_radiobutton", TRUE); | |
1343 if(!fc->in_locked && fc->in_enable) | |
1344 SET_SENSITIVE("xfofs_lockin_radiobutton", TRUE); | |
1345 | |
1346 switch(fc->ofs_type) { | |
1347 case FC_OFFSET_LOCK_OUT: | |
1348 if(!fc->out_enable) { | |
1349 SET_TOGGLE("xfofs_none_radiobutton", TRUE); | |
1350 fc->ofs_type = FC_OFFSET_NONE; | |
1351 } | |
1352 break; | |
1353 case FC_OFFSET_LOCK_IN: | |
1354 if(!(!fc->in_locked && fc->in_enable)) { | |
1355 if((fc->in_locked && fc->out_enable)) { | |
1356 SET_TOGGLE("xfofs_lockout_radiobutton", TRUE); | |
1357 fc->ofs_type = FC_OFFSET_LOCK_OUT; | |
1358 } else { | |
1359 SET_TOGGLE("xfofs_none_radiobutton", TRUE); | |
1360 fc->ofs_type = FC_OFFSET_NONE; | |
1361 } | |
1362 } | |
1363 break; | |
1364 } | |
1365 | |
1366 switch(fc->ofs_type_wanted) { | |
1367 case FC_OFFSET_NONE: | |
1368 SET_TOGGLE("xfofs_none_radiobutton", TRUE); | |
1369 fc->ofs_type = FC_OFFSET_NONE; | |
1370 break; | |
1371 case FC_OFFSET_LOCK_OUT: | |
1372 if(fc->out_enable) { | |
1373 SET_TOGGLE("xfofs_lockout_radiobutton", TRUE); | |
1374 fc->ofs_type = FC_OFFSET_LOCK_OUT; | |
1375 } | |
1376 break; | |
1377 case FC_OFFSET_LOCK_IN: | |
1378 if(!fc->in_locked && fc->in_enable) { | |
1379 SET_TOGGLE("xfofs_lockin_radiobutton", TRUE); | |
1380 fc->ofs_type = FC_OFFSET_LOCK_IN; | |
1381 } | |
1382 else if(fc->out_enable) { | |
1383 SET_TOGGLE("xfofs_lockout_radiobutton", TRUE); | |
1384 fc->ofs_type = FC_OFFSET_LOCK_OUT; | |
1385 } | |
1386 break; | |
1387 case FC_OFFSET_CUSTOM: | |
1388 SET_TOGGLE("xfofs_custom_radiobutton", TRUE); | |
1389 fc->ofs_type = FC_OFFSET_CUSTOM; | |
1390 break; | |
1391 } | |
1392 | |
1393 if(!fc->out_enable) | |
1394 SET_SENSITIVE("xfofs_lockout_radiobutton", FALSE); | |
1395 if(!(!fc->in_locked && fc->in_enable)) | |
1396 SET_SENSITIVE("xfofs_lockin_radiobutton", FALSE); | |
1397 | |
1398 SET_SENSITIVE("xfofs_custom_spin", fc->ofs_type == FC_OFFSET_CUSTOM); | |
1399 SET_SPIN ("xfofs_custom_spin", xfade_cfg_offset(fc)); | |
1400 SET_SPIN ("xftfo_silence_spin", xfade_cfg_offset(fc)); | |
1401 SET_SPIN ("xftfoi_silence_spin", xfade_cfg_offset(fc)); | |
1402 } | |
1403 | |
1404 checking = FALSE; | |
1405 } | |
1406 | |
1407 /*-- crossfader callbacks ---------------------------------------------------*/ | |
1408 | |
1409 void on_xf_buffer_spin_changed(GtkEditable *editable, gpointer user_data) | |
1410 { | |
1411 if(checking) return; | |
1412 cfg->mix_size_ms = gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(editable)); | |
1413 check_crossfader_dependencies(NONE); | |
1414 } | |
1415 | |
1416 void on_xf_autobuf_check_toggled(GtkToggleButton *togglebutton, gpointer user_data) | |
1417 { | |
1418 cfg->mix_size_auto = gtk_toggle_button_get_active(togglebutton); | |
1419 check_crossfader_dependencies(XF_MIX_SIZE); | |
1420 } | |
1421 | |
1422 /* - config/type - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/ | |
1423 | |
1424 void xf_config_cb(GtkWidget *widget, gint index) | |
1425 { | |
1426 if(checking) return; | |
1427 cfg->xf_index = index; | |
1428 check_crossfader_dependencies(ANY & ~XF_CONFIG); | |
1429 } | |
1430 | |
1431 void xf_type_cb(GtkWidget *widget, gint index) | |
1432 { | |
1433 if(checking) return; | |
1434 cfg->fc[cfg->xf_index].type = index; | |
1435 check_crossfader_dependencies(ANY & ~XF_CONFIG); | |
1436 } | |
1437 | |
1438 /* - flush - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/ | |
1439 | |
1440 void on_xftfp_enable_check_toggled(GtkToggleButton *togglebutton, gpointer user_data) | |
1441 { | |
1442 if(checking) return; | |
1443 cfg->fc[cfg->xf_index].flush_pause_enable | |
1444 = gtk_toggle_button_get_active(togglebutton); | |
1445 check_crossfader_dependencies(XF_FLUSH|XF_MIX_SIZE); | |
1446 } | |
1447 | |
1448 void on_xftfp_length_spin_changed(GtkEditable *editable, gpointer user_data) | |
1449 { | |
1450 if(checking) return; | |
1451 cfg->fc[cfg->xf_index].flush_pause_len_ms | |
1452 = gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(editable)); | |
1453 check_crossfader_dependencies(XF_FLUSH); | |
1454 } | |
1455 | |
1456 void on_xftffi_enable_check_toggled(GtkToggleButton *togglebutton, gpointer user_data) | |
1457 { | |
1458 if(checking) return; | |
1459 cfg->fc[cfg->xf_index].flush_in_enable | |
1460 = gtk_toggle_button_get_active(togglebutton); | |
1461 check_crossfader_dependencies(XF_FLUSH|XF_OFFSET|XF_FADEOUT|XF_FADEIN); | |
1462 } | |
1463 | |
1464 void on_xftffi_length_spin_changed(GtkEditable *editable, gpointer user_data) | |
1465 { | |
1466 if(checking) return; | |
1467 cfg->fc[cfg->xf_index].flush_in_len_ms | |
1468 = gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(editable)); | |
1469 check_crossfader_dependencies(XF_FLUSH); | |
1470 } | |
1471 | |
1472 void on_xftffi_volume_spin_changed(GtkEditable *editable, gpointer user_data) | |
1473 { | |
1474 if(checking) return; | |
1475 cfg->fc[cfg->xf_index].flush_in_volume | |
1476 = gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(editable)); | |
1477 check_crossfader_dependencies(XF_FLUSH); | |
1478 } | |
1479 | |
1480 /* - pause - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/ | |
1481 | |
1482 void on_pause_length_spin_changed(GtkEditable *editable, gpointer user_data) | |
1483 { | |
1484 if(checking) return; | |
1485 cfg->fc[cfg->xf_index].pause_len_ms | |
1486 = gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(editable)); | |
1487 check_crossfader_dependencies(XF_MIX_SIZE); | |
1488 } | |
1489 | |
1490 /* - simple - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/ | |
1491 | |
1492 void on_simple_length_spin_changed(GtkEditable *editable, gpointer user_data) | |
1493 { | |
1494 if(checking) return; | |
1495 cfg->fc[cfg->xf_index].simple_len_ms | |
1496 = gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(editable)); | |
1497 check_crossfader_dependencies(XF_MIX_SIZE); | |
1498 } | |
1499 | |
1500 /* - crossfade-fadeout - - - - - - - - - - - - - - - - - - - - - - - - - - -*/ | |
1501 | |
1502 void on_fadeout_enable_check_toggled(GtkToggleButton *togglebutton, gpointer user_data) | |
1503 { | |
1504 if(checking) return; | |
1505 cfg->fc[cfg->xf_index].out_enable | |
1506 = gtk_toggle_button_get_active(togglebutton); | |
1507 check_crossfader_dependencies(XF_MIX_SIZE|XF_OFFSET|XF_FADEOUT|XF_FADEIN); | |
1508 } | |
1509 | |
1510 void on_fadeout_length_spin_changed(GtkEditable *editable, gpointer user_data) | |
1511 { | |
1512 if(checking) return; | |
1513 cfg->fc[cfg->xf_index].out_len_ms | |
1514 = gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(editable)); | |
1515 check_crossfader_dependencies(XF_MIX_SIZE|XF_OFFSET|XF_FADEIN); | |
1516 } | |
1517 | |
1518 void on_fadeout_volume_spin_changed(GtkEditable *editable, gpointer user_data) | |
1519 { | |
1520 cfg->fc[cfg->xf_index].out_volume | |
1521 = gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(editable)); | |
1522 check_crossfader_dependencies(XF_OFFSET|XF_FADEIN); | |
1523 } | |
1524 | |
1525 /* - crossfade-offset - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/ | |
1526 | |
1527 void on_xfofs_none_radiobutton_toggled(GtkToggleButton *togglebutton, gpointer user_data) | |
1528 { | |
1529 if(checking || !gtk_toggle_button_get_active(togglebutton)) return; | |
1530 cfg->fc[cfg->xf_index].ofs_type = FC_OFFSET_NONE; | |
1531 cfg->fc[cfg->xf_index].ofs_type_wanted = FC_OFFSET_NONE; | |
1532 check_crossfader_dependencies(XF_MIX_SIZE|XF_OFFSET); | |
1533 } | |
1534 | |
1535 void on_xfofs_none_radiobutton_clicked(GtkButton *button, gpointer user_data) | |
1536 { | |
1537 if(checking) return; | |
1538 cfg->fc[cfg->xf_index].ofs_type_wanted = FC_OFFSET_NONE; | |
1539 } | |
1540 | |
1541 void on_xfofs_lockout_radiobutton_toggled(GtkToggleButton *togglebutton, gpointer user_data) | |
1542 { | |
1543 if(checking || !gtk_toggle_button_get_active(togglebutton)) return; | |
1544 cfg->fc[cfg->xf_index].ofs_type = FC_OFFSET_LOCK_OUT; | |
1545 cfg->fc[cfg->xf_index].ofs_type_wanted = FC_OFFSET_LOCK_OUT; | |
1546 check_crossfader_dependencies(XF_MIX_SIZE|XF_OFFSET); | |
1547 } | |
1548 | |
1549 void on_xfofs_lockout_radiobutton_clicked(GtkButton *button, gpointer user_data) | |
1550 { | |
1551 if(checking) return; | |
1552 cfg->fc[cfg->xf_index].ofs_type_wanted = FC_OFFSET_LOCK_OUT; | |
1553 } | |
1554 | |
1555 void on_xfofs_lockin_radiobutton_toggled(GtkToggleButton *togglebutton, gpointer user_data) | |
1556 { | |
1557 if(checking || !gtk_toggle_button_get_active(togglebutton)) return; | |
1558 cfg->fc[cfg->xf_index].ofs_type = FC_OFFSET_LOCK_IN; | |
1559 cfg->fc[cfg->xf_index].ofs_type_wanted = FC_OFFSET_LOCK_IN; | |
1560 check_crossfader_dependencies(XF_MIX_SIZE|XF_OFFSET); | |
1561 } | |
1562 | |
1563 void on_xfofs_lockin_radiobutton_clicked(GtkButton *button, gpointer user_data) | |
1564 { | |
1565 if(checking) return; | |
1566 cfg->fc[cfg->xf_index].ofs_type_wanted = FC_OFFSET_LOCK_IN; | |
1567 } | |
1568 | |
1569 void on_xfofs_custom_radiobutton_toggled(GtkToggleButton *togglebutton, gpointer user_data) | |
1570 { | |
1571 if(checking || !gtk_toggle_button_get_active(togglebutton)) return; | |
1572 cfg->fc[cfg->xf_index].ofs_type = FC_OFFSET_CUSTOM; | |
1573 cfg->fc[cfg->xf_index].ofs_type_wanted = FC_OFFSET_CUSTOM; | |
1574 check_crossfader_dependencies(XF_MIX_SIZE|XF_OFFSET); | |
1575 } | |
1576 | |
1577 void on_xfofs_custom_radiobutton_clicked(GtkButton *button, gpointer user_data) | |
1578 { | |
1579 if(checking) return; | |
1580 cfg->fc[cfg->xf_index].ofs_type_wanted = FC_OFFSET_CUSTOM; | |
1581 } | |
1582 | |
1583 void on_xfofs_custom_spin_changed(GtkEditable *editable, gpointer user_data) | |
1584 { | |
1585 if(checking) return; | |
1586 cfg->fc[cfg->xf_index].ofs_custom_ms = gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(editable)); | |
1587 check_crossfader_dependencies(XF_MIX_SIZE); | |
1588 } | |
1589 | |
1590 /* - crossfade-fadein - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/ | |
1591 | |
1592 void on_fadein_lock_check_toggled(GtkToggleButton *togglebutton, gpointer user_data) | |
1593 { | |
1594 if(checking) return; | |
1595 cfg->fc[cfg->xf_index].in_locked = gtk_toggle_button_get_active(togglebutton); | |
1596 check_crossfader_dependencies(XF_OFFSET|XF_FADEIN); | |
1597 } | |
1598 | |
1599 void on_fadein_enable_check_toggled(GtkToggleButton *togglebutton, gpointer user_data) | |
1600 { | |
1601 if(checking) return; | |
1602 cfg->fc[cfg->xf_index].in_enable = gtk_toggle_button_get_active(togglebutton); | |
1603 check_crossfader_dependencies(XF_OFFSET|XF_FADEIN); | |
1604 } | |
1605 | |
1606 void on_fadein_length_spin_changed(GtkEditable *editable, gpointer user_data) | |
1607 { | |
1608 if(checking) return; | |
1609 cfg->fc[cfg->xf_index].in_len_ms = gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(editable)); | |
1610 check_crossfader_dependencies(XF_MIX_SIZE|XF_OFFSET); | |
1611 } | |
1612 | |
1613 void on_fadein_volume_spin_changed(GtkEditable *editable, gpointer user_data) | |
1614 { | |
1615 if(checking) return; | |
1616 cfg->fc[cfg->xf_index].in_volume = gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(editable)); | |
1617 check_crossfader_dependencies(NONE); | |
1618 } | |
1619 | |
1620 /*-- fadein -----------------------------------------------------------------*/ | |
1621 | |
1622 /* signal set to on_fadein_length_spin_changed */ | |
1623 /* signal set to on_fadein_volume_spin_changed */ | |
1624 | |
1625 /*-- fadeout ----------------------------------------------------------------*/ | |
1626 | |
1627 /* signal set to on_fadeout_length_spin_changed */ | |
1628 /* signal set to on_fadeout_volume_spin_changed */ | |
1629 | |
1630 /*-- fadeout/fadein ---------------------------------------------------------*/ | |
1631 | |
1632 /* signal set to on_fadeout_length_spin_changed */ | |
1633 /* signal set to on_xfofs_custom_spin_changed */ | |
1634 /* signal set to on_fadeout_volume_spin_changed */ | |
1635 | |
1636 /*** gap killer **************************************************************/ | |
1637 | |
1638 void check_gapkiller_dependencies() | |
1639 { | |
1640 if(checking) return; | |
1641 checking = TRUE; | |
1642 | |
1643 SET_SENSITIVE("lgap_length_spin", cfg->gap_lead_enable); | |
1644 SET_SENSITIVE("lgap_level_spin", cfg->gap_lead_enable); | |
1645 SET_SENSITIVE("tgap_enable_check", !cfg->gap_trail_locked); | |
1646 SET_SENSITIVE("tgap_length_spin", !cfg->gap_trail_locked && cfg->gap_trail_enable); | |
1647 SET_SENSITIVE("tgap_level_spin", !cfg->gap_trail_locked && cfg->gap_trail_enable); | |
1648 | |
1649 if(cfg->gap_trail_locked) { | |
1650 SET_TOGGLE("tgap_enable_check", cfg->gap_lead_enable); | |
1651 SET_SPIN ("tgap_length_spin", cfg->gap_lead_len_ms); | |
1652 SET_SPIN ("tgap_level_spin", cfg->gap_lead_level); | |
1653 } | |
1654 else { | |
1655 SET_TOGGLE("tgap_enable_check", cfg->gap_trail_enable); | |
1656 SET_SPIN ("tgap_length_spin", cfg->gap_trail_len_ms); | |
1657 SET_SPIN ("tgap_level_spin", cfg->gap_trail_level); | |
1658 } | |
1659 | |
1660 if(cfg->mix_size_auto) | |
1661 SET_SPIN("xf_buffer_spin", xfade_mix_size_ms(cfg)); | |
1662 | |
1663 checking = FALSE; | |
1664 } | |
1665 | |
1666 /*-- gapkiller callbacks ----------------------------------------------------*/ | |
1667 | |
1668 void on_lgap_enable_check_toggled(GtkToggleButton *togglebutton, gpointer user_data) | |
1669 { | |
1670 if(checking) return; | |
1671 cfg->gap_lead_enable = gtk_toggle_button_get_active(togglebutton); | |
1672 check_gapkiller_dependencies(); | |
1673 } | |
1674 | |
1675 void on_lgap_length_spin_changed(GtkEditable *editable, gpointer user_data) | |
1676 { | |
1677 if(checking) return; | |
1678 cfg->gap_lead_len_ms = gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(editable)); | |
1679 check_gapkiller_dependencies(); | |
1680 } | |
1681 | |
1682 void on_lgap_level_spin_changed(GtkEditable *editable, gpointer user_data) | |
1683 { | |
1684 if(checking) return; | |
1685 cfg->gap_lead_level = gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(editable)); | |
1686 check_gapkiller_dependencies(); | |
1687 } | |
1688 | |
1689 void on_tgap_lock_check_toggled(GtkToggleButton *togglebutton, gpointer user_data) | |
1690 { | |
1691 if(checking) return; | |
1692 cfg->gap_trail_locked = gtk_toggle_button_get_active(togglebutton); | |
1693 check_gapkiller_dependencies(); | |
1694 } | |
1695 | |
1696 void on_tgap_enable_check_toggled(GtkToggleButton *togglebutton, gpointer user_data) | |
1697 { | |
1698 if(checking) return; | |
1699 cfg->gap_trail_enable = gtk_toggle_button_get_active(togglebutton); | |
1700 check_gapkiller_dependencies(); | |
1701 } | |
1702 | |
1703 void on_tgap_length_spin_changed(GtkEditable *editable, gpointer user_data) | |
1704 { | |
1705 if(checking) return; | |
1706 cfg->gap_trail_len_ms = gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(editable)); | |
1707 } | |
1708 | |
1709 void on_tgap_level_spin_changed(GtkEditable *editable, gpointer user_data) | |
1710 { | |
1711 if(checking) return; | |
1712 cfg->gap_trail_level = gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(editable)); | |
1713 } | |
1714 | |
1715 /*** misc ********************************************************************/ | |
1716 | |
1717 void check_misc_dependencies() | |
1718 { | |
1719 if(checking) return; | |
1720 checking = TRUE; | |
1721 | |
1722 if(cfg->mix_size_auto) | |
1723 SET_SPIN("xf_buffer_spin", xfade_mix_size_ms(cfg)); | |
1724 | |
1725 SET_SENSITIVE("moth_opmaxused_spin", cfg->enable_op_max_used); | |
1726 | |
1727 checking = FALSE; | |
1728 } | |
1729 | |
1730 /*-- misc callbacks ---------------------------------------------------------*/ | |
1731 | |
1732 void on_config_mixopt_enable_check_toggled(GtkToggleButton *togglebutton, gpointer user_data) | |
1733 { | |
1734 SET_SENSITIVE("mixopt_reverse_check", gtk_toggle_button_get_active(togglebutton)); | |
1735 SET_SENSITIVE("mixopt_software_check", gtk_toggle_button_get_active(togglebutton)); | |
1736 } | |
1737 | |
1738 void on_moth_songchange_spin_changed(GtkEditable *editable, gpointer user_data) | |
1739 { | |
1740 if(checking) return; | |
1741 cfg->songchange_timeout = gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(editable)); | |
1742 check_misc_dependencies(); | |
1743 } | |
1744 | |
1745 void on_moth_opmaxused_check_toggled(GtkToggleButton *togglebutton, gpointer user_data) | |
1746 { | |
1747 if(checking) return; | |
1748 cfg->enable_op_max_used = gtk_toggle_button_get_active(togglebutton); | |
1749 check_misc_dependencies(); | |
1750 } | |
1751 | |
1752 /*** presets *****************************************************************/ | |
1753 | |
1754 void on_presets_list_click_column(GtkCList *clist, gint column, gpointer user_data) | |
1755 { | |
1756 DEBUG(("*** column=%d\n", column)); | |
1757 } | |
1758 | |
1759 /*** main config *************************************************************/ | |
1760 | |
1761 void on_config_apply_clicked(GtkButton *button, gpointer user_data) | |
1762 { | |
1763 GtkWidget *widget; | |
1764 | |
1765 /* get current notebook page */ | |
1766 if((widget = lookup_widget(config_win, "config_notebook"))) | |
1767 cfg->page = gtk_notebook_get_current_page(GTK_NOTEBOOK(widget)); | |
1768 | |
1769 /* output method */ | |
1770 | |
1771 /* sample rate */ | |
1772 | |
1773 /* output method: builtin OSS */ | |
1774 if((widget = lookup_widget(config_win, "output_oss_notebook"))) | |
1775 cfg->oss_page = gtk_notebook_get_current_page(GTK_NOTEBOOK(widget)); | |
1776 | |
1777 if((widget = lookup_widget(config_win, "oss_adevice_alt_entry"))) { | |
1778 if(cfg->oss_alt_audio_device) g_free(cfg->oss_alt_audio_device); | |
1779 cfg->oss_alt_audio_device = gtk_editable_get_chars(GTK_EDITABLE(widget), 0, -1); | |
1780 g_strstrip(cfg->oss_alt_audio_device); | |
1781 } | |
1782 | |
1783 if((widget = lookup_widget(config_win, "oss_mdevice_alt_entry"))) { | |
1784 if(cfg->oss_alt_mixer_device) g_free(cfg->oss_alt_mixer_device); | |
1785 cfg->oss_alt_mixer_device = gtk_editable_get_chars(GTK_EDITABLE(widget), 0, -1); | |
1786 g_strstrip(cfg->oss_alt_mixer_device); | |
1787 } | |
1788 | |
1789 cfg->oss_buffer_size_ms = GET_SPIN ("ossbuf_buffer_spin"); | |
1790 cfg->oss_preload_size_ms = GET_SPIN ("ossbuf_preload_spin"); | |
1791 | |
1792 cfg->oss_fragments = GET_SPIN ("osshwb_fragments_spin"); | |
1793 cfg->oss_fragment_size = GET_SPIN ("osshwb_fragsize_spin"); | |
1794 cfg->oss_maxbuf_enable = GET_TOGGLE("osshwb_maxbuf_check"); | |
1795 | |
1796 cfg->oss_mixer_use_master = GET_TOGGLE("ossmixer_pcm_check"); | |
1797 | |
1798 /* output method: plugin */ | |
1799 op_config.throttle_enable = GET_TOGGLE("op_throttle_check"); | |
1800 op_config.max_write_enable = GET_TOGGLE("op_maxblock_check"); | |
1801 op_config.max_write_len = GET_SPIN ("op_maxblock_spin"); | |
1802 op_config.force_reopen = GET_TOGGLE("op_forcereopen_check"); | |
1803 | |
1804 xfade_save_plugin_config(&cfg->op_config_string, cfg->op_name, &op_config); | |
1805 | |
1806 /* output method: none: */ | |
1807 | |
1808 /* effects: pre-mixing effect plugin */ | |
1809 | |
1810 /* effects: volume normalizer */ | |
1811 cfg->volnorm_target = GET_SPIN ("volnorm_target_spin"); | |
1812 cfg->volnorm_use_qa = GET_TOGGLE("volnorm_quantaudio_check"); | |
1813 | |
1814 /* crossfader */ | |
1815 cfg->mix_size_auto = GET_TOGGLE("xf_autobuf_check"); | |
1816 | |
1817 /* gap killer */ | |
1818 cfg->gap_lead_enable = GET_TOGGLE("lgap_enable_check"); | |
1819 cfg->gap_lead_len_ms = GET_SPIN ("lgap_length_spin"); | |
1820 cfg->gap_lead_level = GET_SPIN ("lgap_level_spin"); | |
1821 | |
1822 cfg->gap_trail_locked = GET_TOGGLE("tgap_lock_check"); | |
1823 | |
1824 cfg->gap_crossing = GET_TOGGLE("gadv_crossing_check"); | |
1825 | |
1826 /* misc */ | |
1827 cfg->enable_debug = GET_TOGGLE("debug_stderr_check"); | |
1828 cfg->enable_monitor = GET_TOGGLE("debug_monitor_check"); | |
1829 cfg->enable_mixer = GET_TOGGLE("mixopt_enable_check"); | |
1830 cfg->mixer_reverse = GET_TOGGLE("mixopt_reverse_check"); | |
1831 cfg->mixer_software = GET_TOGGLE("mixopt_software_check"); | |
1832 cfg->preload_size_ms = GET_SPIN ("moth_preload_spin"); | |
1833 cfg->album_detection = GET_TOGGLE("noxf_album_check"); | |
1834 cfg->no_xfade_if_same_file = GET_TOGGLE("noxf_samefile_check"); | |
1835 cfg->enable_http_workaround = GET_TOGGLE("moth_httpworkaround_check"); | |
1836 cfg->op_max_used_ms = GET_SPIN ("moth_opmaxused_spin"); | |
1837 cfg->output_keep_opened = GET_TOGGLE("moth_outputkeepopened_check"); | |
1838 | |
1839 /* presets */ | |
1840 | |
1841 /* lock buffer */ | |
1842 g_static_mutex_lock(&buffer_mutex); | |
1843 | |
1844 /* free existing strings */ | |
1845 if(config->oss_alt_audio_device) g_free(config->oss_alt_audio_device); | |
1846 if(config->oss_alt_mixer_device) g_free(config->oss_alt_mixer_device); | |
1847 if(config->op_config_string) g_free(config->op_config_string); | |
1848 if(config->op_name) g_free(config->op_name); | |
1849 if(config->ep_name) g_free(config->ep_name); | |
1850 | |
1851 /* copy current settings (dupping the strings) */ | |
1852 *config = *cfg; | |
1853 config->oss_alt_audio_device = g_strdup(cfg->oss_alt_audio_device); | |
1854 config->oss_alt_mixer_device = g_strdup(cfg->oss_alt_mixer_device); | |
1855 config->op_config_string = g_strdup(cfg->op_config_string); | |
1856 config->op_name = g_strdup(cfg->op_name); | |
1857 config->ep_name = g_strdup(cfg->ep_name); | |
1858 | |
1859 /* tell the engine that the config has changed */ | |
1860 xfade_realize_config(); | |
1861 | |
1862 /* unlock buffer */ | |
1863 g_static_mutex_unlock(&buffer_mutex); | |
1864 | |
1865 /* save configuration */ | |
1866 xfade_save_config(); | |
1867 | |
1868 /* show/hide monitor win depending on config->enable_monitor */ | |
1869 xfade_check_monitor_win(); | |
1870 } | |
1871 | |
1872 void on_config_ok_clicked(GtkButton *button, gpointer user_data) | |
1873 { | |
1874 /* apply and save config */ | |
1875 on_config_apply_clicked(button, user_data); | |
1876 | |
1877 /* close and destroy window */ | |
1878 gtk_widget_destroy(config_win); | |
1879 } | |
1880 | |
1881 void xfade_configure() | |
1882 { | |
1883 GtkWidget *widget; | |
1884 | |
1885 if(!config_win) { | |
1886 /* create */ | |
1887 if(!(config_win = create_config_win())) { | |
1888 DEBUG(("[crossfade] plugin_configure: error creating window!\n")); | |
1889 return; | |
1890 } | |
1891 | |
1892 /* update config_win when window is destroyed */ | |
1893 gtk_signal_connect(GTK_OBJECT(config_win), "destroy", | |
1894 GTK_SIGNAL_FUNC(gtk_widget_destroyed), &config_win); | |
1895 | |
1896 /* free any strings that might be left in our local copy of the config */ | |
1897 if(cfg->oss_alt_audio_device) g_free(cfg->oss_alt_audio_device); | |
1898 if(cfg->oss_alt_mixer_device) g_free(cfg->oss_alt_mixer_device); | |
1899 if(cfg->op_config_string) g_free(cfg->op_config_string); | |
1900 if(cfg->op_name) g_free(cfg->op_name); | |
1901 if(cfg->ep_name) g_free(cfg->ep_name); | |
1902 | |
1903 /* copy current settings (dupping the strings) */ | |
1904 *cfg = *config; | |
1905 cfg->oss_alt_audio_device = g_strdup(config->oss_alt_audio_device); | |
1906 cfg->oss_alt_mixer_device = g_strdup(config->oss_alt_mixer_device); | |
1907 cfg->op_config_string = g_strdup(config->op_config_string); | |
1908 cfg->op_name = g_strdup(config->op_name); | |
1909 cfg->ep_name = g_strdup(config->ep_name); | |
1910 | |
1911 /* go to remembered notebook page */ | |
1912 if((widget = lookup_widget(config_win, "config_notebook"))) | |
1913 gtk_notebook_set_page(GTK_NOTEBOOK(widget), config->page); | |
1914 | |
1915 /* output: method */ | |
1916 #ifdef HAVE_OSS | |
1917 SET_SENSITIVE("output_oss_radio", TRUE); | |
1918 #else | |
1919 SET_SENSITIVE("output_oss_radio", FALSE); | |
1920 #endif | |
1921 | |
1922 switch(cfg->output_method) { | |
1923 case OUTPUT_METHOD_BUILTIN_OSS: | |
1924 widget = lookup_widget(config_win, "output_oss_radio"); | |
1925 break; | |
1926 case OUTPUT_METHOD_PLUGIN: | |
1927 widget = lookup_widget(config_win, "output_plugin_radio"); | |
1928 break; | |
1929 case OUTPUT_METHOD_BUILTIN_NULL: | |
1930 widget = lookup_widget(config_win, "output_none_radio"); | |
1931 break; | |
1932 default: | |
1933 widget = NULL; | |
1934 } | |
1935 if(widget) gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget), TRUE); | |
1936 | |
1937 if((widget = lookup_widget(config_win, "output_notebook"))) | |
1938 gtk_notebook_set_page(GTK_NOTEBOOK(widget), cfg->output_method); | |
1939 | |
1940 /* output: resampling rate */ | |
1941 if((widget = lookup_widget(config_win, "resampling_rate_optionmenu"))) { | |
1942 GtkWidget *menu = gtk_menu_new(); | |
1943 GtkWidget *item; | |
1944 | |
1945 item = gtk_menu_item_new_with_label("44100 Hz"); | |
1946 gtk_signal_connect(GTK_OBJECT(item), "activate", GTK_SIGNAL_FUNC(resampling_rate_cb), (gpointer)44100); | |
1947 gtk_widget_show(item); | |
1948 gtk_menu_append(GTK_MENU(menu), item); | |
1949 | |
1950 item = gtk_menu_item_new_with_label("48000 Hz"); | |
1951 gtk_signal_connect(GTK_OBJECT(item), "activate", GTK_SIGNAL_FUNC(resampling_rate_cb), (gpointer)48000); | |
1952 gtk_widget_show(item); | |
1953 gtk_menu_append(GTK_MENU(menu), item); | |
1954 | |
1955 gtk_option_menu_set_menu(GTK_OPTION_MENU(widget), menu); | |
1956 | |
1957 switch(cfg->output_rate) { | |
1958 default: | |
1959 DEBUG(("[crossfade] plugin_configure: WARNING: invalid output sample rate (%d)!\n", cfg->output_rate)); | |
1960 DEBUG(("[crossfade] plugin_configure: ... using default of 44100\n")); | |
1961 cfg->output_rate = 44100; | |
1962 case 44100: gtk_option_menu_set_history(GTK_OPTION_MENU(widget), 0); break; | |
1963 case 48000: gtk_option_menu_set_history(GTK_OPTION_MENU(widget), 1); break; | |
1964 } | |
1965 } | |
1966 | |
1967 /* output: resampling quality (libsamplerate setting) */ | |
1968 #ifdef HAVE_LIBSAMPLERATE | |
1969 if((widget = lookup_widget(config_win, "resampling_quality_optionmenu"))) { | |
1970 GtkWidget *menu = gtk_menu_new(); | |
1971 GtkWidget *item; | |
1972 | |
1973 GtkTooltips *tooltips = (GtkTooltips *)gtk_object_get_data(GTK_OBJECT(config_win), "tooltips"); | |
1974 | |
1975 int converter_type; | |
1976 const char *name, *description; | |
1977 for(converter_type = 0; (name = src_get_name(converter_type)); | |
1978 converter_type++) { | |
1979 description = src_get_description(converter_type); | |
1980 | |
1981 item = gtk_menu_item_new_with_label(name); | |
1982 gtk_tooltips_set_tip(tooltips, item, description, NULL); | |
1983 | |
1984 gtk_signal_connect(GTK_OBJECT(item), "activate", | |
1985 GTK_SIGNAL_FUNC(resampling_quality_cb), (gpointer)converter_type); | |
1986 gtk_widget_show(item); | |
1987 gtk_menu_append(GTK_MENU(menu), item); | |
1988 } | |
1989 | |
1990 gtk_option_menu_set_menu (GTK_OPTION_MENU(widget), menu); | |
1991 gtk_option_menu_set_history(GTK_OPTION_MENU(widget), cfg->output_quality); | |
1992 } | |
1993 #else | |
1994 HIDE("resampling_quality_hbox"); | |
1995 HIDE("resampling_quality_optionmenu"); | |
1996 #endif | |
1997 | |
1998 /* output method: builtin OSS */ | |
1999 if((widget = lookup_widget(config_win, "output_oss_notebook"))) | |
2000 gtk_notebook_set_page(GTK_NOTEBOOK(widget), cfg->oss_page); | |
2001 | |
2002 if((widget = lookup_widget(config_win, "oss_adevice_optionmenu"))) { | |
2003 scan_devices("Audio devices:", widget, config_adevice_cb); | |
2004 gtk_option_menu_set_history(GTK_OPTION_MENU(widget), | |
2005 cfg->oss_audio_device); | |
2006 gtk_widget_set_sensitive(widget, !cfg->oss_use_alt_audio_device); | |
2007 } | |
2008 SET_TOGGLE("oss_adevice_alt_check", cfg->oss_use_alt_audio_device); | |
2009 if((widget = lookup_widget(config_win, "oss_adevice_alt_entry"))) { | |
2010 gtk_entry_set_text(GTK_ENTRY(widget), cfg->oss_alt_audio_device | |
2011 ? cfg->oss_alt_audio_device | |
2012 : DEFAULT_OSS_ALT_AUDIO_DEVICE); | |
2013 gtk_widget_set_sensitive(widget, cfg->oss_use_alt_audio_device); | |
2014 } | |
2015 | |
2016 if((widget = lookup_widget(config_win, "oss_mdevice_optionmenu"))) { | |
2017 scan_devices("Mixers:", widget, config_mdevice_cb); | |
2018 gtk_option_menu_set_history(GTK_OPTION_MENU(widget), | |
2019 cfg->oss_mixer_device); | |
2020 gtk_widget_set_sensitive(widget, !cfg->oss_use_alt_mixer_device); | |
2021 } | |
2022 SET_TOGGLE("oss_mdevice_alt_check", cfg->oss_use_alt_mixer_device); | |
2023 if((widget = lookup_widget(config_win, "oss_mdevice_alt_entry"))) { | |
2024 gtk_entry_set_text(GTK_ENTRY(widget), cfg->oss_alt_mixer_device | |
2025 ? cfg->oss_alt_mixer_device | |
2026 : DEFAULT_OSS_ALT_MIXER_DEVICE); | |
2027 gtk_widget_set_sensitive(widget, cfg->oss_use_alt_mixer_device); | |
2028 } | |
2029 | |
2030 SET_SPIN ("ossbuf_buffer_spin", cfg->oss_buffer_size_ms); | |
2031 SET_SPIN ("ossbuf_preload_spin", cfg->oss_preload_size_ms); | |
2032 | |
2033 SET_SPIN ("osshwb_fragments_spin", cfg->oss_fragments); | |
2034 SET_SPIN ("osshwb_fragsize_spin", cfg->oss_fragment_size); | |
2035 SET_TOGGLE("osshwb_maxbuf_check", cfg->oss_maxbuf_enable); | |
2036 | |
2037 SET_TOGGLE("ossmixer_pcm_check", cfg->oss_mixer_use_master); | |
2038 | |
2039 check_oss_dependencies(); | |
2040 | |
2041 /* output method: plugin */ | |
2042 xfade_load_plugin_config(cfg->op_config_string, cfg->op_name, &op_config); | |
2043 SET_TOGGLE ("op_throttle_check", op_config.throttle_enable); | |
2044 SET_TOGGLE ("op_maxblock_check", op_config.max_write_enable); | |
2045 SET_SPIN ("op_maxblock_spin", op_config.max_write_len); | |
2046 SET_SENSITIVE("op_maxblock_spin", op_config.max_write_enable); | |
2047 SET_TOGGLE ("op_forcereopen_check", op_config.force_reopen); | |
2048 | |
2049 if((widget = lookup_widget(config_win, "op_plugin_optionmenu"))) { | |
2050 OutputPlugin *op = NULL; | |
2051 if((op_index = scan_plugins(widget, cfg->op_name)) >= 0) { | |
2052 gtk_option_menu_set_history(GTK_OPTION_MENU(widget), op_index); | |
2053 op = g_list_nth_data(get_output_list(), op_index); /* XMMS */ | |
2054 } | |
2055 SET_SENSITIVE("op_configure_button", op && (op->configure != NULL)); | |
2056 SET_SENSITIVE("op_about_button", op && (op->about != NULL)); | |
2057 } | |
2058 | |
2059 /* output method: none */ | |
2060 | |
2061 /* effects: pre-mixing effect plugin */ | |
2062 if((widget = lookup_widget(config_win, "ep_plugin_optionmenu"))) { | |
2063 EffectPlugin *ep = NULL; | |
2064 if((ep_index = scan_effect_plugins(widget, cfg->ep_name)) >= 0) { | |
2065 gtk_option_menu_set_history(GTK_OPTION_MENU(widget), ep_index); | |
2066 ep = g_list_nth_data(get_effect_list(), ep_index); /* XMMS */ | |
2067 } | |
2068 SET_SENSITIVE("ep_configure_button", ep && (ep->configure != NULL)); | |
2069 SET_SENSITIVE("ep_about_button", ep && (ep->about != NULL)); | |
2070 SET_TOGGLE ("ep_enable_check", cfg->ep_enable); | |
2071 } | |
2072 | |
2073 /* effects: volume normalizer */ | |
2074 SET_TOGGLE("volnorm_enable_check", cfg->volnorm_enable); | |
2075 SET_TOGGLE("volnorm_quantaudio_check", cfg->volnorm_use_qa); | |
2076 SET_SPIN ("volnorm_target_spin", cfg->volnorm_target); | |
2077 | |
2078 check_effects_dependencies(); | |
2079 | |
2080 /* crossfader */ | |
2081 create_crossfader_config_menu(); | |
2082 | |
2083 if((cfg->xf_index < 0) || (cfg->xf_index >= MAX_FADE_CONFIGS)) { | |
2084 DEBUG(("[crossfade] plugin_configure: crossfade index out of range (%d)!\n", cfg->xf_index)); | |
2085 cfg->xf_index = CLAMP(cfg->xf_index, 0, MAX_FADE_CONFIGS); | |
2086 } | |
2087 | |
2088 check_crossfader_dependencies(ANY); | |
2089 | |
2090 /* gap killer */ | |
2091 SET_TOGGLE ("lgap_enable_check", cfg->gap_lead_enable); | |
2092 SET_SPIN ("lgap_length_spin", cfg->gap_lead_len_ms); | |
2093 SET_SPIN ("lgap_level_spin", cfg->gap_lead_level); | |
2094 SET_TOGGLE ("tgap_lock_check", cfg->gap_trail_locked); | |
2095 SET_TOGGLE ("tgap_enable_check", cfg->gap_trail_enable); | |
2096 SET_SPIN ("tgap_length_spin", cfg->gap_trail_len_ms); | |
2097 SET_SPIN ("tgap_level_spin", cfg->gap_trail_level); | |
2098 SET_TOGGLE ("gadv_crossing_check", cfg->gap_crossing); | |
2099 | |
2100 check_gapkiller_dependencies(); | |
2101 | |
2102 /* misc */ | |
2103 SET_TOGGLE("debug_stderr_check", cfg->enable_debug); | |
2104 SET_TOGGLE("debug_monitor_check", cfg->enable_monitor); | |
2105 SET_TOGGLE("mixopt_enable_check", cfg->enable_mixer); | |
2106 SET_TOGGLE("mixopt_reverse_check", cfg->mixer_reverse); | |
2107 SET_TOGGLE("mixopt_software_check", cfg->mixer_software); | |
2108 SET_SPIN ("moth_songchange_spin", cfg->songchange_timeout); | |
2109 SET_SPIN ("moth_preload_spin", cfg->preload_size_ms); | |
2110 SET_TOGGLE("noxf_album_check", cfg->album_detection); | |
2111 SET_TOGGLE("noxf_samefile_check", cfg->album_detection); | |
2112 SET_TOGGLE("moth_httpworkaround_check", cfg->enable_http_workaround); | |
2113 SET_TOGGLE("moth_opmaxused_check", cfg->enable_op_max_used); | |
2114 SET_SPIN ("moth_opmaxused_spin", cfg->op_max_used_ms); | |
2115 SET_TOGGLE("moth_outputkeepopened_check", cfg->output_keep_opened); | |
2116 | |
2117 check_misc_dependencies(); | |
2118 | |
2119 /* presets */ | |
2120 if((set_wgt = lookup_widget(config_win, "presets_list_list"))) { | |
2121 GList *item; | |
2122 | |
2123 for(item = config->presets; item; item = g_list_next(item)) { | |
2124 gchar *name = (gchar *)item->data; | |
2125 gchar *text[] = {name, "Default", "No"}; | |
2126 gtk_clist_append(GTK_CLIST(set_wgt), text); | |
2127 } | |
2128 } | |
2129 | |
2130 /* show window near mouse pointer */ | |
2131 gtk_window_set_position(GTK_WINDOW(config_win), GTK_WIN_POS_MOUSE); | |
2132 gtk_widget_show(config_win); | |
2133 } | |
2134 else | |
2135 /* bring window to front */ | |
2136 gdk_window_raise(config_win->window); | |
2137 } | |
2138 | |
2139 void xfade_about() | |
2140 { | |
2141 if(!about_win) { | |
2142 gchar *about_text = | |
2143 "XMMS Crossfade Plugin "VERSION"\n" | |
2144 "Copyright (C) 2000-2004 Peter Eisenlohr <peter@eisenlohr.org>\n" | |
2145 "\n" | |
2146 "based on the original OSS Output Plugin Copyright (C) 1998-2000\n" | |
2147 "Peter Alm, Mikael Alm, Olle Hallnas, Thomas Nilsson and 4Front Technologies\n" | |
2148 "\n" | |
2149 "This program is free software; you can redistribute it and/or modify\n" | |
2150 "it under the terms of the GNU General Public License as published by\n" | |
2151 "the Free Software Foundation; either version 2 of the License, or\n" | |
2152 "(at your option) any later version.\n" | |
2153 "\n" | |
2154 "This program is distributed in the hope that it will be useful,\n" | |
2155 "but WITHOUT ANY WARRANTY; without even the implied warranty of\n" | |
2156 "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n" | |
2157 "GNU General Public License for more details.\n" | |
2158 "\n" | |
2159 "You should have received a copy of the GNU General Public License\n" | |
2160 "along with this program; if not, write to the Free Software\n" | |
2161 "Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,\n" | |
2162 "USA."; | |
2163 | |
2164 about_win = create_about_win(); | |
2165 | |
2166 /* update about_win when window is destroyed */ | |
2167 gtk_signal_connect(GTK_OBJECT(about_win), "destroy", GTK_SIGNAL_FUNC(gtk_widget_destroyed), &about_win); | |
2168 | |
2169 /* set about box text (this is done here and not in interface.c because | |
2170 of the VERSION #define -- there is no way to do this with GLADE */ | |
2171 if((set_wgt = lookup_widget(about_win, "about_label"))) | |
2172 gtk_label_set_text(GTK_LABEL(set_wgt), about_text); | |
2173 | |
2174 /* show near mouse pointer */ | |
2175 gtk_window_set_position(GTK_WINDOW(about_win), GTK_WIN_POS_MOUSE); | |
2176 gtk_widget_show(about_win); | |
2177 } | |
2178 else | |
2179 gdk_window_raise(about_win->window); | |
2180 } |