]> code.delx.au - pulseaudio/blob - src/sourceoutput.c
add resampling
[pulseaudio] / src / sourceoutput.c
1 #include <assert.h>
2 #include <stdlib.h>
3 #include <string.h>
4
5 #include "sourceoutput.h"
6 #include "strbuf.h"
7
8 struct source_output* source_output_new(struct source *s, const char *name, const struct pa_sample_spec *spec) {
9 struct source_output *o;
10 struct resampler *resampler = NULL;
11 int r;
12 assert(s && spec);
13
14 if (!pa_sample_spec_equal(&s->sample_spec, spec))
15 if (!(resampler = resampler_new(&s->sample_spec, spec)))
16 return NULL;
17
18 o = malloc(sizeof(struct source_output));
19 assert(o);
20 o->name = name ? strdup(name) : NULL;
21 o->source = s;
22 o->sample_spec = *spec;
23
24 o->push = NULL;
25 o->kill = NULL;
26 o->userdata = NULL;
27 o->resampler = resampler;
28
29 assert(s->core);
30 r = idxset_put(s->core->source_outputs, o, &o->index);
31 assert(r == 0 && o->index != IDXSET_INVALID);
32 r = idxset_put(s->outputs, o, NULL);
33 assert(r == 0);
34
35 return o;
36 }
37
38 void source_output_free(struct source_output* o) {
39 assert(o);
40
41 assert(o->source && o->source->core);
42 idxset_remove_by_data(o->source->core->source_outputs, o, NULL);
43 idxset_remove_by_data(o->source->outputs, o, NULL);
44
45 if (o->resampler)
46 resampler_free(o->resampler);
47
48 free(o->name);
49 free(o);
50 }
51
52 void source_output_kill(struct source_output*i) {
53 assert(i);
54
55 if (i->kill)
56 i->kill(i);
57 }
58
59 char *source_output_list_to_string(struct core *c) {
60 struct strbuf *s;
61 struct source_output *o;
62 uint32_t index = IDXSET_INVALID;
63 assert(c);
64
65 s = strbuf_new();
66 assert(s);
67
68 strbuf_printf(s, "%u source outputs(s) available.\n", idxset_ncontents(c->source_outputs));
69
70 for (o = idxset_first(c->source_outputs, &index); o; o = idxset_next(c->source_outputs, &index)) {
71 assert(o->source);
72 strbuf_printf(s, " %c index: %u, name: <%s>, source: <%u>\n",
73 o->index,
74 o->name,
75 o->source->index);
76 }
77
78 return strbuf_tostring_free(s);
79 }
80
81 void source_output_push(struct source_output *o, const struct memchunk *chunk) {
82 struct memchunk rchunk;
83 assert(o && chunk && chunk->length && o->push);
84
85 if (!o->resampler) {
86 o->push(o, chunk);
87 return;
88 }
89
90 resampler_run(o->resampler, chunk, &rchunk);
91 if (!rchunk.length)
92 return;
93
94 assert(rchunk.memblock);
95 o->push(o, &rchunk);
96 memblock_unref(rchunk.memblock);
97 }