[MPlayer-dev-eng] [PATCH] polypaudio audio driver

Lennart Poettering mzzcynlre at 0pointer.de
Thu Oct 28 02:19:55 CEST 2004


Hi!

I attached a patch against mplayer's current CVS which adds an output driver for
the polypaudio sound server
(http://0pointer.de/lennart/projects/polypaudio/).

Please merge it!

Since polypaudio's API is not fixed yet, expect some more patches to
the driver from me in the next months.

BTW: I'm probably not the first one to suggest it, but: please
consider changing mplayer to use autoconf/automake instead of this
home-grown build system you currently use. ;-)

BTW2: When subscribing to mplayer-dev-eng, the confirmation URL in the
confirmation mail is unaccessible, you get an error 404.

Thank you,
      Lennart Poettering

-- 
name { Lennart Poettering } loc { Hamburg - Germany }
mail { mzft (at) 0pointer (dot) de } gpg { 1A015CC4 }  
www { http://0pointer.de/lennart/ } icq# { 11060553 }
-------------- next part --------------
--- mplayer-cvs.orig/configure	2004-10-24 15:37:35.000000000 +0200
+++ mplayer-cvs/configure	2004-10-28 01:52:42.000000000 +0200
@@ -261,6 +261,7 @@
   --disable-ossaudio     disable OSS sound support [autodetect]
   --disable-arts         disable aRts sound support [autodetect]
   --disable-esd          disable esd sound support [autodetect]
+  --disable-polyp        disable Polypaudio sound support [autodetect]
   --disable-jack         disable JACK sound support [autodetect]
   --disable-nas          disable NAS sound support [autodetect]
   --disable-sgiaudio     disable SGI sound support [autodetect]
@@ -1286,6 +1287,7 @@
 _ossaudio=auto
 _arts=auto
 _esd=auto
+_polyp=auto
 _jack=auto
 _liblzo=auto
 _mad=auto
@@ -1462,6 +1464,8 @@
   --disable-arts)	_arts=no	;;
   --enable-esd)		_esd=yes	;;
   --disable-esd)	_esd=no		;;
+  --enable-polyp)	_polyp=yes	;;
+  --disable-polyp)	_polyp=no		;;
   --enable-jack)	_jack=yes	;;
   --disable-jack)	_jack=no	;;
   --enable-mad)		_mad=yes	;;
@@ -4376,6 +4380,34 @@
   _noaomodules="esd $_noaomodules"
 fi
 
+echocheck "Polyp"
+if test "$_polyp" = auto ; then
+  _polyp=no
+  if ( pkg-config --exists 'polyplib >= 0.6 polyplib-error >= 0.6 polyplib-mainloop >= 0.6' ) >> "$TMPLOG" 2>&1 ; then
+
+cat > $TMPC << EOF
+#include <polyp/polyplib.h>
+#include <polyp/mainloop.h>
+#include <polyp/polyplib-error.h>
+int main(void) { return 0; }
+EOF
+cc_check `pkg-config --libs --cflags polyplib polyplib-error polyplib-mainloop` && ( "$TMPO" >> "$TMPLOG" 2>&1 ) && _polyp=yes
+
+  fi
+fi
+echores "$_polyp"
+
+if test "$_polyp" = yes ; then
+  _def_polyp='#define USE_POLYP 1'
+  _aosrc="$_aosrc ao_polyp.c"
+  _aomodules="polyp $_aomodules"
+  _ld_polyp=`pkg-config --libs polyplib polyplib-error polyplib-mainloop`
+  _inc_polyp=`pkg-config --cflags polyplib polyplib-error polyplib-mainloop`
+else
+  _def_polyp='#undef USE_POLYP'
+  _noaomodules="polyp $_noaomodules"
+fi
+
 
 echocheck "JACK"
 if test "$_jack" = auto ; then
@@ -6452,6 +6484,8 @@
 ARTS_INC = $_inc_arts
 ESD_LIB = $_ld_esd
 ESD_INC = $_inc_esd
+POLYP_LIB = $_ld_polyp
+POLYP_INC = $_inc_polyp
 JACK_LIB = $_ld_jack
 JACK_INC = $_inc_jack
 SGIAUDIO_LIB = $_ld_sgiaudio
@@ -6876,6 +6910,7 @@
 $_def_arts
 $_def_esd
 $_def_esd_latency
+$_def_polyp
 $_def_jack
 $_def_sys_asoundlib_h
 $_def_alsa_asoundlib_h
