-
-
Save antoinechampion/ddfa605a96838e40e108c4b3c27555bc to your computer and use it in GitHub Desktop.
Synthesizer playing the Tetris music
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Generates a note for a given frequency | |
float synth(float freq) { | |
float output = freq*fmod(TIME, 1/freq) / 2; | |
output += freq*fmod(TIME, 1/(freq*1.005)) / 2; | |
output += freq*fmod(TIME, 1/(freq*0.995)) / 2; | |
output += 0.5*pow(sin(2*M_PI*freq / 4 * TIME), 5); | |
return output; | |
} | |
// Linear interpolation | |
float lerp(float x, float x1, float x2, float y1, float y2) { | |
return y1 + (x-x1) * (y2-y1) / (x2-x1) ; | |
} | |
// Manages attak, decay, sustain and release | |
float adsr(float sample, float t, float duration) { | |
float attackTime = 0.01; | |
float decayTime = 0.1; | |
float sustainGain = 0.5; | |
float releaseTime = 0.1; | |
if (t < attackTime) { | |
sample *= lerp(t, 0, attackTime, 0, 1); | |
} | |
else if (t < attackTime + decayTime) { | |
sample *= lerp(t, attackTime, attackTime + decayTime, 1, sustainGain); | |
} | |
else if (t < duration - releaseTime) { | |
sample *= sustainGain; | |
} | |
else { | |
sample *= lerp(t, duration - releaseTime, duration, sustainGain, 0); | |
} | |
return sample; | |
} | |
// Tetris notes and durations | |
const float notes[41][2] = { | |
{659.25, 0.5}, {493.88, 0.25}, {523.25, 0.25}, {587.33, 0.5}, {523.25, 0.25}, {493.88, 0.25}, | |
{440.00, 0.5}, {440.00, 0.25}, {523.25, 0.25}, {659.25, 0.5}, {587.33, 0.25}, {523.25, 0.25}, | |
{493.88, 0.5}, {493.88, 0.25}, {523.25, 0.25}, {587.33, 0.5}, {659.25, 0.5}, | |
{523.25, 0.5}, {440.00, 0.5}, {440.00, 0.5}, {0, 0.5}, | |
{0, 0.25}, {587.33, 0.5}, {698.46, 0.25}, {880.00, 0.5}, {783.99, 0.25}, {698.46, 0.25}, | |
{659.25, 0.75},{523.25, 0.25}, {659.25, 0.5}, {587.33, 0.25}, {523.25, 0.25}, | |
{493.88, 0.5}, {493.88, 0.25}, {523.25, 0.25}, {587.33, 0.5}, {659.25, 0.5}, | |
{523.25, 0.5}, {440.00, 0.5}, {440.00, 0.5}, {0, 0.5}, | |
}; | |
const float totalDuration = 16; | |
formula_main { | |
float output = 0; | |
float musicTime = fmod(TIME, totalDuration); | |
float noteLength, noteFreq; | |
for (int i = 0; i < 41; i++) { | |
noteFreq = notes[i][0]; | |
noteLength = notes[i][1]; | |
if (musicTime < noteLength) { | |
break; | |
} | |
else { | |
musicTime -= noteLength; | |
} | |
} | |
output = synth(noteFreq); | |
output = adsr(output, musicTime, noteLength); | |
return output; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment