#define M_PI 3.1415926535897932384626433832795 float adsr(float t, vec4 v, float s) { v.xyw = max(vec3(2.2e-05), v.xyw); float ta = t/v.x; float td = max(s, 1.0-(t-v.x)*(1.0-s)/v.y); float tr = (1.0 - max(0.0,t-(v.x+v.y+v.z))/v.w); return max(0.0, min(ta, tr*td)); } void main () { float l = 0.; float r = 0.; const float harmonics = 22.; vec2 uv = gl_FragCoord.xy / resolution; vec4 pf = texture(pFrameSynth, vec2(uv.x, uv.y + 0.05)); vec4 vi = texture(iInput0, vec2(uv.x, 1.-uv.y)); vec4 vi1 = texture(iInput1, vec2(uv.x, uv.y) * 2.); vec4 vi2 = texture(iInput2, vec2(uv.x, uv.y) * 2.); vec4 vi3 = texture(iInput3, vec2(uv.x, 1.-uv.y) * 4.); for (int k = 0; k < 48; k += 1) { vec4 data = keyboard[k]; float kfrq = data.x; // frequency float kvel = data.y; // velocity float ktim = data.z; // elpased time float kchn = data.w; // channel if (kfrq == 0.) { break; } if (uv.x < 0.25 && uv.x > 0. && kchn == 1.) { float kktim = abs(mod(ktim/2., 2.) - 1.); float u = abs((tanh(ktim / 8.) * (cos(kktim / 4.) / 3.1415)) * 10.275); for (float i = 1.; i < harmonics; i += 1.) { float amp_1 = ih[int(i) - 1]; float amp_2 = iha[int(i) - 1]; float rate = aeb[1]; float amp = mix(amp_1, amp_2, abs(mod(ktim*rate, 2.) - 1.)); float att = ih2[int(i) - 1] * u; float dec = ih3[int(i) - 1]; float attack = att; float decay = dec; float sustain = 0.; float release = 0.025; float dec_amp = 0.05; float env = kvel * adsr(ktim, vec4(attack, decay, sustain, release), dec_amp); l += fline(kfrq * i) * amp * kvel * env; r += fline(kfrq * i) * amp * kvel * env; } } else if (uv.x < 0.75 && uv.x > 0.5 && kchn == 2.) { float kktim = abs(mod(ktim/2., 2.) - 1.); float u = abs((tanh(ktim / 8.) * (cos(kktim / 4.) / 3.1415)) * 10.275); for (float i = 1.; i < harmonics; i += 1.) { float amp_1 = pow(ih[(int(i) - 1)], harmonics - i / 1.8); float amp_2 = iha[(int(i) - 1)]; float rate = aeb[1]; float amp = mix(amp_1, amp_2, abs(mod(kktim*rate*1.5, 2.) - 1.)); float att = ih2[(int(i) - 1)] / 2.; float dec = ih3[(int(i) - 1) % 2] * abs(sin(globalTime * 4.) / 3.1415); float attack = att; float decay = dec / u; float sustain = 0.; float release = 0.025; float dec_amp = 0.05; float env = kvel * adsr(ktim, vec4(attack, decay, sustain, release), dec_amp); float env2 = kvel * adsr(ktim, vec4(attack, dec * 8., sustain, release), dec_amp); l += fline(kfrq * i) * amp * kvel * env * env2; r += fline(kfrq * i) * amp * kvel * env * env2; } } else if (uv.x < 0.25 && uv.x > 0.5 && kchn == 1.) { float kktim = abs(mod(ktim/2., 2.) - 1.); float u = abs((tanh(ktim / 8.) * (cos(kktim / 4.) / 3.1415)) * 10.275); for (float i = 1.; i < harmonics; i += 1.) { float amp_1 = pow(ih[(int(i) - 1)], harmonics - i / 2.8); float amp_2 = iha[(int(i) - 1)]; float rate = aeb[1]; float amp = mix(amp_2, amp_1, abs(mod(kktim*rate*2., 2.) - 1.)); float att = ih2[(int(i) - 1)] * 4.; float dec = ih3[(int(i) - 1) % 2] * abs(sin(globalTime * 4.) / 3.1415); float attack = att; float decay = dec / u; float sustain = 0.; float release = 0.025; float dec_amp = 0.05; float env = kvel * adsr(ktim, vec4(attack, decay, sustain, release), dec_amp); float env2 = kvel * adsr(ktim, vec4(attack, dec * 8., sustain, release), dec_amp); l += fline(kfrq * i) * amp * kvel * env * env2 * (abs(sin(kktim) / 3.1415) + 0.75); l -= vi.r * 0.005; l = max(l, 0.); r += fline(kfrq * i) * amp * kvel * env * env2 * (abs(cos(kktim) / 3.1415) + 0.95); r -= vi.g * 0.005; r = max(r, 0.); } } else if (uv.x < 1. && uv.x > 0.75 && kchn == 3.) { float kktim = abs(mod(ktim/2., 2.) - 1.); float u = abs((tanh(ktim / 8.) * (cos(kktim / 4.) / 3.1415)) * 10.275); for (float i = 1.; i < harmonics; i += 1.) { float amp_1 = pow(ih[(int(i) - 1)], harmonics - i / 2.8); float amp_2 = iha[(int(i) - 1)]; float rate = aeb[1]; float amp = mix(amp_2, amp_1, abs(mod(kktim*rate/8., 2.) - 1.)); float att = ih2[(int(i) - 1)] / 8.; float dec = ih3[(int(i) - 1) % 2] * abs(sin(globalTime * 4.) / 3.1415); float attack = att; float decay = dec / u; float sustain = 0.; float release = 0.025; float dec_amp = 0.05; float env = kvel * adsr(ktim, vec4(attack, decay, sustain, release), dec_amp); float env2 = kvel * adsr(ktim, vec4(attack, dec * 2., sustain, release), dec_amp); l += fline(kfrq * i) * amp * kvel * env * env2 * (abs(sin(kktim) / 3.1415) + 0.75); l -= vi.r * 0.005; l = max(l, 0.); r += fline(kfrq * i) * amp * kvel * env * env2 * (abs(cos(kktim) / 3.1415) + 0.95); r -= vi.g * 0.005; r = max(r, 0.); } } } synthOutput = vec4(l, r, .179, mod(globalTime*(1.+l), 2.) - 1.); gl_FragColor = vec4(l*0.125, r*0.125, 0., 1.) * 12. + vi; }