Initial commit of project.

This commit is contained in:
Anachronaut
2026-03-13 15:09:17 -04:00
commit 48ee8c2c75
7 changed files with 485 additions and 0 deletions

21
include/midi.h Normal file
View File

@@ -0,0 +1,21 @@
#ifndef MIDI_H
#define MIDI_H
#define _POSIX_C_SOURCE 200809L
#include <alsa/asoundlib.h>
#include "synth.h"
typedef struct {
snd_seq_t *seq;
int port;
int client;
Synth *synth; // pointer to the synth we'll drive with MIDI events
} MidiState;
int midiInit(MidiState *m, Synth *synth);
void midiListInputs(MidiState *m);
void midiConnect(MidiState *m, int srcClient, int srcPort);
void midiClose(MidiState *m);
void *midiThread(void *arg);
#endif

46
include/synth.h Normal file
View File

@@ -0,0 +1,46 @@
#ifndef SYNTH_H
#define SYNTH_H
#include <stdint.h>
#define VOICE_COUNT 8
typedef enum {
WAVE_SINE,
WAVE_TRIANGLE,
WAVE_SAW,
WAVE_RAMP,
WAVE_PULSE,
WAVE_NOISE,
WAVE_COUNT // handy for the modulo wrap on waveform switching
} Waveform;
typedef struct {
float phase;
float freqHz;
float amp;
float targetAmp;
int active;
int midiNote;
} Voice;
typedef struct {
float sampleRate;
float attackSec;
float releaseSec;
float dutyCycle;
Waveform waveform;
Voice voices[VOICE_COUNT];
int lastStolenVoice;
float pitchBend; // -1.0 to +1.0, normalized from raw MIDI value
float pitchBendRange; // semitones, e.g. 2.0f
} Synth;
void synthInit(Synth *s, float sampleRate);
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);
const char *waveformName(Waveform w);
#endif