scons --> make
[aftubes.git] / modules / convert.c
blobd92e99ce6c668be54428eae53b4abc1f22e05bc2
1 #include "modules.h"
2 #include "graph.h"
3 #include "assert.h"
5 struct converter {
6 struct graphpin *in_pin, *out_pin;
7 struct aformat src_af, dest_af;
8 };
10 static err_t get_output_format(struct graphnode *node, struct graphpin *pin, struct aformat *af)
12 struct converter *c = node->extra;
13 assert(pin == c->out_pin);
14 *af = c->dest_af;
15 return EOK;
18 static err_t run(struct graphnode *node)
20 #define DO_CONVERT(s_T, d_T, SCALE) { \
21 s_T *restrict s_ptr = s_buf->data; \
22 d_T *restrict d_ptr = d_buf->data; \
23 int i; \
24 for (i=s_buf->n_samples * s_buf->format.channels; i; --i){ \
25 (*(d_ptr++)) = (d_T) ((*(s_ptr++)) SCALE); \
26 } \
27 return EOK; }
29 struct converter *c = node->extra;
30 struct buffer *s_buf = &c->in_pin->edge->buf,
31 *d_buf = &c->out_pin->edge->buf;
32 err_t err;
34 err = buffer_alloc(d_buf, s_buf->n_samples);
35 if (err != EOK){
36 return err;
39 switch (c->src_af.media){
40 case MT_AUDIO_32F:
41 switch (c->dest_af.media){
42 case MT_AUDIO_16I:
43 DO_CONVERT(float, short, * 32768.0)
44 case MT_AUDIO_32I:
45 DO_CONVERT(float, int, * 2147483648.0)
47 case MT_AUDIO_16I:
48 switch (c->dest_af.media){
49 case MT_AUDIO_32F:
50 DO_CONVERT(short, float, / 32768.0)
51 case MT_AUDIO_32I:
52 DO_CONVERT(short, int, >> 16)
54 case MT_AUDIO_32I:
55 switch (c->dest_af.media){
56 case MT_AUDIO_32F:
57 DO_CONVERT(int, float, / 2147483648.0)
58 case MT_AUDIO_16I:
59 DO_CONVERT(int, short, << 16)
62 return make_error(ENOTIMPL, NULL, "conversion between these media types is not implemented");
65 static const struct graphnode_functab functab = {
66 NULL, // is_acceptable_input_format
67 NULL, // get_ideal_input_format
68 get_output_format,
69 NULL, // set_buffer
70 run,
73 err_t audio_converter_create(struct graphnode **node_out, struct aformat *src_af, struct aformat *dest_af)
75 struct graphnode *node;
76 struct converter *restrict c;
77 err_t err;
79 err = graphnode_create(&node, &functab, sizeof *c);
80 if (err != EOK){
81 return err;
83 c = node->extra;
85 c->src_af = *src_af;
86 c->dest_af = *dest_af;
88 err = graphnode_add_pin(node, &c->in_pin);
89 if (err != EOK){
90 return err;
92 c->in_pin->dir = DIR_IN;
93 c->in_pin->name = "in";
95 err = graphnode_add_pin(node, &c->out_pin);
96 if (err != EOK){
97 return err;
99 c->out_pin->dir = DIR_OUT;
100 c->out_pin->name = "out";
102 *node_out = node;
103 return EOK;