~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~ [ freetext search ] ~ [ file search ] ~

Linux Cross Reference
JACK/drivers/alsa/memops.c


** 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

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~ [ freetext search ] ~ [ file search ] ~

This page was automatically generated by the LXR engine.
Visit the LXR main site for more information.