~ubuntu-branches/ubuntu/breezy/kdemultimedia/breezy

« back to all changes in this revision

Viewing changes to kmidi/mix.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Jonathan Riddell
  • Date: 2005-03-24 04:48:58 UTC
  • mfrom: (1.2.1 upstream) (2.1.1 sarge)
  • Revision ID: james.westby@ubuntu.com-20050324044858-8ff88o9jxej6ii3d
Tags: 4:3.4.0-0ubuntu3
Add kubuntu_02_hide_arts_menu_entries.diff to hide artsbuilder and artscontrol k-menu entries

Show diffs side-by-side

added added

removed removed

Lines of Context:
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 0
46
 
if (voice[v].envelope_offset[stage] >> 23 > 127)
47
 
fprintf(stderr, "offset %d\n", voice[v].envelope_offset[stage]>>23);
48
 
#endif
49
 
 
50
 
  if (stage>5)
51
 
    {
52
 
      /* Envelope ran out. */
53
 
      if (!(voice[v].status & VOICE_FREE))
54
 
        {
55
 
          voice[v].status = VOICE_FREE;
56
 
          ctl->note(v);
57
 
        }
58
 
      return 1;
59
 
    }
60
 
 
61
 
  /**if (voice[v].sample->modes & MODES_ENVELOPE)**/
62
 
  if ((voice[v].sample->modes & MODES_ENVELOPE) && (voice[v].sample->modes & MODES_SUSTAIN))
63
 
    {
64
 
      if (voice[v].status & (VOICE_ON | VOICE_SUSTAINED))
65
 
        {
66
 
          if (stage>2)
67
 
            {
68
 
              /* Freeze envelope until note turns off. Trumpets want this. */
69
 
              voice[v].envelope_increment=0;
70
 
              return 0;
71
 
            }
72
 
        }
73
 
    }
74
 
  voice[v].envelope_stage=stage+1;
75
 
 
76
 
#if 0
77
 
fprintf(stderr, "v=%d stage %d, inc %ld[%ld], vol %ld[%ld], offset %ld[%ld]\n", v,
78
 
stage, voice[v].envelope_increment, voice[v].envelope_increment>>23,
79
 
 voice[v].envelope_volume, voice[v].envelope_volume>>23,
80
 
 voice[v].envelope_offset[stage], voice[v].envelope_offset[stage]>>23);
81
 
#endif
82
 
 
83
 
 
84
 
#ifdef tplus
85
 
  if (voice[v].envelope_volume==(int)voice[v].envelope_offset[stage] ||
86
 
      (stage > 2 && voice[v].envelope_volume < (int)voice[v].envelope_offset[stage]))
87
 
#else
88
 
  if (voice[v].envelope_volume==voice[v].envelope_offset[stage])
89
 
#endif
90
 
 
91
 
#if 0
92
 
  if ( (voice[v].envelope_increment >= 0 && voice[v].envelope_volume >= voice[v].envelope_offset[stage])
93
 
    || (voice[v].envelope_increment < 0  && voice[v].envelope_volume <= voice[v].envelope_offset[stage]) )
94
 
#endif
95
 
    return recompute_envelope(v);
96
 
  voice[v].envelope_target=voice[v].envelope_offset[stage];
97
 
  voice[v].envelope_increment = voice[v].envelope_rate[stage];
98
 
  if ((int)voice[v].envelope_target<voice[v].envelope_volume)
99
 
    voice[v].envelope_increment = -voice[v].envelope_increment;
100
 
 
101
 
#if 0
102
 
fprintf(stderr, "       cont:v=%d, stage %d, inc %ld[%ld], vol %ld[%ld], offset %ld[%ld]\n", v,
103
 
stage, voice[v].envelope_increment, voice[v].envelope_increment>>23,
104
 
 voice[v].envelope_volume, voice[v].envelope_volume>>23,
105
 
 voice[v].envelope_offset[stage], voice[v].envelope_offset[stage]>>23);
