Browse Source

Merge branch 'master' of https://github.com/peteshadbolt/milchlode

Conflicts:
	main.ck
master
Pete Shadbolt 9 years ago
parent
commit
1cf4f3f1ca
2 changed files with 88 additions and 51 deletions
  1. +69
    -36
      main.ck
  2. +19
    -15
      main.py

+ 69
- 36
main.ck View File

@@ -1,32 +1,34 @@
// TODO: turn off adcThru when recording // 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 => PRCRev rev => dac;
.3 => rev.mix;
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;

// 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


// Global loop time
// Default parameters
.5 => adcThru.gain;
10000 => lpf.freq;
1::second => dur loopTime; 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; OscIn oin; 9000 => oin.port;
oin.listenAll(); oin.listenAll();
OscMsg msg; OscMsg msg;


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

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


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 // 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; 0::second => sample.recPos => sample.playPos;
1.0 => sample.feedback; 1.0 => sample.feedback;
1 => sample.loop; 1 => sample.loop;
setLoopPoint(1::second); setLoopPoint(1::second);
setWet(0.5);


public void setLoopPoint( dur length ) { length => sample.loopEnd => sample.loopEndRec; } public void setLoopPoint( dur length ) { length => sample.loopEnd => sample.loopEndRec; }
public void setFeedback( float fb ) { fb => sample.feedback; } 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 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; 1 => sample.play;
panner => ugen;
wet => wetSink;
dry => drySink;
} }


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













/*

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

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





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


} }
*/

+ 19
- 15
main.py View File

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


self.gain.Bind(wx.EVT_SCROLL, self.update) self.gain.Bind(wx.EVT_SCROLL, self.update)
self.pan.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.mute.Bind(wx.EVT_TOGGLEBUTTON, self.update)
self.update() self.update()


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




class Mixer(wx.Panel): class Mixer(wx.Panel):
@@ -213,28 +215,30 @@ class FXPanel(wx.Panel):
wx.Panel.__init__(self, parent) wx.Panel.__init__(self, parent)
sizer = wx.BoxSizer(wx.HORIZONTAL) 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) font = label.GetFont(); font.SetWeight(wx.BOLD); label.SetFont(font)
sizer.Add(label, 0, wx.EXPAND|wx.TOP|wx.BOTTOM|wx.RIGHT, 5) 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, "Lowpass", default_value=0)
sizer.Add(self.lpf, 2, wx.EXPAND|wx.ALL, 5)
self.lpf.Bind(wx.EVT_SCROLL, self.update)

self.reverb=OSCSlider(self, "Reverb", default_value=0)
sizer.Add(self.reverb, 2, wx.EXPAND|wx.ALL, 5)
self.reverb.Bind(wx.EVT_SCROLL, self.update)


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


"""
def update(self, evt): 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.
b=self.reverb.slider.GetValue()/100.
sendOSCSafe("/fx", [a,b])


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


Loading…
Cancel
Save