From 08dd693fa0f8a125637cd8bd523e55ecd400eee7 Mon Sep 17 00:00:00 2001 From: tildearrow Date: Sun, 27 Mar 2022 00:02:17 -0500 Subject: [PATCH] Amiga: add AM/PM effects --- papers/doc/7-systems/amiga.md | 6 +++++- src/engine/dispatch.h | 2 ++ src/engine/platform/amiga.cpp | 21 +++++++++++++++++++++ src/engine/platform/amiga.h | 4 +++- src/engine/playback.cpp | 8 ++++++++ 5 files changed, 39 insertions(+), 2 deletions(-) diff --git a/papers/doc/7-systems/amiga.md b/papers/doc/7-systems/amiga.md index 713300c29..97c1151f6 100644 --- a/papers/doc/7-systems/amiga.md +++ b/papers/doc/7-systems/amiga.md @@ -6,4 +6,8 @@ in this very computer music trackers were born... # effects -- `10xx`: toggle low-pass filter. `0` turns it off and `1` turns it on. \ No newline at end of file +- `10xx`: toggle low-pass filter. `0` turns it off and `1` turns it on. +- `11xx`: toggle amplitude modulation with the next channel. + - does not work on the last channel. +- `12xx`: toggle period (frequency) modulation with the next channel. + - does not work on the last channel. \ No newline at end of file diff --git a/src/engine/dispatch.h b/src/engine/dispatch.h index b535df52d..15f1cf0d5 100644 --- a/src/engine/dispatch.h +++ b/src/engine/dispatch.h @@ -107,6 +107,8 @@ enum DivDispatchCmds { DIV_CMD_SAA_ENVELOPE, DIV_CMD_AMIGA_FILTER, + DIV_CMD_AMIGA_AM, + DIV_CMD_AMIGA_PM, DIV_CMD_LYNX_LFSR_LOAD, diff --git a/src/engine/platform/amiga.cpp b/src/engine/platform/amiga.cpp index a58de52f5..b0f25f728 100644 --- a/src/engine/platform/amiga.cpp +++ b/src/engine/platform/amiga.cpp @@ -17,6 +17,7 @@ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ +#define _USE_MATH_DEFINES #include "amiga.h" #include "../engine.h" #include @@ -68,6 +69,12 @@ const char* DivPlatformAmiga::getEffectName(unsigned char effect) { case 0x10: return "10xx: Toggle filter (0 disables; 1 enables)"; break; + case 0x11: + return "11xx: Toggle AM with next channel"; + break; + case 0x12: + return "12xx: Toggle period modulation with next channel"; + break; } return NULL; } @@ -84,6 +91,14 @@ void DivPlatformAmiga::acquire(short* bufL, short* bufR, size_t start, size_t le DivSample* s=parent->getSample(chan[i].sample); if (s->samples>0) { chan[i].audDat=s->data8[chan[i].audPos++]; + if (i<3 && chan[i].useV) { + chan[i+1].outVol=(unsigned char)chan[i].audDat^0x80; + if (chan[i+1].outVol>64) chan[i+1].outVol=64; + } + if (i<3 && chan[i].useP) { + chan[i+1].freq=(unsigned char)chan[i].audDat^0x80; + if (chan[i+1].freq>AMIGA_DIVIDER) chan[i+1].freq=AMIGA_DIVIDER; + } if (chan[i].audPos>=s->samples || chan[i].audPos>=131071) { if (s->loopStart>=0 && s->loopStart<(int)s->samples) { chan[i].audPos=s->loopStart; @@ -319,6 +334,12 @@ int DivPlatformAmiga::dispatch(DivCommand c) { filterOn=c.value; filtConst=filterOn?filtConstOn:filtConstOff; break; + case DIV_CMD_AMIGA_AM: + chan[c.chan].useV=c.value; + break; + case DIV_CMD_AMIGA_PM: + chan[c.chan].useP=c.value; + break; case DIV_CMD_GET_VOLMAX: return 64; break; diff --git a/src/engine/platform/amiga.h b/src/engine/platform/amiga.h index d73918e96..b5f13701d 100644 --- a/src/engine/platform/amiga.h +++ b/src/engine/platform/amiga.h @@ -36,7 +36,7 @@ class DivPlatformAmiga: public DivDispatch { unsigned char ins; int busClock; int note; - bool active, insChanged, freqChanged, keyOn, keyOff, inPorta, useWave, setPos; + bool active, insChanged, freqChanged, keyOn, keyOff, inPorta, useWave, setPos, useV, useP; signed char vol, outVol; DivMacroInt std; Channel(): @@ -61,6 +61,8 @@ class DivPlatformAmiga: public DivDispatch { inPorta(false), useWave(false), setPos(false), + useV(false), + useP(false), vol(64), outVol(64) {} }; diff --git a/src/engine/playback.cpp b/src/engine/playback.cpp index 7d089e609..4ab6a517c 100644 --- a/src/engine/playback.cpp +++ b/src/engine/playback.cpp @@ -115,6 +115,8 @@ const char* cmdName[DIV_CMD_MAX]={ "SAA_ENVELOPE", "AMIGA_FILTER", + "AMIGA_AM", + "AMIGA_PM", "LYNX_LFSR_LOAD", @@ -656,6 +658,12 @@ bool DivEngine::perSystemPostEffect(int ch, unsigned char effect, unsigned char case 0x10: // toggle filter dispatchCmd(DivCommand(DIV_CMD_AMIGA_FILTER,ch,effectVal)); break; + case 0x11: // toggle AM + dispatchCmd(DivCommand(DIV_CMD_AMIGA_AM,ch,effectVal)); + break; + case 0x12: // toggle PM + dispatchCmd(DivCommand(DIV_CMD_AMIGA_PM,ch,effectVal)); + break; default: return false; }