/*
	$Id:$

    TiMidity++ -- MIDI to WAVE converter and player
    Copyright (C) 1999 Masanao Izumo <mo@goice.co.jp>
    Copyright (C) 1995 Tuukka Toivonen <tt@cgs.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.

*/

#include <math.h>
#include <stdio.h>
#ifdef __FreeBSD__
#include <stdlib.h>
#else
#include <malloc.h>
#endif

#include "gtim.h"
#include "common.h"
#include "instrum.h"
#include "playmidi.h"
#include "output.h"
#include "controls.h"
#include "tables.h"
#include "resample.h"


#define LINEAR_INTERPOLATION
#define CSPLINE_INTERPOLATION
#define FILTER_INTERPOLATION
#define ENVELOPE_PITCH_MODULATION


#ifdef LOOKUP_HACK
#define MAX_DATAVAL 127
#define MIN_DATAVAL -128
#else
#define MAX_DATAVAL 32767
#define MIN_DATAVAL -32768
#endif

#define OVERSHOOT_STEP 50


static resample_t *vib_resample_voice(int, uint32 *, int);
static resample_t *normal_resample_voice(int, uint32 *, int);


static void update_reso(Voice *vp)
{
  FLOAT_T depth=vp->reso_depth / 2.0;
  int32 sweep = vp->reso_sweep << 2;
  int32 reso_vol;

  if (!sweep) return;

      /* Update sweep position */

      if (vp->reso_phase == 0) {
      	vp->reso_sweep_position += sweep;
        if (vp->reso_sweep_position >= (1<<SWEEP_SHIFT))
		vp->reso_phase = 1;
      }
      else {
      	vp->reso_sweep_position -= sweep;
        if (-vp->reso_sweep_position >= (1<<SWEEP_SHIFT))
		vp->reso_phase = 0;
      }
	  /* Need to adjust depth */
      depth *= (FLOAT_T)vp->reso_sweep_position / (FLOAT_T)(1<<SWEEP_SHIFT); /* centibels */
      depth += (FLOAT_T)vp->reso_depth/2.0; /* positive centibels */
      reso_vol = (int32)(depth + 0.5);
//fprintf(stderr,"depth = %f pos = %d factor = %f vol = %d\n", depth, vp->reso_sweep_position,
//	       	(FLOAT_T)vp->reso_sweep_position / (FLOAT_T)(1<<SWEEP_SHIFT), reso_vol );
      if (reso_vol < 0) reso_vol = 0;
      if (reso_vol > vp->reso_max) reso_vol = vp->reso_max;
      vp->reso_volume = reso_vol;
}

static void update_lfo(Voice *vp)
{
  /* FLOAT_T depth=vp->modLfoToFilterFc; */
  FLOAT_T depth=vp->lfo_depth;
  int32 sweep = vp->lfo_sweep << 2;

  if (!sweep) return;
  depth *= 0.01;
  if (depth < 0.1) return;
  if (depth > 0.9) depth = 0.9;

      /* Update sweep position */

      if (vp->lfo_phase == 0) {
      	vp->lfo_sweep_position += sweep;
        if (vp->lfo_sweep_position >= (1<<SWEEP_SHIFT))
		vp->lfo_phase = 1;
      }
      else {
      	vp->lfo_sweep_position -= sweep;
        if (-vp->lfo_sweep_position >= (1<<SWEEP_SHIFT))
		vp->lfo_phase = 0;
      }
	  /* Need to adjust depth */
      depth *= (FLOAT_T)vp->lfo_sweep_position / (FLOAT_T)(1<<SWEEP_SHIFT);
      vp->lfo_volume = 1.0 + depth;
}

static int calc_bw_index(Voice *vp)
{
  FLOAT_T mod_amount=vp->modEnvToFilterFc;
  int32 freq = vp->cutoff_freq;
  int ix;

  if (vp->lfo_phase_increment) update_lfo(vp);
  if (vp->reso_phase_increment) update_reso(vp);

/*  if (!vp->lfo_phase_increment && update_modulation_signal(vp)) return 0; */
  if (!vp->lfo_phase_increment && update_modulation_signal(vp)) return 1;

/* printf("mod_amount %f ", mod_amount); */
  if (vp->lfo_volume>0.05) {
	if (mod_amount) mod_amount *= vp->lfo_volume;
	else mod_amount = vp->lfo_volume;
/* printf("lfo %f -> mod %f ", voice[v].lfo_volume, mod_amount); */
  }

  if (mod_amount > 0.05) {
    if (vp->modulation_volume)
       freq =
	(int32)( (double)freq*(1.0 + (mod_amount - 1.0) * (vp->modulation_volume>>22) / 255.0) );
    else freq = (int32)( (double)freq*mod_amount );
/*
printf("v%d freq %d (was %d), modvol %d, mod_amount %f\n", v, (int)freq, (int)voice[v].sample->cutoff_freq,
(int)voice[v].modulation_volume>>22,
mod_amount);
*/
	ix = (freq+50) / 100;
	if (ix >= MAX_BW_INDEX) ix = MAX_BW_INDEX - 1;
	if (ix < 1) ix = 1;
	vp->bw_index = ix;
	return 1;
  }
	ix = (freq+50) / 100;
	if (ix >= MAX_BW_INDEX) ix = MAX_BW_INDEX - 1;
	if (ix < 1) ix = 1;
	vp->bw_index = ix;
  /* return 0; */
  return 1;
}

/*************** resampling with fixed increment *****************/

static resample_t *rs_plain(int v, uint32 *countptr)
{
  /* Play sample until end, then free the voice. */
  Voice
    *vp=&voice[v];
  int32   v0, v1, v2, v3, temp, overshoot;
  splen_t ofsd;
  int32 offset;
  FLOAT_T insamp, outsamp, a0, a1, a2, b0, b1,
    xx0=vp->current_x0, xx1=vp->current_x1, yy0=vp->current_y0, yy1=vp->current_y1;
  uint32 cc_count=vp->modulation_counter, bw_index=vp->bw_index, fmax;
  uint16 reso;
  resample_t newsample;
  resample_t
    *dest=resample_buffer+resample_buffer_offset;
#ifdef SL32
  samplel_t
    *src=vp->sample->ldata;
#else
  sample_t
    *src=vp->sample->data;
#endif
  int32
    incr=vp->sample_increment;
  splen_t
    ofs=vp->sample_offset;
#if defined(LAGRANGE_INTERPOLATION) || defined(CSPLINE_INTERPOLATION)
  splen_t
    ls=0,
    le=vp->sample->data_length;
#endif /* LAGRANGE_INTERPOLATION */
  splen_t
    se=vp->sample->data_length;
  uint32
    count=*countptr;

  if (!incr) return resample_buffer+resample_buffer_offset; /* --gl */

  overshoot = src[(se>>FRACTION_BITS)-1] / OVERSHOOT_STEP;
  if (overshoot < 0) overshoot = -overshoot;

    reso = vp->resonance + vp->reso_volume;
    if (reso > vp->reso_max) reso = vp->reso_max;
    fmax = (1000 + (vp->reso_max - reso) * (vp->reso_max - reso) * 2) / 100;
    if (reso && bw_index > fmax) bw_index = fmax;
    reso = (reso+5)/10;

    switch(reso) {
	case 0:
		a2 = a0 = butterworth_q0[bw_index][0];
		a1 = butterworth_q0[bw_index][1];
		b0 = butterworth_q0[bw_index][2];
		b1 = butterworth_q0[bw_index][3];
		break;
	case 1:
		a2 = a0 = butterworth_q10[bw_index][0];
		a1 = butterworth_q10[bw_index][1];
		b0 = butterworth_q10[bw_index][2];
		b1 = butterworth_q10[bw_index][3];
		break;
	case 2:
		a2 = a0 = butterworth_q20[bw_index][0];
		a1 = butterworth_q20[bw_index][1];
		b0 = butterworth_q20[bw_index][2];
		b1 = butterworth_q20[bw_index][3];
		break;
	case 3:
		a2 = a0 = butterworth_q30[bw_index][0];
		a1 = butterworth_q30[bw_index][1];
		b0 = butterworth_q30[bw_index][2];
		b1 = butterworth_q30[bw_index][3];
		break;
	case 4:
		a2 = a0 = butterworth_q40[bw_index][0];
		a1 = butterworth_q40[bw_index][1];
		b0 = butterworth_q40[bw_index][2];
		b1 = butterworth_q40[bw_index][3];
		break;
	case 5:
		a2 = a0 = butterworth_q50[bw_index][0];
		a1 = butterworth_q50[bw_index][1];
		b0 = butterworth_q50[bw_index][2];
		b1 = butterworth_q50[bw_index][3];
		break;
	case 6:
		a2 = a0 = butterworth_q60[bw_index][0];
		a1 = butterworth_q60[bw_index][1];
		b0 = butterworth_q60[bw_index][2];
		b1 = butterworth_q60[bw_index][3];
		break;
	case 7:
		a2 = a0 = butterworth_q70[bw_index][0];
		a1 = butterworth_q70[bw_index][1];
		b0 = butterworth_q70[bw_index][2];
		b1 = butterworth_q70[bw_index][3];
		break;
	case 8:
		a2 = a0 = butterworth_q80[bw_index][0];
		a1 = butterworth_q80[bw_index][1];
		b0 = butterworth_q80[bw_index][2];
		b1 = butterworth_q80[bw_index][3];
		break;
	case 9:
		a2 = a0 = butterworth_q90[bw_index][0];
		a1 = butterworth_q90[bw_index][1];
		b0 = butterworth_q90[bw_index][2];
		b1 = butterworth_q90[bw_index][3];
		break;
	case 10:
		a2 = a0 = butterworth_q100[bw_index][0];
		a1 = butterworth_q100[bw_index][1];
		b0 = butterworth_q100[bw_index][2];
		b1 = butterworth_q100[bw_index][3];
		break;
	case 11:
		a2 = a0 = butterworth_q110[bw_index][0];
		a1 = butterworth_q110[bw_index][1];
		b0 = butterworth_q110[bw_index][2];
		b1 = butterworth_q110[bw_index][3];
		break;
	case 12:
		a2 = a0 = butterworth_q120[bw_index][0];
		a1 = butterworth_q120[bw_index][1];
		b0 = butterworth_q120[bw_index][2];
		b1 = butterworth_q120[bw_index][3];
		break;
	case 13:
		a2 = a0 = butterworth_q130[bw_index][0];
		a1 = butterworth_q130[bw_index][1];
		b0 = butterworth_q130[bw_index][2];
		b1 = butterworth_q130[bw_index][3];
		break;
	case 14:
		a2 = a0 = butterworth_q140[bw_index][0];
		a1 = butterworth_q140[bw_index][1];
		b0 = butterworth_q140[bw_index][2];
		b1 = butterworth_q140[bw_index][3];
		break;
	case 15:
		a2 = a0 = butterworth_q150[bw_index][0];
		a1 = butterworth_q150[bw_index][1];
		b0 = butterworth_q150[bw_index][2];
		b1 = butterworth_q150[bw_index][3];
		break;
	case 16:
		a2 = a0 = butterworth_q160[bw_index][0];
		a1 = butterworth_q160[bw_index][1];
		b0 = butterworth_q160[bw_index][2];
		b1 = butterworth_q160[bw_index][3];
		break;
	case 17:
		a2 = a0 = butterworth_q170[bw_index][0];
		a1 = butterworth_q170[bw_index][1];
		b0 = butterworth_q170[bw_index][2];
		b1 = butterworth_q170[bw_index][3];
		break;
	case 18:
		a2 = a0 = butterworth_q180[bw_index][0];
		a1 = butterworth_q180[bw_index][1];
		b0 = butterworth_q180[bw_index][2];
		b1 = butterworth_q180[bw_index][3];
		break;
	case 19:
		a2 = a0 = butterworth_q190[bw_index][0];
		a1 = butterworth_q190[bw_index][1];
		b0 = butterworth_q190[bw_index][2];
		b1 = butterworth_q190[bw_index][3];
		break;
	case 20:
		a2 = a0 = butterworth_q200[bw_index][0];
		a1 = butterworth_q200[bw_index][1];
		b0 = butterworth_q200[bw_index][2];
		b1 = butterworth_q200[bw_index][3];
		break;
	case 21:
		a2 = a0 = butterworth_q210[bw_index][0];
		a1 = butterworth_q210[bw_index][1];
		b0 = butterworth_q210[bw_index][2];
		b1 = butterworth_q210[bw_index][3];
		break;
	case 22:
		a2 = a0 = butterworth_q220[bw_index][0];
		a1 = butterworth_q220[bw_index][1];
		b0 = butterworth_q220[bw_index][2];
		b1 = butterworth_q220[bw_index][3];
		break;
	case 23:
		a2 = a0 = butterworth_q230[bw_index][0];
		a1 = butterworth_q230[bw_index][1];
		b0 = butterworth_q230[bw_index][2];
		b1 = butterworth_q230[bw_index][3];
		break;
	default:
	case 24:
		a2 = a0 = butterworth_q240[bw_index][0];
		a1 = butterworth_q240[bw_index][1];
		b0 = butterworth_q240[bw_index][2];
		b1 = butterworth_q240[bw_index][3];
		break;
    }


    while (count--)
    {


	offset = ofs >> FRACTION_BITS;

	if (ofs >= se) {
		int32 delta = (ofs - se)>>FRACTION_BITS;
        	v1 = (int32)src[(int32)(se>>FRACTION_BITS)-1];
		if (overshoot) v1 -=  (delta+1) * v1 / overshoot;
        }
	else  v1 = (int32)src[offset];

	if (ofs + (1L<<FRACTION_BITS) >= se) {
		v2 = v1;
        }
	else  v2 = (int32)src[offset+1];

	if ( (vp->algorithm & INTERPOLATION_LINEAR) || dont_cspline ||
	   ((ofs-(1L<<FRACTION_BITS))<ls)||((ofs+(2L<<FRACTION_BITS))>le)){
		if (!cc_count--) {
		    cc_count = control_ratio - 1;
		    if (calc_bw_index(vp)) {
		        bw_index = vp->bw_index;


    reso = vp->resonance + vp->reso_volume;
    if (reso > vp->reso_max) reso = vp->reso_max;
    fmax = (1000 + (vp->reso_max - reso) * (vp->reso_max - reso) * 2) / 100;
    if (reso && bw_index > fmax) bw_index = fmax;
    reso = (reso+5)/10;

    switch(reso) {
	case 0:
		a2 = a0 = butterworth_q0[bw_index][0];
		a1 = butterworth_q0[bw_index][1];
		b0 = butterworth_q0[bw_index][2];
		b1 = butterworth_q0[bw_index][3];
		break;
	case 1:
		a2 = a0 = butterworth_q10[bw_index][0];
		a1 = butterworth_q10[bw_index][1];
		b0 = butterworth_q10[bw_index][2];
		b1 = butterworth_q10[bw_index][3];
		break;
	case 2:
		a2 = a0 = butterworth_q20[bw_index][0];
		a1 = butterworth_q20[bw_index][1];
		b0 = butterworth_q20[bw_index][2];
		b1 = butterworth_q20[bw_index][3];
		break;
	case 3:
		a2 = a0 = butterworth_q30[bw_index][0];
		a1 = butterworth_q30[bw_index][1];
		b0 = butterworth_q30[bw_index][2];
		b1 = butterworth_q30[bw_index][3];
		break;
	case 4:
		a2 = a0 = butterworth_q40[bw_index][0];
		a1 = butterworth_q40[bw_index][1];
		b0 = butterworth_q40[bw_index][2];
		b1 = butterworth_q40[bw_index][3];
		break;
	case 5:
		a2 = a0 = butterworth_q50[bw_index][0];
		a1 = butterworth_q50[bw_index][1];
		b0 = butterworth_q50[bw_index][2];
		b1 = butterworth_q50[bw_index][3];
		break;
	case 6:
		a2 = a0 = butterworth_q60[bw_index][0];
		a1 = butterworth_q60[bw_index][1];
		b0 = butterworth_q60[bw_index][2];
		b1 = butterworth_q60[bw_index][3];
		break;
	case 7:
		a2 = a0 = butterworth_q70[bw_index][0];
		a1 = butterworth_q70[bw_index][1];
		b0 = butterworth_q70[bw_index][2];
		b1 = butterworth_q70[bw_index][3];
		break;
	case 8:
		a2 = a0 = butterworth_q80[bw_index][0];
		a1 = butterworth_q80[bw_index][1];
		b0 = butterworth_q80[bw_index][2];
		b1 = butterworth_q80[bw_index][3];
		break;
	case 9:
		a2 = a0 = butterworth_q90[bw_index][0];
		a1 = butterworth_q90[bw_index][1];
		b0 = butterworth_q90[bw_index][2];
		b1 = butterworth_q90[bw_index][3];
		break;
	case 10:
		a2 = a0 = butterworth_q100[bw_index][0];
		a1 = butterworth_q100[bw_index][1];
		b0 = butterworth_q100[bw_index][2];
		b1 = butterworth_q100[bw_index][3];
		break;
	case 11:
		a2 = a0 = butterworth_q110[bw_index][0];
		a1 = butterworth_q110[bw_index][1];
		b0 = butterworth_q110[bw_index][2];
		b1 = butterworth_q110[bw_index][3];
		break;
	case 12:
		a2 = a0 = butterworth_q120[bw_index][0];
		a1 = butterworth_q120[bw_index][1];
		b0 = butterworth_q120[bw_index][2];
		b1 = butterworth_q120[bw_index][3];
		break;
	case 13:
		a2 = a0 = butterworth_q130[bw_index][0];
		a1 = butterworth_q130[bw_index][1];
		b0 = butterworth_q130[bw_index][2];
		b1 = butterworth_q130[bw_index][3];
		break;
	case 14:
		a2 = a0 = butterworth_q140[bw_index][0];
		a1 = butterworth_q140[bw_index][1];
		b0 = butterworth_q140[bw_index][2];
		b1 = butterworth_q140[bw_index][3];
		break;
	case 15:
		a2 = a0 = butterworth_q150[bw_index][0];
		a1 = butterworth_q150[bw_index][1];
		b0 = butterworth_q150[bw_index][2];
		b1 = butterworth_q150[bw_index][3];
		break;
	case 16:
		a2 = a0 = butterworth_q160[bw_index][0];
		a1 = butterworth_q160[bw_index][1];
		b0 = butterworth_q160[bw_index][2];
		b1 = butterworth_q160[bw_index][3];
		break;
	case 17:
		a2 = a0 = butterworth_q170[bw_index][0];
		a1 = butterworth_q170[bw_index][1];
		b0 = butterworth_q170[bw_index][2];
		b1 = butterworth_q170[bw_index][3];
		break;
	case 18:
		a2 = a0 = butterworth_q180[bw_index][0];
		a1 = butterworth_q180[bw_index][1];
		b0 = butterworth_q180[bw_index][2];
		b1 = butterworth_q180[bw_index][3];
		break;
	case 19:
		a2 = a0 = butterworth_q190[bw_index][0];
		a1 = butterworth_q190[bw_index][1];
		b0 = butterworth_q190[bw_index][2];
		b1 = butterworth_q190[bw_index][3];
		break;
	case 20:
		a2 = a0 = butterworth_q200[bw_index][0];
		a1 = butterworth_q200[bw_index][1];
		b0 = butterworth_q200[bw_index][2];
		b1 = butterworth_q200[bw_index][3];
		break;
	case 21:
		a2 = a0 = butterworth_q210[bw_index][0];
		a1 = butterworth_q210[bw_index][1];
		b0 = butterworth_q210[bw_index][2];
		b1 = butterworth_q210[bw_index][3];
		break;
	case 22:
		a2 = a0 = butterworth_q220[bw_index][0];
		a1 = butterworth_q220[bw_index][1];
		b0 = butterworth_q220[bw_index][2];
		b1 = butterworth_q220[bw_index][3];
		break;
	case 23:
		a2 = a0 = butterworth_q230[bw_index][0];
		a1 = butterworth_q230[bw_index][1];
		b0 = butterworth_q230[bw_index][2];
		b1 = butterworth_q230[bw_index][3];
		break;
	default:
	case 24:
		a2 = a0 = butterworth_q240[bw_index][0];
		a1 = butterworth_q240[bw_index][1];
		b0 = butterworth_q240[bw_index][2];
		b1 = butterworth_q240[bw_index][3];
		break;
    }


		    }
		    incr = calc_mod_freq(vp, incr);
		}
                newsample = (resample_t)(v1 + ((int32)((v2-v1) * (ofs & FRACTION_MASK)) >> FRACTION_BITS));
	        if (bw_index) {
                    insamp = (FLOAT_T)newsample;
		    outsamp = a0 * insamp + a1 * xx0 + a2 * xx1 - b0 * yy0 - b1 * yy1;
		    xx1 = xx0;
		    xx0 = insamp;
		    yy1 = yy0;
		    yy0 = outsamp;
		    newsample = (resample_t)outsamp;
	        }
	}
	else {
		ofsd=ofs;
                v0 = (int32)src[offset-1];
                v3 = (int32)src[offset+2];
                ofs &= FRACTION_MASK;
                temp=v2;
		v2 = (6*v2 +
		      (((( ( (5*v3 - 11*v2 + 7*v1 - v0)*
		       (int32)ofs) >>FRACTION_BITS)*(int32)ofs)>>(FRACTION_BITS+2))-1))*(int32)ofs;
                ofs = (1L << FRACTION_BITS) - ofs;
		v1 = (6*v1 +
		      ((((((5*v0 - 11*v1 + 7*temp - v3)*
		       (int32)ofs)>>FRACTION_BITS)*(int32)ofs)>>(FRACTION_BITS+2))-1))*(int32)ofs;
		v1 = (v1 + v2)/(6L<<FRACTION_BITS);
		if (!cc_count--) {
		    cc_count = control_ratio - 1;
		    if (calc_bw_index(vp)) {
			bw_index = vp->bw_index;


    reso = vp->resonance + vp->reso_volume;
    if (reso > vp->reso_max) reso = vp->reso_max;
    fmax = (1000 + (vp->reso_max - reso) * (vp->reso_max - reso) * 2) / 100;
    if (reso && bw_index > fmax) bw_index = fmax;
    reso = (reso+5)/10;

    switch(reso) {
	case 0:
		a2 = a0 = butterworth_q0[bw_index][0];
		a1 = butterworth_q0[bw_index][1];
		b0 = butterworth_q0[bw_index][2];
		b1 = butterworth_q0[bw_index][3];
		break;
	case 1:
		a2 = a0 = butterworth_q10[bw_index][0];
		a1 = butterworth_q10[bw_index][1];
		b0 = butterworth_q10[bw_index][2];
		b1 = butterworth_q10[bw_index][3];
		break;
	case 2:
		a2 = a0 = butterworth_q20[bw_index][0];
		a1 = butterworth_q20[bw_index][1];
		b0 = butterworth_q20[bw_index][2];
		b1 = butterworth_q20[bw_index][3];
		break;
	case 3:
		a2 = a0 = butterworth_q30[bw_index][0];
		a1 = butterworth_q30[bw_index][1];
		b0 = butterworth_q30[bw_index][2];
		b1 = butterworth_q30[bw_index][3];
		break;
	case 4:
		a2 = a0 = butterworth_q40[bw_index][0];
		a1 = butterworth_q40[bw_index][1];
		b0 = butterworth_q40[bw_index][2];
		b1 = butterworth_q40[bw_index][3];
		break;
	case 5:
		a2 = a0 = butterworth_q50[bw_index][0];
		a1 = butterworth_q50[bw_index][1];
		b0 = butterworth_q50[bw_index][2];
		b1 = butterworth_q50[bw_index][3];
		break;
	case 6:
		a2 = a0 = butterworth_q60[bw_index][0];
		a1 = butterworth_q60[bw_index][1];
		b0 = butterworth_q60[bw_index][2];
		b1 = butterworth_q60[bw_index][3];
		break;
	case 7:
		a2 = a0 = butterworth_q70[bw_index][0];
		a1 = butterworth_q70[bw_index][1];
		b0 = butterworth_q70[bw_index][2];
		b1 = butterworth_q70[bw_index][3];
		break;
	case 8:
		a2 = a0 = butterworth_q80[bw_index][0];
		a1 = butterworth_q80[bw_index][1];
		b0 = butterworth_q80[bw_index][2];
		b1 = butterworth_q80[bw_index][3];
		break;
	case 9:
		a2 = a0 = butterworth_q90[bw_index][0];
		a1 = butterworth_q90[bw_index][1];
		b0 = butterworth_q90[bw_index][2];
		b1 = butterworth_q90[bw_index][3];
		break;
	case 10:
		a2 = a0 = butterworth_q100[bw_index][0];
		a1 = butterworth_q100[bw_index][1];
		b0 = butterworth_q100[bw_index][2];
		b1 = butterworth_q100[bw_index][3];
		break;
	case 11:
		a2 = a0 = butterworth_q110[bw_index][0];
		a1 = butterworth_q110[bw_index][1];
		b0 = butterworth_q110[bw_index][2];
		b1 = butterworth_q110[bw_index][3];
		break;
	case 12:
		a2 = a0 = butterworth_q120[bw_index][0];
		a1 = butterworth_q120[bw_index][1];
		b0 = butterworth_q120[bw_index][2];
		b1 = butterworth_q120[bw_index][3];
		break;
	case 13:
		a2 = a0 = butterworth_q130[bw_index][0];
		a1 = butterworth_q130[bw_index][1];
		b0 = butterworth_q130[bw_index][2];
		b1 = butterworth_q130[bw_index][3];
		break;
	case 14:
		a2 = a0 = butterworth_q140[bw_index][0];
		a1 = butterworth_q140[bw_index][1];
		b0 = butterworth_q140[bw_index][2];
		b1 = butterworth_q140[bw_index][3];
		break;
	case 15:
		a2 = a0 = butterworth_q150[bw_index][0];
		a1 = butterworth_q150[bw_index][1];
		b0 = butterworth_q150[bw_index][2];
		b1 = butterworth_q150[bw_index][3];
		break;
	case 16:
		a2 = a0 = butterworth_q160[bw_index][0];
		a1 = butterworth_q160[bw_index][1];
		b0 = butterworth_q160[bw_index][2];
		b1 = butterworth_q160[bw_index][3];
		break;
	case 17:
		a2 = a0 = butterworth_q170[bw_index][0];
		a1 = butterworth_q170[bw_index][1];
		b0 = butterworth_q170[bw_index][2];
		b1 = butterworth_q170[bw_index][3];
		break;
	case 18:
		a2 = a0 = butterworth_q180[bw_index][0];
		a1 = butterworth_q180[bw_index][1];
		b0 = butterworth_q180[bw_index][2];
		b1 = butterworth_q180[bw_index][3];
		break;
	case 19:
		a2 = a0 = butterworth_q190[bw_index][0];
		a1 = butterworth_q190[bw_index][1];
		b0 = butterworth_q190[bw_index][2];
		b1 = butterworth_q190[bw_index][3];
		break;
	case 20:
		a2 = a0 = butterworth_q200[bw_index][0];
		a1 = butterworth_q200[bw_index][1];
		b0 = butterworth_q200[bw_index][2];
		b1 = butterworth_q200[bw_index][3];
		break;
	case 21:
		a2 = a0 = butterworth_q210[bw_index][0];
		a1 = butterworth_q210[bw_index][1];
		b0 = butterworth_q210[bw_index][2];
		b1 = butterworth_q210[bw_index][3];
		break;
	case 22:
		a2 = a0 = butterworth_q220[bw_index][0];
		a1 = butterworth_q220[bw_index][1];
		b0 = butterworth_q220[bw_index][2];
		b1 = butterworth_q220[bw_index][3];
		break;
	case 23:
		a2 = a0 = butterworth_q230[bw_index][0];
		a1 = butterworth_q230[bw_index][1];
		b0 = butterworth_q230[bw_index][2];
		b1 = butterworth_q230[bw_index][3];
		break;
	default:
	case 24:
		a2 = a0 = butterworth_q240[bw_index][0];
		a1 = butterworth_q240[bw_index][1];
		b0 = butterworth_q240[bw_index][2];
		b1 = butterworth_q240[bw_index][3];
		break;
    }




		    }
		    incr = calc_mod_freq(vp, incr);
		}
		newsample = (resample_t)v1;
		if (bw_index) {
                    insamp = (FLOAT_T)newsample;
		    outsamp = a0 * insamp + a1 * xx0 + a2 * xx1 - b0 * yy0 - b1 * yy1;
		    xx1 = xx0;
		    xx0 = insamp;
		    yy1 = yy0;
		    yy0 = outsamp;
		    newsample = (resample_t)outsamp;
		}
		ofs=ofsd;
	}
	*dest++ = newsample;
      ofs += incr;
      if (ofs >= se + (overshoot << FRACTION_BITS))
	{
	  if (!(vp->status&VOICE_FREE))
	    {
	      vp->status=VOICE_FREE;
 	      ctl->note(v);
	    }
	  *countptr-=count+1;
	  break;
	}
    }

  vp->sample_offset=ofs; /* Update offset */
  vp->current_x0=xx0;
  vp->current_x1=xx1;
  vp->current_y0=yy0;
  vp->current_y1=yy1;
  vp->bw_index=bw_index;
  vp->modulation_counter=cc_count;
  return resample_buffer+resample_buffer_offset;
}

