Mercurial > SDL_sound_CoreAudio
annotate decoders/timidity/resample.c @ 555:3b1d1269e20d stable-1.0
Backport from head: clean up decoder list #ifdefs.
author | Ryan C. Gordon <icculus@icculus.org> |
---|---|
date | Tue, 27 Jan 2009 14:08:54 -0500 |
parents | f33471c47efe |
children |
rev | line source |
---|---|
199 | 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 #if HAVE_CONFIG_H | |
24 # include <config.h> | |
25 #endif | |
26 | |
27 #include <math.h> | |
28 #include <stdio.h> | |
29 #include <stdlib.h> | |
30 | |
31 #include "SDL_sound.h" | |
32 | |
33 #define __SDL_SOUND_INTERNAL__ | |
34 #include "SDL_sound_internal.h" | |
35 | |
36 #include "timidity.h" | |
37 #include "options.h" | |
38 #include "common.h" | |
39 #include "instrum.h" | |
40 #include "playmidi.h" | |
41 #include "tables.h" | |
42 #include "resample.h" | |
43 | |
44 /*************** resampling with fixed increment *****************/ | |
45 | |
46 static sample_t *rs_plain(MidiSong *song, int v, Sint32 *countptr) | |
47 { | |
48 | |
49 /* Play sample until end, then free the voice. */ | |
50 | |
51 sample_t v1, v2; | |
52 Voice | |
53 *vp=&(song->voice[v]); | |
54 sample_t | |
55 *dest=song->resample_buffer, | |
56 *src=vp->sample->data; | |
57 Sint32 | |
58 ofs=vp->sample_offset, | |
59 incr=vp->sample_increment, | |
60 le=vp->sample->data_length, | |
61 count=*countptr; | |
62 Sint32 i; | |
63 | |
64 if (incr<0) incr = -incr; /* In case we're coming out of a bidir loop */ | |
65 | |
66 /* Precalc how many times we should go through the loop. | |
67 NOTE: Assumes that incr > 0 and that ofs <= le */ | |
68 i = (le - ofs) / incr + 1; | |
69 | |
70 if (i > count) | |
71 { | |
72 i = count; | |
73 count = 0; | |
74 } | |
75 else count -= i; | |
76 | |
77 while (i--) | |
78 { | |
79 v1 = src[ofs >> FRACTION_BITS]; | |
80 v2 = src[(ofs >> FRACTION_BITS)+1]; | |
81 *dest++ = v1 + (((v2 - v1) * (ofs & FRACTION_MASK)) >> FRACTION_BITS); | |
82 ofs += incr; | |
83 } | |
84 | |
85 if (ofs >= le) | |
86 { | |
87 if (ofs == le) | |
88 *dest++ = src[ofs >> FRACTION_BITS]; | |
89 vp->status=VOICE_FREE; | |
90 *countptr-=count+1; | |
91 } | |
92 | |
93 vp->sample_offset=ofs; /* Update offset */ | |
94 return song->resample_buffer; | |
95 } | |
96 | |
97 static sample_t *rs_loop(MidiSong *song, Voice *vp, Sint32 count) | |
98 { | |
99 | |
100 /* Play sample until end-of-loop, skip back and continue. */ | |
101 | |
102 sample_t v1, v2; | |
103 Sint32 | |
104 ofs=vp->sample_offset, | |
105 incr=vp->sample_increment, | |
106 le=vp->sample->loop_end, | |
107 ll=le - vp->sample->loop_start; | |
108 sample_t | |
109 *dest=song->resample_buffer, | |
110 *src=vp->sample->data; | |
111 Sint32 i; | |
112 | |
113 while (count) | |
114 { | |
115 if (ofs >= le) | |
116 /* NOTE: Assumes that ll > incr and that incr > 0. */ | |
117 ofs -= ll; | |
118 /* Precalc how many times we should go through the loop */ | |
119 i = (le - ofs) / incr + 1; | |
120 if (i > count) | |
121 { | |
122 i = count; | |
123 count = 0; | |
124 } | |
125 else count -= i; | |
126 while (i--) | |
127 { | |
128 v1 = src[ofs >> FRACTION_BITS]; | |
129 v2 = src[(ofs >> FRACTION_BITS)+1]; | |
130 *dest++ = v1 + (((v2 - v1) * (ofs & FRACTION_MASK)) >> FRACTION_BITS); | |
131 ofs += incr; | |
132 } | |
133 } | |
134 | |
135 vp->sample_offset=ofs; /* Update offset */ | |
136 return song->resample_buffer; | |
137 } | |
138 | |
139 static sample_t *rs_bidir(MidiSong *song, Voice *vp, Sint32 count) | |
140 { | |
141 sample_t v1, v2; | |
142 Sint32 | |
143 ofs=vp->sample_offset, | |
144 incr=vp->sample_increment, | |
145 le=vp->sample->loop_end, | |
146 ls=vp->sample->loop_start; | |
147 sample_t | |
148 *dest=song->resample_buffer, | |
149 *src=vp->sample->data; | |
150 Sint32 | |
151 le2 = le<<1, | |
152 ls2 = ls<<1, | |
153 i; | |
154 /* Play normally until inside the loop region */ | |
155 | |
156 if (ofs <= ls) | |
157 { | |
158 /* NOTE: Assumes that incr > 0, which is NOT always the case | |
159 when doing bidirectional looping. I have yet to see a case | |
160 where both ofs <= ls AND incr < 0, however. */ | |
161 i = (ls - ofs) / incr + 1; | |
162 if (i > count) | |
163 { | |
164 i = count; | |
165 count = 0; | |
166 } | |
167 else count -= i; | |
168 while (i--) | |
169 { | |
170 v1 = src[ofs >> FRACTION_BITS]; | |
171 v2 = src[(ofs >> FRACTION_BITS)+1]; | |
172 *dest++ = v1 + (((v2 - v1) * (ofs & FRACTION_MASK)) >> FRACTION_BITS); | |
173 ofs += incr; | |
174 } | |
175 } | |
176 | |
177 /* Then do the bidirectional looping */ | |
178 | |
179 while(count) | |
180 { | |
181 /* Precalc how many times we should go through the loop */ | |
182 i = ((incr > 0 ? le : ls) - ofs) / incr + 1; | |
183 if (i > count) | |
184 { | |
185 i = count; | |
186 count = 0; | |
187 } | |
188 else count -= i; | |
189 while (i--) | |
190 { | |
191 v1 = src[ofs >> FRACTION_BITS]; | |
192 v2 = src[(ofs >> FRACTION_BITS)+1]; | |
193 *dest++ = v1 + (((v2 - v1) * (ofs & FRACTION_MASK)) >> FRACTION_BITS); | |
194 ofs += incr; | |
195 } | |
196 if (ofs>=le) | |
197 { | |
198 /* fold the overshoot back in */ | |
199 ofs = le2 - ofs; | |
200 incr *= -1; | |
201 } | |
202 else if (ofs <= ls) | |
203 { | |
204 ofs = ls2 - ofs; | |
205 incr *= -1; | |
206 } | |
207 } | |
208 | |
209 vp->sample_increment=incr; | |
210 vp->sample_offset=ofs; /* Update offset */ | |
211 return song->resample_buffer; | |
212 } | |
213 | |
214 /*********************** vibrato versions ***************************/ | |
215 | |
216 /* We only need to compute one half of the vibrato sine cycle */ | |
217 static int vib_phase_to_inc_ptr(int phase) | |
218 { | |
219 if (phase < VIBRATO_SAMPLE_INCREMENTS/2) | |
220 return VIBRATO_SAMPLE_INCREMENTS/2-1-phase; | |
221 else if (phase >= 3*VIBRATO_SAMPLE_INCREMENTS/2) | |
222 return 5*VIBRATO_SAMPLE_INCREMENTS/2-1-phase; | |
223 else | |
224 return phase-VIBRATO_SAMPLE_INCREMENTS/2; | |
225 } | |
226 | |
227 static Sint32 update_vibrato(MidiSong *song, Voice *vp, int sign) | |
228 { | |
229 Sint32 depth; | |
230 int phase, pb; | |
231 double a; | |
232 | |
233 if (vp->vibrato_phase++ >= 2*VIBRATO_SAMPLE_INCREMENTS-1) | |
234 vp->vibrato_phase=0; | |
235 phase=vib_phase_to_inc_ptr(vp->vibrato_phase); | |
236 | |
237 if (vp->vibrato_sample_increment[phase]) | |
238 { | |
239 if (sign) | |
240 return -vp->vibrato_sample_increment[phase]; | |
241 else | |
242 return vp->vibrato_sample_increment[phase]; | |
243 } | |
244 | |
245 /* Need to compute this sample increment. */ | |
246 | |
247 depth=vp->sample->vibrato_depth<<7; | |
248 | |
249 if (vp->vibrato_sweep) | |
250 { | |
251 /* Need to update sweep */ | |
252 vp->vibrato_sweep_position += vp->vibrato_sweep; | |
253 if (vp->vibrato_sweep_position >= (1<<SWEEP_SHIFT)) | |
254 vp->vibrato_sweep=0; | |
255 else | |
256 { | |
257 /* Adjust depth */ | |
258 depth *= vp->vibrato_sweep_position; | |
259 depth >>= SWEEP_SHIFT; | |
260 } | |
261 } | |
262 | |
263 a = FSCALE(((double)(vp->sample->sample_rate) * | |
264 (double)(vp->frequency)) / | |
265 ((double)(vp->sample->root_freq) * | |
266 (double)(song->rate)), | |
267 FRACTION_BITS); | |
268 | |
269 pb=(int)((sine(vp->vibrato_phase * | |
270 (SINE_CYCLE_LENGTH/(2*VIBRATO_SAMPLE_INCREMENTS))) | |
271 * (double)(depth) * VIBRATO_AMPLITUDE_TUNING)); | |
272 | |
273 if (pb<0) | |
274 { | |
275 pb=-pb; | |
276 a /= bend_fine[(pb>>5) & 0xFF] * bend_coarse[pb>>13]; | |
277 } | |
278 else | |
279 a *= bend_fine[(pb>>5) & 0xFF] * bend_coarse[pb>>13]; | |
280 | |
281 /* If the sweep's over, we can store the newly computed sample_increment */ | |
282 if (!vp->vibrato_sweep) | |
283 vp->vibrato_sample_increment[phase]=(Sint32) a; | |
284 | |
285 if (sign) | |
286 a = -a; /* need to preserve the loop direction */ | |
287 | |
288 return (Sint32) a; | |
289 } | |
290 | |
291 static sample_t *rs_vib_plain(MidiSong *song, int v, Sint32 *countptr) | |
292 { | |
293 | |
294 /* Play sample until end, then free the voice. */ | |
295 | |
296 sample_t v1, v2; | |
297 Voice *vp=&(song->voice[v]); | |
298 sample_t | |
299 *dest=song->resample_buffer, | |
300 *src=vp->sample->data; | |
301 Sint32 | |
302 le=vp->sample->data_length, | |
303 ofs=vp->sample_offset, | |
304 incr=vp->sample_increment, | |
305 count=*countptr; | |
306 int | |
307 cc=vp->vibrato_control_counter; | |
308 | |
309 /* This has never been tested */ | |
310 | |
311 if (incr<0) incr = -incr; /* In case we're coming out of a bidir loop */ | |
312 | |
313 while (count--) | |
314 { | |
315 if (!cc--) | |
316 { | |
317 cc=vp->vibrato_control_ratio; | |
318 incr=update_vibrato(song, vp, 0); | |
319 } | |
320 v1 = src[ofs >> FRACTION_BITS]; | |
321 v2 = src[(ofs >> FRACTION_BITS)+1]; | |
322 *dest++ = v1 + (((v2 - v1) * (ofs & FRACTION_MASK)) >> FRACTION_BITS); | |
323 ofs += incr; | |
324 if (ofs >= le) | |
325 { | |
326 if (ofs == le) | |
327 *dest++ = src[ofs >> FRACTION_BITS]; | |
328 vp->status=VOICE_FREE; | |
329 *countptr-=count+1; | |
330 break; | |
331 } | |
332 } | |
333 | |
334 vp->vibrato_control_counter=cc; | |
335 vp->sample_increment=incr; | |
336 vp->sample_offset=ofs; /* Update offset */ | |
337 return song->resample_buffer; | |
338 } | |
339 | |
340 static sample_t *rs_vib_loop(MidiSong *song, Voice *vp, Sint32 count) | |
341 { | |
342 | |
343 /* Play sample until end-of-loop, skip back and continue. */ | |
344 | |
345 sample_t v1, v2; | |
346 Sint32 | |
347 ofs=vp->sample_offset, | |
348 incr=vp->sample_increment, | |
349 le=vp->sample->loop_end, | |
350 ll=le - vp->sample->loop_start; | |
351 sample_t | |
352 *dest=song->resample_buffer, | |
353 *src=vp->sample->data; | |
354 int | |
355 cc=vp->vibrato_control_counter; | |
356 Sint32 i; | |
357 int | |
358 vibflag=0; | |
359 | |
360 while (count) | |
361 { | |
362 /* Hopefully the loop is longer than an increment */ | |
363 if(ofs >= le) | |
364 ofs -= ll; | |
365 /* Precalc how many times to go through the loop, taking | |
366 the vibrato control ratio into account this time. */ | |
367 i = (le - ofs) / incr + 1; | |
368 if(i > count) i = count; | |
369 if(i > cc) | |
370 { | |
371 i = cc; | |
372 vibflag = 1; | |
373 } | |
374 else cc -= i; | |
375 count -= i; | |
376 while(i--) | |
377 { | |
378 v1 = src[ofs >> FRACTION_BITS]; | |
379 v2 = src[(ofs >> FRACTION_BITS)+1]; | |
380 *dest++ = v1 + (((v2 - v1) * (ofs & FRACTION_MASK)) >> FRACTION_BITS); | |
381 ofs += incr; | |
382 } | |
383 if(vibflag) | |
384 { | |
385 cc = vp->vibrato_control_ratio; | |
386 incr = update_vibrato(song, vp, 0); | |
387 vibflag = 0; | |
388 } | |
389 } | |
390 | |
391 vp->vibrato_control_counter=cc; | |
392 vp->sample_increment=incr; | |
393 vp->sample_offset=ofs; /* Update offset */ | |
394 return song->resample_buffer; | |
395 } | |
396 | |
397 static sample_t *rs_vib_bidir(MidiSong *song, Voice *vp, Sint32 count) | |
398 { | |
399 sample_t v1, v2; | |
400 Sint32 | |
401 ofs=vp->sample_offset, | |
402 incr=vp->sample_increment, | |
403 le=vp->sample->loop_end, | |
404 ls=vp->sample->loop_start; | |
405 sample_t | |
406 *dest=song->resample_buffer, | |
407 *src=vp->sample->data; | |
408 int | |
409 cc=vp->vibrato_control_counter; | |
410 Sint32 | |
411 le2=le<<1, | |
412 ls2=ls<<1, | |
413 i; | |
414 int | |
415 vibflag = 0; | |
416 | |
417 /* Play normally until inside the loop region */ | |
418 while (count && (ofs <= ls)) | |
419 { | |
420 i = (ls - ofs) / incr + 1; | |
421 if (i > count) i = count; | |
422 if (i > cc) | |
423 { | |
424 i = cc; | |
425 vibflag = 1; | |
426 } | |
427 else cc -= i; | |
428 count -= i; | |
429 while (i--) | |
430 { | |
431 v1 = src[ofs >> FRACTION_BITS]; | |
432 v2 = src[(ofs >> FRACTION_BITS)+1]; | |
433 *dest++ = v1 + (((v2 - v1) * (ofs & FRACTION_MASK)) >> FRACTION_BITS); | |
434 ofs += incr; | |
435 } | |
436 if (vibflag) | |
437 { | |
438 cc = vp->vibrato_control_ratio; | |
439 incr = update_vibrato(song, vp, 0); | |
440 vibflag = 0; | |
441 } | |
442 } | |
443 | |
444 /* Then do the bidirectional looping */ | |
445 | |
446 while (count) | |
447 { | |
448 /* Precalc how many times we should go through the loop */ | |
449 i = ((incr > 0 ? le : ls) - ofs) / incr + 1; | |
450 if(i > count) i = count; | |
451 if(i > cc) | |
452 { | |
453 i = cc; | |
454 vibflag = 1; | |
455 } | |
456 else cc -= i; | |
457 count -= i; | |
458 while (i--) | |
459 { | |
460 v1 = src[ofs >> FRACTION_BITS]; | |
461 v2 = src[(ofs >> FRACTION_BITS)+1]; | |
462 *dest++ = v1 + (((v2 - v1) * (ofs & FRACTION_MASK)) >> FRACTION_BITS); | |
463 ofs += incr; | |
464 } | |
465 if (vibflag) | |
466 { | |
467 cc = vp->vibrato_control_ratio; | |
468 incr = update_vibrato(song, vp, (incr < 0)); | |
469 vibflag = 0; | |
470 } | |
471 if (ofs >= le) | |
472 { | |
473 /* fold the overshoot back in */ | |
474 ofs = le2 - ofs; | |
475 incr *= -1; | |
476 } | |
477 else if (ofs <= ls) | |
478 { | |
479 ofs = ls2 - ofs; | |
480 incr *= -1; | |
481 } | |
482 } | |
483 | |
484 vp->vibrato_control_counter=cc; | |
485 vp->sample_increment=incr; | |
486 vp->sample_offset=ofs; /* Update offset */ | |
487 return song->resample_buffer; | |
488 } | |
489 | |
490 sample_t *resample_voice(MidiSong *song, int v, Sint32 *countptr) | |
491 { | |
492 Sint32 ofs; | |
493 Uint8 modes; | |
494 Voice *vp=&(song->voice[v]); | |
495 | |
496 if (!(vp->sample->sample_rate)) | |
497 { | |
498 /* Pre-resampled data -- just update the offset and check if | |
499 we're out of data. */ | |
500 ofs=vp->sample_offset >> FRACTION_BITS; /* Kind of silly to use | |
501 FRACTION_BITS here... */ | |
502 if (*countptr >= (vp->sample->data_length>>FRACTION_BITS) - ofs) | |
503 { | |
504 /* Note finished. Free the voice. */ | |
505 vp->status = VOICE_FREE; | |
506 | |
507 /* Let the caller know how much data we had left */ | |
508 *countptr = (vp->sample->data_length>>FRACTION_BITS) - ofs; | |
509 } | |
510 else | |
511 vp->sample_offset += *countptr << FRACTION_BITS; | |
512 | |
513 return vp->sample->data+ofs; | |
514 } | |
515 | |
516 /* Need to resample. Use the proper function. */ | |
517 modes=vp->sample->modes; | |
518 | |
519 if (vp->vibrato_control_ratio) | |
520 { | |
521 if ((modes & MODES_LOOPING) && | |
522 ((modes & MODES_ENVELOPE) || | |
523 (vp->status==VOICE_ON || vp->status==VOICE_SUSTAINED))) | |
524 { | |
525 if (modes & MODES_PINGPONG) | |
526 return rs_vib_bidir(song, vp, *countptr); | |
527 else | |
528 return rs_vib_loop(song, vp, *countptr); | |
529 } | |
530 else | |
531 return rs_vib_plain(song, v, countptr); | |
532 } | |
533 else | |
534 { | |
535 if ((modes & MODES_LOOPING) && | |
536 ((modes & MODES_ENVELOPE) || | |
537 (vp->status==VOICE_ON || vp->status==VOICE_SUSTAINED))) | |
538 { | |
539 if (modes & MODES_PINGPONG) | |
540 return rs_bidir(song, vp, *countptr); | |
541 else | |
542 return rs_loop(song, vp, *countptr); | |
543 } | |
544 else | |
545 return rs_plain(song, v, countptr); | |
546 } | |
547 } | |
548 | |
549 void pre_resample(MidiSong *song, Sample *sp) | |
550 { | |
551 double a, xdiff; | |
552 Sint32 incr, ofs, newlen, count; | |
553 Sint16 *newdata, *dest, *src = (Sint16 *) sp->data; | |
554 Sint16 v1, v2, v3, v4, *vptr; | |
555 #ifdef DEBUG_CHATTER | |
556 static const char note_name[12][3] = | |
557 { | |
558 "C", "C#", "D", "D#", "E", "F", "F#", "G", "G#", "A", "A#", "B" | |
559 }; | |
560 #endif | |
561 | |
562 SNDDBG((" * pre-resampling for note %d (%s%d)\n", | |
563 sp->note_to_use, | |
564 note_name[sp->note_to_use % 12], (sp->note_to_use & 0x7F) / 12)); | |
565 | |
566 a = ((double) (sp->sample_rate) * freq_table[(int) (sp->note_to_use)]) / | |
567 ((double) (sp->root_freq) * song->rate); | |
568 newlen = (Sint32)(sp->data_length / a); | |
569 dest = newdata = safe_malloc(newlen >> (FRACTION_BITS - 1)); | |
570 | |
571 count = (newlen >> FRACTION_BITS) - 1; | |
572 ofs = incr = (sp->data_length - (1 << FRACTION_BITS)) / count; | |
573 | |
574 if (--count) | |
575 *dest++ = src[0]; | |
576 | |
577 /* Since we're pre-processing and this doesn't have to be done in | |
578 real-time, we go ahead and do the full sliding cubic interpolation. */ | |
579 while (--count) | |
580 { | |
581 vptr = src + (ofs >> FRACTION_BITS); | |
254 | 582 /* |
583 * Electric Fence to the rescue: Accessing *(vptr - 1) is not a | |
584 * good thing to do when vptr <= src. (TiMidity++ has a similar | |
585 * safe-guard here.) | |
586 */ | |
521
f33471c47efe
Minor correction in Timidity resampling code (Thanks, Sam!).
Ryan C. Gordon <icculus@icculus.org>
parents:
254
diff
changeset
|
587 v1 = (vptr == src) ? *vptr : *(vptr - 1); |
199 | 588 v2 = *vptr; |
589 v3 = *(vptr + 1); | |
590 v4 = *(vptr + 2); | |
591 xdiff = FSCALENEG(ofs & FRACTION_MASK, FRACTION_BITS); | |
592 *dest++ = (Sint16)(v2 + (xdiff / 6.0) * (-2 * v1 - 3 * v2 + 6 * v3 - v4 + | |
593 xdiff * (3 * (v1 - 2 * v2 + v3) + xdiff * (-v1 + 3 * (v2 - v3) + v4)))); | |
594 ofs += incr; | |
595 } | |
596 | |
597 if (ofs & FRACTION_MASK) | |
598 { | |
599 v1 = src[ofs >> FRACTION_BITS]; | |
600 v2 = src[(ofs >> FRACTION_BITS) + 1]; | |
601 *dest++ = v1 + (((v2 - v1) * (ofs & FRACTION_MASK)) >> FRACTION_BITS); | |
602 } | |
603 else | |
604 *dest++ = src[ofs >> FRACTION_BITS]; | |
605 | |
606 sp->data_length = newlen; | |
607 sp->loop_start = (Sint32)(sp->loop_start / a); | |
608 sp->loop_end = (Sint32)(sp->loop_end / a); | |
609 free(sp->data); | |
610 sp->data = (sample_t *) newdata; | |
611 sp->sample_rate = 0; | |
612 } |