timidity_resample.cpp

Go to the documentation of this file.
00001 /*
00002 
00003     TiMidity -- Experimental MIDI to WAVE converter
00004     Copyright (C) 1995 Tuukka Toivonen <toivonen@clinet.fi>
00005 
00006     This program is free software; you can redistribute it and/or modify
00007     it under the terms of the GNU General Public License as published by
00008     the Free Software Foundation; either version 2 of the License, or
00009     (at your option) any later version.
00010 
00011     This program is distributed in the hope that it will be useful,
00012     but WITHOUT ANY WARRANTY; without even the implied warranty of
00013     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014     GNU General Public License for more details.
00015 
00016     You should have received a copy of the GNU General Public License
00017     along with this program; if not, write to the Free Software
00018     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
00019 
00020     resample.c
00021 */
00022 
00023 #include "pent_include.h"
00024 
00025 #ifdef USE_TIMIDITY_MIDI
00026 
00027 #include <cmath>
00028 #include <cstdio>
00029 #include <cstdlib>
00030 
00031 #include "timidity.h"
00032 #include "timidity_common.h"
00033 #include "timidity_instrum.h"
00034 #include "timidity_playmidi.h"
00035 #include "timidity_output.h"
00036 #include "timidity_controls.h"
00037 #include "timidity_tables.h"
00038 #include "timidity_resample.h"
00039 
00040 #ifdef NS_TIMIDITY
00041 namespace NS_TIMIDITY {
00042 #endif
00043 
00044 #ifdef LINEAR_INTERPOLATION
00045 # if defined(LOOKUP_HACK) && defined(LOOKUP_INTERPOLATION)
00046 #   define RESAMPLATION \
00047        v1=src[ofs>>FRACTION_BITS];\
00048        v2=src[(ofs>>FRACTION_BITS)+1];\
00049        *dest++ = static_cast<sample_t>(v1 + (iplookup[(((v2-v1)<<5) & 0x03FE0) | \
00050            ((ofs & FRACTION_MASK) >> (FRACTION_BITS-5))]));
00051 # else
00052 #   define RESAMPLATION \
00053       v1=src[ofs>>FRACTION_BITS];\
00054       v2=src[(ofs>>FRACTION_BITS)+1];\
00055       *dest++ = static_cast<sample_t>(v1 + (((v2-v1) * (ofs & FRACTION_MASK)) >> FRACTION_BITS));
00056 # endif
00057 #  define INTERPVARS sample_t v1, v2
00058 #else
00059 /* Earplugs recommended for maximum listening enjoyment */
00060 #  define RESAMPLATION *dest++=src[ofs>>FRACTION_BITS];
00061 #  define INTERPVARS
00062 #endif
00063 
00064 #define FINALINTERP if (ofs == le) *dest++=src[ofs>>FRACTION_BITS];
00065 /* So it isn't interpolation. At least it's final. */
00066 
00067 extern sample_t *resample_buffer;
00068 
00069 /*************** resampling with fixed increment *****************/
00070 
00071 static sample_t *rs_plain(int v, sint32 *countptr)
00072 {
00073 
00074   /* Play sample until end, then free the voice. */
00075 
00076   INTERPVARS;
00077   Voice 
00078     *vp=&voice[v];
00079   sample_t 
00080     *dest=resample_buffer,
00081     *src=vp->sample->data;
00082   sint32 
00083     ofs=vp->sample_offset,
00084     incr=vp->sample_increment,
00085     le=vp->sample->data_length,
00086     count=*countptr;
00087 
00088 #ifdef PRECALC_LOOPS
00089   sint32 i;
00090 
00091   if (incr<0) incr = -incr; /* In case we're coming out of a bidir loop */
00092 
00093   /* Precalc how many times we should go through the loop.
00094      NOTE: Assumes that incr > 0 and that ofs <= le */
00095   i = (le - ofs) / incr + 1;
00096 
00097   if (i > count)
00098     {
00099       i = count;
00100       count = 0;
00101     } 
00102   else count -= i;
00103 
00104   while (i--) 
00105     {
00106       RESAMPLATION;
00107       ofs += incr;
00108     }
00109 
00110   if (ofs >= le) 
00111     {
00112       FINALINTERP;
00113       vp->status=VOICE_FREE;
00114       ctl->note(v);
00115       *countptr-=count+1;
00116     }
00117 
00118 #else /* PRECALC_LOOPS */
00119     while (count--)
00120     {
00121       RESAMPLATION;
00122       ofs += incr;
00123       if (ofs >= le)
00124         {
00125           FINALINTERP;
00126           vp->status=VOICE_FREE;
00127           ctl->note(v);
00128           *countptr-=count+1;
00129           break;
00130         }
00131     }
00132 #endif /* PRECALC_LOOPS */
00133   
00134   vp->sample_offset=ofs; /* Update offset */
00135   return resample_buffer;
00136 }
00137 
00138 static sample_t *rs_loop(Voice *vp, sint32 count)
00139 {
00140 
00141   /* Play sample until end-of-loop, skip back and continue. */
00142 
00143   INTERPVARS;
00144   sint32 
00145     ofs=vp->sample_offset, 
00146     incr=vp->sample_increment,
00147     le=vp->sample->loop_end, 
00148     ll=le - vp->sample->loop_start;
00149   sample_t
00150     *dest=resample_buffer,
00151     *src=vp->sample->data;
00152 
00153 #ifdef PRECALC_LOOPS
00154   sint32 i;
00155   
00156   while (count) 
00157     {
00158       if (ofs >= le)
00159         /* NOTE: Assumes that ll > incr and that incr > 0. */
00160         ofs -= ll;
00161       /* Precalc how many times we should go through the loop */
00162       i = (le - ofs) / incr + 1;
00163       if (i > count) 
00164         {
00165           i = count;
00166           count = 0;
00167         } 
00168       else count -= i;
00169       while (i--) 
00170         {
00171           RESAMPLATION;
00172           ofs += incr;
00173         }
00174     }
00175 #else
00176   while (count--)
00177     {
00178       RESAMPLATION;
00179       ofs += incr;
00180       if (ofs>=le)
00181         ofs -= ll; /* Hopefully the loop is longer than an increment. */
00182     }
00183 #endif
00184 
00185   vp->sample_offset=ofs; /* Update offset */
00186   return resample_buffer;
00187 }
00188 
00189 static sample_t *rs_bidir(Voice *vp, sint32 count)
00190 {
00191   INTERPVARS;
00192   sint32 
00193     ofs=vp->sample_offset,
00194     incr=vp->sample_increment,
00195     le=vp->sample->loop_end,
00196     ls=vp->sample->loop_start;
00197   sample_t 
00198     *dest=resample_buffer, 
00199     *src=vp->sample->data;
00200 
00201 #ifdef PRECALC_LOOPS
00202   sint32
00203     le2 = le<<1, 
00204     ls2 = ls<<1,
00205     i;
00206   /* Play normally until inside the loop region */
00207 
00208   if (ofs <= ls) 
00209     {
00210       /* NOTE: Assumes that incr > 0, which is NOT always the case
00211          when doing bidirectional looping.  I have yet to see a case
00212          where both ofs <= ls AND incr < 0, however. */
00213       i = (ls - ofs) / incr + 1;
00214       if (i > count) 
00215         {
00216           i = count;
00217           count = 0;
00218         } 
00219       else count -= i;
00220       while (i--) 
00221         {
00222           RESAMPLATION;
00223           ofs += incr;
00224         }
00225     }
00226 
00227   /* Then do the bidirectional looping */
00228   
00229   while(count) 
00230     {
00231       /* Precalc how many times we should go through the loop */
00232       i = ((incr > 0 ? le : ls) - ofs) / incr + 1;
00233       if (i > count) 
00234         {
00235           i = count;
00236           count = 0;
00237         } 
00238       else count -= i;
00239       while (i--) 
00240         {
00241           RESAMPLATION;
00242           ofs += incr;
00243         }
00244       if (ofs>=le) 
00245         {
00246           /* fold the overshoot back in */
00247           ofs = le2 - ofs;
00248           incr *= -1;
00249         } 
00250       else if (ofs <= ls) 
00251         {
00252           ofs = ls2 - ofs;
00253           incr *= -1;
00254         }
00255     }
00256 
00257 #else /* PRECALC_LOOPS */
00258   /* Play normally until inside the loop region */
00259 
00260   if (ofs < ls)
00261     {
00262       while (count--)
00263         {
00264           RESAMPLATION;
00265           ofs += incr;
00266           if (ofs>=ls)
00267             break;
00268         }
00269     }
00270 
00271   /* Then do the bidirectional looping */
00272 
00273   if (count>0)
00274     while (count--)
00275       {
00276         RESAMPLATION;
00277         ofs += incr;
00278         if (ofs>=le)
00279           {
00280             /* fold the overshoot back in */
00281             ofs = le - (ofs - le);
00282             incr = -incr;
00283           }
00284         else if (ofs <= ls)
00285           {
00286             ofs = ls + (ls - ofs);
00287             incr = -incr;
00288           }
00289       }  
00290 #endif /* PRECALC_LOOPS */
00291   vp->sample_increment=incr;
00292   vp->sample_offset=ofs; /* Update offset */
00293   return resample_buffer;
00294 }
00295 
00296 /*********************** vibrato versions ***************************/
00297 
00298 /* We only need to compute one half of the vibrato sine cycle */
00299 static int vib_phase_to_inc_ptr(int phase)
00300 {
00301   if (phase < VIBRATO_SAMPLE_INCREMENTS/2)
00302     return VIBRATO_SAMPLE_INCREMENTS/2-1-phase;
00303   else if (phase >= 3*VIBRATO_SAMPLE_INCREMENTS/2)
00304     return 5*VIBRATO_SAMPLE_INCREMENTS/2-1-phase;
00305   else
00306     return phase-VIBRATO_SAMPLE_INCREMENTS/2;
00307 }
00308 
00309 static sint32 update_vibrato(Voice *vp, int sign)
00310 {
00311   sint32 depth;
00312   int phase, pb;
00313   double a;
00314 
00315   if (vp->vibrato_phase++ >= 2*VIBRATO_SAMPLE_INCREMENTS-1)
00316     vp->vibrato_phase=0;
00317   phase=vib_phase_to_inc_ptr(vp->vibrato_phase);
00318   
00319   if (vp->vibrato_sample_increment[phase])
00320     {
00321       if (sign)
00322         return -vp->vibrato_sample_increment[phase];
00323       else
00324         return vp->vibrato_sample_increment[phase];
00325     }
00326 
00327   /* Need to compute this sample increment. */
00328     
00329   depth=vp->sample->vibrato_depth<<7;
00330 
00331   if (vp->vibrato_sweep)
00332     {
00333       /* Need to update sweep */
00334       vp->vibrato_sweep_position += vp->vibrato_sweep;
00335       if (vp->vibrato_sweep_position >= (1<<SWEEP_SHIFT))
00336         vp->vibrato_sweep=0;
00337       else
00338         {
00339           /* Adjust depth */
00340           depth *= vp->vibrato_sweep_position;
00341           depth >>= SWEEP_SHIFT;
00342         }
00343     }
00344 
00345   a = FSCALE(((double)(vp->sample->sample_rate) *
00346               (double)(vp->frequency)) /
00347              ((double)(vp->sample->root_freq) *
00348               (double)(play_mode->rate)),
00349              FRACTION_BITS);
00350 
00351   pb=(int)((sine(vp->vibrato_phase * 
00352                  (SINE_CYCLE_LENGTH/(2*VIBRATO_SAMPLE_INCREMENTS)))
00353             * (double)(depth) * VIBRATO_AMPLITUDE_TUNING));
00354 
00355   if (pb<0)
00356     {
00357       pb=-pb;
00358       a /= bend_fine[(pb>>5) & 0xFF] * bend_coarse[pb>>13];
00359     }
00360   else
00361     a *= bend_fine[(pb>>5) & 0xFF] * bend_coarse[pb>>13];
00362   
00363   /* If the sweep's over, we can store the newly computed sample_increment */
00364   if (!vp->vibrato_sweep)
00365     vp->vibrato_sample_increment[phase]=(sint32) a;
00366 
00367   if (sign)
00368     a = -a; /* need to preserve the loop direction */
00369 
00370   return (sint32) a;
00371 }
00372 
00373 static sample_t *rs_vib_plain(int v, sint32 *countptr)
00374 {
00375 
00376   /* Play sample until end, then free the voice. */
00377 
00378   INTERPVARS;
00379   Voice *vp=&voice[v];
00380   sample_t 
00381     *dest=resample_buffer, 
00382     *src=vp->sample->data;
00383   sint32 
00384     le=vp->sample->data_length,
00385     ofs=vp->sample_offset, 
00386     incr=vp->sample_increment, 
00387     count=*countptr;
00388   int 
00389     cc=vp->vibrato_control_counter;
00390 
00391   /* This has never been tested */
00392 
00393   if (incr<0) incr = -incr; /* In case we're coming out of a bidir loop */
00394 
00395   while (count--)
00396     {
00397       if (!cc--)
00398         {
00399           cc=vp->vibrato_control_ratio;
00400           incr=update_vibrato(vp, 0);
00401         }
00402       RESAMPLATION;
00403       ofs += incr;
00404       if (ofs >= le)
00405         {
00406           FINALINTERP;
00407           vp->status=VOICE_FREE;
00408           ctl->note(v);
00409           *countptr-=count+1;
00410           break;
00411         }
00412     }
00413   
00414   vp->vibrato_control_counter=cc;
00415   vp->sample_increment=incr;
00416   vp->sample_offset=ofs; /* Update offset */
00417   return resample_buffer;
00418 }
00419 
00420 static sample_t *rs_vib_loop(Voice *vp, sint32 count)
00421 {
00422 
00423   /* Play sample until end-of-loop, skip back and continue. */
00424   
00425   INTERPVARS;
00426   sint32 
00427     ofs=vp->sample_offset, 
00428     incr=vp->sample_increment, 
00429     le=vp->sample->loop_end,
00430     ll=le - vp->sample->loop_start;
00431   sample_t 
00432     *dest=resample_buffer, 
00433     *src=vp->sample->data;
00434   int 
00435     cc=vp->vibrato_control_counter;
00436 
00437 #ifdef PRECALC_LOOPS
00438   sint32 i;
00439   int
00440     vibflag=0;
00441 
00442   while (count) 
00443     {
00444       /* Hopefully the loop is longer than an increment */
00445       if(ofs >= le)
00446         ofs -= ll;
00447       /* Precalc how many times to go through the loop, taking
00448          the vibrato control ratio into account this time. */
00449       i = (le - ofs) / incr + 1;
00450       if(i > count) i = count;
00451       if(i > cc)
00452         {
00453           i = cc;
00454           vibflag = 1;
00455         } 
00456       else cc -= i;
00457       count -= i;
00458       while(i--) 
00459         {
00460           RESAMPLATION;
00461           ofs += incr;
00462         }
00463       if(vibflag) 
00464         {
00465           cc = vp->vibrato_control_ratio;
00466           incr = update_vibrato(vp, 0);
00467           vibflag = 0;
00468         }
00469     }
00470 
00471 #else /* PRECALC_LOOPS */
00472   while (count--)
00473     {
00474       if (!cc--)
00475         {
00476           cc=vp->vibrato_control_ratio;
00477           incr=update_vibrato(vp, 0);
00478         }
00479       RESAMPLATION;
00480       ofs += incr;
00481       if (ofs>=le)
00482         ofs -= ll; /* Hopefully the loop is longer than an increment. */
00483     }
00484 #endif /* PRECALC_LOOPS */
00485 
00486   vp->vibrato_control_counter=cc;
00487   vp->sample_increment=incr;
00488   vp->sample_offset=ofs; /* Update offset */
00489   return resample_buffer;
00490 }
00491 
00492 static sample_t *rs_vib_bidir(Voice *vp, sint32 count)
00493 {
00494   INTERPVARS;
00495   sint32 
00496     ofs=vp->sample_offset, 
00497     incr=vp->sample_increment,
00498     le=vp->sample->loop_end, 
00499     ls=vp->sample->loop_start;
00500   sample_t 
00501     *dest=resample_buffer, 
00502     *src=vp->sample->data;
00503   int 
00504     cc=vp->vibrato_control_counter;
00505 
00506 #ifdef PRECALC_LOOPS
00507   sint32
00508     le2=le<<1,
00509     ls2=ls<<1,
00510     i;
00511   int
00512     vibflag = 0;
00513 
00514   /* Play normally until inside the loop region */
00515   while (count && (ofs <= ls)) 
00516     {
00517       i = (ls - ofs) / incr + 1;
00518       if (i > count) i = count;
00519       if (i > cc) 
00520         {
00521           i = cc;
00522           vibflag = 1;
00523         } 
00524       else cc -= i;
00525       count -= i;
00526       while (i--) 
00527         {
00528           RESAMPLATION;
00529           ofs += incr;
00530         }
00531       if (vibflag) 
00532         {
00533           cc = vp->vibrato_control_ratio;
00534           incr = update_vibrato(vp, 0);
00535           vibflag = 0;
00536         }
00537     }
00538   
00539   /* Then do the bidirectional looping */
00540 
00541   while (count) 
00542     {
00543       /* Precalc how many times we should go through the loop */
00544       i = ((incr > 0 ? le : ls) - ofs) / incr + 1;
00545       if(i > count) i = count;
00546       if(i > cc) 
00547         {
00548           i = cc;
00549           vibflag = 1;
00550         } 
00551       else cc -= i;
00552       count -= i;
00553       while (i--) 
00554         {
00555           RESAMPLATION;
00556           ofs += incr;
00557         }
00558       if (vibflag) 
00559         {
00560           cc = vp->vibrato_control_ratio;
00561           incr = update_vibrato(vp, (incr < 0));
00562           vibflag = 0;
00563         }
00564       if (ofs >= le) 
00565         {
00566           /* fold the overshoot back in */
00567           ofs = le2 - ofs;
00568           incr *= -1;
00569         } 
00570       else if (ofs <= ls) 
00571         {
00572           ofs = ls2 - ofs;
00573           incr *= -1;
00574         }
00575     }
00576 
00577 #else /* PRECALC_LOOPS */
00578   /* Play normally until inside the loop region */
00579 
00580   if (ofs < ls)
00581     {
00582       while (count--)
00583         {
00584           if (!cc--)
00585             {
00586               cc=vp->vibrato_control_ratio;
00587               incr=update_vibrato(vp, 0);
00588             }
00589           RESAMPLATION;
00590           ofs += incr;
00591           if (ofs>=ls)
00592             break;
00593         }
00594     }
00595 
00596   /* Then do the bidirectional looping */
00597 
00598   if (count>0)
00599     while (count--)
00600       {
00601         if (!cc--)
00602           {
00603             cc=vp->vibrato_control_ratio;
00604             incr=update_vibrato(vp, (incr < 0));
00605           }
00606         RESAMPLATION;
00607         ofs += incr;
00608         if (ofs>=le)
00609           {
00610             /* fold the overshoot back in */
00611             ofs = le - (ofs - le);
00612             incr = -incr;
00613           }
00614         else if (ofs <= ls)
00615           {
00616             ofs = ls + (ls - ofs);
00617             incr = -incr;
00618           }
00619       }
00620 #endif /* PRECALC_LOOPS */
00621 
00622   vp->vibrato_control_counter=cc;
00623   vp->sample_increment=incr;
00624   vp->sample_offset=ofs; /* Update offset */
00625   return resample_buffer;
00626 }
00627 
00628 sample_t *resample_voice(int v, sint32 *countptr)
00629 {
00630   sint32 ofs;
00631   uint8 modes;
00632   Voice *vp=&voice[v];
00633   
00634   if (!(vp->sample->sample_rate))
00635     {
00636       /* Pre-resampled data -- just update the offset and check if
00637          we're out of data. */
00638       ofs=vp->sample_offset >> FRACTION_BITS; /* Kind of silly to use
00639                                                  FRACTION_BITS here... */
00640       if (*countptr >= (vp->sample->data_length>>FRACTION_BITS) - ofs)
00641         {
00642           /* Note finished. Free the voice. */
00643           vp->status = VOICE_FREE;
00644           ctl->note(v);
00645           
00646           /* Let the caller know how much data we had left */
00647           *countptr = (vp->sample->data_length>>FRACTION_BITS) - ofs;
00648         }
00649       else
00650         vp->sample_offset += *countptr << FRACTION_BITS;
00651       
00652       return vp->sample->data+ofs;
00653     }
00654 
00655   /* Need to resample. Use the proper function. */
00656   modes=vp->sample->modes;
00657 
00658   if (vp->vibrato_control_ratio)
00659     {
00660       if ((modes & MODES_LOOPING) &&
00661           ((modes & MODES_ENVELOPE) ||
00662            (vp->status==VOICE_ON || vp->status==VOICE_SUSTAINED)))
00663         {
00664           if (modes & MODES_PINGPONG)
00665             return rs_vib_bidir(vp, *countptr);
00666           else
00667             return rs_vib_loop(vp, *countptr);
00668         }
00669       else
00670         return rs_vib_plain(v, countptr);
00671     }
00672   else
00673     {
00674       if ((modes & MODES_LOOPING) &&
00675           ((modes & MODES_ENVELOPE) ||
00676            (vp->status==VOICE_ON || vp->status==VOICE_SUSTAINED)))
00677         {
00678           if (modes & MODES_PINGPONG)
00679             return rs_bidir(vp, *countptr);
00680           else
00681             return rs_loop(vp, *countptr);
00682         }
00683       else
00684         return rs_plain(v, countptr);
00685     }
00686 }
00687 
00688 void pre_resample(Sample * sp)
00689 {
00690   double a, xdiff;
00691   sint32 incr, ofs, newlen, count;
00692   sint16 *newdata, *dest, *src = (sint16 *) sp->data;
00693   sint16 v1, v2, v3, v4, *vptr;
00694   static const char note_name[12][3] =
00695   {
00696     "C", "C#", "D", "D#", "E", "F", "F#", "G", "G#", "A", "A#", "B"
00697   };
00698 
00699   ctl->cmsg(CMSG_INFO, VERB_NOISY, " * pre-resampling for note %d (%s%d)",
00700             sp->note_to_use,
00701             note_name[sp->note_to_use % 12], (sp->note_to_use & 0x7F) / 12);
00702 
00703   a = ((double) (sp->sample_rate) * freq_table[(int) (sp->note_to_use)]) /
00704     ((double) (sp->root_freq) * play_mode->rate);
00705   newlen = (sint32)(sp->data_length / a);
00706   dest = newdata = safe_Malloc<sint16>(newlen >> FRACTION_BITS);
00707 
00708   count = (newlen >> FRACTION_BITS) - 1;
00709   ofs = incr = (sp->data_length - (1 << FRACTION_BITS)) / count;
00710 
00711   if (--count)
00712     *dest++ = src[0];
00713 
00714   /* Since we're pre-processing and this doesn't have to be done in
00715      real-time, we go ahead and do the full sliding cubic interpolation. */
00716   while (--count)
00717     {
00718       vptr = src + (ofs >> FRACTION_BITS);
00719       v1 = *(vptr - 1);
00720       v2 = *vptr;
00721       v3 = *(vptr + 1);
00722       v4 = *(vptr + 2);
00723       xdiff = FSCALENEG(ofs & FRACTION_MASK, FRACTION_BITS);
00724       *dest++ = (sint16)(v2 + (xdiff / 6.0) * (-2 * v1 - 3 * v2 + 6 * v3 - v4 +
00725       xdiff * (3 * (v1 - 2 * v2 + v3) + xdiff * (-v1 + 3 * (v2 - v3) + v4))));
00726       ofs += incr;
00727     }
00728 
00729   if (ofs & FRACTION_MASK)
00730     {
00731       v1 = src[ofs >> FRACTION_BITS];
00732       v2 = src[(ofs >> FRACTION_BITS) + 1];
00733       *dest++ = static_cast<uint16>(v1 + (((v2 - v1) * (ofs & FRACTION_MASK)) >> FRACTION_BITS));
00734     }
00735   else
00736     *dest++ = src[ofs >> FRACTION_BITS];
00737 
00738   sp->data_length = newlen;
00739   sp->loop_start = (sint32)(sp->loop_start / a);
00740   sp->loop_end = (sint32)(sp->loop_end / a);
00741   free(sp->data);
00742   sp->data = (sample_t *) newdata;
00743   sp->sample_rate = 0;
00744 }
00745 
00746 #ifdef NS_TIMIDITY
00747 };
00748 #endif
00749 
00750 #endif //USE_TIMIDITY_MIDI

Generated on Fri Jul 27 22:27:45 2007 for pentagram by  doxygen 1.4.7