106
 
#endif
107
 
 
108
 
 
109
 
 
110
 
 
111
 
  return 0;
112
 
}
113
 
 
114
 
#ifdef tplus
115
 
int apply_envelope_to_amp(int v)
116
 
#else
117
 
void apply_envelope_to_amp(int v)
118
 
#endif
119
 
{
120
 
  FLOAT_T lamp=voice[v].left_amp, ramp;
121
 
  int32 la,ra;
122
 
  if (voice[v].panned == PANNED_MYSTERY)
123
 
    {
124
 
      ramp=voice[v].right_amp;
125
 
      if (voice[v].tremolo_phase_increment)
126
 
        {
127
 
          lamp *= voice[v].tremolo_volume;
128
 
          ramp *= voice[v].tremolo_volume;
129
 
        }
130
 
      if (voice[v].sample->modes & MODES_ENVELOPE)
131
 
        {
132
 
          lamp *= vol_table[voice[v].envelope_volume>>23];
133
 
          ramp *= vol_table[voice[v].envelope_volume>>23];
134
 
#if 0
135
 
if (voice[v].envelope_volume>>23 > 127)
136
 
fprintf(stderr,"env vol %d >>23 = %d\n", voice[v].envelope_volume,
137
 
voice[v].envelope_volume >> 23);
138
 
#endif
139
 
        }
140
 
 
141
 
      la = (int32)FRSCALE(lamp,AMP_BITS);
142
 
      
143
 
      if (la>MAX_AMP_VALUE)
144
 
        la=MAX_AMP_VALUE;
145
 
 
146
 
      ra = (int32)FRSCALE(ramp,AMP_BITS);
147
 
      if (ra>MAX_AMP_VALUE)
148
 
        ra=MAX_AMP_VALUE;
149
 
 
150
 
#ifdef tplus
151
 
      if ((voice[v].status & (VOICE_OFF | VOICE_DIE | VOICE_FREE | VOICE_SUSTAINED))
152
 
          && (la | ra) <= MIN_AMP_VALUE)
153
 
      {
154
 
          if (!(voice[v].status & VOICE_FREE))
155
 
            {
156
 
              voice[v].status = VOICE_FREE;
157
 
              ctl->note(v);
158
 
            }
159
 
          return 1;
160
 
      }
161
 
#endif
162
 
 
163
 
      voice[v].left_mix=FINAL_VOLUME(la);
164
 
      voice[v].right_mix=FINAL_VOLUME(ra);
165
 
    }
166
 
  else
167
 
    {
168
 
      if (voice[v].tremolo_phase_increment)
169
 
        lamp *= voice[v].tremolo_volume;
170
 
      if (voice[v].sample->modes & MODES_ENVELOPE)
171
 
        lamp *= vol_table[voice[v].envelope_volume>>23];
172
 
 
173
 
      la = (int32)FRSCALE(lamp,AMP_BITS);
174
 
 
175
 
      if (la>MAX_AMP_VALUE)
176
 
        la=MAX_AMP_VALUE;
177
 
 
178
 
#ifdef tplus
179
 
      if ( (voice[v].status & (VOICE_OFF | VOICE_DIE | VOICE_FREE | VOICE_SUSTAINED))
180
 
         && la <= MIN_AMP_VALUE)
181
 
      {
182
 
          if (!(voice[v].status & VOICE_FREE))
183
 
            {
184
 
              voice[v].status = VOICE_FREE;
185
 
              ctl->note(v);
186
 
            }
187
 
          return 1;
188
 
      }
189
 
#endif
190
 
 
191
 
      voice[v].left_mix=FINAL_VOLUME(la);
192
 
    }
193
 
#ifdef tplus
194
 
    return 0;
195
 
#endif
196
 
}
197
 
 
198
 
static int update_envelope(int v)
199
 
