#define SAMPLERATE 44100 #define NOTE_DURATION 500 #define SAMPLERATE_DIV (SAMPLERATE / 1000) #define TIME(t) (t / SAMPLERATE_DIV) #define OUTPUT(x) 128 + ((x) * 120.0) #define CURRENT_NOTE_RAW(SONG, t) ((SONG [(TIME(t) / NOTE_DURATION) % (sizeof(SONG) - 1)])) #define CURRENT_NOTE(SONG, t) (CURRENT_NOTE_RAW(SONG, t) & 0xf) #define CURRENT_NOTE_MOD(SONG, t) (CURRENT_NOTE_RAW(SONG, t) & 0xf0) #define INSTRUMENT(t, SONG, ADSR, WAVEFORM) (ADSR((TIME(t) % NOTE_DURATION), CURRENT_NOTE_MOD(SONG, t)) * WAVEFORM(t, CURRENT_NOTE(SONG, t))) #define PLAY(SONG, A, B) ((CURRENT_NOTE_RAW(SONG, t) != ' ') ? INSTRUMENT(t, SONG, A, B) : 0.0) #define FREQ(n) (SAMPLERATE / (440.0 * pow(1.059463, n))) #define A_VAL(t, A_TIME, A_LEVEL) ((t) / (A_TIME / A_LEVEL)) #define D_VAL(t, D_TIME, A_LEVEL, S_LEVEL) (A_LEVEL - (t) / (D_TIME / (A_LEVEL - S_LEVEL))) #define R_VAL(t, R_TIME, S_LEVEL) (t <= R_TIME ? (S_LEVEL - (t) / (R_TIME / S_LEVEL)) : 0.0) #define ADSR(t, mod, A_TIME, A_LEVEL, D_TIME, S_TIME, S_LEVEL, R_TIME) \ (t <= A_TIME ? ((mod & 0x20) ? A_VAL(t, A_TIME, A_LEVEL) : S_LEVEL) : \ (t <= A_TIME + D_TIME ? ((mod & 0x20) ? D_VAL(t - A_TIME, D_TIME, A_LEVEL, S_LEVEL) : S_LEVEL) : \ (t <= A_TIME + D_TIME + S_TIME ? S_LEVEL : \ ((mod & 0x10) ? R_VAL(t - A_TIME - D_TIME - S_TIME, R_TIME, S_LEVEL) : S_LEVEL)))) #define ADSR1(t, mod) ADSR(t, mod, 87, 1.0, 25, 87, 0.7, 200) #define SINE(t, NOTE) (sin(t * M_PI * 2 / FREQ(NOTE))) #define SQUARE(t, NOTE) (fmod(t, FREQ(NOTE)) > FREQ(NOTE) / 2.0 ? 1.0 : -1.0) #define SAWTOOTH(t, NOTE) (fmod(t, FREQ(NOTE)) / FREQ(NOTE) * 2.0 - 1.0) #define TRIANGLE(t, NOTE) ((fmod(t, FREQ(NOTE)) > FREQ(NOTE) / 2.0 ? SAWTOOTH(t, NOTE) : -SAWTOOTH(t, NOTE)) * 2.0 - 1.0) OUTPUT(PLAY("rst ", ADSR1, SINE) + PLAY(" uvw(HX ", ADSR1, SQUARE) + PLAY(" wvut ", ADSR1, SAWTOOTH) + PLAY(" srq", ADSR1, TRIANGLE))