|
|
@@ -1,29 +1,32 @@ |
|
|
|
//TODO: turn off adcThru when recording, and turn it back on afterwards |
|
|
|
//TODO: Effects break panning for some unknown reason |
|
|
|
//TODO varying number of bars |
|
|
|
NRev reverb => LPF lpf => HPF hpf => Dyno outputLimiter => dac; |
|
|
|
outputLimiter.limit(); |
|
|
|
NRev reverb => LPF lpf => HPF hpf => Dyno fxLimiter => dac; |
|
|
|
Dyno outputDryLeft => dac.left; |
|
|
|
Dyno outputDryRight => dac.right; |
|
|
|
fxLimiter.limit(); |
|
|
|
outputDryLeft.limit(); |
|
|
|
outputDryRight.limit(); |
|
|
|
reverb @=> UGen @ outputWet; // Reference to wet output |
|
|
|
outputLimiter @=> UGen @ outputDry; // Reference to dry output |
|
|
|
outputLimiter @=> UGen @ mainOutput; // Reference to main output |
|
|
|
|
|
|
|
// Capture mic/line in and monitor through DAC. Limit |
|
|
|
adc => Dyno inputLimiter => Gain adcThru => mainOutput; // Monitor input |
|
|
|
adc => Dyno inputLimiter => Gain adcThru => fxLimiter; // Monitor input |
|
|
|
inputLimiter.limit(); |
|
|
|
inputLimiter @=> UGen @ mainInput; |
|
|
|
|
|
|
|
// Default parameters |
|
|
|
1 => float adcThruLevel; |
|
|
|
0 => float adcThruLevel; |
|
|
|
1 => int adcThruMute; |
|
|
|
adcThruLevel * adcThruMute => adcThru.gain; |
|
|
|
10000 => lpf.freq; |
|
|
|
10 => hpf.freq; |
|
|
|
2::second => dur globalLoopTime; |
|
|
|
|
|
|
|
// Plug in the pedals |
|
|
|
LoopPedal pedals[4]; |
|
|
|
for( 0 => int i; i < pedals.cap(); i++ ) { |
|
|
|
pedals[i].recordFrom(mainInput); |
|
|
|
pedals[i].outputTo(outputWet, outputDry); |
|
|
|
pedals[i].outputTo(outputWet, outputDryLeft, outputDryRight); |
|
|
|
} |
|
|
|
|
|
|
|
// Create the metronome |
|
|
@@ -45,10 +48,10 @@ while (true) { |
|
|
|
adcThruLevel * adcThruMute => adcThru.gain; |
|
|
|
} |
|
|
|
else if(msg.address=="/delay") { |
|
|
|
msg.getFloat(0)::second => dur loopTime; |
|
|
|
msg.getFloat(0)::second => globalLoopTime; |
|
|
|
msg.getFloat(1) => float feedback; |
|
|
|
for( 0 => int i; i < pedals.cap(); i++ ) { |
|
|
|
pedals[i].setLoopPoint(loopTime); |
|
|
|
pedals[i].setLoopPoint(globalLoopTime); |
|
|
|
pedals[i].setFeedback(feedback); |
|
|
|
} |
|
|
|
} |
|
|
@@ -58,6 +61,10 @@ while (true) { |
|
|
|
pedals[i].setPan(msg.getFloat(2)); |
|
|
|
pedals[i].setWet(msg.getFloat(3)); |
|
|
|
} |
|
|
|
else if(msg.address=="/multiplier"){ |
|
|
|
msg.getInt(0) => int i; |
|
|
|
pedals[i].setLoopPoint(globalLoopTime * msg.getFloat(1)); |
|
|
|
} |
|
|
|
else if(msg.address=="/arm") { |
|
|
|
msg.getInt(0) => int channel; |
|
|
|
(channel<0) => adcThruMute; |
|
|
@@ -77,7 +84,10 @@ while (true) { |
|
|
|
msg.getFloat(2) => reverb.mix; |
|
|
|
} |
|
|
|
else if(msg.address=="/master") { |
|
|
|
msg.getFloat(0) => mainOutput.gain; |
|
|
|
msg.getFloat(0) => float masterGain; |
|
|
|
masterGain => outputDryLeft.gain; |
|
|
|
masterGain => outputDryRight.gain; |
|
|
|
masterGain => fxLimiter.gain; |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
@@ -87,31 +97,34 @@ class LoopPedal |
|
|
|
// We are wrapping a live sampler, LiSa |
|
|
|
LiSa sample; |
|
|
|
sample => Gain wet; |
|
|
|
sample => Gain dry; |
|
|
|
dur loopTime; |
|
|
|
sample => Pan2 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; |
|
|
|
/*.5 => sample.rate;*/ |
|
|
|
setLoopPoint(1::second); |
|
|
|
dur loopTime; |
|
|
|
setLoopPoint(2::second); |
|
|
|
setWet(0.5); |
|
|
|
|
|
|
|
public void setLoopPoint( dur length ) { length => loopTime => sample.loopEnd => sample.loopEndRec; } |
|
|
|
public void setLoopPoint( dur length ) { |
|
|
|
length => loopTime => 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 setPan( float pan ) { pan => dry.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; } |
|
|
|
// TODO: maybe this should be % looptime/multiplier? |
|
|
|
public dur remaining() { return loopTime - sample.playPos(); } |
|
|
|
|
|
|
|
public void outputTo(UGen wetSink, UGen drySink) { |
|
|
|
public void outputTo(UGen wetSink, UGen drySinkLeft, UGen drySinkRight) { |
|
|
|
1 => sample.play; |
|
|
|
wet => wetSink; |
|
|
|
dry => drySink; |
|
|
|
dry.left => drySinkLeft; |
|
|
|
dry.right => drySinkRight; |
|
|
|
} |
|
|
|
|
|
|
|
public void arm(int value) { |
|
|
@@ -125,7 +138,9 @@ class Metronome |
|
|
|
{ |
|
|
|
// A simple metronome |
|
|
|
SinOsc s => ADSR a; |
|
|
|
60 => s.freq; |
|
|
|
0.5 => s.gain; |
|
|
|
0.6 => s.gain; |
|
|
|
a.set(0.001, .1, .5, .13); |
|
|
|
10::ms => dur plipTime; |
|
|
|
|
|
|
@@ -134,21 +149,21 @@ class Metronome |
|
|
|
} |
|
|
|
|
|
|
|
fun void run() { |
|
|
|
while(true) { |
|
|
|
// Compute the beat time |
|
|
|
pedals[0].loopTime/4. - plipTime => dur beatTime; |
|
|
|
|
|
|
|
// Beep four times |
|
|
|
50 => s.freq; |
|
|
|
a.keyOn(); plipTime => now; a.keyOff(); |
|
|
|
beatTime => now; |
|
|
|
50 => s.freq; |
|
|
|
a.keyOn(); plipTime => now; a.keyOff(); |
|
|
|
beatTime => now; |
|
|
|
a.keyOn(); plipTime => now; a.keyOff(); |
|
|
|
beatTime => now; |
|
|
|
a.keyOn(); plipTime => now; a.keyOff(); |
|
|
|
pedals[0].remaining() => now; // Sync |
|
|
|
} |
|
|
|
while(true) { |
|
|
|
// Compute the beat time |
|
|
|
globalLoopTime/4. - plipTime => dur beatTime; |
|
|
|
|
|
|
|
// Beep four times |
|
|
|
0.15::second => a.releaseTime; |
|
|
|
a.keyOn(); plipTime => now; a.keyOff(); |
|
|
|
beatTime => now; |
|
|
|
0.1::second => a.releaseTime; |
|
|
|
a.keyOn(); plipTime => now; a.keyOff(); |
|
|
|
beatTime => now; |
|
|
|
a.keyOn(); plipTime => now; a.keyOff(); |
|
|
|
beatTime => now; |
|
|
|
a.keyOn(); plipTime => now; a.keyOff(); |
|
|
|
pedals[0].remaining() => now; // Sync |
|
|
|
} |
|
|
|
} |
|
|
|
} |