diff options
author | waker <wakeroid@gmail.com> | 2011-03-14 22:08:10 +0100 |
---|---|---|
committer | waker <wakeroid@gmail.com> | 2011-03-14 22:21:38 +0100 |
commit | 5f38b54305d03202e67ec4f5a1cbc09a45366828 (patch) | |
tree | cf52bc65e2af62edc145b731617b2e571b11f8a6 | |
parent | 167aec58c1adcdf2309fd934d9ee82bb830ceab1 (diff) |
converter: added default output format to encoder presets;
added prompting for overwriting output files;
added tooltips to some entry fields in converter dialogs;
hidden GUI of some unimplemented features;
-rw-r--r-- | plugins/converter/callbacks.c | 1 | ||||
-rw-r--r-- | plugins/converter/callbacks.h | 4 | ||||
-rw-r--r-- | plugins/converter/converter.c | 103 | ||||
-rw-r--r-- | plugins/converter/converter.glade | 284 | ||||
-rw-r--r-- | plugins/converter/converter.h | 7 | ||||
-rw-r--r-- | plugins/converter/convgui.c | 125 | ||||
-rw-r--r-- | plugins/converter/interface.c | 56 |
7 files changed, 422 insertions, 158 deletions
diff --git a/plugins/converter/callbacks.c b/plugins/converter/callbacks.c index f609a9a1..b8fb56d3 100644 --- a/plugins/converter/callbacks.c +++ b/plugins/converter/callbacks.c @@ -9,4 +9,3 @@ #include "support.h" - diff --git a/plugins/converter/callbacks.h b/plugins/converter/callbacks.h index 1f5d7938..7e323527 100644 --- a/plugins/converter/callbacks.h +++ b/plugins/converter/callbacks.h @@ -118,3 +118,7 @@ on_output_file_changed (GtkEditable *editable, void on_preserve_folder_root_changed (GtkEditable *editable, gpointer user_data); + +void +on_preserve_root_folder_changed (GtkEditable *editable, + gpointer user_data); diff --git a/plugins/converter/converter.c b/plugins/converter/converter.c index 1ef703ea..b54233d0 100644 --- a/plugins/converter/converter.c +++ b/plugins/converter/converter.c @@ -102,6 +102,19 @@ encoder_preset_load (const char *fname) { else if (!strcmp (str, "formats")) { sscanf (item, "%X", &p->formats); } + else if (!strcmp (str, "defaultfmt")) { + sscanf (item, "%X", &p->default_format); + } + } + + if (!p->title) { + p->title = strdup ("Untitled"); + } + if (!p->ext) { + p->ext = strdup (""); + } + if (!p->encoder) { + p->encoder = strdup (""); } err = 0; @@ -151,6 +164,7 @@ encoder_preset_save (ddb_encoder_preset_t *p, int overwrite) { fprintf (fp, "encoder %s\n", p->encoder); fprintf (fp, "method %d\n", p->method); fprintf (fp, "formats %08X\n", p->formats); + fprintf (fp, "defaultfmt %08X\n", p->default_format); fclose (fp); return 0; @@ -163,6 +177,7 @@ encoder_preset_copy (ddb_encoder_preset_t *to, ddb_encoder_preset_t *from) { to->encoder = strdup (from->encoder); to->method = from->method; to->formats = from->formats; + to->default_format = from->default_format; } ddb_encoder_preset_t * @@ -459,8 +474,17 @@ dsp_preset_replace (ddb_dsp_preset_t *from, ddb_dsp_preset_t *to) { to->next = from->next; } +static void +get_output_path (DB_playItem_t *it, const char *outfolder, const char *outfile, ddb_encoder_preset_t *encoder_preset, char *out, int sz) { + char fname[PATH_MAX]; + int idx = deadbeef->pl_get_idx_of (it); + deadbeef->pl_format_title (it, idx, fname, sizeof (fname), -1, outfile); + snprintf (out, sz, "%s/%s.%s", outfolder, fname, encoder_preset->ext); + +} + int -convert (DB_playItem_t *it, const char *outfolder, const char *outfile, int selected_format, int preserve_folder_structure, const char *root_folder, ddb_encoder_preset_t *encoder_preset, ddb_dsp_preset_t *dsp_preset, int *abort) { +convert (DB_playItem_t *it, const char *outfolder, const char *outfile, int output_bps, int output_is_float, int preserve_folder_structure, const char *root_folder, ddb_encoder_preset_t *encoder_preset, ddb_dsp_preset_t *dsp_preset, int *abort) { int err = -1; FILE *enc_pipe = NULL; FILE *temp_file = NULL; @@ -476,10 +500,7 @@ convert (DB_playItem_t *it, const char *outfolder, const char *outfile, int sele goto error; } if (fileinfo) { - char fname[PATH_MAX]; - int idx = deadbeef->pl_get_idx_of (it); - deadbeef->pl_format_title (it, idx, fname, sizeof (fname), -1, outfile); - snprintf (out, sizeof (out), "%s/%s.%s", outfolder, fname, encoder_preset->ext); + get_output_path (it, outfolder, outfile, encoder_preset, out, sizeof (out)); if (encoder_preset->method == DDB_ENCODER_METHOD_FILE) { const char *tmp = getenv ("TMPDIR"); if (!tmp) { @@ -567,16 +588,51 @@ convert (DB_playItem_t *it, const char *outfolder, const char *outfile, int sele uint32_t outsize = 0; uint32_t outsr = fileinfo->fmt.samplerate; uint16_t outch = fileinfo->fmt.channels; - uint16_t outbps = fileinfo->fmt.bps; - if (selected_format != 0) { - switch (selected_format) { - case 1 ... 4: - outbps = selected_format * 8; - break; - case 5: - outbps = 32; - break; - } + + if (!(encoder_preset->formats & encoder_preset->default_format)) { + fprintf (stderr, "converter: invalid default format in the encoder preset '%s', formats: %X, def: %X\n", encoder_preset->title, encoder_preset->formats, encoder_preset->default_format); + goto error; + } + + // check if encoder supports it + int outfmt = -1; + switch (output_bps) { + case 8: + outfmt = DDB_ENCODER_FMT_8BIT; + break; + case 16: + outfmt = DDB_ENCODER_FMT_16BIT; + break; + case 24: + outfmt = DDB_ENCODER_FMT_24BIT; + break; + case 32: + outfmt = output_is_float ? DDB_ENCODER_FMT_32BITFLOAT : DDB_ENCODER_FMT_24BIT; + break; + } + if (outfmt == -1 || !(encoder_preset->formats & outfmt)) { + // pick default format + outfmt = encoder_preset->default_format; + } + + output_is_float = 0; + switch (outfmt) { + case DDB_ENCODER_FMT_8BIT: + output_bps = 8; + break; + case DDB_ENCODER_FMT_16BIT: + output_bps = 16; + break; + case DDB_ENCODER_FMT_24BIT: + output_bps = 24; + break; + case DDB_ENCODER_FMT_32BIT: + output_bps = 32; + break; + case DDB_ENCODER_FMT_32BITFLOAT: + output_bps = 32; + output_is_float = 1; + break; } int samplesize = fileinfo->fmt.channels * fileinfo->fmt.bps / 8; @@ -616,17 +672,19 @@ convert (DB_playItem_t *it, const char *outfolder, const char *outfile, int sele outsr = fmt.samplerate; outch = fmt.channels; - outfmt.bps = outbps; + outfmt.bps = output_bps; + outfmt.is_float = output_is_float; outfmt.channels = outch; outfmt.samplerate = outsr; int n = deadbeef->pcm_convert (&fmt, dspbuffer, &outfmt, buffer, frames * sizeof (float) * fmt.channels); sz = n; } - else if (fileinfo->fmt.bps != outbps) { + else if (fileinfo->fmt.bps != output_bps || fileinfo->fmt.is_float != output_is_float) { ddb_waveformat_t outfmt; memcpy (&outfmt, &fileinfo->fmt, sizeof (outfmt)); - outfmt.bps = outbps; + outfmt.bps = output_bps; + outfmt.is_float = output_is_float; outfmt.channels = outch; outfmt.samplerate = outsr; @@ -638,9 +696,9 @@ convert (DB_playItem_t *it, const char *outfolder, const char *outfile, int sele outsize += sz; if (!header_written) { - uint32_t size = (it->endsample-it->startsample) * outch * outbps / 8; + uint32_t size = (it->endsample-it->startsample) * outch * output_bps / 8; if (!size) { - size = deadbeef->pl_get_item_duration (it) * fileinfo->fmt.samplerate * outch * outbps / 8; + size = deadbeef->pl_get_item_duration (it) * fileinfo->fmt.samplerate * outch * output_bps / 8; } @@ -653,9 +711,9 @@ convert (DB_playItem_t *it, const char *outfolder, const char *outfile, int sele memcpy (&wavehdr[22], &outch, 2); memcpy (&wavehdr[24], &outsr, 4); - uint16_t blockalign = outch * outbps / 8; + uint16_t blockalign = outch * output_bps / 8; memcpy (&wavehdr[32], &blockalign, 2); - memcpy (&wavehdr[34], &outbps, 2); + memcpy (&wavehdr[34], &output_bps, 2); fwrite (wavehdr, 1, sizeof (wavehdr), temp_file); fwrite (&size, 1, sizeof (size), temp_file); @@ -774,6 +832,7 @@ static ddb_converter_t plugin = { .dsp_preset_append = dsp_preset_append, .dsp_preset_remove = dsp_preset_remove, .dsp_preset_replace = dsp_preset_replace, + .get_output_path = get_output_path, .convert = convert, }; diff --git a/plugins/converter/converter.glade b/plugins/converter/converter.glade index b28c37f3..93c9f35e 100644 --- a/plugins/converter/converter.glade +++ b/plugins/converter/converter.glade @@ -201,7 +201,7 @@ <widget class="GtkEntry" id="output_file"> <property name="visible">True</property> <property name="tooltip" translatable="yes">Extension (e.g. .mp3) will be appended automatically. -Leave the field empty for default.</property> +Leave the field empty for default (%a - %t).</property> <property name="can_focus">True</property> <property name="editable">True</property> <property name="visibility">True</property> @@ -435,7 +435,6 @@ Leave the field empty for default.</property> <child> <widget class="GtkHBox" id="hbox88"> - <property name="visible">True</property> <property name="homogeneous">False</property> <property name="spacing">8</property> @@ -525,7 +524,7 @@ Leave the field empty for default.</property> <child> <widget class="GtkComboBox" id="output_format"> <property name="visible">True</property> - <property name="items" translatable="yes">Keep original + <property name="items" translatable="yes">Auto 8 bit signed int 16 bit signed int 24 bit signed int @@ -605,7 +604,6 @@ Overwrite</property> <child> <widget class="GtkCheckButton" id="preserve_folders"> - <property name="visible">True</property> <property name="can_focus">True</property> <property name="label" translatable="yes">Preserve folder structure, starting from:</property> <property name="use_underline">True</property> @@ -625,12 +623,11 @@ Overwrite</property> <child> <widget class="GtkHBox" id="hbox102"> - <property name="visible">True</property> <property name="homogeneous">False</property> <property name="spacing">0</property> <child> - <widget class="GtkEntry" id="preserve_folder_root"> + <widget class="GtkEntry" id="preserve_root_folder"> <property name="visible">True</property> <property name="can_focus">True</property> <property name="editable">True</property> @@ -640,7 +637,7 @@ Overwrite</property> <property name="has_frame">True</property> <property name="invisible_char">•</property> <property name="activates_default">False</property> - <signal name="changed" handler="on_preserve_folder_root_changed" last_modification_time="Sun, 13 Mar 2011 20:03:13 GMT"/> + <signal name="changed" handler="on_preserve_root_folder_changed" last_modification_time="Mon, 14 Mar 2011 21:00:54 GMT"/> </widget> <packing> <property name="padding">0</property> @@ -1028,122 +1025,191 @@ Temporary file</property> <property name="right_padding">0</property> <child> - <widget class="GtkTable" id="table1"> - <property name="border_width">8</property> + <widget class="GtkVBox" id="vbox35"> + <property name="border_width">12</property> <property name="visible">True</property> - <property name="n_rows">3</property> - <property name="n_columns">2</property> <property name="homogeneous">False</property> - <property name="row_spacing">8</property> - <property name="column_spacing">8</property> - - <child> - <widget class="GtkCheckButton" id="8bit"> - <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="label" translatable="yes">8 bit signed int</property> - <property name="use_underline">True</property> - <property name="relief">GTK_RELIEF_NORMAL</property> - <property name="focus_on_click">True</property> - <property name="active">False</property> - <property name="inconsistent">False</property> - <property name="draw_indicator">True</property> - </widget> - <packing> - <property name="left_attach">0</property> - <property name="right_attach">1</property> - <property name="top_attach">0</property> - <property name="bottom_attach">1</property> - <property name="x_options">fill</property> - <property name="y_options"></property> - </packing> - </child> - - <child> - <widget class="GtkCheckButton" id="16bit"> - <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="label" translatable="yes">16 bit signed int</property> - <property name="use_underline">True</property> - <property name="relief">GTK_RELIEF_NORMAL</property> - <property name="focus_on_click">True</property> - <property name="active">False</property> - <property name="inconsistent">False</property> - <property name="draw_indicator">True</property> - </widget> - <packing> - <property name="left_attach">1</property> - <property name="right_attach">2</property> - <property name="top_attach">0</property> - <property name="bottom_attach">1</property> - <property name="x_options">fill</property> - <property name="y_options"></property> - </packing> - </child> + <property name="spacing">8</property> <child> - <widget class="GtkCheckButton" id="24bit"> + <widget class="GtkTable" id="table1"> <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="label" translatable="yes">24 bit signed int</property> - <property name="use_underline">True</property> - <property name="relief">GTK_RELIEF_NORMAL</property> - <property name="focus_on_click">True</property> - <property name="active">False</property> - <property name="inconsistent">False</property> - <property name="draw_indicator">True</property> + <property name="n_rows">3</property> + <property name="n_columns">2</property> + <property name="homogeneous">False</property> + <property name="row_spacing">8</property> + <property name="column_spacing">8</property> + + <child> + <widget class="GtkCheckButton" id="8bit"> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="label" translatable="yes">8 bit signed int</property> + <property name="use_underline">True</property> + <property name="relief">GTK_RELIEF_NORMAL</property> + <property name="focus_on_click">True</property> + <property name="active">False</property> + <property name="inconsistent">False</property> + <property name="draw_indicator">True</property> + </widget> + <packing> + <property name="left_attach">0</property> + <property name="right_attach">1</property> + <property name="top_attach">0</property> + <property name="bottom_attach">1</property> + <property name="x_options">fill</property> + <property name="y_options"></property> + </packing> + </child> + + <child> + <widget class="GtkCheckButton" id="16bit"> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="label" translatable="yes">16 bit signed int</property> + <property name="use_underline">True</property> + <property name="relief">GTK_RELIEF_NORMAL</property> + <property name="focus_on_click">True</property> + <property name="active">False</property> + <property name="inconsistent">False</property> + <property name="draw_indicator">True</property> + </widget> + <packing> + <property name="left_attach">1</property> + <property name="right_attach">2</property> + <property name="top_attach">0</property> + <property name="bottom_attach">1</property> + <property name="x_options">fill</property> + <property name="y_options"></property> + </packing> + </child> + + <child> + <widget class="GtkCheckButton" id="24bit"> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="label" translatable="yes">24 bit signed int</property> + <property name="use_underline">True</property> + <property name="relief">GTK_RELIEF_NORMAL</property> + <property name="focus_on_click">True</property> + <property name="active">False</property> + <property name="inconsistent">False</property> + <property name="draw_indicator">True</property> + </widget> + <packing> + <property name="left_attach">0</property> + <property name="right_attach">1</property> + <property name="top_attach">1</property> + <property name="bottom_attach">2</property> + <property name="x_options">fill</property> + <property name="y_options"></property> + </packing> + </child> + + <child> + <widget class="GtkCheckButton" id="32bit"> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="label" translatable="yes">32 bit signed int</property> + <property name="use_underline">True</property> + <property name="relief">GTK_RELIEF_NORMAL</property> + <property name="focus_on_click">True</property> + <property name="active">False</property> + <property name="inconsistent">False</property> + <property name="draw_indicator">True</property> + </widget> + <packing> + <property name="left_attach">1</property> + <property name="right_attach">2</property> + <property name="top_attach">1</property> + <property name="bottom_attach">2</property> + <property name="x_options">fill</property> + <property name="y_options"></property> + </packing> + </child> + + <child> + <widget class="GtkCheckButton" id="32bitfloat"> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="label" translatable="yes">32 bit float</property> + <property name="use_underline">True</property> + <property name="relief">GTK_RELIEF_NORMAL</property> + <property name="focus_on_click">True</property> + <property name="active">False</property> + <property name="inconsistent">False</property> + <property name="draw_indicator">True</property> + </widget> + <packing> + <property name="left_attach">0</property> + <property name="right_attach">1</property> + <property name="top_attach">2</property> + <property name="bottom_attach">3</property> + <property name="x_options">fill</property> + <property name="y_options"></property> + </packing> + </child> </widget> <packing> - <property name="left_attach">0</property> - <property name="right_attach">1</property> - <property name="top_attach">1</property> - <property name="bottom_attach">2</property> - <property name="x_options">fill</property> - <property name="y_options"></property> - </packing> - </child> - - <child> - <widget class="GtkCheckButton" id="32bit"> - <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="label" translatable="yes">32 bit signed int</property> - <property name="use_underline">True</property> - <property name="relief">GTK_RELIEF_NORMAL</property> - <property name="focus_on_click">True</property> - <property name="active">False</property> - <property name="inconsistent">False</property> - <property name="draw_indicator">True</property> - </widget> - <packing> - <property name="left_attach">1</property> - <property name="right_attach">2</property> - <property name="top_attach">1</property> - <property name="bottom_attach">2</property> - <property name="x_options">fill</property> - <property name="y_options"></property> + <property name="padding">0</property> + <property name="expand">True</property> + <property name="fill">True</property> </packing> </child> <child> - <widget class="GtkCheckButton" id="32bitfloat"> + <widget class="GtkHBox" id="hbox103"> <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="label" translatable="yes">32 bit float</property> - <property name="use_underline">True</property> - <property name="relief">GTK_RELIEF_NORMAL</property> - <property name="focus_on_click">True</property> - <property name="active">False</property> - <property name="inconsistent">False</property> - <property name="draw_indicator">True</property> + <property name="homogeneous">False</property> + <property name="spacing">8</property> + + <child> + <widget class="GtkLabel" id="label123"> + <property name="visible">True</property> + <property name="label" translatable="yes">Default format:</property> + <property name="use_underline">False</property> + <property name="use_markup">False</property> + <property name="justify">GTK_JUSTIFY_LEFT</property> + <property name="wrap">False</property> + <property name="selectable">False</property> + <property name="xalign">0.5</property> + <property name="yalign">0.5</property> + <property name="xpad">0</property> + <property name="ypad">0</property> + <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property> + <property name="width_chars">-1</property> + <property name="single_line_mode">False</property> + <property name="angle">0</property> + </widget> + <packing> + <property name="padding">0</property> + <property name="expand">False</property> + <property name="fill">False</property> + </packing> + </child> + + <child> + <widget class="GtkComboBox" id="defaultfmt"> + <property name="visible">True</property> + <property name="items" translatable="yes">8 bit signed int +16 bit signed int +24 bit signed int +32 bit signed int +32 bit float</property> + <property name="add_tearoffs">False</property> + <property name="focus_on_click">True</property> + </widget> + <packing> + <property name="padding">0</property> + <property name="expand">True</property> + <property name="fill">True</property> + </packing> + </child> </widget> <packing> - <property name="left_attach">0</property> - <property name="right_attach">1</property> - <property name="top_attach">2</property> - <property name="bottom_attach">3</property> - <property name="x_options">fill</property> - <property name="y_options"></property> + <property name="padding">0</property> + <property name="expand">True</property> + <property name="fill">True</property> </packing> </child> </widget> diff --git a/plugins/converter/converter.h b/plugins/converter/converter.h index 87a595ee..8eb723f1 100644 --- a/plugins/converter/converter.h +++ b/plugins/converter/converter.h @@ -47,6 +47,7 @@ typedef struct ddb_encoder_preset_s { char *encoder; int method; // pipe or file uint32_t formats; // combination of supported flags (FMT_*) + uint32_t default_format; } ddb_encoder_preset_t; typedef struct ddb_dsp_preset_s { @@ -132,8 +133,12 @@ typedef struct { // converter ///////////////////////////// + + void + (*get_output_path) (DB_playItem_t *it, const char *outfolder, const char *outfile, ddb_encoder_preset_t *encoder_preset, char *out, int sz); + int - (*convert) (DB_playItem_t *it, const char *outfolder, const char *outfile, int selected_format, int preserve_folder_structure, const char *root_folder, ddb_encoder_preset_t *encoder_preset, ddb_dsp_preset_t *dsp_preset, int *abort); + (*convert) (DB_playItem_t *it, const char *outfolder, const char *outfile, int output_bps, int output_is_float, int preserve_folder_structure, const char *root_folder, ddb_encoder_preset_t *encoder_preset, ddb_dsp_preset_t *dsp_preset, int *abort); } ddb_converter_t; diff --git a/plugins/converter/convgui.c b/plugins/converter/convgui.c index 3a1f24c0..11d75929 100644 --- a/plugins/converter/convgui.c +++ b/plugins/converter/convgui.c @@ -42,7 +42,9 @@ typedef struct { char *outfile; int preserve_folder_structure; char *preserve_root_folder; - int selected_format; + int output_bps; + int output_is_float; + int overwrite_action; ddb_encoder_preset_t *encoder_preset; ddb_dsp_preset_t *dsp_preset; GtkWidget *progress; @@ -91,6 +93,29 @@ destroy_progress_cb (gpointer ctx) { return FALSE; } +struct overwrite_prompt_ctx { + char *fname; + uintptr_t mutex; + uintptr_t cond; + int result; +}; + +static gboolean +overwrite_prompt_cb (void *ctx) { + struct overwrite_prompt_ctx *ctl = ctx; + GtkWidget *mainwin = gtkui_plugin->get_mainwin (); + GtkWidget *dlg = gtk_message_dialog_new (GTK_WINDOW (mainwin), GTK_DIALOG_MODAL, GTK_MESSAGE_WARNING, GTK_BUTTONS_YES_NO, _("The file already exists. Overwrite?")); + gtk_window_set_transient_for (GTK_WINDOW (dlg), GTK_WINDOW (mainwin)); + gtk_window_set_title (GTK_WINDOW (dlg), _("Converter warning")); + gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG (dlg), ctl->fname); + + int response = gtk_dialog_run (GTK_DIALOG (dlg)); + gtk_widget_destroy (dlg); + ctl->result = response == GTK_RESPONSE_YES ? 1 : 0; + deadbeef->cond_signal (ctl->cond); + return FALSE; +} + static void converter_worker (void *ctx) { converter_ctx_t *conv = ctx; @@ -102,7 +127,29 @@ converter_worker (void *ctx) { info->text = strdup (deadbeef->pl_find_meta (conv->convert_items[n], ":URI")); g_idle_add (update_progress_cb, info); - converter_plugin->convert (conv->convert_items[n], conv->outfolder, conv->outfile, conv->selected_format, conv->preserve_folder_structure, conv->preserve_root_folder, conv->encoder_preset, conv->dsp_preset, &conv->cancelled); + char outpath[2000]; + converter_plugin->get_output_path (conv->convert_items[n], conv->outfolder, conv->outfile, conv->encoder_preset, outpath, sizeof (outpath)); + + if (conv->overwrite_action == 0) { + // prompt if file exists + struct stat st; + int res = stat(outpath, &st); + if (res == 0) { + struct overwrite_prompt_ctx ctl; + ctl.mutex = deadbeef->mutex_create (); + ctl.cond = deadbeef->cond_create (); + ctl.fname = outpath; + ctl.result = 0; + gdk_threads_add_idle (overwrite_prompt_cb, &ctl); + deadbeef->cond_wait (ctl.cond, ctl.mutex); + deadbeef->cond_free (ctl.cond); + deadbeef->mutex_free (ctl.mutex); + } + } + + printf ("outpath: %s\n", outpath); + + converter_plugin->convert (conv->convert_items[n], conv->outfolder, conv->outfile, conv->output_bps, conv->output_is_float, conv->preserve_folder_structure, conv->preserve_root_folder, conv->encoder_preset, conv->dsp_preset, &conv->cancelled); if (conv->cancelled) { for (; n < conv->convert_items_count; n++) { deadbeef->pl_item_unref (conv->convert_items[n]); @@ -125,11 +172,32 @@ int converter_process (converter_ctx_t *conv) { conv->outfolder = strdup (gtk_entry_get_text (GTK_ENTRY (lookup_widget (conv->converter, "output_folder")))); - conv->outfile = strdup (gtk_entry_get_text (GTK_ENTRY (lookup_widget (conv->converter, "output_file")))); + const char *outfile = gtk_entry_get_text (GTK_ENTRY (lookup_widget (conv->converter, "output_file"))); + if (outfile[0] == 0) { + outfile = "%a - %t"; + } + conv->outfile = strdup (outfile); conv->preserve_folder_structure = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (lookup_widget (conv->converter, "preserve_folders"))); conv->preserve_root_folder = strdup (gtk_entry_get_text (GTK_ENTRY (lookup_widget (conv->converter, "preserve_root_folder")))); + conv->overwrite_action = gtk_combo_box_get_active (GTK_COMBO_BOX (lookup_widget (conv->converter, "overwrite_action"))); + + GtkComboBox *combo = GTK_COMBO_BOX (lookup_widget (conv->converter, "output_format")); + int selected_format = gtk_combo_box_get_active (combo); + switch (selected_format) { + case 1 ... 4: + conv->output_bps = selected_format * 8; + conv->output_is_float = 0; + break; + case 5: + conv->output_bps = 32; + conv->output_is_float = 1; + break; + default: + conv->output_bps = -1; // same as input, or encoder default + break; + } - GtkComboBox *combo = GTK_COMBO_BOX (lookup_widget (conv->converter, "encoder")); + combo = GTK_COMBO_BOX (lookup_widget (conv->converter, "encoder")); int enc_preset = gtk_combo_box_get_active (combo); ddb_encoder_preset_t *encoder_preset = NULL; @@ -149,9 +217,6 @@ converter_process (converter_ctx_t *conv) combo = GTK_COMBO_BOX (lookup_widget (conv->converter, "dsp_preset")); int dsp_idx = gtk_combo_box_get_active (combo) - 1; - combo = GTK_COMBO_BOX (lookup_widget (conv->converter, "output_format")); -// int selected_format = gtk_combo_box_get_active (combo); - ddb_dsp_preset_t *dsp_preset = NULL; if (dsp_idx >= 0) { dsp_preset = converter_plugin->dsp_preset_get_for_idx (dsp_idx); @@ -217,7 +282,7 @@ converter_show (DB_plugin_action_t *act, DB_playItem_t *it) { conv->converter = create_converterdlg (); gtk_entry_set_text (GTK_ENTRY (lookup_widget (conv->converter, "output_folder")), deadbeef->conf_get_str ("converter.output_folder", "")); gtk_entry_set_text (GTK_ENTRY (lookup_widget (conv->converter, "output_file")), deadbeef->conf_get_str ("converter.output_file", "")); - gtk_entry_set_text (GTK_ENTRY (lookup_widget (conv->converter, "preserve_folder_root")), deadbeef->conf_get_str ("converter.preserve_root_folder", "")); + gtk_entry_set_text (GTK_ENTRY (lookup_widget (conv->converter, "preserve_root_folder")), deadbeef->conf_get_str ("converter.preserve_root_folder", "")); gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (lookup_widget (conv->converter, "preserve_folders")), deadbeef->conf_get_int ("converter.preserve_folder_structure", 0)); gtk_combo_box_set_active (GTK_COMBO_BOX (lookup_widget (conv->converter, "overwrite_action")), deadbeef->conf_get_int ("converter.overwrite_action", 0)); @@ -413,7 +478,7 @@ on_preserve_folder_browse_clicked (GtkButton *button, folder = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (dlg)); gtk_widget_destroy (dlg); if (folder) { - GtkWidget *entry = lookup_widget (current_ctx->converter, "preserve_folder_root"); + GtkWidget *entry = lookup_widget (current_ctx->converter, "preserve_root_folder"); gtk_entry_set_text (GTK_ENTRY (entry), folder); g_free (folder); } @@ -440,7 +505,7 @@ on_preserve_folders_toggled (GtkToggleButton *togglebutton, } void -on_preserve_folder_root_changed (GtkEntry *entry, +on_preserve_root_folder_changed (GtkEntry *entry, gpointer user_data) { deadbeef->conf_set_str ("converter.preserve_root_folder", gtk_entry_get_text (entry)); @@ -488,6 +553,25 @@ init_encoder_preset_from_dlg (GtkWidget *dlg, ddb_encoder_preset_t *p) { if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (lookup_widget (dlg, "_32bitfloat")))) { p->formats |= DDB_ENCODER_FMT_32BITFLOAT; } + + int default_fmt = gtk_combo_box_get_active (GTK_COMBO_BOX (lookup_widget (dlg, "defaultfmt"))); + switch (default_fmt) { + case 0: + p->default_format = DDB_ENCODER_FMT_8BIT; + break; + case 1: + p->default_format = DDB_ENCODER_FMT_16BIT; + break; + case 2: + p->default_format = DDB_ENCODER_FMT_24BIT; + break; + case 3: + p->default_format = DDB_ENCODER_FMT_32BIT; + break; + case 4: + p->default_format = DDB_ENCODER_FMT_32BITFLOAT; + break; + } } int @@ -525,6 +609,27 @@ edit_encoder_preset (char *title, GtkWidget *toplevel, int overwrite) { if (p->formats & DDB_ENCODER_FMT_32BITFLOAT) { gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (lookup_widget (dlg, "_32bitfloat")), 1); } + int default_fmt = -1; + switch (p->default_format) { + case DDB_ENCODER_FMT_8BIT: + default_fmt = 0; + break; + case DDB_ENCODER_FMT_16BIT: + default_fmt = 1; + break; + case DDB_ENCODER_FMT_24BIT: + default_fmt = 2; + break; + case DDB_ENCODER_FMT_32BIT: + default_fmt = 3; + break; + case DDB_ENCODER_FMT_32BITFLOAT: + default_fmt = 4; + break; + } + if (default_fmt != -1) { + gtk_combo_box_set_active (GTK_COMBO_BOX (lookup_widget (dlg, "defaultfmt")), default_fmt); + } ddb_encoder_preset_t *old = p; int r = GTK_RESPONSE_CANCEL; diff --git a/plugins/converter/interface.c b/plugins/converter/interface.c index e217bf87..8414d2d9 100644 --- a/plugins/converter/interface.c +++ b/plugins/converter/interface.c @@ -66,7 +66,7 @@ create_converterdlg (void) GtkWidget *overwrite_action; GtkWidget *preserve_folders; GtkWidget *hbox102; - GtkWidget *preserve_folder_root; + GtkWidget *preserve_root_folder; GtkWidget *preserve_folder_browse; GtkWidget *dialog_action_area5; GtkWidget *converter_cancel; @@ -126,7 +126,7 @@ create_converterdlg (void) output_file = gtk_entry_new (); gtk_widget_show (output_file); gtk_box_pack_start (GTK_BOX (hbox101), output_file, TRUE, TRUE, 0); - gtk_tooltips_set_tip (tooltips, output_file, _("Extension (e.g. .mp3) will be appended automatically.\nLeave the field empty for default."), NULL); + gtk_tooltips_set_tip (tooltips, output_file, _("Extension (e.g. .mp3) will be appended automatically.\nLeave the field empty for default (%a - %t)."), NULL); gtk_entry_set_invisible_char (GTK_ENTRY (output_file), 8226); custom6 = title_formatting_help_link_create ("custom6", "", "", 0, 0); @@ -184,7 +184,6 @@ create_converterdlg (void) gtk_container_add (GTK_CONTAINER (edit_dsp_presets), image470); hbox88 = gtk_hbox_new (FALSE, 8); - gtk_widget_show (hbox88); gtk_box_pack_start (GTK_BOX (vbox26), hbox88, FALSE, TRUE, 0); label116 = gtk_label_new (_("Number of threads:")); @@ -207,7 +206,7 @@ create_converterdlg (void) output_format = gtk_combo_box_new_text (); gtk_widget_show (output_format); gtk_box_pack_start (GTK_BOX (hbox89), output_format, TRUE, TRUE, 0); - gtk_combo_box_append_text (GTK_COMBO_BOX (output_format), _("Keep original")); + gtk_combo_box_append_text (GTK_COMBO_BOX (output_format), _("Auto")); gtk_combo_box_append_text (GTK_COMBO_BOX (output_format), _("8 bit signed int")); gtk_combo_box_append_text (GTK_COMBO_BOX (output_format), _("16 bit signed int")); gtk_combo_box_append_text (GTK_COMBO_BOX (output_format), _("24 bit signed int")); @@ -229,17 +228,15 @@ create_converterdlg (void) gtk_combo_box_append_text (GTK_COMBO_BOX (overwrite_action), _("Overwrite")); preserve_folders = gtk_check_button_new_with_mnemonic (_("Preserve folder structure, starting from:")); - gtk_widget_show (preserve_folders); gtk_box_pack_start (GTK_BOX (vbox26), preserve_folders, FALSE, FALSE, 0); hbox102 = gtk_hbox_new (FALSE, 0); - gtk_widget_show (hbox102); gtk_box_pack_start (GTK_BOX (vbox26), hbox102, TRUE, TRUE, 0); - preserve_folder_root = gtk_entry_new (); - gtk_widget_show (preserve_folder_root); - gtk_box_pack_start (GTK_BOX (hbox102), preserve_folder_root, TRUE, TRUE, 0); - gtk_entry_set_invisible_char (GTK_ENTRY (preserve_folder_root), 8226); + preserve_root_folder = gtk_entry_new (); + gtk_widget_show (preserve_root_folder); + gtk_box_pack_start (GTK_BOX (hbox102), preserve_root_folder, TRUE, TRUE, 0); + gtk_entry_set_invisible_char (GTK_ENTRY (preserve_root_folder), 8226); preserve_folder_browse = gtk_button_new_with_mnemonic (_("...")); gtk_widget_show (preserve_folder_browse); @@ -292,8 +289,8 @@ create_converterdlg (void) g_signal_connect ((gpointer) preserve_folders, "toggled", G_CALLBACK (on_preserve_folders_toggled), NULL); - g_signal_connect ((gpointer) preserve_folder_root, "changed", - G_CALLBACK (on_preserve_folder_root_changed), + g_signal_connect ((gpointer) preserve_root_folder, "changed", + G_CALLBACK (on_preserve_root_folder_changed), NULL); g_signal_connect ((gpointer) preserve_folder_browse, "clicked", G_CALLBACK (on_preserve_folder_browse_clicked), @@ -336,7 +333,7 @@ create_converterdlg (void) GLADE_HOOKUP_OBJECT (converterdlg, overwrite_action, "overwrite_action"); GLADE_HOOKUP_OBJECT (converterdlg, preserve_folders, "preserve_folders"); GLADE_HOOKUP_OBJECT (converterdlg, hbox102, "hbox102"); - GLADE_HOOKUP_OBJECT (converterdlg, preserve_folder_root, "preserve_folder_root"); + GLADE_HOOKUP_OBJECT (converterdlg, preserve_root_folder, "preserve_root_folder"); GLADE_HOOKUP_OBJECT (converterdlg, preserve_folder_browse, "preserve_folder_browse"); GLADE_HOOKUP_OBJECT_NO_REF (converterdlg, dialog_action_area5, "dialog_action_area5"); GLADE_HOOKUP_OBJECT (converterdlg, converter_cancel, "converter_cancel"); @@ -368,12 +365,16 @@ create_convpreset_editor (void) GtkWidget *method; GtkWidget *frame8; GtkWidget *alignment20; + GtkWidget *vbox35; GtkWidget *table1; GtkWidget *_8bit; GtkWidget *_16bit; GtkWidget *_24bit; GtkWidget *_32bit; GtkWidget *_32bitfloat; + GtkWidget *hbox103; + GtkWidget *label123; + GtkWidget *defaultfmt; GtkWidget *label118; GtkWidget *dialog_action_area6; GtkWidget *convpreset_cancel; @@ -473,10 +474,14 @@ create_convpreset_editor (void) gtk_container_add (GTK_CONTAINER (frame8), alignment20); gtk_alignment_set_padding (GTK_ALIGNMENT (alignment20), 0, 0, 12, 0); + vbox35 = gtk_vbox_new (FALSE, 8); + gtk_widget_show (vbox35); + gtk_container_add (GTK_CONTAINER (alignment20), vbox35); + gtk_container_set_border_width (GTK_CONTAINER (vbox35), 12); + table1 = gtk_table_new (3, 2, FALSE); gtk_widget_show (table1); - gtk_container_add (GTK_CONTAINER (alignment20), table1); - gtk_container_set_border_width (GTK_CONTAINER (table1), 8); + gtk_box_pack_start (GTK_BOX (vbox35), table1, TRUE, TRUE, 0); gtk_table_set_row_spacings (GTK_TABLE (table1), 8); gtk_table_set_col_spacings (GTK_TABLE (table1), 8); @@ -510,6 +515,23 @@ create_convpreset_editor (void) (GtkAttachOptions) (GTK_FILL), (GtkAttachOptions) (0), 0, 0); + hbox103 = gtk_hbox_new (FALSE, 8); + gtk_widget_show (hbox103); + gtk_box_pack_start (GTK_BOX (vbox35), hbox103, TRUE, TRUE, 0); + + label123 = gtk_label_new (_("Default format:")); + gtk_widget_show (label123); + gtk_box_pack_start (GTK_BOX (hbox103), label123, FALSE, FALSE, 0); + + defaultfmt = gtk_combo_box_new_text (); + gtk_widget_show (defaultfmt); + gtk_box_pack_start (GTK_BOX (hbox103), defaultfmt, TRUE, TRUE, 0); + gtk_combo_box_append_text (GTK_COMBO_BOX (defaultfmt), _("8 bit signed int")); + gtk_combo_box_append_text (GTK_COMBO_BOX (defaultfmt), _("16 bit signed int")); + gtk_combo_box_append_text (GTK_COMBO_BOX (defaultfmt), _("24 bit signed int")); + gtk_combo_box_append_text (GTK_COMBO_BOX (defaultfmt), _("32 bit signed int")); + gtk_combo_box_append_text (GTK_COMBO_BOX (defaultfmt), _("32 bit float")); + label118 = gtk_label_new (_("<b>Sample formats supported by the encoder</b>")); gtk_widget_show (label118); gtk_frame_set_label_widget (GTK_FRAME (frame8), label118); @@ -553,12 +575,16 @@ create_convpreset_editor (void) GLADE_HOOKUP_OBJECT (convpreset_editor, method, "method"); GLADE_HOOKUP_OBJECT (convpreset_editor, frame8, "frame8"); GLADE_HOOKUP_OBJECT (convpreset_editor, alignment20, "alignment20"); + GLADE_HOOKUP_OBJECT (convpreset_editor, vbox35, "vbox35"); GLADE_HOOKUP_OBJECT (convpreset_editor, table1, "table1"); GLADE_HOOKUP_OBJECT (convpreset_editor, _8bit, "_8bit"); GLADE_HOOKUP_OBJECT (convpreset_editor, _16bit, "_16bit"); GLADE_HOOKUP_OBJECT (convpreset_editor, _24bit, "_24bit"); GLADE_HOOKUP_OBJECT (convpreset_editor, _32bit, "_32bit"); GLADE_HOOKUP_OBJECT (convpreset_editor, _32bitfloat, "_32bitfloat"); + GLADE_HOOKUP_OBJECT (convpreset_editor, hbox103, "hbox103"); + GLADE_HOOKUP_OBJECT (convpreset_editor, label123, "label123"); + GLADE_HOOKUP_OBJECT (convpreset_editor, defaultfmt, "defaultfmt"); GLADE_HOOKUP_OBJECT (convpreset_editor, label118, "label118"); GLADE_HOOKUP_OBJECT_NO_REF (convpreset_editor, dialog_action_area6, "dialog_action_area6"); GLADE_HOOKUP_OBJECT (convpreset_editor, convpreset_cancel, "convpreset_cancel"); |