ft2-clone

Fasttracker 2 clone
Log | Files | Refs | README | LICENSE

commit a685b2642191830c45e3b99ed79716e423758d82
parent b3226cae30afa0b3a43ebcca5919b2cd02555a1e
Author: Olav Sørensen <olav.sorensen@live.no>
Date:   Sun, 16 Feb 2025 16:23:55 +0100

New mixer interpolator + small tracker scope changes

Diffstat:
Msrc/ft2_audio.c | 7++-----
Msrc/ft2_audio.h | 2+-
Msrc/ft2_config.c | 24++++++++++++------------
Msrc/ft2_config.h | 4++--
Msrc/ft2_main.c | 2+-
Msrc/ft2_radiobuttons.c | 4++--
Msrc/ft2_radiobuttons.h | 4++--
Msrc/ft2_replayer.c | 3++-
Msrc/ft2_replayer.h | 1+
Msrc/mixer/ft2_cubic_spline.c | 52++++++++++++++++++++--------------------------------
Msrc/mixer/ft2_cubic_spline.h | 23+++++++++--------------
Msrc/mixer/ft2_mix.c | 809+++++++++++++++++++++++++++++--------------------------------------------------
Msrc/mixer/ft2_mix.h | 12++++++------
Msrc/mixer/ft2_mix_macros.h | 106++++++++++++++++++++++++++++++++++---------------------------------------------
Asrc/mixer/ft2_quadratic_spline.c | 45+++++++++++++++++++++++++++++++++++++++++++++
Asrc/mixer/ft2_quadratic_spline.h | 15+++++++++++++++
Msrc/scopes/ft2_scope_macros.h | 60++++++++++++++++++++++++++++++++++++------------------------
Msrc/scopes/ft2_scopedraw.c | 32+++++++++++++-------------------
Msrc/scopes/ft2_scopes.c | 4++--
Msrc/scopes/ft2_scopes.h | 6++++--
Mvs2019_project/ft2-clone/ft2-clone.vcxproj | 2++
Mvs2019_project/ft2-clone/ft2-clone.vcxproj.filters | 6++++++
22 files changed, 523 insertions(+), 700 deletions(-)

