-
Notifications
You must be signed in to change notification settings - Fork 332
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
An initial implementation of a Control UI for the daisy patch init
device
- Loading branch information
1 parent
d97fe31
commit e73189c
Showing
3 changed files
with
236 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,213 @@ | ||
#ifndef FAUST_DAISYPATCHINITCONTROL_H | ||
#define FAUST_DAISYPATCHINITCONTROL_H | ||
|
||
#include <string> | ||
#include <vector> | ||
#include <memory> | ||
#include <string.h> | ||
|
||
#include "daisysp.h" | ||
#include "daisy_seed.h" | ||
|
||
#include "faust/gui/DecoratorUI.h" | ||
#include "faust/gui/ValueConverter.h" | ||
|
||
/******************************************************************************* | ||
* DaisyPatchInitControlUI : Faust User Interface | ||
******************************************************************************/ | ||
|
||
class DaisyPatchInitControlUI : public GenericUI | ||
{ | ||
|
||
private: | ||
|
||
// Base class for updatable items | ||
struct UpdatableZone { | ||
FAUSTFLOAT* fZone; | ||
|
||
UpdatableZone(FAUSTFLOAT* zone) : fZone(zone) {} | ||
virtual ~UpdatableZone() {} | ||
|
||
virtual void update() = 0; | ||
}; | ||
|
||
struct SwitchButton : daisy::Switch, UpdatableZone { | ||
|
||
SwitchButton(FAUSTFLOAT* zone):UpdatableZone(zone) | ||
{} | ||
|
||
void update() | ||
{ | ||
*fZone = RawState(); | ||
} | ||
}; | ||
|
||
// Implement checkbox using daisy::Switch | ||
struct CheckButton : daisy::Switch, UpdatableZone { | ||
|
||
FAUSTFLOAT fLastButton; | ||
|
||
CheckButton(FAUSTFLOAT* zone):UpdatableZone(zone), fLastButton(0) | ||
{} | ||
|
||
void update() | ||
{ | ||
FAUSTFLOAT button = RawState(); | ||
if (button == 1.0 && (button != fLastButton)) { | ||
*fZone = !*fZone; | ||
} | ||
fLastButton = button; | ||
} | ||
}; | ||
|
||
// Implements an analog knob by calling Process on the knob instance | ||
// that has already been created inside DaisyPatchSM | ||
struct AnalogKnob : UpdatableZone { | ||
|
||
std::unique_ptr<ValueConverter> fConverter; | ||
daisy::AnalogControl* fControl; | ||
|
||
AnalogKnob(daisy::AnalogControl* control, FAUSTFLOAT* zone, std::unique_ptr<ValueConverter>& converter, int rate) | ||
: UpdatableZone(zone), fConverter(std::move(converter)), fControl(control) | ||
{ | ||
} | ||
|
||
void update() | ||
{ | ||
*fZone = fConverter->ui2faust(fControl->Process()); | ||
} | ||
}; | ||
|
||
std::vector<std::unique_ptr<UpdatableZone>> fItems; | ||
daisy::patch_sm::DaisyPatchSM* fHw; | ||
|
||
std::string fKey, fValue, fScale; | ||
int fRate, fBoxLevel; | ||
|
||
struct KnobContext | ||
{ | ||
int fKnobId; | ||
FAUSTFLOAT* fZone; | ||
FAUSTFLOAT fMin; | ||
FAUSTFLOAT fMax; | ||
std::string fScale; | ||
KnobContext(int kid, | ||
FAUSTFLOAT* zone, | ||
FAUSTFLOAT min, | ||
FAUSTFLOAT max, | ||
const std::string& scale) | ||
:fKnobId(kid), fZone(zone), fMin(min), fMax(max), fScale(scale) | ||
{} | ||
}; | ||
std::vector<KnobContext> fKnobs; | ||
|
||
void InitKnob(int knob_pin, FAUSTFLOAT* zone, FAUSTFLOAT min, FAUSTFLOAT max, const std::string& scale) | ||
{ | ||
// context is kept, to be used in InitKnobs() | ||
fKnobs.push_back(KnobContext(knob_pin, zone, min, max, scale)); | ||
} | ||
|
||
void InitKnobs() | ||
{ | ||
for (size_t i = 0; i < fKnobs.size(); i++) { | ||
std::unique_ptr<ValueConverter> converter; | ||
if (fKnobs[i].fScale == "log") { | ||
converter = std::make_unique<LogValueConverter>(0., 1., fKnobs[i].fMin, fKnobs[i].fMax); | ||
} else if (fKnobs[i].fScale == "exp") { | ||
converter = std::make_unique<ExpValueConverter>(0., 1., fKnobs[i].fMin, fKnobs[i].fMax); | ||
} else { | ||
converter = std::make_unique<LinearValueConverter>(0., 1., fKnobs[i].fMin, fKnobs[i].fMax); | ||
} | ||
std::unique_ptr<AnalogKnob> knob = std::make_unique<AnalogKnob>(&fHw->controls[fKnobs[i].fKnobId], | ||
fKnobs[i].fZone, | ||
converter, | ||
fRate); | ||
fItems.push_back(std::move(knob)); | ||
} | ||
} | ||
|
||
public: | ||
|
||
DaisyPatchInitControlUI(daisy::patch_sm::DaisyPatchSM* hw, int rate) | ||
:fHw(hw), fScale("lin"),fRate(rate), fBoxLevel(0) | ||
{} | ||
|
||
// -- widget's layouts | ||
void openTabBox(const char* label) { fBoxLevel++; } | ||
void openHorizontalBox(const char* label) { fBoxLevel++; } | ||
void openVerticalBox(const char* label) { fBoxLevel++; } | ||
void closeBox() | ||
{ | ||
if (--fBoxLevel == 0) InitKnobs(); | ||
} | ||
|
||
// -- active widgets | ||
void addButton(const char* label, FAUSTFLOAT* zone) | ||
{ | ||
if (fKey == "switch") { | ||
std::unique_ptr<SwitchButton> button = std::make_unique<SwitchButton>(zone); | ||
//if (fValue == "1") { | ||
//button->Init(fSeed->GetPin(SW_1_PIN), fRate); | ||
//} | ||
fItems.push_back(std::move(button)); | ||
} | ||
fValue = fKey = fScale = ""; | ||
} | ||
|
||
void addCheckButton(const char* label, FAUSTFLOAT* zone) | ||
{ | ||
if (fKey == "switch") { | ||
std::unique_ptr<CheckButton> button = std::make_unique<CheckButton>(zone); | ||
//if (fValue == "1") { | ||
//button->Init(fSeed->GetPin(SW_1_PIN), fRate); | ||
//} | ||
fItems.push_back(std::move(button)); | ||
} | ||
fValue = fKey = fScale = ""; | ||
} | ||
|
||
void addVerticalSlider(const char* label, FAUSTFLOAT* zone, FAUSTFLOAT init, FAUSTFLOAT min, FAUSTFLOAT max, FAUSTFLOAT step) | ||
{ | ||
addNumEntry(label, zone, init, min, max, step); | ||
} | ||
void addHorizontalSlider(const char* label, FAUSTFLOAT* zone, FAUSTFLOAT init, FAUSTFLOAT min, FAUSTFLOAT max, FAUSTFLOAT step) | ||
{ | ||
addNumEntry(label, zone, init, min, max, step); | ||
} | ||
void addNumEntry(const char* label, FAUSTFLOAT* zone, FAUSTFLOAT init, FAUSTFLOAT min, FAUSTFLOAT max, FAUSTFLOAT step) | ||
{ | ||
if (fKey == "knob") { | ||
if (fValue == "1") { | ||
InitKnob(daisy::patch_sm::CV_1, zone, min, max, fScale); | ||
} else if (fValue == "2") { | ||
InitKnob(daisy::patch_sm::CV_2, zone, min, max, fScale); | ||
} else if (fValue == "3") { | ||
InitKnob(daisy::patch_sm::CV_3, zone, min, max, fScale); | ||
} else if (fValue == "4") { | ||
InitKnob(daisy::patch_sm::CV_4, zone, min, max, fScale); | ||
} | ||
} | ||
fValue = fKey = fScale = ""; | ||
} | ||
|
||
// -- metadata declarations | ||
void declare(FAUSTFLOAT* zone, const char* key, const char* val) | ||
{ | ||
if (strcmp(key, "switch") == 0 | ||
|| strcmp(key, "knob") == 0) { | ||
fKey = key; | ||
fValue = val; | ||
} else if (std::string(key) == "scale") { | ||
fScale = val; | ||
} | ||
} | ||
|
||
void update() | ||
{ | ||
for (const auto& it : fItems) it->update(); | ||
} | ||
|
||
}; | ||
|
||
#endif // FAUST_DAISYPATCHINITCONTROL_H | ||
/************************** END DaisyPatchInitControlUI.h **************************/ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters