diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..c43514b --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +plugin.dylib +build \ No newline at end of file diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..ddeaa34 --- /dev/null +++ b/Makefile @@ -0,0 +1,11 @@ + +SOURCES = $(wildcard src/*.cpp) + +include ../../plugin.mk + + +dist: all + mkdir -p dist/JW-Modules + cp LICENSE* dist/JW-Modules/ + cp plugin.* dist/JW-Modules/ + cp -R res dist/JW-Modules/ diff --git a/README.md b/README.md new file mode 100644 index 0000000..0adf953 --- /dev/null +++ b/README.md @@ -0,0 +1,20 @@ +# JW-Modules + +Modules for VCV Rack from https://vcvrack.com/ + +## Building + +Compile Rack from source, following the instructions at https://github.com/VCVRack/Rack. + +Check out JW-Modules into the `plugins/` directory + +Then run: + + make + +## Modules + +SimpleClock + +![SimpleClock](./res/SimpleClock.png) + diff --git a/res/DejaVuSansMono.ttf b/res/DejaVuSansMono.ttf new file mode 100644 index 0000000..f578602 Binary files /dev/null and b/res/DejaVuSansMono.ttf differ diff --git a/res/LICENSE-DejaVu.txt b/res/LICENSE-DejaVu.txt new file mode 100644 index 0000000..254e2cc --- /dev/null +++ b/res/LICENSE-DejaVu.txt @@ -0,0 +1,99 @@ +Fonts are (c) Bitstream (see below). DejaVu changes are in public domain. +Glyphs imported from Arev fonts are (c) Tavmjong Bah (see below) + +Bitstream Vera Fonts Copyright +------------------------------ + +Copyright (c) 2003 by Bitstream, Inc. All Rights Reserved. Bitstream Vera is +a trademark of Bitstream, Inc. + +Permission is hereby granted, free of charge, to any person obtaining a copy +of the fonts accompanying this license ("Fonts") and associated +documentation files (the "Font Software"), to reproduce and distribute the +Font Software, including without limitation the rights to use, copy, merge, +publish, distribute, and/or sell copies of the Font Software, and to permit +persons to whom the Font Software is furnished to do so, subject to the +following conditions: + +The above copyright and trademark notices and this permission notice shall +be included in all copies of one or more of the Font Software typefaces. + +The Font Software may be modified, altered, or added to, and in particular +the designs of glyphs or characters in the Fonts may be modified and +additional glyphs or characters may be added to the Fonts, only if the fonts +are renamed to names not containing either the words "Bitstream" or the word +"Vera". + +This License becomes null and void to the extent applicable to Fonts or Font +Software that has been modified and is distributed under the "Bitstream +Vera" names. + +The Font Software may be sold as part of a larger software package but no +copy of one or more of the Font Software typefaces may be sold by itself. + +THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF COPYRIGHT, PATENT, +TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL BITSTREAM OR THE GNOME +FOUNDATION BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, INCLUDING +ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, +WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF +THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM OTHER DEALINGS IN THE +FONT SOFTWARE. + +Except as contained in this notice, the names of Gnome, the Gnome +Foundation, and Bitstream Inc., shall not be used in advertising or +otherwise to promote the sale, use or other dealings in this Font Software +without prior written authorization from the Gnome Foundation or Bitstream +Inc., respectively. For further information, contact: fonts at gnome dot +org. + +Arev Fonts Copyright +------------------------------ + +Copyright (c) 2006 by Tavmjong Bah. All Rights Reserved. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of the fonts accompanying this license ("Fonts") and +associated documentation files (the "Font Software"), to reproduce +and distribute the modifications to the Bitstream Vera Font Software, +including without limitation the rights to use, copy, merge, publish, +distribute, and/or sell copies of the Font Software, and to permit +persons to whom the Font Software is furnished to do so, subject to +the following conditions: + +The above copyright and trademark notices and this permission notice +shall be included in all copies of one or more of the Font Software +typefaces. + +The Font Software may be modified, altered, or added to, and in +particular the designs of glyphs or characters in the Fonts may be +modified and additional glyphs or characters may be added to the +Fonts, only if the fonts are renamed to names not containing either +the words "Tavmjong Bah" or the word "Arev". + +This License becomes null and void to the extent applicable to Fonts +or Font Software that has been modified and is distributed under the +"Tavmjong Bah Arev" names. + +The Font Software may be sold as part of a larger software package but +no copy of one or more of the Font Software typefaces may be sold by +itself. + +THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT +OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL +TAVMJONG BAH BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM +OTHER DEALINGS IN THE FONT SOFTWARE. + +Except as contained in this notice, the name of Tavmjong Bah shall not +be used in advertising or otherwise to promote the sale, use or other +dealings in this Font Software without prior written authorization +from Tavmjong Bah. For further information, contact: tavmjong @ free +. fr. + +$Id: LICENSE 2133 2007-11-28 02:46:28Z lechimp $ diff --git a/res/SimpleClock.png b/res/SimpleClock.png new file mode 100644 index 0000000..f379a1e Binary files /dev/null and b/res/SimpleClock.png differ diff --git a/res/SimpleClock.svg b/res/SimpleClock.svg new file mode 100644 index 0000000..19cd2d4 --- /dev/null +++ b/res/SimpleClock.svg @@ -0,0 +1,164 @@ + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/JWModules.cpp b/src/JWModules.cpp new file mode 100644 index 0000000..08f6385 --- /dev/null +++ b/src/JWModules.cpp @@ -0,0 +1,12 @@ +#include "JWModules.hpp" + + +Plugin *plugin; + +void init(rack::Plugin *p) { + plugin = p; + plugin->slug = "JW-Modules"; + plugin->name = "JW-Modules"; + plugin->homepageUrl = "https://github.com/jeremywen/JW-Modules"; + createModel(plugin, "SimpleClock", "SimpleClock"); +} diff --git a/src/JWModules.hpp b/src/JWModules.hpp new file mode 100644 index 0000000..6a9782d --- /dev/null +++ b/src/JWModules.hpp @@ -0,0 +1,15 @@ +#include "rack.hpp" + + +using namespace rack; + + +extern Plugin *plugin; + +//////////////////// +// module widgets +//////////////////// + +struct SimpleClockWidget : ModuleWidget { + SimpleClockWidget(); +}; diff --git a/src/SimpleClock.cpp b/src/SimpleClock.cpp new file mode 100644 index 0000000..01961c8 --- /dev/null +++ b/src/SimpleClock.cpp @@ -0,0 +1,138 @@ +#include "JWModules.hpp" +#include "dsp/digital.hpp" + + +struct SimpleClock : Module { + enum ParamIds { + CLOCK_PARAM, + RUN_PARAM, + GATE_PARAM, + NUM_PARAMS + }; + enum InputIds { + CLOCK_INPUT, + NUM_INPUTS + }; + enum OutputIds { + GATES_OUTPUT, + RESET_OUTPUT, + NUM_OUTPUTS + }; + + bool running = true; + SchmittTrigger clockTrigger; // for external clock + // For buttons + SchmittTrigger runningTrigger; + SchmittTrigger gateTriggers[8]; + float phase = 0.0; + int index = 0; + + enum GateMode { + TRIGGER, + RETRIGGER, + CONTINUOUS, + }; + GateMode gateMode = TRIGGER; + PulseGenerator gatePulse; + + // Lights + float runningLight = 0.0; + + SimpleClock() : Module(NUM_PARAMS, NUM_INPUTS, NUM_OUTPUTS) {} + void step(); + + json_t *toJson() { + json_t *rootJ = json_object(); + + // running + json_object_set_new(rootJ, "running", json_boolean(running)); + + return rootJ; + } + + void fromJson(json_t *rootJ) { + // running + json_t *runningJ = json_object_get(rootJ, "running"); + if (runningJ) + running = json_is_true(runningJ); + + } + + void initialize() { + } + + void randomize() { + } +}; + + +void SimpleClock::step() { + const float lightLambda = 0.075; + // Run + if (runningTrigger.process(params[RUN_PARAM].value)) { + running = !running; + } + runningLight = running ? 1.0 : 0.0; + + bool nextStep = false; + + if (running) { + // Internal clock + float clockTime = powf(2.0, params[CLOCK_PARAM].value + inputs[CLOCK_INPUT].value); + phase += clockTime / gSampleRate; + if (phase >= 1.0) { + phase -= 1.0; + nextStep = true; + } + } + + if (nextStep) { + // Advance step + int numSteps = 8; + index += 1; + if (index >= numSteps) { + index = 0; + } + gatePulse.trigger(1e-3); + } + + bool pulse = gatePulse.process(1.0 / gSampleRate); + + // Rows + bool gatesOn = running; + if (gateMode == TRIGGER) + gatesOn = gatesOn && pulse; + else if (gateMode == RETRIGGER) + gatesOn = gatesOn && !pulse; + + // Outputs + outputs[RESET_OUTPUT].value = index == 0 ? 10.0 : 0.0; + outputs[GATES_OUTPUT].value = gatesOn ? 10.0 : 0.0; +} + + +SimpleClockWidget::SimpleClockWidget() { + SimpleClock *module = new SimpleClock(); + setModule(module); + box.size = Vec(15*4, 380); + + { + SVGPanel *panel = new SVGPanel(); + panel->box.size = box.size; + panel->setBackground(SVG::load(assetPlugin(plugin, "res/SimpleClock.svg"))); + addChild(panel); + } + + addChild(createScrew(Vec(15, 0))); + addChild(createScrew(Vec(box.size.x-30, 0))); + addChild(createScrew(Vec(15, 365))); + addChild(createScrew(Vec(box.size.x-30, 365))); + + addParam(createParam(Vec(16, 50), module, SimpleClock::CLOCK_PARAM, -2.0, 6.0, 2.0)); + + addParam(createParam(Vec(21, 130), module, SimpleClock::RUN_PARAM, 0.0, 1.0, 0.0)); + addChild(createValueLight>(Vec(26, 135), &module->runningLight)); + + addOutput(createOutput(Vec(18, 218), module, SimpleClock::RESET_OUTPUT)); + addOutput(createOutput(Vec(18, 318), module, SimpleClock::GATES_OUTPUT)); +}