diff --git a/src/ft2_audio.c b/src/ft2_audio.c @@ -367,11 +367,8 @@ void updateVoices(void) if (status & IS_Vol) { - v->fVolume = ch->fFinalVol; - - // set scope volume (scaled) - const int32_t scopeVolume = (int32_t)((ch->fFinalVol * (SCOPE_HEIGHT*(1<<2))) + 0.5f); // rounded - v->scopeVolume = (uint8_t)scopeVolume; + v->fVolume = ch->fFinalVol; // 0.0f .. 1.0f + v->scopeVolume = (uint8_t)((ch->fFinalVol * 255.0f) + 0.5f); // 0..255, rounded } if (status & IS_Pan) diff --git a/src/ft2_audio.h b/src/ft2_audio.h @@ -61,7 +61,7 @@ typedef struct const int8_t *base8, *revBase8; const int16_t *base16, *revBase16; bool active, samplingBackwards, isFadeOutVoice, hasLooped; - uint8_t mixFuncOffset, panning, loopType, scopeVolume; + uint8_t scopeVolume, mixFuncOffset, panning, loopType; int32_t position, sampleEnd, loopStart, loopLength; uint32_t volumeRampLength; uint64_t positionFrac, delta, scopeDelta; diff --git a/src/ft2_config.c b/src/ft2_config.c @@ -835,10 +835,10 @@ void setConfigAudioRadioButtonStates(void) // accessed by other .c files tmpID = RB_CONFIG_AUDIO_INTRP_LINEAR; else if (config.interpolation == INTERPOLATION_SINC16) tmpID = RB_CONFIG_AUDIO_INTRP_SINC16; - else if (config.interpolation == INTERPOLATION_CUBIC4) - tmpID = RB_CONFIG_AUDIO_INTRP_CUBIC4; - else if (config.interpolation == INTERPOLATION_CUBIC6) - tmpID = RB_CONFIG_AUDIO_INTRP_CUBIC6; + else if (config.interpolation == INTERPOLATION_CUBIC) + tmpID = RB_CONFIG_AUDIO_INTRP_CUBIC; + else if (config.interpolation == INTERPOLATION_QUADRATIC) + tmpID = RB_CONFIG_AUDIO_INTRP_QUADRATIC; else tmpID = RB_CONFIG_AUDIO_INTRP_SINC8; // default case @@ -1173,8 +1173,8 @@ void showConfigScreen(void) textOutShadow(405, 91, PAL_FORGRND, PAL_DSKTOP2, "No interpolation"); textOutShadow(405, 105, PAL_FORGRND, PAL_DSKTOP2, "Linear (FT2)"); - textOutShadow(405, 119, PAL_FORGRND, PAL_DSKTOP2, "Cubic (4 point)"); - textOutShadow(405, 133, PAL_FORGRND, PAL_DSKTOP2, "Cubic (6 point)"); + textOutShadow(405, 119, PAL_FORGRND, PAL_DSKTOP2, "Quadratic spline"); + textOutShadow(405, 133, PAL_FORGRND, PAL_DSKTOP2, "Cubic spline"); textOutShadow(405, 147, PAL_FORGRND, PAL_DSKTOP2, "Sinc (8 point)"); textOutShadow(405, 161, PAL_FORGRND, PAL_DSKTOP2, "Sinc (16 point)"); @@ -1629,18 +1629,18 @@ void rbConfigAudioIntrpLinear(void) audioSetInterpolationType(config.interpolation); checkRadioButton(RB_CONFIG_AUDIO_INTRP_LINEAR); } -void rbConfigAudioIntrpCubic4(void) +void rbConfigAudioIntrpCubic(void) { - config.interpolation = INTERPOLATION_CUBIC4; + config.interpolation = INTERPOLATION_CUBIC; audioSetInterpolationType(config.interpolation); - checkRadioButton(RB_CONFIG_AUDIO_INTRP_CUBIC4); + checkRadioButton(RB_CONFIG_AUDIO_INTRP_CUBIC); } -void rbConfigAudioIntrpCubic6(void) +void rbConfigAudioIntrpQuadratic(void) { - config.interpolation = INTERPOLATION_CUBIC6; + config.interpolation = INTERPOLATION_QUADRATIC; audioSetInterpolationType(config.interpolation); - checkRadioButton(RB_CONFIG_AUDIO_INTRP_CUBIC6); + checkRadioButton(RB_CONFIG_AUDIO_INTRP_QUADRATIC); } void rbConfigAudioIntrpSinc8(void) diff --git a/src/ft2_config.h b/src/ft2_config.h @@ -205,8 +205,8 @@ void rbConfigAudio16Bit(void); void rbConfigAudio32BitFloat(void); void rbConfigAudioIntrpDisabled(void); void rbConfigAudioIntrpLinear(void); -void rbConfigAudioIntrpCubic4(void); -void rbConfigAudioIntrpCubic6(void); +void rbConfigAudioIntrpQuadratic(void); +void rbConfigAudioIntrpCubic(void); void rbConfigAudioIntrpSinc8(void); void rbConfigAudioIntrpSinc16(void); void rbConfigAudio44kHz(void); diff --git a/src/ft2_main.c b/src/ft2_main.c @@ -147,7 +147,7 @@ int main(int argc, char *argv[]) #ifdef __APPLE__ osxSetDirToProgramDirFromArgs(argv); #endif - if (!setupExecutablePath() || !loadBMPs() || !setupCubicSplineTables() || !setupWindowedSincTables()) + if (!setupExecutablePath() || !loadBMPs() || !setupQuadraticSplineTable() || !setupCubicSplineTable() || !setupWindowedSincTables()) { cleanUpAndExit(); return 1; diff --git a/src/ft2_radiobuttons.c b/src/ft2_radiobuttons.c @@ -88,8 +88,8 @@ radioButton_t radioButtons[NUM_RADIOBUTTONS] = //x, y, w, group, funcOnUp { 390, 90, 108, RB_GROUP_CONFIG_AUDIO_INTERPOLATION, rbConfigAudioIntrpDisabled }, { 390, 104, 90, RB_GROUP_CONFIG_AUDIO_INTERPOLATION, rbConfigAudioIntrpLinear }, - { 390, 118, 101, RB_GROUP_CONFIG_AUDIO_INTERPOLATION, rbConfigAudioIntrpCubic4 }, - { 390, 132, 101, RB_GROUP_CONFIG_AUDIO_INTERPOLATION, rbConfigAudioIntrpCubic6 }, + { 390, 118, 109, RB_GROUP_CONFIG_AUDIO_INTERPOLATION, rbConfigAudioIntrpQuadratic }, + { 390, 132, 85, RB_GROUP_CONFIG_AUDIO_INTERPOLATION, rbConfigAudioIntrpCubic }, { 390, 146, 94, RB_GROUP_CONFIG_AUDIO_INTERPOLATION, rbConfigAudioIntrpSinc8 }, { 390, 160, 101, RB_GROUP_CONFIG_AUDIO_INTERPOLATION, rbConfigAudioIntrpSinc16 }, diff --git a/src/ft2_radiobuttons.h b/src/ft2_radiobuttons.h @@ -57,8 +57,8 @@ enum // RADIOBUTTONS // AUDIO INTERPOLATION RB_CONFIG_AUDIO_INTRP_DISABLED, RB_CONFIG_AUDIO_INTRP_LINEAR, - RB_CONFIG_AUDIO_INTRP_CUBIC4, - RB_CONFIG_AUDIO_INTRP_CUBIC6, + RB_CONFIG_AUDIO_INTRP_QUADRATIC, + RB_CONFIG_AUDIO_INTRP_CUBIC, RB_CONFIG_AUDIO_INTRP_SINC8, RB_CONFIG_AUDIO_INTRP_SINC16, diff --git a/src/ft2_replayer.c b/src/ft2_replayer.c @@ -2789,7 +2789,8 @@ void closeReplayer(void) instr[131] = NULL; } - freeCubicSplineTables(); + freeQuadraticSplineTable(); + freeCubicSplineTable(); freeWindowedSincTables(); } diff --git a/src/ft2_replayer.h b/src/ft2_replayer.h @@ -3,6 +3,7 @@ #include <stdint.h> #include <stdbool.h> #include "ft2_unicode.h" +#include "mixer/ft2_quadratic_spline.h" #include "mixer/ft2_cubic_spline.h" #include "mixer/ft2_windowed_sinc.h" diff --git a/src/mixer/ft2_cubic_spline.c b/src/mixer/ft2_cubic_spline.c @@ -1,6 +1,4 @@ -/* -** Cubic Hermite spline (Catmull-Rom) interpolation LUT generator -*/ +// 4-point cubic Hermite spline (Catmull-Rom) interpolation LUT generator #include <stdint.h> #include <stdbool.h> @@ -8,33 +6,28 @@ #include "ft2_cubic_spline.h" #include "../ft2_video.h" // showErrorMsgBox() -float *f4PointCubicSplineLUT = NULL, *f6PointCubicSplineLUT = NULL; // globalized +float *fCubicSplineLUT = NULL; // globalized -bool setupCubicSplineTables(void) +bool setupCubicSplineTable(void) { - float *fPtr; - - f4PointCubicSplineLUT = (float *)malloc(4 * CUBIC4P_SPLINE_PHASES * sizeof (float)); - f6PointCubicSplineLUT = (float *)malloc(6 * CUBIC6P_SPLINE_PHASES * sizeof (float)); - - if (f4PointCubicSplineLUT == NULL || f6PointCubicSplineLUT == NULL) + fCubicSplineLUT = (float *)malloc(CUBIC_SPLINE_WIDTH * CUBIC_SPLINE_PHASES * sizeof (float)); + if (fCubicSplineLUT == NULL) { showErrorMsgBox("Not enough memory!"); return false; } - // 4-point Cubic Hermite (Catmull-Rom) - fPtr = f4PointCubicSplineLUT; - for (int32_t i = 0; i < CUBIC4P_SPLINE_PHASES; i++) + float *fPtr = fCubicSplineLUT; + for (int32_t i = 0; i < CUBIC_SPLINE_PHASES; i++) { - const double x1 = i * (1.0 / CUBIC4P_SPLINE_PHASES); + const double x1 = i * (1.0 / CUBIC_SPLINE_PHASES); const double x2 = x1 * x1; // x^2 const double x3 = x2 * x1; // x^3 - double t1 = (-(1.0/2.0) * x3) + ( ( 1.0) * x2) + (-(1.0/2.0) * x1); - double t2 = ( (3.0/2.0) * x3) + (-(5.0/2.0) * x2) + 1.0; - double t3 = (-(3.0/2.0) * x3) + ( ( 2.0) * x2) + ( (1.0/2.0) * x1); - double t4 = ( (1.0/2.0) * x3) + (-(1.0/2.0) * x2); + double t1 = (-0.5 * x3) + ( 1.0 * x2) + (-0.5 * x1); + double t2 = ( 1.5 * x3) + (-2.5 * x2) + 1.0; + double t3 = (-1.5 * x3) + ( 2.0 * x2) + ( 0.5 * x1); + double t4 = ( 0.5 * x3) + (-0.5 * x2); *fPtr++ = (float)t1; *fPtr++ = (float)t2; @@ -42,11 +35,11 @@ bool setupCubicSplineTables(void) *fPtr++ = (float)t4; } + /* // 6-point Cubic Hermite (Catmull-Rom) - fPtr = f6PointCubicSplineLUT; - for (int32_t i = 0; i < CUBIC6P_SPLINE_PHASES; i++) + for (int32_t i = 0; i < CUBIC_SPLINE_PHASES; i++) { - const double x1 = i * (1.0 / CUBIC6P_SPLINE_PHASES); + const double x1 = i * (1.0 / CUBIC_SPLINE_PHASES); const double x2 = x1 * x1; // x^2 const double x3 = x2 * x1; // x^3 @@ -64,21 +57,16 @@ bool setupCubicSplineTables(void) *fPtr++ = (float)t5; *fPtr++ = (float)t6; } + */ return true; } -void freeCubicSplineTables(void) +void freeCubicSplineTable(void) { - if (f4PointCubicSplineLUT != NULL) - { - free(f4PointCubicSplineLUT); - f4PointCubicSplineLUT = NULL; - } - - if (f6PointCubicSplineLUT != NULL) + if (fCubicSplineLUT != NULL) { - free(f6PointCubicSplineLUT); - f6PointCubicSplineLUT = NULL; + free(fCubicSplineLUT); + fCubicSplineLUT = NULL; } } diff --git a/src/mixer/ft2_cubic_spline.h b/src/mixer/ft2_cubic_spline.h @@ -4,19 +4,14 @@ #include <stdbool.h> #include "ft2_mix.h" // MIXER_FRAC_BITS -#define CUBIC4P_SPLINE_WIDTH 4 -#define CUBIC4P_SPLINE_WIDTH_BITS 2 /* log2(CUBIC4P_SPLINE_WIDTH */ -#define CUBIC4P_SPLINE_PHASES 8192 -#define CUBIC4P_SPLINE_PHASES_BITS 13 // log2(CUBIC4P_SPLINE_PHASES) -#define CUBIC4P_SPLINE_FRACSHIFT (MIXER_FRAC_BITS-(CUBIC4P_SPLINE_PHASES_BITS+CUBIC4P_SPLINE_WIDTH_BITS)) -#define CUBIC4P_SPLINE_FRACMASK ((CUBIC4P_SPLINE_WIDTH*CUBIC4P_SPLINE_PHASES)-CUBIC4P_SPLINE_WIDTH) +#define CUBIC_SPLINE_WIDTH 4 +#define CUBIC_SPLINE_WIDTH_BITS 2 /* log2(CUBIC_SPLINE_WIDTH) */ +#define CUBIC_SPLINE_PHASES 8192 +#define CUBIC_SPLINE_PHASES_BITS 13 // log2(CUBIC_SPLINE_PHASES) +#define CUBIC_SPLINE_FRACSHIFT (MIXER_FRAC_BITS-(CUBIC_SPLINE_PHASES_BITS+CUBIC_SPLINE_WIDTH_BITS)) +#define CUBIC_SPLINE_FRACMASK ((CUBIC_SPLINE_WIDTH*CUBIC_SPLINE_PHASES)-CUBIC_SPLINE_WIDTH) -#define CUBIC6P_SPLINE_WIDTH 6 -#define CUBIC6P_SPLINE_PHASES 8192 -#define CUBIC6P_SPLINE_PHASES_BITS 13 // log2(CUBIC6P_SPLINE_PHASES) -#define CUBIC6P_SPLINE_FRACSHIFT (MIXER_FRAC_BITS-CUBIC6P_SPLINE_PHASES_BITS) +extern float *fCubicSplineLUT; -extern float *f4PointCubicSplineLUT, *f6PointCubicSplineLUT; - -bool setupCubicSplineTables(void); -void freeCubicSplineTables(void); +bool setupCubicSplineTable(void); +void freeCubicSplineTable(void); diff --git a/src/mixer/ft2_mix.c b/src/mixer/ft2_mix.c @@ -9,7 +9,7 @@ ** (Note: Mixing macros can be found in ft2_mix_macros.h) ** ** Specifications: -** - Interpolation: None, 2-tap linear, 4-tap/6-tap cubic spline, 8-tap/16-tap windowed-sinc +** - Interpolation: None, 2-tap linear, 3-tap quadratic spline, 4-tap cubic spline, 8-tap/16-tap windowed-sinc ** - FT2-styled linear volume ramping (can be turned off) ** - 32.32 fixed-point precision for resampling delta/position ** - 32-bit floating-point precision for mixing and interpolation @@ -641,7 +641,7 @@ static void mix8bBidiLoopS16Intrp(voice_t *v, uint32_t bufferPos, uint32_t numSa SET_BACK_MIXER_POS } -static void mix8bNoLoopC4PIntrp(voice_t *v, uint32_t bufferPos, uint32_t numSamples) +static void mix8bNoLoopCIntrp(voice_t *v, uint32_t bufferPos, uint32_t numSamples) { const int8_t *base, *smpPtr; float fSample, *fMixBufferL, *fMixBufferR; @@ -661,19 +661,19 @@ static void mix8bNoLoopC4PIntrp(voice_t *v, uint32_t bufferPos, uint32_t numSamp for (i = 0; i < (samplesToMix & 3); i++) { - RENDER_8BIT_SMP_C4PINTRP + RENDER_8BIT_SMP_CINTRP INC_POS } samplesToMix >>= 2; for (i = 0; i < samplesToMix; i++) { - RENDER_8BIT_SMP_C4PINTRP + RENDER_8BIT_SMP_CINTRP INC_POS - RENDER_8BIT_SMP_C4PINTRP + RENDER_8BIT_SMP_CINTRP INC_POS - RENDER_8BIT_SMP_C4PINTRP + RENDER_8BIT_SMP_CINTRP INC_POS - RENDER_8BIT_SMP_C4PINTRP + RENDER_8BIT_SMP_CINTRP INC_POS } @@ -683,7 +683,7 @@ static void mix8bNoLoopC4PIntrp(voice_t *v, uint32_t bufferPos, uint32_t numSamp SET_BACK_MIXER_POS } -static void mix8bLoopC4PIntrp(voice_t *v, uint32_t bufferPos, uint32_t numSamples) +static void mix8bLoopCIntrp(voice_t *v, uint32_t bufferPos, uint32_t numSamples) { const int8_t *base, *smpPtr; int8_t *smpTapPtr; @@ -707,19 +707,19 @@ static void mix8bLoopC4PIntrp(voice_t *v, uint32_t bufferPos, uint32_t numSample { for (i = 0; i < (samplesToMix & 3); i++) { - RENDER_8BIT_SMP_C4PINTRP_TAP_FIX + RENDER_8BIT_SMP_CINTRP_TAP_FIX INC_POS } samplesToMix >>= 2; for (i = 0; i < samplesToMix; i++) { - RENDER_8BIT_SMP_C4PINTRP_TAP_FIX + RENDER_8BIT_SMP_CINTRP_TAP_FIX INC_POS - RENDER_8BIT_SMP_C4PINTRP_TAP_FIX + RENDER_8BIT_SMP_CINTRP_TAP_FIX INC_POS - RENDER_8BIT_SMP_C4PINTRP_TAP_FIX + RENDER_8BIT_SMP_CINTRP_TAP_FIX INC_POS - RENDER_8BIT_SMP_C4PINTRP_TAP_FIX + RENDER_8BIT_SMP_CINTRP_TAP_FIX INC_POS } } @@ -727,19 +727,19 @@ static void mix8bLoopC4PIntrp(voice_t *v, uint32_t bufferPos, uint32_t numSample { for (i = 0; i < (samplesToMix & 3); i++) { - RENDER_8BIT_SMP_C4PINTRP + RENDER_8BIT_SMP_CINTRP INC_POS } samplesToMix >>= 2; for (i = 0; i < samplesToMix; i++) { - RENDER_8BIT_SMP_C4PINTRP + RENDER_8BIT_SMP_CINTRP INC_POS - RENDER_8BIT_SMP_C4PINTRP + RENDER_8BIT_SMP_CINTRP INC_POS - RENDER_8BIT_SMP_C4PINTRP + RENDER_8BIT_SMP_CINTRP INC_POS - RENDER_8BIT_SMP_C4PINTRP + RENDER_8BIT_SMP_CINTRP INC_POS } } @@ -750,7 +750,7 @@ static void mix8bLoopC4PIntrp(voice_t *v, uint32_t bufferPos, uint32_t numSample SET_BACK_MIXER_POS } -static void mix8bBidiLoopC4PIntrp(voice_t *v, uint32_t bufferPos, uint32_t numSamples) +static void mix8bBidiLoopCIntrp(voice_t *v, uint32_t bufferPos, uint32_t numSamples) { const int8_t *base, *revBase, *smpPtr; int8_t *smpTapPtr; @@ -775,19 +775,19 @@ static void mix8bBidiLoopC4PIntrp(voice_t *v, uint32_t bufferPos, uint32_t numSa { for (i = 0; i < (samplesToMix & 3); i++) { - RENDER_8BIT_SMP_C4PINTRP_TAP_FIX + RENDER_8BIT_SMP_CINTRP_TAP_FIX INC_POS_BIDI } samplesToMix >>= 2; for (i = 0; i < samplesToMix; i++) { - RENDER_8BIT_SMP_C4PINTRP_TAP_FIX + RENDER_8BIT_SMP_CINTRP_TAP_FIX INC_POS_BIDI - RENDER_8BIT_SMP_C4PINTRP_TAP_FIX + RENDER_8BIT_SMP_CINTRP_TAP_FIX INC_POS_BIDI - RENDER_8BIT_SMP_C4PINTRP_TAP_FIX + RENDER_8BIT_SMP_CINTRP_TAP_FIX INC_POS_BIDI - RENDER_8BIT_SMP_C4PINTRP_TAP_FIX + RENDER_8BIT_SMP_CINTRP_TAP_FIX INC_POS_BIDI } } @@ -795,19 +795,19 @@ static void mix8bBidiLoopC4PIntrp(voice_t *v, uint32_t bufferPos, uint32_t numSa { for (i = 0; i < (samplesToMix & 3); i++) { - RENDER_8BIT_SMP_C4PINTRP + RENDER_8BIT_SMP_CINTRP INC_POS_BIDI } samplesToMix >>= 2; for (i = 0; i < samplesToMix; i++) { - RENDER_8BIT_SMP_C4PINTRP + RENDER_8BIT_SMP_CINTRP INC_POS_BIDI - RENDER_8BIT_SMP_C4PINTRP + RENDER_8BIT_SMP_CINTRP INC_POS_BIDI - RENDER_8BIT_SMP_C4PINTRP + RENDER_8BIT_SMP_CINTRP INC_POS_BIDI - RENDER_8BIT_SMP_C4PINTRP + RENDER_8BIT_SMP_CINTRP INC_POS_BIDI } } @@ -819,7 +819,7 @@ static void mix8bBidiLoopC4PIntrp(voice_t *v, uint32_t bufferPos, uint32_t numSa SET_BACK_MIXER_POS } -static void mix8bNoLoopC6PIntrp(voice_t *v, uint32_t bufferPos, uint32_t numSamples) +static void mix8bNoLoopQIntrp(voice_t *v, uint32_t bufferPos, uint32_t numSamples) { const int8_t *base, *smpPtr; float fSample, *fMixBufferL, *fMixBufferR; @@ -839,19 +839,19 @@ static void mix8bNoLoopC6PIntrp(voice_t *v, uint32_t bufferPos, uint32_t numSamp for (i = 0; i < (samplesToMix & 3); i++) { - RENDER_8BIT_SMP_C6PINTRP + RENDER_8BIT_SMP_QINTRP INC_POS } samplesToMix >>= 2; for (i = 0; i < samplesToMix; i++) { - RENDER_8BIT_SMP_C6PINTRP + RENDER_8BIT_SMP_QINTRP INC_POS - RENDER_8BIT_SMP_C6PINTRP + RENDER_8BIT_SMP_QINTRP INC_POS - RENDER_8BIT_SMP_C6PINTRP + RENDER_8BIT_SMP_QINTRP INC_POS - RENDER_8BIT_SMP_C6PINTRP + RENDER_8BIT_SMP_QINTRP INC_POS } @@ -861,10 +861,9 @@ static void mix8bNoLoopC6PIntrp(voice_t *v, uint32_t bufferPos, uint32_t numSamp SET_BACK_MIXER_POS } -static void mix8bLoopC6PIntrp(voice_t *v, uint32_t bufferPos, uint32_t numSamples) +static void mix8bLoopQIntrp(voice_t *v, uint32_t bufferPos, uint32_t numSamples) { const int8_t *base, *smpPtr; - int8_t *smpTapPtr; float fSample, *fMixBufferL, *fMixBufferR; int32_t position; uint32_t i, samplesToMix, samplesLeft; @@ -873,7 +872,6 @@ static void mix8bLoopC6PIntrp(voice_t *v, uint32_t bufferPos, uint32_t numSample GET_VOL GET_MIXER_VARS SET_BASE8 - PREPARE_TAP_FIX8 samplesLeft = numSamples; while (samplesLeft > 0) @@ -881,45 +879,22 @@ static void mix8bLoopC6PIntrp(voice_t *v, uint32_t bufferPos, uint32_t numSample LIMIT_MIX_NUM samplesLeft -= samplesToMix; - if (v->hasLooped) // the negative interpolation taps need a special case after the sample has looped once + for (i = 0; i < (samplesToMix & 3); i++) { - for (i = 0; i < (samplesToMix & 3); i++) - { - RENDER_8BIT_SMP_C6PINTRP_TAP_FIX - INC_POS - } - samplesToMix >>= 2; - for (i = 0; i < samplesToMix; i++) - { - RENDER_8BIT_SMP_C6PINTRP_TAP_FIX - INC_POS - RENDER_8BIT_SMP_C6PINTRP_TAP_FIX - INC_POS - RENDER_8BIT_SMP_C6PINTRP_TAP_FIX - INC_POS - RENDER_8BIT_SMP_C6PINTRP_TAP_FIX - INC_POS - } + RENDER_8BIT_SMP_QINTRP + INC_POS } - else + samplesToMix >>= 2; + for (i = 0; i < samplesToMix; i++) { - for (i = 0; i < (samplesToMix & 3); i++) - { - RENDER_8BIT_SMP_C6PINTRP - INC_POS - } - samplesToMix >>= 2; - for (i = 0; i < samplesToMix; i++) - { - RENDER_8BIT_SMP_C6PINTRP - INC_POS - RENDER_8BIT_SMP_C6PINTRP - INC_POS - RENDER_8BIT_SMP_C6PINTRP - INC_POS - RENDER_8BIT_SMP_C6PINTRP - INC_POS - } + RENDER_8BIT_SMP_QINTRP + INC_POS + RENDER_8BIT_SMP_QINTRP + INC_POS + RENDER_8BIT_SMP_QINTRP + INC_POS + RENDER_8BIT_SMP_QINTRP + INC_POS } WRAP_LOOP @@ -928,10 +903,9 @@ static void mix8bLoopC6PIntrp(voice_t *v, uint32_t bufferPos, uint32_t numSample SET_BACK_MIXER_POS } -static void mix8bBidiLoopC6PIntrp(voice_t *v, uint32_t bufferPos, uint32_t numSamples) +static void mix8bBidiLoopQIntrp(voice_t *v, uint32_t bufferPos, uint32_t numSamples) { const int8_t *base, *revBase, *smpPtr; - int8_t *smpTapPtr; float fSample, *fMixBufferL, *fMixBufferR; int32_t position; uint32_t i, samplesToMix, samplesLeft; @@ -940,7 +914,6 @@ static void mix8bBidiLoopC6PIntrp(voice_t *v, uint32_t bufferPos, uint32_t numSa GET_VOL GET_MIXER_VARS SET_BASE8_BIDI - PREPARE_TAP_FIX8 samplesLeft = numSamples; while (samplesLeft > 0) @@ -949,45 +922,22 @@ static void mix8bBidiLoopC6PIntrp(voice_t *v, uint32_t bufferPos, uint32_t numSa samplesLeft -= samplesToMix; START_BIDI - if (v->hasLooped) // the negative interpolation taps need a special case after the sample has looped once + for (i = 0; i < (samplesToMix & 3); i++) { - for (i = 0; i < (samplesToMix & 3); i++) - { - RENDER_8BIT_SMP_C6PINTRP_TAP_FIX - INC_POS_BIDI - } - samplesToMix >>= 2; - for (i = 0; i < samplesToMix; i++) - { - RENDER_8BIT_SMP_C6PINTRP_TAP_FIX - INC_POS_BIDI - RENDER_8BIT_SMP_C6PINTRP_TAP_FIX - INC_POS_BIDI - RENDER_8BIT_SMP_C6PINTRP_TAP_FIX - INC_POS_BIDI - RENDER_8BIT_SMP_C6PINTRP_TAP_FIX - INC_POS_BIDI - } + RENDER_8BIT_SMP_QINTRP + INC_POS_BIDI } - else + samplesToMix >>= 2; + for (i = 0; i < samplesToMix; i++) { - for (i = 0; i < (samplesToMix & 3); i++) - { - RENDER_8BIT_SMP_C6PINTRP - INC_POS_BIDI - } - samplesToMix >>= 2; - for (i = 0; i < samplesToMix; i++) - { - RENDER_8BIT_SMP_C6PINTRP - INC_POS_BIDI - RENDER_8BIT_SMP_C6PINTRP - INC_POS_BIDI - RENDER_8BIT_SMP_C6PINTRP - INC_POS_BIDI - RENDER_8BIT_SMP_C6PINTRP - INC_POS_BIDI - } + RENDER_8BIT_SMP_QINTRP + INC_POS_BIDI + RENDER_8BIT_SMP_QINTRP + INC_POS_BIDI + RENDER_8BIT_SMP_QINTRP + INC_POS_BIDI + RENDER_8BIT_SMP_QINTRP + INC_POS_BIDI } END_BIDI @@ -1726,7 +1676,7 @@ static void mix8bRampBidiLoopS16Intrp(voice_t *v, uint32_t bufferPos, uint32_t n SET_BACK_MIXER_POS } -static void mix8bRampNoLoopC4PIntrp(voice_t *v, uint32_t bufferPos, uint32_t numSamples) +static void mix8bRampNoLoopCIntrp(voice_t *v, uint32_t bufferPos, uint32_t numSamples) { const int8_t *base, *smpPtr; float fSample, *fMixBufferL, *fMixBufferR; @@ -1748,23 +1698,23 @@ static void mix8bRampNoLoopC4PIntrp(voice_t *v, uint32_t bufferPos, uint32_t num for (i = 0; i < (samplesToMix & 3); i++) { - RENDER_8BIT_SMP_C4PINTRP + RENDER_8BIT_SMP_CINTRP VOLUME_RAMPING INC_POS } samplesToMix >>= 2; for (i = 0; i < samplesToMix; i++) { - RENDER_8BIT_SMP_C4PINTRP + RENDER_8BIT_SMP_CINTRP VOLUME_RAMPING INC_POS - RENDER_8BIT_SMP_C4PINTRP + RENDER_8BIT_SMP_CINTRP VOLUME_RAMPING INC_POS - RENDER_8BIT_SMP_C4PINTRP + RENDER_8BIT_SMP_CINTRP VOLUME_RAMPING INC_POS - RENDER_8BIT_SMP_C4PINTRP + RENDER_8BIT_SMP_CINTRP VOLUME_RAMPING INC_POS } @@ -1776,7 +1726,7 @@ static void mix8bRampNoLoopC4PIntrp(voice_t *v, uint32_t bufferPos, uint32_t num SET_BACK_MIXER_POS } -static void mix8bRampLoopC4PIntrp(voice_t *v, uint32_t bufferPos, uint32_t numSamples) +static void mix8bRampLoopCIntrp(voice_t *v, uint32_t bufferPos, uint32_t numSamples) { const int8_t *base, *smpPtr; int8_t *smpTapPtr; @@ -1802,23 +1752,23 @@ static void mix8bRampLoopC4PIntrp(voice_t *v, uint32_t bufferPos, uint32_t numSa { for (i = 0; i < (samplesToMix & 3); i++) { - RENDER_8BIT_SMP_C4PINTRP_TAP_FIX + RENDER_8BIT_SMP_CINTRP_TAP_FIX VOLUME_RAMPING INC_POS } samplesToMix >>= 2; for (i = 0; i < samplesToMix; i++) { - RENDER_8BIT_SMP_C4PINTRP_TAP_FIX + RENDER_8BIT_SMP_CINTRP_TAP_FIX VOLUME_RAMPING INC_POS - RENDER_8BIT_SMP_C4PINTRP_TAP_FIX + RENDER_8BIT_SMP_CINTRP_TAP_FIX VOLUME_RAMPING INC_POS - RENDER_8BIT_SMP_C4PINTRP_TAP_FIX + RENDER_8BIT_SMP_CINTRP_TAP_FIX VOLUME_RAMPING INC_POS - RENDER_8BIT_SMP_C4PINTRP_TAP_FIX + RENDER_8BIT_SMP_CINTRP_TAP_FIX VOLUME_RAMPING INC_POS } @@ -1827,23 +1777,23 @@ static void mix8bRampLoopC4PIntrp(voice_t *v, uint32_t bufferPos, uint32_t numSa { for (i = 0; i < (samplesToMix & 3); i++) { - RENDER_8BIT_SMP_C4PINTRP + RENDER_8BIT_SMP_CINTRP VOLUME_RAMPING INC_POS } samplesToMix >>= 2; for (i = 0; i < samplesToMix; i++) { - RENDER_8BIT_SMP_C4PINTRP + RENDER_8BIT_SMP_CINTRP VOLUME_RAMPING INC_POS - RENDER_8BIT_SMP_C4PINTRP + RENDER_8BIT_SMP_CINTRP VOLUME_RAMPING INC_POS - RENDER_8BIT_SMP_C4PINTRP + RENDER_8BIT_SMP_CINTRP VOLUME_RAMPING INC_POS - RENDER_8BIT_SMP_C4PINTRP + RENDER_8BIT_SMP_CINTRP VOLUME_RAMPING INC_POS } @@ -1856,7 +1806,7 @@ static void mix8bRampLoopC4PIntrp(voice_t *v, uint32_t bufferPos, uint32_t numSa SET_BACK_MIXER_POS } -static void mix8bRampBidiLoopC4PIntrp(voice_t *v, uint32_t bufferPos, uint32_t numSamples) +static void mix8bRampBidiLoopCIntrp(voice_t *v, uint32_t bufferPos, uint32_t numSamples) { const int8_t *base, *revBase, *smpPtr; int8_t *smpTapPtr; @@ -1883,23 +1833,23 @@ static void mix8bRampBidiLoopC4PIntrp(voice_t *v, uint32_t bufferPos, uint32_t n { for (i = 0; i < (samplesToMix & 3); i++) { - RENDER_8BIT_SMP_C4PINTRP_TAP_FIX + RENDER_8BIT_SMP_CINTRP_TAP_FIX VOLUME_RAMPING INC_POS_BIDI } samplesToMix >>= 2; for (i = 0; i < samplesToMix; i++) { - RENDER_8BIT_SMP_C4PINTRP_TAP_FIX + RENDER_8BIT_SMP_CINTRP_TAP_FIX VOLUME_RAMPING INC_POS_BIDI - RENDER_8BIT_SMP_C4PINTRP_TAP_FIX + RENDER_8BIT_SMP_CINTRP_TAP_FIX VOLUME_RAMPING INC_POS_BIDI - RENDER_8BIT_SMP_C4PINTRP_TAP_FIX + RENDER_8BIT_SMP_CINTRP_TAP_FIX VOLUME_RAMPING INC_POS_BIDI - RENDER_8BIT_SMP_C4PINTRP_TAP_FIX + RENDER_8BIT_SMP_CINTRP_TAP_FIX VOLUME_RAMPING INC_POS_BIDI } @@ -1908,23 +1858,23 @@ static void mix8bRampBidiLoopC4PIntrp(voice_t *v, uint32_t bufferPos, uint32_t n { for (i = 0; i < (samplesToMix & 3); i++) { - RENDER_8BIT_SMP_C4PINTRP + RENDER_8BIT_SMP_CINTRP VOLUME_RAMPING INC_POS_BIDI } samplesToMix >>= 2; for (i = 0; i < samplesToMix; i++) { - RENDER_8BIT_SMP_C4PINTRP + RENDER_8BIT_SMP_CINTRP VOLUME_RAMPING INC_POS_BIDI - RENDER_8BIT_SMP_C4PINTRP + RENDER_8BIT_SMP_CINTRP VOLUME_RAMPING INC_POS_BIDI - RENDER_8BIT_SMP_C4PINTRP + RENDER_8BIT_SMP_CINTRP VOLUME_RAMPING INC_POS_BIDI - RENDER_8BIT_SMP_C4PINTRP + RENDER_8BIT_SMP_CINTRP VOLUME_RAMPING INC_POS_BIDI } @@ -1938,7 +1888,7 @@ static void mix8bRampBidiLoopC4PIntrp(voice_t *v, uint32_t bufferPos, uint32_t n SET_BACK_MIXER_POS } -static void mix8bRampNoLoopC6PIntrp(voice_t *v, uint32_t bufferPos, uint32_t numSamples) +static void mix8bRampNoLoopQIntrp(voice_t *v, uint32_t bufferPos, uint32_t numSamples) { const int8_t *base, *smpPtr; float fSample, *fMixBufferL, *fMixBufferR; @@ -1960,23 +1910,23 @@ static void mix8bRampNoLoopC6PIntrp(voice_t *v, uint32_t bufferPos, uint32_t num for (i = 0; i < (samplesToMix & 3); i++) { - RENDER_8BIT_SMP_C6PINTRP + RENDER_8BIT_SMP_QINTRP VOLUME_RAMPING INC_POS } samplesToMix >>= 2; for (i = 0; i < samplesToMix; i++) { - RENDER_8BIT_SMP_C6PINTRP + RENDER_8BIT_SMP_QINTRP VOLUME_RAMPING INC_POS - RENDER_8BIT_SMP_C6PINTRP + RENDER_8BIT_SMP_QINTRP VOLUME_RAMPING INC_POS - RENDER_8BIT_SMP_C6PINTRP + RENDER_8BIT_SMP_QINTRP VOLUME_RAMPING INC_POS - RENDER_8BIT_SMP_C6PINTRP + RENDER_8BIT_SMP_QINTRP VOLUME_RAMPING INC_POS } @@ -1988,10 +1938,9 @@ static void mix8bRampNoLoopC6PIntrp(voice_t *v, uint32_t bufferPos, uint32_t num SET_BACK_MIXER_POS } -static void mix8bRampLoopC6PIntrp(voice_t *v, uint32_t bufferPos, uint32_t numSamples) +static void mix8bRampLoopQIntrp(voice_t *v, uint32_t bufferPos, uint32_t numSamples) { const int8_t *base, *smpPtr; - int8_t *smpTapPtr; float fSample, *fMixBufferL, *fMixBufferR; int32_t position; float fVolumeLDelta, fVolumeRDelta, fVolumeL, fVolumeR; @@ -2001,7 +1950,6 @@ static void mix8bRampLoopC6PIntrp(voice_t *v, uint32_t bufferPos, uint32_t numSa GET_VOL_RAMP GET_MIXER_VARS_RAMP SET_BASE8 - PREPARE_TAP_FIX8 samplesLeft = numSamples; while (samplesLeft > 0) @@ -2010,55 +1958,27 @@ static void mix8bRampLoopC6PIntrp(voice_t *v, uint32_t bufferPos, uint32_t numSa LIMIT_MIX_NUM_RAMP samplesLeft -= samplesToMix; - if (v->hasLooped) // the negative interpolation taps need a special case after the sample has looped once + for (i = 0; i < (samplesToMix & 3); i++) { - for (i = 0; i < (samplesToMix & 3); i++) - { - RENDER_8BIT_SMP_C6PINTRP_TAP_FIX - VOLUME_RAMPING - INC_POS - } - samplesToMix >>= 2; - for (i = 0; i < samplesToMix; i++) - { - RENDER_8BIT_SMP_C6PINTRP_TAP_FIX - VOLUME_RAMPING - INC_POS - RENDER_8BIT_SMP_C6PINTRP_TAP_FIX - VOLUME_RAMPING - INC_POS - RENDER_8BIT_SMP_C6PINTRP_TAP_FIX - VOLUME_RAMPING - INC_POS - RENDER_8BIT_SMP_C6PINTRP_TAP_FIX - VOLUME_RAMPING - INC_POS - } + RENDER_8BIT_SMP_QINTRP + VOLUME_RAMPING + INC_POS } - else + samplesToMix >>= 2; + for (i = 0; i < samplesToMix; i++) { - for (i = 0; i < (samplesToMix & 3); i++) - { - RENDER_8BIT_SMP_C6PINTRP - VOLUME_RAMPING - INC_POS - } - samplesToMix >>= 2; - for (i = 0; i < samplesToMix; i++) - { - RENDER_8BIT_SMP_C6PINTRP - VOLUME_RAMPING - INC_POS - RENDER_8BIT_SMP_C6PINTRP - VOLUME_RAMPING - INC_POS - RENDER_8BIT_SMP_C6PINTRP - VOLUME_RAMPING - INC_POS - RENDER_8BIT_SMP_C6PINTRP - VOLUME_RAMPING - INC_POS - } + RENDER_8BIT_SMP_QINTRP + VOLUME_RAMPING + INC_POS + RENDER_8BIT_SMP_QINTRP + VOLUME_RAMPING + INC_POS + RENDER_8BIT_SMP_QINTRP + VOLUME_RAMPING + INC_POS + RENDER_8BIT_SMP_QINTRP + VOLUME_RAMPING + INC_POS } WRAP_LOOP @@ -2068,10 +1988,9 @@ static void mix8bRampLoopC6PIntrp(voice_t *v, uint32_t bufferPos, uint32_t numSa SET_BACK_MIXER_POS } -static void mix8bRampBidiLoopC6PIntrp(voice_t *v, uint32_t bufferPos, uint32_t numSamples) +static void mix8bRampBidiLoopQIntrp(voice_t *v, uint32_t bufferPos, uint32_t numSamples) { const int8_t *base, *revBase, *smpPtr; - int8_t *smpTapPtr; float fSample, *fMixBufferL, *fMixBufferR; int32_t position; float fVolumeLDelta, fVolumeRDelta, fVolumeL, fVolumeR; @@ -2081,7 +2000,6 @@ static void mix8bRampBidiLoopC6PIntrp(voice_t *v, uint32_t bufferPos, uint32_t n GET_VOL_RAMP GET_MIXER_VARS_RAMP SET_BASE8_BIDI - PREPARE_TAP_FIX8 samplesLeft = numSamples; while (samplesLeft > 0) @@ -2091,55 +2009,27 @@ static void mix8bRampBidiLoopC6PIntrp(voice_t *v, uint32_t bufferPos, uint32_t n samplesLeft -= samplesToMix; START_BIDI - if (v->hasLooped) // the negative interpolation taps need a special case after the sample has looped once + for (i = 0; i < (samplesToMix & 3); i++) { - for (i = 0; i < (samplesToMix & 3); i++) - { - RENDER_8BIT_SMP_C6PINTRP_TAP_FIX - VOLUME_RAMPING - INC_POS_BIDI - } - samplesToMix >>= 2; - for (i = 0; i < samplesToMix; i++) - { - RENDER_8BIT_SMP_C6PINTRP_TAP_FIX - VOLUME_RAMPING - INC_POS_BIDI - RENDER_8BIT_SMP_C6PINTRP_TAP_FIX - VOLUME_RAMPING - INC_POS_BIDI - RENDER_8BIT_SMP_C6PINTRP_TAP_FIX - VOLUME_RAMPING - INC_POS_BIDI - RENDER_8BIT_SMP_C6PINTRP_TAP_FIX - VOLUME_RAMPING - INC_POS_BIDI - } + RENDER_8BIT_SMP_QINTRP + VOLUME_RAMPING + INC_POS_BIDI } - else + samplesToMix >>= 2; + for (i = 0; i < samplesToMix; i++) { - for (i = 0; i < (samplesToMix & 3); i++) - { - RENDER_8BIT_SMP_C6PINTRP - VOLUME_RAMPING - INC_POS_BIDI - } - samplesToMix >>= 2; - for (i = 0; i < samplesToMix; i++) - { - RENDER_8BIT_SMP_C6PINTRP - VOLUME_RAMPING - INC_POS_BIDI - RENDER_8BIT_SMP_C6PINTRP - VOLUME_RAMPING - INC_POS_BIDI - RENDER_8BIT_SMP_C6PINTRP - VOLUME_RAMPING - INC_POS_BIDI - RENDER_8BIT_SMP_C6PINTRP - VOLUME_RAMPING - INC_POS_BIDI - } + RENDER_8BIT_SMP_QINTRP + VOLUME_RAMPING + INC_POS_BIDI + RENDER_8BIT_SMP_QINTRP + VOLUME_RAMPING + INC_POS_BIDI + RENDER_8BIT_SMP_QINTRP + VOLUME_RAMPING + INC_POS_BIDI + RENDER_8BIT_SMP_QINTRP + VOLUME_RAMPING + INC_POS_BIDI } END_BIDI @@ -2766,7 +2656,7 @@ static void mix16bBidiLoopS16Intrp(voice_t *v, uint32_t bufferPos, uint32_t numS SET_BACK_MIXER_POS } -static void mix16bNoLoopC4PIntrp(voice_t *v, uint32_t bufferPos, uint32_t numSamples) +static void mix16bNoLoopCIntrp(voice_t *v, uint32_t bufferPos, uint32_t numSamples) { const int16_t *base, *smpPtr; float fSample, *fMixBufferL, *fMixBufferR; @@ -2786,19 +2676,19 @@ static void mix16bNoLoopC4PIntrp(voice_t *v, uint32_t bufferPos, uint32_t numSam for (i = 0; i < (samplesToMix & 3); i++) { - RENDER_16BIT_SMP_C4PINTRP + RENDER_16BIT_SMP_CINTRP INC_POS } samplesToMix >>= 2; for (i = 0; i < samplesToMix; i++) { - RENDER_16BIT_SMP_C4PINTRP + RENDER_16BIT_SMP_CINTRP INC_POS - RENDER_16BIT_SMP_C4PINTRP + RENDER_16BIT_SMP_CINTRP INC_POS - RENDER_16BIT_SMP_C4PINTRP + RENDER_16BIT_SMP_CINTRP INC_POS - RENDER_16BIT_SMP_C4PINTRP + RENDER_16BIT_SMP_CINTRP INC_POS } @@ -2808,7 +2698,7 @@ static void mix16bNoLoopC4PIntrp(voice_t *v, uint32_t bufferPos, uint32_t numSam SET_BACK_MIXER_POS } -static void mix16bLoopC4PIntrp(voice_t *v, uint32_t bufferPos, uint32_t numSamples) +static void mix16bLoopCIntrp(voice_t *v, uint32_t bufferPos, uint32_t numSamples) { const int16_t *base, *smpPtr; int16_t *smpTapPtr; @@ -2832,19 +2722,19 @@ static void mix16bLoopC4PIntrp(voice_t *v, uint32_t bufferPos, uint32_t numSampl { for (i = 0; i < (samplesToMix & 3); i++) { - RENDER_16BIT_SMP_C4PINTRP_TAP_FIX + RENDER_16BIT_SMP_CINTRP_TAP_FIX INC_POS } samplesToMix >>= 2; for (i = 0; i < samplesToMix; i++) { - RENDER_16BIT_SMP_C4PINTRP_TAP_FIX + RENDER_16BIT_SMP_CINTRP_TAP_FIX INC_POS - RENDER_16BIT_SMP_C4PINTRP_TAP_FIX + RENDER_16BIT_SMP_CINTRP_TAP_FIX INC_POS - RENDER_16BIT_SMP_C4PINTRP_TAP_FIX + RENDER_16BIT_SMP_CINTRP_TAP_FIX INC_POS - RENDER_16BIT_SMP_C4PINTRP_TAP_FIX + RENDER_16BIT_SMP_CINTRP_TAP_FIX INC_POS } } @@ -2852,19 +2742,19 @@ static void mix16bLoopC4PIntrp(voice_t *v, uint32_t bufferPos, uint32_t numSampl { for (i = 0; i < (samplesToMix & 3); i++) { - RENDER_16BIT_SMP_C4PINTRP + RENDER_16BIT_SMP_CINTRP INC_POS } samplesToMix >>= 2; for (i = 0; i < samplesToMix; i++) { - RENDER_16BIT_SMP_C4PINTRP + RENDER_16BIT_SMP_CINTRP INC_POS - RENDER_16BIT_SMP_C4PINTRP + RENDER_16BIT_SMP_CINTRP INC_POS - RENDER_16BIT_SMP_C4PINTRP + RENDER_16BIT_SMP_CINTRP INC_POS - RENDER_16BIT_SMP_C4PINTRP + RENDER_16BIT_SMP_CINTRP INC_POS } } @@ -2875,7 +2765,7 @@ static void mix16bLoopC4PIntrp(voice_t *v, uint32_t bufferPos, uint32_t numSampl SET_BACK_MIXER_POS } -static void mix16bBidiLoopC4PIntrp(voice_t *v, uint32_t bufferPos, uint32_t numSamples) +static void mix16bBidiLoopCIntrp(voice_t *v, uint32_t bufferPos, uint32_t numSamples) { const int16_t *base, *revBase, *smpPtr; int16_t *smpTapPtr; @@ -2900,19 +2790,19 @@ static void mix16bBidiLoopC4PIntrp(voice_t *v, uint32_t bufferPos, uint32_t numS { for (i = 0; i < (samplesToMix & 3); i++) { - RENDER_16BIT_SMP_C4PINTRP_TAP_FIX + RENDER_16BIT_SMP_CINTRP_TAP_FIX INC_POS_BIDI } samplesToMix >>= 2; for (i = 0; i < samplesToMix; i++) { - RENDER_16BIT_SMP_C4PINTRP_TAP_FIX + RENDER_16BIT_SMP_CINTRP_TAP_FIX INC_POS_BIDI - RENDER_16BIT_SMP_C4PINTRP_TAP_FIX + RENDER_16BIT_SMP_CINTRP_TAP_FIX INC_POS_BIDI - RENDER_16BIT_SMP_C4PINTRP_TAP_FIX + RENDER_16BIT_SMP_CINTRP_TAP_FIX INC_POS_BIDI - RENDER_16BIT_SMP_C4PINTRP_TAP_FIX + RENDER_16BIT_SMP_CINTRP_TAP_FIX INC_POS_BIDI } } @@ -2920,19 +2810,19 @@ static void mix16bBidiLoopC4PIntrp(voice_t *v, uint32_t bufferPos, uint32_t numS { for (i = 0; i < (samplesToMix & 3); i++) { - RENDER_16BIT_SMP_C4PINTRP + RENDER_16BIT_SMP_CINTRP INC_POS_BIDI } samplesToMix >>= 2; for (i = 0; i < samplesToMix; i++) { - RENDER_16BIT_SMP_C4PINTRP + RENDER_16BIT_SMP_CINTRP INC_POS_BIDI - RENDER_16BIT_SMP_C4PINTRP + RENDER_16BIT_SMP_CINTRP INC_POS_BIDI - RENDER_16BIT_SMP_C4PINTRP + RENDER_16BIT_SMP_CINTRP INC_POS_BIDI - RENDER_16BIT_SMP_C4PINTRP + RENDER_16BIT_SMP_CINTRP INC_POS_BIDI } } @@ -2944,7 +2834,7 @@ static void mix16bBidiLoopC4PIntrp(voice_t *v, uint32_t bufferPos, uint32_t numS SET_BACK_MIXER_POS } -static void mix16bNoLoopC6PIntrp(voice_t *v, uint32_t bufferPos, uint32_t numSamples) +static void mix16bNoLoopQIntrp(voice_t *v, uint32_t bufferPos, uint32_t numSamples) { const int16_t *base, *smpPtr; float fSample, *fMixBufferL, *fMixBufferR; @@ -2964,19 +2854,19 @@ static void mix16bNoLoopC6PIntrp(voice_t *v, uint32_t bufferPos, uint32_t numSam for (i = 0; i < (samplesToMix & 3); i++) { - RENDER_16BIT_SMP_C6PINTRP + RENDER_16BIT_SMP_QINTRP INC_POS } samplesToMix >>= 2; for (i = 0; i < samplesToMix; i++) { - RENDER_16BIT_SMP_C6PINTRP + RENDER_16BIT_SMP_QINTRP INC_POS - RENDER_16BIT_SMP_C6PINTRP + RENDER_16BIT_SMP_QINTRP INC_POS - RENDER_16BIT_SMP_C6PINTRP + RENDER_16BIT_SMP_QINTRP INC_POS - RENDER_16BIT_SMP_C6PINTRP + RENDER_16BIT_SMP_QINTRP INC_POS } @@ -2986,10 +2876,9 @@ static void mix16bNoLoopC6PIntrp(voice_t *v, uint32_t bufferPos, uint32_t numSam SET_BACK_MIXER_POS } -static void mix16bLoopC6PIntrp(voice_t *v, uint32_t bufferPos, uint32_t numSamples) +static void mix16bLoopQIntrp(voice_t *v, uint32_t bufferPos, uint32_t numSamples) { const int16_t *base, *smpPtr; - int16_t *smpTapPtr; float fSample, *fMixBufferL, *fMixBufferR; int32_t position; uint32_t i, samplesToMix, samplesLeft; @@ -2998,7 +2887,6 @@ static void mix16bLoopC6PIntrp(voice_t *v, uint32_t bufferPos, uint32_t numSampl GET_VOL GET_MIXER_VARS SET_BASE16 - PREPARE_TAP_FIX16 samplesLeft = numSamples; while (samplesLeft > 0) @@ -3006,57 +2894,33 @@ static void mix16bLoopC6PIntrp(voice_t *v, uint32_t bufferPos, uint32_t numSampl LIMIT_MIX_NUM samplesLeft -= samplesToMix; - if (v->hasLooped) // the negative interpolation taps need a special case after the sample has looped once + for (i = 0; i < (samplesToMix & 3); i++) { - for (i = 0; i < (samplesToMix & 3); i++) - { - RENDER_16BIT_SMP_C6PINTRP_TAP_FIX - INC_POS - } - samplesToMix >>= 2; - for (i = 0; i < samplesToMix; i++) - { - RENDER_16BIT_SMP_C6PINTRP_TAP_FIX - INC_POS - RENDER_16BIT_SMP_C6PINTRP_TAP_FIX - INC_POS - RENDER_16BIT_SMP_C6PINTRP_TAP_FIX - INC_POS - RENDER_16BIT_SMP_C6PINTRP_TAP_FIX - INC_POS - } + RENDER_16BIT_SMP_QINTRP + INC_POS } - else + samplesToMix >>= 2; + for (i = 0; i < samplesToMix; i++) { - for (i = 0; i < (samplesToMix & 3); i++) - { - RENDER_16BIT_SMP_C6PINTRP - INC_POS - } - samplesToMix >>= 2; - for (i = 0; i < samplesToMix; i++) - { - RENDER_16BIT_SMP_C6PINTRP - INC_POS - RENDER_16BIT_SMP_C6PINTRP - INC_POS - RENDER_16BIT_SMP_C6PINTRP - INC_POS - RENDER_16BIT_SMP_C6PINTRP - INC_POS - } + RENDER_16BIT_SMP_QINTRP + INC_POS + RENDER_16BIT_SMP_QINTRP + INC_POS + RENDER_16BIT_SMP_QINTRP + INC_POS + RENDER_16BIT_SMP_QINTRP + INC_POS } - + WRAP_LOOP } SET_BACK_MIXER_POS } -static void mix16bBidiLoopC6PIntrp(voice_t *v, uint32_t bufferPos, uint32_t numSamples) +static void mix16bBidiLoopQIntrp(voice_t *v, uint32_t bufferPos, uint32_t numSamples) { const int16_t *base, *revBase, *smpPtr; - int16_t *smpTapPtr; float fSample, *fMixBufferL, *fMixBufferR; int32_t position; uint32_t i, samplesToMix, samplesLeft; @@ -3065,7 +2929,6 @@ static void mix16bBidiLoopC6PIntrp(voice_t *v, uint32_t bufferPos, uint32_t numS GET_VOL GET_MIXER_VARS SET_BASE16_BIDI - PREPARE_TAP_FIX16 samplesLeft = numSamples; while (samplesLeft > 0) @@ -3074,45 +2937,22 @@ static void mix16bBidiLoopC6PIntrp(voice_t *v, uint32_t bufferPos, uint32_t numS samplesLeft -= samplesToMix; START_BIDI - if (v->hasLooped) // the negative interpolation taps need a special case after the sample has looped once + for (i = 0; i < (samplesToMix & 3); i++) { - for (i = 0; i < (samplesToMix & 3); i++) - { - RENDER_16BIT_SMP_C6PINTRP_TAP_FIX - INC_POS_BIDI - } - samplesToMix >>= 2; - for (i = 0; i < samplesToMix; i++) - { - RENDER_16BIT_SMP_C6PINTRP_TAP_FIX - INC_POS_BIDI - RENDER_16BIT_SMP_C6PINTRP_TAP_FIX - INC_POS_BIDI - RENDER_16BIT_SMP_C6PINTRP_TAP_FIX - INC_POS_BIDI - RENDER_16BIT_SMP_C6PINTRP_TAP_FIX - INC_POS_BIDI - } + RENDER_16BIT_SMP_QINTRP + INC_POS_BIDI } - else + samplesToMix >>= 2; + for (i = 0; i < samplesToMix; i++) { - for (i = 0; i < (samplesToMix & 3); i++) - { - RENDER_16BIT_SMP_C6PINTRP - INC_POS_BIDI - } - samplesToMix >>= 2; - for (i = 0; i < samplesToMix; i++) - { - RENDER_16BIT_SMP_C6PINTRP - INC_POS_BIDI - RENDER_16BIT_SMP_C6PINTRP - INC_POS_BIDI - RENDER_16BIT_SMP_C6PINTRP - INC_POS_BIDI - RENDER_16BIT_SMP_C6PINTRP - INC_POS_BIDI - } + RENDER_16BIT_SMP_QINTRP + INC_POS_BIDI + RENDER_16BIT_SMP_QINTRP + INC_POS_BIDI + RENDER_16BIT_SMP_QINTRP + INC_POS_BIDI + RENDER_16BIT_SMP_QINTRP + INC_POS_BIDI } END_BIDI @@ -3850,7 +3690,7 @@ static void mix16bRampBidiLoopS16Intrp(voice_t *v, uint32_t bufferPos, uint32_t SET_BACK_MIXER_POS } -static void mix16bRampNoLoopC4PIntrp(voice_t *v, uint32_t bufferPos, uint32_t numSamples) +static void mix16bRampNoLoopCIntrp(voice_t *v, uint32_t bufferPos, uint32_t numSamples) { const int16_t *base, *smpPtr; float fSample, *fMixBufferL, *fMixBufferR; @@ -3872,23 +3712,23 @@ static void mix16bRampNoLoopC4PIntrp(voice_t *v, uint32_t bufferPos, uint32_t nu for (i = 0; i < (samplesToMix & 3); i++) { - RENDER_16BIT_SMP_C4PINTRP + RENDER_16BIT_SMP_CINTRP VOLUME_RAMPING INC_POS } samplesToMix >>= 2; for (i = 0; i < samplesToMix; i++) { - RENDER_16BIT_SMP_C4PINTRP + RENDER_16BIT_SMP_CINTRP VOLUME_RAMPING INC_POS - RENDER_16BIT_SMP_C4PINTRP + RENDER_16BIT_SMP_CINTRP VOLUME_RAMPING INC_POS - RENDER_16BIT_SMP_C4PINTRP + RENDER_16BIT_SMP_CINTRP VOLUME_RAMPING INC_POS - RENDER_16BIT_SMP_C4PINTRP + RENDER_16BIT_SMP_CINTRP VOLUME_RAMPING INC_POS } @@ -3900,7 +3740,7 @@ static void mix16bRampNoLoopC4PIntrp(voice_t *v, uint32_t bufferPos, uint32_t nu SET_BACK_MIXER_POS } -static void mix16bRampLoopC4PIntrp(voice_t *v, uint32_t bufferPos, uint32_t numSamples) +static void mix16bRampLoopCIntrp(voice_t *v, uint32_t bufferPos, uint32_t numSamples) { const int16_t *base, *smpPtr; int16_t *smpTapPtr; @@ -3926,23 +3766,23 @@ static void mix16bRampLoopC4PIntrp(voice_t *v, uint32_t bufferPos, uint32_t numS { for (i = 0; i < (samplesToMix & 3); i++) { - RENDER_16BIT_SMP_C4PINTRP_TAP_FIX + RENDER_16BIT_SMP_CINTRP_TAP_FIX VOLUME_RAMPING INC_POS } samplesToMix >>= 2; for (i = 0; i < samplesToMix; i++) { - RENDER_16BIT_SMP_C4PINTRP_TAP_FIX + RENDER_16BIT_SMP_CINTRP_TAP_FIX VOLUME_RAMPING INC_POS - RENDER_16BIT_SMP_C4PINTRP_TAP_FIX + RENDER_16BIT_SMP_CINTRP_TAP_FIX VOLUME_RAMPING INC_POS - RENDER_16BIT_SMP_C4PINTRP_TAP_FIX + RENDER_16BIT_SMP_CINTRP_TAP_FIX VOLUME_RAMPING INC_POS - RENDER_16BIT_SMP_C4PINTRP_TAP_FIX + RENDER_16BIT_SMP_CINTRP_TAP_FIX VOLUME_RAMPING INC_POS } @@ -3951,23 +3791,23 @@ static void mix16bRampLoopC4PIntrp(voice_t *v, uint32_t bufferPos, uint32_t numS { for (i = 0; i < (samplesToMix & 3); i++) { - RENDER_16BIT_SMP_C4PINTRP + RENDER_16BIT_SMP_CINTRP VOLUME_RAMPING INC_POS } samplesToMix >>= 2; for (i = 0; i < samplesToMix; i++) { - RENDER_16BIT_SMP_C4PINTRP + RENDER_16BIT_SMP_CINTRP VOLUME_RAMPING INC_POS - RENDER_16BIT_SMP_C4PINTRP + RENDER_16BIT_SMP_CINTRP VOLUME_RAMPING INC_POS - RENDER_16BIT_SMP_C4PINTRP + RENDER_16BIT_SMP_CINTRP VOLUME_RAMPING INC_POS - RENDER_16BIT_SMP_C4PINTRP + RENDER_16BIT_SMP_CINTRP VOLUME_RAMPING INC_POS } @@ -3980,7 +3820,7 @@ static void mix16bRampLoopC4PIntrp(voice_t *v, uint32_t bufferPos, uint32_t numS SET_BACK_MIXER_POS } -static void mix16bRampBidiLoopC4PIntrp(voice_t *v, uint32_t bufferPos, uint32_t numSamples) +static void mix16bRampBidiLoopCIntrp(voice_t *v, uint32_t bufferPos, uint32_t numSamples) { const int16_t *base, *revBase, *smpPtr; int16_t *smpTapPtr; @@ -4007,23 +3847,23 @@ static void mix16bRampBidiLoopC4PIntrp(voice_t *v, uint32_t bufferPos, uint32_t { for (i = 0; i < (samplesToMix & 3); i++) { - RENDER_16BIT_SMP_C4PINTRP_TAP_FIX + RENDER_16BIT_SMP_CINTRP_TAP_FIX VOLUME_RAMPING INC_POS_BIDI } samplesToMix >>= 2; for (i = 0; i < samplesToMix; i++) { - RENDER_16BIT_SMP_C4PINTRP_TAP_FIX + RENDER_16BIT_SMP_CINTRP_TAP_FIX VOLUME_RAMPING INC_POS_BIDI - RENDER_16BIT_SMP_C4PINTRP_TAP_FIX + RENDER_16BIT_SMP_CINTRP_TAP_FIX VOLUME_RAMPING INC_POS_BIDI - RENDER_16BIT_SMP_C4PINTRP_TAP_FIX + RENDER_16BIT_SMP_CINTRP_TAP_FIX VOLUME_RAMPING INC_POS_BIDI - RENDER_16BIT_SMP_C4PINTRP_TAP_FIX + RENDER_16BIT_SMP_CINTRP_TAP_FIX VOLUME_RAMPING INC_POS_BIDI } @@ -4032,23 +3872,23 @@ static void mix16bRampBidiLoopC4PIntrp(voice_t *v, uint32_t bufferPos, uint32_t { for (i = 0; i < (samplesToMix & 3); i++) { - RENDER_16BIT_SMP_C4PINTRP + RENDER_16BIT_SMP_CINTRP VOLUME_RAMPING INC_POS_BIDI } samplesToMix >>= 2; for (i = 0; i < samplesToMix; i++) { - RENDER_16BIT_SMP_C4PINTRP + RENDER_16BIT_SMP_CINTRP VOLUME_RAMPING INC_POS_BIDI - RENDER_16BIT_SMP_C4PINTRP + RENDER_16BIT_SMP_CINTRP VOLUME_RAMPING INC_POS_BIDI - RENDER_16BIT_SMP_C4PINTRP + RENDER_16BIT_SMP_CINTRP VOLUME_RAMPING INC_POS_BIDI - RENDER_16BIT_SMP_C4PINTRP + RENDER_16BIT_SMP_CINTRP VOLUME_RAMPING INC_POS_BIDI } @@ -4062,7 +3902,7 @@ static void mix16bRampBidiLoopC4PIntrp(voice_t *v, uint32_t bufferPos, uint32_t SET_BACK_MIXER_POS } -static void mix16bRampNoLoopC6PIntrp(voice_t *v, uint32_t bufferPos, uint32_t numSamples) +static void mix16bRampNoLoopQIntrp(voice_t *v, uint32_t bufferPos, uint32_t numSamples) { const int16_t *base, *smpPtr; float fSample, *fMixBufferL, *fMixBufferR; @@ -4084,23 +3924,23 @@ static void mix16bRampNoLoopC6PIntrp(voice_t *v, uint32_t bufferPos, uint32_t nu for (i = 0; i < (samplesToMix & 3); i++) { - RENDER_16BIT_SMP_C6PINTRP + RENDER_16BIT_SMP_QINTRP VOLUME_RAMPING INC_POS } samplesToMix >>= 2; for (i = 0; i < samplesToMix; i++) { - RENDER_16BIT_SMP_C6PINTRP + RENDER_16BIT_SMP_QINTRP VOLUME_RAMPING INC_POS - RENDER_16BIT_SMP_C6PINTRP + RENDER_16BIT_SMP_QINTRP VOLUME_RAMPING INC_POS - RENDER_16BIT_SMP_C6PINTRP + RENDER_16BIT_SMP_QINTRP VOLUME_RAMPING INC_POS - RENDER_16BIT_SMP_C6PINTRP + RENDER_16BIT_SMP_QINTRP VOLUME_RAMPING INC_POS } @@ -4112,10 +3952,9 @@ static void mix16bRampNoLoopC6PIntrp(voice_t *v, uint32_t bufferPos, uint32_t nu SET_BACK_MIXER_POS } -static void mix16bRampLoopC6PIntrp(voice_t *v, uint32_t bufferPos, uint32_t numSamples) +static void mix16bRampLoopQIntrp(voice_t *v, uint32_t bufferPos, uint32_t numSamples) { const int16_t *base, *smpPtr; - int16_t *smpTapPtr; float fSample, *fMixBufferL, *fMixBufferR; int32_t position; float fVolumeLDelta, fVolumeRDelta, fVolumeL, fVolumeR; @@ -4125,7 +3964,6 @@ static void mix16bRampLoopC6PIntrp(voice_t *v, uint32_t bufferPos, uint32_t numS GET_VOL_RAMP GET_MIXER_VARS_RAMP SET_BASE16 - PREPARE_TAP_FIX16 samplesLeft = numSamples; while (samplesLeft > 0) @@ -4134,55 +3972,27 @@ static void mix16bRampLoopC6PIntrp(voice_t *v, uint32_t bufferPos, uint32_t numS LIMIT_MIX_NUM_RAMP samplesLeft -= samplesToMix; - if (v->hasLooped) // the negative interpolation taps need a special case after the sample has looped once + for (i = 0; i < (samplesToMix & 3); i++) { - for (i = 0; i < (samplesToMix & 3); i++) - { - RENDER_16BIT_SMP_C6PINTRP_TAP_FIX - VOLUME_RAMPING - INC_POS - } - samplesToMix >>= 2; - for (i = 0; i < samplesToMix; i++) - { - RENDER_16BIT_SMP_C6PINTRP_TAP_FIX - VOLUME_RAMPING - INC_POS - RENDER_16BIT_SMP_C6PINTRP_TAP_FIX - VOLUME_RAMPING - INC_POS - RENDER_16BIT_SMP_C6PINTRP_TAP_FIX - VOLUME_RAMPING - INC_POS - RENDER_16BIT_SMP_C6PINTRP_TAP_FIX - VOLUME_RAMPING - INC_POS - } + RENDER_16BIT_SMP_QINTRP + VOLUME_RAMPING + INC_POS } - else + samplesToMix >>= 2; + for (i = 0; i < samplesToMix; i++) { - for (i = 0; i < (samplesToMix & 3); i++) - { - RENDER_16BIT_SMP_C6PINTRP - VOLUME_RAMPING - INC_POS - } - samplesToMix >>= 2; - for (i = 0; i < samplesToMix; i++) - { - RENDER_16BIT_SMP_C6PINTRP - VOLUME_RAMPING - INC_POS - RENDER_16BIT_SMP_C6PINTRP - VOLUME_RAMPING - INC_POS - RENDER_16BIT_SMP_C6PINTRP - VOLUME_RAMPING - INC_POS - RENDER_16BIT_SMP_C6PINTRP - VOLUME_RAMPING - INC_POS - } + RENDER_16BIT_SMP_QINTRP + VOLUME_RAMPING + INC_POS + RENDER_16BIT_SMP_QINTRP + VOLUME_RAMPING + INC_POS + RENDER_16BIT_SMP_QINTRP + VOLUME_RAMPING + INC_POS + RENDER_16BIT_SMP_QINTRP + VOLUME_RAMPING + INC_POS } WRAP_LOOP @@ -4192,10 +4002,9 @@ static void mix16bRampLoopC6PIntrp(voice_t *v, uint32_t bufferPos, uint32_t numS SET_BACK_MIXER_POS } -static void mix16bRampBidiLoopC6PIntrp(voice_t *v, uint32_t bufferPos, uint32_t numSamples) +static void mix16bRampBidiLoopQIntrp(voice_t *v, uint32_t bufferPos, uint32_t numSamples) { const int16_t *base, *revBase, *smpPtr; - int16_t *smpTapPtr; float fSample, *fMixBufferL, *fMixBufferR; int32_t position; float fVolumeLDelta, fVolumeRDelta, fVolumeL, fVolumeR; @@ -4205,7 +4014,6 @@ static void mix16bRampBidiLoopC6PIntrp(voice_t *v, uint32_t bufferPos, uint32_t GET_VOL_RAMP GET_MIXER_VARS_RAMP SET_BASE16_BIDI - PREPARE_TAP_FIX16 samplesLeft = numSamples; while (samplesLeft > 0) @@ -4215,57 +4023,28 @@ static void mix16bRampBidiLoopC6PIntrp(voice_t *v, uint32_t bufferPos, uint32_t samplesLeft -= samplesToMix; START_BIDI - if (v->hasLooped) // the negative interpolation taps need a special case after the sample has looped once + for (i = 0; i < (samplesToMix & 3); i++) { - for (i = 0; i < (samplesToMix & 3); i++) - { - RENDER_16BIT_SMP_C6PINTRP_TAP_FIX - VOLUME_RAMPING - INC_POS_BIDI - } - samplesToMix >>= 2; - for (i = 0; i < samplesToMix; i++) - { - RENDER_16BIT_SMP_C6PINTRP_TAP_FIX - VOLUME_RAMPING - INC_POS_BIDI - RENDER_16BIT_SMP_C6PINTRP_TAP_FIX - VOLUME_RAMPING - INC_POS_BIDI - RENDER_16BIT_SMP_C6PINTRP_TAP_FIX - VOLUME_RAMPING - INC_POS_BIDI - RENDER_16BIT_SMP_C6PINTRP_TAP_FIX - VOLUME_RAMPING - INC_POS_BIDI - } + RENDER_16BIT_SMP_QINTRP + VOLUME_RAMPING + INC_POS_BIDI } - else + samplesToMix >>= 2; + for (i = 0; i < samplesToMix; i++) { - for (i = 0; i < (samplesToMix & 3); i++) - { - RENDER_16BIT_SMP_C6PINTRP - VOLUME_RAMPING - INC_POS_BIDI - } - samplesToMix >>= 2; - for (i = 0; i < samplesToMix; i++) - { - RENDER_16BIT_SMP_C6PINTRP - VOLUME_RAMPING - INC_POS_BIDI - RENDER_16BIT_SMP_C6PINTRP - VOLUME_RAMPING - INC_POS_BIDI - RENDER_16BIT_SMP_C6PINTRP - VOLUME_RAMPING - INC_POS_BIDI - RENDER_16BIT_SMP_C6PINTRP - VOLUME_RAMPING - INC_POS_BIDI - } + RENDER_16BIT_SMP_QINTRP + VOLUME_RAMPING + INC_POS_BIDI + RENDER_16BIT_SMP_QINTRP + VOLUME_RAMPING + INC_POS_BIDI + RENDER_16BIT_SMP_QINTRP + VOLUME_RAMPING + INC_POS_BIDI + RENDER_16BIT_SMP_QINTRP + VOLUME_RAMPING + INC_POS_BIDI } - END_BIDI WRAP_BIDI_LOOP @@ -4294,12 +4073,12 @@ const mixFunc mixFuncTab[] = (mixFunc)mix8bNoLoopS16Intrp, (mixFunc)mix8bLoopS16Intrp, (mixFunc)mix8bBidiLoopS16Intrp, - (mixFunc)mix8bNoLoopC4PIntrp, - (mixFunc)mix8bLoopC4PIntrp, - (mixFunc)mix8bBidiLoopC4PIntrp, - (mixFunc)mix8bNoLoopC6PIntrp, - (mixFunc)mix8bLoopC6PIntrp, - (mixFunc)mix8bBidiLoopC6PIntrp, + (mixFunc)mix8bNoLoopCIntrp, + (mixFunc)mix8bLoopCIntrp, + (mixFunc)mix8bBidiLoopCIntrp, + (mixFunc)mix8bNoLoopQIntrp, + (mixFunc)mix8bLoopQIntrp, + (mixFunc)mix8bBidiLoopQIntrp, // 16-bit (mixFunc)mix16bNoLoop, @@ -4314,12 +4093,12 @@ const mixFunc mixFuncTab[] = (mixFunc)mix16bNoLoopS16Intrp, (mixFunc)mix16bLoopS16Intrp, (mixFunc)mix16bBidiLoopS16Intrp, - (mixFunc)mix16bNoLoopC4PIntrp, - (mixFunc)mix16bLoopC4PIntrp, - (mixFunc)mix16bBidiLoopC4PIntrp, - (mixFunc)mix16bNoLoopC6PIntrp, - (mixFunc)mix16bLoopC6PIntrp, - (mixFunc)mix16bBidiLoopC6PIntrp, + (mixFunc)mix16bNoLoopCIntrp, + (mixFunc)mix16bLoopCIntrp, + (mixFunc)mix16bBidiLoopCIntrp, + (mixFunc)mix16bNoLoopQIntrp, + (mixFunc)mix16bLoopQIntrp, + (mixFunc)mix16bBidiLoopQIntrp, // volume ramping @@ -4336,12 +4115,12 @@ const mixFunc mixFuncTab[] = (mixFunc)mix8bRampNoLoopS16Intrp, (mixFunc)mix8bRampLoopS16Intrp, (mixFunc)mix8bRampBidiLoopS16Intrp, - (mixFunc)mix8bRampNoLoopC4PIntrp, - (mixFunc)mix8bRampLoopC4PIntrp, - (mixFunc)mix8bRampBidiLoopC4PIntrp, - (mixFunc)mix8bRampNoLoopC6PIntrp, - (mixFunc)mix8bRampLoopC6PIntrp, - (mixFunc)mix8bRampBidiLoopC6PIntrp, + (mixFunc)mix8bRampNoLoopCIntrp, + (mixFunc)mix8bRampLoopCIntrp, + (mixFunc)mix8bRampBidiLoopCIntrp, + (mixFunc)mix8bRampNoLoopQIntrp, + (mixFunc)mix8bRampLoopQIntrp, + (mixFunc)mix8bRampBidiLoopQIntrp, // 16-bit (mixFunc)mix16bRampNoLoop, @@ -4356,10 +4135,10 @@ const mixFunc mixFuncTab[] = (mixFunc)mix16bRampNoLoopS16Intrp, (mixFunc)mix16bRampLoopS16Intrp, (mixFunc)mix16bRampBidiLoopS16Intrp, - (mixFunc)mix16bRampNoLoopC4PIntrp, - (mixFunc)mix16bRampLoopC4PIntrp, - (mixFunc)mix16bRampBidiLoopC4PIntrp, - (mixFunc)mix16bRampNoLoopC6PIntrp, - (mixFunc)mix16bRampLoopC6PIntrp, - (mixFunc)mix16bRampBidiLoopC6PIntrp + (mixFunc)mix16bRampNoLoopCIntrp, + (mixFunc)mix16bRampLoopCIntrp, + (mixFunc)mix16bRampBidiLoopCIntrp, + (mixFunc)mix16bRampNoLoopQIntrp, + (mixFunc)mix16bRampLoopQIntrp, + (mixFunc)mix16bRampBidiLoopQIntrp }; diff --git a/src/mixer/ft2_mix.h b/src/mixer/ft2_mix.h @@ -5,12 +5,12 @@ enum { // don't change the order of these! (yes, it looks weird) - INTERPOLATION_DISABLED = 0, - INTERPOLATION_SINC8 = 1, - INTERPOLATION_LINEAR = 2, - INTERPOLATION_SINC16 = 3, - INTERPOLATION_CUBIC4 = 4, - INTERPOLATION_CUBIC6 = 5, + INTERPOLATION_DISABLED = 0, + INTERPOLATION_SINC8 = 1, + INTERPOLATION_LINEAR = 2, + INTERPOLATION_SINC16 = 3, + INTERPOLATION_CUBIC = 4, + INTERPOLATION_QUADRATIC = 5, // ------ NUM_INTERPOLATORS, diff --git a/src/mixer/ft2_mix_macros.h b/src/mixer/ft2_mix_macros.h @@ -1,6 +1,7 @@ #pragma once #include "../ft2_audio.h" +#include "ft2_quadratic_spline.h" #include "ft2_cubic_spline.h" #include "ft2_windowed_sinc.h" @@ -79,6 +80,13 @@ fVolumeL += fVolumeLDelta; \ fVolumeR += fVolumeRDelta; +/* It may look like we are potentially going out of bounds while looking up the sample points, +** but the sample data is actually padded on both the left (negative) and right side, where correct tap +** samples are stored according to loop mode (or no loop). +** +** There is also a second special case for the left edge (negative taps) after the sample has looped once. +*/ + /* ----------------------------------------------------------------------- */ /* NO INTERPOLATION (NEAREST NEIGHBOR) */ /* ----------------------------------------------------------------------- */ @@ -93,14 +101,11 @@ *fMixBufferL++ += fSample * fVolumeL; \ *fMixBufferR++ += fSample * fVolumeR; + /* ----------------------------------------------------------------------- */ /* LINEAR INTERPOLATION */ /* ----------------------------------------------------------------------- */ -/* It may look like we are potentially going out of bounds while looking up the sample points, -** but the sample data has a fixed sample after the end (sampleEnd/loopEnd). -*/ - #define LINEAR_INTERPOLATION(s, f, scale) \ { \ const int32_t frac = (uint32_t)(f) >> 1; /* uint32 -> int32 range, faster int->float conv. (x86/x86_64) */ \ @@ -118,84 +123,71 @@ *fMixBufferL++ += fSample * fVolumeL; \ *fMixBufferR++ += fSample * fVolumeR; + +/* ----------------------------------------------------------------------- */ +/* QUADRATIC SPLINE INTERPOLATION */ +/* ----------------------------------------------------------------------- */ + +// through LUT: mixer/ft2_quadratic_spline.c + +#define QUADRATIC_SPLINE_INTERPOLATION(s, f, scale) \ +{ \ + const float *t = fQuadraticSplineLUT + (((uint32_t)(f) >> QUADRATIC_SPLINE_FRACSHIFT) * QUADRATIC_SPLINE_WIDTH); \ + fSample = ((s[0] * t[0]) + \ + (s[1] * t[1]) + \ + (s[2] * t[2])) * (1.0f / scale); \ +} + +#define RENDER_8BIT_SMP_QINTRP \ + QUADRATIC_SPLINE_INTERPOLATION(smpPtr, positionFrac, 128) \ + *fMixBufferL++ += fSample * fVolumeL; \ + *fMixBufferR++ += fSample * fVolumeR; + +#define RENDER_16BIT_SMP_QINTRP \ + QUADRATIC_SPLINE_INTERPOLATION(smpPtr, positionFrac, 32768) \ + *fMixBufferL++ += fSample * fVolumeL; \ + *fMixBufferR++ += fSample * fVolumeR; + + /* ----------------------------------------------------------------------- */ /* CUBIC SPLINE INTERPOLATION */ /* ----------------------------------------------------------------------- */ // through LUT: mixer/ft2_cubic_spline.c -/* It may look like we are potentially going out of bounds while looking up the sample points, -** but the sample data is actually padded on both the left (negative) and right side, where correct tap -** samples are stored according to loop mode (or no loop). -** -** There is also a second special case for the left edge (negative taps) after the sample has looped once. -*/ - -#define CUBIC4P_SPLINE_INTERPOLATION(s, f, scale) \ +#define CUBIC_SPLINE_INTERPOLATION(s, f, scale) \ { \ - const float *t = f4PointCubicSplineLUT + (((uint32_t)(f) >> CUBIC4P_SPLINE_FRACSHIFT) & CUBIC4P_SPLINE_FRACMASK); \ + const float *t = fCubicSplineLUT + (((uint32_t)(f) >> CUBIC_SPLINE_FRACSHIFT) & CUBIC_SPLINE_FRACMASK); \ fSample = ((s[-1] * t[0]) + \ ( s[0] * t[1]) + \ ( s[1] * t[2]) + \ ( s[2] * t[3])) * (1.0f / scale); \ } -#define CUBIC6P_SPLINE_INTERPOLATION(s, f, scale) \ -{ \ - const float *t = f6PointCubicSplineLUT + (((uint32_t)(f) >> CUBIC6P_SPLINE_FRACSHIFT) * CUBIC6P_SPLINE_WIDTH); \ - fSample = ((s[-2] * t[0]) + \ - (s[-1] * t[1]) + \ - ( s[0] * t[2]) + \ - ( s[1] * t[3]) + \ - ( s[2] * t[4]) + \ - ( s[3] * t[5])) * (1.0f / scale); \ -} - -#define RENDER_8BIT_SMP_C4PINTRP \ - CUBIC4P_SPLINE_INTERPOLATION(smpPtr, positionFrac, 128) \ +#define RENDER_8BIT_SMP_CINTRP \ + CUBIC_SPLINE_INTERPOLATION(smpPtr, positionFrac, 128) \ *fMixBufferL++ += fSample * fVolumeL; \ *fMixBufferR++ += fSample * fVolumeR; -#define RENDER_16BIT_SMP_C4PINTRP \ - CUBIC4P_SPLINE_INTERPOLATION(smpPtr, positionFrac, 32768) \ +#define RENDER_16BIT_SMP_CINTRP \ + CUBIC_SPLINE_INTERPOLATION(smpPtr, positionFrac, 32768) \ *fMixBufferL++ += fSample * fVolumeL; \ *fMixBufferR++ += fSample * fVolumeR; -#define RENDER_8BIT_SMP_C6PINTRP \ - CUBIC6P_SPLINE_INTERPOLATION(smpPtr, positionFrac, 128) \ - *fMixBufferL++ += fSample * fVolumeL; \ - *fMixBufferR++ += fSample * fVolumeR; - -#define RENDER_16BIT_SMP_C6PINTRP \ - CUBIC6P_SPLINE_INTERPOLATION(smpPtr, positionFrac, 32768) \ - *fMixBufferL++ += fSample * fVolumeL; \ - *fMixBufferR++ += fSample * fVolumeR; /* Special left-edge case mixers to get proper tap data after one loop cycle. ** These are only used on looped samples. */ -#define RENDER_8BIT_SMP_C4PINTRP_TAP_FIX \ - smpTapPtr = (smpPtr <= leftEdgePtr) ? (int8_t *)&v->leftEdgeTaps8[(int32_t)(smpPtr-loopStartPtr)] : (int8_t *)smpPtr; \ - CUBIC4P_SPLINE_INTERPOLATION(smpTapPtr, positionFrac, 128) \ - *fMixBufferL++ += fSample * fVolumeL; \ - *fMixBufferR++ += fSample * fVolumeR; - -#define RENDER_16BIT_SMP_C4PINTRP_TAP_FIX \ - smpTapPtr = (smpPtr <= leftEdgePtr) ? (int16_t *)&v->leftEdgeTaps16[(int32_t)(smpPtr-loopStartPtr)] : (int16_t *)smpPtr; \ - CUBIC4P_SPLINE_INTERPOLATION(smpTapPtr, positionFrac, 32768) \ - *fMixBufferL++ += fSample * fVolumeL; \ - *fMixBufferR++ += fSample * fVolumeR; - -#define RENDER_8BIT_SMP_C6PINTRP_TAP_FIX \ +#define RENDER_8BIT_SMP_CINTRP_TAP_FIX \ smpTapPtr = (smpPtr <= leftEdgePtr) ? (int8_t *)&v->leftEdgeTaps8[(int32_t)(smpPtr-loopStartPtr)] : (int8_t *)smpPtr; \ - CUBIC6P_SPLINE_INTERPOLATION(smpTapPtr, positionFrac, 128) \ + CUBIC_SPLINE_INTERPOLATION(smpTapPtr, positionFrac, 128) \ *fMixBufferL++ += fSample * fVolumeL; \ *fMixBufferR++ += fSample * fVolumeR; -#define RENDER_16BIT_SMP_C6PINTRP_TAP_FIX \ +#define RENDER_16BIT_SMP_CINTRP_TAP_FIX \ smpTapPtr = (smpPtr <= leftEdgePtr) ? (int16_t *)&v->leftEdgeTaps16[(int32_t)(smpPtr-loopStartPtr)] : (int16_t *)smpPtr; \ - CUBIC6P_SPLINE_INTERPOLATION(smpTapPtr, positionFrac, 32768) \ + CUBIC_SPLINE_INTERPOLATION(smpTapPtr, positionFrac, 32768) \ *fMixBufferL++ += fSample * fVolumeL; \ *fMixBufferR++ += fSample * fVolumeR; @@ -206,13 +198,6 @@ // through LUTs: mixer/ft2_windowed_sinc.c -/* It may look like we are potentially going out of bounds while looking up the sample points, -** but the sample data is actually padded on both the left (negative) and right side, where correct tap -** samples are stored according to loop mode (or no loop). -** -** There is also a second special case for the left edge (negative taps) after the sample has looped once. -*/ - #define WINDOWED_SINC8_INTERPOLATION(s, f, scale) \ { \ const float *t = v->fSincLUT + (((uint32_t)(f) >> SINC1_FRACSHIFT) & SINC1_FRACMASK); \ @@ -295,6 +280,7 @@ *fMixBufferL++ += fSample * fVolumeL; \ *fMixBufferR++ += fSample * fVolumeR; + /* ----------------------------------------------------------------------- */ /* SAMPLES-TO-MIX LIMITING MACROS */ /* ----------------------------------------------------------------------- */ diff --git a/src/mixer/ft2_quadratic_spline.c b/src/mixer/ft2_quadratic_spline.c @@ -0,0 +1,45 @@ +// 3-point quadratic spline interpolation LUT generator + +#include <stdint.h> +#include <stdbool.h> +#include <stdlib.h> +#include "ft2_quadratic_spline.h" +#include "../ft2_video.h" // showErrorMsgBox() + +float *fQuadraticSplineLUT = NULL; // globalized + +bool setupQuadraticSplineTable(void) +{ + fQuadraticSplineLUT = (float *)malloc(QUADRATIC_SPLINE_WIDTH * QUADRATIC_SPLINE_PHASES * sizeof (float)); + if (fQuadraticSplineLUT == NULL) + { + showErrorMsgBox("Not enough memory!"); + return false; + } + + float *fPtr = fQuadraticSplineLUT; + for (int32_t i = 0; i < QUADRATIC_SPLINE_PHASES; i++) + { + const double x1 = i * (1.0 / QUADRATIC_SPLINE_PHASES); + const double x2 = x1 * x1; // x^2 + + double t1 = ( 0.5 * x2) + (-1.5 * x1) + 1.0; + double t2 = (-1.0 * x2) + ( 2.0 * x1); + double t3 = ( 0.5 * x2) + (-0.5 * x1); + + *fPtr++ = (float)t1; + *fPtr++ = (float)t2; + *fPtr++ = (float)t3; + } + + return true; +} + +void freeQuadraticSplineTable(void) +{ + if (fQuadraticSplineLUT != NULL) + { + free(fQuadraticSplineLUT); + fQuadraticSplineLUT = NULL; + } +} diff --git a/src/mixer/ft2_quadratic_spline.h b/src/mixer/ft2_quadratic_spline.h @@ -0,0 +1,15 @@ +#pragma once + +#include <stdint.h> +#include <stdbool.h> +#include "ft2_mix.h" // MIXER_FRAC_BITS + +#define QUADRATIC_SPLINE_WIDTH 3 +#define QUADRATIC_SPLINE_PHASES 8192 +#define QUADRATIC_SPLINE_PHASES_BITS 13 // log2(QUADRATIC_SPLINE_PHASES) +#define QUADRATIC_SPLINE_FRACSHIFT (MIXER_FRAC_BITS-QUADRATIC_SPLINE_PHASES_BITS) + +extern float *fQuadraticSplineLUT; + +bool setupQuadraticSplineTable(void); +void freeQuadraticSplineTable(void); diff --git a/src/scopes/ft2_scope_macros.h b/src/scopes/ft2_scope_macros.h @@ -60,24 +60,20 @@ } \ #define CUBIC_SMP8(frac) \ - const int16_t *t = scopeIntrpLUT + (((frac) >> (SCOPE_FRAC_BITS-SCOPE_INTRP_PHASES_BITS)) * SCOPE_INTRP_WIDTH); \ + const int16_t *t = scopeIntrpLUT + (((frac) >> (SCOPE_FRAC_BITS-SCOPE_INTRP_PHASES_BITS)) << SCOPE_INTRP_WIDTH_BITS); \ \ - sample = ((s8[-2] * t[0]) + \ - (s8[-1] * t[1]) + \ - ( s8[0] * t[2]) + \ - ( s8[1] * t[3]) + \ - ( s8[2] * t[4]) + \ - ( s8[3] * t[5])) >> (SCOPE_INTRP_SCALE_BITS-8); + sample = ((s8[-1] * t[0]) + \ + ( s8[0] * t[1]) + \ + ( s8[1] * t[2]) + \ + ( s8[2] * t[3])) >> (SCOPE_INTRP_SCALE_BITS-8); #define CUBIC_SMP16(frac) \ - const int16_t *t = scopeIntrpLUT + (((frac) >> (SCOPE_FRAC_BITS-SCOPE_INTRP_PHASES_BITS)) * SCOPE_INTRP_WIDTH); \ + const int16_t *t = scopeIntrpLUT + (((frac) >> (SCOPE_FRAC_BITS-SCOPE_INTRP_PHASES_BITS)) << SCOPE_INTRP_WIDTH_BITS); \ \ - sample = ((s16[-2] * t[0]) + \ - (s16[-1] * t[1]) + \ - ( s16[0] * t[2]) + \ - ( s16[1] * t[3]) + \ - ( s16[2] * t[4]) + \ - ( s16[3] * t[5])) >> SCOPE_INTRP_SCALE_BITS; + sample = ((s16[-1] * t[0]) + \ + ( s16[0] * t[1]) + \ + ( s16[1] * t[2]) + \ + ( s16[2] * t[3])) >> SCOPE_INTRP_SCALE_BITS; #define CUBIC_INTERPOLATION8(frac) \ { \ @@ -113,7 +109,8 @@ LINEAR_INTERPOLATION8(frac) \ else \ CUBIC_INTERPOLATION8(frac) \ - sample = (sample * s->volume) >> (16+2); + sample = (int32_t)roundf((float)sample * s->fVolume); \ + if (sample > (SCOPE_HEIGHT/2)-1) sample = (SCOPE_HEIGHT/2)-1; /* upper-clamp needed */ #define INTERPOLATE_SMP16(pos, frac) \ const int16_t *s16 = s->base16 + pos; \ @@ -123,7 +120,8 @@ LINEAR_INTERPOLATION16(frac) \ else \ CUBIC_INTERPOLATION16(frac) \ - sample = (sample * s->volume) >> (16+2); + sample = (int32_t)roundf((float)sample * s->fVolume); \ + if (sample > (SCOPE_HEIGHT/2)-1) sample = (SCOPE_HEIGHT/2)-1; /* upper-clamp needed */ #define INTERPOLATE_SMP8_LOOP(pos, frac) \ const int8_t *s8 = s->base8 + pos; \ @@ -133,7 +131,8 @@ LINEAR_INTERPOLATION8(frac) \ else \ CUBIC_INTERPOLATION8_LOOP(pos, frac) \ - sample = (sample * s->volume) >> (16+2); + sample = (int32_t)roundf((float)sample * s->fVolume); \ + if (sample > (SCOPE_HEIGHT/2)-1) sample = (SCOPE_HEIGHT/2)-1; /* upper-clamp needed */ #define INTERPOLATE_SMP16_LOOP(pos, frac) \ const int16_t *s16 = s->base16 + pos; \ @@ -143,25 +142,37 @@ LINEAR_INTERPOLATION16(frac) \ else \ CUBIC_INTERPOLATION16_LOOP(pos, frac) \ - sample = (sample * s->volume) >> (16+2); + sample = (int32_t)roundf((float)sample * s->fVolume); \ + if (sample > (SCOPE_HEIGHT/2)-1) sample = (SCOPE_HEIGHT/2)-1; /* upper-clamp needed */ #define SCOPE_GET_SMP8 \ if (s->active) \ - sample = (s->base8[position] * s->volume) >> (8+2); \ + { \ + sample = (int32_t)roundf((float)(s->base8[position] << 8) * s->fVolume); \ + if (sample > (SCOPE_HEIGHT/2)-1) sample = (SCOPE_HEIGHT/2)-1; /* upper-clamp needed */ \ + } \ else \ - sample = 0; + { \ + sample = 0; \ + } #define SCOPE_GET_SMP16 \ if (s->active) \ - sample = (s->base16[position] * s->volume) >> (16+2); \ + { \ + sample = (int32_t)roundf((float)s->base16[position] * s->fVolume); \ + if (sample > (SCOPE_HEIGHT/2)-1) sample = (SCOPE_HEIGHT/2)-1; /* upper-clamp needed */ \ + } \ else \ - sample = 0; + { \ + sample = 0; \ + } #define SCOPE_GET_SMP8_BIDI \ if (s->active) \ { \ GET_BIDI_POSITION \ - sample = (s->base8[actualPos] * s->volume) >> (8+2); \ + sample = (int32_t)roundf((float)(s->base8[actualPos] << 8) * s->fVolume); \ + if (sample > (SCOPE_HEIGHT/2)-1) sample = (SCOPE_HEIGHT/2)-1; /* upper-clamp needed */ \ } \ else \ { \ @@ -172,7 +183,8 @@ if (s->active) \ { \ GET_BIDI_POSITION \ - sample = (s->base16[actualPos] * s->volume) >> (16+2); \ + sample = (int32_t)roundf((float)s->base16[actualPos] * s->fVolume); \ + if (sample > (SCOPE_HEIGHT/2)-1) sample = (SCOPE_HEIGHT/2)-1; /* upper-clamp needed */ \ } \ else \ { \ diff --git a/src/scopes/ft2_scopedraw.c b/src/scopes/ft2_scopedraw.c @@ -22,11 +22,11 @@ bool calcScopeIntrpLUT(void) /* Several tests have been done to figure out what interpolation method is most suitable ** for the tracker scopes. After testing linear, cubic, Gaussian and windowed-sinc - ** interpolation, I have come to the conclusion that 6-point cubic B-spline is the best. + ** interpolation, I have come to the conclusion that 4-point cubic B-spline is the best. ** This interpolation method also has no overshoot. */ - // 6-point cubic B-spline (no overshoot) + // 4-point cubic B-spline (no overshoot) int16_t *ptr16 = scopeIntrpLUT; for (int32_t i = 0; i < SCOPE_INTRP_PHASES; i++) @@ -34,23 +34,17 @@ bool calcScopeIntrpLUT(void) const double x1 = i * (1.0 / SCOPE_INTRP_PHASES); const double x2 = x1 * x1; // x^2 const double x3 = x2 * x1; // x^3 - const double x4 = x3 * x1; // x^4 - const double x5 = x4 * x1; // x^5 - - double t1 = (-(1.0/120.0) * x5) + ( (1.0/24.0) * x4) + (-(1.0/12.0) * x3) + ( (1.0/12.0) * x2) + (-(1.0/24.0) * x1) + ( 1.0/120.0); - double t2 = ( (1.0/ 24.0) * x5) + (-(1.0/ 6.0) * x4) + ( (1.0/ 6.0) * x3) + ( (1.0/ 6.0) * x2) + (-(5.0/12.0) * x1) + (13.0/ 60.0); - double t3 = (-(1.0/ 12.0) * x5) + ( (1.0/ 4.0) * x4) + (-(1.0/ 2.0) * x2) + (11.0/ 20.0); - double t4 = ( (1.0/ 12.0) * x5) + (-(1.0/ 6.0) * x4) + (-(1.0/ 6.0) * x3) + ( (1.0/ 6.0) * x2) + ( (5.0/12.0) * x1) + (13.0/ 60.0); - double t5 = (-(1.0/ 24.0) * x5) + ( (1.0/24.0) * x4) + ( (1.0/12.0) * x3) + ( (1.0/12.0) * x2) + ( (1.0/24.0) * x1) + ( 1.0/120.0); - double t6 = (1.0/120.0) * x5; - - // important: truncate, do not round (would cause scope overflow) - *ptr16++ = (int16_t)(t1 * SCOPE_INTRP_SCALE); - *ptr16++ = (int16_t)(t2 * SCOPE_INTRP_SCALE); - *ptr16++ = (int16_t)(t3 * SCOPE_INTRP_SCALE); - *ptr16++ = (int16_t)(t4 * SCOPE_INTRP_SCALE); - *ptr16++ = (int16_t)(t5 * SCOPE_INTRP_SCALE); - *ptr16++ = (int16_t)(t6 * SCOPE_INTRP_SCALE); + + double t1 = (-(1.0/6.0) * x3) + ( (1.0/2.0) * x2) + (-(1.0/2.0) * x1) + (1.0/6.0); + double t2 = ( (1.0/2.0) * x3) + ( -1.0 * x2) + (2.0/3.0); + double t3 = (-(1.0/2.0) * x3) + ( (1.0/2.0) * x2) + ( (1.0/2.0) * x1) + (1.0/6.0); + double t4 = (1.0/6.0) * x3; + + // rounding here would make the scopes clip, but we clamp the scopes for another reason anyway + *ptr16++ = (int16_t)round(t1 * SCOPE_INTRP_SCALE); + *ptr16++ = (int16_t)round(t2 * SCOPE_INTRP_SCALE); + *ptr16++ = (int16_t)round(t3 * SCOPE_INTRP_SCALE); + *ptr16++ = (int16_t)round(t4 * SCOPE_INTRP_SCALE); } return true; diff --git a/src/scopes/ft2_scopes.c b/src/scopes/ft2_scopes.c @@ -428,7 +428,7 @@ void drawScopes(void) } volatile scope_t s = scope[i]; // cache scope to lower thread race condition issues - if (s.active && s.volume > 0 && !audio.locked) + if (s.active && s.fVolume > 0.0f && !audio.locked) { // scope is active scope[i].wasCleared = false; @@ -489,7 +489,7 @@ void handleScopesFromChQueue(chSyncData_t *chSyncData, uint8_t *scopeUpdateStatu const uint8_t status = scopeUpdateStatus[i]; if (status & IS_Vol) - sc->volume = ch->scopeVolume; + sc->fVolume = ch->scopeVolume * (1.0f / (255.0f / (SCOPE_HEIGHT/2) * 32768.0f)); if (status & IS_Period) sc->delta = (uint64_t)(dPeriod2Hz(ch->period) * (SCOPE_FRAC_SCALE / (double)SCOPE_HZ)); diff --git a/src/scopes/ft2_scopes.h b/src/scopes/ft2_scopes.h @@ -17,7 +17,8 @@ #define SCOPE_FRAC_SCALE ((int64_t)1 << SCOPE_FRAC_BITS) #define SCOPE_FRAC_MASK (SCOPE_FRAC_SCALE-1) -#define SCOPE_INTRP_WIDTH 6 +#define SCOPE_INTRP_WIDTH 4 +#define SCOPE_INTRP_WIDTH_BITS 2 /* log2(SCOPE_INTRP_WIDTH) */ #define SCOPE_INTRP_SCALE 32768 #define SCOPE_INTRP_SCALE_BITS 15 /* log2(SCOPE_INTRP_SCALE) */ #define SCOPE_INTRP_PHASES 512 /* plentiful for FT2-styled scopes */ @@ -39,8 +40,9 @@ typedef struct scope_t const int16_t *base16; bool wasCleared, sample16Bit, samplingBackwards, hasLooped; uint8_t loopType; - int32_t volume, loopStart, loopLength, loopEnd, sampleEnd, position; + int32_t loopStart, loopLength, loopEnd, sampleEnd, position; uint64_t delta, drawDelta, positionFrac; + float fVolume; // if (loopEnabled && hasLooped && samplingPos <= loopStart+MAX_LEFT_TAPS) readFixedTapsFromThisPointer(); const int8_t *leftEdgeTaps8; diff --git a/vs2019_project/ft2-clone/ft2-clone.vcxproj b/vs2019_project/ft2-clone/ft2-clone.vcxproj @@ -357,6 +357,7 @@ <ClCompile Include="..\..\src\libflac\window.c" /> <ClCompile Include="..\..\src\libflac\windows_unicode_filenames.c" /> <ClCompile Include="..\..\src\mixer\ft2_cubic_spline.c" /> + <ClCompile Include="..\..\src\mixer\ft2_quadratic_spline.c" /> <ClCompile Include="..\..\src\mixer\ft2_windowed_sinc.c" /> <ClCompile Include="..\..\src\mixer\ft2_mix.c" /> <ClCompile Include="..\..\src\mixer\ft2_silence_mix.c" /> @@ -433,6 +434,7 @@ <ClInclude Include="..\..\src\ft2_video.h" /> <ClInclude Include="..\..\src\ft2_wav_renderer.h" /> <ClInclude Include="..\..\src\mixer\ft2_cubic_spline.h" /> + <ClInclude Include="..\..\src\mixer\ft2_quadratic_spline.h" /> <ClInclude Include="..\..\src\mixer\ft2_windowed_sinc.h" /> <ClInclude Include="..\..\src\mixer\ft2_mix.h" /> <ClInclude Include="..\..\src\mixer\ft2_mix_macros.h" /> diff --git a/vs2019_project/ft2-clone/ft2-clone.vcxproj.filters b/vs2019_project/ft2-clone/ft2-clone.vcxproj.filters @@ -173,6 +173,9 @@ <ClCompile Include="..\..\src\modloaders\ft2_load_it.c"> <Filter>modloaders</Filter> </ClCompile> + <ClCompile Include="..\..\src\mixer\ft2_quadratic_spline.c"> + <Filter>mixer</Filter> + </ClCompile> </ItemGroup> <ItemGroup> <ClInclude Include="..\..\src\rtmidi\RtMidi.h"> @@ -331,6 +334,9 @@ <ClInclude Include="..\..\src\ft2_unicode.h"> <Filter>headers</Filter> </ClInclude> + <ClInclude Include="..\..\src\mixer\ft2_quadratic_spline.h"> + <Filter>mixer</Filter> + </ClInclude> </ItemGroup> <ItemGroup> <Filter Include="mixer">