my first loop
 1 loop, 0 filters (1 worker, 1 AudioWorklet)
 tick: 0.000, time: 0.000 (1 bpm)
 
 
 
 
 

auroralcircuits

#LoFiVibes #Retrowave #PunctumContra #OriginalMusic

Log in to post a comment.

// synth chords
function chd(rt, nt, sw) {
const chrr = [chord(f4, chords['7sus4']),
chord(ab3, chords['M7']),
chord(c4, chords['m7']),
chord(db3, chords['M7'])];
let y = 0.;
const ft = .5 * rt;
const ev = env_adc(fract(ft), .4, .64);
const crr = chrr.ring(ft);
for (let i = 0; i < crr.length; i++) {
const x = max(.6, fract(ft)) - cos(.7 * sin(sw * rt) + midi_to_hz(crr.ring(i)) * tau * rt);
y += sin(3 * fract(.5 + x)) + cos(mod(x, tau));
}
y *= .3 * ev;
return y;
}
// strings
const instrument = { vio0: 0, vio1: 1, vio2: 2 };
function strings(rt, mt, type) {
const melscl = scale(f3, scales['melodic_minor_desc'], 2);
let y = 0;
switch (type) {
case instrument.vio0: {
const ft = mt * rt;
y = (cos(1.57 * mod(midi_to_hz(melscl.ring(ft)) * rt * tau, tau))
+ sin(sin(2 * rt) * 3.14 * mod(midi_to_hz(melscl.ring(ft)) * rt * tau, PI / 2)))
* pow(min(1., 10. * fract(ft)) * (1. - fract(ft)), 2.);
};break;
case instrument.vio1: {
const ft = mt * rt;
y = sin(sin(8 * rt) * 2. + 0.523 * mod((2 * midi_to_hz(melscl.ring(ft)) * rt * tau), PI))
* env_adc(fract(ft), .22, .345);
};break;
case instrument.vio2: {
const ft = mt * rt;
y = (sin(2 + 0.785 * mod(midi_to_hz(melscl.ring(ft)) * rt * tau, PI))
+ cos(sin(3 * rt) * 2. + 0.628 * mod(midi_to_hz(melscl.ring(ft)) * rt *tau, tau)))
* env_adc(fract(ft), .124, .467);
};break;
}
return y;
}
//################# InstumentGroup
const InstGr = class {
constructor() {}
process(time) {
let inst0 = 0 //violine
, inst1 = 0 //cello
, inst2 = 0 //cello
, inst3 = 0 //staccato
, inst4 = 0; //chords
inst4 = chd(.15 + time, time, 24) * .7 + chd(.05 + .5025 * time, .5 * time, 12);
// phaseoffset * [...scalestart] * time
inst3 = strings(1.0025 * [1, 4, 3].ring([1, 2].ring(time) * time) + .5 * time, [4, 6].ring(.125 * time),instrument.vio2);
inst3 += .9 * strings(.50005 * [7, 9, 5].ring(.5 * time) + .5 * time, [4, 6].ring(.125 * time), instrument.vio2);
inst0 = strings(.50005 * [5, 4, 7].ring(time) + time, [6, 4].ring(.5 * time), instrument.vio1);
let htime = time * .5; // mod(time * .5, 32);
inst1 = strings(1.0025 * [1, 8, 3].ring(htime) + mod(-.5 * htime, 3) + htime, 4, instrument.vio0)
* lerp(1.,.83, mod(.25 * htime, 1))
inst2 = strings(1.00005 * [3, 5, 1].ring(htime) + mod(-htime, 2) + .5 * htime, 4, instrument.vio0)
* lerp(.77,1., mod(.25 * htime, 1));
inst0 *= .25 * gainEnv(mod(time, 32), 9, 30, 3);
inst1 *= .17 * gainEnv(time, 18, 60, 1);
inst1 += (time > 24 ? (.19 * strings(time, 4, instrument.vio0) * gainEnv(mod(time, 14), 7, 2, 2)) : 0);
inst2 *= .22 * min(1, time/22);
inst3 *= .17 * min(1, time/5);
inst4 *= .7;
return { inst0Out: inst0, inst1Out: inst1, inst2Out: inst2, inst3Out: inst3, inst4Out: inst4 };
}
}
// ################ MIX
const MIX = class {
constructor() {
this.period = 0;
this.cmain = new InstGr();
this.crev = [
new Rev_Mn(), new Rev_Mn(), new Rev_Mn(),new Rev_Mn(),
new Rev_Mn(), new Rev_Mn(),
new Rev_Mn(), new Rev_Mn(), new Rev_Mn(), new Rev_Mn()];
this.fltr = new FilterBank();
this.swidth = [new FilterBank(),new FilterBank() ];
this.eq3band = [new Band3Eq(), new Band3Eq()];
}
process() {
let inst0 = 0//violine
,inst1 = 0//cello
,inst2 = 0//cello
,inst3 = 0//staccato
,inst4 = 0;//chords
let rev_sum = [0, 0], bas_sum = [0,0];
this.period += 1;
let time = this.period / ditty.sampleRate;
const cmain = this.cmain.process(time);
inst0 = this.fltr.svf_opt2(cmain.inst0Out, 460, 1., -12., 2, 0);
inst1 = this.fltr.svf_opt2(cmain.inst1Out, 2300, 1, -7., 8, 1);
inst2 = this.fltr.svf_opt2(cmain.inst2Out, 1800, 1, -10., 8, 2);
inst3 = this.fltr.svf_opt2(cmain.inst3Out, 1600, 1, -12., 8, 3);
inst4 = cmain.inst4Out;
inst4 = lerp(inst4, this.fltr.svf_opt2(inst4, 4200, .7, 3, 1, 4), .7);
let drysum = tanh(2 * ( .7 * inst0 + .3 * inst3 + .4 * inst4 + ( .5 * (inst1 + inst2)))) ;
drysum = this.fltr.svf_opt2(drysum, 40, .7, -6., 2, 5);
let stx = min(1.1, (.75 + smoothstep(0, 16, mod(floor(time), 16.)) ));
// difference +/- 6 will induce a slight panning, which helps with frequency separation
rev_sum[0] = this.crev[0].process(inst0, 0, 25, 0.46);
rev_sum[1] = this.crev[1].process(inst0, 8, 25, 0.47);
bas_sum[0] = this.crev[2].process(inst1, 0, 46, 0.69);
bas_sum[1] = this.crev[3].process(inst1, 8, 46, 0.63);
bas_sum[0] += this.crev[4].process(inst2, 0, 50, 0.42);
bas_sum[1] += this.crev[5].process(inst2, 8, 50, 0.39);
rev_sum[0] += this.crev[6].process(inst3, 0, 30, 0.46);
rev_sum[1] += this.crev[7].process(inst3, 8, 30, 0.41);
rev_sum = this.swidth[0].stwidth(rev_sum, 1.1);
rev_sum[0] += this.crev[8].process(inst4, 0, 32, 0.56);
rev_sum[1] += this.crev[9].process(inst4, 8, 32, 0.61);
bas_sum = this.swidth[1].stwidth(bas_sum, .83);
rev_sum[0] += bas_sum[0] + drysum;
rev_sum[1] += bas_sum[1] + drysum;
// master out
const veq = {lowG:8, midG:-2, hghG:5,lowMidFq:260,midHghFq:2800,masterG:3};
rev_sum[0] = this.eq3band[0].process(rev_sum[0], veq );
rev_sum[1] = this.eq3band[1].process(rev_sum[1], veq );
return rev_sum;
}
}
// ################ REVERB
const Rev_Mn = class {
constructor() {
this.zn = Array.from({length: 8}, () => Array(2639).fill(0));
this.dcBlockState = Array.from({length: 17}, () => [0, 0]);
this.period = 0;
}
process(rv_xin, offs, rtail, scl) {
this.period += 1;
let y = [0, 0, 0, 0, 0, 0, 0, 0];
let rv = 0,itter = 0;
const mat0 = [1, -1, 1, -1, -1, 1, -1, 1, 1, -1, 1, -1, -1, 1, -1, 1];
const mat1 = [-1, 1, -1, 1, 1, -1, 1, 1, 1, -1, 1, -1, 1, 1, -1, -1];
const mat2 = [1, 1, 1, 1, 1, -1, 1, -1, -1, 1, -1, 1, 1, -1, 1, 1];
let dt = [1637, 1277, 1607, 2639, 1823, 751, 1823, 2591];
dt = dt.map((n, idx) => (scl * dt[idx]) | 0);
for (let i = 0; i < 8; i++) {
const it8 = i % 8;
const pdt = this.period % dt[it8];
const g3 = exp(-(1 * rtail * 0.022675736) / (i + 1));
for (let it = 0; it < 2; it++) {
const g4 = exp(-((1.41421 / rtail) * 0.0022675736) * (itter + 1));
y[it8] = this.dcblock((this.zn[it8][pdt] * mat0[itter % 16]), g4, itter);
itter++;
}
this.zn[it8][pdt] = g3 * y[it8] + mat2[i % 8 + offs] * rv_xin;
rv += mat1[i % 8 + offs] * y[it8];
}
rv = this.dcblock(rv, .997, 16);
return rv * 0.25;
}
dcblock(xin, at, instnc) {
let state = this.dcBlockState[instnc];
let y0 = xin - state[0] + at * state[1];
state[0] = xin;
state[1] = y0;
return y0;
}
};
//################ FILTERBANK
class FilterBank {
constructor() {
this.svf_opt2State = Array.from({length: 8}, () => [0, 0]);
this.dcBlockState = Array.from({length: 8}, () => [0, 0]);
//this.sfv_type = {low: 0,band: 1,high: 2,notch: 3,peak: 4,all: 5,bell: 6,lsf: 7,hsf: 8};
}
// http://www.cytomic.com/files/dsp/SvfLinearTrapOptimised2.pdf
svf_opt2(v0, cutoff, Q, bellgaindB, type, instance) {
let m = [0, 0, 0];
let a1 = 0, a2 = 0, a3 = 0;
let v1 = 0, v2 = 0, v3 = 0;
let ic1eq = this.svf_opt2State[instance][0]
, ic2eq = this.svf_opt2State[instance][1];
const A = Math.pow(10.0, bellgaindB / 40.0);
let g = tan(PI * cutoff / 44100);
if (type == 7) g /= sqrt(A) // low shelf
else if (type == 8) g *= sqrt(A) // high shelf
let k = 1 / (type == 6 ? (A * Q) : Q); //bell A*Q
const filter = [[0, 0, 1], [0, 1, 0], [1, -k, -1], [1, -k, 0], [1, -k, -2],
[1, -2 * k, 0], [1, k * (A * A - 1), 0], [1, k * (A - 1), (A * A - 1)], [A * A, k * (1 - A) * A, (1 - A * A)]];
a1 = 1 / (1 + g * (g + k));
 
 
הההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההה
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
7592 chars