#ifndef OSC_H #define OSC_H #include #include #include #include /** * The main idea of the osc is the following: * The root of the sound is a periodic wave function. * This can be a stored period of a wave in a wavetable * or a function like sin(). In order to play a sound with * the wave an external float offset is kept that points to the * next sample, a function is provided to advance this offset * a calucalted step amount, depending on the desired frequency. * Linear interpolation is used so that a float offset can work * and provide autosmoothing. */ enum osc_type { WAVE, SAMPLE }; struct osc_t; struct osc_ops { void (*set_start)(struct osc_t *, long); void (*set_end) (struct osc_t *, long); void (*set_len) (struct osc_t *, long); float (*sample) (struct osc_t *, float); float (*next) (struct osc_t *, float, float); }; typedef struct osc_t { char name[16]; float * data; long len; long start; long end; enum osc_type type; const struct osc_ops * ops; } osc_t; #define MAKE_OSC(_name, _len, _type) { \ .name = _name, \ .data = 0, \ .len = _len, \ .start = 0, \ .end = _len, \ .type = _type, \ }; /* Initializes the wavetables and functions for the oscilators */ void init_osc(); float osc_interpolate(float offset, float start, float end); float osc_next_offset(osc_t * osc, float f, float offset); int osc_next_index(osc_t * osc, float offset); int osc_load_wav(osc_t * osc, const char * path); osc_t * make_tri(const char * name); /***************/ /* OSCILATORS */ /***************/ // function prototypes common for all oscs #define OSC_COMMON_H(osc) \ void \ set_##osc##_start(long start); \ void \ set_##osc##_end(long end); \ void \ set_##osc##_len(long len); \ float \ get_##osc##_len(); \ float \ osc_##osc(float offset); \ float \ osc_##osc##_next(float f, float offset); // function definitions common for all oscs #define OSC_COMMON(osc) \ void \ set_##osc##_start(long start) \ { OSC_##osc.start = start; } \ void \ set_##osc##_end(long end) \ { OSC_##osc.end = end; } \ void \ set_##osc##_len(long len) \ { OSC_##osc.len = len; } \ float \ get_##osc##_len() \ { return OSC_##osc.len; } OSC_COMMON_H(tri) OSC_COMMON_H(sin) OSC_COMMON_H(weird) OSC_COMMON_H(sound) OSC_COMMON_H(saw) OSC_COMMON_H(digisaw) OSC_COMMON_H(sqr) #endif /* OSC_H */