{
200
 
  voice[v].envelope_volume += voice[v].envelope_increment;
201
 
  if (voice[v].envelope_volume<0) voice[v].envelope_volume = 0;
202
 
  /* Why is there no ^^ operator?? */
203
 
  if (((voice[v].envelope_increment < 0) &&
204
 
       (voice[v].envelope_volume <= (int)voice[v].envelope_target)) ||
205
 
      ((voice[v].envelope_increment > 0) &&
206
 
           (voice[v].envelope_volume >= (int)voice[v].envelope_target)))
207
 
    {
208
 
      voice[v].envelope_volume = voice[v].envelope_target;
209
 
      if (recompute_envelope(v))
210
 
        return 1;
211
 
    }
212
 
  return 0;
213
 
}
214
 
 
215
 
static void update_tremolo(int v)
216
 
{
217
 
  int32 depth=voice[v].sample->tremolo_depth<<7;
218
 
 
219
 
  if (voice[v].tremolo_sweep)
220
 
    {
221
 
      /* Update sweep position */
222
 
 
223
 
      voice[v].tremolo_sweep_position += voice[v].tremolo_sweep;
224
 
      if (voice[v].tremolo_sweep_position>=(1<<SWEEP_SHIFT))
225
 
        voice[v].tremolo_sweep=0; /* Swept to max amplitude */
226
 
      else
227
 
        {
228
 
          /* Need to adjust depth */
229
 
          depth *= voice[v].tremolo_sweep_position;
230
 
          depth >>= SWEEP_SHIFT;
231
 
        }
232
 
    }
233
 
 
234
 
  voice[v].tremolo_phase += voice[v].tremolo_phase_increment;
235
 
 
236
 
  /* if (voice[v].tremolo_phase >= (SINE_CYCLE_LENGTH<<RATE_SHIFT))
237
 
     voice[v].tremolo_phase -= SINE_CYCLE_LENGTH<<RATE_SHIFT;  */
238
 
 
239
 
  voice[v].tremolo_volume = 
240
 
    1.0 - FRSCALENEG((sine(voice[v].tremolo_phase >> RATE_SHIFT) + 1.0)
241
 
                    * depth * TREMOLO_AMPLITUDE_TUNING,
242
 
                    17);
243
 
 
244
 
  /* I'm not sure about the +1.0 there -- it makes tremoloed voices'
245
 
     volumes on average the lower the higher the tremolo amplitude. */
246
 
}
247
 
 
248
 
/* Returns 1 if the note died */
249
 
static int update_signal(int v)
250
 
{
251
 
  if (voice[v].envelope_increment && update_envelope(v))
252
 
    return 1;
253
 
 
254
 
  if (voice[v].tremolo_phase_increment)
255
 
    update_tremolo(v);
256
 
 
257
 
#ifdef tplus
258
 
  return apply_envelope_to_amp(v);
259
 
#else
260
 
  apply_envelope_to_amp(v);
261
 
  return 0;
262
 
#endif
263
 
}
264
 
 
265
 
#ifdef LOOKUP_HACK
266
 
#  define MIXATION(a)   *lp++ += mixup[(a<<8) | (uint8)s];
267
 
#else
268
 
#  define MIXATION(a)   *lp++ += (a)*s;
269
 
#endif
270
 
 
271
 
static void mix_mystery_signal(sample_t *sp, int32 *lp, int v, uint32 count)
272
 
