[polypaudio-commits] r457 - /trunk/polyp/module-solaris.c

svnmailer-noreply at 0pointer.de svnmailer-noreply at 0pointer.de
Thu Jan 19 02:24:49 PST 2006


Author: ossman
Date: Thu Jan 19 11:24:49 2006
New Revision: 457

URL: http://0pointer.de/cgi-bin/viewcvs.cgi?rev=457&root=polypaudio&view=rev
Log:
Ugly hack to get around Solaris particularly brain dead sound system.
The system has a buffer size of 0.5 MB which cannot be changed. We emulate
a smaller buffer through some SIGPOLL trickery.

Modified:
    trunk/polyp/module-solaris.c

Modified: trunk/polyp/module-solaris.c
URL: http://0pointer.de/cgi-bin/viewcvs.cgi/trunk/polyp/module-solaris.c?rev=457&root=polypaudio&r1=456&r2=457&view=diff
==============================================================================
--- trunk/polyp/module-solaris.c (original)
+++ trunk/polyp/module-solaris.c Thu Jan 19 11:24:49 2006
@@ -35,6 +35,7 @@
 #include <sys/stat.h>
 #include <sys/types.h>
 
+#include <signal.h>
 #include <stropts.h>
 #include <sys/conf.h>
 #include <sys/audio.h>
@@ -48,6 +49,7 @@
 #include "modargs.h"
 #include "xmalloc.h"
 #include "log.h"
+#include "mainloop-signal.h"
 #include "module-solaris-symdef.h"
 
 PA_MODULE_AUTHOR("Pierre Ossman")
@@ -62,10 +64,12 @@
     pa_source *source;
     pa_iochannel *io;
     pa_core *core;
+    pa_signal_event *sig;
 
     pa_memchunk memchunk, silence;
 
     uint32_t sample_size;
+    uint32_t buffer_size;
     unsigned int written_bytes, read_bytes;
 
     int fd;
@@ -99,7 +103,10 @@
 }
 
 static void do_write(struct userdata *u) {
+    audio_info_t info;
+    int err;
     pa_memchunk *memchunk;
+    size_t len;
     ssize_t r;
     
     assert(u);
@@ -109,17 +116,40 @@
 
     update_usage(u);
 
+    err = ioctl(u->fd, AUDIO_GETINFO, &info);
+    assert(err >= 0);
+
+    /*
+     * Since we cannot modify the size of the output buffer we fake it
+     * by not filling it more than u->buffer_size.
+     */
+    len = u->buffer_size;
+    len -= u->written_bytes - (info.play.samples * u->sample_size);
+
+    /*
+     * Do not fill more than half the buffer in one chunk since we only
+     * get notifications upon completion of entire chunks.
+     */
+    if (len > (u->buffer_size / 2))
+        len = u->buffer_size / 2;
+
+    if (len < u->sample_size)
+        return;
+
     memchunk = &u->memchunk;
     
     if (!memchunk->length)
-        if (pa_sink_render(u->sink, CHUNK_SIZE, memchunk) < 0)
+        if (pa_sink_render(u->sink, len, memchunk) < 0)
             memchunk = &u->silence;
     
     assert(memchunk->memblock);
     assert(memchunk->memblock->data);
     assert(memchunk->length);
-    
-    if ((r = pa_iochannel_write(u->io, (uint8_t*) memchunk->memblock->data + memchunk->index, memchunk->length)) < 0) {
+
+    if (memchunk->length < len)
+        len = memchunk->length;
+    
+    if ((r = pa_iochannel_write(u->io, (uint8_t*) memchunk->memblock->data + memchunk->index, len)) < 0) {
         pa_log(__FILE__": write() failed: %s\n", strerror(errno));
         return;
     }
@@ -137,6 +167,14 @@
     }
 
     u->written_bytes += r;
+
+    /*
+     * Write 0 bytes which will generate a SIGPOLL when "played".
+     */
+    if (write(u->fd, NULL, 0) < 0) {
+        pa_log(__FILE__": write() failed: %s\n", strerror(errno));
+        return;
+    }
 }
 
 static void do_read(struct userdata *u) {
@@ -177,6 +215,12 @@
     assert(u);
     do_write(u);
     do_read(u);
+}
+
+void sig_callback(pa_mainloop_api *api, pa_signal_event*e, int sig, void *userdata) {
+    struct userdata *u = userdata;
+    assert(u);
+    do_write(u);
 }
 
 static pa_usec_t sink_get_latency_cb(pa_sink *s) {
@@ -326,7 +370,7 @@
 
     mode = (playback&&record) ? O_RDWR : (playback ? O_WRONLY : (record ? O_RDONLY : 0));
 
-    buffer_size = -1;    
+    buffer_size = 16384;    
     if (pa_modargs_get_value_s32(ma, "buffer_size", &buffer_size) < 0) {
         pa_log(__FILE__": failed to parse buffer size argument\n");
         goto fail;
@@ -383,6 +427,7 @@
     u->memchunk.memblock = NULL;
     u->memchunk.length = 0;
     u->sample_size = pa_frame_size(&ss);
+    u->buffer_size = buffer_size;
 
     u->silence.memblock = pa_memblock_new(u->silence.length = CHUNK_SIZE, u->core->memblock_stat);
     assert(u->silence.memblock);
@@ -395,6 +440,10 @@
     u->module = m;
     m->userdata = u;
 
+    u->sig = pa_signal_new(SIGPOLL, sig_callback, u);
+    assert(u->sig);
+    ioctl(u->fd, I_SETSIG, S_MSG);
+
     pa_modargs_free(ma);
 
     return 0;
@@ -415,6 +464,9 @@
 
     if (!(u = m->userdata))
         return;
+
+    ioctl(u->fd, I_SETSIG, 0);
+    pa_signal_free(u->sig);
     
     if (u->memchunk.memblock)
         pa_memblock_unref(u->memchunk.memblock);




More information about the pulseaudio-commits mailing list