Skip to content

Instantly share code, notes, and snippets.

@antoinechampion
Created July 2, 2022 16:24
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save antoinechampion/ddfa605a96838e40e108c4b3c27555bc to your computer and use it in GitHub Desktop.
Save antoinechampion/ddfa605a96838e40e108c4b3c27555bc to your computer and use it in GitHub Desktop.
Synthesizer playing the Tetris music
// 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