diff options
Diffstat (limited to 'apps/codecs/dumb/src/core')
-rw-r--r-- | apps/codecs/dumb/src/core/atexit.c | 71 | ||||
-rw-r--r-- | apps/codecs/dumb/src/core/duhlen.c | 34 | ||||
-rw-r--r-- | apps/codecs/dumb/src/core/dumbfile.c | 401 | ||||
-rw-r--r-- | apps/codecs/dumb/src/core/loadduh.c | 42 | ||||
-rw-r--r-- | apps/codecs/dumb/src/core/makeduh.c | 92 | ||||
-rw-r--r-- | apps/codecs/dumb/src/core/rawsig.c | 44 | ||||
-rw-r--r-- | apps/codecs/dumb/src/core/readduh.c | 107 | ||||
-rw-r--r-- | apps/codecs/dumb/src/core/register.c | 104 | ||||
-rw-r--r-- | apps/codecs/dumb/src/core/rendduh.c | 202 | ||||
-rw-r--r-- | apps/codecs/dumb/src/core/rendsig.c | 299 | ||||
-rw-r--r-- | apps/codecs/dumb/src/core/unload.c | 58 |
11 files changed, 1454 insertions, 0 deletions
diff --git a/apps/codecs/dumb/src/core/atexit.c b/apps/codecs/dumb/src/core/atexit.c new file mode 100644 index 0000000000..16c6abdb2c --- /dev/null +++ b/apps/codecs/dumb/src/core/atexit.c | |||
@@ -0,0 +1,71 @@ | |||
1 | /* _______ ____ __ ___ ___ | ||
2 | * \ _ \ \ / \ / \ \ / / ' ' ' | ||
3 | * | | \ \ | | || | \/ | . . | ||
4 | * | | | | | | || ||\ /| | | ||
5 | * | | | | | | || || \/ | | ' ' ' | ||
6 | * | | | | | | || || | | . . | ||
7 | * | |_/ / \ \__// || | | | ||
8 | * /_______/ynamic \____/niversal /__\ /____\usic /| . . ibliotheque | ||
9 | * / \ | ||
10 | * / . \ | ||
11 | * atexit.c - Library Clean-up Management. / / \ \ | ||
12 | * | < / \_ | ||
13 | * By entheh. | \/ /\ / | ||
14 | * \_ / > / | ||
15 | * | \ / / | ||
16 | * | ' / | ||
17 | * \__/ | ||
18 | */ | ||
19 | |||
20 | #include <stdlib.h> | ||
21 | |||
22 | #include "dumb.h" | ||
23 | #include "internal/dumb.h" | ||
24 | |||
25 | |||
26 | |||
27 | typedef struct DUMB_ATEXIT_PROC | ||
28 | { | ||
29 | struct DUMB_ATEXIT_PROC *next; | ||
30 | void (*proc)(void); | ||
31 | } | ||
32 | DUMB_ATEXIT_PROC; | ||
33 | |||
34 | |||
35 | |||
36 | static DUMB_ATEXIT_PROC *dumb_atexit_proc = NULL; | ||
37 | |||
38 | |||
39 | |||
40 | int dumb_atexit(void (*proc)(void)) | ||
41 | { | ||
42 | DUMB_ATEXIT_PROC *dap = dumb_atexit_proc; | ||
43 | |||
44 | while (dap) { | ||
45 | if (dap->proc == proc) return 0; | ||
46 | dap = dap->next; | ||
47 | } | ||
48 | |||
49 | dap = malloc(sizeof(*dap)); | ||
50 | |||
51 | if (!dap) | ||
52 | return -1; | ||
53 | |||
54 | dap->next = dumb_atexit_proc; | ||
55 | dap->proc = proc; | ||
56 | dumb_atexit_proc = dap; | ||
57 | |||
58 | return 0; | ||
59 | } | ||
60 | |||
61 | |||
62 | |||
63 | void dumb_exit(void) | ||
64 | { | ||
65 | while (dumb_atexit_proc) { | ||
66 | DUMB_ATEXIT_PROC *next = dumb_atexit_proc->next; | ||
67 | (*dumb_atexit_proc->proc)(); | ||
68 | free(dumb_atexit_proc); | ||
69 | dumb_atexit_proc = next; | ||
70 | } | ||
71 | } | ||
diff --git a/apps/codecs/dumb/src/core/duhlen.c b/apps/codecs/dumb/src/core/duhlen.c new file mode 100644 index 0000000000..4500d0a50f --- /dev/null +++ b/apps/codecs/dumb/src/core/duhlen.c | |||
@@ -0,0 +1,34 @@ | |||
1 | /* _______ ____ __ ___ ___ | ||
2 | * \ _ \ \ / \ / \ \ / / ' ' ' | ||
3 | * | | \ \ | | || | \/ | . . | ||
4 | * | | | | | | || ||\ /| | | ||
5 | * | | | | | | || || \/ | | ' ' ' | ||
6 | * | | | | | | || || | | . . | ||
7 | * | |_/ / \ \__// || | | | ||
8 | * /_______/ynamic \____/niversal /__\ /____\usic /| . . ibliotheque | ||
9 | * / \ | ||
10 | * / . \ | ||
11 | * duhlen.c - Function to return the length of / / \ \ | ||
12 | * a DUH. | < / \_ | ||
13 | * | \/ /\ / | ||
14 | * By entheh. \_ / > / | ||
15 | * | \ / / | ||
16 | * Note that the length of a DUH is a constant | ' / | ||
17 | * stored in the DUH struct and in the DUH disk \__/ | ||
18 | * format. It will be calculated on loading for | ||
19 | * other formats in which the length is not explicitly stored. Also note that | ||
20 | * it does not necessarily correspond to the length of time for which the DUH | ||
21 | * will generate samples. Rather it represents a suitable point for a player | ||
22 | * such as Winamp to stop, and in any good DUH it will allow for any final | ||
23 | * flourish to fade out and be appreciated. | ||
24 | */ | ||
25 | |||
26 | #include "dumb.h" | ||
27 | #include "internal/dumb.h" | ||
28 | |||
29 | |||
30 | |||
31 | long duh_get_length(DUH *duh) | ||
32 | { | ||
33 | return duh ? duh->length : 0; | ||
34 | } | ||
diff --git a/apps/codecs/dumb/src/core/dumbfile.c b/apps/codecs/dumb/src/core/dumbfile.c new file mode 100644 index 0000000000..71108c0c3b --- /dev/null +++ b/apps/codecs/dumb/src/core/dumbfile.c | |||
@@ -0,0 +1,401 @@ | |||
1 | /* _______ ____ __ ___ ___ | ||
2 | * \ _ \ \ / \ / \ \ / / ' ' ' | ||
3 | * | | \ \ | | || | \/ | . . | ||
4 | * | | | | | | || ||\ /| | | ||
5 | * | | | | | | || || \/ | | ' ' ' | ||
6 | * | | | | | | || || | | . . | ||
7 | * | |_/ / \ \__// || | | | ||
8 | * /_______/ynamic \____/niversal /__\ /____\usic /| . . ibliotheque | ||
9 | * / \ | ||
10 | * / . \ | ||
11 | * dumbfile.c - Hookable, strictly sequential / / \ \ | ||
12 | * file input functions. | < / \_ | ||
13 | * | \/ /\ / | ||
14 | * By entheh. \_ / > / | ||
15 | * | \ / / | ||
16 | * | ' / | ||
17 | * \__/ | ||
18 | */ | ||
19 | |||
20 | #include <stdlib.h> | ||
21 | |||
22 | #include "dumb.h" | ||
23 | |||
24 | |||
25 | |||
26 | static DUMBFILE_SYSTEM *the_dfs = NULL; | ||
27 | |||
28 | |||
29 | |||
30 | void register_dumbfile_system(DUMBFILE_SYSTEM *dfs) | ||
31 | { | ||
32 | ASSERT(dfs); | ||
33 | ASSERT(dfs->open); | ||
34 | ASSERT(dfs->getc); | ||
35 | ASSERT(dfs->close); | ||
36 | the_dfs = dfs; | ||
37 | } | ||
38 | |||
39 | |||
40 | |||
41 | struct DUMBFILE | ||
42 | { | ||
43 | DUMBFILE_SYSTEM *dfs; | ||
44 | void *file; | ||
45 | long pos; | ||
46 | }; | ||
47 | |||
48 | |||
49 | |||
50 | DUMBFILE *dumbfile_open(const char *filename) | ||
51 | { | ||
52 | DUMBFILE *f; | ||
53 | |||
54 | ASSERT(the_dfs); | ||
55 | |||
56 | f = malloc(sizeof(*f)); | ||
57 | |||
58 | if (!f) | ||
59 | return NULL; | ||
60 | |||
61 | f->dfs = the_dfs; | ||
62 | |||
63 | f->file = (*the_dfs->open)(filename); | ||
64 | |||
65 | if (!f->file) { | ||
66 | free(f); | ||
67 | return NULL; | ||
68 | } | ||
69 | |||
70 | f->pos = 0; | ||
71 | |||
72 | return f; | ||
73 | } | ||
74 | |||
75 | |||
76 | |||
77 | DUMBFILE *dumbfile_open_ex(void *file, DUMBFILE_SYSTEM *dfs) | ||
78 | { | ||
79 | DUMBFILE *f; | ||
80 | |||
81 | ASSERT(dfs); | ||
82 | ASSERT(dfs->getc); | ||
83 | ASSERT(file); | ||
84 | |||
85 | f = malloc(sizeof(*f)); | ||
86 | |||
87 | if (!f) { | ||
88 | if (dfs->close) | ||
89 | (*dfs->close)(file); | ||
90 | return NULL; | ||
91 | } | ||
92 | |||
93 | f->dfs = dfs; | ||
94 | f->file = file; | ||
95 | |||
96 | f->pos = 0; | ||
97 | |||
98 | return f; | ||
99 | } | ||
100 | |||
101 | |||
102 | |||
103 | long dumbfile_pos(DUMBFILE *f) | ||
104 | { | ||
105 | ASSERT(f); | ||
106 | |||
107 | return f->pos; | ||
108 | } | ||
109 | |||
110 | |||
111 | |||
112 | int dumbfile_skip(DUMBFILE *f, long n) | ||
113 | { | ||
114 | int rv; | ||
115 | |||
116 | ASSERT(f); | ||
117 | ASSERT(n >= 0); | ||
118 | |||
119 | if (f->pos < 0) | ||
120 | return -1; | ||
121 | |||
122 | f->pos += n; | ||
123 | |||
124 | if (f->dfs->skip) { | ||
125 | rv = (*f->dfs->skip)(f->file, n); | ||
126 | if (rv) { | ||
127 | f->pos = -1; | ||
128 | return rv; | ||
129 | } | ||
130 | } else { | ||
131 | while (n) { | ||
132 | rv = (*f->dfs->getc)(f->file); | ||
133 | if (rv < 0) { | ||
134 | f->pos = -1; | ||
135 | return rv; | ||
136 | } | ||
137 | n--; | ||
138 | } | ||
139 | } | ||
140 | |||
141 | return 0; | ||
142 | } | ||
143 | |||
144 | |||
145 | |||
146 | int dumbfile_getc(DUMBFILE *f) | ||
147 | { | ||
148 | int rv; | ||
149 | |||
150 | ASSERT(f); | ||
151 | |||
152 | if (f->pos < 0) | ||
153 | return -1; | ||
154 | |||
155 | rv = (*f->dfs->getc)(f->file); | ||
156 | |||
157 | if (rv < 0) { | ||
158 | f->pos = -1; | ||
159 | return rv; | ||
160 | } | ||
161 | |||
162 | f->pos++; | ||
163 | |||
164 | return rv; | ||
165 | } | ||
166 | |||
167 | |||
168 | |||
169 | int dumbfile_igetw(DUMBFILE *f) | ||
170 | { | ||
171 | int l, h; | ||
172 | |||
173 | ASSERT(f); | ||
174 | |||
175 | if (f->pos < 0) | ||
176 | return -1; | ||
177 | |||
178 | l = (*f->dfs->getc)(f->file); | ||
179 | if (l < 0) { | ||
180 | f->pos = -1; | ||
181 | return l; | ||
182 | } | ||
183 | |||
184 | h = (*f->dfs->getc)(f->file); | ||
185 | if (h < 0) { | ||
186 | f->pos = -1; | ||
187 | return h; | ||
188 | } | ||
189 | |||
190 | f->pos += 2; | ||
191 | |||
192 | return l | (h << 8); | ||
193 | } | ||
194 | |||
195 | |||
196 | |||
197 | int dumbfile_mgetw(DUMBFILE *f) | ||
198 | { | ||
199 | int l, h; | ||
200 | |||
201 | ASSERT(f); | ||
202 | |||
203 | if (f->pos < 0) | ||
204 | return -1; | ||
205 | |||
206 | h = (*f->dfs->getc)(f->file); | ||
207 | if (h < 0) { | ||
208 | f->pos = -1; | ||
209 | return h; | ||
210 | } | ||
211 | |||
212 | l = (*f->dfs->getc)(f->file); | ||
213 | if (l < 0) { | ||
214 | f->pos = -1; | ||
215 | return l; | ||
216 | } | ||
217 | |||
218 | f->pos += 2; | ||
219 | |||
220 | return l | (h << 8); | ||
221 | } | ||
222 | |||
223 | |||
224 | |||
225 | long dumbfile_igetl(DUMBFILE *f) | ||
226 | { | ||
227 | unsigned long rv, b; | ||
228 | |||
229 | ASSERT(f); | ||
230 | |||
231 | if (f->pos < 0) | ||
232 | return -1; | ||
233 | |||
234 | rv = (*f->dfs->getc)(f->file); | ||
235 | if ((signed long)rv < 0) { | ||
236 | f->pos = -1; | ||
237 | return rv; | ||
238 | } | ||
239 | |||
240 | b = (*f->dfs->getc)(f->file); | ||
241 | if ((signed long)b < 0) { | ||
242 | f->pos = -1; | ||
243 | return b; | ||
244 | } | ||
245 | rv |= b << 8; | ||
246 | |||
247 | b = (*f->dfs->getc)(f->file); | ||
248 | if ((signed long)b < 0) { | ||
249 | f->pos = -1; | ||
250 | return b; | ||
251 | } | ||
252 | rv |= b << 16; | ||
253 | |||
254 | b = (*f->dfs->getc)(f->file); | ||
255 | if ((signed long)b < 0) { | ||
256 | f->pos = -1; | ||
257 | return b; | ||
258 | } | ||
259 | rv |= b << 24; | ||
260 | |||
261 | f->pos += 4; | ||
262 | |||
263 | return rv; | ||
264 | } | ||
265 | |||
266 | |||
267 | |||
268 | long dumbfile_mgetl(DUMBFILE *f) | ||
269 | { | ||
270 | unsigned long rv, b; | ||
271 | |||
272 | ASSERT(f); | ||
273 | |||
274 | if (f->pos < 0) | ||
275 | return -1; | ||
276 | |||
277 | rv = (*f->dfs->getc)(f->file); | ||
278 | if ((signed long)rv < 0) { | ||
279 | f->pos = -1; | ||
280 | return rv; | ||
281 | } | ||
282 | rv <<= 24; | ||
283 | |||
284 | b = (*f->dfs->getc)(f->file); | ||
285 | if ((signed long)b < 0) { | ||
286 | f->pos = -1; | ||
287 | return b; | ||
288 | } | ||
289 | rv |= b << 16; | ||
290 | |||
291 | b = (*f->dfs->getc)(f->file); | ||
292 | if ((signed long)b < 0) { | ||
293 | f->pos = -1; | ||
294 | return b; | ||
295 | } | ||
296 | rv |= b << 8; | ||
297 | |||
298 | b = (*f->dfs->getc)(f->file); | ||
299 | if ((signed long)b < 0) { | ||
300 | f->pos = -1; | ||
301 | return b; | ||
302 | } | ||
303 | rv |= b; | ||
304 | |||
305 | f->pos += 4; | ||
306 | |||
307 | return rv; | ||
308 | } | ||
309 | |||
310 | |||
311 | |||
312 | unsigned long dumbfile_cgetul(DUMBFILE *f) | ||
313 | { | ||
314 | unsigned long rv = 0; | ||
315 | int v; | ||
316 | |||
317 | do { | ||
318 | v = dumbfile_getc(f); | ||
319 | |||
320 | if (v < 0) | ||
321 | return v; | ||
322 | |||
323 | rv <<= 7; | ||
324 | rv |= v & 0x7F; | ||
325 | } while (v & 0x80); | ||
326 | |||
327 | return rv; | ||
328 | } | ||
329 | |||
330 | |||
331 | |||
332 | signed long dumbfile_cgetsl(DUMBFILE *f) | ||
333 | { | ||
334 | unsigned long rv = dumbfile_cgetul(f); | ||
335 | |||
336 | if (f->pos < 0) | ||
337 | return rv; | ||
338 | |||
339 | return (rv >> 1) | (rv << 31); | ||
340 | } | ||
341 | |||
342 | |||
343 | |||
344 | long dumbfile_getnc(char *ptr, long n, DUMBFILE *f) | ||
345 | { | ||
346 | long rv; | ||
347 | |||
348 | ASSERT(f); | ||
349 | ASSERT(n >= 0); | ||
350 | |||
351 | if (f->pos < 0) | ||
352 | return -1; | ||
353 | |||
354 | if (f->dfs->getnc) { | ||
355 | rv = (*f->dfs->getnc)(ptr, n, f->file); | ||
356 | if (rv < n) { | ||
357 | f->pos = -1; | ||
358 | return MAX(rv, 0); | ||
359 | } | ||
360 | } else { | ||
361 | for (rv = 0; rv < n; rv++) { | ||
362 | int c = (*f->dfs->getc)(f->file); | ||
363 | if (c < 0) { | ||
364 | f->pos = -1; | ||
365 | return rv; | ||
366 | } | ||
367 | *ptr++ = c; | ||
368 | } | ||
369 | } | ||
370 | |||
371 | f->pos += rv; | ||
372 | |||
373 | return rv; | ||
374 | } | ||
375 | |||
376 | |||
377 | |||
378 | int dumbfile_error(DUMBFILE *f) | ||
379 | { | ||
380 | ASSERT(f); | ||
381 | |||
382 | return f->pos < 0; | ||
383 | } | ||
384 | |||
385 | |||
386 | |||
387 | int dumbfile_close(DUMBFILE *f) | ||
388 | { | ||
389 | int rv; | ||
390 | |||
391 | ASSERT(f); | ||
392 | |||
393 | rv = f->pos < 0; | ||
394 | |||
395 | if (f->dfs->close) | ||
396 | (*f->dfs->close)(f->file); | ||
397 | |||
398 | free(f); | ||
399 | |||
400 | return rv; | ||
401 | } | ||
diff --git a/apps/codecs/dumb/src/core/loadduh.c b/apps/codecs/dumb/src/core/loadduh.c new file mode 100644 index 0000000000..7dfe5cc100 --- /dev/null +++ b/apps/codecs/dumb/src/core/loadduh.c | |||
@@ -0,0 +1,42 @@ | |||
1 | /* _______ ____ __ ___ ___ | ||
2 | * \ _ \ \ / \ / \ \ / / ' ' ' | ||
3 | * | | \ \ | | || | \/ | . . | ||
4 | * | | | | | | || ||\ /| | | ||
5 | * | | | | | | || || \/ | | ' ' ' | ||
6 | * | | | | | | || || | | . . | ||
7 | * | |_/ / \ \__// || | | | ||
8 | * /_______/ynamic \____/niversal /__\ /____\usic /| . . ibliotheque | ||
9 | * / \ | ||
10 | * / . \ | ||
11 | * loadduh.c - Code to read a DUH from a file, / / \ \ | ||
12 | * opening and closing the file for | < / \_ | ||
13 | * you. | \/ /\ / | ||
14 | * \_ / > / | ||
15 | * By entheh. | \ / / | ||
16 | * | ' / | ||
17 | * \__/ | ||
18 | */ | ||
19 | |||
20 | #include "dumb.h" | ||
21 | #include "internal/dumb.h" | ||
22 | |||
23 | |||
24 | |||
25 | /* load_duh(): loads a .duh file, returning a pointer to a DUH struct. | ||
26 | * When you have finished with it, you must pass the pointer to unload_duh() | ||
27 | * so that the memory can be freed. | ||
28 | */ | ||
29 | DUH *load_duh(const char *filename) | ||
30 | { | ||
31 | DUH *duh; | ||
32 | DUMBFILE *f = dumbfile_open(filename); | ||
33 | |||
34 | if (!f) | ||
35 | return NULL; | ||
36 | |||
37 | duh = read_duh(f); | ||
38 | |||
39 | dumbfile_close(f); | ||
40 | |||
41 | return duh; | ||
42 | } | ||
diff --git a/apps/codecs/dumb/src/core/makeduh.c b/apps/codecs/dumb/src/core/makeduh.c new file mode 100644 index 0000000000..1e422fb502 --- /dev/null +++ b/apps/codecs/dumb/src/core/makeduh.c | |||
@@ -0,0 +1,92 @@ | |||
1 | /* _______ ____ __ ___ ___ | ||
2 | * \ _ \ \ / \ / \ \ / / ' ' ' | ||
3 | * | | \ \ | | || | \/ | . . | ||
4 | * | | | | | | || ||\ /| | | ||
5 | * | | | | | | || || \/ | | ' ' ' | ||
6 | * | | | | | | || || | | . . | ||
7 | * | |_/ / \ \__// || | | | ||
8 | * /_______/ynamic \____/niversal /__\ /____\usic /| . . ibliotheque | ||
9 | * / \ | ||
10 | * / . \ | ||
11 | * makeduh.c - Function to construct a DUH from / / \ \ | ||
12 | * its components. | < / \_ | ||
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 | static DUH_SIGNAL *make_signal(DUH_SIGTYPE_DESC *desc, sigdata_t *sigdata) | ||
28 | { | ||
29 | DUH_SIGNAL *signal; | ||
30 | |||
31 | ASSERT((desc->start_sigrenderer && desc->end_sigrenderer) || (!desc->start_sigrenderer && !desc->end_sigrenderer)); | ||
32 | ASSERT(desc->sigrenderer_get_samples && desc->sigrenderer_get_current_sample); | ||
33 | |||
34 | signal = malloc(sizeof(*signal)); | ||
35 | |||
36 | if (!signal) { | ||
37 | if (desc->unload_sigdata) | ||
38 | if (sigdata) | ||
39 | (*desc->unload_sigdata)(sigdata); | ||
40 | return NULL; | ||
41 | } | ||
42 | |||
43 | signal->desc = desc; | ||
44 | signal->sigdata = sigdata; | ||
45 | |||
46 | return signal; | ||
47 | } | ||
48 | |||
49 | |||
50 | |||
51 | DUH *make_duh(long length, int n_signals, DUH_SIGTYPE_DESC *desc[], sigdata_t *sigdata[]) | ||
52 | { | ||
53 | DUH *duh = malloc(sizeof(*duh)); | ||
54 | int i; | ||
55 | int fail; | ||
56 | |||
57 | if (duh) { | ||
58 | duh->n_signals = n_signals; | ||
59 | |||
60 | duh->signal = malloc(n_signals * sizeof(*duh->signal)); | ||
61 | |||
62 | if (!duh->signal) { | ||
63 | free(duh); | ||
64 | duh = NULL; | ||
65 | } | ||
66 | } | ||
67 | |||
68 | if (!duh) { | ||
69 | for (i = 0; i < n_signals; i++) | ||
70 | if (desc[i]->unload_sigdata) | ||
71 | if (sigdata[i]) | ||
72 | (*desc[i]->unload_sigdata)(sigdata[i]); | ||
73 | return NULL; | ||
74 | } | ||
75 | |||
76 | fail = 0; | ||
77 | |||
78 | for (i = 0; i < n_signals; i++) { | ||
79 | duh->signal[i] = make_signal(desc[i], sigdata[i]); | ||
80 | if (!duh->signal[i]) | ||
81 | fail = 1; | ||
82 | } | ||
83 | |||
84 | if (fail) { | ||
85 | unload_duh(duh); | ||
86 | return NULL; | ||
87 | } | ||
88 | |||
89 | duh->length = length; | ||
90 | |||
91 | return duh; | ||
92 | } | ||
diff --git a/apps/codecs/dumb/src/core/rawsig.c b/apps/codecs/dumb/src/core/rawsig.c new file mode 100644 index 0000000000..926c990655 --- /dev/null +++ b/apps/codecs/dumb/src/core/rawsig.c | |||
@@ -0,0 +1,44 @@ | |||
1 | /* _______ ____ __ ___ ___ | ||
2 | * \ _ \ \ / \ / \ \ / / ' ' ' | ||
3 | * | | \ \ | | || | \/ | . . | ||
4 | * | | | | | | || ||\ /| | | ||
5 | * | | | | | | || || \/ | | ' ' ' | ||
6 | * | | | | | | || || | | . . | ||
7 | * | |_/ / \ \__// || | | | ||
8 | * /_______/ynamic \____/niversal /__\ /____\usic /| . . ibliotheque | ||
9 | * / \ | ||
10 | * / . \ | ||
11 | * rawsig.c - Function to retrieve raw signal / / \ \ | ||
12 | * data from a DUH provided you know | < / \_ | ||
13 | * what type of signal it is. | \/ /\ / | ||
14 | * \_ / > / | ||
15 | * By entheh. | \ / / | ||
16 | * | ' / | ||
17 | * \__/ | ||
18 | */ | ||
19 | |||
20 | #include <stdlib.h> | ||
21 | |||
22 | #include "dumb.h" | ||
23 | #include "internal/dumb.h" | ||
24 | |||
25 | |||
26 | |||
27 | /* You have to specify the type of sigdata, proving you know what to do with | ||
28 | * the pointer. If you get it wrong, you can expect NULL back. | ||
29 | */ | ||
30 | sigdata_t *duh_get_raw_sigdata(DUH *duh, int sig, long type) | ||
31 | { | ||
32 | DUH_SIGNAL *signal; | ||
33 | |||
34 | if (!duh) return NULL; | ||
35 | |||
36 | if ((unsigned int)sig >= (unsigned int)duh->n_signals) return NULL; | ||
37 | |||
38 | signal = duh->signal[sig]; | ||
39 | |||
40 | if (signal && signal->desc->type == type) | ||
41 | return signal->sigdata; | ||
42 | |||
43 | return NULL; | ||
44 | } | ||
diff --git a/apps/codecs/dumb/src/core/readduh.c b/apps/codecs/dumb/src/core/readduh.c new file mode 100644 index 0000000000..514b04a077 --- /dev/null +++ b/apps/codecs/dumb/src/core/readduh.c | |||
@@ -0,0 +1,107 @@ | |||
1 | /* _______ ____ __ ___ ___ | ||
2 | * \ _ \ \ / \ / \ \ / / ' ' ' | ||
3 | * | | \ \ | | || | \/ | . . | ||
4 | * | | | | | | || ||\ /| | | ||
5 | * | | | | | | || || \/ | | ' ' ' | ||
6 | * | | | | | | || || | | . . | ||
7 | * | |_/ / \ \__// || | | | ||
8 | * /_______/ynamic \____/niversal /__\ /____\usic /| . . ibliotheque | ||
9 | * / \ | ||
10 | * / . \ | ||
11 | * readduh.c - Code to read a DUH from an open / / \ \ | ||
12 | * file. | < / \_ | ||
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 | static DUH_SIGNAL *read_signal(DUH *duh, DUMBFILE *f) | ||
28 | { | ||
29 | DUH_SIGNAL *signal; | ||
30 | long type; | ||
31 | |||
32 | signal = malloc(sizeof(*signal)); | ||
33 | |||
34 | if (!signal) | ||
35 | return NULL; | ||
36 | |||
37 | type = dumbfile_mgetl(f); | ||
38 | if (dumbfile_error(f)) { | ||
39 | free(signal); | ||
40 | return NULL; | ||
41 | } | ||
42 | |||
43 | signal->desc = _dumb_get_sigtype_desc(type); | ||
44 | if (!signal->desc) { | ||
45 | free(signal); | ||
46 | return NULL; | ||
47 | } | ||
48 | |||
49 | if (signal->desc->load_sigdata) { | ||
50 | signal->sigdata = (*signal->desc->load_sigdata)(duh, f); | ||
51 | if (!signal->sigdata) { | ||
52 | free(signal); | ||
53 | return NULL; | ||
54 | } | ||
55 | } else | ||
56 | signal->sigdata = NULL; | ||
57 | |||
58 | return signal; | ||
59 | } | ||
60 | |||
61 | |||
62 | |||
63 | /* read_duh(): reads a DUH from an already open DUMBFILE, and returns its | ||
64 | * pointer, or null on error. The file is not closed. | ||
65 | */ | ||
66 | DUH *read_duh(DUMBFILE *f) | ||
67 | { | ||
68 | DUH *duh; | ||
69 | int i; | ||
70 | |||
71 | if (dumbfile_mgetl(f) != DUH_SIGNATURE) | ||
72 | return NULL; | ||
73 | |||
74 | duh = malloc(sizeof(*duh)); | ||
75 | if (!duh) | ||
76 | return NULL; | ||
77 | |||
78 | duh->length = dumbfile_igetl(f); | ||
79 | if (dumbfile_error(f) || duh->length <= 0) { | ||
80 | free(duh); | ||
81 | return NULL; | ||
82 | } | ||
83 | |||
84 | duh->n_signals = dumbfile_igetl(f); | ||
85 | if (dumbfile_error(f) || duh->n_signals <= 0) { | ||
86 | free(duh); | ||
87 | return NULL; | ||
88 | } | ||
89 | |||
90 | duh->signal = malloc(sizeof(*duh->signal) * duh->n_signals); | ||
91 | if (!duh->signal) { | ||
92 | free(duh); | ||
93 | return NULL; | ||
94 | } | ||
95 | |||
96 | for (i = 0; i < duh->n_signals; i++) | ||
97 | duh->signal[i] = NULL; | ||
98 | |||
99 | for (i = 0; i < duh->n_signals; i++) { | ||
100 | if (!(duh->signal[i] = read_signal(duh, f))) { | ||
101 | unload_duh(duh); | ||
102 | return NULL; | ||
103 | } | ||
104 | } | ||
105 | |||
106 | return duh; | ||
107 | } | ||
diff --git a/apps/codecs/dumb/src/core/register.c b/apps/codecs/dumb/src/core/register.c new file mode 100644 index 0000000000..9eed45f796 --- /dev/null +++ b/apps/codecs/dumb/src/core/register.c | |||
@@ -0,0 +1,104 @@ | |||
1 | /* _______ ____ __ ___ ___ | ||
2 | * \ _ \ \ / \ / \ \ / / ' ' ' | ||
3 | * | | \ \ | | || | \/ | . . | ||
4 | * | | | | | | || ||\ /| | | ||
5 | * | | | | | | || || \/ | | ' ' ' | ||
6 | * | | | | | | || || | | . . | ||
7 | * | |_/ / \ \__// || | | | ||
8 | * /_______/ynamic \____/niversal /__\ /____\usic /| . . ibliotheque | ||
9 | * / \ | ||
10 | * / . \ | ||
11 | * register.c - Signal type registration. / / \ \ | ||
12 | * | < / \_ | ||
13 | * By entheh. | \/ /\ / | ||
14 | * \_ / > / | ||
15 | * | \ / / | ||
16 | * | ' / | ||
17 | * \__/ | ||
18 | */ | ||
19 | |||
20 | #include <stdlib.h> | ||
21 | |||
22 | #include "dumb.h" | ||
23 | #include "internal/dumb.h" | ||
24 | |||
25 | |||
26 | |||
27 | static DUH_SIGTYPE_DESC_LINK *sigtype_desc = NULL; | ||
28 | static DUH_SIGTYPE_DESC_LINK **sigtype_desc_tail = &sigtype_desc; | ||
29 | |||
30 | |||
31 | |||
32 | /* destroy_sigtypes(): frees all memory allocated while registering signal | ||
33 | * types. This function is set up to be called by dumb_exit(). | ||
34 | */ | ||
35 | static void destroy_sigtypes(void) | ||
36 | { | ||
37 | DUH_SIGTYPE_DESC_LINK *desc_link = sigtype_desc, *next; | ||
38 | sigtype_desc = NULL; | ||
39 | sigtype_desc_tail = &sigtype_desc; | ||
40 | |||
41 | while (desc_link) { | ||
42 | next = desc_link->next; | ||
43 | free(desc_link); | ||
44 | desc_link = next; | ||
45 | } | ||
46 | } | ||
47 | |||
48 | |||
49 | |||
50 | /* dumb_register_sigtype(): registers a new signal type with DUMB. The signal | ||
51 | * type is identified by a four-character string (e.g. "WAVE"), which you can | ||
52 | * encode using the the DUMB_ID() macro (e.g. DUMB_ID('W','A','V','E')). The | ||
53 | * signal's behaviour is defined by four functions, whose pointers you pass | ||
54 | * here. See the documentation for details. | ||
55 | * | ||
56 | * If a DUH tries to use a signal that has not been registered using this | ||
57 | * function, then the library will fail to load the DUH. | ||
58 | */ | ||
59 | void dumb_register_sigtype(DUH_SIGTYPE_DESC *desc) | ||
60 | { | ||
61 | DUH_SIGTYPE_DESC_LINK *desc_link = sigtype_desc; | ||
62 | |||
63 | ASSERT((desc->load_sigdata && desc->unload_sigdata) || (!desc->load_sigdata && !desc->unload_sigdata)); | ||
64 | ASSERT((desc->start_sigrenderer && desc->end_sigrenderer) || (!desc->start_sigrenderer && !desc->end_sigrenderer)); | ||
65 | ASSERT(desc->sigrenderer_get_samples && desc->sigrenderer_get_current_sample); | ||
66 | |||
67 | if (desc_link) { | ||
68 | do { | ||
69 | if (desc_link->desc->type == desc->type) { | ||
70 | desc_link->desc = desc; | ||
71 | return; | ||
72 | } | ||
73 | desc_link = desc_link->next; | ||
74 | } while (desc_link); | ||
75 | } else | ||
76 | dumb_atexit(&destroy_sigtypes); | ||
77 | |||
78 | desc_link = *sigtype_desc_tail = malloc(sizeof(DUH_SIGTYPE_DESC_LINK)); | ||
79 | |||
80 | if (!desc_link) | ||
81 | return; | ||
82 | |||
83 | desc_link->next = NULL; | ||
84 | sigtype_desc_tail = &desc_link->next; | ||
85 | |||
86 | desc_link->desc = desc; | ||
87 | } | ||
88 | |||
89 | |||
90 | |||
91 | /* _dumb_get_sigtype_desc(): searches the registered functions for a signal | ||
92 | * type matching the parameter. If such a sigtype is found, it returns a | ||
93 | * pointer to a sigtype descriptor containing the necessary functions to | ||
94 | * manage the signal. If none is found, it returns NULL. | ||
95 | */ | ||
96 | DUH_SIGTYPE_DESC *_dumb_get_sigtype_desc(long type) | ||
97 | { | ||
98 | DUH_SIGTYPE_DESC_LINK *desc_link = sigtype_desc; | ||
99 | |||
100 | while (desc_link && desc_link->desc->type != type) | ||
101 | desc_link = desc_link->next; | ||
102 | |||
103 | return desc_link->desc; | ||
104 | } | ||
diff --git a/apps/codecs/dumb/src/core/rendduh.c b/apps/codecs/dumb/src/core/rendduh.c new file mode 100644 index 0000000000..39db8ab8a3 --- /dev/null +++ b/apps/codecs/dumb/src/core/rendduh.c | |||
@@ -0,0 +1,202 @@ | |||
1 | /* _______ ____ __ ___ ___ | ||
2 | * \ _ \ \ / \ / \ \ / / ' ' ' | ||
3 | * | | \ \ | | || | \/ | . . | ||
4 | * | | | | | | || ||\ /| | | ||
5 | * | | | | | | || || \/ | | ' ' ' | ||
6 | * | | | | | | || || | | . . | ||
7 | * | |_/ / \ \__// || | | | ||
8 | * /_______/ynamic \____/niversal /__\ /____\usic /| . . ibliotheque | ||
9 | * / \ | ||
10 | * / . \ | ||
11 | * rendduh.c - Functions for rendering a DUH into / / \ \ | ||
12 | * an end-user sample format. | < / \_ | ||
13 | * | \/ /\ / | ||
14 | * By entheh. \_ / > / | ||
15 | * | \ / / | ||
16 | * | ' / | ||
17 | * \__/ | ||
18 | */ | ||
19 | |||
20 | #include <stdlib.h> | ||
21 | #include <limits.h> | ||
22 | |||
23 | #include "dumb.h" | ||
24 | #include "internal/dumb.h" | ||
25 | |||
26 | |||
27 | |||
28 | /* On the x86, we can use some tricks to speed stuff up */ | ||
29 | #if (defined _MSC_VER) || (defined __DJGPP__) || (defined __MINGW__) | ||
30 | // Can't we detect Linux and other x86 platforms here? :/ | ||
31 | |||
32 | #define FAST_MID(var, min, max) { \ | ||
33 | var -= (min); \ | ||
34 | var &= (~var) >> (sizeof(var) * CHAR_BIT - 1); \ | ||
35 | var += (min); \ | ||
36 | var -= (max); \ | ||
37 | var &= var >> (sizeof(var) * CHAR_BIT - 1); \ | ||
38 | var += (max); \ | ||
39 | } | ||
40 | |||
41 | #define CONVERT8(src, pos, signconv) { \ | ||
42 | signed int f = (src + 0x8000) >> 16; \ | ||
43 | FAST_MID(f, -128, 127); \ | ||
44 | ((char*)sptr)[pos] = (char)f ^ signconv; \ | ||
45 | } | ||
46 | |||
47 | #define CONVERT16(src, pos, signconv) { \ | ||
48 | signed int f = (src + 0x80) >> 8; \ | ||
49 | FAST_MID(f, -32768, 32767); \ | ||
50 | ((short*)sptr)[pos] = (short)(f ^ signconv); \ | ||
51 | } | ||
52 | |||
53 | #else | ||
54 | |||
55 | #define CONVERT8(src, pos, signconv) \ | ||
56 | { \ | ||
57 | signed int f = (src + 0x8000) >> 16; \ | ||
58 | f = MID(-128, f, 127); \ | ||
59 | ((char *)sptr)[pos] = (char)f ^ signconv; \ | ||
60 | } | ||
61 | |||
62 | |||
63 | |||
64 | #define CONVERT16(src, pos, signconv) \ | ||
65 | { \ | ||
66 | signed int f = (src + 0x80) >> 8; \ | ||
67 | f = MID(-32768, f, 32767); \ | ||
68 | ((short *)sptr)[pos] = (short)(f ^ signconv); \ | ||
69 | } | ||
70 | |||
71 | #endif | ||
72 | |||
73 | |||
74 | |||
75 | /* DEPRECATED */ | ||
76 | DUH_SIGRENDERER *duh_start_renderer(DUH *duh, int n_channels, long pos) | ||
77 | { | ||
78 | return duh_start_sigrenderer(duh, 0, n_channels, pos); | ||
79 | } | ||
80 | |||
81 | |||
82 | |||
83 | long duh_render( | ||
84 | DUH_SIGRENDERER *sigrenderer, | ||
85 | int bits, int unsign, | ||
86 | float volume, float delta, | ||
87 | long size, void *sptr | ||
88 | ) | ||
89 | { | ||
90 | long n; | ||
91 | |||
92 | sample_t **sampptr; | ||
93 | |||
94 | int n_channels; | ||
95 | |||
96 | ASSERT(bits == 8 || bits == 16); | ||
97 | ASSERT(sptr); | ||
98 | |||
99 | if (!sigrenderer) | ||
100 | return 0; | ||
101 | |||
102 | n_channels = duh_sigrenderer_get_n_channels(sigrenderer); | ||
103 | |||
104 | ASSERT(n_channels > 0); | ||
105 | /* This restriction will be removed when need be. At the moment, tightly | ||
106 | * optimised loops exist for exactly one or two channels. | ||
107 | */ | ||
108 | ASSERT(n_channels <= 2); | ||
109 | |||
110 | sampptr = create_sample_buffer(n_channels, size); | ||
111 | |||
112 | if (!sampptr) | ||
113 | return 0; | ||
114 | |||
115 | dumb_silence(sampptr[0], n_channels * size); | ||
116 | |||
117 | size = duh_sigrenderer_get_samples(sigrenderer, volume, delta, size, sampptr); | ||
118 | |||
119 | if (bits == 16) { | ||
120 | int signconv = unsign ? 0x8000 : 0x0000; | ||
121 | |||
122 | if (n_channels == 2) { | ||
123 | for (n = 0; n < size; n++) { | ||
124 | CONVERT16(sampptr[0][n], n << 1, signconv); | ||
125 | } | ||
126 | for (n = 0; n < size; n++) { | ||
127 | CONVERT16(sampptr[1][n], (n << 1) + 1, signconv); | ||
128 | } | ||
129 | } else { | ||
130 | for (n = 0; n < size; n++) { | ||
131 | CONVERT16(sampptr[0][n], n, signconv); | ||
132 | } | ||
133 | } | ||
134 | } else { | ||
135 | char signconv = unsign ? 0x80 : 0x00; | ||
136 | |||
137 | if (n_channels == 2) { | ||
138 | for (n = 0; n < size; n++) { | ||
139 | CONVERT8(sampptr[0][n], n << 1, signconv); | ||
140 | } | ||
141 | for (n = 0; n < size; n++) { | ||
142 | CONVERT8(sampptr[1][n], (n << 1) + 1, signconv); | ||
143 | } | ||
144 | } else { | ||
145 | for (n = 0; n < size; n++) { | ||
146 | CONVERT8(sampptr[0][n], n, signconv); | ||
147 | } | ||
148 | } | ||
149 | } | ||
150 | |||
151 | destroy_sample_buffer(sampptr); | ||
152 | |||
153 | return size; | ||
154 | } | ||
155 | |||
156 | |||
157 | |||
158 | /* DEPRECATED */ | ||
159 | int duh_renderer_get_n_channels(DUH_SIGRENDERER *dr) | ||
160 | { | ||
161 | return duh_sigrenderer_get_n_channels(dr); | ||
162 | } | ||
163 | |||
164 | |||
165 | |||
166 | /* DEPRECATED */ | ||
167 | long duh_renderer_get_position(DUH_SIGRENDERER *dr) | ||
168 | { | ||
169 | return duh_sigrenderer_get_position(dr); | ||
170 | } | ||
171 | |||
172 | |||
173 | |||
174 | /* DEPRECATED */ | ||
175 | void duh_end_renderer(DUH_SIGRENDERER *dr) | ||
176 | { | ||
177 | duh_end_sigrenderer(dr); | ||
178 | } | ||
179 | |||
180 | |||
181 | |||
182 | /* DEPRECATED */ | ||
183 | DUH_SIGRENDERER *duh_renderer_encapsulate_sigrenderer(DUH_SIGRENDERER *sigrenderer) | ||
184 | { | ||
185 | return sigrenderer; | ||
186 | } | ||
187 | |||
188 | |||
189 | |||
190 | /* DEPRECATED */ | ||
191 | DUH_SIGRENDERER *duh_renderer_get_sigrenderer(DUH_SIGRENDERER *dr) | ||
192 | { | ||
193 | return dr; | ||
194 | } | ||
195 | |||
196 | |||
197 | |||
198 | /* DEPRECATED */ | ||
199 | DUH_SIGRENDERER *duh_renderer_decompose_to_sigrenderer(DUH_SIGRENDERER *dr) | ||
200 | { | ||
201 | return dr; | ||
202 | } | ||
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 | ||
diff --git a/apps/codecs/dumb/src/core/unload.c b/apps/codecs/dumb/src/core/unload.c new file mode 100644 index 0000000000..3bf0285cd1 --- /dev/null +++ b/apps/codecs/dumb/src/core/unload.c | |||
@@ -0,0 +1,58 @@ | |||
1 | /* _______ ____ __ ___ ___ | ||
2 | * \ _ \ \ / \ / \ \ / / ' ' ' | ||
3 | * | | \ \ | | || | \/ | . . | ||
4 | * | | | | | | || ||\ /| | | ||
5 | * | | | | | | || || \/ | | ' ' ' | ||
6 | * | | | | | | || || | | . . | ||
7 | * | |_/ / \ \__// || | | | ||
8 | * /_______/ynamic \____/niversal /__\ /____\usic /| . . ibliotheque | ||
9 | * / \ | ||
10 | * / . \ | ||
11 | * unload.c - Code to free a DUH from memory. / / \ \ | ||
12 | * | < / \_ | ||
13 | * By entheh. | \/ /\ / | ||
14 | * \_ / > / | ||
15 | * | \ / / | ||
16 | * | ' / | ||
17 | * \__/ | ||
18 | */ | ||
19 | |||
20 | #include <stdlib.h> | ||
21 | |||
22 | #include "dumb.h" | ||
23 | #include "internal/dumb.h" | ||
24 | |||
25 | |||
26 | |||
27 | static void destroy_signal(DUH_SIGNAL *signal) | ||
28 | { | ||
29 | if (signal) { | ||
30 | if (signal->desc) | ||
31 | if (signal->desc->unload_sigdata) | ||
32 | if (signal->sigdata) | ||
33 | (*signal->desc->unload_sigdata)(signal->sigdata); | ||
34 | |||
35 | free(signal); | ||
36 | } | ||
37 | } | ||
38 | |||
39 | |||
40 | |||
41 | /* unload_duh(): destroys a DUH struct. You must call this for every DUH | ||
42 | * struct created, when you've finished with it. | ||
43 | */ | ||
44 | void unload_duh(DUH *duh) | ||
45 | { | ||
46 | int i; | ||
47 | |||
48 | if (duh) { | ||
49 | if (duh->signal) { | ||
50 | for (i = 0; i < duh->n_signals; i++) | ||
51 | destroy_signal(duh->signal[i]); | ||
52 | |||
53 | free(duh->signal); | ||
54 | } | ||
55 | |||
56 | free(duh); | ||
57 | } | ||
58 | } | ||