~ubuntu-branches/ubuntu/karmic/frozen-bubble/karmic

« back to all changes in this revision

Viewing changes to SDL_mixer_patched/timidity/resample.c

  • Committer: Bazaar Package Importer
  • Author(s): Josselin Mouette
  • Date: 2002-04-17 09:21:51 UTC
  • Revision ID: james.westby@ubuntu.com-20020417092151-7ye6ril7bgg9g0he
Tags: upstream-0.9.2
ImportĀ upstreamĀ versionĀ 0.9.2

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
    This program is free software; you can redistribute it and/or modify
 
7
    it under the terms of the GNU General Public License as published by
 
8
    the Free Software Foundation; either version 2 of the License, or
 
9
    (at your option) any later version.
 
10
 
 
11
    This program is distributed in the hope that it will be useful,
 
12
    but WITHOUT ANY WARRANTY; without even the implied warranty of
 
13
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
14
    GNU General Public License for more details.
 
15
 
 
16
    You should have received a copy of the GNU General Public License
 
17
    along with this program; if not, write to the Free Software
 
18
    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 
19
 
 
20
    resample.c
 
21
*/
 
22
 
 
23
#include <math.h>
 
24
#include <stdio.h>
 
25
#include <stdlib.h>
 
26
 
 
27
#include "config.h"
 
28
#include "common.h"
 
29
#include "instrum.h"
 
30
#include "playmidi.h"
 
31
#include "output.h"
 
32
#include "controls.h"
 
33
#include "tables.h"
 
34
#include "resample.h"
 
35
 
 
36
#ifdef LINEAR_INTERPOLATION
 
37
# if defined(LOOKUP_HACK) && defined(LOOKUP_INTERPOLATION)
 
38
#   define RESAMPLATION \
 
39
       v1=src[ofs>>FRACTION_BITS];\
 
40
       v2=src[(ofs>>FRACTION_BITS)+1];\
 
41
       *dest++ = v1 + (iplookup[(((v2-v1)<<5) & 0x03FE0) | \
 
42
           ((ofs & FRACTION_MASK) >> (FRACTION_BITS-5))]);
 
43
# else
 
44
#   define RESAMPLATION \
 
45
      v1=src[ofs>>FRACTION_BITS];\
 
46
      v2=src[(ofs>>FRACTION_BITS)+1];\
 
47
      *dest++ = v1 + (((v2-v1) * (ofs & FRACTION_MASK)) >> FRACTION_BITS);
 
48
# endif
 
49
#  define INTERPVARS sample_t v1, v2
 
50
#else
 
51
/* Earplugs recommended for maximum listening enjoyment */
 
52
#  define RESAMPLATION *dest++=src[ofs>>FRACTION_BITS];
 
53
#  define INTERPVARS
 
54
#endif
 
55
 
 
56
#define FINALINTERP if (ofs == le) *dest++=src[ofs>>FRACTION_BITS];
 
57
/* So it isn't interpolation. At least it's final. */
 
58
 
 
59
extern sample_t *resample_buffer;
 
60
 
 
61
/*************** resampling with fixed increment *****************/
 
62
 
 
63
static sample_t *rs_plain(int v, int32 *countptr)
 
