diff options
Diffstat (limited to 'apps/codecs/dumb/src/core/rendsig.c')
-rw-r--r-- | apps/codecs/dumb/src/core/rendsig.c | 299 |
1 files changed, 299 insertions, 0 deletions
diff --git a/apps/codecs/dumb/src/core/rendsig.c b/apps/codecs/dumb/src/core/rendsig.c new file mode 100644 index 0000000000..a36ceb41cf --- /dev/null +++ b/apps/codecs/dumb/src/core/rendsig.c | |||
@@ -0,0 +1,299 @@ | |||
1 | /* _______ ____ __ ___ ___ | ||
2 | * \ _ \ \ / \ / \ \ / / ' ' ' | ||
3 | * | | \ \ | | || | \/ | . . | ||
4 | * | | | | | | || ||\ /| | | ||
5 | * | | | | | | || || \/ | | ' ' ' | ||
6 | * | | | | | | || || | | . . | ||
7 | * | |_/ / \ \__// || | | | ||
8 | * /_______/ynamic \____/niversal /__\ /____\usic /| . . ibliotheque | ||
9 | * / \ | ||
10 | * / . \ | ||
11 | * rendsig.c - Wrappers to render samples from / / \ \ | ||
12 | * the signals in a DUH. | < / \_ | ||
13 | * | \/ /\ / | ||
14 | * By entheh. \_ / > / | ||
15 | * | \ / / | ||
16 | * | ' / | ||
17 | * \__/ | ||
18 | */ | ||
19 | |||
20 | #include <stdlib.h> | ||
21 | |||
22 | #include "dumb.h" | ||
23 | #include "internal/dumb.h" | ||
24 | |||
25 | |||
26 | |||
27 | struct DUH_SIGRENDERER | ||
28 | { | ||
29 | DUH_SIGTYPE_DESC *desc; | ||
30 | |||
31 | sigrenderer_t *sigrenderer; | ||
32 | |||
33 | int n_channels; | ||
34 | |||
35 | long pos; | ||
36 | int subpos; | ||
37 | |||
38 | DUH_SIGRENDERER_ANALYSER_CALLBACK callback; | ||
39 | void *callback_data; | ||
40 | }; | ||
41 | |||
42 | |||
43 | |||
44 | DUH_SIGRENDERER *duh_start_sigrenderer(DUH *duh, int sig, int n_channels, long pos) | ||
45 | { | ||
46 | DUH_SIGRENDERER *sigrenderer; | ||
47 | |||
48 | DUH_SIGNAL *signal; | ||
49 | DUH_START_SIGRENDERER proc; | ||
50 | |||
51 | if ((unsigned int)sig >= (unsigned int)duh->n_signals) | ||
52 | return NULL; | ||
53 | |||
54 | signal = duh->signal[sig]; | ||
55 | if (!signal) | ||
56 | return NULL; | ||
57 | |||
58 | sigrenderer = malloc(sizeof(*sigrenderer)); | ||
59 | if (!sigrenderer) | ||
60 | return NULL; | ||
61 | |||
62 | sigrenderer->desc = signal->desc; | ||
63 | |||
64 | proc = sigrenderer->desc->start_sigrenderer; | ||
65 | |||
66 | if (proc) { | ||
67 | duh->signal[sig] = NULL; | ||
68 | sigrenderer->sigrenderer = (*proc)(duh, signal->sigdata, n_channels, pos); | ||
69 | duh->signal[sig] = signal; | ||
70 | |||
71 | if (!sigrenderer->sigrenderer) { | ||
72 | free(sigrenderer); | ||
73 | return NULL; | ||
74 | } | ||
75 | } else | ||
76 | sigrenderer->sigrenderer = NULL; | ||
77 | |||
78 | sigrenderer->n_channels = n_channels; | ||
79 | |||
80 | sigrenderer->pos = pos; | ||
81 | sigrenderer->subpos = 0; | ||
82 | |||
83 | sigrenderer->callback = NULL; | ||
84 | |||
85 | return sigrenderer; | ||
86 | } | ||
87 | |||
88 | |||
89 | |||
90 | #include <stdio.h> | ||
91 | void duh_sigrenderer_set_callback( | ||
92 | DUH_SIGRENDERER *sigrenderer, | ||
93 | DUH_SIGRENDERER_CALLBACK callback, void *data | ||
94 | ) | ||
95 | { | ||
96 | (void)sigrenderer; | ||
97 | (void)callback; | ||
98 | (void)data; | ||
99 | /* FIXME | ||
100 | fprintf(stderr, | ||
101 | "Call to deprecated function duh_sigrenderer_set_callback(). The callback\n" | ||
102 | "was not installed. See dumb/docs/deprec.txt for how to fix this.\n");*/ | ||
103 | } | ||
104 | |||
105 | |||
106 | |||
107 | void duh_sigrenderer_set_analyser_callback( | ||
108 | DUH_SIGRENDERER *sigrenderer, | ||
109 | DUH_SIGRENDERER_ANALYSER_CALLBACK callback, void *data | ||
110 | ) | ||
111 | { | ||
112 | if (sigrenderer) { | ||
113 | sigrenderer->callback = callback; | ||
114 | sigrenderer->callback_data = data; | ||
115 | } | ||
116 | } | ||
117 | |||
118 | |||
119 | |||
120 | int duh_sigrenderer_get_n_channels(DUH_SIGRENDERER *sigrenderer) | ||
121 | { | ||
122 | return sigrenderer ? sigrenderer->n_channels : 0; | ||
123 | } | ||
124 | |||
125 | |||
126 | |||
127 | long duh_sigrenderer_get_position(DUH_SIGRENDERER *sigrenderer) | ||
128 | { | ||
129 | return sigrenderer ? sigrenderer->pos : -1; | ||
130 | } | ||
131 | |||
132 | |||
133 | |||
134 | void duh_sigrenderer_set_sigparam( | ||
135 | DUH_SIGRENDERER *sigrenderer, | ||
136 | unsigned char id, long value | ||
137 | ) | ||
138 | { | ||
139 | DUH_SIGRENDERER_SET_SIGPARAM proc; | ||
140 | |||
141 | if (!sigrenderer) return; | ||
142 | |||
143 | proc = sigrenderer->desc->sigrenderer_set_sigparam; | ||
144 | if (proc) | ||
145 | (*proc)(sigrenderer->sigrenderer, id, value); | ||
146 | else | ||
147 | TRACE("Parameter #%d = %ld for signal %c%c%c%c, which does not take parameters.\n", | ||
148 | (int)id, | ||
149 | value, | ||
150 | (int)(sigrenderer->desc->type >> 24), | ||
151 | (int)(sigrenderer->desc->type >> 16), | ||
152 | (int)(sigrenderer->desc->type >> 8), | ||
153 | (int)(sigrenderer->desc->type)); | ||
154 | } | ||
155 | |||
156 | |||
157 | |||
158 | long duh_sigrenderer_get_samples( | ||
159 | DUH_SIGRENDERER *sigrenderer, | ||
160 | float volume, float delta, | ||
161 | long size, sample_t **samples | ||
162 | ) | ||
163 | { | ||
164 | long rendered; | ||
165 | LONG_LONG t; | ||
166 | |||
167 | if (!sigrenderer) return 0; | ||
168 | |||
169 | rendered = (*sigrenderer->desc->sigrenderer_get_samples) | ||
170 | (sigrenderer->sigrenderer, volume, delta, size, samples); | ||
171 | |||
172 | if (rendered) { | ||
173 | if (sigrenderer->callback) | ||
174 | (*sigrenderer->callback)(sigrenderer->callback_data, | ||
175 | (const sample_t *const *)samples, sigrenderer->n_channels, rendered); | ||
176 | |||
177 | t = sigrenderer->subpos + (LONG_LONG)(delta * 65536.0 + 0.5) * rendered; | ||
178 | |||
179 | sigrenderer->pos += (long)(t >> 16); | ||
180 | sigrenderer->subpos = (int)t & 65535; | ||
181 | } | ||
182 | |||
183 | return rendered; | ||
184 | } | ||
185 | |||
186 | |||
187 | |||
188 | /* DEPRECATED */ | ||
189 | long duh_render_signal( | ||
190 | DUH_SIGRENDERER *sigrenderer, | ||
191 | float volume, float delta, | ||
192 | long size, sample_t **samples | ||
193 | ) | ||
194 | { | ||
195 | sample_t **s = create_sample_buffer(sigrenderer->n_channels, size); | ||
196 | long rendered; | ||
197 | long i; | ||
198 | int j; | ||
199 | if (!s) return 0; | ||
200 | rendered = duh_sigrenderer_get_samples(sigrenderer, volume, delta, size, s); | ||
201 | for (j = 0; j < sigrenderer->n_channels; j++) | ||
202 | for (i = 0; i < rendered; i++) | ||
203 | samples[j][i] += s[j][i] >> 8; | ||
204 | destroy_sample_buffer(s); | ||
205 | return rendered; | ||
206 | } | ||
207 | |||
208 | |||
209 | |||
210 | void duh_sigrenderer_get_current_sample(DUH_SIGRENDERER *sigrenderer, float volume, sample_t *samples) | ||
211 | { | ||
212 | if (sigrenderer) | ||
213 | (*sigrenderer->desc->sigrenderer_get_current_sample)(sigrenderer->sigrenderer, volume, samples); | ||
214 | } | ||
215 | |||
216 | |||
217 | |||
218 | void duh_end_sigrenderer(DUH_SIGRENDERER *sigrenderer) | ||
219 | { | ||
220 | if (sigrenderer) { | ||
221 | if (sigrenderer->desc->end_sigrenderer) | ||
222 | if (sigrenderer->sigrenderer) | ||
223 | (*sigrenderer->desc->end_sigrenderer)(sigrenderer->sigrenderer); | ||
224 | |||
225 | free(sigrenderer); | ||
226 | } | ||
227 | } | ||
228 | |||
229 | |||
230 | |||
231 | DUH_SIGRENDERER *duh_encapsulate_raw_sigrenderer(sigrenderer_t *vsigrenderer, DUH_SIGTYPE_DESC *desc, int n_channels, long pos) | ||
232 | { | ||
233 | DUH_SIGRENDERER *sigrenderer; | ||
234 | |||
235 | if (desc->start_sigrenderer && !vsigrenderer) return NULL; | ||
236 | |||
237 | sigrenderer = malloc(sizeof(*sigrenderer)); | ||
238 | if (!sigrenderer) { | ||
239 | if (desc->end_sigrenderer) | ||
240 | if (vsigrenderer) | ||
241 | (*desc->end_sigrenderer)(vsigrenderer); | ||
242 | return NULL; | ||
243 | } | ||
244 | |||
245 | sigrenderer->desc = desc; | ||
246 | sigrenderer->sigrenderer = vsigrenderer; | ||
247 | |||
248 | sigrenderer->n_channels = n_channels; | ||
249 | |||
250 | sigrenderer->pos = pos; | ||
251 | sigrenderer->subpos = 0; | ||
252 | |||
253 | sigrenderer->callback = NULL; | ||
254 | |||
255 | return sigrenderer; | ||
256 | } | ||
257 | |||
258 | |||
259 | |||
260 | sigrenderer_t *duh_get_raw_sigrenderer(DUH_SIGRENDERER *sigrenderer, long type) | ||
261 | { | ||
262 | if (sigrenderer && sigrenderer->desc->type == type) | ||
263 | return sigrenderer->sigrenderer; | ||
264 | |||
265 | return NULL; | ||
266 | } | ||
267 | |||
268 | |||
269 | |||
270 | #if 0 | ||
271 | // This function is disabled because we don't know whether we want to destroy | ||
272 | // the sigrenderer if the type doesn't match. We don't even know if we need | ||
273 | // the function at all. Who would want to keep an IT_SIGRENDERER (for | ||
274 | // instance) without keeping the DUH_SIGRENDERER? | ||
275 | sigrenderer_t *duh_decompose_to_raw_sigrenderer(DUH_SIGRENDERER *sigrenderer, long type) | ||
276 | { | ||
277 | if (sigrenderer && sigrenderer->desc->type == type) { | ||
278 | |||
279 | |||
280 | |||
281 | if (sigrenderer) { | ||
282 | if (sigrenderer->desc->end_sigrenderer) | ||
283 | if (sigrenderer->sigrenderer) | ||
284 | (*sigrenderer->desc->end_sigrenderer)(sigrenderer->sigrenderer); | ||
285 | |||
286 | free(sigrenderer); | ||
287 | } | ||
288 | |||
289 | |||
290 | |||
291 | |||
292 | |||
293 | |||
294 | return sigrenderer->sigrenderer; | ||
295 | } | ||
296 | |||
297 | return NULL; | ||
298 | } | ||
299 | #endif | ||