ref: 0c1f9008cbcd43eaae3f396c6d0a4d1b035586fd
parent: 976b6bb80a6b04f209d13f670a941645fe0a89c7
author: Olav Sørensen <olav.sorensen@live.no>
date: Sat Sep 5 20:04:22 EDT 2020
Cleanup and bugfixes! - Fixed a small initial resampling interpolation error on looping samples whose loop start (Repeat) is above 0. - Fixed a CUBIC_PHASES off-by-one typo, which could probably mess up the resampling interpolation in very rare cases. - Cleaned up some messy logic in tickReplayer() (behavior is the same)
--- a/src/ft2_replayer.c
+++ b/src/ft2_replayer.c
@@ -1072,7 +1072,7 @@
checkMoreEffects(ch);
}
-static void fixTonePorta(stmTyp *ch, tonTyp *p, uint8_t inst)
+static void fixTonePorta(stmTyp *ch, const tonTyp *p, uint8_t inst)
{
uint16_t portaTmp;
@@ -1105,7 +1105,7 @@
}
}
-static void getNewNote(stmTyp *ch, tonTyp *p)
+static void getNewNote(stmTyp *ch, const tonTyp *p)
{
uint8_t inst;
bool checkEfx;
@@ -2094,40 +2094,32 @@
musicPaused = false;
}
-static void noNewAllChannels(void)
-{
- for (int32_t i = 0; i < song.antChn; i++)
- {
- doEffects(&stm[i]);
- fixaEnvelopeVibrato(&stm[i]);
- }
-}
void tickReplayer(void) // periodically called from audio callback
{
- bool readNewNote;
int32_t i;
+ stmTyp *c;
if (musicPaused || !songPlaying)
{
- for (i = 0; i < song.antChn; i++)
- fixaEnvelopeVibrato(&stm[i]);
+ c = stm;
+ for (i = 0; i < song.antChn; i++, c++)
+ fixaEnvelopeVibrato(c);
return;
}
+ // for song playback counter (hh:mm:ss)
if (song.speed >= MIN_BPM && song.speed <= MAX_BPM)
- song.musicTime64 += musicTimeTab64[song.speed]; // for song playback counter (hh:mm:ss)
+ song.musicTime64 += musicTimeTab64[song.speed];
- readNewNote = false;
-
- song.timer--;
- if (song.timer == 0)
+ bool tickZero = false;
+ if (--song.timer == 0)
{
song.timer = song.tempo;
- readNewNote = true;
+ tickZero = true;
}
-
+
// for visuals
song.curReplayerTimer = (uint8_t)song.timer;
song.curReplayerPattPos = (uint8_t)song.pattPos;
@@ -2134,28 +2126,33 @@
song.curReplayerPattNr = (uint8_t)song.pattNr;
song.curReplayerSongPos = (uint8_t)song.songPos;
+ const bool readNewNote = tickZero && song.pattDelTime2 == 0;
if (readNewNote)
{
- if (song.pattDelTime2 == 0)
+ const tonTyp *pattPtr = &nilPatternLine;
+ if (patt[song.pattNr] != NULL)
{
- for (i = 0; i < song.antChn; i++)
- {
- if (patt[song.pattNr] == NULL)
- getNewNote(&stm[i], &nilPatternLine);
- else
- getNewNote(&stm[i], &patt[song.pattNr][(song.pattPos * MAX_VOICES) + i]);
+ assert(song.pattNr >= 0 && song.pattNr < MAX_PATTERNS &&
+ song.pattPos >= 0 && song.pattPos < MAX_PATT_LEN);
- fixaEnvelopeVibrato(&stm[i]);
- }
+ pattPtr = &patt[song.pattNr][song.pattPos * MAX_VOICES];
}
- else
+
+ c = stm;
+ for (i = 0; i < song.antChn; i++, c++, pattPtr++)
{
- noNewAllChannels();
+ getNewNote(c, pattPtr);
+ fixaEnvelopeVibrato(c);
}
}
else
{
- noNewAllChannels();
+ c = stm;
+ for (i = 0; i < song.antChn; i++, c++)
+ {
+ doEffects(c);
+ fixaEnvelopeVibrato(c);
+ }
}
getNextPos();
--- a/src/ft2_sample_ed.c
+++ b/src/ft2_sample_ed.c
@@ -129,6 +129,8 @@
ptr16[loopEnd+0] = ptr16[loopStart+0];
if (loopStart == 0 && loopEnd > 0)
ptr16[-1] = ptr16[loopEnd-1];
+ else
+ ptr16[-1] = 0;
ptr16[loopEnd+1] = ptr16[loopStart+1];
}
@@ -151,6 +153,8 @@
s->pek[loopEnd+0] = s->pek[loopStart+0];
if (loopStart == 0 && loopEnd > 0)
s->pek[-1] = s->pek[loopEnd-1];
+ else
+ s->pek[-1] = 0;
s->pek[loopEnd+1] = s->pek[loopStart+1];
}
@@ -181,6 +185,8 @@
ptr16[loopEnd+0] = ptr16[loopEnd-1];
if (loopStart == 0)
ptr16[-1] = ptr16[0];
+ else
+ ptr16[-1] = 0;
if (loopLen >= 2)
ptr16[loopEnd+1] = ptr16[loopEnd-2];
@@ -208,6 +214,8 @@
s->pek[loopEnd+0] = s->pek[loopEnd-1];
if (loopStart == 0)
s->pek[-1] = s->pek[0];
+ else
+ s->pek[-1] = 0;
if (loopLen >= 2)
s->pek[loopEnd+1] = s->pek[loopEnd-2];
--- a/src/mixer/ft2_cubic.h
+++ b/src/mixer/ft2_cubic.h
@@ -4,7 +4,7 @@
#include "../ft2_audio.h" // MIXER_FRAC_BITS definition
// if you change this, also change CUBIC_PHASES_BITS
-#define CUBIC_PHASES 4095
+#define CUBIC_PHASES 4096
#define CUBIC_PHASES_BITS 12 /* log2(CUBIC_PHASES) */
// don't change these!