Path: blob/master/libs/fluidsynth/src/rvoice/fluid_rvoice_dsp.c
8882 views
/* FluidSynth - A Software Synthesizer1*2* Copyright (C) 2003 Peter Hanappe and others.3*4* This library is free software; you can redistribute it and/or5* modify it under the terms of the GNU Lesser General Public License6* as published by the Free Software Foundation; either version 2.1 of7* the License, or (at your option) any later version.8*9* This library is distributed in the hope that it will be useful, but10* WITHOUT ANY WARRANTY; without even the implied warranty of11* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU12* Lesser General Public License for more details.13*14* You should have received a copy of the GNU Lesser General Public15* License along with this library; if not, write to the Free16* Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA17* 02110-1301, USA18*/1920#include "fluid_sys.h"21#include "fluid_phase.h"22#include "fluid_rvoice.h"23#include "fluid_rvoice_dsp_tables.inc.h"2425/* Purpose:26*27* Interpolates audio data (obtains values between the samples of the original28* waveform data).29*30* Variables loaded from the voice structure (assigned in fluid_rvoice_write()):31* - dsp_data: Pointer to the original waveform data32* - dsp_phase: The position in the original waveform data.33* This has an integer and a fractional part (between samples).34* - dsp_phase_incr: For each output sample, the position in the original35* waveform advances by dsp_phase_incr. This also has an integer36* part and a fractional part.37* If a sample is played at root pitch (no pitch change),38* dsp_phase_incr is integer=1 and fractional=0.39* - dsp_amp: The current amplitude envelope value.40* - dsp_amp_incr: The changing rate of the amplitude envelope.41*42* A couple of variables are used internally, their results are discarded:43* - dsp_i: Index through the output buffer44* - dsp_buf: Output buffer of floating point values (FLUID_BUFSIZE in length)45*/4647/* Interpolation (find a value between two samples of the original waveform) */4849static FLUID_INLINE fluid_real_t50fluid_rvoice_get_float_sample(const short int *dsp_msb, const char *dsp_lsb, unsigned int idx)51{52int32_t sample = fluid_rvoice_get_sample(dsp_msb, dsp_lsb, idx);53return (fluid_real_t)sample;54}5556/* No interpolation. Just take the sample, which is closest to57* the playback pointer. Questionable quality, but very58* efficient. */59int60fluid_rvoice_dsp_interpolate_none(fluid_rvoice_t *rvoice, fluid_real_t *FLUID_RESTRICT dsp_buf, int looping)61{62fluid_rvoice_dsp_t *voice = &rvoice->dsp;63fluid_phase_t dsp_phase = voice->phase;64fluid_phase_t dsp_phase_incr;65short int *dsp_data = voice->sample->data;66char *dsp_data24 = voice->sample->data24;67fluid_real_t dsp_amp = voice->amp;68fluid_real_t dsp_amp_incr = voice->amp_incr;69unsigned int dsp_i = 0;70unsigned int dsp_phase_index;71unsigned int end_index;7273/* Convert playback "speed" floating point value to phase index/fract */74fluid_phase_set_float(dsp_phase_incr, voice->phase_incr);7576end_index = looping ? voice->loopend - 1 : voice->end;7778while(1)79{80dsp_phase_index = fluid_phase_index_round(dsp_phase); /* round to nearest point */8182/* interpolate sequence of sample points */83for(; dsp_i < FLUID_BUFSIZE && dsp_phase_index <= end_index; dsp_i++)84{85fluid_real_t sample = fluid_rvoice_get_float_sample(dsp_data, dsp_data24, dsp_phase_index);8687fluid_iir_filter_apply(&rvoice->resonant_filter, &sample, 1, voice->output_rate);88fluid_iir_filter_apply(&rvoice->resonant_custom_filter, &sample, 1, voice->output_rate);8990dsp_buf[dsp_i] = dsp_amp * sample;9192/* increment phase and amplitude */93fluid_phase_incr(dsp_phase, dsp_phase_incr);94dsp_phase_index = fluid_phase_index_round(dsp_phase); /* round to nearest point */95dsp_amp += dsp_amp_incr;96}9798/* break out if not looping (buffer may not be full) */99if(!looping)100{101break;102}103104/* go back to loop start */105if(dsp_phase_index > end_index)106{107fluid_phase_sub_int(dsp_phase, voice->loopend - voice->loopstart);108voice->has_looped = 1;109}110111/* break out if filled buffer */112if(dsp_i >= FLUID_BUFSIZE)113{114break;115}116}117118voice->phase = dsp_phase;119voice->amp = dsp_amp;120121return (dsp_i);122}123124/* Straight line interpolation.125* Returns number of samples processed (usually FLUID_BUFSIZE but could be126* smaller if end of sample occurs).127*/128int129fluid_rvoice_dsp_interpolate_linear(fluid_rvoice_t *rvoice, fluid_real_t *FLUID_RESTRICT dsp_buf, int looping)130{131fluid_rvoice_dsp_t *voice = &rvoice->dsp;132fluid_phase_t dsp_phase = voice->phase;133fluid_phase_t dsp_phase_incr;134short int *dsp_data = voice->sample->data;135char *dsp_data24 = voice->sample->data24;136fluid_real_t dsp_amp = voice->amp;137fluid_real_t dsp_amp_incr = voice->amp_incr;138unsigned int dsp_i = 0;139unsigned int dsp_phase_index;140unsigned int end_index;141fluid_real_t point;142const fluid_real_t *FLUID_RESTRICT coeffs;143144/* Convert playback "speed" floating point value to phase index/fract */145fluid_phase_set_float(dsp_phase_incr, voice->phase_incr);146147/* last index before 2nd interpolation point must be specially handled */148end_index = (looping ? voice->loopend - 1 : voice->end) - 1;149150/* 2nd interpolation point to use at end of loop or sample */151if(looping)152{153point = fluid_rvoice_get_float_sample(dsp_data, dsp_data24, voice->loopstart); /* loop start */154}155else156{157point = fluid_rvoice_get_float_sample(dsp_data, dsp_data24, voice->end); /* duplicate end for samples no longer looping */158}159160while(1)161{162dsp_phase_index = fluid_phase_index(dsp_phase);163164/* interpolate the sequence of sample points */165for(; dsp_i < FLUID_BUFSIZE && dsp_phase_index <= end_index; dsp_i++)166{167fluid_real_t sample;168coeffs = interp_coeff_linear[fluid_phase_fract_to_tablerow(dsp_phase)];169170sample = (coeffs[0] * fluid_rvoice_get_float_sample(dsp_data, dsp_data24, dsp_phase_index)171+ coeffs[1] * fluid_rvoice_get_float_sample(dsp_data, dsp_data24, dsp_phase_index + 1));172173fluid_iir_filter_apply(&rvoice->resonant_filter, &sample, 1, voice->output_rate);174fluid_iir_filter_apply(&rvoice->resonant_custom_filter, &sample, 1, voice->output_rate);175176dsp_buf[dsp_i] = dsp_amp * sample;177178/* increment phase and amplitude */179fluid_phase_incr(dsp_phase, dsp_phase_incr);180dsp_phase_index = fluid_phase_index(dsp_phase);181dsp_amp += dsp_amp_incr;182}183184/* break out if buffer filled */185if(dsp_i >= FLUID_BUFSIZE)186{187break;188}189190end_index++; /* we're now interpolating the last point */191192/* interpolate within last point */193for(; dsp_phase_index <= end_index && dsp_i < FLUID_BUFSIZE; dsp_i++)194{195fluid_real_t sample;196coeffs = interp_coeff_linear[fluid_phase_fract_to_tablerow(dsp_phase)];197198sample = (coeffs[0] * fluid_rvoice_get_float_sample(dsp_data, dsp_data24, dsp_phase_index)199+ coeffs[1] * point);200201fluid_iir_filter_apply(&rvoice->resonant_filter, &sample, 1, voice->output_rate);202fluid_iir_filter_apply(&rvoice->resonant_custom_filter, &sample, 1, voice->output_rate);203204dsp_buf[dsp_i] = dsp_amp * sample;205206/* increment phase and amplitude */207fluid_phase_incr(dsp_phase, dsp_phase_incr);208dsp_phase_index = fluid_phase_index(dsp_phase);209dsp_amp += dsp_amp_incr; /* increment amplitude */210}211212if(!looping)213{214break; /* break out if not looping (end of sample) */215}216217/* go back to loop start (if past */218if(dsp_phase_index > end_index)219{220fluid_phase_sub_int(dsp_phase, voice->loopend - voice->loopstart);221voice->has_looped = 1;222}223224/* break out if filled buffer */225if(dsp_i >= FLUID_BUFSIZE)226{227break;228}229230end_index--; /* set end back to second to last sample point */231}232233voice->phase = dsp_phase;234voice->amp = dsp_amp;235236return (dsp_i);237}238239/* 4th order (cubic) interpolation.240* Returns number of samples processed (usually FLUID_BUFSIZE but could be241* smaller if end of sample occurs).242*/243int244fluid_rvoice_dsp_interpolate_4th_order(fluid_rvoice_t *rvoice, fluid_real_t *FLUID_RESTRICT dsp_buf, int looping)245{246fluid_rvoice_dsp_t *voice = &rvoice->dsp;247fluid_phase_t dsp_phase = voice->phase;248fluid_phase_t dsp_phase_incr;249short int *dsp_data = voice->sample->data;250char *dsp_data24 = voice->sample->data24;251fluid_real_t dsp_amp = voice->amp;252fluid_real_t dsp_amp_incr = voice->amp_incr;253unsigned int dsp_i = 0;254unsigned int dsp_phase_index;255unsigned int start_index, end_index;256fluid_real_t start_point, end_point1, end_point2;257const fluid_real_t *FLUID_RESTRICT coeffs;258259/* Convert playback "speed" floating point value to phase index/fract */260fluid_phase_set_float(dsp_phase_incr, voice->phase_incr);261262/* last index before 4th interpolation point must be specially handled */263end_index = (looping ? voice->loopend - 1 : voice->end) - 2;264265if(voice->has_looped) /* set start_index and start point if looped or not */266{267start_index = voice->loopstart;268start_point = fluid_rvoice_get_float_sample(dsp_data, dsp_data24, voice->loopend - 1); /* last point in loop (wrap around) */269}270else271{272start_index = voice->start;273start_point = fluid_rvoice_get_float_sample(dsp_data, dsp_data24, voice->start); /* just duplicate the point */274}275276/* get points off the end (loop start if looping, duplicate point if end) */277if(looping)278{279end_point1 = fluid_rvoice_get_float_sample(dsp_data, dsp_data24, voice->loopstart);280end_point2 = fluid_rvoice_get_float_sample(dsp_data, dsp_data24, voice->loopstart + 1);281}282else283{284end_point1 = fluid_rvoice_get_float_sample(dsp_data, dsp_data24, voice->end);285end_point2 = end_point1;286}287288while(1)289{290dsp_phase_index = fluid_phase_index(dsp_phase);291292/* interpolate first sample point (start or loop start) if needed */293for(; dsp_phase_index == start_index && dsp_i < FLUID_BUFSIZE; dsp_i++)294{295fluid_real_t sample;296coeffs = interp_coeff[fluid_phase_fract_to_tablerow(dsp_phase)];297298sample = (coeffs[0] * start_point299+ coeffs[1] * fluid_rvoice_get_float_sample(dsp_data, dsp_data24, dsp_phase_index)300+ coeffs[2] * fluid_rvoice_get_float_sample(dsp_data, dsp_data24, dsp_phase_index + 1)301+ coeffs[3] * fluid_rvoice_get_float_sample(dsp_data, dsp_data24, dsp_phase_index + 2));302303fluid_iir_filter_apply(&rvoice->resonant_filter, &sample, 1, voice->output_rate);304fluid_iir_filter_apply(&rvoice->resonant_custom_filter, &sample, 1, voice->output_rate);305306dsp_buf[dsp_i] = dsp_amp * sample;307308/* increment phase and amplitude */309fluid_phase_incr(dsp_phase, dsp_phase_incr);310dsp_phase_index = fluid_phase_index(dsp_phase);311dsp_amp += dsp_amp_incr;312}313314/* interpolate the sequence of sample points */315for(; dsp_i < FLUID_BUFSIZE && dsp_phase_index <= end_index; dsp_i++)316{317fluid_real_t sample;318coeffs = interp_coeff[fluid_phase_fract_to_tablerow(dsp_phase)];319320sample = (coeffs[0] * fluid_rvoice_get_float_sample(dsp_data, dsp_data24, dsp_phase_index - 1)321+ coeffs[1] * fluid_rvoice_get_float_sample(dsp_data, dsp_data24, dsp_phase_index)322+ coeffs[2] * fluid_rvoice_get_float_sample(dsp_data, dsp_data24, dsp_phase_index + 1)323+ coeffs[3] * fluid_rvoice_get_float_sample(dsp_data, dsp_data24, dsp_phase_index + 2));324325fluid_iir_filter_apply(&rvoice->resonant_filter, &sample, 1, voice->output_rate);326fluid_iir_filter_apply(&rvoice->resonant_custom_filter, &sample, 1, voice->output_rate);327328dsp_buf[dsp_i] = dsp_amp * sample;329330/* increment phase and amplitude */331fluid_phase_incr(dsp_phase, dsp_phase_incr);332dsp_phase_index = fluid_phase_index(dsp_phase);333dsp_amp += dsp_amp_incr;334}335336/* break out if buffer filled */337if(dsp_i >= FLUID_BUFSIZE)338{339break;340}341342end_index++; /* we're now interpolating the 2nd to last point */343344/* interpolate within 2nd to last point */345for(; dsp_phase_index <= end_index && dsp_i < FLUID_BUFSIZE; dsp_i++)346{347fluid_real_t sample;348coeffs = interp_coeff[fluid_phase_fract_to_tablerow(dsp_phase)];349350sample = (coeffs[0] * fluid_rvoice_get_float_sample(dsp_data, dsp_data24, dsp_phase_index - 1)351+ coeffs[1] * fluid_rvoice_get_float_sample(dsp_data, dsp_data24, dsp_phase_index)352+ coeffs[2] * fluid_rvoice_get_float_sample(dsp_data, dsp_data24, dsp_phase_index + 1)353+ coeffs[3] * end_point1);354355fluid_iir_filter_apply(&rvoice->resonant_filter, &sample, 1, voice->output_rate);356fluid_iir_filter_apply(&rvoice->resonant_custom_filter, &sample, 1, voice->output_rate);357358dsp_buf[dsp_i] = dsp_amp * sample;359360/* increment phase and amplitude */361fluid_phase_incr(dsp_phase, dsp_phase_incr);362dsp_phase_index = fluid_phase_index(dsp_phase);363dsp_amp += dsp_amp_incr;364}365366end_index++; /* we're now interpolating the last point */367368/* interpolate within the last point */369for(; dsp_phase_index <= end_index && dsp_i < FLUID_BUFSIZE; dsp_i++)370{371fluid_real_t sample;372coeffs = interp_coeff[fluid_phase_fract_to_tablerow(dsp_phase)];373374375sample = (coeffs[0] * fluid_rvoice_get_float_sample(dsp_data, dsp_data24, dsp_phase_index - 1)376+ coeffs[1] * fluid_rvoice_get_float_sample(dsp_data, dsp_data24, dsp_phase_index)377+ coeffs[2] * end_point1378+ coeffs[3] * end_point2);379380fluid_iir_filter_apply(&rvoice->resonant_filter, &sample, 1, voice->output_rate);381fluid_iir_filter_apply(&rvoice->resonant_custom_filter, &sample, 1, voice->output_rate);382383dsp_buf[dsp_i] = dsp_amp * sample;384385/* increment phase and amplitude */386fluid_phase_incr(dsp_phase, dsp_phase_incr);387dsp_phase_index = fluid_phase_index(dsp_phase);388dsp_amp += dsp_amp_incr;389}390391if(!looping)392{393break; /* break out if not looping (end of sample) */394}395396/* go back to loop start */397if(dsp_phase_index > end_index)398{399fluid_phase_sub_int(dsp_phase, voice->loopend - voice->loopstart);400401if(!voice->has_looped)402{403voice->has_looped = 1;404start_index = voice->loopstart;405start_point = fluid_rvoice_get_float_sample(dsp_data, dsp_data24, voice->loopend - 1);406}407}408409/* break out if filled buffer */410if(dsp_i >= FLUID_BUFSIZE)411{412break;413}414415end_index -= 2; /* set end back to third to last sample point */416}417418voice->phase = dsp_phase;419voice->amp = dsp_amp;420421return (dsp_i);422}423424/* 7th order interpolation.425* Returns number of samples processed (usually FLUID_BUFSIZE but could be426* smaller if end of sample occurs).427*/428int429fluid_rvoice_dsp_interpolate_7th_order(fluid_rvoice_t *rvoice, fluid_real_t *FLUID_RESTRICT dsp_buf, int looping)430{431fluid_rvoice_dsp_t *voice = &rvoice->dsp;432fluid_phase_t dsp_phase = voice->phase;433fluid_phase_t dsp_phase_incr;434short int *dsp_data = voice->sample->data;435char *dsp_data24 = voice->sample->data24;436fluid_real_t dsp_amp = voice->amp;437fluid_real_t dsp_amp_incr = voice->amp_incr;438unsigned int dsp_i = 0;439unsigned int dsp_phase_index;440unsigned int start_index, end_index;441fluid_real_t start_points[3], end_points[3];442const fluid_real_t *FLUID_RESTRICT coeffs;443444/* Convert playback "speed" floating point value to phase index/fract */445fluid_phase_set_float(dsp_phase_incr, voice->phase_incr);446447/* add 1/2 sample to dsp_phase since 7th order interpolation is centered on448* the 4th sample point */449fluid_phase_incr(dsp_phase, (fluid_phase_t)0x80000000);450451/* last index before 7th interpolation point must be specially handled */452end_index = (looping ? voice->loopend - 1 : voice->end) - 3;453454if(voice->has_looped) /* set start_index and start point if looped or not */455{456start_index = voice->loopstart;457start_points[0] = fluid_rvoice_get_float_sample(dsp_data, dsp_data24, voice->loopend - 1);458start_points[1] = fluid_rvoice_get_float_sample(dsp_data, dsp_data24, voice->loopend - 2);459start_points[2] = fluid_rvoice_get_float_sample(dsp_data, dsp_data24, voice->loopend - 3);460}461else462{463start_index = voice->start;464start_points[0] = fluid_rvoice_get_float_sample(dsp_data, dsp_data24, voice->start); /* just duplicate the start point */465start_points[1] = start_points[0];466start_points[2] = start_points[0];467}468469/* get the 3 points off the end (loop start if looping, duplicate point if end) */470if(looping)471{472end_points[0] = fluid_rvoice_get_float_sample(dsp_data, dsp_data24, voice->loopstart);473end_points[1] = fluid_rvoice_get_float_sample(dsp_data, dsp_data24, voice->loopstart + 1);474end_points[2] = fluid_rvoice_get_float_sample(dsp_data, dsp_data24, voice->loopstart + 2);475}476else477{478end_points[0] = fluid_rvoice_get_float_sample(dsp_data, dsp_data24, voice->end);479end_points[1] = end_points[0];480end_points[2] = end_points[0];481}482483while(1)484{485dsp_phase_index = fluid_phase_index(dsp_phase);486487/* interpolate first sample point (start or loop start) if needed */488for(; dsp_phase_index == start_index && dsp_i < FLUID_BUFSIZE; dsp_i++)489{490fluid_real_t sample;491coeffs = sinc_table7[fluid_phase_fract_to_tablerow(dsp_phase)];492493sample = (coeffs[0] * start_points[2]494+ coeffs[1] * start_points[1]495+ coeffs[2] * start_points[0]496+ coeffs[3] * fluid_rvoice_get_float_sample(dsp_data, dsp_data24, dsp_phase_index)497+ coeffs[4] * fluid_rvoice_get_float_sample(dsp_data, dsp_data24, dsp_phase_index + 1)498+ coeffs[5] * fluid_rvoice_get_float_sample(dsp_data, dsp_data24, dsp_phase_index + 2)499+ coeffs[6] * fluid_rvoice_get_float_sample(dsp_data, dsp_data24, dsp_phase_index + 3));500501fluid_iir_filter_apply(&rvoice->resonant_filter, &sample, 1, voice->output_rate);502fluid_iir_filter_apply(&rvoice->resonant_custom_filter, &sample, 1, voice->output_rate);503504dsp_buf[dsp_i] = dsp_amp * sample;505506/* increment phase and amplitude */507fluid_phase_incr(dsp_phase, dsp_phase_incr);508dsp_phase_index = fluid_phase_index(dsp_phase);509dsp_amp += dsp_amp_incr;510}511512start_index++;513514/* interpolate 2nd to first sample point (start or loop start) if needed */515for(; dsp_phase_index == start_index && dsp_i < FLUID_BUFSIZE; dsp_i++)516{517fluid_real_t sample;518coeffs = sinc_table7[fluid_phase_fract_to_tablerow(dsp_phase)];519520sample = (coeffs[0] * start_points[1]521+ coeffs[1] * start_points[0]522+ coeffs[2] * fluid_rvoice_get_float_sample(dsp_data, dsp_data24, dsp_phase_index - 1)523+ coeffs[3] * fluid_rvoice_get_float_sample(dsp_data, dsp_data24, dsp_phase_index)524+ coeffs[4] * fluid_rvoice_get_float_sample(dsp_data, dsp_data24, dsp_phase_index + 1)525+ coeffs[5] * fluid_rvoice_get_float_sample(dsp_data, dsp_data24, dsp_phase_index + 2)526+ coeffs[6] * fluid_rvoice_get_float_sample(dsp_data, dsp_data24, dsp_phase_index + 3));527528fluid_iir_filter_apply(&rvoice->resonant_filter, &sample, 1, voice->output_rate);529fluid_iir_filter_apply(&rvoice->resonant_custom_filter, &sample, 1, voice->output_rate);530531dsp_buf[dsp_i] = dsp_amp * sample;532533/* increment phase and amplitude */534fluid_phase_incr(dsp_phase, dsp_phase_incr);535dsp_phase_index = fluid_phase_index(dsp_phase);536dsp_amp += dsp_amp_incr;537}538539start_index++;540541/* interpolate 3rd to first sample point (start or loop start) if needed */542for(; dsp_phase_index == start_index && dsp_i < FLUID_BUFSIZE; dsp_i++)543{544fluid_real_t sample;545coeffs = sinc_table7[fluid_phase_fract_to_tablerow(dsp_phase)];546547sample = (coeffs[0] * start_points[0]548+ coeffs[1] * fluid_rvoice_get_float_sample(dsp_data, dsp_data24, dsp_phase_index - 2)549+ coeffs[2] * fluid_rvoice_get_float_sample(dsp_data, dsp_data24, dsp_phase_index - 1)550+ coeffs[3] * fluid_rvoice_get_float_sample(dsp_data, dsp_data24, dsp_phase_index)551+ coeffs[4] * fluid_rvoice_get_float_sample(dsp_data, dsp_data24, dsp_phase_index + 1)552+ coeffs[5] * fluid_rvoice_get_float_sample(dsp_data, dsp_data24, dsp_phase_index + 2)553+ coeffs[6] * fluid_rvoice_get_float_sample(dsp_data, dsp_data24, dsp_phase_index + 3));554555fluid_iir_filter_apply(&rvoice->resonant_filter, &sample, 1, voice->output_rate);556fluid_iir_filter_apply(&rvoice->resonant_custom_filter, &sample, 1, voice->output_rate);557558dsp_buf[dsp_i] = dsp_amp * sample;559560/* increment phase and amplitude */561fluid_phase_incr(dsp_phase, dsp_phase_incr);562dsp_phase_index = fluid_phase_index(dsp_phase);563dsp_amp += dsp_amp_incr;564}565566start_index -= 2; /* set back to original start index */567568569/* interpolate the sequence of sample points */570for(; dsp_i < FLUID_BUFSIZE && dsp_phase_index <= end_index; dsp_i++)571{572fluid_real_t sample;573coeffs = sinc_table7[fluid_phase_fract_to_tablerow(dsp_phase)];574575sample = (coeffs[0] * fluid_rvoice_get_float_sample(dsp_data, dsp_data24, dsp_phase_index - 3)576+ coeffs[1] * fluid_rvoice_get_float_sample(dsp_data, dsp_data24, dsp_phase_index - 2)577+ coeffs[2] * fluid_rvoice_get_float_sample(dsp_data, dsp_data24, dsp_phase_index - 1)578+ coeffs[3] * fluid_rvoice_get_float_sample(dsp_data, dsp_data24, dsp_phase_index)579+ coeffs[4] * fluid_rvoice_get_float_sample(dsp_data, dsp_data24, dsp_phase_index + 1)580+ coeffs[5] * fluid_rvoice_get_float_sample(dsp_data, dsp_data24, dsp_phase_index + 2)581+ coeffs[6] * fluid_rvoice_get_float_sample(dsp_data, dsp_data24, dsp_phase_index + 3));582583fluid_iir_filter_apply(&rvoice->resonant_filter, &sample, 1, voice->output_rate);584fluid_iir_filter_apply(&rvoice->resonant_custom_filter, &sample, 1, voice->output_rate);585586dsp_buf[dsp_i] = dsp_amp * sample;587588/* increment phase and amplitude */589fluid_phase_incr(dsp_phase, dsp_phase_incr);590dsp_phase_index = fluid_phase_index(dsp_phase);591dsp_amp += dsp_amp_incr;592}593594/* break out if buffer filled */595if(dsp_i >= FLUID_BUFSIZE)596{597break;598}599600end_index++; /* we're now interpolating the 3rd to last point */601602/* interpolate within 3rd to last point */603for(; dsp_phase_index <= end_index && dsp_i < FLUID_BUFSIZE; dsp_i++)604{605fluid_real_t sample;606coeffs = sinc_table7[fluid_phase_fract_to_tablerow(dsp_phase)];607608sample = (coeffs[0] * fluid_rvoice_get_float_sample(dsp_data, dsp_data24, dsp_phase_index - 3)609+ coeffs[1] * fluid_rvoice_get_float_sample(dsp_data, dsp_data24, dsp_phase_index - 2)610+ coeffs[2] * fluid_rvoice_get_float_sample(dsp_data, dsp_data24, dsp_phase_index - 1)611+ coeffs[3] * fluid_rvoice_get_float_sample(dsp_data, dsp_data24, dsp_phase_index)612+ coeffs[4] * fluid_rvoice_get_float_sample(dsp_data, dsp_data24, dsp_phase_index + 1)613+ coeffs[5] * fluid_rvoice_get_float_sample(dsp_data, dsp_data24, dsp_phase_index + 2)614+ coeffs[6] * end_points[0]);615616fluid_iir_filter_apply(&rvoice->resonant_filter, &sample, 1, voice->output_rate);617fluid_iir_filter_apply(&rvoice->resonant_custom_filter, &sample, 1, voice->output_rate);618619dsp_buf[dsp_i] = dsp_amp * sample;620621/* increment phase and amplitude */622fluid_phase_incr(dsp_phase, dsp_phase_incr);623dsp_phase_index = fluid_phase_index(dsp_phase);624dsp_amp += dsp_amp_incr;625}626627end_index++; /* we're now interpolating the 2nd to last point */628629/* interpolate within 2nd to last point */630for(; dsp_phase_index <= end_index && dsp_i < FLUID_BUFSIZE; dsp_i++)631{632fluid_real_t sample;633coeffs = sinc_table7[fluid_phase_fract_to_tablerow(dsp_phase)];634635sample = (coeffs[0] * fluid_rvoice_get_float_sample(dsp_data, dsp_data24, dsp_phase_index - 3)636+ coeffs[1] * fluid_rvoice_get_float_sample(dsp_data, dsp_data24, dsp_phase_index - 2)637+ coeffs[2] * fluid_rvoice_get_float_sample(dsp_data, dsp_data24, dsp_phase_index - 1)638+ coeffs[3] * fluid_rvoice_get_float_sample(dsp_data, dsp_data24, dsp_phase_index)639+ coeffs[4] * fluid_rvoice_get_float_sample(dsp_data, dsp_data24, dsp_phase_index + 1)640+ coeffs[5] * end_points[0]641+ coeffs[6] * end_points[1]);642643fluid_iir_filter_apply(&rvoice->resonant_filter, &sample, 1, voice->output_rate);644fluid_iir_filter_apply(&rvoice->resonant_custom_filter, &sample, 1, voice->output_rate);645646dsp_buf[dsp_i] = dsp_amp * sample;647648/* increment phase and amplitude */649fluid_phase_incr(dsp_phase, dsp_phase_incr);650dsp_phase_index = fluid_phase_index(dsp_phase);651dsp_amp += dsp_amp_incr;652}653654end_index++; /* we're now interpolating the last point */655656/* interpolate within last point */657for(; dsp_phase_index <= end_index && dsp_i < FLUID_BUFSIZE; dsp_i++)658{659fluid_real_t sample;660coeffs = sinc_table7[fluid_phase_fract_to_tablerow(dsp_phase)];661662sample = (coeffs[0] * fluid_rvoice_get_float_sample(dsp_data, dsp_data24, dsp_phase_index - 3)663+ coeffs[1] * fluid_rvoice_get_float_sample(dsp_data, dsp_data24, dsp_phase_index - 2)664+ coeffs[2] * fluid_rvoice_get_float_sample(dsp_data, dsp_data24, dsp_phase_index - 1)665+ coeffs[3] * fluid_rvoice_get_float_sample(dsp_data, dsp_data24, dsp_phase_index)666+ coeffs[4] * end_points[0]667+ coeffs[5] * end_points[1]668+ coeffs[6] * end_points[2]);669670fluid_iir_filter_apply(&rvoice->resonant_filter, &sample, 1, voice->output_rate);671fluid_iir_filter_apply(&rvoice->resonant_custom_filter, &sample, 1, voice->output_rate);672673dsp_buf[dsp_i] = dsp_amp * sample;674675/* increment phase and amplitude */676fluid_phase_incr(dsp_phase, dsp_phase_incr);677dsp_phase_index = fluid_phase_index(dsp_phase);678dsp_amp += dsp_amp_incr;679}680681if(!looping)682{683break; /* break out if not looping (end of sample) */684}685686/* go back to loop start */687if(dsp_phase_index > end_index)688{689fluid_phase_sub_int(dsp_phase, voice->loopend - voice->loopstart);690691if(!voice->has_looped)692{693voice->has_looped = 1;694start_index = voice->loopstart;695start_points[0] = fluid_rvoice_get_float_sample(dsp_data, dsp_data24, voice->loopend - 1);696start_points[1] = fluid_rvoice_get_float_sample(dsp_data, dsp_data24, voice->loopend - 2);697start_points[2] = fluid_rvoice_get_float_sample(dsp_data, dsp_data24, voice->loopend - 3);698}699}700701/* break out if filled buffer */702if(dsp_i >= FLUID_BUFSIZE)703{704break;705}706707end_index -= 3; /* set end back to 4th to last sample point */708}709710/* sub 1/2 sample from dsp_phase since 7th order interpolation is centered on711* the 4th sample point (correct back to real value) */712fluid_phase_decr(dsp_phase, (fluid_phase_t)0x80000000);713714voice->phase = dsp_phase;715voice->amp = dsp_amp;716717return (dsp_i);718}719720721