{
273
 
  Voice *vp = voice + v;
274
 
  final_volume_t 
275
 
    left=vp->left_mix, 
276
 
    right=vp->right_mix;
277
 
  uint32 cc;
278
 
  sample_t s;
279
 
 
280
 
  if (!(cc = vp->control_counter))
281
 
    {
282
 
      cc = control_ratio;
283
 
      if (update_signal(v))
284
 
        return; /* Envelope ran out */
285
 
      left = vp->left_mix;
286
 
      right = vp->right_mix;
287
 
    }
288
 
  
289
 
  while (count)
290
 
    if (cc < count)
291
 
      {
292
 
        count -= cc;
293
 
        while (cc--)
294
 
          {
295
 
            s = *sp++;
296
 
            MIXATION(left);
297
 
            MIXATION(right);
298
 
          }
299
 
        cc = control_ratio;
300
 
        if (update_signal(v))
301
 
          return;       /* Envelope ran out */
302
 
        left = vp->left_mix;
303
 
        right = vp->right_mix;
304
 
      }
305
 
    else
306
 
      {
307
 
        vp->control_counter = cc - count;
308
 
        while (count--)
309
 
          {
310
 
            s = *sp++;
311
 
            MIXATION(left);
312
 
            MIXATION(right);
313
 
          }
314
 
        return;
315
 
      }
316
 
}
317
 
 
318
 
static void mix_center_signal(sample_t *sp, int32 *lp, int v, uint32 count)
319
 
{
320
 
  Voice *vp = voice + v;
321
 
  final_volume_t 
322
 
    left=vp->left_mix;
323
 
  uint32 cc;
324
 
  sample_t s;
325
 
 
326
 
  if (!(cc = vp->control_counter))
327
 
    {
328
 
      cc = control_ratio;
329
 
      if (update_signal(v))
330
 
        return; /* Envelope ran out */
331
 
      left = vp->left_mix;
332
 
    }
333
 
  
334
 
  while (count)
335
 
    if (cc < count)
336
 
      {
337
 
        count -= cc;
338
 
        while (cc--)
339
 
          {
340
 
            s = *sp++;
341
 
            MIXATION(left);
342
 
            MIXATION(left);
343
 
          }
344
 
        cc = control_ratio;
345
 
        if (update_signal(v))
346
 
          return;       /* Envelope ran out */
347
 
        left = vp->left_mix;
348
 
      }
349
 
    else
350
 
      {
351
 
        vp->control_counter = cc - count;
352
 
        while (count--)
353
 
          {
354
 
            s = *sp++;
355
 
            MIXATION(left);
356
 
            MIXATION(left);
357
 
          }
358
 
        return;
359
 
      }
360
 
}
361
 
 
362
 
static void mix_single_signal(sample_t *sp, int32 *lp, int v, uint32 count)
363
 
{
364
 
  Voice *vp = voice + v;
365
 
  final_volume_t 
366
 
    left=vp->left_mix;
367
 
  uint32 cc;
368
 
  sample_t s;
369
 
  
370
 
  if (!(cc = vp->control_counter))
371
 
    {
372
 
      cc = control_ratio;
373
 
      if (update_signal(v))
374
 
        return; /* Envelope ran out */
375
 
      left = vp->left_mix;
376
 
    }
377
 
  
378
 
  while (count)
379
 
    if (cc < count)
380
 
      {
381
 
        count -= cc;
382
 
        while (cc--)
383
 
          {
384
 
            s = *sp++;
385
 
            MIXATION(left);
386
 
            lp++;
387
 
          }
388
 
        cc = control_ratio;
389
 
        if (update_signal(v))
390
 
          return;       /* Envelope ran out */
391
 
        left = vp->left_mix;
392
 
      }
393
 
    else
394
 
      {
395
 
        vp->control_counter = cc - count;
396
 
        while (count--)
397
 
          {
398
 
            s = *sp++;
399
 
            MIXATION(left);
400
 
            lp++;
401
 
          }
402
 
        return;
403
 
      }
404
 
}
405
 
 
406
 
static void mix_mono_signal(sample_t *sp, int32 *lp, int v, uint32 count)
407
 
