mix.cpp (11159B)
1 /* 2 3 TiMidity -- Experimental MIDI to WAVE converter 4 Copyright (C) 1995 Tuukka Toivonen <toivonen@clinet.fi> 5 6 Suddenly, you realize that this program is free software; you get 7 an overwhelming urge to redistribute it and/or modify it under the 8 terms of the GNU General Public License as published by the Free 9 Software Foundation; either version 2 of the License, or (at your 10 option) any later version. 11 12 This program is distributed in the hope that it will be useful, 13 but WITHOUT ANY WARRANTY; without even the implied warranty of 14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 GNU General Public License for more details. 16 17 You should have received another copy of the GNU General Public 18 License along with this program; if not, write to the Free 19 Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 20 I bet they'll be amazed. 21 22 mix.c */ 23 24 #include <math.h> 25 #include <stdio.h> 26 #include <stdlib.h> 27 28 #include "config.h" 29 #include "common.h" 30 #include "instrum.h" 31 #include "playmidi.h" 32 #include "output.h" 33 #include "controls.h" 34 #include "tables.h" 35 #include "resample.h" 36 #include "mix.h" 37 38 /* Returns 1 if envelope runs out */ 39 int recompute_envelope(int v) 40 { 41 int stage; 42 43 stage = voice[v].envelope_stage; 44 45 if (stage>5) 46 { 47 /* Envelope ran out. */ 48 int tmp=(voice[v].status == VOICE_DIE); /* Already displayed as dead */ 49 voice[v].status = VOICE_FREE; 50 if(!tmp) 51 ctl->note(v); 52 return 1; 53 } 54 55 if (voice[v].sample->modes & MODES_ENVELOPE) 56 { 57 if (voice[v].status==VOICE_ON || voice[v].status==VOICE_SUSTAINED) 58 { 59 if (stage>2) 60 { 61 /* Freeze envelope until note turns off. Trumpets want this. */ 62 voice[v].envelope_increment=0; 63 return 0; 64 } 65 } 66 } 67 voice[v].envelope_stage=stage+1; 68 69 if (voice[v].envelope_volume==voice[v].sample->envelope_offset[stage]) 70 return recompute_envelope(v); 71 voice[v].envelope_target=voice[v].sample->envelope_offset[stage]; 72 voice[v].envelope_increment = voice[v].sample->envelope_rate[stage]; 73 if (voice[v].envelope_target<voice[v].envelope_volume) 74 voice[v].envelope_increment = -voice[v].envelope_increment; 75 return 0; 76 } 77 78 void apply_envelope_to_amp(int v) 79 { 80 float lamp=voice[v].left_amp, ramp; 81 int32_t la,ra; 82 if (voice[v].panned == PANNED_MYSTERY) 83 { 84 ramp=voice[v].right_amp; 85 if (voice[v].tremolo_phase_increment) 86 { 87 lamp *= voice[v].tremolo_volume; 88 ramp *= voice[v].tremolo_volume; 89 } 90 if (voice[v].sample->modes & MODES_ENVELOPE) 91 { 92 lamp *= (float)vol_table[voice[v].envelope_volume>>23]; 93 ramp *= (float)vol_table[voice[v].envelope_volume>>23]; 94 } 95 96 la = (int32_t)FSCALE(lamp,AMP_BITS); 97 98 if (la>MAX_AMP_VALUE) 99 la=MAX_AMP_VALUE; 100 101 ra = (int32_t)FSCALE(ramp,AMP_BITS); 102 if (ra>MAX_AMP_VALUE) 103 ra=MAX_AMP_VALUE; 104 105 106 voice[v].left_mix=FINAL_VOLUME(la); 107 voice[v].right_mix=FINAL_VOLUME(ra); 108 } 109 else 110 { 111 if (voice[v].tremolo_phase_increment) 112 lamp *= voice[v].tremolo_volume; 113 if (voice[v].sample->modes & MODES_ENVELOPE) 114 lamp *= (float)vol_table[voice[v].envelope_volume>>23]; 115 116 la = (int32_t)FSCALE(lamp,AMP_BITS); 117 118 if (la>MAX_AMP_VALUE) 119 la=MAX_AMP_VALUE; 120 121 voice[v].left_mix=FINAL_VOLUME(la); 122 } 123 } 124 125 static int update_envelope(int v) 126 { 127 voice[v].envelope_volume += voice[v].envelope_increment; 128 /* Why is there no ^^ operator?? */ 129 if (((voice[v].envelope_increment < 0) && 130 (voice[v].envelope_volume <= voice[v].envelope_target)) || 131 ((voice[v].envelope_increment > 0) && 132 (voice[v].envelope_volume >= voice[v].envelope_target))) 133 { 134 voice[v].envelope_volume = voice[v].envelope_target; 135 if (recompute_envelope(v)) 136 return 1; 137 } 138 return 0; 139 } 140 141 static void update_tremolo(int v) 142 { 143 int32_t depth=voice[v].sample->tremolo_depth<<7; 144 145 if (voice[v].tremolo_sweep) 146 { 147 /* Update sweep position */ 148 149 voice[v].tremolo_sweep_position += voice[v].tremolo_sweep; 150 if (voice[v].tremolo_sweep_position>=(1<<SWEEP_SHIFT)) 151 voice[v].tremolo_sweep=0; /* Swept to max amplitude */ 152 else 153 { 154 /* Need to adjust depth */ 155 depth *= voice[v].tremolo_sweep_position; 156 depth >>= SWEEP_SHIFT; 157 } 158 } 159 160 voice[v].tremolo_phase += voice[v].tremolo_phase_increment; 161 162 /* if (voice[v].tremolo_phase >= (SINE_CYCLE_LENGTH<<RATE_SHIFT)) 163 voice[v].tremolo_phase -= SINE_CYCLE_LENGTH<<RATE_SHIFT; */ 164 165 voice[v].tremolo_volume = (float) 166 (1.0 - FSCALENEG((sine(voice[v].tremolo_phase >> RATE_SHIFT) + 1.0) 167 * depth * TREMOLO_AMPLITUDE_TUNING, 168 17)); 169 170 /* I'm not sure about the +1.0 there -- it makes tremoloed voices' 171 volumes on average the lower the higher the tremolo amplitude. */ 172 } 173 174 /* Returns 1 if the note died */ 175 static int update_signal(int v) 176 { 177 if (voice[v].envelope_increment && update_envelope(v)) 178 return 1; 179 180 if (voice[v].tremolo_phase_increment) 181 update_tremolo(v); 182 183 apply_envelope_to_amp(v); 184 return 0; 185 } 186 187 #ifdef LOOKUP_HACK 188 # define MIXATION(a) *lp++ += mixup[(a<<8) | (uint8)s]; 189 #else 190 # define MIXATION(a) *lp++ += (a)*s; 191 #endif 192 193 static void mix_mystery_signal(sample_t *sp, int32_t *lp, int v, int count) 194 { 195 Voice *vp = voice + v; 196 final_volume_t 197 left=vp->left_mix, 198 right=vp->right_mix; 199 int cc; 200 sample_t s; 201 202 if (!(cc = vp->control_counter)) 203 { 204 cc = control_ratio; 205 if (update_signal(v)) 206 return; /* Envelope ran out */ 207 left = vp->left_mix; 208 right = vp->right_mix; 209 } 210 211 while (count) 212 if (cc < count) 213 { 214 count -= cc; 215 while (cc--) 216 { 217 s = *sp++; 218 MIXATION(left); 219 MIXATION(right); 220 } 221 cc = control_ratio; 222 if (update_signal(v)) 223 return; /* Envelope ran out */ 224 left = vp->left_mix; 225 right = vp->right_mix; 226 } 227 else 228 { 229 vp->control_counter = cc - count; 230 while (count--) 231 { 232 s = *sp++; 233 MIXATION(left); 234 MIXATION(right); 235 } 236 return; 237 } 238 } 239 240 static void mix_center_signal(sample_t *sp, int32_t *lp, int v, int count) 241 { 242 Voice *vp = voice + v; 243 final_volume_t 244 left=vp->left_mix; 245 int cc; 246 sample_t s; 247 248 if (!(cc = vp->control_counter)) 249 { 250 cc = control_ratio; 251 if (update_signal(v)) 252 return; /* Envelope ran out */ 253 left = vp->left_mix; 254 } 255 256 while (count) 257 if (cc < count) 258 { 259 count -= cc; 260 while (cc--) 261 { 262 s = *sp++; 263 MIXATION(left); 264 MIXATION(left); 265 } 266 cc = control_ratio; 267 if (update_signal(v)) 268 return; /* Envelope ran out */ 269 left = vp->left_mix; 270 } 271 else 272 { 273 vp->control_counter = cc - count; 274 while (count--) 275 { 276 s = *sp++; 277 MIXATION(left); 278 MIXATION(left); 279 } 280 return; 281 } 282 } 283 284 static void mix_single_signal(sample_t *sp, int32_t *lp, int v, int count) 285 { 286 Voice *vp = voice + v; 287 final_volume_t 288 left=vp->left_mix; 289 int cc; 290 sample_t s; 291 292 if (!(cc = vp->control_counter)) 293 { 294 cc = control_ratio; 295 if (update_signal(v)) 296 return; /* Envelope ran out */ 297 left = vp->left_mix; 298 } 299 300 while (count) 301 if (cc < count) 302 { 303 count -= cc; 304 while (cc--) 305 { 306 s = *sp++; 307 MIXATION(left); 308 lp++; 309 } 310 cc = control_ratio; 311 if (update_signal(v)) 312 return; /* Envelope ran out */ 313 left = vp->left_mix; 314 } 315 else 316 { 317 vp->control_counter = cc - count; 318 while (count--) 319 { 320 s = *sp++; 321 MIXATION(left); 322 lp++; 323 } 324 return; 325 } 326 } 327 328 static void mix_mono_signal(sample_t *sp, int32_t *lp, int v, int count) 329 { 330 Voice *vp = voice + v; 331 final_volume_t 332 left=vp->left_mix; 333 int cc; 334 sample_t s; 335 336 if (!(cc = vp->control_counter)) 337 { 338 cc = control_ratio; 339 if (update_signal(v)) 340 return; /* Envelope ran out */ 341 left = vp->left_mix; 342 } 343 344 while (count) 345 if (cc < count) 346 { 347 count -= cc; 348 while (cc--) 349 { 350 s = *sp++; 351 MIXATION(left); 352 } 353 cc = control_ratio; 354 if (update_signal(v)) 355 return; /* Envelope ran out */ 356 left = vp->left_mix; 357 } 358 else 359 { 360 vp->control_counter = cc - count; 361 while (count--) 362 { 363 s = *sp++; 364 MIXATION(left); 365 } 366 return; 367 } 368 } 369 370 static void mix_mystery(sample_t *sp, int32_t *lp, int v, int count) 371 { 372 final_volume_t 373 left=voice[v].left_mix, 374 right=voice[v].right_mix; 375 sample_t s; 376 377 while (count--) 378 { 379 s = *sp++; 380 MIXATION(left); 381 MIXATION(right); 382 } 383 } 384 385 static void mix_center(sample_t *sp, int32_t *lp, int v, int count) 386 { 387 final_volume_t 388 left=voice[v].left_mix; 389 sample_t s; 390 391 while (count--) 392 { 393 s = *sp++; 394 MIXATION(left); 395 MIXATION(left); 396 } 397 } 398 399 static void mix_single(sample_t *sp, int32_t *lp, int v, int count) 400 { 401 final_volume_t 402 left=voice[v].left_mix; 403 sample_t s; 404 405 while (count--) 406 { 407 s = *sp++; 408 MIXATION(left); 409 lp++; 410 } 411 } 412 413 static void mix_mono(sample_t *sp, int32_t *lp, int v, int count) 414 { 415 final_volume_t 416 left=voice[v].left_mix; 417 sample_t s; 418 419 while (count--) 420 { 421 s = *sp++; 422 MIXATION(left); 423 } 424 } 425 426 /* Ramp a note out in c samples */ 427 static void ramp_out(sample_t *sp, int32_t *lp, int v, int32_t c) 428 { 429 430 /* should be final_volume_t, but uint8_t gives trouble. */ 431 int32_t left, right, li, ri; 432 433 sample_t s=0; /* silly warning about uninitialized s */ 434 435 /* Fix by James Caldwell */ 436 if ( c == 0 ) c = 1; 437 438 left=voice[v].left_mix; 439 li=-(left/c); 440 if (!li) li=-1; 441 442 /* I_Printf("Ramping out: left=%d, c=%d, li=%d\n", left, c, li); */ 443 444 if (!(play_mode->encoding & PE_MONO)) 445 { 446 if (voice[v].panned==PANNED_MYSTERY) 447 { 448 right=voice[v].right_mix; 449 ri=-(right/c); 450 while (c--) 451 { 452 left += li; 453 if (left<0) 454 left=0; 455 right += ri; 456 if (right<0) 457 right=0; 458 s=*sp++; 459 MIXATION(left); 460 MIXATION(right); 461 } 462 } 463 else if (voice[v].panned==PANNED_CENTER) 464 { 465 while (c--) 466 { 467 left += li; 468 if (left<0) 469 return; 470 s=*sp++; 471 MIXATION(left); 472 MIXATION(left); 473 } 474 } 475 else if (voice[v].panned==PANNED_LEFT) 476 { 477 while (c--) 478 { 479 left += li; 480 if (left<0) 481 return; 482 s=*sp++; 483 MIXATION(left); 484 lp++; 485 } 486 } 487 else if (voice[v].panned==PANNED_RIGHT) 488 { 489 while (c--) 490 { 491 left += li; 492 if (left<0) 493 return; 494 s=*sp++; 495 lp++; 496 MIXATION(left); 497 } 498 } 499 } 500 else 501 { 502 /* Mono output. */ 503 while (c--) 504 { 505 left += li; 506 if (left<0) 507 return; 508 s=*sp++; 509 MIXATION(left); 510 } 511 } 512 } 513 514 515 /**************** interface function ******************/ 516 517 void mix_voice( int32_t *buf, int v, int32_t c) 518 { 519 Voice *vp=voice+v; 520 sample_t *sp; 521 if (vp->status==VOICE_DIE) 522 { 523 if (c>=MAX_DIE_TIME) 524 c=MAX_DIE_TIME; 525 sp=resample_voice(v, &c); 526 ramp_out(sp, buf, v, c); 527 vp->status=VOICE_FREE; 528 } 529 else 530 { 531 sp=resample_voice(v, &c); 532 if (play_mode->encoding & PE_MONO) 533 { 534 /* Mono output. */ 535 if (vp->envelope_increment || vp->tremolo_phase_increment) 536 mix_mono_signal(sp, buf, v, c); 537 else 538 mix_mono(sp, buf, v, c); 539 } 540 else 541 { 542 if (vp->panned == PANNED_MYSTERY) 543 { 544 if (vp->envelope_increment || vp->tremolo_phase_increment) 545 mix_mystery_signal(sp, buf, v, c); 546 else 547 mix_mystery(sp, buf, v, c); 548 } 549 else if (vp->panned == PANNED_CENTER) 550 { 551 if (vp->envelope_increment || vp->tremolo_phase_increment) 552 mix_center_signal(sp, buf, v, c); 553 else 554 mix_center(sp, buf, v, c); 555 } 556 else 557 { 558 /* It's either full left or full right. In either case, 559 every other sample is 0. Just get the offset right: */ 560 if (vp->panned == PANNED_RIGHT) buf++; 561 562 if (vp->envelope_increment || vp->tremolo_phase_increment) 563 mix_single_signal(sp, buf, v, c); 564 else 565 mix_single(sp, buf, v, c); 566 } 567 } 568 } 569 }