Browse Source

Fixed panning

Pete Shadbolt 4 years ago
parent
commit
1f478ce4b1
3 changed files with 83 additions and 79 deletions
  1. 49
    34
      main.ck
  2. 21
    6
      main.py
  3. 13
    39
      scratch.ck

+ 49
- 34
main.ck View File

@@ -1,29 +1,32 @@
1 1
 //TODO: turn off adcThru when recording, and turn it back on afterwards
2 2
 //TODO: Effects break panning for some unknown reason
3 3
 //TODO varying number of bars
4
-NRev reverb => LPF lpf => HPF hpf => Dyno outputLimiter => dac;
5
-outputLimiter.limit();
4
+NRev reverb => LPF lpf => HPF hpf => Dyno fxLimiter => dac;
5
+Dyno outputDryLeft => dac.left;
6
+Dyno outputDryRight => dac.right;
7
+fxLimiter.limit();
8
+outputDryLeft.limit();
9
+outputDryRight.limit();
6 10
 reverb @=> UGen @ outputWet; // Reference to wet output
7
-outputLimiter @=> UGen @ outputDry; // Reference to dry output
8
-outputLimiter @=> UGen @ mainOutput; // Reference to main output
9 11
 
10 12
 // Capture mic/line in and monitor through DAC. Limit
11
-adc => Dyno inputLimiter => Gain adcThru => mainOutput; // Monitor input 
13
+adc => Dyno inputLimiter => Gain adcThru => fxLimiter; // Monitor input 
12 14
 inputLimiter.limit(); 
13 15
 inputLimiter @=> UGen @ mainInput;
14 16
 
15 17
 // Default parameters
16
-1 => float adcThruLevel;
18
+0 => float adcThruLevel;
17 19
 1 => int adcThruMute;
18 20
 adcThruLevel * adcThruMute => adcThru.gain;
19 21
 10000 => lpf.freq;
20 22
 10 => hpf.freq;
23
+2::second => dur globalLoopTime;
21 24
 
22 25
 // Plug in the pedals
23 26
 LoopPedal pedals[4];
24 27
 for( 0 => int i; i < pedals.cap(); i++ ) { 
25 28
     pedals[i].recordFrom(mainInput);  
26
-    pedals[i].outputTo(outputWet, outputDry); 
29
+    pedals[i].outputTo(outputWet, outputDryLeft, outputDryRight); 
27 30
 }
28 31
 
29 32
 // Create the metronome
@@ -45,10 +48,10 @@ while (true) {
45 48
             adcThruLevel * adcThruMute => adcThru.gain;
46 49
         }
47 50
         else if(msg.address=="/delay") {
48
-            msg.getFloat(0)::second => dur loopTime;
51
+            msg.getFloat(0)::second => globalLoopTime;
49 52
             msg.getFloat(1) => float feedback;
50 53
             for( 0 => int i; i < pedals.cap(); i++ ) { 
51
-                pedals[i].setLoopPoint(loopTime); 
54
+                pedals[i].setLoopPoint(globalLoopTime); 
52 55
                 pedals[i].setFeedback(feedback);
53 56
             }
54 57
          }
@@ -58,6 +61,10 @@ while (true) {
58 61
             pedals[i].setPan(msg.getFloat(2));
59 62
             pedals[i].setWet(msg.getFloat(3));
60 63
         }
64
+        else if(msg.address=="/multiplier"){
65
+            msg.getInt(0) => int i;
66
+            pedals[i].setLoopPoint(globalLoopTime * msg.getFloat(1));
67
+        }
61 68
         else if(msg.address=="/arm") {
62 69
             msg.getInt(0) => int channel;
63 70
             (channel<0) => adcThruMute;
@@ -77,7 +84,10 @@ while (true) {
77 84
             msg.getFloat(2) => reverb.mix;
78 85
         }
79 86
         else if(msg.address=="/master") {
80
-            msg.getFloat(0) => mainOutput.gain;
87
+            msg.getFloat(0) => float masterGain;
88
+            masterGain => outputDryLeft.gain;
89
+            masterGain => outputDryRight.gain;
90
+            masterGain => fxLimiter.gain;
81 91
         }
82 92
     } 
83 93
 }
@@ -87,31 +97,34 @@ class LoopPedal
87 97
     // We are wrapping a live sampler, LiSa
88 98
     LiSa sample;
