Amiga: add AM/PM effects

This commit is contained in:
tildearrow 2022-03-27 00:02:17 -05:00
parent 154ef3f9a3
commit 08dd693fa0
5 changed files with 39 additions and 2 deletions

View file

@ -7,3 +7,7 @@ in this very computer music trackers were born...
# effects # effects
- `10xx`: toggle low-pass filter. `0` turns it off and `1` turns it on. - `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.

View file

@ -107,6 +107,8 @@ enum DivDispatchCmds {
DIV_CMD_SAA_ENVELOPE, DIV_CMD_SAA_ENVELOPE,
DIV_CMD_AMIGA_FILTER, DIV_CMD_AMIGA_FILTER,
DIV_CMD_AMIGA_AM,
DIV_CMD_AMIGA_PM,
DIV_CMD_LYNX_LFSR_LOAD, DIV_CMD_LYNX_LFSR_LOAD,

View file

@ -17,6 +17,7 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/ */
#define _USE_MATH_DEFINES
#include "amiga.h" #include "amiga.h"
#include "../engine.h" #include "../engine.h"
#include <math.h> #include <math.h>
@ -68,6 +69,12 @@ const char* DivPlatformAmiga::getEffectName(unsigned char effect) {
case 0x10: case 0x10:
return "10xx: Toggle filter (0 disables; 1 enables)"; return "10xx: Toggle filter (0 disables; 1 enables)";
break; break;
case 0x11:
return "11xx: Toggle AM with next channel";
break;
case 0x12:
return "12xx: Toggle period modulation with next channel";
break;
} }
return NULL; 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); DivSample* s=parent->getSample(chan[i].sample);
if (s->samples>0) { if (s->samples>0) {
chan[i].audDat=s->data8[chan[i].audPos++]; 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 (chan[i].audPos>=s->samples || chan[i].audPos>=131071) {
if (s->loopStart>=0 && s->loopStart<(int)s->samples) { if (s->loopStart>=0 && s->loopStart<(int)s->samples) {
chan[i].audPos=s->loopStart; chan[i].audPos=s->loopStart;
@ -319,6 +334,12 @@ int DivPlatformAmiga::dispatch(DivCommand c) {
filterOn=c.value; filterOn=c.value;
filtConst=filterOn?filtConstOn:filtConstOff; filtConst=filterOn?filtConstOn:filtConstOff;
break; 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: case DIV_CMD_GET_VOLMAX:
return 64; return 64;
break; break;

View file

@ -36,7 +36,7 @@ class DivPlatformAmiga: public DivDispatch {
unsigned char ins; unsigned char ins;
int busClock; int busClock;
int note; 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; signed char vol, outVol;
DivMacroInt std; DivMacroInt std;
Channel(): Channel():
@ -61,6 +61,8 @@ class DivPlatformAmiga: public DivDispatch {
inPorta(false), inPorta(false),
useWave(false), useWave(false),
setPos(false), setPos(false),
useV(false),
useP(false),
vol(64), vol(64),
outVol(64) {} outVol(64) {}
}; };

View file

@ -115,6 +115,8 @@ const char* cmdName[DIV_CMD_MAX]={
"SAA_ENVELOPE", "SAA_ENVELOPE",
"AMIGA_FILTER", "AMIGA_FILTER",
"AMIGA_AM",
"AMIGA_PM",
"LYNX_LFSR_LOAD", "LYNX_LFSR_LOAD",
@ -656,6 +658,12 @@ bool DivEngine::perSystemPostEffect(int ch, unsigned char effect, unsigned char
case 0x10: // toggle filter case 0x10: // toggle filter
dispatchCmd(DivCommand(DIV_CMD_AMIGA_FILTER,ch,effectVal)); dispatchCmd(DivCommand(DIV_CMD_AMIGA_FILTER,ch,effectVal));
break; 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: default:
return false; return false;
} }