static resample_t *rs_loop(int v, Voice *vp, uint32 *countptr)
{
  /* Play sample until end-of-loop, skip back and continue. */
  int32   v0, v1, v2, v3, temp, overshoot;
  splen_t ofsd;
  int32 offset;
  FLOAT_T insamp, outsamp, a0, a1, a2, b0, b1,
    xx0=vp->current_x0, xx1=vp->current_x1, yy0=vp->current_y0, yy1=vp->current_y1;
  uint32 cc_count=vp->modulation_counter, bw_index=vp->bw_index, fmax;
  uint16 reso;
  resample_t newsample;
  int32
    incr=vp->sample_increment;
  splen_t
    ofs=vp->sample_offset,
    le=vp->loop_end,
#if defined(LAGRANGE_INTERPOLATION) || defined(CSPLINE_INTERPOLATION)
    ls=vp->loop_start,
#endif /* LAGRANGE_INTERPOLATION */
    ll=le - vp->loop_start;
  resample_t
    *dest=resample_buffer+resample_buffer_offset;
#ifdef SL32
  samplel_t
    *src=vp->sample->ldata;
#else
  sample_t
    *src=vp->sample->data;
#endif
  splen_t
    se=vp->sample->data_length;
  uint32
    count = *countptr;
  int
    flag_exit_loop;


  flag_exit_loop =
	(vp->status & (VOICE_FREE | VOICE_DIE)) ||
	((vp->status & VOICE_OFF) && (vp->sample->modes & MODES_FAST_RELEASE) ) ||
	((vp->status & VOICE_OFF) && dont_keep_looping ) ;

  overshoot = src[(se>>FRACTION_BITS)-1] / OVERSHOOT_STEP;
  if (overshoot < 0) overshoot = -overshoot;

    reso = vp->resonance + vp->reso_volume;
    if (reso > vp->reso_max) reso = vp->reso_max;
    fmax = (1000 + (vp->reso_max - reso) * (vp->reso_max - reso) * 2) / 100;
    if (reso && bw_index > fmax) bw_index = fmax;
    reso = (reso+5)/10;

    switch(reso) {
	case 0:
		a2 = a0 = butterworth_q0[bw_index][0];
		a1 = butterworth_q0[bw_index][1];
		b0 = butterworth_q0[bw_index][2];
		b1 = butterworth_q0[bw_index][3];
		break;
	case 1:
		a2 = a0 = butterworth_q10[bw_index][0];
		a1 = butterworth_q10[bw_index][1];
		b0 = butterworth_q10[bw_index][2];
		b1 = butterworth_q10[bw_index][3];
		break;
	case 2:
		a2 = a0 = butterworth_q20[bw_index][0];
		a1 = butterworth_q20[bw_index][1];
		b0 = butterworth_q20[bw_index][2];
		b1 = butterworth_q20[bw_index][3];
		break;
	case 3:
		a2 = a0 = butterworth_q30[bw_index][0];
		a1 = butterworth_q30[bw_index][1];
		b0 = butterworth_q30[bw_index][2];
		b1 = butterworth_q30[bw_index][3];
		break;
	case 4:
		a2 = a0 = butterworth_q40[bw_index][0];
		a1 = butterworth_q40[bw_index][1];
		b0 = butterworth_q40[bw_index][2];
		b1 = butterworth_q40[bw_index][3];
		break;
	case 5:
		a2 = a0 = butterworth_q50[bw_index][0];
		a1 = butterworth_q50[bw_index][1];
		b0 = butterworth_q50[bw_index][2];
		b1 = butterworth_q50[bw_index][3];
		break;
	case 6:
		a2 = a0 = butterworth_q60[bw_index][0];
		a1 = butterworth_q60[bw_index][1];
		b0 = butterworth_q60[bw_index][2];
		b1 = butterworth_q60[bw_index][3];
		break;
	case 7:
		a2 = a0 = butterworth_q70[bw_index][0];
		a1 = butterworth_q70[bw_index][1];
		b0 = butterworth_q70[bw_index][2];
		b1 = butterworth_q70[bw_index][3];
		break;
	case 8:
		a2 = a0 = butterworth_q80[bw_index][0];
		a1 = butterworth_q80[bw_index][1];
		b0 = butterworth_q80[bw_index][2];
		b1 = butterworth_q80[bw_index][3];
		break;
	case 9:
		a2 = a0 = butterworth_q90[bw_index][0];
		a1 = butterworth_q90[bw_index][1];
		b0 = butterworth_q90[bw_index][2];
		b1 = butterworth_q90[bw_index][3];
		break;
	case 10:
		a2 = a0 = butterworth_q100[bw_index][0];
		a1 = butterworth_q100[bw_index][1];
		b0 = butterworth_q100[bw_index][2];
		b1 = butterworth_q100[bw_index][3];
		break;
	case 11:
		a2 = a0 = butterworth_q110[bw_index][0];
		a1 = butterworth_q110[bw_index][1];
		b0 = butterworth_q110[bw_index][2];
		b1 = butterworth_q110[bw_index][3];
		break;
	case 12:
		a2 = a0 = butterworth_q120[bw_index][0];
		a1 = butterworth_q120[bw_index][1];
		b0 = butterworth_q120[bw_index][2];
		b1 = butterworth_q120[bw_index][3];
		break;
	case 13:
		a2 = a0 = butterworth_q130[bw_index][0];
		a1 = butterworth_q130[bw_index][1];
		b0 = butterworth_q130[bw_index][2];
		b1 = butterworth_q130[bw_index][3];
		break;
	case 14:
		a2 = a0 = butterworth_q140[bw_index][0];
		a1 = butterworth_q140[bw_index][1];
		b0 = butterworth_q140[bw_index][2];
		b1 = butterworth_q140[bw_index][3];
		break;
	case 15:
		a2 = a0 = butterworth_q150[bw_index][0];
		a1 = butterworth_q150[bw_index][1];
		b0 = butterworth_q150[bw_index][2];
		b1 = butterworth_q150[bw_index][3];
		break;
	case 16:
		a2 = a0 = butterworth_q160[bw_index][0];
		a1 = butterworth_q160[bw_index][1];
		b0 = butterworth_q160[bw_index][2];
		b1 = butterworth_q160[bw_index][3];
		break;
	case 17:
		a2 = a0 = butterworth_q170[bw_index][0];
		a1 = butterworth_q170[bw_index][1];
		b0 = butterworth_q170[bw_index][2];
		b1 = butterworth_q170[bw_index][3];
		break;
	case 18:
		a2 = a0 = butterworth_q180[bw_index][0];
		a1 = butterworth_q180[bw_index][1];
		b0 = butterworth_q180[bw_index][2];
		b1 = butterworth_q180[bw_index][3];
		break;
	case 19:
		a2 = a0 = butterworth_q190[bw_index][0];
		a1 = butterworth_q190[bw_index][1];
		b0 = butterworth_q190[bw_index][2];
		b1 = butterworth_q190[bw_index][3];
		break;
	case 20:
		a2 = a0 = butterworth_q200[bw_index][0];
		a1 = butterworth_q200[bw_index][1];
		b0 = butterworth_q200[bw_index][2];
		b1 = butterworth_q200[bw_index][3];
		break;
	case 21:
		a2 = a0 = butterworth_q210[bw_index][0];
		a1 = butterworth_q210[bw_index][1];
		b0 = butterworth_q210[bw_index][2];
		b1 = butterworth_q210[bw_index][3];
		break;
	case 22:
		a2 = a0 = butterworth_q220[bw_index][0];
		a1 = butterworth_q220[bw_index][1];
		b0 = butterworth_q220[bw_index][2];
		b1 = butterworth_q220[bw_index][3];
		break;
	case 23:
		a2 = a0 = butterworth_q230[bw_index][0];
		a1 = butterworth_q230[bw_index][1];
		b0 = butterworth_q230[bw_index][2];
		b1 = butterworth_q230[bw_index][3];
		break;
	default:
	case 24:
		a2 = a0 = butterworth_q240[bw_index][0];
		a1 = butterworth_q240[bw_index][1];
		b0 = butterworth_q240[bw_index][2];
		b1 = butterworth_q240[bw_index][3];
		break;
    }


  while (count--)
    {


	offset = ofs >> FRACTION_BITS;

	if (ofs >= se) {
		int32 delta = (ofs - se)>>FRACTION_BITS;
        	v1 = (int32)src[(int32)(se>>FRACTION_BITS)-1];
		if (overshoot) v1 -=  (delta+1) * v1 / overshoot;
        }
	else  v1 = (int32)src[offset];

	if (ofs + (1L<<FRACTION_BITS) >= se) {
		v2 = v1;
        }
	else  v2 = (int32)src[offset+1];

	if ( (vp->algorithm & INTERPOLATION_LINEAR) || dont_cspline ||
	   ((ofs-(1L<<FRACTION_BITS))<ls)||((ofs+(2L<<FRACTION_BITS))>le)){
		if (!cc_count--) {
		    cc_count = control_ratio - 1;
		    if (calc_bw_index(vp)) {
		        bw_index = vp->bw_index;


    reso = vp->resonance + vp->reso_volume;
    if (reso > vp->reso_max) reso = vp->reso_max;
    fmax = (1000 + (vp->reso_max - reso) * (vp->reso_max - reso) * 2) / 100;
    if (reso && bw_index > fmax) bw_index = fmax;
    reso = (reso+5)/10;

    switch(reso) {
	case 0:
		a2 = a0 = butterworth_q0[bw_index][0];
		a1 = butterworth_q0[bw_index][1];
		b0 = butterworth_q0[bw_index][2];
		b1 = butterworth_q0[bw_index][3];
		break;
	case 1:
		a2 = a0 = butterworth_q10[bw_index][0];
		a1 = butterworth_q10[bw_index][1];
		b0 = butterworth_q10[bw_index][2];
		b1 = butterworth_q10[bw_index][3];
		break;
	case 2:
		a2 = a0 = butterworth_q20[bw_index][0];
		a1 = butterworth_q20[bw_index][1];
		b0 = butterworth_q20[bw_index][2];
		b1 = butterworth_q20[bw_index][3];
		break;
	case 3:
		a2 = a0 = butterworth_q30[bw_index][0];
		a1 = butterworth_q30[bw_index][1];
		b0 = butterworth_q30[bw_index][2];
		b1 = butterworth_q30[bw_index][3];
		break;
	case 4:
		a2 = a0 = butterworth_q40[bw_index][0];
		a1 = butterworth_q40[bw_index][1];
		b0 = butterworth_q40[bw_index][2];
		b1 = butterworth_q40[bw_index][3];
		break;
	case 5:
		a2 = a0 = butterworth_q50[bw_index][0];
		a1 = butterworth_q50[bw_index][1];
		b0 = butterworth_q50[bw_index][2];
		b1 = butterworth_q50[bw_index][3];
		break;
	case 6:
		a2 = a0 = butterworth_q60[bw_index][0];
		a1 = butterworth_q60[bw_index][1];
		b0 = butterworth_q60[bw_index][2];
		b1 = butterworth_q60[bw_index][3];
		break;
	case 7:
		a2 = a0 = butterworth_q70[bw_index][0];
		a1 = butterworth_q70[bw_index][1];
		b0 = butterworth_q70[bw_index][2];
		b1 = butterworth_q70[bw_index][3];
		break;
	case 8:
		a2 = a0 = butterworth_q80[bw_index][0];
		a1 = butterworth_q80[bw_index][1];
		b0 = butterworth_q80[bw_index][2];
		b1 = butterworth_q80[bw_index][3];
		break;
	case 9:
		a2 = a0 = butterworth_q90[bw_index][0];
		a1 = butterworth_q90[bw_index][1];
		b0 = butterworth_q90[bw_index][2];
		b1 = butterworth_q90[bw_index][3];
		break;
	case 10:
		a2 = a0 = butterworth_q100[bw_index][0];
		a1 = butterworth_q100[bw_index][1];
		b0 = butterworth_q100[bw_index][2];
		b1 = butterworth_q100[bw_index][3];
		break;
	case 11:
		a2 = a0 = butterworth_q110[bw_index][0];
		a1 = butterworth_q110[bw_index][1];
		b0 = butterworth_q110[bw_index][2];
		b1 = butterworth_q110[bw_index][3];
		break;
	case 12:
		a2 = a0 = butterworth_q120[bw_index][0];
		a1 = butterworth_q120[bw_index][1];
		b0 = butterworth_q120[bw_index][2];
		b1 = butterworth_q120[bw_index][3];
		break;
	case 13:
		a2 = a0 = butterworth_q130[bw_index][0];
		a1 = butterworth_q130[bw_index][1];
		b0 = butterworth_q130[bw_index][2];
		b1 = butterworth_q130[bw_index][3];
		break;
	case 14:
		a2 = a0 = butterworth_q140[bw_index][0];
		a1 = butterworth_q140[bw_index][1];
		b0 = butterworth_q140[bw_index][2];
		b1 = butterworth_q140[bw_index][3];
		break;
	case 15:
		a2 = a0 = butterworth_q150[bw_index][0];
		a1 = butterworth_q150[bw_index][1];
		b0 = butterworth_q150[bw_index][2];
		b1 = butterworth_q150[bw_index][3];
		break;
	case 16:
		a2 = a0 = butterworth_q160[bw_index][0];
		a1 = butterworth_q160[bw_index][1];
		b0 = butterworth_q160[bw_index][2];
		b1 = butterworth_q160[bw_index][3];
		break;
	case 17:
		a2 = a0 = butterworth_q170[bw_index][0];
		a1 = butterworth_q170[bw_index][1];
		b0 = butterworth_q170[bw_index][2];
		b1 = butterworth_q170[bw_index][3];
		break;
	case 18:
		a2 = a0 = butterworth_q180[bw_index][0];
		a1 = butterworth_q180[bw_index][1];
		b0 = butterworth_q180[bw_index][2];
		b1 = butterworth_q180[bw_index][3];
		break;
	case 19:
		a2 = a0 = butterworth_q190[bw_index][0];
		a1 = butterworth_q190[bw_index][1];
		b0 = butterworth_q190[bw_index][2];
		b1 = butterworth_q190[bw_index][3];
		break;
	case 20:
		a2 = a0 = butterworth_q200[bw_index][0];
		a1 = butterworth_q200[bw_index][1];
		b0 = butterworth_q200[bw_index][2];
		b1 = butterworth_q200[bw_index][3];
		break;
	case 21:
		a2 = a0 = butterworth_q210[bw_index][0];
		a1 = butterworth_q210[bw_index][1];
		b0 = butterworth_q210[bw_index][2];
		b1 = butterworth_q210[bw_index][3];
		break;
	case 22:
		a2 = a0 = butterworth_q220[bw_index][0];
		a1 = butterworth_q220[bw_index][1];
		b0 = butterworth_q220[bw_index][2];
		b1 = butterworth_q220[bw_index][3];
		break;
	case 23:
		a2 = a0 = butterworth_q230[bw_index][0];
		a1 = butterworth_q230[bw_index][1];
		b0 = butterworth_q230[bw_index][2];
		b1 = butterworth_q230[bw_index][3];
		break;
	default:
	case 24:
		a2 = a0 = butterworth_q240[bw_index][0];
		a1 = butterworth_q240[bw_index][1];
		b0 = butterworth_q240[bw_index][2];
		b1 = butterworth_q240[bw_index][3];
		break;
    }


		    }
		    incr = calc_mod_freq(vp, incr);
		}
                newsample = (resample_t)(v1 + ((int32)((v2-v1) * (ofs & FRACTION_MASK)) >> FRACTION_BITS));
	        if (bw_index) {
                    insamp = (FLOAT_T)newsample;
		    outsamp = a0 * insamp + a1 * xx0 + a2 * xx1 - b0 * yy0 - b1 * yy1;
		    xx1 = xx0;
		    xx0 = insamp;
		    yy1 = yy0;
		    yy0 = outsamp;
		    newsample = (resample_t)outsamp;
	        }
	}
	else {
		ofsd=ofs;
                v0 = (int32)src[offset-1];
                v3 = (int32)src[offset+2];
                ofs &= FRACTION_MASK;
                temp=v2;
		v2 = (6*v2 +
		      (((( ( (5*v3 - 11*v2 + 7*v1 - v0)*
		       (int32)ofs) >>FRACTION_BITS)*(int32)ofs)>>(FRACTION_BITS+2))-1))*(int32)ofs;
                ofs = (1L << FRACTION_BITS) - ofs;
		v1 = (6*v1 +
		      ((((((5*v0 - 11*v1 + 7*temp - v3)*
		       (int32)ofs)>>FRACTION_BITS)*(int32)ofs)>>(FRACTION_BITS+2))-1))*(int32)ofs;
		v1 = (v1 + v2)/(6L<<FRACTION_BITS);
		if (!cc_count--) {
		    cc_count = control_ratio - 1;
		    if (calc_bw_index(vp)) {
			bw_index = vp->bw_index;


    reso = vp->resonance + vp->reso_volume;
    if (reso > vp->reso_max) reso = vp->reso_max;
    fmax = (1000 + (vp->reso_max - reso) * (vp->reso_max - reso) * 2) / 100;
    if (reso && bw_index > fmax) bw_index = fmax;
    reso = (reso+5)/10;

    switch(reso) {
	case 0:
		a2 = a0 = butterworth_q0[bw_index][0];
		a1 = butterworth_q0[bw_index][1];
		b0 = butterworth_q0[bw_index][2];
		b1 = butterworth_q0[bw_index][3];
		break;
	case 1:
		a2 = a0 = butterworth_q10[bw_index][0];
		a1 = butterworth_q10[bw_index][1];
		b0 = butterworth_q10[bw_index][2];
		b1 = butterworth_q10[bw_index][3];
		break;
	case 2:
		a2 = a0 = butterworth_q20[bw_index][0];
		a1 = butterworth_q20[bw_index][1];
		b0 = butterworth_q20[bw_index][2];
		b1 = butterworth_q20[bw_index][3];
		break;
	case 3:
		a2 = a0 = butterworth_q30[bw_index][0];
		a1 = butterworth_q30[bw_index][1];
		b0 = butterworth_q30[bw_index][2];
		b1 = butterworth_q30[bw_index][3];
		break;
	case 4:
		a2 = a0 = butterworth_q40[bw_index][0];
		a1 = butterworth_q40[bw_index][1];
		b0 = butterworth_q40[bw_index][2];
		b1 = butterworth_q40[bw_index][3];
		break;
	case 5:
		a2 = a0 = butterworth_q50[bw_index][0];
		a1 = butterworth_q50[bw_index][1];
		b0 = butterworth_q50[bw_index][2];
		b1 = butterworth_q50[bw_index][3];
		break;
	case 6:
		a2 = a0 = butterworth_q60[bw_index][0];
		a1 = butterworth_q60[bw_index][1];
		b0 = butterworth_q60[bw_index][2];
		b1 = butterworth_q60[bw_index][3];
		break;
	case 7:
		a2 = a0 = butterworth_q70[bw_index][0];
		a1 = butterworth_q70[bw_index][1];
		b0 = butterworth_q70[bw_index][2];
		b1 = butterworth_q70[bw_index][3];
		break;
	case 8:
		a2 = a0 = butterworth_q80[bw_index][0];
		a1 = butterworth_q80[bw_index][1];
		b0 = butterworth_q80[bw_index][2];
		b1 = butterworth_q80[bw_index][3];
		break;
	case 9:
		a2 = a0 = butterworth_q90[bw_index][0];
		a1 = butterworth_q90[bw_index][1];
		b0 = butterworth_q90[bw_index][2];
		b1 = butterworth_q90[bw_index][3];
		break;
	case 10:
		a2 = a0 = butterworth_q100[bw_index][0];
		a1 = butterworth_q100[bw_index][1];
		b0 = butterworth_q100[bw_index][2];
		b1 = butterworth_q100[bw_index][3];
		break;
	case 11:
		a2 = a0 = butterworth_q110[bw_index][0];
		a1 = butterworth_q110[bw_index][1];
		b0 = butterworth_q110[bw_index][2];
		b1 = butterworth_q110[bw_index][3];
		break;
	case 12:
		a2 = a0 = butterworth_q120[bw_index][0];
		a1 = butterworth_q120[bw_index][1];
		b0 = butterworth_q120[bw_index][2];
		b1 = butterworth_q120[bw_index][3];
		break;
	case 13:
		a2 = a0 = butterworth_q130[bw_index][0];
		a1 = butterworth_q130[bw_index][1];
		b0 = butterworth_q130[bw_index][2];
		b1 = butterworth_q130[bw_index][3];
		break;
	case 14:
		a2 = a0 = butterworth_q140[bw_index][0];
		a1 = butterworth_q140[bw_index][1];
		b0 = butterworth_q140[bw_index][2];
		b1 = butterworth_q140[bw_index][3];
		break;
	case 15:
		a2 = a0 = butterworth_q150[bw_index][0];
		a1 = butterworth_q150[bw_index][1];
		b0 = butterworth_q150[bw_index][2];
		b1 = butterworth_q150[bw_index][3];
		break;
	case 16:
		a2 = a0 = butterworth_q160[bw_index][0];
		a1 = butterworth_q160[bw_index][1];
		b0 = butterworth_q160[bw_index][2];
		b1 = butterworth_q160[bw_index][3];
		break;
	case 17:
		a2 = a0 = butterworth_q170[bw_index][0];
		a1 = butterworth_q170[bw_index][1];
		b0 = butterworth_q170[bw_index][2];
		b1 = butterworth_q170[bw_index][3];
		break;
	case 18:
		a2 = a0 = butterworth_q180[bw_index][0];
		a1 = butterworth_q180[bw_index][1];
		b0 = butterworth_q180[bw_index][2];
		b1 = butterworth_q180[bw_index][3];
		break;
	case 19:
		a2 = a0 = butterworth_q190[bw_index][0];
		a1 = butterworth_q190[bw_index][1];
		b0 = butterworth_q190[bw_index][2];
		b1 = butterworth_q190[bw_index][3];
		break;
	case 20:
		a2 = a0 = butterworth_q200[bw_index][0];
		a1 = butterworth_q200[bw_index][1];
		b0 = butterworth_q200[bw_index][2];
		b1 = butterworth_q200[bw_index][3];
		break;
	case 21:
		a2 = a0 = butterworth_q210[bw_index][0];
		a1 = butterworth_q210[bw_index][1];
		b0 = butterworth_q210[bw_index][2];
		b1 = butterworth_q210[bw_index][3];
		break;
	case 22:
		a2 = a0 = butterworth_q220[bw_index][0];
		a1 = butterworth_q220[bw_index][1];
		b0 = butterworth_q220[bw_index][2];
		b1 = butterworth_q220[bw_index][3];
		break;
	case 23:
		a2 = a0 = butterworth_q230[bw_index][0];
		a1 = butterworth_q230[bw_index][1];
		b0 = butterworth_q230[bw_index][2];
		b1 = butterworth_q230[bw_index][3];
		break;
	default:
	case 24:
		a2 = a0 = butterworth_q240[bw_index][0];
		a1 = butterworth_q240[bw_index][1];
		b0 = butterworth_q240[bw_index][2];
		b1 = butterworth_q240[bw_index][3];
		break;
    }




		    }
		    incr = calc_mod_freq(vp, incr);
		}
		newsample = (resample_t)v1;
		if (bw_index) {
                    insamp = (FLOAT_T)newsample;
		    outsamp = a0 * insamp + a1 * xx0 + a2 * xx1 - b0 * yy0 - b1 * yy1;
		    xx1 = xx0;
		    xx0 = insamp;
		    yy1 = yy0;
		    yy0 = outsamp;
		    newsample = (resample_t)outsamp;
		}
		ofs=ofsd;
	}
	*dest++ = newsample;
      ofs += incr;
      if (ofs>=le)
	{
	  if (flag_exit_loop)
	    {
	    	vp->reverb_time -= ll >> FRACTION_BITS;
	  	if (vp->reverb_time >= 0) ofs -= ll;
	    }
	  else ofs -= ll; /* Hopefully the loop is longer than an increment. */
	}
      if (ofs >= se + (overshoot << FRACTION_BITS))
	{
	  if (!(vp->status&VOICE_FREE))
	    {
	      vp->status=VOICE_FREE;
 	      ctl->note(v);
	    }
	  *countptr-=count+1;
	  break;
	}
    }

  vp->sample_offset=ofs; /* Update offset */
  vp->current_x0=xx0;
  vp->current_x1=xx1;
  vp->current_y0=yy0;
  vp->current_y1=yy1;
  vp->bw_index=bw_index;
  vp->modulation_counter=cc_count;
  return resample_buffer+resample_buffer_offset;
}

