aboutsummaryrefslogtreecommitdiffstats
path: root/BowelyzerAnalyzer.sc
diff options
context:
space:
mode:
Diffstat (limited to 'BowelyzerAnalyzer.sc')
-rw-r--r--BowelyzerAnalyzer.sc155
1 files changed, 155 insertions, 0 deletions
diff --git a/BowelyzerAnalyzer.sc b/BowelyzerAnalyzer.sc
new file mode 100644
index 0000000..f6dda05
--- /dev/null
+++ b/BowelyzerAnalyzer.sc
@@ -0,0 +1,155 @@
+BowelyzerAnalyzer{
+
+ var <>config;
+ var <synths;
+ var <controls;
+ var <analyzerGroup;
+ var <monitoringGroup;
+
+ *new{
+ arg config;
+ ^super.new.init(config);
+ }
+
+ init{
+ arg config;
+ this.config = config;
+ synths = Dictionary.new(config.at("names").size);
+ controls = Dictionary.new(config.at("names").size);
+ config.at("names").do({ |item, i|
+ controls.putPairs([item, Dictionary.new(7)]);
+ });
+ this.setupGroups;
+ this.addAnalysisSynthsFromConfig(this.config);
+ }
+
+ // 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
+ addAnalysisSynthsFromConfig{
+ arg config;
+ config.at("names").size.do({|i|
+ var name = config.at("names")[i],
+ controls = config.at("controls").at(name);
+ ("Adding SynthDef '"++name++"' on input "++(i+config.at("channelOffset")[i])).postln;
+ synths.add(name -> SynthDef(name, {
+ arg 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: i+config.at("channelOffset")[i]);
+ 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.kr(
+ Impulse.kr(sendReplyFreq),
+ '/'++config.at("names")[i].asSymbol,
+ [amplitude, pitch, hasPitch, detect]
+ );
+ }).play(
+ target: analyzerGroup,
+ args: //arguments to the Synth. Order matters!
+ [
+ controls.at("sendReplyFreq"),
+ controls.at("amplitudeAttackTime"),
+ controls.at("amplitudeReleaseTime"),
+ controls.at("hfHainsworth"),
+ controls.at("hfFoote"),
+ controls.at("hfThreshold"),
+ controls.at("hfWaitTime"),
+ controls.at("pitchInitFreq"),
+ controls.at("pitchMinFreq"),
+ controls.at("pitchMaxFreq"),
+ controls.at("pitchExecFreq"),
+ controls.at("pitchMaxBinsPerOctave"),
+ controls.at("pitchMedian"),
+ controls.at("pitchAmpThreshold"),
+ controls.at("pitchPeakThreshold"),
+ controls.at("pitchDownSample")
+ ]
+ )
+ );
+ });
+ }
+
+ setAnalysisSynthControl{
+ arg name, control;
+ controls.at(name).put(control[0], control[1]);
+ synths.at(name).set(control[0], control[1]);
+ }
+//TODO: get all this from BowelyzerConfig
+ getAnalysisSynthControl{
+ arg name, control;
+ synths.at(name).get(
+ control,
+ {
+ arg value;
+ controls.at(name).put(control, value);
+ }
+ );
+ //TODO: wait for the control to be set
+ ^controls.at(name.asSymbol).at(control.asSymbol);
+ }
+
+ startAnalysisSynth{
+ arg name;
+ synths.at(name).run(true);
+ }
+
+ stopAnalysisSynth{
+ arg name;
+ synths.at(name).run(false);
+ }
+
+ startAllAnalysisSynths{
+ analyzerGroup.run(true);
+ }
+
+ stopAllAnalysisSynths{
+ analyzerGroup.run(false);
+ }
+}