--- mplayer-cvs.orig/Makefile	2004-10-26 08:36:38.000000000 +0200
+++ mplayer-cvs/Makefile	2004-10-28 01:53:27.000000000 +0200
@@ -31,7 +31,7 @@
 OBJS_MPLAYER = $(SRCS_MPLAYER:.c=.o)
 
 VO_LIBS = $(AA_LIB) $(X_LIB) $(SDL_LIB) $(GGI_LIB) $(MP1E_LIB) $(MLIB_LIB) $(SVGA_LIB) $(DIRECTFB_LIB) $(CACA_LIB)
-AO_LIBS = $(ARTS_LIB) $(ESD_LIB) $(JACK_LIB) $(NAS_LIB) $(SGIAUDIO_LIB)
+AO_LIBS = $(ARTS_LIB) $(ESD_LIB) $(JACK_LIB) $(NAS_LIB) $(SGIAUDIO_LIB) $(POLYP_LIB)
 CODEC_LIBS = $(AV_LIB) $(FAME_LIB) $(MAD_LIB) $(VORBIS_LIB) $(THEORA_LIB) $(FAAD_LIB) $(LIBLZO_LIB) $(DECORE_LIB) $(XVID_LIB) $(DTS_LIB) $(PNG_LIB) $(Z_LIB) $(JPEG_LIB) $(ALSA_LIB) $(XMMS_LIB) $(X264_LIB)
 COMMON_LIBS = libmpcodecs/libmpcodecs.a $(W32_LIB) $(DS_LIB) libaf/libaf.a libmpdemux/libmpdemux.a input/libinput.a postproc/libswscale.a osdep/libosdep.a $(DVDREAD_LIB) $(CODEC_LIBS) $(FREETYPE_LIB) $(TERMCAP_LIB) $(CDPARANOIA_LIB) $(MPLAYER_NETWORK_LIB) $(WIN32_LIB) $(GIF_LIB) $(MACOSX_FRAMEWORKS) $(SMBSUPPORT_LIB) $(FRIBIDI_LIB) $(FONTCONFIG_LIB) $(ENCA_LIB)
 
--- mplayer-cvs.orig/libao2/Makefile	2004-06-25 20:11:13.000000000 +0200
+++ mplayer-cvs/libao2/Makefile	2004-10-28 01:52:42.000000000 +0200
@@ -6,7 +6,7 @@
 
 OBJS=$(SRCS:.c=.o)
 
-CFLAGS  = $(OPTFLAGS) -I. -I.. $(ARTS_INC) $(ESD_INC) $(JACK_INC) $(SDL_INC) $(X11_INC) $(EXTRA_INC) $(DXR2_INC) $(DVB_INC)
+CFLAGS  = $(OPTFLAGS) -I. -I.. $(ARTS_INC) $(ESD_INC) $(JACK_INC) $(SDL_INC) $(X11_INC) $(EXTRA_INC) $(DXR2_INC) $(DVB_INC) $(POLYP_INC)
 
 .SUFFIXES: .c .o
 