static resample_t *rs_bidir(Voice *vp, uint32 count)
{
  int32   v0, v1, v2, v3, temp, overshoot;
  splen_t ofsd;
  int32 offset;
  FLOAT_T insamp, outsamp, a0, a1, a2, b0, b1,
    xx0=vp->current_x0, xx1=vp->current_x1, yy0=vp->current_y0, yy1=vp->current_y1;
  uint32 cc_count=vp->modulation_counter, bw_index=vp->bw_index, fmax;
  uint16 reso;
  resample_t newsample;
  int32
    incr=vp->sample_increment;
  splen_t
    le=vp->loop_end,
    ls=vp->loop_start,
    ofs=vp->sample_offset,
    se=vp->sample->data_length;
  resample_t
    *dest=resample_buffer+resample_buffer_offset;
#ifdef SL32
  samplel_t
    *src=vp->sample->ldata;
#else
  sample_t
    *src=vp->sample->data;
#endif


#ifdef USE_BIDIR_OVERSHOOT
  int32
    le2 = le<<1,
    ls2 = ls<<1;
#endif
  uint32
    i, j;
  /* Play normally until inside the loop region */

  overshoot = src[(se>>FRACTION_BITS)-1] / OVERSHOOT_STEP;
  if (overshoot < 0) overshoot = -overshoot;

    reso = vp->resonance + vp->reso_volume;
    if (reso > vp->reso_max) reso = vp->reso_max;
    fmax = (1000 + (vp->reso_max - reso) * (vp->reso_max - reso) * 2) / 100;
    if (reso && bw_index > fmax) bw_index = fmax;
    reso = (reso+5)/10;

    switch(reso) {
	case 0:
		a2 = a0 = butterworth_q0[bw_index][0];
		a1 = butterworth_q0[bw_index][1];
		b0 = butterworth_q0[bw_index][2];
		b1 = butterworth_q0[bw_index][3];
		break;
	case 1:
		a2 = a0 = butterworth_q10[bw_index][0];
		a1 = butterworth_q10[bw_index][1];
		b0 = butterworth_q10[bw_index][2];
		b1 = butterworth_q10[bw_index][3];
		break;
	case 2:
		a2 = a0 = butterworth_q20[bw_index][0];
		a1 = butterworth_q20[bw_index][1];
		b0 = butterworth_q20[bw_index][2];
		b1 = butterworth_q20[bw_index][3];
		break;
	case 3:
		a2 = a0 = butterworth_q30[bw_index][0];
		a1 = butterworth_q30[bw_index][1];
		b0 = butterworth_q30[bw_index][2];
		b1 = butterworth_q30[bw_index][3];
		break;
	case 4:
		a2 = a0 = butterworth_q40[bw_index][0];
		a1 = butterworth_q40[bw_index][1];
		b0 = butterworth_q40[bw_index][2];
		b1 = butterworth_q40[bw_index][3];
		break;
	case 5:
		a2 = a0 = butterworth_q50[bw_index][0];
		a1 = butterworth_q50[bw_index][1];
		b0 = butterworth_q50[bw_index][2];
		b1 = butterworth_q50[bw_index][3];
		break;
	case 6:
		a2 = a0 = butterworth_q60[bw_index][0];
		a1 = butterworth_q60[bw_index][1];
		b0 = butterworth_q60[bw_index][2];
		b1 = butterworth_q60[bw_index][3];
		break;
	case 7:
		a2 = a0 = butterworth_q70[bw_index][0];
		a1 = butterworth_q70[bw_index][1];
		b0 = butterworth_q70[bw_index][2];
		b1 = butterworth_q70[bw_index][3];
		break;
	case 8:
		a2 = a0 = butterworth_q80[bw_index][0];
		a1 = butterworth_q80[bw_index][1];
		b0 = butterworth_q80[bw_index][2];
		b1 = butterworth_q80[bw_index][3];
		break;
	case 9:
		a2 = a0 = butterworth_q90[bw_index][0];
		a1 = butterworth_q90[bw_index][1];
		b0 = butterworth_q90[bw_index][2];
		b1 = butterworth_q90[bw_index][3];
		break;
	case 10:
		a2 = a0 = butterworth_q100[bw_index][0];
		a1 = butterworth_q100[bw_index][1];
		b0 = butterworth_q100[bw_index][2];
		b1 = butterworth_q100[bw_index][3];
		break;
	case 11:
		a2 = a0 = butterworth_q110[bw_index][0];
		a1 = butterworth_q110[bw_index][1];
		b0 = butterworth_q110[bw_index][2];
		b1 = butterworth_q110[bw_index][3];
		break;
	case 12:
		a2 = a0 = butterworth_q120[bw_index][0];
		a1 = butterworth_q120[bw_index][1];
		b0 = butterworth_q120[bw_index][2];
		b1 = butterworth_q120[bw_index][3];
		break;
	case 13:
		a2 = a0 = butterworth_q130[bw_index][0];
		a1 = butterworth_q130[bw_index][1];
		b0 = butterworth_q130[bw_index][2];
		b1 = butterworth_q130[bw_index][3];
		break;
	case 14:
		a2 = a0 = butterworth_q140[bw_index][0];
		a1 = butterworth_q140[bw_index][1];
		b0 = butterworth_q140[bw_index][2];
		b1 = butterworth_q140[bw_index][3];
		break;
	case 15:
		a2 = a0 = butterworth_q150[bw_index][0];
		a1 = butterworth_q150[bw_index][1];
		b0 = butterworth_q150[bw_index][2];
		b1 = butterworth_q150[bw_index][3];
		break;
	case 16:
		a2 = a0 = butterworth_q160[bw_index][0];
		a1 = butterworth_q160[bw_index][1];
		b0 = butterworth_q160[bw_index][2];
		b1 = butterworth_q160[bw_index][3];
		break;
	case 17:
		a2 = a0 = butterworth_q170[bw_index][0];
		a1 = butterworth_q170[bw_index][1];
		b0 = butterworth_q170[bw_index][2];
		b1 = butterworth_q170[bw_index][3];
		break;
	case 18:
		a2 = a0 = butterworth_q180[bw_index][0];
		a1 = butterworth_q180[bw_index][1];
		b0 = butterworth_q180[bw_index][2];
		b1 = butterworth_q180[bw_index][3];
		break;
	case 19:
		a2 = a0 = butterworth_q190[bw_index][0];
		a1 = butterworth_q190[bw_index][1];
		b0 = butterworth_q190[bw_index][2];
		b1 = butterworth_q190[bw_index][3];
		break;
	case 20:
		a2 = a0 = butterworth_q200[bw_index][0];
		a1 = butterworth_q200[bw_index][1];
		b0 = butterworth_q200[bw_index][2];
		b1 = butterworth_q200[bw_index][3];
		break;
	case 21:
		a2 = a0 = butterworth_q210[bw_index][0];
		a1 = butterworth_q210[bw_index][1];
		b0 = butterworth_q210[bw_index][2];
		b1 = butterworth_q210[bw_index][3];
		break;
	case 22:
		a2 = a0 = butterworth_q220[bw_index][0];
		a1 = butterworth_q220[bw_index][1];
		b0 = butterworth_q220[bw_index][2];
		b1 = butterworth_q220[bw_index][3];
		break;
	case 23:
		a2 = a0 = butterworth_q230[bw_index][0];
		a1 = butterworth_q230[bw_index][1];
		b0 = butterworth_q230[bw_index][2];
		b1 = butterworth_q230[bw_index][3];
		break;
	default:
	case 24:
		a2 = a0 = butterworth_q240[bw_index][0];
		a1 = butterworth_q240[bw_index][1];
		b0 = butterworth_q240[bw_index][2];
		b1 = butterworth_q240[bw_index][3];
		break;
    }


  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. */
      if (incr < 0) i = ls - ofs;
	else
      i = (ls - ofs) / incr + 1;
      if (i > count)
	{
	  i = count;
	  count = 0;
	}
      else count -= i;
      for(j = 0; j < i; j++)
	{


	offset = ofs >> FRACTION_BITS;

	if (ofs >= se) {
		int32 delta = (ofs - se)>>FRACTION_BITS;
        	v1 = (int32)src[(int32)(se>>FRACTION_BITS)-1];
		if (overshoot) v1 -=  (delta+1) * v1 / overshoot;
        }
	else  v1 = (int32)src[offset];

	if (ofs + (1L<<FRACTION_BITS) >= se) {
		v2 = v1;
        }
	else  v2 = (int32)src[offset+1];

	if ( (vp->algorithm & INTERPOLATION_LINEAR) || dont_cspline ||
	   ((ofs-(1L<<FRACTION_BITS))<ls)||((ofs+(2L<<FRACTION_BITS))>le)){
		if (!cc_count--) {
		    cc_count = control_ratio - 1;
		    if (calc_bw_index(vp)) {
		        bw_index = vp->bw_index;


    reso = vp->resonance + vp->reso_volume;
    if (reso > vp->reso_max) reso = vp->reso_max;
    fmax = (1000 + (vp->reso_max - reso) * (vp->reso_max - reso) * 2) / 100;
    if (reso && bw_index > fmax) bw_index = fmax;
    reso = (reso+5)/10;

    switch(reso) {
	case 0:
		a2 = a0 = butterworth_q0[bw_index][0];
		a1 = butterworth_q0[bw_index][1];
		b0 = butterworth_q0[bw_index][2];
		b1 = butterworth_q0[bw_index][3];
		break;
	case 1:
		a2 = a0 = butterworth_q10[bw_index][0];
		a1 = butterworth_q10[bw_index][1];
		b0 = butterworth_q10[bw_index][2];
		b1 = butterworth_q10[bw_index][3];
		break;
	case 2:
		a2 = a0 = butterworth_q20[bw_index][0];
		a1 = butterworth_q20[bw_index][1];
		b0 = butterworth_q20[bw_index][2];
		b1 = butterworth_q20[bw_index][3];
		break;
	case 3:
		a2 = a0 = butterworth_q30[bw_index][0];
		a1 = butterworth_q30[bw_index][1];
		b0 = butterworth_q30[bw_index][2];
		b1 = butterworth_q30[bw_index][3];
		break;
	case 4:
		a2 = a0 = butterworth_q40[bw_index][0];
		a1 = butterworth_q40[bw_index][1];
		b0 = butterworth_q40[bw_index][2];
		b1 = butterworth_q40[bw_index][3];
		break;
	case 5:
		a2 = a0 = butterworth_q50[bw_index][0];
		a1 = butterworth_q50[bw_index][1];
		b0 = butterworth_q50[bw_index][2];
		b1 = butterworth_q50[bw_index][3];
		break;
	case 6:
		a2 = a0 = butterworth_q60[bw_index][0];
		a1 = butterworth_q60[bw_index][1];
		b0 = butterworth_q60[bw_index][2];
		b1 = butterworth_q60[bw_index][3];
		break;
	case 7:
		a2 = a0 = butterworth_q70[bw_index][0];
		a1 = butterworth_q70[bw_index][1];
		b0 = butterworth_q70[bw_index][2];
		b1 = butterworth_q70[bw_index][3];
		break;
	case 8:
		a2 = a0 = butterworth_q80[bw_index][0];
		a1 = butterworth_q80[bw_index][1];
		b0 = butterworth_q80[bw_index][2];
		b1 = butterworth_q80[bw_index][3];
		break;
	case 9:
		a2 = a0 = butterworth_q90[bw_index][0];
		a1 = butterworth_q90[bw_index][1];
		b0 = butterworth_q90[bw_index][2];
		b1 = butterworth_q90[bw_index][3];
		break;
	case 10:
		a2 = a0 = butterworth_q100[bw_index][0];
		a1 = butterworth_q100[bw_index][1];
		b0 = butterworth_q100[bw_index][2];
		b1 = butterworth_q100[bw_index][3];
		break;
	case 11:
		a2 = a0 = butterworth_q110[bw_index][0];
		a1 = butterworth_q110[bw_index][1];
		b0 = butterworth_q110[bw_index][2];
		b1 = butterworth_q110[bw_index][3];
		break;
	case 12:
		a2 = a0 = butterworth_q120[bw_index][0];
		a1 = butterworth_q120[bw_index][1];
		b0 = butterworth_q120[bw_index][2];
		b1 = butterworth_q120[bw_index][3];
		break;
	case 13:
		a2 = a0 = butterworth_q130[bw_index][0];
		a1 = butterworth_q130[bw_index][1];
		b0 = butterworth_q130[bw_index][2];
		b1 = butterworth_q130[bw_index][3];
		break;
	case 14:
		a2 = a0 = butterworth_q140[bw_index][0];
		a1 = butterworth_q140[bw_index][1];
		b0 = butterworth_q140[bw_index][2];
		b1 = butterworth_q140[bw_index][3];
		break;
	case 15:
		a2 = a0 = butterworth_q150[bw_index][0];
		a1 = butterworth_q150[bw_index][1];
		b0 = butterworth_q150[bw_index][2];
		b1 = butterworth_q150[bw_index][3];
		break;
	case 16:
		a2 = a0 = butterworth_q160[bw_index][0];
		a1 = butterworth_q160[bw_index][1];
		b0 = butterworth_q160[bw_index][2];
		b1 = butterworth_q160[bw_index][3];
		break;
	case 17:
		a2 = a0 = butterworth_q170[bw_index][0];
		a1 = butterworth_q170[bw_index][1];
		b0 = butterworth_q170[bw_index][2];
		b1 = butterworth_q170[bw_index][3];
		break;
	case 18:
		a2 = a0 = butterworth_q180[bw_index][0];
		a1 = butterworth_q180[bw_index][1];
		b0 = butterworth_q180[bw_index][2];
		b1 = butterworth_q180[bw_index][3];
		break;
	case 19:
		a2 = a0 = butterworth_q190[bw_index][0];
		a1 = butterworth_q190[bw_index][1];
		b0 = butterworth_q190[bw_index][2];
		b1 = butterworth_q190[bw_index][3];
		break;
	case 20:
		a2 = a0 = butterworth_q200[bw_index][0];
		a1 = butterworth_q200[bw_index][1];
		b0 = butterworth_q200[bw_index][2];
		b1 = butterworth_q200[bw_index][3];
		break;
	case 21:
		a2 = a0 = butterworth_q210[bw_index][0];
		a1 = butterworth_q210[bw_index][1];
		b0 = butterworth_q210[bw_index][2];
		b1 = butterworth_q210[bw_index][3];
		break;
	case 22:
		a2 = a0 = butterworth_q220[bw_index][0];
		a1 = butterworth_q220[bw_index][1];
		b0 = butterworth_q220[bw_index][2];
		b1 = butterworth_q220[bw_index][3];
		break;
	case 23:
		a2 = a0 = butterworth_q230[bw_index][0];
		a1 = butterworth_q230[bw_index][1];
		b0 = butterworth_q230[bw_index][2];
		b1 = butterworth_q230[bw_index][3];
		break;
	default:
	case 24:
		a2 = a0 = butterworth_q240[bw_index][0];
		a1 = butterworth_q240[bw_index][1];
		b0 = butterworth_q240[bw_index][2];
		b1 = butterworth_q240[bw_index][3];
		break;
    }


		    }
		    incr = calc_mod_freq(vp, incr);
		}
                newsample = (resample_t)(v1 + ((int32)((v2-v1) * (ofs & FRACTION_MASK)) >> FRACTION_BITS));
	        if (bw_index) {
                    insamp = (FLOAT_T)newsample;
		    outsamp = a0 * insamp + a1 * xx0 + a2 * xx1 - b0 * yy0 - b1 * yy1;
		    xx1 = xx0;
		    xx0 = insamp;
		    yy1 = yy0;
		    yy0 = outsamp;
		    newsample = (resample_t)outsamp;
	        }
	}
	else {
		ofsd=ofs;
                v0 = (int32)src[offset-1];
                v3 = (int32)src[offset+2];
                ofs &= FRACTION_MASK;
                temp=v2;
		v2 = (6*v2 +
		      (((( ( (5*v3 - 11*v2 + 7*v1 - v0)*
		       (int32)ofs) >>FRACTION_BITS)*(int32)ofs)>>(FRACTION_BITS+2))-1))*(int32)ofs;
                ofs = (1L << FRACTION_BITS) - ofs;
		v1 = (6*v1 +
		      ((((((5*v0 - 11*v1 + 7*temp - v3)*
		       (int32)ofs)>>FRACTION_BITS)*(int32)ofs)>>(FRACTION_BITS+2))-1))*(int32)ofs;
		v1 = (v1 + v2)/(6L<<FRACTION_BITS);
		if (!cc_count--) {
		    cc_count = control_ratio - 1;
		    if (calc_bw_index(vp)) {
			bw_index = vp->bw_index;


    reso = vp->resonance + vp->reso_volume;
    if (reso > vp->reso_max) reso = vp->reso_max;
    fmax = (1000 + (vp->reso_max - reso) * (vp->reso_max - reso) * 2) / 100;
    if (reso && bw_index > fmax) bw_index = fmax;
    reso = (reso+5)/10;

    switch(reso) {
	case 0:
		a2 = a0 = butterworth_q0[bw_index][0];
		a1 = butterworth_q0[bw_index][1];
		b0 = butterworth_q0[bw_index][2];
		b1 = butterworth_q0[bw_index][3];
		break;
	case 1:
		a2 = a0 = butterworth_q10[bw_index][0];
		a1 = butterworth_q10[bw_index][1];
		b0 = butterworth_q10[bw_index][2];
		b1 = butterworth_q10[bw_index][3];
		break;
	case 2:
		a2 = a0 = butterworth_q20[bw_index][0];
		a1 = butterworth_q20[bw_index][1];
		b0 = butterworth_q20[bw_index][2];
		b1 = butterworth_q20[bw_index][3];
		break;
	case 3:
		a2 = a0 = butterworth_q30[bw_index][0];
		a1 = butterworth_q30[bw_index][1];
		b0 = butterworth_q30[bw_index][2];
		b1 = butterworth_q30[bw_index][3];
		break;
	case 4:
		a2 = a0 = butterworth_q40[bw_index][0];
		a1 = butterworth_q40[bw_index][1];
		b0 = butterworth_q40[bw_index][2];
		b1 = butterworth_q40[bw_index][3];
		break;
	case 5:
		a2 = a0 = butterworth_q50[bw_index][0];
		a1 = butterworth_q50[bw_index][1];
		b0 = butterworth_q50[bw_index][2];
		b1 = butterworth_q50[bw_index][3];
		break;
	case 6:
		a2 = a0 = butterworth_q60[bw_index][0];
		a1 = butterworth_q60[bw_index][1];
		b0 = butterworth_q60[bw_index][2];
		b1 = butterworth_q60[bw_index][3];
		break;
	case 7:
		a2 = a0 = butterworth_q70[bw_index][0];
		a1 = butterworth_q70[bw_index][1];
		b0 = butterworth_q70[bw_index][2];
		b1 = butterworth_q70[bw_index][3];
		break;
	case 8:
		a2 = a0 = butterworth_q80[bw_index][0];
		a1 = butterworth_q80[bw_index][1];
		b0 = butterworth_q80[bw_index][2];
		b1 = butterworth_q80[bw_index][3];
		break;
	case 9:
		a2 = a0 = butterworth_q90[bw_index][0];
		a1 = butterworth_q90[bw_index][1];
		b0 = butterworth_q90[bw_index][2];
		b1 = butterworth_q90[bw_index][3];
		break;
	case 10:
		a2 = a0 = butterworth_q100[bw_index][0];
		a1 = butterworth_q100[bw_index][1];
		b0 = butterworth_q100[bw_index][2];
		b1 = butterworth_q100[bw_index][3];
		break;
	case 11:
		a2 = a0 = butterworth_q110[bw_index][0];
		a1 = butterworth_q110[bw_index][1];
		b0 = butterworth_q110[bw_index][2];
		b1 = butterworth_q110[bw_index][3];
		break;
	case 12:
		a2 = a0 = butterworth_q120[bw_index][0];
		a1 = butterworth_q120[bw_index][1];
		b0 = butterworth_q120[bw_index][2];
		b1 = butterworth_q120[bw_index][3];
		break;
	case 13:
		a2 = a0 = butterworth_q130[bw_index][0];
		a1 = butterworth_q130[bw_index][1];
		b0 = butterworth_q130[bw_index][2];
		b1 = butterworth_q130[bw_index][3];
		break;
	case 14:
		a2 = a0 = butterworth_q140[bw_index][0];
		a1 = butterworth_q140[bw_index][1];
		b0 = butterworth_q140[bw_index][2];
		b1 = butterworth_q140[bw_index][3];
		break;
	case 15:
		a2 = a0 = butterworth_q150[bw_index][0];
		a1 = butterworth_q150[bw_index][1];
		b0 = butterworth_q150[bw_index][2];
		b1 = butterworth_q150[bw_index][3];
		break;
	case 16:
		a2 = a0 = butterworth_q160[bw_index][0];
		a1 = butterworth_q160[bw_index][1];
		b0 = butterworth_q160[bw_index][2];
		b1 = butterworth_q160[bw_index][3];
		break;
	case 17:
		a2 = a0 = butterworth_q170[bw_index][0];
		a1 = butterworth_q170[bw_index][1];
		b0 = butterworth_q170[bw_index][2];
		b1 = butterworth_q170[bw_index][3];
		break;
	case 18:
		a2 = a0 = butterworth_q180[bw_index][0];
		a1 = butterworth_q180[bw_index][1];
		b0 = butterworth_q180[bw_index][2];
		b1 = butterworth_q180[bw_index][3];
		break;
	case 19:
		a2 = a0 = butterworth_q190[bw_index][0];
		a1 = butterworth_q190[bw_index][1];
		b0 = butterworth_q190[bw_index][2];
		b1 = butterworth_q190[bw_index][3];
		break;
	case 20:
		a2 = a0 = butterworth_q200[bw_index][0];
		a1 = butterworth_q200[bw_index][1];
		b0 = butterworth_q200[bw_index][2];
		b1 = butterworth_q200[bw_index][3];
		break;
	case 21:
		a2 = a0 = butterworth_q210[bw_index][0];
		a1 = butterworth_q210[bw_index][1];
		b0 = butterworth_q210[bw_index][2];
		b1 = butterworth_q210[bw_index][3];
		break;
	case 22:
		a2 = a0 = butterworth_q220[bw_index][0];
		a1 = butterworth_q220[bw_index][1];
		b0 = butterworth_q220[bw_index][2];
		b1 = butterworth_q220[bw_index][3];
		break;
	case 23:
		a2 = a0 = butterworth_q230[bw_index][0];
		a1 = butterworth_q230[bw_index][1];
		b0 = butterworth_q230[bw_index][2];
		b1 = butterworth_q230[bw_index][3];
		break;
	default:
	case 24:
		a2 = a0 = butterworth_q240[bw_index][0];
		a1 = butterworth_q240[bw_index][1];
		b0 = butterworth_q240[bw_index][2];
		b1 = butterworth_q240[bw_index][3];
		break;
    }




		    }
		    incr = calc_mod_freq(vp, incr);
		}
		newsample = (resample_t)v1;
		if (bw_index) {
                    insamp = (FLOAT_T)newsample;
		    outsamp = a0 * insamp + a1 * xx0 + a2 * xx1 - b0 * yy0 - b1 * yy1;
		    xx1 = xx0;
		    xx0 = insamp;
		    yy1 = yy0;
		    yy0 = outsamp;
		    newsample = (resample_t)outsamp;
		}
		ofs=ofsd;
	}
	*dest++ = newsample;
	  ofs += incr;
	}
    }

  /* Then do the bidirectional looping */

  while(count)
    {
      /* Precalc how many times we should go through the loop */
#if 1
      i = ((incr > 0 ? le : ls) - ofs) / incr + 1;
#else
/* fix from M. Izumo */
      i = ((incr > 0 ? le : ls) - ofs + incr - 1) / incr;
#endif
      if (i > count)
	{
	  i = count;
	  count = 0;
	}
      else count -= i;
      for(j = 0; j < i && ofs < se; j++)
	{


	offset = ofs >> FRACTION_BITS;

	if (ofs >= se) {
		int32 delta = (ofs - se)>>FRACTION_BITS;
        	v1 = (int32)src[(int32)(se>>FRACTION_BITS)-1];
		if (overshoot) v1 -=  (delta+1) * v1 / overshoot;
        }
	else  v1 = (int32)src[offset];

	if (ofs + (1L<<FRACTION_BITS) >= se) {
		v2 = v1;
        }
	else  v2 = (int32)src[offset+1];

	if ( (vp->algorithm & INTERPOLATION_LINEAR) || dont_cspline ||
	   ((ofs-(1L<<FRACTION_BITS))<ls)||((ofs+(2L<<FRACTION_BITS))>le)){
		if (!cc_count--) {
		    cc_count = control_ratio - 1;
		    if (calc_bw_index(vp)) {
		        bw_index = vp->bw_index;


    reso = vp->resonance + vp->reso_volume;
    if (reso > vp->reso_max) reso = vp->reso_max;
    fmax = (1000 + (vp->reso_max - reso) * (vp->reso_max - reso) * 2) / 100;
    if (reso && bw_index > fmax) bw_index = fmax;
    reso = (reso+5)/10;

    switch(reso) {
	case 0:
		a2 = a0 = butterworth_q0[bw_index][0];
		a1 = butterworth_q0[bw_index][1];
		b0 = butterworth_q0[bw_index][2];
		b1 = butterworth_q0[bw_index][3];
		break;
	case 1:
		a2 = a0 = butterworth_q10[bw_index][0];
		a1 = butterworth_q10[bw_index][1];
		b0 = butterworth_q10[bw_index][2];
		b1 = butterworth_q10[bw_index][3];
		break;
	case 2:
		a2 = a0 = butterworth_q20[bw_index][0];
		a1 = butterworth_q20[bw_index][1];
		b0 = butterworth_q20[bw_index][2];
		b1 = butterworth_q20[bw_index][3];
		break;
	case 3:
		a2 = a0 = butterworth_q30[bw_index][0];
		a1 = butterworth_q30[bw_index][1];
		b0 = butterworth_q30[bw_index][2];
		b1 = butterworth_q30[bw_index][3];
		break;
	case 4:
		a2 = a0 = butterworth_q40[bw_index][0];
		a1 = butterworth_q40[bw_index][1];
		b0 = butterworth_q40[bw_index][2];
		b1 = butterworth_q40[bw_index][3];
		break;
	case 5:
		a2 = a0 = butterworth_q50[bw_index][0];
		a1 = butterworth_q50[bw_index][1];
		b0 = butterworth_q50[bw_index][2];
		b1 = butterworth_q50[bw_index][3];
		break;
	case 6:
		a2 = a0 = butterworth_q60[bw_index][0];
		a1 = butterworth_q60[bw_index][1];
		b0 = butterworth_q60[bw_index][2];
		b1 = butterworth_q60[bw_index][3];
		break;
	case 7:
		a2 = a0 = butterworth_q70[bw_index][0];
		a1 = butterworth_q70[bw_index][1];
		b0 = butterworth_q70[bw_index][2];
		b1 = butterworth_q70[bw_index][3];
		break;
	case 8:
		a2 = a0 = butterworth_q80[bw_index][0];
		a1 = butterworth_q80[bw_index][1];
		b0 = butterworth_q80[bw_index][2];
		b1 = butterworth_q80[bw_index][3];
		break;
	case 9:
		a2 = a0 = butterworth_q90[bw_index][0];
		a1 = butterworth_q90[bw_index][1];
		b0 = butterworth_q90[bw_index][2];
		b1 = butterworth_q90[bw_index][3];
		break;
	case 10:
		a2 = a0 = butterworth_q100[bw_index][0];
		a1 = butterworth_q100[bw_index][1];
		b0 = butterworth_q100[bw_index][2];
		b1 = butterworth_q100[bw_index][3];
		break;
	case 11:
		a2 = a0 = butterworth_q110[bw_index][0];
		a1 = butterworth_q110[bw_index][1];
		b0 = butterworth_q110[bw_index][2];
		b1 = butterworth_q110[bw_index][3];
		break;
	case 12:
		a2 = a0 = butterworth_q120[bw_index][0];
		a1 = butterworth_q120[bw_index][1];
		b0 = butterworth_q120[bw_index][2];
		b1 = butterworth_q120[bw_index][3];
		break;
	case 13:
		a2 = a0 = butterworth_q130[bw_index][0];
		a1 = butterworth_q130[bw_index][1];
		b0 = butterworth_q130[bw_index][2];
		b1 = butterworth_q130[bw_index][3];
		break;
	case 14:
		a2 = a0 = butterworth_q140[bw_index][0];
		a1 = butterworth_q140[bw_index][1];
		b0 = butterworth_q140[bw_index][2];
		b1 = butterworth_q140[bw_index][3];
		break;
	case 15:
		a2 = a0 = butterworth_q150[bw_index][0];
		a1 = butterworth_q150[bw_index][1];
		b0 = butterworth_q150[bw_index][2];
		b1 = butterworth_q150[bw_index][3];
		break;
	case 16:
		a2 = a0 = butterworth_q160[bw_index][0];
		a1 = butterworth_q160[bw_index][1];
		b0 = butterworth_q160[bw_index][2];
		b1 = butterworth_q160[bw_index][3];
		break;
	case 17:
		a2 = a0 = butterworth_q170[bw_index][0];
		a1 = butterworth_q170[bw_index][1];
		b0 = butterworth_q170[bw_index][2];
		b1 = butterworth_q170[bw_index][3];
		break;
	case 18:
		a2 = a0 = butterworth_q180[bw_index][0];
		a1 = butterworth_q180[bw_index][1];
		b0 = butterworth_q180[bw_index][2];
		b1 = butterworth_q180[bw_index][3];
		break;
	case 19:
		a2 = a0 = butterworth_q190[bw_index][0];
		a1 = butterworth_q190[bw_index][1];
		b0 = butterworth_q190[bw_index][2];
		b1 = butterworth_q190[bw_index][3];
		break;
	case 20:
		a2 = a0 = butterworth_q200[bw_index][0];
		a1 = butterworth_q200[bw_index][1];
		b0 = butterworth_q200[bw_index][2];
		b1 = butterworth_q200[bw_index][3];
		break;
	case 21:
		a2 = a0 = butterworth_q210[bw_index][0];
		a1 = butterworth_q210[bw_index][1];
		b0 = butterworth_q210[bw_index][2];
		b1 = butterworth_q210[bw_index][3];
		break;
	case 22:
		a2 = a0 = butterworth_q220[bw_index][0];
		a1 = butterworth_q220[bw_index][1];
		b0 = butterworth_q220[bw_index][2];
		b1 = butterworth_q220[bw_index][3];
		break;
	case 23:
		a2 = a0 = butterworth_q230[bw_index][0];
		a1 = butterworth_q230[bw_index][1];
		b0 = butterworth_q230[bw_index][2];
		b1 = butterworth_q230[bw_index][3];
		break;
	default:
	case 24:
		a2 = a0 = butterworth_q240[bw_index][0];
		a1 = butterworth_q240[bw_index][1];
		b0 = butterworth_q240[bw_index][2];
		b1 = butterworth_q240[bw_index][3];
		break;
    }


		    }
		    incr = calc_mod_freq(vp, incr);
		}
                newsample = (resample_t)(v1 + ((int32)((v2-v1) * (ofs & FRACTION_MASK)) >> FRACTION_BITS));
	        if (bw_index) {
                    insamp = (FLOAT_T)newsample;
		    outsamp = a0 * insamp + a1 * xx0 + a2 * xx1 - b0 * yy0 - b1 * yy1;
		    xx1 = xx0;
		    xx0 = insamp;
		    yy1 = yy0;
		    yy0 = outsamp;
		    newsample = (resample_t)outsamp;
	        }
	}
	else {
		ofsd=ofs;
                v0 = (int32)src[offset-1];
                v3 = (int32)src[offset+2];
                ofs &= FRACTION_MASK;
                temp=v2;
		v2 = (6*v2 +
		      (((( ( (5*v3 - 11*v2 + 7*v1 - v0)*
		       (int32)ofs) >>FRACTION_BITS)*(int32)ofs)>>(FRACTION_BITS+2))-1))*(int32)ofs;
                ofs = (1L << FRACTION_BITS) - ofs;
		v1 = (6*v1 +
		      ((((((5*v0 - 11*v1 + 7*temp - v3)*
		       (int32)ofs)>>FRACTION_BITS)*(int32)ofs)>>(FRACTION_BITS+2))-1))*(int32)ofs;
		v1 = (v1 + v2)/(6L<<FRACTION_BITS);
		if (!cc_count--) {
		    cc_count = control_ratio - 1;
		    if (calc_bw_index(vp)) {
			bw_index = vp->bw_index;


    reso = vp->resonance + vp->reso_volume;
    if (reso > vp->reso_max) reso = vp->reso_max;
    fmax = (1000 + (vp->reso_max - reso) * (vp->reso_max - reso) * 2) / 100;
    if (reso && bw_index > fmax) bw_index = fmax;
    reso = (reso+5)/10;

    switch(reso) {
	case 0:
		a2 = a0 = butterworth_q0[bw_index][0];
		a1 = butterworth_q0[bw_index][1];
		b0 = butterworth_q0[bw_index][2];
		b1 = butterworth_q0[bw_index][3];
		break;
	case 1:
		a2 = a0 = butterworth_q10[bw_index][0];
		a1 = butterworth_q10[bw_index][1];
		b0 = butterworth_q10[bw_index][2];
		b1 = butterworth_q10[bw_index][3];
		break;
	case 2:
		a2 = a0 = butterworth_q20[bw_index][0];
		a1 = butterworth_q20[bw_index][1];
		b0 = butterworth_q20[bw_index][2];
		b1 = butterworth_q20[bw_index][3];
		break;
	case 3:
		a2 = a0 = butterworth_q30[bw_index][0];
		a1 = butterworth_q30[bw_index][1];
		b0 = butterworth_q30[bw_index][2];
		b1 = butterworth_q30[bw_index][3];
		break;
	case 4:
		a2 = a0 = butterworth_q40[bw_index][0];
		a1 = butterworth_q40[bw_index][1];
		b0 = butterworth_q40[bw_index][2];
		b1 = butterworth_q40[bw_index][3];
		break;
	case 5:
		a2 = a0 = butterworth_q50[bw_index][0];
		a1 = butterworth_q50[bw_index][1];
		b0 = butterworth_q50[bw_index][2];
		b1 = butterworth_q50[bw_index][3];
		break;
	case 6:
		a2 = a0 = butterworth_q60[bw_index][0];
		a1 = butterworth_q60[bw_index][1];
		b0 = butterworth_q60[bw_index][2];
		b1 = butterworth_q60[bw_index][3];
		break;
	case 7:
		a2 = a0 = butterworth_q70[bw_index][0];
		a1 = butterworth_q70[bw_index][1];
		b0 = butterworth_q70[bw_index][2];
		b1 = butterworth_q70[bw_index][3];
		break;
	case 8:
		a2 = a0 = butterworth_q80[bw_index][0];
		a1 = butterworth_q80[bw_index][1];
		b0 = butterworth_q80[bw_index][2];
		b1 = butterworth_q80[bw_index][3];
		break;
	case 9:
		a2 = a0 = butterworth_q90[bw_index][0];
		a1 = butterworth_q90[bw_index][1];
		b0 = butterworth_q90[bw_index][2];
		b1 = butterworth_q90[bw_index][3];
		break;
	case 10:
		a2 = a0 = butterworth_q100[bw_index][0];
		a1 = butterworth_q100[bw_index][1];
		b0 = butterworth_q100[bw_index][2];
		b1 = butterworth_q100[bw_index][3];
		break;
	case 11:
		a2 = a0 = butterworth_q110[bw_index][0];
		a1 = butterworth_q110[bw_index][1];
		b0 = butterworth_q110[bw_index][2];
		b1 = butterworth_q110[bw_index][3];
		break;
	case 12:
		a2 = a0 = butterworth_q120[bw_index][0];
		a1 = butterworth_q120[bw_index][1];
		b0 = butterworth_q120[bw_index][2];
		b1 = butterworth_q120[bw_index][3];
		break;
	case 13:
		a2 = a0 = butterworth_q130[bw_index][0];
		a1 = butterworth_q130[bw_index][1];
		b0 = butterworth_q130[bw_index][2];
		b1 = butterworth_q130[bw_index][3];
		break;
	case 14:
		a2 = a0 = butterworth_q140[bw_index][0];
		a1 = butterworth_q140[bw_index][1];
		b0 = butterworth_q140[bw_index][2];
		b1 = butterworth_q140[bw_index][3];
		break;
	case 15:
		a2 = a0 = butterworth_q150[bw_index][0];
		a1 = butterworth_q150[bw_index][1];
		b0 = butterworth_q150[bw_index][2];
		b1 = butterworth_q150[bw_index][3];
		break;
	case 16:
		a2 = a0 = butterworth_q160[bw_index][0];
		a1 = butterworth_q160[bw_index][1];
		b0 = butterworth_q160[bw_index][2];
		b1 = butterworth_q160[bw_index][3];
		break;
	case 17:
		a2 = a0 = butterworth_q170[bw_index][0];
		a1 = butterworth_q170[bw_index][1];
		b0 = butterworth_q170[bw_index][2];
		b1 = butterworth_q170[bw_index][3];
		break;
	case 18:
		a2 = a0 = butterworth_q180[bw_index][0];
		a1 = butterworth_q180[bw_index][1];
		b0 = butterworth_q180[bw_index][2];
		b1 = butterworth_q180[bw_index][3];
		break;
	case 19:
		a2 = a0 = butterworth_q190[bw_index][0];
		a1 = butterworth_q190[bw_index][1];
		b0 = butterworth_q190[bw_index][2];
		b1 = butterworth_q190[bw_index][3];
		break;
	case 20:
		a2 = a0 = butterworth_q200[bw_index][0];
		a1 = butterworth_q200[bw_index][1];
		b0 = butterworth_q200[bw_index][2];
		b1 = butterworth_q200[bw_index][3];
		break;
	case 21:
		a2 = a0 = butterworth_q210[bw_index][0];
		a1 = butterworth_q210[bw_index][1];
		b0 = butterworth_q210[bw_index][2];
		b1 = butterworth_q210[bw_index][3];
		break;
	case 22:
		a2 = a0 = butterworth_q220[bw_index][0];
		a1 = butterworth_q220[bw_index][1];
		b0 = butterworth_q220[bw_index][2];
		b1 = butterworth_q220[bw_index][3];
		break;
	case 23:
		a2 = a0 = butterworth_q230[bw_index][0];
		a1 = butterworth_q230[bw_index][1];
		b0 = butterworth_q230[bw_index][2];
		b1 = butterworth_q230[bw_index][3];
		break;
	default:
	case 24:
		a2 = a0 = butterworth_q240[bw_index][0];
		a1 = butterworth_q240[bw_index][1];
		b0 = butterworth_q240[bw_index][2];
		b1 = butterworth_q240[bw_index][3];
		break;
    }




		    }
		    incr = calc_mod_freq(vp, incr);
		}
		newsample = (resample_t)v1;
		if (bw_index) {
                    insamp = (FLOAT_T)newsample;
		    outsamp = a0 * insamp + a1 * xx0 + a2 * xx1 - b0 * yy0 - b1 * yy1;
		    xx1 = xx0;
		    xx0 = insamp;
		    yy1 = yy0;
		    yy0 = outsamp;
		    newsample = (resample_t)outsamp;
		}
		ofs=ofsd;
	}
	*dest++ = newsample;
	  ofs += incr;
	}
#ifdef USE_BIDIR_OVERSHOOT
      if (ofs>=le)
	{
	  /* fold the overshoot back in */
	  ofs = le2 - ofs;
	  incr *= -1;
	}
      else if (ofs <= ls)
	{
	  ofs = ls2 - ofs;
	  incr *= -1;
	}
#else
	  incr *= -1;
#endif
    }

  vp->sample_increment=incr;
  vp->sample_offset=ofs; /* Update offset */
  vp->current_x0=xx0;
  vp->current_x1=xx1;
  vp->current_y0=yy0;
  vp->current_y1=yy1;
  vp->bw_index=bw_index;
  vp->modulation_counter=cc_count;
  return resample_buffer+resample_buffer_offset;
}

