Skip to content

Instantly share code, notes, and snippets.

@rngtm
Created November 23, 2021 17:30
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save rngtm/3614e3828db6a32b82ebed980b0271a2 to your computer and use it in GitHub Desktop.
Save rngtm/3614e3828db6a32b82ebed980b0271a2 to your computer and use it in GitHub Desktop.
GLSL Sound 03
#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