64
{
 
65
 
 
66
  /* Play sample until end, then free the voice. */
 
67
 
 
68
  INTERPVARS;
 
69
  Voice 
 
70
    *vp=&voice[v];
 
71
  sample_t 
 
72
    *dest=resample_buffer,
 
73
    *src=vp->sample->data;
 
74
  int32 
 
75
    ofs=vp->sample_offset,
 
76
    incr=vp->sample_increment,
 
77
    le=vp->sample->data_length,
 
78
    count=*countptr;
 
79
 
 
80
#ifdef PRECALC_LOOPS
 
81
  int32 i;
 
82
 
 
83
  if (incr<0) incr = -incr; /* In case we're coming out of a bidir loop */
 
84
 
 
85
  /* Precalc how many times we should go through the loop.
 
86
     NOTE: Assumes that incr > 0 and that ofs <= le */
 
87
  i = (le - ofs) / incr + 1;
 
88
 
 
89
  if (i > count)
 
90
    {
 
91
      i = count;
 
92
      count = 0;
 
93
    } 
 
94
  else count -= i;
 
95
 
 
96
  while (i--) 
 
97
    {
 
98
      RESAMPLATION;
 
99
      ofs += incr;
 
100
    }
 
101
 
 
102
  if (ofs >= le) 
 
103
    {
 
104
      FINALINTERP;
 
105
      vp->status=VOICE_FREE;
 
106
      ctl->note(v);
 
107
      *countptr-=count+1;
 
108
    }
 
109
 
 
110
#else /* PRECALC_LOOPS */
 
111
    while (count--)
 
112
    {
 
113
      RESAMPLATION;
 
114
      ofs += incr;
 
115
      if (ofs >= le)
 
116
        {
 
117
          FINALINTERP;
 
118
          vp->status=VOICE_FREE;
 
119
          ctl->note(v);
 
120
          *countptr-=count+1;
 
121
          break;
 
122
        }
 
123
    }
 
124
#endif /* PRECALC_LOOPS */
 
125
  
 
126
  vp->sample_offset=ofs; /* Update offset */
 
127
  return resample_buffer;
 
128
}
 
129
 
 
130
static sample_t *rs_loop(Voice *vp, int32 count)
 
131
{
 
132
 
 
133
  /* Play sample until end-of-loop, skip back and continue. */
 
134
 
 
135
  INTERPVARS;
 
136
  int32 
 
137
    ofs=vp->sample_offset, 
 
138
    incr=vp->sample_increment,
 
139
    le=vp->sample->loop_end, 
 
140
    ll=le - vp->sample->loop_start;
 
141
  sample_t
 
142
    *dest=resample_buffer,
 
143
    *src=vp->sample->data;
 
144
 
 
145
#ifdef PRECALC_LOOPS
 
146
  int32 i;
 
147
  
 
148
  while (count) 
 
149
    {
 
150
      if (ofs >= le)
 
151
        /* NOTE: Assumes that ll > incr and that incr > 0. */
 
152
        ofs -= ll;
 
153
      /* Precalc how many times we should go through the loop */
 
154
      i = (le - ofs) / incr + 1;
 
155
      if (i > count) 
 
156
        {
 
157
          i = count;
 
158
          count = 0;
 
159
        } 
 
160
      else count -= i;
 
161
      while (i--) 
 
162
        {
 
163
          RESAMPLATION;
 
164
          ofs += incr;
 
165
        }
 
166
    }
 
167
#else
 
168
  while (count--)
 
169
    {
 
170
      RESAMPLATION;
 
171
      ofs += incr;
 
172
      if (ofs>=le)
 
173
        ofs -= ll; /* Hopefully the loop is longer than an increment. */
 
174
    }
 
175
#endif
 
176
 
 
177
  vp->sample_offset=ofs; /* Update offset */
 
178
  return resample_buffer;
 
179
}
 
180
 
 
181
static sample_t *rs_bidir(Voice *vp, int32 count)
 
182
{
 
183
  INTERPVARS;
 
184
  int32 
 
185
    ofs=vp->sample_offset,
 
186
    incr=vp->sample_increment,
 
187
    le=vp->sample->loop_end,
 
188
    ls=vp->sample->loop_start;
 
189
  sample_t 
 
190
    *dest=resample_buffer, 
 
191
    *src=vp->sample->data;
 
192
 
 
193
#ifdef PRECALC_LOOPS
 
194
  int32
 
195
    le2 = le<<1, 
 
196
    ls2 = ls<<1,
 
197
    i;
 
198
  /* Play normally until inside the loop region */
 
199
 
 
200
  if (ofs <= ls) 
 
201
    {
 
202
      /* NOTE: Assumes that incr > 0, which is NOT always the case
 
203
         when doing bidirectional looping.  I have yet to see a case
 
204
         where both ofs <= ls AND incr < 0, however. */
 
205
      i = (ls - ofs) / incr + 1;
 
206
      if (i > count) 
 
207
        {
 
208
          i = count;
 
209
          count = 0;
 
210
        } 
 
211
      else count -= i;
 
212
      while (i--) 
 
213
        {
 
214
          RESAMPLATION;
 
215
          ofs += incr;
 
216
        }
 
217
    }
 
218
 
 
219
  /* Then do the bidirectional looping */
 
220
  
 
221
  while(count) 
 
222
    {
 
223
      /* Precalc how many times we should go through the loop */
 
224
      i = ((incr > 0 ? le : ls) - ofs) / incr + 1;
 
225
      if (i > count) 
 
226
        {
 
227
          i = count;
 
228
          count = 0;
 
229
        } 
 
230
      else count -= i;
 
231
      while (i--) 
 
232
        {
 
233
          RESAMPLATION;
 
234
          ofs += incr;
 
235
        }
 
236
      if (ofs>=le) 
 
237
        {
 
238
          /* fold the overshoot back in */
 
239
          ofs = le2 - ofs;
 
240
          incr *= -1;
 
241
        } 
 
242
      else if (ofs <= ls) 
 
243
        {
 
244
          ofs = ls2 - ofs;
 
245
          incr *= -1;
 
246
        }
 
247
    }
 
248
 
 
249
#else /* PRECALC_LOOPS */
 
250
  /* Play normally until inside the loop region */
 
251
 
 
252
  if (ofs < ls)
 
253
    {
 
254
      while (count--)
 
255
        {
 
256
          RESAMPLATION;
 
257
          ofs += incr;
 
258
          if (ofs>=ls)
 
259
            break;
 
260
        }
 
261
    }
 
262
 
 
263
  /* Then do the bidirectional looping */
 
264
 
 
265
  if (count>0)
 
266
    while (count--)
 
267
      {
 
268
        RESAMPLATION;
 
269
        ofs += incr;
 
270
        if (ofs>=le)
 
271
          {
 
272
            /* fold the overshoot back in */
 
273
            ofs = le - (ofs - le);
 
274
            incr = -incr;
 
275
          }
 
276
        else if (ofs <= ls)
 
277
          {
 
278
            ofs = ls + (ls - ofs);
 
279
            incr = -incr;
 
280
          }
 
281
      }  
 
282
#endif /* PRECALC_LOOPS */
 
283
  vp->sample_increment=incr;
 
284
  vp->sample_offset=ofs; /* Update offset */
 
285
  return resample_buffer;
 
286
}
 
287
 
 
288
/*********************** vibrato versions ***************************/
 
289
 
 
290
/* We only need to compute one half of the vibrato sine cycle */
 
291
static int vib_phase_to_inc_ptr(int phase)
 
292
{
 
293
  if (phase < VIBRATO_SAMPLE_INCREMENTS/2)
 
294
    return VIBRATO_SAMPLE_INCREMENTS/2-1-phase;
 
295
  else if (phase >= 3*VIBRATO_SAMPLE_INCREMENTS/2)
 
296
    return 5*VIBRATO_SAMPLE_INCREMENTS/2-1-phase;
 
297
  else
 
298
    return phase-VIBRATO_SAMPLE_INCREMENTS/2;
 
299
}
 
300
 
 
301
static int32 update_vibrato(Voice *vp, int sign)
 
302
{
 
303
  int32 depth;
 
304
  int phase, pb;
 
305
  double a;
 
306
 
 
307
  if (vp->vibrato_phase++ >= 2*VIBRATO_SAMPLE_INCREMENTS-1)
 
308
    vp->vibrato_phase=0;
 
309
  phase=vib_phase_to_inc_ptr(vp->vibrato_phase);
 
310
  
 
311
  if (vp->vibrato_sample_increment[phase])
 
312
    {
 
313
      if (sign)
 
314
        return -vp->vibrato_sample_increment[phase];
 
315
      else
 
316
        return vp->vibrato_sample_increment[phase];
 
317
    }
 
318
 
 
319
  /* Need to compute this sample increment. */
 
320
    
 
321
  depth=vp->sample->vibrato_depth<<7;
 
322
 
 
323
  if (vp->vibrato_sweep)
 
324
    {
 
325
      /* Need to update sweep */
 
326
      vp->vibrato_sweep_position += vp->vibrato_sweep;
 
327
      if (vp->vibrato_sweep_position >= (1<<SWEEP_SHIFT))
 
328
        vp->vibrato_sweep=0;
 
329
      else
 
330
        {
 
331
          /* Adjust depth */
 
332
          depth *= vp->vibrato_sweep_position;
 
333
          depth >>= SWEEP_SHIFT;
 
334
        }
 
335
    }
 
336
 
 
337
  a = FSCALE(((double)(vp->sample->sample_rate) *
 
338
              (double)(vp->frequency)) /
 
339
             ((double)(vp->sample->root_freq) *
 
340
              (double)(play_mode->rate)),
 
341
             FRACTION_BITS);
 
342
 
 
343
  pb=(int)((sine(vp->vibrato_phase * 
 
344
                 (SINE_CYCLE_LENGTH/(2*VIBRATO_SAMPLE_INCREMENTS)))
 
345
            * (double)(depth) * VIBRATO_AMPLITUDE_TUNING));
 
346
 
 
347
  if (pb<0)
 
348
    {
 
349
      pb=-pb;
 
350
      a /= bend_fine[(pb>>5) & 0xFF] * bend_coarse[pb>>13];
 
351
    }
 
352
  else
 
353
    a *= bend_fine[(pb>>5) & 0xFF] * bend_coarse[pb>>13];
 
354
  
 
355
  /* If the sweep's over, we can store the newly computed sample_increment */
 
356
  if (!vp->vibrato_sweep)
 
357
    vp->vibrato_sample_increment[phase]=(int32) a;
 
358
 
 
359
  if (sign)
 
360
    a = -a; /* need to preserve the loop direction */
 
361
 
 
362
  return (int32) a;
 
363
}
 
364
 
 
365
static sample_t *rs_vib_plain(int v, int32 *countptr)
 
366
{
 
367
 
 
368
  /* Play sample until end, then free the voice. */
 
369
 
 
370
  INTERPVARS;
 
371
  Voice *vp=&voice[v];
 
372
  sample_t 
 
373
    *dest=resample_buffer, 
 
374
    *src=vp->sample->data;
 
375
  int32 
 
376
    le=vp->sample->data_length,
 
377
    ofs=vp->sample_offset, 
 
378
    incr=vp->sample_increment, 
 
379
    count=*countptr;
 
380
  int 
 
381
    cc=vp->vibrato_control_counter;
 
382
 
 
383
  /* This has never been tested */
 
384
 
 
385
  if (incr<0) incr = -incr; /* In case we're coming out of a bidir loop */
 
386
 
 
387
  while (count--)
 
388
    {
 
389
      if (!cc--)
 
390
        {
 
391
          cc=vp->vibrato_control_ratio;
 
392
          incr=update_vibrato(vp, 0);
 
393
        }
 
394
      RESAMPLATION;
 
395
      ofs += incr;
 
396
      if (ofs >= le)
 
397
        {
 
398
          FINALINTERP;
 
399
          vp->status=VOICE_FREE;
 
400
          ctl->note(v);
 
401
          *countptr-=count+1;
 
402
          break;
 
403
        }
 
404
    }
 
405
  
 
406
  vp->vibrato_control_counter=cc;
 
407
  vp->sample_increment=incr;
 
408
  vp->sample_offset=ofs; /* Update offset */
 
409
  return resample_buffer;
 
410
}
 
411
 
 
412
static sample_t *rs_vib_loop(Voice *vp, int32 count)
 