--- mplayer-cvs.orig/libao2/ao_polyp.c	1970-01-01 01:00:00.000000000 +0100
+++ mplayer-cvs/libao2/ao_polyp.c	2004-10-28 01:52:42.000000000 +0200
@@ -0,0 +1,267 @@
+#include <assert.h>
+
+#include "../config.h"
+
+#include <polyp/polyplib.h>
+#include <polyp/polyplib-error.h>
+#include <polyp/mainloop.h>
+
+#include "audio_out.h"
+#include "audio_out_internal.h"
+#include "afmt.h"
+#include "../config.h"
+#include "../mp_msg.h"
+
+#define	POLYP_CLIENT_NAME "MPlayer"
+
+static ao_info_t info = {
+    "Polypaudio audio output",
+    "polyp",
+    "Lennart Poettering",
+    ""
+};
+
+static char *sink = NULL;
+
+static struct pa_stream *stream = NULL;
+static struct pa_context *context = NULL;
+static struct pa_mainloop *mainloop = NULL;
+
+LIBAO_EXTERN(polyp)
+
+static void wait_for_completion(void) {
+    assert(context && mainloop);
+
+    while (pa_context_is_pending(context))
+        pa_mainloop_iterate(mainloop, 1, NULL);
+}
+
+static void keep_alive(void) {
+    assert(context && mainloop);
+
+    while (pa_mainloop_iterate(mainloop, 0, NULL) > 0);
+}
+
+static void wait_for_operation(struct pa_operation *o) {
+    assert(o && context && mainloop);
+
+    while (pa_operation_get_state(o) == PA_OPERATION_RUNNING)
+        pa_mainloop_iterate(mainloop, 1, NULL);
+
+    pa_operation_unref(o);
+}
+
+static int init(int rate_hz, int channels, int format, int flags) {
+    struct pa_sample_spec ss;
+    struct pa_buffer_attr a;
+
+    assert(!context && !stream && !mainloop);
+
+    ss.channels = channels;
+    ss.rate = rate_hz;
+
+    switch (format) {
+        case AFMT_U8:
+            ss.format = PA_SAMPLE_U8;
+            break;
+        case AFMT_S16_LE:
+            ss.format = PA_SAMPLE_S16LE;
+            break;
+        case AFMT_S16_BE:
+            ss.format = PA_SAMPLE_S16BE;
+            break;
+        case AFMT_FLOAT:
+            ss.format = PA_SAMPLE_FLOAT32;
+            break;
+        default:
+            mp_msg(MSGT_AO, MSGL_ERR, "AO: [polyp] Unsupported sample spec\n");
+            goto fail;
+    }
+
+
+    if (!pa_sample_spec_valid(&ss)) {
+        mp_msg(MSGT_AO, MSGL_ERR, "AO: [polyp] Invalid sample spec\n");
+        goto fail;
+    }
+        
+
+    mainloop = pa_mainloop_new();
+    assert(mainloop);
+
+    context = pa_context_new(pa_mainloop_get_api(mainloop), POLYP_CLIENT_NAME);
+    assert(context);
+
+    pa_context_connect(context, NULL, 1, NULL);
+
+    wait_for_completion();
+
+    if (pa_context_get_state(context) != PA_CONTEXT_READY) {
+        mp_msg(MSGT_AO, MSGL_ERR, "AO: [polyp] Failed to connect to server: %s\n", pa_strerror(pa_context_errno(context)));
+        goto fail;
+    }
+
+    stream = pa_stream_new(context, "audio stream", &ss);
+    assert(stream);
+
+    a.maxlength = pa_bytes_per_second(&ss)*1;
+    a.tlength = a.maxlength*9/10;
+    a.prebuf = a.tlength/2;
+    a.minreq = a.tlength/10;
+    
+    pa_stream_connect_playback(stream, NULL, &a, PA_STREAM_INTERPOLATE_LATENCY, PA_VOLUME_NORM);
+
+    wait_for_completion();
+
+    if (pa_stream_get_state(stream) != PA_STREAM_READY) {
+        mp_msg(MSGT_AO, MSGL_ERR, "AO: [polyp] Failed to connect to server: %s\n", pa_strerror(pa_context_errno(context)));
+        goto fail;
+    }
+    
+    return 1;
+
+fail:
+    uninit(1);
+    return 0;
+}
+
+static void uninit(int immed) {
+    if (stream) {
+        if (!immed && pa_stream_get_state(stream) == PA_STREAM_READY)
+                wait_for_operation(pa_stream_drain(stream, NULL, NULL));
+        
+        pa_stream_unref(stream);
+        stream = NULL;
+    }
+
+    if (context) {
+        pa_context_unref(context);
+        context = NULL;
+    }
+
+    if (mainloop) {
+        pa_mainloop_free(mainloop);
+        mainloop = NULL;
+    }
+}
+
+static int play(void* data, int len, int flags) {
+    assert(stream && context);
+
+    if (pa_stream_get_state(stream) != PA_STREAM_READY)
+        return -1;
+
+    if (!len)
+        wait_for_operation(pa_stream_trigger(stream, NULL, NULL));
+    else
+        pa_stream_write(stream, data, len, NULL, 0);
+
+    wait_for_completion();
+
+    if (pa_stream_get_state(stream) != PA_STREAM_READY)
+        return -1;
+
+    return len;
+}
+
+static void audio_pause() {
+    assert(stream && context && pa_stream_get_state(stream) == PA_STREAM_READY);
+    wait_for_operation(pa_stream_cork(stream, 1, NULL, NULL));
+}
+
+static void audio_resume() {
+    assert(stream && context && pa_stream_get_state(stream) == PA_STREAM_READY);
+    wait_for_operation(pa_stream_cork(stream, 0, NULL, NULL));
+}
+
+static void reset() {
+    assert(stream && context && pa_stream_get_state(stream) == PA_STREAM_READY);
+    wait_for_operation(pa_stream_flush(stream, NULL, NULL));
+}
+
+static int get_space(void) {
+    uint32_t l;
+    assert(stream && context && pa_stream_get_state(stream) == PA_STREAM_READY);
+    
+    keep_alive();
+
+    l = pa_stream_writable_size(stream);
+    
+    return l;
+}
+
+static pa_usec_t latency = 0;
+
+static void latency_func(struct pa_stream *s, const struct pa_latency_info *l, void *userdata) {
+    if (!l) {
+        mp_msg(MSGT_AO, MSGL_ERR, "AO: [polyp] Invalid sample spec: %s\n", pa_strerror(pa_context_errno(context)));
+        return;
+    }
+
+    latency = l->buffer_usec + l->sink_usec + l->transport_usec;
+}
+
+static float get_delay(void) {
+    assert(stream && context && pa_stream_get_state(stream) == PA_STREAM_READY);
+/*     latency = 0; */
+/*     wait_for_operation(pa_stream_get_latency(stream, latency_func, NULL)); */
+    /*     pa_operation_unref(pa_stream_get_latency(stream, latency_func, NULL)); */
+
+    latency = pa_stream_get_interpolated_latency(stream, NULL);
+    
+    return (float) latency/1000000;
+}
+
+static pa_volume_t volume = PA_VOLUME_NORM;
+
+static void info_func(struct pa_context *c, const struct pa_sink_input_info *i, int is_last, void *userdata) {
+    if (is_last < 0) {
+        mp_msg(MSGT_AO, MSGL_ERR, "AO: [polyp] Failed to get sink input info: %s\n", pa_strerror(pa_context_errno(context)));
+        return;
+    }
+
+    if (!i)
+        return;
+
+    volume = i->volume;
+}
+
+static int control(int cmd, void *arg) {
+    
+    if (!context || !stream)
+        return CONTROL_ERROR;
+    
+    switch (cmd) {
+
+        case AOCONTROL_SET_DEVICE:
+            sink = (char*)arg;
+            return CONTROL_OK;
+            
+        case AOCONTROL_GET_DEVICE:
+            *(char**)arg = sink;
+            return CONTROL_OK;
+        
+        case AOCONTROL_GET_VOLUME: {
+            ao_control_vol_t *vol = (ao_control_vol_t*) arg;
+                
+            volume = PA_VOLUME_NORM;
+            wait_for_operation(pa_context_get_sink_input_info(context, pa_stream_get_index(stream), info_func, NULL));
+            vol->left = vol->right = (int) (pa_volume_to_user(volume)*100);
+            return CONTROL_OK;
+        }
+            
+        case AOCONTROL_SET_VOLUME: {
+            const ao_control_vol_t *vol = (ao_control_vol_t*) arg;
+            int v = vol->left;
+            if (vol->right > v)
+                v = vol->left;
+            
+            wait_for_operation(pa_context_set_sink_input_volume(context, pa_stream_get_index(stream), pa_volume_from_user((double)v/100), NULL, NULL));
+            
+            return CONTROL_OK;
+        }
+            
+        default:
+            return CONTROL_UNKNOWN;
+    }
+}
+
--- mplayer-cvs.orig/libao2/audio_out.c	2004-10-13 18:22:57.000000000 +0200
+++ mplayer-cvs/libao2/audio_out.c	2004-10-28 01:52:42.000000000 +0200
@@ -25,6 +25,9 @@
 #ifdef USE_ESD
 extern ao_functions_t audio_out_esd;
 #endif
+#ifdef USE_POLYP
+extern ao_functions_t audio_out_polyp;
+#endif
 #ifdef USE_JACK
 extern ao_functions_t audio_out_jack;
 #endif
@@ -103,6 +106,9 @@
 #ifdef USE_ESD
         &audio_out_esd,
 #endif
+#ifdef USE_POLYP
+        &audio_out_polyp,
+#endif
 #ifdef USE_JACK
         &audio_out_jack,
 #endif
--- mplayer-cvs.orig/AUTHORS	2004-10-20 23:28:29.000000000 +0200
+++ mplayer-cvs/AUTHORS	2004-10-28 02:05:35.000000000 +0200
@@ -726,6 +726,8 @@
 Zubimendi, Andoni <andoni at lpsat.net>.
     * Spanish documentation translation
 
+Poettering, Lennart <mzzcynlre at 0pointer.de>
+    * Audio driver for the Polypaudio sound server
 
 ________________
 The codecs, libs
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 189 bytes
Desc: Digital signature
URL: <http://lists.mplayerhq.hu/pipermail/mplayer-dev-eng/attachments/20041028/8cbbf20f/attachment.pgp>


More information about the MPlayer-dev-eng mailing list