浏览代码

Added dry/wet FX, fixed limiters, better referencing

master
Pete Shadbolt 10 年前
父节点
当前提交
ca876469cb
共有 2 个文件被更改,包括 82 次插入51 次删除
  1. +68
    -36
      main.ck
  2. +14
    -15
      main.py

+ 68
- 36
main.ck 查看文件

@@ -1,32 +1,34 @@
// TODO: turn off adcThru when recording
// Effects chain
adc => Dyno limitIn => Gain adcThru => dac; // Monitor input through a mixer
// Global effects break panning for some unknown reason
/*Dyno limitOut => JCRev rev => dac;*/
/*Dyno limitOut => JCRev rev => dac;*/
limitIn.limit(); limitOut.limit();
SampleChan channels[4];

// Levels
//0 => adc.gain;
.5 => adcThru.gain;
// 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;

// Global loop time
// 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;

// Each channel should output to the mixer
for( 0 => int i; i < channels.cap(); i++ ) { channels[i].outputTo(limitOut); }
// Plug in the pedals
LoopPedal pedals[4];
for( 0 => int i; i < pedals.cap(); i++ ) {
pedals[i].recordFrom(mainInput);
pedals[i].outputTo(outputWet, outputDry);
}

// Listen to OSC messages
// Start listening to OSC messages
OscIn oin; 9000 => oin.port;
oin.listenAll();
OscMsg msg;

// Start the metronome
0 => int metronomeLevel;
//spork ~plip();
//spork ~vu_meter();

// Event loop
while (true) {
oin => now;
@@ -38,51 +40,61 @@ while (true) {
else if(msg.address=="/delay") {
msg.getFloat(0)::second => loopTime;
msg.getFloat(1) => float feedback;
for( 0 => int i; i < channels.cap(); i++ ) {
channels[i].setLoopPoint(loopTime);
channels[i].setFeedback(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;
channels[i].setGain(msg.getFloat(1));
channels[i].setPan(msg.getFloat(2));
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 < channels.cap(); i++ ) { channels[i].arm(i==channel); }
for( 0 => int i; i < pedals.cap(); i++ ) { pedals[i].arm(i==channel); }
}
else if(msg.address=="/metronome") {
msg.getInt(0) => metronomeLevel;
//msg.getInt(0) => metronomeLevel;
}
else if(msg.address=="/clear") {
msg.getInt(0) => int channel;
channels[channel].clear();
pedals[channel].clear();
}
else if(msg.address=="/fx") {
(100+msg.getFloat(0)*10000) => lpf.freq;
}
}
}

public class SampleChan
public class LoopPedal
{
// Chain
adc => LiSa sample => Pan2 panner;
// We are wrapping a live sampler, LiSa
LiSa sample;
sample => Gain wet;
sample => Gain dry;

// Setup
10::second => sample.duration; //This is the max duration
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 => panner.gain; }
public void setPan( float pan ) { pan => panner.pan; }
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 ugen) {
public void outputTo(UGen wetSink, UGen drySink) {
1 => sample.play;
panner => ugen;
wet => wetSink;
dry => drySink;
}

public void arm(int value) {
@@ -91,6 +103,24 @@ public class SampleChan
}
}












/*

// Start the metronome and the vu meter (optional)
//0 => int metronomeLevel;
//spork ~plip();
//spork ~vu_meter();

fun void vu_meter()
{
// Analysis stuff
@@ -114,6 +144,7 @@ fun void vu_meter()
}



// TODO timing here should be done using events
fun void plip()
{
@@ -131,3 +162,4 @@ fun void plip()
}

}
*/

+ 14
- 15
main.py 查看文件

@@ -163,14 +163,16 @@ class Channel(wx.Panel):

self.gain.Bind(wx.EVT_SCROLL, self.update)
self.pan.Bind(wx.EVT_SCROLL, self.update)
self.fxsend.Bind(wx.EVT_SCROLL, self.update)
self.mute.Bind(wx.EVT_TOGGLEBUTTON, self.update)
self.update()

def update(self, evt=None):
gain=self.gain.GetValue()/100.
pan=self.pan.GetValue()/100.
fxsend=self.fxsend.GetValue()/100.
if self.mute.GetValue(): gain=0.0;
sendOSCSafe("/channel", [self.index, gain, pan])
sendOSCSafe("/channel", [self.index, gain, pan, fxsend])


class Mixer(wx.Panel):
@@ -213,28 +215,25 @@ class FXPanel(wx.Panel):
wx.Panel.__init__(self, parent)
sizer = wx.BoxSizer(wx.HORIZONTAL)

label = wx.StaticText(self, label="FX:")
label = wx.StaticText(self, label="Filter:")
font = label.GetFont(); font.SetWeight(wx.BOLD); label.SetFont(font)
sizer.Add(label, 0, wx.EXPAND|wx.TOP|wx.BOTTOM|wx.RIGHT, 5)

choices=["Low pass filter", "High pass filter", "Reverb"]
self.fxtype= wx.ComboBox(self, choices=choices, style=wx.CB_READONLY, size=(25,25))
sizer.Add(self.fxtype, 1, wx.ALL|wx.EXPAND, 5)
self.fxtype.SetValue(choices[0])
#choices=["Low pass filter", "High pass filter", "Reverb"]
#self.fxtype= wx.ComboBox(self, choices=choices, style=wx.CB_READONLY, size=(25,25))
#sizer.Add(self.fxtype, 1, wx.ALL|wx.EXPAND, 5)
#self.fxtype.SetValue(choices[0])

self.fxStrength=OSCSlider(self, "", default_value=0, align=False)
sizer.Add(self.fxStrength, 2, wx.EXPAND|wx.ALL, 5)
self.lpf=OSCSlider(self, "", default_value=0, align=False)
sizer.Add(self.lpf, 2, wx.EXPAND|wx.ALL, 5)
self.lpf.Bind(wx.EVT_SCROLL, self.update)

self.SetSizerAndFit(sizer)
#self.update(None)
self.update(None)

"""
def update(self, evt):
# Send OSC messages
a=self.delayTime.slider.GetValue()/100.
b=self.feedback.slider.GetValue()/100.
sendOSCSafe("/delay", [a, b])
"""
a=self.lpf.slider.GetValue()/100.
sendOSCSafe("/fx", [a])

class OutputPanel(wx.Panel):
''' Handle the ADC input settings '''


正在加载...
取消
保存