From 3163730fe8e1436938597249e9f2aada7c4ca152 Mon Sep 17 00:00:00 2001 From: tildearrow Date: Wed, 16 Mar 2022 17:01:44 -0500 Subject: [PATCH] prepare for drum kits/sample map --- papers/format.md | 7 ++++++ src/engine/engine.h | 4 +-- src/engine/instrument.cpp | 16 ++++++++++++ src/engine/instrument.h | 9 ++++++- src/gui/insEdit.cpp | 53 +++++++++++++++++++++++++++++++++++++++ 5 files changed, 86 insertions(+), 3 deletions(-) diff --git a/papers/format.md b/papers/format.md index 503099b99..9afa4b47e 100644 --- a/papers/format.md +++ b/papers/format.md @@ -494,6 +494,13 @@ size | description 2 | kick frequency 2 | snare/hi-hat frequency 2 | tom/top frequency + --- | **Sample instrument extra data** (>=67) + 1 | use note map + | - only read the following two data structures if this is true! + 4?? | note frequency × 120 + | - 480 bytes + 2?? | note sample × 120 + | - 240 bytes ``` # wavetable diff --git a/src/engine/engine.h b/src/engine/engine.h index 9e31e5636..a3ac2c249 100644 --- a/src/engine/engine.h +++ b/src/engine/engine.h @@ -37,8 +37,8 @@ warnings+=(String("\n")+x); \ } -#define DIV_VERSION "dev66" -#define DIV_ENGINE_VERSION 66 +#define DIV_VERSION "dev67" +#define DIV_ENGINE_VERSION 67 // for imports #define DIV_VERSION_MOD 0xff01 diff --git a/src/engine/instrument.cpp b/src/engine/instrument.cpp index b22fdced2..785c9b19d 100644 --- a/src/engine/instrument.cpp +++ b/src/engine/instrument.cpp @@ -378,6 +378,13 @@ void DivInstrument::putInsData(SafeWriter* w) { w->writeS(fm.kickFreq); w->writeS(fm.snareHatFreq); w->writeS(fm.tomTopFreq); + + // sample map + w->writeC(amiga.useNoteMap); + if (amiga.useNoteMap) { + w->write(amiga.noteFreq,120*sizeof(unsigned int)); + w->write(amiga.noteMap,120*sizeof(short)); + } } DivDataErrors DivInstrument::readInsData(SafeReader& reader, short version) { @@ -717,6 +724,15 @@ DivDataErrors DivInstrument::readInsData(SafeReader& reader, short version) { std.dutyMacroRel=-1; } + // sample map + if (version>=67) { + amiga.useNoteMap=reader.readC(); + if (amiga.useNoteMap) { + reader.read(amiga.noteFreq,120*sizeof(unsigned int)); + reader.read(amiga.noteMap,120*sizeof(short)); + } + } + return DIV_DATA_SUCCESS; } diff --git a/src/engine/instrument.h b/src/engine/instrument.h index e4613c8b9..97d64da00 100644 --- a/src/engine/instrument.h +++ b/src/engine/instrument.h @@ -373,9 +373,16 @@ struct DivInstrumentC64 { struct DivInstrumentAmiga { short initSample; + bool useNoteMap; + int noteFreq[120]; + short noteMap[120]; DivInstrumentAmiga(): - initSample(0) {} + initSample(0), + useNoteMap(false) { + memset(noteMap,-1,120*sizeof(short)); + memset(noteFreq,0,120*sizeof(int)); + } }; struct DivInstrument { diff --git a/src/gui/insEdit.cpp b/src/gui/insEdit.cpp index e7fe917ac..6e0635a99 100644 --- a/src/gui/insEdit.cpp +++ b/src/gui/insEdit.cpp @@ -1467,6 +1467,59 @@ void FurnaceGUI::drawInsEdit() { } ImGui::EndCombo(); } + P(ImGui::Checkbox("Use sample map (does not work yet!)",&ins->amiga.useNoteMap)); + if (ins->amiga.useNoteMap) { + if (ImGui::BeginTable("NoteMap",3,ImGuiTableFlags_ScrollY|ImGuiTableFlags_Borders|ImGuiTableFlags_SizingStretchSame)) { + ImGui::TableSetupColumn("c0",ImGuiTableColumnFlags_WidthFixed); + ImGui::TableSetupColumn("c1",ImGuiTableColumnFlags_WidthStretch); + ImGui::TableSetupColumn("c2",ImGuiTableColumnFlags_WidthStretch); + + ImGui::TableSetupScrollFreeze(0,1); + + ImGui::TableNextRow(ImGuiTableRowFlags_Headers); + ImGui::TableNextColumn(); + ImGui::TableNextColumn(); + ImGui::Text("Sample"); + ImGui::TableNextColumn(); + ImGui::Text("Frequency"); + for (int i=0; i<120; i++) { + ImGui::TableNextRow(); + ImGui::PushID(fmt::sprintf("NM_%d",i).c_str()); + ImGui::TableNextColumn(); + ImGui::Text("%s",noteNames[60+i]); + ImGui::TableNextColumn(); + if (ins->amiga.noteMap[i]<0 || ins->amiga.noteMap[i]>=e->song.sampleLen) { + sName="-- empty --"; + ins->amiga.noteMap[i]=-1; + } else { + sName=e->song.sample[ins->amiga.noteMap[i]]->name; + } + ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x); + if (ImGui::BeginCombo("##SM",sName.c_str())) { + String id; + if (ImGui::Selectable("-- empty --",ins->amiga.noteMap[i]==-1)) { PARAMETER + ins->amiga.noteMap[i]=-1; + } + for (int j=0; jsong.sampleLen; j++) { + id=fmt::sprintf("%d: %s",j,e->song.sample[j]->name); + if (ImGui::Selectable(id.c_str(),ins->amiga.noteMap[i]==j)) { PARAMETER + ins->amiga.noteMap[i]=j; + if (ins->amiga.noteFreq[i]<=0) ins->amiga.noteFreq[i]=(int)((double)e->song.sample[j]->centerRate*pow(2.0,((double)i-60.0)/12.0)); + } + } + ImGui::EndCombo(); + } + ImGui::TableNextColumn(); + ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x); + if (ImGui::InputInt("##SF",&ins->amiga.noteFreq[i],50,500)) { PARAMETER + if (ins->amiga.noteFreq[i]<0) ins->amiga.noteFreq[i]=0; + if (ins->amiga.noteFreq[i]>262144) ins->amiga.noteFreq[i]=262144; + } + ImGui::PopID(); + } + ImGui::EndTable(); + } + } ImGui::EndTabItem(); } if (ImGui::BeginTabItem("Macros")) {