Skip to content

Commit 6ad2112

Browse files
committed
Merge branch 'main' of https://github.com/koppi/sdl2-synth
2 parents 57f34e9 + 05079ae commit 6ad2112

File tree

2 files changed

+18
-218
lines changed

2 files changed

+18
-218
lines changed

CMakePresets.json

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@
44
{
55
"name": "common",
66
"hidden": true,
7-
"generator": "Ninja",
87
"binaryDir": "build/${presetName}",
98
"cacheVariables": {
109
"CMAKE_POLICY_VERSION_MINIMUM": "3.5"

README.md

Lines changed: 18 additions & 217 deletions
Original file line numberDiff line numberDiff line change
@@ -1,249 +1,50 @@
1-
A modular synthesizer application written in C, using SDL2 for graphics and audio, and supporting MIDI input via libremidi. The GUI is resizable and features oscilloscope and spectrum displays, keyboard input, and real-time control of oscillators, effects, mixer, and arpeggiator.
2-
3-
![sdl2-synth screenshot](screenshot.png)
4-
5-
![GitHub last commit](https://img.shields.io/github/last-commit/koppi/sdl2-synth)
6-
![GitHub commit activity](https://img.shields.io/github/commit-activity/w/koppi/sdl2-synth)
7-
[![OS](https://github.com/koppi/sdl2-synth/actions/workflows/os.yml/badge.svg)](https://github.com/koppi/sdl2-synth/actions/workflows/os.yml)
8-
[![Web](https://github.com/koppi/sdl2-synth/actions/workflows/web.yml/badge.svg)](https://github.com/koppi/sdl2-synth/actions/workflows/web.yml)
9-
[![GitHub issues](https://img.shields.io/github/issues/koppi/sdl2-synth)](https://github.com/koppi/sdl2-synth/issues)
1+
A modular synthesizer application written in C, using SDL2 for graphics and audio, and supporting MIDI input via libremidi.
102

113
## Features
124

13-
- **4-oscillator synth**: Each with independent waveform, pitch, detune, gain, phase, pulse width, and unison controls.
14-
- **Comprehensive Parameter Control**: All oscillator parameters accessible via intuitive combo boxes:
15-
- **Waveform Selection**: SINE, SAW, SQUARE, TRI, NOISE
16-
- **Pitch Presets**: Common semitone offsets (-24 to +24)
17-
- **Detune Presets**: Standard cent values (-100¢ to +100¢)
18-
- **Gain Presets**: Common levels (0%, 12%, 25%, 50%, 75%, 87%, 100%)
19-
- **Phase Presets**: Musical phase relationships (0°, 45°, 90°, 135°, 180°, etc.)
20-
- **Pulse Width Presets**: Standard duty cycles (10%, 25%, 50%, 75%, 90%)
21-
- **Unison Voices**: 1 to 8 voice layering
22-
- **Unison Spread**: Preset detuning amounts (Off, Tight, Medium, Wide, Extra Wide)
23-
- **Modern Dear ImGui Interface**: Clean, responsive GUI using the Dear ImGui library- **Mixer**: Control the mix and master volume of each oscillator with bus compression.
24-
- **Mastering**: Professional post-processing with DC filter, soft clipping, auto gain, and level meters.
25-
- **Effects**: Flanger, delay, reverb, and analog filter with real-time controls.
26-
- **Analog Filter**: Professional-grade resonant filter with multiple types and advanced processing.
27-
- **Filter Types**: Low-pass, High-pass, Bandpass, Notch
28-
- **Adjustable Cutoff**: 20Hz - 20kHz with logarithmic control
29-
- **Resonance (Q)**: 0.1 - 10.0 for filter peaking and character
30-
- **Drive Control**: 1.0 - 10.0 with soft saturation for warmth and distortion
31-
- **Oversampling**: 1x, 2x, 4x, 8x for aliasing reduction
32-
- **Inertial Smoothing**: Prevents zipper noise during parameter changes
33-
- **Wet/Dry Mix**: 0% - 100% for parallel processing
34-
- **Arpeggiator**: Multiple modes, adjustable tempo, octave control, and multi-octave chord arpeggiation.
35-
- **Arpeggiator Modes**: UP, DOWN, ORDER, RANDOM
36-
- **Octave Control**: Select base octave (0-4 = octaves 1-5) for all notes
37-
- **Multi-Octave Spread**: Spread chords across 1-6 octaves for rich, layered arpeggios
38-
- **Hold Function**: Sustain arpeggios after key release
39-
- **Polyphonic Mode**: Play all notes simultaneously or cycle through them in order
40-
- **MIDI CC Control**:
41-
- CC #90: Enable/disable arpeggiator
42-
- CC #91: Select arpeggiator mode (UP/DOWN/ORDER/RANDOM)
43-
- CC #92: Hold function on/off
44-
- CC #93: Base octave selection (0-4)
45-
- CC #94: Octaves spread control (1-6)
46-
- **Mastering**: Professional post-processing with visual feedback.
47-
- **DC Filter**: Removes DC offset with adjustable cutoff (1-100Hz)
48-
- **Soft Clipper**: Gentle clipping with threshold and knee controls (-20 to 0dB)
49-
- **Auto Gain**: Automatic gain adjustment to target level (-20 to 0dB)
50-
- **Level Meters**: Real-time peak and RMS level visualization
51-
- **Status Indicators**: Visual feedback for processing state
52-
- **Multi-Octave Arpeggiation**:
53-
- **Rich Chords**: Set octaves=3 with a C major chord
54-
- **Rising Sequences**: Set octaves=2 and use UP mode with moderate tempo
55-
- **Descending Patterns**: Set octaves=4 with DOWN mode for descending bass lines
56-
- **Random Exploration**: Set octaves=6 with RANDOM mode for experimental textures
57-
- **Oscilloscope & Spectrum**: Visualize output waveform and frequency spectrum.
58-
- **MIDI input**: Map MIDI CC to synth parameters for external control.
59-
- **Interactive Keyboard**: On-screen piano keyboard with visual feedback.
5+
- **4-oscillator synth**: Each with independent waveform, pitch, detune, gain, phase, pulse width, and unison controls
6+
- **Mixer**: Control the mix and master volume of each oscillator with bus compression
7+
- **Effects**: Flanger, delay, reverb, and analog filter with real-time controls
8+
- **Arpeggiator**: Multiple modes, adjustable tempo, octave control, and multi-octave chord arpeggiation
9+
- **Oscilloscope & Spectrum**: Visualize output waveform and frequency spectrum
10+
- **MIDI input**: Map MIDI CC to synth parameters for external control
11+
- **Interactive Keyboard**: On-screen piano keyboard with visual feedback
6012

6113
## Build Dependencies
6214

63-
- [SDL2](https://www.libsdl.org/) (graphics, audio, events)
64-
- [SDL2_ttf](https://github.com/libsdl-org/SDL_ttf) (font rendering)
65-
- [Dear ImGui](https://github.com/ocornut/imgui) (GUI library)
66-
- [libremidi](https://github.com/celtera/libremidi) (MIDI input)
67-
- [math.h], [string.h], [stdlib.h], [stdio.h]
68-
15+
- SDL2 (graphics, audio, events)
16+
- SDL2_ttf (font rendering)
17+
- Dear ImGui (GUI library)
18+
- libremidi (MIDI input)
19+
6920
## Build Instructions
7021

7122
### Linux
7223

73-
Install dependencies (example for Debian/Ubuntu):
74-
7524
```sh
7625
sudo apt-get install git cmake ninja libsdl2-dev libsdl2-ttf-dev
77-
```
78-
79-
Clone, build and run:
80-
81-
```sh
8226
git clone https://github.com/koppi/sdl2-synth && cd sdl2-synth
8327
cmake --preset release
8428
cmake --build --preset synth-release && build/release/synth
8529
```
8630

8731
### macOS
8832

89-
Install dependencies (with Homebrew):
90-
9133
```sh
9234
brew install git ninja sdl2 sdl2_ttf
35+
# Then build as above
9336
```
9437

95-
Then build as above.
96-
9738
### Windows
9839

99-
- Install SDL2, SDL2_ttf and libremidi development libraries.
100-
- Use MinGW or Visual Studio to build the sources (adjust includes/libs as needed).
101-
102-
### Web (Emscripten)
103-
104-
To build the synthesizer as a WebAssembly (WASM) application that runs in the browser:
105-
106-
#### Setup Emscripten
107-
108-
First, install the Emscripten SDK:
109-
110-
```sh
111-
cd /tmp
112-
git clone https://github.com/emscripten-core/emsdk.git
113-
cd emsdk
114-
./emsdk install latest
115-
./emsdk activate latest
116-
source ./emsdk_env.sh
117-
```
118-
119-
Add to your shell profile for permanent access:
120-
121-
```sh
122-
echo 'source "/tmp/emsdk/emsdk_env.sh"' >> $HOME/.bashrc
123-
```
124-
125-
#### Build with CMake and Emscripten
126-
127-
```sh
128-
cd sdl2-synth
129-
cmake --preset emscripten
130-
cmake --build --preset synth-emscripten
131-
```
132-
133-
This generates:
134-
- `synth.js` - JavaScript runtime
135-
- `synth.wasm` - WebAssembly binary
136-
137-
#### Serve the Web Build
138-
139-
Start a local web server to test:
140-
141-
```sh
142-
python3 -m http.server 8000
143-
```
144-
145-
Then open `http://localhost:8000` in your browser and navigate to the build output directory.
40+
Install SDL2, SDL2_ttf and libremidi development libraries, then build with MinGW or Visual Studio.
14641

14742
## Running
14843

14944
```sh
150-
gdb build/debug/synth # debug the build
151-
build/release/synth # run the release build
45+
build/release/synth
15246
```
15347

154-
The application will open a window with the synthesizer GUI.
155-
156-
## MIDI CC Control Mapping
157-
158-
This synthesizer implements General MIDI CC (Continuous Controller) mapping following standard MIDI specifications for universal compatibility with hardware controllers and DAWs. All MIDI CC messages are automatically scaled from MIDI range (0-127) to the appropriate parameter ranges.
159-
160-
### Standard MIDI CC Assignments
161-
162-
#### General MIDI Controllers (CC 1-31)
163-
- **CC 1**: Modulation Wheel → OSC 1 Detune (±1.0 semitones)
164-
- **CC 7**: Volume (Channel Volume) → OSC 1 Gain (0.0-1.0)
165-
- **CC 10**: Pan → OSC 1 Waveform (0=SINE,1=SAW,2=SQUARE,3=TRI,4=NOISE)
166-
- **CC 11**: Expression → OSC 1 Pulse Width (0.0-1.0)
167-
168-
#### Bank Select Controllers (CC 32-63)
169-
- **CC 33**: LSB Bank Select → OSC 6 Waveform (0=SINE,1=SAW,2=SQUARE,3=TRI,4=NOISE)
170-
- **CC 34**: LSB Bank Select → OSC 5 Waveform (0=SINE,1=SAW,2=SQUARE,3=TRI,4=NOISE)
171-
- **CC 35**: LSB Bank Select → OSC 4 Waveform (0=SINE,1=SAW,2=SQUARE,3=TRI,4=NOISE)
172-
- **CC 36**: LSB Bank Select → OSC 3 Waveform (0=SINE,1=SAW,2=SQUARE,3=TRI,4=NOISE)
173-
- **CC 37**: LSB Bank Select → OSC 2 Waveform (0=SINE,1=SAW,2=SQUARE,3=TRI,4=NOISE)
174-
- **CC 38**: LSB Bank Select → OSC 1 Waveform (0=SINE,1=SAW,2=SQUARE,3=TRI,4=NOISE)
175-
176-
#### Effect Controllers (CC 64-95)
177-
- **CC 70**: Sound Controller 1 → Delay Time (0.0-1.0s)
178-
- **CC 71**: Sound Controller 2 → Delay Feedback (0.0-1.0)
179-
- **CC 72**: Sound Controller 3 → Delay Mix (0.0-1.0)
180-
- **CC 73**: Sound Controller 4 → Flanger Rate (0.0-5.0 Hz)
181-
- **CC 74**: Sound Controller 5 → Flanger Depth (0.0-1.0)
182-
- **CC 75**: Sound Controller 6 → Reverb Size (0.0-1.0)
183-
- **CC 76**: Sound Controller 7 → Reverb Mix (0.0-1.0)
184-
- **CC 77**: Sound Controller 8 → Filter Cutoff (20.0-20000.0 Hz)
185-
- **CC 78**: Sound Controller 9 → Filter Resonance (0.1-10.0)
186-
- **CC 79**: Sound Controller 10 → Filter Drive (1.0-10.0)
187-
- **CC 80**: Sound Controller 11 → Filter Mix (0.0-1.0)
188-
189-
#### Channel Pressure & Aftertouch
190-
- **CC 2**: Breath Controller → Alternative OSC 1 Detune (±1.0 semitones)
191-
192-
#### Footswitches & Pedals (CC 64-127)
193-
- **CC 64**: Damper Pedal (Sustain) → Sustain On/Off
194-
- **CC 65**: Portamento → Portamento On/Off
195-
- **CC 66**: Sostenuto → Sostenuto On/Off
196-
- **CC 67**: Soft Pedal → Soft Pedal On/Off
197-
- **CC 68**: Legato Pedal → Legato On/Off
198-
- **CC 69**: Hold Pedal → Hold On/Off
199-
- **CC 83**: General Purpose Controller 1 → Master Volume (0.0-2.0)
200-
- **CC 84**: General Purpose Controller 2 → Compressor Threshold (-24.0 to 0.0 dB)
201-
- **CC 85**: General Purpose Controller 3 → Compressor Ratio (1.0-10.0:1)
202-
- **CC 86**: General Purpose Controller 4 → Compressor Attack (1.0-100.0 ms)
203-
- **CC 87**: General Purpose Controller 5 → Compressor Release (10.0-1000.0 ms)
204-
- **CC 88**: General Purpose Controller 6 → Compressor Makeup Gain (0.0-12.0 dB)
205-
206-
#### High Resolution Controllers (CC 102-119)
207-
- **CC 102-120**: Undefined/Custom → Extended Parameter Control
208-
- **CC 121-119**: RPN/NRPN → Extended parameter access
209-
210-
#### Synthesizer-Specific Mappings (CC 89-95)
211-
- **CC 89**: Sound Controller 1 → Arpeggiator Tempo (60.0-240.0 BPM)
212-
- **CC 90**: Sound Controller 2 → Arpeggiator Enable (0=OFF, 1=ON)
213-
- **CC 91**: Sound Controller 3 → Arpeggiator Mode (0=OFF,1=CHORD,2=UP,3=DOWN,4=UP/DOWN,5=PENDULUM,6=CONVERGE,7=DIVERGE,8=LEAPFROG,9=THUMB-UP,10=THUMB-DOWN,11=PINKY-UP,12=PINKY-DOWN,13=REPEAT,14=RANDOM,15=RANDOM WALK,16=SHUFFLE,17=ORDER)
214-
- **CC 92**: Sound Controller 4 → Arpeggiator Hold (0=OFF, 1=ON)
215-
- **CC 93**: Sound Controller 5 → Arpeggiator Base Octave (0-4 octaves above played note)
216-
- **CC 94**: Sound Controller 6 → Arpeggiator Octave Spread (1-6 octaves of arpeggiated output)
217-
218-
### Multi-Channel Support
219-
220-
#### Channel Messages (CC#1-16)
221-
- **Note On**: Universal on all MIDI channels (1-16)
222-
- **Note Off**: Universal on all MIDI channels (1-16)
223-
- **Velocity Sensitivity**: MIDI velocity 0-127 mapped to amplitude (0.0-1.0)
224-
- **Polyphonic Mode**: Support for multiple simultaneous notes
225-
- **Omni Mode**: Receives on all channels simultaneously
226-
227-
## MIDI Implementation Details
228-
229-
- **MIDI Channel**: Omnitone reception on all channels (1-16)
230-
- **Velocity Sensitivity**: Note velocity maps to amplitude (0/127 = silent, 127/127 = maximum)
231-
- **CC Resolution**: 7-bit MIDI CC scaled to float parameter ranges
232-
- **Real-time Response**: All parameter changes are applied immediately
233-
- **Preset Compatibility**: All MIDI CC mappings work with saved/loaded presets
234-
235-
### Live Performance Control
236-
```
237-
Hands-free control: Assign commonly used parameters to accessible CC numbers
238-
Filter sweeps: Map filter cutoff to CC for real-time sweeps
239-
Dynamic effects: Use CC 69-76 for effect parameter automation
240-
Layer mixing: Use individual OSC gain CCs for live mixing
241-
```
242-
243-
This comprehensive MIDI CC implementation provides studio-level control over all synthesizer parameters, enabling both live performance and production automation workflows.
244-
245-
## Notes
48+
## MIDI Control
24649

247-
- MIDI input is mapped to numerous parameters (see `src/midi.c` for mapping).
248-
- All GUI controls respond to mouse drag and mouse wheel.
249-
- The oscilloscope is fed directly from the audio callback thread for real-time visualization
50+
MIDI input is mapped to numerous parameters (see `src/midi.c` for mapping). All GUI controls respond to mouse drag and mouse wheel. The oscilloscope is fed directly from the audio callback thread for real-time visualization.

0 commit comments

Comments
 (0)