From 3a8df098f471c3c0905aacd89552163f7e0263dd Mon Sep 17 00:00:00 2001 From: djdiskmachine <110535302+djdiskmachine@users.noreply.github.com> Date: Tue, 22 Oct 2024 20:33:43 +0200 Subject: [PATCH] Clsource scales (#157) * added scales * Refactor fields in ProjectView Re-use the same variable for all UIIntVarField --------- Co-authored-by: Camilowser Co-authored-by: djdiskmachine --- projects/Makefile | 2 +- projects/lgpt.vcproj | 8 + projects/lgpt.vcxproj | 2 + projects/lgpt64.xcodeproj/project.pbxproj | 6 + sources/Application/Model/Project.cpp | 28 ++- sources/Application/Model/Project.h | 4 +- sources/Application/Model/Scale.cpp | 199 ++++++++++++++++++++++ sources/Application/Model/Scale.h | 11 ++ sources/Application/Views/PhraseView.cpp | 8 +- sources/Application/Views/ProjectView.cpp | 41 +++-- sources/Foundation/Variables/Variable.cpp | 11 ++ sources/Foundation/Variables/Variable.h | 8 +- 12 files changed, 297 insertions(+), 31 deletions(-) create mode 100644 sources/Application/Model/Scale.cpp create mode 100644 sources/Application/Model/Scale.h diff --git a/projects/Makefile b/projects/Makefile index 5a8073fa..60aa3825 100644 --- a/projects/Makefile +++ b/projects/Makefile @@ -255,7 +255,7 @@ COMMONFILES := \ MessageBox.o \ GrooveView.o UINoteVarField.o UIBigHexVarField.o \ SRPUpdaters.o UIStaticField.o \ - Song.o Chain.o Phrase.o Project.o \ + Song.o Chain.o Phrase.o Project.o Scale.o \ char.o n_assert.o fixed.o wildcard.o \ SyncMaster.o TablePlayback.o Player.o \ Table.o TableView.o\ diff --git a/projects/lgpt.vcproj b/projects/lgpt.vcproj index 01dd6d14..d50935b8 100644 --- a/projects/lgpt.vcproj +++ b/projects/lgpt.vcproj @@ -788,6 +788,14 @@ RelativePath="..\sources\Application\Model\Song.h" > + + + + diff --git a/projects/lgpt.vcxproj b/projects/lgpt.vcxproj index 538ecf44..e6f588df 100644 --- a/projects/lgpt.vcxproj +++ b/projects/lgpt.vcxproj @@ -266,6 +266,7 @@ + @@ -409,6 +410,7 @@ + diff --git a/projects/lgpt64.xcodeproj/project.pbxproj b/projects/lgpt64.xcodeproj/project.pbxproj index 893b8f23..e13964c8 100644 --- a/projects/lgpt64.xcodeproj/project.pbxproj +++ b/projects/lgpt64.xcodeproj/project.pbxproj @@ -168,6 +168,7 @@ A95153FD2C88A4E70060FA44 /* SDLTimer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A95153FB2C88A4E60060FA44 /* SDLTimer.cpp */; }; A95154012C88A6670060FA44 /* MacOSmain.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A95153FE2C88A6670060FA44 /* MacOSmain.cpp */; }; A95154052C88A6720060FA44 /* MacOSSystem.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A95154042C88A6720060FA44 /* MacOSSystem.cpp */; }; + A9A67DC42C9629AF00E923CD /* Scale.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A9A67DC32C9629AF00E923CD /* Scale.cpp */; }; /* End PBXBuildFile section */ /* Begin PBXFileReference section */ @@ -515,6 +516,8 @@ A95153FE2C88A6670060FA44 /* MacOSmain.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = MacOSmain.cpp; path = ../MacOS/MacOSMain/MacOSmain.cpp; sourceTree = ""; }; A95154032C88A6720060FA44 /* MacOSSystem.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = MacOSSystem.h; path = ../../MacOS/MacOSSystem/MacOSSystem.h; sourceTree = ""; }; A95154042C88A6720060FA44 /* MacOSSystem.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = MacOSSystem.cpp; path = ../../MacOS/MacOSSystem/MacOSSystem.cpp; sourceTree = ""; }; + A9A67DC22C9629AF00E923CD /* Scale.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Scale.h; sourceTree = ""; }; + A9A67DC32C9629AF00E923CD /* Scale.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Scale.cpp; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ @@ -762,6 +765,8 @@ 737D11A20BCE66F000099CB3 /* Model */ = { isa = PBXGroup; children = ( + A9A67DC32C9629AF00E923CD /* Scale.cpp */, + A9A67DC22C9629AF00E923CD /* Scale.h */, 87CA0EA80F7E1160001D6BD0 /* Mixer.cpp */, 87CA0EA90F7E1160001D6BD0 /* Mixer.h */, 73A640190D3CF90A00F43955 /* Groove.cpp */, @@ -1509,6 +1514,7 @@ 737D128D0BCE66F000099CB3 /* UIController.cpp in Sources */, 737D128E0BCE66F000099CB3 /* ViewData.cpp in Sources */, 737D12900BCE66F000099CB3 /* Observable.cpp in Sources */, + A9A67DC42C9629AF00E923CD /* Scale.cpp in Sources */, 737D12940BCE66F000099CB3 /* Service.cpp in Sources */, 737D12950BCE66F000099CB3 /* ServiceRegistry.cpp in Sources */, 737D12960BCE66F000099CB3 /* SubService.cpp in Sources */, diff --git a/sources/Application/Model/Project.cpp b/sources/Application/Model/Project.cpp index 4396d0a5..ff203cc6 100644 --- a/sources/Application/Model/Project.cpp +++ b/sources/Application/Model/Project.cpp @@ -1,15 +1,16 @@ #include "Project.h" +#include "Application/Instruments/SampleInstrument.h" +#include "Application/Instruments/SamplePool.h" +#include "Application/Persistency/PersistencyService.h" +#include "Application/Player/SyncMaster.h" +#include "Foundation/Variables/WatchedVariable.h" +#include "Groove.h" +#include "Scale.h" #include "Services/Midi/MidiService.h" -#include "System/FileSystem/FileSystem.h" #include "System/Console/Trace.h" +#include "System/FileSystem/FileSystem.h" #include "System/io/Status.h" -#include "Foundation/Variables/WatchedVariable.h" -#include "Application/Player/SyncMaster.h" #include "Table.h" -#include "Groove.h" -#include "Application/Persistency/PersistencyService.h" -#include "Application/Instruments/SamplePool.h" -#include "Application/Instruments/SampleInstrument.h" #include "ProjectDatas.h" #include @@ -32,9 +33,12 @@ tempoNudge_(0) new Variable("softclip", VAR_SOFTCLIP, softclipStates, 5, 0); this->Insert(softclip); Variable *clipAttenuation = - new Variable("clipAttenuation", VAR_CLIP_ATTENUATION, 10); + new Variable("clipAttenuation", VAR_CLIP_ATTENUATION, 100); this->Insert(clipAttenuation); - + Variable *scale = + new Variable("scale", VAR_SCALE, scaleNames, scaleCount, 0); + this->Insert(scale); + scale->SetInt(0); // Reload the midi device list @@ -67,6 +71,12 @@ Project::~Project() { delete instrumentBank_ ; } ; +int Project::GetScale() { + Variable *v = FindVariable(VAR_SCALE); + NAssert(v); + return v->GetInt(); +} + int Project::GetTempo() { Variable *v=FindVariable(VAR_TEMPO) ; NAssert(v) ; diff --git a/sources/Application/Model/Project.h b/sources/Application/Model/Project.h index eff87be6..c3093ffc 100644 --- a/sources/Application/Model/Project.h +++ b/sources/Application/Model/Project.h @@ -16,6 +16,7 @@ #define VAR_TRANSPOSE MAKE_FOURCC('T','R','S','P') #define VAR_SOFTCLIP MAKE_FOURCC('S', 'F', 'T', 'C') #define VAR_CLIP_ATTENUATION MAKE_FOURCC('C', 'A', 'T', 'N') +#define VAR_SCALE MAKE_FOURCC('S', 'C', 'A', 'L') #define PROJECT_NUMBER "1" #define PROJECT_RELEASE "4" @@ -36,7 +37,8 @@ class Project: public Persistent,public VariableContainer,I_Observer { bool Wrap() ; void OnTempoTap(); void NudgeTempo(int value) ; - int GetTempo() ; // Takes nudging into account + int GetScale(); + int GetTempo() ; // Takes nudging into account int GetTranspose() ; int GetSoftclip(); int GetAttenuation(); diff --git a/sources/Application/Model/Scale.cpp b/sources/Application/Model/Scale.cpp new file mode 100644 index 00000000..2943b8a8 --- /dev/null +++ b/sources/Application/Model/Scale.cpp @@ -0,0 +1,199 @@ +// from: https://github.com/xiphonics/picoTracker +#include "Scale.h" + +// Source of scales in original release: +// https://upload.wikimedia.org/wikipedia/commons/thumb/3/35/PitchConstellations.svg/1280px-PitchConstellations.svg.png + +// Additional Scales +// https://pianoencyclopedia.com/scales/ + +const char *scaleNotes[scaleNoteCount] = { + "C","C#","D", "D#", "E", "F", "F#", "G", "G#", "A", "A#", "B" +}; + +const char *scaleNames[scaleCount] = {"None (Chromatic)", + "Acoustic", + "Adonal malakh", + "Aeolian mode (minor)", + "Algerian", + "Altered", + "Augmented", + "Bebop dominant", + "Blues", + "Dorian", + "Double harmonic", + "Enigmatic", + "Flamenco", + "Gypsy", + "Half diminished", + "Harmonic major", + "Harmonic minor", + "Hirajoshi", + "Hungarian gypsy", + "Hungarian minor", + "Insen", + "Ionian mode (major)", + "Istrian", + "Iwato", + "Locrian", + "Lydian augmented", + "Lydian", + "Major bebop", + "Major locran", + "Major pentatonic", + "Melodic minor", + "Melodic minor (asc)", + "Minor pentatonic", + "Mixolydian", + "Neapolitan major", + "Neapolitan minor", + "Octatonic", + "Persian", + "Phrygian dominant", + "Phrygian", + "Prometheus", + "Ryukyu", + "Tritone", + "Tercera Alta", + "Ukranian", + "Whole tone", + }; + +const bool scaleSteps[scaleCount][scaleNoteCount] = { + // "C","C#","D", "D#", "E", "F", "F#", "G", "G#", "A", "A#", "B" + // "None (Chromatic)" + {true, true, true, true, true, true, true, true, true, true, true, true}, + // "Acoustic" + {true, false, true, false, true, false, true, true, false, true, false, + false}, + // "Adonal malakh" + {true, false, true, false, true, true, false, true, true, false, true, + false}, + // "Aeolian mode (minor)" + {true, false, true, true, false, true, false, true, true, false, true, + false}, + // "Algerian" + {true, false, true, true, false, false, true, true, true, false, false, + true}, + // "Altered" + {true, true, false, true, true, false, true, false, true, false, true, + false}, + // "Augmented" + {true, false, false, true, true, false, false, true, true, false, false, + true}, + // "Bebop dominant" + {true, false, true, false, true, true, false, true, false, true, true, + true}, + // "Blues" + {true, false, false, true, false, true, true, true, false, false, true, + false}, + // "Dorian" + {true, false, true, true, false, true, false, true, false, true, true, + false}, + // "Double harmonic" + {true, true, false, false, true, true, false, true, true, false, false, + true}, + // "Enigmatic" + {true, true, false, false, true, false, true, false, true, false, true, + true}, + // "Flamenco" + {true, true, false, false, true, true, false, true, true, false, false, + true}, + // "Gypsy" + {true, false, true, true, false, false, true, true, true, false, true, + false}, + // "Half diminished" + {true, false, true, true, false, true, true, false, true, false, true, + false}, + // "Harmonic major" + {true, false, true, false, true, true, false, true, true, false, false, + true}, + // "Harmonic minor" + {true, false, true, true, false, true, false, true, true, false, false, + true}, + // "Hirajoshi" + {true, false, true, true, false, false, false, true, true, false, false, + false}, + // "Hungarian gypsy" + {true, false, true, true, false, false, true, true, true, false, false, + true}, + // "Hungarian minor" + {true, false, true, true, false, false, true, true, true, false, false, + true}, + // "Insen" + {true, true, false, false, false, true, false, true, false, false, true, + false}, + // "Ionian mode (major)" + {true, false, true, false, true, true, false, true, false, true, false, + true}, + // "Istrian" + {true, true, false, true, true, false, true, true, false, false, false, + false}, + // "Iwato" + {true, true, false, false, false, true, true, false, false, false, true, + false}, + // "Locrian" + {true, true, false, true, false, true, true, false, true, false, true, + false}, + // "Lydian augmented" + {true, false, true, false, true, false, true, false, true, true, false, + true}, + // "Lydian" + {true, false, true, false, true, false, true, true, false, true, false, + true}, + // "Major bebop" + {true, false, true, false, true, true, false, true, true, true, false, + true}, + // "Major locran" + {true, false, true, false, true, true, true, false, true, false, true, + false}, + // "Major pentatonic" + {true, false, true, false, true, false, false, true, false, true, false, + false}, + // "Melodic minor" + {true, false, true, true, false, true, false, true, true, true, true, true}, + // "Melodic minor (asc)" + {true, false, true, true, false, true, false, true, false, true, false, + true}, + // "Minor pentatonic" + {true, false, false, true, false, true, false, true, false, false, true, + false}, + // "Mixolydian" + {true, false, true, false, true, true, false, true, false, true, true, + false}, + // "Neapolitan major" + {true, true, false, true, false, true, false, true, false, true, false, + true}, + // "Neapolitan minor" + {true, true, false, true, false, true, false, true, true, false, false, + true}, + // "Octatonic" + {true, false, true, true, false, true, true, false, true, true, false, + true}, + // "Persian" + {true, true, false, false, true, true, true, false, true, false, false, + true}, + // "Phrygian dominant" + {true, true, false, false, true, true, false, true, true, false, true, + false}, + // "Phrygian" + {true, true, false, true, false, true, false, true, true, false, true, + false}, + // "Prometheus" + {true, false, true, false, true, false, true, false, false, true, true, + false}, + // Ryukyu + {true, false, false, false, true, true, false, true, false, false, false, true}, + // "Tritone" + {true, true, false, false, true, false, true, true, false, false, true, + false}, + // "Tercera Alta" + {false, true, true, false, false, false, true, false, false, true, false, false}, + // "Ukranian" + {true, false, true, true, false, false, true, true, false, true, true, + false}, + // "Whole tone" + {true, false, true, false, true, false, true, false, true, false, true, + false} + +}; diff --git a/sources/Application/Model/Scale.h b/sources/Application/Model/Scale.h new file mode 100644 index 00000000..de4398cc --- /dev/null +++ b/sources/Application/Model/Scale.h @@ -0,0 +1,11 @@ +// from: https://github.com/xiphonics/picoTracker +#ifndef SCALE_VIEW_H +#define SCALE_VIEW_H + +const int scaleCount = 46; +const int scaleNoteCount = 12; +extern const char *scaleNames[scaleCount]; +extern const char *scaleNotes[scaleNoteCount]; +extern const bool scaleSteps[scaleCount][scaleNoteCount]; + +#endif diff --git a/sources/Application/Views/PhraseView.cpp b/sources/Application/Views/PhraseView.cpp index 2d418f93..10739c01 100644 --- a/sources/Application/Views/PhraseView.cpp +++ b/sources/Application/Views/PhraseView.cpp @@ -1,5 +1,6 @@ #include "PhraseView.h" #include "Application/Instruments/CommandList.h" +#include "Application/Model/Scale.h" #include "Application/Model/Table.h" #include "Application/Utils/HelpLegend.h" #include "Application/Utils/char.h" @@ -147,7 +148,6 @@ void PhraseView::updateCursorValue(ViewUpdateDirection direction, int xOffset, lastCmd_ = *cc; // Set legend break; - case 3: switch (direction) { case VUD_RIGHT: @@ -207,7 +207,11 @@ void PhraseView::updateCursorValue(ViewUpdateDirection direction, int xOffset, } if ((c) && (*c != 0xFF)) { int offset = offsets_[col_ + xOffset][direction]; - + // Add/remove from offset to match selected scale + int scale = viewData_->project_->GetScale(); + while (!scaleSteps[scale][(*c + offset) % 12]) { + offset > 0 ? offset++ : offset--; + } updateData(c, offset, limit, wrap); switch (col_ + xOffset) { case 0: diff --git a/sources/Application/Views/ProjectView.cpp b/sources/Application/Views/ProjectView.cpp index 76530f41..b1782a3e 100644 --- a/sources/Application/Views/ProjectView.cpp +++ b/sources/Application/Views/ProjectView.cpp @@ -1,4 +1,5 @@ #include "ProjectView.h" +#include "Application/Model/Scale.h" #include "Application/Persistency/PersistencyService.h" #include "Application/Views/ModalDialogs/MessageBox.h" #include "Application/Views/ModalDialogs/NewProjectDialog.h" @@ -108,26 +109,36 @@ ProjectView::ProjectView(GUIWindow &w,ViewData *data):FieldView(w,data) { v=project_->FindVariable(VAR_MASTERVOL) ; position._y+=1 ; - UIIntVarField *f1=new UIIntVarField(position,*v,"master: %d",10,200,1,10) ; - T_SimpleList::Insert(f1) ; - - v=project_->FindVariable(VAR_TRANSPOSE) ; - position._y+=1 ; - UIIntVarField *f2=new UIIntVarField(position,*v,"transpose: %3.2d",-48,48,0x1,0xC) ; - T_SimpleList::Insert(f2) ; + UIIntVarField *field = + new UIIntVarField(position, *v, "master: %d", 10, 200, 1, 10); + T_SimpleList::Insert(field) ; v = project_->FindVariable(VAR_SOFTCLIP); position._y += 1; - UIIntVarField *f3 = - new UIIntVarField(position, *v, "soft clip: %s", 0, 4, 1, 3); - T_SimpleList::Insert(f3); + field = new UIIntVarField(position, *v, "soft clip: %s", 0, 4, 1, 3); + T_SimpleList::Insert(field); v = project_->FindVariable(VAR_CLIP_ATTENUATION); position._x += 18; - f3 = new UIIntVarField(position, *v, "post: %d", 1, 100, 1, 10); - T_SimpleList::Insert(f3); + field = new UIIntVarField(position, *v, "post: %d", 1, 100, 1, 10); + T_SimpleList::Insert(field); position._x -= 18; + v = project_->FindVariable(VAR_TRANSPOSE); + position._y+=2 ; + UIIntVarField *f2=new UIIntVarField(position,*v,"transpose: %3.2d",-48,48,0x1,0xC) ; + T_SimpleList::Insert(f2) ; + + v = project_->FindVariable(VAR_SCALE); + // if scale name is not found, set the default chromatic scale + if (v->GetInt() < 0) { + v->SetInt(0); + } + position._y += 1; + field = + new UIIntVarField(position, *v, "scale: %s", 0, scaleCount - 1, 1, 10); + T_SimpleList::Insert(field); + position._y += 2; UIActionField *a1 = new UIActionField("Compact Sequencer", ACTION_PURGE, position); @@ -158,9 +169,9 @@ ProjectView::ProjectView(GUIWindow &w,ViewData *data):FieldView(w,data) { v = project_->FindVariable(VAR_MIDIDEVICE); NAssert(v); position._y += 2; - UIIntVarField *f4 = new UIIntVarField( - position, *v, "MIDI: %s", 0, MidiService::GetInstance()->Size(), 1, 1); - T_SimpleList::Insert(f4); + field = new UIIntVarField(position, *v, "MIDI: %s", 0, + MidiService::GetInstance()->Size(), 1, 1); + T_SimpleList::Insert(field); position._y += 2; a1 = new UIActionField("Exit", ACTION_QUIT, position); diff --git a/sources/Foundation/Variables/Variable.cpp b/sources/Foundation/Variables/Variable.cpp index 4b6fcaca..d25782ea 100644 --- a/sources/Foundation/Variables/Variable.cpp +++ b/sources/Foundation/Variables/Variable.cpp @@ -48,6 +48,17 @@ Variable::Variable(const char *name,FourCC id,char **list,int size,int index) { type_=CHAR_LIST ; } ; +Variable::Variable(const char *name, FourCC id, const char *const *list, + int size, int index) { + name_=name ; + id_=id ; + list_.char_=(char **)list ; + listSize_=size ; + value_.index_=index ; + defaultValue_.index_=index ; + type_=CHAR_LIST ; +}; + Variable::~Variable() { } ; diff --git a/sources/Foundation/Variables/Variable.h b/sources/Foundation/Variables/Variable.h index 1c740d77..285dd1bf 100644 --- a/sources/Foundation/Variables/Variable.h +++ b/sources/Foundation/Variables/Variable.h @@ -24,11 +24,13 @@ class Variable { Variable(const char *name, FourCC id, bool value = false); Variable(const char *name,FourCC id,const char *value=0) ; Variable(const char *name,FourCC id,char **list,int size,int index=-1) ; + Variable(const char *name, FourCC id, const char *const *list, int size, + int index = -1); - virtual ~Variable() ; + virtual ~Variable(); - FourCC GetID() ; - const char *GetName() ; + FourCC GetID(); + const char *GetName(); Type GetType() ; void SetInt(int value,bool notify=true) ;