#ifndef OSC_H #define OSC_H #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 }; typedef struct osc_t { char name[16]; float * data; long len; long start; long end; enum osc_type type; } 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); /***************/ /* 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 \ 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; } OSC_COMMON_H(tri) OSC_COMMON_H(sin) OSC_COMMON_H(weird) OSC_COMMON_H(sound) OSC_COMMON_H(saw) #endif /* OSC_H */