Compare commits
1 Commits
main
...
microsound
| Author | SHA1 | Date |
|---|---|---|
|
|
6129b3788a | 1 year ago |
@ -1,77 +0,0 @@
|
|||||||
s.boot;
|
|
||||||
|
|
||||||
~dict = BmDspAlgs.getDict("synths/bass/saw_bass.scd");
|
|
||||||
~dict[\postAmp] = true;
|
|
||||||
~dict[\useEnv] = true;
|
|
||||||
|
|
||||||
~dict.makeSourceSynthDef().add();
|
|
||||||
|
|
||||||
~sawBass = ();
|
|
||||||
~sawBass[\name] = \saw;
|
|
||||||
|
|
||||||
Ndef(~sawBass[\name]).clear;
|
|
||||||
Ndef(~sawBass[\name]).ar(2);
|
|
||||||
Ndef(~sawBass[\name]).prime(~dict[\name]);
|
|
||||||
Ndef(~sawBass[\name]).play;
|
|
||||||
|
|
||||||
(
|
|
||||||
Tdef(\t, {
|
|
||||||
loop {
|
|
||||||
[40, 45, 47].do({|n|
|
|
||||||
Ndef(~sawBass[\name]).put(
|
|
||||||
n,
|
|
||||||
Ndef(~sawBass[\name]).source,
|
|
||||||
0,
|
|
||||||
[\freq, n.midicps, \gate, 1, \amp, 0.25, \release, 0.5, \attack, 0.01]
|
|
||||||
);
|
|
||||||
0.25.wait;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}).play;
|
|
||||||
)
|
|
||||||
|
|
||||||
(
|
|
||||||
Tdef(\t2, {
|
|
||||||
loop {
|
|
||||||
[55, 61].do({|n|
|
|
||||||
Ndef(~sawBass[\name]).put(
|
|
||||||
n,
|
|
||||||
Ndef(~sawBass[\name]).source,
|
|
||||||
0,
|
|
||||||
[\freq, n.midicps, \gate, 1, \amp, 0.25, \release, 0.1, \attack, 0.01]
|
|
||||||
);
|
|
||||||
(4/7).wait;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}).play;
|
|
||||||
)
|
|
||||||
|
|
||||||
(
|
|
||||||
Ndef(~sawBass[\name]).put( 159, \filter -> { arg in;
|
|
||||||
d = LPF.ar(in, 1100);
|
|
||||||
d
|
|
||||||
});
|
|
||||||
)
|
|
||||||
|
|
||||||
(
|
|
||||||
Ndef(~sawBass[\name]).put( 160, \filter -> { arg in;
|
|
||||||
var d = in;
|
|
||||||
var diffusion = \diffusion.kr(1);
|
|
||||||
var spacesize = \spacesize.kr(0.1);
|
|
||||||
8.do { |i|
|
|
||||||
d = AllpassC.ar(
|
|
||||||
d,
|
|
||||||
delaytime: LFNoise1.kr(0.01!2).range(0.01, spacesize),
|
|
||||||
decaytime: diffusion
|
|
||||||
)
|
|
||||||
};
|
|
||||||
|
|
||||||
d
|
|
||||||
});
|
|
||||||
)
|
|
||||||
|
|
||||||
Ndef(~sawBass[\name]).set(\diffusion, 0.03);
|
|
||||||
Ndef(~sawBass[\name]).set(\spacesize, 0.1);
|
|
||||||
|
|
||||||
Tdef(\t2).stop;
|
|
||||||
Tdef(\t).stop;
|
|
||||||
@ -1,39 +0,0 @@
|
|||||||
(
|
|
||||||
name: 'fft_freeze',
|
|
||||||
func: {
|
|
||||||
var sig = 0;
|
|
||||||
var in = In.ar(\in.kr(0), 1);
|
|
||||||
var gate = \freezeGate.kr(0);
|
|
||||||
var amp = Amplitude.kr(in, 0.01, 0.05);
|
|
||||||
var above = amp > \ampThresh.kr(0.02);
|
|
||||||
var chain = FFT(
|
|
||||||
LocalBuf(2048),
|
|
||||||
in
|
|
||||||
);
|
|
||||||
|
|
||||||
// set: фронт «гейт взведён И амплитуда выше порога» (0 -> 1)
|
|
||||||
var set = HPZ1.kr(gate * above) > 0;
|
|
||||||
// reset: снятие гейта (1 -> 0)
|
|
||||||
var reset = HPZ1.kr(gate) < 0;
|
|
||||||
var isOn = SetResetFF.kr(set, reset);
|
|
||||||
|
|
||||||
chain = PV_Freeze(chain, isOn);
|
|
||||||
//chain = PV_RandComb(chain, \wipe.kr(0.7), \reshuffle.kr(0.5));
|
|
||||||
//chain = PV_BinShift(chain, \binShift.kr(0), \stretch.kr(1));
|
|
||||||
sig = IFFT(chain) * isOn;
|
|
||||||
|
|
||||||
sig;
|
|
||||||
},
|
|
||||||
inChannels: 1,
|
|
||||||
outChannels: 2,
|
|
||||||
requiresBuffer: true,
|
|
||||||
usePan: true,
|
|
||||||
panning: \pan,
|
|
||||||
useSaturation: false,
|
|
||||||
saturationSteps: 4,
|
|
||||||
specs: (
|
|
||||||
freezeGate: [0, 1, \step, 1, 0],
|
|
||||||
phaseJitter: [0, 1, \lin, 0.01, 0.1],
|
|
||||||
ampThresh: [0, 1, \lin, 0.001, 0.02],
|
|
||||||
),
|
|
||||||
)
|
|
||||||
@ -1,28 +0,0 @@
|
|||||||
(
|
|
||||||
name: 'fft_freeze_follow',
|
|
||||||
func: {
|
|
||||||
var sig = 0;
|
|
||||||
var in = In.ar(\in.kr(0), 1);
|
|
||||||
var amp = Amplitude.kr(in, \atk.kr(0.01), \rel.kr(0.1));
|
|
||||||
var gate = \freezeGate.kr(0);
|
|
||||||
var chain = FFT(LocalBuf(2048), in);
|
|
||||||
|
|
||||||
chain = PV_Freeze(chain, amp > \ampGate.kr(0.00001));
|
|
||||||
sig = IFFT(chain) * gate;
|
|
||||||
Normalizer.ar(sig, \normLevel.kr(0.5), \normDur.kr(0.03));
|
|
||||||
},
|
|
||||||
inChannels: 1,
|
|
||||||
outChannels: 2,
|
|
||||||
requiresBuffer: true,
|
|
||||||
usePan: true,
|
|
||||||
panning: \pan,
|
|
||||||
useSaturation: false,
|
|
||||||
specs: (
|
|
||||||
freezeGate: [0, 1, \step, 1, 0],
|
|
||||||
ampGate: [0, 1, \lin, 0.0001, 0.00001],
|
|
||||||
atk: [0.001, 1, \exp, 0.001, 0.01],
|
|
||||||
rel: [0.001, 2, \exp, 0.001, 0.1],
|
|
||||||
normLevel: [0.05, 1, \lin, 0.01, 0.5],
|
|
||||||
normDur: [0.01, 0.5, \lin, 0.01, 0.03],
|
|
||||||
),
|
|
||||||
)
|
|
||||||
@ -1,91 +1,29 @@
|
|||||||
NodeDictionary : IdentityDictionary {
|
NodeDictionary : IdentityDictionary {
|
||||||
getDefaultOr {
|
getDefaultOr {
|
||||||
| key, defaultValue |
|
| key, defaultValue |
|
||||||
if(this[\defaults][key].isNil, {
|
if(this[\defaults][key].isNil, {
|
||||||
^defaultValue
|
^defaultValue
|
||||||
}, {
|
}, {
|
||||||
^this[\defaults][key]
|
^this[\defaults][key]
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
processSig {
|
makeAnalysysNdef {
|
||||||
| sig, gate |
|
^Ndef(this[\name], {
|
||||||
|
var input = SoundIn.ar(\bus.kr(0));
|
||||||
var signal = sig;
|
var signal = SynthDef.wrap(
|
||||||
|
func: this[\func],
|
||||||
var releaseNode = if (
|
prependArgs: [input]
|
||||||
this[\sustained].asBoolean,
|
);
|
||||||
{ 2 },
|
|
||||||
{ nil }
|
if(this[\convertToKr].isNil.not
|
||||||
);
|
and:
|
||||||
|
this[\convertToKr] == true,
|
||||||
var envDoneAction = if (
|
{
|
||||||
this[\sustained].asBoolean,
|
A2K.kr(signal);
|
||||||
{ 0 },
|
}, {
|
||||||
{ 2 }
|
signal;
|
||||||
);
|
});
|
||||||
|
});
|
||||||
if(this[\useLfo].asBoolean, {
|
}
|
||||||
var lfo = switch(this[\lfoWave])
|
|
||||||
{ \sin } { SinOsc }
|
|
||||||
{ \saw } { Saw }
|
|
||||||
{ \tri } { LFTri }
|
|
||||||
{ \pulse } { Pulse }
|
|
||||||
? SinOsc;
|
|
||||||
|
|
||||||
signal = signal * lfo.kr(
|
|
||||||
\lfoFreq.kr(1)
|
|
||||||
).range(
|
|
||||||
1 - \lfoGain.kr(0.5), 1
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
if(this[\useSaturation].asBoolean, {
|
|
||||||
this.getDefaultOr(\saturationSteps, 4).do {
|
|
||||||
signal = signal.tanh;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
if(this[\useEnv].asBoolean, {
|
|
||||||
var att = this.getDefaultOr(\attack, 0.1);
|
|
||||||
var rel = this.getDefaultOr(\release, 0.1);
|
|
||||||
var curve = this.getDefaultOr(\curve, 1);
|
|
||||||
|
|
||||||
var env = Env(
|
|
||||||
[0, 0, 1, 0],
|
|
||||||
[0, \attack.kr(att), \release.kr(rel)],
|
|
||||||
[0, \attackCurve.kr(curve), \releaseCurve.kr(curve)],
|
|
||||||
releaseNode: releaseNode,
|
|
||||||
).kr(envDoneAction, gate: gate);
|
|
||||||
|
|
||||||
signal = signal * env;
|
|
||||||
});
|
|
||||||
|
|
||||||
if(this[\usePan].asBoolean, {
|
|
||||||
switch(this[\panning],
|
|
||||||
\splay, { signal = Splay.ar(signal, \spread.kr(1), center: \pan.kr(0)); },
|
|
||||||
\splayAz, { signal = SplayAz.ar(this[\panningChannels], signal, orientation: \orientation.kr(0.5)); },
|
|
||||||
\pan, { signal = Pan2.ar(signal, \pan.kr(0)); }
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
if(this[\postAmp].asBoolean, {
|
|
||||||
signal = signal * \postAmp.kr(1);
|
|
||||||
});
|
|
||||||
|
|
||||||
// if(this[\detectSilence].asBoolean, {
|
|
||||||
// FreeSelf.kr(
|
|
||||||
// DetectSilence.ar(
|
|
||||||
// [signal[0], signal[1]] + Impulse.ar(0)
|
|
||||||
// ).product)
|
|
||||||
// });
|
|
||||||
|
|
||||||
if(this[\limitDuration].asBoolean, {
|
|
||||||
Line.kr(0, 1, \dur.kr(1), doneAction: 2);
|
|
||||||
});
|
|
||||||
|
|
||||||
signal = signal * \amp.kr(1);
|
|
||||||
|
|
||||||
^signal;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
@ -1,20 +1,14 @@
|
|||||||
+ NodeDictionary {
|
+ NodeDictionary {
|
||||||
makeBufferProcessingNdef {
|
makeBufferProcessingNdef {
|
||||||
| name |
|
| name, buf, quant = 1.0 |
|
||||||
|
var ndef = Ndef(name);
|
||||||
var internalName = if(name.isNil, {this[\name]}, {name});
|
ndef.proxyspace.quant = quant;
|
||||||
|
ndef[0] = SynthDef.wrap(
|
||||||
Ndef(internalName, {
|
func: this[\func],
|
||||||
var signal, dry, gate;
|
prependArgs: [buf]
|
||||||
|
);
|
||||||
gate = \envGate.kr(0);
|
|
||||||
dry = In.ar(\in.kr(0), this[\inChannels] ? 1);
|
ndef.play;
|
||||||
signal = SynthDef.wrap(
|
^ndef;
|
||||||
func: this[\func],
|
|
||||||
);
|
|
||||||
signal = LinXFade2.ar(dry, signal, \drywet.kr(1));
|
|
||||||
|
|
||||||
this.processSig(signal, gate);
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1,20 +1,32 @@
|
|||||||
+ NodeDictionary {
|
+ NodeDictionary {
|
||||||
makeBufferProcessingSynthDef {
|
makeBufferProcessingSynthDef {
|
||||||
SynthDef(this[\name], {
|
SynthDef(this[\name], {
|
||||||
var signal, dry, gate;
|
var buf = \buf.kr;
|
||||||
|
var signal = SynthDef.wrap(
|
||||||
|
func: this[\func],
|
||||||
|
prependArgs: [buf]
|
||||||
|
);
|
||||||
|
|
||||||
gate = \envGate.kr(0);
|
signal = Pan2.ar(
|
||||||
dry = In.ar(\in.kr(0), this[\inChannels] ? 1);
|
signal * \amp.kr(1),
|
||||||
signal = SynthDef.wrap(
|
\pan.kr(0)
|
||||||
func: this[\func],
|
);
|
||||||
);
|
|
||||||
|
|
||||||
signal = LinXFade2.ar(dry, signal, \drywet.kr(1));
|
if(this[\detectSilence].asBoolean, {
|
||||||
|
FreeSelf.kr(
|
||||||
|
DetectSilence.ar(
|
||||||
|
[signal[0], signal[1]] + Impulse.ar(0)
|
||||||
|
).product)
|
||||||
|
});
|
||||||
|
|
||||||
Out.ar(
|
if(this[\limitDuration].asBoolean, {
|
||||||
\out.kr(0),
|
Line.kr(0, 1, \dur.kr(1), doneAction: 2);
|
||||||
this.processSig(signal, gate);
|
});
|
||||||
);
|
|
||||||
});
|
Out.ar(
|
||||||
}
|
\out.kr(0),
|
||||||
|
signal
|
||||||
|
);
|
||||||
|
}).add;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@ -1,24 +1,74 @@
|
|||||||
+ NodeDictionary {
|
+ NodeDictionary {
|
||||||
makeSourceNdef {
|
makeSourceNdef {
|
||||||
| name |
|
| name |
|
||||||
var internalName = if(name.isNil, {this[\name]}, {name});
|
var internalName = if(name.isNil, {this[\name]}, {name});
|
||||||
|
|
||||||
Ndef(internalName, {
|
Ndef(internalName, {
|
||||||
var freq, signal, gate;
|
var freq, signal, env, gate;
|
||||||
|
|
||||||
gate = \gate.tr(0);
|
var releaseNode = if (
|
||||||
freq = \freq.kr(220);
|
this[\sustained].asBoolean,
|
||||||
|
{ 2 },
|
||||||
|
{ nil }
|
||||||
|
);
|
||||||
|
|
||||||
if(this[\useFreqLag].asBoolean, {
|
gate = \gate.tr(0);
|
||||||
freq = Lag.kr(freq, \freqLag.kr(0.5));
|
freq = \freq.kr(220);
|
||||||
});
|
|
||||||
|
|
||||||
signal = SynthDef.wrap(
|
if(this[\useFreqLag].asBoolean, {
|
||||||
func: this[\func],
|
freq = Lag.kr(freq, \freqLag.kr(0.5));
|
||||||
prependArgs: [freq, gate]
|
});
|
||||||
);
|
|
||||||
|
|
||||||
this.processSig(signal, gate);
|
signal = SynthDef.wrap(
|
||||||
});
|
func: this[\func],
|
||||||
}
|
prependArgs: [freq, gate]
|
||||||
|
);
|
||||||
|
|
||||||
|
if(this[\useLfo].asBoolean, {
|
||||||
|
var lfo = switch(this[\lfoWave])
|
||||||
|
{ \sin } { SinOsc }
|
||||||
|
{ \saw } { Saw }
|
||||||
|
{ \tri } { LFTri }
|
||||||
|
{ \pulse } { Pulse }
|
||||||
|
? SinOsc;
|
||||||
|
|
||||||
|
signal = signal * lfo.kr(
|
||||||
|
\lfoFreq.kr(1)
|
||||||
|
).range(
|
||||||
|
1 - \lfoGain.kr(0.5), 1
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
if(this[\useSaturation].asBoolean, {
|
||||||
|
this[\saturationSteps].do {
|
||||||
|
signal = signal.tanh;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
if(this[\useEnv].asBoolean, {
|
||||||
|
var att = this.getDefaultOr(\attack, 0.1);
|
||||||
|
var rel = this.getDefaultOr(\release, 0.1);
|
||||||
|
var curve = this.getDefaultOr(\curve, 1);
|
||||||
|
|
||||||
|
var env = Env(
|
||||||
|
[0, 0, 1, 0],
|
||||||
|
[0, \attack.kr(att), \release.kr(rel)],
|
||||||
|
[0, \attackCurve.kr(curve), \releaseCurve.kr(curve)],
|
||||||
|
releaseNode: releaseNode,
|
||||||
|
).kr(0, gate: gate);
|
||||||
|
|
||||||
|
signal = signal * env;
|
||||||
|
});
|
||||||
|
|
||||||
|
if(this[\usePan].asBoolean, {
|
||||||
|
switch(this[\panning],
|
||||||
|
\splay, { signal = Splay.ar(signal, \spread.kr(1), center: \pan.kr(0)); },
|
||||||
|
\splayAz, { signal = SplayAz.ar(this[\panningChannels], signal, orientation: \orientation.kr(0.5)); },
|
||||||
|
\pan, { signal = Pan2.ar(signal, \pan.kr(0)); }
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
signal * \amp.kr(1);
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@ -1,24 +1,84 @@
|
|||||||
+ NodeDictionary {
|
+ NodeDictionary {
|
||||||
makeSourceSynthDef {
|
makeSourceSynthDef {
|
||||||
^SynthDef(this[\name], {
|
^SynthDef(this[\name], {
|
||||||
var freq, signal, gate;
|
var freq, signal, env, gate;
|
||||||
|
|
||||||
gate = \gate.tr(0);
|
var releaseNode = if (
|
||||||
freq = \freq.kr(220);
|
this[\sustained].asBoolean,
|
||||||
|
{ 2 },
|
||||||
if(this[\useFreqLag].asBoolean, {
|
{ nil }
|
||||||
freq = Lag.kr(freq, \freqLag.kr(0.5));
|
);
|
||||||
});
|
|
||||||
|
var envDoneAction = if (
|
||||||
signal = SynthDef.wrap(
|
this[\sustained].asBoolean,
|
||||||
func: this[\func],
|
{ 0 },
|
||||||
prependArgs: [freq, gate]
|
{ 2 }
|
||||||
);
|
);
|
||||||
|
|
||||||
Out.ar(
|
gate = \gate.tr(0);
|
||||||
\out.kr(0),
|
freq = \freq.kr(220);
|
||||||
signal,
|
|
||||||
);
|
if(this[\useFreqLag].asBoolean, {
|
||||||
});
|
freq = Lag.kr(freq, \freqLag.kr(0.5));
|
||||||
}
|
});
|
||||||
|
|
||||||
|
signal = SynthDef.wrap(
|
||||||
|
func: this[\func],
|
||||||
|
prependArgs: [freq, gate]
|
||||||
|
);
|
||||||
|
|
||||||
|
if(this[\useLfo].asBoolean, {
|
||||||
|
var lfo = switch(this[\lfoWave])
|
||||||
|
{ \sin } { SinOsc }
|
||||||
|
{ \saw } { Saw }
|
||||||
|
{ \tri } { LFTri }
|
||||||
|
{ \pulse } { Pulse }
|
||||||
|
? SinOsc;
|
||||||
|
|
||||||
|
signal = signal * lfo.kr(
|
||||||
|
\lfoFreq.kr(1)
|
||||||
|
).range(
|
||||||
|
1 - \lfoGain.kr(0.5), 1
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
if(this[\useSaturation].asBoolean, {
|
||||||
|
this[\saturationSteps].do {
|
||||||
|
signal = signal.tanh;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
if(this[\useEnv].asBoolean, {
|
||||||
|
var att = this.getDefaultOr(\attack, 0.1);
|
||||||
|
var rel = this.getDefaultOr(\release, 0.1);
|
||||||
|
var curve = this.getDefaultOr(\curve, 1);
|
||||||
|
|
||||||
|
var env = Env(
|
||||||
|
[0, 0, 1, 0],
|
||||||
|
[0, \attack.kr(att), \release.kr(rel)],
|
||||||
|
\envCurve.kr(curve),
|
||||||
|
releaseNode: releaseNode,
|
||||||
|
).kr(envDoneAction, gate: gate);
|
||||||
|
|
||||||
|
signal = signal * env;
|
||||||
|
});
|
||||||
|
|
||||||
|
switch(this[\panning],
|
||||||
|
\splay, { signal = Splay.ar(signal, \spread.kr(1), center: \pan.kr(0)); },
|
||||||
|
\splayAz, { signal = SplayAz.ar(this[\panningChannels], signal, orientation: \orientation.kr(0.5)); },
|
||||||
|
nil, { signal = Pan2.ar(signal, \pan.kr(0)); }
|
||||||
|
);
|
||||||
|
|
||||||
|
signal = signal * \amp.kr(1);
|
||||||
|
|
||||||
|
if(this[\postAmp].asBoolean, {
|
||||||
|
signal = signal * \postAmp.kr(1);
|
||||||
|
});
|
||||||
|
|
||||||
|
Out.ar(
|
||||||
|
\out.kr(0),
|
||||||
|
signal,
|
||||||
|
);
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@ -1,193 +0,0 @@
|
|||||||
// Modulation synthesis with sparse convolution filter and distortions.
|
|
||||||
// ---------------------------------------------------------------------
|
|
||||||
//
|
|
||||||
// A "3D" oscillator oscillating on x,y,z axis, with the radius of x,y used as waveform,
|
|
||||||
// very similar and related to FM / AM.
|
|
||||||
//
|
|
||||||
// The y axis oscillation is set by MIDI pitch, x and z are detuned by simple just tuned ratios.
|
|
||||||
// Feedback acts on the individual sine oscillations (giving a sawtooth like waveform).
|
|
||||||
//
|
|
||||||
// Three weighted copies with time varying shifts are summed in a lossy integrator
|
|
||||||
// (sparse convolution), followed by a peak resonance filter and shaped by
|
|
||||||
// an internal pick-up like distortion and an asymmetric polynomial.
|
|
||||||
//
|
|
||||||
// The convolution tabs give a (variyng) triangle impulse response if integrated twice,
|
|
||||||
// with a -12 dB/octave rolloff and regular notches.
|
|
||||||
// Here only one integrator is used.
|
|
||||||
//
|
|
||||||
// The envelope is hard wired to the oscillation amplitudes and the rise time of the filter.
|
|
||||||
//
|
|
||||||
// An LFO is wired to pitch.
|
|
||||||
//
|
|
||||||
// A resonant EQ and the Dattoro Reverb from the Faust libary are added as effect on the sum.
|
|
||||||
//
|
|
||||||
// Inspired by the history of sound synthesis, namely Trautonium, Mini Moog, Phase Modulation Synthesis,
|
|
||||||
// Variophon Wind Instrument Synthesizer, Physical Modeling, and the work of Thomas D. Rossing.
|
|
||||||
//
|
|
||||||
// References:
|
|
||||||
// Kot, Vítězslav. (2006). DIGITAL SOUND EFFECTS ECHO AND REVERB BASED ON NON EXPONENTIALLY DECAYING COMB FILTER.
|
|
||||||
// https://en.wikipedia.org/wiki/Variophon
|
|
||||||
// Parker, Julian & Zavalishin, Vadim & Le Bivic, Efflam. (2016). Reducing The Aliasing Of Nonlinear Waveshaping Using Continuous-TimeConvolution.
|
|
||||||
// Nicholas G. Horton, Thomas R. Moore. (2008). Modelling The Magnetic Pickup Of An Electric Guitar.
|
|
||||||
// https://www.musicdsp.org/en/latest/Effects/86-waveshaper-gloubi-boulga.html, see comment from 2005-09-22 01:07:58
|
|
||||||
// Frei, Beat. Digital Sound Generation I & II, ICST Zurich University of the Arts
|
|
||||||
// Smith, J.O. Physical Audio Signal Processing,http://ccrma.stanford.edu/~jos/pasp/, online book, 2010 edition
|
|
||||||
|
|
||||||
declare options "[midi:on][nvoices:8]"; declare name "Paradigma_9"; declare version "1.0"; declare author "gabriel";
|
|
||||||
import("stdfaust.lib");
|
|
||||||
|
|
||||||
// Frequency Ratios table
|
|
||||||
frtonum = waveform{1, 16, 9, 6, 5, 4, 7, 3, 8, 5, 7, 15};
|
|
||||||
frtodiv = waveform{1, 15, 8, 5, 4, 3, 5, 2, 5, 3, 4, 8};
|
|
||||||
|
|
||||||
// MIDI
|
|
||||||
// minimum velocity
|
|
||||||
minvelo = 1/32;
|
|
||||||
midigrp(x) = hgroup("[1]MIDI", x);
|
|
||||||
f = nentry("freq[hidden:1]", 200, 40, 2000, 0.1);
|
|
||||||
kmidi = nentry("key[hidden:1]", 69, 0, 127, 1);
|
|
||||||
bend = ba.semi2ratio(hslider("bend[hidden:1][midi:pitchwheel][style:knob]", 0, -2, 2, 0.01));
|
|
||||||
gain = nentry("gain[hidden:1]", 0.6, 0, 1, 0.01)<:*:_*(1-minvelo):_+minvelo;
|
|
||||||
master = hslider("volume[midi:ctrl 7]", 0.6, 0, 1, 0.01);
|
|
||||||
gate = button("gate[hidden:0]");
|
|
||||||
|
|
||||||
// Oscillator Parameter
|
|
||||||
rtogrp(x) = hgroup("[2]Oscillator", x);
|
|
||||||
rto1sel = rtogrp(hslider("[1]x[style:knob]", -12, -36, 36, 1));
|
|
||||||
rto2sel = rtogrp(hslider("[2]z[style:knob]", 19, -36, 36, 1));
|
|
||||||
fbka = rtogrp(hslider("[3]Feedback[style:knob]", 0.15, 0, 1, 0.01)<:*:*(1/ma.PI));
|
|
||||||
detune = rtogrp(hslider("[4]Detune[style:knob]", 0.125, 0, 0.5, 0.005)/ma.SR);
|
|
||||||
|
|
||||||
// LFO and Envelope Parameter
|
|
||||||
lfogrp(x) = hgroup("[3]Envelope & LFO", x);
|
|
||||||
enva = (lfogrp(ba.db2linear(hslider("[1]A[style:knob]", 20, 15, 66, 1))/1000));
|
|
||||||
envd = (lfogrp(ba.db2linear(hslider("[2]D[style:knob]", 74, 26, 100, 1))/1000)*envpscal);
|
|
||||||
envs = (lfogrp(hslider("[3]S[style:knob]", 0, 0, 1, 0.01)));
|
|
||||||
envr = (lfogrp(ba.db2linear(hslider("[4]R[style:knob]", 50, 26, 100, 1))/1000)*envpscal);
|
|
||||||
lfof = lfogrp(hslider("[5]LFO Hz[style:knob]", 3, 0.1, 12, 0.1));
|
|
||||||
lfvibra = lfogrp(hslider("[6]Vibrato[style:knob]", 0.125, 0, 1, 0.01))<:*;
|
|
||||||
env = en.adsre(enva, envd*envpscal, envs, envr*envpscal, gate);
|
|
||||||
envg = env:_*gain;
|
|
||||||
lfosn = qsin(mphasor(lfof/ma.SR));
|
|
||||||
|
|
||||||
// Triangular Filter Parameter
|
|
||||||
fltgrp(x) = hgroup("[4]Filter", x);
|
|
||||||
wid = fltgrp(hslider("[1]Rise[style:knob]", 3, 1, 9, 0.001)):2^_:1/_;
|
|
||||||
edge = fltgrp(hslider("[2]Fall[style:knob]", 6, 1, 9, 0.001)):2^_:1/_;
|
|
||||||
fiq = fltgrp(hslider("[3]Q[style:knob]", 1, 0.5, 3.87, 0.01))<:*;
|
|
||||||
drive = fltgrp(hslider("[4]Drive[style:knob]", -12, -12, 30, 0.1)):_/20.0:10^_;
|
|
||||||
|
|
||||||
// Modulation Frequency Ratios
|
|
||||||
rto1oct = rto1sel/12:floor;
|
|
||||||
rto1semi = rto1sel+36:_%12;
|
|
||||||
rto1a = frtonum, rto1semi:rdtable;
|
|
||||||
rto1b = frtodiv, rto1semi:rdtable;
|
|
||||||
rto1 = (rto1a/rto1b)*(2^rto1oct);
|
|
||||||
rto1r = min((1/rto1), 1);
|
|
||||||
rto2oct = rto2sel/12:floor;
|
|
||||||
rto2semi = rto2sel+36:_%12;
|
|
||||||
rto2a = frtonum, rto2semi:rdtable;
|
|
||||||
rto2b = frtodiv, rto2semi:rdtable;
|
|
||||||
rto2 = rto1*(rto2a/rto2b)*(2^rto2oct);
|
|
||||||
rto2r = min((1/rto2), 1);
|
|
||||||
|
|
||||||
// Pitch
|
|
||||||
lg2f = ma.log2(f/440);
|
|
||||||
stretch = 0.0333*lg2f;
|
|
||||||
envpscal = (-3*lg2f):ba.db2linear;
|
|
||||||
fplus = f*bend+lfosn*lfvibra*f*0.5/12*envg+stretch;
|
|
||||||
w = f/ma.SR;
|
|
||||||
w2 = rto1*w;
|
|
||||||
w3 = rto2*w;
|
|
||||||
wplus = fplus/ma.SR;
|
|
||||||
fbk1 = fbka*(0.5-w)^4;
|
|
||||||
fbk2 = fbka*(0.5-w2)^4*rto1r;
|
|
||||||
fbk3 = fbka*(0.5-w3)^4*rto2r;
|
|
||||||
|
|
||||||
// Modulation Reduction Per Frequency
|
|
||||||
redux1 = ((3.3-((rto1+1)*w))/3.3), 0:max:_^3;
|
|
||||||
redux2 = ((3.3-((rto2+1)*w))/3.3), 0:max:_^3;
|
|
||||||
modep = envg;
|
|
||||||
modep1 = envg*redux1*rto1r*gain;
|
|
||||||
modep2 = envg*redux2*rto2r*gain;
|
|
||||||
|
|
||||||
// Sine Oscillator
|
|
||||||
wrap(n) = n-(floor(n+0.5));
|
|
||||||
// Bhaskara I based approximate sine curve
|
|
||||||
qsincurve(x) = 1-((x*x)<:*(1.2253517*16), (_<:*:*(-3.60562732*16)):>_);
|
|
||||||
qsin(x) = x+(0.5):wrap<:(abs:-(0.25):qsincurve), _:ma.copysign;
|
|
||||||
// Feedback Depth Reduction Curve
|
|
||||||
fbcurve(x) = x:abs:-(1)<:^(3):_, (x):ma.copysign;
|
|
||||||
|
|
||||||
// Oscillator
|
|
||||||
mphasor(fw) = (+(fw)~(wrap));
|
|
||||||
oscsn(fw, off) = mphasor(fw)+off:qsin:+~*(0.5);
|
|
||||||
osc1(fw, off) = ((fw), +(off):(oscsn))~(*(fbk2):fi.pole(0.5):_*fbcurve(fw));
|
|
||||||
|
|
||||||
// 3D to 2D radius
|
|
||||||
oscy(fw, off) = (osc1(fw, off)*osc1(fw*rto2+2*detune, 0.75+off)*modep2)*modep;
|
|
||||||
oscx(fw, off) = (osc1(fw*rto1+detune, 0.25+off)*osc1(fw*rto2+2*detune, 0.25+off)*modep2)*modep1;
|
|
||||||
oscxy(fw, off) = (oscy(fw, off)<:*), (oscx(fw, off)<:*):+:sqrt;
|
|
||||||
|
|
||||||
// Pick-Up like Distortion
|
|
||||||
// distance :
|
|
||||||
pickd = 0.25;
|
|
||||||
pickup(x, pickd) = x, // normal for in < 1.2e-4
|
|
||||||
(x, (x^2:_+pickd:_^(3/2)):/), // ILO:
|
|
||||||
(pickd^(3/2)/(sqrt(x*x+1)):ma.neg:_+pickd^(3/2)):// select
|
|
||||||
ba.if((_:abs:_<=1.2e-4), _, _):_*(pickd^(4/3));
|
|
||||||
|
|
||||||
// Basic Synthvoice, modulated Oscillations
|
|
||||||
synthvox(fw, ph2, ph3, g1, g2, g3) = (oscxy(fw, 0):_*g1), (oscxy(fw, ph2):_*g2), (oscxy(fw, ph3):_*g3):>_:fi.zero(1.0)<:_, (pickd):pickup;
|
|
||||||
|
|
||||||
// Triangle
|
|
||||||
// reduce width with frequency
|
|
||||||
widredux = w<:+:_^3:1.0-_;
|
|
||||||
// diff to max f in octaves, reduced for higher octaves
|
|
||||||
dwo = (0.25/wid):max(_, 1):ma.log2:ma.inv:_*widredux:ma.inv;
|
|
||||||
// falling edge
|
|
||||||
egderto = edge/wid;
|
|
||||||
wid2 = wid*(2^(dwo*(1-envg))):_*(2^(dwo*(1-gain))):min(_, 0.25):max(_, 4/(ma.SR/fplus));
|
|
||||||
wid2e = edge:min(_, 0.25):max(_, 4/(ma.SR/fplus));
|
|
||||||
fiw = wplus/wid2;
|
|
||||||
fiwtail = wplus/wid2e;
|
|
||||||
// triangle coefficients
|
|
||||||
apg0 = fiw;
|
|
||||||
apg1 = -apg0-fiwtail;
|
|
||||||
apg2 = fiwtail;
|
|
||||||
// integration freq
|
|
||||||
igpole = 1.0-5.0/ma.SR;
|
|
||||||
resf = (fplus/(wid2+wid2e)):min(_, (0.249*ma.SR));
|
|
||||||
|
|
||||||
// Asymmetric Shaper x - 0.15x²-0.15x³
|
|
||||||
tubicclip = _:min(_, (1.19419)):max(_, (-1.86086));
|
|
||||||
tubicilo(x) = x, // normal for in < 1.2e-4
|
|
||||||
(x-0.15*(x^2)-0.15*(x^3)), // ILO:
|
|
||||||
((0.5*(x^2)-0.05*(x^3)-0.0375*(x^4)), (x<:_, _':-:_<:(abs:max(_, 1.2e-4)), (ma.signum):ma.copysign):/):// select
|
|
||||||
ba.if((_:abs:_<=1.2e-4), _, _):fi.dcblockerat(10.0);
|
|
||||||
|
|
||||||
// Sound
|
|
||||||
process = synthvox(wplus, wid2, wid2e, apg0, apg1, apg2):fi.dcblockerat(10.0):fi.pole(igpole):fi.svf.peak(resf, fiq):_*drive:tubicclip:tubicilo:_*(1/drive);
|
|
||||||
effect = _*master:preeq(lsf, lsgain, b1f, eqq2, eqg2, b2f, eqq3, eqg3, hsf, hsgain)<:_, _:re.dattorro_rev_default;
|
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------------------------------------------
|
|
||||||
// Resonant EQ for instrument corpus, based on SVF
|
|
||||||
eqgrp(x) = hgroup("[5]EQ", x);
|
|
||||||
lsgain = eqgrp(hslider("[1]Low Gain[style:knob]", 3, -18, 18, 0.25));
|
|
||||||
b1f = eqgrp(hslider("[2]Split F Low[style:knob]", -0.5, -1, 1, 0.05)):(2.0)^_:_*360;
|
|
||||||
b1gain = eqgrp(hslider("[3]Band 1 Gain[style:knob]", 4.5, -18, 18, 0.25));
|
|
||||||
b2f = eqgrp(hslider("[4]Split F Hi[style:knob]", -0.5, -1, 1, 0.05)):(2.0)^_:_*720;
|
|
||||||
b2gain = eqgrp(hslider("[5]Band 2 Gain[style:knob]", 4.5, -18, 18, 0.25));
|
|
||||||
hsgain = eqgrp(hslider("[6]Hi Gain[style:knob]", -3, -18, 18, 0.25));
|
|
||||||
// Q and gain of middle bands are scaled simultanously, with saturation curveongain,
|
|
||||||
// max gain is reduced from the output. Bands are spaced in octaves by default.
|
|
||||||
lsf = b1f*0.5;
|
|
||||||
hsf = b2f*2;
|
|
||||||
gcurve(gain, gainrange) = abs(gain/gainrange)<:*:1-_:_+1:_*0.5;
|
|
||||||
qscal(gain, gainrange) = 1.414*(abs(gain/gainrange)):_+1.414;
|
|
||||||
eqq2 = qscal(b1gain, 18.0);
|
|
||||||
eqg2 = b1gain*gcurve(b1gain, 18.0);
|
|
||||||
eqq3 = qscal(b2gain, 18.0);
|
|
||||||
eqg3 = b2gain*gcurve(b2gain, 18.0);
|
|
||||||
eqredux = max(lsgain, eqg2):max(_, eqg3):max(_, hsgain):ba.db2linear:ma.inv;
|
|
||||||
preeq(f1, g1, f2, q2, g2, f3, q3, g3, f4, g4) = _*eqredux:fi.svf.bell(f1,1.414,g1):fi.svf.bell(f2, q2, g2):fi.svf.bell(f3,q3,g3):fi.svf.hs(f4, 1.414, g4);
|
|
||||||
@ -1,137 +0,0 @@
|
|||||||
import("stdfaust.lib");
|
|
||||||
|
|
||||||
pultec(in1) = wd.buildtree(tree)
|
|
||||||
with{
|
|
||||||
//resistors and potentiometers
|
|
||||||
p_HB_p(i) = wd.resistor(i, (10.0e4 - p_HB_ui + 1));
|
|
||||||
p_HB_m(i) = wd.resistor(i, (p_HB_ui + 1));
|
|
||||||
p_HBQ(i) = wd.resistor(i, (p_HBQ_ui+1));
|
|
||||||
p_LC(i) = wd.resistor(i, (p_LC_ui +1));
|
|
||||||
p_HC_p(i) = wd.resistor(i, (1.0e3 - p_HC_ui + 1));
|
|
||||||
p_HC_m(i) = wd.resistor(i, (p_HC_ui + 1));
|
|
||||||
p_BL(i) = wd.resistor(i, (p_BL_ui + 1));
|
|
||||||
r_a(i) = wd.resistor(i, 570);
|
|
||||||
r_b(i) = wd.resistor(i, 1.0e3);
|
|
||||||
r_c(i) = wd.resistor(i, 75);
|
|
||||||
r_d(i) = wd.resistor_Vout(i, 10.0e3);
|
|
||||||
//capacitors
|
|
||||||
c_HBF(i) = wd.capacitor(i, cl_HBF_ui(0));
|
|
||||||
c_HCF(i) = wd.capacitor(i, c_HCF_ui);
|
|
||||||
c_LF_a(i) = wd.capacitor(i, c_LF_ui(0));
|
|
||||||
c_LF_b(i) = wd.capacitor(i, c_LF_ui(1));
|
|
||||||
//inductor
|
|
||||||
l_HBF(i) = wd.inductor(i, cl_HBF_ui(1));
|
|
||||||
//voltage input
|
|
||||||
vin(i) = wd.resVoltage(i, 10, in1);
|
|
||||||
|
|
||||||
//connection tree parts
|
|
||||||
tree = u_6port : (a, b, c, d, e, f)
|
|
||||||
with{
|
|
||||||
a = wd.series : (p_HC_m, (wd.parallel : (p_LC, c_LF_a)));
|
|
||||||
b = wd.series : (p_HC_p, (wd.parallel : (p_HC_m, (wd.series : (c_HCF, r_c)))));
|
|
||||||
c = r_b;
|
|
||||||
d = r_d;
|
|
||||||
e = wd.parallel : (c_LF_b, p_BL);
|
|
||||||
f = wd.series : ((wd.series : (p_HB_p, (wd.parallel : (vin, r_a)))), (wd.parallel : (p_HB_m, (wd.series : (p_HBQ, (wd.series : (l_HBF, c_HBF)))))));
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
//approximate a potentiometer position as an audio taper (log) resistance (%)
|
|
||||||
log_pot(slider) = 10^(slider/50) - 1;
|
|
||||||
//approximate a potentiometer postion as an inverse log resistance (%)
|
|
||||||
invlog_pot(slider) = (slider+1) : log10*50;
|
|
||||||
|
|
||||||
//ui-elements
|
|
||||||
p_HB_ui = log_pot(hslider("h:PULTEC PROGRAM EQUALIZER/v:[2]HIGH FREQUENCY/h:[0]KNOBS/[0]BOOSTHi[style:knob]", 0, 0, 93, 1))/100 * 10.0e4;
|
|
||||||
p_HC_ui = invlog_pot(hslider("h:PULTEC PROGRAM EQUALIZER/v:[2]HIGH FREQUENCY/h:[0]KNOBS/[1]ATTENHi[style:knob]", 0, 0, 30, 1))/100 * 1.0e3;
|
|
||||||
|
|
||||||
p_HBQ_ui = log_pot(hslider("h:PULTEC PROGRAM EQUALIZER/v:[1]BANDWIDTH/ADJUST[style:knob]", 0, 0, 150, 1))/100 * 2.2e3;
|
|
||||||
p_BL_ui = log_pot(hslider("h:PULTEC PROGRAM EQUALIZER/v:[0]LOW FREQUENCY/h:[0]KNOBS/[0]BOOSTLow[style:knob]", 0, 0, 20, 1))/100 * 10.0e4;
|
|
||||||
p_LC_ui = log_pot(hslider("h:PULTEC PROGRAM EQUALIZER/v:[0]LOW FREQUENCY/h:[0]KNOBS/[1]ATTENLow[style:knob]", 0, 0, 130, 1))/100 * 100.0e1;
|
|
||||||
cl_HBF_ui =
|
|
||||||
case{
|
|
||||||
(0) => (15.0e-9, 15.0e-9, 10.0e-9, 10.0e-9, 6.8e-9, 6.8e-9, 15.0e-9) : ba.selectn(7, switch_HBF); //capacitor switched values
|
|
||||||
(1) => (175.0e-3, 100.0e-3, 90.0e-3, 65.0e-3, 35.0e-3, 23.0e-3, 19.0e-3) : ba.selectn(7, switch_HBF);//inductor switched values
|
|
||||||
//(3kHz, 4kHz, 5kHz, 6kHz, 10kHz, 12kHz, 16kHz)
|
|
||||||
(x) => 5;
|
|
||||||
}with{
|
|
||||||
switch_HBF = hslider("h:PULTEC PROGRAM EQUALIZER/v:[2]HIGH FREQUENCY/[1]CPSHi[style:menu{'3 kHz':0;'4 kHz':1;'5 kHz':2;'6 kHz':3;'10 kHz':4;'12 kHz':5;'16 kHz':6}]", 0, 0, 6, 1);
|
|
||||||
};
|
|
||||||
c_LF_ui =
|
|
||||||
case{
|
|
||||||
(0) => (100.0e-9, 47.0e-9, 22.0e-9, 15.0e-9) : ba.selectn(4, switch_LF); //capacitor switched values
|
|
||||||
(1) => (2.2e-6, 1.0e-6, 470.0e-9, 330.0e-9) : ba.selectn(4, switch_LF);//inductor switched values
|
|
||||||
//(20hz, 30hz, 60hz, 100hz)
|
|
||||||
(x) => 5;
|
|
||||||
}with{
|
|
||||||
switch_LF = hslider("h:PULTEC PROGRAM EQUALIZER/v:[0]LOW FREQUENCY/[1]CPSLow[style:menu{'20 Hz':0;'30 Hz':1;'60 Hz':2;'100 Hz':3}]", 0, 0, 3, 1);
|
|
||||||
};
|
|
||||||
c_HCF_ui = (47.0e-9, 94.0e-9, 197.0e-9) : ba.selectn(3, switch_HCF) //capacitor switched values
|
|
||||||
//(20hz, 30hz, 60hz, 100hz)
|
|
||||||
with{
|
|
||||||
switch_HCF = hslider("h:PULTEC PROGRAM EQUALIZER/v:[3]ATTEN SELECT/HI-CUT F[style:menu{'20':0;'10':1;'5':2}]", 0, 0, 2, 1);
|
|
||||||
};
|
|
||||||
|
|
||||||
u_6port(i) = wd.u_genericNode(i, sixport_scatter)
|
|
||||||
with{
|
|
||||||
sixport_scatter(Ra, Rb, Rc, Rd, Re, Rf) = matrix(6, 6, scatter)
|
|
||||||
with{
|
|
||||||
scatter =
|
|
||||||
case{
|
|
||||||
(1, 1) => ((-Ra)*(Rd*Re + Rb*(Rc + Rd + Re) + Rd*Rf + Re*Rf + Rc*(Re + Rf)) + Rc*(Re*Rf + Rd*(Re + Rf)) + Rb*(Re*Rf + Rc*(Rd + Rf) + Rd*(Re + Rf)))/(Ra*(Rd*Re + Rb*(Rc + Rd + Re) + Rd*Rf + Re*Rf + Rc*(Re + Rf))
|
|
||||||
+ Rc*(Re*Rf + Rd*(Re + Rf)) + Rb*(Re*Rf + Rc*(Rd + Rf) + Rd*(Re + Rf)));
|
|
||||||
(1, 2) => (2*Ra*((Rc + Re)*Rf + Rd*(Re + Rf)))/(Ra*(Rd*Re + Rb*(Rc + Rd + Re) + Rd*Rf + Re*Rf + Rc*(Re + Rf)) + Rc*(Re*Rf + Rd*(Re + Rf)) + Rb*(Re*Rf + Rc*(Rd + Rf) + Rd*(Re + Rf)));
|
|
||||||
(1, 3) => (2*Ra*(Rb*Rd + Re*Rf + Rd*(Re + Rf)))/(Ra*(Rd*Re + Rb*(Rc + Rd + Re) + Rd*Rf + Re*Rf + Rc*(Re + Rf)) + Rc*(Re*Rf + Rd*(Re + Rf)) + Rb*(Re*Rf + Rc*(Rd + Rf) + Rd*(Re + Rf)));
|
|
||||||
(1, 4) => (-1)*((2*Ra*(Rb*(Rc + Re) + Rc*(Re + Rf)))/(Ra*(Rd*Re + Rb*(Rc + Rd + Re) + Rd*Rf + Re*Rf + Rc*(Re + Rf)) + Rc*(Re*Rf + Rd*(Re + Rf)) + Rb*(Re*Rf + Rc*(Rd + Rf) + Rd*(Re + Rf))));
|
|
||||||
(1, 5) => (2*Ra*(Rb*Rd - Rc*Rf))/(Ra*(Rd*Re + Rb*(Rc + Rd + Re) + Rd*Rf + Re*Rf + Rc*(Re + Rf)) + Rc*(Re*Rf + Rd*(Re + Rf)) + Rb*(Re*Rf + Rc*(Rd + Rf) + Rd*(Re + Rf)));
|
|
||||||
(1, 6) => (-1)*((2*Ra*(Rc*Re + Rb*(Rc + Rd + Re)))/(Ra*(Rd*Re + Rb*(Rc + Rd + Re) + Rd*Rf + Re*Rf + Rc*(Re + Rf)) + Rc*(Re*Rf + Rd*(Re + Rf)) + Rb*(Re*Rf + Rc*(Rd + Rf) + Rd*(Re + Rf))));
|
|
||||||
(2, 1) => (2*Rb*((Rc + Re)*Rf + Rd*(Re + Rf)))/(Ra*(Rd*Re + Rb*(Rc + Rd + Re) + Rd*Rf + Re*Rf + Rc*(Re + Rf)) + Rc*(Re*Rf + Rd*(Re + Rf)) + Rb*(Re*Rf + Rc*(Rd + Rf) + Rd*(Re + Rf)));
|
|
||||||
(2, 2) => (Ra*(Rd*Re - Rb*(Rc + Rd + Re) + Rd*Rf + Re*Rf + Rc*(Re + Rf)) + Rc*(Re*Rf + Rd*(Re + Rf)) - Rb*(Re*Rf + Rc*(Rd + Rf) + Rd*(Re + Rf)))/(Ra*(Rd*Re + Rb*(Rc + Rd + Re) + Rd*Rf + Re*Rf + Rc*(Re + Rf))
|
|
||||||
+ Rc*(Re*Rf + Rd*(Re + Rf)) + Rb*(Re*Rf + Rc*(Rd + Rf) + Rd*(Re + Rf)));
|
|
||||||
(2, 3) => (-1)*((2*Rb*(Ra*Re + Re*Rf + Rd*(Re + Rf)))/(Ra*(Rd*Re + Rb*(Rc + Rd + Re) + Rd*Rf + Re*Rf + Rc*(Re + Rf)) + Rc*(Re*Rf + Rd*(Re + Rf)) + Rb*(Re*Rf + Rc*(Rd + Rf) + Rd*(Re + Rf))));
|
|
||||||
(2, 4) => (-2*Ra*Rb*Re + 2*Rb*Rc*Rf)/(Ra*(Rd*Re + Rb*(Rc + Rd + Re) + Rd*Rf + Re*Rf + Rc*(Re + Rf)) + Rc*(Re*Rf + Rd*(Re + Rf)) + Rb*(Re*Rf + Rc*(Rd + Rf) + Rd*(Re + Rf)));
|
|
||||||
(2, 5) => (2*Rb*(Ra*(Rc + Rd) + Rc*(Rd + Rf)))/(Ra*(Rd*Re + Rb*(Rc + Rd + Re) + Rd*Rf + Re*Rf + Rc*(Re + Rf)) + Rc*(Re*Rf + Rd*(Re + Rf)) + Rb*(Re*Rf + Rc*(Rd + Rf) + Rd*(Re + Rf)));
|
|
||||||
(2, 6) => (-1)*((2*Rb*(Rc*Rd + Ra*(Rc + Rd + Re)))/(Ra*(Rd*Re + Rb*(Rc + Rd + Re) + Rd*Rf + Re*Rf + Rc*(Re + Rf)) + Rc*(Re*Rf + Rd*(Re + Rf)) + Rb*(Re*Rf + Rc*(Rd + Rf) + Rd*(Re + Rf))));
|
|
||||||
(3, 1) => (2*Rc*(Rb*Rd + Re*Rf + Rd*(Re + Rf)))/(Ra*(Rd*Re + Rb*(Rc + Rd + Re) + Rd*Rf + Re*Rf + Rc*(Re + Rf)) + Rc*(Re*Rf + Rd*(Re + Rf)) + Rb*(Re*Rf + Rc*(Rd + Rf) + Rd*(Re + Rf)));
|
|
||||||
(3, 2) => (-1)*((2*Rc*(Ra*Re + Re*Rf + Rd*(Re + Rf)))/(Ra*(Rd*Re + Rb*(Rc + Rd + Re) + Rd*Rf + Re*Rf + Rc*(Re + Rf)) + Rc*(Re*Rf + Rd*(Re + Rf)) + Rb*(Re*Rf + Rc*(Rd + Rf) + Rd*(Re + Rf))));
|
|
||||||
(3, 3) => 1 - (2*Rc*(Rd*Re + Rd*Rf + Re*Rf + Rb*(Rd + Rf) + Ra*(Rb + Re + Rf)))/(Ra*(Rd*Re + Rb*(Rc + Rd + Re) + Rd*Rf + Re*Rf + Rc*(Re + Rf)) + Rc*(Re*Rf + Rd*(Re + Rf)) + Rb*(Re*Rf + Rc*(Rd + Rf) + Rd*(Re + Rf)));
|
|
||||||
(3, 4) => (-1)*((2*Rc*(Rb*Rf + Ra*(Rb + Re + Rf)))/(Ra*(Rd*Re + Rb*(Rc + Rd + Re) + Rd*Rf + Re*Rf + Rc*(Re + Rf)) + Rc*(Re*Rf + Rd*(Re + Rf)) + Rb*(Re*Rf + Rc*(Rd + Rf) + Rd*(Re + Rf))));
|
|
||||||
(3, 5) => (-1)*((2*Rc*(Ra*(Rb + Rf) + Rb*(Rd + Rf)))/(Ra*(Rd*Re + Rb*(Rc + Rd + Re) + Rd*Rf + Re*Rf + Rc*(Re + Rf)) + Rc*(Re*Rf + Rd*(Re + Rf)) + Rb*(Re*Rf + Rc*(Rd + Rf) + Rd*(Re + Rf))));
|
|
||||||
(3, 6) => (2*Rc*(Rb*Rd - Ra*Re))/(Ra*(Rd*Re + Rb*(Rc + Rd + Re) + Rd*Rf + Re*Rf + Rc*(Re + Rf)) + Rc*(Re*Rf + Rd*(Re + Rf)) + Rb*(Re*Rf + Rc*(Rd + Rf) + Rd*(Re + Rf)));
|
|
||||||
(4, 1) => (-1)*((2*Rd*(Rb*(Rc + Re) + Rc*(Re + Rf)))/(Ra*(Rd*Re + Rb*(Rc + Rd + Re) + Rd*Rf + Re*Rf + Rc*(Re + Rf)) + Rc*(Re*Rf + Rd*(Re + Rf)) + Rb*(Re*Rf + Rc*(Rd + Rf) + Rd*(Re + Rf))));
|
|
||||||
(4, 2) => (-2*Ra*Rd*Re + 2*Rc*Rd*Rf)/(Ra*(Rd*Re + Rb*(Rc + Rd + Re) + Rd*Rf + Re*Rf + Rc*(Re + Rf)) + Rc*(Re*Rf + Rd*(Re + Rf)) + Rb*(Re*Rf + Rc*(Rd + Rf) + Rd*(Re + Rf)));
|
|
||||||
(4, 3) => (-1)*((2*Rd*(Rb*Rf + Ra*(Rb + Re + Rf)))/(Ra*(Rd*Re + Rb*(Rc + Rd + Re) + Rd*Rf + Re*Rf + Rc*(Re + Rf)) + Rc*(Re*Rf + Rd*(Re + Rf)) + Rb*(Re*Rf + Rc*(Rd + Rf) + Rd*(Re + Rf))));
|
|
||||||
(4, 4) => 1 - (2*Rd*(Rc*(Re + Rf) + Ra*(Rb + Re + Rf) + Rb*(Rc + Re + Rf)))/(Ra*(Rd*Re + Rb*(Rc + Rd + Re) + Rd*Rf + Re*Rf + Rc*(Re + Rf)) + Rc*(Re*Rf + Rd*(Re + Rf)) + Rb*(Re*Rf + Rc*(Rd + Rf) + Rd*(Re + Rf)));
|
|
||||||
(4, 5) => (-1)*((2*Rd*((Rb + Rc)*Rf + Ra*(Rb + Rf)))/(Ra*(Rd*Re + Rb*(Rc + Rd + Re) + Rd*Rf + Re*Rf + Rc*(Re + Rf)) + Rc*(Re*Rf + Rd*(Re + Rf)) + Rb*(Re*Rf + Rc*(Rd + Rf) + Rd*(Re + Rf))));
|
|
||||||
(4, 6) => (-1)*((2*Rd*((Ra + Rc)*Re + Rb*(Rc + Re)))/(Ra*(Rd*Re + Rb*(Rc + Rd + Re) + Rd*Rf + Re*Rf + Rc*(Re + Rf)) + Rc*(Re*Rf + Rd*(Re + Rf)) + Rb*(Re*Rf + Rc*(Rd + Rf) + Rd*(Re + Rf))));
|
|
||||||
(5, 1) => (2*Re*(Rb*Rd - Rc*Rf))/(Ra*(Rd*Re + Rb*(Rc + Rd + Re) + Rd*Rf + Re*Rf + Rc*(Re + Rf)) + Rc*(Re*Rf + Rd*(Re + Rf)) + Rb*(Re*Rf + Rc*(Rd + Rf) + Rd*(Re + Rf)));
|
|
||||||
(5, 2) => (2*Re*(Ra*(Rc + Rd) + Rc*(Rd + Rf)))/(Ra*(Rd*Re + Rb*(Rc + Rd + Re) + Rd*Rf + Re*Rf + Rc*(Re + Rf)) + Rc*(Re*Rf + Rd*(Re + Rf)) + Rb*(Re*Rf + Rc*(Rd + Rf) + Rd*(Re + Rf)));
|
|
||||||
(5, 3) => (-1)*((2*Re*(Ra*(Rb + Rf) + Rb*(Rd + Rf)))/(Ra*(Rd*Re + Rb*(Rc + Rd + Re) + Rd*Rf + Re*Rf + Rc*(Re + Rf)) + Rc*(Re*Rf + Rd*(Re + Rf)) + Rb*(Re*Rf + Rc*(Rd + Rf) + Rd*(Re + Rf))));
|
|
||||||
(5, 4) => (-1)*((2*Re*((Rb + Rc)*Rf + Ra*(Rb + Rf)))/(Ra*(Rd*Re + Rb*(Rc + Rd + Re) + Rd*Rf + Re*Rf + Rc*(Re + Rf)) + Rc*(Re*Rf + Rd*(Re + Rf)) + Rb*(Re*Rf + Rc*(Rd + Rf) + Rd*(Re + Rf))));
|
|
||||||
(5, 5) => 1 - (2*Re*((Rb + Rc)*(Rd + Rf) + Ra*(Rb + Rc + Rd + Rf)))/(Ra*(Rd*Re + Rb*(Rc + Rd + Re) + Rd*Rf + Re*Rf + Rc*(Re + Rf)) + Rc*(Re*Rf + Rd*(Re + Rf)) + Rb*(Re*Rf + Rc*(Rd + Rf) + Rd*(Re + Rf)));
|
|
||||||
(5, 6) => (2*((Rb + Rc)*Rd + Ra*(Rc + Rd))*Re)/(Ra*(Rd*Re + Rb*(Rc + Rd + Re) + Rd*Rf + Re*Rf + Rc*(Re + Rf)) + Rc*(Re*Rf + Rd*(Re + Rf)) + Rb*(Re*Rf + Rc*(Rd + Rf) + Rd*(Re + Rf)));
|
|
||||||
(6, 1) => (-1)*((2*(Rc*Re + Rb*(Rc + Rd + Re))*Rf)/(Ra*(Rd*Re + Rb*(Rc + Rd + Re) + Rd*Rf + Re*Rf + Rc*(Re + Rf)) + Rc*(Re*Rf + Rd*(Re + Rf)) + Rb*(Re*Rf + Rc*(Rd + Rf) + Rd*(Re + Rf))));
|
|
||||||
(6, 2) => (-1)*((2*(Rc*Rd + Ra*(Rc + Rd + Re))*Rf)/(Ra*(Rd*Re + Rb*(Rc + Rd + Re) + Rd*Rf + Re*Rf + Rc*(Re + Rf)) + Rc*(Re*Rf + Rd*(Re + Rf)) + Rb*(Re*Rf + Rc*(Rd + Rf) + Rd*(Re + Rf))));
|
|
||||||
(6, 3) => (2*(Rb*Rd - Ra*Re)*Rf)/(Ra*(Rd*Re + Rb*(Rc + Rd + Re) + Rd*Rf + Re*Rf + Rc*(Re + Rf)) + Rc*(Re*Rf + Rd*(Re + Rf)) + Rb*(Re*Rf + Rc*(Rd + Rf) + Rd*(Re + Rf)));
|
|
||||||
(6, 4) => (-1)*((2*((Ra + Rc)*Re + Rb*(Rc + Re))*Rf)/(Ra*(Rd*Re + Rb*(Rc + Rd + Re) + Rd*Rf + Re*Rf + Rc*(Re + Rf)) + Rc*(Re*Rf + Rd*(Re + Rf)) + Rb*(Re*Rf + Rc*(Rd + Rf) + Rd*(Re + Rf))));
|
|
||||||
(6, 5) => (2*((Rb + Rc)*Rd + Ra*(Rc + Rd))*Rf)/(Ra*(Rd*Re + Rb*(Rc + Rd + Re) + Rd*Rf + Re*Rf + Rc*(Re + Rf)) + Rc*(Re*Rf + Rd*(Re + Rf)) + Rb*(Re*Rf + Rc*(Rd + Rf) + Rd*(Re + Rf)));
|
|
||||||
(6, 6) => 1 - (2*(Rc*(Rd + Re) + Ra*(Rc + Rd + Re) + Rb*(Rc + Rd + Re))*Rf)/(Ra*(Rd*Re + Rb*(Rc + Rd + Re) + Rd*Rf + Re*Rf + Rc*(Re + Rf)) + Rc*(Re*Rf + Rd*(Re + Rf)) + Rb*(Re*Rf + Rc*(Rd + Rf) + Rd*(Re + Rf)));
|
|
||||||
(i, j) => 10;
|
|
||||||
};
|
|
||||||
matrix(M,N,f) = si.bus(N) <: ro.interleave(N,M) : par(n,N, par(m,M,*(f(m+1,n+1)))) :> si.bus(M);
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
capacitorMobius(i, C, aM, bM, cM, dM) = genericNode_output_I(i, f, upPortRes)
|
|
||||||
with{
|
|
||||||
f(a) = a*sF <: _, _'*sB : (_, _, _ :> _)~(_'*sB*sB)
|
|
||||||
with{
|
|
||||||
sB = (-1)*(aM*dM+bM*cM)/(2*aM*cM);
|
|
||||||
sF = (aM*dM-bM*cM)/(2*aM*cM);
|
|
||||||
};
|
|
||||||
upPortRes = cM/C*aM;
|
|
||||||
};
|
|
||||||
|
|
||||||
process = pultec*200;
|
|
||||||
@ -1,46 +0,0 @@
|
|||||||
(
|
|
||||||
~hidCtrl = (
|
|
||||||
defName: \hidCtrl,
|
|
||||||
// Array of HIDInfo objects
|
|
||||||
devices: [],
|
|
||||||
// List of HID objects. Maybe should be private later
|
|
||||||
connected: List.new(),
|
|
||||||
eventsMap: IdentityDictionary[
|
|
||||||
\X -> { | val | val.postln },
|
|
||||||
],
|
|
||||||
connect: {
|
|
||||||
|self|
|
|
||||||
self.devices.do {
|
|
||||||
|hidinfo|
|
|
||||||
var device = HID.open(
|
|
||||||
hidinfo.vendorID,
|
|
||||||
hidinfo.productID,
|
|
||||||
hidinfo.path
|
|
||||||
);
|
|
||||||
|
|
||||||
if(device.notNil) {
|
|
||||||
self.connected.add(device);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
},
|
|
||||||
free: {
|
|
||||||
|self|
|
|
||||||
if(self.connected.size > 0) {
|
|
||||||
self.connected.do { |hid| hid.close };
|
|
||||||
self.connected.clear;
|
|
||||||
};
|
|
||||||
|
|
||||||
HIDdef(self.defName).free;
|
|
||||||
},
|
|
||||||
listen: {
|
|
||||||
|self|
|
|
||||||
HIDdef.usage(self.defName, {
|
|
||||||
|value, rawValue, usage, page, elid, ele, devid, device|
|
|
||||||
var name = HIDUsage.idsToName(page, usage);
|
|
||||||
var handler = self.eventsMap[name];
|
|
||||||
|
|
||||||
if(handler.notNil) { handler.(value) };
|
|
||||||
});
|
|
||||||
}
|
|
||||||
);
|
|
||||||
)
|
|
||||||
@ -0,0 +1,5 @@
|
|||||||
|
(
|
||||||
|
~microsound_explorer = (
|
||||||
|
|
||||||
|
);
|
||||||
|
)
|
||||||
@ -1,50 +0,0 @@
|
|||||||
(defun create-scd-project ()
|
|
||||||
"Create a new project directory with a samples subdirectory and a main.scd file containing SuperCollider code."
|
|
||||||
(interactive)
|
|
||||||
(let* ((project-path (read-directory-name "Project path: " default-directory))
|
|
||||||
(project-name (read-string "Project name: "))
|
|
||||||
(full-path (expand-file-name project-name project-path))
|
|
||||||
(samples-path (expand-file-name "samples" full-path))
|
|
||||||
(main-file (expand-file-name "main.scd" full-path))
|
|
||||||
(supercollider-code (format
|
|
||||||
"(
|
|
||||||
s.options.memSize_(2.pow(20));
|
|
||||||
s.waitForBoot({
|
|
||||||
~makeBuffers = { |path, event, mono = false|
|
|
||||||
var dir = PathName.new(path);
|
|
||||||
var contents = dir.entries;
|
|
||||||
if (contents.select({ |n| n.isFile }).size > 0)
|
|
||||||
{
|
|
||||||
var files, bufArray;
|
|
||||||
files = contents.select({ |n| n.isFile });
|
|
||||||
files = files.select({ |n|
|
|
||||||
[\"aif\", \"aiff\", \"wav\"].includesEqual(n.extension)
|
|
||||||
});
|
|
||||||
if (event[dir.folderName.asSymbol] != nil)
|
|
||||||
{ \"duplicate subfolder name ignored\".warn; }
|
|
||||||
{
|
|
||||||
bufArray = files.collect({ |n|
|
|
||||||
if(mono)
|
|
||||||
{ Buffer.readChannel(s, n.fullPath, channels:[0]) }
|
|
||||||
{ Buffer.read(s, n.fullPath) };
|
|
||||||
});
|
|
||||||
event[dir.folderName.asSymbol] = bufArray;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
if (contents.select({ |n| n.isFolder }).size > 0)
|
|
||||||
{
|
|
||||||
var folders = contents.select({ |n| n.isFolder });
|
|
||||||
folders.do({ |n| ~makeBuffers.(n.fullPath, event, mono) });
|
|
||||||
};
|
|
||||||
event;
|
|
||||||
};
|
|
||||||
~samples = ~makeBuffers.(\"%s\", ());
|
|
||||||
});
|
|
||||||
)"
|
|
||||||
samples-path)))
|
|
||||||
(make-directory full-path t)
|
|
||||||
(make-directory samples-path t)
|
|
||||||
(with-temp-file main-file
|
|
||||||
(insert supercollider-code))
|
|
||||||
(find-file main-file)
|
|
||||||
(save-buffer)))
|
|
||||||
Loading…
Reference in new issue