mirror of
https://gitlab.freedesktop.org/pulseaudio/pulseaudio.git
synced 2025-12-15 08:56:34 -05:00
some more work
git-svn-id: file:///home/lennart/svn/public/pulseaudio/trunk@23 fefdeb5f-60dc-0310-8127-8f9354f1896f
This commit is contained in:
parent
993d1bce74
commit
382e7aefd4
14 changed files with 147 additions and 36 deletions
28
src/cli.c
28
src/cli.c
|
|
@ -9,6 +9,8 @@
|
||||||
#include "sink.h"
|
#include "sink.h"
|
||||||
#include "source.h"
|
#include "source.h"
|
||||||
#include "client.h"
|
#include "client.h"
|
||||||
|
#include "sinkinput.h"
|
||||||
|
#include "sourceoutput.h"
|
||||||
|
|
||||||
struct cli {
|
struct cli {
|
||||||
struct core *core;
|
struct core *core;
|
||||||
|
|
@ -34,7 +36,7 @@ struct cli* cli_new(struct core *core, struct iochannel *io) {
|
||||||
c->eof_callback = NULL;
|
c->eof_callback = NULL;
|
||||||
|
|
||||||
ioline_set_callback(c->line, line_callback, c);
|
ioline_set_callback(c->line, line_callback, c);
|
||||||
ioline_puts(c->line, "Welcome to polypaudio!\n> ");
|
ioline_puts(c->line, "Welcome to polypaudio! Use \"help\" for usage information.\n> ");
|
||||||
|
|
||||||
return c;
|
return c;
|
||||||
}
|
}
|
||||||
|
|
@ -66,10 +68,30 @@ static void line_callback(struct ioline *line, const char *s, void *userdata) {
|
||||||
ioline_puts(line, (t = sink_list_to_string(c->core)));
|
ioline_puts(line, (t = sink_list_to_string(c->core)));
|
||||||
else if (!strcmp(s, "clients"))
|
else if (!strcmp(s, "clients"))
|
||||||
ioline_puts(line, (t = client_list_to_string(c->core)));
|
ioline_puts(line, (t = client_list_to_string(c->core)));
|
||||||
else if (!strcmp(s, "exit")) {
|
else if (!strcmp(s, "source_outputs"))
|
||||||
|
ioline_puts(line, (t = source_output_list_to_string(c->core)));
|
||||||
|
else if (!strcmp(s, "sink_inputs"))
|
||||||
|
ioline_puts(line, (t = sink_input_list_to_string(c->core)));
|
||||||
|
else if (!strcmp(s, "stat")) {
|
||||||
|
char txt[256];
|
||||||
|
snprintf(txt, sizeof(txt), "Memory blocks allocated: %u, total size: %u bytes.\n", memblock_count, memblock_total);
|
||||||
|
ioline_puts(line, txt);
|
||||||
|
} else if (!strcmp(s, "exit")) {
|
||||||
assert(c->core && c->core->mainloop);
|
assert(c->core && c->core->mainloop);
|
||||||
mainloop_quit(c->core->mainloop, -1);
|
mainloop_quit(c->core->mainloop, -1);
|
||||||
} else if (*s)
|
} else if (!strcmp(s, "help"))
|
||||||
|
ioline_puts(line,
|
||||||
|
"Available commands:\n"
|
||||||
|
" modules\t\tlist modules\n"
|
||||||
|
" sinks\t\tlist sinks\n"
|
||||||
|
" sources\t\tlist sources\n"
|
||||||
|
" clients\t\tlist clients\n"
|
||||||
|
" source_outputs\tlist source outputs\n"
|
||||||
|
" sink_inputs\t\tlist sink inputs\n"
|
||||||
|
" stat\t\tshow memblock statistics\n"
|
||||||
|
" exit\t\tterminate the daemon\n"
|
||||||
|
" help\t\tshow this help\n");
|
||||||
|
else if (*s)
|
||||||
ioline_puts(line, "Unknown command\n");
|
ioline_puts(line, "Unknown command\n");
|
||||||
|
|
||||||
free(t);
|
free(t);
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,7 @@
|
||||||
|
|
||||||
#include "memblock.h"
|
#include "memblock.h"
|
||||||
|
|
||||||
unsigned n_blocks = 0;
|
unsigned memblock_count = 0, memblock_total = 0;
|
||||||
|
|
||||||
struct memblock *memblock_new(size_t length) {
|
struct memblock *memblock_new(size_t length) {
|
||||||
struct memblock *b = malloc(sizeof(struct memblock)+length);
|
struct memblock *b = malloc(sizeof(struct memblock)+length);
|
||||||
|
|
@ -13,7 +13,8 @@ struct memblock *memblock_new(size_t length) {
|
||||||
b->ref = 1;
|
b->ref = 1;
|
||||||
b->length = length;
|
b->length = length;
|
||||||
b->data = b+1;
|
b->data = b+1;
|
||||||
n_blocks++;
|
memblock_count++;
|
||||||
|
memblock_total += length;
|
||||||
return b;
|
return b;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -23,7 +24,8 @@ struct memblock *memblock_new_fixed(void *d, size_t length) {
|
||||||
b->ref = 1;
|
b->ref = 1;
|
||||||
b->length = length;
|
b->length = length;
|
||||||
b->data = d;
|
b->data = d;
|
||||||
n_blocks++;
|
memblock_count++;
|
||||||
|
memblock_total += length;
|
||||||
return b;
|
return b;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -33,7 +35,8 @@ struct memblock *memblock_new_dynamic(void *d, size_t length) {
|
||||||
b->ref = 1;
|
b->ref = 1;
|
||||||
b->length = length;
|
b->length = length;
|
||||||
b->data = d;
|
b->data = d;
|
||||||
n_blocks++;
|
memblock_count++;
|
||||||
|
memblock_total += length;
|
||||||
return b;
|
return b;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -50,8 +53,11 @@ void memblock_unref(struct memblock*b) {
|
||||||
if (b->ref == 0) {
|
if (b->ref == 0) {
|
||||||
if (b->type == MEMBLOCK_DYNAMIC)
|
if (b->type == MEMBLOCK_DYNAMIC)
|
||||||
free(b->data);
|
free(b->data);
|
||||||
|
|
||||||
|
memblock_count--;
|
||||||
|
memblock_total -= b->length;
|
||||||
|
|
||||||
free(b);
|
free(b);
|
||||||
n_blocks--;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -29,6 +29,6 @@ void memblock_unref_fixed(struct memblock*b);
|
||||||
|
|
||||||
#define memblock_assert_exclusive(b) assert((b)->ref == 1)
|
#define memblock_assert_exclusive(b) assert((b)->ref == 1)
|
||||||
|
|
||||||
extern unsigned n_blocks;
|
extern unsigned memblock_count, memblock_total;
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
||||||
|
|
@ -16,8 +16,8 @@ struct memblockq {
|
||||||
struct memblock_list *blocks, *blocks_tail;
|
struct memblock_list *blocks, *blocks_tail;
|
||||||
unsigned n_blocks;
|
unsigned n_blocks;
|
||||||
size_t total_length, maxlength, base, prebuf;
|
size_t total_length, maxlength, base, prebuf;
|
||||||
int measure_latency;
|
int measure_delay;
|
||||||
uint32_t latency;
|
uint32_t delay;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct memblockq* memblockq_new(size_t maxlength, size_t base, size_t prebuf) {
|
struct memblockq* memblockq_new(size_t maxlength, size_t base, size_t prebuf) {
|
||||||
|
|
@ -38,8 +38,8 @@ struct memblockq* memblockq_new(size_t maxlength, size_t base, size_t prebuf) {
|
||||||
|
|
||||||
assert(bq->maxlength >= base);
|
assert(bq->maxlength >= base);
|
||||||
|
|
||||||
bq->measure_latency = 1;
|
bq->measure_delay = 0;
|
||||||
bq->latency = 0;
|
bq->delay = 0;
|
||||||
|
|
||||||
return bq;
|
return bq;
|
||||||
}
|
}
|
||||||
|
|
@ -64,7 +64,7 @@ void memblockq_push(struct memblockq* bq, struct memchunk *chunk, size_t delta)
|
||||||
q = malloc(sizeof(struct memblock_list));
|
q = malloc(sizeof(struct memblock_list));
|
||||||
assert(q);
|
assert(q);
|
||||||
|
|
||||||
if (bq->measure_latency)
|
if (bq->measure_delay)
|
||||||
gettimeofday(&q->stamp, NULL);
|
gettimeofday(&q->stamp, NULL);
|
||||||
else
|
else
|
||||||
timerclear(&q->stamp);
|
timerclear(&q->stamp);
|
||||||
|
|
@ -152,8 +152,8 @@ void memblockq_drop(struct memblockq *bq, size_t length) {
|
||||||
if (l > bq->blocks->chunk.length)
|
if (l > bq->blocks->chunk.length)
|
||||||
l = bq->blocks->chunk.length;
|
l = bq->blocks->chunk.length;
|
||||||
|
|
||||||
if (bq->measure_latency)
|
if (bq->measure_delay)
|
||||||
bq->latency = age(&bq->blocks->stamp);
|
bq->delay = age(&bq->blocks->stamp);
|
||||||
|
|
||||||
bq->blocks->chunk.index += l;
|
bq->blocks->chunk.index += l;
|
||||||
bq->blocks->chunk.length -= l;
|
bq->blocks->chunk.length -= l;
|
||||||
|
|
@ -211,6 +211,12 @@ int memblockq_is_writable(struct memblockq *bq, size_t length) {
|
||||||
return bq->total_length + length <= bq->maxlength;
|
return bq->total_length + length <= bq->maxlength;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t memblockq_get_latency(struct memblockq *bq) {
|
uint32_t memblockq_get_delay(struct memblockq *bq) {
|
||||||
return bq->latency;
|
assert(bq);
|
||||||
|
return bq->delay;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t memblockq_get_length(struct memblockq *bq) {
|
||||||
|
assert(bq);
|
||||||
|
return bq->total_length;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -22,6 +22,7 @@ void memblockq_empty(struct memblockq *bq);
|
||||||
int memblockq_is_readable(struct memblockq *bq);
|
int memblockq_is_readable(struct memblockq *bq);
|
||||||
int memblockq_is_writable(struct memblockq *bq, size_t length);
|
int memblockq_is_writable(struct memblockq *bq, size_t length);
|
||||||
|
|
||||||
uint32_t memblockq_get_latency(struct memblockq *bq);
|
uint32_t memblockq_get_delay(struct memblockq *bq);
|
||||||
|
uint32_t memblockq_get_length(struct memblockq *bq);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
||||||
|
|
@ -25,7 +25,7 @@ struct userdata {
|
||||||
|
|
||||||
struct memchunk memchunk, silence;
|
struct memchunk memchunk, silence;
|
||||||
|
|
||||||
uint32_t in_fragment_size, out_fragment_size, sample_size, sample_usec;
|
uint32_t in_fragment_size, out_fragment_size, sample_size;
|
||||||
|
|
||||||
int fd;
|
int fd;
|
||||||
};
|
};
|
||||||
|
|
@ -99,7 +99,7 @@ static void io_callback(struct iochannel *io, void*userdata) {
|
||||||
static uint32_t sink_get_latency_cb(struct sink *s) {
|
static uint32_t sink_get_latency_cb(struct sink *s) {
|
||||||
int arg;
|
int arg;
|
||||||
struct userdata *u = s->userdata;
|
struct userdata *u = s->userdata;
|
||||||
assert(s && u);
|
assert(s && u && u->sink);
|
||||||
|
|
||||||
if (ioctl(u->fd, SNDCTL_DSP_GETODELAY, &arg) < 0) {
|
if (ioctl(u->fd, SNDCTL_DSP_GETODELAY, &arg) < 0) {
|
||||||
fprintf(stderr, "module-oss: device doesn't support SNDCTL_DSP_GETODELAY.\n");
|
fprintf(stderr, "module-oss: device doesn't support SNDCTL_DSP_GETODELAY.\n");
|
||||||
|
|
@ -107,7 +107,7 @@ static uint32_t sink_get_latency_cb(struct sink *s) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
return arg/u->sample_size*u->sample_usec;
|
return samples_usec(arg, &s->sample_spec);
|
||||||
}
|
}
|
||||||
|
|
||||||
int module_init(struct core *c, struct module*m) {
|
int module_init(struct core *c, struct module*m) {
|
||||||
|
|
@ -204,7 +204,6 @@ int module_init(struct core *c, struct module*m) {
|
||||||
u->memchunk.memblock = NULL;
|
u->memchunk.memblock = NULL;
|
||||||
u->memchunk.length = 0;
|
u->memchunk.length = 0;
|
||||||
u->sample_size = sample_size(&ss);
|
u->sample_size = sample_size(&ss);
|
||||||
u->sample_usec = 1000000/ss.rate;
|
|
||||||
|
|
||||||
u->out_fragment_size = out_frag_size;
|
u->out_fragment_size = out_frag_size;
|
||||||
u->in_fragment_size = in_frag_size;
|
u->in_fragment_size = in_frag_size;
|
||||||
|
|
|
||||||
|
|
@ -56,7 +56,6 @@ static void destroy_connection(struct connection *c) {
|
||||||
static int do_read(struct connection *c) {
|
static int do_read(struct connection *c) {
|
||||||
struct memchunk chunk;
|
struct memchunk chunk;
|
||||||
ssize_t r;
|
ssize_t r;
|
||||||
uint32_t u1, u2;
|
|
||||||
|
|
||||||
if (!iochannel_is_readable(c->io))
|
if (!iochannel_is_readable(c->io))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
@ -82,12 +81,6 @@ static int do_read(struct connection *c) {
|
||||||
memblock_unref(chunk.memblock);
|
memblock_unref(chunk.memblock);
|
||||||
sink_notify(c->sink_input->sink);
|
sink_notify(c->sink_input->sink);
|
||||||
|
|
||||||
|
|
||||||
u1 = memblockq_get_latency(c->input_memblockq);
|
|
||||||
u2 = sink_get_latency(c->sink_input->sink);
|
|
||||||
|
|
||||||
fprintf(stderr, "latency: %u+%u=%u\r", u1, u2, u1+u2);
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -120,14 +113,13 @@ static int do_write(struct connection *c) {
|
||||||
|
|
||||||
/*** sink_input callbacks ***/
|
/*** sink_input callbacks ***/
|
||||||
|
|
||||||
static int sink_input_peek_cb(struct sink_input *i, struct memchunk *chunk, uint8_t *volume) {
|
static int sink_input_peek_cb(struct sink_input *i, struct memchunk *chunk) {
|
||||||
struct connection*c = i->userdata;
|
struct connection*c = i->userdata;
|
||||||
assert(i && c && chunk && volume);
|
assert(i && c && chunk);
|
||||||
|
|
||||||
if (memblockq_peek(c->input_memblockq, chunk) < 0)
|
if (memblockq_peek(c->input_memblockq, chunk) < 0)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
*volume = 0xFF;
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -146,6 +138,13 @@ static void sink_input_kill_cb(struct sink_input *i) {
|
||||||
destroy_connection((struct connection *) i->userdata);
|
destroy_connection((struct connection *) i->userdata);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static uint32_t sink_input_get_latency_cb(struct sink_input *i) {
|
||||||
|
struct connection*c = i->userdata;
|
||||||
|
assert(i && c);
|
||||||
|
return samples_usec(memblockq_get_length(c->input_memblockq), &DEFAULT_SAMPLE_SPEC);
|
||||||
|
}
|
||||||
|
|
||||||
/*** source_output callbacks ***/
|
/*** source_output callbacks ***/
|
||||||
|
|
||||||
static void source_output_push_cb(struct source_output *o, struct memchunk *chunk) {
|
static void source_output_push_cb(struct source_output *o, struct memchunk *chunk) {
|
||||||
|
|
@ -163,7 +162,6 @@ static void source_output_kill_cb(struct source_output *o) {
|
||||||
destroy_connection((struct connection *) o->userdata);
|
destroy_connection((struct connection *) o->userdata);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*** client callbacks ***/
|
/*** client callbacks ***/
|
||||||
|
|
||||||
static void client_kill_cb(struct client *c) {
|
static void client_kill_cb(struct client *c) {
|
||||||
|
|
@ -234,6 +232,7 @@ static void on_connection(struct socket_server*s, struct iochannel *io, void *us
|
||||||
c->sink_input->peek = sink_input_peek_cb;
|
c->sink_input->peek = sink_input_peek_cb;
|
||||||
c->sink_input->drop = sink_input_drop_cb;
|
c->sink_input->drop = sink_input_drop_cb;
|
||||||
c->sink_input->kill = sink_input_kill_cb;
|
c->sink_input->kill = sink_input_kill_cb;
|
||||||
|
c->sink_input->get_latency = sink_input_get_latency_cb;
|
||||||
c->sink_input->userdata = c;
|
c->sink_input->userdata = c;
|
||||||
|
|
||||||
l = bytes_per_second(&DEFAULT_SAMPLE_SPEC)/2; /* half a second */
|
l = bytes_per_second(&DEFAULT_SAMPLE_SPEC)/2; /* half a second */
|
||||||
|
|
|
||||||
|
|
@ -113,3 +113,9 @@ size_t mix_chunks(struct mix_info channels[], unsigned nchannels, void *data, si
|
||||||
data += sizeof(int16_t);
|
data += sizeof(int16_t);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint32_t samples_usec(size_t length, struct sample_spec *spec) {
|
||||||
|
assert(spec);
|
||||||
|
|
||||||
|
return (uint32_t) (((double) length /sample_size(spec))/spec->rate*1000000);
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -40,5 +40,6 @@ size_t mix_chunks(struct mix_info channels[], unsigned nchannels, void *data, si
|
||||||
|
|
||||||
size_t bytes_per_second(struct sample_spec *spec);
|
size_t bytes_per_second(struct sample_spec *spec);
|
||||||
size_t sample_size(struct sample_spec *spec);
|
size_t sample_size(struct sample_spec *spec);
|
||||||
|
uint32_t samples_usec(size_t length, struct sample_spec *spec);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
||||||
|
|
@ -81,9 +81,11 @@ static unsigned fill_mix_info(struct sink *s, struct mix_info *info, unsigned ma
|
||||||
|
|
||||||
for (i = idxset_first(s->inputs, &index); maxinfo > 0 && i; i = idxset_next(s->inputs, &index)) {
|
for (i = idxset_first(s->inputs, &index); maxinfo > 0 && i; i = idxset_next(s->inputs, &index)) {
|
||||||
assert(i->peek);
|
assert(i->peek);
|
||||||
if (i->peek(i, &info->chunk, &info->volume) < 0)
|
if (i->peek(i, &info->chunk) < 0)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
info->volume = i->volume;
|
||||||
|
|
||||||
assert(info->chunk.memblock && info->chunk.memblock->data && info->chunk.length);
|
assert(info->chunk.memblock && info->chunk.memblock->data && info->chunk.length);
|
||||||
info->userdata = i;
|
info->userdata = i;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,7 @@
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
#include "sinkinput.h"
|
#include "sinkinput.h"
|
||||||
|
#include "strbuf.h"
|
||||||
|
|
||||||
struct sink_input* sink_input_new(struct sink *s, struct sample_spec *spec, const char *name) {
|
struct sink_input* sink_input_new(struct sink *s, struct sample_spec *spec, const char *name) {
|
||||||
struct sink_input *i;
|
struct sink_input *i;
|
||||||
|
|
@ -18,6 +19,7 @@ struct sink_input* sink_input_new(struct sink *s, struct sample_spec *spec, cons
|
||||||
i->peek = NULL;
|
i->peek = NULL;
|
||||||
i->drop = NULL;
|
i->drop = NULL;
|
||||||
i->kill = NULL;
|
i->kill = NULL;
|
||||||
|
i->get_latency = NULL;
|
||||||
i->userdata = NULL;
|
i->userdata = NULL;
|
||||||
|
|
||||||
assert(s->core);
|
assert(s->core);
|
||||||
|
|
@ -46,3 +48,40 @@ void sink_input_kill(struct sink_input*i) {
|
||||||
if (i->kill)
|
if (i->kill)
|
||||||
i->kill(i);
|
i->kill(i);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
char *sink_input_list_to_string(struct core *c) {
|
||||||
|
struct strbuf *s;
|
||||||
|
struct sink_input *i;
|
||||||
|
uint32_t index = IDXSET_INVALID;
|
||||||
|
assert(c);
|
||||||
|
|
||||||
|
s = strbuf_new();
|
||||||
|
assert(s);
|
||||||
|
|
||||||
|
strbuf_printf(s, "%u sink input(s) available.\n", idxset_ncontents(c->sink_inputs));
|
||||||
|
|
||||||
|
for (i = idxset_first(c->sink_inputs, &index); i; i = idxset_next(c->sink_inputs, &index)) {
|
||||||
|
assert(i->sink);
|
||||||
|
strbuf_printf(s, " index: %u, name: <%s>, sink: <%u>; volume: <0x%02x>, latency: <%u usec>\n",
|
||||||
|
i->index,
|
||||||
|
i->name,
|
||||||
|
i->sink->index,
|
||||||
|
(unsigned) i->volume,
|
||||||
|
sink_input_get_latency(i));
|
||||||
|
}
|
||||||
|
|
||||||
|
return strbuf_tostring_free(s);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t sink_input_get_latency(struct sink_input *i) {
|
||||||
|
uint32_t l = 0;
|
||||||
|
|
||||||
|
assert(i);
|
||||||
|
if (i->get_latency)
|
||||||
|
l += i->get_latency(i);
|
||||||
|
|
||||||
|
assert(i->sink);
|
||||||
|
l += sink_get_latency(i->sink);
|
||||||
|
|
||||||
|
return l;
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -13,10 +13,13 @@ struct sink_input {
|
||||||
char *name;
|
char *name;
|
||||||
struct sink *sink;
|
struct sink *sink;
|
||||||
struct sample_spec spec;
|
struct sample_spec spec;
|
||||||
|
uint8_t volume;
|
||||||
|
|
||||||
int (*peek) (struct sink_input *i, struct memchunk *chunk, uint8_t *volume);
|
int (*peek) (struct sink_input *i, struct memchunk *chunk);
|
||||||
void (*drop) (struct sink_input *i, size_t length);
|
void (*drop) (struct sink_input *i, size_t length);
|
||||||
void (*kill) (struct sink_input *i);
|
void (*kill) (struct sink_input *i);
|
||||||
|
uint32_t (*get_latency) (struct sink_input *i);
|
||||||
|
|
||||||
|
|
||||||
void *userdata;
|
void *userdata;
|
||||||
};
|
};
|
||||||
|
|
@ -28,5 +31,7 @@ void sink_input_free(struct sink_input* i);
|
||||||
* request destruction of it */
|
* request destruction of it */
|
||||||
void sink_input_kill(struct sink_input *i);
|
void sink_input_kill(struct sink_input *i);
|
||||||
|
|
||||||
|
uint32_t sink_input_get_latency(struct sink_input *i);
|
||||||
|
char *sink_input_list_to_string(struct core *c);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,7 @@
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
#include "sourceoutput.h"
|
#include "sourceoutput.h"
|
||||||
|
#include "strbuf.h"
|
||||||
|
|
||||||
struct source_output* source_output_new(struct source *s, struct sample_spec *spec, const char *name) {
|
struct source_output* source_output_new(struct source *s, struct sample_spec *spec, const char *name) {
|
||||||
struct source_output *o;
|
struct source_output *o;
|
||||||
|
|
@ -45,3 +46,25 @@ void source_output_kill(struct source_output*i) {
|
||||||
if (i->kill)
|
if (i->kill)
|
||||||
i->kill(i);
|
i->kill(i);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
char *source_output_list_to_string(struct core *c) {
|
||||||
|
struct strbuf *s;
|
||||||
|
struct source_output *o;
|
||||||
|
uint32_t index = IDXSET_INVALID;
|
||||||
|
assert(c);
|
||||||
|
|
||||||
|
s = strbuf_new();
|
||||||
|
assert(s);
|
||||||
|
|
||||||
|
strbuf_printf(s, "%u source outputs(s) available.\n", idxset_ncontents(c->source_outputs));
|
||||||
|
|
||||||
|
for (o = idxset_first(c->source_outputs, &index); o; o = idxset_next(c->source_outputs, &index)) {
|
||||||
|
assert(o->source);
|
||||||
|
strbuf_printf(s, " %c index: %u, name: <%s>, source: <%u>\n",
|
||||||
|
o->index,
|
||||||
|
o->name,
|
||||||
|
o->source->index);
|
||||||
|
}
|
||||||
|
|
||||||
|
return strbuf_tostring_free(s);
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -25,4 +25,6 @@ void source_output_free(struct source_output* o);
|
||||||
|
|
||||||
void source_output_kill(struct source_output*o);
|
void source_output_kill(struct source_output*o);
|
||||||
|
|
||||||
|
char *source_output_list_to_string(struct core *c);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue