Fix pdbox makefile to actually take part in dependency generation
[kugel-rb.git] / apps / plugins / pdbox / PDa / intern / sfread~.c
blob8a5148a3f35cd7bebda82d3b5f223af17c0d604e
1 #ifdef ROCKBOX
2 #include "plugin.h"
3 #include "../../pdbox.h"
4 #else /* ROCKBOX */
5 #include <unistd.h>
6 #include <fcntl.h>
7 #include <errno.h>
8 #include <stdio.h>
9 #include <string.h>
10 #include <unistd.h>
11 #include <sys/mman.h>
12 #include <sys/stat.h>
13 #endif /* ROCKBOX */
15 #include "../src/m_pd.h"
16 #include <../src/m_fixed.h>
17 #include "../src/g_canvas.h"
19 /* ------------------------ sfread~ ----------------------------- */
21 #include "sformat.h"
23 static t_class *sfread_class;
26 typedef struct _sfread
28 t_object x_obj;
29 void* x_mapaddr;
30 int x_fd;
32 int x_play;
33 int x_channels;
34 long long x_size;
35 int x_loop;
36 t_time x_pos;
38 t_sample x_skip;
39 t_sample x_speed;
41 t_glist * x_glist;
42 t_outlet *x_bangout;
43 } t_sfread;
46 void sfread_open(t_sfread *x,t_symbol *filename)
48 #ifndef ROCKBOX
49 struct stat fstate;
50 #endif
51 char fname[MAXPDSTRING];
53 if (filename == &s_) {
54 post("sfread: open without filename");
55 return;
58 canvas_makefilename(glist_getcanvas(x->x_glist), filename->s_name,
59 fname, MAXPDSTRING);
62 /* close the old file */
64 #ifdef ROCKBOX
65 if (x->x_mapaddr) freebytes(x->x_mapaddr, x->x_size);
66 #else
67 if (x->x_mapaddr) munmap(x->x_mapaddr,x->x_size);
68 #endif
69 if (x->x_fd >= 0) close(x->x_fd);
71 if ((x->x_fd = open(fname,O_RDONLY)) < 0)
73 error("can't open %s",fname);
74 x->x_play = 0;
75 x->x_mapaddr = NULL;
76 return;
79 /* get the size */
80 #ifdef ROCKBOX
81 x->x_size = rb->filesize(x->x_fd);
82 #else
83 fstat(x->x_fd,&fstate);
84 x->x_size = fstate.st_size;
85 #endif
87 /* map the file into memory */
89 #ifdef ROCKBOX
90 x->x_mapaddr = getbytes(x->x_size);
91 if (!x->x_mapaddr)
93 error("can't mmap %s",fname);
94 return;
96 int r = read(x->x_fd, x->x_mapaddr, x->x_size);
97 if (r != x->x_size)
99 error("can't mmap %s",fname);
100 return;
102 #else
103 if (!(x->x_mapaddr = mmap(NULL,x->x_size,PROT_READ,MAP_PRIVATE,x->x_fd,0)))
105 error("can't mmap %s",fname);
106 return;
108 #endif
111 #define MAX_CHANS 4
113 static t_int *sfread_perform(t_int *w)
115 t_sfread* x = (t_sfread*)(w[1]);
116 short* buf = x->x_mapaddr;
117 t_time tmp;
118 int c = x->x_channels;
119 t_time pos = x->x_pos;
120 t_sample speed = x->x_speed;
121 t_time end = itofix(x->x_size/sizeof(short)/c);
122 int i,n;
123 t_sample* out[MAX_CHANS];
125 for (i=0;i<c;i++)
126 out[i] = (t_sample *)(w[3+i]);
127 n = (int)(w[3+c]);
129 /* loop */
131 if (pos > end)
132 pos = end;
134 if (pos + n*speed >= end) { // playing forward end
135 if (!x->x_loop) {
136 x->x_play=0;
138 pos = x->x_skip;
140 tmp = n*speed;
142 if (pos + n*speed <= 0) { // playing backwards end
143 if (!x->x_loop) {
144 x->x_play=0;
146 pos = end;
149 if (x->x_play && x->x_mapaddr) {
150 t_time aoff = fixtoi(pos)*c;
151 while (n--) {
152 long frac = (long long)((1<<fix1)-1)&pos;
154 for (i=0;i<c;i++) {
155 t_sample bs = *(buf+aoff+i)<<(fix1-16);
156 t_sample cs = *(buf+aoff+i+1)<<(fix1-16);
157 *out[i]++ = bs + mult((cs - bs),frac);
160 pos += speed;
161 aoff = fixtoi(pos)*c;
162 if (aoff > end) {
163 if (x->x_loop) pos = x->x_skip;
164 else break;
166 if (aoff < x->x_skip) {
167 if (x->x_loop) pos = end;
168 else break;
171 /* Fill with zero in case of end */
172 n++;
173 while (n--)
174 for (i=0;i<c;i++)
175 *out[i]++ = 0;
177 else {
178 while (n--) {
179 for (i=0;i<c;i++)
180 *out[i]++ = 0.;
184 x->x_pos = pos;
185 return (w+c+4);
189 static void sfread_float(t_sfread *x, t_floatarg f)
191 int t = f;
192 if (t && x->x_mapaddr) {
193 x->x_play=1;
195 else {
196 x->x_play=0;
201 static void sfread_loop(t_sfread *x, t_floatarg f)
203 x->x_loop = f;
208 static void sfread_size(t_sfread* x)
210 t_atom a;
212 SETFLOAT(&a,x->x_size*0.5/x->x_channels);
213 outlet_list(x->x_bangout, gensym("size"),1,&a);
216 static void sfread_state(t_sfread* x)
218 t_atom a;
220 SETFLOAT(&a,x->x_play);
221 outlet_list(x->x_bangout, gensym("state"),1,&a);
227 static void sfread_bang(t_sfread* x)
229 x->x_pos = x->x_skip;
230 sfread_float(x,1.0);
234 static void sfread_dsp(t_sfread *x, t_signal **sp)
236 /* post("sfread: dsp"); */
237 switch (x->x_channels) {
238 case 1:
239 dsp_add(sfread_perform, 4, x, sp[0]->s_vec,
240 sp[1]->s_vec, sp[0]->s_n);
241 break;
242 case 2:
243 dsp_add(sfread_perform, 5, x, sp[0]->s_vec,
244 sp[1]->s_vec,sp[2]->s_vec, sp[0]->s_n);
245 break;
246 case 4:
247 dsp_add(sfread_perform, 6, x, sp[0]->s_vec,
248 sp[1]->s_vec,sp[2]->s_vec,
249 sp[3]->s_vec,sp[4]->s_vec,
250 sp[0]->s_n);
251 break;
256 static void sfread_speed(t_sfread* x, t_floatarg f)
258 x->x_speed = ftofix(f);
261 static void sfread_offset(t_sfread* x, t_floatarg f)
263 x->x_pos = (int)f;
266 static void *sfread_new(t_floatarg chan,t_floatarg skip)
268 #ifdef ROCKBOX
269 (void) skip;
270 #endif
271 t_sfread *x = (t_sfread *)pd_new(sfread_class);
272 t_int c = chan;
274 x->x_glist = (t_glist*) canvas_getcurrent();
276 if (c<1 || c > MAX_CHANS) c = 1;
277 inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_float, gensym("ft1"));
278 inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_float, gensym("ft2"));
281 x->x_fd = -1;
282 x->x_mapaddr = NULL;
284 x->x_size = 0;
285 x->x_loop = 0;
286 x->x_channels = c;
287 x->x_mapaddr=NULL;
288 x->x_pos = 0;
289 x->x_skip = 0;
290 x->x_speed = ftofix(1.0);
291 x->x_play = 0;
293 while (c--) {
294 outlet_new(&x->x_obj, gensym("signal"));
297 x->x_bangout = outlet_new(&x->x_obj, &s_float);
299 return (x);
302 void sfread_tilde_setup(void)
304 /* sfread */
306 sfread_class = class_new(gensym("sfread~"), (t_newmethod)sfread_new, 0,
307 sizeof(t_sfread), 0,A_DEFFLOAT,A_DEFFLOAT,0);
308 class_addmethod(sfread_class, nullfn, gensym("signal"), 0);
309 class_addmethod(sfread_class, (t_method) sfread_dsp, gensym("dsp"), 0);
310 class_addmethod(sfread_class, (t_method) sfread_open, gensym("open"), A_SYMBOL,A_NULL);
311 class_addmethod(sfread_class, (t_method) sfread_size, gensym("size"), 0);
312 class_addmethod(sfread_class, (t_method) sfread_offset, gensym("ft1"), A_FLOAT, A_NULL);
313 class_addmethod(sfread_class, (t_method) sfread_speed, gensym("ft2"), A_FLOAT, A_NULL);
314 class_addmethod(sfread_class, (t_method) sfread_state, gensym("state"), 0);
315 class_addfloat(sfread_class, sfread_float);
316 class_addbang(sfread_class,sfread_bang);
317 class_addmethod(sfread_class,(t_method)sfread_loop,gensym("loop"),A_FLOAT,A_NULL);