123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739 |
- /*
- TiMidity -- Experimental MIDI to WAVE converter
- Copyright (C) 1995 Tuukka Toivonen <toivonen@clinet.fi>
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- resample.c
- */
- #include <math.h>
- #include <stdio.h>
- #include <stdlib.h>
- #include "config.h"
- #include "common.h"
- #include "instrum.h"
- #include "playmidi.h"
- #include "output.h"
- #include "controls.h"
- #include "tables.h"
- #include "resample.h"
- #ifdef LINEAR_INTERPOLATION
- # if defined(LOOKUP_HACK) && defined(LOOKUP_INTERPOLATION)
- # define RESAMPLATION \
- v1=src[ofs>>FRACTION_BITS];\
- v2=src[(ofs>>FRACTION_BITS)+1];\
- *dest++ = v1 + (iplookup[(((v2-v1)<<5) & 0x03FE0) | \
- ((ofs & FRACTION_MASK) >> (FRACTION_BITS-5))]);
- # else
- # define RESAMPLATION \
- v1=src[ofs>>FRACTION_BITS];\
- v2=src[(ofs>>FRACTION_BITS)+1];\
- *dest++ = v1 + (((v2-v1) * (ofs & FRACTION_MASK)) >> FRACTION_BITS);
- # endif
- # define INTERPVARS sample_t v1, v2
- #else
- /* Earplugs recommended for maximum listening enjoyment */
- # define RESAMPLATION *dest++=src[ofs>>FRACTION_BITS];
- # define INTERPVARS
- #endif
- #define FINALINTERP if (ofs == le) *dest++=src[ofs>>FRACTION_BITS];
- /* So it isn't interpolation. At least it's final. */
- extern sample_t *resample_buffer;
- void Real_Tim_Free( void *pt );
- /*************** resampling with fixed increment *****************/
- static sample_t *rs_plain(int v, int32_t *countptr)
- {
- /* Play sample until end, then free the voice. */
- INTERPVARS;
- Voice
- *vp=&voice[v];
- sample_t
- *dest=resample_buffer,
- *src=vp->sample->data;
- int32_t
- ofs=vp->sample_offset,
- incr=vp->sample_increment,
- le=vp->sample->data_length,
- count=*countptr;
- #ifdef PRECALC_LOOPS
- int32_t i;
- if (incr<0) incr = -incr; /* In case we're coming out of a bidir loop */
- /* Precalc how many times we should go through the loop.
- NOTE: Assumes that incr > 0 and that ofs <= le */
- i = (le - ofs) / incr + 1;
- if (i > count)
- {
- i = count;
- count = 0;
- }
- else count -= i;
- while (i--)
- {
- RESAMPLATION;
- ofs += incr;
- }
- if (ofs >= le)
- {
- FINALINTERP;
- vp->status=VOICE_FREE;
- ctl->note(v);
- *countptr-=count+1;
- }
- #else /* PRECALC_LOOPS */
- while (count--)
- {
- RESAMPLATION;
- ofs += incr;
- if (ofs >= le)
- {
- FINALINTERP;
- vp->status=VOICE_FREE;
- ctl->note(v);
- *countptr-=count+1;
- break;
- }
- }
- #endif /* PRECALC_LOOPS */
- vp->sample_offset=ofs; /* Update offset */
- return resample_buffer;
- }
- static sample_t *rs_loop(Voice *vp, int32_t count)
- {
- /* Play sample until end-of-loop, skip back and continue. */
- INTERPVARS;
- int32_t
- ofs=vp->sample_offset,
- incr=vp->sample_increment,
- le=vp->sample->loop_end,
- ll=le - vp->sample->loop_start;
- sample_t
- *dest=resample_buffer,
- *src=vp->sample->data;
- #ifdef PRECALC_LOOPS
- int32_t i;
- while (count)
- {
- if (ofs >= le)
- /* NOTE: Assumes that ll > incr and that incr > 0. */
- ofs -= ll;
- /* Precalc how many times we should go through the loop */
- i = (le - ofs) / incr + 1;
- if (i > count)
- {
- i = count;
- count = 0;
- }
- else count -= i;
- while (i--)
- {
- RESAMPLATION;
- ofs += incr;
- }
- }
- #else
- while (count--)
- {
- RESAMPLATION;
- ofs += incr;
- if (ofs>=le)
- ofs -= ll; /* Hopefully the loop is longer than an increment. */
- }
- #endif
- vp->sample_offset=ofs; /* Update offset */
- return resample_buffer;
- }
- static sample_t *rs_bidir(Voice *vp, int32_t count)
- {
- INTERPVARS;
- int32_t
- ofs=vp->sample_offset,
- incr=vp->sample_increment,
- le=vp->sample->loop_end,
- ls=vp->sample->loop_start;
- sample_t
- *dest=resample_buffer,
- *src=vp->sample->data;
- #ifdef PRECALC_LOOPS
- int32_t
- le2 = le<<1,
- ls2 = ls<<1,
- i;
- /* Play normally until inside the loop region */
- if (ofs <= ls)
- {
- /* NOTE: Assumes that incr > 0, which is NOT always the case
- when doing bidirectional looping. I have yet to see a case
- where both ofs <= ls AND incr < 0, however. */
- i = (ls - ofs) / incr + 1;
- if (i > count)
- {
- i = count;
- count = 0;
- }
- else count -= i;
- while (i--)
- {
- RESAMPLATION;
- ofs += incr;
- }
- }
- /* Then do the bidirectional looping */
- while(count)
- {
- /* Precalc how many times we should go through the loop */
- i = ((incr > 0 ? le : ls) - ofs) / incr + 1;
- if (i > count)
- {
- i = count;
- count = 0;
- }
- else count -= i;
- while (i--)
- {
- RESAMPLATION;
- ofs += incr;
- }
- if (ofs>=le)
- {
- /* fold the overshoot back in */
- ofs = le2 - ofs;
- incr *= -1;
- }
- else if (ofs <= ls)
- {
- ofs = ls2 - ofs;
- incr *= -1;
- }
- }
- #else /* PRECALC_LOOPS */
- /* Play normally until inside the loop region */
- if (ofs < ls)
- {
- while (count--)
- {
- RESAMPLATION;
- ofs += incr;
- if (ofs>=ls)
- break;
- }
- }
- /* Then do the bidirectional looping */
- if (count>0)
- while (count--)
- {
- RESAMPLATION;
- ofs += incr;
- if (ofs>=le)
- {
- /* fold the overshoot back in */
- ofs = le - (ofs - le);
- incr = -incr;
- }
- else if (ofs <= ls)
- {
- ofs = ls + (ls - ofs);
- incr = -incr;
- }
- }
- #endif /* PRECALC_LOOPS */
- vp->sample_increment=incr;
- vp->sample_offset=ofs; /* Update offset */
- return resample_buffer;
- }
- /*********************** vibrato versions ***************************/
- /* We only need to compute one half of the vibrato sine cycle */
- static int vib_phase_to_inc_ptr(int phase)
- {
- if (phase < VIBRATO_SAMPLE_INCREMENTS/2)
- return VIBRATO_SAMPLE_INCREMENTS/2-1-phase;
- else if (phase >= 3*VIBRATO_SAMPLE_INCREMENTS/2)
- return 5*VIBRATO_SAMPLE_INCREMENTS/2-1-phase;
- else
- return phase-VIBRATO_SAMPLE_INCREMENTS/2;
- }
- static int32_t update_vibrato(Voice *vp, int sign)
- {
- int32_t depth;
- int phase, pb;
- double a;
- if (vp->vibrato_phase++ >= 2*VIBRATO_SAMPLE_INCREMENTS-1)
- vp->vibrato_phase=0;
- phase=vib_phase_to_inc_ptr(vp->vibrato_phase);
- if (vp->vibrato_sample_increment[phase])
- {
- if (sign)
- return -vp->vibrato_sample_increment[phase];
- else
- return vp->vibrato_sample_increment[phase];
- }
- /* Need to compute this sample increment. */
- depth=vp->sample->vibrato_depth<<7;
- if (vp->vibrato_sweep)
- {
- /* Need to update sweep */
- vp->vibrato_sweep_position += vp->vibrato_sweep;
- if (vp->vibrato_sweep_position >= (1<<SWEEP_SHIFT))
- vp->vibrato_sweep=0;
- else
- {
- /* Adjust depth */
- depth *= vp->vibrato_sweep_position;
- depth >>= SWEEP_SHIFT;
- }
- }
- a = FSCALE(((double)(vp->sample->sample_rate) *
- (double)(vp->frequency)) /
- ((double)(vp->sample->root_freq) *
- (double)(play_mode->rate)),
- FRACTION_BITS);
- pb=(int)((sine(vp->vibrato_phase *
- (SINE_CYCLE_LENGTH/(2*VIBRATO_SAMPLE_INCREMENTS)))
- * (double)(depth) * VIBRATO_AMPLITUDE_TUNING));
- if (pb<0)
- {
- pb=-pb;
- a /= bend_fine[(pb>>5) & 0xFF] * bend_coarse[pb>>13];
- }
- else
- a *= bend_fine[(pb>>5) & 0xFF] * bend_coarse[pb>>13];
- /* If the sweep's over, we can store the newly computed sample_increment */
- if (!vp->vibrato_sweep)
- vp->vibrato_sample_increment[phase]=(int32_t) a;
- if (sign)
- a = -a; /* need to preserve the loop direction */
- return (int32_t) a;
- }
- static sample_t *rs_vib_plain(int v, int32_t *countptr)
- {
- /* Play sample until end, then free the voice. */
- INTERPVARS;
- Voice *vp=&voice[v];
- sample_t
- *dest=resample_buffer,
- *src=vp->sample->data;
- int32_t
- le=vp->sample->data_length,
- ofs=vp->sample_offset,
- incr=vp->sample_increment,
- count=*countptr;
- int
- cc=vp->vibrato_control_counter;
- /* This has never been tested */
- if (incr<0) incr = -incr; /* In case we're coming out of a bidir loop */
- while (count--)
- {
- if (!cc--)
- {
- cc=vp->vibrato_control_ratio;
- incr=update_vibrato(vp, 0);
- }
- RESAMPLATION;
- ofs += incr;
- if (ofs >= le)
- {
- FINALINTERP;
- vp->status=VOICE_FREE;
- ctl->note(v);
- *countptr-=count+1;
- break;
- }
- }
- vp->vibrato_control_counter=cc;
- vp->sample_increment=incr;
- vp->sample_offset=ofs; /* Update offset */
- return resample_buffer;
- }
- static sample_t *rs_vib_loop(Voice *vp, int32_t count)
- {
- /* Play sample until end-of-loop, skip back and continue. */
- INTERPVARS;
- int32_t
- ofs=vp->sample_offset,
- incr=vp->sample_increment,
- le=vp->sample->loop_end,
- ll=le - vp->sample->loop_start;
- sample_t
- *dest=resample_buffer,
- *src=vp->sample->data;
- int
- cc=vp->vibrato_control_counter;
- #ifdef PRECALC_LOOPS
- int32_t i;
- int
- vibflag=0;
- while (count)
- {
- /* Hopefully the loop is longer than an increment */
- if(ofs >= le)
- ofs -= ll;
- /* Precalc how many times to go through the loop, taking
- the vibrato control ratio into account this time. */
- i = (le - ofs) / incr + 1;
- if(i > count) i = count;
- if(i > cc)
- {
- i = cc;
- vibflag = 1;
- }
- else cc -= i;
- count -= i;
- while(i--)
- {
- RESAMPLATION;
- ofs += incr;
- }
- if(vibflag)
- {
- cc = vp->vibrato_control_ratio;
- incr = update_vibrato(vp, 0);
- vibflag = 0;
- }
- }
- #else /* PRECALC_LOOPS */
- while (count--)
- {
- if (!cc--)
- {
- cc=vp->vibrato_control_ratio;
- incr=update_vibrato(vp, 0);
- }
- RESAMPLATION;
- ofs += incr;
- if (ofs>=le)
- ofs -= ll; /* Hopefully the loop is longer than an increment. */
- }
- #endif /* PRECALC_LOOPS */
- vp->vibrato_control_counter=cc;
- vp->sample_increment=incr;
- vp->sample_offset=ofs; /* Update offset */
- return resample_buffer;
- }
- static sample_t *rs_vib_bidir(Voice *vp, int32_t count)
- {
- INTERPVARS;
- int32_t
- ofs=vp->sample_offset,
- incr=vp->sample_increment,
- le=vp->sample->loop_end,
- ls=vp->sample->loop_start;
- sample_t
- *dest=resample_buffer,
- *src=vp->sample->data;
- int
- cc=vp->vibrato_control_counter;
- #ifdef PRECALC_LOOPS
- int32_t
- le2=le<<1,
- ls2=ls<<1,
- i;
- int
- vibflag = 0;
- /* Play normally until inside the loop region */
- while (count && (ofs <= ls))
- {
- i = (ls - ofs) / incr + 1;
- if (i > count) i = count;
- if (i > cc)
- {
- i = cc;
- vibflag = 1;
- }
- else cc -= i;
- count -= i;
- while (i--)
- {
- RESAMPLATION;
- ofs += incr;
- }
- if (vibflag)
- {
- cc = vp->vibrato_control_ratio;
- incr = update_vibrato(vp, 0);
- vibflag = 0;
- }
- }
- /* Then do the bidirectional looping */
- while (count)
- {
- /* Precalc how many times we should go through the loop */
- i = ((incr > 0 ? le : ls) - ofs) / incr + 1;
- if(i > count) i = count;
- if(i > cc)
- {
- i = cc;
- vibflag = 1;
- }
- else cc -= i;
- count -= i;
- while (i--)
- {
- RESAMPLATION;
- ofs += incr;
- }
- if (vibflag)
- {
- cc = vp->vibrato_control_ratio;
- incr = update_vibrato(vp, (incr < 0));
- vibflag = 0;
- }
- if (ofs >= le)
- {
- /* fold the overshoot back in */
- ofs = le2 - ofs;
- incr *= -1;
- }
- else if (ofs <= ls)
- {
- ofs = ls2 - ofs;
- incr *= -1;
- }
- }
- #else /* PRECALC_LOOPS */
- /* Play normally until inside the loop region */
- if (ofs < ls)
- {
- while (count--)
- {
- if (!cc--)
- {
- cc=vp->vibrato_control_ratio;
- incr=update_vibrato(vp, 0);
- }
- RESAMPLATION;
- ofs += incr;
- if (ofs>=ls)
- break;
- }
- }
- /* Then do the bidirectional looping */
- if (count>0)
- while (count--)
- {
- if (!cc--)
- {
- cc=vp->vibrato_control_ratio;
- incr=update_vibrato(vp, (incr < 0));
- }
- RESAMPLATION;
- ofs += incr;
- if (ofs>=le)
- {
- /* fold the overshoot back in */
- ofs = le - (ofs - le);
- incr = -incr;
- }
- else if (ofs <= ls)
- {
- ofs = ls + (ls - ofs);
- incr = -incr;
- }
- }
- #endif /* PRECALC_LOOPS */
- vp->vibrato_control_counter=cc;
- vp->sample_increment=incr;
- vp->sample_offset=ofs; /* Update offset */
- return resample_buffer;
- }
- sample_t *resample_voice(int v, int32_t *countptr)
- {
- int32_t ofs;
- uint8_t modes;
- Voice *vp=&voice[v];
- if (!(vp->sample->sample_rate))
- {
- /* Pre-resampled data -- just update the offset and check if
- we're out of data. */
- ofs=vp->sample_offset >> FRACTION_BITS; /* Kind of silly to use
- FRACTION_BITS here... */
- if (*countptr >= (vp->sample->data_length>>FRACTION_BITS) - ofs)
- {
- /* Note finished. Free the voice. */
- vp->status = VOICE_FREE;
- ctl->note(v);
- /* Let the caller know how much data we had left */
- *countptr = (vp->sample->data_length>>FRACTION_BITS) - ofs;
- }
- else
- vp->sample_offset += *countptr << FRACTION_BITS;
- return vp->sample->data+ofs;
- }
- /* Need to resample. Use the proper function. */
- modes=vp->sample->modes;
- if (vp->vibrato_control_ratio)
- {
- if ((modes & MODES_LOOPING) &&
- ((modes & MODES_ENVELOPE) ||
- (vp->status==VOICE_ON || vp->status==VOICE_SUSTAINED)))
- {
- if (modes & MODES_PINGPONG)
- return rs_vib_bidir(vp, *countptr);
- else
- return rs_vib_loop(vp, *countptr);
- }
- else
- return rs_vib_plain(v, countptr);
- }
- else
- {
- if ((modes & MODES_LOOPING) &&
- ((modes & MODES_ENVELOPE) ||
- (vp->status==VOICE_ON || vp->status==VOICE_SUSTAINED)))
- {
- if (modes & MODES_PINGPONG)
- return rs_bidir(vp, *countptr);
- else
- return rs_loop(vp, *countptr);
- }
- else
- return rs_plain(v, countptr);
- }
- }
- void pre_resample(Sample * sp)
- {
- double a, xdiff;
- int32_t incr, ofs, newlen, count;
- int16_t *newdata, *dest, *src = (int16_t *) sp->data;
- int16_t v1, v2, v3, v4, *vptr;
- static const char note_name[12][3] =
- {
- "C", "C#", "D", "D#", "E", "F", "F#", "G", "G#", "A", "A#", "B"
- };
- ctl->cmsg(CMSG_INFO, VERB_NOISY, " * pre-resampling for note %d (%s%d)",
- sp->note_to_use,
- note_name[sp->note_to_use % 12], (sp->note_to_use & 0x7F) / 12);
- a = ((double) (sp->sample_rate) * freq_table[(int) (sp->note_to_use)]) /
- ((double) (sp->root_freq) * play_mode->rate);
- newlen = (int32_t)(sp->data_length / a);
- dest = newdata = (int16_t*)safe_malloc(newlen >> (FRACTION_BITS - 1));
- count = (newlen >> FRACTION_BITS) - 1;
- ofs = incr = (sp->data_length - (1 << FRACTION_BITS)) / count;
- if (--count)
- *dest++ = src[0];
- /* Since we're pre-processing and this doesn't have to be done in
- real-time, we go ahead and do the full sliding cubic interpolation. */
- while (--count)
- {
- vptr = src + (ofs >> FRACTION_BITS);
- v1 = *(vptr - 1);
- v2 = *vptr;
- v3 = *(vptr + 1);
- v4 = *(vptr + 2);
- xdiff = FSCALENEG(ofs & FRACTION_MASK, FRACTION_BITS);
- *dest++ = (int16_t)(v2 + (xdiff / 6.0) * (-2 * v1 - 3 * v2 + 6 * v3 - v4 +
- xdiff * (3 * (v1 - 2 * v2 + v3) + xdiff * (-v1 + 3 * (v2 - v3) + v4))));
- ofs += incr;
- }
- if (ofs & FRACTION_MASK)
- {
- v1 = src[ofs >> FRACTION_BITS];
- v2 = src[(ofs >> FRACTION_BITS) + 1];
- *dest++ = v1 + (((v2 - v1) * (ofs & FRACTION_MASK)) >> FRACTION_BITS);
- }
- else
- *dest++ = src[ofs >> FRACTION_BITS];
- sp->data_length = newlen;
- sp->loop_start = (int32_t)(sp->loop_start / a);
- sp->loop_end = (int32_t)(sp->loop_end / a);
- Real_Tim_Free(sp->data);
- sp->data = (sample_t *) newdata;
- sp->sample_rate = 0;
- }
|