summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--deadbeef.h20
-rw-r--r--plugins.c3
-rw-r--r--plugins/dca/Makefile.am2
-rw-r--r--plugins/dsp_libsrc/Makefile.am3
-rw-r--r--plugins/gtkui/converter.c135
-rw-r--r--plugins/musepack/Makefile.am2
6 files changed, 133 insertions, 32 deletions
diff --git a/deadbeef.h b/deadbeef.h
index 2357c407..57cc035b 100644
--- a/deadbeef.h
+++ b/deadbeef.h
@@ -32,6 +32,7 @@
#include <stdio.h>
#ifdef __cplusplus
+#define restrict // shut up g++
extern "C" {
#endif
@@ -280,6 +281,14 @@ typedef struct DB_md5_s {
char data[88];
} DB_md5_t;
+typedef struct {
+ int bps;
+ int is_float; // bps must be 32 if this is true
+ int channels;
+ int samplerate;
+ uint32_t channelmask;
+} ddb_waveformat_t;
+
// forward decl for plugin struct
struct DB_plugin_s;
@@ -533,6 +542,9 @@ typedef struct {
void (*plug_trigger_event_playlistchanged) (void);
// misc utilities
int (*is_local_file) (const char *fname); // returns 1 for local filename, 0 otherwise
+
+ // pcm utilities
+ int (*pcm_convert) (const ddb_waveformat_t * restrict inputfmt, const char * restrict input, const ddb_waveformat_t * restrict outputfmt, char * restrict output, int inputsize);
} DB_functions_t;
enum {
@@ -651,14 +663,6 @@ enum {
DDB_SPEAKER_TOP_BACK_RIGHT = 0x20000
};
-typedef struct {
- int bps;
- int is_float; // bps must be 32 if this is true
- int channels;
- int samplerate;
- uint32_t channelmask;
-} ddb_waveformat_t;
-
typedef struct DB_fileinfo_s {
struct DB_decoder_s *plugin;
diff --git a/plugins.c b/plugins.c
index 238d6524..645f3707 100644
--- a/plugins.c
+++ b/plugins.c
@@ -42,6 +42,7 @@
#include "conf.h"
#include "junklib.h"
#include "vfs.h"
+#include "premix.h"
#define trace(...) { fprintf(stderr, __VA_ARGS__); }
//#define trace(fmt,...)
@@ -268,6 +269,8 @@ static DB_functions_t deadbeef_api = {
.plug_trigger_event_playlistchanged = plug_trigger_event_playlistchanged,
// misc utilities
.is_local_file = plug_is_local_file,
+ // pcm utilities
+ .pcm_convert = pcm_convert,
};
DB_functions_t *deadbeef = &deadbeef_api;
diff --git a/plugins/dca/Makefile.am b/plugins/dca/Makefile.am
index 4a2b4b5a..9819c5aa 100644
--- a/plugins/dca/Makefile.am
+++ b/plugins/dca/Makefile.am
@@ -25,6 +25,6 @@ bitstream.h
dca_la_LDFLAGS = -module
dca_la_LIBADD = $(LDADD) -lm
-AM_CFLAGS = $(CFLAGS) -fPIC
+AM_CFLAGS = $(CFLAGS) -fPIC -std=c99
endif
diff --git a/plugins/dsp_libsrc/Makefile.am b/plugins/dsp_libsrc/Makefile.am
index 798be19f..42c6a347 100644
--- a/plugins/dsp_libsrc/Makefile.am
+++ b/plugins/dsp_libsrc/Makefile.am
@@ -7,7 +7,6 @@ dsp_libsrc_la_LDFLAGS = -module
dsp_libsrc_la_LIBADD = $(LIBADD) $(LIBSAMPLERATE_DEPS_LIBS)
-dsp_libsrc_la_CFLAGS = $(CFLAGS) $(LIBSAMPLERATE_DEPS_CFLAGS)
+dsp_libsrc_la_CFLAGS = $(CFLAGS) $(LIBSAMPLERATE_DEPS_CFLAGS) -std=c99
-AM_CFLAGS = -std=c99
endif
diff --git a/plugins/gtkui/converter.c b/plugins/gtkui/converter.c
index af578f87..18a7fb82 100644
--- a/plugins/gtkui/converter.c
+++ b/plugins/gtkui/converter.c
@@ -555,6 +555,8 @@ on_converter_ok_clicked (GtkButton *button,
if (!p) {
return;
}
+ combo = GTK_COMBO_BOX (lookup_widget (converter, "dsp_preset"));
+ int dsp_idx = gtk_combo_box_get_active (combo);
gtk_widget_destroy (converter);
converter = NULL;
@@ -580,7 +582,14 @@ on_converter_ok_clicked (GtkButton *button,
}
deadbeef->pl_unlock ();
- // ... convert ...
+ ddb_dsp_preset_t *dsp_preset = NULL;
+ if (dsp_idx > 0) {
+ dsp_preset = dsp_presets;
+ while (dsp_preset && dsp_idx--) {
+ dsp_preset = dsp_preset->next;
+ }
+ }
+
for (n = 0; n < nsel; n++) {
it = items[n];
DB_decoder_t *dec = NULL;
@@ -600,30 +609,116 @@ on_converter_ok_clicked (GtkButton *button,
char enc[1024];
snprintf (enc, sizeof (enc), p->encoder, out);
fprintf (stderr, "executing: %s\n", enc);
- FILE *fp = popen (enc, "w");
- if (!fp) {
- fprintf (stderr, "converter: failed to open encoder\n");
+ FILE *enc_pipe = NULL;
+ FILE *temp_file = NULL;
+
+ if (p->method == DDB_ENCODER_METHOD_FILE) {
+ const char *temp_file_name = "/tmp/deadbeef-converter.wav"; // FIXME
+ temp_file = fopen (temp_file_name, "w+b");
+ if (!temp_file) {
+ fprintf (stderr, "converter: failed to open temp file %s\n", temp_file_name);
+ if (fileinfo) {
+ dec->free (fileinfo);
+ }
+ continue;
+ }
}
else {
- // write wave header
- char wavehdr[] = {
- 0x52, 0x49, 0x46, 0x46, 0x24, 0x70, 0x0d, 0x00, 0x57, 0x41, 0x56, 0x45, 0x66, 0x6d, 0x74, 0x20, 0x10, 0x00, 0x00, 0x00, 0x01, 0x00, 0x02, 0x00, 0x44, 0xac, 0x00, 0x00, 0x10, 0xb1, 0x02, 0x00, 0x04, 0x00, 0x10, 0x00, 0x64, 0x61, 0x74, 0x61
- };
- fwrite (wavehdr, 1, sizeof (wavehdr), fp);
- uint32_t size = (it->endsample-it->startsample) * fileinfo->fmt.channels * fileinfo->fmt.bps / 8;
- fwrite (&size, 1, sizeof (size), fp);
-
- int bs = 8192;
- char buffer[bs];
- for (;;) {
- int sz = dec->read (fileinfo, buffer, bs);
- fwrite (buffer, 1, sz, fp);
- if (sz != bs) {
- break;
+ enc_pipe = popen (enc, "w");
+ if (!enc_pipe) {
+ fprintf (stderr, "converter: failed to open encoder\n");
+ if (temp_file) {
+ fclose (temp_file);
+ }
+ if (fileinfo) {
+ dec->free (fileinfo);
}
+ continue;
+ }
+ }
+
+ if (!temp_file) {
+ temp_file = enc_pipe;
+ }
+
+ // write wave header
+ char wavehdr[] = {
+ 0x52, 0x49, 0x46, 0x46, 0x24, 0x70, 0x0d, 0x00, 0x57, 0x41, 0x56, 0x45, 0x66, 0x6d, 0x74, 0x20, 0x10, 0x00, 0x00, 0x00, 0x01, 0x00, 0x02, 0x00, 0x44, 0xac, 0x00, 0x00, 0x10, 0xb1, 0x02, 0x00, 0x04, 0x00, 0x10, 0x00, 0x64, 0x61, 0x74, 0x61
+ };
+ int header_written = 0;
+ uint32_t outsize = 0;
+ uint32_t outsr = fileinfo->fmt.samplerate;
+ uint16_t outch = fileinfo->fmt.channels;
+ uint16_t outbps = fileinfo->fmt.bps;
+
+ int samplesize = fileinfo->fmt.channels * fileinfo->fmt.bps / 8;
+ int bs = 10250 * samplesize;
+ char buffer[bs * 4];
+ int dspsize = bs / samplesize * sizeof (float) * fileinfo->fmt.channels;
+ char dspbuffer[dspsize * 4];
+ int eof = 0;
+ for (;;) {
+ if (eof) {
+ break;
}
+ int sz = dec->read (fileinfo, buffer, bs);
+
+ if (sz != bs) {
+ eof = 1;
+ }
+ float ratio = 1;
+ if (dsp_preset) {
+ ddb_waveformat_t fmt;
+ memcpy (&fmt, &fileinfo->fmt, sizeof (fmt));
+ fmt.bps = 32;
+ fmt.is_float = 1;
+ deadbeef->pcm_convert (&fileinfo->fmt, buffer, &fmt, dspbuffer, sz);
+
+ DB_dsp_instance_t *dsp = dsp_preset->chain;
+ int frames = sz / samplesize;
+ while (dsp) {
+ frames = dsp->plugin->process (dsp, (float *)dspbuffer, frames, &fmt.samplerate, &fmt.channels);
+ dsp = dsp->next;
+ }
+
+ deadbeef->pcm_convert (&fmt, dspbuffer, &fileinfo->fmt, buffer, frames * sizeof (float) * fmt.channels);
+ outsr = fmt.samplerate;
+ outch = fmt.channels;
+ sz = frames * samplesize;
+ }
+ outsize += sz;
+
+ if (!header_written) {
+ uint32_t size = (it->endsample-it->startsample) * fileinfo->fmt.channels * fileinfo->fmt.bps / 8;
+
+ if (outsr != fileinfo->fmt.samplerate) {
+ uint64_t temp = size;
+ temp *= outsr;
+ temp /= fileinfo->fmt.samplerate;
+ size = temp;
+ }
+
+ memcpy (&wavehdr[22], &outch, 2);
+ memcpy (&wavehdr[24], &outsr, 4);
+ memcpy (&wavehdr[34], &outbps, 2);
+
+ fwrite (wavehdr, 1, sizeof (wavehdr), temp_file);
+ fwrite (&size, 1, sizeof (size), temp_file);
+ header_written = 1;
+ }
+
+ fwrite (buffer, 1, sz, temp_file);
+ }
+ if (temp_file && temp_file != enc_pipe) {
+ fclose (temp_file);
+ }
+
+ if (p->method == DDB_ENCODER_METHOD_FILE) {
+ enc_pipe = popen (enc, "w");
+ }
- pclose (fp);
+ if (enc_pipe) {
+ pclose (enc_pipe);
}
dec->free (fileinfo);
}
diff --git a/plugins/musepack/Makefile.am b/plugins/musepack/Makefile.am
index 213fee32..c82490aa 100644
--- a/plugins/musepack/Makefile.am
+++ b/plugins/musepack/Makefile.am
@@ -27,6 +27,6 @@ mpc/minimax.h
musepack_la_LDFLAGS = -module
musepack_la_LIBADD = $(LDADD) -lm
-AM_CFLAGS = $(CFLAGS) -fPIC
+AM_CFLAGS = $(CFLAGS) -fPIC -std=c99
endif