89 99
     sample => Gain wet;
90
-    sample => Gain dry;
91
-    dur loopTime;
100
+    sample => Pan2 dry;
92 101
 
93 102
     // Setup
94 103
     10::second => sample.duration;  // Allocate max 10 secs of memory
95 104
     0::second => sample.recPos => sample.playPos;
96 105
     1.0 => sample.feedback;
97 106
     1 => sample.loop;
98
-    /*.5 => sample.rate;*/
99
-    setLoopPoint(1::second);
107
+    dur loopTime;
108
+    setLoopPoint(2::second);
100 109
     setWet(0.5);
101 110
 
102
-    public void setLoopPoint( dur length ) { length => loopTime => sample.loopEnd => sample.loopEndRec; }
111
+    public void setLoopPoint( dur length ) { 
112
+        length => loopTime => sample.loopEnd => sample.loopEndRec; 
113
+    }
103 114
     public void setFeedback( float fb ) { fb => sample.feedback; }
104 115
     public void setGain( float gain ) { gain => sample.gain; }
105
-    public void setPan( float pan ) { } //pan => panner.pan; }
116
+    public void setPan( float pan ) { pan => dry.pan; }
106 117
     public void setWet( float ratio ) { ratio => wet.gain; 1-ratio => dry.gain;} 
107 118
     public void clear() { sample.clear(); }
108 119
     public void recordFrom(UGen ugen) { ugen => sample; }
120
+    // TODO: maybe this should be % looptime/multiplier?
109 121
     public dur remaining() { return loopTime - sample.playPos(); }
110 122
 
