/** *

Intensified Loops

*

by Benito

*

Weird looper that changes loop length and speed according to mouse position.

*

(Using the same sounds as ExtraVerby from a few days ago…):

* *

I think you can sit around and play with this one for a while…

*/ import net.beadsproject.beads.core.*; import net.beadsproject.beads.ugens.*; import net.beadsproject.beads.data.*; import net.beadsproject.beads.events.*; AudioContext ac; Gain mg; Compressor comp; Envelope speedEnv, sizeEnv; Envelope[] envs; Gain[] gains; ILooper iloop; float[] pent = {0, 1.98, 3.95, 7.02, 8.99}; void setup() { size(400, 400); envs = new Envelope[256]; gains = new Gain[256]; ac = new AudioContext(); speedEnv = new Envelope(ac, 1); sizeEnv = new Envelope(ac, 10000); iloop = new ILooper(ac, speedEnv, sizeEnv); mg = new Gain(ac, 1, .4); comp = new Compressor(ac); comp.addInput(iloop); mg.addInput(comp); ac.out.addInput(mg); ac.start(); } void draw() { background(0); } void mouseMoved() { float sped = pow(2, ((float)mouseY / height) * 4) * .25; speedEnv.clear(); speedEnv.addSegment(sped, 100); float siz = ((float)mouseX / width) * 43100 + 1000; sizeEnv.clear(); sizeEnv.addSegment(siz, 100); println(sped + " " + siz); } void keyPressed() { keyReleased(); if(key == ' ') { Envelope env = new Envelope(ac, 0); env.addSegment(2, 2); env.addSegment(-.8, 4); env.addSegment(.2, 6); env.addSegment(0, 10); env.addSegment(0, 10, new KillTrigger(env)); iloop.addInput(env); } else if(key >= '1' && key <= '9') { Noise n = new Noise(ac); Envelope env = new Envelope(ac, 0); Gain g = new Gain(ac, 1, env); BiquadFilter bf = new BiquadFilter(ac, 1, BiquadFilter.BP_PEAK); float freq = pow(2, (float)key - 49) * 50; bf.setQ(.9).setFrequency(freq); //println(freq); bf.addInput(n); g.addInput(bf); env.addSegment(2, 50); env.addSegment(1, 50); envs[key] = env; gains[key] = g; iloop.addInput(g); } else { Envelope env = new Envelope(ac, 0); int newkey = key % 40; float freq = 55 * pow(2, newkey / pent.length + pent[newkey % pent.length] / 12 + (float)(key % 17) / 500); WavePlayer saw = new WavePlayer(ac, freq, Buffer.SAW); Gain g = new Gain(ac, 1, env); g.addInput(saw); env.addSegment(.4, 10); env.addSegment(.18, 40); envs[key] = env; gains[key] = g; iloop.addInput(g); } // trap escape if(key == ESC) { key = 0; } } void keyReleased() { if(envs[key] != null) { envs[key].addSegment(0, 200, new KillTrigger(gains[key])); envs[key] = null; gains[key] = null; } } class ILooper extends UGen { float[] mem; float index, loopindex; int memsize; UGen speed, loopsize; float lastval = 0; float memval = 0; public ILooper(AudioContext con, UGen speed, UGen loopsize) { super(con, 1, 1); this.speed = speed; this.loopsize = loopsize; memsize = 44101; mem = new float[memsize]; } public void calculateBuffer() { speed.update(); loopsize.update(); float[] bi = bufIn[0]; float[] bo = bufOut[0]; for(int i = 0; i < bufferSize; i++) { float inc = speed.getValue(0, i); int start = (int)index; int len = (int)(index + inc) - start; int ls = (int)loopsize.getValue(0, i); int intindex = start; float thisval = bi[i]; if(len == 1) { memval = mem[start]; bo[i] = mem[start] = memval * .9 + thisval; loopindex++; if(loopindex >= ls) { index = (index + memsize - ls) % memsize; loopindex -= ls; } } else if(len > 1) { for(int j = 0; j < len; j++) { float interpval = lastval + (thisval - lastval) * (j + 1) / len; memval = mem[intindex]; bo[i] = mem[intindex] = memval * .9 + interpval; intindex = (intindex + 1) % memsize; loopindex++; if(loopindex >= ls) { index = (index + memsize - ls) % memsize; intindex = (int) index; loopindex -= ls; } } } index = (index + inc) % memsize; lastval = thisval; } } }