@@ -74,6 +74,9 @@ include compile.mk | |||
dist: all | |||
ifndef VERSION | |||
$(error VERSION must be defined when calling make) | |||
endif | |||
rm -rf dist | |||
$(MAKE) -C plugins/Fundamental dist | |||
@@ -144,7 +147,7 @@ ifeq ($(ARCH), lin) | |||
cp dep/lib/libcurl.so.4 dist/Rack/ | |||
cp dep/lib/libzip.so.5 dist/Rack/ | |||
cp dep/lib/libportaudio.so.2 dist/Rack/ | |||
cp dep/lib/librtmidi.so dist/Rack/ | |||
cp dep/lib/librtmidi.so.4 dist/Rack/ | |||
mkdir -p dist/Rack/plugins | |||
cp -R plugins/Fundamental/dist/Fundamental dist/Rack/plugins/ | |||
endif | |||
@@ -20,7 +20,7 @@ Rack's dependencies (GLEW, glfw, etc) do not need to be installed on your system | |||
### Mac | |||
Install [Xcode](https://developer.apple.com/xcode/). | |||
Install [CMake](https://cmake.org/) and wget, preferably from [Homebrew](https://brew.sh/). | |||
Install [CMake](https://cmake.org/) (for some of Rack's dependencies) and wget, preferably from [Homebrew](https://brew.sh/). | |||
### Windows | |||
@@ -38,7 +38,7 @@ With your distro's package manager, make sure you have installed `gcc`, `make`, | |||
*If the build fails for you, please report the issue with a detailed error message to help the portability of Rack.* | |||
Clone this repository and `cd` into it. | |||
If you would like to build a previous version instead of the master branch, run `git checkout v0.3.2` for example. | |||
If you would like to build a previous version of Rack instead of the master branch, check out the desired tag with `git checkout v0.4.0` for example. | |||
Clone submodules. | |||
@@ -61,6 +61,8 @@ Run Rack. | |||
## Building plugins | |||
Be sure to check out and build the version of Rack you wish to build your plugins against. | |||
Clone your favorite plugin in the `plugins/` directory. e.g.: | |||
cd plugins | |||
@@ -1,12 +1,14 @@ | |||
VERSION ?= dev | |||
FLAGS += -DVERSION=$(VERSION) -DVERSION_$(subst .,_,$(VERSION)) | |||
ifdef VERSION | |||
FLAGS += -DVERSION=$(VERSION) | |||
endif | |||
# Generate dependency files alongside the object files | |||
FLAGS += -MMD | |||
FLAGS += -g | |||
# Optimization | |||
FLAGS += -O3 -march=nocona -ffast-math | |||
FLAGS += -Wall | |||
FLAGS += -g | |||
FLAGS += -Wall -Wextra -Wno-unused-parameter | |||
CXXFLAGS += -Wsuggest-override | |||
CXXFLAGS += -std=c++11 | |||
@@ -50,22 +50,24 @@ struct ModuleWidget : OpaqueWidget { | |||
/** Resets the parameters of the module and calls the Module's randomize(). | |||
Called when the user clicks Initialize in the context menu. | |||
*/ | |||
virtual void initialize(); | |||
virtual void reset(); | |||
/** Deprecated */ | |||
virtual void initialize() final {} | |||
/** Randomizes the parameters of the module and calls the Module's randomize(). | |||
Called when the user clicks Randomize in the context menu. | |||
*/ | |||
virtual void randomize(); | |||
virtual Menu *createContextMenu(); | |||
void draw(NVGcontext *vg); | |||
void draw(NVGcontext *vg) override; | |||
Vec dragPos; | |||
Widget *onMouseMove(Vec pos, Vec mouseRel); | |||
Widget *onHoverKey(Vec pos, int key); | |||
void onDragStart(); | |||
void onDragMove(Vec mouseRel); | |||
void onDragEnd(); | |||
void onMouseDownOpaque(int button); | |||
Widget *onMouseMove(Vec pos, Vec mouseRel) override; | |||
Widget *onHoverKey(Vec pos, int key) override; | |||
void onDragStart() override; | |||
void onDragMove(Vec mouseRel) override; | |||
void onDragEnd() override; | |||
void onMouseDownOpaque(int button) override; | |||
}; | |||
struct ValueLight; | |||
@@ -85,7 +87,7 @@ struct WireWidget : OpaqueWidget { | |||
void updateWire(); | |||
Vec getOutputPos(); | |||
Vec getInputPos(); | |||
void draw(NVGcontext *vg); | |||
void draw(NVGcontext *vg) override; | |||
void drawPlugs(NVGcontext *vg); | |||
}; | |||
@@ -99,7 +101,7 @@ struct WireContainer : TransparentWidget { | |||
void removeAllWires(Port *port); | |||
/** Returns the most recently added wire connected to the given Port, i.e. the top of the stack */ | |||
WireWidget *getTopWire(Port *port); | |||
void draw(NVGcontext *vg); | |||
void draw(NVGcontext *vg) override; | |||
}; | |||
struct RackWidget : OpaqueWidget { | |||
@@ -113,7 +115,10 @@ struct RackWidget : OpaqueWidget { | |||
RackWidget(); | |||
~RackWidget(); | |||
/** Completely clear the rack's modules and wires */ | |||
void clear(); | |||
/** Clears the rack and loads the template patch */ | |||
void reset(); | |||
void openDialog(); | |||
void saveDialog(); | |||
void saveAsDialog(); | |||
@@ -130,20 +135,20 @@ struct RackWidget : OpaqueWidget { | |||
bool requestModuleBox(ModuleWidget *m, Rect box); | |||
/** Moves a module to the closest non-colliding position */ | |||
bool requestModuleBoxNearest(ModuleWidget *m, Rect box); | |||
void step(); | |||
void draw(NVGcontext *vg); | |||
void step() override; | |||
void draw(NVGcontext *vg) override; | |||
void onMouseDownOpaque(int button); | |||
void onMouseDownOpaque(int button) override; | |||
}; | |||
struct RackRail : TransparentWidget { | |||
void draw(NVGcontext *vg); | |||
void draw(NVGcontext *vg) override; | |||
}; | |||
struct Panel : TransparentWidget { | |||
NVGcolor backgroundColor; | |||
std::shared_ptr<Image> backgroundImage; | |||
void draw(NVGcontext *vg); | |||
void draw(NVGcontext *vg) override; | |||
}; | |||
struct SVGPanel : FramebufferWidget { | |||
@@ -156,13 +161,13 @@ struct SVGPanel : FramebufferWidget { | |||
struct CircularShadow : TransparentWidget { | |||
float blur = 0.0; | |||
void draw(NVGcontext *vg); | |||
void draw(NVGcontext *vg) override; | |||
}; | |||
struct Light : TransparentWidget { | |||
NVGcolor bgColor = nvgRGBf(0, 0, 0); | |||
NVGcolor color = nvgRGBf(1, 1, 1); | |||
void draw(NVGcontext *vg); | |||
void draw(NVGcontext *vg) override; | |||
}; | |||
struct ParamWidget : OpaqueWidget, QuantityWidget { | |||
@@ -176,22 +181,25 @@ struct ParamWidget : OpaqueWidget, QuantityWidget { | |||
json_t *toJson(); | |||
void fromJson(json_t *rootJ); | |||
virtual void randomize(); | |||
void onMouseDownOpaque(int button); | |||
void onChange(); | |||
void onMouseDownOpaque(int button) override; | |||
void onChange() override; | |||
}; | |||
/** Implements vertical dragging behavior for ParamWidgets */ | |||
struct Knob : ParamWidget { | |||
void onDragStart(); | |||
void onDragMove(Vec mouseRel); | |||
void onDragEnd(); | |||
/** Snap to nearest integer while dragging */ | |||
bool snap = false; | |||
float dragValue; | |||
void onDragStart() override; | |||
void onDragMove(Vec mouseRel) override; | |||
void onDragEnd() override; | |||
/** Tell engine to smoothly vary this parameter */ | |||
void onChange(); | |||
void onChange() override; | |||
}; | |||
struct SpriteKnob : virtual Knob, SpriteWidget { | |||
int minIndex, maxIndex, spriteCount; | |||
void step(); | |||
void step() override; | |||
}; | |||
/** A knob which rotates an SVG and caches it in a framebuffer */ | |||
@@ -204,16 +212,8 @@ struct SVGKnob : virtual Knob, FramebufferWidget { | |||
SVGKnob(); | |||
void setSVG(std::shared_ptr<SVG> svg); | |||
void step(); | |||
void onChange(); | |||
}; | |||
/** Snaps to the nearest integer value on mouse release */ | |||
struct SnapKnob : virtual Knob { | |||
void onDragEnd() { | |||
setValue(roundf(value)); | |||
Knob::onDragEnd(); | |||
} | |||
void step() override; | |||
void onChange() override; | |||
}; | |||
struct SVGSlider : Knob, FramebufferWidget { | |||
@@ -224,8 +224,8 @@ struct SVGSlider : Knob, FramebufferWidget { | |||
SVGWidget *handle; | |||
SVGSlider(); | |||
void step(); | |||
void onChange(); | |||
void step() override; | |||
void onChange() override; | |||
}; | |||
struct Switch : ParamWidget { | |||
@@ -239,13 +239,13 @@ struct SVGSwitch : virtual Switch, FramebufferWidget { | |||
SVGSwitch(); | |||
/** Adds an SVG file to represent the next switch position */ | |||
void addFrame(std::shared_ptr<SVG> svg); | |||
void step(); | |||
void onChange(); | |||
void step() override; | |||
void onChange() override; | |||
}; | |||
/** A switch that cycles through each mechanical position */ | |||
struct ToggleSwitch : virtual Switch { | |||
void onDragStart() { | |||
void onDragStart() override { | |||
// Cycle through values | |||
// e.g. a range of [0.0, 3.0] would have modes 0, 1, 2, and 3. | |||
if (value >= maxValue) | |||
@@ -258,11 +258,11 @@ struct ToggleSwitch : virtual Switch { | |||
/** A switch that is turned on when held */ | |||
struct MomentarySwitch : virtual Switch { | |||
/** Don't randomize state */ | |||
void randomize() {} | |||
void onDragStart() { | |||
void randomize() override {} | |||
void onDragStart() override { | |||
setValue(maxValue); | |||
} | |||
void onDragEnd() { | |||
void onDragEnd() override { | |||
setValue(minValue); | |||
} | |||
}; | |||
@@ -282,20 +282,20 @@ struct Port : OpaqueWidget { | |||
int portId; | |||
~Port(); | |||
void draw(NVGcontext *vg); | |||
void onMouseDownOpaque(int button); | |||
void onDragEnd(); | |||
void onDragStart(); | |||
void onDragDrop(Widget *origin); | |||
void onDragEnter(Widget *origin); | |||
void onDragLeave(Widget *origin); | |||
void draw(NVGcontext *vg) override; | |||
void onMouseDownOpaque(int button) override; | |||
void onDragEnd() override; | |||
void onDragStart() override; | |||
void onDragDrop(Widget *origin) override; | |||
void onDragEnter(Widget *origin) override; | |||
void onDragLeave(Widget *origin) override; | |||
}; | |||
struct SVGPort : Port, FramebufferWidget { | |||
SVGWidget *background; | |||
SVGPort(); | |||
void draw(NVGcontext *vg); | |||
void draw(NVGcontext *vg) override; | |||
}; | |||
/** If you don't add these to your ModuleWidget, they will fall out of the rack... */ | |||
@@ -316,7 +316,7 @@ struct Toolbar : OpaqueWidget { | |||
RadioButton *plugLightButton; | |||
Toolbar(); | |||
void draw(NVGcontext *vg); | |||
void draw(NVGcontext *vg) override; | |||
}; | |||
struct PluginManagerWidget : Widget { | |||
@@ -324,7 +324,7 @@ struct PluginManagerWidget : Widget { | |||
Widget *manageWidget; | |||
Widget *downloadWidget; | |||
PluginManagerWidget(); | |||
void step(); | |||
void step() override; | |||
}; | |||
struct RackScene : Scene { | |||
@@ -332,9 +332,9 @@ struct RackScene : Scene { | |||
ZoomWidget *zoomWidget; | |||
RackScene(); | |||
void step(); | |||
void draw(NVGcontext *vg); | |||
Widget *onHoverKey(Vec pos, int key); | |||
void step() override; | |||
void draw(NVGcontext *vg) override; | |||
Widget *onHoverKey(Vec pos, int key) override; | |||
}; | |||
//////////////////// | |||
@@ -57,7 +57,11 @@ struct RoundHugeBlackKnob : RoundBlackKnob { | |||
} | |||
}; | |||
struct RoundSmallBlackSnapKnob : RoundSmallBlackKnob, SnapKnob {}; | |||
struct RoundSmallBlackSnapKnob : RoundSmallBlackKnob { | |||
RoundSmallBlackSnapKnob() { | |||
snap = true; | |||
} | |||
}; | |||
struct Davies1900hKnob : SVGKnob { | |||
@@ -109,7 +113,11 @@ struct Davies1900hSmallBlackKnob : Davies1900hKnob { | |||
} | |||
}; | |||
struct Davies1900hSmallBlackSnapKnob : Davies1900hSmallBlackKnob, SnapKnob {}; | |||
struct Davies1900hSmallBlackSnapKnob : Davies1900hSmallBlackKnob { | |||
Davies1900hSmallBlackSnapKnob() { | |||
snap = true; | |||
} | |||
}; | |||
struct Rogan : SVGKnob { | |||
@@ -366,7 +374,11 @@ struct BefacoBigKnob : SVGKnob { | |||
} | |||
}; | |||
struct BefacoBigSnapKnob : BefacoBigKnob, SnapKnob {}; | |||
struct BefacoBigSnapKnob : BefacoBigKnob { | |||
BefacoBigSnapKnob() { | |||
snap = true; | |||
} | |||
}; | |||
struct BefacoTinyKnob : SVGKnob { | |||
BefacoTinyKnob() { | |||
@@ -426,7 +438,7 @@ struct CL1362Port : SVGPort { | |||
struct ValueLight : Light { | |||
float *value = NULL; | |||
virtual void setValue(float v) {} | |||
void step() { | |||
void step() override { | |||
if (value) | |||
setValue(*value); | |||
} | |||
@@ -434,7 +446,7 @@ struct ValueLight : Light { | |||
struct ColorValueLight : ValueLight { | |||
NVGcolor baseColor; | |||
void setValue(float v) { | |||
void setValue(float v) override { | |||
v = sqrtBipolar(v); | |||
color = baseColor; | |||
color.a *= clampf(v, 0.0, 1.0); | |||
@@ -462,7 +474,7 @@ struct GreenValueLight : ColorValueLight { | |||
struct PolarityLight : ValueLight { | |||
NVGcolor posColor; | |||
NVGcolor negColor; | |||
void setValue(float v) { | |||
void setValue(float v) override { | |||
v = sqrtBipolar(v); | |||
color = (v >= 0.0) ? posColor : negColor; | |||
color.a *= clampf(fabsf(v), 0.0, 1.0); | |||
@@ -478,7 +490,7 @@ struct GreenRedPolarityLight : PolarityLight { | |||
struct ModeValueLight : ValueLight { | |||
std::vector<NVGcolor> colors; | |||
void setValue(float v) { | |||
void setValue(float v) override { | |||
int mode = clampi((int)roundf(v), 0, colors.size()); | |||
color = colors[mode]; | |||
} | |||
@@ -615,8 +627,7 @@ struct ScrewBlack : SVGScrew { | |||
struct LightPanel : Panel { | |||
LightPanel() { | |||
// backgroundColor = nvgRGB(0xe6, 0xe6, 0xe6); | |||
backgroundColor = nvgRGB(0xf0, 0xf0, 0xf0); | |||
backgroundColor = nvgRGB(0xe6, 0xe6, 0xe6); | |||
} | |||
}; | |||
@@ -56,8 +56,10 @@ struct Module { | |||
virtual void fromJson(json_t *root) {} | |||
/** Override these to implement spacial behavior when user clicks Initialize and Randomize */ | |||
virtual void initialize() {} | |||
virtual void reset() {} | |||
virtual void randomize() {} | |||
/** Deprecated */ | |||
virtual void initialize() final {} | |||
}; | |||
struct Wire { | |||
@@ -82,8 +84,8 @@ void engineRemoveWire(Wire *wire); | |||
void engineSetParam(Module *module, int paramId, float value); | |||
void engineSetParamSmooth(Module *module, int paramId, float value); | |||
void engineSetSampleRate(float sampleRate); | |||
float engineGetSampleRate(); | |||
extern float gSampleRate; | |||
extern bool gPaused; | |||
@@ -20,7 +20,7 @@ namespace rack { | |||
template <class TModuleWidget> | |||
Model *createModel(Plugin *plugin, std::string slug, std::string name) { | |||
struct TModel : Model { | |||
ModuleWidget *createModuleWidget() { | |||
ModuleWidget *createModuleWidget() override { | |||
ModuleWidget *moduleWidget = new TModuleWidget(); | |||
moduleWidget->model = this; | |||
return moduleWidget; | |||
@@ -141,7 +141,7 @@ struct TransformWidget : Widget { | |||
void translate(Vec delta); | |||
void rotate(float angle); | |||
void scale(Vec s); | |||
void draw(NVGcontext *vg); | |||
void draw(NVGcontext *vg) override; | |||
}; | |||
@@ -151,33 +151,33 @@ struct TransformWidget : Widget { | |||
/** Widget that does not respond to events */ | |||
struct TransparentWidget : virtual Widget { | |||
Widget *onMouseDown(Vec pos, int button) {return NULL;} | |||
Widget *onMouseUp(Vec pos, int button) {return NULL;} | |||
Widget *onMouseMove(Vec pos, Vec mouseRel) {return NULL;} | |||
Widget *onScroll(Vec pos, Vec scrollRel) {return NULL;} | |||
Widget *onMouseDown(Vec pos, int button) override {return NULL;} | |||
Widget *onMouseUp(Vec pos, int button) override {return NULL;} | |||
Widget *onMouseMove(Vec pos, Vec mouseRel) override {return NULL;} | |||
Widget *onScroll(Vec pos, Vec scrollRel) override {return NULL;} | |||
}; | |||
/** Widget that automatically responds to all mouse events but gives a chance for children to respond instead */ | |||
struct OpaqueWidget : virtual Widget { | |||
Widget *onMouseDown(Vec pos, int button) { | |||
Widget *onMouseDown(Vec pos, int button) override { | |||
Widget *w = Widget::onMouseDown(pos, button); | |||
if (w) return w; | |||
onMouseDownOpaque(button); | |||
return this; | |||
} | |||
Widget *onMouseUp(Vec pos, int button) { | |||
Widget *onMouseUp(Vec pos, int button) override { | |||
Widget *w = Widget::onMouseUp(pos, button); | |||
if (w) return w; | |||
onMouseUpOpaque(button); | |||
return this; | |||
} | |||
Widget *onMouseMove(Vec pos, Vec mouseRel) { | |||
Widget *onMouseMove(Vec pos, Vec mouseRel) override { | |||
Widget *w = Widget::onMouseMove(pos, mouseRel); | |||
if (w) return w; | |||
onMouseMoveOpaque(mouseRel); | |||
return this; | |||
} | |||
Widget *onScroll(Vec pos, Vec scrollRel) { | |||
Widget *onScroll(Vec pos, Vec scrollRel) override { | |||
Widget *w = Widget::onScroll(pos, scrollRel); | |||
if (w) return w; | |||
if (onScrollOpaque(scrollRel)) | |||
@@ -199,22 +199,22 @@ struct SpriteWidget : virtual Widget { | |||
Vec spriteSize; | |||
std::shared_ptr<Image> spriteImage; | |||
int index = 0; | |||
void draw(NVGcontext *vg); | |||
void draw(NVGcontext *vg) override; | |||
}; | |||
struct SVGWidget : virtual Widget { | |||
std::shared_ptr<SVG> svg; | |||
/** Sets the box size to the svg image size */ | |||
void wrap(); | |||
void draw(NVGcontext *vg); | |||
void draw(NVGcontext *vg) override; | |||
}; | |||
/** Caches a widget's draw() result to a framebuffer so it is called less frequently | |||
When `dirty` is true, its children will be re-rendered on the next call to step(). | |||
When `dirty` is true, its children will be re-rendered on the next call to step() override. | |||
Events are not passed to the underlying scene. | |||
*/ | |||
struct FramebufferWidget : virtual Widget { | |||
/** Set this to true to re-render the children to the framebuffer in the next step() */ | |||
/** Set this to true to re-render the children to the framebuffer in the next step() override */ | |||
bool dirty = true; | |||
/** A margin in pixels around the children in the framebuffer | |||
This prevents cutting the rendered SVG off on the box edges. | |||
@@ -228,8 +228,8 @@ struct FramebufferWidget : virtual Widget { | |||
FramebufferWidget(); | |||
~FramebufferWidget(); | |||
void step(); | |||
void draw(NVGcontext *vg); | |||
void step() override; | |||
void draw(NVGcontext *vg) override; | |||
int getImageHandle(); | |||
}; | |||
@@ -263,14 +263,14 @@ struct Label : Widget { | |||
Label() { | |||
box.size.y = BND_WIDGET_HEIGHT; | |||
} | |||
void draw(NVGcontext *vg); | |||
void draw(NVGcontext *vg) override; | |||
}; | |||
// Deletes itself from parent when clicked | |||
struct MenuOverlay : OpaqueWidget { | |||
void onDragDrop(Widget *origin); | |||
bool onScrollOpaque(Vec scrollRel) {return true;} | |||
Widget *onHoverKey(Vec pos, int key); | |||
void onDragDrop(Widget *origin) override; | |||
bool onScrollOpaque(Vec scrollRel) override {return true;} | |||
Widget *onHoverKey(Vec pos, int key) override; | |||
}; | |||
struct MenuEntry; | |||
@@ -289,9 +289,9 @@ struct Menu : OpaqueWidget { | |||
void pushChild(Widget *child); | |||
void setChildMenu(Menu *menu); | |||
void fit(); | |||
void step(); | |||
void draw(NVGcontext *vg); | |||
bool onScrollOpaque(Vec scrollRel); | |||
void step() override; | |||
void draw(NVGcontext *vg) override; | |||
bool onScrollOpaque(Vec scrollRel) override; | |||
}; | |||
struct MenuEntry : OpaqueWidget { | |||
@@ -304,16 +304,16 @@ struct MenuEntry : OpaqueWidget { | |||
}; | |||
struct MenuLabel : MenuEntry { | |||
void draw(NVGcontext *vg); | |||
void draw(NVGcontext *vg) override; | |||
}; | |||
struct MenuItem : MenuEntry { | |||
float computeMinWidth(NVGcontext *vg); | |||
void draw(NVGcontext *vg); | |||
float computeMinWidth(NVGcontext *vg) override; | |||
void draw(NVGcontext *vg) override; | |||
virtual Menu *createChildMenu() {return NULL;} | |||
void onMouseEnter(); | |||
void onDragDrop(Widget *origin); | |||
void onMouseEnter() override; | |||
void onDragDrop(Widget *origin) override; | |||
}; | |||
struct Button : OpaqueWidget { | |||
@@ -323,16 +323,16 @@ struct Button : OpaqueWidget { | |||
Button() { | |||
box.size.y = BND_WIDGET_HEIGHT; | |||
} | |||
void draw(NVGcontext *vg); | |||
void onMouseEnter(); | |||
void onMouseLeave(); | |||
void onDragStart(); | |||
void onDragEnd(); | |||
void onDragDrop(Widget *origin); | |||
void draw(NVGcontext *vg) override; | |||
void onMouseEnter() override; | |||
void onMouseLeave() override; | |||
void onDragStart() override; | |||
void onDragEnd() override; | |||
void onDragDrop(Widget *origin) override; | |||
}; | |||
struct ChoiceButton : Button { | |||
void draw(NVGcontext *vg); | |||
void draw(NVGcontext *vg) override; | |||
}; | |||
struct RadioButton : OpaqueWidget, QuantityWidget { | |||
@@ -341,10 +341,10 @@ struct RadioButton : OpaqueWidget, QuantityWidget { | |||
RadioButton() { | |||
box.size.y = BND_WIDGET_HEIGHT; | |||
} | |||
void draw(NVGcontext *vg); | |||
void onMouseEnter(); | |||
void onMouseLeave(); | |||
void onDragDrop(Widget *origin); | |||
void draw(NVGcontext *vg) override; | |||
void onMouseEnter() override; | |||
void onMouseLeave() override; | |||
void onDragDrop(Widget *origin) override; | |||
}; | |||
struct Slider : OpaqueWidget, QuantityWidget { | |||
@@ -353,10 +353,10 @@ struct Slider : OpaqueWidget, QuantityWidget { | |||
Slider() { | |||
box.size.y = BND_WIDGET_HEIGHT; | |||
} | |||
void draw(NVGcontext *vg); | |||
void onDragStart(); | |||
void onDragMove(Vec mouseRel); | |||
void onDragEnd(); | |||
void draw(NVGcontext *vg) override; | |||
void onDragStart() override; | |||
void onDragMove(Vec mouseRel) override; | |||
void onDragEnd() override; | |||
}; | |||
/** Parent must be a ScrollWidget */ | |||
@@ -367,10 +367,10 @@ struct ScrollBar : OpaqueWidget { | |||
ScrollBar() { | |||
box.size = Vec(BND_SCROLLBAR_WIDTH, BND_SCROLLBAR_HEIGHT); | |||
} | |||
void draw(NVGcontext *vg); | |||
void onDragStart(); | |||
void onDragMove(Vec mouseRel); | |||
void onDragEnd(); | |||
void draw(NVGcontext *vg) override; | |||
void onDragStart() override; | |||
void onDragMove(Vec mouseRel) override; | |||
void onDragEnd() override; | |||
}; | |||
/** Handles a container with ScrollBar */ | |||
@@ -381,19 +381,19 @@ struct ScrollWidget : OpaqueWidget { | |||
Vec offset; | |||
ScrollWidget(); | |||
void step(); | |||
Widget *onMouseMove(Vec pos, Vec mouseRel); | |||
bool onScrollOpaque(Vec scrollRel); | |||
void step() override; | |||
Widget *onMouseMove(Vec pos, Vec mouseRel) override; | |||
bool onScrollOpaque(Vec scrollRel) override; | |||
}; | |||
struct ZoomWidget : Widget { | |||
float zoom = 1.0; | |||
void draw(NVGcontext *vg); | |||
Widget *onMouseDown(Vec pos, int button); | |||
Widget *onMouseUp(Vec pos, int button); | |||
Widget *onMouseMove(Vec pos, Vec mouseRel); | |||
Widget *onHoverKey(Vec pos, int key); | |||
Widget *onScroll(Vec pos, Vec scrollRel); | |||
void draw(NVGcontext *vg) override; | |||
Widget *onMouseDown(Vec pos, int button) override; | |||
Widget *onMouseUp(Vec pos, int button) override; | |||
Widget *onMouseMove(Vec pos, Vec mouseRel) override; | |||
Widget *onHoverKey(Vec pos, int key) override; | |||
Widget *onScroll(Vec pos, Vec scrollRel) override; | |||
}; | |||
struct TextField : OpaqueWidget { | |||
@@ -405,36 +405,36 @@ struct TextField : OpaqueWidget { | |||
TextField() { | |||
box.size.y = BND_WIDGET_HEIGHT; | |||
} | |||
void draw(NVGcontext *vg); | |||
Widget *onMouseDown(Vec pos, int button); | |||
bool onFocusText(int codepoint); | |||
bool onFocusKey(int scancode); | |||
bool onFocus(); | |||
void draw(NVGcontext *vg) override; | |||
Widget *onMouseDown(Vec pos, int button) override; | |||
bool onFocusText(int codepoint) override; | |||
bool onFocusKey(int key) override; | |||
bool onFocus() override; | |||
void insertText(std::string newText); | |||
virtual void onTextChange() {} | |||
}; | |||
struct PasswordField : TextField { | |||
void draw(NVGcontext *vg); | |||
void draw(NVGcontext *vg) override; | |||
}; | |||
struct ProgressBar : TransparentWidget, QuantityWidget { | |||
ProgressBar() { | |||
box.size.y = BND_WIDGET_HEIGHT; | |||
} | |||
void draw(NVGcontext *vg); | |||
void draw(NVGcontext *vg) override; | |||
}; | |||
struct Tooltip : Widget { | |||
void step(); | |||
void draw(NVGcontext *vg); | |||
void step() override; | |||
void draw(NVGcontext *vg) override; | |||
}; | |||
struct Scene : OpaqueWidget { | |||
Widget *overlay = NULL; | |||
void setOverlay(Widget *w); | |||
Menu *createMenu(); | |||
void step(); | |||
void step() override; | |||
}; | |||
@@ -4,7 +4,12 @@ | |||
namespace rack { | |||
std::string gApplicationName = "VCV Rack"; | |||
std::string gApplicationVersion = TOSTRING(VERSION); | |||
std::string gApplicationVersion = | |||
#ifdef VERSION | |||
TOSTRING(VERSION); | |||
#else | |||
"dev"; | |||
#endif | |||
std::string gApiHost = "http://api.vcvrack.com"; | |||
RackWidget *gRackWidget = NULL; | |||
@@ -12,6 +12,7 @@ namespace rack { | |||
void Knob::onDragStart() { | |||
guiCursorLock(); | |||
dragValue = value; | |||
randomizable = false; | |||
} | |||
@@ -19,7 +20,11 @@ void Knob::onDragMove(Vec mouseRel) { | |||
// Drag slower if Mod | |||
if (guiIsModPressed()) | |||
mouseRel = mouseRel.mult(1/16.0); | |||
setValue(value - KNOB_SENSITIVITY * (maxValue - minValue) * mouseRel.y); | |||
dragValue += KNOB_SENSITIVITY * (maxValue - minValue) * -mouseRel.y; | |||
if (snap) | |||
setValue(roundf(dragValue)); | |||
else | |||
setValue(dragValue); | |||
} | |||
void Knob::onDragEnd() { | |||
@@ -31,7 +36,10 @@ void Knob::onChange() { | |||
if (!module) | |||
return; | |||
engineSetParamSmooth(module, paramId, value); | |||
if (snap) | |||
engineSetParam(module, paramId, value); | |||
else | |||
engineSetParamSmooth(module, paramId, value); | |||
} | |||
@@ -6,7 +6,7 @@ namespace rack { | |||
void Light::draw(NVGcontext *vg) { | |||
float radius = box.size.x / 2.0; | |||
float oradius = radius + 40.0; | |||
float oradius = radius + 20.0; | |||
// Solid | |||
nvgBeginPath(vg); | |||
@@ -103,12 +103,12 @@ void ModuleWidget::disconnect() { | |||
} | |||
} | |||
void ModuleWidget::initialize() { | |||
void ModuleWidget::reset() { | |||
for (ParamWidget *param : params) { | |||
param->setValue(param->defaultValue); | |||
} | |||
if (module) { | |||
module->initialize(); | |||
module->reset(); | |||
} | |||
} | |||
@@ -170,7 +170,7 @@ Widget *ModuleWidget::onHoverKey(Vec pos, int key) { | |||
switch (key) { | |||
case GLFW_KEY_I: | |||
if (guiIsModPressed() && !guiIsShiftPressed()) { | |||
initialize(); | |||
reset(); | |||
return this; | |||
} | |||
break; | |||
@@ -206,35 +206,35 @@ void ModuleWidget::onDragEnd() { | |||
struct DisconnectMenuItem : MenuItem { | |||
ModuleWidget *moduleWidget; | |||
void onAction() { | |||
void onAction() override { | |||
moduleWidget->disconnect(); | |||
} | |||
}; | |||
struct InitializeMenuItem : MenuItem { | |||
struct ResetMenuItem : MenuItem { | |||
ModuleWidget *moduleWidget; | |||
void onAction() { | |||
moduleWidget->initialize(); | |||
void onAction() override { | |||
moduleWidget->reset(); | |||
} | |||
}; | |||
struct RandomizeMenuItem : MenuItem { | |||
ModuleWidget *moduleWidget; | |||
void onAction() { | |||
void onAction() override { | |||
moduleWidget->randomize(); | |||
} | |||
}; | |||
struct CloneMenuItem : MenuItem { | |||
ModuleWidget *moduleWidget; | |||
void onAction() { | |||
void onAction() override { | |||
gRackWidget->cloneModule(moduleWidget); | |||
} | |||
}; | |||
struct DeleteMenuItem : MenuItem { | |||
ModuleWidget *moduleWidget; | |||
void onAction() { | |||
void onAction() override { | |||
gRackWidget->deleteModule(moduleWidget); | |||
moduleWidget->finalizeEvents(); | |||
delete moduleWidget; | |||
@@ -248,7 +248,7 @@ Menu *ModuleWidget::createContextMenu() { | |||
menuLabel->text = model->plugin->name + ": " + model->name; | |||
menu->pushChild(menuLabel); | |||
InitializeMenuItem *resetItem = new InitializeMenuItem(); | |||
ResetMenuItem *resetItem = new ResetMenuItem(); | |||
resetItem->text = "Initialize"; | |||
resetItem->rightText = GUI_MOD_KEY_NAME "+I"; | |||
resetItem->moduleWidget = this; | |||
@@ -15,7 +15,7 @@ PluginManagerWidget::PluginManagerWidget() { | |||
Vec pos = Vec(0, 0); | |||
struct RegisterButton : Button { | |||
void onAction() { | |||
void onAction() override { | |||
std::thread t(openBrowser, "https://vcvrack.com/"); | |||
t.detach(); | |||
} | |||
@@ -46,7 +46,7 @@ PluginManagerWidget::PluginManagerWidget() { | |||
struct LogInButton : Button { | |||
TextField *emailField; | |||
TextField *passwordField; | |||
void onAction() { | |||
void onAction() override { | |||
std::thread t(pluginLogIn, emailField->text, passwordField->text); | |||
t.detach(); | |||
passwordField->text = ""; | |||
@@ -63,7 +63,7 @@ PluginManagerWidget::PluginManagerWidget() { | |||
pos.x += logInButton->box.size.x; | |||
struct StatusLabel : Label { | |||
void step() { | |||
void step() override { | |||
text = pluginGetLoginStatus(); | |||
} | |||
}; | |||
@@ -79,7 +79,7 @@ PluginManagerWidget::PluginManagerWidget() { | |||
Vec pos = Vec(0, 0); | |||
struct ManageButton : Button { | |||
void onAction() { | |||
void onAction() override { | |||
std::thread t(openBrowser, "https://vcvrack.com/"); | |||
t.detach(); | |||
} | |||
@@ -92,7 +92,7 @@ PluginManagerWidget::PluginManagerWidget() { | |||
pos.x += manageButton->box.size.x; | |||
struct RefreshButton : Button { | |||
void onAction() { | |||
void onAction() override { | |||
std::thread t(pluginRefresh); | |||
t.detach(); | |||
} | |||
@@ -106,7 +106,7 @@ PluginManagerWidget::PluginManagerWidget() { | |||
pos.x += refreshButton->box.size.x; | |||
struct LogOutButton : Button { | |||
void onAction() { | |||
void onAction() override { | |||
pluginLogOut(); | |||
} | |||
}; | |||
@@ -125,7 +125,7 @@ PluginManagerWidget::PluginManagerWidget() { | |||
Vec pos = Vec(0, 0); | |||
struct DownloadProgressBar : ProgressBar { | |||
void step() { | |||
void step() override { | |||
label = "Downloading"; | |||
std::string name = pluginGetDownloadName(); | |||
if (name != "") | |||
@@ -142,7 +142,7 @@ PluginManagerWidget::PluginManagerWidget() { | |||
pos.x += downloadProgress->box.size.x; | |||
// struct CancelButton : Button { | |||
// void onAction() { | |||
// void onAction() override { | |||
// pluginCancelDownload(); | |||
// } | |||
// }; | |||
@@ -86,7 +86,7 @@ Widget *RackScene::onHoverKey(Vec pos, int key) { | |||
switch (key) { | |||
case GLFW_KEY_N: | |||
if (guiIsModPressed() && !guiIsShiftPressed()) { | |||
gRackWidget->clear(); | |||
gRackWidget->reset(); | |||
return this; | |||
} | |||
break; | |||
@@ -38,6 +38,11 @@ void RackWidget::clear() { | |||
lastPath = ""; | |||
} | |||
void RackWidget::reset() { | |||
clear(); | |||
loadPatch(assetLocal("template.vcv")); | |||
} | |||
void RackWidget::openDialog() { | |||
std::string dir = lastPath.empty() ? assetLocal("") : extractDirectory(lastPath); | |||
char *path = osdialog_file(OSDIALOG_OPEN, dir.c_str(), NULL, NULL); | |||
@@ -364,7 +369,7 @@ void RackWidget::draw(NVGcontext *vg) { | |||
struct AddModuleMenuItem : MenuItem { | |||
Model *model; | |||
Vec modulePos; | |||
void onAction() { | |||
void onAction() override { | |||
ModuleWidget *moduleWidget = model->createModuleWidget(); | |||
gRackWidget->moduleContainer->addChild(moduleWidget); | |||
// Move module nearest to the mouse position | |||
@@ -377,7 +382,7 @@ struct AddModuleMenuItem : MenuItem { | |||
struct UrlItem : MenuItem { | |||
std::string url; | |||
void onAction() { | |||
void onAction() override { | |||
std::thread t(openBrowser, url); | |||
t.detach(); | |||
} | |||
@@ -386,7 +391,7 @@ struct UrlItem : MenuItem { | |||
struct AddPluginMenuItem : MenuItem { | |||
Plugin *plugin; | |||
Vec modulePos; | |||
Menu *createChildMenu() { | |||
Menu *createChildMenu() override { | |||
// Model items | |||
Menu *menu = new Menu(); | |||
for (Model *model : plugin->models) { | |||
@@ -5,7 +5,7 @@ namespace rack { | |||
struct PanelBorder : TransparentWidget { | |||
void draw(NVGcontext *vg) { | |||
void draw(NVGcontext *vg) override { | |||
NVGcolor borderColor = nvgRGBAf(0.5, 0.5, 0.5, 0.5); | |||
nvgBeginPath(vg); | |||
nvgRect(vg, 0.5, 0.5, box.size.x - 1.0, box.size.y - 1.0); | |||
@@ -7,76 +7,68 @@ namespace rack { | |||
struct NewItem : MenuItem { | |||
void onAction() { | |||
gRackWidget->clear(); | |||
void onAction() override { | |||
gRackWidget->reset(); | |||
} | |||
}; | |||
struct OpenItem : MenuItem { | |||
void onAction() { | |||
void onAction() override { | |||
gRackWidget->openDialog(); | |||
} | |||
}; | |||
struct SaveItem : MenuItem { | |||
void onAction() { | |||
void onAction() override { | |||
gRackWidget->saveDialog(); | |||
} | |||
}; | |||
struct SaveAsItem : MenuItem { | |||
void onAction() { | |||
void onAction() override { | |||
gRackWidget->saveAsDialog(); | |||
} | |||
}; | |||
struct QuitItem : MenuItem { | |||
void onAction() override { | |||
guiClose(); | |||
} | |||
}; | |||
struct FileChoice : ChoiceButton { | |||
void onAction() { | |||
void onAction() override { | |||
Menu *menu = gScene->createMenu(); | |||
menu->box.pos = getAbsolutePos().plus(Vec(0, box.size.y)); | |||
menu->box.size.x = box.size.x; | |||
{ | |||
MenuItem *newItem = new NewItem(); | |||
newItem->text = "New"; | |||
newItem->rightText = GUI_MOD_KEY_NAME "+N"; | |||
menu->pushChild(newItem); | |||
MenuItem *openItem = new OpenItem(); | |||
openItem->text = "Open"; | |||
openItem->rightText = GUI_MOD_KEY_NAME "+O"; | |||
menu->pushChild(openItem); | |||
MenuItem *saveItem = new SaveItem(); | |||
saveItem->text = "Save"; | |||
saveItem->rightText = GUI_MOD_KEY_NAME "+S"; | |||
menu->pushChild(saveItem); | |||
MenuItem *saveAsItem = new SaveAsItem(); | |||
saveAsItem->text = "Save as"; | |||
saveAsItem->rightText = GUI_MOD_KEY_NAME "+Shift+S"; | |||
menu->pushChild(saveAsItem); | |||
menu->pushChild(construct<NewItem>(&MenuItem::text, "New", &MenuItem::rightText, GUI_MOD_KEY_NAME "+N")); | |||
menu->pushChild(construct<OpenItem>(&MenuItem::text, "Open", &MenuItem::rightText, GUI_MOD_KEY_NAME "+O")); | |||
menu->pushChild(construct<SaveItem>(&MenuItem::text, "Save", &MenuItem::rightText, GUI_MOD_KEY_NAME "+S")); | |||
menu->pushChild(construct<SaveAsItem>(&MenuItem::text, "Save as", &MenuItem::rightText, GUI_MOD_KEY_NAME "+Shift+S")); | |||
menu->pushChild(construct<QuitItem>(&MenuItem::text, "Quit", &MenuItem::rightText, GUI_MOD_KEY_NAME "+Q")); | |||
} | |||
} | |||
}; | |||
struct PauseItem : MenuItem { | |||
void onAction() { | |||
void onAction() override { | |||
gPaused = !gPaused; | |||
} | |||
}; | |||
struct SampleRateItem : MenuItem { | |||
float sampleRate; | |||
void onAction() { | |||
void onAction() override { | |||
engineSetSampleRate(sampleRate); | |||
gPaused = false; | |||
} | |||
}; | |||
struct SampleRateChoice : ChoiceButton { | |||
void onAction() { | |||
void onAction() override { | |||
Menu *menu = gScene->createMenu(); | |||
menu->box.pos = getAbsolutePos().plus(Vec(0, box.size.y)); | |||
menu->box.size.x = box.size.x; | |||
@@ -94,11 +86,11 @@ struct SampleRateChoice : ChoiceButton { | |||
menu->pushChild(item); | |||
} | |||
} | |||
void step() { | |||
void step() override { | |||
if (gPaused) | |||
text = "Paused"; | |||
else | |||
text = stringf("%.0f Hz", gSampleRate); | |||
text = stringf("%.0f Hz", engineGetSampleRate()); | |||
} | |||
}; | |||
@@ -65,7 +65,7 @@ struct AudioInterface : Module { | |||
closeDevice(); | |||
} | |||
void step(); | |||
void step() override; | |||
void stepStream(const float *input, float *output, int numFrames); | |||
int getDeviceCount(); | |||
@@ -84,7 +84,7 @@ struct AudioInterface : Module { | |||
openDevice(deviceId, sampleRate, blockSize); | |||
} | |||
json_t *toJson() { | |||
json_t *toJson() override { | |||
json_t *rootJ = json_object(); | |||
if (deviceId >= 0) { | |||
std::string deviceName = getDeviceName(deviceId); | |||
@@ -95,7 +95,7 @@ struct AudioInterface : Module { | |||
return rootJ; | |||
} | |||
void fromJson(json_t *rootJ) { | |||
void fromJson(json_t *rootJ) override { | |||
json_t *deviceNameJ = json_object_get(rootJ, "deviceName"); | |||
if (deviceNameJ) { | |||
std::string deviceName = json_string_value(deviceNameJ); | |||
@@ -118,7 +118,7 @@ struct AudioInterface : Module { | |||
} | |||
} | |||
void initialize() { | |||
void reset() override { | |||
closeDevice(); | |||
} | |||
}; | |||
@@ -155,7 +155,7 @@ void AudioInterface::step() { | |||
// Once full, sample rate convert the input | |||
// inputBuffer -> SRC -> inputSrcBuffer | |||
if (inputBuffer.full()) { | |||
inputSrc.setRatio(sampleRate / gSampleRate); | |||
inputSrc.setRatio(sampleRate / engineGetSampleRate()); | |||
int inLen = inputBuffer.size(); | |||
int outLen = inputSrcBuffer.capacity(); | |||
inputSrc.process(inputBuffer.startData(), &inLen, inputSrcBuffer.endData(), &outLen); | |||
@@ -194,7 +194,7 @@ void AudioInterface::stepStream(const float *input, float *output, int numFrames | |||
} | |||
// Pass output through sample rate converter | |||
outputSrc.setRatio(gSampleRate / sampleRate); | |||
outputSrc.setRatio(engineGetSampleRate() / sampleRate); | |||
int inLen = numFrames; | |||
int outLen = outputBuffer.capacity(); | |||
outputSrc.process(inputFrames, &inLen, outputBuffer.endData(), &outLen); | |||
@@ -326,14 +326,14 @@ void AudioInterface::closeDevice() { | |||
struct AudioItem : MenuItem { | |||
AudioInterface *audioInterface; | |||
int deviceId; | |||
void onAction() { | |||
void onAction() override { | |||
audioInterface->setDeviceId(deviceId); | |||
} | |||
}; | |||
struct AudioChoice : ChoiceButton { | |||
AudioInterface *audioInterface; | |||
void onAction() { | |||
void onAction() override { | |||
Menu *menu = gScene->createMenu(); | |||
menu->box.pos = getAbsolutePos().plus(Vec(0, box.size.y)); | |||
menu->box.size.x = box.size.x; | |||
@@ -354,7 +354,7 @@ struct AudioChoice : ChoiceButton { | |||
menu->pushChild(audioItem); | |||
} | |||
} | |||
void step() { | |||
void step() override { | |||
std::string name = audioInterface->getDeviceName(audioInterface->deviceId); | |||
text = ellipsize(name, 24); | |||
} | |||
@@ -364,14 +364,14 @@ struct AudioChoice : ChoiceButton { | |||
struct SampleRateItem : MenuItem { | |||
AudioInterface *audioInterface; | |||
float sampleRate; | |||
void onAction() { | |||
void onAction() override { | |||
audioInterface->setSampleRate(sampleRate); | |||
} | |||
}; | |||
struct SampleRateChoice : ChoiceButton { | |||
AudioInterface *audioInterface; | |||
void onAction() { | |||
void onAction() override { | |||
Menu *menu = gScene->createMenu(); | |||
menu->box.pos = getAbsolutePos().plus(Vec(0, box.size.y)); | |||
menu->box.size.x = box.size.x; | |||
@@ -386,7 +386,7 @@ struct SampleRateChoice : ChoiceButton { | |||
menu->pushChild(item); | |||
} | |||
} | |||
void step() { | |||
void step() override { | |||
this->text = stringf("%.0f Hz", audioInterface->sampleRate); | |||
} | |||
}; | |||
@@ -395,14 +395,14 @@ struct SampleRateChoice : ChoiceButton { | |||
struct BlockSizeItem : MenuItem { | |||
AudioInterface *audioInterface; | |||
int blockSize; | |||
void onAction() { | |||
void onAction() override { | |||
audioInterface->setBlockSize(blockSize); | |||
} | |||
}; | |||
struct BlockSizeChoice : ChoiceButton { | |||
AudioInterface *audioInterface; | |||
void onAction() { | |||
void onAction() override { | |||
Menu *menu = gScene->createMenu(); | |||
menu->box.pos = getAbsolutePos().plus(Vec(0, box.size.y)); | |||
menu->box.size.x = box.size.x; | |||
@@ -417,7 +417,7 @@ struct BlockSizeChoice : ChoiceButton { | |||
menu->pushChild(item); | |||
} | |||
} | |||
void step() { | |||
void step() override { | |||
this->text = stringf("%d", audioInterface->blockSize); | |||
} | |||
}; | |||
@@ -10,17 +10,17 @@ struct ModuleResizeHandle : Widget { | |||
ModuleResizeHandle() { | |||
box.size = Vec(RACK_GRID_WIDTH * 1, RACK_GRID_HEIGHT); | |||
} | |||
Widget *onMouseDown(Vec pos, int button) { | |||
Widget *onMouseDown(Vec pos, int button) override { | |||
if (button == 0) | |||
return this; | |||
return NULL; | |||
} | |||
void onDragStart() { | |||
void onDragStart() override { | |||
assert(parent); | |||
originalWidth = parent->box.size.x; | |||
totalX = 0.0; | |||
} | |||
void onDragMove(Vec mouseRel) { | |||
void onDragMove(Vec mouseRel) override { | |||
ModuleWidget *m = dynamic_cast<ModuleWidget*>(parent); | |||
assert(m); | |||
totalX += mouseRel.x; | |||
@@ -38,7 +38,7 @@ struct ModuleResizeHandle : Widget { | |||
} | |||
gRackWidget->requestModuleBox(m, newBox); | |||
} | |||
void draw(NVGcontext *vg) { | |||
void draw(NVGcontext *vg) override { | |||
for (float x = 5.0; x <= 10.0; x += 5.0) { | |||
nvgBeginPath(vg); | |||
const float margin = 5.0; | |||
@@ -18,7 +18,7 @@ struct Bridge : Module { | |||
} | |||
~Bridge() { | |||
} | |||
void step(); | |||
void step() override; | |||
}; | |||
@@ -22,7 +22,7 @@ struct BlankWidget : ModuleWidget { | |||
Widget *bottomRightScrew; | |||
Widget *rightHandle; | |||
BlankWidget(); | |||
void step(); | |||
json_t *toJson(); | |||
void fromJson(json_t *rootJ); | |||
void step() override; | |||
json_t *toJson() override; | |||
void fromJson(json_t *rootJ) override; | |||
}; |
@@ -14,7 +14,7 @@ | |||
namespace rack { | |||
float gSampleRate; | |||
float sampleRate; | |||
bool gPaused = false; | |||
@@ -60,7 +60,7 @@ static void engineStep() { | |||
smoothModule = NULL; | |||
} | |||
else { | |||
value += delta * lambda / gSampleRate; | |||
value += delta * lambda / sampleRate; | |||
smoothModule->params[smoothParamId].value = value; | |||
} | |||
} | |||
@@ -97,7 +97,7 @@ static void engineRun() { | |||
} | |||
} | |||
float stepTime = mutexSteps / gSampleRate; | |||
float stepTime = mutexSteps / sampleRate; | |||
ahead += stepTime; | |||
auto currTime = std::chrono::high_resolution_clock::now(); | |||
const float aheadFactor = 2.0; | |||
@@ -221,12 +221,16 @@ void engineSetParamSmooth(Module *module, int paramId, float value) { | |||
void engineSetSampleRate(float newSampleRate) { | |||
VIPLock vipLock(vipMutex); | |||
std::lock_guard<std::mutex> lock(mutex); | |||
gSampleRate = newSampleRate; | |||
sampleRate = newSampleRate; | |||
// onSampleRateChange | |||
for (Module *module : modules) { | |||
module->onSampleRateChange(); | |||
} | |||
} | |||
float engineGetSampleRate() { | |||
return sampleRate; | |||
} | |||
} // namespace rack |
@@ -32,8 +32,7 @@ static json_t *settingsToJson() { | |||
json_object_set_new(rootJ, "allowCursorLock", allowCursorLockJ); | |||
// sampleRate | |||
float sampleRate = gSampleRate; | |||
json_t *sampleRateJ = json_real(sampleRate); | |||
json_t *sampleRateJ = json_real(engineGetSampleRate()); | |||
json_object_set_new(rootJ, "sampleRate", sampleRateJ); | |||
// plugLight | |||