summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Makefile.am4
-rw-r--r--configure.ac64
-rw-r--r--plugins/oss/oss.c24
3 files changed, 86 insertions, 6 deletions
diff --git a/Makefile.am b/Makefile.am
index a3d0a84a..09629c54 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -19,8 +19,8 @@ SUBDIRS = gme/Game_Music_Emu-0.5.2\
${VFS_CURL_DIR}\
${CDDA_DIR}\
${GTKUI_DIR}\
- ${FFMPEG_DIR}
- plugins/oss
+ ${FFMPEG_DIR}\
+ ${OSS4_DIR}
dumbpath=@top_srcdir@/dumb
sidpath=@top_srcdir@/sid/sidplay-libs-2.1.0
diff --git a/configure.ac b/configure.ac
index 09d4a66c..49073c8c 100644
--- a/configure.ac
+++ b/configure.ac
@@ -176,6 +176,69 @@ if test ${HAVE_FFMPEG}; then
AC_SUBST(FFMPEG_DIR)
fi
+dnl *** OSS4 output (partly stolen from audacious)
+have_oss4=no
+
+AC_MSG_CHECKING(for OSS4 include dir)
+OSS4_CFLAGS=""
+if test -f "/etc/oss.conf" ; then
+ for i in `cat /etc/oss.conf`; do
+ t=`echo $i | sed -e 's/OSSLIBDIR=//'`
+ if test "x$i" != "x$t" ; then
+ if test -f "$t/include/sys/soundcard.h" -o -f "$i/include/soundcard.h" ; then
+ OSS4_CFLAGS="-I$t/include"
+ fi
+ fi
+ done
+fi
+if test -n "$OSS4_CFLAGS" ; then
+ AC_MSG_RESULT([$OSS4_CFLAGS])
+else
+ AC_MSG_RESULT([not found])
+fi
+CFLAGS_save=$CFLAGS
+CFLAGS="$CFLAGS $OSS4_CFLAGS"
+AC_CHECK_HEADERS(soundcard.h)
+AC_CHECK_HEADERS(sys/soundcard.h)
+AC_CHECK_HEADERS(machine/soundcard.h)
+CFLAGS=$CFLAGS_save
+
+if test "x${ac_cv_header_soundcard_h}" = "xyes" || test "x${ac_cv_header_sys_soundcard_h}" = "xyes" || test "x${ac_cv_header_machine_soundcard_h}" = "xyes"; then
+ have_oss4=yes
+fi
+
+if test "x${have_oss4}" = "xyes"; then
+AC_MSG_CHECKING(whether we need -lossaudio)
+ AC_TRY_LINK([
+ #include <sys/ioctl.h>
+ #ifdef HAVE_SYS_SOUNDCARD_H
+ #include <sys/soundcard.h>
+ #else
+ #include <soundcard.h>
+ #endif
+ ], [
+ int fd, value;
+ ioctl(fd, SOUND_MIXER_READ_VOLUME, &value);
+], AC_MSG_RESULT(no), [
+ OSS4_LIBS="-lossaudio"
+ AC_MSG_RESULT(yes)
+ ])
+fi
+
+if test "x$have_oss4" = "xyes"; then
+ AC_DEFINE(HAVE_OSS4, 1, [Define if the OSS4 output plugin should be built])
+else
+ have_oss4=no
+fi
+
+if test "x$have_oss4" = "xyes"; then
+ OSS4_DIR="plugins/oss"
+ AC_SUBST(OSS4_CFLAGS)
+ AC_SUBST(OSS4_DIR)
+ AC_SUBST(OSS4_LIBS)
+fi
+
+
dnl print summary
echo
echo "plugin summary:"
@@ -211,6 +274,7 @@ dnl PRINT_PLUGIN_INFO([faad2],[aac/mp4 player],[test $HAVE_FAAD && test $HAVE_MP
PRINT_PLUGIN_INFO([cdda],[cd audio player],[test $HAVE_CDIO && test $HAVE_CDDB])
PRINT_PLUGIN_INFO([gtkui],[GTK user interface],[test $HAVE_GTK])
PRINT_PLUGIN_INFO([ffmpeg],[ffmpeg codecs],[test $HAVE_FFMPEG])
+PRINT_PLUGIN_INFO([oss],[oss4 output plugin],[test "x$have_oss"="xyes"])
echo
AC_OUTPUT([
diff --git a/plugins/oss/oss.c b/plugins/oss/oss.c
index 06befad5..5507f59e 100644
--- a/plugins/oss/oss.c
+++ b/plugins/oss/oss.c
@@ -39,9 +39,10 @@ DB_functions_t *deadbeef;
static intptr_t oss_tid;
static int oss_terminate;
-static int oss_rate;
+static int oss_rate = 44100;
static int state;
static int fd;
+static uintptr_t mutex;
static void
oss_thread (void *context);
@@ -53,8 +54,8 @@ static int
oss_init (void) {
trace ("oss_init\n");
state = OUTPUT_STATE_STOPPED;
- oss_rate = 44100;
oss_terminate = 0;
+ mutex = 0;
// prepare oss for playback
const char *name = "/dev/dsp";
@@ -102,6 +103,8 @@ oss_init (void) {
trace ("oss: samplerate: %d\n", oss_rate);
+ mutex = deadbeef->mutex_create ();
+
oss_tid = deadbeef->thread_start (oss_thread, NULL);
return 0;
}
@@ -116,6 +119,7 @@ oss_change_rate (int rate) {
trace ("oss_change_rate: same rate (%d), ignored\n", rate);
return rate;
}
+ deadbeef->mutex_lock (mutex);
if (ioctl (fd, SNDCTL_DSP_SPEED, &rate) == -1) {
trace ("oss: can't switch to %d samplerate\n", rate);
perror ("SNDCTL_DSP_CHANNELS");
@@ -123,6 +127,7 @@ oss_change_rate (int rate) {
return -1;
}
oss_rate = rate;
+ deadbeef->mutex_unlock (mutex);
return oss_rate;
}
@@ -140,6 +145,10 @@ oss_free (void) {
if (fd) {
close (fd);
}
+ if (mutex) {
+ deadbeef->mutex_free (mutex);
+ mutex = 0;
+ }
}
return 0;
}
@@ -219,9 +228,13 @@ oss_thread (void *context) {
char buf[1024];
oss_callback (buf, 1024);
- if (write (fd, buf, sizeof (buf)) != sizeof (buf)) {
+ deadbeef->mutex_lock (mutex);
+ int res = write (fd, buf, sizeof (buf));
+ deadbeef->mutex_unlock (mutex);
+ if (res != sizeof (buf)) {
fprintf (stderr, "oss: failed to write buffer\n");
}
+ usleep (1000); // this must be here to prevent mutex deadlock
}
}
@@ -232,6 +245,10 @@ oss_callback (char *stream, int len) {
return;
}
int bytesread = deadbeef->streamer_read (stream, len);
+ 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);
+ }
if (bytesread < len) {
memset (stream + bytesread, 0, len-bytesread);
@@ -266,7 +283,6 @@ static DB_output_t plugin = {
.plugin.version_minor = 1,
.plugin.nostop = 0,
.plugin.type = DB_PLUGIN_OUTPUT,
- .plugin.id = "oss",
.plugin.name = "OSS output plugin",
.plugin.descr = "plays sound via OSS API",
.plugin.author = "Alexey Yakovenko",