summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGravatar waker <wakeroid@gmail.com>2011-03-14 22:08:10 +0100
committerGravatar waker <wakeroid@gmail.com>2011-03-14 22:21:38 +0100
commit5f38b54305d03202e67ec4f5a1cbc09a45366828 (patch)
treecf52bc65e2af62edc145b731617b2e571b11f8a6
parent167aec58c1adcdf2309fd934d9ee82bb830ceab1 (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.c1
-rw-r--r--plugins/converter/callbacks.h4
-rw-r--r--plugins/converter/converter.c103
-rw-r--r--plugins/converter/converter.glade284
-rw-r--r--plugins/converter/converter.h7
-rw-r--r--plugins/converter/convgui.c125
-rw-r--r--plugins/converter/interface.c56
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");