111
-    public void outputTo(UGen wetSink, UGen drySink) { 
123
+    public void outputTo(UGen wetSink, UGen drySinkLeft, UGen drySinkRight) { 
112 124
         1 => sample.play; 
113 125
         wet => wetSink; 
114
-        dry => drySink; 
126
+        dry.left => drySinkLeft; 
127
+        dry.right => drySinkRight; 
115 128
     }
116 129
 
117 130
     public void arm(int value) {
@@ -125,7 +138,9 @@ class Metronome
125 138
 {
126 139
     // A simple metronome
127 140
     SinOsc s => ADSR a;
141
+    60 => s.freq;
128 142
     0.5 => s.gain;
143
+    0.6 => s.gain;
129 144
     a.set(0.001, .1, .5, .13);
130 145
     10::ms => dur plipTime;
131 146
 
@@ -134,21 +149,21 @@ class Metronome
134 149
     }
135 150
 
136 151
     fun void run() {
137
-            while(true) {
138
-                // Compute the beat time
139
-                pedals[0].loopTime/4. - plipTime => dur beatTime;
140
-
141
-                // Beep four times
142
-                50 => s.freq;
143
-                a.keyOn(); plipTime => now; a.keyOff();
144
-                beatTime => now;
145
-                50 => s.freq;
146
-                a.keyOn(); plipTime => now; a.keyOff();
147
-                beatTime => now;
148
-                a.keyOn(); plipTime => now; a.keyOff();
149
-                beatTime => now;
150
-                a.keyOn(); plipTime => now; a.keyOff();
151
-                pedals[0].remaining() => now; // Sync
152
-            }
152
+        while(true) {
153
+            // Compute the beat time
154
+            globalLoopTime/4. - plipTime => dur beatTime;
155
+
156
+            // Beep four times
157
+            0.15::second => a.releaseTime;
158
+            a.keyOn(); plipTime => now; a.keyOff();
159
+            beatTime => now;
160
+            0.1::second => a.releaseTime;
161
+            a.keyOn(); plipTime => now; a.keyOff();
162
+            beatTime => now;
163
+            a.keyOn(); plipTime => now; a.keyOff();
164
+            beatTime => now;
165
+            a.keyOn(); plipTime => now; a.keyOff();
166
+            pedals[0].remaining() => now; // Sync
167
+        }
153 168
     }
154 169
 }

+ 21
- 6
main.py View File

@@ -188,16 +188,18 @@ class Channel(wx.Panel):
188 188
         self.speed.SetValue(choices[0])
189 189
         sizer.Add(self.speed, 0, wx.ALL | wx.EXPAND, 3)
190 190
 
191
-        choices = ["Live →", "Live ←", "Live ↔", "loop1.wav", "loop2.wav", "loop3.wav"]
192
-        self.speed = wx.ComboBox(self, choices=choices, style=wx.CB_READONLY, size=(25, 25))
193
-        self.speed.SetValue(choices[0])
194
-        sizer.Add(self.speed, 0, wx.ALL | wx.EXPAND, 3)
191
+        choices = ["Live →", "Live ←", "Live ↔", "Half speed"]
192
+        self.direction = wx.ComboBox(self, choices=choices, style=wx.CB_READONLY, size=(25, 25))
193
+        self.direction.SetValue(choices[0])
194
+        sizer.Add(self.direction, 0, wx.ALL | wx.EXPAND, 3)
195 195
 
196 196
         self.SetSizerAndFit(sizer)
197 197
 
198 198
         self.gain.Bind(wx.EVT_SCROLL, self.update)
199 199
         self.pan.Bind(wx.EVT_SCROLL, self.update)
200 200
         self.fxsend.Bind(wx.EVT_SCROLL, self.update)
201
+        self.speed.Bind(wx.EVT_COMBOBOX, self.update_multiplier)
202
+        self.direction.Bind(wx.EVT_TOGGLEBUTTON, self.update_direction)
201 203
         self.mute.Bind(wx.EVT_TOGGLEBUTTON, self.update)
202 204
         self.update()
203 205
 
@@ -205,10 +207,23 @@ class Channel(wx.Panel):
205 207
         gain = self.gain.GetValue() 
206 208
         pan = self.pan.GetValue() 
207 209
         fxsend = self.fxsend.GetValue() 
208
-        if self.mute.GetValue():
209
-            gain = 0.0
210
+        if self.mute.GetValue(): gain = 0.0
210 211
         sendOSCSafe("/channel", [self.index, gain, pan, fxsend])
211 212
 
213
+    def update_multiplier(self, evt=None):
214
+        multiplierTable = {"1 bar": 1., "2 bars": 2., "4 bars": 4., "Dephase": 1.3}
215
+        multiplier = multiplierTable[self.speed.GetValue()]
216
+        sendOSCSafe("/multiplier", [self.index, multiplier])
217
+
218
+    def update_direction(self, evt=None):
219
+        #multiplierTable = {"1 bar": 1., "2 bars": 2., "4 bars": 4., "Dephase": 1.3}
220
+        directionTable = {"Live →":0, "Live ←"1, "Live ↔"2, "Half speed"3}
221
+
222
+        direction = directionTable[self.speed.GetValue()]
223
+        sendOSCSafe("/direction", [self.index, direction])
224
+
225
+
226
+
212 227
 
213 228
 class Mixer(wx.Panel):
214 229
 

+ 13
- 39
scratch.ck View File

@@ -1,44 +1,18 @@
1 1
 // the event
2
-KBHit kb;
2
+Dyno d;
3
+SinOsc s => Pan2 p;
4
+p.left => JCRev revr => dac.left;
5
+p.right => JCRev revl => dac.right;
6
+100 => s.freq;
7
+.2 => s.gain;
8
+.1 => p.gain;
3 9
 
4
-class MetronomeEvent extends Event{ int value; }
10
+-1 => p.pan;
11
+1::second => now;
5 12
 
6
-class Metronome {
7
-    MetronomeEvent metronomeEvent;
8
-    spork ~pulse();
13
+0 => p.pan;
14
+1::second => now;
9 15
 
10
-    fun void listen(){
11
-        while (true){
12
-            metronomeEvent => now;
13
-            <<<"Metronome got event " + metronomeEvent.value>>>;
14
-            if (metronomeEvent.value==0){
15
-                spork ~pulse();
16
-            }
17
-        }
18
-    }
16
+1 => p.pan;
17
+1::second => now;
19 18
 
20
-    fun void pulse(){
21
-       1::second => now; 
22
-       0=>metronomeEvent.value;
23
-       metronomeEvent.signal();
24
-    }
25
-
26
-    fun void signal(){
27
-        1=>metronomeEvent.value;
28
-        metronomeEvent.signal();
29
-    }
30
-}
31
-
32
-Metronome m;
33
-spork ~m.listen();
34
-
35
-// time-loop
36
-while( true )
37
-{
38
-    kb => now;
39
-    while( kb.more() )
40
-    {
41
-        <<< "ascii: ", kb.getchar() >>>;
42
-        m.signal();
43
-    }
44
-}