comparison src/timidity/libtimidity/mix.c @ 12:3da1b8942b8b trunk

[svn] - remove src/Input src/Output src/Effect src/General src/Visualization src/Container
author nenolod
date Mon, 18 Sep 2006 03:14:20 -0700
parents src/Input/timidity/libtimidity/mix.c@088092a52fea
children f14d11bf9cbb
comparison
equal deleted inserted replaced
11:cff1d04026ae 12:3da1b8942b8b
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 #if HAVE_CONFIG_H
25 # include <config.h>
26 #endif
27
28 #include "audacious/vfs.h"
29 #include <math.h>
30 #include <stdlib.h>
31
32 #include "timidity.h"
33 #include "timidity_internal.h"
34 #include "options.h"
35 #include "instrum.h"
36 #include "playmidi.h"
37 #include "output.h"
38 #include "tables.h"
39 #include "resample.h"
40 #include "mix.h"
41
42 /* Returns 1 if envelope runs out */
43 int recompute_envelope(MidSong *song, int v)
44 {
45 int stage;
46
47 stage = song->voice[v].envelope_stage;
48
49 if (stage>5)
50 {
51 /* Envelope ran out. */
52 song->voice[v].status = VOICE_FREE;
53 return 1;
54 }
55
56 if (song->voice[v].sample->modes & MODES_ENVELOPE)
57 {
58 if (song->voice[v].status==VOICE_ON || song->voice[v].status==VOICE_SUSTAINED)
59 {
60 if (stage>2)
61 {
62 /* Freeze envelope until note turns off. Trumpets want this. */
63 song->voice[v].envelope_increment=0;
64 return 0;
65 }
66 }
67 }
68 song->voice[v].envelope_stage=stage+1;
69
70 if (song->voice[v].envelope_volume==song->voice[v].sample->envelope_offset[stage])
71 return recompute_envelope(song, v);
72 song->voice[v].envelope_target = song->voice[v].sample->envelope_offset[stage];
73 song->voice[v].envelope_increment = song->voice[v].sample->envelope_rate[stage];
74 if (song->voice[v].envelope_target < song->voice[v].envelope_volume)
75 song->voice[v].envelope_increment = -song->voice[v].envelope_increment;
76 return 0;
77 }
78
79 void apply_envelope_to_amp(MidSong *song, int v)
80 {
81 float lamp = song->voice[v].left_amp, ramp;
82 sint32 la,ra;
83 if (song->voice[v].panned == PANNED_MYSTERY)
84 {
85 ramp = song->voice[v].right_amp;
86 if (song->voice[v].tremolo_phase_increment)
87 {
88 lamp *= song->voice[v].tremolo_volume;
89 ramp *= song->voice[v].tremolo_volume;
90 }
91 if (song->voice[v].sample->modes & MODES_ENVELOPE)
92 {
93 lamp *= (float)vol_table[song->voice[v].envelope_volume>>23];
94 ramp *= (float)vol_table[song->voice[v].envelope_volume>>23];
95 }
96
97 la = (sint32)FSCALE(lamp,AMP_BITS);
98
99 if (la>MAX_AMP_VALUE)
100 la=MAX_AMP_VALUE;
101
102 ra = (sint32)FSCALE(ramp,AMP_BITS);
103 if (ra>MAX_AMP_VALUE)
104 ra=MAX_AMP_VALUE;
105
106 song->voice[v].left_mix = la;
107 song->voice[v].right_mix = ra;
108 }
109 else
110 {
111 if (song->voice[v].tremolo_phase_increment)
112 lamp *= song->voice[v].tremolo_volume;
113 if (song->voice[v].sample->modes & MODES_ENVELOPE)
114 lamp *= (float)vol_table[song->voice[v].envelope_volume>>23];
115
116 la = (sint32)FSCALE(lamp,AMP_BITS);
117
118 if (la>MAX_AMP_VALUE)
119 la=MAX_AMP_VALUE;
120
121 song->voice[v].left_mix = la;
122 }
123 }
124
125 static int update_envelope(MidSong *song, int v)
126 {
127 song->voice[v].envelope_volume += song->voice[v].envelope_increment;
128 /* Why is there no ^^ operator?? */
129 if (((song->voice[v].envelope_increment < 0) &&
130 (song->voice[v].envelope_volume <= song->voice[v].envelope_target)) ||
131 ((song->voice[v].envelope_increment > 0) &&
132 (song->voice[v].envelope_volume >= song->voice[v].envelope_target)))
133 {
134 song->voice[v].envelope_volume = song->voice[v].envelope_target;
135 if (recompute_envelope(song, v))
136 return 1;
137 }
138 return 0;
139 }
140
141 static void update_tremolo(MidSong *song, int v)
142 {
143 sint32 depth = song->voice[v].sample->tremolo_depth << 7;
144
145 if (song->voice[v].tremolo_sweep)
146 {
147 /* Update sweep position */
148
149 song->voice[v].tremolo_sweep_position += song->voice[v].tremolo_sweep;
150 if (song->voice[v].tremolo_sweep_position >= (1 << SWEEP_SHIFT))
151 song->voice[v].tremolo_sweep=0; /* Swept to max amplitude */
152 else
153 {
154 /* Need to adjust depth */
155 depth *= song->voice[v].tremolo_sweep_position;
156 depth >>= SWEEP_SHIFT;
157 }
158 }
159
160 song->voice[v].tremolo_phase += song->voice[v].tremolo_phase_increment;
161
162 /* if (song->voice[v].tremolo_phase >= (SINE_CYCLE_LENGTH<<RATE_SHIFT))
163 song->voice[v].tremolo_phase -= SINE_CYCLE_LENGTH<<RATE_SHIFT; */
164
165 song->voice[v].tremolo_volume = (float)
166 (1.0 - FSCALENEG((sine(song->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(MidSong *song, int v)
176 {
177 if (song->voice[v].envelope_increment && update_envelope(song, v))
178 return 1;
179
180 if (song->voice[v].tremolo_phase_increment)
181 update_tremolo(song, v);
182
183 apply_envelope_to_amp(song, v);
184 return 0;
185 }
186
187 #define MIXATION(a) *lp++ += (a)*s;
188
189 static void mix_mystery_signal(MidSong *song, sample_t *sp, sint32 *lp, int v,
190 int count)
191 {
192 MidVoice *vp = song->voice + v;
193 final_volume_t
194 left=vp->left_mix,
195 right=vp->right_mix;
196 int cc;
197 sample_t s;
198
199 if (!(cc = vp->control_counter))
200 {
201 cc = song->control_ratio;
202 if (update_signal(song, v))
203 return; /* Envelope ran out */
204 left = vp->left_mix;
205 right = vp->right_mix;
206 }
207
208 while (count)
209 if (cc < count)
210 {
211 count -= cc;
212 while (cc--)
213 {
214 s = *sp++;
215 MIXATION(left);
216 MIXATION(right);
217 }
218 cc = song->control_ratio;
219 if (update_signal(song, v))
220 return; /* Envelope ran out */
221 left = vp->left_mix;
222 right = vp->right_mix;
223 }
224 else
225 {
226 vp->control_counter = cc - count;
227 while (count--)
228 {
229 s = *sp++;
230 MIXATION(left);
231 MIXATION(right);
232 }
233 return;
234 }
235 }
236
237 static void mix_center_signal(MidSong *song, sample_t *sp, sint32 *lp, int v,
238 int count)
239 {
240 MidVoice *vp = song->voice + v;
241 final_volume_t
242 left=vp->left_mix;
243 int cc;
244 sample_t s;
245
246 if (!(cc = vp->control_counter))
247 {
248 cc = song->control_ratio;
249 if (update_signal(song, v))
250 return; /* Envelope ran out */
251 left = vp->left_mix;
252 }
253
254 while (count)
255 if (cc < count)
256 {
257 count -= cc;
258 while (cc--)
259 {
260 s = *sp++;
261 MIXATION(left);
262 MIXATION(left);
263 }
264 cc = song->control_ratio;
265 if (update_signal(song, v))
266 return; /* Envelope ran out */
267 left = vp->left_mix;
268 }
269 else
270 {
271 vp->control_counter = cc - count;
272 while (count--)
273 {
274 s = *sp++;
275 MIXATION(left);
276 MIXATION(left);
277 }
278 return;
279 }
280 }
281
282 static void mix_single_signal(MidSong *song, sample_t *sp, sint32 *lp, int v,
283 int count)
284 {
285 MidVoice *vp = song->voice + v;
286 final_volume_t
287 left=vp->left_mix;
288 int cc;
289 sample_t s;
290
291 if (!(cc = vp->control_counter))
292 {
293 cc = song->control_ratio;
294 if (update_signal(song, v))
295 return; /* Envelope ran out */
296 left = vp->left_mix;
297 }
298
299 while (count)
300 if (cc < count)
301 {
302 count -= cc;
303 while (cc--)
304 {
305 s = *sp++;
306 MIXATION(left);
307 lp++;
308 }
309 cc = song->control_ratio;
310 if (update_signal(song, v))
311 return; /* Envelope ran out */
312 left = vp->left_mix;
313 }
314 else
315 {
316 vp->control_counter = cc - count;
317 while (count--)
318 {
319 s = *sp++;
320 MIXATION(left);
321 lp++;
322 }
323 return;
324 }
325 }
326
327 static void mix_mono_signal(MidSong *song, sample_t *sp, sint32 *lp, int v,
328 int count)
329 {
330 MidVoice *vp = song->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 = song->control_ratio;
339 if (update_signal(song, 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 = song->control_ratio;
354 if (update_signal(song, 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(MidSong *song, sample_t *sp, sint32 *lp, int v, int count)
371 {
372 final_volume_t
373 left = song->voice[v].left_mix,
374 right = song->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(MidSong *song, sample_t *sp, sint32 *lp, int v, int count)
386 {
387 final_volume_t
388 left = song->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(MidSong *song, sample_t *sp, sint32 *lp, int v, int count)
400 {
401 final_volume_t
402 left = song->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(MidSong *song, sample_t *sp, sint32 *lp, int v, int count)
414 {
415 final_volume_t
416 left = song->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(MidSong *song, sample_t *sp, sint32 *lp, int v, sint32 c)
428 {
429
430 /* should be final_volume_t, but uint8 gives trouble. */
431 sint32 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=song->voice[v].left_mix;
439 li=-(left/c);
440 if (!li) li=-1;
441
442 /* printf("Ramping out: left=%d, c=%d, li=%d\n", left, c, li); */
443
444 if (!(song->encoding & PE_MONO))
445 {
446 if (song->voice[v].panned==PANNED_MYSTERY)
447 {
448 right=song->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 (song->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 (song->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 (song->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(MidSong *song, sint32 *buf, int v, sint32 c)
518 {
519 MidVoice *vp = song->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(song, v, &c);
526 ramp_out(song, sp, buf, v, c);
527 vp->status=VOICE_FREE;
528 }
529 else
530 {
531 sp=resample_voice(song, v, &c);
532 if (song->encoding & PE_MONO)
533 {
534 /* Mono output. */
535 if (vp->envelope_increment || vp->tremolo_phase_increment)
536 mix_mono_signal(song, sp, buf, v, c);
537 else
538 mix_mono(song, 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(song, sp, buf, v, c);
546 else
547 mix_mystery(song, 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(song, sp, buf, v, c);
553 else
554 mix_center(song, 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(song, sp, buf, v, c);
564 else
565 mix_single(song, sp, buf, v, c);
566 }
567 }
568 }
569 }