root/ocaml-remix/trunk/FB_impl.c

Revision 529, 6.4 kB (checked in by shans, 4 years ago)

Replacing sound implementation - WAS ocaml int arrays, IS native float
arrays. This has not yet been completely been debugged!

Line 
1 #include <caml/alloc.h>
2 #include <caml/callback.h>
3 #include <caml/fail.h>
4 #include <caml/memory.h>
5 #include <caml/misc.h>
6 #include <caml/mlvalues.h>
7
8 #include <string.h>
9 #include <stdlib.h>
10
11 static void finalize_buffer(value block) {
12   float *data = (float *)Field(block, 1);
13   free(data);
14 }
15
16 #define RETURN_NEW_BUFFER(data)                     \
17   CAMLlocal1(block);                                \
18   block = alloc_final(2, &finalize_buffer, 1, 100); \
19   Field(block, 1) = (value)data;                    \
20   CAMLreturn(block)
21
22 #define POINTER_FROM_BUFFER(buffer) ((float *)Field(buffer, 1))
23
24 CAMLprim c_FB_new_buffer(value ml_length, value ml_channels) {
25
26   CAMLparam2(ml_length, ml_channels);
27
28   int length = Int_val(ml_length);
29   int channels = Int_val(ml_channels);
30
31   float *data = calloc(sizeof(float), length * channels);
32
33   RETURN_NEW_BUFFER(data);
34  
35 }
36
37 CAMLprim c_FB_free_buffer(value ml_buffer) {
38
39   CAMLparam1(ml_buffer);
40   finalize_buffer(ml_buffer);
41
42   CAMLreturn(Val_unit);
43 };
44
45 CAMLprim c_FB_fill_buffer(value ml_buf, value ml_length, value ml_channels,
46                                                           value ml_callback) {
47
48   CAMLparam4(ml_buf, ml_length, ml_channels, ml_callback);
49
50   float *buffer = POINTER_FROM_BUFFER(ml_buf);
51   int length = Int_val(ml_length);
52   int channels = Int_val(ml_channels);
53   int i;
54   int j;
55  
56   for (i = 0; i < length; i++) {
57     buffer[i*channels] = (float)(Double_val(callback(ml_callback, Val_int(i))));
58     for (j = 1; j < channels; j++) {
59       buffer[i*channels+j] = buffer[i*channels];
60     }
61   }
62
63   CAMLreturn(Val_unit);
64  
65 }
66
67 CAMLprim c_FB_fill_buffer_from_buffer(value ml_buf, value ml_size,
68     value ml_fillbuf, value ml_fillsize, value ml_offset) {
69
70   CAMLparam5(ml_buf, ml_size, ml_fillbuf, ml_fillsize, ml_offset);
71
72   float *buffer = POINTER_FROM_BUFFER(ml_buf);
73   float *from = POINTER_FROM_BUFFER(ml_fillbuf);
74   int size = Int_val(ml_size);
75   int from_size = Int_val(ml_fillsize);
76   int from_offset = Int_val(ml_offset);
77   int pos;
78  
79   /* offset first */
80   if (from_offset > 0) {
81     memcpy(buffer, from + from_offset,
82           (from_size - from_offset) * sizeof(float));
83   }
84
85   /* whole copies */
86   pos = from_offset;
87   while ((pos + from_size) < size) {
88     memcpy(buffer + pos, from, from_size * sizeof(float));
89     pos += from_size;
90   }
91
92   /* last bit */
93   if (pos < size) {
94     memcpy(buffer + pos, from, (size - pos) * sizeof(float));
95   }
96
97   CAMLreturn(Val_unit);
98  
99 }
100
101 CAMLprim c_FB_add_buffers(value ml_bufa, value ml_bufb, value ml_size) {
102
103   CAMLparam3(ml_bufa, ml_bufb, ml_size);
104
105   int size = Int_val(ml_size);
106   float *bufa = POINTER_FROM_BUFFER(ml_bufa);
107   float *bufb = POINTER_FROM_BUFFER(ml_bufb);
108   float *data = malloc(sizeof(float) * size);
109   int i;
110  
111   for (i = 0; i < size; i++) {
112     data[i] = bufa[i] + bufb[i];
113   }
114
115   RETURN_NEW_BUFFER(data);
116
117 }
118
119 CAMLprim c_FB_mult_buffers(value ml_bufa, value ml_bufb, value ml_size) {
120
121   CAMLparam3(ml_bufa, ml_bufb, ml_size);
122
123   int size = Int_val(ml_size);
124   float *bufa = POINTER_FROM_BUFFER(ml_bufa);
125   float *bufb = POINTER_FROM_BUFFER(ml_bufb);
126   float *data = malloc(sizeof(float) * size);
127   int i;
128
129   for (i = 0; i < size; i++) {
130     data[i] = bufa[i] * bufb[i];
131   }
132
133   RETURN_NEW_BUFFER(data);
134
135 }
136
137 CAMLprim c_FB_transparency(value ml_bufa, value ml_bufb, value ml_trans, value
138     ml_size) {
139
140   CAMLparam4(ml_bufa, ml_bufb, ml_trans, ml_size);
141
142   int size = Int_val(ml_size);
143   float *bufa = POINTER_FROM_BUFFER(ml_bufa);
144   float *bufb = POINTER_FROM_BUFFER(ml_bufb);
145   float *trans = POINTER_FROM_BUFFER(ml_trans);
146   float *data = malloc(sizeof(float) * size);
147   int i;
148
149   for (i = 0; i < size; i++) {
150     data[i] = bufa[i] * trans[i] + bufb[i] * (1 - trans[i]);
151   }
152
153   RETURN_NEW_BUFFER(data);
154 }
155
156 CAMLprim c_FB_at(value ml_buffer, value ml_position) {
157
158   CAMLparam2(ml_buffer, ml_position);
159
160   float *buffer = POINTER_FROM_BUFFER(ml_buffer);
161   int position = Int_val(ml_position);
162
163   CAMLreturn(copy_double(buffer[position]));
164
165 }
166
167 CAMLprim c_FB_short_at(value ml_buffer, value ml_position) {
168
169   CAMLparam2(ml_buffer, ml_position);
170
171   float *buffer = POINTER_FROM_BUFFER(ml_buffer);
172   int position = Int_val(ml_position);
173
174   CAMLreturn(Val_int((int)(buffer[position]*32767)));
175
176 }
177
178 CAMLprim c_FB_split_into_channels(value ml_buffer, value ml_buffers, value ml_length) {
179
180   CAMLparam3(ml_buffer, ml_buffers, ml_length);
181
182   float *buffer = POINTER_FROM_BUFFER(ml_buffer);
183   int channels = Wosize_val(ml_buffers);
184   int length = Int_val(ml_length);
185   int i;
186
187   float **odata = malloc(channels * sizeof(float *));
188
189   for (i = 0; i < channels; i++) {
190     value b = (value)Field(ml_buffers, i);
191     odata[i] = POINTER_FROM_BUFFER(b);
192   }
193
194   length *= channels;
195
196   for (i = 0; i < length; i++) {
197     odata[i % channels][i / channels] = buffer[i];
198   }
199
200   free(odata);
201
202   CAMLreturn(Val_unit);
203
204 }
205
206 CAMLprim c_FB_merge_channels(value ml_buffers, value ml_buffer, value ml_length) {
207  
208   CAMLparam3(ml_buffers, ml_buffer, ml_length);
209  
210   int channels = Wosize_val(ml_buffers);
211   int length = Int_val(ml_length);
212   int i;
213
214   float **idata = malloc(channels * sizeof(float *));
215   float *odata = POINTER_FROM_BUFFER(ml_buffer);
216
217   for (i = 0; i < channels; i++) {
218     value b = (value)Field(ml_buffers, i);
219     idata[i] = POINTER_FROM_BUFFER(b);
220   }
221
222   length *= channels;
223
224   for(i = 0; i < length; i++) {
225     odata[i] = idata[i % channels][i / channels];
226   }
227
228   free(idata);
229
230   CAMLreturn(Val_unit);
231
232 }
233
234 CAMLprim c_FB_average(value ml_buffers, value ml_size) {
235
236   CAMLparam2(ml_buffers, ml_size);
237   int num_buffers = Wosize_val(ml_buffers);
238   int size = Int_val(ml_size);
239   int i, j;
240
241   float **idata = malloc(num_buffers * sizeof(float *));
242   float *odata = malloc(size * sizeof(float));
243
244   for (i = 0; i < num_buffers; i++) {
245     value b = (value)Field(ml_buffers, i);
246     idata[i] = POINTER_FROM_BUFFER(b);
247   }
248
249   for (i = 0; i < size; i++) {
250     odata[i] = 0;
251     for (j = 0; j < num_buffers; j++) {
252       odata[i] += idata[j][i];
253     }
254     odata[i] /= num_buffers;
255   }
256
257   free(idata);
258
259   RETURN_NEW_BUFFER(odata);
260
261 }
262
263 CAMLprim c_FB_blit(value ml_src, value ml_srcpos, value ml_dst, value ml_dstpos,
264                       value ml_length) {
265
266   CAMLparam5(ml_src, ml_srcpos, ml_dst, ml_dstpos, ml_length);
267
268   float *src = POINTER_FROM_BUFFER(ml_src);
269   float *dst = POINTER_FROM_BUFFER(ml_dst);
270   int srcpos = Int_val(ml_srcpos);
271   int dstpos = Int_val(ml_dstpos);
272   int length = Int_val(ml_length);
273
274   memcpy(dst + dstpos, src + srcpos, length * sizeof(float));
275
276   CAMLreturn(Val_unit);
277
278 }
Note: See TracBrowser for help on using the browser.