summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Makefile.am4
-rw-r--r--configure.ac2
-rw-r--r--deadbeef.h72
-rw-r--r--main.c29
-rw-r--r--playback.h34
-rw-r--r--playlist.c1
-rw-r--r--plugins.c10
-rw-r--r--plugins/alsa/alsa.c197
-rw-r--r--plugins/dumb/Makefile.am2
-rw-r--r--plugins/dumb/cdumb.c28
-rw-r--r--plugins/dumb/dumb-kode54/src/it/loadmod.c4
-rw-r--r--plugins/dumb/dumb-kode54/src/it/loadmod2.c4
-rw-r--r--plugins/dumb/dumb-kode54/src/it/readmod.c8
-rw-r--r--plugins/dumb/dumb-kode54/src/it/readmod2.c4
-rw-r--r--plugins/gtkui/gtkui.c14
-rw-r--r--plugins/mpgmad/mpgmad.c49
-rw-r--r--plugins/mpris/mpris.c20
-rw-r--r--plugins/supereq/supereq.c2
-rw-r--r--plugins/wavpack/wavpack.c125
-rw-r--r--premix.c294
-rw-r--r--premix.h27
-rwxr-xr-xscripts/configure_minimal.sh1
-rw-r--r--scripts/pluginstall.sh37
-rwxr-xr-xscripts/quickinstall.sh37
-rw-r--r--streamer.c225
25 files changed, 804 insertions, 426 deletions
diff --git a/Makefile.am b/Makefile.am
index eb1eb738..cab4aa3b 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -21,9 +21,9 @@ deadbeef_SOURCES =\
plugins.c plugins.h moduleconf.h\
playlist.c playlist.h \
streamer.c streamer.h\
+ premix.c premix.h\
messagepump.c messagepump.h\
conf.c conf.h\
- playback.h\
threading_pthread.c threading.h\
volume.c volume.h\
junklib.h junklib.c utf8.c utf8.h u8_lc_map.h\
@@ -36,7 +36,7 @@ deadbeef_SOURCES =\
sdkdir = $(pkgincludedir)
sdk_HEADERS = deadbeef.h
-deadbeef_LDADD = $(LDADD) $(DEPS_LIBS) $(ICONV_LIB) -lm
+deadbeef_LDADD = $(LDADD) $(DEPS_LIBS) $(ICONV_LIB) -lm -ldl -lpthread
AM_CFLAGS = $(DEPS_CFLAGS) -std=c99
AM_CPPFLAGS = $(DEPS_CFLAGS)
diff --git a/configure.ac b/configure.ac
index 36f5b1b1..eacf3af7 100644
--- a/configure.ac
+++ b/configure.ac
@@ -491,7 +491,7 @@ fi
fi
if test "x$enable_mpris" != "xno" ; then
- PKG_CHECK_MODULES(MPRIS_DEPS, gio-2.0 glib-2.0 >= 2.26.0, HAVE_MPRIS=yes, HAVE_MPRIS=no)
+ PKG_CHECK_MODULES(MPRIS_DEPS, indicate >= 0.4.4 glib-2.0 >= 2.26.0, HAVE_MPRIS=yes, HAVE_MPRIS=no)
fi
PLUGINS_DIRS="plugins/lastfm plugins/mpgmad plugins/vorbis plugins/flac plugins/wavpack plugins/sndfile plugins/vfs_curl plugins/cdda plugins/gtkui plugins/alsa plugins/ffmpeg plugins/hotkeys plugins/oss plugins/artwork plugins/adplug plugins/ffap plugins/sid plugins/nullout plugins/supereq plugins/vtx plugins/gme plugins/dumb plugins/pulse plugins/notify plugins/musepack plugins/wildmidi plugins/tta plugins/dca plugins/aac plugins/mms plugins/shn plugins/ao plugins/shellexec plugins/mpris"
diff --git a/deadbeef.h b/deadbeef.h
index 2826502e..4296a7e7 100644
--- a/deadbeef.h
+++ b/deadbeef.h
@@ -622,20 +622,63 @@ typedef struct DB_plugin_s {
const char *configdialog;
} DB_plugin_t;
-typedef struct DB_fileinfo_s {
- struct DB_decoder_s *plugin;
+// file format stuff
+
+// channel mask - combine following flags to tell streamer which channels are
+// present in input/output streams
+enum {
+ DDB_SPEAKER_FRONT_LEFT = 0x1,
+ DDB_SPEAKER_FRONT_RIGHT = 0x2,
+ DDB_SPEAKER_FRONT_CENTER = 0x4,
+ DDB_SPEAKER_LOW_FREQUENCY = 0x8,
+ DDB_SPEAKER_BACK_LEFT = 0x10,
+ DDB_SPEAKER_BACK_RIGHT = 0x20,
+ DDB_SPEAKER_FRONT_LEFT_OF_CENTER = 0x40,
+ DDB_SPEAKER_FRONT_RIGHT_OF_CENTER = 0x80,
+ DDB_SPEAKER_BACK_CENTER = 0x100,
+ DDB_SPEAKER_SIDE_LEFT = 0x200,
+ DDB_SPEAKER_SIDE_RIGHT = 0x400,
+ DDB_SPEAKER_TOP_CENTER = 0x800,
+ DDB_SPEAKER_TOP_FRONT_LEFT = 0x1000,
+ DDB_SPEAKER_TOP_FRONT_CENTER = 0x2000,
+ DDB_SPEAKER_TOP_FRONT_RIGHT = 0x4000,
+ DDB_SPEAKER_TOP_BACK_LEFT = 0x8000,
+ DDB_SPEAKER_TOP_BACK_CENTER = 0x10000,
+ DDB_SPEAKER_TOP_BACK_RIGHT = 0x20000
+};
+
+typedef struct {
int bps;
+ int is_float; // bps must be 32 if this is true
+ int is_multichannel; // usually 0, in which case channels=1 is mono, and channels=2 is stereo
int channels;
int samplerate;
+ uint32_t channelmask;
+} ddb_waveformat_t;
+
+typedef struct DB_fileinfo_s {
+ struct DB_decoder_s *plugin;
+
+ // these parameters should be set in decoder->open
+ ddb_waveformat_t fmt;
+
+ // readpos should be updated to current decoder time (in seconds)
float readpos;
+
+ // this is the (optional) file handle, that can be used by streamer to
+ // request interruption of current read operation
DB_FILE *file;
} DB_fileinfo_t;
+enum {
+ DDB_DECODER_HINT_16BIT = 0x1, // that flag means streamer prefers 16 bit streams for performance reasons
+};
+
// decoder plugin
typedef struct DB_decoder_s {
DB_plugin_t plugin;
- DB_fileinfo_t *(*open) (void);
+ DB_fileinfo_t *(*open) (uint32_t hints);
// init is called to prepare song to be started
int (*init) (DB_fileinfo_t *info, DB_playItem_t *it);
@@ -645,12 +688,7 @@ typedef struct DB_decoder_s {
// read is called by streamer to decode specified number of bytes
// must return number of bytes that were successfully decoded (sample aligned)
-
- // read_int16 must always output 16 bit signed integer samples
- int (*read_int16) (DB_fileinfo_t *info, char *buffer, int size);
-
- // read_float32 must always output 32 bit floating point samples
- int (*read_float32) (DB_fileinfo_t *info, char *buffer, int size);
+ int (*read) (DB_fileinfo_t *info, char *buffer, int nbytes);
int (*seek) (DB_fileinfo_t *info, float seconds);
@@ -684,8 +722,8 @@ typedef struct DB_output_s {
int (*init) (void);
// free is called if output plugin was changed to another, or unload is about to happen
int (*free) (void);
- // reconfigure output to another samplerate, if supported
- int (*change_rate) (int rate);
+ // reconfigure output to another format, if supported
+ void (*setformat) (ddb_waveformat_t *fmt);
// play, stop, pause, unpause are called by deadbeef in response to user
// events, or as part of streaming process
int (*play) (void);
@@ -694,15 +732,11 @@ typedef struct DB_output_s {
int (*unpause) (void);
// one of output_state_t enum values
int (*state) (void);
- // following functions must return output sampling rate, bits per sample and number
- // of channels
- int (*samplerate) (void);
- int (*bitspersample) (void);
- int (*channels) (void);
- // must return 0 for little endian output, or 1 for big endian
- int (*endianness) (void);
// soundcard enumeration (can be NULL)
void (*enum_soundcards) (void (*callback)(const char *name, const char *desc, void*), void *userdata);
+
+ // parameters of current output
+ ddb_waveformat_t fmt;
} DB_output_t;
// dsp plugin
@@ -711,7 +745,7 @@ typedef struct DB_dsp_s {
// process gets called before SRC
// stereo samples are stored in interleaved format
// stereo sample is counted as 1 sample
- int (*process_int16) (int16_t *samples, int nsamples, int nch, int bps, int srate);
+ int (*process) (char * restrict samples, ddb_waveformat_t * restrict fmt);
void (*reset) (void);
void (*enable) (int e);
int (*enabled) (void);
diff --git a/main.c b/main.c
index b71f456f..d5a54822 100644
--- a/main.c
+++ b/main.c
@@ -47,7 +47,6 @@
#include <unistd.h>
#include "gettext.h"
#include "playlist.h"
-#include "playback.h"
#include "threading.h"
#include "messagepump.h"
#include "streamer.h"
@@ -368,6 +367,7 @@ player_mainloop (void) {
uint32_t p1;
uint32_t p2;
while (messagepump_pop(&msg, &ctx, &p1, &p2) != -1) {
+ DB_output_t *output = plug_get_output ();
switch (msg) {
case M_REINIT_SOUND:
plug_reinit_sound ();
@@ -377,7 +377,7 @@ player_mainloop (void) {
return;
case M_PLAYSONG:
if (p1) {
- p_stop ();
+ output->stop ();
pl_playqueue_clear ();
streamer_set_nextsong (0, 1);
}
@@ -386,7 +386,7 @@ player_mainloop (void) {
}
break;
case M_PLAYSONGNUM:
- p_stop ();
+ output->stop ();
pl_playqueue_clear ();
streamer_set_nextsong (p1, 1);
break;
@@ -394,25 +394,25 @@ player_mainloop (void) {
streamer_set_nextsong (-2, 0);
break;
case M_NEXTSONG:
- p_stop ();
+ output->stop ();
streamer_move_to_nextsong (1);
break;
case M_PREVSONG:
- p_stop ();
+ output->stop ();
streamer_move_to_prevsong ();
break;
case M_PAUSESONG:
- if (p_get_state () == OUTPUT_STATE_PAUSED) {
- p_unpause ();
+ if (output->state () == OUTPUT_STATE_PAUSED) {
+ output->unpause ();
plug_trigger_event_paused (0);
}
else {
- p_pause ();
+ output->pause ();
plug_trigger_event_paused (1);
}
break;
case M_PLAYRANDOM:
- p_stop ();
+ output->stop ();
streamer_move_to_randomsong ();
break;
case M_PLAYLISTREFRESH:
@@ -488,10 +488,11 @@ sigsegv_handler (int sig) {
void
save_resume_state (void) {
playItem_t *trk = streamer_get_playing_track ();
+ DB_output_t *output = plug_get_output ();
float playpos = -1;
int playtrack = -1;
int playlist = streamer_get_current_playlist ();
- int paused = (p_get_state () == OUTPUT_STATE_PAUSED);
+ int paused = (output->state () == OUTPUT_STATE_PAUSED);
if (trk && playlist >= 0) {
playtrack = str_get_idx_of (trk);
playpos = streamer_get_playpos ();
@@ -506,7 +507,8 @@ save_resume_state (void) {
void
restore_resume_state (void) {
- if (conf_get_int ("resume_last_session", 0) && p_isstopped ()) {
+ DB_output_t *output = plug_get_output ();
+ if (conf_get_int ("resume_last_session", 0) && output->state () == OUTPUT_STATE_STOPPED) {
int plt = conf_get_int ("resume.playlist", -1);
int track = conf_get_int ("resume.track", -1);
float pos = conf_get_float ("resume.position", -1);
@@ -811,9 +813,10 @@ main (int argc, char *argv[]) {
server_close ();
// stop streaming and playback before unloading plugins
- p_stop ();
+ DB_output_t *output = plug_get_output ();
+ output->stop ();
streamer_free ();
- p_free ();
+ output->free ();
// plugins might still hood references to playitems,
// and query configuration in background
diff --git a/playback.h b/playback.h
deleted file mode 100644
index 21ac74f1..00000000
--- a/playback.h
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
- 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, see <http://www.gnu.org/licenses/>.
-*/
-#ifndef __PLAYBACK_H
-#define __PLAYBACK_H
-
-#define p_init plug_get_output ()->init
-#define p_free plug_get_output ()->free
-#define p_play plug_get_output ()->play
-#define p_stop plug_get_output ()->stop
-#define p_pause plug_get_output ()->pause
-#define p_unpause plug_get_output ()->unpause
-#define p_get_rate plug_get_output ()->samplerate
-#define p_get_state plug_get_output ()->state
-
-#define p_state() (plug_get_output ()->state ())
-#define p_isstopped() (p_state () == OUTPUT_STATE_STOPPED)
-#define p_ispaused() (p_state () == OUTPUT_STATE_PAUSED)
-
-#endif // __PLAYBACK_H
diff --git a/playlist.c b/playlist.c
index 16cb424c..23c55650 100644
--- a/playlist.c
+++ b/playlist.c
@@ -39,7 +39,6 @@
#include "playlist.h"
#include "streamer.h"
#include "messagepump.h"
-#include "playback.h"
#include "plugins.h"
#include "junklib.h"
#include "vfs.h"
diff --git a/plugins.c b/plugins.c
index 0fc5ff48..cf6e68db 100644
--- a/plugins.c
+++ b/plugins.c
@@ -38,7 +38,6 @@
#include "playlist.h"
#include "volume.h"
#include "streamer.h"
-#include "playback.h"
#include "common.h"
#include "conf.h"
#include "junklib.h"
@@ -933,9 +932,10 @@ plug_select_output (void) {
void
plug_reinit_sound (void) {
- int state = p_get_state ();
+ DB_output_t *output = plug_get_output ();
+ int state = output->state ();
- p_free ();
+ output->free ();
DB_output_t *prev = plug_get_output ();
if (plug_select_output () < 0) {
@@ -944,13 +944,13 @@ plug_reinit_sound (void) {
output_plugin = prev;
}
streamer_reset (1);
- if (p_init () < 0) {
+ if (output->init () < 0) {
streamer_set_nextsong (-2, 0);
return;
}
if (state != OUTPUT_STATE_PAUSED && state != OUTPUT_STATE_STOPPED) {
- if (p_play () < 0) {
+ if (output->play () < 0) {
trace ("failed to reinit sound output\n");
streamer_set_nextsong (-2, 0);
}
diff --git a/plugins/alsa/alsa.c b/plugins/alsa/alsa.c
index 65178e55..887bc205 100644
--- a/plugins/alsa/alsa.c
+++ b/plugins/alsa/alsa.c
@@ -23,8 +23,8 @@
#include "../../deadbeef.h"
#include "../../config.h"
-//#define trace(...) { fprintf(stderr, __VA_ARGS__); }
-#define trace(fmt,...)
+#define trace(...) { fprintf(stderr, __VA_ARGS__); }
+//#define trace(fmt,...)
#define min(x,y) ((x)<(y)?(x):(y))
@@ -41,8 +41,7 @@ DB_functions_t *deadbeef;
static snd_pcm_t *audio;
static int alsa_terminate;
-static int requested_rate = -1;
-static int alsa_rate = 44100;
+static ddb_waveformat_t requested_fmt;
static int state; // one of output_state_t
static uintptr_t mutex;
static intptr_t alsa_tid;
@@ -90,8 +89,8 @@ palsa_init (void);
static int
palsa_free (void);
-static int
-palsa_change_rate (int rate);
+static void
+palsa_setformat (ddb_waveformat_t *fmt);
static int
palsa_play (void);
@@ -106,12 +105,6 @@ static int
palsa_unpause (void);
static int
-palsa_get_rate (void);
-
-static int
-palsa_get_bps (void);
-
-static int
palsa_get_channels (void);
static int
@@ -121,9 +114,8 @@ static void
palsa_enum_soundcards (void (*callback)(const char *name, const char *desc, void*), void *userdata);
static int
-palsa_set_hw_params (int samplerate) {
+palsa_set_hw_params (ddb_waveformat_t *fmt) {
snd_pcm_hw_params_t *hw_params = NULL;
-// int alsa_resample = conf_get_int ("alsa.resample", 0);
int err = 0;
if ((err = snd_pcm_hw_params_malloc (&hw_params)) < 0) {
@@ -144,22 +136,46 @@ palsa_set_hw_params (int samplerate) {
goto error;
}
- snd_pcm_format_t fmt;
+ snd_pcm_format_t sample_fmt;
+
+ switch (fmt->bps) {
+ case 8:
+ sample_fmt = SND_PCM_FORMAT_S8;
+ break;
+ case 16:
+#if WORDS_BIGENDIAN
+ sample_fmt = SND_PCM_FORMAT_S16_BE;
+#else
+ sample_fmt = SND_PCM_FORMAT_S16_LE;
+#endif
+ break;
+ case 24:
+#if WORDS_BIGENDIAN
+ sample_fmt = SND_PCM_FORMAT_S24_3BE;
+#else
+ sample_fmt = SND_PCM_FORMAT_S24_3LE;
+#endif
+ break;
+ case 32:
#if WORDS_BIGENDIAN
- fmt = SND_PCM_FORMAT_S16_BE;
+ sample_fmt = SND_PCM_FORMAT_S32_BE;
#else
- fmt = SND_PCM_FORMAT_S16_LE;
+ sample_fmt = SND_PCM_FORMAT_S32_LE;
#endif
- if ((err = snd_pcm_hw_params_set_format (audio, hw_params, fmt)) < 0) {
+ break;
+ };
+
+ //sample_fmt = SND_PCM_FORMAT_S16_LE;
+ if ((err = snd_pcm_hw_params_set_format (audio, hw_params, sample_fmt)) < 0) {
fprintf (stderr, "cannot set sample format (%s)\n",
snd_strerror (err));
goto error;
}
- snd_pcm_hw_params_get_format (hw_params, &fmt);
+ snd_pcm_hw_params_get_format (hw_params, &sample_fmt);
trace ("chosen sample format: %04Xh\n", (int)fmt);
- int val = samplerate;
+ int val = fmt->samplerate;
int ret = 0;
if ((err = snd_pcm_hw_params_set_rate_resample (audio, hw_params, conf_alsa_resample)) < 0) {
@@ -173,10 +189,10 @@ palsa_set_hw_params (int samplerate) {
snd_strerror (err));
goto error;
}
- alsa_rate = val;
- trace ("chosen samplerate: %d Hz\n", alsa_rate);
+ plugin.fmt.samplerate = val;
+ trace ("chosen samplerate: %d Hz\n", val);
- if ((err = snd_pcm_hw_params_set_channels (audio, hw_params, 2)) < 0) {
+ if ((err = snd_pcm_hw_params_set_channels (audio, hw_params, fmt->channels)) < 0) {
fprintf (stderr, "cannot set channel count (%s)\n",
snd_strerror (err));
goto error;
@@ -202,6 +218,60 @@ palsa_set_hw_params (int samplerate) {
snd_strerror (err));
goto error;
}
+
+ plugin.fmt.is_float = 0;
+ switch (sample_fmt) {
+ case SND_PCM_FORMAT_S8:
+ plugin.fmt.bps = 8;
+ break;
+ case SND_PCM_FORMAT_S16_BE:
+ case SND_PCM_FORMAT_S16_LE:
+ plugin.fmt.bps = 16;
+ break;
+ case SND_PCM_FORMAT_S24_3BE:
+ case SND_PCM_FORMAT_S24_3LE:
+ plugin.fmt.bps = 24;
+ break;
+ case SND_PCM_FORMAT_S32_BE:
+ case SND_PCM_FORMAT_S32_LE:
+ plugin.fmt.bps = 32;
+ break;
+ case SND_PCM_FORMAT_FLOAT_LE:
+ case SND_PCM_FORMAT_FLOAT_BE:
+ plugin.fmt.bps = 32;
+ plugin.fmt.is_float = 1;
+ break;
+ }
+
+ trace ("chosen bps: %d (%s)\n", plugin.fmt.bps, plugin.fmt.is_float ? "float" : "int");
+
+ plugin.fmt.channels = nchan;
+ plugin.fmt.is_multichannel = 0;
+ plugin.fmt.channelmask = 0;
+ if (nchan == 1) {
+ plugin.fmt.channelmask = DDB_SPEAKER_FRONT_LEFT;
+ }
+ if (nchan == 2) {
+ plugin.fmt.channelmask = DDB_SPEAKER_FRONT_LEFT | DDB_SPEAKER_FRONT_RIGHT;
+ }
+ if (nchan == 3) {
+ plugin.fmt.channelmask = DDB_SPEAKER_FRONT_LEFT | DDB_SPEAKER_FRONT_RIGHT | DDB_SPEAKER_LOW_FREQUENCY;
+ }
+ if (nchan == 4) {
+ plugin.fmt.channelmask = DDB_SPEAKER_FRONT_LEFT | DDB_SPEAKER_FRONT_RIGHT | DDB_SPEAKER_BACK_LEFT | DDB_SPEAKER_BACK_RIGHT;
+ }
+ if (nchan == 5) {
+ plugin.fmt.channelmask = DDB_SPEAKER_FRONT_LEFT | DDB_SPEAKER_FRONT_RIGHT | DDB_SPEAKER_BACK_LEFT | DDB_SPEAKER_BACK_RIGHT | DDB_SPEAKER_FRONT_CENTER;
+ }
+ if (nchan == 6) {
+ plugin.fmt.channelmask = DDB_SPEAKER_FRONT_LEFT | DDB_SPEAKER_FRONT_RIGHT | DDB_SPEAKER_BACK_LEFT | DDB_SPEAKER_BACK_RIGHT | DDB_SPEAKER_FRONT_CENTER | DDB_SPEAKER_LOW_FREQUENCY;
+ }
+ if (nchan == 7) {
+ plugin.fmt.channelmask = DDB_SPEAKER_FRONT_LEFT | DDB_SPEAKER_FRONT_RIGHT | DDB_SPEAKER_BACK_LEFT | DDB_SPEAKER_BACK_RIGHT | DDB_SPEAKER_FRONT_CENTER | DDB_SPEAKER_SIDE_LEFT | DDB_SPEAKER_SIDE_RIGHT;
+ }
+ if (nchan == 8) {
+ plugin.fmt.channelmask = DDB_SPEAKER_FRONT_LEFT | DDB_SPEAKER_FRONT_RIGHT | DDB_SPEAKER_BACK_LEFT | DDB_SPEAKER_BACK_RIGHT | DDB_SPEAKER_FRONT_CENTER | DDB_SPEAKER_SIDE_LEFT | DDB_SPEAKER_SIDE_RIGHT | DDB_SPEAKER_LOW_FREQUENCY;
+ }
error:
if (hw_params) {
snd_pcm_hw_params_free (hw_params);
@@ -232,11 +302,11 @@ palsa_init (void) {
mutex = deadbeef->mutex_create ();
- if (requested_rate != -1) {
- alsa_rate = requested_rate;
+ if (requested_fmt.samplerate != 0) {
+ memcpy (&plugin.fmt, &requested_fmt, sizeof (ddb_waveformat_t));
}
- if (palsa_set_hw_params (alsa_rate) < 0) {
+ if (palsa_set_hw_params (&plugin.fmt) < 0) {
goto open_error;
}
@@ -308,28 +378,27 @@ open_error:
return -1;
}
-int
-palsa_change_rate (int rate) {
- trace ("palsa_change_rate: %d\n", rate);
- requested_rate = rate;
+void
+palsa_setformat (ddb_waveformat_t *fmt) {
+ memcpy (&requested_fmt, fmt, sizeof (ddb_waveformat_t));
+ trace ("palsa_setformat %dbit %s %s %dch %dHz channelmask=%X\n", fmt->bps, fmt->is_float ? "float" : "int", fmt->is_multichannel ? "multichannel" : "", fmt->channels, fmt->samplerate, fmt->channelmask);
if (!audio) {
- return alsa_rate;
+ return;
}
- if (rate == alsa_rate) {
- trace ("palsa_change_rate %d: ignored\n", rate);
- return rate;
+ if (!memcmp (fmt, &plugin.fmt, sizeof (ddb_waveformat_t))) {
+ trace ("palsa_setformat ignored\n");
+ return;
}
state = OUTPUT_STATE_STOPPED;
LOCK;
snd_pcm_drop (audio);
- int ret = palsa_set_hw_params (rate);
+ int ret = palsa_set_hw_params (fmt);
UNLOCK;
if (ret < 0) {
- trace ("palsa_change_rate: impossible to set samplerate to %d\n", rate);
- return alsa_rate;
+ trace ("palsa_change_rate: impossible to set requested format\n");
+ return;
}
- trace ("chosen samplerate: %d\n", alsa_rate);
- return alsa_rate;
+ trace ("new format %dbit %s %s %dch %dHz channelmask=%X\n", plugin.fmt.bps, plugin.fmt.is_float ? "float" : "int", plugin.fmt.is_multichannel ? "multichannel" : "", plugin.fmt.channels, plugin.fmt.samplerate, plugin.fmt.channelmask);
}
int
@@ -453,33 +522,6 @@ palsa_unpause (void) {
return 0;
}
-int
-palsa_get_rate (void) {
- if (!audio) {
- palsa_init ();
- }
- return alsa_rate;
-}
-
-int
-palsa_get_bps (void) {
- return 16;
-}
-
-int
-palsa_get_channels (void) {
- return 2;
-}
-
-static int
-palsa_get_endianness (void) {
-#if WORDS_BIGENDIAN
- return 1;
-#else
- return 0;
-#endif
-}
-
static void
palsa_thread (void *context) {
prctl (PR_SET_NAME, "deadbeef-alsa", 0, 0, 0, 0);
@@ -500,10 +542,10 @@ palsa_thread (void *context) {
break;
}
err = 0;
- char buf[period_size * 4];
- int bytes_to_write = palsa_callback (buf, period_size * 4);
+ char buf[period_size * (plugin.fmt.bps>>3) * plugin.fmt.channels];
+ int bytes_to_write = palsa_callback (buf, period_size * (plugin.fmt.bps>>3) * plugin.fmt.channels);
- if ( bytes_to_write >= 4 ) {
+ if (bytes_to_write >= (plugin.fmt.bps>>3) * plugin.fmt.channels) {
err = snd_pcm_writei (audio, buf, snd_pcm_bytes_to_frames(audio, bytes_to_write));
}
else {
@@ -541,7 +583,7 @@ palsa_thread (void *context) {
frames_to_deliver = snd_pcm_avail_update (audio);
}
UNLOCK;
- usleep (period_size * 1000000 / alsa_rate / 2);
+ usleep (period_size * 1000000 / plugin.fmt.samplerate / 2);
}
}
@@ -581,10 +623,10 @@ palsa_callback (char *stream, int len) {
);
#else
- int16_t ivolume = deadbeef->volume_get_amp () * 1000;
- for (int i = 0; i < bytesread/2; i++) {
- ((int16_t*)stream)[i] = (int16_t)(((int32_t)(((int16_t*)stream)[i])) * ivolume / 1000);
- }
+// int16_t ivolume = deadbeef->volume_get_amp () * 1000;
+// for (int i = 0; i < bytesread/2; i++) {
+// ((int16_t*)stream)[i] = (int16_t)(((int32_t)(((int16_t*)stream)[i])) * ivolume / 1000);
+// }
#endif
return bytesread;
}
@@ -682,15 +724,12 @@ static DB_output_t plugin = {
.plugin.configdialog = settings_dlg,
.init = palsa_init,
.free = palsa_free,
- .change_rate = palsa_change_rate,
+ .setformat = palsa_setformat,
.play = palsa_play,
.stop = palsa_stop,
.pause = palsa_pause,
.unpause = palsa_unpause,
.state = palsa_get_state,
- .samplerate = palsa_get_rate,
- .bitspersample = palsa_get_bps,
- .channels = palsa_get_channels,
- .endianness = palsa_get_endianness,
.enum_soundcards = palsa_enum_soundcards,
+ .fmt = {.samplerate = 44100}
};
diff --git a/plugins/dumb/Makefile.am b/plugins/dumb/Makefile.am
index de165bdd..f3bb7f46 100644
--- a/plugins/dumb/Makefile.am
+++ b/plugins/dumb/Makefile.am
@@ -5,7 +5,7 @@ EXTRA_DIST = $(dumbpath)/readme.txt $(dumbpath)/ChangeLog $(dumbpath)/licence.tx
pkglib_LTLIBRARIES = dumb.la
-AM_CFLAGS = $(CFLAGS) -I$(dumbpath)/include
+AM_CFLAGS = $(CFLAGS) -I$(dumbpath)/include -std=c99
dumb_la_LDFLAGS = -module -lm
dumb_la_SOURCES =\
diff --git a/plugins/dumb/cdumb.c b/plugins/dumb/cdumb.c
index b3f6bb2a..c7072fcc 100644
--- a/plugins/dumb/cdumb.c
+++ b/plugins/dumb/cdumb.c
@@ -51,7 +51,7 @@ static DUH*
open_module(const char *fname, const char *ext, int *start_order, int *is_it, int *is_dos, const char **filetype);
static DB_fileinfo_t *
-cdumb_open (void) {
+cdumb_open (uint32_t hints) {
DB_fileinfo_t *_info = malloc (sizeof (dumb_info_t));
memset (_info, 0, sizeof (dumb_info_t));
return _info;
@@ -75,10 +75,11 @@ cdumb_init (DB_fileinfo_t *_info, DB_playItem_t *it) {
dumb_it_do_initial_runthrough (info->duh);
_info->plugin = &plugin;
- _info->bps = 16;
- _info->channels = 2;
- _info->samplerate = deadbeef->conf_get_int ("synth.samplerate", 44100);
+ _info->fmt.bps = deadbeef->conf_get_int ("dumb.8bitoutput", 0) ? 8 : 16;
+ _info->fmt.channels = 2;
+ _info->fmt.samplerate = deadbeef->conf_get_int ("synth.samplerate", 44100);
_info->readpos = 0;
+ _info->fmt.channelmask = _info->fmt.channels == 1 ? DDB_SPEAKER_FRONT_LEFT : (DDB_SPEAKER_FRONT_LEFT | DDB_SPEAKER_FRONT_RIGHT);
if (cdumb_startrenderer (_info) < 0) {
return -1;
@@ -139,12 +140,13 @@ static int
cdumb_read (DB_fileinfo_t *_info, char *bytes, int size) {
trace ("cdumb_read req %d\n", size);
dumb_info_t *info = (dumb_info_t *)_info;
- int length = size / 4;
+ int samplesize = (_info->fmt.bps >> 3) * _info->fmt.channels;
+ int length = size / samplesize;
long ret;
- ret = duh_render (info->renderer, 16, 0, 1, 65536.f / _info->samplerate, length, bytes);
- _info->readpos += ret / (float)_info->samplerate;
- trace ("cdumb_read %d\n", ret*4);
- return ret*4;
+ ret = duh_render (info->renderer, _info->fmt.bps, 0, 1, 65536.f / _info->fmt.samplerate, length, bytes);
+ _info->readpos += ret / (float)_info->fmt.samplerate;
+ trace ("cdumb_read %d\n", ret*samplesize);
+ return ret*samplesize;
}
static int
@@ -159,8 +161,8 @@ cdumb_seek (DB_fileinfo_t *_info, float time) {
else {
time -= _info->readpos;
}
- int pos = time * _info->samplerate;
- duh_sigrenderer_generate_samples (info->renderer, 0, 65536.0f / _info->samplerate, pos, NULL);
+ int pos = time * _info->fmt.samplerate;
+ duh_sigrenderer_generate_samples (info->renderer, 0, 65536.0f / _info->fmt.samplerate, pos, NULL);
_info->readpos = duh_sigrenderer_get_position (info->renderer) / 65536.f;
return 0;
}
@@ -811,7 +813,9 @@ static const char *filetypes[] = { "IT", "XM", "S3M", "STM", "669", "PTM", "PSM"
static const char settings_dlg[] =
"property \"Resampling quality (0..2, higher is better)\" entry dumb.resampling_quality 2;\n"
+ "property \"8-bit output (default is 16)\" checkbox dumb.8bitoutput 0;\n"
;
+
// define plugin interface
static DB_decoder_t plugin = {
DB_PLUGIN_SET_API_VERSION
@@ -830,7 +834,7 @@ static DB_decoder_t plugin = {
.open = cdumb_open,
.init = cdumb_init,
.free = cdumb_free,
- .read_int16 = cdumb_read,
+ .read = cdumb_read,
.seek = cdumb_seek,
.insert = cdumb_insert,
.exts = exts,
diff --git a/plugins/dumb/dumb-kode54/src/it/loadmod.c b/plugins/dumb/dumb-kode54/src/it/loadmod.c
index 0b7dc618..dd43b611 100644
--- a/plugins/dumb/dumb-kode54/src/it/loadmod.c
+++ b/plugins/dumb/dumb-kode54/src/it/loadmod.c
@@ -26,7 +26,7 @@
* pointer to the DUH struct. When you have finished with it, you must
* pass the pointer to unload_duh() so that the memory can be freed.
*/
-DUH *dumb_load_mod_quick(const char *filename, int restrict)
+DUH *dumb_load_mod_quick(const char *filename, int restr)
{
DUH *duh;
DUMBFILE *f = dumbfile_open(filename);
@@ -34,7 +34,7 @@ DUH *dumb_load_mod_quick(const char *filename, int restrict)
if (!f)
return NULL;
- duh = dumb_read_mod_quick(f, restrict);
+ duh = dumb_read_mod_quick(f, restr);
dumbfile_close(f);
diff --git a/plugins/dumb/dumb-kode54/src/it/loadmod2.c b/plugins/dumb/dumb-kode54/src/it/loadmod2.c
index 7847d19f..c1f46e4c 100644
--- a/plugins/dumb/dumb-kode54/src/it/loadmod2.c
+++ b/plugins/dumb/dumb-kode54/src/it/loadmod2.c
@@ -21,9 +21,9 @@
-DUH *dumb_load_mod(const char *filename, int restrict)
+DUH *dumb_load_mod(const char *filename, int restr)
{
- DUH *duh = dumb_load_mod_quick(filename, restrict);
+ DUH *duh = dumb_load_mod_quick(filename, restr);
dumb_it_do_initial_runthrough(duh);
return duh;
}
diff --git a/plugins/dumb/dumb-kode54/src/it/readmod.c b/plugins/dumb/dumb-kode54/src/it/readmod.c
index a934af40..538d86ba 100644
--- a/plugins/dumb/dumb-kode54/src/it/readmod.c
+++ b/plugins/dumb/dumb-kode54/src/it/readmod.c
@@ -439,7 +439,7 @@ static DUMBFILE *dumbfile_buffer_mod_2(DUMBFILE *f, long *remain)
}
-static DUMB_IT_SIGDATA *it_mod_load_sigdata(DUMBFILE *f, int restrict)
+static DUMB_IT_SIGDATA *it_mod_load_sigdata(DUMBFILE *f, int restr)
{
DUMB_IT_SIGDATA *sigdata;
int n_channels;
@@ -554,7 +554,7 @@ static DUMB_IT_SIGDATA *it_mod_load_sigdata(DUMBFILE *f, int restrict)
}
// moo
- if ( restrict && sigdata->n_samples == 15 )
+ if ( restr && sigdata->n_samples == 15 )
{
free(sigdata);
dumbfile_close(f);
@@ -760,13 +760,13 @@ static DUMB_IT_SIGDATA *it_mod_load_sigdata(DUMBFILE *f, int restrict)
return sigdata;
}
-DUH *dumb_read_mod_quick(DUMBFILE *f, int restrict)
+DUH *dumb_read_mod_quick(DUMBFILE *f, int restr)
{
sigdata_t *sigdata;
DUH_SIGTYPE_DESC *descptr = &_dumb_sigtype_it;
- sigdata = it_mod_load_sigdata(f, restrict);
+ sigdata = it_mod_load_sigdata(f, restr);
if (!sigdata)
return NULL;
diff --git a/plugins/dumb/dumb-kode54/src/it/readmod2.c b/plugins/dumb/dumb-kode54/src/it/readmod2.c
index 102ead12..299c584e 100644
--- a/plugins/dumb/dumb-kode54/src/it/readmod2.c
+++ b/plugins/dumb/dumb-kode54/src/it/readmod2.c
@@ -21,9 +21,9 @@
-DUH *dumb_read_mod(DUMBFILE *f, int restrict)
+DUH *dumb_read_mod(DUMBFILE *f, int restr)
{
- DUH *duh = dumb_read_mod_quick(f, restrict);
+ DUH *duh = dumb_read_mod_quick(f, restr);
dumb_it_do_initial_runthrough(duh);
return duh;
}
diff --git a/plugins/gtkui/gtkui.c b/plugins/gtkui/gtkui.c
index 06ceb756..a2da9d74 100644
--- a/plugins/gtkui/gtkui.c
+++ b/plugins/gtkui/gtkui.c
@@ -45,8 +45,8 @@
#include "eq.h"
#include "actions.h"
-//#define trace(...) { fprintf(stderr, __VA_ARGS__); }
-#define trace(fmt,...)
+#define trace(...) { fprintf(stderr, __VA_ARGS__); }
+//#define trace(fmt,...)
static DB_gui_t plugin;
DB_functions_t *deadbeef;
@@ -154,15 +154,15 @@ update_songinfo (gpointer ctx) {
const char *mode;
char temp[20];
- if (c->channels <= 2) {
- mode = c->channels == 1 ? _("Mono") : _("Stereo");
+ if (c->fmt.channels <= 2) {
+ mode = c->fmt.channels == 1 ? _("Mono") : _("Stereo");
}
else {
- snprintf (temp, sizeof (temp), "%dch Multichannel", c->channels);
+ snprintf (temp, sizeof (temp), "%dch Multichannel", c->fmt.channels);
mode = temp;
}
- int samplerate = c->samplerate;
- int bitspersample = c->bps;
+ int samplerate = c->fmt.samplerate;
+ int bitspersample = c->fmt.bps;
songpos = playpos;
// codec_unlock ();
diff --git a/plugins/mpgmad/mpgmad.c b/plugins/mpgmad/mpgmad.c
index 03ddbc91..6b4d96ea 100644
--- a/plugins/mpgmad/mpgmad.c
+++ b/plugins/mpgmad/mpgmad.c
@@ -567,7 +567,7 @@ cmp3_scan_stream (buffer_t *buffer, int sample) {
static DB_fileinfo_t *
-cmp3_open (void) {
+cmp3_open (uint32_t hints) {
DB_fileinfo_t *_info = malloc (sizeof (mpgmad_info_t));
mpgmad_info_t *info = (mpgmad_info_t *)_info;
memset (info, 0, sizeof (mpgmad_info_t));
@@ -651,9 +651,10 @@ cmp3_init (DB_fileinfo_t *_info, DB_playItem_t *it) {
trace ("bad mpeg file: %f\n", it->fname);
return -1;
}
- _info->bps = info->buffer.bitspersample;
- _info->samplerate = info->buffer.samplerate;
- _info->channels = info->buffer.channels;
+ _info->fmt.bps = info->buffer.bitspersample;
+ _info->fmt.samplerate = info->buffer.samplerate;
+ _info->fmt.channels = info->buffer.channels;
+ _info->fmt.channelmask = _info->fmt.channels == 1 ? DDB_SPEAKER_FRONT_LEFT : (DDB_SPEAKER_FRONT_LEFT | DDB_SPEAKER_FRONT_RIGHT);
mad_stream_init(&info->stream);
mad_stream_options (&info->stream, MAD_OPTION_IGNORECRC);
@@ -748,12 +749,12 @@ cmp3_decode_requested_int16 (mpgmad_info_t *info) {
*((int16_t*)info->buffer.out) = sample;
info->buffer.readsize -= 2;
info->buffer.out += 2;
- if (MAD_NCHANNELS(&info->frame.header) == 2 && info->info.channels == 2) {
+ if (MAD_NCHANNELS(&info->frame.header) == 2 && info->info.fmt.channels == 2) {
*((int16_t*)info->buffer.out) = MadFixedToSshort (info->synth.pcm.samples[1][idx]);
info->buffer.readsize -= 2;
info->buffer.out += 2;
}
- else if (MAD_NCHANNELS(&info->frame.header) == 1 && info->info.channels == 2) {
+ else if (MAD_NCHANNELS(&info->frame.header) == 1 && info->info.fmt.channels == 2) {
*((int16_t*)info->buffer.out) = sample;
info->buffer.readsize -= 2;
info->buffer.out += 2;
@@ -775,12 +776,12 @@ cmp3_decode_requested_float32 (mpgmad_info_t *info) {
*((float*)info->buffer.out) = sample;
info->buffer.readsize -= 4;
info->buffer.out += 4;
- if (MAD_NCHANNELS(&info->frame.header) == 2 && info->info.channels == 2) {
+ if (MAD_NCHANNELS(&info->frame.header) == 2 && info->info.fmt.channels == 2) {
*((float*)info->buffer.out) = MadFixedToFloat (info->synth.pcm.samples[1][idx]);
info->buffer.readsize -= 4;
info->buffer.out += 4;
}
- else if (MAD_NCHANNELS(&info->frame.header) == 1 && info->info.channels == 2) {
+ else if (MAD_NCHANNELS(&info->frame.header) == 1 && info->info.fmt.channels == 2) {
*((float*)info->buffer.out) = sample;
info->buffer.readsize -= 4;
info->buffer.out += 4;
@@ -864,11 +865,11 @@ cmp3_stream_frame (mpgmad_info_t *info) {
}
}
- info->info.samplerate = info->frame.header.samplerate;
+ info->info.fmt.samplerate = info->frame.header.samplerate;
#if 0
// don't switch number of channels on the fly
- if (info->info.channels == 0) {
- info->info.channels = MAD_NCHANNELS(&info->frame.header);
+ if (info->info.fmt.channels == 0) {
+ info->info.fmt.channels = MAD_NCHANNELS(&info->frame.header);
}
#endif
@@ -937,6 +938,28 @@ cmp3_free (DB_fileinfo_t *_info) {
}
static int
+cmp3_read (DB_fileinfo_t *_info, char *bytes, int size) {
+#if WRITE_DUMP
+ if (!out) {
+ out = fopen ("out.raw", "w+b");
+ }
+#endif
+ mpgmad_info_t *info = (mpgmad_info_t *)_info;
+ info->buffer.readsize = size;
+ info->buffer.out = bytes;
+ cmp3_decode_int16 (info);
+ info->buffer.currentsample += (size - info->buffer.readsize) / 4;
+ _info->readpos = (float)(info->buffer.currentsample - info->buffer.startsample) / info->buffer.samplerate;
+#if WRITE_DUMP
+ if (size - info->buffer.readsize > 0) {
+ fwrite (bytes, 1, size - info->buffer.readsize, out);
+ }
+#endif
+ return size - info->buffer.readsize;
+}
+
+#if 0
+static int
cmp3_read_int16 (DB_fileinfo_t *_info, char *bytes, int size) {
#if WRITE_DUMP
if (!out) {
@@ -968,6 +991,7 @@ cmp3_read_float32 (DB_fileinfo_t *_info, char *bytes, int size) {
_info->readpos = (float)(info->buffer.currentsample - info->buffer.startsample) / info->buffer.samplerate;
return size - info->buffer.readsize;
}
+#endif
static int
cmp3_seek_sample (DB_fileinfo_t *_info, int sample) {
@@ -1246,8 +1270,7 @@ static DB_decoder_t plugin = {
.open = cmp3_open,
.init = cmp3_init,
.free = cmp3_free,
- .read_int16 = cmp3_read_int16,
- .read_float32 = cmp3_read_float32,
+ .read = cmp3_read,
.seek = cmp3_seek,
.seek_sample = cmp3_seek_sample,
.insert = cmp3_insert,
diff --git a/plugins/mpris/mpris.c b/plugins/mpris/mpris.c
index 040de84c..37b6e4c9 100644
--- a/plugins/mpris/mpris.c
+++ b/plugins/mpris/mpris.c
@@ -19,7 +19,7 @@
#include <time.h>
#include <gio/gio.h>
-//#include <libindicate/server.h>
+#include <libindicate/server.h>
#include <deadbeef/deadbeef.h>
#include "../artwork/artwork.h"
@@ -36,7 +36,7 @@ DB_functions_t *deadbeef;
static short enabled = 0;
DB_artwork_plugin_t *coverart_plugin = NULL;
-//static IndicateServer *indicate_server;
+static IndicateServer *indicate_server;
static GDBusConnection *connection;
static guint name_own_id;
static guint root_id;
@@ -1087,10 +1087,10 @@ name_lost_cb (GDBusConnection *connection, const char *name, gpointer *user_data
static gboolean
mpris_begin ()
{
-// indicate_server = indicate_server_ref_default ();
-// indicate_server_set_type (indicate_server, "music.deadbeef");
-// indicate_server_set_desktop_file (indicate_server, DESKTOP_FILE);
-// indicate_server_show (indicate_server);
+ indicate_server = indicate_server_ref_default ();
+ indicate_server_set_type (indicate_server, "music.deadbeef");
+ indicate_server_set_desktop_file (indicate_server, DESKTOP_FILE);
+ indicate_server_show (indicate_server);
GError *error = NULL;
GDBusInterfaceInfo *ifaceinfo;
@@ -1201,7 +1201,7 @@ mpris_end ()
name_own_id = 0;
}
-// indicate_server_hide (indicate_server);
+ indicate_server_hide (indicate_server);
deadbeef->mutex_lock(emit_id_mtx);
if (player_property_emit_id != 0) {
@@ -1291,9 +1291,9 @@ static DB_dsp_t plugin = {
.plugin.api_vmajor = DB_API_VERSION_MAJOR,
.plugin.api_vminor = DB_API_VERSION_MINOR,
.plugin.type = DB_PLUGIN_MISC,
- .plugin.id = "mpris",
- .plugin.name = "MPRIS",
- .plugin.descr = "MPRIS",
+ .plugin.id = "Sound Menu",
+ .plugin.name = "Sound Menu",
+ .plugin.descr = "Ubuntu Sound Menu plugin",
.plugin.author = "Robert Y",
.plugin.email = "Decatf@gmail.com",
.plugin.website = "http://deadbeef.sf.net",
diff --git a/plugins/supereq/supereq.c b/plugins/supereq/supereq.c
index 577af84a..6ebf9b24 100644
--- a/plugins/supereq/supereq.c
+++ b/plugins/supereq/supereq.c
@@ -129,7 +129,7 @@ supereq_regen_table_thread (void *param) {
}
int
-supereq_process_int16 (int16_t *samples, int nsamples, int nch, int bps, int srate) {
+supereq_process (char * restrict samples, ddb_waveformat_t * restrict fmt) {
if ((nch != 1 && nch != 2) || (bps != 8 && bps != 16 && bps != 24)) return nsamples;
if (params_changed && !tid) {
tid = deadbeef->thread_start (supereq_regen_table_thread, NULL);
diff --git a/plugins/wavpack/wavpack.c b/plugins/wavpack/wavpack.c
index 72cc7e3c..05130f87 100644
--- a/plugins/wavpack/wavpack.c
+++ b/plugins/wavpack/wavpack.c
@@ -31,8 +31,8 @@
#define min(x,y) ((x)<(y)?(x):(y))
#define max(x,y) ((x)>(y)?(x):(y))
-//#define trace(...) { fprintf(stderr, __VA_ARGS__); }
-#define trace(fmt,...)
+#define trace(...) { fprintf(stderr, __VA_ARGS__); }
+//#define trace(fmt,...)
static DB_decoder_t plugin;
static DB_functions_t *deadbeef;
@@ -106,7 +106,7 @@ static WavpackStreamReader wsr = {
#endif
static DB_fileinfo_t *
-wv_open (void) {
+wv_open (uint32_t hints) {
DB_fileinfo_t *_info = malloc (sizeof (wvctx_t));
memset (_info, 0, sizeof (wvctx_t));
return _info;
@@ -143,9 +143,11 @@ wv_init (DB_fileinfo_t *_info, DB_playItem_t *it) {
return -1;
}
_info->plugin = &plugin;
- _info->bps = WavpackGetBytesPerSample (info->ctx) * 8;
- _info->channels = WavpackGetNumChannels (info->ctx);
- _info->samplerate = WavpackGetSampleRate (info->ctx);
+ _info->fmt.bps = WavpackGetBytesPerSample (info->ctx) * 8;
+ _info->fmt.channels = WavpackGetNumChannels (info->ctx);
+ _info->fmt.samplerate = WavpackGetSampleRate (info->ctx);
+ _info->fmt.is_float = (WavpackGetMode (info->ctx) & MODE_FLOAT) ? 1 : 0;
+ _info->fmt.channelmask = _info->fmt.channels == 1 ? DDB_SPEAKER_FRONT_LEFT : (DDB_SPEAKER_FRONT_LEFT | DDB_SPEAKER_FRONT_RIGHT);
_info->readpos = 0;
if (it->endsample > 0) {
info->startsample = it->startsample;
@@ -184,49 +186,57 @@ wv_free (DB_fileinfo_t *_info) {
}
static int
-wv_read_int16 (DB_fileinfo_t *_info, char *bytes, int size) {
+wv_read (DB_fileinfo_t *_info, char *bytes, int size) {
wvctx_t *info = (wvctx_t *)_info;
int currentsample = WavpackGetSampleIndex (info->ctx);
- int nchannels = WavpackGetReducedChannels (info->ctx);
- if (size / (2 * nchannels) + currentsample > info->endsample) {
- size = (info->endsample - currentsample + 1) * 2 * nchannels;
+// int nchannels = WavpackGetReducedChannels (info->ctx);
+ int samplesize = (_info->fmt.bps >> 3) * _info->fmt.channels;
+ if (size / samplesize + currentsample > info->endsample) {
+ size = (info->endsample - currentsample + 1) * samplesize;
trace ("wv: size truncated to %d bytes, cursample=%d, endsample=%d\n", size, currentsample, info->endsample);
if (size <= 0) {
return 0;
}
}
- int32_t buffer[size/2];
- int n = WavpackUnpackSamples (info->ctx, buffer, size/(2*nchannels));
- size = n * 2 * nchannels;
- // convert to int16
- int32_t *p = buffer;
- n *= nchannels;
-
+ int n;
if (WavpackGetMode (info->ctx) & MODE_FLOAT) {
- while (n > 0) {
- float val = *(float*)p;
- if (val >= 1.0)
- *((int16_t *)bytes) = 32767;
- else if (val <= -1.0)
- *((int16_t *)bytes) = -32768;
- else
- *((int16_t *)bytes) = floor (val * 32768.f);
- bytes += sizeof (int16_t);
- p++;
- n--;
- }
+ _info->fmt.is_float = 1;
+ }
+ if (_info->fmt.is_float || _info->fmt.bps == 32) {
+ n = WavpackUnpackSamples (info->ctx, (int32_t *)bytes, size / samplesize);
+ size = n * samplesize;
}
else {
- while (n > 0) {
- if (_info->bps >= 16) {
- *((int16_t *)bytes) = (int16_t)((*p) >> (_info->bps-16));
+ int32_t buffer[size/(_info->fmt.bps >> 3)];
+ n = WavpackUnpackSamples (info->ctx, (int32_t *)buffer, size / samplesize);
+ size = n * samplesize;
+ n *= _info->fmt.channels;
+
+ // convert from int32 to input (what???)
+ int32_t *p = buffer;
+ if (_info->fmt.bps == 16) {
+ while (n > 0) {
+ *((int16_t *)bytes) = (int16_t)(*p);
+ bytes += sizeof (int16_t);
+ p++;
+ n--;
+ }
+ }
+ else if (_info->fmt.bps == 8) {
+ while (n > 0) {
+ *bytes++ = (char)(*p);
+ p++;
+ n--;
}
- else {
- *((int16_t *)bytes) = (int16_t)((*p) << (16-_info->bps));
+ }
+ else if (_info->fmt.bps == 24) {
+ while (n > 0) {
+ *bytes++ = (*p)&0xff;
+ *bytes++ = ((*p)&0xff00)>>8;
+ *bytes++ = ((*p)&0xff0000)>>16;
+ p++;
+ n--;
}
- bytes += sizeof (int16_t);
- p++;
- n--;
}
}
_info->readpos = (float)(WavpackGetSampleIndex (info->ctx)-info->startsample)/WavpackGetSampleRate (info->ctx);
@@ -239,44 +249,6 @@ wv_read_int16 (DB_fileinfo_t *_info, char *bytes, int size) {
}
static int
-wv_read_float32 (DB_fileinfo_t *_info, char *bytes, int size) {
- wvctx_t *info = (wvctx_t *)_info;
- int nchannels = WavpackGetReducedChannels (info->ctx);
- int currentsample = WavpackGetSampleIndex (info->ctx);
- if (size / (4 * nchannels) + currentsample > info->endsample) {
- size = (info->endsample - currentsample + 1) * 4 * nchannels;
- trace ("wv: size truncated to %d bytes, cursample=%d, endsample=%d\n", size, currentsample, info->endsample);
- if (size <= 0) {
- return 0;
- }
- }
- int32_t buffer[size/4];
- int n = WavpackUnpackSamples (info->ctx, buffer, size/(4*nchannels));
- size = n * 4 * nchannels;
- // convert to float32
- n *= nchannels;
-
- if (WavpackGetMode (info->ctx) & MODE_FLOAT) {
- memcpy (bytes, buffer, size);
- }
- else {
- float mul = 1.f/ (1UL << (_info->bps-1));
- int32_t *p = buffer;
- while (n > 0) {
- *((float *)bytes) = (*p) * mul;
- bytes += sizeof (float);
- p++;
- n--;
- }
- }
- _info->readpos = (float)(WavpackGetSampleIndex (info->ctx)-info->startsample)/WavpackGetSampleRate (info->ctx);
-#ifndef TINYWV
- deadbeef->streamer_set_bitrate (WavpackGetInstantBitrate (info->ctx) / 1000);
-#endif
- return size;
-}
-
-static int
wv_seek_sample (DB_fileinfo_t *_info, int sample) {
#ifndef TINYWV
wvctx_t *info = (wvctx_t *)_info;
@@ -454,8 +426,7 @@ static DB_decoder_t plugin = {
.open = wv_open,
.init = wv_init,
.free = wv_free,
- .read_int16 = wv_read_int16,
- .read_float32 = wv_read_float32,
+ .read = wv_read,
.seek = wv_seek,
.seek_sample = wv_seek_sample,
.insert = wv_insert,
diff --git a/premix.c b/premix.c
new file mode 100644
index 00000000..89cbef11
--- /dev/null
+++ b/premix.c
@@ -0,0 +1,294 @@
+/*
+ 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.
+*/
+
+#include <assert.h>
+#include <string.h>
+#include <stdlib.h>
+#include "deadbeef.h"
+#include "premix.h"
+
+#define trace(...) { fprintf(stderr, __VA_ARGS__); }
+//#define trace(fmt,...)
+
+
+static inline void
+pcm_write_samples_8_to_8 (const ddb_waveformat_t * restrict inputfmt, const char * restrict input, const ddb_waveformat_t * restrict outputfmt, char * restrict output, int nsamples, int * restrict channelmap, int outputsamplesize) {
+ for (int s = 0; s < nsamples; s++) {
+ for (int c = 0; c < inputfmt->channels; c++) {
+ if (channelmap[c] != -1) {
+ *(output + (outputfmt->bps >> 3) * channelmap[c]) = *input;
+ }
+ input++;
+ }
+ output += outputsamplesize;
+ }
+}
+
+static inline void
+pcm_write_samples_8_to_16 (const ddb_waveformat_t * restrict inputfmt, const char * restrict input, const ddb_waveformat_t * restrict outputfmt, char * restrict output, int nsamples, int * restrict channelmap, int outputsamplesize) {
+ for (int s = 0; s < nsamples; s++) {
+ for (int c = 0; c < inputfmt->channels; c++) {
+ if (channelmap[c] != -1) {
+ *((int16_t*)(output + (outputfmt->bps >> 3) * channelmap[c])) = (int16_t)(*input) << 8;
+ }
+ input++;
+ }
+ output += outputsamplesize;
+ }
+}
+
+static inline void
+pcm_write_samples_8_to_24 (const ddb_waveformat_t * restrict inputfmt, const char * restrict input, const ddb_waveformat_t * restrict outputfmt, char * restrict output, int nsamples, int * restrict channelmap, int outputsamplesize) {
+ for (int s = 0; s < nsamples; s++) {
+ for (int c = 0; c < inputfmt->channels; c++) {
+ if (channelmap[c] != -1) {
+ char *out = output + (outputfmt->bps >> 3) * channelmap[c];
+ out[0] = 0;
+ out[1] = 0;
+ out[2] = input[0];
+ }
+ input += 1;
+ }
+ output += outputsamplesize;
+ }
+}
+
+static inline void
+pcm_write_samples_8_to_32 (const ddb_waveformat_t * restrict inputfmt, const char * restrict input, const ddb_waveformat_t * restrict outputfmt, char * restrict output, int nsamples, int * restrict channelmap, int outputsamplesize) {
+ for (int s = 0; s < nsamples; s++) {
+ for (int c = 0; c < inputfmt->channels; c++) {
+ if (channelmap[c] != -1) {
+ char *out = output + (outputfmt->bps >> 3) * channelmap[c];
+ out[0] = 0;
+ out[1] = 0;
+ out[2] = 0;
+ out[3] = input[0];
+ }
+ input += 1;
+ }
+ output += outputsamplesize;
+ }
+}
+
+static inline void
+pcm_write_samples_8_to_float (const ddb_waveformat_t * restrict inputfmt, const char * restrict input, const ddb_waveformat_t * restrict outputfmt, char * restrict output, int nsamples, int * restrict channelmap, int outputsamplesize) {
+ for (int s = 0; s < nsamples; s++) {
+ for (int c = 0; c < inputfmt->channels; c++) {
+ if (channelmap[c] != -1) {
+ float sample = (*input) / (float)0x7f;
+ *((float *)(output + (outputfmt->bps >> 3) * channelmap[c])) = sample;
+ }
+ input++;
+ }
+ output += outputsamplesize;
+ }
+}
+
+static inline void
+pcm_write_samples_16_to_16 (const ddb_waveformat_t * restrict inputfmt, const char * restrict input, const ddb_waveformat_t * restrict outputfmt, char * restrict output, int nsamples, int * restrict channelmap, int outputsamplesize) {
+ for (int s = 0; s < nsamples; s++) {
+ for (int c = 0; c < inputfmt->channels; c++) {
+ if (channelmap[c] != -1) {
+ *((int16_t*)(output + (outputfmt->bps >> 3) * channelmap[c])) = *((int16_t*)input);
+ }
+ input += 2;
+ }
+ output += outputsamplesize;
+ }
+}
+
+static inline void
+pcm_write_samples_16_to_8 (const ddb_waveformat_t * restrict inputfmt, const char * restrict input, const ddb_waveformat_t * restrict outputfmt, char * restrict output, int nsamples, int * restrict channelmap, int outputsamplesize) {
+ for (int s = 0; s < nsamples; s++) {
+ for (int c = 0; c < inputfmt->channels; c++) {
+ if (channelmap[c] != -1) {
+ *((int8_t*)(output + (outputfmt->bps >> 3) * channelmap[c])) = *((int16_t*)input) >> 8;
+ }
+ input += 2;
+ }
+ output += outputsamplesize;
+ }
+}
+
+static inline void
+pcm_write_samples_16_to_24 (const ddb_waveformat_t * restrict inputfmt, const char * restrict input, const ddb_waveformat_t * restrict outputfmt, char * restrict output, int nsamples, int * restrict channelmap, int outputsamplesize) {
+ for (int s = 0; s < nsamples; s++) {
+ for (int c = 0; c < inputfmt->channels; c++) {
+ if (channelmap[c] != -1) {
+ char *out = output + (outputfmt->bps >> 3) * channelmap[c];
+ out[0] = 0;
+ out[1] = input[0];
+ out[2] = input[1];
+ }
+ input += 2;
+ }
+ output += outputsamplesize;
+ }
+}
+
+static inline void
+pcm_write_samples_16_to_32 (const ddb_waveformat_t * restrict inputfmt, const char * restrict input, const ddb_waveformat_t * restrict outputfmt, char * restrict output, int nsamples, int * restrict channelmap, int outputsamplesize) {
+ for (int s = 0; s < nsamples; s++) {
+ for (int c = 0; c < inputfmt->channels; c++) {
+ if (channelmap[c] != -1) {
+ char *out = output + (outputfmt->bps >> 3) * channelmap[c];
+ out[0] = 0;
+ out[1] = 0;
+ out[2] = input[0];
+ out[3] = input[1];
+ }
+ input += 2;
+ }
+ output += outputsamplesize;
+ }
+}
+
+static inline void
+pcm_write_samples_16_to_float (const ddb_waveformat_t * restrict inputfmt, const char * restrict input, const ddb_waveformat_t * restrict outputfmt, char * restrict output, int nsamples, int * restrict channelmap, int outputsamplesize) {
+ for (int s = 0; s < nsamples; s++) {
+ for (int c = 0; c < inputfmt->channels; c++) {
+ if (channelmap[c] != -1) {
+ float sample = (*((int16_t*)input)) / (float)0x7fff;
+ *((float *)(output + (outputfmt->bps >> 3) * channelmap[c])) = sample;
+ }
+ input += 2;
+ }
+ output += outputsamplesize;
+ }
+}
+
+static inline void
+pcm_write_samples_32_to_32 (const ddb_waveformat_t * restrict inputfmt, const char * restrict input, const ddb_waveformat_t * restrict outputfmt, char * restrict output, int nsamples, int * restrict channelmap, int outputsamplesize) {
+ for (int s = 0; s < nsamples; s++) {
+ for (int c = 0; c < inputfmt->channels; c++) {
+ if (channelmap[c] != -1) {
+ *((int32_t*)(output + (outputfmt->bps >> 3) * channelmap[c])) = *((int32_t*)input);
+ }
+ input += 4;
+ }
+ output += outputsamplesize;
+ }
+}
+
+static inline void
+pcm_write_samples_24_to_24 (const ddb_waveformat_t * restrict inputfmt, const char * restrict input, const ddb_waveformat_t * restrict outputfmt, char * restrict output, int nsamples, int * restrict channelmap, int outputsamplesize) {
+ for (int s = 0; s < nsamples; s++) {
+ for (int c = 0; c < inputfmt->channels; c++) {
+ if (channelmap[c] != -1) {
+ char *out = output + (outputfmt->bps >> 3) * channelmap[c];
+ out[0] = input[0];
+ out[1] = input[1];
+ out[2] = input[2];
+ }
+ input += 3;
+ }
+ output += outputsamplesize;
+ }
+}
+
+int
+pcm_convert (const ddb_waveformat_t * restrict inputfmt, const char * restrict input, const ddb_waveformat_t * restrict outputfmt, char * restrict output, int inputsize) {
+ // calculate output size
+ int inputsamplesize = (inputfmt->bps >> 3) * inputfmt->channels;
+ int outputsamplesize = (outputfmt->bps >> 3) * outputfmt->channels;
+ int nsamples = inputsize / inputsamplesize;
+
+ uint32_t outchannels = 0;
+
+ if (output) {
+ // build channelmap
+ int channelmap[32] = {-1};
+ uint32_t inputbitmask = 1;
+ for (int i = 0; i < inputfmt->channels; i++) {
+ // find next input channel
+ while (inputbitmask < 0x80000000 && !(inputfmt->channelmask & inputbitmask)) {
+ inputbitmask <<= 1;
+ }
+ if (!(inputfmt->channelmask & inputbitmask)) {
+ trace ("pcm_convert: channelmask doesn't correspond inputfmt (channels=%d, channelmask=%X)!\n", inputfmt->channels, inputfmt->channelmask);
+ break;
+ }
+ if (outputfmt->channelmask & inputbitmask) {
+ int o = 0;
+ uint32_t outputbitmask = 1;
+ while (outputbitmask < 0x80000000 && (outputfmt->channelmask & outputbitmask) != inputbitmask) {
+ outputbitmask <<= 1;
+ o++;
+ }
+ if (!(inputfmt->channelmask & outputbitmask)) {
+ // no corresponding output channel -- ignore
+ continue;
+ }
+ outchannels |= outputbitmask;
+ channelmap[i] = o; // input channel i going to output channel o
+ //trace ("channelmap[%d]=%d\n", i, o);
+ }
+ inputbitmask <<= 1;
+ }
+
+ if (outchannels != outputfmt->channelmask) {
+ // some of the channels are not used
+ memset (output, 0, nsamples * outputsamplesize);
+ }
+
+ // FIXME: access through function pointer table
+ //trace ("converting from %d to %d\n", inputfmt->bps, outputfmt->bps);
+ if (inputfmt->bps == 8 && outputfmt->bps == 8) {
+ pcm_write_samples_8_to_8 (inputfmt, input, outputfmt, output, nsamples, channelmap, outputsamplesize);
+ }
+ else if (inputfmt->bps == 8 && outputfmt->bps == 16) {
+ pcm_write_samples_8_to_16 (inputfmt, input, outputfmt, output, nsamples, channelmap, outputsamplesize);
+ }
+ else if (inputfmt->bps == 8 && outputfmt->bps == 24) {
+ pcm_write_samples_8_to_24 (inputfmt, input, outputfmt, output, nsamples, channelmap, outputsamplesize);
+ }
+ else if (inputfmt->bps == 8 && outputfmt->bps == 32 && !outputfmt->is_float) {
+ pcm_write_samples_8_to_32 (inputfmt, input, outputfmt, output, nsamples, channelmap, outputsamplesize);
+ }
+ else if (inputfmt->bps == 8 && outputfmt->bps == 32 && outputfmt->is_float) {
+ pcm_write_samples_8_to_float (inputfmt, input, outputfmt, output, nsamples, channelmap, outputsamplesize);
+ }
+ else if (inputfmt->bps == 16 && outputfmt->bps == 16) {
+ pcm_write_samples_16_to_16 (inputfmt, input, outputfmt, output, nsamples, channelmap, outputsamplesize);
+ }
+ else if (inputfmt->bps == 16 && outputfmt->bps == 8) {
+ pcm_write_samples_16_to_8 (inputfmt, input, outputfmt, output, nsamples, channelmap, outputsamplesize);
+ }
+ else if (inputfmt->bps == 16 && outputfmt->bps == 24) {
+ pcm_write_samples_16_to_24 (inputfmt, input, outputfmt, output, nsamples, channelmap, outputsamplesize);
+ }
+ else if (inputfmt->bps == 16 && outputfmt->bps == 32 && !outputfmt->is_float) {
+ pcm_write_samples_16_to_32 (inputfmt, input, outputfmt, output, nsamples, channelmap, outputsamplesize);
+ }
+ else if (inputfmt->bps == 16 && outputfmt->bps == 32 && outputfmt->is_float) {
+ pcm_write_samples_16_to_float (inputfmt, input, outputfmt, output, nsamples, channelmap, outputsamplesize);
+ }
+ else if (inputfmt->bps == 24 && outputfmt->bps == 24) {
+ pcm_write_samples_24_to_24 (inputfmt, input, outputfmt, output, nsamples, channelmap, outputsamplesize);
+ }
+ else if (inputfmt->bps == 32 && outputfmt->bps == 32) {
+ pcm_write_samples_32_to_32 (inputfmt, input, outputfmt, output, nsamples, channelmap, outputsamplesize);
+ }
+ else {
+ trace ("no converter from %d to %d\n", inputfmt->bps, outputfmt->bps);
+ }
+ }
+ return nsamples * outputsamplesize;
+}
+
diff --git a/premix.h b/premix.h
new file mode 100644
index 00000000..e25707da
--- /dev/null
+++ b/premix.h
@@ -0,0 +1,27 @@
+/*
+ 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 __PREMIX_H
+#define __PREMIX_H
+
+// @returns number of output bytes
+int
+pcm_convert (const ddb_waveformat_t * restrict inputfmt, const char * restrict input, const ddb_waveformat_t * restrict outputfmt, char * restrict output, int inputsize);
+
+#endif
diff --git a/scripts/configure_minimal.sh b/scripts/configure_minimal.sh
new file mode 100755
index 00000000..7ec8607d
--- /dev/null
+++ b/scripts/configure_minimal.sh
@@ -0,0 +1 @@
+./configure --enable-maintainer-mode --disable-nullout --disable-oss --disable-sid --disable-ffap --disable-vtx --disable-adplug --disable-vorbis --disable-ffmpeg --disable-flac --disable-sndfile --disable-cdda --disable-gme --disable-musepack --disable-wildmidi --disable-tta --disable-dca --disable-aac --disable-mms --disable-shn --disable-ao --disable-supereq --disable-artwork --disable-lfm --disable-vfs-curl --disable-hotkeys --disable-notify --disable-shellexec
diff --git a/scripts/pluginstall.sh b/scripts/pluginstall.sh
index cb296fac..433a5d8d 100644
--- a/scripts/pluginstall.sh
+++ b/scripts/pluginstall.sh
@@ -1,36 +1,3 @@
-./scripts/portable_postbuild.sh
+#./scripts/portable_postbuild.sh
+sudo ./scripts/quickinstall.sh
-#sudo cp ./deadbeef /usr/local/bin/
-#sudo cp ./plugins/nullout/.libs/nullout.so /usr/local/lib/deadbeef/
-#sudo cp ./plugins/cdda/.libs/cdda.so /usr/local/lib/deadbeef/
-#sudo cp ./plugins/flac/.libs/flac.so /usr/local/lib/deadbeef/
-#sudo cp ./plugins/alsa/.libs/alsa.so /usr/local/lib/deadbeef/
-#sudo cp ./plugins/mpgmad/.libs/mpgmad.so /usr/local/lib/deadbeef/
-#sudo cp ./plugins/hotkeys/.libs/hotkeys.so /usr/local/lib/deadbeef/
-#sudo cp ./plugins/vtx/.libs/vtx.so /usr/local/lib/deadbeef/
-#sudo cp ./plugins/ffap/.libs/ffap.so /usr/local/lib/deadbeef/
-#sudo cp ./plugins/wavpack/.libs/wavpack.so /usr/local/lib/deadbeef/
-#sudo cp ./plugins/vorbis/.libs/vorbis.so /usr/local/lib/deadbeef/
-#sudo cp ./plugins/oss/.libs/oss.so /usr/local/lib/deadbeef/
-#sudo cp ./plugins/vfs_curl/.libs/vfs_curl.so /usr/local/lib/deadbeef/
-#sudo cp ./plugins/ffmpeg/.libs/ffmpeg.so /usr/local/lib/deadbeef/
-#sudo cp ./plugins/lastfm/.libs/lastfm.so /usr/local/lib/deadbeef/
-#sudo cp ./plugins/sid/.libs/sid.so /usr/local/lib/deadbeef/
-#sudo cp ./plugins/adplug/.libs/adplug.so /usr/local/lib/deadbeef/
-#sudo cp ./plugins/gtkui/.libs/gtkui.so /usr/local/lib/deadbeef/
-#sudo cp ./plugins/sndfile/.libs/sndfile.so /usr/local/lib/deadbeef/
-#sudo cp ./plugins/pulse/.libs/pulse.so /usr/local/lib/deadbeef/
-#sudo cp ./plugins/artwork/.libs/artwork.so /usr/local/lib/deadbeef/
-#sudo cp ./plugins/supereq/.libs/supereq.so /usr/local/lib/deadbeef/
-#sudo cp ./plugins/gme/.libs/gme.so /usr/local/lib/deadbeef/
-#sudo cp ./plugins/dumb/.libs/dumb.so /usr/local/lib/deadbeef/
-#sudo cp ./plugins/notify/.libs/notify.so /usr/local/lib/deadbeef/
-#sudo cp ./plugins/musepack/.libs/musepack.so /usr/local/lib/deadbeef/
-#sudo cp ./plugins/wildmidi/.libs/wildmidi.so /usr/local/lib/deadbeef/
-#sudo cp ./plugins/tta/.libs/tta.so /usr/local/lib/deadbeef/
-#sudo cp ./plugins/dca/.libs/dca.so /usr/local/lib/deadbeef/
-#sudo cp ./plugins/aac/.libs/aac.so /usr/local/lib/deadbeef/
-#sudo cp ./plugins/mms/.libs/mms.so /usr/local/lib/deadbeef/
-#sudo cp ./plugins/shn/.libs/shn.so /usr/local/lib/deadbeef/
-#sudo cp ./plugins/ao/.libs/ao.so /usr/local/lib/deadbeef/
-#sudo cp ./plugins/shellexec/.libs/shellexec.so /usr/local/lib/deadbeef/
diff --git a/scripts/quickinstall.sh b/scripts/quickinstall.sh
new file mode 100755
index 00000000..28fccb1c
--- /dev/null
+++ b/scripts/quickinstall.sh
@@ -0,0 +1,37 @@
+#!/bin/sh
+rm /usr/local/lib/deadbeef/*
+cp ./deadbeef /usr/local/bin/
+cp ./plugins/nullout/.libs/nullout.so /usr/local/lib/deadbeef/
+cp ./plugins/cdda/.libs/cdda.so /usr/local/lib/deadbeef/
+cp ./plugins/flac/.libs/flac.so /usr/local/lib/deadbeef/
+cp ./plugins/alsa/.libs/alsa.so /usr/local/lib/deadbeef/
+cp ./plugins/mpgmad/.libs/mpgmad.so /usr/local/lib/deadbeef/
+cp ./plugins/hotkeys/.libs/hotkeys.so /usr/local/lib/deadbeef/
+cp ./plugins/vtx/.libs/vtx.so /usr/local/lib/deadbeef/
+cp ./plugins/ffap/.libs/ffap.so /usr/local/lib/deadbeef/
+cp ./plugins/wavpack/.libs/wavpack.so /usr/local/lib/deadbeef/
+cp ./plugins/vorbis/.libs/vorbis.so /usr/local/lib/deadbeef/
+cp ./plugins/oss/.libs/oss.so /usr/local/lib/deadbeef/
+cp ./plugins/vfs_curl/.libs/vfs_curl.so /usr/local/lib/deadbeef/
+cp ./plugins/ffmpeg/.libs/ffmpeg.so /usr/local/lib/deadbeef/
+cp ./plugins/lastfm/.libs/lastfm.so /usr/local/lib/deadbeef/
+cp ./plugins/sid/.libs/sid.so /usr/local/lib/deadbeef/
+cp ./plugins/adplug/.libs/adplug.so /usr/local/lib/deadbeef/
+cp ./plugins/gtkui/.libs/gtkui.so /usr/local/lib/deadbeef/
+cp ./plugins/sndfile/.libs/sndfile.so /usr/local/lib/deadbeef/
+cp ./plugins/pulse/.libs/pulse.so /usr/local/lib/deadbeef/
+cp ./plugins/artwork/.libs/artwork.so /usr/local/lib/deadbeef/
+cp ./plugins/supereq/.libs/supereq.so /usr/local/lib/deadbeef/
+cp ./plugins/gme/.libs/gme.so /usr/local/lib/deadbeef/
+cp ./plugins/dumb/.libs/dumb.so /usr/local/lib/deadbeef/
+cp ./plugins/notify/.libs/notify.so /usr/local/lib/deadbeef/
+cp ./plugins/musepack/.libs/musepack.so /usr/local/lib/deadbeef/
+cp ./plugins/wildmidi/.libs/wildmidi.so /usr/local/lib/deadbeef/
+cp ./plugins/tta/.libs/tta.so /usr/local/lib/deadbeef/
+cp ./plugins/dca/.libs/dca.so /usr/local/lib/deadbeef/
+cp ./plugins/aac/.libs/aac.so /usr/local/lib/deadbeef/
+cp ./plugins/mms/.libs/mms.so /usr/local/lib/deadbeef/
+cp ./plugins/shn/.libs/shn.so /usr/local/lib/deadbeef/
+cp ./plugins/ao/.libs/ao.so /usr/local/lib/deadbeef/
+cp ./plugins/shellexec/.libs/shellexec.so /usr/local/lib/deadbeef/
+
diff --git a/streamer.c b/streamer.c
index b1834cd0..b1f2836f 100644
--- a/streamer.c
+++ b/streamer.c
@@ -29,18 +29,18 @@
#include "playlist.h"
#include "common.h"
#include "streamer.h"
-#include "playback.h"
#include "messagepump.h"
#include "conf.h"
#include "plugins.h"
#include "optmath.h"
#include "volume.h"
#include "vfs.h"
+#include "premix.h"
-//#define trace(...) { fprintf(stderr, __VA_ARGS__); }
-#define trace(fmt,...)
+#define trace(...) { fprintf(stderr, __VA_ARGS__); }
+//#define trace(fmt,...)
-// #define WRITE_DUMP 1
+#define WRITE_DUMP 1
#if WRITE_DUMP
FILE *out;
@@ -118,6 +118,18 @@ src_unlock (void) {
mutex_unlock (srcmutex);
}
+void
+adjust_waveformat (ddb_waveformat_t *fmt) {
+ if (!fmt->is_multichannel) {
+ if (fmt->channels == 1) {
+ fmt->channelmask = DDB_SPEAKER_FRONT_LEFT;
+ }
+ else if (fmt->channelmask == 2) {
+ fmt->channelmask = DDB_SPEAKER_FRONT_LEFT | DDB_SPEAKER_FRONT_RIGHT;
+ }
+ }
+}
+
static void
streamer_abort_files (void) {
if (fileinfo && fileinfo->file) {
@@ -539,6 +551,7 @@ streamer_song_removed_notify (playItem_t *it) {
// that must be called after last sample from str_playing_song was done reading
static int
streamer_set_current (playItem_t *it) {
+ DB_output_t *output = plug_get_output ();
int err = 0;
playItem_t *from, *to;
// need to add refs here, because streamer_start_playback can destroy items
@@ -551,7 +564,7 @@ streamer_set_current (playItem_t *it) {
pl_item_ref (to);
}
trace ("\033[0;35mstreamer_set_current from %p to %p\033[37;0m\n", from, it);
- if (!playing_track || p_isstopped ()) {
+ if (!playing_track || output->state () == OUTPUT_STATE_STOPPED) {
trace ("buffering = on\n");
streamer_buffering = 1;
trace ("\033[0;35mstreamer_start_playback[1] from %p to %p\033[37;0m\n", from, it);
@@ -633,12 +646,13 @@ streamer_set_current (playItem_t *it) {
dec = plug_get_decoder_for_id (it->decoder_id);
if (dec) {
trace ("\033[0;33minit decoder for %s\033[37;0m\n", it->fname);
- fileinfo = dec->open ();
+ fileinfo = dec->open (0);
if (fileinfo && dec->init (fileinfo, DB_PLAYITEM (it)) != 0) {
trace ("\033[0;31mfailed to init decoder\033[37;0m\n")
dec->free (fileinfo);
fileinfo = NULL;
}
+ adjust_waveformat (&fileinfo->fmt);
}
if (!dec || !fileinfo) {
@@ -660,7 +674,7 @@ streamer_set_current (playItem_t *it) {
streaming_track = it;
pl_item_ref (streaming_track);
mutex_unlock (decodemutex);
- trace ("bps=%d, channels=%d, samplerate=%d\n", fileinfo->bps, fileinfo->channels, fileinfo->samplerate);
+ trace ("bps=%d, channels=%d, samplerate=%d\n", fileinfo->fmt.bps, fileinfo->fmt.channels, fileinfo->fmt.samplerate);
}
// FIXME: that might break streaming at boundaries between 2 different samplerates
// streamer_reset (0); // reset SRC
@@ -719,12 +733,13 @@ streamer_get_apx_bitrate (void) {
void
streamer_set_nextsong (int song, int pstate) {
+ DB_output_t *output = plug_get_output ();
trace ("streamer_set_nextsong %d %d\n", song, pstate);
streamer_lock ();
streamer_abort_files ();
nextsong = song;
nextsong_pstate = pstate;
- if (p_isstopped ()) {
+ if (output->state () == OUTPUT_STATE_STOPPED) {
if (pstate == 1) { // means user initiated this
streamer_playlist = plt_get_curr_ptr ();
}
@@ -748,6 +763,7 @@ static void
streamer_start_new_song (void) {
trace ("nextsong=%d\n", nextsong);
streamer_lock ();
+ DB_output_t *output = plug_get_output ();
int sng = nextsong;
int initsng = nextsong;
int pstate = nextsong_pstate;
@@ -763,7 +779,7 @@ streamer_start_new_song (void) {
playItem_t *try = str_get_for_idx (sng);
if (!try) { // track is not in playlist
trace ("track #%d is not in playlist; stopping playback\n", sng);
- p_stop ();
+ output->stop ();
mutex_lock (decodemutex);
if (playing_track) {
@@ -806,39 +822,41 @@ streamer_start_new_song (void) {
try = NULL;
badsong = -1;
trace ("pstate = %d\n", pstate);
- trace ("playback state = %d\n", p_state ());
+ trace ("playback state = %d\n", output->state ());
if (pstate == 0) {
- p_stop ();
+ output->stop ();
}
else if (pstate == 1 || pstate == 3) {
last_bitrate = -1;
avg_bitrate = -1;
- if (p_state () != OUTPUT_STATE_PLAYING) {
+ if (output->state () != OUTPUT_STATE_PLAYING) {
streamer_reset (1);
if (fileinfo) {
- plug_get_output ()->change_rate (fileinfo->samplerate);
+ plug_get_output ()->setformat (&fileinfo->fmt);
+ adjust_waveformat (&plug_get_output ()->fmt);
}
- if (p_play () < 0) {
+ if (output->play () < 0) {
fprintf (stderr, "streamer: failed to start playback; output plugin doesn't work\n");
streamer_set_nextsong (-2, 0);
}
}
}
else if (pstate == 2) {
- if (p_get_state () == OUTPUT_STATE_STOPPED) {
+ if (output->state () == OUTPUT_STATE_STOPPED) {
last_bitrate = -1;
avg_bitrate = -1;
streamer_reset (1);
if (fileinfo) {
- plug_get_output ()->change_rate (fileinfo->samplerate);
+ plug_get_output ()->setformat (&fileinfo->fmt);
+ adjust_waveformat (&plug_get_output ()->fmt);
}
- if (p_play () < 0) {
+ if (output->play () < 0) {
fprintf (stderr, "streamer: failed to start playback; output plugin doesn't work\n");
streamer_set_nextsong (-2, 0);
return;
}
}
- p_pause ();
+ output->pause ();
}
}
@@ -851,6 +869,7 @@ streamer_thread (void *ctx) {
while (!streaming_terminate) {
struct timeval tm1;
+ DB_output_t *output = plug_get_output ();
gettimeofday (&tm1, NULL);
if (nextsong >= 0) { // start streaming next song
trace ("\033[0;34mnextsong=%d\033[37;0m\n", nextsong);
@@ -866,7 +885,7 @@ streamer_thread (void *ctx) {
bytes_until_next_song = -1;
trace ("nextsong=-2\n");
nextsong = -1;
- p_stop ();
+ output->stop ();
if (playing_track) {
trace ("sending songfinished to plugins [1]\n");
plug_trigger_event (DB_EV_SONGFINISHED, 0);
@@ -886,7 +905,7 @@ streamer_thread (void *ctx) {
streamer_unlock ();
continue;
}
- else if (p_isstopped ()) {
+ else if (output->state () == OUTPUT_STATE_STOPPED) {
usleep (50000);
continue;
}
@@ -896,7 +915,7 @@ streamer_thread (void *ctx) {
if (!streaming_track) {
// means last song was deleted during final drain
nextsong = -1;
- p_stop ();
+ output->stop ();
streamer_set_current (NULL);
streamer_unlock ();
continue;
@@ -924,23 +943,27 @@ streamer_thread (void *ctx) {
if (conf_get_int ("playback.dynsamplerate", 0)) {
// don't switch if unchanged
- int prevtrack_samplerate = p_get_rate ();
- if (prevtrack_samplerate != fileinfo->samplerate) {
- int newrate = plug_get_output ()->change_rate (fileinfo->samplerate);
- if (newrate != prevtrack_samplerate) {
+ ddb_waveformat_t prevfmt;
+ memcpy (&prevfmt, &output->fmt, sizeof (ddb_waveformat_t));
+ if (memcmp (&output->fmt, &fileinfo->fmt, sizeof (ddb_waveformat_t))) {
+ output->setformat (&fileinfo->fmt);
+ adjust_waveformat (&output->fmt);
+ // check if the format actually changed
+ if (memcmp (&output->fmt, &prevfmt, sizeof (ddb_waveformat_t))) {
// restart streaming of current track
- trace ("streamer: output samplerate changed from %d to %d; restarting track\n", prevtrack_samplerate, newrate);
+ trace ("streamer: output samplerate changed from %d to %d; restarting track\n", prevfmt.samplerate, output->fmt.samplerate);
mutex_lock (decodemutex);
fileinfo->plugin->free (fileinfo);
fileinfo = NULL;
DB_decoder_t *dec = NULL;
dec = plug_get_decoder_for_id (streaming_track->decoder_id);
if (dec) {
- fileinfo = dec->open ();
+ fileinfo = dec->open (0);
if (fileinfo && dec->init (fileinfo, DB_PLAYITEM (streaming_track)) < 0) {
dec->free (fileinfo);
fileinfo = NULL;
}
+ adjust_waveformat (&fileinfo->fmt);
}
if (!dec || !fileinfo) {
// FIXME: handle error
@@ -949,18 +972,16 @@ streamer_thread (void *ctx) {
bytes_until_next_song = -1;
streamer_buffering = 1;
streamer_reset (1);
- if (fileinfo) {
- prevtrack_samplerate = fileinfo->samplerate;
- }
}
}
// output plugin may stop playback before switching samplerate
- if (p_state () != OUTPUT_STATE_PLAYING) {
+ if (output->state () != OUTPUT_STATE_PLAYING) {
if (fileinfo) {
- plug_get_output ()->change_rate (fileinfo->samplerate);
+ plug_get_output ()->setformat (&fileinfo->fmt);
+ adjust_waveformat (&plug_get_output ()->fmt);
}
- if (p_play () < 0) {
+ if (output->play () < 0) {
fprintf (stderr, "streamer: failed to start playback after samplerate change; output plugin doesn't work\n");
streamer_set_nextsong (-2, 0);
streamer_unlock ();
@@ -1005,11 +1026,12 @@ streamer_thread (void *ctx) {
DB_decoder_t *dec = NULL;
dec = plug_get_decoder_for_id (streaming_track->decoder_id);
if (dec) {
- fileinfo = dec->open ();
+ fileinfo = dec->open (0);
if (fileinfo && dec->init (fileinfo, DB_PLAYITEM (streaming_track)) != 0) {
dec->free (fileinfo);
fileinfo = NULL;
}
+ adjust_waveformat (&fileinfo->fmt);
}
mutex_unlock (decodemutex);
@@ -1048,14 +1070,14 @@ streamer_thread (void *ctx) {
}
// read ahead at 2x speed of output samplerate, in 4k blocks
- int rate = p_get_rate ();
+ int rate = output->fmt.samplerate;
if (!rate) {
trace ("str: got 0 output samplerate\n");
usleep(20000);
continue;
}
- int channels = 2; // FIXME: needs to be queried from output plugin
- int bytes_in_one_second = rate * sizeof (int16_t) * channels;
+ int channels = output->fmt.channels;
+ int bytes_in_one_second = rate * (output->fmt.bps>>3) * channels;
const int blocksize = 4096;
int alloc_time = 1000 / (bytes_in_one_second * 2 / blocksize);
@@ -1073,6 +1095,13 @@ streamer_thread (void *ctx) {
assert ((sz&3) == 0);
char buf[sz];
streamer_unlock ();
+
+ // ensure that size is possible with current format
+ int samplesize = output->fmt.channels * (output->fmt.bps>>3);
+ if (sz % samplesize) {
+ sz -= (sz % samplesize);
+ }
+
int bytesread = streamer_read_async (buf,sz);
streamer_lock ();
memcpy (streambuffer+streambuffer_fill, buf, sz);
@@ -1187,7 +1216,7 @@ streamer_reset (int full) { // must be called when current song changes by exter
src_reset (src);
// reset dsp
DB_dsp_t **dsp = deadbeef->plug_get_dsp_list ();
- //int srate = p_get_rate ();
+ //int srate = output->fmt.samplerate;
for (int i = 0; dsp[i]; i++) {
if (dsp[i]->enabled ()) {
dsp[i]->reset ();
@@ -1357,9 +1386,10 @@ float32_to_int16 (float *in, int16_t *out, int nsamples) {
*/
+#if 0
static int
streamer_read_data_for_src (int16_t *buffer, int frames) {
- int channels = fileinfo->channels;
+ int channels = fileinfo->fmt.channels;
if (channels > 2) {
channels = 2;
}
@@ -1379,7 +1409,7 @@ streamer_read_data_for_src (int16_t *buffer, int frames) {
static int
streamer_read_data_for_src_float (float *buffer, int frames) {
- int channels = fileinfo->channels;
+ int channels = fileinfo->fmt.channels;
if (channels > 2) {
channels = 2;
}
@@ -1410,16 +1440,17 @@ streamer_read_data_for_src_float (float *buffer, int frames) {
static int
streamer_decode_src_libsamplerate (uint8_t *bytes, int size) {
+ DB_output_t *output = plug_get_output ();
int initsize = size;
int16_t *out = (int16_t *)bytes;
- int samplerate = fileinfo->samplerate;
+ int samplerate = fileinfo->fmt.samplerate;
if (!samplerate) {
return 0;
}
- float ratio = p_get_rate ()/(float)samplerate;
+ float ratio = output->fmt.samplerate/(float)samplerate;
while (size > 0) {
int n_output_frames = size / sizeof (int16_t) / 2;
- int n_input_frames = n_output_frames * samplerate / p_get_rate () + 100;
+ int n_input_frames = n_output_frames * samplerate / output->fmt.samplerate + 100;
// read data from decoder
if (n_input_frames >= SRC_BUFFER - src_remaining ) {
n_input_frames = SRC_BUFFER - src_remaining;
@@ -1444,7 +1475,7 @@ streamer_decode_src_libsamplerate (uint8_t *bytes, int size) {
srcdata.input_frames = src_remaining;
srcdata.output_frames = size/4;
srcdata.src_ratio = ratio;
-// trace ("SRC from %d to %d\n", samplerate, p_get_rate ());
+// trace ("SRC from %d to %d\n", samplerate, output->fmt.samplerate);
srcdata.end_of_input = 0;//(nread == n_input_frames) ? 0 : 1;
//if (streamer_buffering)
src_lock ();
@@ -1478,54 +1509,13 @@ streamer_decode_src_libsamplerate (uint8_t *bytes, int size) {
}
return initsize-size;
}
-
-#if 0
-static int
-streamer_decode_src (uint8_t *bytes, int size) {
- int initsize = size;
- int16_t *out = (int16_t *)bytes;
- DB_decoder_t *decoder = streaming_track->decoder;
- int samplerate = decoder->info.samplerate;
- float ratio = (float)samplerate / p_get_rate ();
- while (size > 0) {
- int n_output_frames = size / sizeof (int16_t) / 2;
- int n_input_frames = n_output_frames * samplerate / p_get_rate () + 100;
- // read data from decoder
- if (n_input_frames > SRC_BUFFER - src_remaining ) {
- n_input_frames = SRC_BUFFER - src_remaining;
- }
- int nread = streamer_read_data_for_src (&g_src_in_buffer[src_remaining*2], n_input_frames);
- src_remaining += nread;
- // resample
- float idx = 0;
- int i = 0;
- while (i < n_output_frames && idx < src_remaining) {
- int k = (int)idx;
- out[0] = g_src_in_buffer[k*2+0];
- out[1] = g_src_in_buffer[k*2+1];
- i++;
- idx += ratio;
- out += 2;
- }
- size -= i*4;
- src_remaining -= idx;
- if (src_remaining < 0) {
- src_remaining = 0;
- }
- else if (src_remaining > 0) {
- memmove (g_src_in_buffer, &g_src_in_buffer[(SRC_BUFFER-src_remaining)*2], src_remaining*2*sizeof (int16_t));
- }
- if (nread != n_input_frames) {
- break;
- }
- }
- return initsize-size;
-}
#endif
+// decodes data and converts to current output format
// returns number of bytes been read
static int
streamer_read_async (char *bytes, int size) {
+ DB_output_t *output = plug_get_output ();
int initsize = size;
for (;;) {
int bytesread = 0;
@@ -1535,13 +1525,36 @@ streamer_read_async (char *bytes, int size) {
mutex_unlock (decodemutex);
break;
}
- if (fileinfo->samplerate != -1) {
- int nchannels = fileinfo->channels;
+ if (fileinfo->fmt.samplerate != -1) {
+ if (!memcmp (&fileinfo->fmt, &output->fmt, sizeof (ddb_waveformat_t)), 0) {
+ bytesread = fileinfo->plugin->read (fileinfo, bytes, size);
+ }
+ else {
+// trace ("format mismatch, converting:\n");
+// trace ("input bps=%d, channels=%d, samplerate=%d, channelmask=%X\n", fileinfo->fmt.bps, fileinfo->fmt.channels, fileinfo->fmt.samplerate, fileinfo->fmt.channelmask);
+// trace ("output bps=%d, channels=%d, samplerate=%d, channelmask=%X\n", output->fmt.bps, output->fmt.channels, output->fmt.samplerate, output->fmt.channelmask);
+
+ int outputsamplesize = (output->fmt.bps>>3)*output->fmt.channels;
+ int inputsamplesize = (fileinfo->fmt.bps>>3)*fileinfo->fmt.channels;
+ int inputsize = size/outputsamplesize*inputsamplesize;
+ char input[inputsize];
+ inputsize = fileinfo->plugin->read (fileinfo, input, inputsize);
+ bytesread = pcm_convert (&fileinfo->fmt, input, &output->fmt, bytes, inputsize);
+// trace ("decoded %d bytes, writing %d bytes, requested %d bytes\n", inputsize, bytesread, size);
+ }
+#if WRITE_DUMP
+ if (bytesread) {
+ fwrite (bytes, 1, bytesread, out);
+ }
+#endif
+
+#if 0
+ int nchannels = fileinfo->fmt.channels;
if (nchannels > 2) {
nchannels = 2;
}
- int samplerate = fileinfo->samplerate;
- if (fileinfo->samplerate == p_get_rate ()) {
+ int samplerate = fileinfo->fmt.samplerate;
+ if (fileinfo->fmt.samplerate == output->fmt.samplerate) {
// samplerate match
if (nchannels == 2) {
bytesread = fileinfo->plugin->read_int16 (fileinfo, bytes, size);
@@ -1555,31 +1568,32 @@ streamer_read_async (char *bytes, int size) {
bytesread *= 2;
}
}
- else if (src_is_valid_ratio (p_get_rate ()/(double)samplerate)) {
+ else if (src_is_valid_ratio (output->fmt.samplerate/(double)samplerate)) {
bytesread = streamer_decode_src_libsamplerate (bytes, size);
}
else {
- fprintf (stderr, "error: invalid ratio! %d / %d (this indicates decoder or streamer bug)\n", p_get_rate (), samplerate);
+ fprintf (stderr, "error: invalid ratio! %d / %d (this indicates decoder or streamer bug)\n", output->fmt.samplerate, samplerate);
fprintf (stderr, "error: file: %s\n", streaming_track ? streaming_track->fname : "(null)");
// immediately start streaming next track
bytes_until_next_song = -1;
}
+#endif
}
- trace ("streamer: bytesread=%d\n", bytesread);
+#if 0
if (bytesread > 0) {
// apply dsp
DB_dsp_t **dsp = deadbeef->plug_get_dsp_list ();
- int srate = p_get_rate ();
+ int srate = output->fmt.samplerate;
for (int i = 0; dsp[i]; i++) {
if (dsp[i]->enabled ()) {
- dsp[i]->process_int16 ((int16_t *)bytes, bytesread/4, 2, 16, srate);
+ dsp[i]->process (bytes, bytesread/4, &output->fmt);
}
}
}
+#endif
mutex_unlock (decodemutex);
bytes += bytesread;
size -= bytesread;
- trace ("streamer: size=%d\n", size);
if (size == 0) {
return initsize;
}
@@ -1612,14 +1626,15 @@ streamer_read (char *bytes, int size) {
if (!playing_track) {
return -1;
}
+ DB_output_t *output = plug_get_output ();
streamer_lock ();
int sz = min (size, streambuffer_fill);
if (sz) {
memcpy (bytes, streambuffer, sz);
memmove (streambuffer, streambuffer+sz, streambuffer_fill-sz);
streambuffer_fill -= sz;
- playpos += (float)sz/p_get_rate ()/4.f;
- playing_track->playtime += (float)sz/p_get_rate ()/4.f;
+ playpos += (float)sz/output->fmt.samplerate/((output->fmt.bps>>3)*output->fmt.channels);
+ playing_track->playtime += (float)sz/output->fmt.samplerate/((output->fmt.bps>>3)*output->fmt.channels);
if (playlist_track) {
playing_track->filetype = playlist_track->filetype;
}
@@ -1667,9 +1682,6 @@ streamer_read (char *bytes, int size) {
int ms = (tm2.tv_sec*1000+tm2.tv_usec/1000) - (tm1.tv_sec*1000+tm1.tv_usec/1000);
printf ("streamer_read took %d ms\n", ms);
#endif
-#if WRITE_DUMP
- fwrite (bytes, 1, sz, out);
-#endif
return sz;
}
@@ -1721,14 +1733,15 @@ streamer_configchanged (void) {
void
streamer_play_current_track (void) {
playlist_t *plt = plt_get_curr_ptr ();
- if (p_ispaused () && playing_track) {
+ DB_output_t *output = plug_get_output ();
+ if (output->state () == OUTPUT_STATE_PAUSED && playing_track) {
// unpause currently paused track
- p_unpause ();
+ output->unpause ();
plug_trigger_event_paused (0);
}
else if (plt->current_row[PL_MAIN] != -1) {
// play currently selected track in current playlist
- p_stop ();
+ output->stop ();
// get next song in queue
int idx = -1;
playItem_t *next = pl_playqueue_getnext ();
@@ -1746,7 +1759,7 @@ streamer_play_current_track (void) {
}
else {
// restart currently playing track
- p_stop ();
+ output->stop ();
streamer_set_nextsong (0, 1);
}
}