implement tremolo

This commit is contained in:
tildearrow 2023-02-04 16:08:20 -05:00
parent 43ba2ff8f2
commit 31ccb58a48
3 changed files with 28 additions and 0 deletions

View file

@ -4470,6 +4470,9 @@ bool DivEngine::init() {
for (int i=0; i<64; i++) { for (int i=0; i<64; i++) {
vibTable[i]=127*sin(((double)i/64.0)*(2*M_PI)); vibTable[i]=127*sin(((double)i/64.0)*(2*M_PI));
} }
for (int i=0; i<128; i++) {
tremTable[i]=255*0.5*(1.0-cos(((double)i/128.0)*(2*M_PI)));
}
for (int i=0; i<4096; i++) { for (int i=0; i<4096; i++) {
reversePitchTable[i]=round(1024.0*pow(2.0,(2048.0-(double)i)/(12.0*128.0))); reversePitchTable[i]=round(1024.0*pow(2.0,(2048.0-(double)i)/(12.0*128.0)));
pitchTable[i]=round(1024.0*pow(2.0,((double)i-2048.0)/(12.0*128.0))); pitchTable[i]=round(1024.0*pow(2.0,((double)i-2048.0)/(12.0*128.0)));

View file

@ -413,6 +413,7 @@ class DivEngine {
} sPreview; } sPreview;
short vibTable[64]; short vibTable[64];
short tremTable[128];
int reversePitchTable[4096]; int reversePitchTable[4096];
int pitchTable[4096]; int pitchTable[4096];
char c163NameCS[1024]; char c163NameCS[1024];
@ -1158,6 +1159,7 @@ class DivEngine {
memset(dispatchOfChan,0,DIV_MAX_CHANS*sizeof(int)); memset(dispatchOfChan,0,DIV_MAX_CHANS*sizeof(int));
memset(sysOfChan,0,DIV_MAX_CHANS*sizeof(int)); memset(sysOfChan,0,DIV_MAX_CHANS*sizeof(int));
memset(vibTable,0,64*sizeof(short)); memset(vibTable,0,64*sizeof(short));
memset(tremTable,0,128*sizeof(short));
memset(reversePitchTable,0,4096*sizeof(int)); memset(reversePitchTable,0,4096*sizeof(int));
memset(pitchTable,0,4096*sizeof(int)); memset(pitchTable,0,4096*sizeof(int));
memset(sysDefs,0,256*sizeof(void*)); memset(sysDefs,0,256*sizeof(void*));

View file

@ -689,6 +689,13 @@ void DivEngine::processRow(int i, bool afterDelay) {
// - then a volume slide down starts to the low boundary, and then when this is reached a volume slide up begins // - then a volume slide down starts to the low boundary, and then when this is reached a volume slide up begins
// - this process repeats until 0700 or 0Axy are found // - this process repeats until 0700 or 0Axy are found
// - note that a volume value does not stop tremolo - instead it glitches this whole thing up // - note that a volume value does not stop tremolo - instead it glitches this whole thing up
if (chan[i].tremoloDepth==0) {
chan[i].tremoloPos=0;
}
chan[i].tremoloDepth=effectVal&15;
chan[i].tremoloRate=effectVal>>4;
// tremolo and vol slides are incompatiblw
chan[i].volSpeed=0;
break; break;
case 0x0a: // volume ramp case 0x0a: // volume ramp
// TODO: non-0x-or-x0 value should be treated as 00 // TODO: non-0x-or-x0 value should be treated as 00
@ -698,6 +705,9 @@ void DivEngine::processRow(int i, bool afterDelay) {
} else { } else {
chan[i].volSpeed=(effectVal>>4)*64; chan[i].volSpeed=(effectVal>>4)*64;
} }
// tremolo and vol slides are incompatible
chan[i].tremoloDepth=0;
chan[i].tremoloRate=0;
} else { } else {
chan[i].volSpeed=0; chan[i].volSpeed=0;
} }
@ -838,10 +848,16 @@ void DivEngine::processRow(int i, bool afterDelay) {
if (!song.arpNonPorta) dispatchCmd(DivCommand(DIV_CMD_PRE_PORTA,i,false,0)); if (!song.arpNonPorta) dispatchCmd(DivCommand(DIV_CMD_PRE_PORTA,i,false,0));
break; break;
case 0xf3: // fine volume ramp up case 0xf3: // fine volume ramp up
// tremolo and vol slides are incompatible
chan[i].tremoloDepth=0;
chan[i].tremoloRate=0;
chan[i].volSpeed=effectVal; chan[i].volSpeed=effectVal;
dispatchCmd(DivCommand(DIV_CMD_HINT_VOL_SLIDE,i,chan[i].volSpeed)); dispatchCmd(DivCommand(DIV_CMD_HINT_VOL_SLIDE,i,chan[i].volSpeed));
break; break;
case 0xf4: // fine volume ramp down case 0xf4: // fine volume ramp down
// tremolo and vol slides are incompatible
chan[i].tremoloDepth=0;
chan[i].tremoloRate=0;
chan[i].volSpeed=-effectVal; chan[i].volSpeed=-effectVal;
dispatchCmd(DivCommand(DIV_CMD_HINT_VOL_SLIDE,i,chan[i].volSpeed)); dispatchCmd(DivCommand(DIV_CMD_HINT_VOL_SLIDE,i,chan[i].volSpeed));
break; break;
@ -868,6 +884,9 @@ void DivEngine::processRow(int i, bool afterDelay) {
} else { } else {
chan[i].volSpeed=(effectVal>>4)*256; chan[i].volSpeed=(effectVal>>4)*256;
} }
// tremolo and vol slides are incompatible
chan[i].tremoloDepth=0;
chan[i].tremoloRate=0;
} else { } else {
chan[i].volSpeed=0; chan[i].volSpeed=0;
} }
@ -1239,6 +1258,10 @@ bool DivEngine::nextTick(bool noAccum, bool inhibitLowLat) {
} else { } else {
dispatchCmd(DivCommand(DIV_CMD_VOLUME,i,chan[i].volume>>8)); dispatchCmd(DivCommand(DIV_CMD_VOLUME,i,chan[i].volume>>8));
} }
} else if (chan[i].tremoloDepth>0) {
chan[i].tremoloPos+=chan[i].tremoloRate;
chan[i].tremoloPos&=127;
dispatchCmd(DivCommand(DIV_CMD_VOLUME,i,MAX(0,chan[i].volume-(tremTable[chan[i].tremoloPos]*chan[i].tremoloDepth))>>8));
} }
} }
if (chan[i].vibratoDepth>0) { if (chan[i].vibratoDepth>0) {