diff --git a/Frameworks/modplay/modplay/ft2play.c b/Frameworks/modplay/modplay/ft2play.c index c33876947..9ec9c82bc 100644 --- a/Frameworks/modplay/modplay/ft2play.c +++ b/Frameworks/modplay/modplay/ft2play.c @@ -398,24 +398,24 @@ typedef struct int8_t LinearFrqTab; uint32_t soundBufferSize; uint32_t outputFreq; - + TonTyp *NilPatternLine; TonTyp *Patt[256]; StmTyp Stm[MAX_VOICES]; SongTyp Song; InstrTyp *Instr[255 + 1]; VOICE voice[TOTAL_VOICES]; - + void *resampler[TOTAL_VOICES*2]; - + float *PanningTab; float f_outputFreq; - + #ifdef USE_VOL_RAMP float f_samplesPerFrame005; float f_samplesPerFrame010; #endif - + /* pre-initialized variables */ int8_t samplingInterpolation;/* = 1; */ int8_t rampStyle; @@ -423,14 +423,14 @@ typedef struct float *masterBufferR;/* = NULL; */ int32_t samplesLeft;/* = 0; must be signed */ uint32_t samplesPerFrame;/* = 882; */ - + /* globally accessed */ int8_t ModuleLoaded;/* = 0; */ int8_t Playing;/* = 0; */ uint16_t numChannels;/* = 127; */ - + uint8_t muted[16]; - + uint32_t loopCount; void * playedRows; uint16_t playedRowsPatLoop[1024]; @@ -628,7 +628,7 @@ static void StartTone(PLAYER *p, uint8_t Ton, uint8_t EffTyp, uint8_t Eff, StmTy ch->OldVol = s->Vol; - /* + /* ** FT2 doesn't do this, but we don't want to blow our eardrums ** on malicious XMs... */ @@ -829,7 +829,7 @@ static void CheckEffects(PLAYER *p, StmTyp *ch) tmpEff = ch->Eff & 0x0F; if (!tmpEff) tmpEff = ch->FPortaUpSpeed; - + ch->FPortaUpSpeed = tmpEff; ch->RealPeriod -= ((int16_t)(tmpEff) << 2); @@ -845,7 +845,7 @@ static void CheckEffects(PLAYER *p, StmTyp *ch) tmpEff = ch->Eff & 0x0F; if (!tmpEff) tmpEff = ch->FPortaDownSpeed; - + ch->FPortaDownSpeed = tmpEff; ch->RealPeriod += ((int16_t)(tmpEff) << 2); @@ -914,7 +914,7 @@ static void CheckEffects(PLAYER *p, StmTyp *ch) tmpEff = ch->Eff & 0x0F; if (!tmpEff) tmpEff = ch->FVolSlideUpSpeed; - + ch->FVolSlideUpSpeed = tmpEff; ch->RealVol += tmpEff; @@ -930,7 +930,7 @@ static void CheckEffects(PLAYER *p, StmTyp *ch) tmpEff = ch->Eff & 0x0F; if (!tmpEff) tmpEff = ch->FVolSlideDownSpeed; - + ch->FVolSlideDownSpeed = tmpEff; ch->RealVol -= tmpEff; @@ -1063,7 +1063,7 @@ static void CheckEffects(PLAYER *p, StmTyp *ch) if (envPos >= ch->InstrSeg.EnvVPAnt) envPos = (int16_t)(ch->InstrSeg.EnvVPAnt) - 1; - + ch->EnvVPos = (envPos < 0) ? 0 : (uint8_t)(envPos); } @@ -1124,7 +1124,7 @@ static void CheckEffects(PLAYER *p, StmTyp *ch) if (envPos >= ch->InstrSeg.EnvPPAnt) envPos = (int16_t)(ch->InstrSeg.EnvPPAnt) - 1; - + ch->EnvPPos = (envPos < 0) ? 0 : (uint8_t)(envPos); } } @@ -1135,13 +1135,13 @@ static void CheckEffects(PLAYER *p, StmTyp *ch) tmpEff = ch->Eff & 0x0F; if (!tmpEff) tmpEff = ch->RetrigSpeed; - + ch->RetrigSpeed = tmpEff; tmpEffHi = ch->Eff >> 4; if (!tmpEffHi) tmpEffHi = ch->RetrigVol; - + ch->RetrigVol = tmpEffHi; if (!ch->VolKolVol) MultiRetrig(p, ch); @@ -1153,7 +1153,7 @@ static void CheckEffects(PLAYER *p, StmTyp *ch) tmpEff = ch->Eff & 0x0F; if (!tmpEff) tmpEff = ch->EPortaUpSpeed; - + ch->EPortaUpSpeed = tmpEff; ch->RealPeriod -= tmpEff; @@ -1169,7 +1169,7 @@ static void CheckEffects(PLAYER *p, StmTyp *ch) tmpEff = ch->Eff & 0x0F; if (!tmpEff) tmpEff = ch->EPortaDownSpeed; - + ch->EPortaDownSpeed = tmpEff; ch->RealPeriod += tmpEff; @@ -1185,7 +1185,7 @@ static void fixTonePorta(PLAYER *pl, StmTyp *ch, TonTyp *p, uint8_t inst) { uint16_t portaTmp; uint8_t tmpFTune; - + if (p->Ton) { if (p->Ton == 97) @@ -1197,11 +1197,11 @@ static void fixTonePorta(PLAYER *pl, StmTyp *ch, TonTyp *p, uint8_t inst) // signed 8-bit >>3 without rounding or undefined behavior (FT2 exact) tmpFTune = (ch->FineTune >= 0) ? (ch->FineTune >> 3) : (0xE0 | ((uint8_t)(ch->FineTune) >> 3)); portaTmp = ((((p->Ton - 1) + ch->RelTonNr) & 0x00FF) << 4) + ((tmpFTune + 16) & 0x00FF); - + if (portaTmp < ((12 * 10 * 16) + 16)) { ch->WantPeriod = pl->Note2Period[portaTmp]; - + if (ch->WantPeriod == ch->RealPeriod) ch->PortaDir = 0; else if (ch->WantPeriod > ch->RealPeriod) @@ -1211,11 +1211,11 @@ static void fixTonePorta(PLAYER *pl, StmTyp *ch, TonTyp *p, uint8_t inst) } } } - + if (inst) { RetrigVolume(ch); - + if (p->Ton != 97) RetrigEnvelopeVibrato(ch); } @@ -1224,9 +1224,9 @@ static void fixTonePorta(PLAYER *pl, StmTyp *ch, TonTyp *p, uint8_t inst) static inline void GetNewNote(PLAYER *pl, StmTyp *ch, TonTyp *p) { uint8_t inst; - + ch->VolKolVol = p->Vol; - + if (!ch->EffTyp) { if (ch->Eff) @@ -1249,11 +1249,11 @@ static inline void GetNewNote(PLAYER *pl, StmTyp *ch, TonTyp *p) } } } - + ch->EffTyp = p->EffTyp; ch->Eff = p->Eff; ch->TonTyp = (p->Instr << 8) | p->Ton; - + /* 'inst' var is used for later if checks... */ inst = p->Instr; if (inst) @@ -1263,48 +1263,48 @@ static inline void GetNewNote(PLAYER *pl, StmTyp *ch, TonTyp *p) else inst = 0; } - + if (p->EffTyp == 0x0E) { if ((p->Eff >= 0xD1) && (p->Eff <= 0xDF)) return; /* we have a note delay (ED1..EDF) */ } - + if (!((p->EffTyp == 0x0E) && (p->Eff == 0x90))) /* E90 is 'retrig' speed 0 */ { if ((ch->VolKolVol & 0xF0) == 0xF0) /* gxx */ { if (ch->VolKolVol & 0x0F) ch->PortaSpeed = (int16_t)(ch->VolKolVol & 0x0F) << 6; - + fixTonePorta(pl, ch, p, inst); - + CheckEffects(pl, ch); return; } - + if ((p->EffTyp == 3) || (p->EffTyp == 5)) /* 3xx or 5xx */ { if ((p->EffTyp != 5) && p->Eff) ch->PortaSpeed = (int16_t)(p->Eff) << 2; - + fixTonePorta(pl, ch, p, inst); - + CheckEffects(pl, ch); return; } - + if ((p->EffTyp == 0x14) && !p->Eff) /* K00 (KeyOff) */ { KeyOff(ch); - + if (inst) RetrigVolume(ch); - + CheckEffects(pl, ch); return; } - + if (!p->Ton) { if (inst) @@ -1312,25 +1312,25 @@ static inline void GetNewNote(PLAYER *pl, StmTyp *ch, TonTyp *p) RetrigVolume(ch); RetrigEnvelopeVibrato(ch); } - + CheckEffects(pl, ch); return; } } - + if (p->Ton == 97) KeyOff(ch); else StartTone(pl, p->Ton, p->EffTyp, p->Eff, ch); - + if (inst) { RetrigVolume(ch); - + if (p->Ton != 97) RetrigEnvelopeVibrato(ch); } - + CheckEffects(pl, ch); } @@ -1577,33 +1577,33 @@ static int16_t RelocateTon(PLAYER *p, int16_t inPeriod, int8_t addNote, StmTyp * int16_t oldPeriod; int16_t addPeriod; - + int32_t outPeriod; - + oldPeriod = 0; addPeriod = (8 * 12 * 16) * 2; - + // safe signed 8-bit >>3 (FT2 exact even on non-x86 platforms) if (ch->FineTune >= 0) fineTune = ch->FineTune >> 2; else fineTune = (int8_t)(0xE0 | ((uint8_t)(ch->FineTune) >> 3)) * 2; - + for (i = 0; i < 8; ++i) { outPeriod = (((oldPeriod + addPeriod) >> 1) & 0xFFE0) + fineTune; if (outPeriod < fineTune) outPeriod += (1 << 8); - + if (outPeriod < 16) outPeriod = 16; - + if (inPeriod >= p->Note2Period[(outPeriod - 16) >> 1]) { outPeriod -= fineTune; if (outPeriod & 0x00010000) outPeriod = (outPeriod - (1 << 8)) & 0x0000FFE0; - + addPeriod = (int16_t)(outPeriod); } else @@ -1611,22 +1611,22 @@ static int16_t RelocateTon(PLAYER *p, int16_t inPeriod, int8_t addNote, StmTyp * outPeriod -= fineTune; if (outPeriod & 0x00010000) outPeriod = (outPeriod - (1 << 8)) & 0x0000FFE0; - + oldPeriod = (int16_t)(outPeriod); } } - + outPeriod = oldPeriod + fineTune; if (outPeriod < fineTune) outPeriod += (1 << 8); - + if (outPeriod < 0) outPeriod = 0; - + outPeriod += ((int16_t)(addNote) << 5); if (outPeriod >= ((((8 * 12 * 16) + 15) * 2) - 1)) outPeriod = ((8 * 12 * 16) + 15) * 2; - + return (p->Note2Period[outPeriod >> 1]); // 16-bit look-up, shift it down } @@ -1669,7 +1669,7 @@ static void Volume(StmTyp *ch) /* actually volume slide */ tmpEff = ch->Eff; if (!tmpEff) tmpEff = ch->VolSlideSpeed; - + ch->VolSlideSpeed = tmpEff; if (!(tmpEff & 0xF0)) @@ -1833,7 +1833,7 @@ static inline void DoEffects(PLAYER *p, StmTyp *ch) tmpEff = ch->Eff; if (!tmpEff) tmpEff = ch->PortaUpSpeed; - + ch->PortaUpSpeed = tmpEff; ch->RealPeriod -= ((int16_t)(tmpEff) << 2); @@ -1849,7 +1849,7 @@ static inline void DoEffects(PLAYER *p, StmTyp *ch) tmpEff = ch->Eff; if (!tmpEff) tmpEff = ch->PortaUpSpeed; - + ch->PortaUpSpeed = tmpEff; ch->RealPeriod += ((int16_t)(tmpEff) << 2); @@ -1963,7 +1963,7 @@ static inline void DoEffects(PLAYER *p, StmTyp *ch) if (ch->TonTyp & 0xFF00) RetrigVolume(ch); - + RetrigEnvelopeVibrato(ch); if ((ch->VolKolVol >= 0x10) && (ch->VolKolVol <= 0x50)) @@ -2014,7 +2014,7 @@ static inline void DoEffects(PLAYER *p, StmTyp *ch) tmpEff = ch->Eff; if (!tmpEff) tmpEff = ch->PanningSlideSpeed; - + ch->PanningSlideSpeed = tmpEff; if (!(ch->Eff & 0xF0)) @@ -2040,7 +2040,7 @@ static inline void DoEffects(PLAYER *p, StmTyp *ch) tmpEff = ch->Eff; if (!tmpEff) tmpEff = ch->TremorSave; - + ch->TremorSave = tmpEff; tremorSign = ch->TremorPos & 0x80; @@ -2074,7 +2074,7 @@ static void MainPlayer(PLAYER *p) /* periodically called from mixer */ uint8_t i; int8_t tickzero; - + #ifdef USE_VOL_RAMP int32_t rampStyle = p->rampStyle; #endif @@ -2124,15 +2124,15 @@ static void MainPlayer(PLAYER *p) /* periodically called from mixer */ if (p->Song.Timer == 1) { size_t playedRowsCount; - + p->Song.PattPos++; - + if (p->Song.PattDelTime) { p->Song.PattDelTime2 = p->Song.PattDelTime; p->Song.PattDelTime = 0; } - + if (p->Song.PattDelTime2) { p->Song.PattDelTime2--; @@ -2142,32 +2142,33 @@ static void MainPlayer(PLAYER *p) /* periodically called from mixer */ bit_array_clear(p->playedRows, p->Song.SongPos * 1024 + p->Song.PattPos); } } - + if (p->Song.PBreakFlag) { p->Song.PBreakFlag = 0; p->Song.PattPos = p->Song.PBreakPos; } - + for (playedRowsCount = 0; playedRowsCount < 1024 && p->playedRowsPatLoop[playedRowsCount] != 0xFFFF; ++playedRowsCount); - + if ((p->Song.PattPos >= p->Song.PattLen) || p->Song.PosJumpFlag) { int16_t oldSongPos = p->Song.SongPos; - + p->Song.PattPos = p->Song.PBreakPos; p->Song.PBreakPos = 0; p->Song.PosJumpFlag = 0; - + p->Song.SongPos++; if (p->Song.SongPos >= p->Song.Len) p->Song.SongPos = p->Song.RepS; - + p->Song.PattNr = p->Song.SongTab[p->Song.SongPos]; p->Song.PattLen = p->PattLens[p->Song.PattNr]; - + if (oldSongPos != p->Song.SongPos) { - for (size_t i = 0; i < playedRowsCount; ++i) + size_t i; + for (i = 0; i < playedRowsCount; ++i) bit_array_set(p->playedRows, oldSongPos * 1024 + p->playedRowsPatLoop[i]); memset(p->playedRowsPatLoop, 0xFF, playedRowsCount * 2); playedRowsCount = 0; @@ -2203,7 +2204,7 @@ static void MainPlayer(PLAYER *p) /* periodically called from mixer */ { int32_t ChNr = ch->Nr; memcpy(p->voice + SPARE_OFFSET + ChNr, p->voice + ChNr, sizeof (VOICE)); - + p->voice[SPARE_OFFSET + ChNr].faderDest = 0.0f; p->voice[SPARE_OFFSET + ChNr].faderDelta = (p->voice[SPARE_OFFSET + ChNr].faderDest - p->voice[SPARE_OFFSET + ChNr].fader) * p->f_samplesPerFrame010; @@ -2214,10 +2215,10 @@ static void MainPlayer(PLAYER *p) /* periodically called from mixer */ resampler_clear(p->resampler[TOTAL_VOICES + ChNr]); } #endif - + voiceSetSource(p, ch->Nr, s.Pek, s.Len, s.RepL, s.RepS + s.RepL, s.Typ & 3, s.Typ & 16, s.Typ & 32); voiceSetSamplePosition(p, ch->Nr, ch->SmpStartPos); - + #ifdef USE_VOL_RAMP if (rampStyle > 0) { @@ -2230,10 +2231,10 @@ static void MainPlayer(PLAYER *p) /* periodically called from mixer */ if (ch->Status & IS_Vol) voiceSetVolume(p, ch->Nr, ch->FinalVol, ch->FinalPan, ch->Status & IS_NyTon); - + if (ch->Status & IS_Period) voiceSetSamplingFrequency(p, ch->Nr, GetFrequenceValue(p, ch->FinalPeriod)); - + ch->Status = 0; } } @@ -2429,20 +2430,20 @@ static void Adpcm2Samp(uint8_t * sample, uint32_t length) { const int8_t *sampleDictionary; const uint8_t *sampleData; - + uint32_t samplePosition; int8_t lastDelta; - + uint8_t * sampleDataOut = (uint8_t *) malloc(length); if (!sampleDataOut) return; - + sampleDictionary = (const int8_t *)sample; sampleData = (uint8_t*)sampleDictionary + 16; - + samplePosition = 0; lastDelta = 0; - + while (samplePosition < length) { sampleDataOut[samplePosition] = GetAdpcmSample(sampleDictionary, sampleData, samplePosition, &lastDelta); @@ -2490,7 +2491,7 @@ static int8_t LoadInstrHeader(PLAYER *p, MEM *f, uint16_t i) InstrHeaderTyp ih; size_t size; - + memset(&ih, 0, InstrHeaderSize); mread_swap(&ih.InstrSize, 4, 1, f, 0, 3); @@ -2499,7 +2500,7 @@ static int8_t LoadInstrHeader(PLAYER *p, MEM *f, uint16_t i) ih.InstrSize = InstrHeaderSize; size = ih.InstrSize - 4; - + mread(ih.Name, min(size, 22), 1, f); if (size > 22) mread(&ih.Typ, min(size - 22, 1), 1, f); if (size > 23) mread_swap(&ih.AntSamp, min(size - 23, 2), 1, f, 0, 1); @@ -2743,18 +2744,18 @@ static int8_t LoadPatterns(PLAYER *p, MEM *f) static void ft2play_FreeSong(PLAYER *p) { p->Playing = 0; - + memset(p->voice, 0, sizeof (p->voice)); - + FreeMusic(p); - + p->ModuleLoaded = 0; } int8_t ft2play_LoadModule(void *_p, const uint8_t *buffer, size_t size) { uint16_t i; - + PLAYER *p = (PLAYER *)_p; MEM *f; @@ -2946,7 +2947,7 @@ static inline void voiceSetSamplePosition(PLAYER *p, uint8_t i, uint16_t value) v->samplePosition = 0; v->sampleData = NULL; } - + v->interpolating = 1; } @@ -2954,7 +2955,7 @@ static inline void voiceSetVolume(PLAYER *p, uint8_t i, float vol, uint8_t pan, { VOICE *v; v = &p->voice[i]; - + #ifdef USE_VOL_RAMP if (!note_on && p->rampStyle > 1) { @@ -2986,7 +2987,7 @@ static inline void mix8b(PLAYER *p, uint32_t ch, uint32_t samples) uint32_t j; const int8_t *sampleData; - + VOICE *v; float sample; @@ -3002,17 +3003,17 @@ static inline void mix8b(PLAYER *p, uint32_t ch, uint32_t samples) int8_t loopEnabled; int8_t loopBidi; int8_t loopingForward; - + int32_t interpolating; - + #ifdef USE_VOL_RAMP int32_t rampStyle = p->rampStyle; #endif - + void * resampler; v = &p->voice[ch]; - + sampleLength = v->sampleLength; sampleLoopLength = v->sampleLoopLength; sampleLoopEnd = v->sampleLoopEnd; @@ -3023,16 +3024,16 @@ static inline void mix8b(PLAYER *p, uint32_t ch, uint32_t samples) interpolating = v->interpolating; sampleData = v->sampleData; - + resampler = p->resampler[ch]; - + resampler_set_rate(resampler, v->incRate); for (j = 0; (j < samples) && (v->sampleData != NULL); ++j) { samplePosition = v->samplePosition; - while (interpolating && (resampler_get_free_count(resampler) || + while (interpolating > 0 && (resampler_get_free_count(resampler) || !resampler_get_sample_count(resampler))) { resampler_write_sample_fixed(resampler, sampleData[samplePosition], 8); @@ -3041,7 +3042,7 @@ static inline void mix8b(PLAYER *p, uint32_t ch, uint32_t samples) ++samplePosition; else --samplePosition; - + if (loopEnabled) { if (loopBidi) @@ -3071,15 +3072,22 @@ static inline void mix8b(PLAYER *p, uint32_t ch, uint32_t samples) } else if ((samplePosition < 0) || (samplePosition >= sampleLength)) { - interpolating = 0; + interpolating = -resampler_get_padding_size(); break; } } - + + while (interpolating < 0 && (resampler_get_free_count(resampler) || + !resampler_get_sample_count(resampler))) + { + resampler_write_sample_fixed(resampler, 0, 8); + ++interpolating; + } + v->samplePosition = samplePosition; v->loopingForward = loopingForward; v->interpolating = (int8_t)interpolating; - + if ( !resampler_get_sample_count(resampler) ) { resampler_clear(resampler); @@ -3089,12 +3097,12 @@ static inline void mix8b(PLAYER *p, uint32_t ch, uint32_t samples) sample = resampler_get_sample_float(resampler); resampler_remove_sample(resampler, 1); - + #ifdef USE_VOL_RAMP if (rampStyle > 0) { v->fader += v->faderDelta; - + if ((v->faderDelta > 0.0f) && (v->fader > v->faderDest)) { v->fader = v->faderDest; @@ -3105,20 +3113,20 @@ static inline void mix8b(PLAYER *p, uint32_t ch, uint32_t samples) resampler_clear(resampler); v->sampleData = NULL; } - + sample *= v->fader; } #endif - + sampleL = sample * v->volumeL; sampleR = sample * v->volumeR; - + #ifdef USE_VOL_RAMP if (rampStyle > 1) { v->volumeL += v->volDeltaL; v->volumeR += v->volDeltaR; - + if ((v->volDeltaL > 0.0f) && (v->volumeL > v->targetVolL)) { v->volumeL = v->targetVolL; @@ -3127,7 +3135,7 @@ static inline void mix8b(PLAYER *p, uint32_t ch, uint32_t samples) { v->volumeL = v->targetVolL; } - + if ((v->volDeltaR > 0.0f) && (v->volumeR > v->targetVolR)) { v->volumeR = v->targetVolR; @@ -3138,7 +3146,7 @@ static inline void mix8b(PLAYER *p, uint32_t ch, uint32_t samples) } } #endif - + p->masterBufferL[j] += sampleL; p->masterBufferR[j] += sampleR; } @@ -3147,34 +3155,34 @@ static inline void mix8b(PLAYER *p, uint32_t ch, uint32_t samples) static inline void mix8bstereo(PLAYER *p, uint32_t ch, uint32_t samples) { uint32_t j; - + const int8_t *sampleData; - + VOICE *v; - + float sampleL; float sampleR; - + int32_t sampleLength; int32_t sampleLoopEnd; int32_t sampleLoopLength; int32_t sampleLoopBegin; int32_t samplePosition; - + int8_t loopEnabled; int8_t loopBidi; int8_t loopingForward; - + int32_t interpolating; - + #ifdef USE_VOL_RAMP int32_t rampStyle = p->rampStyle; #endif - + void * resampler[2]; - + v = &p->voice[ch]; - + sampleLength = v->sampleLength; sampleLoopLength = v->sampleLoopLength; sampleLoopEnd = v->sampleLoopEnd; @@ -3183,31 +3191,31 @@ static inline void mix8bstereo(PLAYER *p, uint32_t ch, uint32_t samples) loopBidi = v->loopBidi; loopingForward = v->loopingForward; interpolating = v->interpolating; - + sampleData = v->sampleData; - + resampler[0] = p->resampler[ch]; resampler[1] = p->resampler[ch+TOTAL_VOICES]; - + resampler_set_rate(resampler[0], v->incRate); resampler_set_rate(resampler[1], v->incRate); - + for (j = 0; (j < samples) && (v->sampleData != NULL); ++j) { samplePosition = v->samplePosition; - - while (interpolating && (resampler_get_free_count(resampler[0]) || + + while (interpolating > 0 && (resampler_get_free_count(resampler[0]) || (!resampler_get_sample_count(resampler[0]) && !resampler_get_sample_count(resampler[1])))) { resampler_write_sample_fixed(resampler[0], sampleData[samplePosition], 8); resampler_write_sample_fixed(resampler[1], sampleData[sampleLength + samplePosition], 8); - + if (loopingForward) ++samplePosition; else --samplePosition; - + if (loopEnabled) { if (loopBidi) @@ -3237,15 +3245,24 @@ static inline void mix8bstereo(PLAYER *p, uint32_t ch, uint32_t samples) } else if ((samplePosition < 0) || (samplePosition >= sampleLength)) { - interpolating = 0; + interpolating = -resampler_get_padding_size(); break; } } - + + while (interpolating < 0 && (resampler_get_free_count(resampler[0]) || + (!resampler_get_sample_count(resampler[0]) && + !resampler_get_sample_count(resampler[1])))) + { + resampler_write_sample_fixed(resampler[0], 0, 8); + resampler_write_sample_fixed(resampler[1], 0, 8); + ++interpolating; + } + v->samplePosition = samplePosition; v->loopingForward = loopingForward; v->interpolating = (int8_t)interpolating; - + if ( !resampler_get_sample_count(resampler[0]) ) { resampler_clear(resampler[0]); @@ -3253,17 +3270,17 @@ static inline void mix8bstereo(PLAYER *p, uint32_t ch, uint32_t samples) v->sampleData = NULL; break; } - + sampleL = resampler_get_sample_float(resampler[0]); sampleR = resampler_get_sample_float(resampler[1]); resampler_remove_sample(resampler[0], 1); resampler_remove_sample(resampler[1], 1); - + #ifdef USE_VOL_RAMP if (rampStyle > 0) { v->fader += v->faderDelta; - + if ((v->faderDelta > 0.0f) && (v->fader > v->faderDest)) { v->fader = v->faderDest; @@ -3275,21 +3292,21 @@ static inline void mix8bstereo(PLAYER *p, uint32_t ch, uint32_t samples) resampler_clear(resampler[1]); v->sampleData = NULL; } - + sampleL *= v->fader; sampleR *= v->fader; } #endif - + sampleL *= v->volumeL; sampleR *= v->volumeR; - + #ifdef USE_VOL_RAMP if (rampStyle > 1) { v->volumeL += v->volDeltaL; v->volumeR += v->volDeltaR; - + if ((v->volDeltaL > 0.0f) && (v->volumeL > v->targetVolL)) { v->volumeL = v->targetVolL; @@ -3298,7 +3315,7 @@ static inline void mix8bstereo(PLAYER *p, uint32_t ch, uint32_t samples) { v->volumeL = v->targetVolL; } - + if ((v->volDeltaR > 0.0f) && (v->volumeR > v->targetVolR)) { v->volumeR = v->targetVolR; @@ -3309,7 +3326,7 @@ static inline void mix8bstereo(PLAYER *p, uint32_t ch, uint32_t samples) } } #endif - + p->masterBufferL[j] += sampleL; p->masterBufferR[j] += sampleR; } @@ -3318,35 +3335,35 @@ static inline void mix8bstereo(PLAYER *p, uint32_t ch, uint32_t samples) static inline void mix16b(PLAYER *p, uint32_t ch, uint32_t samples) { uint32_t j; - + const int16_t *sampleData; - + VOICE *v; - + float sample; float sampleL; float sampleR; - + int32_t sampleLength; int32_t sampleLoopEnd; int32_t sampleLoopLength; int32_t sampleLoopBegin; int32_t samplePosition; - + int8_t loopEnabled; int8_t loopBidi; int8_t loopingForward; - + int32_t interpolating; - + #ifdef USE_VOL_RAMP int32_t rampStyle = p->rampStyle; #endif - + void * resampler; - + v = &p->voice[ch]; - + sampleLength = v->sampleLength; sampleLoopLength = v->sampleLoopLength; sampleLoopEnd = v->sampleLoopEnd; @@ -3355,27 +3372,27 @@ static inline void mix16b(PLAYER *p, uint32_t ch, uint32_t samples) loopBidi = v->loopBidi; loopingForward = v->loopingForward; interpolating = v->interpolating; - + sampleData = (const int16_t *) v->sampleData; - + resampler = p->resampler[ch]; - + resampler_set_rate(resampler, v->incRate); - + for (j = 0; (j < samples) && (v->sampleData != NULL); ++j) { samplePosition = v->samplePosition; - - while (interpolating && (resampler_get_free_count(resampler) || + + while (interpolating > 0 && (resampler_get_free_count(resampler) || !resampler_get_sample_count(resampler))) { resampler_write_sample_fixed(resampler, sampleData[samplePosition], 16); - + if (loopingForward) ++samplePosition; else --samplePosition; - + if (loopEnabled) { if (loopBidi) @@ -3405,30 +3422,37 @@ static inline void mix16b(PLAYER *p, uint32_t ch, uint32_t samples) } else if ((samplePosition < 0) || (samplePosition >= sampleLength)) { - interpolating = 0; + interpolating = -resampler_get_padding_size(); break; } } - + + while (interpolating < 0 && (resampler_get_free_count(resampler) || + !resampler_get_sample_count(resampler))) + { + resampler_write_sample_fixed(resampler, 0, 16); + ++interpolating; + } + v->samplePosition = samplePosition; v->loopingForward = loopingForward; v->interpolating = (int8_t)interpolating; - + if ( !resampler_get_sample_count(resampler) ) { resampler_clear(resampler); v->sampleData = NULL; break; } - + sample = resampler_get_sample_float(resampler); resampler_remove_sample(resampler, 1); - + #ifdef USE_VOL_RAMP if (rampStyle > 0) { v->fader += v->faderDelta; - + if ((v->faderDelta > 0.0f) && (v->fader > v->faderDest)) { v->fader = v->faderDest; @@ -3439,20 +3463,20 @@ static inline void mix16b(PLAYER *p, uint32_t ch, uint32_t samples) resampler_clear(resampler); v->sampleData = NULL; } - + sample *= v->fader; } #endif - + sampleL = sample * v->volumeL; sampleR = sample * v->volumeR; - + #ifdef USE_VOL_RAMP if (rampStyle > 1) { v->volumeL += v->volDeltaL; v->volumeR += v->volDeltaR; - + if ((v->volDeltaL > 0.0f) && (v->volumeL > v->targetVolL)) { v->volumeL = v->targetVolL; @@ -3461,7 +3485,7 @@ static inline void mix16b(PLAYER *p, uint32_t ch, uint32_t samples) { v->volumeL = v->targetVolL; } - + if ((v->volDeltaR > 0.0f) && (v->volumeR > v->targetVolR)) { v->volumeR = v->targetVolR; @@ -3472,7 +3496,7 @@ static inline void mix16b(PLAYER *p, uint32_t ch, uint32_t samples) } } #endif - + p->masterBufferL[j] += sampleL; p->masterBufferR[j] += sampleR; } @@ -3481,34 +3505,34 @@ static inline void mix16b(PLAYER *p, uint32_t ch, uint32_t samples) static inline void mix16bstereo(PLAYER *p, uint32_t ch, uint32_t samples) { uint32_t j; - + const int16_t *sampleData; - + VOICE *v; - + float sampleL; float sampleR; - + int32_t sampleLength; int32_t sampleLoopEnd; int32_t sampleLoopLength; int32_t sampleLoopBegin; int32_t samplePosition; - + int8_t loopEnabled; int8_t loopBidi; int8_t loopingForward; - + int32_t interpolating; - + #ifdef USE_VOL_RAMP int32_t rampStyle = p->rampStyle; #endif - + void * resampler[2]; - + v = &p->voice[ch]; - + sampleLength = v->sampleLength; sampleLoopLength = v->sampleLoopLength; sampleLoopEnd = v->sampleLoopEnd; @@ -3517,31 +3541,31 @@ static inline void mix16bstereo(PLAYER *p, uint32_t ch, uint32_t samples) loopBidi = v->loopBidi; loopingForward = v->loopingForward; interpolating = v->interpolating; - + sampleData = (const int16_t *) v->sampleData; - + resampler[0] = p->resampler[ch]; resampler[1] = p->resampler[ch+TOTAL_VOICES]; - + resampler_set_rate(resampler[0], v->incRate); resampler_set_rate(resampler[1], v->incRate); - + for (j = 0; (j < samples) && (v->sampleData != NULL); ++j) { samplePosition = v->samplePosition; - - while (interpolating && (resampler_get_free_count(resampler[0]) || + + while (interpolating > 0 && (resampler_get_free_count(resampler[0]) || (!resampler_get_sample_count(resampler[0]) && !resampler_get_sample_count(resampler[1])))) { resampler_write_sample_fixed(resampler[0], sampleData[samplePosition], 16); resampler_write_sample_fixed(resampler[1], sampleData[sampleLength + samplePosition], 16); - + if (loopingForward) ++samplePosition; else --samplePosition; - + if (loopEnabled) { if (loopBidi) @@ -3571,15 +3595,24 @@ static inline void mix16bstereo(PLAYER *p, uint32_t ch, uint32_t samples) } else if ((samplePosition < 0) || (samplePosition >= sampleLength)) { - interpolating = 0; + interpolating = -resampler_get_padding_size(); break; } } - + + while (interpolating < 0 && (resampler_get_free_count(resampler[0]) || + (!resampler_get_sample_count(resampler[0]) && + !resampler_get_sample_count(resampler[1])))) + { + resampler_write_sample_fixed(resampler[0], 0, 16); + resampler_write_sample_fixed(resampler[1], 0, 16); + ++interpolating; + } + v->samplePosition = samplePosition; v->loopingForward = loopingForward; v->interpolating = (int8_t)interpolating; - + if ( !resampler_get_sample_count(resampler[0]) ) { resampler_clear(resampler[0]); @@ -3587,17 +3620,17 @@ static inline void mix16bstereo(PLAYER *p, uint32_t ch, uint32_t samples) v->sampleData = NULL; break; } - + sampleL = resampler_get_sample_float(resampler[0]); sampleR = resampler_get_sample_float(resampler[1]); resampler_remove_sample(resampler[0], 1); resampler_remove_sample(resampler[1], 1); - + #ifdef USE_VOL_RAMP if (rampStyle > 0) { v->fader += v->faderDelta; - + if ((v->faderDelta > 0.0f) && (v->fader > v->faderDest)) { v->fader = v->faderDest; @@ -3609,21 +3642,21 @@ static inline void mix16bstereo(PLAYER *p, uint32_t ch, uint32_t samples) resampler_clear(resampler[1]); v->sampleData = NULL; } - + sampleL *= v->fader; sampleR *= v->fader; } #endif - + sampleL *= v->volumeL; sampleR *= v->volumeR; - + #ifdef USE_VOL_RAMP if (rampStyle > 1) { v->volumeL += v->volDeltaL; v->volumeR += v->volDeltaR; - + if ((v->volDeltaL > 0.0f) && (v->volumeL > v->targetVolL)) { v->volumeL = v->targetVolL; @@ -3632,7 +3665,7 @@ static inline void mix16bstereo(PLAYER *p, uint32_t ch, uint32_t samples) { v->volumeL = v->targetVolL; } - + if ((v->volDeltaR > 0.0f) && (v->volumeR > v->targetVolR)) { v->volumeR = v->targetVolR; @@ -3643,7 +3676,7 @@ static inline void mix16bstereo(PLAYER *p, uint32_t ch, uint32_t samples) } } #endif - + p->masterBufferL[j] += sampleL; p->masterBufferR[j] += sampleR; } @@ -3711,25 +3744,25 @@ void ft2play_RenderFloat(void *_p, float *buffer, int32_t count) PLAYER * p = (PLAYER *)_p; int32_t samplesTodo; float * outputStream; - + if (p->Playing) { outputStream = buffer; - + while (count) { if (p->samplesLeft) { samplesTodo = (count < p->samplesLeft) ? count : p->samplesLeft; samplesTodo = (samplesTodo < p->soundBufferSize) ? samplesTodo : p->soundBufferSize; - + if (outputStream) { mixSampleBlock(p, outputStream, samplesTodo); - + outputStream += (samplesTodo << 1); } - + p->samplesLeft -= samplesTodo; count -= samplesTodo; } @@ -3737,7 +3770,7 @@ void ft2play_RenderFloat(void *_p, float *buffer, int32_t count) { if (p->Playing) MainPlayer(p); - + p->samplesLeft = p->samplesPerFrame; } } @@ -3793,15 +3826,15 @@ void * ft2play_Alloc(uint32_t _samplingFrequency, int8_t interpolation, int8_t r uint16_t i; int16_t noteVal; uint16_t noteIndex; - + PLAYER * p = (PLAYER *) calloc(1, sizeof(PLAYER)); - + if ( !p ) return NULL; - + p->samplesPerFrame = 882; p->numChannels = MAX_VOICES; - + p->outputFreq = _samplingFrequency; p->f_outputFreq = (float)(p->outputFreq); #ifdef USE_VOL_RAMP @@ -3814,7 +3847,7 @@ void * ft2play_Alloc(uint32_t _samplingFrequency, int8_t interpolation, int8_t r p->masterBufferR = (float *)(malloc(p->soundBufferSize * sizeof (float))); if ( !p->masterBufferL || !p->masterBufferR ) goto error; - + setSamplingInterpolation(p, interpolation); #ifdef USE_VOL_RAMP @@ -3829,43 +3862,43 @@ void * ft2play_Alloc(uint32_t _samplingFrequency, int8_t interpolation, int8_t r goto error; resampler_set_quality(p->resampler[i], interpolation); } - + /* allocate memory for pointers */ - + p->NilPatternLine = (TonTyp *)(calloc(sizeof (TonTyp), 256 * MAX_VOICES)); if (p->NilPatternLine == NULL) goto error; - + p->linearPeriods = (int16_t *)(malloc(sizeof (int16_t) * ((12 * 10 * 16) + 16))); if (p->linearPeriods == NULL) goto error; - + p->amigaPeriods = (int16_t *)(malloc(sizeof (int16_t) * ((12 * 10 * 16) + 16))); if (p->amigaPeriods == NULL) goto error; - + p->VibSineTab = (int8_t *)(malloc(256)); if (p->VibSineTab == NULL) goto error; - + p->PanningTab = (float *)(malloc(sizeof (float) * 257)); if (p->PanningTab == NULL) goto error; - + p->LogTab = (uint32_t *)(malloc(sizeof (uint32_t) * 768)); if (p->LogTab == NULL) goto error; - + /* generate tables */ - + /* generate log table (value-exact to its original table) */ for (i = 0; i < 768; ++i) p->LogTab[i] = (uint32_t)(floor(((256.0f * 8363.0f) * exp((float)(i) / 768.0f * logf(2.0f))) + 0.5f)); - + /* generate linear table (value-exact to its original table) */ for (i = 0; i < ((12 * 10 * 16) + 16); ++i) p->linearPeriods[i] = (((12 * 10 * 16) + 16) * 4) - (i << 2); - + /* generate amiga period table (value-exact to its original table, except for last 17 entries) */ noteIndex = 0; for (i = 0; i < 10; ++i) @@ -3879,7 +3912,7 @@ void * ft2play_Alloc(uint32_t _samplingFrequency, int8_t interpolation, int8_t r p->amigaPeriods[noteIndex++] = noteVal; } } - + /* interpolate between points (end-result is exact to FT2's end-result, except for last 17 entries) */ for (i = 0; i < (12 * 10 * 8) + 7; ++i) p->amigaPeriods[(i << 1) + 1] = (p->amigaPeriods[i << 1] + p->amigaPeriods[(i << 1) + 2]) >> 1; @@ -3895,19 +3928,19 @@ void * ft2play_Alloc(uint32_t _samplingFrequency, int8_t interpolation, int8_t r p->amigaPeriods[1928] = 0; p->amigaPeriods[1929] = 16; p->amigaPeriods[1930] = 32; p->amigaPeriods[1931] = 24; p->amigaPeriods[1932] = 16; p->amigaPeriods[1933] = 8; p->amigaPeriods[1934] = 0; p->amigaPeriods[1935] = 0; - + /* generate auto-vibrato table (value-exact to its original table) */ for (i = 0; i < 256; ++i) p->VibSineTab[i] = (int8_t)floorf((64.0f * sinf(((float)(-i) * (2.0f * 3.1415927f)) / 256.0f)) + 0.5f); - + /* generate FT2's pan table [round(65536*sqrt(n/256)) for n = 0...256] */ for (i = 0; i < 257; ++i) p->PanningTab[i] = sqrtf((float)(i) / 256.0f); p->playedRows = NULL; - + return p; - + error: ft2play_Free( p ); return NULL; @@ -3916,9 +3949,9 @@ error: void ft2play_Free(void *_p) { uint32_t i; - + PLAYER * p = (PLAYER *)_p; - + if (p->Playing) { if (p->playedRows) bit_array_destroy(p->playedRows); p->playedRows = NULL; @@ -3926,32 +3959,32 @@ void ft2play_Free(void *_p) if (p->masterBufferL) free(p->masterBufferL); p->masterBufferL = NULL; if (p->masterBufferR) free(p->masterBufferR); p->masterBufferR = NULL; } - + p->Playing = 0; - + ft2play_FreeSong(p); - + if (p->LogTab) free(p->LogTab); p->LogTab = NULL; if (p->PanningTab) free(p->PanningTab); p->PanningTab = NULL; if (p->VibSineTab) free(p->VibSineTab); p->VibSineTab = NULL; if (p->amigaPeriods) free(p->amigaPeriods); p->amigaPeriods = NULL; if (p->linearPeriods) free(p->linearPeriods); p->linearPeriods = NULL; if (p->NilPatternLine) free(p->NilPatternLine); p->NilPatternLine = NULL; - + for ( i = 0; i < TOTAL_VOICES * 2; ++i ) { if ( p->resampler[i] ) resampler_delete( p->resampler[i] ); p->resampler[i] = NULL; } - + free (p); } void ft2play_PlaySong(void *_p, int32_t startOrder) { PLAYER * p = (PLAYER *)_p; - + if (!p->ModuleLoaded) return; StopVoices(p); @@ -3961,17 +3994,17 @@ void ft2play_PlaySong(void *_p, int32_t startOrder) p->Playing = 1; setSamplesPerFrame(p, ((p->outputFreq * 5UL) / 2 / p->Song.Speed)); - + SetPos(p, (int16_t)startOrder, 0); - + p->Song.startOrder = (int16_t)startOrder; - + p->loopCount = 0; - + if (p->playedRows) bit_array_destroy(p->playedRows); p->playedRows = bit_array_create(1024 * (p->Song.Len ? p->Song.Len : 1)); bit_array_set(p->playedRows, startOrder * 1024); - + p->playedRowsPatLoop[0] = 0; memset(p->playedRowsPatLoop + 1, 0xFF, 1023 * 2); } @@ -3987,12 +4020,12 @@ static MEM *mopen(const uint8_t *src, size_t length) uint32_t a; uint8_t b[4]; } endian_test; - + if ((src == NULL) || (length <= 0)) return (NULL); b = (MEM *)(malloc(sizeof (MEM))); if (b == NULL) return (NULL); - + endian_test.a = 1; mopen_is_big_endian = endian_test.b[3]; @@ -4044,17 +4077,17 @@ static size_t mread_swap(void *buffer, size_t size, size_t count, MEM *buf, uint size_t wrcnt; ssize_t pcnt; uint8_t xor; - + if (buf == NULL) return (0); if (buf->_ptr == NULL) return (0); - + wrcnt = size * count; if ((size == 0) || buf->_eof) return (0); - + xor = mopen_is_big_endian ? be_xor : le_xor; - + pcnt = (buf->_cnt > wrcnt) ? wrcnt : buf->_cnt; - + if ( !xor ) memcpy(buffer, buf->_ptr, pcnt); else @@ -4064,17 +4097,17 @@ static size_t mread_swap(void *buffer, size_t size, size_t count, MEM *buf, uint for (i = 0; i < pcnt; i++) bbuffer[i ^ xor] = buf->_ptr[i]; } - + buf->_cnt -= pcnt; buf->_ptr += pcnt; - + if (buf->_cnt <= 0) { buf->_ptr = buf->_base + buf->_bufsiz; buf->_cnt = 0; buf->_eof = 1; } - + return (pcnt / size); } diff --git a/Frameworks/modplay/modplay/resampler.c b/Frameworks/modplay/modplay/resampler.c index 97d13ea3d..ed58bf2ac 100644 --- a/Frameworks/modplay/modplay/resampler.c +++ b/Frameworks/modplay/modplay/resampler.c @@ -303,6 +303,11 @@ static int resampler_output_delay(resampler *r) } } +int resampler_get_padding_size() +{ + return SINC_WIDTH - 1; +} + int resampler_ready(void *_r) { resampler * r = ( resampler * ) _r; diff --git a/Frameworks/modplay/modplay/resampler.h b/Frameworks/modplay/modplay/resampler.h index bf6352f1a..f43638a42 100644 --- a/Frameworks/modplay/modplay/resampler.h +++ b/Frameworks/modplay/modplay/resampler.h @@ -3,7 +3,6 @@ #define RESAMPLER_DECORATE modplay -// Ugglay #ifdef RESAMPLER_DECORATE #define PASTE(a,b) a ## b #define EVALUATE(a,b) PASTE(a,b) @@ -14,6 +13,7 @@ #define resampler_dup_inplace EVALUATE(RESAMPLER_DECORATE,_resampler_dup_inplace) #define resampler_set_quality EVALUATE(RESAMPLER_DECORATE,_resampler_set_quality) #define resampler_get_free_count EVALUATE(RESAMPLER_DECORATE,_resampler_get_free_count) +#define resampler_get_padding_size EVALUATE(RESAMPLER_DECORATE,_resampler_get_padding_size) #define resampler_write_sample EVALUATE(RESAMPLER_DECORATE,_resampler_write_sample) #define resampler_write_sample_fixed EVALUATE(RESAMPLER_DECORATE,_resampler_write_sample_fixed) #define resampler_set_rate EVALUATE(RESAMPLER_DECORATE,_resampler_set_rate) @@ -47,6 +47,7 @@ enum void resampler_set_quality(void *, int quality); int resampler_get_free_count(void *); +int resampler_get_padding_size(); void resampler_write_sample(void *, short sample); void resampler_write_sample_fixed(void *, int sample, unsigned char depth); void resampler_set_rate( void *, double new_factor ); diff --git a/Frameworks/modplay/modplay/st3play.c b/Frameworks/modplay/modplay/st3play.c index 6f7636e56..01ce364db 100644 --- a/Frameworks/modplay/modplay/st3play.c +++ b/Frameworks/modplay/modplay/st3play.c @@ -12,7 +12,7 @@ ** - Added S9E/S9F (non-ST3, play sample backwards/forwards) ** - Fixed a bug in setspd() in Amiga limit mode ** - Proper tracker handling for non-ST3 effects -** - Panbrello (Yxy) didn't set the panning at all (heh) +** - Panbrello (Yxy) didn't set the panning at all ** - Decodes ADPCM samples at load time instead of play time ** - Mxx (set cannel volume) didn't work correctly ** @@ -149,7 +149,7 @@ typedef struct int32_t sampleLoopEnd; int32_t samplePosition; int32_t sampleLoopLength; - + float incRate; float volume; float panningL; @@ -192,37 +192,35 @@ typedef struct int32_t aspdmin; uint32_t np_patseg; chn_t chn[32]; - + uint8_t mixingVolume; int32_t soundBufferSize; uint32_t outputFreq; - + #ifdef USE_VOL_RAMP VOICE voice[32 * 2]; - void *resampler[64 * 2]; #else VOICE voice[32]; - void *resampler[64]; #endif - + void *fmChip; void *fmResampler; - + const uint8_t *fmPatchTable[9]; uint8_t fmLastB0[9]; - - int8_t ** adpcmSamples; - + + int8_t **adpcmSamples; + float f_outputFreq; float f_masterVolume; - + #ifdef USE_VOL_RAMP float f_samplesPerFrame; float f_samplesPerFrameSharp; #endif - + int8_t samplingInterpolation; #ifdef USE_VOL_RAMP int8_t rampStyle; @@ -232,12 +230,12 @@ typedef struct int32_t samplesLeft; int8_t isMixing; uint32_t samplesPerFrame; - + // GLOBAL VARIABLES int8_t ModuleLoaded; int8_t MusicPaused; int8_t Playing; - + uint8_t *mseg; int8_t lastachannelused; int8_t tracker; @@ -254,9 +252,9 @@ typedef struct int8_t stereomode; uint8_t mastervol; uint32_t mseg_len; - + uint8_t muted[4]; - + uint32_t loopCount; uint8_t playedOrder[8192]; } PLAYER; @@ -501,13 +499,13 @@ void * st3play_Alloc(uint32_t outputFreq, int8_t interpolation, int8_t ramp_styl { int32_t i; PLAYER *p; - + p = (PLAYER *)(calloc(sizeof (PLAYER), 1)); if (p == NULL) return (0); resampler_init(); - + #ifdef USE_VOL_RAMP for (i = 0; i < (64 * 2); ++i) #else @@ -520,20 +518,20 @@ void * st3play_Alloc(uint32_t outputFreq, int8_t interpolation, int8_t ramp_styl st3play_Free(p); return (0); } - + resampler_set_quality(p->resampler[i], interpolation); } - + p->soundBufferSize = _soundBufferSize; p->masterBufferL = (float *)(malloc(p->soundBufferSize * sizeof (float))); p->masterBufferR = (float *)(malloc(p->soundBufferSize * sizeof (float))); - + if ((p->masterBufferL == NULL) || (p->masterBufferR == NULL)) { st3play_Free(p); return (0); } - + p->stereomode = 1; p->numChannels = 32; p->globalvol = 64; @@ -546,8 +544,8 @@ void * st3play_Alloc(uint32_t outputFreq, int8_t interpolation, int8_t ramp_styl #ifdef USE_VOL_RAMP setRampStyle(p, ramp_style); #endif - setSamplesPerFrame(p, ((outputFreq * 5UL) / 2 / 125)); - + setSamplesPerFrame(p, ((outputFreq * 5) / 2 / 125)); + return (p); } @@ -556,18 +554,18 @@ static int st3play_AdlibInit(PLAYER *p) p->fmChip = malloc(Chip_GetSize()); if (p->fmChip == NULL) return (-1); - + Chip_Init(p->fmChip); Chip_Setup(p->fmChip, 3579545 * 4, 49716); Chip_WriteReg(p->fmChip, 0x01, 0x20); // enable wave select, but rather pointless with dbopl - + p->fmResampler = resampler_create(); if (p->fmResampler == NULL) return (-1); - + resampler_set_quality(p->fmResampler, RESAMPLER_QUALITY_MAX); resampler_set_rate(p->fmResampler, 49716.0f / p->f_outputFreq); - + return (0); } @@ -578,13 +576,13 @@ void st3play_Free(void *_p) p = (PLAYER *)(_p); FreeSong(p); - + if (p->fmResampler) resampler_delete(p->fmResampler); - + if (p->fmChip) free(p->fmChip); - + #ifdef USE_VOL_RAMP for (i = 0; i < (64 * 2); ++i) #else @@ -594,7 +592,7 @@ void st3play_Free(void *_p) if (p->resampler[i]) resampler_delete(p->resampler[i]); } - + if (p->masterBufferL) free(p->masterBufferL); if (p->masterBufferR) free(p->masterBufferR); @@ -604,7 +602,7 @@ void st3play_Free(void *_p) static inline uint16_t get_le16(const void *_p) { const uint8_t *p; - + p = (const uint8_t *)(_p); return (p[0] | (p[1] << 8)); } @@ -612,7 +610,7 @@ static inline uint16_t get_le16(const void *_p) static inline void set_le16(void *_p, uint16_t v) { uint8_t *p; - + p = (uint8_t *)(_p); p[0] = (uint8_t)(v); p[1] = v >> 8; @@ -621,7 +619,7 @@ static inline void set_le16(void *_p, uint16_t v) static inline uint32_t get_le32(const void *_p) { const uint8_t *p; - + p = (const uint8_t *)(_p); return (p[0] | (p[1] << 8) | (p[2] << 16) | (p[3] << 24)); } @@ -629,7 +627,7 @@ static inline uint32_t get_le32(const void *_p) static inline void getlastnfo(PLAYER *p, chn_t *ch) { (void)(p); - + if (!ch->info) ch->info = ch->alastnfo; } @@ -645,19 +643,19 @@ static void settempo(PLAYER *p, uint16_t val) if (val > 32) { p->tempo = val; - setSamplesPerFrame(p, ((p->outputFreq * 5UL) / 2) / p->tempo); + setSamplesPerFrame(p, ((p->outputFreq * 5) / 2) / p->tempo); } } static void st3play_AdlibHertzTouch(PLAYER *p, uint8_t ch, int32_t Hertz, uint8_t keyoff) { int32_t Oct; - - for (Oct = 0; Hertz > 0x1FF; Oct++) - Hertz >>= 1; - + + for (Oct = 0; Hertz >= 512; Oct++) + Hertz /= 2; + Chip_WriteReg(p->fmChip, 0xA0 + ch, Hertz & 0xFF); - + p->fmLastB0[ch] = (keyoff ? 0 : 0x20) | ((Hertz >> 8) & 3) | ((Oct & 7) << 2); Chip_WriteReg(p->fmChip, 0xB0 + ch, p->fmLastB0[ch]); } @@ -666,21 +664,21 @@ static inline void setspd(PLAYER *p, uint8_t ch) { uint8_t adlibChannel; int32_t tmpspd; - + adlibChannel = (p->mseg[0x40 + ch] & 0x7F) - 16; p->chn[ch].achannelused |= 0x80; - + tmpspd = p->chn[ch].aspd; - + if (p->amigalimits) { if (p->chn[ch].aorgspd > p->aspdmax) p->chn[ch].aorgspd = p->aspdmax; if (p->chn[ch].aorgspd < p->aspdmin) p->chn[ch].aorgspd = p->aspdmin; - + if (p->chn[ch].aspd > p->aspdmax) p->chn[ch].aspd = p->aspdmax; } - + if ((p->tracker == SCREAM_TRACKER) || p->amigalimits) { if (tmpspd > p->aspdmax) @@ -692,22 +690,22 @@ static inline void setspd(PLAYER *p, uint8_t ch) if (tmpspd > 14317056) tmpspd = 14317056; } - + if (tmpspd == 0) { // cut channel voiceSetSamplingFrequency(p, ch, 0); return; } - + if (tmpspd < p->aspdmin) { tmpspd = p->aspdmin; - + if (p->amigalimits && (p->chn[ch].aspd < p->aspdmin)) p->chn[ch].aspd = p->aspdmin; } - + // ST3 actually uses 14317056 (3.579264MHz * 4) instead of 14317456 (8363*1712) if (tmpspd > 0) voiceSetSamplingFrequency(p, ch, 14317056 / tmpspd); @@ -719,17 +717,17 @@ static inline void setspd(PLAYER *p, uint8_t ch) static void st3play_AdlibTouch(PLAYER *p, uint8_t ch, const uint8_t * patch, uint8_t vol) { int32_t Operator; - + if (!patch) { patch = p->fmPatchTable[ch]; if (!patch) return; } - + p->fmPatchTable[ch] = patch; Operator = Adlib_PortBases[ch]; - + Chip_WriteReg(p->fmChip, 0x40 + Operator, (patch[2] & 0xC0) | (((int32_t)(patch[2] & 63) - 63) * vol + 63 * 64 - 32) / 64); Chip_WriteReg(p->fmChip, 0x43 + Operator, (patch[3] & 0xC0) | (((int32_t)(patch[3] & 63) - 63) * vol + 63 * 64 - 32) / 64); } @@ -737,10 +735,10 @@ static void st3play_AdlibTouch(PLAYER *p, uint8_t ch, const uint8_t * patch, uin static inline void setvol(PLAYER *p, uint8_t ch, uint8_t offset, uint8_t note_on) { uint8_t adlibChannel; - + adlibChannel = (p->mseg[0x40 + ch] & 0x7F) - 16; p->chn[ch].achannelused |= 0x80; - + #ifdef USE_VOL_RAMP voiceSetVolume(p, ch + offset, ((float)(p->chn[ch].avol) / 63.0f) * ((float)(p->chn[ch].chanvol) / 64.0f) * ((float)(p->globalvol) / 64.0f), note_on); #else @@ -763,8 +761,8 @@ static inline int16_t stnote2herz(PLAYER *p, uint8_t note) if (note == 254) return (0); - tmpnote = note & 0x0F; - tmpocta = note >> 0x04; + tmpnote = note & 0x0F; + tmpocta = note >> 4; // ST3 doesn't do this, but do it for safety if (tmpnote > 11) tmpnote = 11; @@ -778,11 +776,11 @@ static inline int16_t stnote2herz(PLAYER *p, uint8_t note) static inline int32_t scalec2spd(PLAYER *p, uint8_t ch, int32_t spd) { - spd *= 8363UL; + spd *= 8363; if (p->tracker == SCREAM_TRACKER) { - if ((spd >> 16) > p->chn[ch].ac2spd) + if ((spd / 65536) > p->chn[ch].ac2spd) return (32767); } @@ -812,7 +810,7 @@ static inline int32_t roundspd(PLAYER *p, uint8_t ch, int32_t spd) if (p->tracker == SCREAM_TRACKER) { - if ((newspd >> 16) >= 8363) + if ((newspd / 65536) >= 8363) return (spd); } @@ -820,11 +818,11 @@ static inline int32_t roundspd(PLAYER *p, uint8_t ch, int32_t spd) // find octave octa = 0; - lastspd = ((1712 * 8) + notespd[11]) >> 1; + lastspd = ((1712 * 8) + (907 * 16)) / 2;; while (newspd < lastspd) { octa++; - lastspd >>= 1; + lastspd /= 2; } // find note @@ -834,7 +832,7 @@ static inline int32_t roundspd(PLAYER *p, uint8_t ch, int32_t spd) if (p->tracker == SCREAM_TRACKER) lastspd = 32767; else - lastspd = 32767 * 2; // Might be wrong? Probably not + lastspd = 32767 * 2; while (newnote < 11) { @@ -851,11 +849,11 @@ static inline int32_t roundspd(PLAYER *p, uint8_t ch, int32_t spd) } // get new speed from new note - newspd = (uint32_t)(stnote2herz(p, (octa << 4) | (lastnote & 0x0F))) * 8363; + newspd = (stnote2herz(p, (octa << 4) | (lastnote & 0x0F))) * 8363; if (p->tracker == SCREAM_TRACKER) { - if ((newspd >> 16) >= p->chn[ch].ac2spd) + if ((newspd / 65536) >= p->chn[ch].ac2spd) return (spd); } @@ -867,14 +865,14 @@ static inline int32_t roundspd(PLAYER *p, uint8_t ch, int32_t spd) static int16_t neworder(PLAYER *p) { -skip: +newOrderSkip: p->np_ord++; - if ((p->mseg[0x60+(p->np_ord-1)]==255)||(p->np_ord>get_le16(&p->mseg[0x20]))) // end + if ((p->mseg[0x60 + (p->np_ord - 1)] == 255) || (p->np_ord > get_le16(&p->mseg[0x20]))) // end p->np_ord = 1; if (p->mseg[0x60 + (p->np_ord - 1)] == 254) // skip - goto skip; // avoid recursive calling + goto newOrderSkip; // avoid recursive calling p->np_pat = (int16_t)(p->mseg[0x60 + (p->np_ord - 1)]); p->np_patoff = -1; // force reseek @@ -896,7 +894,7 @@ static inline void seekpat(PLAYER *p) if (p->np_patoff == -1) // seek must be done { - p->np_patseg = (uint32_t)(get_le16(&p->mseg[p->patternadd + (p->np_pat << 1)])) << 4; + p->np_patseg = get_le16(&p->mseg[p->patternadd + (p->np_pat * 2)]) * 16; if (p->np_patseg) { j = 2; // skip packed pat len flag @@ -983,10 +981,10 @@ static inline uint8_t getnote(PLAYER *p) static void st3play_AdlibPatch(PLAYER *p, uint8_t ch, const uint8_t *patch) { int32_t Operator; - + Operator = Adlib_PortBases[ch]; p->fmPatchTable[ch] = patch; - + Chip_WriteReg(p->fmChip, 0x20 + Operator, patch[0]); Chip_WriteReg(p->fmChip, 0x60 + Operator, patch[4]); Chip_WriteReg(p->fmChip, 0x80 + Operator, patch[6]); @@ -1013,14 +1011,14 @@ static inline void doamiga(PLAYER *p, uint8_t ch) uint32_t inslen; uint32_t insrepbeg; uint32_t insrepend; - + #ifdef USE_VOL_RAMP uint8_t volassigned; #endif - + volassigned = 0; adlibChannel = (p->mseg[0x40 + ch] & 0x7F) - 16; - + if ((p->fmChip == NULL) || (p->fmResampler == NULL)) // safety check adlibChannel = 255; @@ -1031,13 +1029,13 @@ static inline void doamiga(PLAYER *p, uint8_t ch) if (p->chn[ch].ins <= get_le16(&p->mseg[0x22])) // added for safety reasons { - insdat = &p->mseg[(uint32_t)(get_le16(&p->mseg[p->instrumentadd + ((p->chn[ch].ins - 1) << 1)])) << 4]; + insdat = &p->mseg[get_le16(&p->mseg[p->instrumentadd + ((p->chn[ch].ins - 1) * 2)]) * 16]; if (insdat[0]) { - if (insdat[0] == 1 && adlibChannel >= 9) + if ((insdat[0] == 1) && (adlibChannel >= 9)) { p->chn[ch].ac2spd = get_le32(&insdat[0x20]); - + if ((p->tracker == OPENMPT) || (p->tracker == BEROTRACKER)) { if ((p->chn[ch].cmd == ('S' - 64)) && ((p->chn[ch].info & 0xF0) == 0x20)) @@ -1045,12 +1043,13 @@ static inline void doamiga(PLAYER *p, uint8_t ch) } p->chn[ch].avol = (int8_t)(insdat[0x1C]); - if (p->chn[ch].avol < 0) p->chn[ch].avol = 0; - if (p->chn[ch].avol > 63) p->chn[ch].avol = 63; + + if (p->chn[ch].avol < 0) p->chn[ch].avol = 0; + else if (p->chn[ch].avol > 63) p->chn[ch].avol = 63; p->chn[ch].aorgvol = p->chn[ch].avol; - insoffs = (uint32_t)(((uint32_t)(insdat[0x0D])<<16)|((uint16_t)(insdat[0x0F])<<8)|insdat[0x0E])<<4; + insoffs = ((insdat[0x0D] << 16) | (insdat[0x0F] << 8) | insdat[0x0E]) * 16; if (insoffs > p->mseg_len) insoffs = p->mseg_len; @@ -1080,14 +1079,14 @@ static inline void doamiga(PLAYER *p, uint8_t ch) memcpy(p->voice + 32 + (int32_t)(ch), p->voice + (int32_t)(ch), sizeof (VOICE)); p->voice[ch + 32].faderDest = 0.0f; p->voice[ch + 32].faderDelta = (p->voice[ch + 32].faderDest - p->voice[ch + 32].fader) * p->f_samplesPerFrameSharp; - + setvol(p, ch, 32, 0); - + resampler_dup_inplace(p->resampler[ch + 32], p->resampler[ch]); resampler_dup_inplace(p->resampler[ch + 32 + 64], p->resampler[ch + 64]); resampler_clear(p->resampler[ch]); resampler_clear(p->resampler[ch + 64]); - + if (p->chn[ch].vol != 255) { if (p->chn[ch].vol <= 64) @@ -1099,19 +1098,19 @@ static inline void doamiga(PLAYER *p, uint8_t ch) { p->chn[ch].surround = 0; voiceSetSurround(p, ch, 0); - - p->chn[ch].apanpos = (p->chn[ch].vol - 128) << 2; + + p->chn[ch].apanpos = (p->chn[ch].vol - 128) * 4; setpan(p, ch); } } - + setvol(p, ch, 0, 1); volassigned = 1; } else #endif setvol(p, ch, 0, 0); - + // This specific phase differs from what sound card driver you use in ST3... // GUS: Don't set new voice sample. SB: Set new voice sample. // Let's use the GUS model here. @@ -1125,7 +1124,7 @@ static inline void doamiga(PLAYER *p, uint8_t ch) insrepend - insrepbeg, insrepend, loop, insdat[0x1F] & 4, insdat[0x1F] & 2); } - + #ifdef USE_VOL_RAMP if (p->rampStyle > 0) { @@ -1137,10 +1136,10 @@ static inline void doamiga(PLAYER *p, uint8_t ch) } else if (insdat[0] == 2 && adlibChannel < 9) { - p->chn[ch].ac2spd = 8363 * 164 / 249; + p->chn[ch].ac2spd = (8363 * 164) / 249; p->chn[ch].avol = (int8_t)(insdat[0x1C]); p->chn[ch].aorgvol = p->chn[ch].avol; - + st3play_AdlibPatch(p, adlibChannel, &insdat[0x10]); voiceSetSource(p, ch, NULL, 0, 0, 0, 0, 0, 0); voiceSetSamplePosition(p, ch, 0); @@ -1164,7 +1163,7 @@ static inline void doamiga(PLAYER *p, uint8_t ch) } else { - p->chn[ch].astartoffset = (uint16_t)(p->chn[ch].info) << 8; + p->chn[ch].astartoffset = 256 * p->chn[ch].info; p->chn[ch].astartoffset00 = p->chn[ch].astartoffset; } } @@ -1198,7 +1197,7 @@ static inline void doamiga(PLAYER *p, uint8_t ch) { if ((p->chn[ch].cmd != ('G' - 64)) && (p->chn[ch].cmd != ('L' - 64))) voiceSetSamplePosition(p, ch, p->chn[ch].astartoffset); - + if ((p->tracker == OPENMPT) || (p->tracker == BEROTRACKER)) { voiceSetPlayBackwards(p, ch, 0); @@ -1206,19 +1205,19 @@ static inline void doamiga(PLAYER *p, uint8_t ch) voiceSetReadPosToEnd(p, ch); } } - + if (!p->chn[ch].aorgspd || ((p->chn[ch].cmd != ('G' - 64)) && (p->chn[ch].cmd != ('L' - 64)))) { p->chn[ch].aspd = scalec2spd(p, ch, stnote2herz(p, p->chn[ch].note)); p->chn[ch].aorgspd = p->chn[ch].aspd; p->chn[ch].avibcnt = 0; p->chn[ch].apancnt = 0; - + setspd(p, ch); } p->chn[ch].asldspd = scalec2spd(p, ch, stnote2herz(p, p->chn[ch].note)); - + if (adlibChannel < 9) { st3play_AdlibNoteOff(p, adlibChannel); @@ -1249,8 +1248,8 @@ static inline void doamiga(PLAYER *p, uint8_t ch) { p->chn[ch].surround = 0; voiceSetSurround(p, ch, 0); - - p->chn[ch].apanpos = (p->chn[ch].vol - 128) << 2; + + p->chn[ch].apanpos = (p->chn[ch].vol - 128) * 4; setpan(p, ch); } } @@ -1268,7 +1267,7 @@ static inline void donewnote(PLAYER *p, uint8_t ch, int8_t notedelayflag) { p->lastachannelused = ch + 1; - // hackish fix, fixes call_me_an_angel.s3m crash + // sanity fix if (p->lastachannelused > 31) p->lastachannelused = 31; } @@ -1305,7 +1304,7 @@ static inline void donotes(PLAYER *p) ch = getnote(p); if (ch == 255) break; // end of row/channels - if ((p->mseg[0x40 + ch] & 0x7F) <= 15 + 9) + if ((p->mseg[0x40 + ch] & 0x7F) <= (15 + 9)) donewnote(p, ch, 0); } } @@ -1328,16 +1327,13 @@ static inline void docmd1(PLAYER *p) if (p->chn[i].cmd == ('D' - 64)) { - // THEORY: I think this fix is related to - // AdLib channels... - // fix retrig if Dxy p->chn[i].atrigcnt = 0; // fix speed if tone port noncomplete if (p->chn[i].aspd != p->chn[i].aorgspd) { - p->chn[i].aspd = p->chn[i].aorgspd; + p->chn[i].aspd = p->chn[i].aorgspd; setspd(p, i); } } @@ -1375,7 +1371,7 @@ static inline void docmd1(PLAYER *p) { // NON-ST3 if (p->tracker != SCREAM_TRACKER) - { + { // recalc pans setpan(p, i); voiceSetSurround(p, i, p->chn[i].surround); @@ -1420,9 +1416,10 @@ static inline void docmd2(PLAYER *p) void dorow(PLAYER *p) // periodically called from mixer { - int32_t offset, bit; - - p->patmusicrand = (uint16_t)(((uint32_t)(p->patmusicrand) * 0xCDEF) >> 16) + 0x1727; + int8_t offset; + int8_t bit; + + p->patmusicrand = (((p->patmusicrand * 0xCDEF) >> 16) + 0x1727) & 0x0000FFFF; if (!p->musiccount) { @@ -1474,18 +1471,18 @@ void dorow(PLAYER *p) // periodically called from mixer p->x_np_ord = p->np_ord; p->x_np_row = p->np_row; p->x_np_pat = p->np_pat; - + if (p->np_row == 0) { offset = (p->np_ord - 1) / 8; bit = 1 << ((p->np_ord - 1) % 8); - + if (p->playedOrder[offset] & bit) { p->loopCount++; memset(p->playedOrder, 0, sizeof (p->playedOrder)); } - + p->playedOrder[offset] |= bit; } @@ -1496,27 +1493,28 @@ void dorow(PLAYER *p) // periodically called from mixer static inline int8_t get_adpcm_sample(const int8_t *sampleDictionary, const uint8_t *sampleData, int32_t samplePosition, int8_t *lastDelta) { uint8_t byte; - - byte = sampleData[samplePosition >> 1]; - byte = (samplePosition & 1) ? byte >> 4 : byte & 15; - return *lastDelta += sampleDictionary[byte]; + + byte = sampleData[samplePosition / 2]; + byte = (samplePosition & 1) ? (byte >> 4) : (byte & 0x0F); + + return (*(lastDelta) += sampleDictionary[byte]); } - -static inline void decode_adpcm(const uint8_t * sampleData, int8_t * decodedSampleData, int32_t sampleLength) + +static inline void decode_adpcm(const uint8_t *sampleData, int8_t *decodedSampleData, int32_t sampleLength) { - int i; - int8_t lastDelta, sample; - const int8_t * sampleDictionary; - + int32_t i; + int8_t lastDelta; + int8_t sample; + const int8_t *sampleDictionary; + sampleDictionary = (const int8_t *)(sampleData); sampleData += 16; - + lastDelta = 0; - for (i = 0; i < sampleLength; ++i) { sample = get_adpcm_sample(sampleDictionary, sampleData, i, &lastDelta); - + *decodedSampleData++ = sample; } } @@ -1577,7 +1575,7 @@ static void loadheaderparms(PLAYER *p) p->fastvolslide = p->mseg[0x26] & 0x40; if (p->amigalimits) - { + { p->aspdmax = 1712 * 2; p->aspdmin = 907 / 2; } @@ -1588,7 +1586,7 @@ static void loadheaderparms(PLAYER *p) p->fastvolslide = 1; p->oldstvib = p->mseg[0x26] & 0x01; - + if (*((uint16_t *)(&p->mseg[0x2A]))) { // we have unsigned samples, convert to signed @@ -1596,8 +1594,8 @@ static void loadheaderparms(PLAYER *p) insnum = get_le16(&p->mseg[0x22]); for (i = 0; i < insnum; ++i) { - insdat = &p->mseg[get_le16(&p->mseg[p->instrumentadd + (i << 1)]) << 4]; - insoff = (uint32_t)(((uint32_t)(insdat[0x0D])<<16)|((uint16_t)(insdat[0x0F])<<8)|insdat[0x0E])<<4; + insdat = &p->mseg[get_le16(&p->mseg[p->instrumentadd + (i * 2)]) * 16]; + insoff = ((insdat[0x0D] << 16) | (insdat[0x0F] << 8) | insdat[0x0E]) * 16; if (insoff && (insdat[0] == 1)) // PCM { @@ -1605,11 +1603,12 @@ static void loadheaderparms(PLAYER *p) insoff = p->mseg_len; inslen = get_le32(&insdat[0x10]); - + if (insdat[0x1E] == 4) // modplug packed { if (p->adpcmSamples == NULL) p->adpcmSamples = (int8_t **)(calloc(sizeof(int8_t *), insnum)); + if (p->adpcmSamples) { p->adpcmSamples[i] = (int8_t *)(calloc(1, inslen)); @@ -1617,28 +1616,32 @@ static void loadheaderparms(PLAYER *p) { if ((insoff + (16 + (inslen + 1) / 2)) > p->mseg_len) inslen = ((p->mseg_len - insoff) - 16) * 2; + if (inslen >= 1) decode_adpcm(&p->mseg[insoff], p->adpcmSamples[i], inslen); } } + continue; } - if (insdat[0x1F] & 2) inslen <<= 1; // stereo + if (insdat[0x1F] & 2) inslen *= 2; // stereo if (insdat[0x1F] & 4) { // 16-bit - if (insoff + inslen * 2 > p->mseg_len) + if ((insoff + (inslen * 2)) > p->mseg_len) inslen = (p->mseg_len - insoff) / 2; + for (j = 0; j < inslen; ++j) - set_le16(&p->mseg[insoff + (j << 1)], get_le16(&p->mseg[insoff + (j << 1)]) - 0x8000); + set_le16(&p->mseg[insoff + (j * 2)], get_le16(&p->mseg[insoff + (j * 2)]) - 0x8000); } else { // 8-bit - if (insoff + inslen > p->mseg_len) + if ((insoff + inslen) > p->mseg_len) inslen = p->mseg_len - insoff; + for (j = 0; j < inslen; ++j) p->mseg[insoff + j] = p->mseg[insoff + j] - 0x80; } @@ -1655,6 +1658,8 @@ static void loadheaderparms(PLAYER *p) void st3play_PlaySong(void *_p, int16_t startOrder) { uint8_t i; + int8_t offset; + int8_t bit; uint8_t dat; int16_t pan; PLAYER *p; @@ -1674,28 +1679,29 @@ void st3play_PlaySong(void *_p, int16_t startOrder) for (i = 0; i < 32; ++i) { pan = (p->mseg[0x33] & 0x80) ? ((p->mseg[0x40 + i] & 0x08) ? 192 : 64) : 128; + if (p->mseg[0x35] == 0xFC) // non-default pannings follow { - dat = p->mseg[(p->patternadd + (get_le16(&p->mseg[0x24]) << 1)) + i]; + dat = p->mseg[(p->patternadd + (get_le16(&p->mseg[0x24]) * 2)) + i]; if (dat & 0x20) - pan = (dat & 0x0F) << 4; + pan = (dat & 0x0F) * 16; } - if (p->stereomode) - p->chn[i].apanpos = pan; - else - p->chn[i].apanpos = 128; - + p->chn[i].apanpos = p->stereomode ? pan : 128; voiceSetPanning(p, i, pan); } p->Playing = 1; - setSamplesPerFrame(p, ((p->outputFreq * 5UL) / 2 / p->tempo)); + setSamplesPerFrame(p, ((p->outputFreq * 5) / 2 / p->tempo)); p->isMixing = 1; - + p->loopCount = 0; memset(p->playedOrder, 0, sizeof (p->playedOrder)); - p->playedOrder[startOrder / 8] = 1 << (startOrder % 8); + + offset = startOrder / 8; + bit = 1 << (startOrder % 8); + + p->playedOrder[offset] = bit; } int8_t st3play_LoadModule(void *_p, const uint8_t *module, size_t size) @@ -1703,7 +1709,7 @@ int8_t st3play_LoadModule(void *_p, const uint8_t *module, size_t size) char SCRM[4]; uint16_t i; PLAYER *p; - + p = (PLAYER *)(_p); if (p->ModuleLoaded) FreeSong(p); @@ -1738,7 +1744,7 @@ int8_t st3play_LoadModule(void *_p, const uint8_t *module, size_t size) p->mseg_len = (uint32_t)(size); p->instrumentadd = 0x60 + p->mseg[0x20]; - p->patternadd = p->instrumentadd + (p->mseg[0x22] << 1); + p->patternadd = p->instrumentadd + (p->mseg[0x22] * 2); p->tickdelay = 0; p->musiccount = 0; p->patterndelay = 0; @@ -1807,7 +1813,7 @@ static void s_setfinetune(PLAYER *p, chn_t *ch) // this function does nothing in ST3 and many other trackers if ((p->tracker == OPENMPT) || (p->tracker == BEROTRACKER)) ch->ac2spd = xfinetune_amiga[ch->info & 0x0F]; -} +} static void s_setvibwave(PLAYER *p, chn_t *ch) { @@ -1832,7 +1838,8 @@ static void s_tickdelay(PLAYER *p, chn_t *ch) // NON-ST3 if ( (p->tracker == OPENMPT) || (p->tracker == BEROTRACKER) || (p->tracker == IMPULSE_TRACKER) - || (p->tracker == SCHISM_TRACKER)) + || (p->tracker == SCHISM_TRACKER) + ) { p->tickdelay += (ch->info & 0x0F); } @@ -1842,8 +1849,8 @@ static void s_setpanpos(PLAYER *p, chn_t *ch) { ch->surround = 0; voiceSetSurround(p, ch->channelnum, 0); - - ch->apanpos = (ch->info & 0x0F) << 4; + + ch->apanpos = (ch->info & 0x0F) * 16; setpan(p, ch->channelnum); } @@ -1879,6 +1886,9 @@ static void s_sndcntrl(PLAYER *p, chn_t *ch) // NON-ST3 static void s_patloop(PLAYER *p, chn_t *ch) { + int8_t offset; + int8_t bit; + if (!(ch->info & 0x0F)) { p->patloopstart = p->np_row; @@ -1898,9 +1908,14 @@ static void s_patloop(PLAYER *p, chn_t *ch) p->patloopcount--; p->jumptorow = p->patloopstart; p->np_patoff = -1; // force reseek - - if (p->patloopstart == 0) - p->playedOrder[(p->np_ord - 1) / 8] &= ~(1 << ((p->np_ord - 1) % 8)); + + if (p->patloopstart == 0) + { + offset = (p->np_ord - 1) / 8; + bit = 1 << ((p->np_ord - 1) % 8); + + p->playedOrder[offset] &= ~bit; + } } else { @@ -1925,9 +1940,9 @@ static void s_notecutb(PLAYER *p, chn_t *ch) if (!ch->anotecutcnt) { adlibChannel = (p->mseg[0x40 + ch->channelnum] & 0x7F) - 16; - + voiceSetSamplingFrequency(p, ch->channelnum, 0); // cut note - + if (adlibChannel < 9) st3play_AdlibNoteOff(p, adlibChannel); } @@ -1963,7 +1978,7 @@ static void s_setspeed(PLAYER *p, chn_t *ch) static void s_jmpto(PLAYER *p, chn_t *ch) { - if (ch->info != 255) + if (ch->info != 0xFF) { p->breakpat = 1; p->np_ord = ch->info; @@ -1987,8 +2002,8 @@ static void s_volslide(PLAYER *p, chn_t *ch) getlastnfo(p, ch); - infohi = ch->info >> 0x04; - infolo = ch->info & 0x0F; + infohi = ch->info >> 4; + infolo = ch->info & 0x0F; if (infolo == 0x0F) { @@ -2016,15 +2031,13 @@ static void s_volslide(PLAYER *p, chn_t *ch) return; // illegal slide } - if (ch->avol < 0) ch->avol = 0; - if (ch->avol > 63) ch->avol = 63; + if (ch->avol < 0) ch->avol = 0; + else if (ch->avol > 63) ch->avol = 63; setvol(p, ch->channelnum, 0, 0); - if (p->volslidetype == 1) - s_vibrato(p, ch); - else if (p->volslidetype == 2) - s_toneslide(p, ch); + if (p->volslidetype == 1) s_vibrato(p, ch); + else if (p->volslidetype == 2) s_toneslide(p, ch); } static void s_slidedown(PLAYER *p, chn_t *ch) @@ -2037,7 +2050,7 @@ static void s_slidedown(PLAYER *p, chn_t *ch) { if (ch->info >= 0xE0) return; // no fine slides here - ch->aspd += ((uint16_t)(ch->info) << 2); + ch->aspd += (ch->info * 4); if (ch->aspd > 32767) ch->aspd = 32767; } else @@ -2051,7 +2064,7 @@ static void s_slidedown(PLAYER *p, chn_t *ch) } else { - ch->aspd += ((ch->info & 0x0F) << 2); + ch->aspd += ((ch->info & 0x0F) * 4); if (ch->aspd > 32767) ch->aspd = 32767; } } @@ -2071,7 +2084,7 @@ static void s_slideup(PLAYER *p, chn_t *ch) { if (ch->info >= 0xE0) return; // no fine slides here - ch->aspd -= ((uint16_t)(ch->info) << 2); + ch->aspd -= (ch->info * 4); if (ch->aspd < 0) ch->aspd = 0; } else @@ -2085,7 +2098,7 @@ static void s_slideup(PLAYER *p, chn_t *ch) } else { - ch->aspd -= ((ch->info & 0x0F) << 2); + ch->aspd -= ((ch->info & 0x0F) * 4); if (ch->aspd < 0) ch->aspd = 0; } } @@ -2122,13 +2135,13 @@ static void s_toneslide(PLAYER *p, chn_t *ch) { if (ch->aorgspd < ch->asldspd) { - ch->aorgspd += ((uint16_t)(ch->info) << 2); + ch->aorgspd += (ch->info * 4); if (ch->aorgspd > ch->asldspd) ch->aorgspd = ch->asldspd; } else { - ch->aorgspd -= ((uint16_t)(ch->info) << 2); + ch->aorgspd -= (ch->info * 4); if (ch->aorgspd < ch->asldspd) ch->aorgspd = ch->asldspd; } @@ -2180,7 +2193,7 @@ static void s_vibrato(PLAYER *p, chn_t *ch) if (cnt & 0x80) cnt = 0; } - dat = vibsin[cnt >> 1]; + dat = vibsin[cnt / 2]; } // ramp @@ -2195,7 +2208,7 @@ static void s_vibrato(PLAYER *p, chn_t *ch) if (cnt & 0x80) cnt = 0; } - dat = vibramp[cnt >> 1]; + dat = vibramp[cnt / 2]; } // square @@ -2210,7 +2223,7 @@ static void s_vibrato(PLAYER *p, chn_t *ch) if (cnt & 0x80) cnt = 0; } - dat = vibsqu[cnt >> 1]; + dat = vibsqu[cnt / 2]; } // random @@ -2225,7 +2238,7 @@ static void s_vibrato(PLAYER *p, chn_t *ch) if (cnt & 0x80) cnt = 0; } - dat = (int32_t)(vibsin[cnt >> 1]); + dat = vibsin[cnt / 2]; cnt += (p->patmusicrand & 0x1E); } @@ -2243,7 +2256,7 @@ static void s_vibrato(PLAYER *p, chn_t *ch) ch->aspd = dat; setspd(p, ch->channelnum); - ch->avibcnt = (cnt + ((ch->info >> 4) << 1)) & 0x7E; + ch->avibcnt = (cnt + ((ch->info >> 4) * 2)) & 0x7E; } } @@ -2286,17 +2299,16 @@ static void s_arp(PLAYER *p, chn_t *ch) getlastnfo(p, ch); - tick = p->musiccount % 3; - noteadd = 0; + tick = p->musiccount % 3; - if (tick == 1) - noteadd = ch->info >> 4; - else if (tick == 2) - noteadd = ch->info & 0x0F; + if (tick == 1) noteadd = ch->info >> 4; + else if (tick == 2) noteadd = ch->info & 0x0F; + else noteadd = 0; // check for octave overflow octa = ch->lastnote & 0xF0; note = (ch->lastnote & 0x0F) + noteadd; + while (note >= 12) { note -= 12; @@ -2313,7 +2325,7 @@ static void s_chanvol(PLAYER *p, chn_t *ch) // NON-ST3 { if (ch->info <= 0x40) ch->chanvol = ch->info; - + setvol(p, ch->channelnum, 0, 0); } } @@ -2330,8 +2342,8 @@ static void s_chanvolslide(PLAYER *p, chn_t *ch) // NON-ST3 else ch->info = ch->nxymem; - infohi = ch->nxymem >> 0x04; - infolo = ch->nxymem & 0x0F; + infohi = ch->nxymem >> 4; + infolo = ch->nxymem & 0x0F; if (infolo == 0x0F) { @@ -2359,8 +2371,8 @@ static void s_chanvolslide(PLAYER *p, chn_t *ch) // NON-ST3 return; // illegal slide } - if (ch->chanvol < 0) ch->chanvol = 0; - if (ch->chanvol > 64) ch->chanvol = 64; + if (ch->chanvol < 0) ch->chanvol = 0; + else if (ch->chanvol > 64) ch->chanvol = 64; setvol(p, ch->channelnum, 0, 0); } @@ -2390,37 +2402,37 @@ static void s_panslide(PLAYER *p, chn_t *ch) // NON-ST3 else ch->info = ch->pxymem; - infohi = ch->pxymem >> 0x04; - infolo = ch->pxymem & 0x0F; + infohi = ch->pxymem >> 4; + infolo = ch->pxymem & 0x0F; if (infolo == 0x0F) { if (!infohi) - ch->apanpos += (infolo << 2); + ch->apanpos += (infolo * 4); else if (!p->musiccount) - ch->apanpos -= (infohi << 2); + ch->apanpos -= (infohi * 4); } else if (infohi == 0x0F) { if (!infolo) - ch->apanpos -= (infohi << 2); + ch->apanpos -= (infohi * 4); else if (!p->musiccount) - ch->apanpos += (infolo << 2); + ch->apanpos += (infolo * 4); } else if (p->musiccount) // don't rely on fastvolslide flag here { if (!infolo) - ch->apanpos -= (infohi << 2); + ch->apanpos -= (infohi * 4); else - ch->apanpos += (infolo << 2); + ch->apanpos += (infolo * 4); } else { return; // illegal slide } - if (ch->apanpos < 0) ch->apanpos = 0; - if (ch->apanpos > 256) ch->apanpos = 256; + if (ch->apanpos < 0) ch->apanpos = 0; + else if (ch->apanpos > 256) ch->apanpos = 256; setpan(p, ch->channelnum); } @@ -2431,7 +2443,7 @@ static void s_retrig(PLAYER *p, chn_t *ch) uint8_t infohi; getlastnfo(p, ch); - infohi = ch->info >> 0x04; + infohi = ch->info >> 4; if (!(ch->info & 0x0F) || (ch->atrigcnt < (ch->info & 0x0F))) { @@ -2447,10 +2459,10 @@ static void s_retrig(PLAYER *p, chn_t *ch) if (!retrigvoladd[16 + infohi]) ch->avol += retrigvoladd[infohi]; else - ch->avol = (int8_t)(((int16_t)(ch->avol) * retrigvoladd[16 + infohi]) >> 4); + ch->avol = (int8_t)((ch->avol * retrigvoladd[16 + infohi]) / 16); - if (ch->avol > 63) ch->avol = 63; - if (ch->avol < 0) ch->avol = 0; + if (ch->avol > 63) ch->avol = 63; + else if (ch->avol < 0) ch->avol = 0; setvol(p, ch->channelnum, 0, 0); @@ -2487,7 +2499,7 @@ static void s_tremolo(PLAYER *p, chn_t *ch) if (cnt & 0x80) cnt = 0; } - dat = vibsin[cnt >> 1]; + dat = vibsin[cnt / 2]; } // ramp @@ -2502,7 +2514,7 @@ static void s_tremolo(PLAYER *p, chn_t *ch) if (cnt & 0x80) cnt = 0; } - dat = vibramp[cnt >> 1]; + dat = vibramp[cnt / 2]; } // square @@ -2517,7 +2529,7 @@ static void s_tremolo(PLAYER *p, chn_t *ch) if (cnt & 0x80) cnt = 0; } - dat = vibsqu[cnt >> 1]; + dat = vibsqu[cnt / 2]; } // random @@ -2532,7 +2544,7 @@ static void s_tremolo(PLAYER *p, chn_t *ch) if (cnt & 0x80) cnt = 0; } - dat = vibsin[cnt >> 1]; + dat = vibsin[cnt / 2]; cnt += (p->patmusicrand & 0x1E); } @@ -2543,13 +2555,14 @@ static void s_tremolo(PLAYER *p, chn_t *ch) } dat = ((dat * (ch->info & 0x0F)) >> 7) + ch->aorgvol; - if (dat > 63) dat = 63; - if (dat < 0) dat = 0; + + if (dat > 63) dat = 63; + else if (dat < 0) dat = 0; ch->avol = (int8_t)(dat); setvol(p, ch->channelnum, 0, 0); - ch->avibcnt = (cnt + ((ch->info >> 4) << 1)) & 0x7E; + ch->avibcnt = (cnt + ((ch->info >> 4) * 2)) & 0x7E; } } @@ -2632,7 +2645,7 @@ static void s_finevibrato(PLAYER *p, chn_t *ch) if (cnt & 0x80) cnt = 0; } - dat = vibsin[cnt >> 1]; + dat = vibsin[cnt / 2]; } // ramp @@ -2647,7 +2660,7 @@ static void s_finevibrato(PLAYER *p, chn_t *ch) if (cnt & 0x80) cnt = 0; } - dat = vibramp[cnt >> 1]; + dat = vibramp[cnt / 2]; } // square @@ -2662,7 +2675,7 @@ static void s_finevibrato(PLAYER *p, chn_t *ch) if (cnt & 0x80) cnt = 0; } - dat = vibsqu[cnt >> 1]; + dat = vibsqu[cnt / 2]; } // random @@ -2677,7 +2690,7 @@ static void s_finevibrato(PLAYER *p, chn_t *ch) if (cnt & 0x80) cnt = 0; } - dat = vibsin[cnt >> 1]; + dat = vibsin[cnt / 2]; cnt += (p->patmusicrand & 0x1E); } @@ -2695,7 +2708,7 @@ static void s_finevibrato(PLAYER *p, chn_t *ch) ch->aspd = dat; setspd(p, ch->channelnum); - ch->avibcnt = (cnt + ((ch->info >> 4) << 1)) & 0x7E; + ch->avibcnt = (cnt + ((ch->info >> 4) * 2)) & 0x7E; } } @@ -2718,8 +2731,8 @@ static void s_globvolslide(PLAYER *p, chn_t *ch) // NON-ST3 else ch->info = ch->wxymem; - infohi = ch->wxymem >> 0x04; - infolo = ch->wxymem & 0x0F; + infohi = ch->wxymem >> 4; + infolo = ch->wxymem & 0x0F; if (infolo == 0x0F) { @@ -2747,11 +2760,12 @@ static void s_globvolslide(PLAYER *p, chn_t *ch) // NON-ST3 return; // illegal slide } - if (p->globalvol < 0) p->globalvol = 0; - if (p->globalvol > 64) p->globalvol = 64; + if (p->globalvol < 0) p->globalvol = 0; + else if (p->globalvol > 64) p->globalvol = 64; // update all channels now - for (i = 0; i < (p->lastachannelused + 1); ++i) setvol(p, i, 0, 0); + for (i = 0; i < (p->lastachannelused + 1); ++i) + setvol(p, i, 0, 0); } } @@ -2764,8 +2778,8 @@ static void s_setpan(PLAYER *p, chn_t *ch) // NON-ST3 { ch->surround = 0; voiceSetSurround(p, ch->channelnum, 0); - - ch->apanpos = (int16_t)(ch->info) << 1; + + ch->apanpos = ch->info * 2; setpan(p, ch->channelnum); } else if (ch->info == 0xA4) // surround @@ -2815,7 +2829,7 @@ static void s_panbrello(PLAYER *p, chn_t *ch) // NON-ST3 if (cnt & 0x80) cnt = 0; } - dat = vibsin[cnt >> 1]; + dat = vibsin[cnt / 2]; } // ramp @@ -2830,7 +2844,7 @@ static void s_panbrello(PLAYER *p, chn_t *ch) // NON-ST3 if (cnt & 0x80) cnt = 0; } - dat = vibramp[cnt >> 1]; + dat = vibramp[cnt / 2]; } // square @@ -2845,7 +2859,7 @@ static void s_panbrello(PLAYER *p, chn_t *ch) // NON-ST3 if (cnt & 0x80) cnt = 0; } - dat = vibsqu[cnt >> 1]; + dat = vibsqu[cnt / 2]; } // random @@ -2860,7 +2874,7 @@ static void s_panbrello(PLAYER *p, chn_t *ch) // NON-ST3 if (cnt & 0x80) cnt = 0; } - dat = vibsin[cnt >> 1]; + dat = vibsin[cnt / 2]; cnt += (p->patmusicrand & 0x1E); } @@ -2872,19 +2886,19 @@ static void s_panbrello(PLAYER *p, chn_t *ch) // NON-ST3 dat = ((dat * (ch->info & 0x0F)) >> 4) + ch->apanpos; - if (dat < 0) dat = 0; - if (dat > 256) dat = 256; + if (dat < 0) dat = 0; + else if (dat > 256) dat = 256; voiceSetPanning(p, ch->channelnum, dat); - ch->apancnt = (cnt + ((ch->info >> 6) << 1)) & 0x7E; + ch->apancnt = (cnt + ((ch->info >> 6) * 2)) & 0x7E; } } void setSamplesPerFrame(PLAYER *p, uint32_t val) { p->samplesPerFrame = val; - + #ifdef USE_VOL_RAMP p->f_samplesPerFrame = 1.0f / ((float)(val) / 4.0f); p->f_samplesPerFrameSharp = 1.0f / (p->f_outputFreq / 1000.0f); // 1ms @@ -2923,10 +2937,10 @@ void voiceSetSource(PLAYER *p, uint8_t voiceNumber, const int8_t *sampleData, p->voice[voiceNumber].sampleLoopEnd = sampleLoopEnd; p->voice[voiceNumber].sampleLoopLength = sampleLoopLength; p->voice[voiceNumber].loopEnabled = loopEnabled; - + p->voice[voiceNumber].sixteenBit = sixteenbit; p->voice[voiceNumber].stereo = stereo; - + p->voice[voiceNumber].mixing = 1; p->voice[voiceNumber].interpolating = 1; @@ -2984,7 +2998,7 @@ void voiceSetSurround(PLAYER *p, uint8_t voiceNumber, int8_t surround) p->chn[voiceNumber].apanpos = 128; setpan(p, voiceNumber); } - + #ifdef USE_VOL_RAMP rampRate = p->f_samplesPerFrameSharp; if (p->rampStyle > 1) @@ -2993,7 +3007,7 @@ void voiceSetSurround(PLAYER *p, uint8_t voiceNumber, int8_t surround) p->voice[voiceNumber].targetPanR = -p->voice[voiceNumber].orgPanR; else p->voice[voiceNumber].targetPanR = p->voice[voiceNumber].orgPanR; - + p->voice[voiceNumber].panDeltaR = (p->voice[voiceNumber].targetPanR - p->voice[voiceNumber].panningR) * rampRate; } else @@ -3002,7 +3016,7 @@ void voiceSetSurround(PLAYER *p, uint8_t voiceNumber, int8_t surround) p->voice[voiceNumber].panningR = -p->voice[voiceNumber].orgPanR; else p->voice[voiceNumber].panningR = p->voice[voiceNumber].orgPanR; - + p->voice[voiceNumber].targetPanR = p->voice[voiceNumber].panningR; p->voice[voiceNumber].panDeltaR = 0; } @@ -3018,7 +3032,7 @@ void voiceSetPanning(PLAYER *p, uint8_t voiceNumber, uint16_t pan) { float pf; float rampRate; - + pf = (float)(pan) / 256.0f; #ifdef USE_VOL_RAMP @@ -3081,13 +3095,13 @@ static inline void mix8b(PLAYER *p, uint8_t ch, uint32_t samples) float panningR; void *resampler; VOICE *v; - + v = &p->voice[ch]; #ifdef USE_VOL_RAMP rampStyle = p->rampStyle; #endif - + sampleLength = v->sampleLength; sampleLoopLength = v->sampleLoopLength; sampleLoopEnd = v->sampleLoopEnd; @@ -3097,23 +3111,23 @@ static inline void mix8b(PLAYER *p, uint8_t ch, uint32_t samples) panningL = v->panningL; panningR = v->panningR; interpolating = v->interpolating; - sampleData = v->sampleData; + sampleData = v->sampleData; resampler = p->resampler[ch]; - + resampler_set_rate(resampler, v->incRate); - + for (j = 0; (j < samples) && sampleData; ++j) { samplePosition = v->samplePosition; - while (interpolating && (resampler_get_free_count(resampler) || !resampler_get_sample_count(resampler))) + while (interpolating > 0 && (resampler_get_free_count(resampler) || !resampler_get_sample_count(resampler))) { resampler_write_sample_fixed(resampler, sampleData[samplePosition], 8); - + if (v->playBackwards) { --samplePosition; - + if (loopEnabled) { if (samplePosition < sampleLoopBegin) @@ -3124,14 +3138,14 @@ static inline void mix8b(PLAYER *p, uint8_t ch, uint32_t samples) if (samplePosition < 0) { samplePosition = 0; - interpolating = 0; + interpolating = -resampler_get_padding_size(); } } } else { ++samplePosition; - + if (loopEnabled) { if (samplePosition >= sampleLoopEnd) @@ -3140,22 +3154,28 @@ static inline void mix8b(PLAYER *p, uint8_t ch, uint32_t samples) else { if (samplePosition >= sampleLength) - interpolating = 0; + interpolating = -resampler_get_padding_size(); } } } - + + while (interpolating < 0 && (resampler_get_free_count(resampler) || !resampler_get_sample_count(resampler))) + { + resampler_write_sample_fixed(resampler, 0, 8); + ++interpolating; + } + v->samplePosition = samplePosition; v->interpolating = (int8_t)(interpolating); if (!resampler_get_sample_count(resampler)) { resampler_clear(resampler); - + v->mixing = 0; break; } - + sample = resampler_get_sample_float(resampler); resampler_remove_sample(resampler, 1); @@ -3163,7 +3183,7 @@ static inline void mix8b(PLAYER *p, uint8_t ch, uint32_t samples) if (rampStyle > 0) { v->fader += v->faderDelta; - + if ((v->faderDelta > 0.0f) && (v->fader > v->faderDest)) { v->fader = v->faderDest; @@ -3172,37 +3192,37 @@ static inline void mix8b(PLAYER *p, uint8_t ch, uint32_t samples) { v->fader = v->faderDest; resampler_clear(resampler); - + v->mixing = 0; sampleData = 0; } - + sample *= v->fader; } #endif - + sample *= volume; p->masterBufferL[j] += (sample * panningL); p->masterBufferR[j] += (sample * panningR); - + #ifdef USE_VOL_RAMP if (rampStyle > 1) { volume += v->volDelta; panningL += v->panDeltaL; panningR += v->panDeltaR; - + if ((v->volDelta > 0.0f) && (volume > v->targetVol)) volume = v->targetVol; else if ((v->volDelta < 0.0f) && (volume < v->targetVol)) volume = v->targetVol; - + if ((v->panDeltaL > 0.0f) && (panningL > v->targetPanL)) panningL = v->targetPanL; else if ((v->panDeltaL < 0.0f) && (panningL < v->targetPanL)) panningL = v->targetPanL; - + if ((v->panDeltaR > 0.0f) && (panningR > v->targetPanR)) panningR = v->targetPanR; else if ((v->panDeltaR < 0.0f) && (panningR < v->targetPanR)) @@ -3236,9 +3256,9 @@ static inline void mix8bstereo(PLAYER *p, uint8_t ch, uint32_t samples) float sampleR; float panningL; float panningR; - void *resampler[2]; + void *resampler[2]; VOICE *v; - + v = &p->voice[ch]; #ifdef USE_VOL_RAMP rampStyle = p->rampStyle; @@ -3254,32 +3274,32 @@ static inline void mix8bstereo(PLAYER *p, uint8_t ch, uint32_t samples) panningR = v->panningR; interpolating = v->interpolating; sampleData = v->sampleData; - + resampler[0] = p->resampler[ch]; #ifdef USE_VOL_RAMP resampler[1] = p->resampler[ch + 64]; #else resampler[1] = p->resampler[ch + 32]; #endif - + resampler_set_rate(resampler[0], v->incRate ); resampler_set_rate(resampler[1], v->incRate ); for (j = 0; (j < samples) && sampleData; ++j) { samplePosition = v->samplePosition; - - while (interpolating && (resampler_get_free_count(resampler[0]) || + + while (interpolating > 0 && (resampler_get_free_count(resampler[0]) || (!resampler_get_sample_count(resampler[0]) && !resampler_get_sample_count(resampler[1])))) { resampler_write_sample_fixed(resampler[0], sampleData[samplePosition], 8); resampler_write_sample_fixed(resampler[1], sampleData[sampleLength + samplePosition], 8); - + if (v->playBackwards) { --samplePosition; - + if (loopEnabled) { if (samplePosition < sampleLoopBegin) @@ -3290,14 +3310,14 @@ static inline void mix8bstereo(PLAYER *p, uint8_t ch, uint32_t samples) if (samplePosition < 0) { samplePosition = 0; - interpolating = 0; + interpolating = -resampler_get_padding_size(); } } } else { ++samplePosition; - + if (loopEnabled) { if (samplePosition >= sampleLoopEnd) @@ -3306,23 +3326,32 @@ static inline void mix8bstereo(PLAYER *p, uint8_t ch, uint32_t samples) else { if (samplePosition >= sampleLength) - interpolating = 0; + interpolating = -resampler_get_padding_size(); } } } - + + while (interpolating < 0 && (resampler_get_free_count(resampler[0]) || + (!resampler_get_sample_count(resampler[0]) && + !resampler_get_sample_count(resampler[1])))) + { + resampler_write_sample_fixed(resampler[0], 0, 8); + resampler_write_sample_fixed(resampler[1], 0, 8); + ++interpolating; + } + v->samplePosition = samplePosition; v->interpolating = (int8_t)(interpolating); - + if (!resampler_get_sample_count(resampler[0])) { resampler_clear(resampler[0]); resampler_clear(resampler[1]); - + v->mixing = 0; break; } - + sampleL = resampler_get_sample_float(resampler[0]); sampleR = resampler_get_sample_float(resampler[1]); resampler_remove_sample(resampler[0], 1); @@ -3332,7 +3361,7 @@ static inline void mix8bstereo(PLAYER *p, uint8_t ch, uint32_t samples) if (rampStyle > 0) { v->fader += v->faderDelta; - + if ((v->faderDelta > 0.0f) && (v->fader > v->faderDest)) { v->fader = v->faderDest; @@ -3341,39 +3370,39 @@ static inline void mix8bstereo(PLAYER *p, uint8_t ch, uint32_t samples) { v->fader = v->faderDest; resampler_clear(resampler); - + v->mixing = 0; sampleData = 0; } - + sampleL *= v->fader; sampleR *= v->fader; } #endif - + sampleL *= volume; sampleR *= volume; p->masterBufferL[j] += (sampleL * panningL); p->masterBufferR[j] += (sampleR * panningR); - + #ifdef USE_VOL_RAMP if (rampStyle > 1) { volume += v->volDelta; panningL += v->panDeltaL; panningR += v->panDeltaR; - + if ((v->volDelta > 0.0f) && (volume > v->targetVol)) volume = v->targetVol; else if ((v->volDelta < 0.0f) && (volume < v->targetVol)) volume = v->targetVol; - + if ((v->panDeltaL > 0.0f) && (panningL > v->targetPanL)) panningL = v->targetPanL; else if ((v->panDeltaL < 0.0f) && (panningL < v->targetPanL)) panningL = v->targetPanL; - + if ((v->panDeltaR > 0.0f) && (panningR > v->targetPanR)) panningR = v->targetPanR; else if ((v->panDeltaR < 0.0f) && (panningR < v->targetPanR)) @@ -3408,12 +3437,12 @@ static inline void mix16b(PLAYER *p, uint8_t ch, uint32_t samples) float panningR; void *resampler; VOICE *v; - + v = &p->voice[ch]; #ifdef USE_VOL_RAMP rampStyle = p->rampStyle; #endif - + sampleLength = v->sampleLength; sampleLoopLength = v->sampleLoopLength; sampleLoopEnd = v->sampleLoopEnd; @@ -3425,21 +3454,21 @@ static inline void mix16b(PLAYER *p, uint8_t ch, uint32_t samples) interpolating = v->interpolating; sampleData = (const int16_t *)(v->sampleData); resampler = p->resampler[ch]; - + resampler_set_rate(resampler, v->incRate); - + for (j = 0; (j < samples) && sampleData; ++j) { samplePosition = v->samplePosition; - - while (interpolating && (resampler_get_free_count(resampler) || !resampler_get_sample_count(resampler))) + + while (interpolating > 0 && (resampler_get_free_count(resampler) || !resampler_get_sample_count(resampler))) { resampler_write_sample_fixed(resampler, (int16_t)(get_le16(&sampleData[samplePosition])), 16); - + if (v->playBackwards) { --samplePosition; - + if (loopEnabled) { if (samplePosition < sampleLoopBegin) @@ -3450,14 +3479,14 @@ static inline void mix16b(PLAYER *p, uint8_t ch, uint32_t samples) if (samplePosition < 0) { samplePosition = 0; - interpolating = 0; + interpolating = -resampler_get_padding_size(); } } } else { ++samplePosition; - + if (loopEnabled) { if (samplePosition >= sampleLoopEnd) @@ -3466,30 +3495,36 @@ static inline void mix16b(PLAYER *p, uint8_t ch, uint32_t samples) else { if (samplePosition >= sampleLength) - interpolating = 0; + interpolating = -resampler_get_padding_size(); } } } - + + while (interpolating < 0 && (resampler_get_free_count(resampler) || !resampler_get_sample_count(resampler))) + { + resampler_write_sample_fixed(resampler, 0, 16); + ++interpolating; + } + v->samplePosition = samplePosition; v->interpolating = (int8_t)(interpolating); - + if (!resampler_get_sample_count(resampler)) { resampler_clear(resampler); - + v->mixing = 0; break; } - + sample = resampler_get_sample_float(resampler); resampler_remove_sample(resampler, 1); - + #ifdef USE_VOL_RAMP if (rampStyle > 0) { v->fader += v->faderDelta; - + if ((v->faderDelta > 0.0f) && (v->fader > v->faderDest)) { v->fader = v->faderDest; @@ -3498,37 +3533,37 @@ static inline void mix16b(PLAYER *p, uint8_t ch, uint32_t samples) { v->fader = v->faderDest; resampler_clear(resampler); - + v->mixing = 0; sampleData = 0; } - + sample *= v->fader; } #endif - + sample *= volume; - + p->masterBufferL[j] += (sample * panningL); p->masterBufferR[j] += (sample * panningR); - + #ifdef USE_VOL_RAMP if (rampStyle > 1) { volume += v->volDelta; panningL += v->panDeltaL; panningR += v->panDeltaR; - + if ((v->volDelta > 0.0f) && (volume > v->targetVol)) volume = v->targetVol; else if ((v->volDelta < 0.0f) && (volume < v->targetVol)) volume = v->targetVol; - + if ((v->panDeltaL > 0.0f) && (panningL > v->targetPanL)) panningL = v->targetPanL; else if ((v->panDeltaL < 0.0f) && (panningL < v->targetPanL)) panningL = v->targetPanL; - + if ((v->panDeltaR > 0.0f) && (panningR > v->targetPanR)) panningR = v->targetPanR; else if ((v->panDeltaR < 0.0f) && (panningR < v->targetPanR)) @@ -3564,12 +3599,12 @@ static inline void mix16bstereo(PLAYER *p, uint8_t ch, uint32_t samples) float panningR; void *resampler[2]; VOICE *v; - + v = &p->voice[ch]; #ifdef USE_VOL_RAMP rampStyle = p->rampStyle; #endif - + sampleLength = v->sampleLength; sampleLoopLength = v->sampleLoopLength; sampleLoopEnd = v->sampleLoopEnd; @@ -3580,32 +3615,32 @@ static inline void mix16bstereo(PLAYER *p, uint8_t ch, uint32_t samples) panningR = v->panningR; interpolating = v->interpolating; sampleData = (const int16_t *)(v->sampleData); - + resampler[0] = p->resampler[ch]; #ifdef USE_VOL_RAMP resampler[1] = p->resampler[ch+64]; #else resampler[1] = p->resampler[ch+32]; #endif - + resampler_set_rate(resampler[0], v->incRate); resampler_set_rate(resampler[1], v->incRate); - + for (j = 0; (j < samples) && sampleData; ++j) { samplePosition = v->samplePosition; - - while (interpolating && (resampler_get_free_count(resampler[0]) || + + while (interpolating > 0 && (resampler_get_free_count(resampler[0]) || (!resampler_get_sample_count(resampler[0]) && !resampler_get_sample_count(resampler[1])))) { resampler_write_sample_fixed(resampler[0], (int16_t)(get_le16(&sampleData[samplePosition])), 16); resampler_write_sample_fixed(resampler[1], (int16_t)(get_le16(&sampleData[sampleLength + samplePosition])), 16); - + if (v->playBackwards) { --samplePosition; - + if (loopEnabled) { if (samplePosition < sampleLoopBegin) @@ -3616,14 +3651,14 @@ static inline void mix16bstereo(PLAYER *p, uint8_t ch, uint32_t samples) if (samplePosition < 0) { samplePosition = 0; - interpolating = 0; + interpolating = -resampler_get_padding_size(); } } } else { ++samplePosition; - + if (loopEnabled) { if (samplePosition >= sampleLoopEnd) @@ -3632,33 +3667,42 @@ static inline void mix16bstereo(PLAYER *p, uint8_t ch, uint32_t samples) else { if (samplePosition >= sampleLength) - interpolating = 0; + interpolating = -resampler_get_padding_size(); } } } - + + while (interpolating < 0 && (resampler_get_free_count(resampler[0]) || + (!resampler_get_sample_count(resampler[0]) && + !resampler_get_sample_count(resampler[1])))) + { + resampler_write_sample_fixed(resampler[0], 0, 16); + resampler_write_sample_fixed(resampler[1], 0, 16); + ++interpolating; + } + v->samplePosition = samplePosition; v->interpolating = (int8_t)(interpolating); - + if (!resampler_get_sample_count(resampler[0])) { resampler_clear(resampler[0]); resampler_clear(resampler[1]); - - v->mixing = 0; + + v->mixing = 0; break; } - + sampleL = resampler_get_sample_float(resampler[0]); sampleR = resampler_get_sample_float(resampler[1]); resampler_remove_sample(resampler[0], 1); resampler_remove_sample(resampler[1], 1); - + #ifdef USE_VOL_RAMP if (rampStyle > 0) { v->fader += v->faderDelta; - + if ((v->faderDelta > 0.0f) && (v->fader > v->faderDest)) { v->fader = v->faderDest; @@ -3667,39 +3711,39 @@ static inline void mix16bstereo(PLAYER *p, uint8_t ch, uint32_t samples) { v->fader = v->faderDest; resampler_clear(resampler); - + v->mixing = 0; sampleData = 0; } - + sampleL *= v->fader; sampleR *= v->fader; } #endif - + sampleL *= volume; sampleR *= volume; - + p->masterBufferL[j] += (sampleL * panningL); p->masterBufferR[j] += (sampleR * panningR); - + #ifdef USE_VOL_RAMP if (rampStyle > 1) { volume += v->volDelta; panningL += v->panDeltaL; panningR += v->panDeltaR; - + if ((v->volDelta > 0.0f) && (volume > v->targetVol)) volume = v->targetVol; else if ((v->volDelta < 0.0f) && (volume < v->targetVol)) volume = v->targetVol; - + if ((v->panDeltaL > 0.0f) && (panningL > v->targetPanL)) panningL = v->targetPanL; else if ((v->panDeltaL < 0.0f) && (panningL < v->targetPanL)) panningL = v->targetPanL; - + if ((v->panDeltaR > 0.0f) && (panningR > v->targetPanR)) panningR = v->targetPanR; else if ((v->panDeltaR < 0.0f) && (panningR < v->targetPanR)) @@ -3742,7 +3786,7 @@ void mixSampleBlock(PLAYER *p, float *outputStream, uint32_t sampleBlockLength) uint32_t j; float outL; float outR; - + #ifdef USE_VOL_RAMP int32_t rampStyle = p->rampStyle; #endif @@ -3756,9 +3800,9 @@ void mixSampleBlock(PLAYER *p, float *outputStream, uint32_t sampleBlockLength) { if (p->muted[i / 8] & (1 << (i % 8))) continue; - + mixChannel(p, i, sampleBlockLength); - + #ifdef USE_VOL_RAMP if (rampStyle > 0) mixChannel(p, i + 32, sampleBlockLength); @@ -3782,34 +3826,34 @@ static void st3play_AdlibMix(PLAYER *p, float *buffer, int32_t count) int32_t outbuffer_avail; int32_t i; float sample; - + while (count) { - inbuffer_free = resampler_get_free_count(p->fmResampler); + inbuffer_free = resampler_get_free_count(p->fmResampler); if (inbuffer_free > 256) inbuffer_free = 256; - + if (inbuffer_free) { Chip_GenerateBlock_Mono(p->fmChip, inbuffer_free, tempbuffer); - + for (i = 0; i < inbuffer_free; ++i) resampler_write_sample_fixed( p->fmResampler, (int32_t)(tempbuffer[i]), 16); } - - outbuffer_avail = resampler_get_sample_count(p->fmResampler); + + outbuffer_avail = resampler_get_sample_count(p->fmResampler); if (outbuffer_avail > count) outbuffer_avail = count; - + for (i = 0; i < outbuffer_avail; ++i) { sample = resampler_get_sample_float(p->fmResampler); resampler_remove_sample(p->fmResampler, 1); - + buffer[(i * 2) + 0] += sample; buffer[(i * 2) + 1] += sample; } - + buffer += (outbuffer_avail * 2); count -= outbuffer_avail; } @@ -3820,7 +3864,7 @@ void st3play_RenderFloat(void *_p, float *buffer, int32_t count) PLAYER *p; int32_t samplesTodo; float *outputStream; - + p = (PLAYER *)(_p); if (p->isMixing) { @@ -3839,10 +3883,10 @@ void st3play_RenderFloat(void *_p, float *buffer, int32_t count) if (p->fmChip && p->fmResampler) st3play_AdlibMix(p, outputStream, samplesTodo); - - outputStream += (samplesTodo << 1); + + outputStream += (samplesTodo * 2); } - + p->samplesLeft -= samplesTodo; count -= samplesTodo; } @@ -3863,22 +3907,22 @@ void st3play_RenderFixed32(void *_p, int32_t *buffer, int32_t count, int8_t dept float *fbuffer; float scale; float sample; - + assert(sizeof (int32_t) == sizeof (float)); - + fbuffer = (float *)(buffer); - st3play_RenderFloat(_p, fbuffer, count); - + st3play_RenderFloat(_p, fbuffer, count); + if (buffer) { scale = (float)(1 << (depth - 1)); for (i = 0; i < (count * 2); ++i) { sample = fbuffer[i] * scale; - - if (sample > INT_MAX) sample = INT_MAX; + + if (sample > INT_MAX) sample = INT_MAX; else if (sample < INT_MIN) sample = INT_MIN; - + buffer[i] = (int32_t)(sample); } } @@ -3891,30 +3935,30 @@ void st3play_RenderFixed16(void *_p, int16_t *buffer, int32_t count, int8_t dept float scale; float sample; float fbuffer[1024]; - + if (buffer == NULL) { st3play_RenderFloat(_p, 0, count); - } + } else { scale = (float)(1 << (depth - 1)); - + while (count) { SamplesTodo = (count < 512) ? count : 512; - + st3play_RenderFloat(_p, fbuffer, SamplesTodo); for (i = 0; i < (SamplesTodo * 2); ++i) { sample = fbuffer[i] * scale; - + if (sample > 32767) sample = 32767; else if (sample < -32768) sample = -32768; - + buffer[i] = (int16_t)(sample); } - + buffer += (SamplesTodo * 2); count -= SamplesTodo; } @@ -3923,20 +3967,22 @@ void st3play_RenderFixed16(void *_p, int16_t *buffer, int32_t count, int8_t dept void FreeSong(PLAYER *p) { + uint16_t i; + p->Playing = 0; - if (p->adpcmSamples) + if (p->adpcmSamples != NULL) { - int i, j; - for (i = 0, j = get_le16(&p->mseg[0x22]); i < j; i++) + for (i = 0; i < get_le16(&p->mseg[0x22]); ++i) { - if (p->adpcmSamples[i]) + if (p->adpcmSamples[i] != NULL) free(p->adpcmSamples[i]); } + free(p->adpcmSamples); p->adpcmSamples = NULL; } - + memset(p->voice, 0, sizeof (p->voice)); if (p->mseg) @@ -3951,22 +3997,25 @@ void FreeSong(PLAYER *p) void st3play_Mute(void *_p, int8_t channel, int8_t mute) { PLAYER *p; - int8_t mask; + int8_t offset; + int8_t bit; uint8_t adlibChannel; - + if (channel > 31) return; - + p = (PLAYER *)(_p); - + adlibChannel = (p->mseg[0x40 + channel] & 0x7F) - 16; - mask = 1 << (channel % 8); - + + offset = channel / 8; + bit = 1 << (channel % 8); + if (mute) - p->muted[channel / 8] |= mask; + p->muted[offset] |= bit; else - p->muted[channel / 8] &= ~mask; - + p->muted[offset] &= ~bit; + if (adlibChannel < 9) Chip_Mute(p->fmChip, adlibChannel, mute); } @@ -3982,17 +4031,17 @@ void st3play_GetInfo(void *_p, st3_info *info) int32_t i; int32_t channels_playing; PLAYER *p; - + p = (PLAYER *)(_p); - + info->order = p->x_np_ord - 1; info->pattern = p->x_np_pat; info->row = p->x_np_row; info->speed = p->musicmax; info->tempo = p->tempo; - + channels_playing = 0; - + if (p->isMixing) { for (i = 0; i < 32; ++i) @@ -4000,11 +4049,11 @@ void st3play_GetInfo(void *_p, st3_info *info) if (p->voice[i].mixing) ++channels_playing; } - + if (p->fmChip) channels_playing += Chip_GetActiveChannels(p->fmChip); } - + info->channels_playing = (int8_t)(channels_playing); }