diff options
Diffstat (limited to 'apps/plugins/pdbox/PDa/intern/sfread~.c')
-rw-r--r-- | apps/plugins/pdbox/PDa/intern/sfread~.c | 576 |
1 files changed, 576 insertions, 0 deletions
diff --git a/apps/plugins/pdbox/PDa/intern/sfread~.c b/apps/plugins/pdbox/PDa/intern/sfread~.c new file mode 100644 index 0000000000..0980583fa3 --- /dev/null +++ b/apps/plugins/pdbox/PDa/intern/sfread~.c | |||
@@ -0,0 +1,576 @@ | |||
1 | #include <unistd.h> | ||
2 | #include <fcntl.h> | ||
3 | #include <errno.h> | ||
4 | #include <stdio.h> | ||
5 | #include <string.h> | ||
6 | #include <unistd.h> | ||
7 | #include <sys/mman.h> | ||
8 | #include <sys/stat.h> | ||
9 | |||
10 | #include <m_pd.h> | ||
11 | #include <m_fixed.h> | ||
12 | #include "g_canvas.h" | ||
13 | |||
14 | /* ------------------------ sfread~ ----------------------------- */ | ||
15 | |||
16 | #include "sformat.h" | ||
17 | |||
18 | static t_class *sfread_class; | ||
19 | |||
20 | |||
21 | typedef struct _sfread | ||
22 | { | ||
23 | t_object x_obj; | ||
24 | void* x_mapaddr; | ||
25 | int x_fd; | ||
26 | |||
27 | int x_play; | ||
28 | int x_channels; | ||
29 | long long x_size; | ||
30 | int x_loop; | ||
31 | t_time x_pos; | ||
32 | |||
33 | t_sample x_skip; | ||
34 | t_sample x_speed; | ||
35 | |||
36 | t_glist * x_glist; | ||
37 | t_outlet *x_bangout; | ||
38 | } t_sfread; | ||
39 | |||
40 | |||
41 | void sfread_open(t_sfread *x,t_symbol *filename) | ||
42 | { | ||
43 | struct stat fstate; | ||
44 | char fname[MAXPDSTRING]; | ||
45 | |||
46 | if (filename == &s_) { | ||
47 | post("sfread: open without filename"); | ||
48 | return; | ||
49 | } | ||
50 | |||
51 | canvas_makefilename(glist_getcanvas(x->x_glist), filename->s_name, | ||
52 | fname, MAXPDSTRING); | ||
53 | |||
54 | |||
55 | /* close the old file */ | ||
56 | |||
57 | if (x->x_mapaddr) munmap(x->x_mapaddr,x->x_size); | ||
58 | if (x->x_fd >= 0) close(x->x_fd); | ||
59 | |||
60 | if ((x->x_fd = open(fname,O_RDONLY)) < 0) | ||
61 | { | ||
62 | error("can't open %s",fname); | ||
63 | x->x_play = 0; | ||
64 | x->x_mapaddr = NULL; | ||
65 | return; | ||
66 | } | ||
67 | |||
68 | /* get the size */ | ||
69 | |||
70 | fstat(x->x_fd,&fstate); | ||
71 | x->x_size = fstate.st_size; | ||
72 | |||
73 | /* map the file into memory */ | ||
74 | |||
75 | if (!(x->x_mapaddr = mmap(NULL,x->x_size,PROT_READ,MAP_PRIVATE,x->x_fd,0))) | ||
76 | { | ||
77 | error("can't mmap %s",fname); | ||
78 | return; | ||
79 | } | ||
80 | } | ||
81 | |||
82 | #define MAX_CHANS 4 | ||
83 | |||
84 | static t_int *sfread_perform(t_int *w) | ||
85 | { | ||
86 | t_sfread* x = (t_sfread*)(w[1]); | ||
87 | short* buf = x->x_mapaddr; | ||
88 | t_time tmp; | ||
89 | int c = x->x_channels; | ||
90 | t_time pos = x->x_pos; | ||
91 | t_sample speed = x->x_speed; | ||
92 | t_time end = itofix(x->x_size/sizeof(short)/c); | ||
93 | int i,n; | ||
94 | t_sample* out[MAX_CHANS]; | ||
95 | |||
96 | for (i=0;i<c;i++) | ||
97 | out[i] = (t_sample *)(w[3+i]); | ||
98 | n = (int)(w[3+c]); | ||
99 | |||
100 | /* loop */ | ||
101 | |||
102 | if (pos > end) | ||
103 | pos = end; | ||
104 | |||
105 | if (pos + n*speed >= end) { // playing forward end | ||
106 | if (!x->x_loop) { | ||
107 | x->x_play=0; | ||
108 | } | ||
109 | pos = x->x_skip; | ||
110 | } | ||
111 | tmp = n*speed; | ||
112 | |||
113 | if (pos + n*speed <= 0) { // playing backwards end | ||
114 | if (!x->x_loop) { | ||
115 | x->x_play=0; | ||
116 | } | ||
117 | pos = end; | ||
118 | |||
119 | } | ||
120 | if (x->x_play && x->x_mapaddr) { | ||
121 | t_time aoff = fixtoi(pos)*c; | ||
122 | while (n--) { | ||
123 | long frac = (long long)((1<<fix1)-1)&pos; | ||
124 | |||
125 | for (i=0;i<c;i++) { | ||
126 | t_sample bs = *(buf+aoff+i)<<(fix1-16); | ||
127 | t_sample cs = *(buf+aoff+i+1)<<(fix1-16); | ||
128 | *out[i]++ = bs + mult((cs - bs),frac); | ||
129 | |||
130 | } | ||
131 | pos += speed; | ||
132 | aoff = fixtoi(pos)*c; | ||
133 | if (aoff > end) { | ||
134 | if (x->x_loop) pos = x->x_skip; | ||
135 | else break; | ||
136 | } | ||
137 | if (aoff < x->x_skip) { | ||
138 | if (x->x_loop) pos = end; | ||
139 | else break; | ||
140 | } | ||
141 | } | ||
142 | /* Fill with zero in case of end */ | ||
143 | n++; | ||
144 | while (n--) | ||
145 | for (i=0;i<c;i++) | ||
146 | *out[i]++ = 0; | ||
147 | } | ||
148 | else { | ||
149 | while (n--) { | ||
150 | for (i=0;i<c;i++) | ||
151 | *out[i]++ = 0.; | ||
152 | } | ||
153 | } | ||
154 | |||
155 | x->x_pos = pos; | ||
156 | return (w+c+4); | ||
157 | } | ||
158 | |||
159 | |||
160 | static void sfread_float(t_sfread *x, t_floatarg f) | ||
161 | { | ||
162 | int t = f; | ||
163 | if (t && x->x_mapaddr) { | ||
164 | x->x_play=1; | ||
165 | } | ||
166 | else { | ||
167 | x->x_play=0; | ||
168 | } | ||
169 | |||
170 | } | ||
171 | |||
172 | static void sfread_loop(t_sfread *x, t_floatarg f) | ||
173 | { | ||
174 | x->x_loop = f; | ||
175 | } | ||
176 | |||
177 | |||
178 | |||
179 | static void sfread_size(t_sfread* x) | ||
180 | { | ||
181 | t_atom a; | ||
182 | |||
183 | SETFLOAT(&a,x->x_size*0.5/x->x_channels); | ||
184 | outlet_list(x->x_bangout, gensym("size"),1,&a); | ||
185 | } | ||
186 | |||
187 | static void sfread_state(t_sfread* x) | ||
188 | { | ||
189 | t_atom a; | ||
190 | |||
191 | SETFLOAT(&a,x->x_play); | ||
192 | outlet_list(x->x_bangout, gensym("state"),1,&a); | ||
193 | } | ||
194 | |||
195 | |||
196 | |||
197 | |||
198 | static void sfread_bang(t_sfread* x) | ||
199 | { | ||
200 | x->x_pos = x->x_skip; | ||
201 | sfread_float(x,1.0); | ||
202 | } | ||
203 | |||
204 | |||
205 | static void sfread_dsp(t_sfread *x, t_signal **sp) | ||
206 | { | ||
207 | /* post("sfread: dsp"); */ | ||
208 | switch (x->x_channels) { | ||
209 | case 1: | ||
210 | dsp_add(sfread_perform, 4, x, sp[0]->s_vec, | ||
211 | sp[1]->s_vec, sp[0]->s_n); | ||
212 | break; | ||
213 | case 2: | ||
214 | dsp_add(sfread_perform, 5, x, sp[0]->s_vec, | ||
215 | sp[1]->s_vec,sp[2]->s_vec, sp[0]->s_n); | ||
216 | break; | ||
217 | case 4: | ||
218 | dsp_add(sfread_perform, 6, x, sp[0]->s_vec, | ||
219 | sp[1]->s_vec,sp[2]->s_vec, | ||
220 | sp[3]->s_vec,sp[4]->s_vec, | ||
221 | sp[0]->s_n); | ||
222 | break; | ||
223 | } | ||
224 | } | ||
225 | |||
226 | |||
227 | static void sfread_speed(t_sfread* x, t_floatarg f) | ||
228 | { | ||
229 | x->x_speed = ftofix(f); | ||
230 | } | ||
231 | |||
232 | static void sfread_offset(t_sfread* x, t_floatarg f) | ||
233 | { | ||
234 | x->x_pos = (int)f; | ||
235 | } | ||
236 | |||
237 | static void *sfread_new(t_floatarg chan,t_floatarg skip) | ||
238 | { | ||
239 | t_sfread *x = (t_sfread *)pd_new(sfread_class); | ||
240 | t_int c = chan; | ||
241 | |||
242 | x->x_glist = (t_glist*) canvas_getcurrent(); | ||
243 | |||
244 | if (c<1 || c > MAX_CHANS) c = 1; | ||
245 | inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_float, gensym("ft1")); | ||
246 | inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_float, gensym("ft2")); | ||
247 | |||
248 | |||
249 | x->x_fd = -1; | ||
250 | x->x_mapaddr = NULL; | ||
251 | |||
252 | x->x_size = 0; | ||
253 | x->x_loop = 0; | ||
254 | x->x_channels = c; | ||
255 | x->x_mapaddr=NULL; | ||
256 | x->x_pos = 0; | ||
257 | x->x_skip = 0; | ||
258 | x->x_speed = ftofix(1.0); | ||
259 | x->x_play = 0; | ||
260 | |||
261 | while (c--) { | ||
262 | outlet_new(&x->x_obj, gensym("signal")); | ||
263 | } | ||
264 | |||
265 | x->x_bangout = outlet_new(&x->x_obj, &s_float); | ||
266 | |||
267 | return (x); | ||
268 | } | ||
269 | |||
270 | void sfread_tilde_setup(void) | ||
271 | { | ||
272 | /* sfread */ | ||
273 | |||
274 | sfread_class = class_new(gensym("sfread~"), (t_newmethod)sfread_new, 0, | ||
275 | sizeof(t_sfread), 0,A_DEFFLOAT,A_DEFFLOAT,0); | ||
276 | class_addmethod(sfread_class, nullfn, gensym("signal"), 0); | ||
277 | class_addmethod(sfread_class, (t_method) sfread_dsp, gensym("dsp"), 0); | ||
278 | class_addmethod(sfread_class, (t_method) sfread_open, gensym("open"), A_SYMBOL,A_NULL); | ||
279 | class_addmethod(sfread_class, (t_method) sfread_size, gensym("size"), 0); | ||
280 | class_addmethod(sfread_class, (t_method) sfread_offset, gensym("ft1"), A_FLOAT, A_NULL); | ||
281 | class_addmethod(sfread_class, (t_method) sfread_speed, gensym("ft2"), A_FLOAT, A_NULL); | ||
282 | class_addmethod(sfread_class, (t_method) sfread_state, gensym("state"), 0); | ||
283 | class_addfloat(sfread_class, sfread_float); | ||
284 | class_addbang(sfread_class,sfread_bang); | ||
285 | class_addmethod(sfread_class,(t_method)sfread_loop,gensym("loop"),A_FLOAT,A_NULL); | ||
286 | |||
287 | } | ||
288 | |||
289 | #include <unistd.h> | ||
290 | #include <fcntl.h> | ||
291 | #include <errno.h> | ||
292 | #include <stdio.h> | ||
293 | #include <string.h> | ||
294 | #include <unistd.h> | ||
295 | #include <sys/mman.h> | ||
296 | #include <sys/stat.h> | ||
297 | |||
298 | #include <m_pd.h> | ||
299 | #include <m_fixed.h> | ||
300 | #include "g_canvas.h" | ||
301 | |||
302 | /* ------------------------ sfread~ ----------------------------- */ | ||
303 | |||
304 | #include "sformat.h" | ||
305 | |||
306 | static t_class *sfread_class; | ||
307 | |||
308 | |||
309 | typedef struct _sfread | ||
310 | { | ||
311 | t_object x_obj; | ||
312 | void* x_mapaddr; | ||
313 | int x_fd; | ||
314 | |||
315 | int x_play; | ||
316 | int x_channels; | ||
317 | long long x_size; | ||
318 | int x_loop; | ||
319 | t_time x_pos; | ||
320 | |||
321 | t_sample x_skip; | ||
322 | t_sample x_speed; | ||
323 | |||
324 | t_glist * x_glist; | ||
325 | t_outlet *x_bangout; | ||
326 | } t_sfread; | ||
327 | |||
328 | |||
329 | void sfread_open(t_sfread *x,t_symbol *filename) | ||
330 | { | ||
331 | struct stat fstate; | ||
332 | char fname[MAXPDSTRING]; | ||
333 | |||
334 | if (filename == &s_) { | ||
335 | post("sfread: open without filename"); | ||
336 | return; | ||
337 | } | ||
338 | |||
339 | canvas_makefilename(glist_getcanvas(x->x_glist), filename->s_name, | ||
340 | fname, MAXPDSTRING); | ||
341 | |||
342 | |||
343 | /* close the old file */ | ||
344 | |||
345 | if (x->x_mapaddr) munmap(x->x_mapaddr,x->x_size); | ||
346 | if (x->x_fd >= 0) close(x->x_fd); | ||
347 | |||
348 | if ((x->x_fd = open(fname,O_RDONLY)) < 0) | ||
349 | { | ||
350 | error("can't open %s",fname); | ||
351 | x->x_play = 0; | ||
352 | x->x_mapaddr = NULL; | ||
353 | return; | ||
354 | } | ||
355 | |||
356 | /* get the size */ | ||
357 | |||
358 | fstat(x->x_fd,&fstate); | ||
359 | x->x_size = fstate.st_size; | ||
360 | |||
361 | /* map the file into memory */ | ||
362 | |||
363 | if (!(x->x_mapaddr = mmap(NULL,x->x_size,PROT_READ,MAP_PRIVATE,x->x_fd,0))) | ||
364 | { | ||
365 | error("can't mmap %s",fname); | ||
366 | return; | ||
367 | } | ||
368 | } | ||
369 | |||
370 | #define MAX_CHANS 4 | ||
371 | |||
372 | static t_int *sfread_perform(t_int *w) | ||
373 | { | ||
374 | t_sfread* x = (t_sfread*)(w[1]); | ||
375 | short* buf = x->x_mapaddr; | ||
376 | t_time tmp; | ||
377 | int c = x->x_channels; | ||
378 | t_time pos = x->x_pos; | ||
379 | t_sample speed = x->x_speed; | ||
380 | t_time end = itofix(x->x_size/sizeof(short)/c); | ||
381 | int i,n; | ||
382 | t_sample* out[MAX_CHANS]; | ||
383 | |||
384 | for (i=0;i<c;i++) | ||
385 | out[i] = (t_sample *)(w[3+i]); | ||
386 | n = (int)(w[3+c]); | ||
387 | |||
388 | /* loop */ | ||
389 | |||
390 | if (pos > end) | ||
391 | pos = end; | ||
392 | |||
393 | if (pos + n*speed >= end) { // playing forward end | ||
394 | if (!x->x_loop) { | ||
395 | x->x_play=0; | ||
396 | } | ||
397 | pos = x->x_skip; | ||
398 | } | ||
399 | tmp = n*speed; | ||
400 | |||
401 | if (pos + n*speed <= 0) { // playing backwards end | ||
402 | if (!x->x_loop) { | ||
403 | x->x_play=0; | ||
404 | } | ||
405 | pos = end; | ||
406 | |||
407 | } | ||
408 | if (x->x_play && x->x_mapaddr) { | ||
409 | t_time aoff = fixtoi(pos)*c; | ||
410 | while (n--) { | ||
411 | long frac = (long long)((1<<fix1)-1)&pos; | ||
412 | |||
413 | for (i=0;i<c;i++) { | ||
414 | t_sample bs = *(buf+aoff+i)<<(fix1-16); | ||
415 | t_sample cs = *(buf+aoff+i+1)<<(fix1-16); | ||
416 | *out[i]++ = bs + mult((cs - bs),frac); | ||
417 | |||
418 | } | ||
419 | pos += speed; | ||
420 | aoff = fixtoi(pos)*c; | ||
421 | if (aoff > end) { | ||
422 | if (x->x_loop) pos = x->x_skip; | ||
423 | else break; | ||
424 | } | ||
425 | if (aoff < x->x_skip) { | ||
426 | if (x->x_loop) pos = end; | ||
427 | else break; | ||
428 | } | ||
429 | } | ||
430 | /* Fill with zero in case of end */ | ||
431 | n++; | ||
432 | while (n--) | ||
433 | for (i=0;i<c;i++) | ||
434 | *out[i]++ = 0; | ||
435 | } | ||
436 | else { | ||
437 | while (n--) { | ||
438 | for (i=0;i<c;i++) | ||
439 | *out[i]++ = 0.; | ||
440 | } | ||
441 | } | ||
442 | |||
443 | x->x_pos = pos; | ||
444 | return (w+c+4); | ||
445 | } | ||
446 | |||
447 | |||
448 | static void sfread_float(t_sfread *x, t_floatarg f) | ||
449 | { | ||
450 | int t = f; | ||
451 | if (t && x->x_mapaddr) { | ||
452 | x->x_play=1; | ||
453 | } | ||
454 | else { | ||
455 | x->x_play=0; | ||
456 | } | ||
457 | |||
458 | } | ||
459 | |||
460 | static void sfread_loop(t_sfread *x, t_floatarg f) | ||
461 | { | ||
462 | x->x_loop = f; | ||
463 | } | ||
464 | |||
465 | |||
466 | |||
467 | static void sfread_size(t_sfread* x) | ||
468 | { | ||
469 | t_atom a; | ||
470 | |||
471 | SETFLOAT(&a,x->x_size*0.5/x->x_channels); | ||
472 | outlet_list(x->x_bangout, gensym("size"),1,&a); | ||
473 | } | ||
474 | |||
475 | static void sfread_state(t_sfread* x) | ||
476 | { | ||
477 | t_atom a; | ||
478 | |||
479 | SETFLOAT(&a,x->x_play); | ||
480 | outlet_list(x->x_bangout, gensym("state"),1,&a); | ||
481 | } | ||
482 | |||
483 | |||
484 | |||
485 | |||
486 | static void sfread_bang(t_sfread* x) | ||
487 | { | ||
488 | x->x_pos = x->x_skip; | ||
489 | sfread_float(x,1.0); | ||
490 | } | ||
491 | |||
492 | |||
493 | static void sfread_dsp(t_sfread *x, t_signal **sp) | ||
494 | { | ||
495 | /* post("sfread: dsp"); */ | ||
496 | switch (x->x_channels) { | ||
497 | case 1: | ||
498 | dsp_add(sfread_perform, 4, x, sp[0]->s_vec, | ||
499 | sp[1]->s_vec, sp[0]->s_n); | ||
500 | break; | ||
501 | case 2: | ||
502 | dsp_add(sfread_perform, 5, x, sp[0]->s_vec, | ||
503 | sp[1]->s_vec,sp[2]->s_vec, sp[0]->s_n); | ||
504 | break; | ||
505 | case 4: | ||
506 | dsp_add(sfread_perform, 6, x, sp[0]->s_vec, | ||
507 | sp[1]->s_vec,sp[2]->s_vec, | ||
508 | sp[3]->s_vec,sp[4]->s_vec, | ||
509 | sp[0]->s_n); | ||
510 | break; | ||
511 | } | ||
512 | } | ||
513 | |||
514 | |||
515 | static void sfread_speed(t_sfread* x, t_floatarg f) | ||
516 | { | ||
517 | x->x_speed = ftofix(f); | ||
518 | } | ||
519 | |||
520 | static void sfread_offset(t_sfread* x, t_floatarg f) | ||
521 | { | ||
522 | x->x_pos = (int)f; | ||
523 | } | ||
524 | |||
525 | static void *sfread_new(t_floatarg chan,t_floatarg skip) | ||
526 | { | ||
527 | t_sfread *x = (t_sfread *)pd_new(sfread_class); | ||
528 | t_int c = chan; | ||
529 | |||
530 | x->x_glist = (t_glist*) canvas_getcurrent(); | ||
531 | |||
532 | if (c<1 || c > MAX_CHANS) c = 1; | ||
533 | inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_float, gensym("ft1")); | ||
534 | inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_float, gensym("ft2")); | ||
535 | |||
536 | |||
537 | x->x_fd = -1; | ||
538 | x->x_mapaddr = NULL; | ||
539 | |||
540 | x->x_size = 0; | ||
541 | x->x_loop = 0; | ||
542 | x->x_channels = c; | ||
543 | x->x_mapaddr=NULL; | ||
544 | x->x_pos = 0; | ||
545 | x->x_skip = 0; | ||
546 | x->x_speed = ftofix(1.0); | ||
547 | x->x_play = 0; | ||
548 | |||
549 | while (c--) { | ||
550 | outlet_new(&x->x_obj, gensym("signal")); | ||
551 | } | ||
552 | |||
553 | x->x_bangout = outlet_new(&x->x_obj, &s_float); | ||
554 | |||
555 | return (x); | ||
556 | } | ||
557 | |||
558 | void sfread_tilde_setup(void) | ||
559 | { | ||
560 | /* sfread */ | ||
561 | |||
562 | sfread_class = class_new(gensym("sfread~"), (t_newmethod)sfread_new, 0, | ||
563 | sizeof(t_sfread), 0,A_DEFFLOAT,A_DEFFLOAT,0); | ||
564 | class_addmethod(sfread_class, nullfn, gensym("signal"), 0); | ||
565 | class_addmethod(sfread_class, (t_method) sfread_dsp, gensym("dsp"), 0); | ||
566 | class_addmethod(sfread_class, (t_method) sfread_open, gensym("open"), A_SYMBOL,A_NULL); | ||
567 | class_addmethod(sfread_class, (t_method) sfread_size, gensym("size"), 0); | ||
568 | class_addmethod(sfread_class, (t_method) sfread_offset, gensym("ft1"), A_FLOAT, A_NULL); | ||
569 | class_addmethod(sfread_class, (t_method) sfread_speed, gensym("ft2"), A_FLOAT, A_NULL); | ||
570 | class_addmethod(sfread_class, (t_method) sfread_state, gensym("state"), 0); | ||
571 | class_addfloat(sfread_class, sfread_float); | ||
572 | class_addbang(sfread_class,sfread_bang); | ||
573 | class_addmethod(sfread_class,(t_method)sfread_loop,gensym("loop"),A_FLOAT,A_NULL); | ||
574 | |||
575 | } | ||
576 | |||