From 8c45cbc006d751df91eb637032190ff4a33fc78e Mon Sep 17 00:00:00 2001 From: David Runge Date: Sun, 3 Jul 2016 16:34:58 +0200 Subject: classes/*.sc: Moving all classes to the proper subfolder classes. --- classes/BowelyzerConfig.sc | 362 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 362 insertions(+) create mode 100644 classes/BowelyzerConfig.sc (limited to 'classes/BowelyzerConfig.sc') diff --git a/classes/BowelyzerConfig.sc b/classes/BowelyzerConfig.sc new file mode 100644 index 0000000..287aad4 --- /dev/null +++ b/classes/BowelyzerConfig.sc @@ -0,0 +1,362 @@ +BowelyzerConfig{ + + const true, + \amplitudeAttackTime -> 0.01, + \amplitudeReleaseTime -> 0.1, + \hfHainsworth -> 1.0, + \hfFoote -> 0.0, + \hfThreshold -> 0.3, + \hfWaitTime -> 0.04, + \pitchInitFreq -> 440, + \pitchMinFreq -> 60, + \pitchMaxFreq -> 4000, + \pitchExecFreq -> 100, + \pitchMaxBinsPerOctave -> 16, + \pitchMedian -> 1, + \pitchAmpThreshold -> 0.01, + \pitchPeakThreshold -> 0.5, + \pitchDownSample -> 1, + \sendReplyFreq ->20 + ]); + defaultConfig = Dictionary.with(*[ + \inputs -> Dictionary.with(*[ + \left -> 0, + \right -> 1 + ]), + //names -> [left, right], + \synthServerAddress -> "127.0.0.1", + \synthServerPort -> 57110, + \hubAddress -> "127.0.0.1", + \hubPort -> 57120, + \forwardAddress -> "127.0.0.1", + \forwardPort -> 57120, + \controls -> Dictionary.with(*[ + \left -> defaultControls, + \right -> defaultControls + ]) + ]); + } + +// read configuration from file + readConfigurationFile{ + arg configFile; + var configFromFile, reader, path; + path = PathName.new(configFile.asString); + if(path.isFile,{ + postln("Reading configuration file: "++configFile); + try{ + configFromFile = (configFile.asString).parseYAMLFile; + configFromFile.keysValuesDo({|key, value| + switch(key.asSymbol, + \controls,{ + // adding names dictionary + config.put(key.asSymbol, Dictionary.new(value.size)); + // going through the names and their associated dictionaries + value.keysValuesDo({|name, dictionary| + if(dictionary.isKindOf(Dictionary),{ + config.at(key.asSymbol).put(name.asSymbol, Dictionary.new(dictionary.size)); + // going through each control dictionary with controls and their values + dictionary.keysValuesDo({|control, controlValue| + if(defaultControls.includesKey(control.asSymbol),{ + config.at(key.asSymbol).at(name.asSymbol).put(control.asSymbol, this.getControlValue(control.asSymbol, controlValue)); + }); + }); + },{ + error("This element should be of type Dictionary: "++dictionary); + }); + }); + }, + \inputs,{ + config.put(key.asSymbol, Dictionary.new()); + value.keysValuesDo({|name, channel| + config.at(\inputs).put(name.asSymbol, channel.asInteger); + }); + }, + { + if(defaultConfig.includesKey(key.asSymbol),{ + config.put(key.asSymbol, this.getSettingValue(key.asSymbol, value)); + },{ + error("Key is not included in known configuration: "++key); + }); + } + ); + }); + postln("Reading of configuration complete. Now validating..."); + if(this.validateConfig,{ + postln("Validation complete."); + ^true; + },{ + postln("Validation failed."); + ^false; + }); + }{ + ("Failed parsing the file: "++configFile).error; + ("Make sure its JSON syntax is valid!").error; + ^false; + }; + }, { + error("File not readable:"++configFile.asString); + ^false; + }); + } + + //TODO: add writeConfigurationFile + + // return a control value as correct type and within its defined ControlSpec range + getControlValue{ + arg control, value; + if(defaultControls.includesKey(control.asSymbol),{ + if(hasToBeFloat.includes(control.asSymbol),{ + ^control.asSymbol.asSpec.constrain(value.asFloat).asFloat; + }); + if(hasToBeInteger.includes(control.asSymbol),{ + ^control.asSymbol.asSpec.constrain(value.asInteger).asInteger; + }); + if(hasToBeBool.includes(control.asSymbol),{ + switch(value, + 0,{^false}, + 1,{^true}, + "true",{^true}, + "false",{^false} + ); + }); + },{ + ^nil; + }); + } + + //get a setting value as correct type + getSettingValue{ + arg setting, value; + if(defaultConfig.includesKey(setting.asSymbol),{ + if(hasToBeString.includes(setting.asSymbol),{ + ^value.asString; + }); + if(hasToBeInteger.includes(setting.asSymbol),{ + ^value.asInteger; + }); + },{ + ^nil; + }); + } + + // validate/extend/fix the config and return true if it's useable + validateConfig{ + var broken = false; + //fail if there are no inputs defined + if(config.includesKey(\inputs).not,{ + ^false; + }); + // if there are no controls defined at all, add at least a Dictionary for them + if(config.includesKey(\controls).not,{ + config.put(\controls, Dictionary.new(config.at(\inputs).size)); + }); + // go through the defaultConfig/defaultControl collection and compare it to the provided config + defaultConfig.keysValuesDo({|key, value| + if(key != \controls && key != \inputs,{ + // if a standard setting is not in the configuration, add it from the default + if(config.includesKey(key).not,{ + config.put(key, value); + }); + }); + }); + // go through the inputs and add controls, if there are none setup for them + config.at(\inputs).keysValuesDo({|name, channel| + // if there are no controls defined for the input, add them from default + if(config.at(\controls).includesKey(name).not,{ + config.at(\controls).put(name, defaultControls); + }); + }); + // go through each control dictionary + config.at(\controls).keysValuesDo({|name, controlDictionary| + if(config.at(\inputs).includesKey(name),{ + // go through the defaultControl Dictionary and add missing controls to controls from config + defaultControls.keysValuesDo({|defaultControl, defaultControlValue| + if(controlDictionary.includesKey(defaultControl).not,{ + config.at(\controls).at(name).put(defaultControl, defaultControlValue); + }); + }); + },{ + // remove controls for non-existing inputs + config.at(\controls).removeAt(name); + }); + }); + ^true; + } + + //print the current config + showConfig{ + postln("Configuration is: "); + config.keysValuesDo{|key, value| + switch(key, + \controls, { + postln(key++" ("++key.class++") -> ("++value.class++")"); + value.keysValuesDo({|subKey, subValue| + postln(" "++subKey++" ("++subKey.class++") -> ("++subValue.class++")"); + subValue.keysValuesDo({|subSubKey, subSubValue| + postln(" "++subSubKey++" ("++subSubKey.class++") -> "++subSubValue++" ("++subSubValue.class++")"); + }); + }); + }, + \inputs, { + postln(key++" ("++key.class++") -> ("++value.class++")"); + value.keysValuesDo({|subKey, subValue| + postln(" "++subKey++" ("++subKey.class++") -> "++subValue++" ("++subValue.class++")"); + }); + }, + {postln(key++" ("++key.class++") -> "++value++" ("++value.class++")");} + ); + }; + } + + getSynthControl{ + arg name, control; + if(config.at(\controls).includesKey(name) && config.at(\controls).at(name).includes(control),{ + ^config.at(\controls).at(name).at(control); + },{ + ^false; + }); + } + + // sets a control to a value for a synth + setSynthControl{ + arg name, control; + if(config.at(\controls).includesKey(name) && config.at(\controls).at(name).includes(control[0]),{ + config.at(\controls).at(name).put(control[0], control[1]); + ^true; + },{ + ^false; + }); + } + +} -- cgit v1.2.3-54-g00ecf