Update the plug-in to the newer 3.x plug-in semantics. Fixes audacious

unpausing by itself as various other bugs caused by using the version
2.x plug-in.

ok stsp, dcoppa
This commit is contained in:
ratchov 2012-05-09 20:53:35 +00:00
parent b2dd2d7451
commit d155f572cb
2 changed files with 102 additions and 89 deletions

View File

@ -1,4 +1,4 @@
# $OpenBSD: Makefile,v 1.43 2012/04/06 14:38:01 dcoppa Exp $ # $OpenBSD: Makefile,v 1.44 2012/05/09 20:53:35 ratchov Exp $
SHARED_ONLY = Yes SHARED_ONLY = Yes
@ -6,7 +6,7 @@ COMMENT = input and output plugins for audacious
V = 3.2 V = 3.2
DISTNAME = audacious-plugins-$V DISTNAME = audacious-plugins-$V
REVISION = 2 REVISION = 3
CATEGORIES = audio multimedia CATEGORIES = audio multimedia

View File

@ -15,11 +15,13 @@
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/ */
#include <errno.h>
#include <poll.h>
#include <pthread.h>
#include <sndio.h> #include <sndio.h>
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include <pthread.h>
#include <gtk/gtk.h> #include <gtk/gtk.h>
#include <audacious/plugin.h> #include <audacious/plugin.h>
#include <audacious/misc.h> #include <audacious/misc.h>
@ -39,6 +41,8 @@ void sndio_get_volume(int *, int *);
void sndio_set_volume(int, int); void sndio_set_volume(int, int);
bool_t sndio_open(int, int, int); bool_t sndio_open(int, int, int);
void sndio_close(void); void sndio_close(void);
int sndio_buffer_free(void);
void sndio_period_wait(void);
void sndio_write(void *, int); void sndio_write(void *, int);
void sndio_pause(bool_t); void sndio_pause(bool_t);
void sndio_flush(int); void sndio_flush(int);
@ -56,12 +60,10 @@ static struct sio_par par;
static struct sio_hdl *hdl; static struct sio_hdl *hdl;
static long long rdpos; static long long rdpos;
static long long wrpos; static long long wrpos;
static int paused, flushed, volume; static int paused, restarted, volume;
static int flush_time, pause_flag, volume_target; static int pause_pending, flush_pending, volume_pending;
static int writing, pause_pending, flush_pending, volume_pending;
static int bytes_per_sec; static int bytes_per_sec;
static pthread_mutex_t mtx; static pthread_mutex_t mtx;
static pthread_t sndio_thread;
static GtkWidget *configure_win; static GtkWidget *configure_win;
static GtkWidget *adevice_entry; static GtkWidget *adevice_entry;
@ -80,6 +82,8 @@ AUD_OUTPUT_PLUGIN
.open_audio = sndio_open, .open_audio = sndio_open,
.write_audio = sndio_write, .write_audio = sndio_write,
.close_audio = sndio_close, .close_audio = sndio_close,
.buffer_free = sndio_buffer_free,
.period_wait = sndio_period_wait,
.flush = sndio_flush, .flush = sndio_flush,
.pause = sndio_pause, .pause = sndio_pause,
.output_time = sndio_output_time, .output_time = sndio_output_time,
@ -100,70 +104,62 @@ static struct fmt_to_par {
{FMT_U32_LE, 32, 0, 1}, {FMT_U32_BE, 32, 0, 0} {FMT_U32_LE, 32, 0, 1}, {FMT_U32_BE, 32, 0, 0}
}; };
static const gchar * const sndio_defaults[] = {
"volume", "100",
"audiodev", "",
NULL,
};
static void static void
volume_do(int v) reset(void)
{ {
if (writing) { if (!restarted) {
volume_target = v; restarted = 1;
volume_pending = 1; sio_stop(hdl);
} else { sio_start(hdl);
if (hdl) rdpos = wrpos;
sio_setvol(hdl, v * SIO_MAXVOL / 100); }
}
static void
wait_ready(void)
{
int n;
struct pollfd pfds[16];
if (volume_pending) {
sio_setvol(hdl, volume * SIO_MAXVOL / 100);
volume_pending = 0; volume_pending = 0;
} }
} if (flush_pending) {
reset();
static void flush_pending = 0;
pause_do(int flag) }
{ if (pause_pending) {
if (writing) { if (paused)
pause_flag = flag; reset();
pause_pending = 1;
} else {
if (flag && !paused && !flushed) {
sio_stop(hdl);
sio_start(hdl);
rdpos = wrpos;
}
paused = flag;
pause_pending = 0; pause_pending = 0;
} }
} if (paused) {
pthread_mutex_unlock(&mtx);
static void usleep(20000);
flush_do(int time) pthread_mutex_lock(&mtx);
{ return;
if (writing) {
flush_time = time;
flush_pending = 1;
} else {
if (!paused && !flushed) {
sio_stop(hdl);
sio_start(hdl);
}
rdpos = wrpos = (long long)time * bytes_per_sec / 1000;
flush_pending = 0;
flushed = 1;
} }
n = sio_pollfd(hdl, pfds, POLLOUT);
if (n != 0) {
pthread_mutex_unlock(&mtx);
while (poll(pfds, n, -1) < 0) {
if (errno != EINTR) {
perror("poll");
exit(1);
}
}
pthread_mutex_lock(&mtx);
}
(void)sio_revents(hdl, pfds);
} }
void
sndio_about(void)
{
static GtkWidget *about = NULL;
audgui_simple_message(&about, GTK_MESSAGE_INFO,
_("About Sndio Output Plugin"),
_("Sndio Output Plugin\n\n"
"Written by Thomas Pfaff <tpfaff@tp76.info>\n"));
}
static const gchar * const sndio_defaults[] = {
"volume", "100",
"audiodev", "",
NULL,
};
bool_t bool_t
sndio_init(void) sndio_init(void)
{ {
@ -184,6 +180,17 @@ sndio_cleanup(void)
pthread_mutex_destroy(&mtx); pthread_mutex_destroy(&mtx);
} }
void
sndio_about(void)
{
static GtkWidget *about = NULL;
audgui_simple_message(&about, GTK_MESSAGE_INFO,
_("About Sndio Output Plugin"),
_("Sndio Output Plugin\n\n"
"Written by Thomas Pfaff <tpfaff@tp76.info>\n"));
}
void void
sndio_get_volume(int *l, int *r) sndio_get_volume(int *l, int *r)
{ {
@ -198,7 +205,7 @@ sndio_set_volume(int l, int r)
/* Ignore balance control, so use unattenuated channel. */ /* Ignore balance control, so use unattenuated channel. */
pthread_mutex_lock(&mtx); pthread_mutex_lock(&mtx);
volume = l > r ? l : r; volume = l > r ? l : r;
volume_do(volume); volume_pending = 1;
pthread_mutex_unlock(&mtx); pthread_mutex_unlock(&mtx);
} }
@ -209,7 +216,7 @@ sndio_open(int fmt, int rate, int nch)
struct sio_par askpar; struct sio_par askpar;
GtkWidget *dialog = NULL; GtkWidget *dialog = NULL;
hdl = sio_open(strlen(audiodev) > 0 ? audiodev : NULL, SIO_PLAY, 0); hdl = sio_open(strlen(audiodev) > 0 ? audiodev : NULL, SIO_PLAY, 1);
if (!hdl) { if (!hdl) {
g_warning("failed to open audio device %s", audiodev); g_warning("failed to open audio device %s", audiodev);
return (0); return (0);
@ -256,7 +263,7 @@ sndio_open(int fmt, int rate, int nch)
wrpos = 0; wrpos = 0;
sio_onmove(hdl, onmove_cb, NULL); sio_onmove(hdl, onmove_cb, NULL);
sio_onvol(hdl, onvol_cb, NULL); sio_onvol(hdl, onvol_cb, NULL);
volume_do(volume); sio_setvol(hdl, volume * SIO_MAXVOL / 100);
if (!sio_start(hdl)) { if (!sio_start(hdl)) {
g_warning("failed to start audio device"); g_warning("failed to start audio device");
sndio_close(); sndio_close();
@ -264,7 +271,7 @@ sndio_open(int fmt, int rate, int nch)
} }
pause_pending = flush_pending = volume_pending = 0; pause_pending = flush_pending = volume_pending = 0;
bytes_per_sec = par.bps * par.pchan * par.rate; bytes_per_sec = par.bps * par.pchan * par.rate;
flushed = 1; restarted = 1;
paused = 0; paused = 0;
return (1); return (1);
} }
@ -275,25 +282,19 @@ sndio_write(void *ptr, int length)
unsigned n; unsigned n;
pthread_mutex_lock(&mtx); pthread_mutex_lock(&mtx);
flushed = 0; for (;;) {
if (!paused) { if (paused)
writing = 1; break;
pthread_mutex_unlock(&mtx); restarted = 0;
n = sio_write(hdl, ptr, length); n = sio_write(hdl, ptr, length);
pthread_mutex_lock(&mtx); if (n == 0 && sio_eof(hdl))
writing = 0; return;
wrpos += n; wrpos += n;
} length -= n;
if (volume_pending) ptr = (char *)ptr + n;
volume_do(volume); if (length == 0)
if (flush_pending) break;
flush_do(flush_time); wait_ready();
if (pause_pending)
pause_do(pause_flag);
if (paused) {
pthread_mutex_unlock(&mtx);
usleep(10000);
pthread_mutex_lock(&mtx);
} }
pthread_mutex_unlock(&mtx); pthread_mutex_unlock(&mtx);
} }
@ -307,11 +308,26 @@ sndio_close(void)
hdl = NULL; hdl = NULL;
} }
int
sndio_buffer_free(void)
{
return paused ? 0 : par.round * par.pchan * par.bps;
}
void
sndio_period_wait(void)
{
pthread_mutex_lock(&mtx);
wait_ready();
pthread_mutex_unlock(&mtx);
}
void void
sndio_flush(int time) sndio_flush(int time)
{ {
pthread_mutex_lock(&mtx); pthread_mutex_lock(&mtx);
flush_do(time); rdpos = wrpos = (long long)time * bytes_per_sec / 1000;
flush_pending = 1;
pthread_mutex_unlock(&mtx); pthread_mutex_unlock(&mtx);
} }
@ -319,7 +335,8 @@ void
sndio_pause(bool_t flag) sndio_pause(bool_t flag)
{ {
pthread_mutex_lock(&mtx); pthread_mutex_lock(&mtx);
pause_do(flag); paused = flag;
pause_pending = 1;
pthread_mutex_unlock(&mtx); pthread_mutex_unlock(&mtx);
} }
@ -367,19 +384,15 @@ sndio_set_written_time(int time)
void void
onmove_cb(void *addr, int delta) onmove_cb(void *addr, int delta)
{ {
pthread_mutex_lock(&mtx);
rdpos += delta * (int)(par.bps * par.pchan); rdpos += delta * (int)(par.bps * par.pchan);
pthread_mutex_unlock(&mtx);
} }
void void
onvol_cb(void *addr, unsigned ctl) onvol_cb(void *addr, unsigned ctl)
{ {
/* Update volume only if it actually changed */ /* Update volume only if it actually changed */
pthread_mutex_lock(&mtx);
if (ctl != volume * SIO_MAXVOL / 100) if (ctl != volume * SIO_MAXVOL / 100)
volume = ctl * 100 / SIO_MAXVOL; volume = ctl * 100 / SIO_MAXVOL;
pthread_mutex_unlock(&mtx);
} }
void void