v0.9.5 beta — full feature build ready for distribution
Core additions since initial commit: - Platform-split MIDI (midi_linux.c / midi_windows.c) - Patch system: save/load/scan, subdirectory navigation, favourites - Config system: last MIDI device and CC mappings persisted to disk - Custom embedded pixel font and sprite sheet (no loose asset files at runtime) - Window icon embedded at runtime (SetWindowIcon) and in Windows .exe (windres) - chdirToExeDir() in platform.c so double-click launch finds patches/ correctly - About screen accessible from Master panel UI polish: - TITLE_BAR_H constant (20 px) — sprite buttons now fit inside title bars - All title bar text, button overlay text, and close/active labels vertically centred - Full-screen dim overlay computed from camera transform (no more partial coverage) - Patch browser: folder navigation, breadcrumb title, 256-slot limit lifted Build: - Makefile auto-discovers sources; embeds sprites/font/icon via xxd rules - Windows cross-compile: make PLATFORM=windows (mingw-w64 + windres) - windows.h isolated in platform.c to avoid Rectangle/CloseWindow conflicts with raylib.h - WIN_RES uses lazy = assignment so OBJ_DIR expands correctly for windres output path Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
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
|
||||
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