413
{
 
414
 
 
415
  /* Play sample until end-of-loop, skip back and continue. */
 
416
  
 
417
  INTERPVARS;
 
418
  int32 
 
419
    ofs=vp->sample_offset, 
 
420
    incr=vp->sample_increment, 
 
421
    le=vp->sample->loop_end,
 
422
    ll=le - vp->sample->loop_start;
 
423
  sample_t 
 
424
    *dest=resample_buffer, 
 
425
    *src=vp->sample->data;
 
426
  int 
 
427
    cc=vp->vibrato_control_counter;
 
428
 
 
429
#ifdef PRECALC_LOOPS
 
430
  int32 i;
 
431
  int
 
432
    vibflag=0;
 
433
 
 
434
  while (count) 
 
435
    {
 
436
      /* Hopefully the loop is longer than an increment */
 
437
      if(ofs >= le)
 
438
        ofs -= ll;
 
439
      /* Precalc how many times to go through the loop, taking
 
440
         the vibrato control ratio into account this time. */
 
441
      i = (le - ofs) / incr + 1;
 
442
      if(i > count) i = count;
 
443
      if(i > cc)
 
444
        {
 
445
          i = cc;
 
446
          vibflag = 1;
 
447
        } 
 
448
      else cc -= i;
 
449
      count -= i;
 
450
      while(i--) 
 
451
        {
 
452
          RESAMPLATION;
 
453
          ofs += incr;
 
454
        }
 
455
      if(vibflag) 
 
456
        {
 
457
          cc = vp->vibrato_control_ratio;
 
458
          incr = update_vibrato(vp, 0);
 
459
          vibflag = 0;
 
460
        }
 
461
    }
 
462
 
 
463
#else /* PRECALC_LOOPS */
 
464
  while (count--)
 
465
    {
 
466
      if (!cc--)
 
467
        {
 
468
          cc=vp->vibrato_control_ratio;
 
469
          incr=update_vibrato(vp, 0);
 
470
        }
 
471
      RESAMPLATION;
 
472
      ofs += incr;
 
473
      if (ofs>=le)
 
474
        ofs -= ll; /* Hopefully the loop is longer than an increment. */
 
475
    }
 
476
#endif /* PRECALC_LOOPS */
 
477
 
 
478
  vp->vibrato_control_counter=cc;
 
479
  vp->sample_increment=incr;
 
480
  vp->sample_offset=ofs; /* Update offset */
 
481
  return resample_buffer;
 
482
}
 
483
 
 
484
static sample_t *rs_vib_bidir(Voice *vp, int32 count)
 
