From a965433bbae9631aac807426e4f49bad272ba84b Mon Sep 17 00:00:00 2001 From: tildearrow Date: Fri, 7 Oct 2022 14:17:25 -0500 Subject: [PATCH] start working on LFO macro mode --- papers/format.md | 12 ++++-------- src/engine/macroInt.cpp | 28 +++++++++++++++++++++++++--- src/engine/macroInt.h | 5 +++-- 3 files changed, 32 insertions(+), 13 deletions(-) diff --git a/papers/format.md b/papers/format.md index ee76ce70f..2649cd298 100644 --- a/papers/format.md +++ b/papers/format.md @@ -32,7 +32,8 @@ these fields are 0 in format versions prior to 100 (0.6pre1). the format versions are: -- 119: Furnace dev119 (still not released) +- 120: Furnace dev120 +- 119: Furnace dev119 - 118: Furnace dev118 - 117: Furnace dev117 - 116: Furnace 0.6pre1.5 @@ -441,7 +442,6 @@ notes: - 0: sequence (normal) - 1: ADSR - 2: LFO - - 3: ADSR+LFO - see sub-section for information on how to interpret parameters. - FM operator order is: - 1/3/2/4 (internal order) for OPN, OPM, OPZ and OPL 4-op @@ -1044,18 +1044,14 @@ size | description - `val[7]`: decay 2 - `val[8]`: release - LFO: - - `val[9]`: bottom - - `val[10]`: top - `val[11]`: speed - `val[12]`: waveform - 0: triangle - - 1: sine - - 2: saw - - 3: pulse + - 1: saw + - 2: pulse - `val[13]`: phase - `val[14]`: loop - `val[15]`: global (not sure how will I implement this) -- for ADSR+LFO just interpret both ADSR and LFO params. # wavetable diff --git a/src/engine/macroInt.cpp b/src/engine/macroInt.cpp index 90a4a6aa8..c463e7b24 100644 --- a/src/engine/macroInt.cpp +++ b/src/engine/macroInt.cpp @@ -31,11 +31,18 @@ #define ADSR_SR source.val[7] #define ADSR_RR source.val[8] +#define LFO_SPEED source.val[11] +#define LFO_WAVE source.val[12] +#define LFO_PHASE source.val[13] +#define LFO_LOOP source.val[14] +#define LFO_GLOBAL source.val[15] + void DivMacroStruct::prepare(DivInstrumentMacro& source, DivEngine* e) { has=had=actualHad=will=true; mode=source.mode; type=(source.open>>1)&3; linger=(source.name=="vol" && e->song.volMacroLinger); + lfoPos=LFO_PHASE; } void DivMacroStruct::doMacro(DivInstrumentMacro& source, bool released, bool tick) { @@ -86,7 +93,7 @@ void DivMacroStruct::doMacro(DivInstrumentMacro& source, bool released, bool tic } } } - if (type==1 || type==3) { // ADSR + if (type==1) { // ADSR if (released && lastPos<3) lastPos=3; switch (lastPos) { case 0: // attack @@ -126,8 +133,23 @@ void DivMacroStruct::doMacro(DivInstrumentMacro& source, bool released, bool tic } val=ADSR_LOW+((pos+(ADSR_HIGH-ADSR_LOW)*pos)>>8); } - if (type==2 || type==3) { // LFO - + if (type==2) { // LFO + lfoPos+=LFO_SPEED; + lfoPos&=1023; + + int lfoOut=0; + switch (LFO_WAVE&3) { + case 0: // triangle + lfoOut=((lfoPos&512)?(1023-lfoPos):(lfoPos))>>1; + break; + case 1: // saw + lfoOut=lfoPos>>2; + break; + case 2: // pulse + lfoOut=(lfoPos&512)?255:0; + break; + } + val=ADSR_LOW+((lfoOut+(ADSR_HIGH-ADSR_LOW)*lfoOut)>>8); } } } diff --git a/src/engine/macroInt.h b/src/engine/macroInt.h index 64d81e1bf..ac829a575 100644 --- a/src/engine/macroInt.h +++ b/src/engine/macroInt.h @@ -25,13 +25,13 @@ class DivEngine; struct DivMacroStruct { - int pos, lastPos, delay; + int pos, lastPos, lfoPos, delay; int val; bool has, had, actualHad, finished, will, linger, began; unsigned int mode, type; void doMacro(DivInstrumentMacro& source, bool released, bool tick); void init() { - pos=lastPos=mode=type=delay=0; + pos=lastPos=lfoPos=mode=type=delay=0; has=had=actualHad=will=false; linger=false; began=true; @@ -42,6 +42,7 @@ struct DivMacroStruct { DivMacroStruct(): pos(0), lastPos(0), + lfoPos(0), delay(0), val(0), has(false),