diff options
Diffstat (limited to 'mmband/instrument.c')
-rw-r--r-- | mmband/instrument.c | 108 |
1 files changed, 107 insertions, 1 deletions
diff --git a/mmband/instrument.c b/mmband/instrument.c index 96a8952..38c7d43 100644 --- a/mmband/instrument.c +++ b/mmband/instrument.c @@ -1,4 +1,110 @@ +#include <math.h> +#include <stdlib.h> + #include <mmband/api/instrument.h> #include <mmband/api/adsr.h> -struct instrument { }; +#include <mmband/waves/waveform.h> + +struct oscillation { + enum osc_type type; + + float frequency; + float phase; + float amplitude; +}; + +struct instrument { + struct oscillation carrier; + struct oscillation modulator; + + float frequency_ratio; +}; + +float osc_tick (struct oscillation *osc, int sample_rate) { + float sample = 0.0; + + switch (osc->type) { + case OSC_NONE: + sample = osc->amplitude * none(osc->phase); + break; + case OSC_SINE: + sample = osc->amplitude * sine(osc->phase); + break; + case OSC_SQUARE: + sample = osc->amplitude * square(osc->phase); + break; + case OSC_SAW: + sample = osc->amplitude * saw(osc->phase); + break; + case OSC_TRIANGLE: + sample = osc->amplitude * triangle(osc->phase); + break; + } + + osc->phase = fmod(osc->phase + osc->frequency * 2.0 * M_PI / sample_rate, 2.0 * M_PI); + return sample; +} + +// Currently default to ring modulation +// TODO: add others +float modulate (struct oscillation *carrier, struct oscillation *modulator, int sample_rate) { + return osc_tick(carrier, sample_rate) * osc_tick(modulator, sample_rate); +} + +instrument_ref ins_new () { + instrument_ref instrument = malloc(sizeof(struct instrument)); + + instrument->frequency_ratio = 1.0; + + instrument->carrier.type = OSC_SINE; + instrument->carrier.amplitude = 0.0; + instrument->carrier.frequency = 0.0; + instrument->carrier.phase = 0.0; + + instrument->modulator.type = OSC_SINE; + instrument->carrier.amplitude = 0.0; + instrument->carrier.frequency = 0.0; + instrument->carrier.phase = 0.0; + + return instrument; +} + +void ins_free (instrument_ref instrument) { + free(instrument); +} + +void ins_set_carrier (instrument_ref instrument, enum osc_type osc) { + instrument->carrier.type = osc; + instrument->carrier.amplitude = 0.0; + instrument->carrier.frequency = 0.0; + instrument->carrier.phase = 0.0; +} + +void ins_set_modulator (instrument_ref instrument, enum osc_type osc) { + instrument->modulator.type = osc; + instrument->modulator.amplitude = 0.0; + instrument->modulator.frequency = 0.0; + instrument->modulator.phase = 0.0; +} + +void ins_set_carrier_amplitude (instrument_ref instrument, float amplitude) { + instrument->carrier.amplitude = amplitude; +} + +void ins_set_modulator_aplitude (instrument_ref instrument, float amplitude) { + instrument->modulator.amplitude = amplitude; +} + +void ins_set_frequency_ratio (instrument_ref instrument, float frequency_ratio) { + instrument->frequency_ratio = frequency_ratio; +} + +void ins_set_frequency (instrument_ref instrument, float frequency) { + instrument->carrier.frequency = frequency; + instrument->modulator.frequency = frequency * instrument->frequency_ratio; +} + +float ins_tick (instrument_ref instrument, int sample_rate) { + return modulate(&instrument->carrier, &instrument->modulator, sample_rate); +} |