485
{
 
486
  INTERPVARS;
 
487
  int32 
 
488
    ofs=vp->sample_offset, 
 
489
    incr=vp->sample_increment,
 
490
    le=vp->sample->loop_end, 
 
491
    ls=vp->sample->loop_start;
 
492
  sample_t 
 
493
    *dest=resample_buffer, 
 
494
    *src=vp->sample->data;
 
495
  int 
 
496
    cc=vp->vibrato_control_counter;
 
497
 
 
498
#ifdef PRECALC_LOOPS
 
499
  int32
 
500
    le2=le<<1,
 
501
    ls2=ls<<1,
 
502
    i;
 
503
  int
 
504
    vibflag = 0;
 
505
 
 
506
  /* Play normally until inside the loop region */
 
507
  while (count && (ofs <= ls)) 
 
508
    {
 
509
      i = (ls - ofs) / incr + 1;
 
510
      if (i > count) i = count;
 
511
      if (i > cc) 
 
512
        {
 
513
          i = cc;
 
514
          vibflag = 1;
 
515
        } 
 
516
      else cc -= i;
 
517
      count -= i;
 
518
      while (i--) 
 
519
        {
 
520
          RESAMPLATION;
 
521
          ofs += incr;
 
522
        }
 
523
      if (vibflag) 
 
524
        {
 
525
          cc = vp->vibrato_control_ratio;
 
526
          incr = update_vibrato(vp, 0);
 
527
          vibflag = 0;
 
528
        }
 
529
    }
 
530
  
 
531
  /* Then do the bidirectional looping */
 
532
 
 
533
  while (count) 
 
534
    {
 
535
      /* Precalc how many times we should go through the loop */
 
536
      i = ((incr > 0 ? le : ls) - ofs) / incr + 1;
 
537
      if(i > count) i = count;
 
538
      if(i > cc) 
 
539
        {
 
540
          i = cc;
 
541
          vibflag = 1;
 
542
        } 
 
543
      else cc -= i;
 
544
      count -= i;
 
545
      while (i--) 
 
546
        {
 
547
          RESAMPLATION;
 
548
          ofs += incr;
 
549
        }
 
550
      if (vibflag) 
 
551
        {
 
552
          cc = vp->vibrato_control_ratio;
 
553
          incr = update_vibrato(vp, (incr < 0));
 
554
          vibflag = 0;
 
555
        }
 
556
      if (ofs >= le) 
 
557
        {
 
558
          /* fold the overshoot back in */
 
559
          ofs = le2 - ofs;
 
560
          incr *= -1;
 
561
        } 
 
562
      else if (ofs <= ls) 
 
563
        {
 
564
          ofs = ls2 - ofs;
 
565
          incr *= -1;
 
566
        }
 
567
    }
 
568
 
 
569
#else /* PRECALC_LOOPS */
 
570
  /* Play normally until inside the loop region */
 
571
 
 
572
  if (ofs < ls)
 
573
    {
 
574
      while (count--)
 
575
        {
 
576
          if (!cc--)
 
577
            {
 
578
              cc=vp->vibrato_control_ratio;
 
579
              incr=update_vibrato(vp, 0);
 
580
            }
 
581
          RESAMPLATION;
 
582
          ofs += incr;
 
583
          if (ofs>=ls)
 
584
            break;
 
585
        }
 
586
    }
 
587
 
 
588
  /* Then do the bidirectional looping */
 
589
 
 
590
  if (count>0)
 
591
    while (count--)
 
592
      {
 
593
        if (!cc--)
 
594
          {
 
595
            cc=vp->vibrato_control_ratio;
 
596
            incr=update_vibrato(vp, (incr < 0));
 
597
          }
 
598
        RESAMPLATION;
 
599
        ofs += incr;
 
600
        if (ofs>=le)
 
601
          {
 
602
            /* fold the overshoot back in */
 
603
            ofs = le - (ofs - le);
 
604
            incr = -incr;
 
605
          }
 
606
        else if (ofs <= ls)
 
607
          {
 
608
            ofs = ls + (ls - ofs);
 
609
            incr = -incr;
 
610
          }
 
611
      }
 
612
#endif /* PRECALC_LOOPS */
 
613
 
 
614
  vp->vibrato_control_counter=cc;
 
615
  vp->sample_increment=incr;
 
616
  vp->sample_offset=ofs; /* Update offset */
 
617
  return resample_buffer;
 
618
}
 
619
 
 
620
sample_t *resample_voice(int v, int32 *countptr)
 
621
{
 
622
  int32 ofs;
 
623
  uint8 modes;
 
624
  Voice *vp=&voice[v];
 
625
  
 
626
  if (!(vp->sample->sample_rate))
 
627
    {
 
628
      /* Pre-resampled data -- just update the offset and check if
 
629
         we're out of data. */
 
630
      ofs=vp->sample_offset >> FRACTION_BITS; /* Kind of silly to use
 
631
                                                 FRACTION_BITS here... */
 
632
      if (*countptr >= (vp->sample->data_length>>FRACTION_BITS) - ofs)
 
633
        {
 
634
          /* Note finished. Free the voice. */
 
635
          vp->status = VOICE_FREE;
 
636
          ctl->note(v);
 
637
          
 
638
          /* Let the caller know how much data we had left */
 
639
          *countptr = (vp->sample->data_length>>FRACTION_BITS) - ofs;
 
640
        }
 
641
      else
 
642
        vp->sample_offset += *countptr << FRACTION_BITS;
 
643
      
 
644
      return vp->sample->data+ofs;
 
645
    }
 
646
 
 
647
  /* Need to resample. Use the proper function. */
 
648
  modes=vp->sample->modes;
 
649
 
 
650
  if (vp->vibrato_control_ratio)
 
651
    {
 
652
      if ((modes & MODES_LOOPING) &&
 
653
          ((modes & MODES_ENVELOPE) ||
 
654
           (vp->status==VOICE_ON || vp->status==VOICE_SUSTAINED)))
 
655
        {
 
656
          if (modes & MODES_PINGPONG)
 
657
            return rs_vib_bidir(vp, *countptr);
 
658
          else
 
659
            return rs_vib_loop(vp, *countptr);
 
660
        }
 
661
      else
 
662
        return rs_vib_plain(v, countptr);
 
663
    }
 
664
  else
 
665
    {
 
666
      if ((modes & MODES_LOOPING) &&
 
667
          ((modes & MODES_ENVELOPE) ||
 
668
           (vp->status==VOICE_ON || vp->status==VOICE_SUSTAINED)))
 
669
        {
 
670
          if (modes & MODES_PINGPONG)
 
671
            return rs_bidir(vp, *countptr);
 
672
          else
 
673
            return rs_loop(vp, *countptr);
 
674
        }
 
675
      else
 
676
        return rs_plain(v, countptr);
 
677
    }
 
678
}
 
