#include #include "instruments.h" #include "noise.h" static inline double sine_wave(int step, double period); static inline double square_wave(int step, double period); static inline double sawtooth_wave(int step, double period); static inline double triangle_wave(int step, double period); static inline double exp_envelope(int step, double dur); #define INSTRUMENT(name, dur) struct instrument_t name = {inst_##name, (dur)} static double inst_sine(struct voice_t* v) { return sine_wave(v->step, v->period) * exp_envelope(v->step, v->dur); } INSTRUMENT(sine, 1.25); static double inst_sine_fifths(struct voice_t* v) { return (sine_wave(v->step, v->period) + sine_wave(v->step * pow(2, 7.0 / 12), v->period)) / 2 * exp_envelope(v->step, v->dur); } INSTRUMENT(sine_fifths, 1.25); static double inst_thunk(struct voice_t* v) { return (sin(cos(2 * M_PI * v->step / v->period) * v->period / (v->step + 1) * 16) + 1) / 2; } INSTRUMENT(thunk, 1.25); static double inst_square(struct voice_t* v) { return square_wave(v->step, v->period) * exp_envelope(v->step, v->dur); } INSTRUMENT(square, 1.25); static double inst_sawtooth(struct voice_t* v) { return sawtooth_wave(v->step, v->period) * exp_envelope(v->step, v->dur); } INSTRUMENT(sawtooth, 1.25); static double inst_tri(struct voice_t* v) { return triangle_wave(v->step, v->period) * exp_envelope(v->step, v->dur); } INSTRUMENT(tri, 1.25); static double inst_saw_square(struct voice_t* v) { return (sawtooth_wave(v->step, v->period) + square_wave(v->step, v->period)) / 2 * exp_envelope(v->step, v->dur); } INSTRUMENT(saw_square, 1); static double inst_triangle_sines(struct voice_t* v) { return (sine_wave(v->step, v->period) + sine_wave(v->step * 8 / 3, v->period) + triangle_wave(v->step, v->period)) / 3 * exp_envelope(v->step, v->dur); } INSTRUMENT(triangle_sines, 1); static double inst_weird(struct voice_t* v) { return (sine_wave(v->step, v->period) * (1 - sine_wave(v->step * 8 / 3, v->period)) + 2) / 3; } INSTRUMENT(weird, 1); /* Some basic functions used by instruments */ static inline double sine_wave(int step, double period) { return (sin(2 * M_PI * step / period) + 1) / 2; } static inline double square_wave(int step, double period) { return step % (int)period > period / 2 ? 1 : 0; } static inline double sawtooth_wave(int step, double period) { return (double)(step % (int)period) / period; } static inline double triangle_wave(int step, double period) { return (step % (int)period > period / 2 ? 1 - (double)(step % (int)period / 2) / (period / 2) : (double)(step % (int)period / 2) / (period / 2)) * 2; } static inline double exp_envelope(int step, double dur) { //return 1; //return exp(-step / dur); return 1 - step / dur; }