diff options
author | Alexey Yakovenko <wakeroid@gmail.com> | 2009-12-11 21:40:13 +0100 |
---|---|---|
committer | Alexey Yakovenko <wakeroid@gmail.com> | 2009-12-11 21:40:50 +0100 |
commit | b5196b51f6858347bc1af2e243cbc1cd742110ee (patch) | |
tree | 7d8728acd1c8d5fb178269636d3abd2bd205a080 | |
parent | 3dfee5bd02b3f264f3ccdf7513c5078b2806196c (diff) |
alsa code converted into output plugin
-rw-r--r-- | Makefile.am | 3 | ||||
-rw-r--r-- | cdumb.c | 2 | ||||
-rw-r--r-- | cgme.c | 5 | ||||
-rw-r--r-- | configure.ac | 14 | ||||
-rw-r--r-- | csid.cpp | 4 | ||||
-rw-r--r-- | deadbeef.h | 24 | ||||
-rw-r--r-- | main.c | 20 | ||||
-rw-r--r-- | palsa.h | 58 | ||||
-rw-r--r-- | playback.h | 33 | ||||
-rw-r--r-- | plugins.c | 48 | ||||
-rw-r--r-- | plugins.h | 3 | ||||
-rw-r--r-- | plugins/alsa/alsa.c (renamed from palsa.c) | 186 | ||||
-rw-r--r-- | plugins/gtkui/callbacks.c | 2 | ||||
-rw-r--r-- | plugins/gtkui/gtkplaylist.c | 2 | ||||
-rw-r--r-- | plugins/gtkui/gtkui.c | 4 | ||||
-rw-r--r-- | streamer.c | 2 |
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\ @@ -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) { @@ -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 @@ -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; @@ -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 @@ -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 - @@ -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 @@ -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; +} @@ -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); } @@ -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; } } |