- #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))