aboutsummaryrefslogtreecommitdiffstats
path: root/classes/BowelyzerAnalyzer.sc
diff options
context:
space:
mode:
Diffstat (limited to 'classes/BowelyzerAnalyzer.sc')
-rw-r--r--classes/BowelyzerAnalyzer.sc209
1 files changed, 209 insertions, 0 deletions
diff --git a/classes/BowelyzerAnalyzer.sc b/classes/BowelyzerAnalyzer.sc
new file mode 100644
index 0000000..39728bd
--- /dev/null
+++ b/classes/BowelyzerAnalyzer.sc
@@ -0,0 +1,209 @@
+BowelyzerAnalyzer{
+
+ var <synths;
+ var <analyzerGroup;
+ var <monitoringGroup;
+
+ *new{
+ arg config;
+ ^super.new.init(config);
+ }
+
+ init{
+ arg config;
+ synths = Dictionary.new(config.at(\inputs).size);
+ this.setupGroups;
+ this.addSynthsFromConfig(config);
+ Routine{
+ 1.wait;
+ this.startSynthsFromConfig(config);
+ }.play;
+ }
+
+ // setup a synth group for the analyzers
+ setupGroups{
+ analyzerGroup = Group.new;
+ monitoringGroup = Group.after(analyzerGroup);
+ NodeWatcher.register(analyzerGroup);
+ NodeWatcher.register(monitoringGroup);
+ }
+
+ // add synths for the defined channels
+ addSynthsFromConfig{
+ arg config;
+ config.at(\inputs).keysValuesDo({|name, inputChannel|
+ ("Adding SynthDef \""++name++"\" on input "++inputChannel).postln;
+ this.addSynthWithName(name);
+ });
+ }
+
+ addSynthWithName{
+ arg name;
+ SynthDef(name, {
+ arg inputChannel,
+ sendReplyFreq,
+ amplitudeAttackTime,
+ amplitudeReleaseTime,
+ hfHainsworth,
+ hfFoote,
+ hfThreshold,
+ hfWaitTime,
+ pitchInitFreq,
+ pitchMinFreq,
+ pitchMaxFreq,
+ pitchExecFreq,
+ pitchMaxBinsPerOctave,
+ pitchMedian,
+ pitchAmpThreshold,
+ pitchPeakThreshold,
+ pitchDownSample
+ ;
+ var amplitude, input, detect, pitch, hasPitch;
+ //TODO: Add volume for SoundIn
+ input = SoundIn.ar(bus: inputChannel);
+ amplitude = Amplitude.kr(
+ in: input,
+ attackTime: amplitudeAttackTime,
+ releaseTime: amplitudeReleaseTime
+ );
+ detect = A2K.kr(
+ PV_HainsworthFoote.ar(
+ FFT(LocalBuf(2048), input),
+ proph: hfHainsworth,
+ propf: hfFoote,
+ threshold: hfThreshold,
+ waittime: hfWaitTime
+ )
+ );
+ # pitch, hasPitch = Pitch.kr(
+ in: input,
+ initFreq: pitchInitFreq,
+ minFreq: pitchMinFreq,
+ maxFreq: pitchMaxFreq,
+ execFreq: pitchExecFreq,
+ maxBinsPerOctave: pitchMaxBinsPerOctave,
+ median: pitchMedian,
+ ampThreshold: pitchAmpThreshold,
+ peakThreshold: pitchPeakThreshold,
+ downSample: pitchDownSample
+ );
+ // SendReply for OSCHub
+ SendReply.kr(
+ Impulse.kr(sendReplyFreq),
+ "/"++name,
+ [amplitude, pitch, hasPitch, detect]
+ );
+ // SendReply for LevelIndicator
+ SendReply.kr(
+ Impulse.kr(10),
+ "/levels/"++name,
+ [
+ Amplitude.kr(input),
+ K2A.ar(
+ Peak.ar(
+ input,
+ Delay1.kr(Impulse.kr(10))
+ ).lag(0, 3)
+ )
+ ]
+ );
+ }).add;
+ }
+
+ startSynthsFromConfig{
+ arg config;
+ config.at(\controls).keysValuesDo({|name, controls|
+ postln("Starting synth \""++name++"\".");
+ this.startSynthWithNameAndControls(name, controls, config.at(\inputs).at(name));
+ });
+ }
+
+ // add and start the Synth with name, controls and input channel
+ startSynthWithNameAndControls{
+ arg name, controls, input;
+ // if the input is set to active, start right away, else pause
+ if(controls.at(\active),{
+ synths.add(name -> Synth.new(
+ name,
+ [
+ inputChannel: input,
+ sendReplyFreq: controls.at(\sendReplyFreq),
+ amplitudeAttackTime: controls.at(\amplitudeAttackTime),
+ amplitudeReleaseTime: controls.at(\amplitudeReleaseTime),
+ hfHainsworth: controls.at(\hfhainsworth),
+ hfFoote: controls.at(\hfFoote),
+ hfThreshold: controls.at(\hfThreshold),
+ hfWaitTime: controls.at(\hfWaitTime),
+ pitchInitFreq: controls.at(\pitchInitFreq),
+ pitchMinFreq: controls.at(\pitchMinFreq),
+ pitchMaxFreq: controls.at(\pitchMaxFreq),
+ pitchExecFreq: controls.at(\pitchExecFreq),
+ pitchMaxBinsPerOctave: controls.at(\pitchMaxBinsPerOctave),
+ pitchMedian: controls.at(\pitchMedian),
+ pitchAmpThreshold: controls.at(\pitchAmpThreshold),
+ pitchPeakThreshold: controls.at(\pitchPeakThreshold),
+ pitchDownSample: controls.at(\pitchDownSample)
+ ],
+ analyzerGroup
+ ).register;
+ );
+ },{
+ synths.add(name -> Synth.newPaused(
+ name,
+ [
+ inputChannel: input,
+ sendReplyFreq: controls.at(\sendReplyFreq),
+ amplitudeAttackTime: controls.at(\amplitudeAttackTime),
+ amplitudeReleaseTime: controls.at(\amplitudeReleaseTime),
+ hfHainsworth: controls.at(\hfhainsworth),
+ hfFoote: controls.at(\hfFoote),
+ hfThreshold: controls.at(\hfThreshold),
+ hfWaitTime: controls.at(\hfWaitTime),
+ pitchInitFreq: controls.at(\pitchInitFreq),
+ pitchMinFreq: controls.at(\pitchMinFreq),
+ pitchMaxFreq: controls.at(\pitchMaxFreq),
+ pitchExecFreq: controls.at(\pitchExecFreq),
+ pitchMaxBinsPerOctave: controls.at(\pitchMaxBinsPerOctave),
+ pitchMedian: controls.at(\pitchMedian),
+ pitchAmpThreshold: controls.at(\pitchAmpThreshold),
+ pitchPeakThreshold: controls.at(\pitchPeakThreshold),
+ pitchDownSample: controls.at(\pitchDownSample)
+ ],
+ analyzerGroup
+ ).register;
+ );
+ });
+ }
+
+ // set a synth control by provoding its name, its control name and control value
+ setSynthControl{
+ arg name, controlName, controlValue;
+ synths.at(name).set(controlName, controlValue);
+ }
+
+ // start a synth by name
+ startAnalysisSynth{
+ arg name;
+ synths.at(name).run(true);
+ }
+
+ // stop a synth by name
+ stopAnalysisSynth{
+ arg name;
+ synths.at(name).run(false);
+ }
+
+ // free a synth by name
+ freeAnalysisSynth{
+ arg name;
+ synths.at(name).free;
+ }
+
+ startAllAnalysisSynths{
+ analyzerGroup.run(true);
+ }
+
+ stopAllAnalysisSynths{
+ analyzerGroup.run(false);
+ }
+}