|
- // TODO: turn off adcThru when recording
- // TODO: Effects break panning for some unknown reason
-
- // Capture mic/line in and monitor through DAC. Limit
- adc => Dyno inputLimiter => Gain adcThru => dac; // Monitor input
- inputLimiter.limit();
- inputLimiter @=> UGen @ mainInput;
-
- // Effects chain with limiters, reverb, filters
- PRCRev reverb => LPF lpf => Dyno outputLimiter => dac;
- outputLimiter.limit();
- reverb @=> UGen @ outputWet; // Reference to wet output
- outputLimiter @=> UGen @ outputDry; // Reference to dry output
-
- // Default parameters
- .5 => adcThru.gain;
- 10000 => lpf.freq;
- 1::second => dur loopTime;
-
- // Plug in the pedals
- LoopPedal pedals[4];
- for( 0 => int i; i < pedals.cap(); i++ ) {
- pedals[i].recordFrom(mainInput);
- pedals[i].outputTo(outputWet, outputDry);
- }
-
- // Start listening to OSC messages
- OscIn oin; 9000 => oin.port;
- oin.listenAll();
- OscMsg msg;
-
- // Event loop
- while (true) {
- oin => now;
- while (oin.recv(msg)) {
- if (msg.address=="/input") {
- msg.getFloat(0) => adc.gain;
- msg.getFloat(1) => adcThru.gain;
- }
- else if(msg.address=="/delay") {
- msg.getFloat(0)::second => loopTime;
- msg.getFloat(1) => float feedback;
- for( 0 => int i; i < pedals.cap(); i++ ) {
- pedals[i].setLoopPoint(loopTime);
- pedals[i].setFeedback(feedback);
- }
- }
- else if(msg.address=="/channel") {
- msg.getInt(0) => int i;
- pedals[i].setGain(msg.getFloat(1));
- pedals[i].setPan(msg.getFloat(2));
- pedals[i].setWet(msg.getFloat(3));
- }
- else if(msg.address=="/arm") {
- msg.getInt(0) => int channel;
- for( 0 => int i; i < pedals.cap(); i++ ) { pedals[i].arm(i==channel); }
- }
- else if(msg.address=="/metronome") {
- //msg.getInt(0) => metronomeLevel;
- }
- else if(msg.address=="/clear") {
- msg.getInt(0) => int channel;
- pedals[channel].clear();
- }
- else if(msg.address=="/fx") {
- (100+msg.getFloat(0)*10000) => lpf.freq;
- }
- }
- }
-
- public class LoopPedal
- {
- // We are wrapping a live sampler, LiSa
- LiSa sample;
- sample => Gain wet;
- sample => Gain dry;
-
- // Setup
- 10::second => sample.duration; // Allocate max 10 secs of memory
- 0::second => sample.recPos => sample.playPos;
- 1.0 => sample.feedback;
- 1 => sample.loop;
- setLoopPoint(1::second);
- setWet(0.5);
-
- public void setLoopPoint( dur length ) { length => sample.loopEnd => sample.loopEndRec; }
- public void setFeedback( float fb ) { fb => sample.feedback; }
- public void setGain( float gain ) { gain => sample.gain; }
- public void setPan( float pan ) { } //pan => panner.pan; }
- public void setWet( float ratio ) { ratio => wet.gain; 1-ratio => dry.gain;}
- public void clear() { sample.clear(); }
- public void recordFrom(UGen ugen) { ugen => sample; }
-
- public void outputTo(UGen wetSink, UGen drySink) {
- 1 => sample.play;
- wet => wetSink;
- dry => drySink;
- }
-
- public void arm(int value) {
- sample.playPos() => sample.recPos;
- value => sample.record;
- }
- }
-
-
-
-
-
-
-
-
-
-
-
-
- /*
-
- // Start the metronome and the vu meter (optional)
- //0 => int metronomeLevel;
- //spork ~plip();
- //spork ~vu_meter();
-
- fun void vu_meter()
- {
- // Analysis stuff
- adc => FFT fft =^ RMS rms => blackhole;
- 1<<12 => int fftsize;
- fftsize => fft.size;
- Windowing.hann(fftsize) => fft.window;
-
- // Comms
- OscOut xmit; xmit.dest( "localhost", 6649 );
-
- // Infinite loop: get RMS and send to GUI
- while(true)
- {
- rms.upchuck() @=> UAnaBlob blob;
- xmit.start("/vu");
- blob.fval(0) => xmit.add;
- xmit.send();
- fft.size()::samp => now;
- }
- }
-
-
-
- // TODO timing here should be done using events
- fun void plip()
- {
- SinOsc s => dac;
- 0.01::second => dur plipTime;
-
- while(true){
- for( 0 => int i; i < 4; i++ ) {
- if (i==0){2000 => s.freq;} else {1000 => s.freq;}
- .1*metronomeLevel => s.gain;
- plipTime => now;
- 0 => s.gain;
- loopTime/4 - plipTime => now;
- }
- }
-
- }
- */
|