{
408
 
  Voice *vp = voice + v;
409
 
  final_volume_t 
410
 
    left=vp->left_mix;
411
 
  uint32 cc;
412
 
  sample_t s;
413
 
  
414
 
  if (!(cc = vp->control_counter))
415
 
    {
416
 
      cc = control_ratio;
417
 
      if (update_signal(v))
418
 
        return; /* Envelope ran out */
419
 
      left = vp->left_mix;
420
 
    }
421
 
  
422
 
  while (count)
423
 
    if (cc < count)
424
 
      {
425
 
        count -= cc;
426
 
        while (cc--)
427
 
          {
428
 
            s = *sp++;
429
 
            MIXATION(left);
430
 
          }
431
 
        cc = control_ratio;
432
 
        if (update_signal(v))
433
 
          return;       /* Envelope ran out */
434
 
        left = vp->left_mix;
435
 
      }
436
 
    else
437
 
      {
438
 
        vp->control_counter = cc - count;
439
 
        while (count--)
440
 
          {
441
 
            s = *sp++;
442
 
            MIXATION(left);
443
 
          }
444
 
        return;
445
 
      }
446
 
}
447
 
 
448
 
static void mix_mystery(sample_t *sp, int32 *lp, int v, uint32 count)
449
 
{
450
 
  final_volume_t 
451
 
    left=voice[v].left_mix, 
452
 
    right=voice[v].right_mix;
453
 
  sample_t s;
454
 
  
455
 
  while (count--)
456
 
    {
457
 
      s = *sp++;
458
 
      MIXATION(left);
459
 
      MIXATION(right);
460
 
    }
461
 
}
462
 
 
463
 
static void mix_center(sample_t *sp, int32 *lp, int v, uint32 count)
464
 
{
465
 
  final_volume_t 
466
 
    left=voice[v].left_mix;
467
 
  sample_t s;
468
 
  
469
 
  while (count--)
470
 
    {
471
 
      s = *sp++;
472
 
      MIXATION(left);
473
 
      MIXATION(left);
474
 
    }
475
 
}
476
 
 
477
 
static void mix_single(sample_t *sp, int32 *lp, int v, uint32 count)
478
 
{
479
 
  final_volume_t 
480
 
    left=voice[v].left_mix;
481
 
  sample_t s;
482
 
  
483
 
  while (count--)
484
 
    {
485
 
      s = *sp++;
486
 
      MIXATION(left);
487
 
      lp++;
488
 
    }
489
 
}
490
 
 
491
 
static void mix_mono(sample_t *sp, int32 *lp, int v, uint32 count)
492
 
{
493
 
  final_volume_t 
494
 
    left=voice[v].left_mix;
495
 
  sample_t s;
496
 
  
497
 
  while (count--)
498
 
    {
499
 
      s = *sp++;
500
 
      MIXATION(left);
501
 
    }
502
 
}
503
 
 
504
 
/* Ramp a note out in c samples */
505
 
static void ramp_out(sample_t *sp, int32 *lp, int v, uint32 c)
506
 
