Browse Source

Add Vec::crossfade. Rearrange various methods.

tags/v1.0.0
Andrew Belt 5 years ago
parent
commit
ac468a6670
5 changed files with 99 additions and 76 deletions
  1. +5
    -2
      include/math.hpp
  2. +68
    -68
      src/Core/MIDI_CV.cpp
  3. +13
    -2
      src/app/ModuleBrowser.cpp
  4. +1
    -0
      src/app/SVGSlider.cpp
  5. +12
    -4
      src/app/Toolbar.cpp

+ 5
- 2
include/math.hpp View File

@@ -134,8 +134,8 @@ inline float rescale(float x, float a, float b, float yMin, float yMax) {
return yMin + (x - a) / (b - a) * (yMax - yMin);
}

inline float crossfade(float a, float b, float frac) {
return a + frac * (b - a);
inline float crossfade(float a, float b, float p) {
return a + (b - a) * p;
}

/** Linearly interpolate an array `p` with index `x`
@@ -240,6 +240,9 @@ struct Vec {
}
Vec clamp(Rect bound) const;
Vec clampSafe(Rect bound) const;
Vec crossfade(Vec b, float p) {
return this->plus(b.minus(*this).mult(p));
}
};




+ 68
- 68
src/Core/MIDI_CV.cpp View File

@@ -60,35 +60,6 @@ struct MIDI_CV : Module {
onReset();
}

json_t *dataToJson() override {
json_t *rootJ = json_object();

json_t *divisionsJ = json_array();
for (int i = 0; i < 2; i++) {
json_t *divisionJ = json_integer(divisions[i]);
json_array_append_new(divisionsJ, divisionJ);
}
json_object_set_new(rootJ, "divisions", divisionsJ);

json_object_set_new(rootJ, "midi", midiInput.toJson());
return rootJ;
}

void dataFromJson(json_t *rootJ) override {
json_t *divisionsJ = json_object_get(rootJ, "divisions");
if (divisionsJ) {
for (int i = 0; i < 2; i++) {
json_t *divisionJ = json_array_get(divisionsJ, i);
if (divisionJ)
divisions[i] = json_integer_value(divisionJ);
}
}

json_t *midiJ = json_object_get(rootJ, "midi");
if (midiJ)
midiInput.fromJson(midiJ);
}

void onReset() override {
heldNotes.clear();
lastNote = 60;
@@ -100,45 +71,6 @@ struct MIDI_CV : Module {
midiInput.reset();
}

void pressNote(uint8_t note) {
// Remove existing similar note
auto it = std::find(heldNotes.begin(), heldNotes.end(), note);
if (it != heldNotes.end())
heldNotes.erase(it);
// Push note
heldNotes.push_back(note);
lastNote = note;
gate = true;
retriggerPulse.trigger(1e-3);
}

void releaseNote(uint8_t note) {
// Remove the note
auto it = std::find(heldNotes.begin(), heldNotes.end(), note);
if (it != heldNotes.end())
heldNotes.erase(it);
// Hold note if pedal is pressed
if (pedal)
return;
// Set last note
if (!heldNotes.empty()) {
lastNote = heldNotes[heldNotes.size() - 1];
gate = true;
}
else {
gate = false;
}
}

void pressPedal() {
pedal = true;
}

void releasePedal() {
pedal = false;
releaseNote(255);
}

void step() override {
midi::Message msg;
while (midiInput.shift(&msg)) {
@@ -254,6 +186,74 @@ struct MIDI_CV : Module {
default: break;
}
}

void pressNote(uint8_t note) {
// Remove existing similar note
auto it = std::find(heldNotes.begin(), heldNotes.end(), note);
if (it != heldNotes.end())
heldNotes.erase(it);
// Push note
heldNotes.push_back(note);
lastNote = note;
gate = true;
retriggerPulse.trigger(1e-3);
}

void releaseNote(uint8_t note) {
// Remove the note
auto it = std::find(heldNotes.begin(), heldNotes.end(), note);
if (it != heldNotes.end())
heldNotes.erase(it);
// Hold note if pedal is pressed
if (pedal)
return;
// Set last note
if (!heldNotes.empty()) {
lastNote = heldNotes[heldNotes.size() - 1];
gate = true;
}
else {
gate = false;
}
}

void pressPedal() {
pedal = true;
}

void releasePedal() {
pedal = false;
releaseNote(255);
}

json_t *dataToJson() override {
json_t *rootJ = json_object();

json_t *divisionsJ = json_array();
for (int i = 0; i < 2; i++) {
json_t *divisionJ = json_integer(divisions[i]);
json_array_append_new(divisionsJ, divisionJ);
}
json_object_set_new(rootJ, "divisions", divisionsJ);

json_object_set_new(rootJ, "midi", midiInput.toJson());
return rootJ;
}

void dataFromJson(json_t *rootJ) override {
json_t *divisionsJ = json_object_get(rootJ, "divisions");
if (divisionsJ) {
for (int i = 0; i < 2; i++) {
json_t *divisionJ = json_array_get(divisionsJ, i);
if (divisionJ)
divisions[i] = json_integer_value(divisionJ);
}
}

json_t *midiJ = json_object_get(rootJ, "midi");
if (midiJ)
midiInput.fromJson(midiJ);
}
};




+ 13
- 2
src/app/ModuleBrowser.cpp View File

@@ -48,19 +48,30 @@ struct ModuleBox : OpaqueWidget {
}

void draw(NVGcontext *vg) override {
DEBUG("%p model", model);

// Lazily create ModuleWidget when drawn
if (!initialized) {
Widget *transparentWidget = new TransparentWidget;
addChild(transparentWidget);

FramebufferWidget *fbWidget = new FramebufferWidget;
if (math::isNear(app()->window->pixelRatio, 1.0)) {
// Small details draw poorly at low DPI, so oversample when drawing to the framebuffer
fbWidget->oversample = 2.0;
}
transparentWidget->addChild(fbWidget);

ZoomWidget *zoomWidget = new ZoomWidget;
zoomWidget->setZoom(0.5f);
transparentWidget->addChild(zoomWidget);
fbWidget->addChild(zoomWidget);

ModuleWidget *moduleWidget = model->createModuleWidgetNull();
zoomWidget->addChild(moduleWidget);

float width = std::ceil(moduleWidget->box.size.x * 0.5f);
zoomWidget->box.size.x = moduleWidget->box.size.x * zoomWidget->zoom;
zoomWidget->box.size.y = RACK_GRID_HEIGHT;
float width = std::ceil(zoomWidget->box.size.x);
box.size.x = std::max(box.size.x, width);
initialized = true;
}


+ 1
- 0
src/app/SVGSlider.cpp View File

@@ -25,6 +25,7 @@ void SVGSlider::setBackgroundSVG(std::shared_ptr<SVG> backgroundSVG) {

void SVGSlider::setHandleSVG(std::shared_ptr<SVG> handleSVG) {
handle->setSVG(handleSVG);
handle->box.pos = maxHandlePos;
fb->dirty = true;
}



+ 12
- 4
src/app/Toolbar.cpp View File

@@ -269,7 +269,7 @@ struct EnginePauseItem : MenuItem {

struct SampleRateValueItem : MenuItem {
float sampleRate;
SampleRateValueItem(float sampleRate) {
void setSampleRate(float sampleRate) {
this->sampleRate = sampleRate;
text = string::f("%.0f Hz", sampleRate);
rightText = CHECKMARK(app()->engine->getSampleRate() == sampleRate);
@@ -292,7 +292,9 @@ struct SampleRateItem : MenuItem {

std::vector<float> sampleRates = {44100, 48000, 88200, 96000, 176400, 192000};
for (float sampleRate : sampleRates) {
menu->addChild(new SampleRateValueItem(sampleRate));
SampleRateValueItem *item = new SampleRateValueItem;
item->setSampleRate(sampleRate);
menu->addChild(item);
}
return menu;
}
@@ -301,9 +303,13 @@ struct SampleRateItem : MenuItem {

struct ThreadCountValueItem : MenuItem {
int threadCount;
ThreadCountValueItem(int threadCount) {
void setThreadCount(int threadCount) {
this->threadCount = threadCount;
text = string::f("%d", threadCount);
if (threadCount == 1)
text += " (default)";
else if (threadCount == system::getPhysicalCoreCount() / 2)
text += " (recommended)";
rightText = CHECKMARK(app()->engine->threadCount == threadCount);
}
void onAction(const event::Action &e) override {
@@ -321,7 +327,9 @@ struct ThreadCount : MenuItem {

int coreCount = system::getPhysicalCoreCount();
for (int i = 1; i <= coreCount; i++) {
menu->addChild(new ThreadCountValueItem(i));
ThreadCountValueItem *item = new ThreadCountValueItem;
item->setThreadCount(i);
menu->addChild(item);
}
return menu;
}


Loading…
Cancel
Save