audio backends can be called from different threads, so use a mutex
to protect global objects. from Thomas Pfaff, thanks
This commit is contained in:
parent
ebe658d00d
commit
6cf9c67d51
@ -1,4 +1,4 @@
|
||||
# $OpenBSD: Makefile,v 1.60 2008/12/28 22:31:51 jakemsr Exp $
|
||||
# $OpenBSD: Makefile,v 1.61 2009/01/16 04:15:46 jakemsr Exp $
|
||||
|
||||
COMMENT-main= Multimedia player for the X Window System
|
||||
COMMENT-vorbis= Ogg Vorbis input plugin for XMMS
|
||||
@ -9,7 +9,7 @@ SHARED_ONLY= Yes
|
||||
|
||||
VERSION= 1.2.11
|
||||
DISTNAME= xmms-${VERSION}
|
||||
PKGNAME-main= xmms-${VERSION}p3
|
||||
PKGNAME-main= xmms-${VERSION}p4
|
||||
PKGNAME-vorbis= xmms-vorbis-${VERSION}p0
|
||||
PKGNAME-mikmod= xmms-mikmod-${VERSION}p0
|
||||
PKGNAME-mp3= xmms-mp3-${VERSION}p0
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2008 Thomas Pfaff <tpfaff@tp76.info>
|
||||
* Copyright (c) 2008,2009 Thomas Pfaff <tpfaff@tp76.info>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
@ -14,23 +14,23 @@
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <gtk/gtk.h>
|
||||
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <sndio.h>
|
||||
|
||||
#include <xmms/plugin.h>
|
||||
#include <xmms/i18n.h>
|
||||
#include <libxmms/util.h>
|
||||
#include <libxmms/configfile.h>
|
||||
#include <pthread.h>
|
||||
#include <sndio.h>
|
||||
#include <xmms/i18n.h>
|
||||
#include <xmms/plugin.h>
|
||||
|
||||
#define VERSION "1.0"
|
||||
#define XMMS_MAXVOL 100
|
||||
|
||||
static void op_about (void);
|
||||
static void op_init (void);
|
||||
static void op_about (void);
|
||||
static void op_configure (void);
|
||||
static void op_get_volume (int *, int *);
|
||||
static void op_set_volume (int, int);
|
||||
@ -57,6 +57,7 @@ static long long wrpos;
|
||||
static int paused;
|
||||
static int volume = XMMS_MAXVOL;
|
||||
static long bytes_per_sec;
|
||||
static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
|
||||
|
||||
static GtkWidget *configure_win;
|
||||
static GtkWidget *adevice_entry;
|
||||
@ -65,7 +66,7 @@ static gchar *audiodev;
|
||||
static OutputPlugin sndio_op = {
|
||||
NULL,
|
||||
NULL,
|
||||
"sndio Output Plugin",
|
||||
"sndio Output Plugin " VERSION,
|
||||
op_init,
|
||||
op_about,
|
||||
op_configure,
|
||||
@ -98,7 +99,7 @@ op_about (void)
|
||||
|
||||
about = xmms_show_message (
|
||||
"About sndio Output Plugin",
|
||||
"XMMS sndio Output Plugin\n\n"
|
||||
"XMMS sndio Output Plugin " VERSION "\n\n"
|
||||
"Written by Thomas Pfaff <tpfaff@tp76.info>\n",
|
||||
"Ok", FALSE, NULL, NULL);
|
||||
|
||||
@ -122,16 +123,20 @@ op_init (void)
|
||||
static void
|
||||
op_get_volume (int *left, int *right)
|
||||
{
|
||||
pthread_mutex_lock (&mutex);
|
||||
*left = *right = volume;
|
||||
pthread_mutex_unlock (&mutex);
|
||||
}
|
||||
|
||||
static void
|
||||
op_set_volume (int left, int right)
|
||||
{
|
||||
/* Ignore balance control, so use unattenuated channel. */
|
||||
pthread_mutex_lock (&mutex);
|
||||
volume = left > right ? left : right;
|
||||
if (hdl != NULL)
|
||||
sio_setvol (hdl, volume * SIO_MAXVOL / XMMS_MAXVOL);
|
||||
pthread_mutex_unlock (&mutex);
|
||||
}
|
||||
|
||||
static int
|
||||
@ -139,13 +144,12 @@ op_open (AFormat fmt, int rate, int nch)
|
||||
{
|
||||
struct sio_par askpar;
|
||||
|
||||
if (strlen(audiodev) == 0)
|
||||
hdl = sio_open (NULL, SIO_PLAY, 0);
|
||||
else
|
||||
hdl = sio_open (audiodev, SIO_PLAY, 0);
|
||||
pthread_mutex_lock (&mutex);
|
||||
|
||||
hdl = sio_open (strlen (audiodev) > 0 ? audiodev : NULL, SIO_PLAY, 0);
|
||||
if (hdl == NULL) {
|
||||
fprintf (stderr, "%s: failed to open audio device\n", __func__);
|
||||
return 0;
|
||||
goto error;
|
||||
}
|
||||
|
||||
sio_initpar (&par);
|
||||
@ -189,8 +193,7 @@ op_open (AFormat fmt, int rate, int nch)
|
||||
break;
|
||||
default:
|
||||
fprintf (stderr, "%s: unknown format requested\n", __func__);
|
||||
op_close ();
|
||||
return 0;
|
||||
goto error;
|
||||
}
|
||||
par.pchan = nch;
|
||||
par.rate = rate;
|
||||
@ -201,8 +204,7 @@ op_open (AFormat fmt, int rate, int nch)
|
||||
askpar = par;
|
||||
if (!sio_setpar (hdl, &par) || !sio_getpar (hdl, &par)) {
|
||||
fprintf (stderr, "%s: failed to set parameters\n", __func__);
|
||||
op_close ();
|
||||
return 0;
|
||||
goto error;
|
||||
}
|
||||
|
||||
if ((par.bits == 16 && par.le != askpar.le) ||
|
||||
@ -215,50 +217,65 @@ op_open (AFormat fmt, int rate, int nch)
|
||||
"format that is not supported by the audio device.\n\n"
|
||||
"Please try again with the aucat(1) server running.",
|
||||
"OK", FALSE, NULL, NULL);
|
||||
op_close ();
|
||||
return 0;
|
||||
goto error;
|
||||
}
|
||||
|
||||
wrpos = 0;
|
||||
rdpos = 0;
|
||||
wrpos = 0;
|
||||
sio_onmove (hdl, onmove_cb, NULL);
|
||||
|
||||
op_set_volume (volume, volume);
|
||||
|
||||
paused = 0;
|
||||
if (!sio_start (hdl)) {
|
||||
fprintf (stderr, "%s: failed to start audio device\n",
|
||||
__func__);
|
||||
op_close ();
|
||||
return 0;
|
||||
goto error;
|
||||
}
|
||||
|
||||
bytes_per_sec = par.bps * par.pchan * par.rate;
|
||||
return 1;
|
||||
pthread_mutex_unlock (&mutex);
|
||||
op_set_volume (volume, volume);
|
||||
return TRUE;
|
||||
|
||||
error:
|
||||
pthread_mutex_unlock (&mutex);
|
||||
op_close ();
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static void
|
||||
op_write (void *ptr, int len)
|
||||
{
|
||||
if (!paused)
|
||||
wrpos += sio_write (hdl, ptr, len);
|
||||
if (!paused) {
|
||||
/* Do not lock sio_write as this will cause the GUI thread
|
||||
to block waiting for a blocked sio_write to return. */
|
||||
int bytes = sio_write (hdl, ptr, len);
|
||||
pthread_mutex_lock (&mutex);
|
||||
wrpos += bytes;
|
||||
pthread_mutex_unlock (&mutex);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
op_close (void)
|
||||
{
|
||||
pthread_mutex_lock (&mutex);
|
||||
if (hdl != NULL) {
|
||||
sio_close (hdl);
|
||||
hdl = NULL;
|
||||
}
|
||||
pthread_mutex_unlock (&mutex);
|
||||
}
|
||||
|
||||
static void
|
||||
op_seek (int time_ms)
|
||||
{
|
||||
int bufused = (rdpos < 0) ? wrpos : wrpos - rdpos;
|
||||
int bufused;
|
||||
|
||||
pthread_mutex_lock (&mutex);
|
||||
bufused = (rdpos < 0) ? wrpos : wrpos - rdpos;
|
||||
rdpos = time_ms / 1000 * bytes_per_sec;
|
||||
wrpos = rdpos + bufused;
|
||||
pthread_mutex_unlock (&mutex);
|
||||
}
|
||||
|
||||
static void
|
||||
@ -283,22 +300,35 @@ op_playing (void)
|
||||
static int
|
||||
op_get_output_time (void)
|
||||
{
|
||||
return hdl ? rdpos * 1000 / bytes_per_sec : 0;
|
||||
int time_ms;
|
||||
|
||||
pthread_mutex_lock (&mutex);
|
||||
time_ms = hdl ? rdpos * 1000 / bytes_per_sec : 0;
|
||||
pthread_mutex_unlock (&mutex);
|
||||
return time_ms;
|
||||
}
|
||||
|
||||
static int
|
||||
op_get_written_time (void)
|
||||
{
|
||||
return hdl ? wrpos * 1000 / bytes_per_sec : 0;
|
||||
int time_ms;
|
||||
|
||||
pthread_mutex_lock (&mutex);
|
||||
time_ms = hdl ? wrpos * 1000 / bytes_per_sec : 0;
|
||||
pthread_mutex_unlock (&mutex);
|
||||
return time_ms;
|
||||
}
|
||||
|
||||
static void
|
||||
onmove_cb (void *addr, int delta)
|
||||
{
|
||||
pthread_mutex_lock (&mutex);
|
||||
rdpos += delta * (int)(par.bps * par.pchan);
|
||||
pthread_mutex_unlock (&mutex);
|
||||
}
|
||||
|
||||
static void op_configure(void)
|
||||
static void
|
||||
op_configure(void)
|
||||
{
|
||||
GtkWidget *dev_vbox;
|
||||
GtkWidget *adevice_frame, *adevice_text, *adevice_vbox;
|
||||
|
Loading…
Reference in New Issue
Block a user