/*********************** vibrato versions ***************************/

/* We only need to compute one half of the vibrato sine cycle */
static uint32 vib_phase_to_inc_ptr(uint32 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 update_vibrato(Voice *vp, int sign)
{
  uint32 depth, freq=vp->frequency;
#ifdef ENVELOPE_PITCH_MODULATION
  FLOAT_T mod_amount=vp->modEnvToPitch;
#endif
  uint32 phase;
  int pb;
  double a;

  if(vp->vibrato_delay > 0)
  {
      vp->vibrato_delay -= vp->vibrato_control_ratio;
      if(vp->vibrato_delay > 0)
	  return vp->sample_increment;
  }

  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->vibrato_depth;
  if(depth < vp->modulation_wheel)
      depth = vp->modulation_wheel;
  depth <<= 7;

  if (vp->vibrato_sweep && !vp->modulation_wheel)
    {
      /* 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;
	}
    }

#ifdef ENVELOPE_PITCH_MODULATION
#ifndef FILTER_INTERPOLATION
  if (update_modulation_signal(vp)) mod_amount = 0;
  else
#endif
  if (mod_amount>0.5)
   freq = (int32)( (double)freq*(1.0 + (mod_amount - 1.0) * (vp->modulation_volume>>22) / 255.0) );
#endif

  pb=(int)((sine(vp->vibrato_phase *
			(SINE_CYCLE_LENGTH/(2*VIBRATO_SAMPLE_INCREMENTS)))
	    * (double)(depth) * VIBRATO_AMPLITUDE_TUNING));

  a = FRSCALE(((double)(vp->sample->sample_rate) *
		  (double)(freq)) /
		 ((double)(vp->sample->root_freq) *
		  (double)(play_mode->rate)),
		 FRACTION_BITS);
  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];
  a += 0.5;

  /* If the sweep's over, we can store the newly computed sample_increment */
  if (!vp->vibrato_sweep || vp->modulation_wheel)
    vp->vibrato_sample_increment[phase]=(int32) a;

  if (sign)
    a = -a; /* need to preserve the loop direction */

  return (int32) a;
}

static resample_t *rs_vib_plain(int v, uint32 *countptr)
{

  /* Play sample until end, then free the voice. */

  Voice *vp=&voice[v];
  int32   v0, v1, v2, v3, temp, overshoot;
  splen_t ofsd;
  int32 offset;
  FLOAT_T insamp, outsamp, a0, a1, a2, b0, b1,
    xx0=vp->current_x0, xx1=vp->current_x1, yy0=vp->current_y0, yy1=vp->current_y1;
  uint32 cc_count=vp->modulation_counter, bw_index=vp->bw_index, fmax;
  uint16 reso;
  resample_t newsample;
  resample_t
    *dest=resample_buffer+resample_buffer_offset;
#ifdef SL32
  samplel_t
    *src=vp->sample->ldata;
#else
  sample_t
    *src=vp->sample->data;
#endif
  int32
    incr=vp->sample_increment;
#if defined(LAGRANGE_INTERPOLATION) || defined(CSPLINE_INTERPOLATION)
  splen_t
    ls=0,
    le=vp->sample->data_length;
#endif /* LAGRANGE_INTERPOLATION */
  splen_t
    ofs=vp->sample_offset,
    se=vp->sample->data_length,
    count=*countptr;
  uint32
    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 */

  overshoot = src[(se>>FRACTION_BITS)-1] / OVERSHOOT_STEP;
  if (overshoot < 0) overshoot = -overshoot;

    reso = vp->resonance + vp->reso_volume;
    if (reso > vp->reso_max) reso = vp->reso_max;
    fmax = (1000 + (vp->reso_max - reso) * (vp->reso_max - reso) * 2) / 100;
    if (reso && bw_index > fmax) bw_index = fmax;
    reso = (reso+5)/10;

    switch(reso) {
	case 0:
		a2 = a0 = butterworth_q0[bw_index][0];
		a1 = butterworth_q0[bw_index][1];
		b0 = butterworth_q0[bw_index][2];
		b1 = butterworth_q0[bw_index][3];
		break;
	case 1:
		a2 = a0 = butterworth_q10[bw_index][0];
		a1 = butterworth_q10[bw_index][1];
		b0 = butterworth_q10[bw_index][2];
		b1 = butterworth_q10[bw_index][3];
		break;
	case 2:
		a2 = a0 = butterworth_q20[bw_index][0];
		a1 = butterworth_q20[bw_index][1];
		b0 = butterworth_q20[bw_index][2];
		b1 = butterworth_q20[bw_index][3];
		break;
	case 3:
		a2 = a0 = butterworth_q30[bw_index][0];
		a1 = butterworth_q30[bw_index][1];
		b0 = butterworth_q30[bw_index][2];
		b1 = butterworth_q30[bw_index][3];
		break;
	case 4:
		a2 = a0 = butterworth_q40[bw_index][0];
		a1 = butterworth_q40[bw_index][1];
		b0 = butterworth_q40[bw_index][2];
		b1 = butterworth_q40[bw_index][3];
		break;
	case 5:
		a2 = a0 = butterworth_q50[bw_index][0];
		a1 = butterworth_q50[bw_index][1];
		b0 = butterworth_q50[bw_index][2];
		b1 = butterworth_q50[bw_index][3];
		break;
	case 6:
		a2 = a0 = butterworth_q60[bw_index][0];
		a1 = butterworth_q60[bw_index][1];
		b0 = butterworth_q60[bw_index][2];
		b1 = butterworth_q60[bw_index][3];
		break;
	case 7:
		a2 = a0 = butterworth_q70[bw_index][0];
		a1 = butterworth_q70[bw_index][1];
		b0 = butterworth_q70[bw_index][2];
		b1 = butterworth_q70[bw_index][3];
		break;
	case 8:
		a2 = a0 = butterworth_q80[bw_index][0];
		a1 = butterworth_q80[bw_index][1];
		b0 = butterworth_q80[bw_index][2];
		b1 = butterworth_q80[bw_index][3];
		break;
	case 9:
		a2 = a0 = butterworth_q90[bw_index][0];
		a1 = butterworth_q90[bw_index][1];
		b0 = butterworth_q90[bw_index][2];
		b1 = butterworth_q90[bw_index][3];
		break;
	case 10:
		a2 = a0 = butterworth_q100[bw_index][0];
		a1 = butterworth_q100[bw_index][1];
		b0 = butterworth_q100[bw_index][2];
		b1 = butterworth_q100[bw_index][3];
		break;
	case 11:
		a2 = a0 = butterworth_q110[bw_index][0];
		a1 = butterworth_q110[bw_index][1];
		b0 = butterworth_q110[bw_index][2];
		b1 = butterworth_q110[bw_index][3];
		break;
	case 12:
		a2 = a0 = butterworth_q120[bw_index][0];
		a1 = butterworth_q120[bw_index][1];
		b0 = butterworth_q120[bw_index][2];
		b1 = butterworth_q120[bw_index][3];
		break;
	case 13:
		a2 = a0 = butterworth_q130[bw_index][0];
		a1 = butterworth_q130[bw_index][1];
		b0 = butterworth_q130[bw_index][2];
		b1 = butterworth_q130[bw_index][3];
		break;
	case 14:
		a2 = a0 = butterworth_q140[bw_index][0];
		a1 = butterworth_q140[bw_index][1];
		b0 = butterworth_q140[bw_index][2];
		b1 = butterworth_q140[bw_index][3];
		break;
	case 15:
		a2 = a0 = butterworth_q150[bw_index][0];
		a1 = butterworth_q150[bw_index][1];
		b0 = butterworth_q150[bw_index][2];
		b1 = butterworth_q150[bw_index][3];
		break;
	case 16:
		a2 = a0 = butterworth_q160[bw_index][0];
		a1 = butterworth_q160[bw_index][1];
		b0 = butterworth_q160[bw_index][2];
		b1 = butterworth_q160[bw_index][3];
		break;
	case 17:
		a2 = a0 = butterworth_q170[bw_index][0];
		a1 = butterworth_q170[bw_index][1];
		b0 = butterworth_q170[bw_index][2];
		b1 = butterworth_q170[bw_index][3];
		break;
	case 18:
		a2 = a0 = butterworth_q180[bw_index][0];
		a1 = butterworth_q180[bw_index][1];
		b0 = butterworth_q180[bw_index][2];
		b1 = butterworth_q180[bw_index][3];
		break;
	case 19:
		a2 = a0 = butterworth_q190[bw_index][0];
		a1 = butterworth_q190[bw_index][1];
		b0 = butterworth_q190[bw_index][2];
		b1 = butterworth_q190[bw_index][3];
		break;
	case 20:
		a2 = a0 = butterworth_q200[bw_index][0];
		a1 = butterworth_q200[bw_index][1];
		b0 = butterworth_q200[bw_index][2];
		b1 = butterworth_q200[bw_index][3];
		break;
	case 21:
		a2 = a0 = butterworth_q210[bw_index][0];
		a1 = butterworth_q210[bw_index][1];
		b0 = butterworth_q210[bw_index][2];
		b1 = butterworth_q210[bw_index][3];
		break;
	case 22:
		a2 = a0 = butterworth_q220[bw_index][0];
		a1 = butterworth_q220[bw_index][1];
		b0 = butterworth_q220[bw_index][2];
		b1 = butterworth_q220[bw_index][3];
		break;
	case 23:
		a2 = a0 = butterworth_q230[bw_index][0];
		a1 = butterworth_q230[bw_index][1];
		b0 = butterworth_q230[bw_index][2];
		b1 = butterworth_q230[bw_index][3];
		break;
	default:
	case 24:
		a2 = a0 = butterworth_q240[bw_index][0];
		a1 = butterworth_q240[bw_index][1];
		b0 = butterworth_q240[bw_index][2];
		b1 = butterworth_q240[bw_index][3];
		break;
    }

  while (count--)
    {
      if (!cc--)
	{
	  cc=vp->vibrato_control_ratio;
	  incr=update_vibrato(vp, 0);
	}


	offset = ofs >> FRACTION_BITS;

	if (ofs >= se) {
		int32 delta = (ofs - se)>>FRACTION_BITS;
        	v1 = (int32)src[(int32)(se>>FRACTION_BITS)-1];
		if (overshoot) v1 -=  (delta+1) * v1 / overshoot;
        }
	else  v1 = (int32)src[offset];

	if (ofs + (1L<<FRACTION_BITS) >= se) {
		v2 = v1;
        }
	else  v2 = (int32)src[offset+1];

	if ( (vp->algorithm & INTERPOLATION_LINEAR) || dont_cspline ||
	   ((ofs-(1L<<FRACTION_BITS))<ls)||((ofs+(2L<<FRACTION_BITS))>le)){
		if (!cc_count--) {
		    cc_count = control_ratio - 1;
		    if (calc_bw_index(vp)) {
		        bw_index = vp->bw_index;


    reso = vp->resonance + vp->reso_volume;
    if (reso > vp->reso_max) reso = vp->reso_max;
    fmax = (1000 + (vp->reso_max - reso) * (vp->reso_max - reso) * 2) / 100;
    if (reso && bw_index > fmax) bw_index = fmax;
    reso = (reso+5)/10;

    switch(reso) {
	case 0:
		a2 = a0 = butterworth_q0[bw_index][0];
		a1 = butterworth_q0[bw_index][1];
		b0 = butterworth_q0[bw_index][2];
		b1 = butterworth_q0[bw_index][3];
		break;
	case 1:
		a2 = a0 = butterworth_q10[bw_index][0];
		a1 = butterworth_q10[bw_index][1];
		b0 = butterworth_q10[bw_index][2];
		b1 = butterworth_q10[bw_index][3];
		break;
	case 2:
		a2 = a0 = butterworth_q20[bw_index][0];
		a1 = butterworth_q20[bw_index][1];
		b0 = butterworth_q20[bw_index][2];
		b1 = butterworth_q20[bw_index][3];
		break;
	case 3:
		a2 = a0 = butterworth_q30[bw_index][0];
		a1 = butterworth_q30[bw_index][1];
		b0 = butterworth_q30[bw_index][2];
		b1 = butterworth_q30[bw_index][3];
		break;
	case 4:
		a2 = a0 = butterworth_q40[bw_index][0];
		a1 = butterworth_q40[bw_index][1];
		b0 = butterworth_q40[bw_index][2];
		b1 = butterworth_q40[bw_index][3];
		break;
	case 5:
		a2 = a0 = butterworth_q50[bw_index][0];
		a1 = butterworth_q50[bw_index][1];
		b0 = butterworth_q50[bw_index][2];
		b1 = butterworth_q50[bw_index][3];
		break;
	case 6:
		a2 = a0 = butterworth_q60[bw_index][0];
		a1 = butterworth_q60[bw_index][1];
		b0 = butterworth_q60[bw_index][2];
		b1 = butterworth_q60[bw_index][3];
		break;
	case 7:
		a2 = a0 = butterworth_q70[bw_index][0];
		a1 = butterworth_q70[bw_index][1];
		b0 = butterworth_q70[bw_index][2];
		b1 = butterworth_q70[bw_index][3];
		break;
	case 8:
		a2 = a0 = butterworth_q80[bw_index][0];
		a1 = butterworth_q80[bw_index][1];
		b0 = butterworth_q80[bw_index][2];
		b1 = butterworth_q80[bw_index][3];
		break;
	case 9:
		a2 = a0 = butterworth_q90[bw_index][0];
		a1 = butterworth_q90[bw_index][1];
		b0 = butterworth_q90[bw_index][2];
		b1 = butterworth_q90[bw_index][3];
		break;
	case 10:
		a2 = a0 = butterworth_q100[bw_index][0];
		a1 = butterworth_q100[bw_index][1];
		b0 = butterworth_q100[bw_index][2];
		b1 = butterworth_q100[bw_index][3];
		break;
	case 11:
		a2 = a0 = butterworth_q110[bw_index][0];
		a1 = butterworth_q110[bw_index][1];
		b0 = butterworth_q110[bw_index][2];
		b1 = butterworth_q110[bw_index][3];
		break;
	case 12:
		a2 = a0 = butterworth_q120[bw_index][0];
		a1 = butterworth_q120[bw_index][1];
		b0 = butterworth_q120[bw_index][2];
		b1 = butterworth_q120[bw_index][3];
		break;
	case 13:
		a2 = a0 = butterworth_q130[bw_index][0];
		a1 = butterworth_q130[bw_index][1];
		b0 = butterworth_q130[bw_index][2];
		b1 = butterworth_q130[bw_index][3];
		break;
	case 14:
		a2 = a0 = butterworth_q140[bw_index][0];
		a1 = butterworth_q140[bw_index][1];
		b0 = butterworth_q140[bw_index][2];
		b1 = butterworth_q140[bw_index][3];
		break;
	case 15:
		a2 = a0 = butterworth_q150[bw_index][0];
		a1 = butterworth_q150[bw_index][1];
		b0 = butterworth_q150[bw_index][2];
		b1 = butterworth_q150[bw_index][3];
		break;
	case 16:
		a2 = a0 = butterworth_q160[bw_index][0];
		a1 = butterworth_q160[bw_index][1];
		b0 = butterworth_q160[bw_index][2];
		b1 = butterworth_q160[bw_index][3];
		break;
	case 17:
		a2 = a0 = butterworth_q170[bw_index][0];
		a1 = butterworth_q170[bw_index][1];
		b0 = butterworth_q170[bw_index][2];
		b1 = butterworth_q170[bw_index][3];
		break;
	case 18:
		a2 = a0 = butterworth_q180[bw_index][0];
		a1 = butterworth_q180[bw_index][1];
		b0 = butterworth_q180[bw_index][2];
		b1 = butterworth_q180[bw_index][3];
		break;
	case 19:
		a2 = a0 = butterworth_q190[bw_index][0];
		a1 = butterworth_q190[bw_index][1];
		b0 = butterworth_q190[bw_index][2];
		b1 = butterworth_q190[bw_index][3];
		break;
	case 20:
		a2 = a0 = butterworth_q200[bw_index][0];
		a1 = butterworth_q200[bw_index][1];
		b0 = butterworth_q200[bw_index][2];
		b1 = butterworth_q200[bw_index][3];
		break;
	case 21:
		a2 = a0 = butterworth_q210[bw_index][0];
		a1 = butterworth_q210[bw_index][1];
		b0 = butterworth_q210[bw_index][2];
		b1 = butterworth_q210[bw_index][3];
		break;
	case 22:
		a2 = a0 = butterworth_q220[bw_index][0];
		a1 = butterworth_q220[bw_index][1];
		b0 = butterworth_q220[bw_index][2];
		b1 = butterworth_q220[bw_index][3];
		break;
	case 23:
		a2 = a0 = butterworth_q230[bw_index][0];
		a1 = butterworth_q230[bw_index][1];
		b0 = butterworth_q230[bw_index][2];
		b1 = butterworth_q230[bw_index][3];
		break;
	default:
	case 24:
		a2 = a0 = butterworth_q240[bw_index][0];
		a1 = butterworth_q240[bw_index][1];
		b0 = butterworth_q240[bw_index][2];
		b1 = butterworth_q240[bw_index][3];
		break;
    }


		    }
		    incr = calc_mod_freq(vp, incr);
		}
                newsample = (resample_t)(v1 + ((int32)((v2-v1) * (ofs & FRACTION_MASK)) >> FRACTION_BITS));
	        if (bw_index) {
                    insamp = (FLOAT_T)newsample;
		    outsamp = a0 * insamp + a1 * xx0 + a2 * xx1 - b0 * yy0 - b1 * yy1;
		    xx1 = xx0;
		    xx0 = insamp;
		    yy1 = yy0;
		    yy0 = outsamp;
		    newsample = (resample_t)outsamp;
	        }
	}
	else {
		ofsd=ofs;
                v0 = (int32)src[offset-1];
                v3 = (int32)src[offset+2];
                ofs &= FRACTION_MASK;
                temp=v2;
		v2 = (6*v2 +
		      (((( ( (5*v3 - 11*v2 + 7*v1 - v0)*
		       (int32)ofs) >>FRACTION_BITS)*(int32)ofs)>>(FRACTION_BITS+2))-1))*(int32)ofs;
                ofs = (1L << FRACTION_BITS) - ofs;
		v1 = (6*v1 +
		      ((((((5*v0 - 11*v1 + 7*temp - v3)*
		       (int32)ofs)>>FRACTION_BITS)*(int32)ofs)>>(FRACTION_BITS+2))-1))*(int32)ofs;
		v1 = (v1 + v2)/(6L<<FRACTION_BITS);
		if (!cc_count--) {
		    cc_count = control_ratio - 1;
		    if (calc_bw_index(vp)) {
			bw_index = vp->bw_index;


    reso = vp->resonance + vp->reso_volume;
    if (reso > vp->reso_max) reso = vp->reso_max;
    fmax = (1000 + (vp->reso_max - reso) * (vp->reso_max - reso) * 2) / 100;
    if (reso && bw_index > fmax) bw_index = fmax;
    reso = (reso+5)/10;

    switch(reso) {
	case 0:
		a2 = a0 = butterworth_q0[bw_index][0];
		a1 = butterworth_q0[bw_index][1];
		b0 = butterworth_q0[bw_index][2];
		b1 = butterworth_q0[bw_index][3];
		break;
	case 1:
		a2 = a0 = butterworth_q10[bw_index][0];
		a1 = butterworth_q10[bw_index][1];
		b0 = butterworth_q10[bw_index][2];
		b1 = butterworth_q10[bw_index][3];
		break;
	case 2:
		a2 = a0 = butterworth_q20[bw_index][0];
		a1 = butterworth_q20[bw_index][1];
		b0 = butterworth_q20[bw_index][2];
		b1 = butterworth_q20[bw_index][3];
		break;
	case 3:
		a2 = a0 = butterworth_q30[bw_index][0];
		a1 = butterworth_q30[bw_index][1];
		b0 = butterworth_q30[bw_index][2];
		b1 = butterworth_q30[bw_index][3];
		break;
	case 4:
		a2 = a0 = butterworth_q40[bw_index][0];
		a1 = butterworth_q40[bw_index][1];
		b0 = butterworth_q40[bw_index][2];
		b1 = butterworth_q40[bw_index][3];
		break;
	case 5:
		a2 = a0 = butterworth_q50[bw_index][0];
		a1 = butterworth_q50[bw_index][1];
		b0 = butterworth_q50[bw_index][2];
		b1 = butterworth_q50[bw_index][3];
		break;
	case 6:
		a2 = a0 = butterworth_q60[bw_index][0];
		a1 = butterworth_q60[bw_index][1];
		b0 = butterworth_q60[bw_index][2];
		b1 = butterworth_q60[bw_index][3];
		break;
	case 7:
		a2 = a0 = butterworth_q70[bw_index][0];
		a1 = butterworth_q70[bw_index][1];
		b0 = butterworth_q70[bw_index][2];
		b1 = butterworth_q70[bw_index][3];
		break;
	case 8:
		a2 = a0 = butterworth_q80[bw_index][0];
		a1 = butterworth_q80[bw_index][1];
		b0 = butterworth_q80[bw_index][2];
		b1 = butterworth_q80[bw_index][3];
		break;
	case 9:
		a2 = a0 = butterworth_q90[bw_index][0];
		a1 = butterworth_q90[bw_index][1];
		b0 = butterworth_q90[bw_index][2];
		b1 = butterworth_q90[bw_index][3];
		break;
	case 10:
		a2 = a0 = butterworth_q100[bw_index][0];
		a1 = butterworth_q100[bw_index][1];
		b0 = butterworth_q100[bw_index][2];
		b1 = butterworth_q100[bw_index][3];
		break;
	case 11:
		a2 = a0 = butterworth_q110[bw_index][0];
		a1 = butterworth_q110[bw_index][1];
		b0 = butterworth_q110[bw_index][2];
		b1 = butterworth_q110[bw_index][3];
		break;
	case 12:
		a2 = a0 = butterworth_q120[bw_index][0];
		a1 = butterworth_q120[bw_index][1];
		b0 = butterworth_q120[bw_index][2];
		b1 = butterworth_q120[bw_index][3];
		break;
	case 13:
		a2 = a0 = butterworth_q130[bw_index][0];
		a1 = butterworth_q130[bw_index][1];
		b0 = butterworth_q130[bw_index][2];
		b1 = butterworth_q130[bw_index][3];
		break;
	case 14:
		a2 = a0 = butterworth_q140[bw_index][0];
		a1 = butterworth_q140[bw_index][1];
		b0 = butterworth_q140[bw_index][2];
		b1 = butterworth_q140[bw_index][3];
		break;
	case 15:
		a2 = a0 = butterworth_q150[bw_index][0];
		a1 = butterworth_q150[bw_index][1];
		b0 = butterworth_q150[bw_index][2];
		b1 = butterworth_q150[bw_index][3];
		break;
	case 16:
		a2 = a0 = butterworth_q160[bw_index][0];
		a1 = butterworth_q160[bw_index][1];
		b0 = butterworth_q160[bw_index][2];
		b1 = butterworth_q160[bw_index][3];
		break;
	case 17:
		a2 = a0 = butterworth_q170[bw_index][0];
		a1 = butterworth_q170[bw_index][1];
		b0 = butterworth_q170[bw_index][2];
		b1 = butterworth_q170[bw_index][3];
		break;
	case 18:
		a2 = a0 = butterworth_q180[bw_index][0];
		a1 = butterworth_q180[bw_index][1];
		b0 = butterworth_q180[bw_index][2];
		b1 = butterworth_q180[bw_index][3];
		break;
	case 19:
		a2 = a0 = butterworth_q190[bw_index][0];
		a1 = butterworth_q190[bw_index][1];
		b0 = butterworth_q190[bw_index][2];
		b1 = butterworth_q190[bw_index][3];
		break;
	case 20:
		a2 = a0 = butterworth_q200[bw_index][0];
		a1 = butterworth_q200[bw_index][1];
		b0 = butterworth_q200[bw_index][2];
		b1 = butterworth_q200[bw_index][3];
		break;
	case 21:
		a2 = a0 = butterworth_q210[bw_index][0];
		a1 = butterworth_q210[bw_index][1];
		b0 = butterworth_q210[bw_index][2];
		b1 = butterworth_q210[bw_index][3];
		break;
	case 22:
		a2 = a0 = butterworth_q220[bw_index][0];
		a1 = butterworth_q220[bw_index][1];
		b0 = butterworth_q220[bw_index][2];
		b1 = butterworth_q220[bw_index][3];
		break;
	case 23:
		a2 = a0 = butterworth_q230[bw_index][0];
		a1 = butterworth_q230[bw_index][1];
		b0 = butterworth_q230[bw_index][2];
		b1 = butterworth_q230[bw_index][3];
		break;
	default:
	case 24:
		a2 = a0 = butterworth_q240[bw_index][0];
		a1 = butterworth_q240[bw_index][1];
		b0 = butterworth_q240[bw_index][2];
		b1 = butterworth_q240[bw_index][3];
		break;
    }




		    }
		    incr = calc_mod_freq(vp, incr);
		}
		newsample = (resample_t)v1;
		if (bw_index) {
                    insamp = (FLOAT_T)newsample;
		    outsamp = a0 * insamp + a1 * xx0 + a2 * xx1 - b0 * yy0 - b1 * yy1;
		    xx1 = xx0;
		    xx0 = insamp;
		    yy1 = yy0;
		    yy0 = outsamp;
		    newsample = (resample_t)outsamp;
		}
		ofs=ofsd;
	}
	*dest++ = newsample;
      ofs += incr;
      if (ofs >= se + (overshoot << FRACTION_BITS))
	{
	  if (!(vp->status&VOICE_FREE))
	    {
	      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 */
  vp->current_x0=xx0;
  vp->current_x1=xx1;
  vp->current_y0=yy0;
  vp->current_y1=yy1;
  vp->bw_index=bw_index;
  vp->modulation_counter=cc_count;
  return resample_buffer+resample_buffer_offset;
}

static resample_t *rs_vib_loop(int v, Voice *vp, uint32 *countptr)
{
  /* Play sample until end-of-loop, skip back and continue. */
  int32   v0, v1, v2, v3, temp, overshoot;
  splen_t ofsd;
  int32 offset;
  FLOAT_T insamp, outsamp, a0, a1, a2, b0, b1,
    xx0=vp->current_x0, xx1=vp->current_x1, yy0=vp->current_y0, yy1=vp->current_y1;
  uint32 cc_count=vp->modulation_counter, bw_index=vp->bw_index, fmax;
  uint16 reso;
  resample_t newsample;
  int32
    incr=vp->sample_increment;
  splen_t
#if defined(LAGRANGE_INTERPOLATION) || defined(CSPLINE_INTERPOLATION)
    ls=vp->loop_start,
#endif /* LAGRANGE_INTERPOLATION */
    le=vp->loop_end,
    ll=le - vp->loop_start;
  resample_t
    *dest=resample_buffer+resample_buffer_offset;
#ifdef SL32
  samplel_t
    *src=vp->sample->ldata;
#else
  sample_t
    *src=vp->sample->data;
#endif
  splen_t
    ofs=vp->sample_offset,
    se=vp->sample->data_length,
    count = *countptr;
  uint32
    cc=vp->vibrato_control_counter;
  int
    flag_exit_loop;


  flag_exit_loop =
	(vp->status & (VOICE_FREE | VOICE_DIE)) ||
	((vp->status & VOICE_OFF) && (vp->sample->modes & MODES_FAST_RELEASE) ) ||
	((vp->status & VOICE_OFF) && dont_keep_looping ) ;

  overshoot = src[(se>>FRACTION_BITS)-1] / OVERSHOOT_STEP;
  if (overshoot < 0) overshoot = -overshoot;

    reso = vp->resonance + vp->reso_volume;
    if (reso > vp->reso_max) reso = vp->reso_max;
    fmax = (1000 + (vp->reso_max - reso) * (vp->reso_max - reso) * 2) / 100;
    if (reso && bw_index > fmax) bw_index = fmax;
    reso = (reso+5)/10;

    switch(reso) {
	case 0:
		a2 = a0 = butterworth_q0[bw_index][0];
		a1 = butterworth_q0[bw_index][1];
		b0 = butterworth_q0[bw_index][2];
		b1 = butterworth_q0[bw_index][3];
		break;
	case 1:
		a2 = a0 = butterworth_q10[bw_index][0];
		a1 = butterworth_q10[bw_index][1];
		b0 = butterworth_q10[bw_index][2];
		b1 = butterworth_q10[bw_index][3];
		break;
	case 2:
		a2 = a0 = butterworth_q20[bw_index][0];
		a1 = butterworth_q20[bw_index][1];
		b0 = butterworth_q20[bw_index][2];
		b1 = butterworth_q20[bw_index][3];
		break;
	case 3:
		a2 = a0 = butterworth_q30[bw_index][0];
		a1 = butterworth_q30[bw_index][1];
		b0 = butterworth_q30[bw_index][2];
		b1 = butterworth_q30[bw_index][3];
		break;
	case 4:
		a2 = a0 = butterworth_q40[bw_index][0];
		a1 = butterworth_q40[bw_index][1];
		b0 = butterworth_q40[bw_index][2];
		b1 = butterworth_q40[bw_index][3];
		break;
	case 5:
		a2 = a0 = butterworth_q50[bw_index][0];
		a1 = butterworth_q50[bw_index][1];
		b0 = butterworth_q50[bw_index][2];
		b1 = butterworth_q50[bw_index][3];
		break;
	case 6:
		a2 = a0 = butterworth_q60[bw_index][0];
		a1 = butterworth_q60[bw_index][1];
		b0 = butterworth_q60[bw_index][2];
		b1 = butterworth_q60[bw_index][3];
		break;
	case 7:
		a2 = a0 = butterworth_q70[bw_index][0];
		a1 = butterworth_q70[bw_index][1];
		b0 = butterworth_q70[bw_index][2];
		b1 = butterworth_q70[bw_index][3];
		break;
	case 8:
		a2 = a0 = butterworth_q80[bw_index][0];
		a1 = butterworth_q80[bw_index][1];
		b0 = butterworth_q80[bw_index][2];
		b1 = butterworth_q80[bw_index][3];
		break;
	case 9:
		a2 = a0 = butterworth_q90[bw_index][0];
		a1 = butterworth_q90[bw_index][1];
		b0 = butterworth_q90[bw_index][2];
		b1 = butterworth_q90[bw_index][3];
		break;
	case 10:
		a2 = a0 = butterworth_q100[bw_index][0];
		a1 = butterworth_q100[bw_index][1];
		b0 = butterworth_q100[bw_index][2];
		b1 = butterworth_q100[bw_index][3];
		break;
	case 11:
		a2 = a0 = butterworth_q110[bw_index][0];
		a1 = butterworth_q110[bw_index][1];
		b0 = butterworth_q110[bw_index][2];
		b1 = butterworth_q110[bw_index][3];
		break;
	case 12:
		a2 = a0 = butterworth_q120[bw_index][0];
		a1 = butterworth_q120[bw_index][1];
		b0 = butterworth_q120[bw_index][2];
		b1 = butterworth_q120[bw_index][3];
		break;
	case 13:
		a2 = a0 = butterworth_q130[bw_index][0];
		a1 = butterworth_q130[bw_index][1];
		b0 = butterworth_q130[bw_index][2];
		b1 = butterworth_q130[bw_index][3];
		break;
	case 14:
		a2 = a0 = butterworth_q140[bw_index][0];
		a1 = butterworth_q140[bw_index][1];
		b0 = butterworth_q140[bw_index][2];
		b1 = butterworth_q140[bw_index][3];
		break;
	case 15:
		a2 = a0 = butterworth_q150[bw_index][0];
		a1 = butterworth_q150[bw_index][1];
		b0 = butterworth_q150[bw_index][2];
		b1 = butterworth_q150[bw_index][3];
		break;
	case 16:
		a2 = a0 = butterworth_q160[bw_index][0];
		a1 = butterworth_q160[bw_index][1];
		b0 = butterworth_q160[bw_index][2];
		b1 = butterworth_q160[bw_index][3];
		break;
	case 17:
		a2 = a0 = butterworth_q170[bw_index][0];
		a1 = butterworth_q170[bw_index][1];
		b0 = butterworth_q170[bw_index][2];
		b1 = butterworth_q170[bw_index][3];
		break;
	case 18:
		a2 = a0 = butterworth_q180[bw_index][0];
		a1 = butterworth_q180[bw_index][1];
		b0 = butterworth_q180[bw_index][2];
		b1 = butterworth_q180[bw_index][3];
		break;
	case 19:
		a2 = a0 = butterworth_q190[bw_index][0];
		a1 = butterworth_q190[bw_index][1];
		b0 = butterworth_q190[bw_index][2];
		b1 = butterworth_q190[bw_index][3];
		break;
	case 20:
		a2 = a0 = butterworth_q200[bw_index][0];
		a1 = butterworth_q200[bw_index][1];
		b0 = butterworth_q200[bw_index][2];
		b1 = butterworth_q200[bw_index][3];
		break;
	case 21:
		a2 = a0 = butterworth_q210[bw_index][0];
		a1 = butterworth_q210[bw_index][1];
		b0 = butterworth_q210[bw_index][2];
		b1 = butterworth_q210[bw_index][3];
		break;
	case 22:
		a2 = a0 = butterworth_q220[bw_index][0];
		a1 = butterworth_q220[bw_index][1];
		b0 = butterworth_q220[bw_index][2];
		b1 = butterworth_q220[bw_index][3];
		break;
	case 23:
		a2 = a0 = butterworth_q230[bw_index][0];
		a1 = butterworth_q230[bw_index][1];
		b0 = butterworth_q230[bw_index][2];
		b1 = butterworth_q230[bw_index][3];
		break;
	default:
	case 24:
		a2 = a0 = butterworth_q240[bw_index][0];
		a1 = butterworth_q240[bw_index][1];
		b0 = butterworth_q240[bw_index][2];
		b1 = butterworth_q240[bw_index][3];
		break;
    }

  while (count--)
    {
      if (!cc--)
	{
	  cc=vp->vibrato_control_ratio;
	  incr=update_vibrato(vp, 0);
	}


	offset = ofs >> FRACTION_BITS;

	if (ofs >= se) {
		int32 delta = (ofs - se)>>FRACTION_BITS;
        	v1 = (int32)src[(int32)(se>>FRACTION_BITS)-1];
		if (overshoot) v1 -=  (delta+1) * v1 / overshoot;
        }
	else  v1 = (int32)src[offset];

	if (ofs + (1L<<FRACTION_BITS) >= se) {
		v2 = v1;
        }
	else  v2 = (int32)src[offset+1];

	if ( (vp->algorithm & INTERPOLATION_LINEAR) || dont_cspline ||
	   ((ofs-(1L<<FRACTION_BITS))<ls)||((ofs+(2L<<FRACTION_BITS))>le)){
		if (!cc_count--) {
		    cc_count = control_ratio - 1;
		    if (calc_bw_index(vp)) {
		        bw_index = vp->bw_index;


    reso = vp->resonance + vp->reso_volume;
    if (reso > vp->reso_max) reso = vp->reso_max;
    fmax = (1000 + (vp->reso_max - reso) * (vp->reso_max - reso) * 2) / 100;
    if (reso && bw_index > fmax) bw_index = fmax;
    reso = (reso+5)/10;

    switch(reso) {
	case 0:
		a2 = a0 = butterworth_q0[bw_index][0];
		a1 = butterworth_q0[bw_index][1];
		b0 = butterworth_q0[bw_index][2];
		b1 = butterworth_q0[bw_index][3];
		break;
	case 1:
		a2 = a0 = butterworth_q10[bw_index][0];
		a1 = butterworth_q10[bw_index][1];
		b0 = butterworth_q10[bw_index][2];
		b1 = butterworth_q10[bw_index][3];
		break;
	case 2:
		a2 = a0 = butterworth_q20[bw_index][0];
		a1 = butterworth_q20[bw_index][1];
		b0 = butterworth_q20[bw_index][2];
		b1 = butterworth_q20[bw_index][3];
		break;
	case 3:
		a2 = a0 = butterworth_q30[bw_index][0];
		a1 = butterworth_q30[bw_index][1];
		b0 = butterworth_q30[bw_index][2];
		b1 = butterworth_q30[bw_index][3];
		break;
	case 4:
		a2 = a0 = butterworth_q40[bw_index][0];
		a1 = butterworth_q40[bw_index][1];
		b0 = butterworth_q40[bw_index][2];
		b1 = butterworth_q40[bw_index][3];
		break;
	case 5:
		a2 = a0 = butterworth_q50[bw_index][0];
		a1 = butterworth_q50[bw_index][1];
		b0 = butterworth_q50[bw_index][2];
		b1 = butterworth_q50[bw_index][3];
		break;
	case 6:
		a2 = a0 = butterworth_q60[bw_index][0];
		a1 = butterworth_q60[bw_index][1];
		b0 = butterworth_q60[bw_index][2];
		b1 = butterworth_q60[bw_index][3];
		break;
	case 7:
		a2 = a0 = butterworth_q70[bw_index][0];
		a1 = butterworth_q70[bw_index][1];
		b0 = butterworth_q70[bw_index][2];
		b1 = butterworth_q70[bw_index][3];
		break;
	case 8:
		a2 = a0 = butterworth_q80[bw_index][0];
		a1 = butterworth_q80[bw_index][1];
		b0 = butterworth_q80[bw_index][2];
		b1 = butterworth_q80[bw_index][3];
		break;
	case 9:
		a2 = a0 = butterworth_q90[bw_index][0];
		a1 = butterworth_q90[bw_index][1];
		b0 = butterworth_q90[bw_index][2];
		b1 = butterworth_q90[bw_index][3];
		break;
	case 10:
		a2 = a0 = butterworth_q100[bw_index][0];
		a1 = butterworth_q100[bw_index][1];
		b0 = butterworth_q100[bw_index][2];
		b1 = butterworth_q100[bw_index][3];
		break;
	case 11:
		a2 = a0 = butterworth_q110[bw_index][0];
		a1 = butterworth_q110[bw_index][1];
		b0 = butterworth_q110[bw_index][2];
		b1 = butterworth_q110[bw_index][3];
		break;
	case 12:
		a2 = a0 = butterworth_q120[bw_index][0];
		a1 = butterworth_q120[bw_index][1];
		b0 = butterworth_q120[bw_index][2];
		b1 = butterworth_q120[bw_index][3];
		break;
	case 13:
		a2 = a0 = butterworth_q130[bw_index][0];
		a1 = butterworth_q130[bw_index][1];
		b0 = butterworth_q130[bw_index][2];
		b1 = butterworth_q130[bw_index][3];
		break;
	case 14:
		a2 = a0 = butterworth_q140[bw_index][0];
		a1 = butterworth_q140[bw_index][1];
		b0 = butterworth_q140[bw_index][2];
		b1 = butterworth_q140[bw_index][3];
		break;
	case 15:
		a2 = a0 = butterworth_q150[bw_index][0];
		a1 = butterworth_q150[bw_index][1];
		b0 = butterworth_q150[bw_index][2];
		b1 = butterworth_q150[bw_index][3];
		break;
	case 16:
		a2 = a0 = butterworth_q160[bw_index][0];
		a1 = butterworth_q160[bw_index][1];
		b0 = butterworth_q160[bw_index][2];
		b1 = butterworth_q160[bw_index][3];
		break;
	case 17:
		a2 = a0 = butterworth_q170[bw_index][0];
		a1 = butterworth_q170[bw_index][1];
		b0 = butterworth_q170[bw_index][2];
		b1 = butterworth_q170[bw_index][3];
		break;
	case 18:
		a2 = a0 = butterworth_q180[bw_index][0];
		a1 = butterworth_q180[bw_index][1];
		b0 = butterworth_q180[bw_index][2];
		b1 = butterworth_q180[bw_index][3];
		break;
	case 19:
		a2 = a0 = butterworth_q190[bw_index][0];
		a1 = butterworth_q190[bw_index][1];
		b0 = butterworth_q190[bw_index][2];
		b1 = butterworth_q190[bw_index][3];
		break;
	case 20:
		a2 = a0 = butterworth_q200[bw_index][0];
		a1 = butterworth_q200[bw_index][1];
		b0 = butterworth_q200[bw_index][2];
		b1 = butterworth_q200[bw_index][3];
		break;
	case 21:
		a2 = a0 = butterworth_q210[bw_index][0];
		a1 = butterworth_q210[bw_index][1];
		b0 = butterworth_q210[bw_index][2];
		b1 = butterworth_q210[bw_index][3];
		break;
	case 22:
		a2 = a0 = butterworth_q220[bw_index][0];
		a1 = butterworth_q220[bw_index][1];
		b0 = butterworth_q220[bw_index][2];
		b1 = butterworth_q220[bw_index][3];
		break;
	case 23:
		a2 = a0 = butterworth_q230[bw_index][0];
		a1 = butterworth_q230[bw_index][1];
		b0 = butterworth_q230[bw_index][2];
		b1 = butterworth_q230[bw_index][3];
		break;
	default:
	case 24:
		a2 = a0 = butterworth_q240[bw_index][0];
		a1 = butterworth_q240[bw_index][1];
		b0 = butterworth_q240[bw_index][2];
		b1 = butterworth_q240[bw_index][3];
		break;
    }


		    }
		    incr = calc_mod_freq(vp, incr);
		}
                newsample = (resample_t)(v1 + ((int32)((v2-v1) * (ofs & FRACTION_MASK)) >> FRACTION_BITS));
	        if (bw_index) {
                    insamp = (FLOAT_T)newsample;
		    outsamp = a0 * insamp + a1 * xx0 + a2 * xx1 - b0 * yy0 - b1 * yy1;
		    xx1 = xx0;
		    xx0 = insamp;
		    yy1 = yy0;
		    yy0 = outsamp;
		    newsample = (resample_t)outsamp;
	        }
	}
	else {
		ofsd=ofs;
                v0 = (int32)src[offset-1];
                v3 = (int32)src[offset+2];
                ofs &= FRACTION_MASK;
                temp=v2;
		v2 = (6*v2 +
		      (((( ( (5*v3 - 11*v2 + 7*v1 - v0)*
		       (int32)ofs) >>FRACTION_BITS)*(int32)ofs)>>(FRACTION_BITS+2))-1))*(int32)ofs;
                ofs = (1L << FRACTION_BITS) - ofs;
		v1 = (6*v1 +
		      ((((((5*v0 - 11*v1 + 7*temp - v3)*
		       (int32)ofs)>>FRACTION_BITS)*(int32)ofs)>>(FRACTION_BITS+2))-1))*(int32)ofs;
		v1 = (v1 + v2)/(6L<<FRACTION_BITS);
		if (!cc_count--) {
		    cc_count = control_ratio - 1;
		    if (calc_bw_index(vp)) {
			bw_index = vp->bw_index;


    reso = vp->resonance + vp->reso_volume;
    if (reso > vp->reso_max) reso = vp->reso_max;
    fmax = (1000 + (vp->reso_max - reso) * (vp->reso_max - reso) * 2) / 100;
    if (reso && bw_index > fmax) bw_index = fmax;
    reso = (reso+5)/10;

    switch(reso) {
	case 0:
		a2 = a0 = butterworth_q0[bw_index][0];
		a1 = butterworth_q0[bw_index][1];
		b0 = butterworth_q0[bw_index][2];
		b1 = butterworth_q0[bw_index][3];
		break;
	case 1:
		a2 = a0 = butterworth_q10[bw_index][0];
		a1 = butterworth_q10[bw_index][1];
		b0 = butterworth_q10[bw_index][2];
		b1 = butterworth_q10[bw_index][3];
		break;
	case 2:
		a2 = a0 = butterworth_q20[bw_index][0];
		a1 = butterworth_q20[bw_index][1];
		b0 = butterworth_q20[bw_index][2];
		b1 = butterworth_q20[bw_index][3];
		break;
	case 3:
		a2 = a0 = butterworth_q30[bw_index][0];
		a1 = butterworth_q30[bw_index][1];
		b0 = butterworth_q30[bw_index][2];
		b1 = butterworth_q30[bw_index][3];
		break;
	case 4:
		a2 = a0 = butterworth_q40[bw_index][0];
		a1 = butterworth_q40[bw_index][1];
		b0 = butterworth_q40[bw_index][2];
		b1 = butterworth_q40[bw_index][3];
		break;
	case 5:
		a2 = a0 = butterworth_q50[bw_index][0];
		a1 = butterworth_q50[bw_index][1];
		b0 = butterworth_q50[bw_index][2];
		b1 = butterworth_q50[bw_index][3];
		break;
	case 6:
		a2 = a0 = butterworth_q60[bw_index][0];
		a1 = butterworth_q60[bw_index][1];
		b0 = butterworth_q60[bw_index][2];
		b1 = butterworth_q60[bw_index][3];
		break;
	case 7:
		a2 = a0 = butterworth_q70[bw_index][0];
		a1 = butterworth_q70[bw_index][1];
		b0 = butterworth_q70[bw_index][2];
		b1 = butterworth_q70[bw_index][3];
		break;
	case 8:
		a2 = a0 = butterworth_q80[bw_index][0];
		a1 = butterworth_q80[bw_index][1];
		b0 = butterworth_q80[bw_index][2];
		b1 = butterworth_q80[bw_index][3];
		break;
	case 9:
		a2 = a0 = butterworth_q90[bw_index][0];
		a1 = butterworth_q90[bw_index][1];
		b0 = butterworth_q90[bw_index][2];
		b1 = butterworth_q90[bw_index][3];
		break;
	case 10:
		a2 = a0 = butterworth_q100[bw_index][0];
		a1 = butterworth_q100[bw_index][1];
		b0 = butterworth_q100[bw_index][2];
		b1 = butterworth_q100[bw_index][3];
		break;
	case 11:
		a2 = a0 = butterworth_q110[bw_index][0];
		a1 = butterworth_q110[bw_index][1];
		b0 = butterworth_q110[bw_index][2];
		b1 = butterworth_q110[bw_index][3];
		break;
	case 12:
		a2 = a0 = butterworth_q120[bw_index][0];
		a1 = butterworth_q120[bw_index][1];
		b0 = butterworth_q120[bw_index][2];
		b1 = butterworth_q120[bw_index][3];
		break;
	case 13:
		a2 = a0 = butterworth_q130[bw_index][0];
		a1 = butterworth_q130[bw_index][1];
		b0 = butterworth_q130[bw_index][2];
		b1 = butterworth_q130[bw_index][3];
		break;
	case 14:
		a2 = a0 = butterworth_q140[bw_index][0];
		a1 = butterworth_q140[bw_index][1];
		b0 = butterworth_q140[bw_index][2];
		b1 = butterworth_q140[bw_index][3];
		break;
	case 15:
		a2 = a0 = butterworth_q150[bw_index][0];
		a1 = butterworth_q150[bw_index][1];
		b0 = butterworth_q150[bw_index][2];
		b1 = butterworth_q150[bw_index][3];
		break;
	case 16:
		a2 = a0 = butterworth_q160[bw_index][0];
		a1 = butterworth_q160[bw_index][1];
		b0 = butterworth_q160[bw_index][2];
		b1 = butterworth_q160[bw_index][3];
		break;
	case 17:
		a2 = a0 = butterworth_q170[bw_index][0];
		a1 = butterworth_q170[bw_index][1];
		b0 = butterworth_q170[bw_index][2];
		b1 = butterworth_q170[bw_index][3];
		break;
	case 18:
		a2 = a0 = butterworth_q180[bw_index][0];
		a1 = butterworth_q180[bw_index][1];
		b0 = butterworth_q180[bw_index][2];
		b1 = butterworth_q180[bw_index][3];
		break;
	case 19:
		a2 = a0 = butterworth_q190[bw_index][0];
		a1 = butterworth_q190[bw_index][1];
		b0 = butterworth_q190[bw_index][2];
		b1 = butterworth_q190[bw_index][3];
		break;
	case 20:
		a2 = a0 = butterworth_q200[bw_index][0];
		a1 = butterworth_q200[bw_index][1];
		b0 = butterworth_q200[bw_index][2];
		b1 = butterworth_q200[bw_index][3];
		break;
	case 21:
		a2 = a0 = butterworth_q210[bw_index][0];
		a1 = butterworth_q210[bw_index][1];
		b0 = butterworth_q210[bw_index][2];
		b1 = butterworth_q210[bw_index][3];
		break;
	case 22:
		a2 = a0 = butterworth_q220[bw_index][0];
		a1 = butterworth_q220[bw_index][1];
		b0 = butterworth_q220[bw_index][2];
		b1 = butterworth_q220[bw_index][3];
		break;
	case 23:
		a2 = a0 = butterworth_q230[bw_index][0];
		a1 = butterworth_q230[bw_index][1];
		b0 = butterworth_q230[bw_index][2];
		b1 = butterworth_q230[bw_index][3];
		break;
	default:
	case 24:
		a2 = a0 = butterworth_q240[bw_index][0];
		a1 = butterworth_q240[bw_index][1];
		b0 = butterworth_q240[bw_index][2];
		b1 = butterworth_q240[bw_index][3];
		break;
    }




		    }
		    incr = calc_mod_freq(vp, incr);
		}
		newsample = (resample_t)v1;
		if (bw_index) {
                    insamp = (FLOAT_T)newsample;
		    outsamp = a0 * insamp + a1 * xx0 + a2 * xx1 - b0 * yy0 - b1 * yy1;
		    xx1 = xx0;
		    xx0 = insamp;
		    yy1 = yy0;
		    yy0 = outsamp;
		    newsample = (resample_t)outsamp;
		}
		ofs=ofsd;
	}
	*dest++ = newsample;
      ofs += incr;
      if (ofs>=le)
	{
	  if (flag_exit_loop)
	    {
	    	vp->reverb_time -= ll >> FRACTION_BITS;
	  	if (vp->reverb_time >= 0) ofs -= ll;
	    }
	  else ofs -= ll; /* Hopefully the loop is longer than an increment. */
	}
      if (ofs >= se + (overshoot << FRACTION_BITS))
	{
	  if (!(vp->status&VOICE_FREE))
	    {
	      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 */
  vp->current_x0=xx0;
  vp->current_x1=xx1;
  vp->current_y0=yy0;
  vp->current_y1=yy1;
  vp->bw_index=bw_index;
  vp->modulation_counter=cc_count;
  return resample_buffer+resample_buffer_offset;
}

static resample_t *rs_vib_bidir(Voice *vp, uint32 count)
{
  int32   v0, v1, v2, v3, temp, overshoot;
  splen_t ofsd;
  int32 offset;
  FLOAT_T insamp, outsamp, a0, a1, a2, b0, b1,
    xx0=vp->current_x0, xx1=vp->current_x1, yy0=vp->current_y0, yy1=vp->current_y1;
  uint32 cc_count=vp->modulation_counter, bw_index=vp->bw_index, fmax;
  uint16 reso;
  resample_t newsample;
  int32
    incr=vp->sample_increment;
  splen_t
    le=vp->loop_end,
    ls=vp->loop_start,
    ofs=vp->sample_offset,
    se=vp->sample->data_length;
  resample_t
    *dest=resample_buffer+resample_buffer_offset;
#ifdef SL32
  samplel_t
    *src=vp->sample->ldata;
#else
  sample_t
    *src=vp->sample->data;
#endif
  uint32
    cc=vp->vibrato_control_counter;


#ifdef USE_BIDIR_OVERSHOOT
  splen_t
    le2=le<<1,
    ls2=ls<<1;
#endif
  uint32
    i, j;
  int
    vibflag = 0;


  overshoot = src[(se>>FRACTION_BITS)-1] / OVERSHOOT_STEP;
  if (overshoot < 0) overshoot = -overshoot;

    reso = vp->resonance + vp->reso_volume;
    if (reso > vp->reso_max) reso = vp->reso_max;
    fmax = (1000 + (vp->reso_max - reso) * (vp->reso_max - reso) * 2) / 100;
    if (reso && bw_index > fmax) bw_index = fmax;
    reso = (reso+5)/10;

    switch(reso) {
	case 0:
		a2 = a0 = butterworth_q0[bw_index][0];
		a1 = butterworth_q0[bw_index][1];
		b0 = butterworth_q0[bw_index][2];
		b1 = butterworth_q0[bw_index][3];
		break;
	case 1:
		a2 = a0 = butterworth_q10[bw_index][0];
		a1 = butterworth_q10[bw_index][1];
		b0 = butterworth_q10[bw_index][2];
		b1 = butterworth_q10[bw_index][3];
		break;
	case 2:
		a2 = a0 = butterworth_q20[bw_index][0];
		a1 = butterworth_q20[bw_index][1];
		b0 = butterworth_q20[bw_index][2];
		b1 = butterworth_q20[bw_index][3];
		break;
	case 3:
		a2 = a0 = butterworth_q30[bw_index][0];
		a1 = butterworth_q30[bw_index][1];
		b0 = butterworth_q30[bw_index][2];
		b1 = butterworth_q30[bw_index][3];
		break;
	case 4:
		a2 = a0 = butterworth_q40[bw_index][0];
		a1 = butterworth_q40[bw_index][1];
		b0 = butterworth_q40[bw_index][2];
		b1 = butterworth_q40[bw_index][3];
		break;
	case 5:
		a2 = a0 = butterworth_q50[bw_index][0];
		a1 = butterworth_q50[bw_index][1];
		b0 = butterworth_q50[bw_index][2];
		b1 = butterworth_q50[bw_index][3];
		break;
	case 6:
		a2 = a0 = butterworth_q60[bw_index][0];
		a1 = butterworth_q60[bw_index][1];
		b0 = butterworth_q60[bw_index][2];
		b1 = butterworth_q60[bw_index][3];
		break;
	case 7:
		a2 = a0 = butterworth_q70[bw_index][0];
		a1 = butterworth_q70[bw_index][1];
		b0 = butterworth_q70[bw_index][2];
		b1 = butterworth_q70[bw_index][3];
		break;
	case 8:
		a2 = a0 = butterworth_q80[bw_index][0];
		a1 = butterworth_q80[bw_index][1];
		b0 = butterworth_q80[bw_index][2];
		b1 = butterworth_q80[bw_index][3];
		break;
	case 9:
		a2 = a0 = butterworth_q90[bw_index][0];
		a1 = butterworth_q90[bw_index][1];
		b0 = butterworth_q90[bw_index][2];
		b1 = butterworth_q90[bw_index][3];
		break;
	case 10:
		a2 = a0 = butterworth_q100[bw_index][0];
		a1 = butterworth_q100[bw_index][1];
		b0 = butterworth_q100[bw_index][2];
		b1 = butterworth_q100[bw_index][3];
		break;
	case 11:
		a2 = a0 = butterworth_q110[bw_index][0];
		a1 = butterworth_q110[bw_index][1];
		b0 = butterworth_q110[bw_index][2];
		b1 = butterworth_q110[bw_index][3];
		break;
	case 12:
		a2 = a0 = butterworth_q120[bw_index][0];
		a1 = butterworth_q120[bw_index][1];
		b0 = butterworth_q120[bw_index][2];
		b1 = butterworth_q120[bw_index][3];
		break;
	case 13:
		a2 = a0 = butterworth_q130[bw_index][0];
		a1 = butterworth_q130[bw_index][1];
		b0 = butterworth_q130[bw_index][2];
		b1 = butterworth_q130[bw_index][3];
		break;
	case 14:
		a2 = a0 = butterworth_q140[bw_index][0];
		a1 = butterworth_q140[bw_index][1];
		b0 = butterworth_q140[bw_index][2];
		b1 = butterworth_q140[bw_index][3];
		break;
	case 15:
		a2 = a0 = butterworth_q150[bw_index][0];
		a1 = butterworth_q150[bw_index][1];
		b0 = butterworth_q150[bw_index][2];
		b1 = butterworth_q150[bw_index][3];
		break;
	case 16:
		a2 = a0 = butterworth_q160[bw_index][0];
		a1 = butterworth_q160[bw_index][1];
		b0 = butterworth_q160[bw_index][2];
		b1 = butterworth_q160[bw_index][3];
		break;
	case 17:
		a2 = a0 = butterworth_q170[bw_index][0];
		a1 = butterworth_q170[bw_index][1];
		b0 = butterworth_q170[bw_index][2];
		b1 = butterworth_q170[bw_index][3];
		break;
	case 18:
		a2 = a0 = butterworth_q180[bw_index][0];
		a1 = butterworth_q180[bw_index][1];
		b0 = butterworth_q180[bw_index][2];
		b1 = butterworth_q180[bw_index][3];
		break;
	case 19:
		a2 = a0 = butterworth_q190[bw_index][0];
		a1 = butterworth_q190[bw_index][1];
		b0 = butterworth_q190[bw_index][2];
		b1 = butterworth_q190[bw_index][3];
		break;
	case 20:
		a2 = a0 = butterworth_q200[bw_index][0];
		a1 = butterworth_q200[bw_index][1];
		b0 = butterworth_q200[bw_index][2];
		b1 = butterworth_q200[bw_index][3];
		break;
	case 21:
		a2 = a0 = butterworth_q210[bw_index][0];
		a1 = butterworth_q210[bw_index][1];
		b0 = butterworth_q210[bw_index][2];
		b1 = butterworth_q210[bw_index][3];
		break;
	case 22:
		a2 = a0 = butterworth_q220[bw_index][0];
		a1 = butterworth_q220[bw_index][1];
		b0 = butterworth_q220[bw_index][2];
		b1 = butterworth_q220[bw_index][3];
		break;
	case 23:
		a2 = a0 = butterworth_q230[bw_index][0];
		a1 = butterworth_q230[bw_index][1];
		b0 = butterworth_q230[bw_index][2];
		b1 = butterworth_q230[bw_index][3];
		break;
	default:
	case 24:
		a2 = a0 = butterworth_q240[bw_index][0];
		a1 = butterworth_q240[bw_index][1];
		b0 = butterworth_q240[bw_index][2];
		b1 = butterworth_q240[bw_index][3];
		break;
    }

  /* 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;
      for(j = 0; j < i; j++)
	{


	offset = ofs >> FRACTION_BITS;

	if (ofs >= se) {
		int32 delta = (ofs - se)>>FRACTION_BITS;
        	v1 = (int32)src[(int32)(se>>FRACTION_BITS)-1];
		if (overshoot) v1 -=  (delta+1) * v1 / overshoot;
        }
	else  v1 = (int32)src[offset];

	if (ofs + (1L<<FRACTION_BITS) >= se) {
		v2 = v1;
        }
	else  v2 = (int32)src[offset+1];

	if ( (vp->algorithm & INTERPOLATION_LINEAR) || dont_cspline ||
	   ((ofs-(1L<<FRACTION_BITS))<ls)||((ofs+(2L<<FRACTION_BITS))>le)){
		if (!cc_count--) {
		    cc_count = control_ratio - 1;
		    if (calc_bw_index(vp)) {
		        bw_index = vp->bw_index;


    reso = vp->resonance + vp->reso_volume;
    if (reso > vp->reso_max) reso = vp->reso_max;
    fmax = (1000 + (vp->reso_max - reso) * (vp->reso_max - reso) * 2) / 100;
    if (reso && bw_index > fmax) bw_index = fmax;
    reso = (reso+5)/10;

    switch(reso) {
	case 0:
		a2 = a0 = butterworth_q0[bw_index][0];
		a1 = butterworth_q0[bw_index][1];
		b0 = butterworth_q0[bw_index][2];
		b1 = butterworth_q0[bw_index][3];
		break;
	case 1:
		a2 = a0 = butterworth_q10[bw_index][0];
		a1 = butterworth_q10[bw_index][1];
		b0 = butterworth_q10[bw_index][2];
		b1 = butterworth_q10[bw_index][3];
		break;
	case 2:
		a2 = a0 = butterworth_q20[bw_index][0];
		a1 = butterworth_q20[bw_index][1];
		b0 = butterworth_q20[bw_index][2];
		b1 = butterworth_q20[bw_index][3];
		break;
	case 3:
		a2 = a0 = butterworth_q30[bw_index][0];
		a1 = butterworth_q30[bw_index][1];
		b0 = butterworth_q30[bw_index][2];
		b1 = butterworth_q30[bw_index][3];
		break;
	case 4:
		a2 = a0 = butterworth_q40[bw_index][0];
		a1 = butterworth_q40[bw_index][1];
		b0 = butterworth_q40[bw_index][2];
		b1 = butterworth_q40[bw_index][3];
		break;
	case 5:
		a2 = a0 = butterworth_q50[bw_index][0];
		a1 = butterworth_q50[bw_index][1];
		b0 = butterworth_q50[bw_index][2];
		b1 = butterworth_q50[bw_index][3];
		break;
	case 6:
		a2 = a0 = butterworth_q60[bw_index][0];
		a1 = butterworth_q60[bw_index][1];
		b0 = butterworth_q60[bw_index][2];
		b1 = butterworth_q60[bw_index][3];
		break;
	case 7:
		a2 = a0 = butterworth_q70[bw_index][0];
		a1 = butterworth_q70[bw_index][1];
		b0 = butterworth_q70[bw_index][2];
		b1 = butterworth_q70[bw_index][3];
		break;
	case 8:
		a2 = a0 = butterworth_q80[bw_index][0];
		a1 = butterworth_q80[bw_index][1];
		b0 = butterworth_q80[bw_index][2];
		b1 = butterworth_q80[bw_index][3];
		break;
	case 9:
		a2 = a0 = butterworth_q90[bw_index][0];
		a1 = butterworth_q90[bw_index][1];
		b0 = butterworth_q90[bw_index][2];
		b1 = butterworth_q90[bw_index][3];
		break;
	case 10:
		a2 = a0 = butterworth_q100[bw_index][0];
		a1 = butterworth_q100[bw_index][1];
		b0 = butterworth_q100[bw_index][2];
		b1 = butterworth_q100[bw_index][3];
		break;
	case 11:
		a2 = a0 = butterworth_q110[bw_index][0];
		a1 = butterworth_q110[bw_index][1];
		b0 = butterworth_q110[bw_index][2];
		b1 = butterworth_q110[bw_index][3];
		break;
	case 12:
		a2 = a0 = butterworth_q120[bw_index][0];
		a1 = butterworth_q120[bw_index][1];
		b0 = butterworth_q120[bw_index][2];
		b1 = butterworth_q120[bw_index][3];
		break;
	case 13:
		a2 = a0 = butterworth_q130[bw_index][0];
		a1 = butterworth_q130[bw_index][1];
		b0 = butterworth_q130[bw_index][2];
		b1 = butterworth_q130[bw_index][3];
		break;
	case 14:
		a2 = a0 = butterworth_q140[bw_index][0];
		a1 = butterworth_q140[bw_index][1];
		b0 = butterworth_q140[bw_index][2];
		b1 = butterworth_q140[bw_index][3];
		break;
	case 15:
		a2 = a0 = butterworth_q150[bw_index][0];
		a1 = butterworth_q150[bw_index][1];
		b0 = butterworth_q150[bw_index][2];
		b1 = butterworth_q150[bw_index][3];
		break;
	case 16:
		a2 = a0 = butterworth_q160[bw_index][0];
		a1 = butterworth_q160[bw_index][1];
		b0 = butterworth_q160[bw_index][2];
		b1 = butterworth_q160[bw_index][3];
		break;
	case 17:
		a2 = a0 = butterworth_q170[bw_index][0];
		a1 = butterworth_q170[bw_index][1];
		b0 = butterworth_q170[bw_index][2];
		b1 = butterworth_q170[bw_index][3];
		break;
	case 18:
		a2 = a0 = butterworth_q180[bw_index][0];
		a1 = butterworth_q180[bw_index][1];
		b0 = butterworth_q180[bw_index][2];
		b1 = butterworth_q180[bw_index][3];
		break;
	case 19:
		a2 = a0 = butterworth_q190[bw_index][0];
		a1 = butterworth_q190[bw_index][1];
		b0 = butterworth_q190[bw_index][2];
		b1 = butterworth_q190[bw_index][3];
		break;
	case 20:
		a2 = a0 = butterworth_q200[bw_index][0];
		a1 = butterworth_q200[bw_index][1];
		b0 = butterworth_q200[bw_index][2];
		b1 = butterworth_q200[bw_index][3];
		break;
	case 21:
		a2 = a0 = butterworth_q210[bw_index][0];
		a1 = butterworth_q210[bw_index][1];
		b0 = butterworth_q210[bw_index][2];
		b1 = butterworth_q210[bw_index][3];
		break;
	case 22:
		a2 = a0 = butterworth_q220[bw_index][0];
		a1 = butterworth_q220[bw_index][1];
		b0 = butterworth_q220[bw_index][2];
		b1 = butterworth_q220[bw_index][3];
		break;
	case 23:
		a2 = a0 = butterworth_q230[bw_index][0];
		a1 = butterworth_q230[bw_index][1];
		b0 = butterworth_q230[bw_index][2];
		b1 = butterworth_q230[bw_index][3];
		break;
	default:
	case 24:
		a2 = a0 = butterworth_q240[bw_index][0];
		a1 = butterworth_q240[bw_index][1];
		b0 = butterworth_q240[bw_index][2];
		b1 = butterworth_q240[bw_index][3];
		break;
    }


		    }
		    incr = calc_mod_freq(vp, incr);
		}
                newsample = (resample_t)(v1 + ((int32)((v2-v1) * (ofs & FRACTION_MASK)) >> FRACTION_BITS));
	        if (bw_index) {
                    insamp = (FLOAT_T)newsample;
		    outsamp = a0 * insamp + a1 * xx0 + a2 * xx1 - b0 * yy0 - b1 * yy1;
		    xx1 = xx0;
		    xx0 = insamp;
		    yy1 = yy0;
		    yy0 = outsamp;
		    newsample = (resample_t)outsamp;
	        }
	}
	else {
		ofsd=ofs;
                v0 = (int32)src[offset-1];
                v3 = (int32)src[offset+2];
                ofs &= FRACTION_MASK;
                temp=v2;
		v2 = (6*v2 +
		      (((( ( (5*v3 - 11*v2 + 7*v1 - v0)*
		       (int32)ofs) >>FRACTION_BITS)*(int32)ofs)>>(FRACTION_BITS+2))-1))*(int32)ofs;
                ofs = (1L << FRACTION_BITS) - ofs;
		v1 = (6*v1 +
		      ((((((5*v0 - 11*v1 + 7*temp - v3)*
		       (int32)ofs)>>FRACTION_BITS)*(int32)ofs)>>(FRACTION_BITS+2))-1))*(int32)ofs;
		v1 = (v1 + v2)/(6L<<FRACTION_BITS);
		if (!cc_count--) {
		    cc_count = control_ratio - 1;
		    if (calc_bw_index(vp)) {
			bw_index = vp->bw_index;


    reso = vp->resonance + vp->reso_volume;
    if (reso > vp->reso_max) reso = vp->reso_max;
    fmax = (1000 + (vp->reso_max - reso) * (vp->reso_max - reso) * 2) / 100;
    if (reso && bw_index > fmax) bw_index = fmax;
    reso = (reso+5)/10;

    switch(reso) {
	case 0:
		a2 = a0 = butterworth_q0[bw_index][0];
		a1 = butterworth_q0[bw_index][1];
		b0 = butterworth_q0[bw_index][2];
		b1 = butterworth_q0[bw_index][3];
		break;
	case 1:
		a2 = a0 = butterworth_q10[bw_index][0];
		a1 = butterworth_q10[bw_index][1];
		b0 = butterworth_q10[bw_index][2];
		b1 = butterworth_q10[bw_index][3];
		break;
	case 2:
		a2 = a0 = butterworth_q20[bw_index][0];
		a1 = butterworth_q20[bw_index][1];
		b0 = butterworth_q20[bw_index][2];
		b1 = butterworth_q20[bw_index][3];
		break;
	case 3:
		a2 = a0 = butterworth_q30[bw_index][0];
		a1 = butterworth_q30[bw_index][1];
		b0 = butterworth_q30[bw_index][2];
		b1 = butterworth_q30[bw_index][3];
		break;
	case 4:
		a2 = a0 = butterworth_q40[bw_index][0];
		a1 = butterworth_q40[bw_index][1];
		b0 = butterworth_q40[bw_index][2];
		b1 = butterworth_q40[bw_index][3];
		break;
	case 5:
		a2 = a0 = butterworth_q50[bw_index][0];
		a1 = butterworth_q50[bw_index][1];
		b0 = butterworth_q50[bw_index][2];
		b1 = butterworth_q50[bw_index][3];
		break;
	case 6:
		a2 = a0 = butterworth_q60[bw_index][0];
		a1 = butterworth_q60[bw_index][1];
		b0 = butterworth_q60[bw_index][2];
		b1 = butterworth_q60[bw_index][3];
		break;
	case 7:
		a2 = a0 = butterworth_q70[bw_index][0];
		a1 = butterworth_q70[bw_index][1];
		b0 = butterworth_q70[bw_index][2];
		b1 = butterworth_q70[bw_index][3];
		break;
	case 8:
		a2 = a0 = butterworth_q80[bw_index][0];
		a1 = butterworth_q80[bw_index][1];
		b0 = butterworth_q80[bw_index][2];
		b1 = butterworth_q80[bw_index][3];
		break;
	case 9:
		a2 = a0 = butterworth_q90[bw_index][0];
		a1 = butterworth_q90[bw_index][1];
		b0 = butterworth_q90[bw_index][2];
		b1 = butterworth_q90[bw_index][3];
		break;
	case 10:
		a2 = a0 = butterworth_q100[bw_index][0];
		a1 = butterworth_q100[bw_index][1];
		b0 = butterworth_q100[bw_index][2];
		b1 = butterworth_q100[bw_index][3];
		break;
	case 11:
		a2 = a0 = butterworth_q110[bw_index][0];
		a1 = butterworth_q110[bw_index][1];
		b0 = butterworth_q110[bw_index][2];
		b1 = butterworth_q110[bw_index][3];
		break;
	case 12:
		a2 = a0 = butterworth_q120[bw_index][0];
		a1 = butterworth_q120[bw_index][1];
		b0 = butterworth_q120[bw_index][2];
		b1 = butterworth_q120[bw_index][3];
		break;
	case 13:
		a2 = a0 = butterworth_q130[bw_index][0];
		a1 = butterworth_q130[bw_index][1];
		b0 = butterworth_q130[bw_index][2];
		b1 = butterworth_q130[bw_index][3];
		break;
	case 14:
		a2 = a0 = butterworth_q140[bw_index][0];
		a1 = butterworth_q140[bw_index][1];
		b0 = butterworth_q140[bw_index][2];
		b1 = butterworth_q140[bw_index][3];
		break;
	case 15:
		a2 = a0 = butterworth_q150[bw_index][0];
		a1 = butterworth_q150[bw_index][1];
		b0 = butterworth_q150[bw_index][2];
		b1 = butterworth_q150[bw_index][3];
		break;
	case 16:
		a2 = a0 = butterworth_q160[bw_index][0];
		a1 = butterworth_q160[bw_index][1];
		b0 = butterworth_q160[bw_index][2];
		b1 = butterworth_q160[bw_index][3];
		break;
	case 17:
		a2 = a0 = butterworth_q170[bw_index][0];
		a1 = butterworth_q170[bw_index][1];
		b0 = butterworth_q170[bw_index][2];
		b1 = butterworth_q170[bw_index][3];
		break;
	case 18:
		a2 = a0 = butterworth_q180[bw_index][0];
		a1 = butterworth_q180[bw_index][1];
		b0 = butterworth_q180[bw_index][2];
		b1 = butterworth_q180[bw_index][3];
		break;
	case 19:
		a2 = a0 = butterworth_q190[bw_index][0];
		a1 = butterworth_q190[bw_index][1];
		b0 = butterworth_q190[bw_index][2];
		b1 = butterworth_q190[bw_index][3];
		break;
	case 20:
		a2 = a0 = butterworth_q200[bw_index][0];
		a1 = butterworth_q200[bw_index][1];
		b0 = butterworth_q200[bw_index][2];
		b1 = butterworth_q200[bw_index][3];
		break;
	case 21:
		a2 = a0 = butterworth_q210[bw_index][0];
		a1 = butterworth_q210[bw_index][1];
		b0 = butterworth_q210[bw_index][2];
		b1 = butterworth_q210[bw_index][3];
		break;
	case 22:
		a2 = a0 = butterworth_q220[bw_index][0];
		a1 = butterworth_q220[bw_index][1];
		b0 = butterworth_q220[bw_index][2];
		b1 = butterworth_q220[bw_index][3];
		break;
	case 23:
		a2 = a0 = butterworth_q230[bw_index][0];
		a1 = butterworth_q230[bw_index][1];
		b0 = butterworth_q230[bw_index][2];
		b1 = butterworth_q230[bw_index][3];
		break;
	default:
	case 24:
		a2 = a0 = butterworth_q240[bw_index][0];
		a1 = butterworth_q240[bw_index][1];
		b0 = butterworth_q240[bw_index][2];
		b1 = butterworth_q240[bw_index][3];
		break;
    }




		    }
		    incr = calc_mod_freq(vp, incr);
		}
		newsample = (resample_t)v1;
		if (bw_index) {
                    insamp = (FLOAT_T)newsample;
		    outsamp = a0 * insamp + a1 * xx0 + a2 * xx1 - b0 * yy0 - b1 * yy1;
		    xx1 = xx0;
		    xx0 = insamp;
		    yy1 = yy0;
		    yy0 = outsamp;
		    newsample = (resample_t)outsamp;
		}
		ofs=ofsd;
	}
	*dest++ = newsample;
	  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 */
#if 1
      i = ((incr > 0 ? le : ls) - ofs) / incr + 1;
#else
/* fix from M. Izumo */
      i = ((incr > 0 ? le : ls) - ofs + incr - 1) / incr;
#endif
      if(i > count) i = count;
      if(i > cc)
	{
	  i = cc;
	  vibflag = 1;
	}
      else cc -= i;
      count -= i;
      while (i-- && ofs < se)
	{


	offset = ofs >> FRACTION_BITS;

	if (ofs >= se) {
		int32 delta = (ofs - se)>>FRACTION_BITS;
        	v1 = (int32)src[(int32)(se>>FRACTION_BITS)-1];
		if (overshoot) v1 -=  (delta+1) * v1 / overshoot;
        }
	else  v1 = (int32)src[offset];

	if (ofs + (1L<<FRACTION_BITS) >= se) {
		v2 = v1;
        }
	else  v2 = (int32)src[offset+1];

	if ( (vp->algorithm & INTERPOLATION_LINEAR) || dont_cspline ||
	   ((ofs-(1L<<FRACTION_BITS))<ls)||((ofs+(2L<<FRACTION_BITS))>le)){
		if (!cc_count--) {
		    cc_count = control_ratio - 1;
		    if (calc_bw_index(vp)) {
		        bw_index = vp->bw_index;


    reso = vp->resonance + vp->reso_volume;
    if (reso > vp->reso_max) reso = vp->reso_max;
    fmax = (1000 + (vp->reso_max - reso) * (vp->reso_max - reso) * 2) / 100;
    if (reso && bw_index > fmax) bw_index = fmax;
    reso = (reso+5)/10;

    switch(reso) {
	case 0:
		a2 = a0 = butterworth_q0[bw_index][0];
		a1 = butterworth_q0[bw_index][1];
		b0 = butterworth_q0[bw_index][2];
		b1 = butterworth_q0[bw_index][3];
		break;
	case 1:
		a2 = a0 = butterworth_q10[bw_index][0];
		a1 = butterworth_q10[bw_index][1];
		b0 = butterworth_q10[bw_index][2];
		b1 = butterworth_q10[bw_index][3];
		break;
	case 2:
		a2 = a0 = butterworth_q20[bw_index][0];
		a1 = butterworth_q20[bw_index][1];
		b0 = butterworth_q20[bw_index][2];
		b1 = butterworth_q20[bw_index][3];
		break;
	case 3:
		a2 = a0 = butterworth_q30[bw_index][0];
		a1 = butterworth_q30[bw_index][1];
		b0 = butterworth_q30[bw_index][2];
		b1 = butterworth_q30[bw_index][3];
		break;
	case 4:
		a2 = a0 = butterworth_q40[bw_index][0];
		a1 = butterworth_q40[bw_index][1];
		b0 = butterworth_q40[bw_index][2];
		b1 = butterworth_q40[bw_index][3];
		break;
	case 5:
		a2 = a0 = butterworth_q50[bw_index][0];
		a1 = butterworth_q50[bw_index][1];
		b0 = butterworth_q50[bw_index][2];
		b1 = butterworth_q50[bw_index][3];
		break;
	case 6:
		a2 = a0 = butterworth_q60[bw_index][0];
		a1 = butterworth_q60[bw_index][1];
		b0 = butterworth_q60[bw_index][2];
		b1 = butterworth_q60[bw_index][3];
		break;
	case 7:
		a2 = a0 = butterworth_q70[bw_index][0];
		a1 = butterworth_q70[bw_index][1];
		b0 = butterworth_q70[bw_index][2];
		b1 = butterworth_q70[bw_index][3];
		break;
	case 8:
		a2 = a0 = butterworth_q80[bw_index][0];
		a1 = butterworth_q80[bw_index][1];
		b0 = butterworth_q80[bw_index][2];
		b1 = butterworth_q80[bw_index][3];
		break;
	case 9:
		a2 = a0 = butterworth_q90[bw_index][0];
		a1 = butterworth_q90[bw_index][1];
		b0 = butterworth_q90[bw_index][2];
		b1 = butterworth_q90[bw_index][3];
		break;
	case 10:
		a2 = a0 = butterworth_q100[bw_index][0];
		a1 = butterworth_q100[bw_index][1];
		b0 = butterworth_q100[bw_index][2];
		b1 = butterworth_q100[bw_index][3];
		break;
	case 11:
		a2 = a0 = butterworth_q110[bw_index][0];
		a1 = butterworth_q110[bw_index][1];
		b0 = butterworth_q110[bw_index][2];
		b1 = butterworth_q110[bw_index][3];
		break;
	case 12:
		a2 = a0 = butterworth_q120[bw_index][0];
		a1 = butterworth_q120[bw_index][1];
		b0 = butterworth_q120[bw_index][2];
		b1 = butterworth_q120[bw_index][3];
		break;
	case 13:
		a2 = a0 = butterworth_q130[bw_index][0];
		a1 = butterworth_q130[bw_index][1];
		b0 = butterworth_q130[bw_index][2];
		b1 = butterworth_q130[bw_index][3];
		break;
	case 14:
		a2 = a0 = butterworth_q140[bw_index][0];
		a1 = butterworth_q140[bw_index][1];
		b0 = butterworth_q140[bw_index][2];
		b1 = butterworth_q140[bw_index][3];
		break;
	case 15:
		a2 = a0 = butterworth_q150[bw_index][0];
		a1 = butterworth_q150[bw_index][1];
		b0 = butterworth_q150[bw_index][2];
		b1 = butterworth_q150[bw_index][3];
		break;
	case 16:
		a2 = a0 = butterworth_q160[bw_index][0];
		a1 = butterworth_q160[bw_index][1];
		b0 = butterworth_q160[bw_index][2];
		b1 = butterworth_q160[bw_index][3];
		break;
	case 17:
		a2 = a0 = butterworth_q170[bw_index][0];
		a1 = butterworth_q170[bw_index][1];
		b0 = butterworth_q170[bw_index][2];
		b1 = butterworth_q170[bw_index][3];
		break;
	case 18:
		a2 = a0 = butterworth_q180[bw_index][0];
		a1 = butterworth_q180[bw_index][1];
		b0 = butterworth_q180[bw_index][2];
		b1 = butterworth_q180[bw_index][3];
		break;
	case 19:
		a2 = a0 = butterworth_q190[bw_index][0];
		a1 = butterworth_q190[bw_index][1];
		b0 = butterworth_q190[bw_index][2];
		b1 = butterworth_q190[bw_index][3];
		break;
	case 20:
		a2 = a0 = butterworth_q200[bw_index][0];
		a1 = butterworth_q200[bw_index][1];
		b0 = butterworth_q200[bw_index][2];
		b1 = butterworth_q200[bw_index][3];
		break;
	case 21:
		a2 = a0 = butterworth_q210[bw_index][0];
		a1 = butterworth_q210[bw_index][1];
		b0 = butterworth_q210[bw_index][2];
		b1 = butterworth_q210[bw_index][3];
		break;
	case 22:
		a2 = a0 = butterworth_q220[bw_index][0];
		a1 = butterworth_q220[bw_index][1];
		b0 = butterworth_q220[bw_index][2];
		b1 = butterworth_q220[bw_index][3];
		break;
	case 23:
		a2 = a0 = butterworth_q230[bw_index][0];
		a1 = butterworth_q230[bw_index][1];
		b0 = butterworth_q230[bw_index][2];
		b1 = butterworth_q230[bw_index][3];
		break;
	default:
	case 24:
		a2 = a0 = butterworth_q240[bw_index][0];
		a1 = butterworth_q240[bw_index][1];
		b0 = butterworth_q240[bw_index][2];
		b1 = butterworth_q240[bw_index][3];
		break;
    }


		    }
		    incr = calc_mod_freq(vp, incr);
		}
                newsample = (resample_t)(v1 + ((int32)((v2-v1) * (ofs & FRACTION_MASK)) >> FRACTION_BITS));
	        if (bw_index) {
                    insamp = (FLOAT_T)newsample;
		    outsamp = a0 * insamp + a1 * xx0 + a2 * xx1 - b0 * yy0 - b1 * yy1;
		    xx1 = xx0;
		    xx0 = insamp;
		    yy1 = yy0;
		    yy0 = outsamp;
		    newsample = (resample_t)outsamp;
	        }
	}
	else {
		ofsd=ofs;
                v0 = (int32)src[offset-1];
                v3 = (int32)src[offset+2];
                ofs &= FRACTION_MASK;
                temp=v2;
		v2 = (6*v2 +
		      (((( ( (5*v3 - 11*v2 + 7*v1 - v0)*
		       (int32)ofs) >>FRACTION_BITS)*(int32)ofs)>>(FRACTION_BITS+2))-1))*(int32)ofs;
                ofs = (1L << FRACTION_BITS) - ofs;
		v1 = (6*v1 +
		      ((((((5*v0 - 11*v1 + 7*temp - v3)*
		       (int32)ofs)>>FRACTION_BITS)*(int32)ofs)>>(FRACTION_BITS+2))-1))*(int32)ofs;
		v1 = (v1 + v2)/(6L<<FRACTION_BITS);
		if (!cc_count--) {
		    cc_count = control_ratio - 1;
		    if (calc_bw_index(vp)) {
			bw_index = vp->bw_index;


    reso = vp->resonance + vp->reso_volume;
    if (reso > vp->reso_max) reso = vp->reso_max;
    fmax = (1000 + (vp->reso_max - reso) * (vp->reso_max - reso) * 2) / 100;
    if (reso && bw_index > fmax) bw_index = fmax;
    reso = (reso+5)/10;

    switch(reso) {
	case 0:
		a2 = a0 = butterworth_q0[bw_index][0];
		a1 = butterworth_q0[bw_index][1];
		b0 = butterworth_q0[bw_index][2];
		b1 = butterworth_q0[bw_index][3];
		break;
	case 1:
		a2 = a0 = butterworth_q10[bw_index][0];
		a1 = butterworth_q10[bw_index][1];
		b0 = butterworth_q10[bw_index][2];
		b1 = butterworth_q10[bw_index][3];
		break;
	case 2:
		a2 = a0 = butterworth_q20[bw_index][0];
		a1 = butterworth_q20[bw_index][1];
		b0 = butterworth_q20[bw_index][2];
		b1 = butterworth_q20[bw_index][3];
		break;
	case 3:
		a2 = a0 = butterworth_q30[bw_index][0];
		a1 = butterworth_q30[bw_index][1];
		b0 = butterworth_q30[bw_index][2];
		b1 = butterworth_q30[bw_index][3];
		break;
	case 4:
		a2 = a0 = butterworth_q40[bw_index][0];
		a1 = butterworth_q40[bw_index][1];
		b0 = butterworth_q40[bw_index][2];
		b1 = butterworth_q40[bw_index][3];
		break;
	case 5:
		a2 = a0 = butterworth_q50[bw_index][0];
		a1 = butterworth_q50[bw_index][1];
		b0 = butterworth_q50[bw_index][2];
		b1 = butterworth_q50[bw_index][3];
		break;
	case 6:
		a2 = a0 = butterworth_q60[bw_index][0];
		a1 = butterworth_q60[bw_index][1];
		b0 = butterworth_q60[bw_index][2];
		b1 = butterworth_q60[bw_index][3];
		break;
	case 7:
		a2 = a0 = butterworth_q70[bw_index][0];
		a1 = butterworth_q70[bw_index][1];
		b0 = butterworth_q70[bw_index][2];
		b1 = butterworth_q70[bw_index][3];
		break;
	case 8:
		a2 = a0 = butterworth_q80[bw_index][0];
		a1 = butterworth_q80[bw_index][1];
		b0 = butterworth_q80[bw_index][2];
		b1 = butterworth_q80[bw_index][3];
		break;
	case 9:
		a2 = a0 = butterworth_q90[bw_index][0];
		a1 = butterworth_q90[bw_index][1];
		b0 = butterworth_q90[bw_index][2];
		b1 = butterworth_q90[bw_index][3];
		break;
	case 10:
		a2 = a0 = butterworth_q100[bw_index][0];
		a1 = butterworth_q100[bw_index][1];
		b0 = butterworth_q100[bw_index][2];
		b1 = butterworth_q100[bw_index][3];
		break;
	case 11:
		a2 = a0 = butterworth_q110[bw_index][0];
		a1 = butterworth_q110[bw_index][1];
		b0 = butterworth_q110[bw_index][2];
		b1 = butterworth_q110[bw_index][3];
		break;
	case 12:
		a2 = a0 = butterworth_q120[bw_index][0];
		a1 = butterworth_q120[bw_index][1];
		b0 = butterworth_q120[bw_index][2];
		b1 = butterworth_q120[bw_index][3];
		break;
	case 13:
		a2 = a0 = butterworth_q130[bw_index][0];
		a1 = butterworth_q130[bw_index][1];
		b0 = butterworth_q130[bw_index][2];
		b1 = butterworth_q130[bw_index][3];
		break;
	case 14:
		a2 = a0 = butterworth_q140[bw_index][0];
		a1 = butterworth_q140[bw_index][1];
		b0 = butterworth_q140[bw_index][2];
		b1 = butterworth_q140[bw_index][3];
		break;
	case 15:
		a2 = a0 = butterworth_q150[bw_index][0];
		a1 = butterworth_q150[bw_index][1];
		b0 = butterworth_q150[bw_index][2];
		b1 = butterworth_q150[bw_index][3];
		break;
	case 16:
		a2 = a0 = butterworth_q160[bw_index][0];
		a1 = butterworth_q160[bw_index][1];
		b0 = butterworth_q160[bw_index][2];
		b1 = butterworth_q160[bw_index][3];
		break;
	case 17:
		a2 = a0 = butterworth_q170[bw_index][0];
		a1 = butterworth_q170[bw_index][1];
		b0 = butterworth_q170[bw_index][2];
		b1 = butterworth_q170[bw_index][3];
		break;
	case 18:
		a2 = a0 = butterworth_q180[bw_index][0];
		a1 = butterworth_q180[bw_index][1];
		b0 = butterworth_q180[bw_index][2];
		b1 = butterworth_q180[bw_index][3];
		break;
	case 19:
		a2 = a0 = butterworth_q190[bw_index][0];
		a1 = butterworth_q190[bw_index][1];
		b0 = butterworth_q190[bw_index][2];
		b1 = butterworth_q190[bw_index][3];
		break;
	case 20:
		a2 = a0 = butterworth_q200[bw_index][0];
		a1 = butterworth_q200[bw_index][1];
		b0 = butterworth_q200[bw_index][2];
		b1 = butterworth_q200[bw_index][3];
		break;
	case 21:
		a2 = a0 = butterworth_q210[bw_index][0];
		a1 = butterworth_q210[bw_index][1];
		b0 = butterworth_q210[bw_index][2];
		b1 = butterworth_q210[bw_index][3];
		break;
	case 22:
		a2 = a0 = butterworth_q220[bw_index][0];
		a1 = butterworth_q220[bw_index][1];
		b0 = butterworth_q220[bw_index][2];
		b1 = butterworth_q220[bw_index][3];
		break;
	case 23:
		a2 = a0 = butterworth_q230[bw_index][0];
		a1 = butterworth_q230[bw_index][1];
		b0 = butterworth_q230[bw_index][2];
		b1 = butterworth_q230[bw_index][3];
		break;
	default:
	case 24:
		a2 = a0 = butterworth_q240[bw_index][0];
		a1 = butterworth_q240[bw_index][1];
		b0 = butterworth_q240[bw_index][2];
		b1 = butterworth_q240[bw_index][3];
		break;
    }




		    }
		    incr = calc_mod_freq(vp, incr);
		}
		newsample = (resample_t)v1;
		if (bw_index) {
                    insamp = (FLOAT_T)newsample;
		    outsamp = a0 * insamp + a1 * xx0 + a2 * xx1 - b0 * yy0 - b1 * yy1;
		    xx1 = xx0;
		    xx0 = insamp;
		    yy1 = yy0;
		    yy0 = outsamp;
		    newsample = (resample_t)outsamp;
		}
		ofs=ofsd;
	}
	*dest++ = newsample;
	  ofs += incr;
	}
      if (vibflag)
	{
	  cc = vp->vibrato_control_ratio;
	  incr = update_vibrato(vp, (incr < 0));
	  vibflag = 0;
	}
      if (ofs >= le)
	{
#ifdef USE_BIDIR_OVERSHOOT
	  /* fold the overshoot back in */
	  ofs = le2 - ofs;
#endif
	  incr *= -1;
	}
      else if (ofs <= ls)
	{
#ifdef USE_BIDIR_OVERSHOOT
	  ofs = ls2 - ofs;
#endif
	  incr *= -1;
	}
    }


  vp->vibrato_control_counter=cc;
  vp->sample_increment=incr;
  vp->sample_offset=ofs; /* Update offset */
  vp->current_x0=xx0;
  vp->current_x1=xx1;
  vp->current_y0=yy0;
  vp->current_y1=yy1;
  vp->bw_index=bw_index;
  vp->modulation_counter=cc_count;
  return resample_buffer+resample_buffer_offset;
}

static int rs_update_porta(int v)
{
    Voice *vp=&voice[v];
    int32 d;

    d = vp->porta_dpb;
    if(vp->porta_pb < 0)
    {
	if(d > -vp->porta_pb)
	    d = -vp->porta_pb;
    }
    else
    {
	if(d > vp->porta_pb)
	    d = -vp->porta_pb;
	else
	    d = -d;
    }

    vp->porta_pb += d;
    if(vp->porta_pb == 0)
    {
	vp->porta_control_ratio = 0;
	vp->porta_pb = 0;
    }
    recompute_freq(v);
    return vp->porta_control_ratio;
}

static resample_t *porta_resample_voice(int v, uint32 *countptr, int mode)
{
    Voice *vp=&voice[v];
    uint32 n = *countptr;
    uint32 i;
    resample_t *(* resampler)(int, uint32 *, int);
    int cc = vp->porta_control_counter;
    int loop;

    if(vp->vibrato_control_ratio)
	resampler = vib_resample_voice;
    else
	resampler = normal_resample_voice;
    if(mode != 1)
	loop = 1;
    else
	loop = 0;

    /* vp->cache = NULL; */
    resample_buffer_offset = 0;
    while(resample_buffer_offset < n)
    {
	if(cc == 0)
	{
	    if((cc = rs_update_porta(v)) == 0)
	    {
		i = n - resample_buffer_offset;
		resampler(v, &i, mode);
		resample_buffer_offset += i;
		break;
	    }
	}

	i = n - resample_buffer_offset;
	if(i > (uint32)cc)
	    i = (uint32)cc;
	resampler(v, &i, mode);
	resample_buffer_offset += i;

	/* if(!loop && vp->status == VOICE_FREE) */
	if(vp->status == VOICE_FREE)
	    break;
	cc -= (int)i;
    }
    *countptr = resample_buffer_offset;
    resample_buffer_offset = 0;
    vp->porta_control_counter = cc;
    return resample_buffer;
}

static resample_t *vib_resample_voice(int v, uint32 *countptr, int mode)
{
    Voice *vp = &voice[v];

    /* vp->cache = NULL; */
    if(mode == 0)
	return rs_vib_loop(v, vp, countptr);
    if(mode == 1)
	return rs_vib_plain(v, countptr);
    return rs_vib_bidir(vp, *countptr);
}

static resample_t *normal_resample_voice(int v, uint32 *countptr, int mode)
{
    Voice *vp = &voice[v];
    if(mode == 0)
	return rs_loop(v, vp, countptr);
    if(mode == 1)
	return rs_plain(v, countptr);
    return rs_bidir(vp, *countptr);
}

resample_t *resample_voice_butterworth(int v, uint32 *countptr)
{
    Voice *vp=&voice[v];
    int mode;

    mode = vp->sample->modes;
    if((mode & MODES_LOOPING) &&
       ((mode & MODES_ENVELOPE) ||
	(vp->status & (VOICE_ON | VOICE_SUSTAINED))))
    {
	if(mode & MODES_PINGPONG)
	{
	    /* vp->cache = NULL; */
	    mode = 2;
	}
	else
	    mode = 0;
    }
    else
	mode = 1;

    if(vp->porta_control_ratio)
	return porta_resample_voice(v, countptr, mode);

    if(vp->vibrato_control_ratio)
	return vib_resample_voice(v, countptr, mode);

    return normal_resample_voice(v, countptr, mode);
}

