** Warning: Cannot open xref database.
1 /*
2 Copyright (C) 2000 Paul Davis
3
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 2 of the License, or
7 (at your option) any later version.
8
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
13
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, write to the Free Software
16 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
17
18 $Id: memops.c,v 1.6 2004/01/04 17:55:47 joq Exp $
19 */
20
21 #define _ISOC9X_SOURCE 1
22 #define _ISOC99_SOURCE 1
23
24 #define __USE_ISOC9X 1
25 #define __USE_ISOC99 1
26
27 #include <stdio.h>
28 #include <string.h>
29 #include <math.h>
30 #include <memory.h>
31 #include <stdlib.h>
32 #include <limits.h>
33
34 #include "memops.h"
35
36 #define SAMPLE_MAX_24BIT 8388608.0f
37 #define SAMPLE_MAX_16BIT 32768.0f
38
39 #define f_round(f) lrintf(f)
40
41 /* Linear Congruential noise generator. From the music-dsp list
42 * less random than rand(), but good enough and 10x faster */
43 inline unsigned int fast_rand();
44
45 inline unsigned int fast_rand() {
46 static unsigned int seed = 22222;
47 seed = (seed * 96314165) + 907633515;
48
49 return seed;
50 }
51
52 void sample_move_d32u24_sS (char *dst, jack_default_audio_sample_t *src, unsigned long nsamples, unsigned long dst_skip, dither_state_t *state)
53
54 {
55 long long y;
56
57 while (nsamples--) {
58 y = (long long)(*src * SAMPLE_MAX_24BIT) << 8;
59 if (y > INT_MAX) {
60 *((int *) dst) = INT_MAX;
61 } else if (y < INT_MIN) {
62 *((int *) dst) = INT_MIN;
63 } else {
64 *((int *) dst) = (int)y;
65 }
66 dst += dst_skip;
67 src++;
68 }
69 }
70
71 void sample_move_dS_s32u24 (jack_default_audio_sample_t *dst, char *src, unsigned long nsamples, unsigned long src_skip)
72 {
73 /* ALERT: signed sign-extension portability !!! */
74
75 while (nsamples--) {
76 *dst = (*((int *) src) >> 8) / SAMPLE_MAX_24BIT;
77 dst++;
78 src += src_skip;
79 }
80 }
81
82 void sample_move_dither_rect_d32u24_sS (char *dst, jack_default_audio_sample_t *src, unsigned long nsamples, unsigned long dst_skip, dither_state_t *state)
83
84 {
85 /* ALERT: signed sign-extension portability !!! */
86 jack_default_audio_sample_t x;
87 long long y;
88
89 while (nsamples--) {
90 x = *src * SAMPLE_MAX_16BIT;
91 x -= (float)fast_rand() / (float)INT_MAX;
92 y = (long long)f_round(x);
93 y <<= 16;
94 if (y > INT_MAX) {
95 *((int *) dst) = INT_MAX;
96 } else if (y < INT_MIN) {
97 *((int *) dst) = INT_MIN;
98 } else {
99 *((int *) dst) = (int)y;
100 }
101 dst += dst_skip;
102 src++;
103 }
104 }
105
106 void sample_move_dither_tri_d32u24_sS (char *dst, jack_default_audio_sample_t *src, unsigned long nsamples, unsigned long dst_skip, dither_state_t *state)
107
108 {
109 jack_default_audio_sample_t x;
110 float r;
111 float rm1 = state->rm1;
112 long long y;
113
114 while (nsamples--) {
115 x = *src * (float)SAMPLE_MAX_16BIT;
116 r = 2.0f * (float)fast_rand() / (float)INT_MAX - 1.0f;
117 x += r - rm1;
118 rm1 = r;
119 y = (long long)f_round(x);
120 y <<= 16;
121
122 if (y > INT_MAX) {
123 *((int *) dst) = INT_MAX;
124 } else if (y < INT_MIN) {
125 *((int *) dst) = INT_MIN;
126 } else {
127 *((int *) dst) = (int)y;
128 }
129
130 dst += dst_skip;
131 src++;
132 }
133 state->rm1 = rm1;
134 }
135
136 void sample_move_dither_shaped_d32u24_sS (char *dst, jack_default_audio_sample_t *src, unsigned long nsamples, unsigned long dst_skip, dither_state_t *state)
137
138 {
139 jack_default_audio_sample_t x;
140 jack_default_audio_sample_t xe; /* the innput sample - filtered error */
141 jack_default_audio_sample_t xp; /* x' */
142 float r;
143 float rm1 = state->rm1;
144 unsigned int idx = state->idx;
145 long long y;
146
147 while (nsamples--) {
148 x = *src * (float)SAMPLE_MAX_16BIT;
149 r = 2.0f * (float)fast_rand() / (float)INT_MAX - 1.0f;
150 /* Filter the error with Lipshitz's minimally audible FIR:
151 [2.033 -2.165 1.959 -1.590 0.6149] */
152 xe = x
153 - state->e[idx] * 2.033f
154 + state->e[(idx - 1) & DITHER_BUF_MASK] * 2.165f
155 - state->e[(idx - 2) & DITHER_BUF_MASK] * 1.959f
156 + state->e[(idx - 3) & DITHER_BUF_MASK] * 1.590f
157 - state->e[(idx - 4) & DITHER_BUF_MASK] * 0.6149f;
158 xp = xe + r - rm1;
159 rm1 = r;
160
161 /* This could be some inline asm on x86 */
162 y = (long long)f_round(xp);
163
164 /* Intrinsic z^-1 delay */
165 idx = (idx + 1) & DITHER_BUF_MASK;
166 state->e[idx] = y - xe;
167
168 y <<= 16;
169
170 if (y > INT_MAX) {
171 *((int *) dst) = INT_MAX;
172 } else if (y < INT_MIN) {
173 *((int *) dst) = INT_MIN;
174 } else {
175 *((int *) dst) = y;
176 }
177 dst += dst_skip;
178 src++;
179 }
180 state->rm1 = rm1;
181 state->idx = idx;
182 }
183
184 void sample_move_d24_sS (char *dst, jack_default_audio_sample_t *src, unsigned long nsamples, unsigned long dst_skip, dither_state_t *state)
185
186 {
187 long long y;
188
189 while (nsamples--) {
190 y = (long long)(*src * SAMPLE_MAX_24BIT);
191
192 if (y > (INT_MAX >> 8 )) {
193 y = (INT_MAX >> 8);
194 } else if (y < (INT_MIN >> 8 )) {
195 y = (INT_MIN >> 8 );
196 }
197 #if __BYTE_ORDER == __LITTLE_ENDIAN
198 memcpy (dst, &y, 3);
199 #elif __BYTE_ORDER == __BIG_ENDIAN
200 memcpy (dst, (char *)&y + 5, 3);
201 #endif
202 dst += dst_skip;
203 src++;
204 }
205 }
206
207 void sample_move_dS_s24 (jack_default_audio_sample_t *dst, char *src, unsigned long nsamples, unsigned long src_skip)
208 {
209 /* ALERT: signed sign-extension portability !!! */
210
211 while (nsamples--) {
212 int x;
213 #if __BYTE_ORDER == __LITTLE_ENDIAN
214 memcpy((char*)&x + 1, src, 3);
215 #elif __BYTE_ORDER == __BIG_ENDIAN
216 memcpy(&x, src, 3);
217 #endif
218 x >>= 8;
219 *dst = x / SAMPLE_MAX_24BIT;
220 dst++;
221 src += src_skip;
222 }
223 }
224
225 void sample_move_dither_rect_d24_sS (char *dst, jack_default_audio_sample_t *src, unsigned long nsamples, unsigned long dst_skip, dither_state_t *state)
226
227 {
228 /* ALERT: signed sign-extension portability !!! */
229 jack_default_audio_sample_t x;
230 long long y;
231
232 while (nsamples--) {
233 x = *src * SAMPLE_MAX_16BIT;
234 x -= (float)fast_rand() / (float)INT_MAX;
235 y = (long long)f_round(x);
236
237 y <<= 8;
238
239 if (y > (INT_MAX >> 8)) {
240 y = (INT_MAX >> 8);
241 } else if (y < (INT_MIN >> 8)) {
242 y = (INT_MIN >> 8);
243 }
244 #if __BYTE_ORDER == __LITTLE_ENDIAN
245 memcpy (dst, &y, 3);
246 #elif __BYTE_ORDER == __BIG_ENDIAN
247 memcpy (dst, (char *)&y + 5, 3);
248 #endif
249
250 dst += dst_skip;
251 src++;
252 }
253 }
254
255 void sample_move_dither_tri_d24_sS (char *dst, jack_default_audio_sample_t *src, unsigned long nsamples, unsigned long dst_skip, dither_state_t *state)
256
257 {
258 jack_default_audio_sample_t x;
259 float r;
260 float rm1 = state->rm1;
261 long long y;
262
263 while (nsamples--) {
264 x = *src * (float)SAMPLE_MAX_16BIT;
265 r = 2.0f * (float)fast_rand() / (float)INT_MAX - 1.0f;
266 x += r - rm1;
267 rm1 = r;
268 y = (long long)f_round(x);
269
270 y <<= 8;
271
272 if (y > (INT_MAX >> 8)) {
273 y = (INT_MAX >> 8);
274 } else if (y < (INT_MIN >> 8)) {
275 y = (INT_MIN >> 8);
276 }
277 #if __BYTE_ORDER == __LITTLE_ENDIAN
278 memcpy (dst, &y, 3);
279 #elif __BYTE_ORDER == __BIG_ENDIAN
280 memcpy (dst, (char *)&y + 5, 3);
281 #endif
282
283 dst += dst_skip;
284 src++;
285 }
286 state->rm1 = rm1;
287 }
288
289 void sample_move_dither_shaped_d24_sS (char *dst, jack_default_audio_sample_t *src, unsigned long nsamples, unsigned long dst_skip, dither_state_t *state)
290
291 {
292 jack_default_audio_sample_t x;
293 jack_default_audio_sample_t xe; /* the innput sample - filtered error */
294 jack_default_audio_sample_t xp; /* x' */
295 float r;
296 float rm1 = state->rm1;
297 unsigned int idx = state->idx;
298 long long y;
299
300 while (nsamples--) {
301 x = *src * (float)SAMPLE_MAX_16BIT;
302 r = 2.0f * (float)fast_rand() / (float)INT_MAX - 1.0f;
303 /* Filter the error with Lipshitz's minimally audible FIR:
304 [2.033 -2.165 1.959 -1.590 0.6149] */
305 xe = x
306 - state->e[idx] * 2.033f
307 + state->e[(idx - 1) & DITHER_BUF_MASK] * 2.165f
308 - state->e[(idx - 2) & DITHER_BUF_MASK] * 1.959f
309 + state->e[(idx - 3) & DITHER_BUF_MASK] * 1.590f
310 - state->e[(idx - 4) & DITHER_BUF_MASK] * 0.6149f;
311 xp = xe + r - rm1;
312 rm1 = r;
313
314 /* This could be some inline asm on x86 */
315 y = (long long)f_round(xp);
316
317 /* Intrinsic z^-1 delay */
318 idx = (idx + 1) & DITHER_BUF_MASK;
319 state->e[idx] = y - xe;
320
321 y <<= 8;
322
323 if (y > (INT_MAX >> 8)) {
324 y = (INT_MAX >> 8);
325 } else if (y < (INT_MIN >> 8)) {
326 y = (INT_MIN >> 8);
327 }
328 #if __BYTE_ORDER == __LITTLE_ENDIAN
329 memcpy (dst, &y, 3);
330 #elif __BYTE_ORDER == __BIG_ENDIAN
331 memcpy (dst, (char *)&y + 5, 3);
332 #endif
333
334 dst += dst_skip;
335 src++;
336 }
337 state->rm1 = rm1;
338 state->idx = idx;
339 }
340
341 void sample_move_d16_sS (char *dst, jack_default_audio_sample_t *src, unsigned long nsamples, unsigned long dst_skip, dither_state_t *state)
342
343 {
344 jack_default_audio_sample_t val;
345
346 /* ALERT: signed sign-extension portability !!! */
347
348 while (nsamples--) {
349 val = *src;
350 if (val > 1.0f) {
351 *((short *)dst) = SHRT_MAX;
352 } else if (val < -1.0f) {
353 *((short *)dst) = SHRT_MIN;
354 } else {
355 *((short *) dst) = (short) f_round(val * SAMPLE_MAX_16BIT);
356 }
357 dst += dst_skip;
358 src++;
359 }
360 }
361
362 void sample_move_dither_rect_d16_sS (char *dst, jack_default_audio_sample_t *src, unsigned long nsamples, unsigned long dst_skip, dither_state_t *state)
363
364 {
365 jack_default_audio_sample_t val;
366 int tmp;
367
368 while (nsamples--) {
369 val = *src * (float)SAMPLE_MAX_16BIT;
370 val -= (float)fast_rand() / (float)INT_MAX;
371 tmp = f_round(val);
372 if (tmp > SHRT_MAX) {
373 *((short *)dst) = SHRT_MAX;
374 } else if (tmp < SHRT_MIN) {
375 *((short *)dst) = SHRT_MIN;
376 } else {
377 *((short *) dst) = (short)tmp;
378 }
379 dst += dst_skip;
380 src++;
381 }
382 }
383
384 void sample_move_dither_tri_d16_sS (char *dst, jack_default_audio_sample_t *src, unsigned long nsamples, unsigned long dst_skip, dither_state_t *state)
385
386 {
387 jack_default_audio_sample_t x;
388 float r;
389 float rm1 = state->rm1;
390 int y;
391
392 while (nsamples--) {
393 x = *src * (float)SAMPLE_MAX_16BIT;
394 r = 2.0f * (float)fast_rand() / (float)INT_MAX - 1.0f;
395 x += r - rm1;
396 rm1 = r;
397 y = f_round(x);
398
399 if (y > SHRT_MAX) {
400 *((short *)dst) = SHRT_MAX;
401 } else if (y < SHRT_MIN) {
402 *((short *)dst) = SHRT_MIN;
403 } else {
404 *((short *) dst) = (short)y;
405 }
406
407 dst += dst_skip;
408 src++;
409 }
410 state->rm1 = rm1;
411 }
412
413 void sample_move_dither_shaped_d16_sS (char *dst, jack_default_audio_sample_t *src, unsigned long nsamples, unsigned long dst_skip, dither_state_t *state)
414
415 {
416 jack_default_audio_sample_t x;
417 jack_default_audio_sample_t xe; /* the innput sample - filtered error */
418 jack_default_audio_sample_t xp; /* x' */
419 float r;
420 float rm1 = state->rm1;
421 unsigned int idx = state->idx;
422 int y;
423
424 while (nsamples--) {
425 x = *src * (float)SAMPLE_MAX_16BIT;
426 r = 2.0f * (float)fast_rand() / (float)INT_MAX - 1.0f;
427 /* Filter the error with Lipshitz's minimally audible FIR:
428 [2.033 -2.165 1.959 -1.590 0.6149] */
429 xe = x
430 - state->e[idx] * 2.033f
431 + state->e[(idx - 1) & DITHER_BUF_MASK] * 2.165f
432 - state->e[(idx - 2) & DITHER_BUF_MASK] * 1.959f
433 + state->e[(idx - 3) & DITHER_BUF_MASK] * 1.590f
434 - state->e[(idx - 4) & DITHER_BUF_MASK] * 0.6149f;
435 xp = xe + r - rm1;
436 rm1 = r;
437
438 /* This could be some inline asm on x86 */
439 y = f_round(xp);
440
441 /* Intrinsic z^-1 delay */
442 idx = (idx + 1) & DITHER_BUF_MASK;
443 state->e[idx] = y - xe;
444
445 if (y > SHRT_MAX) {
446 *((short *)dst) = SHRT_MAX;
447 } else if (y < SHRT_MIN) {
448 *((short *)dst) = SHRT_MIN;
449 } else {
450 *((short *) dst) = (short)y;
451 }
452 dst += dst_skip;
453 src++;
454 }
455 state->rm1 = rm1;
456 state->idx = idx;
457 }
458
459 void sample_move_dS_s16 (jack_default_audio_sample_t *dst, char *src, unsigned long nsamples, unsigned long src_skip)
460
461 {
462 /* ALERT: signed sign-extension portability !!! */
463 while (nsamples--) {
464 *dst = (*((short *) src)) / SAMPLE_MAX_16BIT;
465 dst++;
466 src += src_skip;
467 }
468 }
469
470 void sample_merge_d16_sS (char *dst, jack_default_audio_sample_t *src, unsigned long nsamples, unsigned long dst_skip, dither_state_t *state)
471 {
472 short val;
473
474 /* ALERT: signed sign-extension portability !!! */
475
476 while (nsamples--) {
477 val = (short) (*src * SAMPLE_MAX_16BIT);
478
479 if (val > SHRT_MAX - *((short *) dst)) {
480 *((short *)dst) = SHRT_MAX;
481 } else if (val < SHRT_MIN - *((short *) dst)) {
482 *((short *)dst) = SHRT_MIN;
483 } else {
484 *((short *) dst) += val;
485 }
486 dst += dst_skip;
487 src++;
488 }
489 }
490
491 void sample_merge_d32u24_sS (char *dst, jack_default_audio_sample_t *src, unsigned long nsamples, unsigned long dst_skip, dither_state_t *state)
492
493 {
494 /* ALERT: signed sign-extension portability !!! */
495
496 while (nsamples--) {
497 *((int *) dst) += (((int) (*src * SAMPLE_MAX_24BIT)) << 8);
498 dst += dst_skip;
499 src++;
500 }
501 }
502
503 void memset_interleave (char *dst, char val, unsigned long bytes,
504 unsigned long unit_bytes,
505 unsigned long skip_bytes)
506 {
507 switch (unit_bytes) {
508 case 1:
509 while (bytes--) {
510 *dst = val;
511 dst += skip_bytes;
512 }
513 break;
514 case 2:
515 while (bytes) {
516 *((short *) dst) = (short) val;
517 dst += skip_bytes;
518 bytes -= 2;
519 }
520 break;
521 case 4:
522 while (bytes) {
523 *((int *) dst) = (int) val;
524 dst += skip_bytes;
525 bytes -= 4;
526 }
527 break;
528 default:
529 while (bytes) {
530 memset(dst, val, unit_bytes);
531 dst += skip_bytes;
532 bytes -= unit_bytes;
533 }
534 break;
535 }
536 }
537
538 /* COPY FUNCTIONS: used to move data from an input channel to an
539 output channel. Note that we assume that the skip distance
540 is the same for both channels. This is completely fine
541 unless the input and output were on different audio interfaces that
542 were interleaved differently. We don't try to handle that.
543 */
544
545 void
546 memcpy_fake (char *dst, char *src, unsigned long src_bytes, unsigned long foo, unsigned long bar)
547 {
548 memcpy (dst, src, src_bytes);
549 }
550
551 void
552 merge_memcpy_d16_s16 (char *dst, char *src, unsigned long src_bytes,
553 unsigned long dst_skip_bytes, unsigned long src_skip_bytes)
554 {
555 while (src_bytes) {
556 *((short *) dst) += *((short *) src);
557 dst += 2;
558 src += 2;
559 src_bytes -= 2;
560 }
561 }
562
563 void
564 merge_memcpy_d32_s32 (char *dst, char *src, unsigned long src_bytes,
565 unsigned long dst_skip_bytes, unsigned long src_skip_bytes)
566
567 {
568 while (src_bytes) {
569 *((int *) dst) += *((int *) src);
570 dst += 4;
571 src += 4;
572 src_bytes -= 4;
573 }
574 }
575
576 void
577 merge_memcpy_interleave_d16_s16 (char *dst, char *src, unsigned long src_bytes,
578 unsigned long dst_skip_bytes, unsigned long src_skip_bytes)
579
580 {
581 while (src_bytes) {
582 *((short *) dst) += *((short *) src);
583 dst += dst_skip_bytes;
584 src += src_skip_bytes;
585 src_bytes -= 2;
586 }
587 }
588
589 void
590 merge_memcpy_interleave_d32_s32 (char *dst, char *src, unsigned long src_bytes,
591 unsigned long dst_skip_bytes, unsigned long src_skip_bytes)
592 {
593 while (src_bytes) {
594 *((int *) dst) += *((int *) src);
595 dst += dst_skip_bytes;
596 src += src_skip_bytes;
597 src_bytes -= 4;
598 }
599 }
600
601 void
602 merge_memcpy_interleave_d24_s24 (char *dst, char *src, unsigned long src_bytes,
603 unsigned long dst_skip_bytes, unsigned long src_skip_bytes)
604 {
605 while (src_bytes) {
606 int acc = (*(int *)dst & 0xFFFFFF) + (*(int *)src & 0xFFFFFF);
607 memcpy(dst, &acc, 3);
608 dst += dst_skip_bytes;
609 src += src_skip_bytes;
610 src_bytes -= 3;
611 }
612 }
613
614 void
615 memcpy_interleave_d16_s16 (char *dst, char *src, unsigned long src_bytes,
616 unsigned long dst_skip_bytes, unsigned long src_skip_bytes)
617 {
618 while (src_bytes) {
619 *((short *) dst) = *((short *) src);
620 dst += dst_skip_bytes;
621 src += src_skip_bytes;
622 src_bytes -= 2;
623 }
624 }
625
626 void
627 memcpy_interleave_d24_s24 (char *dst, char *src, unsigned long src_bytes,
628 unsigned long dst_skip_bytes, unsigned long src_skip_bytes)
629
630 {
631 while (src_bytes) {
632 memcpy(dst, src, 3);
633 dst += dst_skip_bytes;
634 src += src_skip_bytes;
635 src_bytes -= 3;
636 }
637 }
638
639 void
640 memcpy_interleave_d32_s32 (char *dst, char *src, unsigned long src_bytes,
641 unsigned long dst_skip_bytes, unsigned long src_skip_bytes)
642
643 {
644 while (src_bytes) {
645 *((int *) dst) = *((int *) src);
646 dst += dst_skip_bytes;
647 src += src_skip_bytes;
648 src_bytes -= 4;
649 }
650 }
651
This page was automatically generated by the
LXR engine.
Visit the LXR main site for more
information.