From 2f2d4268b7d5fbc6677b482e45ebe97a9db6d19d Mon Sep 17 00:00:00 2001 From: David Runge Date: Wed, 29 Jun 2016 20:24:38 +0200 Subject: BowelyzerGUI.sc: Moving LevelIndicator listener to Bowelyzer.sc. Removing all of the helper functions. Removing useless controlName in toggle message. Bowelyzer.sc: Adding usage of LevelIndicator listener and OSC indicator listener. Separating those from plain listeners for GUI elements. All should now properly survive the renaming of channels. Further clarifying names in setup functions for readability. --- Bowelyzer.sc | 141 ++++++++++++++++++++++++++++++++++++++++++++------------ BowelyzerGUI.sc | 62 ++----------------------- 2 files changed, 114 insertions(+), 89 deletions(-) diff --git a/Bowelyzer.sc b/Bowelyzer.sc index 3071588..e2d868a 100644 --- a/Bowelyzer.sc +++ b/Bowelyzer.sc @@ -24,12 +24,14 @@ Bowelyzer{ analyzer = BowelyzerAnalyzer.new(config.config); gui = BowelyzerGUI.new(config.config); this.addGUIListeners; + this.addServerListeners; }, 5, {"scsynth failed to start!".postln}); } addGUIListeners{ + // listen for control changes OSCdef.newMatching( key: \controls, func: {|msg, time, addr, recvPort| @@ -46,50 +48,60 @@ Bowelyzer{ path: "/controls", srcID: NetAddr.new("127.0.0.1", NetAddr.langPort) ); + // listen for input changes (rename and input channel) OSCdef.newMatching( key: \inputs, func: {|msg, time, addr, recvPort| + var name = msg[1], + type = msg[2], + update = msg[3]; postln("Received: "++msg); - if(msg[1].notNil && msg[2].notNil && msg[3].notNil,{ - if(config.config.at(\inputs).includesKey(msg[1]) && config.config.at(\controls).includesKey(msg[1]),{ - switch(msg[2], + if(name.notNil && type.notNil && update.notNil,{ + if(config.config.at(\inputs).includesKey(name) && config.config.at(\controls).includesKey(name),{ + switch(type, \name,{ //if the name exists and the new name is not empty, change it - if(msg[3]!= "",{ + if(update != "",{ //move the controls - config.config.at(\controls).put(msg[3].asSymbol, config.config.at(\controls).at(msg[1])); - config.config.at(\controls).removeAt(msg[1].asSymbol); + config.config.at(\controls).put(update.asSymbol, config.config.at(\controls).at(name)); + config.config.at(\controls).removeAt(name.asSymbol); // rename the input - config.config.at(\inputs).put(msg[3].asSymbol, config.config.at(\inputs).at(msg[1])); - config.config.at(\inputs).removeAt(msg[1]); - // rename the GUI element in channelView + config.config.at(\inputs).put(update.asSymbol, config.config.at(\inputs).at(name)); + config.config.at(\inputs).removeAt(name); Routine{ - gui.channels.keysValuesDo({|name, channelView| - postln(name++"->"++channelView.name); - if(channelView.name.asSymbol == msg[1].asSymbol, { - channelView.name = msg[3].asSymbol; + // rename the channel View + gui.channels.do({|channel| + if(channel.name.asSymbol == name.asSymbol, { + channel.name = update.asSymbol; }); }); - //TODO: rename the LevelListener + // OSC indicator: stop old task, remove it and create a new one with updated name + gui.indicators.at(name).stop; + gui.indicators.removeAt(name); + gui.addOSCIndicatorFadeOutTask(update); }.play(AppClock); + // stop the listener for LevelIndicator by name and start a new one based upon the updated name + OSCdef(\levels_++name).free; + this.setupLevelListener(update, NetAddr.new(config.config.at(\synthServerAddress), config.config.at(\synthServerPort))); // free the synth on the server and start a new one according to the config - analyzer.freeAnalysisSynth(msg[1].asSymbol); - analyzer.addSynthWithName(msg[3]); + analyzer.freeAnalysisSynth(name.asSymbol); + analyzer.addSynthWithName(update); + //TODO: only start the Synth, if the channel toggle button is okay Routine{ 1.wait; - analyzer.startSynthWithNameAndControls(msg[3].asSymbol, config.config.at(\controls).at(msg[3]), config.config.at(\inputs).at(msg[3])); + analyzer.startSynthWithNameAndControls(update.asSymbol, config.config.at(\controls).at(update), config.config.at(\inputs).at(update)); }.play; - hub.freeSynthListener(msg[1]); - hub.addSynthListener(msg[3]); - hub.startSynthListener(msg[3]); + hub.freeSynthListener(name); + hub.addSynthListener(update); + hub.startSynthListener(update); }); }, \input,{ // if the input name exists and the new is an Integer and greater/equal 0 - if(((msg[3].isInteger) && (msg[3].asInteger >= 0)),{ + if(((update.isInteger) && (update.asInteger >= 0)),{ // change the input in configuration - config.config.at(\inputs).put(msg[1], msg[3].asInteger); - analyzer.setSynthControl(msg[1].asSymbol, \inputChannel, msg[3].asInteger); + config.config.at(\inputs).put(name, update.asInteger); + analyzer.setSynthControl(name.asSymbol, \inputChannel, update.asInteger); }); } ); @@ -99,15 +111,18 @@ Bowelyzer{ path: "/inputs", srcID: NetAddr.new("127.0.0.1", NetAddr.langPort) ); + // listen for toggling messages to "mute" channel OSCdef.newMatching( key: \toggle, func: {|msg, time, addr, recvPort| + var name = msg[1], + toggle = msg[2]; postln("Received: "++msg); - if(msg[1].notNil && msg[2].notNil && msg[3].notNil,{ - if(config.config.at(\inputs).includesKey(msg[1]),{ - switch(msg[3], - 0,{analyzer.startAnalysisSynth(msg[1])}, - 1,{analyzer.stopAnalysisSynth(msg[1])} + if(msg[1].notNil && msg[2].notNil && msg[2].isInteger,{ + if(config.config.at(\inputs).includesKey(name),{ + switch(toggle, + 0,{analyzer.startAnalysisSynth(name)}, + 1,{analyzer.stopAnalysisSynth(name)} ); }); }); @@ -116,6 +131,72 @@ Bowelyzer{ srcID: NetAddr.new("127.0.0.1", NetAddr.langPort) ); } - //TODO: add SimpleController - //TODO: delegate changes to BowelyzerConfig.config and update analyzer and GUI with it + + // add OSCdefs listening for messages coming from scsynth, to update the GUI + addServerListeners{ + this.setupIndicatorListener; + // add and start a listener for each channel's LevelIndicator + config.config.at(\inputs).pairsDo({|key,value| + this.setupLevelListener(key, NetAddr.new(config.config.at(\synthServerAddress), config.config.at(\synthServerPort))); + }); + } + + // setup a listener for a level indicator by name and source (of synth server) + setupIndicatorListener{ + // listen for indicator messages + OSCdef.newMatching( + key: \indicate, + func: {|msg, time, addr, recvPort| + var name = msg[1]; + //postln("Indicate for "++name); + if(config.config.at(\inputs).includesKey(name),{ + if(gui.indicators.includesKey(name),{ + gui.indicators.at(name).stop; + gui.indicators.at(name).reset; + gui.indicators.at(name).start(AppClock); + }); + }); + }, + path: "/indicate", + srcID: NetAddr.new("127.0.0.1", NetAddr.langPort) + ); + } + + // setup a listener for a level indicator by name and source (of synth server) + setupLevelListener{ + arg name, server; + postln("Setting up LevelListener for: "++name); + OSCdef.newMatching( + key: \levels_++name, + func: {|msg, time, addr, recvPort| + var name = msg[0].asString.replace("/levels/", "").asSymbol, + value = msg[3].ampdb.linlin(-40, 0, 0, 1), + peak = msg[4].ampdb.linlin(-40, 0, 0, 1); + //postln("Receiving: "++msg); + { + gui.channels.do({|channel| + if(channel.name.asSymbol == name,{ + channel.children.do({|channelChild| + if(channelChild.name.asSymbol == \meterAndControls,{ + channelChild.children.do({|meterAndControls| + if(meterAndControls.name.asSymbol == \meterView, { + meterAndControls.children.do({|meterView| + if(meterView.isKindOf(LevelIndicator), { + //postln("Setting up LevelIndicator for "++name); + meterView.value = value; + meterView.peakLevel = peak; + }); + }); + }); + }); + }); + }); + }); + }); + }.defer; + }, + path: "/levels/"++name, + srcID: server + ); + } } diff --git a/BowelyzerGUI.sc b/BowelyzerGUI.sc index f50ac63..99d1f47 100644 --- a/BowelyzerGUI.sc +++ b/BowelyzerGUI.sc @@ -1,11 +1,10 @@ BowelyzerGUI{ - var mainView, - channelContainerView, + var mainView, channelContainerView,