679
 
 
680
void pre_resample(Sample * sp)
 
681
{
 
682
  double a, xdiff;
 
683
  int32 incr, ofs, newlen, count;
 
684
  int16 *newdata, *dest, *src = (int16 *) sp->data;
 
685
  int16 v1, v2, v3, v4, *vptr;
 
686
  static const char note_name[12][3] =
 
687
  {
 
688
    "C", "C#", "D", "D#", "E", "F", "F#", "G", "G#", "A", "A#", "B"
 
689
  };
 
690
 
 
691
  ctl->cmsg(CMSG_INFO, VERB_NOISY, " * pre-resampling for note %d (%s%d)",
 
692
            sp->note_to_use,
 
693
            note_name[sp->note_to_use % 12], (sp->note_to_use & 0x7F) / 12);
 
694
 
 
695
  a = ((double) (sp->sample_rate) * freq_table[(int) (sp->note_to_use)]) /
 
696
    ((double) (sp->root_freq) * play_mode->rate);
 
697
  newlen = (int32)(sp->data_length / a);
 
698
  dest = newdata = safe_malloc(newlen >> (FRACTION_BITS - 1));
 
699
 
 
700
  count = (newlen >> FRACTION_BITS) - 1;
 
701
  ofs = incr = (sp->data_length - (1 << FRACTION_BITS)) / count;
 
702
 
 
703
  if (--count)
 
704
    *dest++ = src[0];
 
705
 
 
706
  /* Since we're pre-processing and this doesn't have to be done in
 
707
     real-time, we go ahead and do the full sliding cubic interpolation. */
 
708
  while (--count)
 
709
    {
 
710
      vptr = src + (ofs >> FRACTION_BITS);
 
711
      v1 = *(vptr - 1);
 
712
      v2 = *vptr;
 
713
      v3 = *(vptr + 1);
 
714
      v4 = *(vptr + 2);
 
715
      xdiff = FSCALENEG(ofs & FRACTION_MASK, FRACTION_BITS);
 
716
      *dest++ = (int16)(v2 + (xdiff / 6.0) * (-2 * v1 - 3 * v2 + 6 * v3 - v4 +
 
717
      xdiff * (3 * (v1 - 2 * v2 + v3) + xdiff * (-v1 + 3 * (v2 - v3) + v4))));
 
718
      ofs += incr;
 
719
    }
 
720
 
 
721
  if (ofs & FRACTION_MASK)
 
722
    {
 
723
      v1 = src[ofs >> FRACTION_BITS];
 
724
      v2 = src[(ofs >> FRACTION_BITS) + 1];
 
725
      *dest++ = v1 + (((v2 - v1) * (ofs & FRACTION_MASK)) >> FRACTION_BITS);
 
726
    }
 
727
  else
 
728
    *dest++ = src[ofs >> FRACTION_BITS];
 
729
 
 
730
  sp->data_length = newlen;
 
731
  sp->loop_start = (int32)(sp->loop_start / a);
 
732
  sp->loop_end = (int32)(sp->loop_end / a);
 
733
  free(sp->data);
 
734
  sp->data = (sample_t *) newdata;
 
735
  sp->sample_rate = 0;
 
736
}