{
507
 
 
508
 
  /* should be final_volume_t, but uint8 gives trouble. */
509
 
  int32 left, right, li, ri;
510
 
 
511
 
  sample_t s=0; /* silly warning about uninitialized s */
512
 
 
513
 
  left=voice[v].left_mix;
514
 
  if (c < 1) return;
515
 
  li=-(left/c); /*NB: c can be 0 here */
516
 
  if (!li) li=-1;
517
 
 
518
 
  /* printf("Ramping out: left=%d, c=%d, li=%d\n", left, c, li); */
519
 
 
520
 
  if (!(play_mode->encoding & PE_MONO))
521
 
    {
522
 
      if (voice[v].panned==PANNED_MYSTERY)
523
 
        {
524
 
          right=voice[v].right_mix;
525
 
          ri=-(right/c);
526
 
          while (c--)
527
 
            {
528
 
              left += li;
529
 
              if (left<0)
530
 
                left=0;
531
 
              right += ri;
532
 
              if (right<0)
533
 
                right=0;
534
 
              s=*sp++;
535
 
              MIXATION(left);
536
 
              MIXATION(right);
537
 
            }
538
 
        }
539
 
      else if (voice[v].panned==PANNED_CENTER)
540
 
        {
541
 
          while (c--)
542
 
            {
543
 
              left += li;
544
 
              if (left<0)
545
 
                return;
546
 
              s=*sp++;  
547
 
              MIXATION(left);
548
 
              MIXATION(left);
549
 
            }
550
 
        }
551
 
      else if (voice[v].panned==PANNED_LEFT)
552
 
        {
553
 
          while (c--)
554
 
            {
555
 
              left += li;
556
 
              if (left<0)
557
 
                return;
558
 
              s=*sp++;
559
 
              MIXATION(left);
560
 
              lp++;
561
 
            }
562
 
        }
563
 
      else if (voice[v].panned==PANNED_RIGHT)
564
 
        {
565
 
          while (c--)
566
 
            {
567
 
              left += li;
568
 
              if (left<0)
569
 
                return;
570
 
              s=*sp++;
571
 
              lp++;
572
 
              MIXATION(left);
573
 
            }
574
 
        }
575
 
    }
576
 
  else
577
 
    {
578
 
      /* Mono output.  */
579
 
      while (c--)
580
 
        {
581
 
          left += li;
582
 
          if (left<0)
583
 
            return;
584
 
          s=*sp++;
585
 
          MIXATION(left);
586
 
        }
587
 
    }
588
 
}
589
 
 
590
 
/**************** interface function ******************/
591
 
 
592
 
void mix_voice(int32 *buf, int v, uint32 c)
593
 
{
594
 
  Voice *vp=voice+v;
595
 
  sample_t *sp;
596
 
  uint32 count=c;
597
 
  if (vp->status&VOICE_DIE)
598
 
    {
599
 
/* this seems no longer useful: resample kill voices
600
 
   before they get here
601
 
*/
602
 
      if (count>=MAX_DIE_TIME)
603
 
        count=MAX_DIE_TIME;
604
 
      sp=resample_voice(v, &count);
605
 
      ramp_out(sp, buf, v, count);
606
 
      vp->status=VOICE_FREE;
607
 
    }
608
 
  else
609
 
    {
610
 
      sp=resample_voice(v, &count);
611
 
      if (count<1)
612
 
        {
613
 
          vp->status=VOICE_FREE;
614
 
          return;
615
 
        }
616
 
      if (play_mode->encoding & PE_MONO)
617
 
        {
618
 
          /* Mono output. */
619
 
          if (vp->envelope_increment || vp->tremolo_phase_increment)
620
 
            mix_mono_signal(sp, buf, v, count);
621
 
          else
622
 
            mix_mono(sp, buf, v, count);
623
 
        }
624
 
      else
625
 
        {
626
 
          if (vp->panned == PANNED_MYSTERY)
627
 
            {
628
 
              if (vp->envelope_increment || vp->tremolo_phase_increment)
629
 
                mix_mystery_signal(sp, buf, v, count);
630
 
              else
631
 
                mix_mystery(sp, buf, v, count);
632
 
            }
633
 
          else if (vp->panned == PANNED_CENTER)
634
 
            {
635
 
              if (vp->envelope_increment || vp->tremolo_phase_increment)
636
 
                mix_center_signal(sp, buf, v, count);
637
 
              else
638
 
                mix_center(sp, buf, v, count);
639
 
            }
640
 
          else
641
 
            { 
642
 
              /* It's either full left or full right. In either case,
643
 
                 every other sample is 0. Just get the offset right: */
644
 
              if (vp->panned == PANNED_RIGHT) buf++;
645
 
              
646
 
              if (vp->envelope_increment || vp->tremolo_phase_increment)
647
 
                mix_single_signal(sp, buf, v, count);
648
 
              else 
649
 
                mix_single(sp, buf, v, count);
650
 
            }
651
 
        }
652
 
    }
653
 
}