]> code.delx.au - pulseaudio/blobdiff - polyp/module-pipe-sink.c
Make the whole stuff LGPL only
[pulseaudio] / polyp / module-pipe-sink.c
index 088ed405d3b4ddbc99010b61d7f6f9cf46e8ee94..6c441cc8c0e7d3b4d3b7da92db9405522ef33c89 100644 (file)
@@ -4,7 +4,7 @@
   This file is part of polypaudio.
  
   polypaudio is free software; you can redistribute it and/or modify
-  it under the terms of the GNU General Public License as published
+  it under the terms of the GNU Lesser General Public License as published
   by the Free Software Foundation; either version 2 of the License,
   or (at your option) any later version.
  
@@ -13,7 +13,7 @@
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
   General Public License for more details.
  
-  You should have received a copy of the GNU General Public License
+  You should have received a copy of the GNU Lesser General Public License
   along with polypaudio; if not, write to the Free Software
   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
   USA.
 #include "util.h"
 #include "modargs.h"
 #include "xmalloc.h"
+#include "log.h"
+#include "module-pipe-sink-symdef.h"
 
-#define DEFAULT_FIFO_NAME "/tmp/musicfifo"
+PA_MODULE_AUTHOR("Lennart Poettering")
+PA_MODULE_DESCRIPTION("UNIX pipe sink")
+PA_MODULE_VERSION(PACKAGE_VERSION)
+PA_MODULE_USAGE("sink_name=<name for the sink> file=<path of the FIFO> format=<sample format> channels=<number of channels> rate=<sample rate>")
+
+#define DEFAULT_FIFO_NAME "/tmp/music.output"
 #define DEFAULT_SINK_NAME "fifo_output"
 
 struct userdata {
@@ -59,8 +66,8 @@ struct userdata {
 static const char* const valid_modargs[] = {
     "file",
     "rate",
-    "channels",
     "format",
+    "channels",
     "sink_name",
     NULL
 };
@@ -83,7 +90,7 @@ static void do_write(struct userdata *u) {
     assert(u->memchunk.memblock && u->memchunk.length);
     
     if ((r = pa_iochannel_write(u->io, (uint8_t*) u->memchunk.memblock->data + u->memchunk.index, u->memchunk.length)) < 0) {
-        fprintf(stderr, "write() failed: %s\n", strerror(errno));
+        pa_log(__FILE__": write() failed: %s\n", strerror(errno));
         return;
     }
 
@@ -104,6 +111,13 @@ static void notify_cb(struct pa_sink*s) {
         u->core->mainloop->defer_enable(u->defer_event, 1);
 }
 
+static pa_usec_t get_latency_cb(struct pa_sink *s) {
+    struct userdata *u = s->userdata;
+    assert(s && u);
+
+    return u->memchunk.memblock ? pa_bytes_to_usec(u->memchunk.length, &s->sample_spec) : 0;
+}
+
 static void defer_callback(struct pa_mainloop_api *m, struct pa_defer_event*e, void *userdata) {
     struct userdata *u = userdata;
     assert(u);
@@ -116,7 +130,7 @@ static void io_callback(struct pa_iochannel *io, void*userdata) {
     do_write(u);
 }
 
-int pa_module_init(struct pa_core *c, struct pa_module*m) {
+int pa__init(struct pa_core *c, struct pa_module*m) {
     struct userdata *u = NULL;
     struct stat st;
     const char *p;
@@ -126,45 +140,47 @@ int pa_module_init(struct pa_core *c, struct pa_module*m) {
     assert(c && m);
     
     if (!(ma = pa_modargs_new(m->argument, valid_modargs))) {
-        fprintf(stderr, __FILE__": failed to parse module arguments\n");
+        pa_log(__FILE__": failed to parse module arguments\n");
         goto fail;
     }
 
     ss = c->default_sample_spec;
     if (pa_modargs_get_sample_spec(ma, &ss) < 0) {
-        fprintf(stderr, __FILE__": invalid sample format specification\n");
+        pa_log(__FILE__": invalid sample format specification\n");
         goto fail;
     }
     
     mkfifo(p = pa_modargs_get_value(ma, "file", DEFAULT_FIFO_NAME), 0777);
 
     if ((fd = open(p, O_RDWR)) < 0) {
-        fprintf(stderr, __FILE__": open('%s'): %s\n", p, strerror(errno));
+        pa_log(__FILE__": open('%s'): %s\n", p, strerror(errno));
         goto fail;
     }
 
     pa_fd_set_cloexec(fd, 1);
     
     if (fstat(fd, &st) < 0) {
-        fprintf(stderr, __FILE__": fstat('%s'): %s\n", p, strerror(errno));
+        pa_log(__FILE__": fstat('%s'): %s\n", p, strerror(errno));
         goto fail;
     }
 
     if (!S_ISFIFO(st.st_mode)) {
-        fprintf(stderr, __FILE__": '%s' is not a FIFO.\n", p);
+        pa_log(__FILE__": '%s' is not a FIFO.\n", p);
         goto fail;
     }
 
     u = pa_xmalloc0(sizeof(struct userdata));
-
     u->filename = pa_xstrdup(p);
     u->core = c;
+    u->module = m;
+    m->userdata = u;
     
     if (!(u->sink = pa_sink_new(c, pa_modargs_get_value(ma, "sink_name", DEFAULT_SINK_NAME), 0, &ss))) {
-        fprintf(stderr, __FILE__": failed to create sink.\n");
+        pa_log(__FILE__": failed to create sink.\n");
         goto fail;
     }
     u->sink->notify = notify_cb;
+    u->sink->get_latency = get_latency_cb;
     u->sink->userdata = u;
     pa_sink_set_owner(u->sink, m);
     u->sink->description = pa_sprintf_malloc("Unix FIFO sink '%s'", p);
@@ -181,9 +197,6 @@ int pa_module_init(struct pa_core *c, struct pa_module*m) {
     assert(u->defer_event);
     c->mainloop->defer_enable(u->defer_event, 0);
 
-    u->module = m;
-    m->userdata = u;
-
     pa_modargs_free(ma);
     
     return 0;
@@ -195,12 +208,12 @@ fail:
     if (fd >= 0)
         close(fd);
 
-    pa_module_done(c, m);
+    pa__done(c, m);
 
     return -1;
 }
 
-void pa_module_done(struct pa_core *c, struct pa_module*m) {
+void pa__done(struct pa_core *c, struct pa_module*m) {
     struct userdata *u;
     assert(c && m);
 
@@ -210,7 +223,8 @@ void pa_module_done(struct pa_core *c, struct pa_module*m) {
     if (u->memchunk.memblock)
         pa_memblock_unref(u->memchunk.memblock);
         
-    pa_sink_free(u->sink);
+    pa_sink_disconnect(u->sink);
+    pa_sink_unref(u->sink);
     pa_iochannel_free(u->io);
     u->core->mainloop->defer_free(u->defer_event);