Created
November 23, 2021 17:30
-
-
Save rngtm/3614e3828db6a32b82ebed980b0271a2 to your computer and use it in GitHub Desktop.
GLSL Sound 03
This file contains hidden or 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
#define PI acos(-1.0) | |
#define VOLUME pow(10.0, -5.0/10.0) | |
float DB(float db) { return pow(10.0, db/10.0); } | |
float random(float co) { return fract(sin(co*(91.3458)) * 47453.5453); } | |
struct Note | |
{ | |
float freq; | |
}; | |
Note GetNote(int index) | |
{ | |
Note n; | |
n.freq = 440.0 * exp2(float(index)/12.0); | |
return n; | |
} | |
float Tone(int index) | |
{ | |
return 440.0 * exp2(float(index)/12.0); | |
} | |
float SawWave(float time, float freq) | |
{ | |
return fract(time * freq); | |
} | |
float SineWave(float time, float freq) | |
{ | |
return sin(time * freq * 2.0 * PI); | |
} | |
float KickWave(float time) | |
{ | |
float freq = 30.0; | |
float kickVolume = pow(fract(-time*2.),4.); | |
//float kick = 3.0 * sin(450.0 * PI * time) * kickVolume * 0.8; | |
kickVolume = pow(kickVolume, 1.0); | |
float s = SineWave(time, freq)*kickVolume; | |
// float s = smoothstep(0.0, 0.1, fract(time * freq)); | |
// float th = 0.2; | |
// s = s / th; | |
// s = clamp(s, -1.0, 1.0); | |
return s; | |
// return SineWave(time, freq); | |
} | |
float SuperSawWave(float time, float freq) | |
{ | |
float wave; | |
float vol = 1.0; | |
int n = 10; | |
for (int i = 0; i < n; i++) | |
{ | |
float saw = SawWave(time, freq); | |
saw = pow(saw, 4.0); | |
// wave += SawWave(time, freq) * vol; | |
wave += saw * vol; | |
time += 0.1; | |
freq *= 1.007; | |
vol *= 0.73; | |
} | |
wave /= 8.0; | |
return wave; | |
} | |
float Wave(float time, float freq) | |
{ | |
float wave; | |
float vol = 1.0; | |
// freq *= 1.0 + 0.05 * SineWave(time, 1.0); | |
for (int i = 0; i < 7; i++) | |
{ | |
wave += SawWave(time, freq) * vol; | |
time += 0.1; | |
freq *= 1.007; | |
vol *= 0.73; | |
} | |
wave /= 7.0; | |
return wave; | |
} | |
float HighHat(float time) | |
{ | |
// if (time <= 0.5) return 0.0; | |
float tempo = 8.0; | |
float[] notes = float[] ( | |
0.2, | |
0.3, | |
1.0, | |
0.3 | |
); | |
float note = notes[int(time*tempo) % 4]; | |
time += exp2(-2.0); | |
float amp = fract(-time*tempo); | |
amp = pow(amp, 6.0)*note; | |
return (fract(sin(time*1e3)*1e6)-.5) * amp; | |
} | |
float CrashWave(float time) | |
{ | |
// if (time <= 0.5) return 0.0; | |
// float tempo = 8.0; | |
// float[] notes = float[] ( | |
// 0.2, | |
// 0.3, | |
// 1.0, | |
// 0.3 | |
// ); | |
// float note = notes[int(time*tempo) % 4]; | |
time = mod(time, 4.0); | |
int[] notes = int[] | |
( | |
1, | |
1, | |
1, | |
1 | |
); | |
// time += exp2(-2.0); | |
float release = 16.0; | |
float amp = 1.0 - time * release; | |
amp = max(0.0, amp); | |
// amp = pow(amp, 6.0); | |
return (fract(sin(time*1e3)*1e6)-.5) * amp; | |
} | |
float SquareWave(float time, float freq, float rate) | |
{ | |
return step(fract(time * freq), rate); | |
} | |
float TriangleWave(float time, float freq, float a) | |
{ | |
float t = fract(time*freq); | |
return min(t / a, (1.0-t)/(1.0 - a)); | |
} | |
float SuperSquareWave(float time, float freq, float rate) | |
{ | |
float wave; | |
float vol = 1.0; | |
int n = 10; | |
for (int i = 0; i < n; i++) | |
{ | |
float saw = SquareWave(time, freq, rate); | |
saw = pow(saw, 4.0); | |
// wave += SawWave(time, freq) * vol; | |
wave += saw * vol; | |
time += 0.1; | |
freq *= 1.007; | |
vol *= 0.73; | |
} | |
wave /= 8.0; | |
return wave; | |
} | |
float Wave1(float time) | |
{ | |
float tempo = 0.5; | |
int noteCount = 4; | |
float waveTime = time; | |
time *= tempo; | |
//float amp = exp(-3.0 * fract(time)); | |
int noteIndex = int(time / 2.0); | |
noteIndex = noteIndex % noteCount; | |
int key = -8-12; | |
Note[] notes1 = Note[] | |
( | |
GetNote(0), | |
GetNote(-2+12), | |
GetNote(-4), | |
GetNote(-7) | |
); | |
Note[] notes2 = Note[] | |
( | |
GetNote(3), | |
GetNote(0), | |
GetNote(-2+12), | |
GetNote(-2) | |
); | |
Note[] notes3 = Note[] | |
( | |
GetNote(5), | |
GetNote(3), | |
GetNote(3), | |
GetNote(0+12) | |
); | |
Note n1 = notes1[noteIndex]; | |
Note n2 = notes2[noteIndex]; | |
Note n3 = notes3[noteIndex]; | |
int ampIndex = int(fract(time)) % 4; | |
#define PLUCK pow(1.0 - fract(time * 8.0), 0.7) | |
float amp = | |
pow(fract(mod(-time* 16., 8.)/3.), 0.3) | |
* mix(0.1, 1.0, PLUCK); | |
float freqRange = 4.0; | |
float wave = | |
SuperSawWave(waveTime, (n1.freq) * exp2(float(key)/12.0)) + | |
SuperSawWave(waveTime, (n2.freq) * exp2(float(key)/12.0)) + | |
SuperSawWave(waveTime, (n3.freq) * exp2(float(key)/12.0)) | |
; | |
return wave * amp; | |
} | |
float PicoPicoRandomArp(float time) | |
{ | |
float tempo = 0.5; | |
int noteCount = 8; | |
int[] notes = int[] ( | |
0, | |
5, | |
8, | |
10, | |
0 + 12, | |
5 + 12, | |
8 + 12, | |
10 + 12 | |
); | |
float waveTime = time; | |
float release = 16.0; | |
time *= tempo; | |
float ampTime = time * release; | |
int noteIndex = int(time*16.0); | |
int key = -8; | |
noteIndex = int(random(float(noteIndex)) * float(noteCount)); | |
int tone = notes[noteIndex % noteCount]; | |
float freq = 440.0 * exp2(float(tone + key)/12.0); | |
#define PLUCK02 pow(1.0 - fract(ampTime), 0.01) | |
float amp = | |
pow(fract(mod(-time* 16., 8.)/3.), 0.3) | |
* mix(0.1, 1.0, PLUCK02); | |
float freqRange = 4.0; | |
return SquareWave(waveTime, freq, 0.5) * amp; | |
} | |
float PicoPicoAscendArp(float time) | |
{ | |
float tempo = 0.5; | |
int noteCount = 16; | |
int[] notes1 = int[] ( | |
0, | |
5, | |
8, | |
10, | |
0 + 12, | |
5 + 12, | |
8 + 12, | |
10 + 12, | |
0 + 12*2, | |
5 + 12*2, | |
8 + 12*2, | |
10 + 12*2, | |
0 + 12*2, | |
5 + 12*2, | |
8 + 12*2, | |
10 + 12*2 | |
// 0 + 12*0, | |
// 5 + 12*1, | |
// 8 + 12*2, | |
// 10 + 12*2 | |
); | |
int[] notes2 = int[] ( | |
0, | |
5, | |
8, | |
10, | |
0 + 12, | |
5 + 12, | |
8 + 12, | |
10 + 12, | |
0 + 12*2, | |
5 + 12*2, | |
8 + 12*2, | |
10 + 12*2, | |
// 10 + 12*2, | |
// 8 + 12*1, | |
// 5 + 12*0, | |
// 0 + 12*0 | |
// 0 + 12*0, | |
// 5 + 12*1, | |
// 8 + 12*2, | |
// 10 + 12*2 | |
0 + 12*3, | |
5 + 12*3, | |
8 + 12*3, | |
10 + 12*3 | |
); | |
float[] vels1 = float[] | |
( | |
1.0, | |
1.0, | |
1.0, | |
1.0, | |
1.0, | |
1.0, | |
1.0, | |
1.0, | |
1.0, | |
1.0, | |
1.0, | |
1.0, | |
DB(-1.0), | |
DB(-1.0), | |
DB(-2.0), | |
DB(-2.0) | |
); | |
float[] vels2 = float[] | |
( | |
1.0, | |
1.0, | |
1.0, | |
1.0, | |
1.0, | |
1.0, | |
1.0, | |
1.0, | |
1.0, | |
1.0, | |
1.0, | |
1.0, | |
DB(-4.0), | |
DB(-4.0), | |
DB(-4.0), | |
DB(-4.0) | |
); | |
float waveTime = time; | |
float release = 16.0; | |
time *= tempo; | |
float ampTime = time * release; | |
int noteIndex = int(time*16.0); | |
int barIndex = noteIndex / noteCount; | |
int key = -8-12; | |
noteIndex = noteIndex % noteCount; | |
int tone = barIndex % 4 < 3 ? | |
notes1[noteIndex] : | |
notes2[noteIndex]; | |
float vel = barIndex % 4 < 3 ? | |
vels1[noteIndex] : | |
vels2[noteIndex]; | |
// float freq = 440.0 * exp2(float(tone + key)/12.0); | |
float freq = Tone(tone + key); | |
#define PLUCK02 pow(1.0 - fract(ampTime), 0.01) | |
float amp = | |
pow(fract(mod(-time* 16., 8.)/3.), 0.3) | |
* mix(0.1, 1.0, PLUCK02) | |
* vel | |
; | |
float freqRange = 4.0; | |
return SquareWave(waveTime, freq, 0.5) * amp; | |
} | |
float Wave2(float time) | |
{ | |
float wave; | |
if (time < 32.0) | |
wave += PicoPicoAscendArp(time); | |
// else | |
if (time > 32.0) | |
wave += PicoPicoRandomArp(time); | |
return wave; | |
} | |
float BaseWave(float time, float freq) | |
{ | |
float wave; | |
wave += SquareWave(time, freq, 0.2); | |
wave += SquareWave(time, freq * 2.0, 0.2) * 0.5; | |
wave += SquareWave(time, freq * 4.0, 0.2) * 0.15; | |
return wave / 2.0; | |
} | |
float Wave3(float time) | |
{ | |
time -= 1.0 / 4.0; | |
float wave = BaseWave(time, 440.0*exp2(-4.0)); | |
float amp = SquareWave(time - 0.5, 2.0, 0.5); | |
return wave * 0.1 * amp; | |
} | |
float Wave4(float time) | |
{ | |
int noteCount = 24; | |
float tempo = 0.5; | |
int key = -8-24; | |
int[] notes = int[] | |
( | |
0, | |
0, | |
3, | |
3, | |
7, | |
7, | |
5, | |
3, | |
0, | |
0, | |
3, | |
3, | |
7, | |
7, | |
5, | |
3, | |
0+12, | |
0+12, | |
8, | |
8, | |
7, | |
7, | |
5, | |
5, | |
0+12, | |
0+12, | |
8, | |
8, | |
7, | |
7, | |
3, | |
3 | |
); | |
int tone = notes[int(time * tempo) % noteCount]; | |
// float freq = notes[index].freq * exp2(float(key)/-24.0) + SineWave(time, .0); | |
float freq = Tone(tone + key); | |
float wave; | |
float a = 0.5; | |
float amp = 1.0 - fract(time); | |
wave += SuperSquareWave(time, freq * 1.0, a) / 4.0; | |
wave += SuperSquareWave(time, freq * 2.0, a) / 2.0; | |
wave += SuperSquareWave(time, freq * 3.0, a); | |
return wave * 0.2; | |
} | |
float RiseFX(float time) | |
{ | |
float noteDivs = 40.0; | |
float riseTime = 6.0; | |
float freq1 = Tone(-24 + 12 + 10); | |
float freq2 = Tone(-24 + 12 + 10 + 12); | |
int noteCount = 2; | |
float[] notes = float[] | |
( | |
Tone(0), | |
Tone(6) | |
); | |
float t = clamp(time / riseTime, 0.0, 1.0); | |
float note = notes[int(time*noteDivs)%noteCount]; | |
float finalFreq = mix(freq1, freq2, t) + note; | |
float volume = 1.0 - t; | |
float wave; | |
wave += SawWave(time, finalFreq); | |
return wave * volume; | |
} | |
float DownFX(float time) | |
{ | |
float noteDivs = 40.0; | |
float riseTime = 6.0; | |
float freq1 = Tone(-24 + 18 + 12); | |
float freq2 = Tone(-24 + 18); | |
int noteCount = 2; | |
float[] notes = float[] | |
( | |
Tone(0), | |
Tone(6) | |
); | |
float t = (time / riseTime); | |
t = clamp(t, 0.0, 1.0); | |
float note = notes[int(time*noteDivs)%noteCount]; | |
float finalFreq = mix(freq1, freq2, t) + note; | |
float volume = 1.0 - t; | |
float wave; | |
wave += SawWave(time, finalFreq); | |
return wave * volume; | |
} | |
#define TimeScale exp2(3.0/12.0) | |
vec2 mainSound(float time){ | |
float realTime = time; | |
time = time * TimeScale; | |
time = mod(time, 64.0); | |
float waveTime = time; | |
float kickVolume = pow(fract(-time*2.),4.); | |
float kick = KickWave(waveTime); | |
float hat = HighHat(time); | |
// delay | |
float wave1; | |
{ | |
float sum; | |
float delay = 0.12; | |
for (int i = 5; i >= 1; i--) | |
{ | |
wave1 += Wave1(waveTime - delay * float(i)); | |
wave1 *= 0.7; | |
sum += 0.7; | |
} | |
wave1 *= 0.5; | |
wave1 += Wave1(waveTime); | |
wave1 = wave1 / sum * 2.0; | |
} | |
float melo; | |
{ | |
// フェードイン | |
float amp = time; | |
time /= 16.0; | |
float delay = 0.12; | |
amp = min(amp, 1.0); | |
amp = pow(amp, 0.1); | |
amp = mix(0.2, 1.0, amp); | |
for (int i = 5; i >= 1; i--) | |
{ | |
melo += Wave4(waveTime - delay * float(i)); | |
melo *= 0.7; | |
} | |
melo *= 0.3; | |
melo += Wave4(waveTime); | |
melo *= amp; | |
} | |
// else | |
float arp; | |
{ | |
//wave2 += Wave2(waveTime); | |
float delay = 0.24; | |
for (int i = 3; i >= 1; i--) | |
{ | |
arp += Wave2(waveTime - delay * float(i)); | |
arp *= 0.7; | |
} | |
arp *= 0.5; | |
arp += Wave2(waveTime); | |
} | |
float chord = wave1; | |
float bass = Wave3(time); | |
float chordVolume = (time < 32.0) ? pow(10.0, -3.0/10.0): pow(10.0, -8.0/10.0); | |
float arpVolume = (time < 32.0) ? DB(-16.0) : DB(-14.0); | |
float fx = DownFX(realTime); | |
float wave = | |
+ chord * (1.0 - kickVolume) * chordVolume | |
+ hat * DB(-10.0) | |
+ arp * arpVolume | |
+ kick * DB(-3.0) | |
+ bass * DB(-2.0) * (1.0 - kickVolume) | |
+ melo * DB(-4.0) | |
+ fx*DB(-18.0) | |
+ CrashWave(time)*DB(-15.0) | |
; | |
return vec2(wave*DB(2.0)); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment