diff options
-rw-r--r-- | deadbeef.h | 8 | ||||
-rw-r--r-- | plugins/converter/converter.c | 13 | ||||
-rw-r--r-- | plugins/dsp_libsrc/src.c | 22 | ||||
-rw-r--r-- | plugins/gtkui/convgui.c | 55 | ||||
-rw-r--r-- | plugins/gtkui/eq.c | 47 | ||||
-rw-r--r-- | plugins/gtkui/gtkui.h | 5 | ||||
-rw-r--r-- | plugins/gtkui/pluginconf.c | 288 | ||||
-rw-r--r-- | plugins/gtkui/pluginconf.h | 32 | ||||
-rw-r--r-- | plugins/gtkui/prefwin.c | 15 | ||||
-rw-r--r-- | plugins/supereq/supereq.c | 59 | ||||
-rw-r--r-- | streamer.c | 14 |
11 files changed, 447 insertions, 111 deletions
@@ -799,14 +799,12 @@ typedef struct DB_dsp_s { int (*num_params) (void); const char *(*get_param_name) (int p); - void (*set_param) (ddb_dsp_context_t *ctx, int p, float val); - float (*get_param) (ddb_dsp_context_t *ctx, int p); + void (*set_param) (ddb_dsp_context_t *ctx, int p, const char *val); + void (*get_param) (ddb_dsp_context_t *ctx, int p, char *str, int len); - void (*set_param_str) (ddb_dsp_context_t *ctx, int p, const char *val); - void (*get_param_str) (ddb_dsp_context_t *ctx, int p, char *str, int len); + const char *configdialog; // separate dialog per dsp context } DB_dsp_t; - // misc plugin // purpose is to provide extra services // e.g. scrobbling, converting, tagging, custom gui, etc. diff --git a/plugins/converter/converter.c b/plugins/converter/converter.c index 93976b8e..6046002f 100644 --- a/plugins/converter/converter.c +++ b/plugins/converter/converter.c @@ -249,7 +249,9 @@ dsp_preset_copy (ddb_dsp_preset_t *to, ddb_dsp_preset_t *from) { if (dsp->plugin->num_params) { int n = dsp->plugin->num_params (); for (int j = 0; j < n; j++) { - i->plugin->set_param (i, j, dsp->plugin->get_param (dsp, j)); + char s[1000] = ""; + dsp->plugin->get_param (dsp, j, s, sizeof (s)); + i->plugin->set_param (i, j, s); } } if (tail) { @@ -320,7 +322,7 @@ dsp_preset_load (const char *fname) { int n = 0; for (;;) { - float value; + char value[1000]; if (!fgets (temp, sizeof (temp), fp)) { fprintf (stderr, "unexpected eof while reading plugin params\n"); goto error; @@ -328,7 +330,7 @@ dsp_preset_load (const char *fname) { if (!strcmp (temp, "}\n")) { break; } - else if (1 != sscanf (temp, "\t%f\n", &value)) { + else if (1 != sscanf (temp, "\t%1000[^\n]\n", value)) { fprintf (stderr, "error loading param %d\n", n); goto error; } @@ -392,8 +394,9 @@ dsp_preset_save (ddb_dsp_preset_t *p, int overwrite) { int n = ctx->plugin->num_params (); int i; for (i = 0; i < n; i++) { - float v = ctx->plugin->get_param (ctx, i); - fprintf (fp, "\t%f\n", v); + char v[1000]; + ctx->plugin->get_param (ctx, i, v, sizeof (v)); + fprintf (fp, "\t%s\n", v); } } fprintf (fp, "}\n"); diff --git a/plugins/dsp_libsrc/src.c b/plugins/dsp_libsrc/src.c index 432bf871..fdb96d14 100644 --- a/plugins/dsp_libsrc/src.c +++ b/plugins/dsp_libsrc/src.c @@ -197,13 +197,13 @@ ddb_src_get_param_name (int p) { } } void -ddb_src_set_param (ddb_dsp_context_t *ctx, int p, float val) { +ddb_src_set_param (ddb_dsp_context_t *ctx, int p, const char *val) { switch (p) { case SRC_PARAM_SAMPLERATE: - ((ddb_src_libsamplerate_t*)ctx)->samplerate = val; + ((ddb_src_libsamplerate_t*)ctx)->samplerate = atof (val); break; case SRC_PARAM_QUALITY: - ((ddb_src_libsamplerate_t*)ctx)->quality = val; + ((ddb_src_libsamplerate_t*)ctx)->quality = atoi (val); ((ddb_src_libsamplerate_t*)ctx)->quality_changed = 1; break; default: @@ -211,18 +211,25 @@ ddb_src_set_param (ddb_dsp_context_t *ctx, int p, float val) { } } -float -ddb_src_get_param (ddb_dsp_context_t *ctx, int p) { +void +ddb_src_get_param (ddb_dsp_context_t *ctx, int p, char *val, int sz) { switch (p) { case SRC_PARAM_SAMPLERATE: - return ((ddb_src_libsamplerate_t*)ctx)->samplerate; + snprintf (val, sz, "%f", ((ddb_src_libsamplerate_t*)ctx)->samplerate); + break; case SRC_PARAM_QUALITY: - return ((ddb_src_libsamplerate_t*)ctx)->quality; + snprintf (val, sz, "%d", ((ddb_src_libsamplerate_t*)ctx)->quality); + break; default: fprintf (stderr, "ddb_src_get_param: invalid param index (%d)\n", p); } } +static const char settings_dlg[] = + "property \"Target Samplerate\" spinbtn[8192,192000,1] 0 48000;\n" + "property \"Quality / Algorythm\" select[5] 1 2 SINC_BEST_QUALITY SINC_MEDIUM_QUALITY SINC_FASTEST ZERO_ORDER_HOLD LINEAR;\n" +; + static DB_dsp_t plugin = { .plugin.api_vmajor = DB_API_VERSION_MAJOR, .plugin.api_vminor = DB_API_VERSION_MINOR, @@ -243,6 +250,7 @@ static DB_dsp_t plugin = { .set_param = ddb_src_set_param, .get_param = ddb_src_get_param, .reset = ddb_src_reset, + .configdialog = settings_dlg, }; DB_plugin_t * diff --git a/plugins/gtkui/convgui.c b/plugins/gtkui/convgui.c index faedb699..4edb42a8 100644 --- a/plugins/gtkui/convgui.c +++ b/plugins/gtkui/convgui.c @@ -26,6 +26,7 @@ #include "support.h" #include "interface.h" #include "gtkui.h" +#include "pluginconf.h" ddb_encoder_preset_t *current_encoder_preset; ddb_dsp_preset_t *current_dsp_preset; @@ -618,6 +619,19 @@ on_dsp_preset_remove_plugin_clicked (GtkButton *button, } } +static ddb_dsp_context_t *current_dsp_context = NULL; + +void +dsp_ctx_set_param (const char *key, const char *value) { + current_dsp_context->plugin->set_param (current_dsp_context, atoi (key), value); +} + +void +dsp_ctx_get_param (const char *key, char *value, int len, const char *def) { + strncpy (value, def, len); + current_dsp_context->plugin->get_param (current_dsp_context, atoi (key), value, len); +} + void on_dsp_preset_plugin_configure_clicked (GtkButton *button, gpointer user_data) @@ -637,12 +651,44 @@ on_dsp_preset_plugin_configure_clicked (GtkButton *button, if (idx == -1) { return; } + ddb_dsp_context_t *p = current_dsp_preset->chain; + int i = idx; + while (p && i--) { + p = p->next; + } + if (!p || !p->plugin->configdialog) { + return; + } + current_dsp_context = p; + pluginconf_t conf = { + .title = p->plugin->plugin.name, + .layout = p->plugin->configdialog, + .set_param = dsp_ctx_set_param, + .get_param = dsp_ctx_get_param, + }; + plugin_configure (toplevel, &conf); + current_dsp_context = NULL; + +#if 0 + GtkWidget *toplevel = gtk_widget_get_toplevel (GTK_WIDGET (button)); + GtkWidget *list = lookup_widget (toplevel, "plugins"); + GtkTreePath *path; + GtkTreeViewColumn *col; + gtk_tree_view_get_cursor (GTK_TREE_VIEW (list), &path, &col); + if (!path || !col) { + // nothing selected + return; + } + int *indices = gtk_tree_path_get_indices (path); + int idx = *indices; + g_free (indices); + if (idx == -1) { + return; + } ddb_dsp_context_t *p = current_dsp_preset->chain; - ddb_dsp_context_t *prev = NULL; int i = idx; while (p && i--) { - prev = p; p = p->next; } if (!p || !p->plugin->num_params || !p->plugin->num_params ()) { @@ -700,6 +746,7 @@ on_dsp_preset_plugin_configure_clicked (GtkButton *button, } } gtk_widget_destroy (dlg); +#endif } void @@ -734,7 +781,6 @@ edit_dsp_preset (const char *title, GtkWidget *toplevel, int overwrite) { } { - // left list GtkWidget *list = lookup_widget (dlg, "plugins"); GtkCellRenderer *title_cell = gtk_cell_renderer_text_new (); GtkTreeViewColumn *col = gtk_tree_view_column_new_with_attributes (_("Plugin"), title_cell, "text", 0, NULL); @@ -798,6 +844,9 @@ refresh_dsp_lists (GtkComboBox *combo, GtkTreeView *list) { int act = gtk_combo_box_get_active (combo); mdl = GTK_LIST_STORE (gtk_combo_box_get_model (combo)); gtk_list_store_clear (mdl); + GtkTreeIter iter; + gtk_list_store_append (mdl, &iter); + gtk_list_store_set (mdl, &iter, 0, "Pass through", -1); fill_presets (mdl, (ddb_preset_t *)converter_plugin->dsp_preset_get_list ()); gtk_combo_box_set_active (combo, act); } diff --git a/plugins/gtkui/eq.c b/plugins/gtkui/eq.c index e137511e..1917e871 100644 --- a/plugins/gtkui/eq.c +++ b/plugins/gtkui/eq.c @@ -54,7 +54,9 @@ get_supereq (void) { static void set_param (ddb_dsp_context_t *eq, int i, float v) { - eq->plugin->set_param (eq, i, v); + char fv[100]; + snprintf (fv, sizeof (fv), "%f", v); + eq->plugin->set_param (eq, i, fv); if (i == 0) { deadbeef->conf_set_float ("eq.preamp", v); } @@ -71,9 +73,9 @@ eq_value_changed (DdbEqualizer *widget) ddb_dsp_context_t *eq = get_supereq (); if (eq) { for (int i = 0; i < 18; i++) { - set_param (eq, i+1, db_to_amp (ddb_equalizer_get_band (widget, i))); + set_param (eq, i+1, ddb_equalizer_get_band (widget, i)); } - set_param (eq, 0, db_to_amp (ddb_equalizer_get_preamp (widget))); + set_param (eq, 0, ddb_equalizer_get_preamp (widget)); } } @@ -95,13 +97,13 @@ on_zero_all_clicked (GtkButton *button, ddb_dsp_context_t *eq = get_supereq (); if (eq) { ddb_equalizer_set_preamp (DDB_EQUALIZER (eqwin), 0); - set_param (eq, 0, 1); + set_param (eq, 0, 0); for (int i = 0; i < 18; i++) { // set gui ddb_equalizer_set_band (DDB_EQUALIZER (eqwin), i, 0); // set dsp - set_param (eq, i+1, 1); + set_param (eq, i+1, 0); } gdk_window_invalidate_rect (eqwin->window, NULL, FALSE); } @@ -114,7 +116,7 @@ on_zero_preamp_clicked (GtkButton *button, if (eqwin) { ddb_dsp_context_t *eq = get_supereq (); if (eq) { - set_param (eq, 0, 1); + set_param (eq, 0, 0); ddb_equalizer_set_preamp (DDB_EQUALIZER (eqwin), 0); gdk_window_invalidate_rect (eqwin->window, NULL, FALSE); } @@ -129,7 +131,7 @@ on_zero_bands_clicked (GtkButton *button, if (eq) { for (int i = 0; i < 18; i++) { ddb_equalizer_set_band (DDB_EQUALIZER (eqwin), i, 0); - set_param (eq, i+1, 1); + set_param (eq, i+1, 0); } gdk_window_invalidate_rect (eqwin->window, NULL, FALSE); } @@ -161,10 +163,16 @@ on_save_preset_clicked (GtkButton *button, if (fp) { ddb_dsp_context_t *eq = get_supereq (); if (eq) { + char fv[100]; + float v; for (int i = 0; i < 18; i++) { - fprintf (fp, "%f\n", amp_to_db (eq->plugin->get_param (eq, i+1))); + eq->plugin->get_param (eq, i+1, fv, sizeof (fv)); + v = atof (fv); + fprintf (fp, "%f\n", v); } - fprintf (fp, "%f\n", amp_to_db (eq->plugin->get_param (eq, 0))); + eq->plugin->get_param (eq, 0, fv, sizeof (fv)); + v = atof (fv); + fprintf (fp, "%f\n", v); } fclose (fp); } @@ -219,11 +227,11 @@ on_load_preset_clicked (GtkButton *button, // apply and save config ddb_dsp_context_t *eq = get_supereq (); if (eq) { - set_param (eq, 0, db_to_amp (vals[18])); + set_param (eq, 0, vals[18]); ddb_equalizer_set_preamp (DDB_EQUALIZER (eqwin), vals[18]); for (int i = 0; i < 18; i++) { ddb_equalizer_set_band (DDB_EQUALIZER (eqwin), i, vals[i]); - set_param (eq, i+1, db_to_amp (vals[i])); + set_param (eq, i+1, vals[i]); } gdk_window_invalidate_rect (eqwin->window, NULL, FALSE); deadbeef->conf_save (); @@ -282,11 +290,11 @@ on_import_fb2k_preset_clicked (GtkButton *button, // apply and save config ddb_dsp_context_t *eq = get_supereq (); if (eq) { - set_param (eq, 0, 1); + set_param (eq, 0, 0); ddb_equalizer_set_preamp (DDB_EQUALIZER (eqwin), 0); for (int i = 0; i < 18; i++) { - ddb_equalizer_set_band (DDB_EQUALIZER (eqwin), i, vals[i]); - set_param (eq, i+1, db_to_amp (vals[i])); + ddb_equalizer_set_band (DDB_EQUALIZER (eqwin), i, amp_to_db (vals[i])); + set_param (eq, i+1, amp_to_db (vals[i])); } gdk_window_invalidate_rect (eqwin->window, NULL, FALSE); deadbeef->conf_save (); @@ -372,11 +380,16 @@ eq_window_show (void) { gtk_widget_set_size_request (eqwin, -1, 200); if (eq) { - ddb_equalizer_set_preamp (DDB_EQUALIZER (eqwin), amp_to_db (eq->plugin->get_param (eq, 0))); + char fv[100]; + float v; + eq->plugin->get_param (eq, 0, fv, sizeof (fv)); + v = atof (fv); + ddb_equalizer_set_preamp (DDB_EQUALIZER (eqwin), v); for (int i = 0; i < 18; i++) { if (eq) { - float val = eq->plugin->get_param (eq, i+1); - ddb_equalizer_set_band (DDB_EQUALIZER (eqwin), i, amp_to_db (val)); + eq->plugin->get_param (eq, i+1, fv, sizeof (fv)); + v = atof (fv); + ddb_equalizer_set_band (DDB_EQUALIZER (eqwin), i, v); } } } diff --git a/plugins/gtkui/gtkui.h b/plugins/gtkui/gtkui.h index 7cb2dff4..4f759916 100644 --- a/plugins/gtkui/gtkui.h +++ b/plugins/gtkui/gtkui.h @@ -74,11 +74,6 @@ gtkui_open_files (struct _GSList *lst); void gtkui_receive_fm_drop (DB_playItem_t *before, char *mem, int length); -// plugin configuration dialogs - -void -plugin_configure (GtkWidget *parentwin, DB_plugin_t *p); - void preferences_fill_soundcards (void); diff --git a/plugins/gtkui/pluginconf.c b/plugins/gtkui/pluginconf.c index 601f72e8..b024bcf8 100644 --- a/plugins/gtkui/pluginconf.c +++ b/plugins/gtkui/pluginconf.c @@ -30,6 +30,7 @@ #include "gtkui.h" #include "parser.h" #include "support.h" +#include "pluginconf.h" //#define trace(...) { fprintf (stderr, __VA_ARGS__); } #define trace(fmt,...) @@ -65,14 +66,14 @@ on_prop_browse_file (GtkButton *button, gpointer user_data) { } } -static void apply_conf (GtkWidget *w, DB_plugin_t *p) { +static void apply_conf (GtkWidget *w, pluginconf_t *conf) { // parse script char token[MAX_TOKEN]; - const char *script = p->configdialog; + const char *script = conf->layout; parser_line = 1; while (script = gettoken (script, token)) { if (strcmp (token, "property")) { - fprintf (stderr, "invalid token while loading plugin %s config dialog: %s at line %d\n", p->name, token, parser_line); + fprintf (stderr, "invalid token while loading plugin %s config dialog: %s at line %d\n", conf->title, token, parser_line); break; } char labeltext[MAX_TOKEN]; @@ -85,8 +86,34 @@ static void apply_conf (GtkWidget *w, DB_plugin_t *p) { if (!script) { break; } + + // skip containers + if (!strncmp (type, "hbox[", 5) || !strncmp (type, "vbox[", 5)) { + // skip to ; + char semicolon[MAX_TOKEN]; + while (script = gettoken_warn_eof (script, semicolon)) { + if (!strcmp (semicolon, ";")) { + break; + } + } + continue; + } + + // ignore layout options char key[MAX_TOKEN]; - script = gettoken_warn_eof (script, key); + const char *skiptokens[] = { "vert", NULL }; + for (;;) { + script = gettoken_warn_eof (script, key); + int i = 0; + for (i = 0; skiptokens[i]; i++) { + if (!strcmp (key, skiptokens[i])) { + break; + } + } + if (!skiptokens[i]) { + break; + } + } if (!script) { break; } @@ -95,36 +122,63 @@ static void apply_conf (GtkWidget *w, DB_plugin_t *p) { if (!script) { break; } - script = gettoken_warn_eof (script, token); - if (!script) { - break; - } - if (strcmp (token, ";")) { - fprintf (stderr, "expected `;' while loading plugin %s config dialog: %s at line %d\n", p->name, token, parser_line); - break; - } // fetch data GtkWidget *widget = lookup_widget (w, key); if (widget) { if (!strcmp (type, "entry") || !strcmp (type, "password")) { - deadbeef->conf_set_str (key, gtk_entry_get_text (GTK_ENTRY (widget))); + conf->set_param (key, gtk_entry_get_text (GTK_ENTRY (widget))); } else if (!strcmp (type, "file")) { if (deadbeef->conf_get_int ("gtkui.pluginconf.use_filechooser_button", 0)) { // filechooser - deadbeef->conf_set_str (key, gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (widget))); + conf->set_param (key, gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (widget))); } else { - deadbeef->conf_set_str (key, gtk_entry_get_text (GTK_ENTRY (widget))); + conf->set_param (key, gtk_entry_get_text (GTK_ENTRY (widget))); } } else if (!strcmp (type, "checkbox")) { - deadbeef->conf_set_int (key, gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (widget))); + conf->set_param (key, gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (widget)) ? "1" : "0"); + } + else if (!strncmp (type, "hscale[", 7) || !strncmp (type, "vscale[", 7)) { + char s[20]; + snprintf (s, sizeof (s), "%f", gtk_range_get_value (GTK_RANGE (widget))); + conf->set_param (key, s); } - else if (!strncmp (type, "hscale[", 7)) { - deadbeef->conf_set_float (key, gtk_range_get_value (GTK_RANGE (widget))); + else if (!strncmp (type, "spinbtn[", 8)) { + char s[20]; + snprintf (s, sizeof (s), "%f", (float)gtk_spin_button_get_value (GTK_SPIN_BUTTON (widget))); + conf->set_param (key, s); } + else if (!strncmp (type, "select[", 7)) { + int n; + if (1 != sscanf (type+6, "[%d]", &n)) { + break; + } + for (int i = 0; i < n; i++) { + char value[MAX_TOKEN]; + script = gettoken_warn_eof (script, value); + if (!script) { + break; + } + } + if (!script) { + break; + } + char s[20]; + snprintf (s, sizeof (s), "%d", gtk_combo_box_get_active (GTK_COMBO_BOX (widget))); + conf->set_param (key, s); + } + } + + script = gettoken_warn_eof (script, token); + if (!script) { + break; + } + if (strcmp (token, ";")) { + fprintf (stderr, "expected `;' while loading plugin %s config dialog: %s at line %d\n", conf->title, token, parser_line); + break; } } deadbeef->sendmessage (M_CONFIGCHANGED, 0, 0, 0); @@ -136,10 +190,10 @@ prop_changed (GtkWidget *editable, gpointer user_data) { } void -plugin_configure (GtkWidget *parentwin, DB_plugin_t *p) { +plugin_configure (GtkWidget *parentwin, pluginconf_t *conf) { // create window char title[200]; - snprintf (title, sizeof (title), _("Setup %s"), p->name); + snprintf (title, sizeof (title), _("Configure %s"), conf->title); GtkWidget *win = gtk_dialog_new_with_buttons (title, GTK_WINDOW (parentwin), GTK_DIALOG_MODAL, GTK_STOCK_APPLY, GTK_RESPONSE_APPLY, GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, GTK_STOCK_OK, GTK_RESPONSE_OK, NULL); gtk_dialog_set_default_response (GTK_DIALOG (win), GTK_RESPONSE_OK); gtk_window_set_type_hint (GTK_WINDOW (win), GDK_WINDOW_TYPE_HINT_DIALOG); @@ -148,9 +202,13 @@ plugin_configure (GtkWidget *parentwin, DB_plugin_t *p) { gtk_window_set_title (GTK_WINDOW (win), title); gtk_window_set_modal (GTK_WINDOW (win), TRUE); gtk_window_set_transient_for (GTK_WINDOW (win), GTK_WINDOW (parentwin)); - GtkWidget *vbox; - vbox = GTK_DIALOG (win)->vbox; - gtk_box_set_spacing (GTK_BOX (vbox), 8); + + GtkWidget *widgets[100] = {NULL}; + int pack[100] = {0}; + int ncurr = 0; + + widgets[ncurr] = GTK_DIALOG (win)->vbox; + gtk_box_set_spacing (GTK_BOX (widgets[ncurr]), 8); GtkWidget *action_area = GTK_DIALOG (win)->action_area; gtk_widget_show (action_area); gtk_button_box_set_layout (GTK_BUTTON_BOX (action_area), GTK_BUTTONBOX_END); @@ -158,11 +216,11 @@ plugin_configure (GtkWidget *parentwin, DB_plugin_t *p) { // parse script char token[MAX_TOKEN]; - const char *script = p->configdialog; + const char *script = conf->layout; parser_line = 1; while (script = gettoken (script, token)) { if (strcmp (token, "property")) { - fprintf (stderr, "invalid token while loading plugin %s config dialog: %s at line %d\n", p->name, token, parser_line); + fprintf (stderr, "invalid token while loading plugin %s config dialog: %s at line %d\n", conf->title, token, parser_line); break; } char labeltext[MAX_TOKEN]; @@ -170,34 +228,100 @@ plugin_configure (GtkWidget *parentwin, DB_plugin_t *p) { if (!script) { break; } + + if (ncurr > 0) { + pack[ncurr]--; + if (pack[ncurr] < 0) { + ncurr--; + } + } + char type[MAX_TOKEN]; script = gettoken_warn_eof (script, type); if (!script) { break; } + + if (!strncmp (type, "hbox[", 5) || !strncmp (type, "vbox[", 5)) { + ncurr++; + int n = 0; + if (1 != sscanf (type+4, "[%d]", &n)) { + break; + } + pack[ncurr] = n; + + int vert = 0; + int hmg = FALSE; + int fill = FALSE; + int expand = FALSE; + int border = 0; + int spacing = 8; + int height = 100; + + char param[MAX_TOKEN]; + for (;;) { + script = gettoken_warn_eof (script, param); + if (!script) { + break; + } + if (!strcmp (param, ";")) { + break; + } + else if (!strcmp (param, "hmg")) { + hmg = TRUE; + } + else if (!strcmp (param, "fill")) { + fill = TRUE; + } + else if (!strcmp (param, "expand")) { + expand = TRUE; + } + else if (!strncmp (param, "border=", 7)) { + border = atoi (param+7); + } + else if (!strncmp (param, "spacing=", 8)) { + spacing = atoi (param+8); + } + else if (!strncmp (param, "height=", 7)) { + height = atoi (param+7); + } + } + + widgets[ncurr] = vert ? gtk_vbox_new (TRUE, spacing) : gtk_hbox_new (TRUE, spacing); + gtk_widget_set_size_request (widgets[ncurr], -1, height); + gtk_widget_show (widgets[ncurr]); + gtk_box_pack_start (GTK_BOX(widgets[ncurr-1]), widgets[ncurr], fill, expand, border); + continue; + } + + int vertical = 0; + char key[MAX_TOKEN]; - script = gettoken_warn_eof (script, key); - if (!script) { - break; + for (;;) { + script = gettoken_warn_eof (script, key); + if (!script) { + break; + } + if (!strcmp (key, "vert")) { + vertical = 1; + } + else { + break; + } } + char def[MAX_TOKEN]; script = gettoken_warn_eof (script, def); if (!script) { break; } - script = gettoken_warn_eof (script, token); - if (!script) { - break; - } - if (strcmp (token, ";")) { - fprintf (stderr, "expected `;' while loading plugin %s config dialog: %s at line %d\n", p->name, token, parser_line); - break; - } // add to dialog GtkWidget *label = NULL; GtkWidget *prop = NULL; GtkWidget *cont = NULL; + char value[1000]; + conf->get_param (key, value, sizeof (value), def); if (!strcmp (type, "entry") || !strcmp (type, "password")) { label = gtk_label_new (_(labeltext)); gtk_widget_show (label); @@ -205,13 +329,17 @@ plugin_configure (GtkWidget *parentwin, DB_plugin_t *p) { gtk_entry_set_activates_default (GTK_ENTRY (prop), TRUE); g_signal_connect (G_OBJECT (prop), "changed", G_CALLBACK (prop_changed), win); gtk_widget_show (prop); - gtk_entry_set_text (GTK_ENTRY (prop), deadbeef->conf_get_str (key, def)); + gtk_entry_set_text (GTK_ENTRY (prop), value); + + if (!strcmp (type, "password")) { + gtk_entry_set_visibility (GTK_ENTRY (prop), FALSE); + } } else if (!strcmp (type, "checkbox")) { prop = gtk_check_button_new_with_label (_(labeltext)); g_signal_connect (G_OBJECT (prop), "toggled", G_CALLBACK (prop_changed), win); gtk_widget_show (prop); - int val = deadbeef->conf_get_int (key, atoi (def)); + int val = atoi (value); gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (prop), val); } else if (!strcmp (type, "file")) { @@ -220,7 +348,7 @@ plugin_configure (GtkWidget *parentwin, DB_plugin_t *p) { if (deadbeef->conf_get_int ("gtkui.pluginconf.use_filechooser_button", 0)) { prop = gtk_file_chooser_button_new (_(labeltext), GTK_FILE_CHOOSER_ACTION_OPEN); gtk_widget_show (prop); - gtk_file_chooser_set_filename (GTK_FILE_CHOOSER (prop), deadbeef->conf_get_str (key, def)); + gtk_file_chooser_set_filename (GTK_FILE_CHOOSER (prop), value); g_signal_connect (G_OBJECT (prop), "file-set", G_CALLBACK (prop_changed), win); } else { @@ -231,7 +359,7 @@ plugin_configure (GtkWidget *parentwin, DB_plugin_t *p) { g_signal_connect (G_OBJECT (prop), "changed", G_CALLBACK (prop_changed), win); gtk_widget_show (prop); gtk_editable_set_editable (GTK_EDITABLE (prop), FALSE); - gtk_entry_set_text (GTK_ENTRY (prop), deadbeef->conf_get_str (key, def)); + gtk_entry_set_text (GTK_ENTRY (prop), value); gtk_box_pack_start (GTK_BOX (cont), prop, TRUE, TRUE, 0); GtkWidget *btn = gtk_button_new_with_label ("…"); gtk_widget_show (btn); @@ -239,36 +367,88 @@ plugin_configure (GtkWidget *parentwin, DB_plugin_t *p) { g_signal_connect (G_OBJECT (btn), "clicked", G_CALLBACK (on_prop_browse_file), prop); } } - else if (!strncmp (type, "hscale[", 7)) { + else if (!strncmp (type, "select[", 7)) { + int n; + if (1 != sscanf (type+6, "[%d]", &n)) { + break; + } + + label = gtk_label_new (_(labeltext)); + gtk_widget_show (label); + + prop = gtk_combo_box_new_text (); + gtk_widget_show (prop); + + for (int i = 0; i < n; i++) { + char entry[MAX_TOKEN]; + script = gettoken_warn_eof (script, entry); + if (!script) { + break; + } + + gtk_combo_box_append_text (GTK_COMBO_BOX (prop), entry); + } + if (!script) { + break; + } + gtk_combo_box_set_active (GTK_COMBO_BOX (prop), atoi (value)); + g_signal_connect ((gpointer) prop, "changed", + G_CALLBACK (prop_changed), + win); + } + else if (!strncmp (type, "hscale[", 7) || !strncmp (type, "vscale[", 7) || !strncmp (type, "spinbtn[", 8)) { float min, max, step; - if (3 != sscanf (type+6, "[%f,%f,%f]", &min, &max, &step)) { - min = 0; - max = 100; - step = 1; + const char *args; + if (type[0] == 's') { + args = type + 7; + } + else { + args = type + 6; } + if (3 != sscanf (args, "[%f,%f,%f]", &min, &max, &step)) { + break; + } + int invert = 0; if (min >= max) { float tmp = min; min = max; max = tmp; - break; + invert = 1; } if (step <= 0) { step = 1; } - prop = gtk_hscale_new_with_range (min, max, step); + if (type[0] == 's') { + prop = gtk_spin_button_new_with_range (min, max, step); + gtk_spin_button_set_value (GTK_SPIN_BUTTON (prop), atof (value)); + } + else { + prop = type[0] == 'h' ? gtk_hscale_new_with_range (min, max, step) : gtk_vscale_new_with_range (min, max, step); + if (invert) { + gtk_range_set_inverted (GTK_RANGE (prop), TRUE); + } + gtk_range_set_value (GTK_RANGE (prop), (gdouble)atof (value)); + gtk_scale_set_value_pos (GTK_SCALE (prop), GTK_POS_RIGHT); + } label = gtk_label_new (_(labeltext)); gtk_widget_show (label); g_signal_connect (G_OBJECT (prop), "value-changed", G_CALLBACK (prop_changed), win); gtk_widget_show (prop); - gtk_range_set_value (GTK_RANGE (prop), (gdouble)deadbeef->conf_get_float (key, (float)*def)); - gtk_scale_set_value_pos (GTK_SCALE (prop), GTK_POS_RIGHT); } - if (!strcmp (type, "password")) { - gtk_entry_set_visibility (GTK_ENTRY (prop), FALSE); + + script = gettoken_warn_eof (script, token); + if (!script) { + break; + } + if (strcmp (token, ";")) { + fprintf (stderr, "expected `;' while loading plugin %s config dialog: %s at line %d\n", conf->title, token, parser_line); + break; } + + if (label && prop) { GtkWidget *hbox = NULL; - hbox = gtk_hbox_new (FALSE, 8); + hbox = vertical ? gtk_vbox_new (FALSE, 8) : gtk_hbox_new (FALSE, 8); gtk_widget_show (hbox); gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 0); gtk_box_pack_start (GTK_BOX (hbox), cont ? cont : prop, TRUE, TRUE, 0); @@ -281,7 +461,7 @@ plugin_configure (GtkWidget *parentwin, DB_plugin_t *p) { g_object_set_data (G_OBJECT (win), key, prop); } if (cont) { - gtk_box_pack_start (GTK_BOX (vbox), cont, FALSE, FALSE, 0); + gtk_box_pack_start (GTK_BOX (widgets[ncurr]), cont, FALSE, FALSE, 0); } } @@ -290,7 +470,7 @@ plugin_configure (GtkWidget *parentwin, DB_plugin_t *p) { gtk_dialog_set_response_sensitive (GTK_DIALOG (win), GTK_RESPONSE_APPLY, FALSE); response = gtk_dialog_run (GTK_DIALOG (win)); if (response == GTK_RESPONSE_APPLY || response == GTK_RESPONSE_OK) { - apply_conf (win, p); + apply_conf (win, conf); } } while (response == GTK_RESPONSE_APPLY); gtk_widget_destroy (win); diff --git a/plugins/gtkui/pluginconf.h b/plugins/gtkui/pluginconf.h new file mode 100644 index 00000000..66a64f1f --- /dev/null +++ b/plugins/gtkui/pluginconf.h @@ -0,0 +1,32 @@ +/* + DeaDBeeF - ultimate music player for GNU/Linux systems with X11 + Copyright (C) 2009-2010 Alexey Yakovenko <waker@users.sourceforge.net> + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License + as published by the Free Software Foundation; either version 2 + of the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +*/ +#ifndef __PLUGINCONF_H +#define __PLUGINCONF_H + +typedef struct { + const char *title; + const char *layout; + void (*set_param) (const char *key, const char *value); + void (*get_param) (const char *key, char *value, int len, const char *def); +} pluginconf_t; + +void +plugin_configure (GtkWidget *parentwin, pluginconf_t *conf); + +#endif diff --git a/plugins/gtkui/prefwin.c b/plugins/gtkui/prefwin.c index 4e1c42b0..411ca284 100644 --- a/plugins/gtkui/prefwin.c +++ b/plugins/gtkui/prefwin.c @@ -34,6 +34,7 @@ #include "support.h" #include "eq.h" #include "ddblistview.h" +#include "pluginconf.h" #define GLADE_HOOKUP_OBJECT(component,widget,name) \ g_object_set_data_full (G_OBJECT (component), name, \ @@ -812,6 +813,12 @@ on_pref_pluginlist_cursor_changed (GtkTreeView *treeview, } void +gtkui_conf_get_str (const char *key, char *value, int len, const char *def) { + // FIXME: conf_get_str must be changed + strcpy (value, deadbeef->conf_get_str (key, def)); +} + +void on_configure_plugin_clicked (GtkButton *button, gpointer user_data) { @@ -828,7 +835,13 @@ on_configure_plugin_clicked (GtkButton *button, DB_plugin_t **plugins = deadbeef->plug_get_list (); DB_plugin_t *p = plugins[*indices]; if (p->configdialog) { - plugin_configure (prefwin, p); + pluginconf_t conf = { + .title = p->name, + .layout = p->configdialog, + .set_param = deadbeef->conf_set_str, + .get_param = gtkui_conf_get_str, + }; + plugin_configure (prefwin, &conf); } } diff --git a/plugins/supereq/supereq.c b/plugins/supereq/supereq.c index 67b89c5d..9e957116 100644 --- a/plugins/supereq/supereq.c +++ b/plugins/supereq/supereq.c @@ -19,6 +19,7 @@ #include <stdio.h> #include <string.h> #include <stdlib.h> +#include <math.h> #include "../../deadbeef.h" #include "Equ.h" @@ -186,28 +187,41 @@ const char * supereq_get_param_name (int p) { return bandnames[p]; } + + +static inline float +db_to_amp (float dB) { + const float ln10=2.3025850929940002f; + return exp(ln10*dB/20.f); +} + +static inline float +amp_to_db (float amp) { + return 20*log10 (amp); +} + void -supereq_set_param (ddb_dsp_context_t *ctx, int p, float val) { +supereq_set_param (ddb_dsp_context_t *ctx, int p, const char *val) { switch (p) { case 0: - supereq_set_preamp (ctx, val); + supereq_set_preamp (ctx, db_to_amp (atof (val))); break; case 1 ... 18: - supereq_set_band (ctx, p, val); + supereq_set_band (ctx, p-1, db_to_amp (atof (val))); break; default: fprintf (stderr, "supereq_set_param: invalid param index (%d)\n", p); } } -float -supereq_get_param (ddb_dsp_context_t *ctx, int p) { +void +supereq_get_param (ddb_dsp_context_t *ctx, int p, char *v, int sz) { switch (p) { case 0: - return supereq_get_preamp (ctx); + snprintf (v, sz, "%f", amp_to_db (supereq_get_preamp (ctx))); break; case 1 ... 18: - return supereq_get_band (ctx, p); + snprintf (v, sz, "%f", amp_to_db (supereq_get_band (ctx, p-1))); break; default: fprintf (stderr, "supereq_get_param: invalid param index (%d)\n", p); @@ -225,10 +239,13 @@ supereq_open (void) { supereq->last_srate = 44100; supereq->last_nch = 2; supereq->mutex = deadbeef->mutex_create (); + supereq->preamp = 1; + for (int i = 0; i < 18; i++) { + supereq->lbands[i] = 1; + supereq->rbands[i] = 1; + } recalc_table (supereq); equ_clearbuf (&supereq->state); -// deadbeef->ev_subscribe (DB_PLUGIN (&plugin), DB_EV_CONFIGCHANGED, DB_CALLBACK (supereq_on_configchanged), 0); - return (ddb_dsp_context_t*)supereq; } @@ -245,6 +262,29 @@ supereq_close (ddb_dsp_context_t *ctx) { free (ctx); } +static const char settings_dlg[] = + "property \"\" hbox[19] hmg fill expand border=0 spacing=8 height=200;\n" + "property \"Preamp\" vscale[20,-20,1] vert 0 0;\n" + "property \"55 Hz\" vscale[20,-20,1] vert 1 0;\n" + "property \"77 Hz\" vscale[20,-20,1] vert 2 0;\n" + "property \"110 Hz\" vscale[20,-20,1] vert 3 0;\n" + "property \"156 Hz\" vscale[20,-20,1] vert 4 0;\n" + "property \"220 Hz\" vscale[20,-20,1] vert 5 0;\n" + "property \"311 Hz\" vscale[20,-20,1] vert 6 0;\n" + "property \"440 Hz\" vscale[20,-20,1] vert 7 0;\n" + "property \"622 Hz\" vscale[20,-20,1] vert 8 0;\n" + "property \"880 Hz\" vscale[20,-20,1] vert 9 0;\n" + "property \"1.2 kHz\" vscale[20,-20,1] vert 10 0;\n" + "property \"1.8 kHz\" vscale[20,-20,1] vert 11 0;\n" + "property \"2.5 kHz\" vscale[20,-20,1] vert 12 0;\n" + "property \"3.5 kHz\" vscale[20,-20,1] vert 13 0;\n" + "property \"5 kHz\" vscale[20,-20,1] vert 14 0;\n" + "property \"7 kHz\" vscale[20,-20,1] vert 15 0;\n" + "property \"10 kHz\" vscale[20,-20,1] vert 16 0;\n" + "property \"14 kHz\" vscale[20,-20,1] vert 17 0;\n" + "property \"20 kHz\" vscale[20,-20,1] vert 18 0;\n" +; + static DB_dsp_t plugin = { .plugin.api_vmajor = DB_API_VERSION_MAJOR, .plugin.api_vminor = DB_API_VERSION_MINOR, @@ -268,6 +308,7 @@ static DB_dsp_t plugin = { .get_param_name = supereq_get_param_name, .set_param = supereq_set_param, .get_param = supereq_get_param, + .configdialog = settings_dlg, }; DB_plugin_t * @@ -1144,7 +1144,7 @@ streamer_init (void) { srcplug = (DB_dsp_t*)plug_get_for_id ("SRC"); if (srcplug) { src = srcplug->open (); - srcplug->set_param (src, SRC_PARAM_QUALITY, conf_get_int ("src_quality", 2)); + srcplug->set_param (src, SRC_PARAM_QUALITY, conf_get_str ("src_quality", "2")); src->next = dsp_chain; dsp_chain = src; } @@ -1156,11 +1156,11 @@ streamer_init (void) { // load settings eqplug->enable (eq, deadbeef->conf_get_int ("eq.enable", 0)); - eqplug->set_param (eq, 0, conf_get_float ("eq.preamp", 1)); + eqplug->set_param (eq, 0, conf_get_str ("eq.preamp", "1")); for (int i = 0; i < 18; i++) { char key[100]; snprintf (key, sizeof (key), "eq.band%d", i); - eqplug->set_param (eq, 1+i, conf_get_float (key, 1)); + eqplug->set_param (eq, 1+i, conf_get_str (key, "1")); } eq->next = dsp_chain; @@ -1386,7 +1386,11 @@ streamer_read_async (char *bytes, int size) { // convert to float int tempsize = pcm_convert (&fileinfo->fmt, input, &dspfmt, tempbuf, inputsize); if (srcplug) { - srcplug->set_param (src, SRC_PARAM_SAMPLERATE, dspfmt.samplerate); + // FIXME: update on change only, conversion from float to + // str and back is slow + char s[100]; + snprintf (s, sizeof (s), "%d", dspfmt.samplerate); + srcplug->set_param (src, SRC_PARAM_SAMPLERATE, s); } int nframes = inputsize / inputsamplesize; @@ -1591,7 +1595,7 @@ streamer_configchanged (void) { pl_set_order (conf_get_int ("playback.order", 0)); if (srcplug) { - srcplug->set_param (src, SRC_PARAM_QUALITY, conf_get_int ("src_quality", 2)); + srcplug->set_param (src, SRC_PARAM_QUALITY, conf_get_str ("src_quality", "2")); } } |