From fe28f1c73c93b8fb20a3cee14acc1625adef37de Mon Sep 17 00:00:00 2001 From: Norbert Lange Date: Mon, 8 Jun 2009 23:12:35 +0000 Subject: tfmx.cpp: added "vibrato-effect" paula.cpp: fixed bug introduced in last commit svn-id: r41392 --- sound/mods/paula.cpp | 2 +- sound/mods/tfmx.cpp | 60 ++++++++++++++++++++++++++++++++++++++-------------- sound/mods/tfmx.h | 23 +++++++++++++------- 3 files changed, 60 insertions(+), 25 deletions(-) (limited to 'sound/mods') diff --git a/sound/mods/paula.cpp b/sound/mods/paula.cpp index 64d387cdc9..40b5a904e6 100644 --- a/sound/mods/paula.cpp +++ b/sound/mods/paula.cpp @@ -150,7 +150,7 @@ int Paula::readBufferIntern(int16 *buffer, const int numSamples) { if (_voice[voice].period != _voice[voice].periodRepeat) { _voice[voice].period = _voice[voice].periodRepeat; - rate = doubleToFrac(_periodScale / _rate); + rate = doubleToFrac(_periodScale / _voice[voice].period); } // If the "rate" exceeds the sample rate, we would have to perform constant diff --git a/sound/mods/tfmx.cpp b/sound/mods/tfmx.cpp index 96f3f051e3..31f4df78c4 100644 --- a/sound/mods/tfmx.cpp +++ b/sound/mods/tfmx.cpp @@ -51,7 +51,7 @@ Tfmx::Tfmx(int rate, bool stereo) _playerCtx.song = -1; for (int i = 0; i < kNumVoices; ++i) - _channelCtx[i].paulaChannel = i; + _channelCtx[i].paulaChannel = (byte)i; } Tfmx::~Tfmx() { @@ -103,13 +103,29 @@ void Tfmx::effects(ChannelContext &channel) { else channel.sfxLocked = false; + // addBegin + // TODO: macroNote pending? if (0) { channel.sfxLocked = false; // TODO: macronote } - // vibratio + // vibrato + if (channel.vibLength) { + channel.vibValue += channel.vibDelta; + const uint16 setPeriod = (channel.period * ((1 << 11) + channel.vibValue)) >> 11; + + if (!channel.portaRate) + Paula::setChannelPeriod(channel.paulaChannel, setPeriod); + + if (--channel.vibCount == 0) { + channel.vibCount = channel.vibLength; + channel.vibDelta = -channel.vibDelta; + } + } + + // porta @@ -127,9 +143,7 @@ FORCEINLINE bool Tfmx::macroStep(ChannelContext &channel) { switch (macroPtr[0]) { case 0x00: // Reset + DMA Off. Parameters: deferWait, addset, vol - channel.envReset = 0; - channel.vibReset = 0; - channel.portaRate = 0; + clearEffects(channel); // FT case 0x13: // DMA Off. Parameters: deferWait, addset, vol // TODO: implement PArameters @@ -200,12 +214,15 @@ FORCEINLINE bool Tfmx::macroStep(ChannelContext &channel) { return false; case 0x1F: // AddPrevNote. Parameters: Note, Finetune(W) + temp = channel.prevNote; + goto setNote; case 0x08: // AddNote. Parameters: Note, Finetune(W) - temp = (macroPtr[0] == 0x08) ? channel.note : channel.prevNote; + temp = channel.note; // Fallthrough to SetNote +setNote: case 0x09: { // SetNote. Parameters: Note, Finetune(W) const uint16 noteInt = noteIntervalls[(temp + macroPtr[1]) & 0x3F]; - const uint16 finetune = READ_BE_UINT16(¯oPtr[2]) + channel.fineTune + 0x0100; + const uint16 finetune = READ_BE_UINT16(¯oPtr[2]) + channel.fineTune + (1 << 8); channel.portaDestPeriod = (uint16)((noteInt * finetune) >> 8); if (!channel.portaRate) { channel.period = channel.portaDestPeriod; @@ -216,7 +233,7 @@ FORCEINLINE bool Tfmx::macroStep(ChannelContext &channel) { case 0x0A: // Clear Effects channel.envReset = 0; - channel.vibReset = 0; + channel.vibLength = 0; channel.portaRate = 0; return true; @@ -226,8 +243,14 @@ FORCEINLINE bool Tfmx::macroStep(ChannelContext &channel) { return true; case 0x0C: // Vibrato. Parameters: Speed, intensity - macroPtr[1]; - macroPtr[3]; + channel.vibLength = macroPtr[1]; + channel.vibCount = macroPtr[1] / 2; + channel.vibDelta = macroPtr[3]; + if (!channel.portaRate) { + // TODO: unnecessary command? + Paula::setChannelPeriod(channel.paulaChannel, channel.period); + channel.vibValue = 0; + } return true; case 0x0D: // Add Volume. Parameters: unknown, volume @@ -295,7 +318,7 @@ FORCEINLINE bool Tfmx::macroStep(ChannelContext &channel) { temp = READ_BE_UINT16(¯oPtr[2]); assert(!(temp & 1)); channel.sampleStart += temp & 0xFFFE; - channel.sampleLen -= (temp / 2); + channel.sampleLen -= (uint16)(temp / 2); Paula::setChannelSampleStart(channel.paulaChannel, _resource.getSamplePtr(channel.sampleStart)); Paula::setChannelSampleLen(channel.paulaChannel, channel.sampleLen); return true; @@ -604,10 +627,9 @@ void Tfmx::noteCommand(const uint8 note, const uint8 param1, const uint8 param2, channel.keyUp = false; break; case 6: // Vibratio - channel.vibReset = param1 & 0xFE; - channel.vibTime = param1 / 2; - channel.vibFlag = 1; - channel.vibOffset = 0; + channel.vibLength = param1 & 0xFE; + channel.vibCount = param1 / 2; + channel.vibValue = 0; break; case 7: // Envelope channel.envRate = param1; @@ -745,10 +767,13 @@ void Tfmx::doMacro(int macro, int note) { for (int i = 0; i < kNumVoices; ++i) { _channelCtx[i].sfxLocked = false; + _channelCtx[i].sfxLockTime = -1; + clearEffects(_channelCtx[i]); + _channelCtx[i].vibValue = 0; stopChannel(_channelCtx[i]); } - noteCommand(note, macro, channel, 0); + noteCommand((uint8)note, (uint8)macro, (uint8)channel, 0); setTimerBaseValue(kPalCiaClock); setInterruptFreqUnscaled(kPalDefaultCiaVal); @@ -787,6 +812,9 @@ void Tfmx::doSong(int songPos) { for (int i = 0; i < kNumVoices; ++i) { _channelCtx[i].sfxLocked = false; + _channelCtx[i].sfxLockTime = -1; + clearEffects(_channelCtx[i]); + _channelCtx[i].vibValue = 0; stopChannel(_channelCtx[i]); } diff --git a/sound/mods/tfmx.h b/sound/mods/tfmx.h index fa132d5618..0f33ecb763 100644 --- a/sound/mods/tfmx.h +++ b/sound/mods/tfmx.h @@ -122,7 +122,7 @@ public: uint32 macroOffset; uint32 macroReturnOffset; uint16 macroStep; - uint32 macroReturnStep; + uint16 macroReturnStep; uint8 macroLoopCount; bool macroRun; @@ -142,7 +142,7 @@ public: uint8 relVol; uint8 note; uint8 prevNote; - uint16 fineTune; + int16 fineTune; uint16 portaDestPeriod; uint16 portaPeriod; @@ -155,15 +155,14 @@ public: uint8 envRate; uint8 envEndVolume; - int16 vibOffset; - int8 vibWidth; - uint8 vibFlag; - uint8 vibReset; - uint8 vibTime; + uint8 vibLength; + uint8 vibCount; + int16 vibValue; + int8 vibDelta; uint8 addBeginTime; uint8 addBeginReset; - int32 addBegin; + int16 addBeginDelta; } _channelCtx[kNumVoices]; struct PatternContext { @@ -211,6 +210,14 @@ public: channel.countDmaInterrupts = false; } + void clearEffects(ChannelContext &channel) { + channel.envReset = 0; + + channel.vibLength = 0; + + channel.portaRate = 0; + } + void stopChannel(ChannelContext &channel) { if (!channel.sfxLocked) { channel.macroRun = false; -- cgit v1.2.3