Headless Hybrid Speech/Physical Modeling Synthesizer for Raspberry Pi
Unified polyphonic (4-voice default) synthesizer combining Disyn distortion algorithms, Chatterbox formant synthesis, and PM-Synth physical modeling. Designed for headless operation on Raspberry Pi 4 with MIDI control.
- Disyn Oscillators: 17 distortion synthesis algorithms (7 original + 10 extended with param3 control: Dirichlet Pulse, DSF Single/Double, Tanh Square/Saw, PAF, Modified FM, plus extended variants)
- Chatterbox Formants: 4-formant cascade (F1-F4) with nasal resonance and vocal modes (Sing, Shout, Nasal, Fry)
- PM-Synth Physical Modeling: 12 interface strategies (Pluck, Hit, Reed, Flute, Brass, Bow, Bell, Drum, Crystal, Vapor, Quantum, Plasma)
- Dual DC Blocking: Prevents feedback latching with -60dB DC rejection
- Calibrated Signal Levels: Optimized 0.81 peak output for maximum S16_LE bit depth usage
- ALSA Audio: Direct PCM output (32 kHz default, 512 samples; configure at build/runtime)
- ALSA MIDI: Auto-connects to best external MIDI port on startup
- Headless Control: Comprehensive MIDI CC mapping (29 parameters + 6 control notes)
- Polyphony: 4 voices by default (set
-Dmax_voices=at configure time)
MIDI Input (Note + 29 CCs)
↓
Disyn Oscillators (7 algorithms, ×0.8 level)
↓
[DC Blocker 1] (R=0.999, catches DC at source)
↓
Sources (Noise 0.15 + DC) → Mix
↓
Envelope (AR, exponential time mapping, gate-driven)
↓
Chatterbox Formants (F1→F2→F3→F4 cascade, ×2.0 makeup)
↓
+ Feedback ← [DC Blocker 2] ← Feedback Mix ← Delay1/2 + Filter
↓
Interface Strategy (12 physical models, nonlinear)
↓
Dual Delay Lines (pitch-tracked with tuning/ratio)
↓
State-Variable Filter (LP/BP/HP morph, Q control)
↓
× AM Modulation (LFO bipolar AM↔FM)
↓
Global Processing (×0.85 pad → tanh clip → ×0.95 master)
↓
ALSA Audio Out (peak ~0.81, optimized for S16_LE bit depth)
- Dual DC Blocking: R=0.999 (-60dB @ DC, -3dB @ 7.6 Hz)
- DC Blocker 1 after Disyn: Catches DC at source
- DC Blocker 2 on feedback path: Prevents loop accumulation
- Level Management:
- Disyn level: 0.8 (user adjustable via CC 19)
- Formant makeup: 2.0× (compensates for Q-induced attenuation)
- Global pad: 0.85× + soft clip (tanh) + master 0.95×
- Final peak: ~0.81 (optimized for S16_LE, with tanh safety)
- Debug Toggles: MIDI notes 36-41 toggle DSP sections (disabled by default; enable with
FLUES_CONTROL_NOTES=1)
- Raspberry Pi OS (64-bit recommended)
- 2GB+ RAM
sudo apt update
sudo apt install build-essential meson ninja-build libasound2-devPre-built binaries optimized for Raspberry Pi 4 (aarch64) are available:
Download flues-synth-v*.tar.gz, extract, and install:
tar xzf flues-synth-v0.1.0-aarch64.tar.gz
cd flues-synth-v0.1.0
sudo cp flues-synth/flues-synth /usr/local/bin/
sudo chmod +x /usr/local/bin/flues-synth
flues-synth # RunOn Raspberry Pi (recommended for optimal performance):
cd flues-synth
meson setup builddir
meson compile -C builddirFor multi-platform releases (desktop + Pi builds), see ../scripts/MULTI_PLATFORM_BUILD.md for the complete workflow.
Set voice count (default: 4):
meson setup builddir -Dmax_voices=8
meson compile -C builddirEnable ARM NEON optimizations (Raspberry Pi 4):
meson setup builddir -Denable_simd=true
meson compile -C builddirChange audio device (run-time):
./builddir/flues-synth hw:1,0rm -rf builddir
meson setup builddir
meson compile -C builddircd flues-synth
./builddir/flues-synthExpected output:
=== Flues-Synth v0.1.0 ===
Unified Polyphonic Synthesizer (4-voice default)
Target: Raspberry Pi 4 (ARM Cortex-A72)
Control notes 36-42: disabled (set FLUES_CONTROL_NOTES=1 to enable)
Synth engine initialized
...
If no MIDI device is found, connect manually:
# List ALSA MIDI ports
aconnect -l
# Connect your MIDI device to Flues-Synth
aconnect 20:0 128:0The synth prints CC names on first occurrence:
CC ch1: 20 -> 64 [Noise Level]
CC ch1: 71 -> 45 [F1 (Jaw)]
CC ch1: 20 -> 65
CC ch1: 20 -> 66
After the first move of each CC, subsequent values show only numbers for cleaner console output.
Set your nine sliders to these CC numbers (left→right): 73, 72, 28, 30, 74, 71, 1, 27, 7. These feed the per-program maps in src/midi_mapping.c (Program 0: Disyn Alg, P1, P2, Interface Type, Intensity, Tuning, Delay1 Feedback, Attack, Release). Compatibility aliases exist for common legacy defaults (91/92/93/5/84), but if you see “Unmapped CC…” in the console, reprogram the controller to the canonical list so parameter names and ranges match.
FLUES_CONTROL_NOTES=1– enable debug control notes 36-41 (default: off to avoid stealing low notes from DAWs).FLUES_MIDI_DEBUG=1– verbose MIDI event logging (note on/off/CC/All Notes Off with ALSA source port).
Press Ctrl+C for clean shutdown.
See docs/startup.md for a systemd user service that launches /home/danny/github/flues/play on boot and restarts it if it crashes.
See docs/how-it-works.md for a quick architecture walkthrough and block descriptions.
- First isolate the synth: send
CC 7(Master Gain) to0, or trigger control note 41 (Hard Mute, requiresFLUES_CONTROL_NOTES=1). If the hum remains, it is coming from the audio path, not the DSP. - Toggle sections to see if noise changes: control notes 36 (Noise) and 38 (Feedback) off/on. If no change, suspect hardware/ALSA.
- Check the output device:
hw:0,0analog outs can pick up mains/ground noise. Try a USB DAC (./builddir/flues-synth hw:2,0) orplughwto add ALSA conversion. - Verify baseline with ALSA:
speaker-test -D hw:0,0 -c1 -t s16 -f 0should be silent; hum here indicates device/grounding, not the synth. - Ensure capture paths are muted in
alsamixer(mic/boost off) and avoid sharing loopback capture with the playback device.
To use an external USB DAC instead of the built-in audio output:
1. Detect Available Audio Devices
List all playback hardware devices:
aplay -lExample output:
card 0: Headphones [bcm2835 Headphones], device 0: bcm2835 Headphones [bcm2835 Headphones]
card 2: DAC [USB Audio DAC], device 0: USB Audio [USB Audio]
In this example, the USB DAC is hw:2,0 (card 2, device 0).
2. List Device Names (Including Plugin Devices)
aplay -LShows additional options:
hw:X,Y- Direct hardware accessplughw:X,Y- Hardware with automatic format conversiondefault:CARD=XXX- Named card reference
3. Test the USB DAC
Generate a test tone to verify the device works:
# Mono test on hw:2,0
speaker-test -D hw:2,0 -c 1 -t sine
# Stereo test
speaker-test -D hw:2,0 -c 2 -t sinePress Ctrl+C to stop the test.
4. Run Flues-Synth with USB DAC
Pass the device as a command-line argument:
./builddir/flues-synth hw:2,05. Set USB DAC as Default (Optional)
To make the USB DAC the system default, create or edit ~/.asoundrc:
nano ~/.asoundrcAdd:
pcm.!default {
type hw
card 2
device 0
}
Then run flues-synth without arguments:
./builddir/flues-synth6. Check Active Audio
See which devices are currently in use:
cat /proc/asound/pcmIf no device is specified, flues-synth tries these in order:
- Command-line argument (e.g.,
hw:2,0) hw:Headphones(Raspberry Pi headphone jack)plughw:Headphoneshw:2,0(common USB DAC location)plughw:2,0hw:1,0default
Override with: ./builddir/flues-synth <device-name>
Flues-synth supports multiple ALSA PCM formats with automatic fallback:
Preferred Formats (tried in order):
- S16_LE (16-bit signed little-endian) - Most widely supported
- FLOAT_LE (32-bit float) - Best quality, less common
S16_LE Signal Optimization:
- Bit depth usage: 81% of full scale (0.85 × 0.95 master gain)
- Effective range: ±26,542 of ±32,768 possible values
- Uses ~15.4 of 16 available bits for optimal SNR
- TPDF Dithering: Triangular PDF dither (±1 LSB) linearizes quantization
- Eliminates low-level distortion and quantization artifacts
- Decorrelates quantization noise from signal
- Improves perceived SNR by ~3-4 dB
- Proper Rounding: Uses round-to-nearest instead of truncation to prevent DC bias
Why This Matters:
- Without dithering, low-level signals (quiet passages, reverb tails) produce audible "digital grunge"
- TPDF dither trades a tiny amount of noise floor (~-96 dBFS) for much cleaner low-level reproduction
- Signal levels optimized to use maximum bit depth without clipping
Format Detection:
# Check what format your device negotiated
cat /proc/asound/card*/pcm*p/sub*/hw_paramsExample output:
access: RW_INTERLEAVED
format: S16_LE
subformat: STD
channels: 1
rate: 48000 (48000/1)
Full MIDI specification: See docs/midi.md for complete reference including:
- 29 MIDI Programs (0-28) with signal chain configurations
- 29 MIDI CCs with exponential/bipolar scaling formulas
- 6 Control Notes (36-41) for debug toggles
- Complete parameter mapping and ranges
Quick reference for common controls:
Special MIDI notes toggle DSP sections for diagnostics and isolation:
| Note | Function | Description |
|---|---|---|
| 36 | Toggle Noise | Enable/disable white noise source |
| 37 | Toggle Disyn | Enable/disable Disyn oscillator |
| 38 | Toggle Feedback | Enable/disable feedback loop |
| 39 | Toggle Formants | Enable/disable formant cascade |
| 40 | Toggle Filter | Enable/disable SVF filter |
| 41 | Hard Mute | Emergency mute (clears delays, DC blockers, filters) |
| 42 | Reset | Reset all parameters to defaults and clear all notes |
| 48+ | Musical Notes | Standard MIDI note range (C3 = 48) |
Usage: Press any of notes 36-42 to toggle or reset. Console shows:
Ctl Note 36: Noise ENABLED
Ctl Note 37: Disyn DISABLED
| CC | Parameter | Range | Description |
|---|---|---|---|
| 1 | Intensity | 0-1 | Interface intensity (mod wheel) |
| 7 | Master Gain | 0-1 | Output volume |
| 10 | F2 (Tongue) | 500-3000 Hz | Second formant frequency |
| 71 | F1 (Jaw) | 200-1000 Hz | First formant frequency |
| 72 | Release | 0-1 | Envelope release time |
| 73 | Attack | 0-1 | Envelope attack time |
| 74 | F3 (Lips) | 1500-4000 Hz | Third formant frequency |
| 75 | F4 (Quality) | 2500-4500 Hz | Fourth formant frequency |
| CC | Parameter | Description |
|---|---|---|
| 80 | Nasal | Enable nasal formant (250 Hz) |
| 81 | Sing | Vibrato (5.5 Hz ±1.5%) |
| 82 | Shout | 15% formant frequency boost |
| 83 | Fry | Vocal fry (f₀/2 subharmonic) |
| CC | Parameter | Range | Description |
|---|---|---|---|
| 16 | Algorithm | 0-6 | Disyn synthesis algorithm |
| 17 | Param1 | 0-1 | Algorithm parameter 1 |
| 18 | Param2 | 0-1 | Algorithm parameter 2 |
| 19 | Disyn Level | 0-1 | Oscillator mix level |
| 20 | Noise Level | 0-1 | White noise mix level |
| 21 | DC Level | 0-1 | DC offset mix level |
| CC | Parameter | Range | Description |
|---|---|---|---|
| 24 | Interface Type | 0-11 | Physical model (see below) |
| 26 | Tuning | -12 to +12 | Delay line pitch offset |
| 27 | Ratio | 0.5 to 2.0 | Delay2/Delay1 length ratio |
| CC | Parameter | Range | Description |
|---|---|---|---|
| 28 | Delay1 Feedback | 0-1 | First delay return level |
| 29 | Delay2 Feedback | 0-1 | Second delay return level |
| 30 | Filter Feedback | 0-1 | Filter output return level |
| CC | Parameter | Range | Description |
|---|---|---|---|
| 32 | Frequency | 20-20000 Hz | Filter cutoff frequency |
| 33 | Q | 0.1-10 | Filter resonance |
| 34 | Shape | 0-1 | LP (0) → BP (0.5) → HP (1) |
| CC | Parameter | Range | Description |
|---|---|---|---|
| 36 | LFO Freq | 0.1-20 Hz | Modulation LFO frequency |
| 37 | AM ↔ FM | -1 to +1 | AM (-1) ↔ None (0) ↔ FM (+1) |
| ID | Name | Description | Character |
|---|---|---|---|
| 0 | Pluck | Karplus-Strong plucked string | Bright, metallic attack |
| 1 | Hit | Struck/mallet percussion | Sharp transient, decay |
| 2 | Reed | Clarinet-style reed instrument | Woody, breathy |
| 3 | Flute | Jet-edge aerophone | Airy, hollow |
| 4 | Brass | Lip-buzz brass instrument | Buzzy, brassy |
| 5 | Bow | Bowed string (friction) | Sustained, singing |
| 6 | Bell | Metallic resonator | Bright, ringing |
| 7 | Drum | Membrane percussion | Thuddy, resonant |
| 8 | Crystal | Golden-ratio coupled oscillators | Glassy, shimmering |
| 9 | Vapor | Chaotic turbulent flow | Unstable, evolving |
| 10 | Quantum | Phase-locked harmonic coupling | Metallic, interference |
| 11 | Plasma | Amplitude-driven energy feedback | Aggressive, growling |
17 Total Algorithms (7 original + 10 extended with param3 control):
| ID | Name | Description |
|---|---|---|
| 0 | Dirichlet Pulse | Sum of harmonics (Param1: harmonics) |
| 1 | DSF Single | Discrete summation formula |
| 2 | DSF Double | Two DSF oscillators (Param2: detune) |
| 3 | Tanh Square | Waveshaped square wave |
| 4 | Tanh Saw | Waveshaped sawtooth wave |
| 5 | PAF | Phase-aligned formant |
| 6 | Modified FM | Phase-modulated FM synthesis |
| 7-16 | Extended Variants | Enhanced algorithms with param3 control |
Note: Algorithms 7-16 are extended variants that use param3 for additional spectral control. See docs/algorithms.md for complete algorithm documentation.
- Check Disyn level: Default 0.8, boost via CC 19 if needed
- Check Master gain: Default 0.5, boost via CC 7 if needed
- Verify parts not toggled off: Use notes 36-41 to check status
- Test audio device:
# List audio devices aplay -l # Test device speaker-test -D default -c 1 # Try different device ./builddir/flues-synth hw:1,0
If output is too quiet with only Disyn enabled (formants/feedback off):
- Boost Disyn level: CC 19 to 100-127 (0.78-1.0)
- Boost Master gain: CC 7 to 100-127
- Reason: Default levels (0.8 Disyn, 0.5 master) are calibrated for full signal chain
- Reduce Disyn level: CC 19 to 30-60 (0.24-0.47) when using formants
- Turn off Shout mode: CC 82 < 64 (15% boost can cause clipping)
- Lower feedback: Reduce CC 28-30 (delay/filter returns)
- Check formant tuning: Extreme F1-F4 values can cause resonance buildup
If audio locks up or produces continuous tone:
- Hard mute: Press MIDI note 41 (clears delays, DC blockers, filters)
- Disable feedback: Press note 38 to isolate feedback loop
- Check DC level: CC 21 should be 0 (no DC injection)
- Restart synth: DC blockers reset on note on, but hard mute is faster
DC Blocking Protection:
- Two-stage DC blocking (R=0.999, -60dB @ DC)
- DC Blocker 1 after Disyn catches source DC
- DC Blocker 2 on feedback prevents loop accumulation
- Hard mute (note 41) resets all DC blockers
# List MIDI ports
aconnect -l
# Check if device is detected
cat /proc/asound/cards
# Manual connection
aconnect <source-port> <flues-synth-port>- Increase buffer size in
include/config.h:#define DEFAULT_BUFFER_SIZE 1024 // Increase from 512
- Rebuild:
meson compile -C builddir
- Disable ARM optimizations:
meson setup builddir -Denable_simd=false - Reduce voice count:
meson setup builddir -Dmax_voices=1 - Lower sample rate to 44100 Hz in
config.h
# Clean build
rm -rf builddir
meson setup builddir
meson compile -C builddir
# Check dependencies
dpkg -l | grep -E 'meson|ninja|alsa'Raspberry Pi 4 (Cortex-A72):
- Single voice: ~5-10% CPU @ 48kHz
- Target (4 voices): ~20-30% CPU
- Latency: ~5.3ms (256 samples)
Three test suites verify correct operation:
# Run all tests
meson test -C builddir
# Individual tests
./builddir/engine-smoke # Basic signal generation (RMS check)
./builddir/envelope-test # Envelope attack/sustain/release
./builddir/disyn-levels # Disyn algorithm level analysisExpected output:
1/3 engine-smoke OK (RMS: 0.019+, verifies non-zero output)
2/3 envelope-test OK (attack/sustain/release phases detected)
3/3 disyn-levels OK (all 7 algorithms within safe bounds)
Smoke Test Details:
- Renders 1 second of audio with default settings
- Measures RMS level of last 0.5 seconds
- Verifies RMS > 0.01 (signal present, not zero)
- Catches DC blocker issues, envelope failures, signal path breaks
Envelope Test Details:
- Tests note on triggers envelope attack
- Verifies sustained tone has stable output
- Tests note off triggers release decay
- Tests rapid note retriggering (5 cycles)
Disyn Levels Test Details:
- Measures peak/RMS for all 7 algorithms
- Sweeps Param1/Param2 across full ranges
- Verifies peaks within safe bounds (<2.2)
- Reports clipping warnings if any
- The app auto-falls back through common Pi audio devices if no CLI device given:
hw:Headphones,plughw:Headphones,hw:2,0,plughw:2,0,hw:1,0, thendefault - Override with:
./builddir/flues-synth hw:2,0 - Quick rebuild on Pi:
meson setup builddir --reconfigure && meson compile -C builddir && meson test -C builddir - Enable MIDI debug:
FLUES_MIDI_DEBUG=1 ./builddir/flues-synth hw:2,0
flues-synth/
├── include/
│ ├── config.h # Build-time configuration
│ ├── dsp_modules.h # Module interfaces
│ ├── dsp_utils.h # DSP utilities
│ ├── synth_engine.h # Main coordinator
│ ├── audio_backend_alsa.h # ALSA audio
│ └── midi_backend_alsa.h # ALSA MIDI
├── src/
│ ├── main.c # Entry point + CC mapping
│ ├── synth_engine.c # Voice management + signal flow
│ └── audio/
│ ├── audio_backend_alsa.c # ALSA PCM output
│ ├── midi_backend_alsa.c # ALSA sequencer input
│ └── modules/
│ ├── disyn_wrapper.cpp # C++ Disyn → C interface
│ ├── sources_module.c # Noise + DC
│ ├── envelope_module.c # Attack/Release
│ ├── formant_module.c # Biquad bandpass filter
│ ├── formant_bank_module.c # 4-formant cascade
│ ├── interface_module.c # Strategy pattern
│ ├── delay_lines_module.c # Dual delays
│ ├── feedback_module.c # 3-way mixer
│ ├── filter_module.c # State-variable filter
│ ├── modulation_module.c # LFO
│ └── strategies/ # 12 interface implementations
├── meson.build # Build configuration
├── meson_options.txt # Build options
└── README.md # This file
- MIDI Reference - Complete MIDI control specification (29 CCs, 29 programs, control notes)
- Program Change Guide - Signal chain configurations and slider remapping
- Algorithm Reference - Implementation-level DSP documentation (all synthesis algorithms, filters, and signal processing)
- Signal Flow Diagram - Visual architecture with signal levels
- Handover Document - Original implementation notes and design decisions
- Envelope Fix - DC blocker optimization (removed output blocker)
- Level Analysis - Signal level calibration and test results
- DC Blocking Protection - Feedback latch prevention strategy
- Level Fix Verification - Before/after measurements
- ✅ Single-voice operation
- ✅ Disyn + Chatterbox + PM-Synth integration
- ✅ ALSA audio/MIDI backends with auto-connect
- ✅ 29 MIDI CC controls with name printing
- ✅ 6 control notes for debug toggles
- ✅ Dual DC blocking protection
- ✅ Calibrated signal levels (0.81 peak, optimized for S16_LE)
- ✅ TPDF dithering for clean 16-bit output
- ✅ Test suite (engine-smoke, envelope-test, disyn-levels)
- ☐ 4-voice polyphony
- ☐ Voice allocation and stealing
- ☐ Per-voice parameter management
- ☐ Polyphonic aftertouch
- ☐ GTK4 UI (optional)
- ☐ MIDI learn
- ☐ Preset system
- ☐ Performance profiling
First official release with 29 MIDI programs (expanded from 8), 17 Disyn algorithms (expanded from 7), and multi-platform build support.
Download: GitHub Releases
Key Features:
- 29 MIDI Programs: Comprehensive preset library covering physical modeling, distortion synthesis, hybrid chains, and experimental combinations
- 17 Disyn Algorithms: 7 original algorithms + 10 extended variants with param3 control for enhanced spectral manipulation
- Program 6 Re-Enabled: Full Hybrid mode now working (race condition fixed in December 2025)
- Backwards Compatibility: All existing code works without modification; param3 is optional with default value
- Multi-Platform Builds: Optimized binaries for Ubuntu desktop (x86_64) and Raspberry Pi (aarch64)
- Complete Documentation: Algorithm reference, MIDI spec, program guide, signal flow diagrams
Program Categories:
- Programs 0-7: Original physical modeling presets (Classic Reed, Pluck, Brass, etc.)
- Programs 8-17: Distortion synthesis explorations (ModFM Formant, DSF Bells, PAF Vowels, Hybrid chains)
- Programs 18-28: Experimental combinations (Morphing engines, feedback networks, spectral animators)
Each program includes optimized 9-slider mappings and level safety verification. See docs/PROGRAM_CHANGE.md for complete program guide.
Technical Improvements:
- Dual DC blocking (R=0.999) prevents feedback latching
- Calibrated signal levels (0.81 peak, optimized for S16_LE)
- TPDF dithering for clean 16-bit output
- Test suite: engine-smoke, envelope-test, disyn-levels (all passing)
- Increased signal levels for better bit depth usage (56% → 81% of full scale)
- Global pad: 0.7 → 0.85
- Master gain: 0.8 → 0.95
- Peak output: 0.28 → 0.81 (uses ~15.4 effective bits instead of ~13 bits)
- Added TPDF dithering for S16_LE conversion (±1 LSB triangular PDF)
- Eliminates quantization distortion on low-level signals
- Improves perceived SNR by ~3-4 dB
- Fixed truncation bias using proper round-to-nearest conversion
- Result: Much cleaner quiet passages, reverb tails, and overall sound quality
- Removed aggressive output DC blocker (was killing envelope attack)
- Optimized to dual DC blocking (source + feedback loop, R=0.999)
- Increased default noise level (0.02 → 0.15) for formant excitation
- Reduced formant makeup gain (3.0× → 2.0×) to prevent Disyn clipping
- Boosted master gain (0.35 → 0.5) and global pad (0.5 → 0.7)
- Increased Disyn level (0.2 → 0.8) for better audibility
- Added CC name printing on first occurrence for each controller
- All 3 test suites passing (engine-smoke, envelope-test, disyn-levels)
- Merged Disyn + Chatterbox + PM-Synth architectures
- Implemented triple DC blocking (later reduced to dual)
- Created test suite for signal verification
- Calibrated signal levels to prevent clipping
Part of the Flues project. See main repository for license information.
- experiments/disyn: JavaScript distortion synthesizer
- experiments/chatterbox: JavaScript formant speech synthesizer
- experiments/pm-synth: JavaScript physical modeling synthesizer
- lv2/disyn: Disyn LV2 plugin
- lv2/chatterbox: Chatterbox LV2 plugin
- lv2/floozy: Hybrid Disyn+PM LV2 plugin
- gtk-synth: GTK4 desktop PM-Synth
- Disyn: Distortion synthesis algorithms
- Chatterbox: Formant synthesis and vocal modes
- PM-Synth: Physical modeling framework
- Built with: Meson, ALSA, C11/C++17