summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGravatar Alexey Yakovenko <wakeroid@gmail.com>2009-12-11 21:40:13 +0100
committerGravatar Alexey Yakovenko <wakeroid@gmail.com>2009-12-11 21:40:50 +0100
commitb5196b51f6858347bc1af2e243cbc1cd742110ee (patch)
tree7d8728acd1c8d5fb178269636d3abd2bd205a080
parent3dfee5bd02b3f264f3ccdf7513c5078b2806196c (diff)
alsa code converted into output plugin
-rw-r--r--Makefile.am3
-rw-r--r--cdumb.c2
-rw-r--r--cgme.c5
-rw-r--r--configure.ac14
-rw-r--r--csid.cpp4
-rw-r--r--deadbeef.h24
-rw-r--r--main.c20
-rw-r--r--palsa.h58
-rw-r--r--playback.h33
-rw-r--r--plugins.c48
-rw-r--r--plugins.h3
-rw-r--r--plugins/alsa/alsa.c (renamed from palsa.c)186
-rw-r--r--plugins/gtkui/callbacks.c2
-rw-r--r--plugins/gtkui/gtkplaylist.c2
-rw-r--r--plugins/gtkui/gtkui.c4
-rw-r--r--streamer.c2
16 files changed, 255 insertions, 155 deletions
diff --git a/Makefile.am b/Makefile.am
index 3cded06c..ba9ef329 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -9,6 +9,7 @@ SUBDIRS = gme/Game_Music_Emu-0.5.2\
icons\
plugins/hotkeys\
plugins/ffap\
+ ${ALSA_DIR}\
${LFM_DIR}\
${MPGMAD_DIR}\
${VORBIS_DIR}\
@@ -34,7 +35,7 @@ deadbeef_SOURCES =\
messagepump.c messagepump.h\
conf.c conf.h\
cgme.c cdumb.c csid.cpp\
- palsa.c palsa.h playback.h\
+ playback.h\
threading_pthread.c threading.h\
md5/md5.c md5/md5.h md5/md5_loc.h\
volume.c volume.h\
diff --git a/cdumb.c b/cdumb.c
index 0aaaec71..2799d6d8 100644
--- a/cdumb.c
+++ b/cdumb.c
@@ -100,7 +100,7 @@ cdumb_init (DB_playItem_t *it) {
plugin.info.bps = 16;
plugin.info.channels = 2;
- plugin.info.samplerate = deadbeef->playback_get_samplerate ();
+ plugin.info.samplerate = deadbeef->get_output ()->samplerate ();
plugin.info.readpos = 0;
if (cdumb_startrenderer () < 0) {
diff --git a/cgme.c b/cgme.c
index 21aeb292..f4e805ce 100644
--- a/cgme.c
+++ b/cgme.c
@@ -32,7 +32,8 @@ static float duration; // of current song
static int
cgme_init (DB_playItem_t *it) {
- if (gme_open_file (it->fname, &emu, deadbeef->playback_get_samplerate ())) {
+ int samplerate = deadbeef->get_output ()->samplerate ();
+ if (gme_open_file (it->fname, &emu, samplerate)) {
return -1;
}
gme_mute_voices (emu, cgme_voicemask);
@@ -41,7 +42,7 @@ cgme_init (DB_playItem_t *it) {
gme_track_info (emu, &inf, it->tracknum);
plugin.info.bps = 16;
plugin.info.channels = 2;
- plugin.info.samplerate = deadbeef->playback_get_samplerate ();
+ plugin.info.samplerate = samplerate;
duration = deadbeef->pl_get_item_duration (it);
reallength = inf.length;
nzerosamples = 0;
diff --git a/configure.ac b/configure.ac
index d782f7eb..ed726b13 100644
--- a/configure.ac
+++ b/configure.ac
@@ -39,8 +39,11 @@ test "x$prefix" = xNONE && prefix=$ac_default_prefix
CFLAGS="$CFLAGS -D_GNU_SOURCE -DLIBDIR=\\\"$libdir\\\" -DPREFIX=\\\"$prefix\\\""
CPPFLAGS="$CFLAGS"
-PKG_CHECK_MODULES(DEPS, samplerate alsa)
+PKG_CHECK_MODULES(DEPS, samplerate)
PKG_CHECK_MODULES(GTKUI_DEPS, gtk+-2.0 >= 2.12 gthread-2.0 glib-2.0, HAVE_GTK=1)
+PKG_CHECK_MODULES(ALSA_DEPS, alsa, HAVE_ALSA=1)
+AC_CHECK_LIB([pthread], [main])
+AC_CHECK_LIB([dl], [main])
AX_CHECK_COMPILER_FLAGS(-msse2, SIMD_FLAGS="$SIMD_FLAGS -msse2";HAVE_SSE2=1, [])
if test ${HAVE_SSE2}; then
@@ -153,6 +156,13 @@ if test ${HAVE_GTK}; then
AC_SUBST(GTKUI_DIR)
fi
+AM_CONDITIONAL(HAVE_ALSA, test $HAVE_ALSA)
+if test ${HAVE_ALSA}; then
+ ALSA_DIR="plugins/alsa"
+ AC_SUBST(ALSA_DEPS_CFLAGS)
+ AC_SUBST(ALSA_DEPS_LIBS)
+ AC_SUBST(ALSA_DIR)
+fi
dnl print summary
echo
@@ -170,6 +180,7 @@ AC_DEFUN([PRINT_PLUGIN_INFO],
)
PRINT_PLUGIN_INFO([stdio],[Standard IO plugin],[true])
+PRINT_PLUGIN_INFO([alsa],[alsa output],[test $HAVE_ALSA])
PRINT_PLUGIN_INFO([sid],[SID player based on libsidplay2],[true])
PRINT_PLUGIN_INFO([gme],[chiptune music player based on GME],[true])
PRINT_PLUGIN_INFO([dumb],[module player based on DUMB library],[true])
@@ -194,6 +205,7 @@ gme/Game_Music_Emu-0.5.2/Makefile
gme/Game_Music_Emu-0.5.2/gme/Makefile
sid/sidplay-libs-2.1.0/Makefile
dumb/Makefile
+plugins/alsa/Makefile
plugins/hotkeys/Makefile
plugins/lastfm/Makefile
plugins/ffap/Makefile
diff --git a/csid.cpp b/csid.cpp
index fc742cc9..9051a1df 100644
--- a/csid.cpp
+++ b/csid.cpp
@@ -343,7 +343,7 @@ csid_init (DB_playItem_t *it) {
resid->create (sidplay->info ().maxsids);
// resid->create (1);
resid->filter (true);
- resid->sampling (deadbeef->playback_get_samplerate ());
+ resid->sampling (deadbeef->get_output ()->samplerate ());
duration = deadbeef->pl_get_item_duration (it);
tune = new SidTune (it->fname);
@@ -351,7 +351,7 @@ csid_init (DB_playItem_t *it) {
plugin.info.channels = tune->isStereo () ? 2 : 1;
sid2_config_t conf;
conf = sidplay->config ();
- conf.frequency = deadbeef->playback_get_samplerate ();
+ conf.frequency = deadbeef->get_output ()->samplerate ();
conf.precision = 16;
conf.playback = plugin.info.channels == 2 ? sid2_stereo : sid2_mono;
conf.sidEmulation = resid;
diff --git a/deadbeef.h b/deadbeef.h
index 5bbe4660..f6a3c0b5 100644
--- a/deadbeef.h
+++ b/deadbeef.h
@@ -100,6 +100,13 @@ enum {
DB_PLUGIN_VFS = 5,
};
+// output plugin states
+enum output_state_t {
+ OUTPUT_STATE_STOPPED = 0,
+ OUTPUT_STATE_PLAYING = 1,
+ OUTPUT_STATE_PAUSED = 2,
+};
+
typedef struct {
int event;
time_t time;
@@ -202,6 +209,7 @@ typedef struct {
void (*md5) (uint8_t sig[16], const char *in, int len);
void (*md5_to_str) (char *str, const uint8_t sig[16]);
// playback control
+ struct DB_output_s* (*get_output) (void);
void (*playback_next) (void);
void (*playback_prev) (void);
void (*playback_pause) (void);
@@ -210,12 +218,8 @@ typedef struct {
void (*playback_random) (void);
float (*playback_get_pos) (void); // [0..100]
void (*playback_set_pos) (float pos); // [0..100]
- int (*playback_get_samplerate) (void); // output samplerate
void (*playback_update_bitrate) (float bitrate);
void (*playback_enum_soundcards) (void (*callback)(const char *name, const char *desc, void*), void *userdata);
- // playback status
- int (*playback_isstopped) (void);
- int (*playback_ispaused) (void);
// streamer access
// FIXME: needs to be thread-safe
DB_playItem_t *(*streamer_get_playing_track) (void);
@@ -223,6 +227,8 @@ typedef struct {
float (*streamer_get_playpos) (void);
void (*streamer_seek) (float time);
int (*streamer_ok_to_read) (int len);
+ void (*streamer_reset) (int full);
+ int (*streamer_read) (char *bytes, int size);
// process control
const char *(*get_config_dir) (void);
void (*quit) (void);
@@ -438,21 +444,21 @@ typedef struct DB_decoder_s {
} DB_decoder_t;
// output plugin
-typedef struct {
+typedef struct DB_output_s {
DB_plugin_t plugin;
// init is called once at plugin activation
- int (*init) (void (*callback)(char *stream, int len));
+ 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);
// play, stop, pause, unpause are called by deadbeef in response to user
// events, or as part of streaming process
- // state must be 0 for stopped, 1 for playing and 2 for paused
int (*play) (void);
int (*stop) (void);
int (*pause) (void);
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
@@ -460,7 +466,9 @@ typedef struct {
int (*bitspersample) (void);
int (*channels) (void);
// must return 0 for little endian output, or 1 for big endian
- int (*endianess) (void);
+ int (*endianness) (void);
+ // soundcard enumeration (can be NULL)
+ void (*enum_soundcards) (void (*callback)(const char *name, const char *desc, void*), void *userdata);
} DB_output_t;
// dsp plugin
diff --git a/main.c b/main.c
index 6df2c6c6..1d512df9 100644
--- a/main.c
+++ b/main.c
@@ -235,15 +235,13 @@ player_thread (uintptr_t ctx) {
switch (msg) {
case M_REINIT_SOUND:
{
- int play = 0;
- if (!palsa_ispaused () && !palsa_isstopped ()) {
- play = 1;
- }
-
- palsa_free ();
- palsa_init ();
- if (play) {
- palsa_play ();
+ int state = p_get_state ();
+
+ p_free ();
+ p_init ();
+
+ if (state != OUTPUT_STATE_PAUSED && state != OUTPUT_STATE_STOPPED) {
+ p_play ();
}
}
break;
@@ -274,7 +272,7 @@ player_thread (uintptr_t ctx) {
pl_prevsong ();
break;
case M_PAUSESONG:
- if (p_ispaused ()) {
+ if (p_get_state () == OUTPUT_STATE_PAUSED) {
p_unpause ();
plug_trigger_event_paused (0);
}
@@ -291,7 +289,7 @@ player_thread (uintptr_t ctx) {
plug_trigger_event_playlistchanged ();
break;
case M_CONFIGCHANGED:
- palsa_configchanged ();
+ //plug_get_output ()->configchanged ();
streamer_configchanged ();
plug_trigger_event (DB_EV_CONFIGCHANGED, 0);
break;
diff --git a/palsa.h b/palsa.h
deleted file mode 100644
index 2896702a..00000000
--- a/palsa.h
+++ /dev/null
@@ -1,58 +0,0 @@
-/*
- DeaDBeeF - ultimate music player for GNU/Linux systems with X11
- Copyright (C) 2009 Alexey Yakovenko
-
- 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 __PALSA_H
-#define __PALSA_H
-
-int
-palsa_init (void);
-
-void
-palsa_free (void);
-
-int
-palsa_change_rate (int rate);
-
-int
-palsa_play (void);
-
-int
-palsa_stop (void);
-
-int
-palsa_isstopped (void);
-
-int
-palsa_ispaused (void);
-
-int
-palsa_pause (void);
-
-int
-palsa_unpause (void);
-
-int
-palsa_get_rate (void);
-
-void
-palsa_configchanged (void);
-
-void
-palsa_enum_soundcards (void (*callback)(const char *name, const char *desc, void*), void *userdata);
-
-#endif // __PALSA_H
-
diff --git a/playback.h b/playback.h
index 2a4ce722..da12504f 100644
--- a/playback.h
+++ b/playback.h
@@ -18,27 +18,16 @@
#ifndef __PLAYBACK_H
#define __PLAYBACK_H
-#if USE_SDL
-#include "psdl.h"
-#define p_init psdl_init
-#define p_free psdl_free
-#define p_play psdl_play
-#define p_stop psdl_stop
-#define p_ispaused psdl_ispaused
-#define p_pause psdl_pause
-#define p_unpause psdl_unpause
-#define p_get_rate psdl_get_rate
-#else
-#include "palsa.h"
-#define p_init palsa_init
-#define p_free palsa_free
-#define p_play palsa_play
-#define p_stop palsa_stop
-#define p_ispaused palsa_ispaused
-#define p_pause palsa_pause
-#define p_unpause palsa_unpause
-#define p_get_rate palsa_get_rate
-#define p_isstopped palsa_isstopped
-#endif
+#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_isstopped() (plug_get_output ()->state () == OUTPUT_STATE_STOPPED)
+#define p_ispaused() (plug_get_output ()->state () == OUTPUT_STATE_PAUSED)
#endif // __PLAYBACK_H
diff --git a/plugins.c b/plugins.c
index b982cc82..d8a1534f 100644
--- a/plugins.c
+++ b/plugins.c
@@ -51,6 +51,7 @@ static DB_functions_t deadbeef_api = {
.ev_unsubscribe = plug_ev_unsubscribe,
.md5 = plug_md5,
.md5_to_str = plug_md5_to_str,
+ .get_output = plug_get_output,
.playback_next = plug_playback_next,
.playback_prev = plug_playback_prev,
.playback_pause = plug_playback_pause,
@@ -59,18 +60,15 @@ static DB_functions_t deadbeef_api = {
.playback_random = plug_playback_random,
.playback_get_pos = plug_playback_get_pos,
.playback_set_pos = plug_playback_set_pos,
- .playback_get_samplerate = p_get_rate,
.playback_update_bitrate = streamer_update_bitrate,
- .playback_enum_soundcards = palsa_enum_soundcards,
- // playback status
- .playback_isstopped = p_isstopped,
- .playback_ispaused = p_ispaused,
// streamer access
.streamer_get_playing_track = (DB_playItem_t *(*) (void))streamer_get_playing_track,
.streamer_get_streaming_track = (DB_playItem_t *(*) (void))streamer_get_streaming_track,
.streamer_get_playpos = streamer_get_playpos,
.streamer_seek = streamer_set_seek,
.streamer_ok_to_read = streamer_ok_to_read,
+ .streamer_reset = streamer_reset,
+ .streamer_read = streamer_read,
// process control
.get_config_dir = plug_get_config_dir,
.quit = plug_quit,
@@ -197,6 +195,10 @@ DB_decoder_t *g_decoder_plugins[MAX_DECODER_PLUGINS+1];
#define MAX_VFS_PLUGINS 10
DB_vfs_t *g_vfs_plugins[MAX_VFS_PLUGINS+1];
+#define MAX_OUTPUT_PLUGINS 10
+DB_output_t *g_output_plugins[MAX_OUTPUT_PLUGINS+1];
+DB_output_t *output_plugin = NULL;
+
void
plug_md5 (uint8_t sig[16], const char *in, int len) {
md5_buffer (in, len, sig);
@@ -558,6 +560,7 @@ plug_load_all (void) {
int numplugins = 0;
int numdecoders = 0;
int numvfs = 0;
+ int numoutput = 0;
for (plugin_t *plug = plugins; plug; plug = plug->next) {
g_plugins[numplugins++] = plug->plugin;
if (plug->plugin->type == DB_PLUGIN_DECODER) {
@@ -574,11 +577,41 @@ plug_load_all (void) {
}
g_vfs_plugins[numvfs++] = (DB_vfs_t *)plug->plugin;
}
+ else if (plug->plugin->type == DB_PLUGIN_OUTPUT) {
+ fprintf (stderr, "found output plugin %s\n", plug->plugin->name);
+ if (numvfs >= MAX_OUTPUT_PLUGINS) {
+ break;
+ }
+ g_output_plugins[numoutput++] = (DB_output_t *)plug->plugin;
+ }
}
// fprintf (stderr, "numplugins: %d, numdecoders: %d, numvfs: %d\n", numplugins, numdecoders, numvfs);
g_plugins[numplugins] = NULL;
g_decoder_plugins[numdecoders] = NULL;
g_vfs_plugins[numvfs] = NULL;
+ g_output_plugins[numoutput] = NULL;
+
+ // select output plugin
+ const char *outplugname = conf_get_str ("output_plugin", "alsa");
+ for (int i = 0; g_output_plugins[i]; i++) {
+ DB_output_t *p = g_output_plugins[i];
+ if (!strcmp (p->plugin.name, outplugname)) {
+ fprintf (stderr, "selected output plugin: %s\n", outplugname);
+ output_plugin = p;
+ break;
+ }
+ }
+ if (!output_plugin) {
+ output_plugin = g_output_plugins[0];
+ }
+ if (output_plugin) {
+ fprintf (stderr, "selected output plugin: %s\n", output_plugin->plugin.name);
+ conf_set_str ("output_plugin", output_plugin->plugin.name);
+ }
+ else {
+ fprintf (stderr, "failed to find output plugin!\n");
+ exit (-1);
+ }
}
void
@@ -650,3 +683,8 @@ plug_activate (DB_plugin_t *plug, int activate) {
}
}
}
+
+DB_output_t *
+plug_get_output (void) {
+ return output_plugin;
+}
diff --git a/plugins.h b/plugins.h
index 7a1ce845..cfa7df11 100644
--- a/plugins.h
+++ b/plugins.h
@@ -106,4 +106,7 @@ plug_get_config_dir (void);
int
plug_activate (DB_plugin_t *plug, int activate);
+DB_output_t *
+plug_get_output (void);
+
#endif // __PLUGINS_H
diff --git a/palsa.c b/plugins/alsa/alsa.c
index 284755c5..186a5f9d 100644
--- a/palsa.c
+++ b/plugins/alsa/alsa.c
@@ -20,19 +20,13 @@
#include <stdint.h>
#include <unistd.h>
#include <sys/prctl.h>
-#ifdef HAVE_CONFIG_H
-# include <config.h>
-#endif
-#include "palsa.h"
-#include "threading.h"
-#include "streamer.h"
-#include "conf.h"
-#include "volume.h"
-#include "messagepump.h"
#include "deadbeef.h"
-//#define trace(...) { fprintf(stderr, __VA_ARGS__); }
-#define trace(fmt,...)
+#define trace(...) { fprintf(stderr, __VA_ARGS__); }
+//#define trace(fmt,...)
+
+static DB_output_t plugin;
+DB_functions_t *deadbeef;
static snd_pcm_t *audio;
static int bufsize = -1;
@@ -52,6 +46,48 @@ static void
palsa_thread (void *context);
static int
+palsa_init (void);
+
+static int
+palsa_free (void);
+
+static int
+palsa_change_rate (int rate);
+
+static int
+palsa_play (void);
+
+static int
+palsa_stop (void);
+
+static int
+palsa_isstopped (void);
+
+static int
+palsa_ispaused (void);
+
+static int
+palsa_pause (void);
+
+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
+palsa_get_endianness (void);
+
+static void
+palsa_enum_soundcards (void (*callback)(const char *name, const char *desc, void*), void *userdata);
+
+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);
@@ -149,8 +185,8 @@ palsa_init (void) {
int err;
// get and cache conf variables
- strcpy (conf_alsa_soundcard, conf_get_str ("alsa_soundcard", "default"));
- conf_alsa_resample = conf_get_int ("alsa.resample", 0);
+ strcpy (conf_alsa_soundcard, deadbeef->conf_get_str ("alsa_soundcard", "default"));
+ conf_alsa_resample = deadbeef->conf_get_int ("alsa.resample", 0);
trace ("alsa_soundcard: %s\n", conf_alsa_soundcard);
trace ("alsa.resample: %d\n", conf_alsa_resample);
@@ -163,7 +199,7 @@ palsa_init (void) {
return -1;
}
- mutex = mutex_create ();
+ mutex = deadbeef->mutex_create ();
if (palsa_set_hw_params (alsa_rate) < 0) {
goto open_error;
@@ -219,7 +255,7 @@ palsa_init (void) {
snd_pcm_start (audio);
alsa_terminate = 0;
- alsa_tid = thread_start (palsa_thread, NULL);
+ alsa_tid = deadbeef->thread_start (palsa_thread, NULL);
return 0;
@@ -244,13 +280,13 @@ palsa_change_rate (int rate) {
return rate;
}
trace ("trying to change samplerate to: %d\n", rate);
- mutex_lock (mutex);
+ deadbeef->mutex_lock (mutex);
snd_pcm_drop (audio);
int ret = palsa_set_hw_params (rate);
if (state != 0) {
snd_pcm_start (audio);
}
- mutex_unlock (mutex);
+ deadbeef->mutex_unlock (mutex);
if (ret < 0) {
return -1;
}
@@ -258,19 +294,20 @@ palsa_change_rate (int rate) {
return alsa_rate;
}
-void
+int
palsa_free (void) {
trace ("palsa_free\n");
if (audio && !alsa_terminate) {
alsa_terminate = 1;
- thread_join (alsa_tid);
+ deadbeef->thread_join (alsa_tid);
alsa_tid = 0;
snd_pcm_close(audio);
audio = NULL;
- mutex_free (mutex);
+ deadbeef->mutex_free (mutex);
state = 0;
alsa_terminate = 0;
}
+ return 0;
}
static void
@@ -322,15 +359,15 @@ palsa_stop (void) {
return 0;
}
state = 0;
- if (conf_get_int ("alsa.freeonstop", 0)) {
+ if (deadbeef->conf_get_int ("alsa.freeonstop", 0)) {
palsa_free ();
}
else {
- mutex_lock (mutex);
+ deadbeef->mutex_lock (mutex);
snd_pcm_drop (audio);
- mutex_unlock (mutex);
+ deadbeef->mutex_unlock (mutex);
}
- streamer_reset (1);
+ deadbeef->streamer_reset (1);
return 0;
}
@@ -371,6 +408,25 @@ palsa_get_rate (void) {
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);
@@ -384,21 +440,21 @@ palsa_thread (void *context) {
continue;
}
- mutex_lock (mutex);
+ deadbeef->mutex_lock (mutex);
/* wait till the interface is ready for data, or 1 second
has elapsed.
*/
if ((err = snd_pcm_wait (audio, 500)) < 0 && state == 1) {
if (err == -ESTRPIPE) {
trace ("alsa: trying to recover from suspend...\n");
- messagepump_push (M_REINIT_SOUND, 0, 0, 0);
- mutex_unlock (mutex);
+ deadbeef->sendmessage (M_REINIT_SOUND, 0, 0, 0);
+ deadbeef->mutex_unlock (mutex);
break;
}
else {
trace ("alsa: trying to recover from xrun...\n");
snd_pcm_prepare (audio);
- mutex_unlock (mutex);
+ deadbeef->mutex_unlock (mutex);
continue;
}
}
@@ -408,11 +464,11 @@ palsa_thread (void *context) {
snd_pcm_sframes_t frames_to_deliver;
if ((frames_to_deliver = snd_pcm_avail_update (audio)) < 0) {
if (frames_to_deliver == -EPIPE) {
- mutex_unlock (mutex);
+ deadbeef->mutex_unlock (mutex);
trace ("an xrun occured\n");
continue;
} else {
- mutex_unlock (mutex);
+ deadbeef->mutex_unlock (mutex);
trace ("unknown ALSA avail update return value (%d)\n",
(int)frames_to_deliver);
continue;
@@ -429,18 +485,18 @@ palsa_thread (void *context) {
snd_pcm_prepare (audio);
snd_pcm_start (audio);
}
- mutex_unlock (mutex);
+ deadbeef->mutex_unlock (mutex);
usleep (1000); // this must be here to prevent mutex deadlock
}
}
static void
palsa_callback (char *stream, int len) {
- if (!streamer_ok_to_read (len)) {
+ if (!deadbeef->streamer_ok_to_read (len)) {
memset (stream, 0, len);
return;
}
- int bytesread = streamer_read (stream, len);
+ int bytesread = deadbeef->streamer_read (stream, len);
// FIXME: move volume control to streamer_read for copy optimization
#if 0
@@ -474,7 +530,7 @@ palsa_callback (char *stream, int len) {
);
#else
- int16_t ivolume = volume_get_amp () * 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);
}
@@ -484,13 +540,13 @@ palsa_callback (char *stream, int len) {
}
}
-void
-palsa_configchanged (void) {
- int alsa_resample = conf_get_int ("alsa.resample", 0);
- const char *alsa_soundcard = conf_get_str ("alsa_soundcard", "default");
+static int
+palsa_configchanged (DB_event_t *ev, uintptr_t data) {
+ int alsa_resample = deadbeef->conf_get_int ("alsa.resample", 0);
+ const char *alsa_soundcard = deadbeef->conf_get_str ("alsa_soundcard", "default");
if (alsa_resample != conf_alsa_resample
|| strcmp (alsa_soundcard, conf_alsa_soundcard)) {
- messagepump_push (M_REINIT_SOUND, 0, 0, 0);
+ deadbeef->sendmessage (M_REINIT_SOUND, 0, 0, 0);
}
}
@@ -522,3 +578,55 @@ palsa_enum_soundcards (void (*callback)(const char *name, const char *desc, void
}
snd_device_name_free_hint(hints);
}
+
+int
+palsa_get_state (void) {
+ return state;
+}
+
+int
+alsa_start (void) {
+ deadbeef->ev_subscribe (DB_PLUGIN (&plugin), DB_EV_CONFIGCHANGED, DB_CALLBACK (palsa_configchanged), 0);
+ return 0;
+}
+
+int
+alsa_stop (void) {
+ deadbeef->ev_unsubscribe (DB_PLUGIN (&plugin), DB_EV_CONFIGCHANGED, DB_CALLBACK (palsa_configchanged), 0);
+ return 0;
+}
+
+DB_plugin_t *
+alsa_load (DB_functions_t *api) {
+ deadbeef = api;
+ return DB_PLUGIN (&plugin);
+}
+
+// define plugin interface
+static DB_output_t plugin = {
+ DB_PLUGIN_SET_API_VERSION
+ .plugin.version_major = 0,
+ .plugin.version_minor = 1,
+ .plugin.nostop = 1,
+ .plugin.type = DB_PLUGIN_OUTPUT,
+ .plugin.name = "alsa output plugin",
+ .plugin.descr = "plays sound through linux standard alsa library",
+ .plugin.author = "Alexey Yakovenko",
+ .plugin.email = "waker@users.sourceforge.net",
+ .plugin.website = "http://deadbeef.sf.net",
+ .plugin.start = alsa_start,
+ .plugin.stop = alsa_stop,
+ .init = palsa_init,
+ .free = palsa_free,
+ .change_rate = palsa_change_rate,
+ .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,
+};
diff --git a/plugins/gtkui/callbacks.c b/plugins/gtkui/callbacks.c
index d83fa534..be2e7d12 100644
--- a/plugins/gtkui/callbacks.c
+++ b/plugins/gtkui/callbacks.c
@@ -975,7 +975,7 @@ on_seekbar_button_press_event (GtkWidget *widget,
GdkEventButton *event,
gpointer user_data)
{
- if (deadbeef->playback_isstopped ()) {
+ if (deadbeef->get_output ()->state () == OUTPUT_STATE_STOPPED) {
return FALSE;
}
seekbar_moving = 1;
diff --git a/plugins/gtkui/gtkplaylist.c b/plugins/gtkui/gtkplaylist.c
index a01d2889..a9a0d44b 100644
--- a/plugins/gtkui/gtkplaylist.c
+++ b/plugins/gtkui/gtkplaylist.c
@@ -387,7 +387,7 @@ gtkpl_draw_pl_row (gtkplaylist_t *ps, int row, DB_playItem_t *it) {
gtkpl_column_t *c;
for (c = ps->columns; c; c = c->next) {
if (it == deadbeef->pl_getcurrent () && c->id == DB_COLUMN_PLAYING/* && !p_isstopped ()*/) {
- int paused = deadbeef->playback_ispaused ();
+ int paused = deadbeef->get_output ()->state () == OUTPUT_STATE_PAUSED;
int buffering = !deadbeef->streamer_ok_to_read (-1);
uintptr_t pixbuf;
if (paused) {
diff --git a/plugins/gtkui/gtkui.c b/plugins/gtkui/gtkui.c
index 1eba2b02..248b38b8 100644
--- a/plugins/gtkui/gtkui.c
+++ b/plugins/gtkui/gtkui.c
@@ -73,7 +73,7 @@ update_songinfo (gpointer ctx) {
DB_playItem_t *track = deadbeef->streamer_get_playing_track ();
float duration = deadbeef->pl_get_item_duration (track);
- if (deadbeef->playback_isstopped ()) {
+ if (deadbeef->get_output ()->state () == OUTPUT_STATE_STOPPED) {
snprintf (sbtext_new, sizeof (sbtext_new), "Stopped | %d tracks | %s total playtime", deadbeef->pl_getcount (), totaltime_str);
songpos = 0;
}
@@ -107,7 +107,7 @@ update_songinfo (gpointer ctx) {
snprintf (sbitrate, sizeof (sbitrate), "%d kbps ", bitrate);
}
#endif
- const char *spaused = deadbeef->playback_ispaused () ? "Paused | " : "";
+ const char *spaused = deadbeef->get_output ()->state () == OUTPUT_STATE_PAUSED ? "Paused | " : "";
snprintf (sbtext_new, sizeof (sbtext_new), "%s%s %s| %dHz | %d bit | %s | %d:%02d / %s | %d tracks | %s total playtime", spaused, track->filetype ? track->filetype:"-", sbitrate, samplerate, bitspersample, mode, minpos, secpos, t, deadbeef->pl_getcount (), totaltime_str);
}
diff --git a/streamer.c b/streamer.c
index f13ecf94..da07cd84 100644
--- a/streamer.c
+++ b/streamer.c
@@ -369,7 +369,7 @@ streamer_thread (void *ctx) {
avg_bitrate = -1;
// change samplerate
if (prevtrack_samplerate != str_playing_song.decoder->info.samplerate) {
- palsa_change_rate (str_playing_song.decoder->info.samplerate);
+ plug_get_output ()->change_rate (str_playing_song.decoder->info.samplerate);
prevtrack_samplerate = str_playing_song.decoder->info.samplerate;
}
}