Skip to content

Commit

Permalink
dev185 - SoundUnit: hardware sweep sequences
Browse files Browse the repository at this point in the history
kinda buggy in note off... may require a rewrite of volume handling
  • Loading branch information
tildearrow committed Oct 21, 2023
1 parent 10c72f3 commit f718fbb
Show file tree
Hide file tree
Showing 7 changed files with 406 additions and 12 deletions.
25 changes: 25 additions & 0 deletions papers/newIns.md
Original file line number Diff line number Diff line change
Expand Up @@ -556,6 +556,31 @@ size | description
size | description
-----|------------------------------------
1 | switch roles of phase reset timer and frequency
1 | hardware sequence length (>=185)
??? | hardware sequence...
| - length: 5*hwSeqLen
```

a value in the hardware sequence has the following format:

```
size | description
-----|------------------------------------
1 | command
| - 0: set volume sweep
| - 1: set frequency sweep
| - 2: set cutoff sweep
| - 3: wait
| - 4: wait for release
| - 5: loop
| - 6: loop until release
1 | sweep bound
1 | sweep amount/command data
| - if "set sweep", this is amount.
| - for wait: length in ticks
| - for wait for release: nothing
| - for loop/loop until release: position
2 | sweep period
```

# ES5506 data (ES)
Expand Down
4 changes: 2 additions & 2 deletions src/engine/engine.h
Original file line number Diff line number Diff line change
Expand Up @@ -54,8 +54,8 @@ class DivWorkPool;

#define DIV_UNSTABLE

#define DIV_VERSION "dev184"
#define DIV_ENGINE_VERSION 184
#define DIV_VERSION "dev185"
#define DIV_ENGINE_VERSION 185
// for imports
#define DIV_VERSION_MOD 0xff01
#define DIV_VERSION_FC 0xff02
Expand Down
23 changes: 22 additions & 1 deletion src/engine/instrument.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -196,7 +196,10 @@ bool DivInstrumentWaveSynth::operator==(const DivInstrumentWaveSynth& other) {
}

bool DivInstrumentSoundUnit::operator==(const DivInstrumentSoundUnit& other) {
return _C(switchRoles);
return (
_C(switchRoles) &&
_C(hwSeqLen)
);
}

bool DivInstrumentES5506::operator==(const DivInstrumentES5506& other) {
Expand Down Expand Up @@ -691,6 +694,14 @@ void DivInstrument::writeFeatureSU(SafeWriter* w) {

w->writeC(su.switchRoles);

w->writeC(su.hwSeqLen);
for (int i=0; i<su.hwSeqLen; i++) {
w->writeC(su.hwSeq[i].cmd);
w->writeC(su.hwSeq[i].bound);
w->writeC(su.hwSeq[i].val);
w->writeS(su.hwSeq[i].speed);
}

FEATURE_END;
}

Expand Down Expand Up @@ -2536,6 +2547,16 @@ void DivInstrument::readFeatureSU(SafeReader& reader, short version) {

su.switchRoles=reader.readC();

if (version>=185) {
su.hwSeqLen=reader.readC();
for (int i=0; i<su.hwSeqLen; i++) {
su.hwSeq[i].cmd=reader.readC();
su.hwSeq[i].bound=reader.readC();
su.hwSeq[i].val=reader.readC();
su.hwSeq[i].speed=reader.readS();
}
}

READ_FEAT_END;
}

Expand Down
28 changes: 25 additions & 3 deletions src/engine/instrument.h
Original file line number Diff line number Diff line change
Expand Up @@ -385,7 +385,7 @@ struct DivInstrumentGB {

DIV_GB_HWCMD_MAX
};
struct HWSeqCommand {
struct HWSeqCommandGB {
unsigned char cmd;
unsigned short data;
} hwSeq[256];
Expand All @@ -403,7 +403,7 @@ struct DivInstrumentGB {
hwSeqLen(0),
softEnv(false),
alwaysInit(false) {
memset(hwSeq,0,256*sizeof(int));
memset(hwSeq,0,256*sizeof(HWSeqCommandGB));
}
};

Expand Down Expand Up @@ -663,14 +663,36 @@ struct DivInstrumentWaveSynth {

struct DivInstrumentSoundUnit {
bool switchRoles;
unsigned char hwSeqLen;
enum HWSeqCommands: unsigned char {
DIV_SU_HWCMD_VOL=0,
DIV_SU_HWCMD_PITCH,
DIV_SU_HWCMD_CUT,
DIV_SU_HWCMD_WAIT,
DIV_SU_HWCMD_WAIT_REL,
DIV_SU_HWCMD_LOOP,
DIV_SU_HWCMD_LOOP_REL,

DIV_SU_HWCMD_MAX
};
struct HWSeqCommandSU {
unsigned char cmd;
unsigned char bound;
unsigned char val;
unsigned short speed;
unsigned short padding;
} hwSeq[256];

bool operator==(const DivInstrumentSoundUnit& other);
bool operator!=(const DivInstrumentSoundUnit& other) {
return !(*this==other);
}

DivInstrumentSoundUnit():
switchRoles(false) {}
switchRoles(false),
hwSeqLen(0) {
memset(hwSeq,0,256*sizeof(HWSeqCommandSU));
}
};

struct DivInstrumentES5506 {
Expand Down
79 changes: 79 additions & 0 deletions src/engine/platform/su.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,79 @@ void DivPlatformSoundUnit::tick(bool sysTick) {
}
writeControlUpper(i);
}

// run hardware sequence
if (chan[i].active) {
if (--chan[i].hwSeqDelay<=0) {
chan[i].hwSeqDelay=0;
DivInstrument* ins=parent->getIns(chan[i].ins,DIV_INS_SU);
int hwSeqCount=0;
while (chan[i].hwSeqPos<ins->su.hwSeqLen && hwSeqCount<8) {
bool leave=false;
unsigned char bound=ins->su.hwSeq[chan[i].hwSeqPos].bound;
unsigned char val=ins->su.hwSeq[chan[i].hwSeqPos].val;
unsigned short speed=ins->su.hwSeq[chan[i].hwSeqPos].speed;
switch (ins->su.hwSeq[chan[i].hwSeqPos].cmd) {
case DivInstrumentSoundUnit::DIV_SU_HWCMD_VOL:
chan[i].volSweepP=speed;
chan[i].volSweepV=val;
chan[i].volSweepB=bound;
chan[i].volSweep=(val>0);
chWrite(i,0x14,chan[i].volSweepP&0xff);
chWrite(i,0x15,chan[i].volSweepP>>8);
chWrite(i,0x16,chan[i].volSweepV);
chWrite(i,0x17,chan[i].volSweepB);
writeControlUpper(i);
break;
case DivInstrumentSoundUnit::DIV_SU_HWCMD_PITCH:
chan[i].freqSweepP=speed;
chan[i].freqSweepV=val;
chan[i].freqSweepB=bound;
chan[i].freqSweep=(val>0);
chWrite(i,0x10,chan[i].freqSweepP&0xff);
chWrite(i,0x11,chan[i].freqSweepP>>8);
chWrite(i,0x12,chan[i].freqSweepV);
chWrite(i,0x13,chan[i].freqSweepB);
writeControlUpper(i);
break;
case DivInstrumentSoundUnit::DIV_SU_HWCMD_CUT:
chan[i].cutSweepP=speed;
chan[i].cutSweepV=val;
chan[i].cutSweepB=bound;
chan[i].cutSweep=(val>0);
chWrite(i,0x18,chan[i].cutSweepP&0xff);
chWrite(i,0x19,chan[i].cutSweepP>>8);
chWrite(i,0x1a,chan[i].cutSweepV);
chWrite(i,0x1b,chan[i].cutSweepB);
writeControlUpper(i);
break;
case DivInstrumentSoundUnit::DIV_SU_HWCMD_WAIT:
chan[i].hwSeqDelay=(val+1)*parent->tickMult;
leave=true;
break;
case DivInstrumentSoundUnit::DIV_SU_HWCMD_WAIT_REL:
if (!chan[i].released) {
chan[i].hwSeqPos--;
leave=true;
}
break;
case DivInstrumentSoundUnit::DIV_SU_HWCMD_LOOP:
chan[i].hwSeqPos=val-1;
break;
case DivInstrumentSoundUnit::DIV_SU_HWCMD_LOOP_REL:
if (!chan[i].released) {
chan[i].hwSeqPos=val-1;
}
break;
}

chan[i].hwSeqPos++;
if (leave) break;
hwSeqCount++;
}
}
}

if (chan[i].freqChanged || chan[i].keyOn || chan[i].keyOff) {
//DivInstrument* ins=parent->getIns(chan[i].ins,DIV_INS_SU);
chan[i].freq=parent->calcFreq(chan[i].baseFreq,chan[i].pitch,chan[i].fixedArp?chan[i].baseNoteOverride:chan[i].arpOff,chan[i].fixedArp,chan[i].switchRoles,2,chan[i].pitch2,chipClock,chan[i].switchRoles?CHIP_DIVIDER:CHIP_FREQBASE);
Expand Down Expand Up @@ -220,6 +293,9 @@ int DivPlatformSoundUnit::dispatch(DivCommand c) {
}
chan[c.chan].active=true;
chan[c.chan].keyOn=true;
chan[c.chan].released=false;
chan[c.chan].hwSeqPos=0;
chan[c.chan].hwSeqDelay=0;
chWrite(c.chan,0x02,chan[c.chan].vol);
chan[c.chan].macroInit(ins);
if (!parent->song.brokenOutVol && !chan[c.chan].std.vol.will) {
Expand All @@ -231,11 +307,14 @@ int DivPlatformSoundUnit::dispatch(DivCommand c) {
case DIV_CMD_NOTE_OFF:
chan[c.chan].active=false;
chan[c.chan].keyOff=true;
chan[c.chan].hwSeqPos=0;
chan[c.chan].hwSeqDelay=0;
chan[c.chan].macroInit(NULL);
break;
case DIV_CMD_NOTE_OFF_ENV:
case DIV_CMD_ENV_RELEASE:
chan[c.chan].std.release();
chan[c.chan].released=true;
break;
case DIV_CMD_INSTRUMENT:
if (chan[c.chan].ins!=c.value || c.value2==1) {
Expand Down
9 changes: 7 additions & 2 deletions src/engine/platform/su.h
Original file line number Diff line number Diff line change
Expand Up @@ -30,12 +30,14 @@ class DivPlatformSoundUnit: public DivDispatch {
signed char pan;
unsigned char duty;
bool noise, pcm, phaseReset, filterPhaseReset, switchRoles;
bool pcmLoop, timerSync, freqSweep, volSweep, cutSweep;
bool pcmLoop, timerSync, freqSweep, volSweep, cutSweep, released;
unsigned short freqSweepP, volSweepP, cutSweepP;
unsigned char freqSweepB, volSweepB, cutSweepB;
unsigned char freqSweepV, volSweepV, cutSweepV;
unsigned short syncTimer;
signed short wave;
unsigned short hwSeqPos;
short hwSeqDelay;
Channel():
SharedChannel<signed char>(127),
cutoff(16383),
Expand All @@ -56,6 +58,7 @@ class DivPlatformSoundUnit: public DivDispatch {
freqSweep(false),
volSweep(false),
cutSweep(false),
released(false),
freqSweepP(0),
volSweepP(0),
cutSweepP(0),
Expand All @@ -66,7 +69,9 @@ class DivPlatformSoundUnit: public DivDispatch {
volSweepV(0),
cutSweepV(0),
syncTimer(0),
wave(0) {}
wave(0),
hwSeqPos(0),
hwSeqDelay(0) {}
};
Channel chan[8];
DivDispatchOscBuffer* oscBuf[8];
Expand Down
Loading

0 comments on commit f718fbb

Please sign in to comment.