summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Makefile.am1
-rw-r--r--deadbeef.h59
-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.c67
-rw-r--r--plugins/gtkui/gtkui.c10
-rw-r--r--plugins/mpgmad/mpgmad.c22
-rw-r--r--scripts/configure_minimal.sh1
-rwxr-xr-xscripts/quickinstall.sh1
-rw-r--r--streamer.c107
12 files changed, 163 insertions, 179 deletions
diff --git a/Makefile.am b/Makefile.am
index fb4a7b5f..77db2954 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -23,7 +23,6 @@ deadbeef_SOURCES =\
streamer.c streamer.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\
diff --git a/deadbeef.h b/deadbeef.h
index 1c091920..d09e8ac9 100644
--- a/deadbeef.h
+++ b/deadbeef.h
@@ -619,20 +619,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);
@@ -691,15 +734,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
diff --git a/main.c b/main.c
index 86117f1b..6e57d013 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:
@@ -487,10 +487,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 ();
@@ -505,7 +506,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);
@@ -795,9 +797,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 c67df13d..ff5260bc 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"
@@ -931,9 +930,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) {
@@ -942,13 +942,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..b74dcabf 100644
--- a/plugins/alsa/alsa.c
+++ b/plugins/alsa/alsa.c
@@ -42,7 +42,6 @@ DB_functions_t *deadbeef;
static snd_pcm_t *audio;
static int alsa_terminate;
static int requested_rate = -1;
-static int alsa_rate = 44100;
static int state; // one of output_state_t
static uintptr_t mutex;
static intptr_t alsa_tid;
@@ -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
@@ -123,7 +116,6 @@ palsa_enum_soundcards (void (*callback)(const char *name, const char *desc, void
static int
palsa_set_hw_params (int samplerate) {
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) {
@@ -173,8 +165,8 @@ 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) {
fprintf (stderr, "cannot set channel count (%s)\n",
@@ -202,6 +194,13 @@ palsa_set_hw_params (int samplerate) {
snd_strerror (err));
goto error;
}
+
+ plugin.fmt.bps = 16;
+ plugin.fmt.channels = 2;
+ plugin.fmt.is_float = 0;
+ plugin.fmt.is_multichannel = 0;
+ plugin.fmt.channelmask = 0;
+
error:
if (hw_params) {
snd_pcm_hw_params_free (hw_params);
@@ -233,10 +232,10 @@ palsa_init (void) {
mutex = deadbeef->mutex_create ();
if (requested_rate != -1) {
- alsa_rate = requested_rate;
+ plugin.fmt.samplerate = requested_rate;
}
- if (palsa_set_hw_params (alsa_rate) < 0) {
+ if (palsa_set_hw_params (plugin.fmt.samplerate) < 0) {
goto open_error;
}
@@ -313,9 +312,9 @@ palsa_change_rate (int rate) {
trace ("palsa_change_rate: %d\n", rate);
requested_rate = rate;
if (!audio) {
- return alsa_rate;
+ return plugin.fmt.samplerate;
}
- if (rate == alsa_rate) {
+ if (rate == plugin.fmt.samplerate) {
trace ("palsa_change_rate %d: ignored\n", rate);
return rate;
}
@@ -326,10 +325,10 @@ palsa_change_rate (int rate) {
UNLOCK;
if (ret < 0) {
trace ("palsa_change_rate: impossible to set samplerate to %d\n", rate);
- return alsa_rate;
+ return plugin.fmt.samplerate;
}
- trace ("chosen samplerate: %d\n", alsa_rate);
- return alsa_rate;
+ trace ("chosen samplerate: %d\n", plugin.fmt.samplerate);
+ return plugin.fmt.samplerate;
}
int
@@ -453,33 +452,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);
@@ -541,7 +513,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);
}
}
@@ -688,9 +660,6 @@ static DB_output_t plugin = {
.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/gtkui/gtkui.c b/plugins/gtkui/gtkui.c
index 06ceb756..46b3edf8 100644
--- a/plugins/gtkui/gtkui.c
+++ b/plugins/gtkui/gtkui.c
@@ -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..1d5890ac 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,9 @@ 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;
mad_stream_init(&info->stream);
mad_stream_options (&info->stream, MAD_OPTION_IGNORECRC);
@@ -748,12 +748,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 +775,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 +864,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
diff --git a/scripts/configure_minimal.sh b/scripts/configure_minimal.sh
new file mode 100644
index 00000000..4044a03c
--- /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-wavpack --disable-cdda --disable-gme --disable-dumb --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/quickinstall.sh b/scripts/quickinstall.sh
index 39a948ea..28fccb1c 100755
--- a/scripts/quickinstall.sh
+++ b/scripts/quickinstall.sh
@@ -1,4 +1,5 @@
#!/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/
diff --git a/streamer.c b/streamer.c
index b1834cd0..0b89583a 100644
--- a/streamer.c
+++ b/streamer.c
@@ -29,7 +29,6 @@
#include "playlist.h"
#include "common.h"
#include "streamer.h"
-#include "playback.h"
#include "messagepump.h"
#include "conf.h"
#include "plugins.h"
@@ -539,6 +538,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 +551,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,7 +633,7 @@ 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);
@@ -660,7 +660,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->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 +719,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 +749,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 +765,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 +808,39 @@ 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 ()->change_rate (fileinfo->fmt.samplerate);
}
- 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 ()->change_rate (fileinfo->fmt.samplerate);
}
- 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 +853,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 +869,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 +889,7 @@ streamer_thread (void *ctx) {
streamer_unlock ();
continue;
}
- else if (p_isstopped ()) {
+ else if (output->state () == OUTPUT_STATE_STOPPED) {
usleep (50000);
continue;
}
@@ -896,7 +899,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,9 +927,9 @@ 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);
+ int prevtrack_samplerate = output->fmt.samplerate;
+ if (prevtrack_samplerate != fileinfo->fmt.samplerate) {
+ int newrate = output->change_rate (fileinfo->fmt.samplerate);
if (newrate != prevtrack_samplerate) {
// restart streaming of current track
trace ("streamer: output samplerate changed from %d to %d; restarting track\n", prevtrack_samplerate, newrate);
@@ -936,7 +939,7 @@ 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;
@@ -950,17 +953,17 @@ streamer_thread (void *ctx) {
streamer_buffering = 1;
streamer_reset (1);
if (fileinfo) {
- prevtrack_samplerate = fileinfo->samplerate;
+ prevtrack_samplerate = fileinfo->fmt.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 ()->change_rate (fileinfo->fmt.samplerate);
}
- 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,7 +1008,7 @@ 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;
@@ -1048,7 +1051,7 @@ 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);
@@ -1187,7 +1190,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 ();
@@ -1359,7 +1362,7 @@ float32_to_int16 (float *in, int16_t *out, int nsamples) {
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 +1382,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 +1413,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 +1448,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 ();
@@ -1486,10 +1490,10 @@ streamer_decode_src (uint8_t *bytes, int 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 ();
+ float ratio = (float)samplerate / output->fmt.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;
@@ -1526,6 +1530,7 @@ streamer_decode_src (uint8_t *bytes, int size) {
// 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 +1540,13 @@ streamer_read_async (char *bytes, int size) {
mutex_unlock (decodemutex);
break;
}
- if (fileinfo->samplerate != -1) {
- int nchannels = fileinfo->channels;
+ if (fileinfo->fmt.samplerate != -1) {
+ 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,11 +1560,11 @@ 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;
@@ -1569,7 +1574,7 @@ streamer_read_async (char *bytes, int size) {
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);
@@ -1612,14 +1617,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/4.f;
+ playing_track->playtime += (float)sz/output->fmt.samplerate/4.f;
if (playlist_track) {
playing_track->filetype = playlist_track->filetype;
}
@@ -1721,14 +1727,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 +1753,7 @@ streamer_play_current_track (void) {
}
else {
// restart currently playing track
- p_stop ();
+ output->stop ();
streamer_set_nextsong (0, 1);
}
}