1 /* 2 * Copyright (c) 2009, The MilkyTracker Team. 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions are met: 7 * 8 * - Redistributions of source code must retain the above copyright notice, 9 * this list of conditions and the following disclaimer. 10 * - Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in the 12 * documentation and/or other materials provided with the distribution. 13 * - Neither the name of the <ORGANIZATION> nor the names of its contributors 14 * may be used to endorse or promote products derived from this software 15 * without specific prior written permission. 16 * 17 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 18 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 20 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 21 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 22 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 23 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 24 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 25 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 26 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 27 * POSSIBILITY OF SUCH DAMAGE. 28 */ 29 30 /* 31 * ResamplerMacros.h 32 * MilkyPlay mixer macros & "templates" 33 * 34 * 35 * "- Be prepared! Are you sure you want to know? :-)" 36 * 37 */ 38 #ifndef __RESAMPLERMACROS_H__ 39 #define __RESAMPLERMACROS_H__ 40 41 #define VALIDATE \ 42 /*ASSERT((void*)(sample+(posfixed>>16)) >= (void*)chn->sample);*/ 43 44 #define PROCESS_BLOCK(MIXER) \ 45 mp_sint32 blockCount = count>>3; \ 46 mp_sint32 remainCount = count & 7; \ 47 while (blockCount) \ 48 { \ 49 VALIDATE \ 50 MIXER \ 51 posfixed+=smpadd; \ 52 VALIDATE \ 53 MIXER \ 54 posfixed+=smpadd; \ 55 VALIDATE \ 56 MIXER \ 57 posfixed+=smpadd; \ 58 VALIDATE \ 59 MIXER \ 60 posfixed+=smpadd; \ 61 VALIDATE \ 62 MIXER \ 63 posfixed+=smpadd; \ 64 VALIDATE \ 65 MIXER \ 66 posfixed+=smpadd; \ 67 VALIDATE \ 68 MIXER \ 69 posfixed+=smpadd; \ 70 VALIDATE \ 71 MIXER \ 72 posfixed+=smpadd; \ 73 blockCount--; \ 74 } \ 75 while (remainCount) \ 76 { \ 77 VALIDATE \ 78 MIXER \ 79 posfixed+=smpadd; \ 80 remainCount--; \ 81 } 82 83 #define NOCHECKMIXER_TEMPLATE(MIXER_8BIT,MIXER_16BIT) \ 84 if (!(chn->flags&4)) \ 85 { \ 86 const mp_sbyte* sample = chn->sample + basepos; \ 87 PROCESS_BLOCK(MIXER_8BIT) \ 88 } \ 89 else \ 90 { \ 91 const mp_sword* sample = (const mp_sword*)chn->sample + basepos; \ 92 PROCESS_BLOCK(MIXER_16BIT) \ 93 } 94 95 ///////////////////////////////////////////////////////// 96 // NO INTERPOLATION AND NO VOLUME RAMPING // 97 ///////////////////////////////////////////////////////// 98 #define NOCHECKMIXER_8BIT_NORMAL \ 99 sd1 = sample[posfixed>>16]<<8; \ 100 \ 101 /* adjust volume for left channel & mix */ \ 102 (*buffer++)+=((sd1*(voll>>15))>>15); \ 103 /* adjust volume for right channel & mix */ \ 104 (*buffer++)+=((sd1*(volr>>15))>>15); 105 106 #define NOCHECKMIXER_16BIT_NORMAL \ 107 sd1 = sample[posfixed>>16]; \ 108 \ 109 /* adjust volume for left channel & mix */ \ 110 (*buffer++)+=((sd1*(voll>>15))>>15); \ 111 /* adjust volume for right channel & mix */ \ 112 (*buffer++)+=((sd1*(volr>>15))>>15); 113 114 ///////////////////////////////////////////////////////// 115 // NO INTERPOLATION BUT VOLUME RAMPING // 116 ///////////////////////////////////////////////////////// 117 #define NOCHECKMIXER_8BIT_NORMAL_RAMP(_RAMP_) \ 118 sd1 = sample[posfixed>>16]<<8; \ 119 /* adjust volume for left channel & mix */ \ 120 (*buffer++)+=((sd1*(voll>>15))>>15); \ 121 /* adjust volume for right channel & mix */ \ 122 (*buffer++)+=((sd1*(volr>>15))>>15); \ 123 if ((_RAMP_)) \ 124 { \ 125 voll+=rampFromVolStepL; \ 126 volr+=rampFromVolStepR; \ 127 } 128 129 #define NOCHECKMIXER_16BIT_NORMAL_RAMP(_RAMP_) \ 130 sd1 = sample[posfixed>>16]; \ 131 /* adjust volume for left channel & mix */ \ 132 (*buffer++)+=((sd1*(voll>>15))>>15); \ 133 /* adjust volume for right channel & mix */ \ 134 (*buffer++)+=((sd1*(volr>>15))>>15); \ 135 if ((_RAMP_)) \ 136 { \ 137 voll+=rampFromVolStepL; \ 138 volr+=rampFromVolStepR; \ 139 } 140 141 ///////////////////////////////////////////////////////// 142 // INTERPOLATION AND NO VOLUME RAMPING // 143 ///////////////////////////////////////////////////////// 144 #define NOCHECKMIXER_8BIT_LERP \ 145 sd1 = sample[posfixed>>16]<<8; \ 146 sd2 = sample[(posfixed>>16)+1]<<8; \ 147 \ 148 sd1 =((sd1<<12)+((posfixed>>4)&0xfff)*(sd2-sd1))>>12; \ 149 \ 150 /* adjust volume for left channel & mix */ \ 151 (*buffer++)+=((sd1*(voll>>15))>>15); \ 152 /* adjust volume for right channel & mix */ \ 153 (*buffer++)+=((sd1*(volr>>15))>>15); 154 155 #define NOCHECKMIXER_16BIT_LERP \ 156 sd1 = sample[posfixed>>16]; \ 157 sd2 = sample[(posfixed>>16)+1]; \ 158 \ 159 sd1 =((sd1<<12)+((posfixed>>4)&0xfff)*(sd2-sd1))>>12; \ 160 \ 161 /* adjust volume for left channel & mix */ \ 162 (*buffer++)+=((sd1*(voll>>15))>>15); \ 163 /* adjust volume for right channel & mix */ \ 164 (*buffer++)+=((sd1*(volr>>15))>>15); 165 166 ///////////////////////////////////////////////////////// 167 // INTERPOLATION AND VOLUME RAMPING // 168 ///////////////////////////////////////////////////////// 169 #define NOCHECKMIXER_8BIT_LERP_RAMP(_RAMP_) \ 170 sd1 = sample[posfixed>>16]<<8; \ 171 sd2 = sample[(posfixed>>16)+1]<<8; \ 172 \ 173 sd1 =((sd1<<12)+((posfixed>>4)&0xfff)*(sd2-sd1))>>12; \ 174 \ 175 /* adjust volume for left channel & mix */ \ 176 (*buffer++)+=((sd1*(voll>>15))>>15); \ 177 /* adjust volume for right channel & mix */ \ 178 (*buffer++)+=((sd1*(volr>>15))>>15); \ 179 \ 180 if ((_RAMP_)) \ 181 { \ 182 voll+=rampFromVolStepL; \ 183 volr+=rampFromVolStepR; \ 184 } 185 186 #define NOCHECKMIXER_16BIT_LERP_RAMP(_RAMP_) \ 187 sd1 = sample[posfixed>>16]; \ 188 sd2 = sample[(posfixed>>16)+1]; \ 189 \ 190 sd1 =((sd1<<12)+((posfixed>>4)&0xfff)*(sd2-sd1))>>12; \ 191 \ 192 /* adjust volume for left channel & mix */ \ 193 (*buffer++)+=((sd1*(voll>>15))>>15); \ 194 /* adjust volume for right channel & mix */ \ 195 (*buffer++)+=((sd1*(volr>>15))>>15); \ 196 \ 197 if ((_RAMP_)) \ 198 { \ 199 voll+=rampFromVolStepL; \ 200 volr+=rampFromVolStepR; \ 201 } 202 203 ///////////////////////////////////////////////////////// 204 // INTERPOLATION/VOLUME RAMPING and FILTERING // 205 ///////////////////////////////////////////////////////// 206 #define NOCHECKMIXER_8BIT_LERP_RAMP_FILTER(_RAMP_) \ 207 sd1 = sample[posfixed>>16]<<8; \ 208 sd2 = sample[(posfixed>>16)+1]<<8; \ 209 \ 210 sd1 =((sd1<<12)+((posfixed>>4)&0xfff)*(sd2-sd1))>>12; \ 211 \ 212 sd1 = (MP_FP_MUL(sd1, a) + MP_FP_MUL(currsample, b) + MP_FP_MUL(prevsample, c)) >> ChannelMixer::MP_FILTERPRECISION; \ 213 prevsample = currsample; \ 214 currsample = sd1; \ 215 \ 216 /* adjust volume for left/right channels & mix */ \ 217 (*buffer++)+=MP_FP_MUL(sd1, voll>>14); \ 218 (*buffer++)+=MP_FP_MUL(sd1, volr>>14); \ 219 \ 220 if ((_RAMP_)) \ 221 { \ 222 voll+=rampFromVolStepL; \ 223 volr+=rampFromVolStepR; \ 224 } 225 226 #define NOCHECKMIXER_16BIT_LERP_RAMP_FILTER(_RAMP_) \ 227 sd1 = sample[posfixed>>16]; \ 228 sd2 = sample[(posfixed>>16)+1]; \ 229 \ 230 sd1 =((sd1<<12)+((posfixed>>4)&0xfff)*(sd2-sd1))>>12; \ 231 \ 232 sd1 = (MP_FP_MUL(sd1, a) + MP_FP_MUL(currsample, b) + MP_FP_MUL(prevsample, c)) >> ChannelMixer::MP_FILTERPRECISION; \ 233 prevsample = currsample; \ 234 currsample = sd1; \ 235 \ 236 /* adjust volume for left/right channels & mix */ \ 237 (*buffer++)+=MP_FP_MUL(sd1, voll>>14); \ 238 (*buffer++)+=MP_FP_MUL(sd1, volr>>14); \ 239 \ 240 if ((_RAMP_)) \ 241 { \ 242 voll+=rampFromVolStepL; \ 243 volr+=rampFromVolStepR; \ 244 } 245 246 #define BIDIR_REPOSITION(FRACBITS, SMPPOS, SMPPOSFRAC, LOOPSTART, LOOPEND) \ 247 if (!((SMPPOS == LOOPEND) && (SMPPOSFRAC == 0) ||\ 248 (SMPPOS == LOOPSTART) && (SMPPOSFRAC == 0))) \ 249 { \ 250 do \ 251 { \ 252 if (SMPPOS >= LOOPEND) \ 253 SMPPOS = LOOPEND-(SMPPOS-LOOPEND+1); \ 254 else if (SMPPOS < LOOPSTART) \ 255 SMPPOS = LOOPSTART + (LOOPSTART-SMPPOS - 1); \ 256 SMPPOSFRAC = ((1<<FRACBITS)-SMPPOSFRAC) & ((1<<FRACBITS)-1); \ 257 } while (!(SMPPOS >= LOOPSTART && SMPPOS <= LOOPEND)); \ 258 } 259 260 261 #define FULLMIXER_TEMPLATE(MIXER_8BIT, MIXER_16BIT, FRACBITS, LABELNO) \ 262 mp_sint32 smppos = chn->smppos; \ 263 mp_sint32 smpposfrac = chn->smpposfrac; \ 264 mp_sint32 smpadd = chn->smpadd; \ 265 mp_sint32 loopstart = chn->loopstart; \ 266 mp_sint32 loopend = chn->loopend; \ 267 mp_sint32 flags = chn->flags; \ 268 const mp_sbyte* sample = chn->sample; \ 269 mp_sint32 sd1,sd2; \ 270 \ 271 /* 8 bit version */ \ 272 if (!(flags&4)) \ 273 { \ 274 \ 275 if (((((flags&3) == 0 || (flags&3) == 1)) && !(flags&ChannelMixer::MP_SAMPLE_BACKWARD)) || \ 276 ((flags&3) == 2 && (flags&ChannelMixer::MP_SAMPLE_BACKWARD) == 0)) \ 277 { \ 278 \ 279 while (count) \ 280 { \ 281 MIXER_8BIT \ 282 MP_INCREASESMPPOS(smppos,smpposfrac,smpadd,FRACBITS); \ 283 /* stop playing if necessary */ \ 284 if (smppos>=loopend) \ 285 { \ 286 if ((flags & 3) == 0) \ 287 { \ 288 if (flags & ChannelMixer::MP_SAMPLE_ONESHOT) \ 289 { \ 290 flags &= ~ChannelMixer::MP_SAMPLE_ONESHOT; \ 291 flags |= 1; \ 292 chn->loopend = chn->loopendcopy; \ 293 loopend = chn->loopend; \ 294 /*ASSERT(loopend-loopstart > 0);*/ \ 295 smppos = ((smppos - loopstart)%(loopend-loopstart))+loopstart; \ 296 } \ 297 else \ 298 { \ 299 flags&=~ChannelMixer::MP_SAMPLE_PLAY; \ 300 break; \ 301 } \ 302 } \ 303 else if ((flags & 3) == 1) \ 304 { \ 305 /*if (smppos>=((loopend<<1)-loopstart))*/ \ 306 /* smppos=loopstart;*/ \ 307 /*else */\ 308 /* smppos=loopstart+(smppos-loopend); */\ 309 /*ASSERT(loopend-loopstart > 0);*/ \ 310 smppos = ((smppos - loopstart)%(loopend-loopstart))+loopstart; \ 311 } \ 312 else \ 313 { \ 314 flags|=ChannelMixer::MP_SAMPLE_BACKWARD; \ 315 BIDIR_REPOSITION(FRACBITS, smppos, smpposfrac, loopstart, loopend) \ 316 /*ASSERT(smppos >= loopstart && smppos <= loopend);*/ \ 317 goto continueWithBiDir8_## LABELNO; \ 318 } \ 319 } \ 320 \ 321 continueWithNormalDir8_## LABELNO: \ 322 \ 323 count--; \ 324 \ 325 } \ 326 \ 327 } \ 328 /* bi-dir loop */ \ 329 else \ 330 { \ 331 while (count) \ 332 { \ 333 MIXER_8BIT \ 334 MP_INCREASESMPPOS(smppos,smpposfrac,-smpadd,FRACBITS); \ 335 \ 336 if (loopstart>smppos) \ 337 { \ 338 if ((flags & 3) == 0) \ 339 { \ 340 flags&=~ChannelMixer::MP_SAMPLE_PLAY; \ 341 break; \ 342 } \ 343 else if ((flags & 3) == 1) \ 344 { \ 345 smppos = loopend-((loopstart-smppos)%(loopend-loopstart)); \ 346 } \ 347 else \ 348 { \ 349 flags&=~ChannelMixer::MP_SAMPLE_BACKWARD; \ 350 BIDIR_REPOSITION(FRACBITS, smppos, smpposfrac, loopstart, loopend) \ 351 /*ASSERT(smppos >= loopstart && smppos <= loopend);*/ \ 352 goto continueWithNormalDir8_## LABELNO; \ 353 } \ 354 } \ 355 \ 356 continueWithBiDir8_## LABELNO: \ 357 \ 358 count--; \ 359 \ 360 } \ 361 \ 362 } \ 363 \ 364 } \ 365 else \ 366 { \ 367 \ 368 if (((((flags&3) == 0 || (flags&3) == 1)) && !(flags&ChannelMixer::MP_SAMPLE_BACKWARD)) || \ 369 ((flags&3) == 2 && (flags&ChannelMixer::MP_SAMPLE_BACKWARD) == 0)) \ 370 { \ 371 \ 372 while (count) \ 373 { \ 374 MIXER_16BIT \ 375 MP_INCREASESMPPOS(smppos,smpposfrac,smpadd,FRACBITS); \ 376 /* stop playing if necessary */ \ 377 if (smppos>=loopend) \ 378 { \ 379 if ((flags & 3) == 0) \ 380 { \ 381 if (flags & ChannelMixer::MP_SAMPLE_ONESHOT) \ 382 { \ 383 flags &= ~ChannelMixer::MP_SAMPLE_ONESHOT; \ 384 flags |= 1; \ 385 chn->loopend = chn->loopendcopy; \ 386 loopend = chn->loopend; \ 387 smppos = ((smppos - loopstart)%(loopend-loopstart))+loopstart; \ 388 } \ 389 else \ 390 { \ 391 flags&=~ChannelMixer::MP_SAMPLE_PLAY; \ 392 break; \ 393 } \ 394 } \ 395 else if ((flags & 3) == 1) \ 396 { \ 397 /*if (smppos>=((loopend<<1)-loopstart))*/ \ 398 /* smppos=loopstart;*/ \ 399 /*else */\ 400 /* smppos=loopstart+(smppos-loopend); */\ 401 smppos = ((smppos - loopstart)%(loopend-loopstart))+loopstart; \ 402 } \ 403 else \ 404 { \ 405 flags|=ChannelMixer::MP_SAMPLE_BACKWARD; \ 406 BIDIR_REPOSITION(FRACBITS, smppos, smpposfrac, loopstart, loopend) \ 407 /*ASSERT(smppos >= loopstart && smppos <= loopend);*/ \ 408 goto continueWithBiDir16_## LABELNO; \ 409 } \ 410 } \ 411 \ 412 continueWithNormalDir16_## LABELNO: \ 413 \ 414 count--; \ 415 \ 416 } \ 417 \ 418 } \ 419 /* bi-dir loop */ \ 420 else \ 421 { \ 422 while (count) \ 423 { \ 424 MIXER_16BIT \ 425 MP_INCREASESMPPOS(smppos,smpposfrac,-smpadd,FRACBITS); \ 426 \ 427 if (loopstart>smppos) \ 428 { \ 429 if ((flags & 3) == 0) \ 430 { \ 431 flags&=~ChannelMixer::MP_SAMPLE_PLAY; \ 432 break; \ 433 } \ 434 else if ((flags & 3) == 1) \ 435 { \ 436 smppos = loopend-((loopstart-smppos)%(loopend-loopstart)); \ 437 } \ 438 else \ 439 { \ 440 flags&=~ChannelMixer::MP_SAMPLE_BACKWARD; \ 441 BIDIR_REPOSITION(FRACBITS, smppos, smpposfrac, loopstart, loopend) \ 442 /*ASSERT(smppos >= loopstart && smppos <= loopend);*/ \ 443 goto continueWithNormalDir16_## LABELNO; \ 444 } \ 445 } \ 446 \ 447 continueWithBiDir16_## LABELNO: \ 448 \ 449 count--; \ 450 \ 451 } \ 452 \ 453 } \ 454 \ 455 } \ 456 chn->smppos = smppos; \ 457 chn->smpposfrac = smpposfrac; \ 458 /*chn->smpadd = smpadd;*/ \ 459 chn->flags = flags; 460 461 ///////////////////////////////////////////////////////// 462 // NO INTERPOLATION AND NO VOLUME RAMPING // 463 ///////////////////////////////////////////////////////// 464 #define FULLMIXER_8BIT_NORMAL \ 465 /* 8 bit sample */ \ 466 sd1 = ((mp_sbyte)sample[smppos])<<8; \ 467 /* adjust volume for left channel & mix */ \ 468 (*buffer++)+=((sd1*(voll>>15))>>15); \ 469 /* adjust volume for right channel & mix */ \ 470 (*buffer++)+=((sd1*(volr>>15))>>15); 471 472 #define FULLMIXER_16BIT_NORMAL \ 473 /* 16 bit sample */ \ 474 sd1 = ((mp_sword*)(sample))[smppos]; \ 475 /* adjust volume for left channel & mix */ \ 476 (*buffer++)+=((sd1*(voll>>15))>>15); \ 477 /* adjust volume for right channel & mix */ \ 478 (*buffer++)+=((sd1*(volr>>15))>>15); 479 480 ///////////////////////////////////////////////////////// 481 // NO INTERPOLATION BUT VOLUME RAMPING // 482 ///////////////////////////////////////////////////////// 483 #define FULLMIXER_8BIT_NORMAL_RAMP(_RAMP_) \ 484 /* 8 bit sample */ \ 485 sd1 = ((mp_sbyte)sample[smppos])<<8; \ 486 /* adjust volume for left channel & mix */ \ 487 (*buffer++)+=((sd1*(voll>>15))>>15); \ 488 /* adjust volume for right channel & mix */ \ 489 (*buffer++)+=((sd1*(volr>>15))>>15); \ 490 if ((_RAMP_)) \ 491 { \ 492 voll+=rampFromVolStepL; \ 493 volr+=rampFromVolStepR; \ 494 } 495 496 #define FULLMIXER_16BIT_NORMAL_RAMP(_RAMP_) \ 497 /* 16 bit sample */ \ 498 sd1 = ((mp_sword*)(sample))[smppos]; \ 499 /* adjust volume for left channel & mix */ \ 500 (*buffer++)+=((sd1*(voll>>15))>>15); \ 501 /* adjust volume for right channel & mix */ \ 502 (*buffer++)+=((sd1*(volr>>15))>>15); \ 503 if ((_RAMP_)) \ 504 { \ 505 voll+=rampFromVolStepL; \ 506 volr+=rampFromVolStepR; \ 507 } 508 509 ///////////////////////////////////////////////////////// 510 // INTERPOLATION AND NO VOLUME RAMPING // 511 ///////////////////////////////////////////////////////// 512 #define FULLMIXER_8BIT_LERP \ 513 /* 8 bit sample */ \ 514 sd1 = ((mp_sbyte)sample[smppos])<<8; \ 515 sd2 = ((mp_sbyte)sample[smppos+1])<<8; \ 516 \ 517 sd1 =((sd1<<12)+(smpposfrac>>4)*(sd2-sd1))>>12; \ 518 \ 519 /* adjust volume for left channel & mix */ \ 520 (*buffer++)+=((sd1*(voll>>15))>>15); \ 521 /* adjust volume for right channel & mix */ \ 522 (*buffer++)+=((sd1*(volr>>15))>>15); 523 524 #define FULLMIXER_16BIT_LERP \ 525 /* 16 bit sample */ \ 526 sd1 = ((mp_sword*)(sample))[smppos]; \ 527 sd2 = ((mp_sword*)(sample))[smppos+1]; \ 528 \ 529 sd1 =((sd1<<12)+(smpposfrac>>4)*(sd2-sd1))>>12; \ 530 \ 531 /* adjust volume for left channel & mix */ \ 532 (*buffer++)+=((sd1*(voll>>15))>>15); \ 533 /* adjust volume for right channel & mix */ \ 534 (*buffer++)+=((sd1*(volr>>15))>>15); 535 536 ///////////////////////////////////////////////////////// 537 // INTERPOLATION AND VOLUME RAMPING // 538 ///////////////////////////////////////////////////////// 539 #define FULLMIXER_8BIT_LERP_RAMP(_RAMP_) \ 540 /* 8 bit sample */ \ 541 sd1 = ((mp_sbyte)sample[smppos])<<8; \ 542 sd2 = ((mp_sbyte)sample[smppos+1])<<8; \ 543 \ 544 sd1 =((sd1<<12)+(smpposfrac>>4)*(sd2-sd1))>>12; \ 545 \ 546 /* adjust volume for left channel & mix */ \ 547 (*buffer++)+=((sd1*(voll>>15))>>15); \ 548 /* adjust volume for right channel & mix */ \ 549 (*buffer++)+=((sd1*(volr>>15))>>15); \ 550 \ 551 if ((_RAMP_)) \ 552 { \ 553 voll+=rampFromVolStepL; \ 554 volr+=rampFromVolStepR; \ 555 } 556 557 #define FULLMIXER_16BIT_LERP_RAMP(_RAMP_) \ 558 /* 16 bit sample */ \ 559 sd1 = ((mp_sword*)(sample))[smppos]; \ 560 sd2 = ((mp_sword*)(sample))[smppos+1]; \ 561 \ 562 sd1 =((sd1<<12)+(smpposfrac>>4)*(sd2-sd1))>>12; \ 563 \ 564 /* adjust volume for left channel & mix */ \ 565 (*buffer++)+=((sd1*(voll>>15))>>15); \ 566 /* adjust volume for right channel & mix */ \ 567 (*buffer++)+=((sd1*(volr>>15))>>15); \ 568 \ 569 if ((_RAMP_)) \ 570 { \ 571 voll+=rampFromVolStepL; \ 572 volr+=rampFromVolStepR; \ 573 } 574 575 ///////////////////////////////////////////////////////// 576 // INTERPOLATION/VOLUME RAMPING and FILTERING // 577 ///////////////////////////////////////////////////////// 578 #define FULLMIXER_8BIT_LERP_RAMP_FILTER(_RAMP_) \ 579 sd1 = ((mp_sbyte)sample[smppos])<<8; \ 580 sd2 = ((mp_sbyte)sample[smppos+1])<<8; \ 581 \ 582 sd1 =((sd1<<12)+((smpposfrac>>4)&0xfff)*(sd2-sd1))>>12; \ 583 \ 584 sd1 = (MP_FP_MUL(sd1, a) + MP_FP_MUL(currsample, b) + MP_FP_MUL(prevsample, c)) >> ChannelMixer::MP_FILTERPRECISION; \ 585 prevsample = currsample; \ 586 currsample = sd1; \ 587 \ 588 /* adjust volume for left/right channels & mix */ \ 589 (*buffer++)+=MP_FP_MUL(sd1, voll>>14); \ 590 (*buffer++)+=MP_FP_MUL(sd1, volr>>14); \ 591 \ 592 if ((_RAMP_)) \ 593 { \ 594 voll+=rampFromVolStepL; \ 595 volr+=rampFromVolStepR; \ 596 } 597 598 #define FULLMIXER_16BIT_LERP_RAMP_FILTER(_RAMP_) \ 599 sd1 = ((mp_sword*)(sample))[smppos]; \ 600 sd2 = ((mp_sword*)(sample))[smppos+1]; \ 601 \ 602 sd1 =((sd1<<12)+((smpposfrac>>4)&0xfff)*(sd2-sd1))>>12; \ 603 \ 604 sd1 = (MP_FP_MUL(sd1, a) + MP_FP_MUL(currsample, b) + MP_FP_MUL(prevsample, c)) >> ChannelMixer::MP_FILTERPRECISION; \ 605 prevsample = currsample; \ 606 currsample = sd1; \ 607 \ 608 /* adjust volume for left/right channels & mix */ \ 609 (*buffer++)+=MP_FP_MUL(sd1, voll>>14); \ 610 (*buffer++)+=MP_FP_MUL(sd1, volr>>14); \ 611 \ 612 if ((_RAMP_)) \ 613 { \ 614 voll+=rampFromVolStepL; \ 615 volr+=rampFromVolStepR; \ 616 } 617 618 619 ///////////////////////////////////////////////////////// 620 // INTERPOLATION AND VOLUME RAMPING HIRES // 621 ///////////////////////////////////////////////////////// 622 #define FULLMIXER_8BIT_LERP_RAMP_HIRES(_RAMP_) \ 623 /* 8 bit sample */ \ 624 sd1 = ((mp_sbyte)sample[smppos])<<8; \ 625 sd2 = ((mp_sbyte)sample[smppos+1])<<8; \ 626 \ 627 sd1 =((sd1<<12)+(smpposfrac>>(4+12))*(sd2-sd1))>>12; \ 628 \ 629 /* adjust volume for left channel & mix */ \ 630 (*buffer++)+=((sd1*(voll>>15))>>15); \ 631 /* adjust volume for right channel & mix */ \ 632 (*buffer++)+=((sd1*(volr>>15))>>15); \ 633 \ 634 if ((_RAMP_)) \ 635 { \ 636 voll+=rampFromVolStepL; \ 637 volr+=rampFromVolStepR; \ 638 } 639 640 #define FULLMIXER_16BIT_LERP_RAMP_HIRES(_RAMP_) \ 641 /* 16 bit sample */ \ 642 sd1 = ((mp_sword*)(sample))[smppos]; \ 643 sd2 = ((mp_sword*)(sample))[smppos+1]; \ 644 \ 645 sd1 =((sd1<<12)+(smpposfrac>>(4+12))*(sd2-sd1))>>12; \ 646 \ 647 /* adjust volume for left channel & mix */ \ 648 (*buffer++)+=((sd1*(voll>>15))>>15); \ 649 /* adjust volume for right channel & mix */ \ 650 (*buffer++)+=((sd1*(volr>>15))>>15); \ 651 \ 652 if ((_RAMP_)) \ 653 { \ 654 voll+=rampFromVolStepL; \ 655 volr+=rampFromVolStepR; \ 656 } 657 658 659 #endif 660