aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--sound/mods/paula.cpp2
-rw-r--r--sound/mods/tfmx.cpp60
-rw-r--r--sound/mods/tfmx.h23
-rw-r--r--tfmx/tfmxplayer.cpp8
4 files changed, 64 insertions, 29 deletions
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(&macroPtr[2]) + channel.fineTune + 0x0100;
+ const uint16 finetune = READ_BE_UINT16(&macroPtr[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(&macroPtr[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;
diff --git a/tfmx/tfmxplayer.cpp b/tfmx/tfmxplayer.cpp
index dce7d6180c..1e2b905abb 100644
--- a/tfmx/tfmxplayer.cpp
+++ b/tfmx/tfmxplayer.cpp
@@ -111,7 +111,7 @@ void tfmxmain(const int argc, const char *const argv[]) {
debug( "play Macro %02X", param);
dumpMacro(*player, 0x11);
playflag = 1;
- player->doMacro(param,0x40);
+ player->doMacro(param,0x1B);
++i;
}
break;
@@ -129,9 +129,9 @@ void tfmxmain(const int argc, const char *const argv[]) {
if (!playflag) {
playflag = 1;
- //player->doMacro(20,0x40);
- player->doSong(4);
- dumpTrackstepsBySong(*player, 4);
+ player->doMacro(0x17,0x1B);
+ //player->doSong(4);
+ //dumpTrackstepsBySong(*player, 4);
}