mirror of
https://codeberg.org/armin/sm-26.git
synced 2026-10-11 17:01:53 +02:00
Add README, thread-safe engine, standalone format
This commit is contained in:
parent
8734ac25f1
commit
001a5a5324
4 changed files with 78 additions and 2 deletions
|
|
@ -20,9 +20,9 @@ endif()
|
||||||
add_subdirectory("${JUCE_ROOT}" juce_build)
|
add_subdirectory("${JUCE_ROOT}" juce_build)
|
||||||
|
|
||||||
if(APPLE)
|
if(APPLE)
|
||||||
set(SM26_FORMATS AU VST3)
|
set(SM26_FORMATS Standalone AU VST3)
|
||||||
elseif(UNIX)
|
elseif(UNIX)
|
||||||
set(SM26_FORMATS VST3)
|
set(SM26_FORMATS Standalone VST3)
|
||||||
else()
|
else()
|
||||||
set(SM26_FORMATS VST3)
|
set(SM26_FORMATS VST3)
|
||||||
endif()
|
endif()
|
||||||
|
|
@ -68,6 +68,8 @@ target_compile_definitions(SM-26 PRIVATE
|
||||||
|
|
||||||
juce_generate_juce_header(SM-26)
|
juce_generate_juce_header(SM-26)
|
||||||
|
|
||||||
|
target_link_libraries (SM-26 PRIVATE juce::juce_audio_utils juce::juce_audio_devices)
|
||||||
|
|
||||||
add_custom_target(gen_buildinfo ALL
|
add_custom_target(gen_buildinfo ALL
|
||||||
COMMAND "${CMAKE_CURRENT_SOURCE_DIR}/tools/gen_buildinfo.sh"
|
COMMAND "${CMAKE_CURRENT_SOURCE_DIR}/tools/gen_buildinfo.sh"
|
||||||
"${CMAKE_CURRENT_SOURCE_DIR}"
|
"${CMAKE_CURRENT_SOURCE_DIR}"
|
||||||
|
|
|
||||||
4
Makefile
4
Makefile
|
|
@ -83,6 +83,10 @@ install: build
|
||||||
if [ -n "$$VST3" ]; then rm -rf "$(DEST_VST3)"; cp -R "$$VST3" "$(HOME)/.vst3/"; else echo "!! VST3 not found in build dir"; exit 1; fi; \
|
if [ -n "$$VST3" ]; then rm -rf "$(DEST_VST3)"; cp -R "$$VST3" "$(HOME)/.vst3/"; else echo "!! VST3 not found in build dir"; exit 1; fi; \
|
||||||
fi
|
fi
|
||||||
@echo ">> SM-26 installed."
|
@echo ">> SM-26 installed."
|
||||||
|
@echo ""
|
||||||
|
@echo ">> To make newly-installed AUs visible to macOS immediately, run:"
|
||||||
|
@echo ">> sudo killall -HUP coreaudiod"
|
||||||
|
@echo ">> (or simply restart your audio host / DAW)"
|
||||||
|
|
||||||
uninstall:
|
uninstall:
|
||||||
@if [ "$(UNAME_S)" = "Darwin" ]; then \
|
@if [ "$(UNAME_S)" = "Darwin" ]; then \
|
||||||
|
|
|
||||||
58
README.md
Normal file
58
README.md
Normal file
|
|
@ -0,0 +1,58 @@
|
||||||
|
# SM-26
|
||||||
|
|
||||||
|
A simple subtractive synthesizer plugin built with JUCE / C++.
|
||||||
|
|
||||||
|
* **VST3** + **Audio Unit** (macOS arm64), **VST3** (Linux)
|
||||||
|
* 4 rotary knobs on the front panel whose meaning follows the selected preset
|
||||||
|
* 52 factory presets (Bass / Lead / Pad / Keys / Pluck / FX / Stab / Arp)
|
||||||
|
* tempo-synced delay (follows the host transport / BPM)
|
||||||
|
* 4x80 HD44780-style pixel display with a cascaded on-screen menu
|
||||||
|
* left/right/up/down navigation diamond + ENTER / ESC controls the menu
|
||||||
|
* status footer with the git revision and local build time
|
||||||
|
|
||||||
|
## Build
|
||||||
|
|
||||||
|
Requires a C++17 compiler, CMake >= 3.22 and (on Linux) X11/ALSA dev headers.
|
||||||
|
|
||||||
|
```sh
|
||||||
|
make # clones JUCE (once) into deps/ and builds
|
||||||
|
make install # installs + ad-hoc signs + un-quarantines
|
||||||
|
make uninstall # removes the installed plugins
|
||||||
|
make distclean # wipes build/
|
||||||
|
```
|
||||||
|
|
||||||
|
* macOS installs to `~/Library/Audio/Plug-Ins/` (AU + VST3).
|
||||||
|
* Linux installs to `~/.vst3/`.
|
||||||
|
|
||||||
|
If a freshly installed AU is not visible to `auval` / your DAW:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
sudo killall -HUP coreaudiod
|
||||||
|
```
|
||||||
|
|
||||||
|
## Usage
|
||||||
|
|
||||||
|
* Ship MIDI into the plugin; the 4 front-panel knobs drive whichever
|
||||||
|
parameters the current preset maps them to (e.g. cutoff/resonance/
|
||||||
|
envelope/delay, but many other routings exist).
|
||||||
|
* **Nav diamond + ENTER/ESC** drive the on-screen menu:
|
||||||
|
* root menu -> PRESETS / OSCILLATORS / FILTER / ENVELOPE / DELAY / SYSTEM
|
||||||
|
* up/down = move, left/right = adjust value, ENTER = open/confirm, ESC = back
|
||||||
|
* The LCD shows the current preset, the four knob mappings with live values,
|
||||||
|
host BPM and voice count. The delay can be set to a rhythmic subdivision
|
||||||
|
(SYNC) and locks to the host tempo.
|
||||||
|
|
||||||
|
## Layout
|
||||||
|
|
||||||
|
```
|
||||||
|
Build: Makefile -> CMake -> JUCE (deps/juce)
|
||||||
|
Source/
|
||||||
|
PluginProcessor.* audio processor + DSP shell
|
||||||
|
SynthEngine.* osc/filter/ADSR/delay voice engine
|
||||||
|
Presets.* 52 preset definitions + knob routings
|
||||||
|
SynthParams.* parameter model + formatting
|
||||||
|
PluginEditor.* panel, knobs, nav diamond, footer
|
||||||
|
LcdDisplay.* 4x80 HD44780-style display renderer
|
||||||
|
MenuSystem.* cascaded menu state machine
|
||||||
|
tools/gen_buildinfo.sh generates git-version + build-time header
|
||||||
|
```
|
||||||
|
|
@ -42,6 +42,7 @@ void SynthEngine::reset()
|
||||||
|
|
||||||
void SynthEngine::loadPreset (const Preset& p)
|
void SynthEngine::loadPreset (const Preset& p)
|
||||||
{
|
{
|
||||||
|
juce::SpinLock::ScopedLockType lock (paramLock);
|
||||||
for (int i = 0; i < kNumParams; ++i)
|
for (int i = 0; i < kNumParams; ++i)
|
||||||
params[i] = p.base[i];
|
params[i] = p.base[i];
|
||||||
for (int i = 0; i < kNumKnobs; ++i)
|
for (int i = 0; i < kNumKnobs; ++i)
|
||||||
|
|
@ -63,6 +64,7 @@ void SynthEngine::setPresetIndex (int i)
|
||||||
void SynthEngine::setParam (int id, float n01)
|
void SynthEngine::setParam (int id, float n01)
|
||||||
{
|
{
|
||||||
if (id < 0 || id >= kNumParams) return;
|
if (id < 0 || id >= kNumParams) return;
|
||||||
|
juce::SpinLock::ScopedLockType lock (paramLock);
|
||||||
params[id] = juce::jlimit (0.0f, 1.0f, n01);
|
params[id] = juce::jlimit (0.0f, 1.0f, n01);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -79,6 +81,8 @@ SynthEngine::KnobView SynthEngine::knobView (int knob) const
|
||||||
k.name = knobNames[knob];
|
k.name = knobNames[knob];
|
||||||
k.param = knobParams[knob];
|
k.param = knobParams[knob];
|
||||||
k.value01 = getParam (k.param);
|
k.value01 = getParam (k.param);
|
||||||
|
k.lo = knobLows[knob];
|
||||||
|
k.hi = knobHighs[knob];
|
||||||
return k;
|
return k;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -192,6 +196,14 @@ void SynthEngine::process (AudioBuffer<float>& buffer, MidiBuffer& midi,
|
||||||
wasPlaying = transportPlaying;
|
wasPlaying = transportPlaying;
|
||||||
lastBpmValue = (bpm > 10.0 && bpm < 300.0) ? bpm : 120.0;
|
lastBpmValue = (bpm > 10.0 && bpm < 300.0) ? bpm : 120.0;
|
||||||
|
|
||||||
|
std::array<float, kNumParams> snap;
|
||||||
|
{
|
||||||
|
juce::SpinLock::ScopedLockType lock (paramLock);
|
||||||
|
for (int i = 0; i < kNumParams; ++i)
|
||||||
|
snap[(size_t) i] = params[i];
|
||||||
|
}
|
||||||
|
const float* const params = snap.data();
|
||||||
|
|
||||||
const float cutN01 = params[PCUTOFF];
|
const float cutN01 = params[PCUTOFF];
|
||||||
const float resN01 = params[PRES];
|
const float resN01 = params[PRES];
|
||||||
const float fenvN01 = params[PFENV];
|
const float fenvN01 = params[PFENV];
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue