Compare commits
2 Commits
801ea22d3e
...
ff59c7c66a
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
ff59c7c66a | ||
|
|
75e0894ff8 |
9
.gitignore
vendored
Normal file
9
.gitignore
vendored
Normal file
@@ -0,0 +1,9 @@
|
||||
bin/
|
||||
build/
|
||||
.exe
|
||||
*.old
|
||||
config/
|
||||
untracked/
|
||||
reference/
|
||||
resume.sh
|
||||
patches/favorites.txt
|
||||
135
README.md
Normal file
135
README.md
Normal file
@@ -0,0 +1,135 @@
|
||||
# SoundThing
|
||||
|
||||
*A polyphonic subtractive synthesizer for Linux, written in C with Raylib.*
|
||||
|
||||
**v0.9.5 beta** | Linux | Windows (cross-compile) | C11 | Raylib
|
||||
|
||||
---
|
||||
|
||||
## What is SoundThing?
|
||||
|
||||
SoundThing is a self-contained polyphonic synthesizer application. It runs standalone on Linux, receives MIDI input from any connected device, and produces audio through your system's default output. No plugin host, no runtime dependencies beyond the system libraries — just a binary and a folder of patches.
|
||||
|
||||
The UI is built with a custom pixel-art sprite sheet and an embedded 8×8 pixel font, giving it a deliberately retro character while remaining fully functional as an instrument. All assets are compiled directly into the binary; nothing loose needs to ship alongside the executable.
|
||||
|
||||
---
|
||||
|
||||
## Features
|
||||
|
||||
| Module | Description |
|
||||
|---|---|
|
||||
| **Polyphony** | 8 voices, round-robin stealing |
|
||||
| **Oscillators** | 2 per voice — Sine, Triangle, Saw, Ramp, Pulse, Noise |
|
||||
| **Envelopes** | 2 × ADSR — Amp and Mod, independently routable |
|
||||
| **LFOs** | 2 × LFO with the same six waveforms as the oscillators |
|
||||
| **Filter** | TPT state-variable filter — LP, HP, BP; cutoff and resonance both modulatable |
|
||||
| **Modulation** | Per-parameter routing to Amp Env, Mod Env, LFO 0, or LFO 1 |
|
||||
| **MIDI** | In-app device picker with rescan; CC Learn maps any knob to any CC |
|
||||
| **Patch browser** | Save, load, favourites, and folder-based organisation navigable in-app |
|
||||
|
||||
---
|
||||
|
||||
## Building from Source
|
||||
|
||||
### Dependencies (Linux)
|
||||
|
||||
- `gcc`
|
||||
- `libraylib-dev` — or build [Raylib](https://github.com/raysan5/raylib) from source
|
||||
- `libasound2-dev` — ALSA
|
||||
|
||||
```sh
|
||||
git clone https://github.com/Anachronaut/soundThing
|
||||
cd soundThing
|
||||
make
|
||||
./bin/soundThing
|
||||
```
|
||||
|
||||
### Windows (cross-compile from Linux)
|
||||
|
||||
Additional dependencies:
|
||||
|
||||
- `x86_64-w64-mingw32-gcc`
|
||||
- `x86_64-w64-mingw32-windres`
|
||||
- Raylib win64 MinGW distribution — set `RAYLIB_WIN` in the Makefile to point at it
|
||||
|
||||
```sh
|
||||
make PLATFORM=windows
|
||||
```
|
||||
|
||||
> **Note:** Run `make clean` when switching between platforms to avoid mixing object files from different toolchains.
|
||||
|
||||
### Makefile targets
|
||||
|
||||
| Target | Action |
|
||||
|---|---|
|
||||
| `make` | Build for Linux (default) |
|
||||
| `make PLATFORM=windows` | Cross-compile for Windows |
|
||||
| `make clean` | Remove `build/` and the binary |
|
||||
| `make run` | Build and run immediately |
|
||||
|
||||
---
|
||||
|
||||
## Running & Distributing
|
||||
|
||||
The Linux binary dynamically links against Raylib and ALSA as system libraries. The Windows `.exe` is statically linked and fully self-contained.
|
||||
|
||||
In both cases, the `patches/` folder must sit alongside the executable. SoundThing changes its working directory to the executable's location at startup, so double-clicking from a file manager works correctly.
|
||||
|
||||
```
|
||||
soundThing/
|
||||
├── soundThing (or soundThing.exe)
|
||||
└── patches/
|
||||
├── Classic/
|
||||
├── Atmospheric/
|
||||
└── ...
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## The Patch System
|
||||
|
||||
Patches are plain JSON files stored in `patches/` and its subdirectories. Organise them however you like in your filesystem — SoundThing's built-in browser lets you navigate into folders, save into whichever directory you're currently viewing, and mark favourites.
|
||||
|
||||
- Open the patch browser from the **Master** panel.
|
||||
- Click a folder row (shown in blue) to navigate into it; click `..` to go back.
|
||||
- Type a name in the save field and press the save button to write a new patch.
|
||||
- Star any patch to add it to your favourites list.
|
||||
|
||||
SoundThing ships with a library of presets across several categories: Classic, Atmospheric, Chiptune, and Keys.
|
||||
|
||||
---
|
||||
|
||||
## MIDI Setup
|
||||
|
||||
Open the **MIDI** panel from the Master section to scan for and connect to an input device. The last-used device is remembered between sessions.
|
||||
|
||||
### CC Learn
|
||||
|
||||
Any knob or slider can be mapped to a MIDI CC:
|
||||
|
||||
1. Enable **MIDI Lrn** in the Master panel (it will pulse yellow).
|
||||
2. Click the knob or slider you want to control.
|
||||
3. Wiggle the physical control on your MIDI device.
|
||||
4. The mapping is saved automatically and restored on next launch.
|
||||
|
||||
The modulation wheel (CC 1) is pre-mapped to oscillator pulse width.
|
||||
|
||||
---
|
||||
|
||||
## Built With
|
||||
|
||||
- [Raylib](https://www.raylib.com/) — graphics, audio streaming, and windowing (zlib license)
|
||||
- ALSA — Linux audio/MIDI (LGPL, dynamically linked)
|
||||
- WinMM — Windows MIDI (system library)
|
||||
|
||||
If SoundThing has been useful to you, consider supporting [Raylib's development](https://github.com/sponsors/raysan5).
|
||||
|
||||
---
|
||||
|
||||
## License
|
||||
|
||||
License TBD. All rights reserved until stated otherwise.
|
||||
|
||||
---
|
||||
|
||||
*Made by [Anachronaut](https://github.com/Anachronaut) — anachronautics@gmail.com*
|
||||
BIN
assets/NPNGear.ico
Normal file
BIN
assets/NPNGear.ico
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 3.6 KiB |
BIN
assets/NPNGear.png
Normal file
BIN
assets/NPNGear.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 3.6 KiB |
BIN
assets/myFont.png
Normal file
BIN
assets/myFont.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 1.9 KiB |
BIN
assets/source/soundThingUI.pxo
Normal file
BIN
assets/source/soundThingUI.pxo
Normal file
Binary file not shown.
BIN
assets/sprites.png
Normal file
BIN
assets/sprites.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 542 B |
20
include/config.h
Normal file
20
include/config.h
Normal file
@@ -0,0 +1,20 @@
|
||||
#ifndef CONFIG_H
|
||||
#define CONFIG_H
|
||||
|
||||
#define CONFIG_DIR "config"
|
||||
#define CONFIG_NAME_LEN 128
|
||||
|
||||
typedef struct {
|
||||
int cc;
|
||||
int controlId;
|
||||
float min;
|
||||
float max;
|
||||
} ConfigCcEntry;
|
||||
|
||||
void configSanitizeName(const char *in, char *out, int maxLen);
|
||||
int configSaveLastDevice(const char *deviceName);
|
||||
int configLoadLastDevice(char *out, int maxLen);
|
||||
int configSaveCcMappings(const char *deviceName, ConfigCcEntry *entries, int count);
|
||||
int configLoadCcMappings(const char *deviceName, ConfigCcEntry *entries, int maxCount);
|
||||
|
||||
#endif
|
||||
7
include/font_data.h
Normal file
7
include/font_data.h
Normal file
@@ -0,0 +1,7 @@
|
||||
#ifndef FONT_DATA_H
|
||||
#define FONT_DATA_H
|
||||
|
||||
extern unsigned char font_png[];
|
||||
extern unsigned int font_png_len;
|
||||
|
||||
#endif
|
||||
7
include/icon_data.h
Normal file
7
include/icon_data.h
Normal file
@@ -0,0 +1,7 @@
|
||||
#ifndef ICON_DATA_H
|
||||
#define ICON_DATA_H
|
||||
|
||||
extern unsigned char icon_png[];
|
||||
extern unsigned int icon_png_len;
|
||||
|
||||
#endif
|
||||
@@ -1,20 +1,52 @@
|
||||
#ifndef MIDI_H
|
||||
#define MIDI_H
|
||||
|
||||
#define _POSIX_C_SOURCE 200809L
|
||||
#include <alsa/asoundlib.h>
|
||||
#ifndef _WIN32
|
||||
# define _POSIX_C_SOURCE 200809L
|
||||
# include <alsa/asoundlib.h>
|
||||
#endif
|
||||
|
||||
#include <stdatomic.h>
|
||||
#include "synth.h"
|
||||
|
||||
#define MIDI_MAX_INPUTS 16
|
||||
|
||||
typedef struct {
|
||||
int active;
|
||||
float *valuePtr; // direct pointer into Synth for CC to write
|
||||
float min, max; // CC 0 → min, CC 127 → max
|
||||
int controlId; // stable UI control ID, used for persistence
|
||||
} CcMapping;
|
||||
|
||||
typedef struct {
|
||||
int client;
|
||||
int port;
|
||||
char clientName[64];
|
||||
char portName[64];
|
||||
} MidiInputInfo;
|
||||
|
||||
typedef struct {
|
||||
#ifdef _WIN32
|
||||
void *hMidiIn; // HMIDIIN; kept opaque to avoid including windows.h here
|
||||
#else
|
||||
snd_seq_t *seq;
|
||||
int port;
|
||||
int client;
|
||||
Synth *synth; // pointer to the synth we'll drive with MIDI events
|
||||
#endif
|
||||
Synth *synth;
|
||||
int connectedClient; // WinMM device index on Windows, ALSA client on Linux; -1 if not connected
|
||||
int connectedPort; // always 0 on Windows, ALSA port on Linux
|
||||
MidiInputInfo inputs[MIDI_MAX_INPUTS];
|
||||
int inputCount;
|
||||
atomic_int midiLearnMode; // 1 while waiting for CC wiggle
|
||||
atomic_int midiLearnCC; // -1 or the CC number received
|
||||
CcMapping ccMappings[128];
|
||||
} MidiState;
|
||||
|
||||
int midiInit(MidiState *m, Synth *synth);
|
||||
void midiListInputs(MidiState *m);
|
||||
void midiConnect(MidiState *m, int srcClient, int srcPort);
|
||||
void midiScanInputs(MidiState *m);
|
||||
void midiDevConnect(MidiState *m, int srcClient, int srcPort);
|
||||
void midiDevDisconnect(MidiState *m);
|
||||
void midiClose(MidiState *m);
|
||||
void *midiThread(void *arg);
|
||||
|
||||
|
||||
19
include/patch.h
Normal file
19
include/patch.h
Normal file
@@ -0,0 +1,19 @@
|
||||
#ifndef PATCH_H
|
||||
#define PATCH_H
|
||||
|
||||
#include "synth.h"
|
||||
|
||||
#define PATCH_NAME_LEN 64
|
||||
#define PATCH_MAX_FILES 256
|
||||
#define PATCH_MAX_DIRS 64
|
||||
|
||||
int patchSave(Synth *s, const char *path);
|
||||
int patchLoad(Synth *s, const char *path);
|
||||
int patchScanFiles(char (*files)[PATCH_NAME_LEN], int maxFiles);
|
||||
int patchScanDir(const char *relPath,
|
||||
char (*files)[PATCH_NAME_LEN], int maxFiles,
|
||||
char (*dirs)[PATCH_NAME_LEN], int maxDirs, int *outDirCount);
|
||||
int patchLoadFavs(char (*favs)[PATCH_NAME_LEN], int maxFavs);
|
||||
int patchSaveFavs(char (*favs)[PATCH_NAME_LEN], int favCount);
|
||||
|
||||
#endif
|
||||
6
include/platform.h
Normal file
6
include/platform.h
Normal file
@@ -0,0 +1,6 @@
|
||||
#ifndef PLATFORM_H
|
||||
#define PLATFORM_H
|
||||
|
||||
void chdirToExeDir(void);
|
||||
|
||||
#endif
|
||||
7
include/sprites_data.h
Normal file
7
include/sprites_data.h
Normal file
@@ -0,0 +1,7 @@
|
||||
#ifndef SPRITES_DATA_H
|
||||
#define SPRITES_DATA_H
|
||||
|
||||
extern unsigned char sprites_png[];
|
||||
extern unsigned int sprites_png_len;
|
||||
|
||||
#endif
|
||||
125
include/synth.h
125
include/synth.h
@@ -3,7 +3,10 @@
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#define VOICE_COUNT 16
|
||||
#define VOICE_COUNT 8
|
||||
#define OSC_COUNT 2
|
||||
#define LFO_COUNT 2
|
||||
#define OSC_MAX_GAIN 4.0f
|
||||
|
||||
typedef enum {
|
||||
WAVE_SINE,
|
||||
@@ -15,32 +18,124 @@ typedef enum {
|
||||
WAVE_COUNT // handy for the modulo wrap on waveform switching
|
||||
} Waveform;
|
||||
|
||||
// Envelope structures:
|
||||
typedef enum {
|
||||
ENV_IDLE,
|
||||
ENV_ATTACK,
|
||||
ENV_DECAY,
|
||||
ENV_SUSTAIN,
|
||||
ENV_RELEASE
|
||||
} EnvStage;
|
||||
|
||||
typedef enum {
|
||||
MOD_SOURCE_NONE = 0,
|
||||
MOD_SOURCE_AMP_ENV = 1,
|
||||
MOD_SOURCE_MOD_ENV = 2,
|
||||
MOD_SOURCE_LFO = 3,
|
||||
MOD_SOURCE_LFO2 = 4
|
||||
} ModSource;
|
||||
|
||||
typedef struct {
|
||||
float phase;
|
||||
float freqHz;
|
||||
float amp;
|
||||
float targetAmp;
|
||||
int active;
|
||||
int midiNote;
|
||||
EnvStage stage;
|
||||
float value; // current output value, 0.0 to 1.0
|
||||
float attackSec;
|
||||
float decaySec;
|
||||
float sustainLevel;
|
||||
float releaseSec;
|
||||
} Envelope;
|
||||
|
||||
typedef struct {
|
||||
float phase;
|
||||
float rate; // Hz
|
||||
Waveform waveform;
|
||||
int active;
|
||||
float noiseHeld;
|
||||
float noisePhase;
|
||||
} LFO;
|
||||
|
||||
typedef enum {
|
||||
FILTER_LOWPASS,
|
||||
FILTER_HIGHPASS,
|
||||
FILTER_BANDPASS,
|
||||
FILTER_COUNT
|
||||
} FilterType;
|
||||
|
||||
typedef struct {
|
||||
float cutoff; // Hz
|
||||
float resonance; // 0.0 (flat) to 0.99 (near self-oscillation)
|
||||
FilterType type;
|
||||
int active;
|
||||
float low, band; // TPT integrator states s1, s2
|
||||
int modRouting;
|
||||
float modDepth; // Hz
|
||||
int resModRouting;
|
||||
float resModDepth; // resonance units (-0.99..0.99)
|
||||
} Filter;
|
||||
|
||||
typedef struct {
|
||||
float phase;
|
||||
float dutyCycle;
|
||||
Waveform waveform;
|
||||
float detune; // cents, 0 = no detune
|
||||
float noiseHeld; // last drawn random value for clocked noise
|
||||
float noisePhase; // tracks when to draw a new noise value
|
||||
float gain;
|
||||
int active; // whether this oscillator contributes to output
|
||||
int octave; // transposition in octaves, -2 to +2
|
||||
// Modulation routing: one source per destination by design.
|
||||
// Each parameter (pwm, detune, gain) has exactly one mod source and one depth.
|
||||
int modRouting[3]; // 0=off, 1=env0, 2=env1, 3=lfo0, 4=lfo1
|
||||
float modDepth[3]; // Depth of modulation parameter
|
||||
} Oscillator;
|
||||
|
||||
typedef struct {
|
||||
Oscillator oscillators[OSC_COUNT];
|
||||
float freqHz;
|
||||
int active;
|
||||
int midiNote;
|
||||
Envelope ampEnv;
|
||||
Envelope modEnv;
|
||||
Filter filter;
|
||||
} Voice;
|
||||
|
||||
typedef struct {
|
||||
float sampleRate;
|
||||
float attackSec;
|
||||
float releaseSec;
|
||||
float dutyCycle;
|
||||
Waveform waveform;
|
||||
Voice voices[VOICE_COUNT];
|
||||
float pitchBend;
|
||||
float pitchBendRange;
|
||||
int lastStolenVoice;
|
||||
float pitchBend; // -1.0 to +1.0, normalized from raw MIDI value
|
||||
float pitchBendRange; // semitones, e.g. 2.0f
|
||||
Voice voices[VOICE_COUNT];
|
||||
float volume; // 0.0 to 1.0, master output level
|
||||
LFO lfos[LFO_COUNT];
|
||||
} Synth;
|
||||
|
||||
// Envelope functions:
|
||||
void envelopeInit(Envelope *e, float attackSec, float decaySec, float sustainLevel, float releaseSec);
|
||||
void envelopeNoteOn(Envelope *e);
|
||||
void envelopeNoteOff(Envelope *e);
|
||||
float envelopeTick(Envelope *e, float sampleRate);
|
||||
|
||||
// Oscillator functions:
|
||||
void oscillatorInit(Oscillator *o, Waveform waveform, float dutyCycle, float detune, float gain);
|
||||
float oscillatorTick(Oscillator *o, float freqHz, float bendMultiplier, float sampleRate,
|
||||
float dutyCycle, float detune, float gain);
|
||||
|
||||
// Synth functions:
|
||||
void synthInit(Synth *s, float sampleRate);
|
||||
void synthResetPatch(Synth *s);
|
||||
void synthNoteOn(Synth *s, int midiNote);
|
||||
void synthNoteOff(Synth *s, int midiNote);
|
||||
void synthFillBuffer(Synth *s, int16_t *out, int frames);
|
||||
float waveformSample(Waveform w, float phase, float dutyCycle);
|
||||
void synthSyncVoices(Synth *s);
|
||||
|
||||
// LFO functions:
|
||||
float lfoTick(LFO *l, float sampleRate);
|
||||
|
||||
// Filter functions:
|
||||
float filterTick(Filter *f, float input, float cutoff, float resonance, float sampleRate);
|
||||
const char *filterTypeName(FilterType t);
|
||||
|
||||
// Waveform functions:
|
||||
float waveformSample(Waveform w, float phase, float dutyCycle, float noiseHeld);
|
||||
const char *waveformName(Waveform w);
|
||||
|
||||
#endif
|
||||
|
||||
110
include/ui.h
Normal file
110
include/ui.h
Normal file
@@ -0,0 +1,110 @@
|
||||
#ifndef UI_H
|
||||
#define UI_H
|
||||
|
||||
#include "raylib.h"
|
||||
#include "synth.h"
|
||||
#include "midi.h"
|
||||
#include "patch.h"
|
||||
#include "config.h"
|
||||
|
||||
typedef struct {
|
||||
int id;
|
||||
float *valuePtr;
|
||||
float min;
|
||||
float max;
|
||||
} UIControlEntry;
|
||||
|
||||
// Sprite indices
|
||||
typedef enum {
|
||||
SPRITE_WAVE_SINE = 0,
|
||||
SPRITE_WAVE_TRIANGLE,
|
||||
SPRITE_WAVE_SAW,
|
||||
SPRITE_WAVE_RAMP,
|
||||
SPRITE_WAVE_PULSE,
|
||||
SPRITE_WAVE_NOISE,
|
||||
SPRITE_BTN_RED,
|
||||
SPRITE_BTN_GREEN,
|
||||
SPRITE_SLIDER,
|
||||
SPRITE_KNOB
|
||||
} SpriteIndex;
|
||||
|
||||
// UI state that needs to persist between frames
|
||||
typedef struct {
|
||||
Texture2D sprites;
|
||||
Font font;
|
||||
MidiState *midi;
|
||||
Camera2D *camera;
|
||||
// About menu state
|
||||
int aboutMenuOpen;
|
||||
|
||||
// MIDI menu state
|
||||
int midiMenuOpen;
|
||||
int midiMenuSelected; // -1 if none
|
||||
|
||||
// Knob drag state
|
||||
int draggingKnob; // -1 if none
|
||||
Vector2 dragStart;
|
||||
float dragStartValue;
|
||||
|
||||
// Slider drag state
|
||||
int draggingSlider; // -1 if none
|
||||
|
||||
// MIDI learn state
|
||||
int midiLearnActive; // 0=off 1=click a control 2=wiggle CC
|
||||
int midiLearnTargetId; // id of selected control (-1 if none)
|
||||
float *midiLearnValuePtr;
|
||||
float midiLearnMin;
|
||||
float midiLearnMax;
|
||||
|
||||
// Patch browser state
|
||||
int patchMenuOpen;
|
||||
int focusedTextInput; // -1 if none
|
||||
int patchConfirmOverwrite;
|
||||
int patchConfirmClear;
|
||||
char patchSaveName[PATCH_NAME_LEN];
|
||||
char patchCurrentName[PATCH_NAME_LEN];
|
||||
int patchFileCount;
|
||||
char patchFiles[PATCH_MAX_FILES][PATCH_NAME_LEN];
|
||||
int patchScrollOffset;
|
||||
int patchShowFavsOnly;
|
||||
char patchFavs[PATCH_MAX_FILES][PATCH_NAME_LEN];
|
||||
int patchFavCount;
|
||||
char patchCurrentDir[256];
|
||||
char patchSubDirs[PATCH_MAX_DIRS][PATCH_NAME_LEN];
|
||||
int patchSubDirCount;
|
||||
|
||||
// Control registry — built lazily by uiKnob/uiSlider for CC mapping persistence
|
||||
UIControlEntry controlRegistry[128];
|
||||
int controlRegistryCount;
|
||||
// CC mappings loaded from file but not yet resolved (registry not yet populated)
|
||||
ConfigCcEntry pendingMappings[128];
|
||||
int pendingCount;
|
||||
} UIState;
|
||||
|
||||
// Lifecycle
|
||||
void uiInit(UIState *ui, MidiState *midi, Camera2D *camera);
|
||||
void uiClose(UIState *ui);
|
||||
|
||||
// Primitives
|
||||
float uiKnob(UIState *ui, int id, float x, float y, float *ptr, float min, float max, const char *label);
|
||||
float uiSlider(UIState *ui, int id, float x, float y, float width, float *ptr, float min, float max, const char *label);
|
||||
int uiWaveformSelector(UIState *ui, float x, float y, int currentWaveform);
|
||||
void uiADSRShape(float x, float y, float width, float height, float attack, float decay, float sustain, float release, Color color);
|
||||
void uiVoiceMeter(UIState *ui, float x, float y, Voice *voices, int voiceCount);
|
||||
|
||||
// Panels
|
||||
void uiOscillatorPanel(UIState *ui, int baseId, float x, float y, float width, float height, Oscillator *osc, const char *title);
|
||||
void uiEnvelopePanel(UIState *ui, int baseId, float x, float y, float width, float height, Envelope *env, const char *title);
|
||||
void uiLfoPanel(UIState *ui, int baseId, float x, float y, float width, float height, LFO *lfo, const char *title);
|
||||
void uiFilterPanel(UIState *ui, float x, float y, float width, float height, Filter *filter, const char *title);
|
||||
void uiMasterPanel(UIState *ui, float x, float y, float width, float height, Synth *s);
|
||||
void uiMidiMenu(UIState *ui, float x, float y, float width, MidiState *midi);
|
||||
void uiPatchMenu(UIState *ui, float x, float y, float width, Synth *s);
|
||||
void uiAboutMenu(UIState *ui, float x, float y, float width);
|
||||
void uiLoadCcMappingsForDevice(UIState *ui, const char *deviceName);
|
||||
|
||||
// Window helpers
|
||||
|
||||
void recomputeViewPort(Camera2D* camera, int x_logical_resolution, int y_logical_resolution, int border_width);
|
||||
|
||||
#endif
|
||||
80
makefile
80
makefile
@@ -1,12 +1,38 @@
|
||||
# Recursive Directory Digesting Makefile V1.0
|
||||
# === Project Settings ===
|
||||
PROJECT := soundThing # Change this to your project name
|
||||
CC := gcc
|
||||
CFLAGS := -Wall -Wextra -std=c11 -O2
|
||||
# Preprocessor flags (deps only here)
|
||||
CPPFLAGS := -MMD -MP
|
||||
# Add linker flags
|
||||
LDFLAGS = -lraylib -lm -ldl -lpthread -lGL -lrt -lX11 -lasound #here (e.g. -lm)
|
||||
|
||||
# === Platform Selection ===
|
||||
# Build for Linux (default): make
|
||||
# Cross-compile for Windows: make PLATFORM=windows
|
||||
PLATFORM ?= linux
|
||||
|
||||
ifeq ($(PLATFORM),windows)
|
||||
CC := x86_64-w64-mingw32-gcc
|
||||
BIN_NAME := $(PROJECT).exe
|
||||
# Point RAYLIB_WIN at the extracted raylib-*_win64_mingw-w64 directory, e.g.:
|
||||
# make PLATFORM=windows RAYLIB_WIN=/opt/raylib-win64
|
||||
# RAYLIB_WIN ?=
|
||||
RAYLIB_WIN = /home/qwhilla/projects/externalLibraries/win64/raylib
|
||||
ifneq ($(RAYLIB_WIN),)
|
||||
CPPFLAGS += -I$(RAYLIB_WIN)/include
|
||||
LDFLAGS := -L$(RAYLIB_WIN)/lib -lraylib -lm -lpthread -lopengl32 -lwinmm -lgdi32 -lws2_32 -static
|
||||
else
|
||||
LDFLAGS := -lraylib -lm -lpthread -lopengl32 -lwinmm -lgdi32 -lws2_32 -static
|
||||
endif
|
||||
MIDI_SRC := midi_windows.c
|
||||
WINDRES := x86_64-w64-mingw32-windres
|
||||
WIN_RES = $(OBJ_DIR)/icon_res.o
|
||||
else
|
||||
CC := gcc
|
||||
BIN_NAME := $(PROJECT)
|
||||
LDFLAGS := -lraylib -lm -ldl -lpthread -lGL -lrt -lX11 -lasound
|
||||
MIDI_SRC := midi_linux.c
|
||||
WIN_RES :=
|
||||
endif
|
||||
|
||||
# === Directory Structure ===
|
||||
SRC_DIR := source
|
||||
@@ -18,25 +44,31 @@ INC_DIR := include
|
||||
INC_SUBDIRS := $(shell find $(INC_DIR) -type d)
|
||||
CPPFLAGS += $(addprefix -I,$(INC_SUBDIRS))
|
||||
|
||||
# === Discover sources recursively ===
|
||||
SRC := $(shell find $(SRC_DIR) -type f -name '*.c')
|
||||
# === Discover sources (exclude platform-split MIDI files, add the right one) ===
|
||||
SRC_AUTO := $(shell find $(SRC_DIR) -type f -name '*.c' ! -name 'midi_*.c' ! -name '*.old')
|
||||
SRC := $(SRC_AUTO) $(SRC_DIR)/$(MIDI_SRC)
|
||||
# Map source paths to object paths (mirror folders under build/)
|
||||
OBJ := $(patsubst $(SRC_DIR)/%.c,$(OBJ_DIR)/%.o,$(SRC))
|
||||
DEP := $(OBJ:.o=.d)
|
||||
BIN := $(BIN_DIR)/$(PROJECT)
|
||||
BIN := $(BIN_DIR)/$(BIN_NAME)
|
||||
|
||||
# === Embedded assets ===
|
||||
SPRITES_DATA := $(SRC_DIR)/sprites_data.c
|
||||
FONT_DATA := $(SRC_DIR)/font_data.c
|
||||
ICON_DATA := $(SRC_DIR)/icon_data.c
|
||||
|
||||
# === Rules ===
|
||||
.PHONY: all clean run dirs
|
||||
|
||||
all: dirs $(BIN)
|
||||
all: dirs $(SPRITES_DATA) $(FONT_DATA) $(ICON_DATA) $(BIN)
|
||||
|
||||
dirs:
|
||||
@mkdir -p $(BIN_DIR)
|
||||
@mkdir -p $(sort $(dir $(OBJ))) # create object subdirs that mirror source/
|
||||
|
||||
# Link objects into final executable
|
||||
$(BIN): $(OBJ)
|
||||
$(CC) $(OBJ) -o $@ $(LDFLAGS)
|
||||
$(BIN): $(OBJ) $(WIN_RES)
|
||||
$(CC) $(OBJ) $(WIN_RES) -o $@ $(LDFLAGS)
|
||||
@echo "Linked -> $@"
|
||||
|
||||
# Compile each .c into a .o, with auto header deps
|
||||
@@ -56,3 +88,33 @@ clean:
|
||||
|
||||
# Include auto-generated dependency files (if present)
|
||||
-include $(DEP)
|
||||
|
||||
# Regenerate embedded sprite data when the PNG changes
|
||||
$(SPRITES_DATA): assets/sprites.png
|
||||
xxd -i $< | sed 's/assets_sprites_png/sprites_png/g' > $@
|
||||
@echo "Generated -> $@"
|
||||
|
||||
# Regenerate embedded font data when the PNG changes
|
||||
$(FONT_DATA): assets/myFont.png
|
||||
xxd -i $< | sed 's/assets_myFont_png/font_png/g' > $@
|
||||
@echo "Generated -> $@"
|
||||
|
||||
# Regenerate embedded icon data when the PNG changes
|
||||
$(ICON_DATA): assets/NPNGear.png
|
||||
xxd -i $< | sed 's/assets_NPNGear_png/icon_png/g' > $@
|
||||
@echo "Generated -> $@"
|
||||
|
||||
# Generate .ico from PNG using pure Python3 stdlib (no Pillow required)
|
||||
assets/NPNGear.ico: assets/NPNGear.png
|
||||
python3 -c "import struct; d=open('$<','rb').read(); \
|
||||
hdr=struct.pack('<HHH',0,1,1); \
|
||||
ent=struct.pack('<BBBBHHII',128,128,0,0,1,32,len(d),22); \
|
||||
open('$@','wb').write(hdr+ent+d)"
|
||||
@echo "Generated -> $@"
|
||||
|
||||
# Compile Windows resource (icon.rc -> icon_res.o), only when cross-compiling
|
||||
ifeq ($(PLATFORM),windows)
|
||||
$(WIN_RES): icon.rc assets/NPNGear.ico
|
||||
$(WINDRES) $< -o $@
|
||||
@echo "Compiled resource -> $@"
|
||||
endif
|
||||
|
||||
50
patches/Atmospheric/CrystalDrift.json
Normal file
50
patches/Atmospheric/CrystalDrift.json
Normal file
@@ -0,0 +1,50 @@
|
||||
{
|
||||
"osc0_waveform": 0,
|
||||
"osc0_dutyCycle": 0.500000,
|
||||
"osc0_detune": 0.000000,
|
||||
"osc0_gain": 3.000000,
|
||||
"osc0_active": 1,
|
||||
"osc0_octave": 1,
|
||||
"osc0_modRouting0": 0,
|
||||
"osc0_modRouting1": 3,
|
||||
"osc0_modRouting2": 0,
|
||||
"osc0_modDepth0": 0.000000,
|
||||
"osc0_modDepth1": 7.000000,
|
||||
"osc0_modDepth2": 0.000000,
|
||||
"osc1_waveform": 1,
|
||||
"osc1_dutyCycle": 0.500000,
|
||||
"osc1_detune": 5.000000,
|
||||
"osc1_gain": 2.200000,
|
||||
"osc1_active": 1,
|
||||
"osc1_octave": 1,
|
||||
"osc1_modRouting0": 0,
|
||||
"osc1_modRouting1": 4,
|
||||
"osc1_modRouting2": 0,
|
||||
"osc1_modDepth0": 0.000000,
|
||||
"osc1_modDepth1": 5.000000,
|
||||
"osc1_modDepth2": 0.000000,
|
||||
"ampEnv_attack": 1.200000,
|
||||
"ampEnv_decay": 0.300000,
|
||||
"ampEnv_sustain": 0.700000,
|
||||
"ampEnv_release": 2.000000,
|
||||
"modEnv_attack": 0.001000,
|
||||
"modEnv_decay": 0.500000,
|
||||
"modEnv_sustain": 0.000000,
|
||||
"modEnv_release": 0.200000,
|
||||
"lfo0_rate": 0.110000,
|
||||
"lfo0_waveform": 0,
|
||||
"lfo0_active": 1,
|
||||
"lfo1_rate": 0.073000,
|
||||
"lfo1_waveform": 0,
|
||||
"lfo1_active": 1,
|
||||
"filter_cutoff": 8000.000000,
|
||||
"filter_resonance": 0.100000,
|
||||
"filter_type": 1,
|
||||
"filter_active": 1,
|
||||
"filter_modRouting": 0,
|
||||
"filter_modDepth": 0.000000,
|
||||
"filter_resModRouting": 0,
|
||||
"filter_resModDepth": 0.000000,
|
||||
"master_volume": 0.650000,
|
||||
"master_pitchBendRange": 2.000000
|
||||
}
|
||||
50
patches/Atmospheric/DarkDrone.json
Normal file
50
patches/Atmospheric/DarkDrone.json
Normal file
@@ -0,0 +1,50 @@
|
||||
{
|
||||
"osc0_waveform": 0,
|
||||
"osc0_dutyCycle": 0.500000,
|
||||
"osc0_detune": -0.800000,
|
||||
"osc0_gain": 4.000000,
|
||||
"osc0_active": 1,
|
||||
"osc0_octave": -2,
|
||||
"osc0_modRouting0": 0,
|
||||
"osc0_modRouting1": 0,
|
||||
"osc0_modRouting2": 4,
|
||||
"osc0_modDepth0": 0.000000,
|
||||
"osc0_modDepth1": 0.000000,
|
||||
"osc0_modDepth2": 0.900000,
|
||||
"osc1_waveform": 0,
|
||||
"osc1_dutyCycle": 0.500000,
|
||||
"osc1_detune": 0.800000,
|
||||
"osc1_gain": 3.500000,
|
||||
"osc1_active": 1,
|
||||
"osc1_octave": -2,
|
||||
"osc1_modRouting0": 0,
|
||||
"osc1_modRouting1": 0,
|
||||
"osc1_modRouting2": 0,
|
||||
"osc1_modDepth0": 0.000000,
|
||||
"osc1_modDepth1": 0.000000,
|
||||
"osc1_modDepth2": 0.000000,
|
||||
"ampEnv_attack": 1.800000,
|
||||
"ampEnv_decay": 0.300000,
|
||||
"ampEnv_sustain": 0.880000,
|
||||
"ampEnv_release": 2.000000,
|
||||
"modEnv_attack": 0.001000,
|
||||
"modEnv_decay": 0.500000,
|
||||
"modEnv_sustain": 0.000000,
|
||||
"modEnv_release": 0.200000,
|
||||
"lfo0_rate": 0.060000,
|
||||
"lfo0_waveform": 0,
|
||||
"lfo0_active": 1,
|
||||
"lfo1_rate": 0.095000,
|
||||
"lfo1_waveform": 0,
|
||||
"lfo1_active": 1,
|
||||
"filter_cutoff": 500.000000,
|
||||
"filter_resonance": 0.350000,
|
||||
"filter_type": 0,
|
||||
"filter_active": 1,
|
||||
"filter_modRouting": 3,
|
||||
"filter_modDepth": 700.000000,
|
||||
"filter_resModRouting": 0,
|
||||
"filter_resModDepth": 0.000000,
|
||||
"master_volume": 0.700000,
|
||||
"master_pitchBendRange": 2.000000
|
||||
}
|
||||
50
patches/Atmospheric/EtherealAir.json
Normal file
50
patches/Atmospheric/EtherealAir.json
Normal file
@@ -0,0 +1,50 @@
|
||||
{
|
||||
"osc0_waveform": 1,
|
||||
"osc0_dutyCycle": 0.500000,
|
||||
"osc0_detune": 0.000000,
|
||||
"osc0_gain": 2.800000,
|
||||
"osc0_active": 1,
|
||||
"osc0_octave": 0,
|
||||
"osc0_modRouting0": 0,
|
||||
"osc0_modRouting1": 3,
|
||||
"osc0_modRouting2": 0,
|
||||
"osc0_modDepth0": 0.000000,
|
||||
"osc0_modDepth1": 5.000000,
|
||||
"osc0_modDepth2": 0.000000,
|
||||
"osc1_waveform": 5,
|
||||
"osc1_dutyCycle": 0.500000,
|
||||
"osc1_detune": 0.000000,
|
||||
"osc1_gain": 0.700000,
|
||||
"osc1_active": 1,
|
||||
"osc1_octave": 0,
|
||||
"osc1_modRouting0": 0,
|
||||
"osc1_modRouting1": 0,
|
||||
"osc1_modRouting2": 0,
|
||||
"osc1_modDepth0": 0.000000,
|
||||
"osc1_modDepth1": 0.000000,
|
||||
"osc1_modDepth2": 0.000000,
|
||||
"ampEnv_attack": 1.600000,
|
||||
"ampEnv_decay": 0.300000,
|
||||
"ampEnv_sustain": 0.700000,
|
||||
"ampEnv_release": 2.000000,
|
||||
"modEnv_attack": 0.001000,
|
||||
"modEnv_decay": 0.500000,
|
||||
"modEnv_sustain": 0.000000,
|
||||
"modEnv_release": 0.200000,
|
||||
"lfo0_rate": 0.180000,
|
||||
"lfo0_waveform": 0,
|
||||
"lfo0_active": 1,
|
||||
"lfo1_rate": 0.085000,
|
||||
"lfo1_waveform": 0,
|
||||
"lfo1_active": 1,
|
||||
"filter_cutoff": 2200.000000,
|
||||
"filter_resonance": 0.200000,
|
||||
"filter_type": 0,
|
||||
"filter_active": 1,
|
||||
"filter_modRouting": 4,
|
||||
"filter_modDepth": 800.000000,
|
||||
"filter_resModRouting": 0,
|
||||
"filter_resModDepth": 0.000000,
|
||||
"master_volume": 0.620000,
|
||||
"master_pitchBendRange": 2.000000
|
||||
}
|
||||
50
patches/Atmospheric/NightStatic.json
Normal file
50
patches/Atmospheric/NightStatic.json
Normal file
@@ -0,0 +1,50 @@
|
||||
{
|
||||
"osc0_waveform": 5,
|
||||
"osc0_dutyCycle": 0.500000,
|
||||
"osc0_detune": 0.000000,
|
||||
"osc0_gain": 4.000000,
|
||||
"osc0_active": 1,
|
||||
"osc0_octave": 0,
|
||||
"osc0_modRouting0": 0,
|
||||
"osc0_modRouting1": 0,
|
||||
"osc0_modRouting2": 0,
|
||||
"osc0_modDepth0": 0.000000,
|
||||
"osc0_modDepth1": 0.000000,
|
||||
"osc0_modDepth2": 0.000000,
|
||||
"osc1_waveform": 0,
|
||||
"osc1_dutyCycle": 0.500000,
|
||||
"osc1_detune": 0.000000,
|
||||
"osc1_gain": 0.400000,
|
||||
"osc1_active": 1,
|
||||
"osc1_octave": -1,
|
||||
"osc1_modRouting0": 0,
|
||||
"osc1_modRouting1": 0,
|
||||
"osc1_modRouting2": 0,
|
||||
"osc1_modDepth0": 0.000000,
|
||||
"osc1_modDepth1": 0.000000,
|
||||
"osc1_modDepth2": 0.000000,
|
||||
"ampEnv_attack": 2.000000,
|
||||
"ampEnv_decay": 0.300000,
|
||||
"ampEnv_sustain": 0.800000,
|
||||
"ampEnv_release": 2.000000,
|
||||
"modEnv_attack": 0.001000,
|
||||
"modEnv_decay": 0.500000,
|
||||
"modEnv_sustain": 0.000000,
|
||||
"modEnv_release": 0.200000,
|
||||
"lfo0_rate": 0.150000,
|
||||
"lfo0_waveform": 0,
|
||||
"lfo0_active": 1,
|
||||
"lfo1_rate": 0.220000,
|
||||
"lfo1_waveform": 0,
|
||||
"lfo1_active": 1,
|
||||
"filter_cutoff": 1800.000000,
|
||||
"filter_resonance": 0.350000,
|
||||
"filter_type": 2,
|
||||
"filter_active": 1,
|
||||
"filter_modRouting": 3,
|
||||
"filter_modDepth": 1200.000000,
|
||||
"filter_resModRouting": 4,
|
||||
"filter_resModDepth": 0.150000,
|
||||
"master_volume": 0.600000,
|
||||
"master_pitchBendRange": 2.000000
|
||||
}
|
||||
50
patches/Atmospheric/SpaceWind.json
Normal file
50
patches/Atmospheric/SpaceWind.json
Normal file
@@ -0,0 +1,50 @@
|
||||
{
|
||||
"osc0_waveform": 5,
|
||||
"osc0_dutyCycle": 0.500000,
|
||||
"osc0_detune": 0.000000,
|
||||
"osc0_gain": 3.500000,
|
||||
"osc0_active": 1,
|
||||
"osc0_octave": 0,
|
||||
"osc0_modRouting0": 0,
|
||||
"osc0_modRouting1": 0,
|
||||
"osc0_modRouting2": 0,
|
||||
"osc0_modDepth0": 0.000000,
|
||||
"osc0_modDepth1": 0.000000,
|
||||
"osc0_modDepth2": 0.000000,
|
||||
"osc1_waveform": 5,
|
||||
"osc1_dutyCycle": 0.500000,
|
||||
"osc1_detune": 0.000000,
|
||||
"osc1_gain": 0.000000,
|
||||
"osc1_active": 0,
|
||||
"osc1_octave": 0,
|
||||
"osc1_modRouting0": 0,
|
||||
"osc1_modRouting1": 0,
|
||||
"osc1_modRouting2": 0,
|
||||
"osc1_modDepth0": 0.000000,
|
||||
"osc1_modDepth1": 0.000000,
|
||||
"osc1_modDepth2": 0.000000,
|
||||
"ampEnv_attack": 2.000000,
|
||||
"ampEnv_decay": 0.500000,
|
||||
"ampEnv_sustain": 0.800000,
|
||||
"ampEnv_release": 2.000000,
|
||||
"modEnv_attack": 0.001000,
|
||||
"modEnv_decay": 0.500000,
|
||||
"modEnv_sustain": 0.000000,
|
||||
"modEnv_release": 0.200000,
|
||||
"lfo0_rate": 0.080000,
|
||||
"lfo0_waveform": 0,
|
||||
"lfo0_active": 1,
|
||||
"lfo1_rate": 0.130000,
|
||||
"lfo1_waveform": 0,
|
||||
"lfo1_active": 1,
|
||||
"filter_cutoff": 900.000000,
|
||||
"filter_resonance": 0.150000,
|
||||
"filter_type": 0,
|
||||
"filter_active": 1,
|
||||
"filter_modRouting": 3,
|
||||
"filter_modDepth": 1800.000000,
|
||||
"filter_resModRouting": 4,
|
||||
"filter_resModDepth": 0.120000,
|
||||
"master_volume": 0.650000,
|
||||
"master_pitchBendRange": 2.000000
|
||||
}
|
||||
50
patches/Atmospheric/VoidHum.json
Normal file
50
patches/Atmospheric/VoidHum.json
Normal file
@@ -0,0 +1,50 @@
|
||||
{
|
||||
"osc0_waveform": 2,
|
||||
"osc0_dutyCycle": 0.500000,
|
||||
"osc0_detune": -2.000000,
|
||||
"osc0_gain": 3.200000,
|
||||
"osc0_active": 1,
|
||||
"osc0_octave": -2,
|
||||
"osc0_modRouting0": 0,
|
||||
"osc0_modRouting1": 0,
|
||||
"osc0_modRouting2": 0,
|
||||
"osc0_modDepth0": 0.000000,
|
||||
"osc0_modDepth1": 0.000000,
|
||||
"osc0_modDepth2": 0.000000,
|
||||
"osc1_waveform": 2,
|
||||
"osc1_dutyCycle": 0.500000,
|
||||
"osc1_detune": 2.000000,
|
||||
"osc1_gain": 2.800000,
|
||||
"osc1_active": 1,
|
||||
"osc1_octave": -2,
|
||||
"osc1_modRouting0": 0,
|
||||
"osc1_modRouting1": 0,
|
||||
"osc1_modRouting2": 4,
|
||||
"osc1_modDepth0": 0.000000,
|
||||
"osc1_modDepth1": 0.000000,
|
||||
"osc1_modDepth2": 1.000000,
|
||||
"ampEnv_attack": 2.000000,
|
||||
"ampEnv_decay": 0.500000,
|
||||
"ampEnv_sustain": 0.850000,
|
||||
"ampEnv_release": 2.000000,
|
||||
"modEnv_attack": 0.001000,
|
||||
"modEnv_decay": 0.500000,
|
||||
"modEnv_sustain": 0.000000,
|
||||
"modEnv_release": 0.200000,
|
||||
"lfo0_rate": 0.065000,
|
||||
"lfo0_waveform": 0,
|
||||
"lfo0_active": 1,
|
||||
"lfo1_rate": 0.042000,
|
||||
"lfo1_waveform": 0,
|
||||
"lfo1_active": 1,
|
||||
"filter_cutoff": 380.000000,
|
||||
"filter_resonance": 0.420000,
|
||||
"filter_type": 0,
|
||||
"filter_active": 1,
|
||||
"filter_modRouting": 3,
|
||||
"filter_modDepth": 550.000000,
|
||||
"filter_resModRouting": 0,
|
||||
"filter_resModDepth": 0.000000,
|
||||
"master_volume": 0.720000,
|
||||
"master_pitchBendRange": 2.000000
|
||||
}
|
||||
50
patches/Chiptune/ChipBass.json
Normal file
50
patches/Chiptune/ChipBass.json
Normal file
@@ -0,0 +1,50 @@
|
||||
{
|
||||
"osc0_waveform": 1,
|
||||
"osc0_dutyCycle": 0.500000,
|
||||
"osc0_detune": 0.000000,
|
||||
"osc0_gain": 4.500000,
|
||||
"osc0_active": 1,
|
||||
"osc0_octave": -1,
|
||||
"osc0_modRouting0": 0,
|
||||
"osc0_modRouting1": 0,
|
||||
"osc0_modRouting2": 0,
|
||||
"osc0_modDepth0": 0.000000,
|
||||
"osc0_modDepth1": 0.000000,
|
||||
"osc0_modDepth2": 0.000000,
|
||||
"osc1_waveform": 1,
|
||||
"osc1_dutyCycle": 0.500000,
|
||||
"osc1_detune": 0.000000,
|
||||
"osc1_gain": 0.000000,
|
||||
"osc1_active": 0,
|
||||
"osc1_octave": 0,
|
||||
"osc1_modRouting0": 0,
|
||||
"osc1_modRouting1": 0,
|
||||
"osc1_modRouting2": 0,
|
||||
"osc1_modDepth0": 0.000000,
|
||||
"osc1_modDepth1": 0.000000,
|
||||
"osc1_modDepth2": 0.000000,
|
||||
"ampEnv_attack": 0.001000,
|
||||
"ampEnv_decay": 0.700000,
|
||||
"ampEnv_sustain": 0.000000,
|
||||
"ampEnv_release": 0.080000,
|
||||
"modEnv_attack": 0.001000,
|
||||
"modEnv_decay": 0.500000,
|
||||
"modEnv_sustain": 0.000000,
|
||||
"modEnv_release": 0.200000,
|
||||
"lfo0_rate": 1.000000,
|
||||
"lfo0_waveform": 0,
|
||||
"lfo0_active": 0,
|
||||
"lfo1_rate": 1.000000,
|
||||
"lfo1_waveform": 0,
|
||||
"lfo1_active": 0,
|
||||
"filter_cutoff": 20000.000000,
|
||||
"filter_resonance": 0.000000,
|
||||
"filter_type": 0,
|
||||
"filter_active": 0,
|
||||
"filter_modRouting": 0,
|
||||
"filter_modDepth": 0.000000,
|
||||
"filter_resModRouting": 0,
|
||||
"filter_resModDepth": 0.000000,
|
||||
"master_volume": 0.800000,
|
||||
"master_pitchBendRange": 1.000000
|
||||
}
|
||||
50
patches/Chiptune/ChipBell.json
Normal file
50
patches/Chiptune/ChipBell.json
Normal file
@@ -0,0 +1,50 @@
|
||||
{
|
||||
"osc0_waveform": 4,
|
||||
"osc0_dutyCycle": 0.500000,
|
||||
"osc0_detune": 0.000000,
|
||||
"osc0_gain": 3.500000,
|
||||
"osc0_active": 1,
|
||||
"osc0_octave": 0,
|
||||
"osc0_modRouting0": 0,
|
||||
"osc0_modRouting1": 0,
|
||||
"osc0_modRouting2": 0,
|
||||
"osc0_modDepth0": 0.000000,
|
||||
"osc0_modDepth1": 0.000000,
|
||||
"osc0_modDepth2": 0.000000,
|
||||
"osc1_waveform": 4,
|
||||
"osc1_dutyCycle": 0.500000,
|
||||
"osc1_detune": 14.000000,
|
||||
"osc1_gain": 0.500000,
|
||||
"osc1_active": 1,
|
||||
"osc1_octave": 1,
|
||||
"osc1_modRouting0": 0,
|
||||
"osc1_modRouting1": 0,
|
||||
"osc1_modRouting2": 2,
|
||||
"osc1_modDepth0": 0.000000,
|
||||
"osc1_modDepth1": 0.000000,
|
||||
"osc1_modDepth2": 2.000000,
|
||||
"ampEnv_attack": 0.001000,
|
||||
"ampEnv_decay": 1.400000,
|
||||
"ampEnv_sustain": 0.000000,
|
||||
"ampEnv_release": 0.300000,
|
||||
"modEnv_attack": 0.001000,
|
||||
"modEnv_decay": 0.060000,
|
||||
"modEnv_sustain": 0.000000,
|
||||
"modEnv_release": 0.030000,
|
||||
"lfo0_rate": 1.000000,
|
||||
"lfo0_waveform": 0,
|
||||
"lfo0_active": 0,
|
||||
"lfo1_rate": 1.000000,
|
||||
"lfo1_waveform": 0,
|
||||
"lfo1_active": 0,
|
||||
"filter_cutoff": 20000.000000,
|
||||
"filter_resonance": 0.000000,
|
||||
"filter_type": 0,
|
||||
"filter_active": 0,
|
||||
"filter_modRouting": 0,
|
||||
"filter_modDepth": 0.000000,
|
||||
"filter_resModRouting": 0,
|
||||
"filter_resModDepth": 0.000000,
|
||||
"master_volume": 0.750000,
|
||||
"master_pitchBendRange": 1.000000
|
||||
}
|
||||
50
patches/Chiptune/ChipLead.json
Normal file
50
patches/Chiptune/ChipLead.json
Normal file
@@ -0,0 +1,50 @@
|
||||
{
|
||||
"osc0_waveform": 4,
|
||||
"osc0_dutyCycle": 0.500000,
|
||||
"osc0_detune": 0.000000,
|
||||
"osc0_gain": 4.000000,
|
||||
"osc0_active": 1,
|
||||
"osc0_octave": 0,
|
||||
"osc0_modRouting0": 0,
|
||||
"osc0_modRouting1": 0,
|
||||
"osc0_modRouting2": 0,
|
||||
"osc0_modDepth0": 0.000000,
|
||||
"osc0_modDepth1": 0.000000,
|
||||
"osc0_modDepth2": 0.000000,
|
||||
"osc1_waveform": 4,
|
||||
"osc1_dutyCycle": 0.500000,
|
||||
"osc1_detune": 0.000000,
|
||||
"osc1_gain": 0.000000,
|
||||
"osc1_active": 0,
|
||||
"osc1_octave": 0,
|
||||
"osc1_modRouting0": 0,
|
||||
"osc1_modRouting1": 0,
|
||||
"osc1_modRouting2": 0,
|
||||
"osc1_modDepth0": 0.000000,
|
||||
"osc1_modDepth1": 0.000000,
|
||||
"osc1_modDepth2": 0.000000,
|
||||
"ampEnv_attack": 0.001000,
|
||||
"ampEnv_decay": 0.050000,
|
||||
"ampEnv_sustain": 0.850000,
|
||||
"ampEnv_release": 0.040000,
|
||||
"modEnv_attack": 0.001000,
|
||||
"modEnv_decay": 0.500000,
|
||||
"modEnv_sustain": 0.000000,
|
||||
"modEnv_release": 0.200000,
|
||||
"lfo0_rate": 1.000000,
|
||||
"lfo0_waveform": 0,
|
||||
"lfo0_active": 0,
|
||||
"lfo1_rate": 1.000000,
|
||||
"lfo1_waveform": 0,
|
||||
"lfo1_active": 0,
|
||||
"filter_cutoff": 20000.000000,
|
||||
"filter_resonance": 0.000000,
|
||||
"filter_type": 0,
|
||||
"filter_active": 0,
|
||||
"filter_modRouting": 0,
|
||||
"filter_modDepth": 0.000000,
|
||||
"filter_resModRouting": 0,
|
||||
"filter_resModDepth": 0.000000,
|
||||
"master_volume": 0.750000,
|
||||
"master_pitchBendRange": 1.000000
|
||||
}
|
||||
50
patches/Chiptune/ChipPad.json
Normal file
50
patches/Chiptune/ChipPad.json
Normal file
@@ -0,0 +1,50 @@
|
||||
{
|
||||
"osc0_waveform": 4,
|
||||
"osc0_dutyCycle": 0.250000,
|
||||
"osc0_detune": -4.000000,
|
||||
"osc0_gain": 2.800000,
|
||||
"osc0_active": 1,
|
||||
"osc0_octave": 0,
|
||||
"osc0_modRouting0": 3,
|
||||
"osc0_modRouting1": 0,
|
||||
"osc0_modRouting2": 0,
|
||||
"osc0_modDepth0": 0.100000,
|
||||
"osc0_modDepth1": 0.000000,
|
||||
"osc0_modDepth2": 0.000000,
|
||||
"osc1_waveform": 4,
|
||||
"osc1_dutyCycle": 0.250000,
|
||||
"osc1_detune": 4.000000,
|
||||
"osc1_gain": 2.800000,
|
||||
"osc1_active": 1,
|
||||
"osc1_octave": 0,
|
||||
"osc1_modRouting0": 0,
|
||||
"osc1_modRouting1": 0,
|
||||
"osc1_modRouting2": 0,
|
||||
"osc1_modDepth0": 0.000000,
|
||||
"osc1_modDepth1": 0.000000,
|
||||
"osc1_modDepth2": 0.000000,
|
||||
"ampEnv_attack": 0.120000,
|
||||
"ampEnv_decay": 0.100000,
|
||||
"ampEnv_sustain": 0.800000,
|
||||
"ampEnv_release": 0.200000,
|
||||
"modEnv_attack": 0.001000,
|
||||
"modEnv_decay": 0.500000,
|
||||
"modEnv_sustain": 0.000000,
|
||||
"modEnv_release": 0.200000,
|
||||
"lfo0_rate": 0.350000,
|
||||
"lfo0_waveform": 0,
|
||||
"lfo0_active": 1,
|
||||
"lfo1_rate": 1.000000,
|
||||
"lfo1_waveform": 0,
|
||||
"lfo1_active": 0,
|
||||
"filter_cutoff": 20000.000000,
|
||||
"filter_resonance": 0.000000,
|
||||
"filter_type": 0,
|
||||
"filter_active": 0,
|
||||
"filter_modRouting": 0,
|
||||
"filter_modDepth": 0.000000,
|
||||
"filter_resModRouting": 0,
|
||||
"filter_resModDepth": 0.000000,
|
||||
"master_volume": 0.700000,
|
||||
"master_pitchBendRange": 1.000000
|
||||
}
|
||||
50
patches/Chiptune/GameBoyLead.json
Normal file
50
patches/Chiptune/GameBoyLead.json
Normal file
@@ -0,0 +1,50 @@
|
||||
{
|
||||
"osc0_waveform": 4,
|
||||
"osc0_dutyCycle": 0.125000,
|
||||
"osc0_detune": 0.000000,
|
||||
"osc0_gain": 4.000000,
|
||||
"osc0_active": 1,
|
||||
"osc0_octave": 0,
|
||||
"osc0_modRouting0": 0,
|
||||
"osc0_modRouting1": 0,
|
||||
"osc0_modRouting2": 0,
|
||||
"osc0_modDepth0": 0.000000,
|
||||
"osc0_modDepth1": 0.000000,
|
||||
"osc0_modDepth2": 0.000000,
|
||||
"osc1_waveform": 4,
|
||||
"osc1_dutyCycle": 0.125000,
|
||||
"osc1_detune": 0.000000,
|
||||
"osc1_gain": 2.000000,
|
||||
"osc1_active": 1,
|
||||
"osc1_octave": 1,
|
||||
"osc1_modRouting0": 0,
|
||||
"osc1_modRouting1": 0,
|
||||
"osc1_modRouting2": 0,
|
||||
"osc1_modDepth0": 0.000000,
|
||||
"osc1_modDepth1": 0.000000,
|
||||
"osc1_modDepth2": 0.000000,
|
||||
"ampEnv_attack": 0.001000,
|
||||
"ampEnv_decay": 0.030000,
|
||||
"ampEnv_sustain": 0.700000,
|
||||
"ampEnv_release": 0.030000,
|
||||
"modEnv_attack": 0.001000,
|
||||
"modEnv_decay": 0.500000,
|
||||
"modEnv_sustain": 0.000000,
|
||||
"modEnv_release": 0.200000,
|
||||
"lfo0_rate": 1.000000,
|
||||
"lfo0_waveform": 0,
|
||||
"lfo0_active": 0,
|
||||
"lfo1_rate": 1.000000,
|
||||
"lfo1_waveform": 0,
|
||||
"lfo1_active": 0,
|
||||
"filter_cutoff": 20000.000000,
|
||||
"filter_resonance": 0.000000,
|
||||
"filter_type": 0,
|
||||
"filter_active": 0,
|
||||
"filter_modRouting": 0,
|
||||
"filter_modDepth": 0.000000,
|
||||
"filter_resModRouting": 0,
|
||||
"filter_resModDepth": 0.000000,
|
||||
"master_volume": 0.700000,
|
||||
"master_pitchBendRange": 1.000000
|
||||
}
|
||||
50
patches/Chiptune/SIDLead.json
Normal file
50
patches/Chiptune/SIDLead.json
Normal file
@@ -0,0 +1,50 @@
|
||||
{
|
||||
"osc0_waveform": 2,
|
||||
"osc0_dutyCycle": 0.500000,
|
||||
"osc0_detune": -3.000000,
|
||||
"osc0_gain": 3.000000,
|
||||
"osc0_active": 1,
|
||||
"osc0_octave": 0,
|
||||
"osc0_modRouting0": 0,
|
||||
"osc0_modRouting1": 0,
|
||||
"osc0_modRouting2": 0,
|
||||
"osc0_modDepth0": 0.000000,
|
||||
"osc0_modDepth1": 0.000000,
|
||||
"osc0_modDepth2": 0.000000,
|
||||
"osc1_waveform": 4,
|
||||
"osc1_dutyCycle": 0.300000,
|
||||
"osc1_detune": 3.000000,
|
||||
"osc1_gain": 2.500000,
|
||||
"osc1_active": 1,
|
||||
"osc1_octave": 0,
|
||||
"osc1_modRouting0": 4,
|
||||
"osc1_modRouting1": 0,
|
||||
"osc1_modRouting2": 0,
|
||||
"osc1_modDepth0": 0.250000,
|
||||
"osc1_modDepth1": 0.000000,
|
||||
"osc1_modDepth2": 0.000000,
|
||||
"ampEnv_attack": 0.001000,
|
||||
"ampEnv_decay": 0.080000,
|
||||
"ampEnv_sustain": 0.800000,
|
||||
"ampEnv_release": 0.060000,
|
||||
"modEnv_attack": 0.001000,
|
||||
"modEnv_decay": 0.180000,
|
||||
"modEnv_sustain": 0.000000,
|
||||
"modEnv_release": 0.080000,
|
||||
"lfo0_rate": 1.000000,
|
||||
"lfo0_waveform": 0,
|
||||
"lfo0_active": 0,
|
||||
"lfo1_rate": 6.000000,
|
||||
"lfo1_waveform": 1,
|
||||
"lfo1_active": 1,
|
||||
"filter_cutoff": 1200.000000,
|
||||
"filter_resonance": 0.550000,
|
||||
"filter_type": 0,
|
||||
"filter_active": 1,
|
||||
"filter_modRouting": 2,
|
||||
"filter_modDepth": 7000.000000,
|
||||
"filter_resModRouting": 0,
|
||||
"filter_resModDepth": 0.000000,
|
||||
"master_volume": 0.750000,
|
||||
"master_pitchBendRange": 2.000000
|
||||
}
|
||||
50
patches/Chiptune/SidSquare.json
Normal file
50
patches/Chiptune/SidSquare.json
Normal file
@@ -0,0 +1,50 @@
|
||||
{
|
||||
"osc0_waveform": 4,
|
||||
"osc0_dutyCycle": 0.153236,
|
||||
"osc0_detune": 0.000000,
|
||||
"osc0_gain": 4.000000,
|
||||
"osc0_active": 1,
|
||||
"osc0_octave": 0,
|
||||
"osc0_modRouting0": 1,
|
||||
"osc0_modRouting1": 0,
|
||||
"osc0_modRouting2": 3,
|
||||
"osc0_modDepth0": 0.290788,
|
||||
"osc0_modDepth1": 0.000000,
|
||||
"osc0_modDepth2": -0.833591,
|
||||
"osc1_waveform": 1,
|
||||
"osc1_dutyCycle": 0.500000,
|
||||
"osc1_detune": 0.000000,
|
||||
"osc1_gain": 0.000000,
|
||||
"osc1_active": 0,
|
||||
"osc1_octave": 0,
|
||||
"osc1_modRouting0": 0,
|
||||
"osc1_modRouting1": 0,
|
||||
"osc1_modRouting2": 0,
|
||||
"osc1_modDepth0": 0.000000,
|
||||
"osc1_modDepth1": 0.000000,
|
||||
"osc1_modDepth2": 0.000000,
|
||||
"ampEnv_attack": 0.005000,
|
||||
"ampEnv_decay": 0.100000,
|
||||
"ampEnv_sustain": 0.700000,
|
||||
"ampEnv_release": 0.500000,
|
||||
"modEnv_attack": 0.005000,
|
||||
"modEnv_decay": 0.500000,
|
||||
"modEnv_sustain": 0.000000,
|
||||
"modEnv_release": 0.100000,
|
||||
"lfo0_rate": 2.598532,
|
||||
"lfo0_waveform": 0,
|
||||
"lfo0_active": 1,
|
||||
"lfo1_rate": 1.000000,
|
||||
"lfo1_waveform": 0,
|
||||
"lfo1_active": 0,
|
||||
"filter_cutoff": 8000.000000,
|
||||
"filter_resonance": 0.000000,
|
||||
"filter_type": 0,
|
||||
"filter_active": 0,
|
||||
"filter_modRouting": 0,
|
||||
"filter_modDepth": 0.000000,
|
||||
"filter_resModRouting": 0,
|
||||
"filter_resModDepth": 0.000000,
|
||||
"master_volume": 0.362205,
|
||||
"master_pitchBendRange": 2.000000
|
||||
}
|
||||
50
patches/Classic/AcidBass.json
Normal file
50
patches/Classic/AcidBass.json
Normal file
@@ -0,0 +1,50 @@
|
||||
{
|
||||
"osc0_waveform": 2,
|
||||
"osc0_dutyCycle": 0.500000,
|
||||
"osc0_detune": 0.000000,
|
||||
"osc0_gain": 4.000000,
|
||||
"osc0_active": 1,
|
||||
"osc0_octave": -1,
|
||||
"osc0_modRouting0": 0,
|
||||
"osc0_modRouting1": 0,
|
||||
"osc0_modRouting2": 0,
|
||||
"osc0_modDepth0": 0.000000,
|
||||
"osc0_modDepth1": 0.000000,
|
||||
"osc0_modDepth2": 0.000000,
|
||||
"osc1_waveform": 2,
|
||||
"osc1_dutyCycle": 0.500000,
|
||||
"osc1_detune": 0.000000,
|
||||
"osc1_gain": 0.000000,
|
||||
"osc1_active": 0,
|
||||
"osc1_octave": 0,
|
||||
"osc1_modRouting0": 0,
|
||||
"osc1_modRouting1": 0,
|
||||
"osc1_modRouting2": 0,
|
||||
"osc1_modDepth0": 0.000000,
|
||||
"osc1_modDepth1": 0.000000,
|
||||
"osc1_modDepth2": 0.000000,
|
||||
"ampEnv_attack": 0.001000,
|
||||
"ampEnv_decay": 0.500000,
|
||||
"ampEnv_sustain": 0.300000,
|
||||
"ampEnv_release": 0.100000,
|
||||
"modEnv_attack": 0.001000,
|
||||
"modEnv_decay": 0.120000,
|
||||
"modEnv_sustain": 0.000000,
|
||||
"modEnv_release": 0.050000,
|
||||
"lfo0_rate": 1.000000,
|
||||
"lfo0_waveform": 0,
|
||||
"lfo0_active": 0,
|
||||
"lfo1_rate": 1.000000,
|
||||
"lfo1_waveform": 0,
|
||||
"lfo1_active": 0,
|
||||
"filter_cutoff": 700.000000,
|
||||
"filter_resonance": 0.700000,
|
||||
"filter_type": 0,
|
||||
"filter_active": 1,
|
||||
"filter_modRouting": 2,
|
||||
"filter_modDepth": 9000.000000,
|
||||
"filter_resModRouting": 0,
|
||||
"filter_resModDepth": 0.000000,
|
||||
"master_volume": 0.800000,
|
||||
"master_pitchBendRange": 1.000000
|
||||
}
|
||||
50
patches/Classic/Banjo.json
Normal file
50
patches/Classic/Banjo.json
Normal file
@@ -0,0 +1,50 @@
|
||||
{
|
||||
"osc0_waveform": 4,
|
||||
"osc0_dutyCycle": 0.200000,
|
||||
"osc0_detune": 0.000000,
|
||||
"osc0_gain": 3.500000,
|
||||
"osc0_active": 1,
|
||||
"osc0_octave": 0,
|
||||
"osc0_modRouting0": 0,
|
||||
"osc0_modRouting1": 0,
|
||||
"osc0_modRouting2": 0,
|
||||
"osc0_modDepth0": 0.000000,
|
||||
"osc0_modDepth1": 0.000000,
|
||||
"osc0_modDepth2": 0.000000,
|
||||
"osc1_waveform": 5,
|
||||
"osc1_dutyCycle": 0.500000,
|
||||
"osc1_detune": 0.000000,
|
||||
"osc1_gain": 0.000000,
|
||||
"osc1_active": 1,
|
||||
"osc1_octave": 0,
|
||||
"osc1_modRouting0": 0,
|
||||
"osc1_modRouting1": 0,
|
||||
"osc1_modRouting2": 2,
|
||||
"osc1_modDepth0": 0.000000,
|
||||
"osc1_modDepth1": 0.000000,
|
||||
"osc1_modDepth2": 1.500000,
|
||||
"ampEnv_attack": 0.001000,
|
||||
"ampEnv_decay": 0.900000,
|
||||
"ampEnv_sustain": 0.000000,
|
||||
"ampEnv_release": 0.250000,
|
||||
"modEnv_attack": 0.000000,
|
||||
"modEnv_decay": 0.050000,
|
||||
"modEnv_sustain": 0.000000,
|
||||
"modEnv_release": 0.025000,
|
||||
"lfo0_rate": 1.000000,
|
||||
"lfo0_waveform": 0,
|
||||
"lfo0_active": 0,
|
||||
"lfo1_rate": 1.000000,
|
||||
"lfo1_waveform": 0,
|
||||
"lfo1_active": 0,
|
||||
"filter_cutoff": 5000.000000,
|
||||
"filter_resonance": 0.150000,
|
||||
"filter_type": 0,
|
||||
"filter_active": 1,
|
||||
"filter_modRouting": 1,
|
||||
"filter_modDepth": 5000.000000,
|
||||
"filter_resModRouting": 0,
|
||||
"filter_resModDepth": 0.000000,
|
||||
"master_volume": 0.750000,
|
||||
"master_pitchBendRange": 1.000000
|
||||
}
|
||||
50
patches/Classic/BrassStab.json
Normal file
50
patches/Classic/BrassStab.json
Normal file
@@ -0,0 +1,50 @@
|
||||
{
|
||||
"osc0_waveform": 2,
|
||||
"osc0_dutyCycle": 0.500000,
|
||||
"osc0_detune": -3.000000,
|
||||
"osc0_gain": 3.000000,
|
||||
"osc0_active": 1,
|
||||
"osc0_octave": 0,
|
||||
"osc0_modRouting0": 0,
|
||||
"osc0_modRouting1": 0,
|
||||
"osc0_modRouting2": 0,
|
||||
"osc0_modDepth0": 0.000000,
|
||||
"osc0_modDepth1": 0.000000,
|
||||
"osc0_modDepth2": 0.000000,
|
||||
"osc1_waveform": 2,
|
||||
"osc1_dutyCycle": 0.500000,
|
||||
"osc1_detune": 3.000000,
|
||||
"osc1_gain": 2.500000,
|
||||
"osc1_active": 1,
|
||||
"osc1_octave": 0,
|
||||
"osc1_modRouting0": 0,
|
||||
"osc1_modRouting1": 0,
|
||||
"osc1_modRouting2": 0,
|
||||
"osc1_modDepth0": 0.000000,
|
||||
"osc1_modDepth1": 0.000000,
|
||||
"osc1_modDepth2": 0.000000,
|
||||
"ampEnv_attack": 0.012000,
|
||||
"ampEnv_decay": 0.250000,
|
||||
"ampEnv_sustain": 0.650000,
|
||||
"ampEnv_release": 0.220000,
|
||||
"modEnv_attack": 0.000000,
|
||||
"modEnv_decay": 0.150000,
|
||||
"modEnv_sustain": 0.000000,
|
||||
"modEnv_release": 0.100000,
|
||||
"lfo0_rate": 1.000000,
|
||||
"lfo0_waveform": 0,
|
||||
"lfo0_active": 0,
|
||||
"lfo1_rate": 1.000000,
|
||||
"lfo1_waveform": 0,
|
||||
"lfo1_active": 0,
|
||||
"filter_cutoff": 700.000000,
|
||||
"filter_resonance": 0.400000,
|
||||
"filter_type": 0,
|
||||
"filter_active": 1,
|
||||
"filter_modRouting": 2,
|
||||
"filter_modDepth": 7500.000000,
|
||||
"filter_resModRouting": 0,
|
||||
"filter_resModDepth": 0.000000,
|
||||
"master_volume": 0.750000,
|
||||
"master_pitchBendRange": 2.000000
|
||||
}
|
||||
50
patches/Classic/Cello.json
Normal file
50
patches/Classic/Cello.json
Normal file
@@ -0,0 +1,50 @@
|
||||
{
|
||||
"osc0_waveform": 2,
|
||||
"osc0_dutyCycle": 0.500000,
|
||||
"osc0_detune": -3.000000,
|
||||
"osc0_gain": 3.500000,
|
||||
"osc0_active": 1,
|
||||
"osc0_octave": 0,
|
||||
"osc0_modRouting0": 0,
|
||||
"osc0_modRouting1": 3,
|
||||
"osc0_modRouting2": 0,
|
||||
"osc0_modDepth0": 0.000000,
|
||||
"osc0_modDepth1": 12.000000,
|
||||
"osc0_modDepth2": 0.000000,
|
||||
"osc1_waveform": 2,
|
||||
"osc1_dutyCycle": 0.500000,
|
||||
"osc1_detune": 3.000000,
|
||||
"osc1_gain": 2.000000,
|
||||
"osc1_active": 1,
|
||||
"osc1_octave": 0,
|
||||
"osc1_modRouting0": 0,
|
||||
"osc1_modRouting1": 0,
|
||||
"osc1_modRouting2": 0,
|
||||
"osc1_modDepth0": 0.000000,
|
||||
"osc1_modDepth1": 0.000000,
|
||||
"osc1_modDepth2": 0.000000,
|
||||
"ampEnv_attack": 0.280000,
|
||||
"ampEnv_decay": 0.150000,
|
||||
"ampEnv_sustain": 0.850000,
|
||||
"ampEnv_release": 0.600000,
|
||||
"modEnv_attack": 0.001000,
|
||||
"modEnv_decay": 0.200000,
|
||||
"modEnv_sustain": 0.000000,
|
||||
"modEnv_release": 0.100000,
|
||||
"lfo0_rate": 5.200000,
|
||||
"lfo0_waveform": 0,
|
||||
"lfo0_active": 1,
|
||||
"lfo1_rate": 1.000000,
|
||||
"lfo1_waveform": 0,
|
||||
"lfo1_active": 0,
|
||||
"filter_cutoff": 2500.000000,
|
||||
"filter_resonance": 0.150000,
|
||||
"filter_type": 0,
|
||||
"filter_active": 1,
|
||||
"filter_modRouting": 1,
|
||||
"filter_modDepth": 1500.000000,
|
||||
"filter_resModRouting": 0,
|
||||
"filter_resModDepth": 0.000000,
|
||||
"master_volume": 0.700000,
|
||||
"master_pitchBendRange": 2.000000
|
||||
}
|
||||
50
patches/Classic/Choir.json
Normal file
50
patches/Classic/Choir.json
Normal file
@@ -0,0 +1,50 @@
|
||||
{
|
||||
"osc0_waveform": 4,
|
||||
"osc0_dutyCycle": 0.550000,
|
||||
"osc0_detune": -4.000000,
|
||||
"osc0_gain": 3.000000,
|
||||
"osc0_active": 1,
|
||||
"osc0_octave": 0,
|
||||
"osc0_modRouting0": 3,
|
||||
"osc0_modRouting1": 0,
|
||||
"osc0_modRouting2": 0,
|
||||
"osc0_modDepth0": 0.120000,
|
||||
"osc0_modDepth1": 0.000000,
|
||||
"osc0_modDepth2": 0.000000,
|
||||
"osc1_waveform": 4,
|
||||
"osc1_dutyCycle": 0.450000,
|
||||
"osc1_detune": 4.000000,
|
||||
"osc1_gain": 2.500000,
|
||||
"osc1_active": 1,
|
||||
"osc1_octave": 0,
|
||||
"osc1_modRouting0": 0,
|
||||
"osc1_modRouting1": 0,
|
||||
"osc1_modRouting2": 0,
|
||||
"osc1_modDepth0": 0.000000,
|
||||
"osc1_modDepth1": 0.000000,
|
||||
"osc1_modDepth2": 0.000000,
|
||||
"ampEnv_attack": 0.380000,
|
||||
"ampEnv_decay": 0.250000,
|
||||
"ampEnv_sustain": 0.700000,
|
||||
"ampEnv_release": 0.900000,
|
||||
"modEnv_attack": 0.001000,
|
||||
"modEnv_decay": 0.500000,
|
||||
"modEnv_sustain": 0.000000,
|
||||
"modEnv_release": 0.200000,
|
||||
"lfo0_rate": 0.280000,
|
||||
"lfo0_waveform": 0,
|
||||
"lfo0_active": 1,
|
||||
"lfo1_rate": 1.000000,
|
||||
"lfo1_waveform": 0,
|
||||
"lfo1_active": 0,
|
||||
"filter_cutoff": 1600.000000,
|
||||
"filter_resonance": 0.280000,
|
||||
"filter_type": 0,
|
||||
"filter_active": 1,
|
||||
"filter_modRouting": 1,
|
||||
"filter_modDepth": 1800.000000,
|
||||
"filter_resModRouting": 0,
|
||||
"filter_resModDepth": 0.000000,
|
||||
"master_volume": 0.650000,
|
||||
"master_pitchBendRange": 2.000000
|
||||
}
|
||||
50
patches/Classic/ClassicLead.json
Normal file
50
patches/Classic/ClassicLead.json
Normal file
@@ -0,0 +1,50 @@
|
||||
{
|
||||
"osc0_waveform": 2,
|
||||
"osc0_dutyCycle": 0.500000,
|
||||
"osc0_detune": 0.000000,
|
||||
"osc0_gain": 3.000000,
|
||||
"osc0_active": 1,
|
||||
"osc0_octave": 0,
|
||||
"osc0_modRouting0": 0,
|
||||
"osc0_modRouting1": 0,
|
||||
"osc0_modRouting2": 0,
|
||||
"osc0_modDepth0": 0.000000,
|
||||
"osc0_modDepth1": 0.000000,
|
||||
"osc0_modDepth2": 0.000000,
|
||||
"osc1_waveform": 2,
|
||||
"osc1_dutyCycle": 0.500000,
|
||||
"osc1_detune": 4.000000,
|
||||
"osc1_gain": 2.000000,
|
||||
"osc1_active": 1,
|
||||
"osc1_octave": 0,
|
||||
"osc1_modRouting0": 0,
|
||||
"osc1_modRouting1": 0,
|
||||
"osc1_modRouting2": 0,
|
||||
"osc1_modDepth0": 0.000000,
|
||||
"osc1_modDepth1": 0.000000,
|
||||
"osc1_modDepth2": 0.000000,
|
||||
"ampEnv_attack": 0.008000,
|
||||
"ampEnv_decay": 0.150000,
|
||||
"ampEnv_sustain": 0.720000,
|
||||
"ampEnv_release": 0.200000,
|
||||
"modEnv_attack": 0.000000,
|
||||
"modEnv_decay": 0.300000,
|
||||
"modEnv_sustain": 0.000000,
|
||||
"modEnv_release": 0.150000,
|
||||
"lfo0_rate": 5.500000,
|
||||
"lfo0_waveform": 0,
|
||||
"lfo0_active": 0,
|
||||
"lfo1_rate": 1.000000,
|
||||
"lfo1_waveform": 0,
|
||||
"lfo1_active": 0,
|
||||
"filter_cutoff": 2200.000000,
|
||||
"filter_resonance": 0.500000,
|
||||
"filter_type": 0,
|
||||
"filter_active": 1,
|
||||
"filter_modRouting": 2,
|
||||
"filter_modDepth": 6000.000000,
|
||||
"filter_resModRouting": 0,
|
||||
"filter_resModDepth": 0.000000,
|
||||
"master_volume": 0.750000,
|
||||
"master_pitchBendRange": 2.000000
|
||||
}
|
||||
50
patches/Classic/DeepBass.json
Normal file
50
patches/Classic/DeepBass.json
Normal file
@@ -0,0 +1,50 @@
|
||||
{
|
||||
"osc0_waveform": 0,
|
||||
"osc0_dutyCycle": 0.500000,
|
||||
"osc0_detune": 0.000000,
|
||||
"osc0_gain": 3.500000,
|
||||
"osc0_active": 1,
|
||||
"osc0_octave": -2,
|
||||
"osc0_modRouting0": 0,
|
||||
"osc0_modRouting1": 0,
|
||||
"osc0_modRouting2": 0,
|
||||
"osc0_modDepth0": 0.000000,
|
||||
"osc0_modDepth1": 0.000000,
|
||||
"osc0_modDepth2": 0.000000,
|
||||
"osc1_waveform": 2,
|
||||
"osc1_dutyCycle": 0.500000,
|
||||
"osc1_detune": 0.000000,
|
||||
"osc1_gain": 1.800000,
|
||||
"osc1_active": 1,
|
||||
"osc1_octave": -1,
|
||||
"osc1_modRouting0": 0,
|
||||
"osc1_modRouting1": 0,
|
||||
"osc1_modRouting2": 0,
|
||||
"osc1_modDepth0": 0.000000,
|
||||
"osc1_modDepth1": 0.000000,
|
||||
"osc1_modDepth2": 0.000000,
|
||||
"ampEnv_attack": 0.006000,
|
||||
"ampEnv_decay": 0.200000,
|
||||
"ampEnv_sustain": 0.650000,
|
||||
"ampEnv_release": 0.180000,
|
||||
"modEnv_attack": 0.000000,
|
||||
"modEnv_decay": 0.100000,
|
||||
"modEnv_sustain": 0.000000,
|
||||
"modEnv_release": 0.080000,
|
||||
"lfo0_rate": 1.000000,
|
||||
"lfo0_waveform": 0,
|
||||
"lfo0_active": 0,
|
||||
"lfo1_rate": 1.000000,
|
||||
"lfo1_waveform": 0,
|
||||
"lfo1_active": 0,
|
||||
"filter_cutoff": 500.000000,
|
||||
"filter_resonance": 0.300000,
|
||||
"filter_type": 0,
|
||||
"filter_active": 1,
|
||||
"filter_modRouting": 2,
|
||||
"filter_modDepth": 3500.000000,
|
||||
"filter_resModRouting": 0,
|
||||
"filter_resModDepth": 0.000000,
|
||||
"master_volume": 0.800000,
|
||||
"master_pitchBendRange": 1.000000
|
||||
}
|
||||
50
patches/Classic/Flute.json
Normal file
50
patches/Classic/Flute.json
Normal file
@@ -0,0 +1,50 @@
|
||||
{
|
||||
"osc0_waveform": 0,
|
||||
"osc0_dutyCycle": 0.500000,
|
||||
"osc0_detune": 0.000000,
|
||||
"osc0_gain": 3.000000,
|
||||
"osc0_active": 1,
|
||||
"osc0_octave": 0,
|
||||
"osc0_modRouting0": 0,
|
||||
"osc0_modRouting1": 3,
|
||||
"osc0_modRouting2": 0,
|
||||
"osc0_modDepth0": 0.000000,
|
||||
"osc0_modDepth1": 6.000000,
|
||||
"osc0_modDepth2": 0.000000,
|
||||
"osc1_waveform": 5,
|
||||
"osc1_dutyCycle": 0.500000,
|
||||
"osc1_detune": 0.000000,
|
||||
"osc1_gain": 0.233685,
|
||||
"osc1_active": 1,
|
||||
"osc1_octave": 2,
|
||||
"osc1_modRouting0": 0,
|
||||
"osc1_modRouting1": 0,
|
||||
"osc1_modRouting2": 0,
|
||||
"osc1_modDepth0": 0.000000,
|
||||
"osc1_modDepth1": 0.000000,
|
||||
"osc1_modDepth2": 0.000000,
|
||||
"ampEnv_attack": 0.090000,
|
||||
"ampEnv_decay": 0.050000,
|
||||
"ampEnv_sustain": 0.850000,
|
||||
"ampEnv_release": 0.280000,
|
||||
"modEnv_attack": 0.000000,
|
||||
"modEnv_decay": 0.500000,
|
||||
"modEnv_sustain": 0.000000,
|
||||
"modEnv_release": 0.200000,
|
||||
"lfo0_rate": 5.200000,
|
||||
"lfo0_waveform": 0,
|
||||
"lfo0_active": 1,
|
||||
"lfo1_rate": 1.000000,
|
||||
"lfo1_waveform": 0,
|
||||
"lfo1_active": 0,
|
||||
"filter_cutoff": 7000.000000,
|
||||
"filter_resonance": 0.050000,
|
||||
"filter_type": 0,
|
||||
"filter_active": 1,
|
||||
"filter_modRouting": 0,
|
||||
"filter_modDepth": 0.000000,
|
||||
"filter_resModRouting": 0,
|
||||
"filter_resModDepth": 0.000000,
|
||||
"master_volume": 1.000000,
|
||||
"master_pitchBendRange": 2.000000
|
||||
}
|
||||
50
patches/Classic/GlassyBell.json
Normal file
50
patches/Classic/GlassyBell.json
Normal file
@@ -0,0 +1,50 @@
|
||||
{
|
||||
"osc0_waveform": 0,
|
||||
"osc0_dutyCycle": 0.500000,
|
||||
"osc0_detune": 0.000000,
|
||||
"osc0_gain": 3.500000,
|
||||
"osc0_active": 1,
|
||||
"osc0_octave": 0,
|
||||
"osc0_modRouting0": 0,
|
||||
"osc0_modRouting1": 0,
|
||||
"osc0_modRouting2": 0,
|
||||
"osc0_modDepth0": 0.000000,
|
||||
"osc0_modDepth1": 0.000000,
|
||||
"osc0_modDepth2": 0.000000,
|
||||
"osc1_waveform": 0,
|
||||
"osc1_dutyCycle": 0.500000,
|
||||
"osc1_detune": 14.000000,
|
||||
"osc1_gain": 0.500000,
|
||||
"osc1_active": 1,
|
||||
"osc1_octave": 1,
|
||||
"osc1_modRouting0": 0,
|
||||
"osc1_modRouting1": 0,
|
||||
"osc1_modRouting2": 2,
|
||||
"osc1_modDepth0": 0.000000,
|
||||
"osc1_modDepth1": 0.000000,
|
||||
"osc1_modDepth2": 2.800000,
|
||||
"ampEnv_attack": 0.003000,
|
||||
"ampEnv_decay": 3.000000,
|
||||
"ampEnv_sustain": 0.000000,
|
||||
"ampEnv_release": 1.000000,
|
||||
"modEnv_attack": 0.000000,
|
||||
"modEnv_decay": 0.180000,
|
||||
"modEnv_sustain": 0.000000,
|
||||
"modEnv_release": 0.100000,
|
||||
"lfo0_rate": 1.000000,
|
||||
"lfo0_waveform": 0,
|
||||
"lfo0_active": 0,
|
||||
"lfo1_rate": 1.000000,
|
||||
"lfo1_waveform": 0,
|
||||
"lfo1_active": 0,
|
||||
"filter_cutoff": 14000.000000,
|
||||
"filter_resonance": 0.050000,
|
||||
"filter_type": 0,
|
||||
"filter_active": 1,
|
||||
"filter_modRouting": 0,
|
||||
"filter_modDepth": 0.000000,
|
||||
"filter_resModRouting": 0,
|
||||
"filter_resModDepth": 0.000000,
|
||||
"master_volume": 0.700000,
|
||||
"master_pitchBendRange": 0.000000
|
||||
}
|
||||
50
patches/Classic/LushStrings.json
Normal file
50
patches/Classic/LushStrings.json
Normal file
@@ -0,0 +1,50 @@
|
||||
{
|
||||
"osc0_waveform": 4,
|
||||
"osc0_dutyCycle": 0.500000,
|
||||
"osc0_detune": -8.000000,
|
||||
"osc0_gain": 2.500000,
|
||||
"osc0_active": 1,
|
||||
"osc0_octave": 0,
|
||||
"osc0_modRouting0": 3,
|
||||
"osc0_modRouting1": 0,
|
||||
"osc0_modRouting2": 0,
|
||||
"osc0_modDepth0": 0.280000,
|
||||
"osc0_modDepth1": 0.000000,
|
||||
"osc0_modDepth2": 0.000000,
|
||||
"osc1_waveform": 4,
|
||||
"osc1_dutyCycle": 0.500000,
|
||||
"osc1_detune": 8.000000,
|
||||
"osc1_gain": 2.500000,
|
||||
"osc1_active": 1,
|
||||
"osc1_octave": 0,
|
||||
"osc1_modRouting0": 4,
|
||||
"osc1_modRouting1": 0,
|
||||
"osc1_modRouting2": 0,
|
||||
"osc1_modDepth0": 0.280000,
|
||||
"osc1_modDepth1": 0.000000,
|
||||
"osc1_modDepth2": 0.000000,
|
||||
"ampEnv_attack": 0.420000,
|
||||
"ampEnv_decay": 0.100000,
|
||||
"ampEnv_sustain": 0.880000,
|
||||
"ampEnv_release": 1.300000,
|
||||
"modEnv_attack": 0.000000,
|
||||
"modEnv_decay": 0.500000,
|
||||
"modEnv_sustain": 0.000000,
|
||||
"modEnv_release": 0.400000,
|
||||
"lfo0_rate": 0.290000,
|
||||
"lfo0_waveform": 0,
|
||||
"lfo0_active": 1,
|
||||
"lfo1_rate": 0.370000,
|
||||
"lfo1_waveform": 0,
|
||||
"lfo1_active": 1,
|
||||
"filter_cutoff": 4200.000000,
|
||||
"filter_resonance": 0.080000,
|
||||
"filter_type": 0,
|
||||
"filter_active": 1,
|
||||
"filter_modRouting": 1,
|
||||
"filter_modDepth": 2800.000000,
|
||||
"filter_resModRouting": 0,
|
||||
"filter_resModDepth": 0.000000,
|
||||
"master_volume": 0.720000,
|
||||
"master_pitchBendRange": 2.000000
|
||||
}
|
||||
50
patches/Classic/Oboe.json
Normal file
50
patches/Classic/Oboe.json
Normal file
@@ -0,0 +1,50 @@
|
||||
{
|
||||
"osc0_waveform": 4,
|
||||
"osc0_dutyCycle": 0.250000,
|
||||
"osc0_detune": 0.000000,
|
||||
"osc0_gain": 3.000000,
|
||||
"osc0_active": 1,
|
||||
"osc0_octave": 0,
|
||||
"osc0_modRouting0": 0,
|
||||
"osc0_modRouting1": 3,
|
||||
"osc0_modRouting2": 0,
|
||||
"osc0_modDepth0": 0.000000,
|
||||
"osc0_modDepth1": 5.000000,
|
||||
"osc0_modDepth2": 0.000000,
|
||||
"osc1_waveform": 4,
|
||||
"osc1_dutyCycle": 0.200000,
|
||||
"osc1_detune": 2.000000,
|
||||
"osc1_gain": 2.000000,
|
||||
"osc1_active": 1,
|
||||
"osc1_octave": 0,
|
||||
"osc1_modRouting0": 0,
|
||||
"osc1_modRouting1": 0,
|
||||
"osc1_modRouting2": 0,
|
||||
"osc1_modDepth0": 0.000000,
|
||||
"osc1_modDepth1": 0.000000,
|
||||
"osc1_modDepth2": 0.000000,
|
||||
"ampEnv_attack": 0.055000,
|
||||
"ampEnv_decay": 0.030000,
|
||||
"ampEnv_sustain": 0.920000,
|
||||
"ampEnv_release": 0.150000,
|
||||
"modEnv_attack": 0.000000,
|
||||
"modEnv_decay": 0.500000,
|
||||
"modEnv_sustain": 0.000000,
|
||||
"modEnv_release": 0.200000,
|
||||
"lfo0_rate": 5.000000,
|
||||
"lfo0_waveform": 0,
|
||||
"lfo0_active": 1,
|
||||
"lfo1_rate": 1.000000,
|
||||
"lfo1_waveform": 0,
|
||||
"lfo1_active": 0,
|
||||
"filter_cutoff": 2500.000000,
|
||||
"filter_resonance": 0.400000,
|
||||
"filter_type": 0,
|
||||
"filter_active": 1,
|
||||
"filter_modRouting": 0,
|
||||
"filter_modDepth": 0.000000,
|
||||
"filter_resModRouting": 0,
|
||||
"filter_resModDepth": 0.000000,
|
||||
"master_volume": 0.700000,
|
||||
"master_pitchBendRange": 2.000000
|
||||
}
|
||||
50
patches/Classic/PanFlute.json
Normal file
50
patches/Classic/PanFlute.json
Normal file
@@ -0,0 +1,50 @@
|
||||
{
|
||||
"osc0_waveform": 0,
|
||||
"osc0_dutyCycle": 0.500000,
|
||||
"osc0_detune": 0.000000,
|
||||
"osc0_gain": 0.600000,
|
||||
"osc0_active": 1,
|
||||
"osc0_octave": 0,
|
||||
"osc0_modRouting0": 0,
|
||||
"osc0_modRouting1": 3,
|
||||
"osc0_modRouting2": 0,
|
||||
"osc0_modDepth0": 0.000000,
|
||||
"osc0_modDepth1": 8.000000,
|
||||
"osc0_modDepth2": 0.000000,
|
||||
"osc1_waveform": 5,
|
||||
"osc1_dutyCycle": 0.500000,
|
||||
"osc1_detune": 0.000000,
|
||||
"osc1_gain": 0.060000,
|
||||
"osc1_active": 1,
|
||||
"osc1_octave": 0,
|
||||
"osc1_modRouting0": 0,
|
||||
"osc1_modRouting1": 0,
|
||||
"osc1_modRouting2": 2,
|
||||
"osc1_modDepth0": 0.000000,
|
||||
"osc1_modDepth1": 0.000000,
|
||||
"osc1_modDepth2": 0.150000,
|
||||
"ampEnv_attack": 0.040000,
|
||||
"ampEnv_decay": 0.080000,
|
||||
"ampEnv_sustain": 0.850000,
|
||||
"ampEnv_release": 0.220000,
|
||||
"modEnv_attack": 0.010000,
|
||||
"modEnv_decay": 0.280000,
|
||||
"modEnv_sustain": 0.000000,
|
||||
"modEnv_release": 0.060000,
|
||||
"lfo0_rate": 5.500000,
|
||||
"lfo0_waveform": 0,
|
||||
"lfo0_active": 1,
|
||||
"lfo1_rate": 2.000000,
|
||||
"lfo1_waveform": 0,
|
||||
"lfo1_active": 0,
|
||||
"filter_cutoff": 2200.000000,
|
||||
"filter_resonance": 0.050000,
|
||||
"filter_type": 0,
|
||||
"filter_active": 1,
|
||||
"filter_modRouting": 2,
|
||||
"filter_modDepth": 1800.000000,
|
||||
"filter_resModRouting": 0,
|
||||
"filter_resModDepth": 0.000000,
|
||||
"master_volume": 0.650000,
|
||||
"master_pitchBendRange": 2.000000
|
||||
}
|
||||
50
patches/Classic/Piano.json
Normal file
50
patches/Classic/Piano.json
Normal file
@@ -0,0 +1,50 @@
|
||||
{
|
||||
"osc0_waveform": 1,
|
||||
"osc0_dutyCycle": 0.500000,
|
||||
"osc0_detune": 0.000000,
|
||||
"osc0_gain": 3.500000,
|
||||
"osc0_active": 1,
|
||||
"osc0_octave": 0,
|
||||
"osc0_modRouting0": 0,
|
||||
"osc0_modRouting1": 0,
|
||||
"osc0_modRouting2": 0,
|
||||
"osc0_modDepth0": 0.000000,
|
||||
"osc0_modDepth1": 0.000000,
|
||||
"osc0_modDepth2": 0.000000,
|
||||
"osc1_waveform": 1,
|
||||
"osc1_dutyCycle": 0.500000,
|
||||
"osc1_detune": 7.000000,
|
||||
"osc1_gain": 1.000000,
|
||||
"osc1_active": 1,
|
||||
"osc1_octave": 1,
|
||||
"osc1_modRouting0": 0,
|
||||
"osc1_modRouting1": 0,
|
||||
"osc1_modRouting2": 2,
|
||||
"osc1_modDepth0": 0.000000,
|
||||
"osc1_modDepth1": 0.000000,
|
||||
"osc1_modDepth2": 2.000000,
|
||||
"ampEnv_attack": 0.003000,
|
||||
"ampEnv_decay": 2.000000,
|
||||
"ampEnv_sustain": 0.000000,
|
||||
"ampEnv_release": 0.600000,
|
||||
"modEnv_attack": 0.000000,
|
||||
"modEnv_decay": 0.120000,
|
||||
"modEnv_sustain": 0.000000,
|
||||
"modEnv_release": 0.060000,
|
||||
"lfo0_rate": 1.000000,
|
||||
"lfo0_waveform": 0,
|
||||
"lfo0_active": 0,
|
||||
"lfo1_rate": 1.000000,
|
||||
"lfo1_waveform": 0,
|
||||
"lfo1_active": 0,
|
||||
"filter_cutoff": 8000.000000,
|
||||
"filter_resonance": 0.050000,
|
||||
"filter_type": 0,
|
||||
"filter_active": 1,
|
||||
"filter_modRouting": 2,
|
||||
"filter_modDepth": 4000.000000,
|
||||
"filter_resModRouting": 0,
|
||||
"filter_resModDepth": 0.000000,
|
||||
"master_volume": 0.750000,
|
||||
"master_pitchBendRange": 1.000000
|
||||
}
|
||||
50
patches/Classic/PipeOrgan.json
Normal file
50
patches/Classic/PipeOrgan.json
Normal file
@@ -0,0 +1,50 @@
|
||||
{
|
||||
"osc0_waveform": 0,
|
||||
"osc0_dutyCycle": 0.500000,
|
||||
"osc0_detune": 0.000000,
|
||||
"osc0_gain": 4.000000,
|
||||
"osc0_active": 1,
|
||||
"osc0_octave": 0,
|
||||
"osc0_modRouting0": 0,
|
||||
"osc0_modRouting1": 0,
|
||||
"osc0_modRouting2": 0,
|
||||
"osc0_modDepth0": 0.000000,
|
||||
"osc0_modDepth1": 0.000000,
|
||||
"osc0_modDepth2": 0.000000,
|
||||
"osc1_waveform": 5,
|
||||
"osc1_dutyCycle": 0.500000,
|
||||
"osc1_detune": 0.000000,
|
||||
"osc1_gain": 0.000000,
|
||||
"osc1_active": 1,
|
||||
"osc1_octave": 0,
|
||||
"osc1_modRouting0": 0,
|
||||
"osc1_modRouting1": 0,
|
||||
"osc1_modRouting2": 2,
|
||||
"osc1_modDepth0": 0.000000,
|
||||
"osc1_modDepth1": 0.000000,
|
||||
"osc1_modDepth2": 2.500000,
|
||||
"ampEnv_attack": 0.012000,
|
||||
"ampEnv_decay": 0.050000,
|
||||
"ampEnv_sustain": 0.920000,
|
||||
"ampEnv_release": 0.120000,
|
||||
"modEnv_attack": 0.001000,
|
||||
"modEnv_decay": 0.055000,
|
||||
"modEnv_sustain": 0.000000,
|
||||
"modEnv_release": 0.025000,
|
||||
"lfo0_rate": 1.000000,
|
||||
"lfo0_waveform": 0,
|
||||
"lfo0_active": 0,
|
||||
"lfo1_rate": 1.000000,
|
||||
"lfo1_waveform": 0,
|
||||
"lfo1_active": 0,
|
||||
"filter_cutoff": 4500.000000,
|
||||
"filter_resonance": 0.050000,
|
||||
"filter_type": 0,
|
||||
"filter_active": 1,
|
||||
"filter_modRouting": 0,
|
||||
"filter_modDepth": 0.000000,
|
||||
"filter_resModRouting": 0,
|
||||
"filter_resModDepth": 0.000000,
|
||||
"master_volume": 0.750000,
|
||||
"master_pitchBendRange": 1.000000
|
||||
}
|
||||
50
patches/Classic/Rhodes.json
Normal file
50
patches/Classic/Rhodes.json
Normal file
@@ -0,0 +1,50 @@
|
||||
{
|
||||
"osc0_waveform": 0,
|
||||
"osc0_dutyCycle": 0.500000,
|
||||
"osc0_detune": 0.000000,
|
||||
"osc0_gain": 3.500000,
|
||||
"osc0_active": 1,
|
||||
"osc0_octave": 0,
|
||||
"osc0_modRouting0": 0,
|
||||
"osc0_modRouting1": 0,
|
||||
"osc0_modRouting2": 0,
|
||||
"osc0_modDepth0": 0.000000,
|
||||
"osc0_modDepth1": 0.000000,
|
||||
"osc0_modDepth2": 0.000000,
|
||||
"osc1_waveform": 0,
|
||||
"osc1_dutyCycle": 0.500000,
|
||||
"osc1_detune": 7.000000,
|
||||
"osc1_gain": 0.400000,
|
||||
"osc1_active": 1,
|
||||
"osc1_octave": 1,
|
||||
"osc1_modRouting0": 0,
|
||||
"osc1_modRouting1": 0,
|
||||
"osc1_modRouting2": 2,
|
||||
"osc1_modDepth0": 0.000000,
|
||||
"osc1_modDepth1": 0.000000,
|
||||
"osc1_modDepth2": 2.200000,
|
||||
"ampEnv_attack": 0.002000,
|
||||
"ampEnv_decay": 1.800000,
|
||||
"ampEnv_sustain": 0.000000,
|
||||
"ampEnv_release": 0.500000,
|
||||
"modEnv_attack": 0.001000,
|
||||
"modEnv_decay": 0.100000,
|
||||
"modEnv_sustain": 0.000000,
|
||||
"modEnv_release": 0.050000,
|
||||
"lfo0_rate": 1.000000,
|
||||
"lfo0_waveform": 0,
|
||||
"lfo0_active": 0,
|
||||
"lfo1_rate": 1.000000,
|
||||
"lfo1_waveform": 0,
|
||||
"lfo1_active": 0,
|
||||
"filter_cutoff": 3500.000000,
|
||||
"filter_resonance": 0.100000,
|
||||
"filter_type": 0,
|
||||
"filter_active": 1,
|
||||
"filter_modRouting": 2,
|
||||
"filter_modDepth": 4000.000000,
|
||||
"filter_resModRouting": 0,
|
||||
"filter_resModDepth": 0.000000,
|
||||
"master_volume": 0.750000,
|
||||
"master_pitchBendRange": 2.000000
|
||||
}
|
||||
50
patches/Classic/WarmPad.json
Normal file
50
patches/Classic/WarmPad.json
Normal file
@@ -0,0 +1,50 @@
|
||||
{
|
||||
"osc0_waveform": 2,
|
||||
"osc0_dutyCycle": 0.500000,
|
||||
"osc0_detune": -5.000000,
|
||||
"osc0_gain": 2.500000,
|
||||
"osc0_active": 1,
|
||||
"osc0_octave": 0,
|
||||
"osc0_modRouting0": 0,
|
||||
"osc0_modRouting1": 3,
|
||||
"osc0_modRouting2": 0,
|
||||
"osc0_modDepth0": 0.000000,
|
||||
"osc0_modDepth1": 8.000000,
|
||||
"osc0_modDepth2": 0.000000,
|
||||
"osc1_waveform": 1,
|
||||
"osc1_dutyCycle": 0.500000,
|
||||
"osc1_detune": 5.000000,
|
||||
"osc1_gain": 2.000000,
|
||||
"osc1_active": 1,
|
||||
"osc1_octave": 0,
|
||||
"osc1_modRouting0": 0,
|
||||
"osc1_modRouting1": 0,
|
||||
"osc1_modRouting2": 0,
|
||||
"osc1_modDepth0": 0.000000,
|
||||
"osc1_modDepth1": 0.000000,
|
||||
"osc1_modDepth2": 0.000000,
|
||||
"ampEnv_attack": 0.700000,
|
||||
"ampEnv_decay": 0.300000,
|
||||
"ampEnv_sustain": 0.750000,
|
||||
"ampEnv_release": 1.200000,
|
||||
"modEnv_attack": 0.001000,
|
||||
"modEnv_decay": 0.500000,
|
||||
"modEnv_sustain": 0.000000,
|
||||
"modEnv_release": 0.200000,
|
||||
"lfo0_rate": 0.450000,
|
||||
"lfo0_waveform": 0,
|
||||
"lfo0_active": 1,
|
||||
"lfo1_rate": 1.000000,
|
||||
"lfo1_waveform": 0,
|
||||
"lfo1_active": 0,
|
||||
"filter_cutoff": 1000.000000,
|
||||
"filter_resonance": 0.100000,
|
||||
"filter_type": 0,
|
||||
"filter_active": 1,
|
||||
"filter_modRouting": 1,
|
||||
"filter_modDepth": 2500.000000,
|
||||
"filter_resModRouting": 0,
|
||||
"filter_resModDepth": 0.000000,
|
||||
"master_volume": 0.700000,
|
||||
"master_pitchBendRange": 2.000000
|
||||
}
|
||||
50
patches/Jake Patches/Shlabadome.json
Normal file
50
patches/Jake Patches/Shlabadome.json
Normal file
@@ -0,0 +1,50 @@
|
||||
{
|
||||
"osc0_waveform": 4,
|
||||
"osc0_dutyCycle": 0.500000,
|
||||
"osc0_detune": 0.000000,
|
||||
"osc0_gain": 4.000000,
|
||||
"osc0_active": 1,
|
||||
"osc0_octave": 0,
|
||||
"osc0_modRouting0": 0,
|
||||
"osc0_modRouting1": 0,
|
||||
"osc0_modRouting2": 0,
|
||||
"osc0_modDepth0": 0.000000,
|
||||
"osc0_modDepth1": 0.000000,
|
||||
"osc0_modDepth2": 0.000000,
|
||||
"osc1_waveform": 4,
|
||||
"osc1_dutyCycle": 0.500000,
|
||||
"osc1_detune": 0.000000,
|
||||
"osc1_gain": 4.000000,
|
||||
"osc1_active": 1,
|
||||
"osc1_octave": 0,
|
||||
"osc1_modRouting0": 0,
|
||||
"osc1_modRouting1": 4,
|
||||
"osc1_modRouting2": 0,
|
||||
"osc1_modDepth0": 0.000000,
|
||||
"osc1_modDepth1": -9.448853,
|
||||
"osc1_modDepth2": 0.000000,
|
||||
"ampEnv_attack": 0.079701,
|
||||
"ampEnv_decay": 0.913929,
|
||||
"ampEnv_sustain": 0.700000,
|
||||
"ampEnv_release": 0.567646,
|
||||
"modEnv_attack": 0.005000,
|
||||
"modEnv_decay": 0.500000,
|
||||
"modEnv_sustain": 0.244094,
|
||||
"modEnv_release": 0.488945,
|
||||
"lfo0_rate": 1.000000,
|
||||
"lfo0_waveform": 0,
|
||||
"lfo0_active": 1,
|
||||
"lfo1_rate": 2.528425,
|
||||
"lfo1_waveform": 0,
|
||||
"lfo1_active": 1,
|
||||
"filter_cutoff": 2851.811279,
|
||||
"filter_resonance": 0.226063,
|
||||
"filter_type": 0,
|
||||
"filter_active": 1,
|
||||
"filter_modRouting": 1,
|
||||
"filter_modDepth": 0.000000,
|
||||
"filter_resModRouting": 0,
|
||||
"filter_resModDepth": 0.000000,
|
||||
"master_volume": 0.291339,
|
||||
"master_pitchBendRange": 2.000000
|
||||
}
|
||||
50
patches/Jake Patches/SquareBad.json
Normal file
50
patches/Jake Patches/SquareBad.json
Normal file
@@ -0,0 +1,50 @@
|
||||
{
|
||||
"osc0_waveform": 4,
|
||||
"osc0_dutyCycle": 0.500000,
|
||||
"osc0_detune": -3.345787,
|
||||
"osc0_gain": 4.000000,
|
||||
"osc0_active": 1,
|
||||
"osc0_octave": 0,
|
||||
"osc0_modRouting0": 2,
|
||||
"osc0_modRouting1": 1,
|
||||
"osc0_modRouting2": 0,
|
||||
"osc0_modDepth0": 0.114713,
|
||||
"osc0_modDepth1": 11.471191,
|
||||
"osc0_modDepth2": -2.256021,
|
||||
"osc1_waveform": 4,
|
||||
"osc1_dutyCycle": 0.500000,
|
||||
"osc1_detune": 0.000000,
|
||||
"osc1_gain": 4.000000,
|
||||
"osc1_active": 1,
|
||||
"osc1_octave": 0,
|
||||
"osc1_modRouting0": 2,
|
||||
"osc1_modRouting1": 3,
|
||||
"osc1_modRouting2": 0,
|
||||
"osc1_modDepth0": -0.095594,
|
||||
"osc1_modDepth1": 17.206787,
|
||||
"osc1_modDepth2": -1.472151,
|
||||
"ampEnv_attack": 0.169107,
|
||||
"ampEnv_decay": 0.679732,
|
||||
"ampEnv_sustain": 1.000000,
|
||||
"ampEnv_release": 0.601745,
|
||||
"modEnv_attack": 0.179308,
|
||||
"modEnv_decay": 0.500000,
|
||||
"modEnv_sustain": 0.000000,
|
||||
"modEnv_release": 0.158102,
|
||||
"lfo0_rate": 1.668824,
|
||||
"lfo0_waveform": 1,
|
||||
"lfo0_active": 1,
|
||||
"lfo1_rate": 0.010000,
|
||||
"lfo1_waveform": 1,
|
||||
"lfo1_active": 1,
|
||||
"filter_cutoff": 20.000000,
|
||||
"filter_resonance": 0.000000,
|
||||
"filter_type": 0,
|
||||
"filter_active": 1,
|
||||
"filter_modRouting": 2,
|
||||
"filter_modDepth": 7551.934570,
|
||||
"filter_resModRouting": 0,
|
||||
"filter_resModDepth": 0.000000,
|
||||
"master_volume": 0.906796,
|
||||
"master_pitchBendRange": 2.000000
|
||||
}
|
||||
50
patches/Jake Patches/Squibbable.json
Normal file
50
patches/Jake Patches/Squibbable.json
Normal file
@@ -0,0 +1,50 @@
|
||||
{
|
||||
"osc0_waveform": 4,
|
||||
"osc0_dutyCycle": 0.500000,
|
||||
"osc0_detune": 0.000000,
|
||||
"osc0_gain": 4.000000,
|
||||
"osc0_active": 1,
|
||||
"osc0_octave": 0,
|
||||
"osc0_modRouting0": 0,
|
||||
"osc0_modRouting1": 0,
|
||||
"osc0_modRouting2": 0,
|
||||
"osc0_modDepth0": 0.000000,
|
||||
"osc0_modDepth1": 0.000000,
|
||||
"osc0_modDepth2": 0.000000,
|
||||
"osc1_waveform": 4,
|
||||
"osc1_dutyCycle": 0.384412,
|
||||
"osc1_detune": -1.938599,
|
||||
"osc1_gain": 4.000000,
|
||||
"osc1_active": 1,
|
||||
"osc1_octave": 0,
|
||||
"osc1_modRouting0": 3,
|
||||
"osc1_modRouting1": 4,
|
||||
"osc1_modRouting2": 0,
|
||||
"osc1_modDepth0": 0.382870,
|
||||
"osc1_modDepth1": -47.244019,
|
||||
"osc1_modDepth2": 0.000000,
|
||||
"ampEnv_attack": 0.095441,
|
||||
"ampEnv_decay": 0.929669,
|
||||
"ampEnv_sustain": 0.000000,
|
||||
"ampEnv_release": 0.536165,
|
||||
"modEnv_attack": 0.001000,
|
||||
"modEnv_decay": 0.221362,
|
||||
"modEnv_sustain": 0.251969,
|
||||
"modEnv_release": 0.473205,
|
||||
"lfo0_rate": 1.000000,
|
||||
"lfo0_waveform": 0,
|
||||
"lfo0_active": 1,
|
||||
"lfo1_rate": 2.843228,
|
||||
"lfo1_waveform": 0,
|
||||
"lfo1_active": 1,
|
||||
"filter_cutoff": 2537.165283,
|
||||
"filter_resonance": 0.233858,
|
||||
"filter_type": 0,
|
||||
"filter_active": 1,
|
||||
"filter_modRouting": 2,
|
||||
"filter_modDepth": -6688.119629,
|
||||
"filter_resModRouting": 0,
|
||||
"filter_resModDepth": 0.000000,
|
||||
"master_volume": 0.307087,
|
||||
"master_pitchBendRange": 2.000000
|
||||
}
|
||||
50
patches/Jake Patches/WobblyDoo.json
Normal file
50
patches/Jake Patches/WobblyDoo.json
Normal file
@@ -0,0 +1,50 @@
|
||||
{
|
||||
"osc0_waveform": 2,
|
||||
"osc0_dutyCycle": 0.500000,
|
||||
"osc0_detune": -3.345787,
|
||||
"osc0_gain": 4.000000,
|
||||
"osc0_active": 1,
|
||||
"osc0_octave": 0,
|
||||
"osc0_modRouting0": 0,
|
||||
"osc0_modRouting1": 1,
|
||||
"osc0_modRouting2": 4,
|
||||
"osc0_modDepth0": 0.000000,
|
||||
"osc0_modDepth1": 11.471191,
|
||||
"osc0_modDepth2": -2.256021,
|
||||
"osc1_waveform": 2,
|
||||
"osc1_dutyCycle": 0.500000,
|
||||
"osc1_detune": 0.000000,
|
||||
"osc1_gain": 4.000000,
|
||||
"osc1_active": 1,
|
||||
"osc1_octave": 0,
|
||||
"osc1_modRouting0": 0,
|
||||
"osc1_modRouting1": 3,
|
||||
"osc1_modRouting2": 4,
|
||||
"osc1_modDepth0": 0.000000,
|
||||
"osc1_modDepth1": 17.206787,
|
||||
"osc1_modDepth2": -1.472151,
|
||||
"ampEnv_attack": 0.050191,
|
||||
"ampEnv_decay": 0.810141,
|
||||
"ampEnv_sustain": 0.000000,
|
||||
"ampEnv_release": 0.500000,
|
||||
"modEnv_attack": 0.005000,
|
||||
"modEnv_decay": 0.500000,
|
||||
"modEnv_sustain": 0.000000,
|
||||
"modEnv_release": 0.100000,
|
||||
"lfo0_rate": 1.668824,
|
||||
"lfo0_waveform": 1,
|
||||
"lfo0_active": 1,
|
||||
"lfo1_rate": 3.102018,
|
||||
"lfo1_waveform": 1,
|
||||
"lfo1_active": 1,
|
||||
"filter_cutoff": 2789.458252,
|
||||
"filter_resonance": 0.274451,
|
||||
"filter_type": 0,
|
||||
"filter_active": 1,
|
||||
"filter_modRouting": 0,
|
||||
"filter_modDepth": -286.782837,
|
||||
"filter_resModRouting": 0,
|
||||
"filter_resModDepth": 0.000000,
|
||||
"master_volume": 1.000000,
|
||||
"master_pitchBendRange": 2.000000
|
||||
}
|
||||
50
patches/Keys/ClassicLead.json
Normal file
50
patches/Keys/ClassicLead.json
Normal file
@@ -0,0 +1,50 @@
|
||||
{
|
||||
"osc0_waveform": 2,
|
||||
"osc0_dutyCycle": 0.500000,
|
||||
"osc0_detune": 0.000000,
|
||||
"osc0_gain": 3.000000,
|
||||
"osc0_active": 1,
|
||||
"osc0_octave": 0,
|
||||
"osc0_modRouting0": 0,
|
||||
"osc0_modRouting1": 0,
|
||||
"osc0_modRouting2": 0,
|
||||
"osc0_modDepth0": 0.000000,
|
||||
"osc0_modDepth1": 0.000000,
|
||||
"osc0_modDepth2": 0.000000,
|
||||
"osc1_waveform": 2,
|
||||
"osc1_dutyCycle": 0.500000,
|
||||
"osc1_detune": 4.000000,
|
||||
"osc1_gain": 2.000000,
|
||||
"osc1_active": 1,
|
||||
"osc1_octave": 0,
|
||||
"osc1_modRouting0": 0,
|
||||
"osc1_modRouting1": 0,
|
||||
"osc1_modRouting2": 0,
|
||||
"osc1_modDepth0": 0.000000,
|
||||
"osc1_modDepth1": 0.000000,
|
||||
"osc1_modDepth2": 0.000000,
|
||||
"ampEnv_attack": 0.008000,
|
||||
"ampEnv_decay": 0.150000,
|
||||
"ampEnv_sustain": 0.720000,
|
||||
"ampEnv_release": 0.200000,
|
||||
"modEnv_attack": 0.000000,
|
||||
"modEnv_decay": 0.300000,
|
||||
"modEnv_sustain": 0.000000,
|
||||
"modEnv_release": 0.150000,
|
||||
"lfo0_rate": 5.500000,
|
||||
"lfo0_waveform": 0,
|
||||
"lfo0_active": 0,
|
||||
"lfo1_rate": 1.000000,
|
||||
"lfo1_waveform": 0,
|
||||
"lfo1_active": 0,
|
||||
"filter_cutoff": 2200.000000,
|
||||
"filter_resonance": 0.500000,
|
||||
"filter_type": 0,
|
||||
"filter_active": 1,
|
||||
"filter_modRouting": 2,
|
||||
"filter_modDepth": 6000.000000,
|
||||
"filter_resModRouting": 0,
|
||||
"filter_resModDepth": 0.000000,
|
||||
"master_volume": 0.750000,
|
||||
"master_pitchBendRange": 2.000000
|
||||
}
|
||||
50
patches/Keys/Clavichord.json
Normal file
50
patches/Keys/Clavichord.json
Normal file
@@ -0,0 +1,50 @@
|
||||
{
|
||||
"osc0_waveform": 1,
|
||||
"osc0_dutyCycle": 0.500000,
|
||||
"osc0_detune": 0.000000,
|
||||
"osc0_gain": 2.500000,
|
||||
"osc0_active": 1,
|
||||
"osc0_octave": 0,
|
||||
"osc0_modRouting0": 0,
|
||||
"osc0_modRouting1": 0,
|
||||
"osc0_modRouting2": 0,
|
||||
"osc0_modDepth0": 0.000000,
|
||||
"osc0_modDepth1": 0.000000,
|
||||
"osc0_modDepth2": 0.000000,
|
||||
"osc1_waveform": 0,
|
||||
"osc1_dutyCycle": 0.500000,
|
||||
"osc1_detune": 0.000000,
|
||||
"osc1_gain": 0.300000,
|
||||
"osc1_active": 1,
|
||||
"osc1_octave": 2,
|
||||
"osc1_modRouting0": 0,
|
||||
"osc1_modRouting1": 0,
|
||||
"osc1_modRouting2": 2,
|
||||
"osc1_modDepth0": 0.000000,
|
||||
"osc1_modDepth1": 0.000000,
|
||||
"osc1_modDepth2": 2.000000,
|
||||
"ampEnv_attack": 0.003000,
|
||||
"ampEnv_decay": 0.080000,
|
||||
"ampEnv_sustain": 0.800000,
|
||||
"ampEnv_release": 0.250000,
|
||||
"modEnv_attack": 0.000000,
|
||||
"modEnv_decay": 0.090000,
|
||||
"modEnv_sustain": 0.000000,
|
||||
"modEnv_release": 0.050000,
|
||||
"lfo0_rate": 1.000000,
|
||||
"lfo0_waveform": 0,
|
||||
"lfo0_active": 0,
|
||||
"lfo1_rate": 1.000000,
|
||||
"lfo1_waveform": 0,
|
||||
"lfo1_active": 0,
|
||||
"filter_cutoff": 5000.000000,
|
||||
"filter_resonance": 0.150000,
|
||||
"filter_type": 0,
|
||||
"filter_active": 1,
|
||||
"filter_modRouting": 2,
|
||||
"filter_modDepth": 4500.000000,
|
||||
"filter_resModRouting": 0,
|
||||
"filter_resModDepth": 0.000000,
|
||||
"master_volume": 0.650000,
|
||||
"master_pitchBendRange": 1.000000
|
||||
}
|
||||
50
patches/Keys/Farfisa.json
Normal file
50
patches/Keys/Farfisa.json
Normal file
@@ -0,0 +1,50 @@
|
||||
{
|
||||
"osc0_waveform": 4,
|
||||
"osc0_dutyCycle": 0.250000,
|
||||
"osc0_detune": 0.000000,
|
||||
"osc0_gain": 4.000000,
|
||||
"osc0_active": 1,
|
||||
"osc0_octave": 0,
|
||||
"osc0_modRouting0": 0,
|
||||
"osc0_modRouting1": 0,
|
||||
"osc0_modRouting2": 0,
|
||||
"osc0_modDepth0": 0.000000,
|
||||
"osc0_modDepth1": 0.000000,
|
||||
"osc0_modDepth2": 0.000000,
|
||||
"osc1_waveform": 4,
|
||||
"osc1_dutyCycle": 0.250000,
|
||||
"osc1_detune": 0.000000,
|
||||
"osc1_gain": 1.800000,
|
||||
"osc1_active": 1,
|
||||
"osc1_octave": 1,
|
||||
"osc1_modRouting0": 0,
|
||||
"osc1_modRouting1": 0,
|
||||
"osc1_modRouting2": 0,
|
||||
"osc1_modDepth0": 0.000000,
|
||||
"osc1_modDepth1": 0.000000,
|
||||
"osc1_modDepth2": 0.000000,
|
||||
"ampEnv_attack": 0.001000,
|
||||
"ampEnv_decay": 0.001000,
|
||||
"ampEnv_sustain": 1.000000,
|
||||
"ampEnv_release": 0.015000,
|
||||
"modEnv_attack": 0.001000,
|
||||
"modEnv_decay": 0.500000,
|
||||
"modEnv_sustain": 0.000000,
|
||||
"modEnv_release": 0.200000,
|
||||
"lfo0_rate": 1.000000,
|
||||
"lfo0_waveform": 0,
|
||||
"lfo0_active": 0,
|
||||
"lfo1_rate": 1.000000,
|
||||
"lfo1_waveform": 0,
|
||||
"lfo1_active": 0,
|
||||
"filter_cutoff": 6000.000000,
|
||||
"filter_resonance": 0.100000,
|
||||
"filter_type": 0,
|
||||
"filter_active": 1,
|
||||
"filter_modRouting": 0,
|
||||
"filter_modDepth": 0.000000,
|
||||
"filter_resModRouting": 0,
|
||||
"filter_resModDepth": 0.000000,
|
||||
"master_volume": 0.720000,
|
||||
"master_pitchBendRange": 2.000000
|
||||
}
|
||||
50
patches/Keys/Hammond.json
Normal file
50
patches/Keys/Hammond.json
Normal file
@@ -0,0 +1,50 @@
|
||||
{
|
||||
"osc0_waveform": 4,
|
||||
"osc0_dutyCycle": 0.500000,
|
||||
"osc0_detune": 0.000000,
|
||||
"osc0_gain": 3.500000,
|
||||
"osc0_active": 1,
|
||||
"osc0_octave": 0,
|
||||
"osc0_modRouting0": 0,
|
||||
"osc0_modRouting1": 3,
|
||||
"osc0_modRouting2": 4,
|
||||
"osc0_modDepth0": 0.000000,
|
||||
"osc0_modDepth1": 8.000000,
|
||||
"osc0_modDepth2": 0.700000,
|
||||
"osc1_waveform": 4,
|
||||
"osc1_dutyCycle": 0.500000,
|
||||
"osc1_detune": 0.000000,
|
||||
"osc1_gain": 2.000000,
|
||||
"osc1_active": 1,
|
||||
"osc1_octave": 1,
|
||||
"osc1_modRouting0": 0,
|
||||
"osc1_modRouting1": 3,
|
||||
"osc1_modRouting2": 4,
|
||||
"osc1_modDepth0": 0.000000,
|
||||
"osc1_modDepth1": 8.000000,
|
||||
"osc1_modDepth2": 0.500000,
|
||||
"ampEnv_attack": 0.001000,
|
||||
"ampEnv_decay": 0.001000,
|
||||
"ampEnv_sustain": 1.000000,
|
||||
"ampEnv_release": 0.020000,
|
||||
"modEnv_attack": 0.001000,
|
||||
"modEnv_decay": 0.500000,
|
||||
"modEnv_sustain": 0.000000,
|
||||
"modEnv_release": 0.200000,
|
||||
"lfo0_rate": 5.500000,
|
||||
"lfo0_waveform": 0,
|
||||
"lfo0_active": 1,
|
||||
"lfo1_rate": 5.500000,
|
||||
"lfo1_waveform": 1,
|
||||
"lfo1_active": 1,
|
||||
"filter_cutoff": 8000.000000,
|
||||
"filter_resonance": 0.050000,
|
||||
"filter_type": 0,
|
||||
"filter_active": 1,
|
||||
"filter_modRouting": 0,
|
||||
"filter_modDepth": 0.000000,
|
||||
"filter_resModRouting": 0,
|
||||
"filter_resModDepth": 0.000000,
|
||||
"master_volume": 0.700000,
|
||||
"master_pitchBendRange": 2.000000
|
||||
}
|
||||
50
patches/Keys/Harpsichord.json
Normal file
50
patches/Keys/Harpsichord.json
Normal file
@@ -0,0 +1,50 @@
|
||||
{
|
||||
"osc0_waveform": 4,
|
||||
"osc0_dutyCycle": 0.700000,
|
||||
"osc0_detune": 0.000000,
|
||||
"osc0_gain": 3.500000,
|
||||
"osc0_active": 1,
|
||||
"osc0_octave": 0,
|
||||
"osc0_modRouting0": 0,
|
||||
"osc0_modRouting1": 0,
|
||||
"osc0_modRouting2": 0,
|
||||
"osc0_modDepth0": 0.000000,
|
||||
"osc0_modDepth1": 0.000000,
|
||||
"osc0_modDepth2": 0.000000,
|
||||
"osc1_waveform": 4,
|
||||
"osc1_dutyCycle": 0.700000,
|
||||
"osc1_detune": 3.000000,
|
||||
"osc1_gain": 1.500000,
|
||||
"osc1_active": 1,
|
||||
"osc1_octave": 1,
|
||||
"osc1_modRouting0": 0,
|
||||
"osc1_modRouting1": 0,
|
||||
"osc1_modRouting2": 2,
|
||||
"osc1_modDepth0": 0.000000,
|
||||
"osc1_modDepth1": 0.000000,
|
||||
"osc1_modDepth2": 1.000000,
|
||||
"ampEnv_attack": 0.001000,
|
||||
"ampEnv_decay": 0.700000,
|
||||
"ampEnv_sustain": 0.000000,
|
||||
"ampEnv_release": 0.060000,
|
||||
"modEnv_attack": 0.000000,
|
||||
"modEnv_decay": 0.060000,
|
||||
"modEnv_sustain": 0.000000,
|
||||
"modEnv_release": 0.030000,
|
||||
"lfo0_rate": 1.000000,
|
||||
"lfo0_waveform": 0,
|
||||
"lfo0_active": 0,
|
||||
"lfo1_rate": 1.000000,
|
||||
"lfo1_waveform": 0,
|
||||
"lfo1_active": 0,
|
||||
"filter_cutoff": 9000.000000,
|
||||
"filter_resonance": 0.120000,
|
||||
"filter_type": 0,
|
||||
"filter_active": 1,
|
||||
"filter_modRouting": 2,
|
||||
"filter_modDepth": 5000.000000,
|
||||
"filter_resModRouting": 0,
|
||||
"filter_resModDepth": 0.000000,
|
||||
"master_volume": 0.750000,
|
||||
"master_pitchBendRange": 0.000000
|
||||
}
|
||||
50
patches/Keys/Piano.json
Normal file
50
patches/Keys/Piano.json
Normal file
@@ -0,0 +1,50 @@
|
||||
{
|
||||
"osc0_waveform": 1,
|
||||
"osc0_dutyCycle": 0.500000,
|
||||
"osc0_detune": 0.000000,
|
||||
"osc0_gain": 3.500000,
|
||||
"osc0_active": 1,
|
||||
"osc0_octave": 0,
|
||||
"osc0_modRouting0": 0,
|
||||
"osc0_modRouting1": 0,
|
||||
"osc0_modRouting2": 0,
|
||||
"osc0_modDepth0": 0.000000,
|
||||
"osc0_modDepth1": 0.000000,
|
||||
"osc0_modDepth2": 0.000000,
|
||||
"osc1_waveform": 1,
|
||||
"osc1_dutyCycle": 0.500000,
|
||||
"osc1_detune": 7.000000,
|
||||
"osc1_gain": 1.000000,
|
||||
"osc1_active": 1,
|
||||
"osc1_octave": 1,
|
||||
"osc1_modRouting0": 0,
|
||||
"osc1_modRouting1": 0,
|
||||
"osc1_modRouting2": 2,
|
||||
"osc1_modDepth0": 0.000000,
|
||||
"osc1_modDepth1": 0.000000,
|
||||
"osc1_modDepth2": 2.000000,
|
||||
"ampEnv_attack": 0.003000,
|
||||
"ampEnv_decay": 2.000000,
|
||||
"ampEnv_sustain": 0.000000,
|
||||
"ampEnv_release": 0.600000,
|
||||
"modEnv_attack": 0.000000,
|
||||
"modEnv_decay": 0.120000,
|
||||
"modEnv_sustain": 0.000000,
|
||||
"modEnv_release": 0.060000,
|
||||
"lfo0_rate": 1.000000,
|
||||
"lfo0_waveform": 0,
|
||||
"lfo0_active": 0,
|
||||
"lfo1_rate": 1.000000,
|
||||
"lfo1_waveform": 0,
|
||||
"lfo1_active": 0,
|
||||
"filter_cutoff": 8000.000000,
|
||||
"filter_resonance": 0.050000,
|
||||
"filter_type": 0,
|
||||
"filter_active": 1,
|
||||
"filter_modRouting": 2,
|
||||
"filter_modDepth": 4000.000000,
|
||||
"filter_resModRouting": 0,
|
||||
"filter_resModDepth": 0.000000,
|
||||
"master_volume": 0.750000,
|
||||
"master_pitchBendRange": 1.000000
|
||||
}
|
||||
50
patches/Keys/PipeOrgan.json
Normal file
50
patches/Keys/PipeOrgan.json
Normal file
@@ -0,0 +1,50 @@
|
||||
{
|
||||
"osc0_waveform": 0,
|
||||
"osc0_dutyCycle": 0.500000,
|
||||
"osc0_detune": 0.000000,
|
||||
"osc0_gain": 4.000000,
|
||||
"osc0_active": 1,
|
||||
"osc0_octave": 0,
|
||||
"osc0_modRouting0": 0,
|
||||
"osc0_modRouting1": 0,
|
||||
"osc0_modRouting2": 0,
|
||||
"osc0_modDepth0": 0.000000,
|
||||
"osc0_modDepth1": 0.000000,
|
||||
"osc0_modDepth2": 0.000000,
|
||||
"osc1_waveform": 5,
|
||||
"osc1_dutyCycle": 0.500000,
|
||||
"osc1_detune": 0.000000,
|
||||
"osc1_gain": 0.000000,
|
||||
"osc1_active": 1,
|
||||
"osc1_octave": 0,
|
||||
"osc1_modRouting0": 0,
|
||||
"osc1_modRouting1": 0,
|
||||
"osc1_modRouting2": 2,
|
||||
"osc1_modDepth0": 0.000000,
|
||||
"osc1_modDepth1": 0.000000,
|
||||
"osc1_modDepth2": 2.500000,
|
||||
"ampEnv_attack": 0.012000,
|
||||
"ampEnv_decay": 0.050000,
|
||||
"ampEnv_sustain": 0.920000,
|
||||
"ampEnv_release": 0.120000,
|
||||
"modEnv_attack": 0.001000,
|
||||
"modEnv_decay": 0.055000,
|
||||
"modEnv_sustain": 0.000000,
|
||||
"modEnv_release": 0.025000,
|
||||
"lfo0_rate": 1.000000,
|
||||
"lfo0_waveform": 0,
|
||||
"lfo0_active": 0,
|
||||
"lfo1_rate": 1.000000,
|
||||
"lfo1_waveform": 0,
|
||||
"lfo1_active": 0,
|
||||
"filter_cutoff": 4500.000000,
|
||||
"filter_resonance": 0.050000,
|
||||
"filter_type": 0,
|
||||
"filter_active": 1,
|
||||
"filter_modRouting": 0,
|
||||
"filter_modDepth": 0.000000,
|
||||
"filter_resModRouting": 0,
|
||||
"filter_resModDepth": 0.000000,
|
||||
"master_volume": 0.750000,
|
||||
"master_pitchBendRange": 1.000000
|
||||
}
|
||||
50
patches/Keys/Vibraphone.json
Normal file
50
patches/Keys/Vibraphone.json
Normal file
@@ -0,0 +1,50 @@
|
||||
{
|
||||
"osc0_waveform": 0,
|
||||
"osc0_dutyCycle": 0.500000,
|
||||
"osc0_detune": 0.000000,
|
||||
"osc0_gain": 4.000000,
|
||||
"osc0_active": 1,
|
||||
"osc0_octave": 0,
|
||||
"osc0_modRouting0": 0,
|
||||
"osc0_modRouting1": 3,
|
||||
"osc0_modRouting2": 0,
|
||||
"osc0_modDepth0": 0.000000,
|
||||
"osc0_modDepth1": 10.000000,
|
||||
"osc0_modDepth2": 0.000000,
|
||||
"osc1_waveform": 0,
|
||||
"osc1_dutyCycle": 0.500000,
|
||||
"osc1_detune": 2.000000,
|
||||
"osc1_gain": 0.300000,
|
||||
"osc1_active": 1,
|
||||
"osc1_octave": 1,
|
||||
"osc1_modRouting0": 0,
|
||||
"osc1_modRouting1": 0,
|
||||
"osc1_modRouting2": 2,
|
||||
"osc1_modDepth0": 0.000000,
|
||||
"osc1_modDepth1": 0.000000,
|
||||
"osc1_modDepth2": 1.500000,
|
||||
"ampEnv_attack": 0.001000,
|
||||
"ampEnv_decay": 2.000000,
|
||||
"ampEnv_sustain": 0.000000,
|
||||
"ampEnv_release": 0.600000,
|
||||
"modEnv_attack": 0.001000,
|
||||
"modEnv_decay": 0.080000,
|
||||
"modEnv_sustain": 0.000000,
|
||||
"modEnv_release": 0.040000,
|
||||
"lfo0_rate": 4.500000,
|
||||
"lfo0_waveform": 0,
|
||||
"lfo0_active": 1,
|
||||
"lfo1_rate": 1.000000,
|
||||
"lfo1_waveform": 0,
|
||||
"lfo1_active": 0,
|
||||
"filter_cutoff": 10000.000000,
|
||||
"filter_resonance": 0.100000,
|
||||
"filter_type": 0,
|
||||
"filter_active": 1,
|
||||
"filter_modRouting": 0,
|
||||
"filter_modDepth": 0.000000,
|
||||
"filter_resModRouting": 0,
|
||||
"filter_resModDepth": 0.000000,
|
||||
"master_volume": 0.800000,
|
||||
"master_pitchBendRange": 2.000000
|
||||
}
|
||||
91
source/config.c
Normal file
91
source/config.c
Normal file
@@ -0,0 +1,91 @@
|
||||
#define _POSIX_C_SOURCE 200809L
|
||||
#include "config.h"
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#ifdef _WIN32
|
||||
# include <direct.h>
|
||||
# define MAKE_DIR(p) _mkdir(p)
|
||||
#else
|
||||
# include <sys/stat.h>
|
||||
# define MAKE_DIR(p) mkdir(p, 0755)
|
||||
#endif
|
||||
|
||||
void configSanitizeName(const char *in, char *out, int maxLen)
|
||||
{
|
||||
int i = 0;
|
||||
for (; in[i] && i < maxLen - 1; i++) {
|
||||
char c = in[i];
|
||||
if ((c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z') ||
|
||||
(c >= '0' && c <= '9') || c == '_' || c == '-')
|
||||
out[i] = c;
|
||||
else
|
||||
out[i] = '_';
|
||||
}
|
||||
out[i] = '\0';
|
||||
}
|
||||
|
||||
int configSaveLastDevice(const char *deviceName)
|
||||
{
|
||||
MAKE_DIR(CONFIG_DIR);
|
||||
FILE *f = fopen(CONFIG_DIR "/last_device.txt", "w");
|
||||
if (!f) return 0;
|
||||
fprintf(f, "%s\n", deviceName);
|
||||
fclose(f);
|
||||
return 1;
|
||||
}
|
||||
|
||||
int configLoadLastDevice(char *out, int maxLen)
|
||||
{
|
||||
FILE *f = fopen(CONFIG_DIR "/last_device.txt", "r");
|
||||
if (!f) return 0;
|
||||
int ok = (fgets(out, maxLen, f) != NULL);
|
||||
fclose(f);
|
||||
if (!ok) return 0;
|
||||
int len = (int)strlen(out);
|
||||
if (len > 0 && out[len - 1] == '\n') out[len - 1] = '\0';
|
||||
return out[0] != '\0';
|
||||
}
|
||||
|
||||
int configSaveCcMappings(const char *deviceName, ConfigCcEntry *entries, int count)
|
||||
{
|
||||
MAKE_DIR(CONFIG_DIR);
|
||||
char safe[CONFIG_NAME_LEN];
|
||||
configSanitizeName(deviceName, safe, sizeof(safe));
|
||||
char path[CONFIG_NAME_LEN + 32];
|
||||
snprintf(path, sizeof(path), CONFIG_DIR "/cc_%s.cfg", safe);
|
||||
|
||||
FILE *f = fopen(path, "w");
|
||||
if (!f) return 0;
|
||||
for (int i = 0; i < count; i++)
|
||||
fprintf(f, "%d %d %f %f\n",
|
||||
entries[i].cc, entries[i].controlId,
|
||||
entries[i].min, entries[i].max);
|
||||
fclose(f);
|
||||
return 1;
|
||||
}
|
||||
|
||||
int configLoadCcMappings(const char *deviceName, ConfigCcEntry *entries, int maxCount)
|
||||
{
|
||||
char safe[CONFIG_NAME_LEN];
|
||||
configSanitizeName(deviceName, safe, sizeof(safe));
|
||||
char path[CONFIG_NAME_LEN + 32];
|
||||
snprintf(path, sizeof(path), CONFIG_DIR "/cc_%s.cfg", safe);
|
||||
|
||||
FILE *f = fopen(path, "r");
|
||||
if (!f) return 0;
|
||||
int count = 0;
|
||||
while (count < maxCount) {
|
||||
int cc, id;
|
||||
float mn, mx;
|
||||
if (fscanf(f, "%d %d %f %f\n", &cc, &id, &mn, &mx) != 4) break;
|
||||
if (cc >= 0 && cc < 128) {
|
||||
entries[count].cc = cc;
|
||||
entries[count].controlId = id;
|
||||
entries[count].min = mn;
|
||||
entries[count].max = mx;
|
||||
count++;
|
||||
}
|
||||
}
|
||||
fclose(f);
|
||||
return count;
|
||||
}
|
||||
165
source/font_data.c
Normal file
165
source/font_data.c
Normal file
@@ -0,0 +1,165 @@
|
||||
unsigned char font_png[] = {
|
||||
0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, 0x00, 0x00, 0x00, 0x0d,
|
||||
0x49, 0x48, 0x44, 0x52, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x70,
|
||||
0x08, 0x06, 0x00, 0x00, 0x00, 0xd6, 0xac, 0x78, 0xd2, 0x00, 0x00, 0x00,
|
||||
0x01, 0x73, 0x52, 0x47, 0x42, 0x00, 0xae, 0xce, 0x1c, 0xe9, 0x00, 0x00,
|
||||
0x07, 0x51, 0x49, 0x44, 0x41, 0x54, 0x78, 0x9c, 0xed, 0x9c, 0xdd, 0x76,
|
||||
0xe3, 0x30, 0x08, 0x84, 0x93, 0x9e, 0xbe, 0xff, 0x2b, 0x7b, 0x6f, 0x56,
|
||||
0x3d, 0x94, 0x0c, 0x30, 0x48, 0x72, 0x12, 0x37, 0xf3, 0x5d, 0x35, 0x96,
|
||||
0xf8, 0x91, 0x04, 0x08, 0xa7, 0xdd, 0xbd, 0xdd, 0xc4, 0x47, 0x73, 0x67,
|
||||
0x27, 0x1e, 0xc7, 0x71, 0xdc, 0x6e, 0xb7, 0xdb, 0xfd, 0x7e, 0x87, 0x32,
|
||||
0x76, 0x1c, 0xcd, 0x3d, 0x8e, 0xe3, 0x18, 0x9f, 0xed, 0xcf, 0x8c, 0x8d,
|
||||
0x4a, 0x9f, 0x9d, 0xc3, 0xfa, 0x98, 0x8d, 0x7b, 0x3d, 0xd1, 0xf3, 0x2b,
|
||||
0x33, 0xd6, 0xf4, 0xf5, 0x4c, 0x63, 0xc7, 0x7f, 0xec, 0x33, 0x3f, 0xc7,
|
||||
0xcf, 0xcb, 0xf4, 0xd9, 0xcf, 0x77, 0x43, 0x26, 0xcb, 0xe8, 0x1c, 0x7a,
|
||||
0xa2, 0xcf, 0x91, 0xef, 0xd9, 0xfa, 0x98, 0x75, 0x3d, 0x0b, 0xeb, 0xc3,
|
||||
0xb6, 0x00, 0xf0, 0x1b, 0x86, 0xc6, 0xec, 0x46, 0x66, 0xd9, 0x9c, 0x1d,
|
||||
0x00, 0x93, 0xc5, 0xd1, 0x18, 0x93, 0xf9, 0x59, 0x76, 0x67, 0x15, 0xc7,
|
||||
0x07, 0xf0, 0xbb, 0x56, 0x09, 0xef, 0xf7, 0xf7, 0x4e, 0xe5, 0x59, 0x10,
|
||||
0x54, 0x72, 0xcc, 0x06, 0x46, 0x87, 0x1f, 0x5d, 0x3b, 0x95, 0x8f, 0xbb,
|
||||
0x88, 0xb2, 0x3d, 0xba, 0x42, 0x58, 0x5f, 0x33, 0xfd, 0x83, 0xce, 0x7a,
|
||||
0x50, 0xa0, 0xbf, 0xcd, 0x15, 0xe0, 0x83, 0xa7, 0xb3, 0x69, 0xf6, 0x0a,
|
||||
0xc8, 0x4a, 0xf0, 0x59, 0x20, 0x9f, 0xba, 0x81, 0xb6, 0x7a, 0x3d, 0x74,
|
||||
0xae, 0xcd, 0x97, 0x54, 0x27, 0x9f, 0xe1, 0x7e, 0xcc, 0x83, 0xc6, 0xb3,
|
||||
0xcf, 0x91, 0xad, 0x8e, 0x7f, 0xcc, 0x26, 0x46, 0xfe, 0x79, 0xbf, 0xa2,
|
||||
0xaa, 0x10, 0xe9, 0x3f, 0x33, 0x00, 0xb2, 0xb5, 0x6d, 0x7b, 0x0b, 0xd8,
|
||||
0x01, 0x6b, 0x03, 0xcd, 0xf3, 0x11, 0x3e, 0xaa, 0xc2, 0x8c, 0x7d, 0xab,
|
||||
0x27, 0x7b, 0xde, 0xa5, 0x5a, 0xdf, 0x8c, 0xcf, 0x3b, 0xec, 0x8a, 0x0f,
|
||||
0x26, 0x7c, 0xb5, 0xe9, 0x34, 0x61, 0x8c, 0xfc, 0xca, 0x78, 0x54, 0xda,
|
||||
0xb2, 0x39, 0x3b, 0xe5, 0x23, 0x1d, 0x67, 0x37, 0x94, 0x33, 0x4d, 0x22,
|
||||
0xf3, 0xa6, 0x63, 0xe7, 0x7d, 0xd9, 0x41, 0xf4, 0xba, 0x15, 0x29, 0x40,
|
||||
0x63, 0x91, 0x7c, 0x67, 0x3c, 0x5b, 0xe8, 0xdd, 0xc1, 0xea, 0xf7, 0xf2,
|
||||
0x3b, 0xfc, 0x47, 0x3a, 0x98, 0xfe, 0x21, 0x5b, 0x5f, 0x76, 0x90, 0x07,
|
||||
0x00, 0xcd, 0x45, 0x36, 0xb2, 0xf5, 0x7d, 0x7b, 0x25, 0x59, 0xb6, 0x64,
|
||||
0x0b, 0xc8, 0x0e, 0x6f, 0x57, 0xa6, 0xb0, 0xd9, 0x71, 0xc5, 0xbb, 0x6e,
|
||||
0x26, 0xf3, 0x2d, 0xf6, 0x7c, 0x7c, 0x2f, 0x91, 0xee, 0x95, 0x15, 0xb0,
|
||||
0x91, 0x82, 0x1a, 0x12, 0x26, 0x53, 0x99, 0x46, 0xc7, 0x8f, 0x33, 0x25,
|
||||
0x1a, 0xcd, 0xad, 0xb2, 0x3d, 0xb3, 0x5f, 0xf9, 0xf0, 0xcc, 0x2b, 0x60,
|
||||
0xf5, 0xf0, 0x59, 0x5d, 0x68, 0xec, 0xcb, 0x0f, 0xae, 0x38, 0xc0, 0xe8,
|
||||
0xa8, 0x2a, 0x4d, 0xa4, 0x97, 0xd5, 0x9d, 0xe9, 0xaf, 0x0e, 0x3f, 0x93,
|
||||
0x47, 0x57, 0x4f, 0xe4, 0x63, 0x77, 0x9c, 0x49, 0x86, 0xec, 0x0a, 0xa8,
|
||||
0xd6, 0x97, 0xd9, 0xfb, 0x42, 0x03, 0x9d, 0xc3, 0xf1, 0xc6, 0xa3, 0xac,
|
||||
0xad, 0xae, 0x0f, 0xbf, 0xb9, 0x4c, 0x06, 0xcf, 0xf8, 0x97, 0xe9, 0x7e,
|
||||
0x25, 0x4c, 0x10, 0x64, 0x30, 0xeb, 0x43, 0x01, 0xbc, 0xa5, 0x8b, 0x9e,
|
||||
0x89, 0xec, 0xce, 0x15, 0xc1, 0xc8, 0xb3, 0xe3, 0x6c, 0x60, 0xad, 0x5c,
|
||||
0x73, 0x99, 0x5c, 0x25, 0x33, 0x13, 0xa8, 0xac, 0xcc, 0x8e, 0x2a, 0x2f,
|
||||
0xfe, 0x18, 0x5b, 0x9a, 0x20, 0xa6, 0x41, 0x5a, 0x91, 0x3f, 0xa3, 0x02,
|
||||
0x21, 0xf9, 0xa8, 0x2f, 0x98, 0xb5, 0xef, 0xe5, 0xd1, 0x7c, 0x34, 0xee,
|
||||
0x61, 0xfd, 0x8b, 0xc6, 0x91, 0x8f, 0xe3, 0x39, 0xfd, 0x3d, 0x80, 0x17,
|
||||
0x8c, 0xc6, 0x90, 0xbc, 0x5f, 0x70, 0xe6, 0xd4, 0x4a, 0x1f, 0x12, 0xc1,
|
||||
0xda, 0x8f, 0x40, 0xfd, 0x09, 0xda, 0x07, 0x66, 0xce, 0x4a, 0x2f, 0x32,
|
||||
0x64, 0xb3, 0x46, 0x31, 0x7b, 0x8e, 0xd6, 0x4e, 0x7d, 0x0f, 0xe0, 0xa3,
|
||||
0x69, 0x44, 0x1d, 0x73, 0xa7, 0x59, 0xfc, 0x06, 0x65, 0xf3, 0x90, 0xfe,
|
||||
0xca, 0x56, 0x67, 0x7c, 0xe7, 0x3d, 0xc8, 0xea, 0xda, 0xd1, 0x88, 0x56,
|
||||
0x41, 0xdb, 0x3d, 0x93, 0xad, 0x7f, 0x0f, 0x70, 0x76, 0xa7, 0xdd, 0x69,
|
||||
0xe4, 0x32, 0xfb, 0xd1, 0xbc, 0x9d, 0x55, 0x27, 0xe3, 0x8c, 0xbd, 0x99,
|
||||
0xe5, 0x21, 0x00, 0xd8, 0x8d, 0x43, 0xd8, 0x2a, 0xd2, 0x8d, 0x44, 0x86,
|
||||
0x5d, 0xfa, 0xec, 0xbd, 0x19, 0xe9, 0xef, 0x04, 0x43, 0xb7, 0xbb, 0x9e,
|
||||
0xed, 0xc6, 0x87, 0xdf, 0x99, 0xff, 0x63, 0xef, 0x59, 0x9d, 0x3f, 0x01,
|
||||
0xc0, 0x1c, 0xd8, 0x6a, 0xb6, 0x58, 0x1b, 0xd9, 0x26, 0x44, 0x63, 0x51,
|
||||
0x23, 0x13, 0x7d, 0xce, 0xec, 0xbf, 0x82, 0xaa, 0xf7, 0xa8, 0xd6, 0x17,
|
||||
0x3d, 0xf3, 0xe3, 0xed, 0x00, 0x40, 0x91, 0x33, 0xb3, 0x51, 0x91, 0xbc,
|
||||
0x75, 0x2a, 0xb3, 0x71, 0xd6, 0x15, 0xc2, 0xda, 0x8f, 0xf0, 0x1b, 0x9a,
|
||||
0xf5, 0x44, 0x5d, 0xbd, 0xcf, 0x08, 0xc8, 0x5d, 0xe7, 0x2b, 0xfe, 0x20,
|
||||
0x5b, 0xdf, 0xa3, 0x77, 0xcb, 0x8f, 0x39, 0x28, 0xb3, 0xec, 0xb3, 0xdd,
|
||||
0xe3, 0xd5, 0xe7, 0x48, 0x3e, 0xdb, 0x03, 0x66, 0xfd, 0x4c, 0x73, 0xeb,
|
||||
0x65, 0xd1, 0xdc, 0x4e, 0x76, 0x3f, 0xfc, 0x2e, 0x00, 0x2d, 0x92, 0xed,
|
||||
0x9a, 0x77, 0xc8, 0x47, 0xba, 0xde, 0x01, 0xb4, 0x9e, 0x2e, 0x77, 0x43,
|
||||
0xa4, 0xbf, 0x23, 0xb3, 0xea, 0x1f, 0xfc, 0xab, 0xe0, 0xc8, 0x90, 0xbd,
|
||||
0xf3, 0x32, 0xa5, 0xcc, 0xb8, 0x5d, 0xd0, 0xab, 0x0f, 0xdb, 0x66, 0x22,
|
||||
0xca, 0xc6, 0x28, 0x68, 0xbd, 0xff, 0x7e, 0x0d, 0xec, 0x9a, 0xaa, 0x4a,
|
||||
0xc9, 0x10, 0xf5, 0x29, 0x15, 0x30, 0x00, 0x56, 0x22, 0xdc, 0xca, 0xa3,
|
||||
0x80, 0x39, 0x0c, 0x2b, 0x36, 0x32, 0xbb, 0x99, 0x6e, 0xe6, 0xba, 0x42,
|
||||
0x07, 0xc7, 0x1c, 0xee, 0x4a, 0x93, 0xb5, 0x12, 0x04, 0x6c, 0x85, 0x45,
|
||||
0xfc, 0x0a, 0x80, 0xaa, 0x53, 0xac, 0x36, 0x38, 0xeb, 0x84, 0x51, 0x96,
|
||||
0xec, 0x0a, 0x82, 0x2a, 0x43, 0x19, 0xac, 0x1c, 0xf2, 0xab, 0xd2, 0xbb,
|
||||
0x72, 0xf8, 0x48, 0x6e, 0x66, 0x6f, 0xd8, 0x0a, 0x6d, 0xf9, 0xf5, 0x45,
|
||||
0x50, 0x56, 0xfa, 0xab, 0xfb, 0x1c, 0xcd, 0xb3, 0xa5, 0xb5, 0xb2, 0xb1,
|
||||
0x8a, 0xb5, 0x1d, 0xd9, 0x89, 0x02, 0x18, 0x35, 0x7d, 0x1d, 0xff, 0xb3,
|
||||
0xf2, 0x3b, 0x53, 0x09, 0xd0, 0x1e, 0x56, 0x32, 0xd9, 0xb3, 0x2c, 0x98,
|
||||
0xe8, 0x7f, 0x19, 0xc4, 0x66, 0x30, 0x1a, 0x5f, 0xcd, 0x50, 0x7f, 0x30,
|
||||
0x59, 0x95, 0xc9, 0x9e, 0x67, 0x3f, 0x77, 0xfc, 0x58, 0x81, 0xb9, 0x02,
|
||||
0x51, 0xe5, 0x3d, 0xeb, 0xda, 0x14, 0x1f, 0x4e, 0x9a, 0xad, 0x2c, 0x2b,
|
||||
0xb2, 0x3b, 0xf5, 0xf9, 0x0c, 0x61, 0xe5, 0x59, 0x7b, 0xb3, 0xf3, 0x18,
|
||||
0xb9, 0x67, 0x5c, 0x93, 0x88, 0x87, 0x5f, 0x06, 0x45, 0xf7, 0xce, 0xaa,
|
||||
0x83, 0xb3, 0x87, 0xc3, 0xca, 0x57, 0x9b, 0xbc, 0x6a, 0xbf, 0x23, 0xb3,
|
||||
0x2b, 0x90, 0xb2, 0xb9, 0xe3, 0x9c, 0xfc, 0xb9, 0x64, 0xf3, 0x91, 0x8f,
|
||||
0xad, 0x4d, 0x8c, 0xe6, 0x75, 0x7b, 0x81, 0xaa, 0x37, 0xf0, 0x3a, 0x2a,
|
||||
0x79, 0xf6, 0xf0, 0x2b, 0xf9, 0xc8, 0xff, 0x48, 0x4f, 0x44, 0x66, 0x2f,
|
||||
0xd3, 0x51, 0x1d, 0x1e, 0xe3, 0x3f, 0xb2, 0x91, 0x7d, 0xa6, 0xde, 0x02,
|
||||
0xbc, 0x91, 0x08, 0xdf, 0xac, 0x45, 0xfa, 0xd8, 0x05, 0x66, 0x3e, 0x9c,
|
||||
0x51, 0xa5, 0x58, 0xff, 0x67, 0x59, 0xbd, 0x2a, 0xab, 0x33, 0x98, 0xd1,
|
||||
0x4b, 0xfd, 0x41, 0x08, 0x7b, 0x40, 0x67, 0x53, 0x2d, 0x30, 0x0b, 0xb8,
|
||||
0x33, 0xbb, 0xe8, 0xee, 0xc1, 0x9e, 0x11, 0x5c, 0xb3, 0x3c, 0xe5, 0x3f,
|
||||
0x88, 0xf0, 0xec, 0x38, 0x8c, 0xae, 0xfc, 0xdd, 0xb0, 0x62, 0x77, 0x85,
|
||||
0x55, 0xfb, 0x67, 0xf8, 0x4f, 0x55, 0x00, 0x9f, 0x41, 0xf6, 0x73, 0x74,
|
||||
0x8f, 0xdb, 0xe7, 0x28, 0x03, 0xab, 0xf1, 0xcc, 0xbe, 0x97, 0xaf, 0x60,
|
||||
0xef, 0xf8, 0x59, 0x66, 0xfc, 0x7b, 0x66, 0x15, 0x58, 0xdd, 0x3f, 0xf1,
|
||||
0x87, 0x79, 0xab, 0x28, 0x58, 0x6d, 0x92, 0xae, 0x40, 0x96, 0x85, 0xd5,
|
||||
0x5b, 0x00, 0x1a, 0x63, 0x6d, 0x46, 0x72, 0xdf, 0xde, 0x40, 0xe5, 0x1c,
|
||||
0x1a, 0x67, 0x0e, 0x2e, 0x93, 0xaf, 0x60, 0x5e, 0x6b, 0x90, 0xbf, 0x9d,
|
||||
0xf1, 0x4a, 0x3f, 0xf3, 0xd9, 0xc3, 0x5c, 0x8f, 0x0c, 0xfe, 0xed, 0x84,
|
||||
0xd1, 0xc1, 0xec, 0xd1, 0xed, 0x96, 0xfc, 0x41, 0x88, 0x75, 0xd8, 0x2a,
|
||||
0xcb, 0x16, 0x7d, 0x18, 0x22, 0x67, 0x22, 0xfd, 0xd9, 0x67, 0x06, 0xe4,
|
||||
0x6f, 0x67, 0x3c, 0x7b, 0xce, 0xc2, 0x34, 0x69, 0xab, 0x4d, 0x60, 0x34,
|
||||
0x16, 0xed, 0xbd, 0x9f, 0xe3, 0x9f, 0x51, 0x6f, 0x01, 0x6c, 0x04, 0x46,
|
||||
0x0e, 0xa2, 0xcc, 0xf1, 0x73, 0x7d, 0x53, 0xf8, 0xcc, 0x6b, 0xc0, 0x67,
|
||||
0x6a, 0x64, 0x3f, 0xcb, 0xf4, 0xa8, 0x3a, 0x78, 0x1b, 0x2b, 0x41, 0x56,
|
||||
0x5d, 0x11, 0x95, 0x0f, 0xc8, 0x7e, 0xf8, 0xf7, 0x00, 0x68, 0x01, 0x6c,
|
||||
0x84, 0x47, 0xc1, 0x71, 0xbf, 0xe3, 0x6e, 0x7f, 0xd7, 0x61, 0x57, 0x9b,
|
||||
0x9b, 0x65, 0x48, 0x54, 0xae, 0xab, 0x31, 0x64, 0x3f, 0xdb, 0xf8, 0x1d,
|
||||
0x15, 0x20, 0xf3, 0x81, 0x39, 0x27, 0x2b, 0x0f, 0xaf, 0x80, 0x48, 0x78,
|
||||
0x6c, 0x60, 0x37, 0x9a, 0x51, 0x60, 0xcd, 0x64, 0x42, 0x74, 0x80, 0xe8,
|
||||
0x80, 0x3a, 0x1b, 0xed, 0xd7, 0x85, 0xfc, 0x63, 0xf6, 0xc6, 0xda, 0x3d,
|
||||
0xe3, 0x9a, 0x61, 0x2a, 0x50, 0x35, 0xee, 0xe7, 0xd2, 0xff, 0x34, 0x0c,
|
||||
0xdd, 0xa1, 0xec, 0x26, 0xa3, 0xcc, 0xef, 0x1c, 0xd0, 0x90, 0x47, 0xcf,
|
||||
0xec, 0xc2, 0xb2, 0xea, 0xe5, 0x03, 0x37, 0xb2, 0x8f, 0x6c, 0xb1, 0x41,
|
||||
0x17, 0xcd, 0xb5, 0xf3, 0xab, 0x6b, 0x14, 0xb1, 0xab, 0x62, 0xc2, 0xca,
|
||||
0x3c, 0xa3, 0xe8, 0x2c, 0xd0, 0xc6, 0x54, 0x19, 0xc3, 0x66, 0xe4, 0xea,
|
||||
0x9c, 0xb3, 0xe8, 0x54, 0xaf, 0x33, 0xc6, 0x5f, 0xf2, 0x55, 0xf0, 0x3b,
|
||||
0xc0, 0x64, 0xed, 0x27, 0xb0, 0xf5, 0x5f, 0x07, 0xaf, 0xc0, 0x94, 0x4e,
|
||||
0xf4, 0xbc, 0xa3, 0xcb, 0x8f, 0xfb, 0xb2, 0x5c, 0xdd, 0xa3, 0x99, 0xce,
|
||||
0xca, 0x46, 0x57, 0xd6, 0xcb, 0xed, 0x0c, 0x52, 0xab, 0x1f, 0xfe, 0x41,
|
||||
0x48, 0x26, 0x7c, 0xa6, 0x63, 0x95, 0xdd, 0x99, 0x2b, 0xc2, 0x83, 0x74,
|
||||
0xd8, 0x1e, 0x65, 0xf6, 0x7e, 0xdd, 0xcd, 0xd9, 0xfb, 0x3a, 0xf4, 0x3f,
|
||||
0xbc, 0x06, 0xb2, 0x82, 0x57, 0x24, 0xcb, 0xca, 0x95, 0xb7, 0x93, 0x5d,
|
||||
0x30, 0xc1, 0xb7, 0x3b, 0x40, 0xc3, 0x2b, 0x80, 0xcd, 0xf4, 0x5d, 0x9d,
|
||||
0xec, 0xec, 0xc6, 0x23, 0xfb, 0x48, 0x17, 0x53, 0x92, 0xdf, 0xa1, 0x12,
|
||||
0x3c, 0xcb, 0xee, 0xb0, 0x43, 0xff, 0xd3, 0xb0, 0x55, 0xc7, 0x7c, 0xc9,
|
||||
0xdd, 0xad, 0x3f, 0xd3, 0xd5, 0xb9, 0x8f, 0xdf, 0xa1, 0x12, 0x9c, 0xcd,
|
||||
0x47, 0xbd, 0x05, 0xcc, 0x34, 0x63, 0x9f, 0x10, 0x04, 0x83, 0x32, 0x53,
|
||||
0x3a, 0x1b, 0xb8, 0x2a, 0x8f, 0x74, 0xfd, 0x38, 0xfa, 0x22, 0xf9, 0x77,
|
||||
0x69, 0x0a, 0xcf, 0xe2, 0xf4, 0x0a, 0x30, 0x93, 0x4d, 0x57, 0xdc, 0x7c,
|
||||
0xfb, 0x0d, 0x9f, 0xfd, 0x19, 0xcd, 0xab, 0xf4, 0x54, 0x36, 0x32, 0xdd,
|
||||
0xd5, 0x98, 0x9f, 0xf3, 0xf0, 0x9f, 0x45, 0x47, 0x4e, 0xac, 0x94, 0xc3,
|
||||
0x4e, 0x10, 0x5c, 0xf5, 0xf0, 0xab, 0x9f, 0xed, 0xe7, 0x2a, 0x38, 0x66,
|
||||
0xf6, 0x7a, 0x34, 0xae, 0xf6, 0x75, 0xd9, 0xeb, 0x1d, 0xe3, 0xf6, 0xd9,
|
||||
0x77, 0x27, 0x52, 0xd1, 0x33, 0xf6, 0xa0, 0x98, 0x0e, 0xfb, 0x8a, 0x87,
|
||||
0xcf, 0x82, 0x0e, 0x25, 0xfb, 0x3e, 0xc3, 0x8e, 0x67, 0x67, 0xd1, 0xd9,
|
||||
0x7f, 0xfb, 0xf3, 0x90, 0x7f, 0x6a, 0x13, 0xb8, 0x73, 0x41, 0x57, 0x62,
|
||||
0x36, 0xe3, 0xd9, 0x4a, 0xe0, 0x83, 0x09, 0x55, 0x81, 0x88, 0xef, 0x6a,
|
||||
0xc3, 0xad, 0xa2, 0x6c, 0xae, 0x2f, 0x7d, 0xd1, 0x5c, 0x54, 0x09, 0xae,
|
||||
0x7e, 0xf8, 0xd1, 0x86, 0x8f, 0xf5, 0xac, 0x8e, 0xef, 0x20, 0xaa, 0x28,
|
||||
0x53, 0x9d, 0x3d, 0x1a, 0x8f, 0x60, 0xe5, 0x66, 0xf5, 0xb3, 0xac, 0xbe,
|
||||
0x45, 0x30, 0x7a, 0x99, 0x64, 0x61, 0xae, 0xc0, 0xae, 0x7c, 0xe4, 0x6b,
|
||||
0x76, 0xc5, 0x8c, 0xb1, 0x97, 0xfd, 0x32, 0xc8, 0x46, 0xfd, 0x55, 0x33,
|
||||
0xdf, 0x33, 0xd6, 0x84, 0xd6, 0x83, 0x9a, 0x43, 0x3f, 0x6f, 0x56, 0x9e,
|
||||
0xd9, 0xbf, 0xb7, 0xd9, 0xe3, 0x2c, 0xb3, 0xc6, 0xd5, 0x30, 0x23, 0xcb,
|
||||
0xc8, 0x8b, 0x47, 0x7e, 0xfe, 0xbb, 0x78, 0xc4, 0x98, 0x94, 0x35, 0x6d,
|
||||
0x11, 0x2b, 0x07, 0x39, 0x23, 0x53, 0xf9, 0x2b, 0x30, 0x3f, 0x6f, 0x01,
|
||||
0x77, 0x87, 0x9d, 0xe4, 0x9b, 0x94, 0xec, 0x1e, 0x63, 0xc6, 0xc7, 0x1c,
|
||||
0xd6, 0xc9, 0x99, 0x60, 0x53, 0x10, 0x70, 0xd0, 0x3d, 0x40, 0x76, 0x67,
|
||||
0xb3, 0x8d, 0x0d, 0x1a, 0xeb, 0x06, 0x4a, 0x37, 0x70, 0xde, 0xe6, 0xee,
|
||||
0x7b, 0x53, 0xb6, 0x34, 0x81, 0xb6, 0x79, 0xe9, 0x6e, 0xfa, 0x6a, 0xf6,
|
||||
0xa2, 0x4e, 0x57, 0x87, 0xce, 0xd3, 0xfa, 0xab, 0x60, 0xfb, 0x1e, 0x39,
|
||||
0xf3, 0x0d, 0xd4, 0x90, 0xf5, 0x63, 0xd5, 0x6b, 0x0c, 0xf3, 0x7a, 0x24,
|
||||
0xe6, 0xf8, 0xf5, 0xbb, 0x00, 0xd4, 0x00, 0x8e, 0xb1, 0xea, 0x9b, 0xa6,
|
||||
0x6e, 0xf6, 0x7b, 0x7d, 0xdd, 0x71, 0x71, 0x51, 0xf4, 0x1a, 0x28, 0x84,
|
||||
0x10, 0x42, 0x08, 0x21, 0x84, 0x10, 0x42, 0x08, 0x21, 0x84, 0x10, 0x42,
|
||||
0x08, 0x21, 0x84, 0x10, 0x42, 0x08, 0x21, 0x84, 0x10, 0x42, 0x08, 0x21,
|
||||
0x84, 0x10, 0x42, 0x08, 0x21, 0x84, 0x10, 0x42, 0x08, 0x21, 0x84, 0x10,
|
||||
0x42, 0x08, 0x21, 0x84, 0x10, 0x42, 0x08, 0x21, 0x84, 0x10, 0x42, 0x08,
|
||||
0x81, 0xf9, 0x07, 0x4e, 0x1f, 0xd4, 0x6d, 0xe4, 0x18, 0xb7, 0xb8, 0x00,
|
||||
0x00, 0x00, 0x00, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82
|
||||
};
|
||||
unsigned int font_png_len = 1943;
|
||||
312
source/icon_data.c
Normal file
312
source/icon_data.c
Normal file
@@ -0,0 +1,312 @@
|
||||
unsigned char icon_png[] = {
|
||||
0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, 0x00, 0x00, 0x00, 0x0d,
|
||||
0x49, 0x48, 0x44, 0x52, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x80,
|
||||
0x08, 0x06, 0x00, 0x00, 0x00, 0xc3, 0x3e, 0x61, 0xcb, 0x00, 0x00, 0x00,
|
||||
0x01, 0x73, 0x52, 0x47, 0x42, 0x00, 0xae, 0xce, 0x1c, 0xe9, 0x00, 0x00,
|
||||
0x0e, 0x2d, 0x49, 0x44, 0x41, 0x54, 0x78, 0x9c, 0xed, 0x5d, 0x3b, 0x6f,
|
||||
0x1b, 0xc7, 0x16, 0xfe, 0x78, 0x13, 0x58, 0x8a, 0x40, 0x3d, 0x6c, 0xfd,
|
||||
0x98, 0x54, 0x41, 0x0a, 0x23, 0x4d, 0xe2, 0x2e, 0x69, 0x0c, 0xd8, 0x95,
|
||||
0x00, 0x03, 0x6e, 0x2c, 0x20, 0x80, 0x85, 0x14, 0x4a, 0x65, 0x15, 0x81,
|
||||
0x02, 0x04, 0xb0, 0x1a, 0x03, 0x04, 0x5c, 0x39, 0x40, 0x1a, 0xdd, 0x2e,
|
||||
0x57, 0xcd, 0x45, 0x8a, 0x8b, 0x5b, 0xdd, 0x1f, 0x43, 0x89, 0x22, 0x09,
|
||||
0xd9, 0x32, 0x10, 0xf0, 0x16, 0xf4, 0x8c, 0x67, 0x67, 0xce, 0xcc, 0x9c,
|
||||
0x79, 0xec, 0xce, 0x2c, 0xcd, 0x0f, 0xa0, 0x4d, 0x2d, 0x97, 0xcb, 0xd9,
|
||||
0x39, 0xdf, 0x9e, 0xe7, 0x3c, 0x06, 0x58, 0x03, 0x00, 0x16, 0xca, 0xfb,
|
||||
0x41, 0xb1, 0x56, 0x14, 0xc0, 0x2a, 0xde, 0xec, 0x42, 0xfb, 0xdb, 0x77,
|
||||
0x8f, 0xfa, 0xf9, 0x9c, 0xef, 0xac, 0x0c, 0xfe, 0x51, 0xba, 0x01, 0x99,
|
||||
0x41, 0x09, 0x93, 0x3a, 0xd6, 0xf8, 0xec, 0x74, 0xf4, 0x06, 0xa3, 0xf3,
|
||||
0x8b, 0x90, 0xdf, 0x50, 0x5f, 0xbd, 0xc6, 0xe7, 0xa5, 0x1b, 0xd0, 0x06,
|
||||
0x4e, 0x47, 0x6f, 0xe4, 0xfb, 0xa3, 0x27, 0x8f, 0x81, 0xa5, 0xa0, 0x9c,
|
||||
0x4f, 0xf5, 0xe4, 0x72, 0x8c, 0xd1, 0xf9, 0x05, 0x9e, 0xfc, 0xf0, 0xad,
|
||||
0xeb, 0x7c, 0x1b, 0xc1, 0x7a, 0xab, 0x31, 0xfa, 0x42, 0x80, 0x50, 0xb5,
|
||||
0xce, 0xbe, 0xa6, 0x4a, 0x96, 0xc9, 0xe5, 0x98, 0xd5, 0x86, 0xdf, 0xff,
|
||||
0xfc, 0x0b, 0x00, 0xf0, 0xe8, 0xc1, 0xfd, 0x0c, 0xcd, 0x28, 0x8b, 0x3e,
|
||||
0x98, 0x80, 0x50, 0xb5, 0xde, 0x80, 0x22, 0xe0, 0x2c, 0xea, 0x5a, 0x08,
|
||||
0x7f, 0x55, 0xd0, 0x07, 0x02, 0x00, 0x00, 0x8e, 0x4f, 0xcf, 0x1a, 0x4f,
|
||||
0x2b, 0xba, 0xb5, 0xbf, 0x0b, 0x00, 0x18, 0x9d, 0x5f, 0xe0, 0xe6, 0xdd,
|
||||
0x6d, 0xe8, 0xf7, 0xaa, 0xf6, 0x17, 0x7a, 0x43, 0x00, 0x00, 0x98, 0x4e,
|
||||
0xae, 0x74, 0x12, 0x84, 0x62, 0xa1, 0xfd, 0xcf, 0x39, 0xd7, 0xc0, 0xcd,
|
||||
0xbb, 0x5b, 0x0e, 0x11, 0x92, 0x34, 0x57, 0x57, 0xe8, 0x15, 0x01, 0x00,
|
||||
0x83, 0x04, 0xac, 0x0e, 0x4d, 0xd0, 0x1c, 0xb1, 0x4f, 0xee, 0x02, 0x00,
|
||||
0xfe, 0xf9, 0xef, 0xff, 0xca, 0x57, 0xad, 0x28, 0x4d, 0x80, 0x28, 0xf5,
|
||||
0x38, 0x9d, 0x5c, 0xd9, 0xae, 0x65, 0x05, 0xa5, 0x39, 0xb8, 0xc7, 0x5c,
|
||||
0xc7, 0x43, 0xdb, 0x51, 0x1b, 0x4a, 0x46, 0x01, 0x7a, 0x47, 0x05, 0x85,
|
||||
0x53, 0xc7, 0xa7, 0x67, 0x38, 0x39, 0x7a, 0x46, 0x5d, 0xc7, 0x0a, 0xae,
|
||||
0x10, 0x6d, 0xe7, 0x4d, 0x2e, 0xc7, 0xd8, 0xbb, 0xb7, 0x4f, 0x7d, 0x24,
|
||||
0xda, 0xde, 0x88, 0x14, 0xde, 0xde, 0xbe, 0x07, 0x00, 0x7c, 0xb1, 0x71,
|
||||
0x87, 0xdb, 0xc4, 0xce, 0x51, 0x4a, 0x03, 0xc8, 0x8e, 0x3a, 0x3e, 0x3d,
|
||||
0x23, 0x8f, 0xeb, 0xf8, 0x20, 0x6c, 0x2f, 0x12, 0x7d, 0x04, 0x2f, 0x26,
|
||||
0x97, 0x63, 0x5b, 0xb8, 0x28, 0xdb, 0xae, 0x27, 0x95, 0x04, 0x11, 0x6a,
|
||||
0x44, 0xa9, 0x04, 0xc6, 0x02, 0x68, 0x0a, 0x5f, 0x13, 0xf0, 0x40, 0x3f,
|
||||
0x57, 0x3f, 0x5f, 0xc5, 0xce, 0xde, 0xdd, 0xac, 0x8d, 0xe3, 0x62, 0xef,
|
||||
0xde, 0xbe, 0x48, 0x1c, 0x49, 0xa8, 0xc2, 0xdf, 0xda, 0xdc, 0x90, 0xef,
|
||||
0x95, 0x9c, 0x81, 0xde, 0xe7, 0x45, 0x53, 0xd1, 0xd5, 0x24, 0x82, 0x14,
|
||||
0x95, 0x0e, 0x04, 0x9a, 0x83, 0xe9, 0xe4, 0xaa, 0x18, 0x09, 0x5c, 0x29,
|
||||
0x64, 0x11, 0x29, 0x28, 0x24, 0xe1, 0x08, 0x5f, 0x1c, 0xef, 0x84, 0x04,
|
||||
0xa5, 0x4c, 0xc0, 0x00, 0x30, 0xd5, 0x3a, 0x61, 0x0e, 0xd8, 0xf6, 0xdd,
|
||||
0xe2, 0x18, 0xb6, 0x0a, 0x87, 0x39, 0xe0, 0x40, 0xde, 0x5b, 0xc9, 0x68,
|
||||
0xa1, 0x74, 0x14, 0x60, 0xc0, 0xa6, 0xe6, 0x6d, 0xc7, 0x55, 0x94, 0x20,
|
||||
0x01, 0xe0, 0x4d, 0x21, 0xab, 0x30, 0xf2, 0x10, 0xa5, 0x43, 0xc4, 0xd2,
|
||||
0x45, 0x0c, 0xc3, 0x17, 0x48, 0x85, 0xcd, 0x59, 0x0c, 0x71, 0x0e, 0x3f,
|
||||
0x14, 0x90, 0xa2, 0xae, 0x41, 0x45, 0x09, 0xba, 0x9f, 0xa0, 0x42, 0x27,
|
||||
0xc0, 0xf7, 0xdf, 0x7c, 0x25, 0xde, 0x76, 0x22, 0x9b, 0xb6, 0x7e, 0x84,
|
||||
0xeb, 0xd8, 0x24, 0x13, 0x80, 0x1b, 0x1d, 0x00, 0x3c, 0x01, 0xda, 0x84,
|
||||
0x1f, 0x72, 0x3d, 0x2e, 0x09, 0x7e, 0xff, 0xf3, 0x2f, 0x23, 0x44, 0xec,
|
||||
0x9a, 0x00, 0x6d, 0x38, 0x81, 0x9d, 0x38, 0x36, 0x0e, 0xc1, 0x73, 0xcb,
|
||||
0xb8, 0x3e, 0x78, 0xaf, 0x23, 0xc8, 0xa2, 0x13, 0x81, 0xca, 0x17, 0x50,
|
||||
0xce, 0xa2, 0x48, 0x29, 0xef, 0xef, 0x6e, 0x03, 0xe8, 0x5e, 0xf8, 0x40,
|
||||
0x8b, 0x51, 0xc0, 0xc1, 0xe1, 0x73, 0x00, 0xc0, 0x70, 0x7b, 0x07, 0x2f,
|
||||
0x4f, 0x7e, 0x16, 0x87, 0x45, 0x07, 0x36, 0x6e, 0x70, 0x36, 0xbd, 0xc6,
|
||||
0xf6, 0xce, 0xae, 0xf7, 0x9a, 0x81, 0x42, 0x6f, 0x03, 0xa4, 0x17, 0xaf,
|
||||
0x6a, 0x0d, 0x41, 0x06, 0x47, 0xd2, 0xc8, 0xc0, 0xf8, 0x7a, 0xd6, 0x08,
|
||||
0x19, 0xbb, 0x44, 0xeb, 0x61, 0xe0, 0x7c, 0x36, 0xc5, 0xe1, 0xf1, 0x0b,
|
||||
0x00, 0xa0, 0x88, 0x20, 0x31, 0x9b, 0x5e, 0x03, 0x00, 0x49, 0x04, 0x8b,
|
||||
0xe0, 0x4b, 0xfb, 0x2f, 0xc0, 0xc7, 0x36, 0xc8, 0xfb, 0x51, 0xb5, 0x82,
|
||||
0x70, 0x0e, 0x39, 0x44, 0xf0, 0x8c, 0x2d, 0x68, 0x2d, 0x57, 0xd0, 0x49,
|
||||
0x14, 0x30, 0x9f, 0x4d, 0x1b, 0x44, 0x50, 0xa1, 0x1f, 0x13, 0x44, 0x00,
|
||||
0x96, 0x82, 0x27, 0x84, 0x3f, 0x40, 0x1d, 0xc2, 0x57, 0x31, 0x80, 0xd6,
|
||||
0xae, 0xa3, 0x27, 0x8f, 0x25, 0x19, 0x02, 0xc3, 0xc5, 0x90, 0x5c, 0x41,
|
||||
0x32, 0xda, 0xe8, 0x48, 0xd9, 0x30, 0x61, 0x06, 0x54, 0x0c, 0xb7, 0x77,
|
||||
0x58, 0x17, 0x51, 0xb4, 0x85, 0x40, 0x4a, 0x5b, 0xa5, 0xb3, 0xe9, 0x4b,
|
||||
0x18, 0x29, 0xea, 0x3c, 0xb5, 0x6f, 0x64, 0x3f, 0xa8, 0x3e, 0x82, 0x4d,
|
||||
0x1b, 0x10, 0xc9, 0xa2, 0x86, 0x80, 0xd5, 0x68, 0x21, 0xa7, 0xaf, 0xd0,
|
||||
0x86, 0x09, 0x68, 0x14, 0x45, 0x74, 0xcc, 0x67, 0x53, 0x27, 0x09, 0x32,
|
||||
0x0b, 0xde, 0x40, 0x87, 0x59, 0x43, 0xd9, 0x0f, 0x81, 0x66, 0xc1, 0x2a,
|
||||
0xf8, 0x36, 0xd0, 0xaa, 0x09, 0x78, 0xfd, 0xf2, 0x57, 0xf2, 0xb8, 0x30,
|
||||
0x09, 0x3a, 0x34, 0xe1, 0xb7, 0xa6, 0xea, 0x3b, 0x4c, 0x18, 0x19, 0x66,
|
||||
0x41, 0x40, 0x37, 0x0b, 0xb6, 0x94, 0xf2, 0xf8, 0x7a, 0xd6, 0x5e, 0xeb,
|
||||
0xd0, 0xae, 0x2d, 0x75, 0x9a, 0x02, 0x01, 0xa1, 0x0d, 0x08, 0xe1, 0x67,
|
||||
0x6f, 0x8b, 0x9e, 0x6f, 0xa0, 0x34, 0x41, 0x46, 0x13, 0x40, 0xb6, 0x01,
|
||||
0x30, 0xc3, 0x46, 0x8e, 0x93, 0x48, 0x84, 0x8a, 0x40, 0x41, 0x13, 0xc0,
|
||||
0xf1, 0x4a, 0xa5, 0x0a, 0xbc, 0x99, 0xcf, 0xb1, 0x35, 0x1c, 0x92, 0x17,
|
||||
0x6a, 0x5b, 0xe5, 0xbb, 0x20, 0x34, 0x41, 0x87, 0x26, 0x01, 0x00, 0x16,
|
||||
0x7a, 0xfe, 0x80, 0x13, 0x32, 0x8e, 0xaf, 0x67, 0x7a, 0x32, 0xa9, 0x58,
|
||||
0x14, 0xe0, 0xf2, 0x4a, 0x17, 0xb6, 0xf3, 0x6e, 0xe6, 0x73, 0xdc, 0xcc,
|
||||
0xe7, 0x8d, 0x2f, 0x68, 0x26, 0xa2, 0x98, 0x77, 0x3f, 0x9d, 0x5c, 0x75,
|
||||
0x6d, 0x16, 0x00, 0x98, 0x26, 0xc1, 0x85, 0x36, 0x84, 0x0f, 0x24, 0x38,
|
||||
0x81, 0x0f, 0x0f, 0x9e, 0xca, 0xf7, 0x7f, 0xbc, 0x7e, 0xa5, 0x7e, 0xe4,
|
||||
0x0c, 0x4f, 0x04, 0x09, 0xb4, 0xef, 0x54, 0x11, 0xd6, 0x75, 0x4c, 0x02,
|
||||
0xe9, 0x20, 0x06, 0x0e, 0x62, 0xc9, 0xda, 0x57, 0x59, 0x9c, 0xc0, 0x87,
|
||||
0x07, 0x4f, 0xe5, 0x8b, 0xfa, 0x4c, 0x47, 0x8d, 0xc2, 0x2f, 0x00, 0x43,
|
||||
0x13, 0x24, 0x94, 0x97, 0xa3, 0x87, 0x9f, 0x47, 0x6b, 0x80, 0x3f, 0x5e,
|
||||
0xbf, 0x62, 0x0b, 0x5c, 0xff, 0x9e, 0x82, 0x4f, 0x55, 0xf8, 0x02, 0xa4,
|
||||
0x26, 0x60, 0xa6, 0x91, 0x7d, 0x73, 0x1e, 0x59, 0x7d, 0x1b, 0xa3, 0x01,
|
||||
0xa2, 0x85, 0xb6, 0x16, 0x3e, 0x89, 0x50, 0x9f, 0xc0, 0x78, 0xca, 0x47,
|
||||
0xe7, 0x17, 0x18, 0x9d, 0x5f, 0xe8, 0x39, 0x03, 0x96, 0x26, 0x88, 0x35,
|
||||
0x01, 0x03, 0xc0, 0x10, 0xa8, 0x13, 0x6b, 0xe1, 0x3b, 0xe1, 0x25, 0x01,
|
||||
0x95, 0x27, 0x10, 0x82, 0x17, 0x18, 0x5f, 0xcf, 0x82, 0xa7, 0xae, 0x25,
|
||||
0x67, 0x02, 0x6d, 0xa6, 0xc0, 0x81, 0xb5, 0xf0, 0x69, 0x90, 0x19, 0x54,
|
||||
0xd5, 0x1c, 0x70, 0xa6, 0xb0, 0x87, 0x4e, 0x58, 0x4d, 0x71, 0x02, 0x65,
|
||||
0xd8, 0xe6, 0xd3, 0x04, 0xca, 0xe7, 0x6b, 0xe1, 0xbb, 0x31, 0x00, 0xcc,
|
||||
0x41, 0x29, 0x5c, 0xc7, 0x30, 0x26, 0x54, 0x6c, 0xbd, 0x1a, 0x18, 0x62,
|
||||
0x26, 0xd6, 0x00, 0xe0, 0x20, 0x41, 0x42, 0x45, 0xd1, 0x0a, 0x1f, 0x01,
|
||||
0xf4, 0xf0, 0xc2, 0x99, 0xec, 0xd1, 0xb1, 0xb6, 0xfb, 0x69, 0xa0, 0x86,
|
||||
0xa7, 0x51, 0x24, 0x78, 0xf2, 0xc3, 0xb7, 0xae, 0xa1, 0xe7, 0x4e, 0xb8,
|
||||
0x08, 0xe0, 0x0b, 0x33, 0x42, 0xe2, 0xcd, 0x2a, 0x84, 0x3f, 0x9b, 0x5e,
|
||||
0x37, 0xc6, 0x1b, 0x54, 0x0c, 0xef, 0x6a, 0x26, 0x82, 0x08, 0xa9, 0x19,
|
||||
0x42, 0xaf, 0x13, 0xa8, 0x17, 0x72, 0x6e, 0xe6, 0x73, 0x43, 0xad, 0x7b,
|
||||
0x92, 0x3d, 0x55, 0x08, 0x5f, 0x85, 0x6b, 0xf4, 0x51, 0x45, 0x18, 0xe0,
|
||||
0x43, 0xdd, 0xc0, 0x35, 0x57, 0x51, 0x3b, 0x3f, 0x18, 0xc1, 0x51, 0xc0,
|
||||
0xd6, 0x70, 0x88, 0x83, 0xc3, 0xe7, 0x46, 0x5e, 0x5f, 0x45, 0x5f, 0xec,
|
||||
0x3e, 0x77, 0x2c, 0x62, 0x69, 0x44, 0xa4, 0x8b, 0xd9, 0x88, 0x0e, 0x03,
|
||||
0x45, 0x75, 0xcf, 0x45, 0x04, 0x54, 0xf8, 0xf4, 0xeb, 0xa8, 0x5c, 0x1b,
|
||||
0x38, 0x07, 0xd7, 0x58, 0xe0, 0x3a, 0xdf, 0x90, 0x87, 0xcb, 0x07, 0x18,
|
||||
0x00, 0xcb, 0x8a, 0x9d, 0x6d, 0x60, 0x07, 0xb0, 0x24, 0x82, 0x5a, 0xea,
|
||||
0xed, 0xcb, 0xd3, 0xaf, 0xa3, 0x62, 0xff, 0x80, 0x8c, 0x0a, 0x08, 0x70,
|
||||
0xfc, 0x32, 0xe3, 0x73, 0x9f, 0x06, 0x90, 0x0c, 0x14, 0x24, 0xb0, 0x0d,
|
||||
0xee, 0xd8, 0x1a, 0x0e, 0x75, 0x6d, 0x50, 0xfd, 0xd3, 0xbf, 0x0a, 0x38,
|
||||
0x1d, 0xbd, 0x31, 0xc8, 0x41, 0x25, 0x8c, 0x6c, 0xb3, 0x93, 0x38, 0x26,
|
||||
0xa0, 0xa1, 0x86, 0x5e, 0xbf, 0xfc, 0xd5, 0x4a, 0x82, 0xbe, 0x3e, 0xfd,
|
||||
0x3d, 0x80, 0xd3, 0x21, 0xe4, 0x4c, 0x4c, 0xb1, 0x81, 0x9b, 0x08, 0x0a,
|
||||
0x1d, 0xac, 0xb1, 0x7e, 0xfa, 0x0b, 0x43, 0x8d, 0x10, 0x5c, 0x73, 0x13,
|
||||
0xab, 0x9b, 0x1d, 0xbc, 0x46, 0x3e, 0x4c, 0x2e, 0xc7, 0xde, 0x3c, 0x41,
|
||||
0x48, 0x14, 0xe0, 0x74, 0x30, 0x14, 0x47, 0xb1, 0xda, 0xa7, 0x5f, 0x1d,
|
||||
0x89, 0xcc, 0x9d, 0x9f, 0x50, 0x11, 0xbc, 0x79, 0x01, 0x15, 0x84, 0xd3,
|
||||
0x48, 0xca, 0x45, 0x27, 0x40, 0xaf, 0x56, 0xb8, 0x4a, 0x81, 0x20, 0x43,
|
||||
0x0f, 0x89, 0xe0, 0x04, 0x57, 0xf0, 0x02, 0xaa, 0x09, 0x60, 0x09, 0xff,
|
||||
0xf0, 0xf8, 0x85, 0xd1, 0x69, 0xae, 0x30, 0xb1, 0x26, 0x50, 0x39, 0x0b,
|
||||
0x6a, 0x7e, 0x42, 0xc5, 0xe0, 0x86, 0x84, 0xe2, 0x5c, 0xaf, 0x36, 0x36,
|
||||
0x4c, 0x00, 0x35, 0x7f, 0x8f, 0x82, 0x20, 0x81, 0xd6, 0x81, 0xd5, 0xaa,
|
||||
0x7f, 0x01, 0x41, 0x02, 0x35, 0x77, 0xe1, 0x9b, 0xad, 0xb4, 0xca, 0x48,
|
||||
0x76, 0x02, 0xfb, 0xda, 0x71, 0xba, 0x36, 0xe8, 0x99, 0x26, 0xe0, 0x20,
|
||||
0x6e, 0x48, 0xd8, 0xcb, 0x93, 0x9f, 0x6b, 0x4d, 0x8b, 0x66, 0xc7, 0x27,
|
||||
0x42, 0x02, 0x67, 0x49, 0x5f, 0x25, 0x80, 0x54, 0xdf, 0x27, 0x47, 0xcf,
|
||||
0xd8, 0x24, 0x50, 0x66, 0xf6, 0x54, 0xaf, 0xfe, 0x29, 0x50, 0x13, 0x56,
|
||||
0x2a, 0x87, 0xd3, 0x0f, 0x08, 0x5d, 0xd2, 0x56, 0xf7, 0x01, 0x64, 0xd6,
|
||||
0x4f, 0x9d, 0x97, 0xcf, 0xf5, 0x0b, 0xfa, 0x0c, 0xd7, 0xf4, 0xb5, 0xbe,
|
||||
0xc1, 0x47, 0x02, 0x95, 0x3c, 0x94, 0x0f, 0x60, 0x78, 0x8f, 0xc4, 0xfc,
|
||||
0xbd, 0x95, 0x44, 0xcf, 0x34, 0x41, 0x16, 0xf8, 0xaa, 0x81, 0xbd, 0x54,
|
||||
0xeb, 0x6b, 0xd8, 0xa1, 0x9b, 0x0e, 0x76, 0x14, 0xf0, 0xa9, 0x38, 0x86,
|
||||
0xab, 0x0c, 0x4d, 0xf8, 0x03, 0xc0, 0x9f, 0x0a, 0x6e, 0x84, 0x12, 0xdb,
|
||||
0x3b, 0xbb, 0xae, 0x9a, 0xf9, 0xaa, 0x65, 0x11, 0xab, 0xbf, 0x1f, 0xce,
|
||||
0x6a, 0x27, 0x16, 0x67, 0x51, 0x6a, 0x76, 0x5d, 0x03, 0x78, 0x27, 0x19,
|
||||
0xea, 0x9a, 0xa0, 0x2f, 0x0e, 0x22, 0x77, 0xf2, 0x4a, 0xe0, 0x24, 0x97,
|
||||
0x62, 0x10, 0x8b, 0x5d, 0xb8, 0x66, 0x34, 0x5b, 0xd2, 0xc2, 0x03, 0xfd,
|
||||
0x00, 0xe0, 0x61, 0xbb, 0x6d, 0x25, 0xcf, 0xd8, 0x11, 0x34, 0xa9, 0xf1,
|
||||
0x76, 0xd7, 0xce, 0x9a, 0x2b, 0x3a, 0xc8, 0x99, 0x08, 0x4b, 0x31, 0xb3,
|
||||
0xba, 0x26, 0xa0, 0xd4, 0x3d, 0x85, 0xcf, 0xc1, 0x58, 0x8f, 0xdf, 0x06,
|
||||
0xd1, 0xe0, 0x50, 0x22, 0x0c, 0xb7, 0x77, 0x92, 0x48, 0xc0, 0x1c, 0x8f,
|
||||
0x98, 0x0d, 0xae, 0x10, 0x31, 0x67, 0x1a, 0x39, 0x65, 0x7c, 0xa2, 0x63,
|
||||
0xb5, 0x13, 0x5e, 0x31, 0x28, 0x65, 0xbd, 0xde, 0x98, 0x06, 0xe7, 0xe8,
|
||||
0xb4, 0x2e, 0xe3, 0x76, 0x17, 0xd9, 0x72, 0x67, 0x10, 0x53, 0xc6, 0x26,
|
||||
0x12, 0x26, 0xc1, 0xa9, 0xdd, 0xb3, 0x0d, 0x08, 0xd9, 0xde, 0xd9, 0x0d,
|
||||
0x26, 0x42, 0x2e, 0x12, 0x74, 0x45, 0x84, 0x9e, 0x93, 0x80, 0xf4, 0xeb,
|
||||
0x0c, 0x1f, 0x20, 0xd7, 0xd2, 0xed, 0xa1, 0x37, 0x90, 0xa3, 0x03, 0xbb,
|
||||
0xf4, 0x0d, 0x7c, 0xa4, 0xcb, 0x65, 0x16, 0x52, 0xfc, 0x02, 0xcf, 0x4a,
|
||||
0xea, 0x03, 0xf9, 0xcf, 0x07, 0x90, 0xaa, 0x22, 0x85, 0x10, 0x31, 0x2c,
|
||||
0xee, 0x93, 0x83, 0xd8, 0x07, 0x12, 0x00, 0x4d, 0xbf, 0x40, 0x77, 0x0e,
|
||||
0xd9, 0x4b, 0xab, 0xaf, 0x89, 0x40, 0xa3, 0x0f, 0x11, 0x02, 0x60, 0x27,
|
||||
0x81, 0xab, 0x16, 0x90, 0x2d, 0x0d, 0x5c, 0xca, 0x3f, 0xe8, 0x02, 0xae,
|
||||
0x6a, 0xa2, 0x58, 0x11, 0x35, 0x87, 0x79, 0x4b, 0x9d, 0xb4, 0xa2, 0xfa,
|
||||
0x05, 0x6a, 0xb1, 0xc8, 0xe7, 0x04, 0x66, 0xad, 0x05, 0xc4, 0x90, 0x40,
|
||||
0xbc, 0x42, 0xd1, 0x75, 0x65, 0xcf, 0xa7, 0x71, 0x72, 0x10, 0x21, 0x07,
|
||||
0x09, 0xa6, 0x93, 0xab, 0x86, 0x06, 0x08, 0x4a, 0x05, 0xdb, 0x10, 0xb2,
|
||||
0x6d, 0x4b, 0x0e, 0xb8, 0x96, 0x9e, 0x55, 0x41, 0xcc, 0x56, 0x02, 0xd0,
|
||||
0x9c, 0xc0, 0x92, 0x9a, 0xf9, 0x2b, 0x35, 0x19, 0x86, 0x6b, 0x92, 0x7d,
|
||||
0x8e, 0xa0, 0x4d, 0x03, 0xb0, 0xe7, 0xff, 0x77, 0x2d, 0x7c, 0x20, 0x6c,
|
||||
0x10, 0xaa, 0x6f, 0xee, 0x62, 0x8a, 0x00, 0x4b, 0xce, 0x84, 0xe2, 0xf4,
|
||||
0xbb, 0x67, 0x87, 0x95, 0x01, 0x60, 0xaf, 0x05, 0x34, 0xc0, 0x64, 0xdb,
|
||||
0xa0, 0x83, 0x57, 0x34, 0xb6, 0x86, 0x43, 0xeb, 0x8a, 0x25, 0x99, 0x04,
|
||||
0xd9, 0xc5, 0xfd, 0x37, 0xfa, 0xc1, 0x65, 0x12, 0x88, 0x9d, 0x58, 0xc9,
|
||||
0x7e, 0x54, 0x4d, 0x80, 0xb1, 0x9a, 0x75, 0xa9, 0x7d, 0xf8, 0x2c, 0x90,
|
||||
0xed, 0x3b, 0x3c, 0x7e, 0x11, 0x6c, 0x4f, 0x89, 0x75, 0x89, 0xc5, 0xff,
|
||||
0x0b, 0x20, 0x6a, 0xb5, 0x33, 0x3c, 0x3c, 0x78, 0xaa, 0x92, 0xa7, 0xb3,
|
||||
0xdd, 0x3e, 0x55, 0x30, 0xd6, 0x38, 0x60, 0xa5, 0x82, 0x17, 0xc0, 0x52,
|
||||
0xf0, 0xaa, 0x87, 0x58, 0x6a, 0x3b, 0x56, 0x02, 0x0d, 0xe1, 0x03, 0x08,
|
||||
0x72, 0x0e, 0x2d, 0xc2, 0x37, 0xfe, 0x8e, 0xd1, 0x04, 0x1a, 0x69, 0x8a,
|
||||
0x94, 0x90, 0x53, 0x9c, 0x43, 0x6f, 0x2a, 0x78, 0x67, 0xef, 0x6e, 0x69,
|
||||
0x22, 0x18, 0xc2, 0x57, 0xe1, 0x23, 0x82, 0x47, 0xf8, 0xc6, 0xf1, 0xbe,
|
||||
0x92, 0xc0, 0x01, 0xa7, 0x3f, 0xc7, 0xae, 0x05, 0x14, 0x22, 0x81, 0x53,
|
||||
0xf8, 0x2a, 0x28, 0x12, 0x30, 0x85, 0x6f, 0x7c, 0xde, 0x47, 0x12, 0xe8,
|
||||
0x5a, 0xe0, 0xf8, 0xf4, 0x8c, 0xb5, 0x17, 0x33, 0x6b, 0x3c, 0x80, 0xc0,
|
||||
0xe9, 0xe8, 0x0d, 0xe9, 0x17, 0x28, 0x0e, 0x47, 0x4e, 0x1b, 0x48, 0xd6,
|
||||
0x27, 0x5c, 0xea, 0x4e, 0xf5, 0x0b, 0x02, 0x85, 0x4f, 0xfe, 0x6e, 0x4c,
|
||||
0x88, 0xd8, 0xc1, 0xd2, 0x78, 0xce, 0x87, 0xc2, 0xe6, 0x0f, 0x10, 0x4e,
|
||||
0x21, 0x80, 0x8f, 0x1a, 0x80, 0xd5, 0xd0, 0xa3, 0x27, 0x8f, 0xbb, 0xd2,
|
||||
0x04, 0xd6, 0xe2, 0x94, 0x2b, 0xab, 0x28, 0xcc, 0x41, 0x82, 0xf0, 0x1b,
|
||||
0xe7, 0xd7, 0xac, 0x09, 0x6c, 0x1a, 0xd1, 0xf6, 0x80, 0x10, 0xda, 0x00,
|
||||
0x80, 0x39, 0x31, 0x84, 0x15, 0x7e, 0xb5, 0xec, 0x17, 0xb0, 0x2a, 0x93,
|
||||
0x36, 0x12, 0x64, 0xda, 0x7b, 0xa8, 0x17, 0x24, 0xb0, 0x81, 0x49, 0x02,
|
||||
0x00, 0x61, 0x2b, 0x84, 0x18, 0x68, 0x81, 0x08, 0x41, 0x65, 0x69, 0x5d,
|
||||
0x1b, 0x64, 0xde, 0x78, 0x6a, 0x25, 0x49, 0xa0, 0x23, 0xd8, 0x36, 0xda,
|
||||
0x66, 0x9d, 0x64, 0xd8, 0x6d, 0x2b, 0x69, 0x4c, 0x82, 0xcd, 0xc6, 0x65,
|
||||
0x40, 0xdb, 0x3e, 0x41, 0x48, 0xfe, 0x60, 0x01, 0xb8, 0x1d, 0xe2, 0x80,
|
||||
0x49, 0x3c, 0x64, 0x26, 0xd0, 0xf6, 0xa3, 0x6d, 0x33, 0xb8, 0x56, 0xe1,
|
||||
0x37, 0xae, 0xd7, 0x82, 0x26, 0x58, 0x58, 0x8e, 0x47, 0x21, 0x54, 0xf8,
|
||||
0x80, 0x7f, 0xad, 0xe0, 0x46, 0xc3, 0x5c, 0x73, 0xce, 0x94, 0xcf, 0xa2,
|
||||
0x17, 0x36, 0xac, 0x50, 0xf8, 0xc6, 0x75, 0x33, 0x92, 0x20, 0xe7, 0x02,
|
||||
0x90, 0x14, 0x58, 0x3e, 0x9d, 0xab, 0x18, 0x04, 0xe0, 0xe3, 0xae, 0x14,
|
||||
0x9c, 0xcd, 0x0a, 0x22, 0xd0, 0x07, 0xe1, 0x1b, 0xd7, 0x2f, 0xe9, 0x13,
|
||||
0x30, 0x2b, 0xa1, 0xec, 0xbe, 0xa0, 0x08, 0xd0, 0x10, 0xbe, 0x8a, 0xbd,
|
||||
0x7b, 0xfb, 0xec, 0xf5, 0xe7, 0x18, 0xe8, 0x93, 0xf0, 0x8d, 0xdf, 0x89,
|
||||
0x21, 0xc1, 0xd3, 0x1f, 0x7f, 0x72, 0xfe, 0xcd, 0x45, 0xce, 0x01, 0xa8,
|
||||
0xd6, 0x21, 0x61, 0xbe, 0x27, 0xde, 0xb6, 0x79, 0x01, 0xd3, 0x19, 0xec,
|
||||
0xa3, 0xf0, 0x55, 0x44, 0x3b, 0x86, 0x7b, 0xbb, 0xcd, 0xf0, 0xf5, 0xd5,
|
||||
0x6f, 0xbf, 0x88, 0xb7, 0xde, 0xfe, 0x52, 0x9f, 0x7e, 0x2a, 0xf3, 0x19,
|
||||
0xb3, 0x0b, 0x6b, 0xd0, 0x62, 0xd1, 0xfa, 0x82, 0x83, 0xa3, 0xf3, 0x8b,
|
||||
0x98, 0x7d, 0xee, 0xfa, 0x2e, 0x7c, 0xf1, 0xbb, 0x51, 0x55, 0xc4, 0xc9,
|
||||
0xf5, 0x32, 0x3c, 0xd3, 0x89, 0x80, 0xc0, 0x6a, 0x22, 0x35, 0x21, 0x45,
|
||||
0x44, 0x07, 0x0a, 0x11, 0xbc, 0xd7, 0x64, 0x0f, 0x0a, 0xb5, 0x81, 0x22,
|
||||
0x81, 0x43, 0x0b, 0xac, 0x82, 0xf0, 0x55, 0x24, 0x85, 0x88, 0x82, 0x04,
|
||||
0x1e, 0x2d, 0x60, 0x3c, 0xfd, 0x3a, 0x18, 0xda, 0xc0, 0xda, 0x57, 0xb6,
|
||||
0x41, 0xa1, 0x2e, 0x18, 0x9f, 0x3b, 0xfc, 0x02, 0x72, 0x7b, 0x99, 0xd3,
|
||||
0xd1, 0x9b, 0xe0, 0x24, 0x52, 0x85, 0xc2, 0x07, 0xf2, 0x0f, 0x2a, 0xd1,
|
||||
0x21, 0xfb, 0x2c, 0x74, 0x52, 0x8a, 0x96, 0x2b, 0x08, 0xae, 0x06, 0xfa,
|
||||
0x42, 0x08, 0x27, 0x09, 0x88, 0x70, 0xd1, 0x18, 0x6c, 0x22, 0xc0, 0x21,
|
||||
0x42, 0xa5, 0xc2, 0x17, 0x68, 0x9b, 0x04, 0x52, 0xbb, 0x24, 0x92, 0x80,
|
||||
0x44, 0x4a, 0x67, 0x5a, 0x9d, 0x45, 0x61, 0x12, 0xf4, 0xe9, 0xc9, 0x9c,
|
||||
0x05, 0x8c, 0xf4, 0x6a, 0x63, 0xe5, 0xc2, 0x57, 0x21, 0x49, 0xfe, 0xf4,
|
||||
0xc7, 0x9f, 0xa4, 0xad, 0xf7, 0xc1, 0x61, 0x06, 0xac, 0xe6, 0x45, 0x8c,
|
||||
0x71, 0xa4, 0xc6, 0x46, 0x1e, 0x1c, 0x3e, 0x6f, 0x98, 0x04, 0xdf, 0x22,
|
||||
0x5e, 0xb1, 0x3b, 0x86, 0x38, 0xfd, 0x04, 0xca, 0x24, 0x70, 0x57, 0xaf,
|
||||
0x12, 0xda, 0x60, 0x3a, 0xb9, 0xea, 0x93, 0xf0, 0x01, 0xc5, 0x31, 0x7c,
|
||||
0xf5, 0xdb, 0x2f, 0x41, 0x24, 0x20, 0xe0, 0xf4, 0x2d, 0xa8, 0x7d, 0x9b,
|
||||
0x04, 0x42, 0x57, 0x6d, 0x8d, 0x21, 0x80, 0x35, 0x4f, 0xa0, 0x23, 0x32,
|
||||
0x4a, 0x00, 0xd0, 0xab, 0x27, 0x5f, 0x85, 0x24, 0x41, 0x02, 0x62, 0x1c,
|
||||
0x4b, 0xdf, 0xb8, 0x8e, 0x20, 0x27, 0xd0, 0x05, 0xb6, 0xf0, 0x05, 0x62,
|
||||
0x92, 0x47, 0xdc, 0xc5, 0x0d, 0x2a, 0x84, 0xec, 0x9f, 0xf7, 0x7f, 0xff,
|
||||
0x8d, 0xbd, 0xdd, 0x5d, 0x2a, 0xdc, 0x6b, 0x40, 0x68, 0x09, 0x3d, 0x29,
|
||||
0x14, 0x21, 0x7c, 0xf1, 0xde, 0x5b, 0xce, 0xb7, 0x7d, 0xd9, 0x87, 0x60,
|
||||
0xe1, 0x53, 0xf0, 0x69, 0x84, 0x55, 0x10, 0xbe, 0x1a, 0xb2, 0xdd, 0xf9,
|
||||
0xec, 0xb3, 0xc6, 0x49, 0x09, 0x66, 0xa1, 0x81, 0x5c, 0xdb, 0xf2, 0x05,
|
||||
0x95, 0x21, 0x01, 0xc8, 0xdd, 0xa9, 0x6f, 0xde, 0xdd, 0x46, 0xff, 0x28,
|
||||
0x23, 0x8b, 0x08, 0xf4, 0x4b, 0xf8, 0x80, 0x43, 0xf5, 0xdb, 0x52, 0xbe,
|
||||
0xa9, 0x64, 0xc8, 0x31, 0xfc, 0x2c, 0x88, 0x00, 0xea, 0xfe, 0xf4, 0x6f,
|
||||
0x6f, 0xdf, 0x03, 0x58, 0x12, 0x81, 0xca, 0x10, 0xfa, 0xe0, 0x48, 0x1e,
|
||||
0x85, 0xb4, 0xab, 0x46, 0x38, 0x7d, 0x00, 0x9d, 0x0c, 0x29, 0x24, 0xe8,
|
||||
0x9c, 0x00, 0x00, 0xf0, 0xaf, 0xff, 0xfc, 0x0f, 0xef, 0xde, 0x2f, 0x85,
|
||||
0xff, 0xfd, 0x37, 0x5f, 0x59, 0xbf, 0x10, 0x52, 0x4b, 0x58, 0x21, 0xe1,
|
||||
0x53, 0x70, 0x6a, 0x86, 0x1c, 0x26, 0x21, 0xc5, 0x1c, 0x44, 0xf9, 0x00,
|
||||
0x9e, 0x6b, 0xb1, 0x8a, 0x49, 0xc0, 0x92, 0x04, 0x2b, 0x2e, 0x7c, 0x0a,
|
||||
0x8d, 0x7e, 0xcc, 0xb1, 0x2c, 0x5d, 0x8a, 0x26, 0x08, 0x09, 0x03, 0xa9,
|
||||
0x10, 0x27, 0x49, 0x60, 0x9f, 0xa0, 0xf0, 0x81, 0xc0, 0xa1, 0xf8, 0x80,
|
||||
0x7f, 0x36, 0xb3, 0x36, 0x45, 0x2d, 0x08, 0xa1, 0x79, 0x80, 0x4f, 0x45,
|
||||
0x48, 0x6d, 0x63, 0x01, 0xf0, 0x9e, 0x7e, 0xd7, 0x6c, 0xe6, 0x1c, 0xda,
|
||||
0x23, 0xb7, 0x40, 0x25, 0xab, 0x85, 0xc3, 0x38, 0xbe, 0x9e, 0x39, 0xbf,
|
||||
0x90, 0xba, 0xfd, 0x79, 0x0f, 0xc1, 0x4e, 0xf4, 0x10, 0xaa, 0x9d, 0xa3,
|
||||
0x35, 0x82, 0xfa, 0x30, 0xe7, 0xbe, 0x81, 0x86, 0xf0, 0x01, 0x60, 0x7f,
|
||||
0x77, 0x1b, 0x5b, 0x9b, 0x1b, 0xd6, 0x2f, 0x69, 0xc3, 0xcd, 0xba, 0x18,
|
||||
0x80, 0x5a, 0x0a, 0x8d, 0x7b, 0x3b, 0x38, 0x7c, 0x1e, 0xb2, 0x8a, 0x89,
|
||||
0x5a, 0x84, 0x73, 0x25, 0x77, 0x82, 0x1f, 0xa0, 0xe8, 0xdd, 0xc3, 0x35,
|
||||
0x90, 0xc2, 0x57, 0xb1, 0xb5, 0xb9, 0xe1, 0xcc, 0x1d, 0x8c, 0xce, 0x2f,
|
||||
0x54, 0x6d, 0x50, 0x64, 0xaa, 0x75, 0x8b, 0x20, 0x93, 0x44, 0x81, 0xdf,
|
||||
0xb7, 0xce, 0x6a, 0x4e, 0x41, 0xae, 0x4e, 0x5e, 0x00, 0xcb, 0x10, 0x11,
|
||||
0x80, 0x0c, 0x13, 0x05, 0xd4, 0x70, 0xd1, 0x17, 0x1d, 0x10, 0xdb, 0x9c,
|
||||
0xf6, 0x99, 0x08, 0x0d, 0x6d, 0xe6, 0x12, 0xbe, 0xad, 0xd4, 0x9b, 0x2b,
|
||||
0xe3, 0x67, 0x43, 0x2b, 0x04, 0x00, 0xe0, 0xcc, 0x15, 0x70, 0x42, 0xc4,
|
||||
0x15, 0xf0, 0x0d, 0xd8, 0xc2, 0x17, 0x28, 0x41, 0x82, 0xd6, 0x08, 0xf0,
|
||||
0xdd, 0xd7, 0x5f, 0x52, 0xbf, 0x15, 0x54, 0x4f, 0xe8, 0xa9, 0x36, 0x68,
|
||||
0x08, 0x5e, 0x0c, 0xca, 0x08, 0x19, 0xc9, 0xab, 0x13, 0xa1, 0xcd, 0x19,
|
||||
0xc7, 0x59, 0x09, 0xc0, 0xfc, 0x8d, 0x05, 0xb0, 0xac, 0x29, 0x70, 0xeb,
|
||||
0x09, 0x96, 0xdd, 0xaf, 0x6b, 0x22, 0x83, 0x71, 0xff, 0xd4, 0x68, 0x1c,
|
||||
0x8a, 0x04, 0x7a, 0xfd, 0x5e, 0x68, 0x0a, 0x07, 0x09, 0xaa, 0x24, 0x00,
|
||||
0x40, 0x93, 0xc0, 0x3a, 0x28, 0x34, 0xa6, 0xa8, 0x54, 0x21, 0x11, 0x9c,
|
||||
0x0b, 0x6a, 0xd9, 0x26, 0x68, 0x0a, 0x22, 0xd8, 0x06, 0x6f, 0x50, 0x24,
|
||||
0x68, 0x8b, 0x00, 0xb9, 0xa2, 0x00, 0x20, 0xa0, 0x61, 0x42, 0xf8, 0x80,
|
||||
0x3f, 0x3a, 0x50, 0x21, 0xcc, 0x86, 0x96, 0x42, 0xce, 0x9a, 0x9d, 0xf4,
|
||||
0xc0, 0xaa, 0xe9, 0x42, 0x46, 0x39, 0x13, 0xfb, 0x25, 0xa8, 0x6d, 0x5e,
|
||||
0x08, 0x62, 0x1c, 0x1c, 0x3e, 0x6f, 0x7d, 0xc9, 0xdb, 0xae, 0x9f, 0x1e,
|
||||
0xa9, 0xfe, 0x75, 0x84, 0x96, 0x97, 0x6d, 0xe3, 0x0e, 0x2d, 0x88, 0xb9,
|
||||
0x4f, 0x6f, 0x3e, 0x82, 0x2b, 0x74, 0x9b, 0x26, 0x70, 0x8c, 0xd7, 0x0b,
|
||||
0x31, 0xa9, 0x49, 0xc8, 0xa9, 0x01, 0x7c, 0x90, 0x37, 0xf5, 0xc5, 0xc6,
|
||||
0x1d, 0x59, 0x4e, 0x06, 0x80, 0x47, 0x0f, 0xee, 0x1b, 0x27, 0xfb, 0x9c,
|
||||
0xc4, 0xbd, 0x7b, 0xfb, 0x98, 0x5c, 0x8e, 0x8d, 0xb1, 0x86, 0x16, 0x42,
|
||||
0x64, 0x4b, 0x2e, 0xc5, 0xcc, 0x67, 0xf0, 0x6c, 0xb6, 0x05, 0x98, 0x71,
|
||||
0xbe, 0x2d, 0xeb, 0x57, 0x6d, 0x14, 0xc0, 0x81, 0x91, 0x2b, 0x78, 0x7b,
|
||||
0xfb, 0x9e, 0x14, 0xbe, 0x40, 0xcc, 0xb8, 0x02, 0x0a, 0x4c, 0x2d, 0x61,
|
||||
0x20, 0xd7, 0xde, 0x09, 0x2a, 0x74, 0x22, 0x94, 0xde, 0x7a, 0xb7, 0x4b,
|
||||
0x0d, 0xd0, 0xc0, 0xe6, 0x9d, 0x3b, 0xfa, 0xa1, 0xe0, 0x2a, 0x19, 0xf0,
|
||||
0x71, 0x04, 0xb2, 0x8b, 0x08, 0xdc, 0x11, 0xc9, 0xb9, 0x17, 0xc6, 0xd4,
|
||||
0x97, 0x6a, 0x3d, 0x3e, 0x3d, 0x8b, 0xde, 0x67, 0xa9, 0x2d, 0xe4, 0xac,
|
||||
0x05, 0x04, 0xe1, 0xbb, 0xaf, 0xbf, 0xb4, 0x0d, 0x28, 0x91, 0x4f, 0x82,
|
||||
0xab, 0x86, 0xa0, 0x23, 0xc7, 0xac, 0xe5, 0x9c, 0xcb, 0xdd, 0x50, 0xeb,
|
||||
0xf4, 0xaa, 0xc7, 0xc4, 0xf2, 0x36, 0x4a, 0xb8, 0x58, 0xa4, 0x06, 0xd2,
|
||||
0xb9, 0x06, 0xb0, 0x24, 0x88, 0xac, 0x10, 0x24, 0xe0, 0x38, 0x89, 0xc2,
|
||||
0x2f, 0x48, 0xc1, 0xce, 0xde, 0xdd, 0xdc, 0x9a, 0xc0, 0xa9, 0xd9, 0x4a,
|
||||
0xef, 0xc8, 0xda, 0x25, 0x01, 0xb8, 0x03, 0x4a, 0xc8, 0x8e, 0xda, 0xda,
|
||||
0xdc, 0x88, 0x72, 0x16, 0x63, 0xa0, 0x4e, 0x4e, 0xc9, 0x88, 0x01, 0x80,
|
||||
0x85, 0xd0, 0x02, 0x6d, 0xf8, 0x17, 0x31, 0xa8, 0x29, 0x9b, 0x26, 0x40,
|
||||
0x86, 0x8a, 0x21, 0xce, 0x62, 0xaa, 0x16, 0x50, 0xe1, 0x99, 0xaa, 0x06,
|
||||
0x80, 0x16, 0xa6, 0x63, 0xf1, 0xcc, 0xc6, 0x0c, 0xe9, 0xd2, 0x13, 0x60,
|
||||
0x8a, 0xf9, 0x00, 0x09, 0xf0, 0x4e, 0x76, 0xc8, 0xb9, 0x92, 0x89, 0xea,
|
||||
0x17, 0x64, 0xda, 0x1b, 0x41, 0xb6, 0xbd, 0xb4, 0xf0, 0x81, 0x82, 0x51,
|
||||
0x40, 0x08, 0x2c, 0x4f, 0xbf, 0x73, 0x84, 0x0c, 0x95, 0x36, 0x66, 0x2c,
|
||||
0x71, 0x47, 0x9e, 0x6b, 0x71, 0x0e, 0xa5, 0x6d, 0x3f, 0x39, 0x7a, 0x16,
|
||||
0xaa, 0xd2, 0xf5, 0xb6, 0x17, 0xd3, 0xc4, 0xd5, 0x6b, 0x00, 0x4d, 0xf8,
|
||||
0x64, 0x47, 0xe9, 0xd1, 0x82, 0xa5, 0x66, 0x40, 0x0a, 0xda, 0x96, 0x23,
|
||||
0xf0, 0xe4, 0x0e, 0x72, 0x08, 0x8c, 0x35, 0x75, 0xab, 0x6d, 0x54, 0x4b,
|
||||
0x80, 0x47, 0x0f, 0xee, 0xb3, 0x84, 0x2f, 0x60, 0x09, 0x19, 0x43, 0x3b,
|
||||
0x38, 0x46, 0x18, 0x03, 0xa0, 0xcc, 0xd6, 0x39, 0x39, 0x50, 0x23, 0x01,
|
||||
0x28, 0x21, 0xb0, 0x04, 0xb3, 0xb5, 0xb9, 0x91, 0x52, 0x31, 0xb4, 0x2e,
|
||||
0x7e, 0xc1, 0x45, 0x1f, 0x49, 0x50, 0xab, 0x0f, 0x90, 0x4b, 0xc5, 0x76,
|
||||
0x05, 0x69, 0xd3, 0xfb, 0x46, 0x82, 0x1a, 0x35, 0x40, 0x34, 0x5c, 0xa1,
|
||||
0x62, 0x20, 0x06, 0x40, 0x70, 0x0d, 0x21, 0x5a, 0x73, 0x95, 0x44, 0xad,
|
||||
0x1a, 0x20, 0x08, 0x84, 0xe0, 0x59, 0x1d, 0x9f, 0x61, 0x81, 0xeb, 0xa8,
|
||||
0xdf, 0xad, 0x09, 0xbd, 0x6b, 0x30, 0x81, 0x90, 0x01, 0x21, 0x8d, 0x15,
|
||||
0xcf, 0x19, 0x04, 0x08, 0x5e, 0x71, 0xa3, 0x6f, 0x58, 0x99, 0x1b, 0x61,
|
||||
0x22, 0xa6, 0xc6, 0xde, 0xe5, 0x88, 0xa3, 0xce, 0xb1, 0x52, 0x37, 0xc3,
|
||||
0x44, 0x15, 0x09, 0x98, 0x5a, 0xf0, 0x7f, 0x84, 0x1d, 0xed, 0xfe, 0xb1,
|
||||
0x2a, 0x47, 0x9d, 0x00, 0x00, 0x00, 0x00, 0x49, 0x45, 0x4e, 0x44, 0xae,
|
||||
0x42, 0x60, 0x82
|
||||
};
|
||||
unsigned int icon_png_len = 3699;
|
||||
117
source/midi.c
117
source/midi.c
@@ -1,117 +0,0 @@
|
||||
#include "midi.h"
|
||||
#include <stdio.h>
|
||||
#include <poll.h>
|
||||
#include <stdatomic.h>
|
||||
#include <alloca.h>
|
||||
|
||||
extern atomic_int gRunning;
|
||||
|
||||
int midiInit(MidiState *m, Synth *synth)
|
||||
{
|
||||
if (snd_seq_open(&m->seq, "default", SND_SEQ_OPEN_INPUT | SND_SEQ_NONBLOCK, 0) < 0) {
|
||||
fprintf(stderr, "Failed to open ALSA sequencer\n");
|
||||
return 0;
|
||||
}
|
||||
snd_seq_nonblock(m->seq, 1);
|
||||
snd_seq_set_client_name(m->seq, "soundThing");
|
||||
m->client = snd_seq_client_id(m->seq);
|
||||
m->port = snd_seq_create_simple_port(m->seq, "MIDI In",
|
||||
SND_SEQ_PORT_CAP_WRITE | SND_SEQ_PORT_CAP_SUBS_WRITE,
|
||||
SND_SEQ_PORT_TYPE_APPLICATION);
|
||||
m->synth = synth;
|
||||
return 1;
|
||||
}
|
||||
|
||||
void midiListInputs(MidiState *m)
|
||||
{
|
||||
snd_seq_client_info_t *cinfo;
|
||||
snd_seq_port_info_t *pinfo;
|
||||
snd_seq_client_info_alloca(&cinfo);
|
||||
snd_seq_port_info_alloca(&pinfo);
|
||||
|
||||
printf("\nAvailable MIDI inputs:\n");
|
||||
snd_seq_client_info_set_client(cinfo, -1);
|
||||
while (snd_seq_query_next_client(m->seq, cinfo) >= 0) {
|
||||
int client = snd_seq_client_info_get_client(cinfo);
|
||||
if (client == m->client) continue;
|
||||
|
||||
snd_seq_port_info_set_client(pinfo, client);
|
||||
snd_seq_port_info_set_port(pinfo, -1);
|
||||
while (snd_seq_query_next_port(m->seq, pinfo) >= 0) {
|
||||
unsigned int caps = snd_seq_port_info_get_capability(pinfo);
|
||||
if (caps & SND_SEQ_PORT_CAP_READ && caps & SND_SEQ_PORT_CAP_SUBS_READ) {
|
||||
printf(" [%d:%d] %s — %s\n",
|
||||
client,
|
||||
snd_seq_port_info_get_port(pinfo),
|
||||
snd_seq_client_info_get_name(cinfo),
|
||||
snd_seq_port_info_get_name(pinfo));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void midiConnect(MidiState *m, int srcClient, int srcPort)
|
||||
{
|
||||
snd_seq_port_subscribe_t *sub;
|
||||
snd_seq_addr_t sender, dest;
|
||||
|
||||
sender.client = srcClient;
|
||||
sender.port = srcPort;
|
||||
dest.client = m->client;
|
||||
dest.port = m->port;
|
||||
|
||||
snd_seq_port_subscribe_alloca(&sub);
|
||||
snd_seq_port_subscribe_set_sender(sub, &sender);
|
||||
snd_seq_port_subscribe_set_dest(sub, &dest);
|
||||
snd_seq_subscribe_port(m->seq, sub);
|
||||
|
||||
printf("Connected [%d:%d] to Cricket\n", srcClient, srcPort);
|
||||
}
|
||||
|
||||
void midiClose(MidiState *m)
|
||||
{
|
||||
snd_seq_close(m->seq);
|
||||
}
|
||||
|
||||
void *midiThread(void *arg)
|
||||
{
|
||||
MidiState *m = (MidiState *)arg;
|
||||
struct pollfd pfd;
|
||||
snd_seq_poll_descriptors(m->seq, &pfd, 1, POLLIN);
|
||||
|
||||
while (gRunning) {
|
||||
int ready = poll(&pfd, 1, 50);
|
||||
if (ready <= 0) continue;
|
||||
|
||||
snd_seq_event_t *ev = NULL;
|
||||
while (snd_seq_event_input(m->seq, &ev) >= 0 && ev) {
|
||||
switch (ev->type) {
|
||||
case SND_SEQ_EVENT_NOTEON:
|
||||
if (ev->data.note.velocity == 0)
|
||||
synthNoteOff(m->synth, ev->data.note.note);
|
||||
else
|
||||
synthNoteOn(m->synth, ev->data.note.note);
|
||||
break;
|
||||
case SND_SEQ_EVENT_NOTEOFF:
|
||||
synthNoteOff(m->synth, ev->data.note.note);
|
||||
break;
|
||||
case SND_SEQ_EVENT_CONTROLLER:
|
||||
// This are controller parameter changes.
|
||||
// Map the Mod Wheel to PWM:
|
||||
if (ev->data.control.param == 1)
|
||||
m->synth->dutyCycle = 0.05f + (ev->data.control.value / 127.0f) * 0.90f;
|
||||
// This naively maps parameter 70 to the waveform in a way that does not play so nice with real pots.
|
||||
if (ev->data.control.param == 70)
|
||||
m->synth->waveform = ev->data.control.value % WAVE_COUNT;
|
||||
break;
|
||||
case SND_SEQ_EVENT_PITCHBEND:
|
||||
m->synth->pitchBend = ev->data.control.value / 8191.0f;
|
||||
break;
|
||||
|
||||
}
|
||||
snd_seq_free_event(ev);
|
||||
ev = NULL;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
157
source/midi_linux.c
Normal file
157
source/midi_linux.c
Normal file
@@ -0,0 +1,157 @@
|
||||
#include "midi.h"
|
||||
#include <stdio.h>
|
||||
#include <poll.h>
|
||||
#include <stdatomic.h>
|
||||
#include <alloca.h>
|
||||
|
||||
extern atomic_int gRunning;
|
||||
|
||||
int midiInit(MidiState *m, Synth *synth)
|
||||
{
|
||||
if (snd_seq_open(&m->seq, "default", SND_SEQ_OPEN_INPUT | SND_SEQ_NONBLOCK, 0) < 0) {
|
||||
fprintf(stderr, "Failed to open ALSA sequencer\n");
|
||||
return 0;
|
||||
}
|
||||
snd_seq_nonblock(m->seq, 1);
|
||||
snd_seq_set_client_name(m->seq, "soundThing");
|
||||
m->client = snd_seq_client_id(m->seq);
|
||||
m->port = snd_seq_create_simple_port(m->seq, "MIDI In",
|
||||
SND_SEQ_PORT_CAP_WRITE | SND_SEQ_PORT_CAP_SUBS_WRITE,
|
||||
SND_SEQ_PORT_TYPE_APPLICATION);
|
||||
m->synth = synth;
|
||||
m->connectedClient = -1;
|
||||
m->connectedPort = -1;
|
||||
m->inputCount = 0;
|
||||
atomic_store(&m->midiLearnMode, 0);
|
||||
atomic_store(&m->midiLearnCC, -1);
|
||||
for (int i = 0; i < 128; i++) m->ccMappings[i].active = 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
void midiScanInputs(MidiState *m)
|
||||
{
|
||||
m->inputCount = 0;
|
||||
snd_seq_client_info_t *cinfo;
|
||||
snd_seq_port_info_t *pinfo;
|
||||
snd_seq_client_info_alloca(&cinfo);
|
||||
snd_seq_port_info_alloca(&pinfo);
|
||||
|
||||
snd_seq_client_info_set_client(cinfo, -1);
|
||||
while (snd_seq_query_next_client(m->seq, cinfo) >= 0) {
|
||||
int client = snd_seq_client_info_get_client(cinfo);
|
||||
if (client == m->client) continue;
|
||||
|
||||
snd_seq_port_info_set_client(pinfo, client);
|
||||
snd_seq_port_info_set_port(pinfo, -1);
|
||||
while (snd_seq_query_next_port(m->seq, pinfo) >= 0) {
|
||||
if (m->inputCount >= MIDI_MAX_INPUTS) break;
|
||||
unsigned int caps = snd_seq_port_info_get_capability(pinfo);
|
||||
if ((caps & SND_SEQ_PORT_CAP_READ) && (caps & SND_SEQ_PORT_CAP_SUBS_READ)) {
|
||||
MidiInputInfo *info = &m->inputs[m->inputCount++];
|
||||
info->client = client;
|
||||
info->port = snd_seq_port_info_get_port(pinfo);
|
||||
snprintf(info->clientName, sizeof(info->clientName), "%s",
|
||||
snd_seq_client_info_get_name(cinfo));
|
||||
snprintf(info->portName, sizeof(info->portName), "%s",
|
||||
snd_seq_port_info_get_name(pinfo));
|
||||
}
|
||||
}
|
||||
if (m->inputCount >= MIDI_MAX_INPUTS) break;
|
||||
}
|
||||
}
|
||||
|
||||
void midiDevDisconnect(MidiState *m)
|
||||
{
|
||||
if (m->connectedClient < 0) return;
|
||||
|
||||
snd_seq_port_subscribe_t *sub;
|
||||
snd_seq_addr_t sender, dest;
|
||||
|
||||
sender.client = m->connectedClient;
|
||||
sender.port = m->connectedPort;
|
||||
dest.client = m->client;
|
||||
dest.port = m->port;
|
||||
|
||||
snd_seq_port_subscribe_alloca(&sub);
|
||||
snd_seq_port_subscribe_set_sender(sub, &sender);
|
||||
snd_seq_port_subscribe_set_dest(sub, &dest);
|
||||
snd_seq_unsubscribe_port(m->seq, sub);
|
||||
|
||||
m->connectedClient = -1;
|
||||
m->connectedPort = -1;
|
||||
}
|
||||
|
||||
void midiDevConnect(MidiState *m, int srcClient, int srcPort)
|
||||
{
|
||||
midiDevDisconnect(m);
|
||||
|
||||
snd_seq_port_subscribe_t *sub;
|
||||
snd_seq_addr_t sender, dest;
|
||||
|
||||
sender.client = srcClient;
|
||||
sender.port = srcPort;
|
||||
dest.client = m->client;
|
||||
dest.port = m->port;
|
||||
|
||||
snd_seq_port_subscribe_alloca(&sub);
|
||||
snd_seq_port_subscribe_set_sender(sub, &sender);
|
||||
snd_seq_port_subscribe_set_dest(sub, &dest);
|
||||
snd_seq_subscribe_port(m->seq, sub);
|
||||
|
||||
m->connectedClient = srcClient;
|
||||
m->connectedPort = srcPort;
|
||||
}
|
||||
|
||||
void midiClose(MidiState *m)
|
||||
{
|
||||
midiDevDisconnect(m);
|
||||
snd_seq_close(m->seq);
|
||||
}
|
||||
|
||||
void *midiThread(void *arg)
|
||||
{
|
||||
MidiState *m = (MidiState *)arg;
|
||||
struct pollfd pfd;
|
||||
snd_seq_poll_descriptors(m->seq, &pfd, 1, POLLIN);
|
||||
|
||||
while (gRunning) {
|
||||
int ready = poll(&pfd, 1, 50);
|
||||
if (ready <= 0) continue;
|
||||
|
||||
snd_seq_event_t *ev = NULL;
|
||||
while (snd_seq_event_input(m->seq, &ev) >= 0 && ev) {
|
||||
switch (ev->type) {
|
||||
case SND_SEQ_EVENT_NOTEON:
|
||||
if (ev->data.note.velocity == 0)
|
||||
synthNoteOff(m->synth, ev->data.note.note);
|
||||
else
|
||||
synthNoteOn(m->synth, ev->data.note.note);
|
||||
break;
|
||||
case SND_SEQ_EVENT_NOTEOFF:
|
||||
synthNoteOff(m->synth, ev->data.note.note);
|
||||
break;
|
||||
case SND_SEQ_EVENT_CONTROLLER: {
|
||||
int cc = ev->data.control.param;
|
||||
int val = ev->data.control.value;
|
||||
if (cc < 128) {
|
||||
if (atomic_load(&m->midiLearnMode))
|
||||
atomic_store(&m->midiLearnCC, cc);
|
||||
if (m->ccMappings[cc].active) {
|
||||
float t = (float)val / 127.0f;
|
||||
*m->ccMappings[cc].valuePtr =
|
||||
m->ccMappings[cc].min +
|
||||
t * (m->ccMappings[cc].max - m->ccMappings[cc].min);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case SND_SEQ_EVENT_PITCHBEND:
|
||||
m->synth->pitchBend = ev->data.control.value / 8191.0f;
|
||||
break;
|
||||
}
|
||||
snd_seq_free_event(ev);
|
||||
ev = NULL;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
108
source/midi_windows.c
Normal file
108
source/midi_windows.c
Normal file
@@ -0,0 +1,108 @@
|
||||
#include "midi.h"
|
||||
#include <windows.h>
|
||||
#include <mmsystem.h>
|
||||
#include <stdatomic.h>
|
||||
#include <stdio.h>
|
||||
|
||||
extern atomic_int gRunning;
|
||||
|
||||
static void CALLBACK midiCallbackWin32(HMIDIIN hIn, UINT msg, DWORD_PTR instance,
|
||||
DWORD_PTR param1, DWORD_PTR param2)
|
||||
{
|
||||
(void)hIn; (void)param2;
|
||||
if (msg != MIM_DATA) return;
|
||||
|
||||
MidiState *m = (MidiState *)instance;
|
||||
BYTE status = (BYTE)( param1 & 0xFF);
|
||||
BYTE data1 = (BYTE)((param1 >> 8) & 0xFF);
|
||||
BYTE data2 = (BYTE)((param1 >> 16) & 0xFF);
|
||||
BYTE type = status & 0xF0;
|
||||
|
||||
if (type == 0x90 && data2 > 0) {
|
||||
synthNoteOn(m->synth, data1);
|
||||
} else if (type == 0x80 || (type == 0x90 && data2 == 0)) {
|
||||
synthNoteOff(m->synth, data1);
|
||||
} else if (type == 0xB0) {
|
||||
int cc = data1, val = data2;
|
||||
if (cc < 128) {
|
||||
if (atomic_load(&m->midiLearnMode))
|
||||
atomic_store(&m->midiLearnCC, cc);
|
||||
if (m->ccMappings[cc].active) {
|
||||
float t = (float)val / 127.0f;
|
||||
*m->ccMappings[cc].valuePtr =
|
||||
m->ccMappings[cc].min + t * (m->ccMappings[cc].max - m->ccMappings[cc].min);
|
||||
}
|
||||
}
|
||||
} else if (type == 0xE0) {
|
||||
int pb = (data2 << 7) | data1; // 0..16383, centre = 8192
|
||||
m->synth->pitchBend = (pb - 8192) / 8191.0f;
|
||||
}
|
||||
}
|
||||
|
||||
int midiInit(MidiState *m, Synth *synth)
|
||||
{
|
||||
m->synth = synth;
|
||||
m->hMidiIn = NULL;
|
||||
m->connectedClient = -1;
|
||||
m->connectedPort = -1;
|
||||
m->inputCount = 0;
|
||||
atomic_store(&m->midiLearnMode, 0);
|
||||
atomic_store(&m->midiLearnCC, -1);
|
||||
for (int i = 0; i < 128; i++) m->ccMappings[i].active = 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
void midiScanInputs(MidiState *m)
|
||||
{
|
||||
m->inputCount = 0;
|
||||
UINT n = midiInGetNumDevs();
|
||||
for (UINT i = 0; i < n && m->inputCount < MIDI_MAX_INPUTS; i++) {
|
||||
MIDIINCAPSA caps;
|
||||
if (midiInGetDevCapsA(i, &caps, sizeof(caps)) == MMSYSERR_NOERROR) {
|
||||
MidiInputInfo *info = &m->inputs[m->inputCount++];
|
||||
info->client = (int)i;
|
||||
info->port = 0;
|
||||
snprintf(info->clientName, sizeof(info->clientName), "%s", caps.szPname);
|
||||
snprintf(info->portName, sizeof(info->portName), "%s", caps.szPname);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void midiDevDisconnect(MidiState *m)
|
||||
{
|
||||
if (m->hMidiIn) {
|
||||
midiInStop((HMIDIIN)m->hMidiIn);
|
||||
midiInClose((HMIDIIN)m->hMidiIn);
|
||||
m->hMidiIn = NULL;
|
||||
}
|
||||
m->connectedClient = -1;
|
||||
m->connectedPort = -1;
|
||||
}
|
||||
|
||||
void midiDevConnect(MidiState *m, int srcClient, int srcPort)
|
||||
{
|
||||
(void)srcPort;
|
||||
midiDevDisconnect(m);
|
||||
HMIDIIN hIn = NULL;
|
||||
if (midiInOpen(&hIn, (UINT)srcClient, (DWORD_PTR)midiCallbackWin32,
|
||||
(DWORD_PTR)m, CALLBACK_FUNCTION) == MMSYSERR_NOERROR) {
|
||||
midiInStart(hIn);
|
||||
m->hMidiIn = hIn;
|
||||
m->connectedClient = srcClient;
|
||||
m->connectedPort = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void midiClose(MidiState *m)
|
||||
{
|
||||
midiDevDisconnect(m);
|
||||
}
|
||||
|
||||
void *midiThread(void *arg)
|
||||
{
|
||||
// WinMM delivers MIDI events via midiCallbackWin32 on its own MM thread.
|
||||
// This function exists only to satisfy the pthread_create call in soundThing.c.
|
||||
(void)arg;
|
||||
while (gRunning) Sleep(50);
|
||||
return NULL;
|
||||
}
|
||||
288
source/patch.c
Normal file
288
source/patch.c
Normal file
@@ -0,0 +1,288 @@
|
||||
#define _POSIX_C_SOURCE 200809L
|
||||
#include "patch.h"
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <dirent.h>
|
||||
#ifdef _WIN32
|
||||
# include <direct.h>
|
||||
# include <sys/stat.h>
|
||||
# define MAKE_DIR(p) _mkdir(p)
|
||||
#else
|
||||
# include <sys/stat.h>
|
||||
# define MAKE_DIR(p) mkdir(p, 0755)
|
||||
#endif
|
||||
|
||||
// ------------------------------------------------------------------ HELPERS
|
||||
|
||||
static const char *findValue(const char *json, const char *key)
|
||||
{
|
||||
char pattern[PATCH_NAME_LEN + 4];
|
||||
snprintf(pattern, sizeof(pattern), "\"%s\"", key);
|
||||
const char *p = strstr(json, pattern);
|
||||
if (!p) return NULL;
|
||||
p += strlen(pattern);
|
||||
while (*p && (*p == ' ' || *p == ':' || *p == '\t' || *p == '\n' || *p == '\r')) p++;
|
||||
return p;
|
||||
}
|
||||
|
||||
static int readInt(const char *json, const char *key, int *out)
|
||||
{
|
||||
const char *p = findValue(json, key);
|
||||
if (!p) return 0;
|
||||
*out = (int)strtol(p, NULL, 10);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int readFloat(const char *json, const char *key, float *out)
|
||||
{
|
||||
const char *p = findValue(json, key);
|
||||
if (!p) return 0;
|
||||
*out = strtof(p, NULL);
|
||||
return 1;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------ SAVE
|
||||
|
||||
int patchSave(Synth *s, const char *path)
|
||||
{
|
||||
MAKE_DIR("patches");
|
||||
FILE *f = fopen(path, "w");
|
||||
if (!f) return 0;
|
||||
|
||||
fprintf(f, "{\n");
|
||||
|
||||
for (int o = 0; o < OSC_COUNT; o++) {
|
||||
Oscillator *osc = &s->voices[0].oscillators[o];
|
||||
fprintf(f, " \"osc%d_waveform\": %d,\n", o, (int)osc->waveform);
|
||||
fprintf(f, " \"osc%d_dutyCycle\": %f,\n", o, osc->dutyCycle);
|
||||
fprintf(f, " \"osc%d_detune\": %f,\n", o, osc->detune);
|
||||
fprintf(f, " \"osc%d_gain\": %f,\n", o, osc->gain);
|
||||
fprintf(f, " \"osc%d_active\": %d,\n", o, osc->active);
|
||||
fprintf(f, " \"osc%d_octave\": %d,\n", o, osc->octave);
|
||||
for (int m = 0; m < 3; m++)
|
||||
fprintf(f, " \"osc%d_modRouting%d\": %d,\n", o, m, osc->modRouting[m]);
|
||||
for (int m = 0; m < 3; m++)
|
||||
fprintf(f, " \"osc%d_modDepth%d\": %f,\n", o, m, osc->modDepth[m]);
|
||||
}
|
||||
|
||||
Envelope *ae = &s->voices[0].ampEnv;
|
||||
fprintf(f, " \"ampEnv_attack\": %f,\n", ae->attackSec);
|
||||
fprintf(f, " \"ampEnv_decay\": %f,\n", ae->decaySec);
|
||||
fprintf(f, " \"ampEnv_sustain\": %f,\n", ae->sustainLevel);
|
||||
fprintf(f, " \"ampEnv_release\": %f,\n", ae->releaseSec);
|
||||
|
||||
Envelope *me = &s->voices[0].modEnv;
|
||||
fprintf(f, " \"modEnv_attack\": %f,\n", me->attackSec);
|
||||
fprintf(f, " \"modEnv_decay\": %f,\n", me->decaySec);
|
||||
fprintf(f, " \"modEnv_sustain\": %f,\n", me->sustainLevel);
|
||||
fprintf(f, " \"modEnv_release\": %f,\n", me->releaseSec);
|
||||
|
||||
for (int l = 0; l < LFO_COUNT; l++) {
|
||||
LFO *lfo = &s->lfos[l];
|
||||
fprintf(f, " \"lfo%d_rate\": %f,\n", l, lfo->rate);
|
||||
fprintf(f, " \"lfo%d_waveform\": %d,\n", l, (int)lfo->waveform);
|
||||
fprintf(f, " \"lfo%d_active\": %d,\n", l, lfo->active);
|
||||
}
|
||||
|
||||
Filter *flt = &s->voices[0].filter;
|
||||
fprintf(f, " \"filter_cutoff\": %f,\n", flt->cutoff);
|
||||
fprintf(f, " \"filter_resonance\": %f,\n", flt->resonance);
|
||||
fprintf(f, " \"filter_type\": %d,\n", (int)flt->type);
|
||||
fprintf(f, " \"filter_active\": %d,\n", flt->active);
|
||||
fprintf(f, " \"filter_modRouting\": %d,\n", flt->modRouting);
|
||||
fprintf(f, " \"filter_modDepth\": %f,\n", flt->modDepth);
|
||||
fprintf(f, " \"filter_resModRouting\": %d,\n", flt->resModRouting);
|
||||
fprintf(f, " \"filter_resModDepth\": %f,\n", flt->resModDepth);
|
||||
|
||||
fprintf(f, " \"master_volume\": %f,\n", s->volume);
|
||||
fprintf(f, " \"master_pitchBendRange\": %f\n", s->pitchBendRange);
|
||||
|
||||
fprintf(f, "}\n");
|
||||
fclose(f);
|
||||
return 1;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------ LOAD
|
||||
|
||||
int patchLoad(Synth *s, const char *path)
|
||||
{
|
||||
FILE *f = fopen(path, "r");
|
||||
if (!f) return 0;
|
||||
|
||||
fseek(f, 0, SEEK_END);
|
||||
long size = ftell(f);
|
||||
fseek(f, 0, SEEK_SET);
|
||||
|
||||
char *buf = (char *)malloc((size_t)size + 1);
|
||||
if (!buf) { fclose(f); return 0; }
|
||||
size_t got = fread(buf, 1, (size_t)size, f);
|
||||
buf[got] = '\0';
|
||||
fclose(f);
|
||||
|
||||
int iv;
|
||||
float fv;
|
||||
char key[PATCH_NAME_LEN];
|
||||
|
||||
for (int o = 0; o < OSC_COUNT; o++) {
|
||||
Oscillator *osc = &s->voices[0].oscillators[o];
|
||||
snprintf(key, sizeof(key), "osc%d_waveform", o);
|
||||
if (readInt(buf, key, &iv) && iv >= 0 && iv < WAVE_COUNT)
|
||||
osc->waveform = (Waveform)iv;
|
||||
snprintf(key, sizeof(key), "osc%d_dutyCycle", o);
|
||||
if (readFloat(buf, key, &fv)) osc->dutyCycle = fv;
|
||||
snprintf(key, sizeof(key), "osc%d_detune", o);
|
||||
if (readFloat(buf, key, &fv)) osc->detune = fv;
|
||||
snprintf(key, sizeof(key), "osc%d_gain", o);
|
||||
if (readFloat(buf, key, &fv)) osc->gain = fv;
|
||||
snprintf(key, sizeof(key), "osc%d_active", o);
|
||||
if (readInt(buf, key, &iv)) osc->active = iv;
|
||||
snprintf(key, sizeof(key), "osc%d_octave", o);
|
||||
if (readInt(buf, key, &iv) && iv >= -2 && iv <= 2) osc->octave = iv;
|
||||
for (int m = 0; m < 3; m++) {
|
||||
snprintf(key, sizeof(key), "osc%d_modRouting%d", o, m);
|
||||
if (readInt(buf, key, &iv)) osc->modRouting[m] = iv;
|
||||
snprintf(key, sizeof(key), "osc%d_modDepth%d", o, m);
|
||||
if (readFloat(buf, key, &fv)) osc->modDepth[m] = fv;
|
||||
}
|
||||
}
|
||||
|
||||
Envelope *ae = &s->voices[0].ampEnv;
|
||||
if (readFloat(buf, "ampEnv_attack", &fv)) ae->attackSec = fv;
|
||||
if (readFloat(buf, "ampEnv_decay", &fv)) ae->decaySec = fv;
|
||||
if (readFloat(buf, "ampEnv_sustain", &fv)) ae->sustainLevel = fv;
|
||||
if (readFloat(buf, "ampEnv_release", &fv)) ae->releaseSec = fv;
|
||||
|
||||
Envelope *me = &s->voices[0].modEnv;
|
||||
if (readFloat(buf, "modEnv_attack", &fv)) me->attackSec = fv;
|
||||
if (readFloat(buf, "modEnv_decay", &fv)) me->decaySec = fv;
|
||||
if (readFloat(buf, "modEnv_sustain", &fv)) me->sustainLevel = fv;
|
||||
if (readFloat(buf, "modEnv_release", &fv)) me->releaseSec = fv;
|
||||
|
||||
for (int l = 0; l < LFO_COUNT; l++) {
|
||||
LFO *lfo = &s->lfos[l];
|
||||
snprintf(key, sizeof(key), "lfo%d_rate", l);
|
||||
if (readFloat(buf, key, &fv)) lfo->rate = fv;
|
||||
snprintf(key, sizeof(key), "lfo%d_waveform", l);
|
||||
if (readInt(buf, key, &iv) && iv >= 0 && iv < WAVE_COUNT)
|
||||
lfo->waveform = (Waveform)iv;
|
||||
snprintf(key, sizeof(key), "lfo%d_active", l);
|
||||
if (readInt(buf, key, &iv)) lfo->active = iv;
|
||||
lfo->phase = 0.0f;
|
||||
lfo->noisePhase = 0.0f;
|
||||
}
|
||||
|
||||
Filter *flt = &s->voices[0].filter;
|
||||
if (readFloat(buf, "filter_cutoff", &fv)) flt->cutoff = fv;
|
||||
if (readFloat(buf, "filter_resonance", &fv)) flt->resonance = fv;
|
||||
if (readInt (buf, "filter_type", &iv) && iv >= 0 && iv < FILTER_COUNT)
|
||||
flt->type = (FilterType)iv;
|
||||
if (readInt (buf, "filter_active", &iv)) flt->active = iv;
|
||||
if (readInt (buf, "filter_modRouting", &iv)) flt->modRouting = iv;
|
||||
if (readFloat(buf, "filter_modDepth", &fv)) flt->modDepth = fv;
|
||||
if (readInt (buf, "filter_resModRouting",&iv)) flt->resModRouting = iv;
|
||||
if (readFloat(buf, "filter_resModDepth", &fv)) flt->resModDepth = fv;
|
||||
flt->low = 0.0f;
|
||||
flt->band = 0.0f;
|
||||
|
||||
if (readFloat(buf, "master_volume", &fv)) s->volume = fv;
|
||||
if (readFloat(buf, "master_pitchBendRange", &fv)) s->pitchBendRange = fv;
|
||||
|
||||
free(buf);
|
||||
return 1;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------ FAVORITES
|
||||
|
||||
int patchLoadFavs(char (*favs)[PATCH_NAME_LEN], int maxFavs)
|
||||
{
|
||||
FILE *f = fopen("patches/favorites.txt", "r");
|
||||
if (!f) return 0;
|
||||
int count = 0;
|
||||
while (count < maxFavs && fgets(favs[count], PATCH_NAME_LEN, f)) {
|
||||
size_t len = strlen(favs[count]);
|
||||
if (len > 0 && favs[count][len - 1] == '\n') favs[count][len - 1] = '\0';
|
||||
if (favs[count][0] != '\0') count++;
|
||||
}
|
||||
fclose(f);
|
||||
return count;
|
||||
}
|
||||
|
||||
int patchSaveFavs(char (*favs)[PATCH_NAME_LEN], int favCount)
|
||||
{
|
||||
MAKE_DIR("patches");
|
||||
FILE *f = fopen("patches/favorites.txt", "w");
|
||||
if (!f) return 0;
|
||||
for (int i = 0; i < favCount; i++)
|
||||
fprintf(f, "%s\n", favs[i]);
|
||||
fclose(f);
|
||||
return 1;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------ SCAN
|
||||
|
||||
static int cmpStrings(const void *a, const void *b)
|
||||
{
|
||||
return strcmp((const char *)a, (const char *)b);
|
||||
}
|
||||
|
||||
int patchScanFiles(char (*files)[PATCH_NAME_LEN], int maxFiles)
|
||||
{
|
||||
int count = 0;
|
||||
DIR *d = opendir("patches");
|
||||
if (!d) return 0;
|
||||
|
||||
struct dirent *ent;
|
||||
while ((ent = readdir(d)) != NULL && count < maxFiles) {
|
||||
const char *name = ent->d_name;
|
||||
size_t len = strlen(name);
|
||||
if (len > 5 && strcmp(name + len - 5, ".json") == 0) {
|
||||
snprintf(files[count], PATCH_NAME_LEN, "%.*s", (int)(len - 5), name);
|
||||
count++;
|
||||
}
|
||||
}
|
||||
closedir(d);
|
||||
|
||||
qsort(files, (size_t)count, PATCH_NAME_LEN, cmpStrings);
|
||||
return count;
|
||||
}
|
||||
|
||||
int patchScanDir(const char *relPath,
|
||||
char (*files)[PATCH_NAME_LEN], int maxFiles,
|
||||
char (*dirs)[PATCH_NAME_LEN], int maxDirs, int *outDirCount)
|
||||
{
|
||||
char scanPath[512];
|
||||
if (relPath && relPath[0])
|
||||
snprintf(scanPath, sizeof(scanPath), "patches/%s", relPath);
|
||||
else
|
||||
snprintf(scanPath, sizeof(scanPath), "patches");
|
||||
MAKE_DIR(scanPath);
|
||||
|
||||
int fc = 0, dc = 0;
|
||||
DIR *d = opendir(scanPath);
|
||||
if (!d) { *outDirCount = 0; return 0; }
|
||||
|
||||
struct dirent *ent;
|
||||
while ((ent = readdir(d)) != NULL) {
|
||||
const char *name = ent->d_name;
|
||||
if (name[0] == '.') continue;
|
||||
size_t len = strlen(name);
|
||||
char full[1024];
|
||||
snprintf(full, sizeof(full), "%s/%s", scanPath, name);
|
||||
struct stat st;
|
||||
if (stat(full, &st) != 0) continue;
|
||||
if (S_ISDIR(st.st_mode)) {
|
||||
if (dc < maxDirs)
|
||||
snprintf(dirs[dc++], PATCH_NAME_LEN, "%s", name);
|
||||
} else if (len > 5 && strcmp(name + len - 5, ".json") == 0) {
|
||||
if (fc < maxFiles)
|
||||
snprintf(files[fc++], PATCH_NAME_LEN, "%.*s", (int)(len - 5), name);
|
||||
}
|
||||
}
|
||||
closedir(d);
|
||||
|
||||
qsort(files, (size_t)fc, PATCH_NAME_LEN, cmpStrings);
|
||||
qsort(dirs, (size_t)dc, PATCH_NAME_LEN, cmpStrings);
|
||||
*outDirCount = dc;
|
||||
return fc;
|
||||
}
|
||||
29
source/platform.c
Normal file
29
source/platform.c
Normal file
@@ -0,0 +1,29 @@
|
||||
#define _POSIX_C_SOURCE 200809L
|
||||
/* Isolated from raylib.h to avoid Rectangle/CloseWindow/ShowCursor conflicts
|
||||
with windows.h on Windows cross-compile targets. */
|
||||
#ifdef _WIN32
|
||||
# include <windows.h>
|
||||
# include <direct.h>
|
||||
#else
|
||||
# include <unistd.h>
|
||||
# include <libgen.h>
|
||||
#endif
|
||||
#include <string.h>
|
||||
#include "platform.h"
|
||||
|
||||
void chdirToExeDir(void)
|
||||
{
|
||||
char path[1024];
|
||||
#ifdef _WIN32
|
||||
DWORD len = GetModuleFileNameA(NULL, path, (DWORD)sizeof(path));
|
||||
if (!len) return;
|
||||
char *last = strrchr(path, '\\');
|
||||
if (!last) last = strrchr(path, '/');
|
||||
if (last) { *last = '\0'; _chdir(path); }
|
||||
#else
|
||||
ssize_t len = readlink("/proc/self/exe", path, sizeof(path) - 1);
|
||||
if (len <= 0) return;
|
||||
path[len] = '\0';
|
||||
if (chdir(dirname(path)) != 0) { }
|
||||
#endif
|
||||
}
|
||||
@@ -1,60 +1,60 @@
|
||||
#define _POSIX_C_SOURCE 200809L
|
||||
#include "raylib.h"
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdatomic.h>
|
||||
#include <pthread.h>
|
||||
#include <alloca.h>
|
||||
#include <alsa/asoundlib.h>
|
||||
#include "raylib.h"
|
||||
#include "synth.h"
|
||||
#include "midi.h"
|
||||
#include "ui.h"
|
||||
#include "config.h"
|
||||
#include "icon_data.h"
|
||||
#include "platform.h"
|
||||
|
||||
#define LOGICAL_WIDTH 1020
|
||||
#define LOGICAL_HEIGHT 710
|
||||
#define BORDER_WIDTH 8
|
||||
|
||||
atomic_int gRunning = 1;
|
||||
|
||||
static Synth gSynth = {0};
|
||||
static MidiState gMidi = {0};
|
||||
static UIState gUI = {0};
|
||||
|
||||
static void AudioOutputCallback(void *buffer, unsigned int frames)
|
||||
{
|
||||
synthFillBuffer(&gSynth, (int16_t *)buffer, (int)frames);
|
||||
}
|
||||
|
||||
static void drawWaveform(Waveform w, float dutyCycle, int x, int y, int width, int height)
|
||||
{
|
||||
int steps = width;
|
||||
for (int i = 0; i < steps - 1; i++) {
|
||||
float phase0 = (float)i / steps;
|
||||
float phase1 = (float)(i + 1) / steps;
|
||||
float s0 = waveformSample(w, phase0, dutyCycle);
|
||||
float s1 = waveformSample(w, phase1, dutyCycle);
|
||||
|
||||
int cx = x + i;
|
||||
int cy = y + (int)((1.0f - (s0 * 0.5f + 0.5f)) * height);
|
||||
int nx = x + i + 1;
|
||||
int ny = y + (int)((1.0f - (s1 * 0.5f + 0.5f)) * height);
|
||||
|
||||
DrawLine(cx, cy, nx, ny, GREEN);
|
||||
}
|
||||
DrawRectangleLines(x, y, width, height, DARKGRAY);
|
||||
}
|
||||
|
||||
int main(void)
|
||||
{
|
||||
chdirToExeDir();
|
||||
const int sampleRate = 48000;
|
||||
|
||||
if (!midiInit(&gMidi, &gSynth)) return 1;
|
||||
midiListInputs(&gMidi);
|
||||
|
||||
int srcClient, srcPort;
|
||||
printf("\nEnter client and port to connect (e.g. '20 0'), or -1 -1 to skip: ");
|
||||
if (scanf("%d %d", &srcClient, &srcPort) == 2 && srcClient != -1)
|
||||
midiConnect(&gMidi, srcClient, srcPort);
|
||||
midiScanInputs(&gMidi);
|
||||
|
||||
pthread_t midiTid;
|
||||
pthread_create(&midiTid, NULL, midiThread, &gMidi);
|
||||
|
||||
synthInit(&gSynth, (float)sampleRate);
|
||||
|
||||
InitWindow(800, 450, "SoundThing");
|
||||
// Window setup
|
||||
SetConfigFlags(FLAG_WINDOW_RESIZABLE);
|
||||
InitWindow(LOGICAL_WIDTH + 2 * BORDER_WIDTH, LOGICAL_HEIGHT + 2 * BORDER_WIDTH, "SoundThing");
|
||||
{
|
||||
Image appIcon = LoadImageFromMemory(".png", icon_png, (int)icon_png_len);
|
||||
SetWindowIcon(appIcon);
|
||||
UnloadImage(appIcon);
|
||||
}
|
||||
|
||||
// Camera2D setup
|
||||
Camera2D ui_cam = { 0 };
|
||||
ui_cam.zoom = 1.0f;
|
||||
recomputeViewPort(&ui_cam, LOGICAL_WIDTH, LOGICAL_HEIGHT, BORDER_WIDTH);
|
||||
|
||||
// Audio device setup
|
||||
InitAudioDevice();
|
||||
SetAudioStreamBufferSizeDefault(1024);
|
||||
|
||||
@@ -63,34 +63,141 @@ int main(void)
|
||||
PlayAudioStream(stream);
|
||||
SetTargetFPS(120);
|
||||
|
||||
uiInit(&gUI, &gMidi, &ui_cam);
|
||||
|
||||
// Auto-connect to last used MIDI device if still available
|
||||
{
|
||||
char lastDev[CONFIG_NAME_LEN];
|
||||
if (configLoadLastDevice(lastDev, sizeof(lastDev))) {
|
||||
for (int i = 0; i < gMidi.inputCount; i++) {
|
||||
if (strcmp(gMidi.inputs[i].clientName, lastDev) == 0) {
|
||||
midiDevConnect(&gMidi, gMidi.inputs[i].client, gMidi.inputs[i].port);
|
||||
uiLoadCcMappingsForDevice(&gUI, lastDev);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Layout constants
|
||||
const float pad = 10.0f;
|
||||
const float oscW = 220.0f;
|
||||
const float oscH = 340.0f;
|
||||
const float envW = 180.0f;
|
||||
const float envH = 280.0f;
|
||||
const float masterW = 180.0f;
|
||||
const float masterH = 360.0f;
|
||||
const float lfoW = 180.0f;
|
||||
const float lfoH = 155.0f;
|
||||
const float filterW = 200.0f;
|
||||
const float filterH = 300.0f;
|
||||
|
||||
while (!WindowShouldClose()) {
|
||||
if (IsKeyPressed(KEY_UP))
|
||||
gSynth.waveform = (gSynth.waveform + 1) % WAVE_COUNT;
|
||||
if (IsKeyPressed(KEY_DOWN))
|
||||
gSynth.waveform = (gSynth.waveform + WAVE_COUNT - 1) % WAVE_COUNT;
|
||||
// Sync voice settings from voice 0
|
||||
synthSyncVoices(&gSynth);
|
||||
|
||||
BeginDrawing();
|
||||
ClearBackground(BLACK);
|
||||
BeginMode2D(ui_cam);
|
||||
if(IsWindowResized()) {
|
||||
recomputeViewPort(&ui_cam, LOGICAL_WIDTH, LOGICAL_HEIGHT, BORDER_WIDTH);
|
||||
}
|
||||
ClearBackground((Color){ 189, 168, 131, 255 }); // tan background
|
||||
|
||||
drawWaveform(gSynth.waveform, gSynth.dutyCycle, 20, 120, 400, 150);
|
||||
// // Oscillator panels — left side, stacked vertically
|
||||
// uiOscillatorPanel(&gUI, 0,
|
||||
// padding, padding,
|
||||
// oscW, oscH,
|
||||
// &gSynth.voices[0].oscillators[0], "Oscillator 0");
|
||||
//
|
||||
// uiOscillatorPanel(&gUI, 100,
|
||||
// padding, padding + oscH + padding,
|
||||
// oscW, oscH,
|
||||
// &gSynth.voices[0].oscillators[1], "Oscillator 1");
|
||||
//
|
||||
// // Envelope panels — to the right of oscillators
|
||||
// float envX = padding + oscW + padding;
|
||||
// uiEnvelopePanel(&gUI, 200,
|
||||
// envX, padding,
|
||||
// envW, envH,
|
||||
// &gSynth.voices[0].ampEnv, "Amp Envelope");
|
||||
//
|
||||
// uiEnvelopePanel(&gUI, 250,
|
||||
// envX, padding + envH + padding,
|
||||
// envW, envH,
|
||||
// &gSynth.voices[0].modEnv, "Mod Envelope");
|
||||
//
|
||||
// // Master panel — to the right of envelopes
|
||||
// float masterX = envX + envW + padding;
|
||||
// uiMasterPanel(&gUI,
|
||||
// masterX, padding,
|
||||
// masterW, masterH,
|
||||
// &gSynth);
|
||||
|
||||
DrawText("SoundThing", 20, 20, 24, RAYWHITE);
|
||||
DrawText(TextFormat("Waveform: %s (UP/DOWN to change)", waveformName(gSynth.waveform)),
|
||||
20, 55, 20, RAYWHITE);
|
||||
DrawText(TextFormat("MIDI: client %d port %d", gMidi.client, gMidi.port),
|
||||
20, 90, 20, GRAY);
|
||||
if (gSynth.waveform == WAVE_PULSE)
|
||||
DrawText(TextFormat("Duty Cycle: %.2f", gSynth.dutyCycle), 20, 280, 20, GREEN);
|
||||
// Left column — oscillator panels stacked vertically
|
||||
float oscX = pad;
|
||||
uiOscillatorPanel(&gUI, 0,
|
||||
oscX, pad,
|
||||
oscW, oscH,
|
||||
&gSynth.voices[0].oscillators[0], "Oscillator 0");
|
||||
|
||||
uiOscillatorPanel(&gUI, 100,
|
||||
oscX, pad + oscH + pad,
|
||||
oscW, oscH,
|
||||
&gSynth.voices[0].oscillators[1], "Oscillator 1");
|
||||
|
||||
// Middle column — envelope panels stacked vertically
|
||||
float envX = pad + oscW + pad;
|
||||
uiEnvelopePanel(&gUI, 200,
|
||||
envX, pad,
|
||||
envW, envH,
|
||||
&gSynth.voices[0].ampEnv, "Envelope 0 - Amp");
|
||||
|
||||
uiEnvelopePanel(&gUI, 250,
|
||||
envX, pad + envH + pad,
|
||||
envW, envH,
|
||||
&gSynth.voices[0].modEnv, "Envelope 1 - Mod");
|
||||
|
||||
// LFO column
|
||||
float lfoX = pad + oscW + pad + envW + pad;
|
||||
uiLfoPanel(&gUI, 500,
|
||||
lfoX, pad,
|
||||
lfoW, lfoH,
|
||||
&gSynth.lfos[0], "LFO 0");
|
||||
uiLfoPanel(&gUI, 600,
|
||||
lfoX, pad + lfoH + pad,
|
||||
lfoW, lfoH,
|
||||
&gSynth.lfos[1], "LFO 1");
|
||||
|
||||
// Filter panel
|
||||
float filterX = lfoX + lfoW + pad;
|
||||
uiFilterPanel(&gUI,
|
||||
filterX, pad,
|
||||
filterW, filterH,
|
||||
&gSynth.voices[0].filter, "Filter");
|
||||
|
||||
// Master panel — rightmost
|
||||
float masterX = filterX + filterW + pad;
|
||||
uiMasterPanel(&gUI,
|
||||
masterX, pad,
|
||||
masterW, masterH,
|
||||
&gSynth);
|
||||
|
||||
// Floating overlays — drawn last, each one on top of the previous
|
||||
uiMidiMenu(&gUI, (LOGICAL_WIDTH - 420) * 0.5f, 100.0f, 420.0f, &gMidi);
|
||||
uiPatchMenu(&gUI, (LOGICAL_WIDTH - 420) * 0.5f, 80.0f, 420.0f, &gSynth);
|
||||
uiAboutMenu(&gUI, (LOGICAL_WIDTH - 420) * 0.5f, 160.0f, 420.0f);
|
||||
|
||||
EndDrawing();
|
||||
}
|
||||
|
||||
|
||||
gRunning = 0;
|
||||
StopAudioStream(stream);
|
||||
UnloadAudioStream(stream);
|
||||
CloseAudioDevice();
|
||||
CloseWindow();
|
||||
pthread_join(midiTid, NULL);
|
||||
uiClose(&gUI);
|
||||
CloseWindow();
|
||||
midiClose(&gMidi);
|
||||
return 0;
|
||||
}
|
||||
|
||||
49
source/sprites_data.c
Normal file
49
source/sprites_data.c
Normal file
@@ -0,0 +1,49 @@
|
||||
unsigned char sprites_png[] = {
|
||||
0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, 0x00, 0x00, 0x00, 0x0d,
|
||||
0x49, 0x48, 0x44, 0x52, 0x00, 0x00, 0x00, 0x58, 0x00, 0x00, 0x00, 0x10,
|
||||
0x08, 0x06, 0x00, 0x00, 0x00, 0x92, 0x9e, 0xb8, 0x35, 0x00, 0x00, 0x00,
|
||||
0x01, 0x73, 0x52, 0x47, 0x42, 0x00, 0xae, 0xce, 0x1c, 0xe9, 0x00, 0x00,
|
||||
0x01, 0xd8, 0x49, 0x44, 0x41, 0x54, 0x58, 0x85, 0xed, 0x58, 0xc1, 0x91,
|
||||
0xc2, 0x30, 0x0c, 0xdc, 0x30, 0x14, 0xa0, 0x12, 0x5c, 0x82, 0x4b, 0xa0,
|
||||
0x83, 0xb8, 0x84, 0x94, 0x40, 0x29, 0xbe, 0x0e, 0x28, 0x21, 0xa5, 0xa8,
|
||||
0x04, 0x4a, 0x50, 0x07, 0xb9, 0x07, 0xe3, 0xa0, 0x18, 0xc5, 0x36, 0x1c,
|
||||
0x30, 0xc7, 0x5d, 0x76, 0x26, 0x0f, 0xbc, 0x96, 0xac, 0xac, 0x14, 0x45,
|
||||
0xa4, 0xc3, 0x87, 0x83, 0x88, 0xa6, 0x57, 0xfa, 0x17, 0x91, 0xae, 0xf5,
|
||||
0x4c, 0x6b, 0xef, 0x1e, 0x00, 0x98, 0x79, 0x35, 0x48, 0xef, 0x7d, 0xa7,
|
||||
0xf9, 0x10, 0x02, 0xc6, 0x71, 0x5c, 0xf0, 0xce, 0xb9, 0x09, 0xc0, 0x62,
|
||||
0x7d, 0xcd, 0x5e, 0xfb, 0x01, 0x80, 0xf3, 0xf9, 0x6c, 0xf2, 0x35, 0xfb,
|
||||
0xe4, 0x43, 0x44, 0xe0, 0xbd, 0x37, 0x6d, 0x99, 0x39, 0xf9, 0x68, 0xe2,
|
||||
0x87, 0x61, 0x00, 0x00, 0x9c, 0x4e, 0xa7, 0x05, 0xaf, 0x41, 0x44, 0x53,
|
||||
0xc1, 0xdf, 0x94, 0x8b, 0xbc, 0xd7, 0xc1, 0x02, 0xb6, 0x48, 0x7a, 0xcf,
|
||||
0x38, 0x8e, 0x37, 0x22, 0x27, 0x3b, 0x6b, 0xbd, 0xe6, 0xc7, 0xe2, 0x6a,
|
||||
0x76, 0xfa, 0xcc, 0xc3, 0xe1, 0x00, 0xe0, 0x22, 0x0e, 0x11, 0x01, 0x00,
|
||||
0x44, 0x64, 0x16, 0x29, 0xa1, 0xc6, 0x13, 0xd1, 0xec, 0x9b, 0x88, 0x20,
|
||||
0x22, 0x37, 0xe7, 0x97, 0xc4, 0x05, 0x2e, 0x89, 0xca, 0x45, 0xde, 0xe9,
|
||||
0xc0, 0xf3, 0x9b, 0x2e, 0xdd, 0xac, 0x85, 0x35, 0xd1, 0x34, 0x5a, 0x92,
|
||||
0x90, 0x62, 0xb1, 0x92, 0x58, 0x8a, 0xab, 0x0f, 0x01, 0x7d, 0x29, 0x41,
|
||||
0x7d, 0x40, 0xe8, 0x6d, 0x5e, 0x44, 0x10, 0x42, 0x98, 0x9f, 0x8a, 0x1c,
|
||||
0xb9, 0xb8, 0x44, 0xb4, 0xb8, 0x12, 0xbc, 0xf7, 0x8b, 0x16, 0xb2, 0x47,
|
||||
0x23, 0xb4, 0x30, 0xa5, 0x6a, 0x2d, 0x71, 0xad, 0x15, 0x5e, 0xc3, 0x9a,
|
||||
0x8f, 0xaf, 0x18, 0x01, 0x00, 0x64, 0xb2, 0x40, 0xfc, 0xba, 0xf0, 0xd6,
|
||||
0x86, 0x52, 0x05, 0x5b, 0xe2, 0xe6, 0x49, 0xd0, 0x6b, 0xba, 0x92, 0x77,
|
||||
0x79, 0xc0, 0x49, 0xa0, 0x9f, 0x88, 0x61, 0x55, 0x72, 0xc9, 0x5f, 0x3a,
|
||||
0x6f, 0xad, 0x32, 0x5b, 0x9f, 0x2a, 0xe7, 0x1c, 0x9c, 0x73, 0x0f, 0xf1,
|
||||
0x6b, 0x15, 0xdc, 0x22, 0x6e, 0xb2, 0xb7, 0x2a, 0xd9, 0xac, 0xe0, 0x5c,
|
||||
0x88, 0x52, 0xcf, 0x5d, 0x83, 0xe6, 0x6b, 0xc9, 0x6a, 0x69, 0x19, 0xba,
|
||||
0x8d, 0x59, 0x3e, 0xf3, 0x9e, 0x9a, 0xa3, 0xc6, 0x37, 0xf6, 0x60, 0x73,
|
||||
0x3d, 0x21, 0x89, 0xac, 0xf7, 0xdc, 0x8c, 0x15, 0x9f, 0x86, 0x57, 0x8f,
|
||||
0x69, 0xc0, 0x75, 0xca, 0xa8, 0x09, 0x9c, 0xef, 0x61, 0xe6, 0xf6, 0x1e,
|
||||
0xfc, 0x5b, 0x61, 0xcd, 0x9e, 0xcf, 0x44, 0x29, 0x81, 0xc3, 0x30, 0x54,
|
||||
0x9f, 0x8c, 0xdd, 0xb3, 0x03, 0xfa, 0x2f, 0x68, 0x11, 0x17, 0xb8, 0x63,
|
||||
0x8a, 0xd8, 0x70, 0xed, 0xb1, 0x21, 0x04, 0x53, 0x5c, 0xab, 0x85, 0x6c,
|
||||
0x15, 0x5c, 0x81, 0x88, 0x74, 0xfa, 0x1f, 0xdd, 0xda, 0x0b, 0x3b, 0x17,
|
||||
0x97, 0x99, 0x21, 0x22, 0xdd, 0xc7, 0xbf, 0xe4, 0xde, 0x01, 0xe7, 0xdc,
|
||||
0x24, 0x22, 0x88, 0x31, 0xce, 0x95, 0xab, 0x47, 0x32, 0x00, 0xa6, 0xb8,
|
||||
0xc0, 0x56, 0xc1, 0xcd, 0x88, 0x31, 0xe2, 0x78, 0x3c, 0xce, 0xbf, 0x45,
|
||||
0x64, 0x71, 0x25, 0x68, 0x71, 0x81, 0x3f, 0x30, 0xa6, 0xbd, 0x03, 0xcc,
|
||||
0x3c, 0xa5, 0x99, 0xbe, 0xf6, 0x71, 0x29, 0x9f, 0x6a, 0x36, 0x81, 0x1f,
|
||||
0xc0, 0x3d, 0x9f, 0x2b, 0xbf, 0x01, 0xc8, 0x27, 0x72, 0x5f, 0xca, 0xe5,
|
||||
0xdb, 0x35, 0x00, 0x00, 0x00, 0x00, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42,
|
||||
0x60, 0x82
|
||||
};
|
||||
unsigned int sprites_png_len = 542;
|
||||
438
source/synth.c
438
source/synth.c
@@ -2,6 +2,7 @@
|
||||
#include <math.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#ifndef M_PI
|
||||
#define M_PI 3.14159265358979323846
|
||||
@@ -9,26 +10,231 @@
|
||||
|
||||
void synthInit(Synth *s, float sampleRate)
|
||||
{
|
||||
s->sampleRate = sampleRate;
|
||||
s->attackSec = 0.005f;
|
||||
s->releaseSec = 0.050f;
|
||||
s->dutyCycle = 0.5f;
|
||||
s->waveform = WAVE_SINE;
|
||||
s->lastStolenVoice = 0;
|
||||
s->sampleRate = sampleRate;
|
||||
s->pitchBend = 0.0f;
|
||||
s->pitchBendRange = 2.0f;
|
||||
s->lastStolenVoice = 0;
|
||||
s->volume = 0.8f;
|
||||
|
||||
for (int i = 0; i < VOICE_COUNT; i++) {
|
||||
s->voices[i].phase = 0.0f;
|
||||
s->voices[i].freqHz = 440.0f;
|
||||
s->voices[i].amp = 0.0f;
|
||||
s->voices[i].targetAmp = 0.0f;
|
||||
s->voices[i].active = 0;
|
||||
s->voices[i].midiNote = -1;
|
||||
s->pitchBend = 0.0f;
|
||||
s->pitchBendRange = 2.0f;
|
||||
s->voices[i].freqHz = 440.0f;
|
||||
s->voices[i].active = 0;
|
||||
s->voices[i].midiNote = -1;
|
||||
|
||||
oscillatorInit(&s->voices[i].oscillators[0], WAVE_TRIANGLE, 0.5f, 0.0f, OSC_MAX_GAIN);
|
||||
oscillatorInit(&s->voices[i].oscillators[1], WAVE_TRIANGLE, 0.5f, 0.0f, 0.0f);
|
||||
|
||||
envelopeInit(&s->voices[i].ampEnv,
|
||||
0.005f, // attack
|
||||
0.10f, // decay
|
||||
0.70f, // sustain
|
||||
0.50f); // release
|
||||
|
||||
envelopeInit(&s->voices[i].modEnv,
|
||||
0.005f, // attack
|
||||
0.50f, // decay
|
||||
0.0f, // sustain
|
||||
0.10f); // release
|
||||
|
||||
s->voices[i].filter.cutoff = 8000.0f;
|
||||
s->voices[i].filter.resonance = 0.0f;
|
||||
s->voices[i].filter.type = FILTER_LOWPASS;
|
||||
s->voices[i].filter.active = 0;
|
||||
s->voices[i].filter.low = 0.0f;
|
||||
s->voices[i].filter.band = 0.0f;
|
||||
s->voices[i].filter.modRouting = MOD_SOURCE_NONE;
|
||||
s->voices[i].filter.modDepth = 0.0f;
|
||||
s->voices[i].filter.resModRouting = MOD_SOURCE_NONE;
|
||||
s->voices[i].filter.resModDepth = 0.0f;
|
||||
}
|
||||
s->voices[0].oscillators[0].active = 1;
|
||||
|
||||
for (int l = 0; l < LFO_COUNT; l++) {
|
||||
s->lfos[l].phase = 0.0f;
|
||||
s->lfos[l].rate = 1.0f;
|
||||
s->lfos[l].waveform = WAVE_SINE;
|
||||
s->lfos[l].active = 0;
|
||||
s->lfos[l].noiseHeld = 0.0f;
|
||||
s->lfos[l].noisePhase = 0.0f;
|
||||
}
|
||||
}
|
||||
|
||||
float waveformSample(Waveform w, float phase, float dutyCycle)
|
||||
void synthResetPatch(Synth *s)
|
||||
{
|
||||
Voice *v = &s->voices[0];
|
||||
|
||||
oscillatorInit(&v->oscillators[0], WAVE_TRIANGLE, 0.5f, 0.0f, OSC_MAX_GAIN);
|
||||
v->oscillators[0].active = 1;
|
||||
for (int m = 0; m < 3; m++) {
|
||||
v->oscillators[0].modRouting[m] = MOD_SOURCE_NONE;
|
||||
v->oscillators[0].modDepth[m] = 0.0f;
|
||||
}
|
||||
|
||||
oscillatorInit(&v->oscillators[1], WAVE_TRIANGLE, 0.5f, 0.0f, 0.0f);
|
||||
v->oscillators[1].active = 0;
|
||||
for (int m = 0; m < 3; m++) {
|
||||
v->oscillators[1].modRouting[m] = MOD_SOURCE_NONE;
|
||||
v->oscillators[1].modDepth[m] = 0.0f;
|
||||
}
|
||||
|
||||
envelopeInit(&v->ampEnv, 0.005f, 0.10f, 0.70f, 0.50f);
|
||||
envelopeInit(&v->modEnv, 0.005f, 0.50f, 0.0f, 0.10f);
|
||||
|
||||
v->filter.cutoff = 8000.0f;
|
||||
v->filter.resonance = 0.0f;
|
||||
v->filter.type = FILTER_LOWPASS;
|
||||
v->filter.active = 0;
|
||||
v->filter.low = 0.0f;
|
||||
v->filter.band = 0.0f;
|
||||
v->filter.modRouting = MOD_SOURCE_NONE;
|
||||
v->filter.modDepth = 0.0f;
|
||||
v->filter.resModRouting = MOD_SOURCE_NONE;
|
||||
v->filter.resModDepth = 0.0f;
|
||||
|
||||
for (int l = 0; l < LFO_COUNT; l++) {
|
||||
s->lfos[l].phase = 0.0f;
|
||||
s->lfos[l].rate = 1.0f;
|
||||
s->lfos[l].waveform = WAVE_SINE;
|
||||
s->lfos[l].active = 0;
|
||||
s->lfos[l].noiseHeld = 0.0f;
|
||||
s->lfos[l].noisePhase = 0.0f;
|
||||
}
|
||||
|
||||
s->volume = 0.8f;
|
||||
s->pitchBendRange = 2.0f;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void oscillatorInit(Oscillator *o, Waveform waveform, float dutyCycle, float detune, float gain)
|
||||
{
|
||||
o->phase = 0.0f;
|
||||
o->waveform = waveform;
|
||||
o->dutyCycle = dutyCycle;
|
||||
o->detune = detune;
|
||||
o->noiseHeld = 0.0f;
|
||||
o->noisePhase = 0.0f;
|
||||
o->gain = gain;
|
||||
o->octave = 0;
|
||||
}
|
||||
|
||||
|
||||
static float getModValue(float ampEnv, float modEnv, float lfo0, float lfo1, ModSource source)
|
||||
{
|
||||
switch (source) {
|
||||
case MOD_SOURCE_AMP_ENV: return ampEnv;
|
||||
case MOD_SOURCE_MOD_ENV: return modEnv;
|
||||
case MOD_SOURCE_LFO: return lfo0;
|
||||
case MOD_SOURCE_LFO2: return lfo1;
|
||||
default: return 0.0f;
|
||||
}
|
||||
}
|
||||
|
||||
float lfoTick(LFO *l, float sampleRate)
|
||||
{
|
||||
if (!l->active) return 0.0f;
|
||||
l->phase += l->rate / sampleRate;
|
||||
if (l->phase >= 1.0f) l->phase -= 1.0f;
|
||||
if (l->waveform == WAVE_NOISE) {
|
||||
l->noisePhase += l->rate / sampleRate;
|
||||
if (l->noisePhase >= 1.0f) {
|
||||
l->noisePhase -= 1.0f;
|
||||
l->noiseHeld = ((float)rand() / (float)RAND_MAX) * 2.0f - 1.0f;
|
||||
}
|
||||
}
|
||||
return waveformSample(l->waveform, l->phase, 0.5f, l->noiseHeld);
|
||||
}
|
||||
|
||||
float filterTick(Filter *f, float input, float cutoff, float resonance, float sampleRate)
|
||||
{
|
||||
if (!f->active) return input;
|
||||
|
||||
if (cutoff < 20.0f) cutoff = 20.0f;
|
||||
if (cutoff > sampleRate * 0.499f) cutoff = sampleRate * 0.499f;
|
||||
if (resonance < 0.0f) resonance = 0.0f;
|
||||
if (resonance > 0.99f) resonance = 0.99f;
|
||||
|
||||
// Andy Simper TPT SVF (bilinear integration — unconditionally stable)
|
||||
float g = tanf((float)M_PI * cutoff / sampleRate);
|
||||
float Q = 0.5f + resonance * 9.5f; // resonance 0..0.99 → Q 0.5..10.0
|
||||
float k = 1.0f / Q;
|
||||
float a1 = 1.0f / (1.0f + g * (g + k));
|
||||
float a2 = g * a1;
|
||||
float a3 = g * a2;
|
||||
|
||||
// f->band = s1, f->low = s2 (integrator states)
|
||||
float v3 = input - f->low;
|
||||
float v1 = a1 * f->band + a2 * v3;
|
||||
float v2 = f->low + a2 * f->band + a3 * v3;
|
||||
f->band = 2.0f * v1 - f->band;
|
||||
f->low = 2.0f * v2 - f->low;
|
||||
|
||||
switch (f->type) {
|
||||
case FILTER_LOWPASS: return v2;
|
||||
case FILTER_HIGHPASS: return input - k * v1 - v2;
|
||||
case FILTER_BANDPASS: return v1;
|
||||
default: return v2;
|
||||
}
|
||||
}
|
||||
|
||||
const char *filterTypeName(FilterType t)
|
||||
{
|
||||
switch (t) {
|
||||
case FILTER_LOWPASS: return "LP";
|
||||
case FILTER_HIGHPASS: return "HP";
|
||||
case FILTER_BANDPASS: return "BP";
|
||||
default: return "??";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// float oscillatorTick(Oscillator *o, float freqHz, float bendMultiplier, float sampleRate,
|
||||
// float dutyCycle, float detune, float gain)
|
||||
// {
|
||||
// float detuneMultiplier = powf(2.0f, o->detune / 1200.0f);
|
||||
// float freq = freqHz * detuneMultiplier * bendMultiplier;
|
||||
//
|
||||
// // Advance phase
|
||||
// o->phase += freq / sampleRate;
|
||||
// if (o->phase >= 1.0f) o->phase -= 1.0f;
|
||||
//
|
||||
// // Clocked noise — draw a new random value once per cycle
|
||||
// if (o->waveform == WAVE_NOISE) {
|
||||
// o->noisePhase += freq / sampleRate;
|
||||
// if (o->noisePhase >= 1.0f) {
|
||||
// o->noisePhase -= 1.0f;
|
||||
// o->noiseHeld = ((float)rand() / (float)RAND_MAX) * 2.0f - 1.0f;
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// return waveformSample(o->waveform, o->phase, o->dutyCycle, o->noiseHeld) * o->gain;
|
||||
// }
|
||||
|
||||
float oscillatorTick(Oscillator *o, float freqHz, float bendMultiplier, float sampleRate,
|
||||
float dutyCycle, float detune, float gain)
|
||||
{
|
||||
float detuneMultiplier = powf(2.0f, detune / 1200.0f);
|
||||
float freq = freqHz * detuneMultiplier * bendMultiplier;
|
||||
|
||||
// Advance phase
|
||||
o->phase += freq / sampleRate;
|
||||
if (o->phase >= 1.0f) o->phase -= 1.0f;
|
||||
|
||||
// Clocked noise — draw a new random value once per cycle
|
||||
if (o->waveform == WAVE_NOISE) {
|
||||
o->noisePhase += freq / sampleRate;
|
||||
if (o->noisePhase >= 1.0f) {
|
||||
o->noisePhase -= 1.0f;
|
||||
o->noiseHeld = ((float)rand() / (float)RAND_MAX) * 2.0f - 1.0f;
|
||||
}
|
||||
}
|
||||
|
||||
return waveformSample(o->waveform, o->phase, dutyCycle, o->noiseHeld) * gain;
|
||||
}
|
||||
|
||||
|
||||
|
||||
float waveformSample(Waveform w, float phase, float dutyCycle, float noiseHeld)
|
||||
{
|
||||
switch (w) {
|
||||
case WAVE_SINE:
|
||||
@@ -44,7 +250,7 @@ float waveformSample(Waveform w, float phase, float dutyCycle)
|
||||
case WAVE_PULSE:
|
||||
return (phase < dutyCycle) ? 1.0f : -1.0f;
|
||||
case WAVE_NOISE:
|
||||
return ((float)rand() / (float)RAND_MAX) * 2.0f - 1.0f;
|
||||
return noiseHeld;
|
||||
default:
|
||||
return 0.0f;
|
||||
}
|
||||
@@ -69,67 +275,95 @@ void synthNoteOn(Synth *s, int midiNote)
|
||||
|
||||
for (int i = 0; i < VOICE_COUNT; i++) {
|
||||
if (!s->voices[i].active) {
|
||||
s->voices[i].freqHz = hz;
|
||||
s->voices[i].midiNote = midiNote;
|
||||
s->voices[i].targetAmp = 1.0f;
|
||||
s->voices[i].active = 1;
|
||||
s->voices[i].freqHz = hz;
|
||||
s->voices[i].midiNote = midiNote;
|
||||
s->voices[i].active = 1;
|
||||
s->voices[i].filter.low = 0.0f;
|
||||
s->voices[i].filter.band = 0.0f;
|
||||
envelopeNoteOn(&s->voices[i].ampEnv);
|
||||
envelopeNoteOn(&s->voices[i].modEnv);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// No free voice — steal round-robin
|
||||
// Steal round-robin
|
||||
int i = s->lastStolenVoice % VOICE_COUNT;
|
||||
s->lastStolenVoice++;
|
||||
s->voices[i].freqHz = hz;
|
||||
s->voices[i].midiNote = midiNote;
|
||||
s->voices[i].targetAmp = 1.0f;
|
||||
s->voices[i].phase = 0.0f;
|
||||
s->voices[i].active = 1;
|
||||
s->voices[i].freqHz = hz;
|
||||
s->voices[i].midiNote = midiNote;
|
||||
s->voices[i].active = 1;
|
||||
s->voices[i].filter.low = 0.0f;
|
||||
s->voices[i].filter.band = 0.0f;
|
||||
envelopeNoteOn(&s->voices[i].ampEnv);
|
||||
envelopeNoteOn(&s->voices[i].modEnv);
|
||||
}
|
||||
|
||||
void synthNoteOff(Synth *s, int midiNote)
|
||||
{
|
||||
|
||||
void synthNoteOff(Synth *s, int midiNote) {
|
||||
for (int i = 0; i < VOICE_COUNT; i++) {
|
||||
if (s->voices[i].active && s->voices[i].midiNote == midiNote)
|
||||
s->voices[i].targetAmp = 0.0f;
|
||||
if (s->voices[i].active && s->voices[i].midiNote == midiNote) {
|
||||
envelopeNoteOff(&s->voices[i].ampEnv);
|
||||
envelopeNoteOff(&s->voices[i].modEnv);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void synthFillBuffer(Synth *s, int16_t *out, int frames)
|
||||
{
|
||||
const float sr = s->sampleRate;
|
||||
const float attackInc = (s->attackSec <= 0.0f) ? 1.0f : (1.0f / (s->attackSec * sr));
|
||||
const float releaseInc = (s->releaseSec <= 0.0f) ? 1.0f : (1.0f / (s->releaseSec * sr));
|
||||
void synthFillBuffer(Synth *s, int16_t *out, int frames) {
|
||||
const float sr = s->sampleRate;
|
||||
const float bendMultiplier = powf(2.0f, (s->pitchBend * s->pitchBendRange) / 12.0f);
|
||||
|
||||
for (int i = 0; i < frames; i++) {
|
||||
float mix = 0.0f;
|
||||
|
||||
float lfo0 = lfoTick(&s->lfos[0], sr);
|
||||
float lfo1 = lfoTick(&s->lfos[1], sr);
|
||||
|
||||
for (int v = 0; v < VOICE_COUNT; v++) {
|
||||
Voice *vv = &s->voices[v];
|
||||
if (!vv->active) continue;
|
||||
|
||||
if (vv->targetAmp > vv->amp) {
|
||||
vv->amp += attackInc;
|
||||
if (vv->amp > vv->targetAmp) vv->amp = vv->targetAmp;
|
||||
} else if (vv->targetAmp < vv->amp) {
|
||||
vv->amp -= releaseInc;
|
||||
if (vv->amp < vv->targetAmp) vv->amp = vv->targetAmp;
|
||||
}
|
||||
float amp = envelopeTick(&vv->ampEnv, sr);
|
||||
float mod = envelopeTick(&vv->modEnv, sr);
|
||||
|
||||
if (vv->amp <= 0.0f && vv->targetAmp == 0.0f) {
|
||||
if (vv->ampEnv.stage == ENV_IDLE) {
|
||||
vv->active = 0;
|
||||
continue;
|
||||
}
|
||||
|
||||
//vv->phase += vv->freqHz / sr;
|
||||
float bendMultiplier = powf(2.0f, (s->pitchBend * s->pitchBendRange) / 12.0f);
|
||||
vv->phase += (vv->freqHz * bendMultiplier) / sr;
|
||||
if (vv->phase >= 1.0f) vv->phase -= 1.0f;
|
||||
float oscMix = 0.0f;
|
||||
int activeOscs = 0;
|
||||
for (int o = 0; o < OSC_COUNT; o++) {
|
||||
Oscillator *osc = &vv->oscillators[o];
|
||||
if (!osc->active) continue;
|
||||
|
||||
mix += waveformSample(s->waveform, vv->phase, s->dutyCycle) * vv->amp;
|
||||
float dutyCycle = osc->dutyCycle +
|
||||
getModValue(amp, mod, lfo0, lfo1, osc->modRouting[0]) * osc->modDepth[0];
|
||||
float detune = osc->detune + (float)osc->octave * 1200.0f +
|
||||
getModValue(amp, mod, lfo0, lfo1, osc->modRouting[1]) * osc->modDepth[1];
|
||||
float gain = osc->gain +
|
||||
getModValue(amp, mod, lfo0, lfo1, osc->modRouting[2]) * osc->modDepth[2];
|
||||
|
||||
if (dutyCycle < 0.05f) dutyCycle = 0.05f;
|
||||
if (dutyCycle > 0.95f) dutyCycle = 0.95f;
|
||||
if (gain < 0.0f) gain = 0.0f;
|
||||
if (gain > OSC_MAX_GAIN) gain = OSC_MAX_GAIN;
|
||||
|
||||
oscMix += oscillatorTick(osc, vv->freqHz, bendMultiplier, sr, dutyCycle, detune, gain);
|
||||
activeOscs++;
|
||||
}
|
||||
|
||||
if (activeOscs > 0) oscMix /= activeOscs;
|
||||
|
||||
float cutoff = vv->filter.cutoff +
|
||||
getModValue(amp, mod, lfo0, lfo1, vv->filter.modRouting) * vv->filter.modDepth;
|
||||
float resonance = vv->filter.resonance +
|
||||
getModValue(amp, mod, lfo0, lfo1, vv->filter.resModRouting) * vv->filter.resModDepth;
|
||||
oscMix = filterTick(&vv->filter, oscMix, cutoff, resonance, sr);
|
||||
|
||||
mix += oscMix * amp;
|
||||
}
|
||||
|
||||
mix *= (0.2f / VOICE_COUNT) * 4.0f;
|
||||
mix *= (0.2f / VOICE_COUNT) * 4.0f * s->volume;
|
||||
|
||||
int32_t sample = (int32_t)lrintf(mix * 32767.0f);
|
||||
if (sample > 32767) sample = 32767;
|
||||
@@ -137,3 +371,109 @@ void synthFillBuffer(Synth *s, int16_t *out, int frames)
|
||||
out[i] = (int16_t)sample;
|
||||
}
|
||||
}
|
||||
|
||||
void envelopeInit(Envelope *e, float attackSec, float decaySec, float sustainLevel, float releaseSec)
|
||||
{
|
||||
e->stage = ENV_IDLE;
|
||||
e->value = 0.0f;
|
||||
e->attackSec = attackSec;
|
||||
e->decaySec = decaySec;
|
||||
e->sustainLevel = sustainLevel;
|
||||
e->releaseSec = releaseSec;
|
||||
}
|
||||
|
||||
void envelopeNoteOn(Envelope *e)
|
||||
{
|
||||
e->value = 0.0f;
|
||||
e->stage = ENV_ATTACK;
|
||||
}
|
||||
|
||||
void envelopeNoteOff(Envelope *e)
|
||||
{
|
||||
// Only trigger release if we're actually playing
|
||||
if (e->stage != ENV_IDLE)
|
||||
e->stage = ENV_RELEASE;
|
||||
}
|
||||
|
||||
float envelopeTick(Envelope *e, float sampleRate)
|
||||
{
|
||||
switch (e->stage) {
|
||||
case ENV_ATTACK: {
|
||||
float inc = (e->attackSec <= 0.0f) ? 1.0f : (1.0f / (e->attackSec * sampleRate));
|
||||
e->value += inc;
|
||||
if (e->value >= 1.0f) {
|
||||
e->value = 1.0f;
|
||||
e->stage = ENV_DECAY;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case ENV_DECAY: {
|
||||
float inc = (e->decaySec <= 0.0f) ? 1.0f : (1.0f / (e->decaySec * sampleRate));
|
||||
e->value -= inc;
|
||||
if (e->value <= e->sustainLevel) {
|
||||
e->value = e->sustainLevel;
|
||||
e->stage = ENV_SUSTAIN;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case ENV_SUSTAIN:
|
||||
e->value = e->sustainLevel;
|
||||
break;
|
||||
case ENV_RELEASE: {
|
||||
float inc = (e->releaseSec <= 0.0f) ? 1.0f : (1.0f / (e->releaseSec * sampleRate));
|
||||
e->value -= inc;
|
||||
if (e->value <= 0.0f) {
|
||||
e->value = 0.0f;
|
||||
e->stage = ENV_IDLE;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case ENV_IDLE:
|
||||
e->value = 0.0f;
|
||||
break;
|
||||
}
|
||||
return e->value;
|
||||
}
|
||||
|
||||
void synthSyncVoices(Synth *s)
|
||||
{
|
||||
for (int v = 1; v < VOICE_COUNT; v++) {
|
||||
// Sync oscillator settings
|
||||
for (int o = 0; o < OSC_COUNT; o++) {
|
||||
s->voices[v].oscillators[o].waveform = s->voices[0].oscillators[o].waveform;
|
||||
s->voices[v].oscillators[o].dutyCycle = s->voices[0].oscillators[o].dutyCycle;
|
||||
s->voices[v].oscillators[o].detune = s->voices[0].oscillators[o].detune;
|
||||
s->voices[v].oscillators[o].gain = s->voices[0].oscillators[o].gain;
|
||||
s->voices[v].oscillators[o].active = s->voices[0].oscillators[o].active;
|
||||
s->voices[v].oscillators[o].octave = s->voices[0].oscillators[o].octave;
|
||||
s->voices[v].oscillators[o].modRouting[0] = s->voices[0].oscillators[o].modRouting[0];
|
||||
s->voices[v].oscillators[o].modRouting[1] = s->voices[0].oscillators[o].modRouting[1];
|
||||
s->voices[v].oscillators[o].modRouting[2] = s->voices[0].oscillators[o].modRouting[2];
|
||||
s->voices[v].oscillators[o].modDepth[0] = s->voices[0].oscillators[o].modDepth[0];
|
||||
s->voices[v].oscillators[o].modDepth[1] = s->voices[0].oscillators[o].modDepth[1];
|
||||
s->voices[v].oscillators[o].modDepth[2] = s->voices[0].oscillators[o].modDepth[2];
|
||||
}
|
||||
|
||||
// Sync filter params but not state (low/band are per-voice)
|
||||
s->voices[v].filter.cutoff = s->voices[0].filter.cutoff;
|
||||
s->voices[v].filter.resonance = s->voices[0].filter.resonance;
|
||||
s->voices[v].filter.type = s->voices[0].filter.type;
|
||||
s->voices[v].filter.active = s->voices[0].filter.active;
|
||||
s->voices[v].filter.modRouting = s->voices[0].filter.modRouting;
|
||||
s->voices[v].filter.modDepth = s->voices[0].filter.modDepth;
|
||||
s->voices[v].filter.resModRouting = s->voices[0].filter.resModRouting;
|
||||
s->voices[v].filter.resModDepth = s->voices[0].filter.resModDepth;
|
||||
|
||||
// Sync envelope settings but NOT runtime state
|
||||
// Each voice needs its own stage, value — just copy the parameters
|
||||
s->voices[v].ampEnv.attackSec = s->voices[0].ampEnv.attackSec;
|
||||
s->voices[v].ampEnv.decaySec = s->voices[0].ampEnv.decaySec;
|
||||
s->voices[v].ampEnv.sustainLevel = s->voices[0].ampEnv.sustainLevel;
|
||||
s->voices[v].ampEnv.releaseSec = s->voices[0].ampEnv.releaseSec;
|
||||
// Sync the mod envelope, too.
|
||||
s->voices[v].modEnv.attackSec = s->voices[0].modEnv.attackSec;
|
||||
s->voices[v].modEnv.decaySec = s->voices[0].modEnv.decaySec;
|
||||
s->voices[v].modEnv.sustainLevel = s->voices[0].modEnv.sustainLevel;
|
||||
s->voices[v].modEnv.releaseSec = s->voices[0].modEnv.releaseSec;
|
||||
}
|
||||
}
|
||||
|
||||
1719
source/ui.c
Normal file
1719
source/ui.c
Normal file
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user