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.; vec2 uv = gl_FragCoord.xy / resolution; float attenuation_constant = 1.495; const float harmonics = 24.; vec4 t = texture(iInput0, vec2(uv.x, uv.y)); vec4 t2 = texture(iInput1, vec2(1.-uv.x, uv.y)); vec4 t3 = texture(iInput2, vec2(uv.x, uv.y)); float grain_sample = 0.28; for (int k = 0; k < 28; k += 1) { vec4 data = keyboard[k]; float kfrq = data.x; float kvel = data.y; float ktim = data.z; float kchn = data.w; if (kfrq == 0.) { break; } vec3 pdata = pKey[int(kchn)]; if (uv.x > 0. && uv.x < 0.25 && kchn == 0.) { for (float i = 1.; i < harmonics; i += 1.25) { float a = 1. / pow(i, attenuation_constant + abs(cos(ktim * 0.8385 * (i / 2.)) * (i / 3.)) * 2.); float env_l = adsr(ktim, vec4(0.00195, 0.18 + abs(tan(a / 8. + ktim / 8.)), 0.25, 0.0725), 0.0125); float env_r = adsr(ktim, vec4(0.00295, 0.12 + abs(sin(a/8. + ktim / 8.)), 0.25, 0.0725), 0.0125); l += fline(kfrq * i) * a * kvel * env_l * 2.; r += fline(kfrq * i) * a * kvel * env_r * 2.; } } else if (uv.x > 0.25 && uv.x < 0.5 && kchn == 1.) { for (float i = 1.; i < harmonics / 2.; i += 1.65) { float a = 1. / pow(i, attenuation_constant + abs(sin(ktim / 8. * (i / 1.25)) * (i / 2. * 2.))); float a2 = 1. / pow(i, attenuation_constant + abs(sin(ktim / 8. * (i / 1.25)) * (i / 2. * 2.))); float env_l = adsr(ktim, vec4(0.05, 0.0018 + abs(sin(a / 8. + ktim * 2.) *i), 0.0025, 0.00525), 0.025); float env_r = adsr(ktim, vec4(0.05, 0.0012 + abs(sin(a / 8. + ktim * 2.) * i), 0.0025, 0.00525), 0.025); l += fline(kfrq * i) * a * kvel * env_l * 2.; r += fline(kfrq * i) * a2 * kvel * env_r * 2.; } grain_sample = 2.02492; } else if (uv.x > 0.5 && uv.x < 0.75 && kchn == 2.) { kfrq = mix(pdata.x, kfrq, min(ktim * 20., 1.)); for (float i = 1.; i < harmonics / 3.; i += 1.) { float a = 1. / pow(i, attenuation_constant + abs(sin(ktim / 4. * (i * 1.25)) * (i / 2.))); float env_l = adsr(ktim, vec4(0.025, 0.18 + abs(sin(a / 8. + ktim / 2.)), 0.025, 0.0525), 0.025); float env_r = adsr(ktim, vec4(0.035, 0.12 + abs(sin(a / 8. + ktim / 2.)), 0.025, 0.0525), 0.025); l += fline(kfrq * i) * a * kvel * env_l * 2.; r += fline(kfrq * i) * a * kvel * env_r * 2.; } grain_sample = 0.028; } else if (uv.x > 0.75 && uv.x < 1. && kchn == 3.) { kfrq = mix(pdata.x, kfrq, min(ktim * 10., 1.)); for (float i = 1.; i < harmonics / 3.; i += 1.5) { float a = 1. / pow(i, attenuation_constant + abs(sin(ktim / 8. * (i / 2.25)) * (i / 8.))); float a2 = 1. / pow(i, attenuation_constant + abs(sin(ktim /8. * (i / 2.25)) * (i / 8.))); float env_l = adsr(ktim, vec4(0.5, 0.0018 + abs(sin(a * 8. + ktim * 8.)), 0.025, 0.525), 0.025); float env_r = adsr(ktim, vec4(0.5, 0.0012 + abs(sin(a * 8. + ktim * 8.)), 0.025, 0.525), 0.025); l += fline(kfrq * i) * a * kvel * env_l * 2.; r += fline(kfrq * i) * a2 * kvel * env_r * 2.; } grain_sample = 3.66695; } } float grain_index = mod(globalTime / 16. * uv.y + uv.x, 0.8); synthOutput = vec4(l, r, grain_sample, grain_index); gl_FragColor = vec4(l, r, 0., 1.) * 12. + (t3 + (t * 0.085 * sin(globalTime / 1.))) + t3 * 0.25; }