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.
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 {
static const char* const valid_modargs[] = {
"file",
"rate",
- "channels",
"format",
+ "channels",
"sink_name",
NULL
};
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;
}
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);
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;
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);
assert(u->defer_event);
c->mainloop->defer_enable(u->defer_event, 0);
- u->module = m;
- m->userdata = u;
-
pa_modargs_free(ma);
return 0;
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);
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);