diff --git a/papers/format.md b/papers/format.md index ca8092a5a..97e22a4e5 100644 --- a/papers/format.md +++ b/papers/format.md @@ -810,6 +810,9 @@ size | description 1 | vib depth 1 | am depth 23 | reserved + --- | **Sound Unit data** (>=104) + 1 | use sample + 1 | switch roles of phase reset timer and frequency ``` # wavetable diff --git a/src/engine/engine.h b/src/engine/engine.h index 6f969efc9..256b0c96d 100644 --- a/src/engine/engine.h +++ b/src/engine/engine.h @@ -45,8 +45,8 @@ #define BUSY_BEGIN_SOFT softLocked=true; isBusy.lock(); #define BUSY_END isBusy.unlock(); softLocked=false; -#define DIV_VERSION "dev103" -#define DIV_ENGINE_VERSION 103 +#define DIV_VERSION "dev104" +#define DIV_ENGINE_VERSION 104 // for imports #define DIV_VERSION_MOD 0xff01 diff --git a/src/engine/instrument.cpp b/src/engine/instrument.cpp index a76588561..4d274e18c 100644 --- a/src/engine/instrument.cpp +++ b/src/engine/instrument.cpp @@ -528,6 +528,10 @@ void DivInstrument::putInsData(SafeWriter* w) { w->writeC(0); } + // Sound Unit + w->writeC(su.useSample); + w->writeC(su.switchRoles); + blockEndSeek=w->tell(); w->seek(blockStartSeek,SEEK_SET); w->writeI(blockEndSeek-blockStartSeek-4); @@ -1075,6 +1079,12 @@ DivDataErrors DivInstrument::readInsData(SafeReader& reader, short version) { for (int k=0; k<23; k++) reader.readC(); } + // Sound Unit + if (version>=104) { + su.useSample=reader.readC(); + su.switchRoles=reader.readC(); + } + return DIV_DATA_SUCCESS; } diff --git a/src/engine/instrument.h b/src/engine/instrument.h index 18bf2c5f7..1c25988e4 100644 --- a/src/engine/instrument.h +++ b/src/engine/instrument.h @@ -437,6 +437,14 @@ struct DivInstrumentWaveSynth { param4(0) {} }; +struct DivInstrumentSoundUnit { + bool useSample; + bool switchRoles; + DivInstrumentSoundUnit(): + useSample(false), + switchRoles(false) {} +}; + struct DivInstrument { String name; bool mode; @@ -450,6 +458,7 @@ struct DivInstrument { DivInstrumentFDS fds; DivInstrumentMultiPCM multipcm; DivInstrumentWaveSynth ws; + DivInstrumentSoundUnit su; /** * save the instrument to a SafeWriter. diff --git a/src/engine/platform/su.cpp b/src/engine/platform/su.cpp index 2d1a38932..4320798ab 100644 --- a/src/engine/platform/su.cpp +++ b/src/engine/platform/su.cpp @@ -256,12 +256,12 @@ int DivPlatformSoundUnit::dispatch(DivCommand c) { switch (c.cmd) { case DIV_CMD_NOTE_ON: { DivInstrument* ins=parent->getIns(chan[c.chan].ins,DIV_INS_SU); - if (chan[c.chan].pcm && ins->type!=DIV_INS_AMIGA) { - chan[c.chan].pcm=(ins->type==DIV_INS_AMIGA); + if (chan[c.chan].pcm && !(ins->type==DIV_INS_AMIGA || ins->su.useSample)) { + chan[c.chan].pcm=(ins->type==DIV_INS_AMIGA || ins->su.useSample); writeControl(c.chan); writeControlUpper(c.chan); } - chan[c.chan].pcm=(ins->type==DIV_INS_AMIGA); + chan[c.chan].pcm=(ins->type==DIV_INS_AMIGA || ins->su.useSample); if (c.value!=DIV_NOTE_NULL) { chan[c.chan].baseFreq=NOTE_FREQUENCY(c.value); chan[c.chan].freqChanged=true; diff --git a/src/gui/insEdit.cpp b/src/gui/insEdit.cpp index f991b9e2a..8e405251e 100644 --- a/src/gui/insEdit.cpp +++ b/src/gui/insEdit.cpp @@ -3093,13 +3093,17 @@ void FurnaceGUI::drawInsEdit() { P(ImGui::Checkbox("Don't test/gate before new note",&ins->c64.noTest)); ImGui::EndTabItem(); } - if (ins->type==DIV_INS_AMIGA) if (ImGui::BeginTabItem("Sample")) { + if (ins->type==DIV_INS_AMIGA || ins->type==DIV_INS_SU) if (ImGui::BeginTabItem((ins->type==DIV_INS_SU)?"Sound Unit":"Sample")) { String sName; if (ins->amiga.initSample<0 || ins->amiga.initSample>=e->song.sampleLen) { sName="none selected"; } else { sName=e->song.sample[ins->amiga.initSample]->name; } + if (ins->type==DIV_INS_SU) { + P(ImGui::Checkbox("Use sample",&ins->su.useSample)); + P(ImGui::Checkbox("Switch roles of frequency and phase reset timer",&ins->su.switchRoles)); + } if (ImGui::BeginCombo("Initial Sample",sName.c_str())) { String id; for (int i=0; isong.sampleLen; i++) { @@ -3110,14 +3114,16 @@ void FurnaceGUI::drawInsEdit() { } ImGui::EndCombo(); } - P(ImGui::Checkbox("Use wavetable (Amiga only)",&ins->amiga.useWave)); - if (ins->amiga.useWave) { - int len=ins->amiga.waveLen+1; - if (ImGui::InputInt("Width",&len,2,16)) { - if (len<2) len=2; - if (len>256) len=256; - ins->amiga.waveLen=(len&(~1))-1; - PARAMETER + if (ins->type==DIV_INS_AMIGA) { + P(ImGui::Checkbox("Use wavetable (Amiga only)",&ins->amiga.useWave)); + if (ins->amiga.useWave) { + int len=ins->amiga.waveLen+1; + if (ImGui::InputInt("Width",&len,2,16)) { + if (len<2) len=2; + if (len>256) len=256; + ins->amiga.waveLen=(len&(~1))-1; + PARAMETER + } } } ImGui::BeginDisabled(ins->amiga.useWave);