[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[sc-dev] SF.net SVN: quarks:[1296] Manta



Revision: 1296
          http://quarks.svn.sourceforge.net/quarks/?rev=1296&view=rev
Author:   decampo
Date:     2009-12-18 13:29:15 +0000 (Fri, 18 Dec 2009)

Log Message:
-----------
add quark for Manta controller.

Added Paths:
-----------
    Manta/
    Manta/Manta.html
    Manta/Manta.sc
    Manta/MantaNormal.html

Added: Manta/Manta.html
===================================================================
--- Manta/Manta.html	                        (rev 0)
+++ Manta/Manta.html	2009-12-18 13:29:15 UTC (rev 1296)
@@ -0,0 +1,635 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd";>
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<meta http-equiv="Content-Style-Type" content="text/css">
+<title></title>
+<meta name="Generator" content="Cocoa HTML Writer">
+<meta name="CocoaVersion" content="1038.25">
+<style type="text/css">
+p.p1 {margin: 0.0px 0.0px 0.0px 0.0px; font: 12.0px Helvetica}
+p.p2 {margin: 0.0px 0.0px 0.0px 0.0px; font: 12.0px Helvetica; min-height: 14.0px}
+p.p3 {margin: 0.0px 0.0px 0.0px 0.0px; font: 9.0px Monaco; min-height: 12.0px}
+p.p4 {margin: 0.0px 0.0px 0.0px 0.0px; font: 14.0px Helvetica}
+p.p5 {margin: 0.0px 0.0px 0.0px 57.0px; text-indent: -57.0px; font: 9.0px Monaco; min-height: 12.0px}
+p.p6 {margin: 0.0px 0.0px 0.0px 57.0px; text-indent: -57.0px; font: 12.0px Helvetica}
+p.p7 {margin: 0.0px 0.0px 0.0px 57.0px; text-indent: -57.0px; font: 12.0px Helvetica; min-height: 14.0px}
+p.p8 {margin: 0.0px 0.0px 0.0px 57.0px; text-indent: -57.0px; font: 9.0px Monaco}
+p.p9 {margin: 0.0px 0.0px 0.0px 85.0px; text-indent: -85.0px; font: 12.0px Helvetica}
+p.p10 {margin: 0.0px 0.0px 0.0px 57.0px; text-indent: -57.0px; font: 9.0px Monaco; color: #cd0b0b}
+p.p11 {margin: 0.0px 0.0px 0.0px 57.0px; text-indent: -57.0px; font: 9.0px Monaco; color: #2024c7}
+p.p12 {margin: 0.0px 0.0px 0.0px 57.0px; text-indent: -57.0px; font: 9.0px Monaco; color: #e10000}
+p.p13 {margin: 0.0px 0.0px 0.0px 57.0px; text-indent: -57.0px; font: 14.0px Helvetica}
+p.p14 {margin: 0.0px 0.0px 0.0px 57.0px; text-indent: -57.0px; font: 9.0px Monaco; color: #e20000}
+p.p15 {margin: 0.0px 0.0px 0.0px 57.0px; text-indent: -57.0px; font: 14.0px Helvetica; min-height: 17.0px}
+p.p16 {margin: 0.0px 0.0px 0.0px 57.0px; text-indent: -57.0px; font: 9.0px Monaco; color: #d40000}
+p.p17 {margin: 0.0px 0.0px 0.0px 57.0px; text-indent: -57.0px; font: 9.0px Monaco; color: #008417}
+p.p18 {margin: 0.0px 0.0px 0.0px 57.0px; text-indent: -57.0px; font: 9.0px Monaco; color: #737373}
+p.p19 {margin: 0.0px 0.0px 0.0px 0.0px; font: 9.0px Monaco}
+p.p20 {margin: 0.0px 0.0px 0.0px 0.0px; font: 9.0px Monaco; color: #cd0b0b}
+p.p21 {margin: 0.0px 0.0px 0.0px 85.0px; text-indent: -85.0px; font: 12.0px Helvetica; min-height: 14.0px}
+p.p22 {margin: 0.0px 0.0px 0.0px 0.0px; font: 9.0px Monaco; color: #d40000; min-height: 12.0px}
+p.p23 {margin: 0.0px 0.0px 0.0px 57.0px; text-indent: -57.0px; font: 9.0px Monaco; color: #008919}
+p.p24 {margin: 0.0px 0.0px 0.0px 57.0px; text-indent: -57.0px; font: 9.0px Monaco; color: #e20000; min-height: 12.0px}
+p.p25 {margin: 0.0px 0.0px 0.0px 57.0px; text-indent: -57.0px; font: 9.0px Monaco; color: #0000cf}
+p.p26 {margin: 0.0px 0.0px 0.0px 57.0px; text-indent: -57.0px; font: 9.0px Monaco; color: #008a00}
+p.p27 {margin: 0.0px 0.0px 0.0px 0.0px; font: 9.0px Monaco; color: #0000cf}
+p.p28 {margin: 0.0px 0.0px 0.0px 0.0px; font: 9.0px Monaco; color: #e20000}
+span.s1 {font: 18.0px Helvetica}
+span.s2 {text-decoration: underline}
+span.s3 {color: #2b30fa}
+span.s4 {color: #1102c4}
+span.s5 {color: #0000cf}
+span.s6 {color: #e20000}
+span.s7 {color: #2226cf}
+span.s8 {color: #2024c7}
+span.s9 {color: #000000}
+span.s10 {color: #cd0b0b}
+span.s11 {font: 9.0px Monaco}
+span.s12 {color: #008417}
+span.s13 {color: #008900}
+span.s14 {color: #008a00}
+span.s15 {color: #e10000}
+span.s16 {color: #737373}
+span.s17 {font: 14.0px Helvetica}
+span.s18 {color: #008919}
+span.Apple-tab-span {white-space:pre}
+</style>
+</head>
+<body>
+<p class="p1"><span class="s1"><b>Manta<span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span></b></span><b>using the Snyderphonics Manta controller with SC3</b></p>
+<p class="p2"><br></p>
+<p class="p3"><br></p>
+<p class="p1">to be used with the MantaCocoa application, which sends OSC data from the Manta controller.<span class="Apple-converted-space"> </span></p>
+<p class="p2"><br></p>
+<p class="p1">A Manta object has OSCresponders for the different messages the Manta controller sends.<span class="Apple-converted-space"> </span></p>
+<p class="p1">One can add and remove functions for each type of incoming event, as well as<span class="Apple-converted-space"> </span></p>
+<p class="p1">for every individual pad, slider, noteOn, noteOff, velocity and centroid message coming in.</p>
+<p class="p2"><br></p>
+<p class="p1">The Manta class keeps around the most recent values for every slider and pad.<span class="Apple-converted-space"> </span></p>
+<p class="p1">Optionally, it can<span class="Apple-converted-space"> </span></p>
+<p class="p1"><span class="Apple-tab-span">	</span>normalize the incoming values for pads and sliders to 0.0 - 1.0,<span class="Apple-converted-space"> </span></p>
+<p class="p1"><span class="Apple-tab-span">	</span>mirror all the values on buses,<span class="Apple-converted-space"> </span></p>
+<p class="p1"><span class="Apple-tab-span">	</span>and create noteOn events based on incoming simple pad values.<span class="Apple-converted-space"> </span></p>
+<p class="p1"><span class="Apple-tab-span">	</span>(this functionalitz may move to the MantaCocoa app eventually).<span class="Apple-converted-space"> </span></p>
+<p class="p2"><span class="Apple-tab-span">	</span></p>
+<p class="p1">Finally, one can switch between several setups of functions,<span class="Apple-converted-space"> </span></p>
+<p class="p1">and add/remove globalActions that remain the same across different setups.<span class="Apple-converted-space"> </span></p>
+<p class="p2"><br></p>
+<p class="p1"><b>See also: </b><span class="s2">http://www.snyderphonics.com</span></p>
+<p class="p1"><b>See also: </b><a href="MantaNormal.html"><span class="s3"><b>MantaNormal</b></span></a><span class="s3"><b> </b></span><b>for normalsing pad and slider values</b></p>
+<p class="p2"><br></p>
+<p class="p4"><b>Creation / Class Methods and Variables</b></p>
+<p class="p5"><br></p>
+<p class="p6"><b><span class="Apple-tab-span">	</span>*appPath</b><span class="Apple-tab-span">	</span></p>
+<p class="p6"><span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span>the file path to the MantaCocoa.app.<span class="Apple-converted-space"> </span></p>
+<p class="p6"><span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span>Default is "/Applications/manta*/MantaCocoa.app"</p>
+<p class="p7"><br></p>
+<p class="p8"><span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span><span class="s4">Manta</span>.appPath;</p>
+<p class="p8"><span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span>// set it to some other path</p>
+<p class="p8"><span class="Apple-tab-span">	</span>//<span class="Apple-tab-span">	</span><span class="s4">Manta</span>.appPath_("/path/to/MantaCocoa.app");</p>
+<p class="p5"><br></p>
+<p class="p6"><b><span class="Apple-tab-span">	</span>*start</b></p>
+<p class="p6"><span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span>start the MantaCocoa.app</p>
+<p class="p7"><span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span></p>
+<p class="p8"><span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span><span class="s5">Manta</span>.start;</p>
+<p class="p7"><b><span class="Apple-tab-span">	</span></b></p>
+<p class="p6"><b><span class="Apple-tab-span">	</span>*verbose</b></p>
+<p class="p6"><b><span class="Apple-tab-span">	</span></b><span class="Apple-tab-span">	</span>Turn posting of debugging info on and off</p>
+<p class="p5"><br></p>
+<p class="p8"><span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span><span class="s5">Manta</span>.verbose_(<span class="s5">true</span>); <span class="s6">// post</span></p>
+<p class="p8"><span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span><span class="s5">Manta</span>.verbose_(<span class="s5">false</span>); <span class="s6">// no posting</span></p>
+<p class="p7"><br></p>
+<p class="p6"><span class="Apple-tab-span">	</span>*killPrefs<span class="Apple-converted-space"> </span></p>
+<p class="p6"><span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span>deletes the preference file that the MantaCocoa app writes, which is sometimes broken.</p>
+<p class="p6"><span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span>Restarting MantaCocoa after killPrefs restores it to the default config, which works fine.</p>
+<p class="p5"><br></p>
+<p class="p8"><span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span><span class="s7">Manta</span>.killPrefs;</p>
+<p class="p5"><br></p>
+<p class="p6"><b><span class="Apple-tab-span">	</span>*new (addr, addResps, makeBuses, server, usesTops)</b></p>
+<p class="p7"><b><span class="Apple-tab-span">	</span></b></p>
+<p class="p6"><b><span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span></b>Create a Manta object.</p>
+<p class="p9"><span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span><b>addr <span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span></b>- The NetAddr of the Manta app to listen to.<span class="Apple-converted-space"> </span></p>
+<p class="p9"><span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span>Default value is nil, which listens to all sending ports.</p>
+<p class="p9"><span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span><b>addResps <span class="Apple-tab-span">	</span></b>- a flag whether to add all OSCresponderNodes on creation.<span class="Apple-converted-space"> </span></p>
+<p class="p9"><span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span>Default<span class="Apple-converted-space">  </span>is true.<span class="Apple-converted-space"> </span></p>
+<p class="p9"><span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span><b>makeBuses</b> <span class="Apple-tab-span">	</span>- a flag whether to make buses on the server.</p>
+<p class="p9"><span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span><b>server</b> <span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span>- which server to make the buses on, default is Server.default.</p>
+<p class="p6"><span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span><b>usesTops <span class="Apple-tab-span">	</span></b>- a flag whether to use the 4 top buttons separately as topButtons, or as pads 49-52.<span class="Apple-converted-space"> </span></p>
+<p class="p6"><span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span>Default is true, which keeps them separate, false joins them to the main 48 pads.</p>
+<p class="p7"><span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span></p>
+<p class="p8"><span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span>g = <span class="s8">Manta</span>.new;</p>
+<p class="p8"><span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span><span class="s8">Manta</span>.verbose_(<span class="s8">true</span>);</p>
+<p class="p10"><span class="s9"><span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span></span>// touch all the surfaces now: it posts values for all the controllers</p>
+<p class="p5"><span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span></p>
+<p class="p10"><span class="s9"><span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span></span>// cleanup<span class="Apple-converted-space"> </span></p>
+<p class="p8"><span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span><span class="s8">Manta</span>.verbose_(<span class="s8">false</span>); <span class="s10">// no posting</span></p>
+<p class="p8"><span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span>g.free;</p>
+<p class="p5"><span class="Apple-tab-span">	</span></p>
+<p class="p6"><b><span class="Apple-tab-span">	</span>*setups</b></p>
+<p class="p7"><b><span class="Apple-tab-span">	</span></b></p>
+<p class="p6"><span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span>The Manta class can keep multiple setups that can be switched.<span class="Apple-converted-space"> </span></p>
+<p class="p6"><span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span>See setup examples further down.</p>
+<p class="p5"><span class="Apple-tab-span">	</span></p>
+<p class="p5"><br></p>
+<p class="p6"><span class="s11"><span class="Apple-tab-span">	</span></span><b>Example 1: control the volumes of 48 continuous sounds,<span class="Apple-converted-space">  </span>using only buses.</b></p>
+<p class="p6"><b><span class="Apple-tab-span">	</span>upper slider controls vibrato.<span class="Apple-converted-space"> </span></b></p>
+<p class="p5"><span class="Apple-tab-span">	</span></p>
+<p class="p8"><span class="Apple-tab-span">	</span>g.free; g = <span class="s8">Manta</span>.new; <span class="s8">Manta</span>.verbose = <span class="s8">true</span>;</p>
+<p class="p5"><span class="Apple-tab-span">	</span></p>
+<p class="p8">(</p>
+<p class="p10"><span class="s9"><span class="Apple-tab-span">	</span></span>// this example uses unscaled controller data, so turn normed off:<span class="Apple-converted-space"> </span></p>
+<p class="p8"><span class="Apple-tab-span">	</span>g.normed = <span class="s8">false</span>;<span class="Apple-converted-space"> </span></p>
+<p class="p5"><br></p>
+<p class="p11"><span class="s9"><span class="Apple-tab-span">	</span></span>Ndef<span class="s9">(</span><span class="s12">\manta</span><span class="s9">, { </span>|lag=0.003|</p>
+<p class="p8"><span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span><span class="s8">var</span> freqs = (48 + (0..47)).midicps;<span class="Apple-converted-space"> </span></p>
+<p class="p11"><span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span>var sliderBus = <span class="s9">g.buses[</span><span class="s12">\slider</span><span class="s9">].kr;<span class="Apple-converted-space"> </span></span></p>
+<p class="p8"><span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span>var padBus = g.buses[<span class="s12">\pad</span>].kr;</p>
+<p class="p5"><span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span></p>
+<p class="p10"><span class="s9"><span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span></span>// scaling bus values here</p>
+<p class="p8"><span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span><span class="s8">var</span> modCtl = (<span class="s8">sliderBus</span>[0] / 4000).squared * 0.02;</p>
+<p class="p8"><span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span><span class="s8">var</span> volCtl = (<span class="s8">sliderBus</span>[1] - 20 / 4000).max(0); <span class="s10">// top Slider</span></p>
+<p class="p8"><span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span><span class="s8">var</span> amps = (padBus * 0.005 * <span class="s8">AmpComp</span>.ir(freqs)).squared.lag(lag);<span class="Apple-converted-space"> </span></p>
+<p class="p5"><br></p>
+<p class="p8"><span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span>var mod = <span class="s8">SinOsc</span>.kr({ rrand(5.0, 6.0) }!48) * modCtl;</p>
+<p class="p8"><span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span><span class="s8">var</span> oscs = <span class="s8">SinOsc</span>.ar(freqs * (1+mod));<span class="Apple-converted-space"> </span></p>
+<p class="p10"><span class="s9"><span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span></span><span class="s8">Splay</span><span class="s9">.ar(oscs * amps); </span>// * volCtl // add optional master vol by slider</p>
+<p class="p8"><span class="Apple-tab-span">	</span>});</p>
+<p class="p8"><span class="Apple-tab-span">	</span><span class="s8">Ndef</span>(<span class="s12">\manta</span>).play;</p>
+<p class="p8">)</p>
+<p class="p5"><br></p>
+<p class="p8">(</p>
+<p class="p10"><span class="s9"><span class="Apple-tab-span">	</span></span>// this uses normed pad and slider values, so turn normed back on:<span class="Apple-converted-space"> </span></p>
+<p class="p8"><span class="Apple-tab-span">	</span>g.normed = <span class="s8">true</span>;<span class="Apple-converted-space"> </span></p>
+<p class="p5"><br></p>
+<p class="p11"><span class="s9"><span class="Apple-tab-span">	</span></span>Ndef<span class="s9">(</span><span class="s12">\manta</span><span class="s9">, { </span>|lag=0.003|</p>
+<p class="p8"><span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span><span class="s8">var</span> freqs = (48 + (0..47)).midicps;<span class="Apple-converted-space"> </span></p>
+<p class="p11"><span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span>var sliderBus = <span class="s9">g.buses[</span><span class="s12">\slider</span><span class="s9">].kr;<span class="Apple-converted-space"> </span></span></p>
+<p class="p8"><span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span>var padBus = g.buses[<span class="s12">\pad</span>].kr;</p>
+<p class="p5"><span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span></p>
+<p class="p10"><span class="s9"><span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span></span>// buses are normed, so simpler scaling here</p>
+<p class="p8"><span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span><span class="s8">var</span> modCtl = (<span class="s8">sliderBus</span>[0]).squared * 0.02;</p>
+<p class="p8"><span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span><span class="s8">var</span> volCtl = <span class="s8">sliderBus</span>[1].squared; <span class="s10">// top Slider</span></p>
+<p class="p8"><span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span><span class="s8">var</span> amps = (padBus * <span class="s8">AmpComp</span>.ir(freqs)).squared.lag(lag);<span class="Apple-converted-space"> </span></p>
+<p class="p5"><br></p>
+<p class="p8"><span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span>var mod = <span class="s8">SinOsc</span>.kr({ rrand(5.0, 6.0) }!48) * modCtl;</p>
+<p class="p8"><span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span><span class="s8">var</span> oscs = <span class="s8">SinOsc</span>.ar(freqs * (1+mod));<span class="Apple-converted-space"> </span></p>
+<p class="p10"><span class="s9"><span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span></span><span class="s8">Splay</span><span class="s9">.ar(oscs * amps)</span> // * volCtl // add optional master vol by slider</p>
+<p class="p8"><span class="Apple-tab-span">	</span>});</p>
+<p class="p8"><span class="Apple-tab-span">	</span><span class="s8">Ndef</span>(<span class="s12">\manta</span>).play;</p>
+<p class="p8">)</p>
+<p class="p5"><br></p>
+<p class="p8"><span class="Apple-tab-span">	</span>g.free; <span class="s8">Ndef</span>(<span class="s12">\manta</span>).end;<span class="Apple-converted-space"> </span></p>
+<p class="p5"><br></p>
+<p class="p5"><br></p>
+<p class="p6"><span class="s11"><span class="Apple-tab-span">	</span></span><b>Example 2 - start individual synths for each pad.</b></p>
+<p class="p8"><span class="Apple-tab-span">	</span>// make a little voicer by hand, and play synths with it:<span class="Apple-converted-space"> </span></p>
+<p class="p8"><span class="Apple-tab-span">	</span>// this is unreliable when you play lots of notes very quickly,<span class="Apple-converted-space"> </span></p>
+<p class="p8"><span class="Apple-tab-span">	</span>// as you can get hanging silent synths: while all the synths are properly<span class="Apple-converted-space"> </span></p>
+<p class="p8"><span class="Apple-tab-span">	</span>// removed from the dict, some may not have been released properly!</p>
+<p class="p8"><span class="Apple-tab-span">	</span>// this happens in all cases, with \vel, \noteOn, and \pad as synth starters.<span class="Apple-converted-space"> </span></p>
+<p class="p5"><span class="Apple-tab-span">	</span></p>
+<p class="p8"><span class="Apple-tab-span">	</span>// not sure where that happens, needs more precise testing.<span class="Apple-converted-space"> </span></p>
+<p class="p5"><br></p>
+<p class="p8"><span class="Apple-tab-span">	</span>g.free; g = Manta.new;</p>
+<p class="p8">(</p>
+<p class="p8"><span class="Apple-tab-span">	</span>q = ();</p>
+<p class="p8"><span class="Apple-tab-span">	</span>q.synths = ();<span class="Apple-converted-space"> </span></p>
+<p class="p5"><span class="Apple-tab-span">	</span></p>
+<p class="p8"><span class="Apple-tab-span">	</span>g.addMulti(<span class="s13">\pad</span>, { <span class="s5">|key, val|</span><span class="Apple-converted-space"> </span></p>
+<p class="p8"><span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span>var synth = q.synths[key];</p>
+<p class="p5"><br></p>
+<p class="p8"><span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span>if (val == 0) { // "end synth".postln;</p>
+<p class="p8"><span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span>q.synths.removeAt(key).release;</p>
+<p class="p8"><span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span>} {<span class="Apple-converted-space"> </span></p>
+<p class="p8"><span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span>if (synth.isNil) { // "make synth".postln;</p>
+<p class="p8"><span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span>q.synths.put(key, <span class="s5">Synth</span>(<span class="s14">\default</span>, [<span class="s14">\freq</span>, (key - 1 + 60).midicps, <span class="s14">\amp</span>, (val * 0.5).squared ]));</p>
+<p class="p8"><span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span>} {<span class="Apple-converted-space"> </span></p>
+<p class="p8"><span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span>// "update synth".postln; // e.g.<span class="s15"> uncomment to try aftertouch</span></p>
+<p class="p12"><span class="s9"><span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span></span><span class="Apple-tab-span">	</span>q.synths.at(key).set(\amp, (val * 0.5).squared);</p>
+<p class="p12"><span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span>};</p>
+<p class="p8"><span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span>};</p>
+<p class="p8"><span class="Apple-tab-span">	</span>});</p>
+<p class="p8">)</p>
+<p class="p8">g.free;</p>
+<p class="p5"><br></p>
+<p class="p5"><br></p>
+<p class="p5"><br></p>
+<p class="p13"><b>Instance Variables</b></p>
+<p class="p7"><span class="Apple-tab-span">	</span></p>
+<p class="p6"><span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span>// make 2 Mantas, to compare what usesTops does.</p>
+<p class="p7"><span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span></p>
+<p class="p14"><span class="s9"><span class="Apple-tab-span">	</span>g = </span><span class="s5">Manta</span><span class="s9">.new; <span class="Apple-tab-span">	</span></span>// with buses and 48 pads / 4 topButtons etc<span class="Apple-converted-space"> </span></p>
+<p class="p14"><span class="s9"><span class="Apple-tab-span">	</span>h = </span><span class="s5">Manta</span><span class="s9">.new(</span><span class="s5">makeBuses: false, </span><span class="s9">usesTops: </span><span class="s5">false</span><span class="s9">); <span class="Apple-tab-span">	</span></span>// no buses, all 52 pads are uniform.</p>
+<p class="p7"><span class="Apple-tab-span">	</span></p>
+<p class="p6"><b><span class="Apple-tab-span">	</span>responders</b><span class="Apple-tab-span">	</span>- a dictionary of all the OSCresponderNodes that listen to the different control events</p>
+<p class="p7"><br></p>
+<p class="p8"><span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span>g.responders;</p>
+<p class="p8"><span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span>h.responders;</p>
+<p class="p7"><br></p>
+<p class="p6"><b><span class="Apple-tab-span">	</span>multi</b><span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span>- a dictionary where the different actions for each kind of incoming event are.</p>
+<p class="p7"><span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span></p>
+<p class="p8"><span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span>g.multi;</p>
+<p class="p8"><span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span>h.multi;</p>
+<p class="p7"><span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span></p>
+<p class="p6"><b><span class="Apple-tab-span">	</span>indiv</b><span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span>- a dictionary where all the registered functions per individual pad/button/slider are.</p>
+<p class="p7"><span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span></p>
+<p class="p8"><span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span>g.indiv;<span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span>// with topButton, topNote, topVelocity etc</p>
+<p class="p8"><span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span>h.indiv;<span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span>// no tops</p>
+<p class="p7"><br></p>
+<p class="p6"><b><span class="Apple-tab-span">	</span>actions</b><span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span>- a dictionary where multi and indiv actions are stored, mainly for saving setups.</p>
+<p class="p7"><span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span></p>
+<p class="p8"><span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span>g.actions;<span class="Apple-tab-span">	</span></p>
+<p class="p8"><span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span>h.actions;</p>
+<p class="p7"><span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span></p>
+<p class="p6"><b><span class="Apple-tab-span">	</span>addr</b><span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span>- the NetAddr the Manta object is listening to. Default value nil means it listens to all senders.</p>
+<p class="p7"><br></p>
+<p class="p8"><span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span>g.addr;</p>
+<p class="p7"><br></p>
+<p class="p7"><span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span></p>
+<p class="p6"><span class="Apple-tab-span">	</span><b>values</b><span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span>- a dictionary where the recent values for all controls are kept.</p>
+<p class="p7"><br></p>
+<p class="p14"><span class="s9"><span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span>g.values;<span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span></span>// with topButton etc etc</p>
+<p class="p8"><span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span>h.values;<span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span><span class="s6">// no top</span></p>
+<p class="p7"><br></p>
+<p class="p6"><span class="Apple-tab-span">	</span><b>buses</b><span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span>- a dictionary of the optional buses that provide the recent values on the server.</p>
+<p class="p7"><br></p>
+<p class="p8"><span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span>g.buses<span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span><span class="s6">// with top</span></p>
+<p class="p8"><span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span>h.buses<span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span><span class="s6">// no buses</span></p>
+<p class="p7"><br></p>
+<p class="p6"><span class="Apple-tab-span">	</span>h.free;</p>
+<p class="p7"><br></p>
+<p class="p13"><b>Configuring how the Manta object responds to touches</b></p>
+<p class="p15"><br></p>
+<p class="p6">OSCresponders can be added and removed by names:</p>
+<p class="p7"><span class="Apple-tab-span">	</span></p>
+<p class="p6"><b><span class="Apple-tab-span">	</span>addResps (keys)</b></p>
+<p class="p7"><b><span class="Apple-tab-span">	</span></b></p>
+<p class="p6"><b><span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span></b>Short prose description of method.</p>
+<p class="p9"><span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span><b>keys </b>- Explanation of keys. Default value is nil, meaning all responders are added.</p>
+<p class="p6"><span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span>// turn on 2 responders by name</p>
+<p class="p8"><span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span>g.addResps([\sliderResp, \padResp]);</p>
+<p class="p5"><br></p>
+<p class="p5"><br></p>
+<p class="p6"><b><span class="Apple-tab-span">	</span>removeResps (keys)</b></p>
+<p class="p7"><b><span class="Apple-tab-span">	</span></b><span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span></p>
+<p class="p16"><span class="s9"><span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span></span>// turn off 2 other responders</p>
+<p class="p8"><span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span>g.removeResps([\velocityResp, \centroidResp]);</p>
+<p class="p5"><br></p>
+<p class="p8"><span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span>g.addResps();</p>
+<p class="p5"><br></p>
+<p class="p15"><b><span class="Apple-tab-span">	</span></b></p>
+<p class="p13"><b><span class="Apple-tab-span">	</span>Adding actions for one type of events, e.g. all pad touches:<span class="Apple-converted-space"> </span></b></p>
+<p class="p5"><span class="Apple-tab-span">	</span></p>
+<p class="p6"><b><span class="Apple-tab-span">	</span>setMultiAction (key, func)</b></p>
+<p class="p6"><b><span class="Apple-tab-span">	</span>removeMultiAction (key)</b></p>
+<p class="p6"><span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span>set and remove the actions to happen when a pad, a topbutton, a slider,<span class="Apple-converted-space"> </span></p>
+<p class="p6"><span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span>a velocity, noteOn, noteOff comes in.</p>
+<p class="p7"><span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span></p>
+<p class="p8"><span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span>g.addMulti(<span class="s12">\pad</span>, { <span class="s8">|key, val|</span> <span class="s16">"pad num: % val: %\n"</span>.postf(key, val) });</p>
+<p class="p10"><span class="s9"><span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span></span>// try the pads now</p>
+<p class="p8"><span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span>g.addMulti(<span class="s12">\topButton</span>, { <span class="s8">|key, val|</span> <span class="s16">"<span class="Apple-tab-span">	</span>topButton num: % val: %\n"</span>.postf(key, val) });</p>
+<p class="p10"><span class="s9"><span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span></span>// try the 4 topButtons now</p>
+<p class="p5"><br></p>
+<p class="p8"><span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span>g.removeMulti(<span class="s12">\pad</span>);</p>
+<p class="p8"><span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span>g.removeMulti(<span class="s12">\topButton</span>);</p>
+<p class="p10"><span class="s9"><span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span>g.removeMulti([</span><span class="s12">\pad</span><span class="s9">, </span><span class="s12">\topButton</span><span class="s9">]); </span>// remove several at the same time</p>
+<p class="p5"><br></p>
+<p class="p8"><span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span>g.addMulti(<span class="s12">\slider</span>, { <span class="s8">|key, val|</span> <span class="s16">"slider - num: % val: %\n"</span>.postf(key, val) });</p>
+<p class="p10"><span class="s9"><span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span></span>// try the sliders now</p>
+<p class="p5"><br></p>
+<p class="p10"><span class="s9"><span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span></span>// test the noteOnLogic in the Manta Class</p>
+<p class="p8"><span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span>g.usesNoteOn = <span class="s8">true</span>;</p>
+<p class="p10"><span class="s9"><span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span></span>// noteOn and velocity should be disabled in the Manta.app</p>
+<p class="p8"><span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span>g.addMulti(<span class="s12">\noteOn</span>, { <span class="s8">|key, val|</span> <span class="s16">"noteOn - num: % val: %\n"</span>.postf(key, val) });</p>
+<p class="p8"><span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span>g.addMulti(<span class="s12">\noteOff</span>, { <span class="s8">|key, val|</span> <span class="s16">"noteOff - num: % val: %\n"</span>.postf(key, val) });</p>
+<p class="p8"><span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span>// first touch on a pad should trigger noteOn, release creates a noteOff</p>
+<p class="p5"><br></p>
+<p class="p10"><span class="s9"><span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span></span>// separate velocity message makes no sense really</p>
+<p class="p10">//<span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span>g.addMulti(\velocity, { |key, val| "velocity - num: % val: %\n".postf(key, val) });</p>
+<p class="p5"><br></p>
+<p class="p17"><span class="s9"><span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span>g.removeMulti([</span>\slider<span class="s9">, </span>\noteOn<span class="s9">, </span>\noteOff<span class="s9">, </span>\velocity<span class="s9">]);</span></p>
+<p class="p5"><br></p>
+<p class="p10"><span class="s9"><span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span></span>// test centroid calculation that is done in the Manta Class:</p>
+<p class="p10"><span class="s9"><span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span></span>// centroid should be disabled in the Manta.app.<span class="Apple-converted-space"> </span></p>
+<p class="p8"><span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span>g.usesCentroid = <span class="s8">true</span>;<span class="Apple-converted-space"> </span></p>
+<p class="p18"><span class="s9"><span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span>g.addMulti(</span><span class="s12">\centroid</span><span class="s9">, { </span><span class="s8">|key, vals|</span><span class="s9"> </span>"centroid - vals x, y, totalVal: %\n"<span class="s9">.postf(vals) });</span></p>
+<p class="p10"><span class="s9"><span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span></span>// touch some pads now - centroid should be posted</p>
+<p class="p8"><span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span>g.removeMulti([<span class="s12">\centroid</span>]);</p>
+<p class="p8"><span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span>g.usesCentroid = <span class="s8">false</span>;<span class="Apple-converted-space"> </span></p>
+<p class="p5"><br></p>
+<p class="p13"><b><span class="Apple-tab-span">	</span>Adding/removing<span class="Apple-converted-space">  </span>functions for individual pads, topButtons, sliders:</b></p>
+<p class="p7"><br></p>
+<p class="p6"><b><span class="Apple-tab-span">	</span>add (type, key, func)</b></p>
+<p class="p6"><b><span class="Apple-tab-span">	</span>add(type, key, func)</b></p>
+<p class="p7"><b><span class="Apple-tab-span">	</span></b></p>
+<p class="p6"><b><span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span></b>Add a function for one type and key:</p>
+<p class="p6"><span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span><b>type</b> - the type of event; one of [<span class="s13">\pad</span>, <span class="s13">\slider</span>, <span class="s13">\noteOn</span>, <span class="s13">\noteOff</span>].<span class="Apple-converted-space"> </span></p>
+<p class="p6"><span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span>or if usesTops, also [<span class="s13">\topButton</span>, <span class="s13">\topNoteOn</span>, <span class="s13">\topNoteOff</span>].</p>
+<p class="p9"><span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span><b>key </b>- the pad key from 1 - 52:<span class="Apple-converted-space"> </span></p>
+<p class="p9"><span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span>1 is bottom left, 48 is top right;<span class="Apple-converted-space"> </span></p>
+<p class="p9"><span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span>49-52 are the extra 4 small touchbuttons on the top right.<span class="Apple-converted-space"> </span></p>
+<p class="p9"><span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span><b>func </b>- the function to run when that pad/button senses a value.</p>
+<p class="p7"><span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span></p>
+<p class="p8"><span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span>g.add(<span class="s13">\pad</span>, 1, { <span class="s5">|val|</span> <span class="s16">"yo, pad 1: %\n"</span>.postf(val) });</p>
+<p class="p18"><span class="s9"><span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span>g.add(</span><span class="s13">\topButton</span><span class="s9">, 49, {<span class="Apple-converted-space">  </span></span><span class="s5">|val|</span><span class="s9"> </span>"top 4 buttons, the top left button? : %\n"<span class="s9">.postf(val) });</span></p>
+<p class="p5"><br></p>
+<p class="p6"><b><span class="Apple-tab-span">	</span>remove(type, key)</b></p>
+<p class="p7"><b><span class="Apple-tab-span">	</span></b></p>
+<p class="p6"><b><span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span></b>Remove the function for type and key:<span class="Apple-converted-space"> </span></p>
+<p class="p6"><span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span><b>type</b> - the type of event; one of [<span class="s14">\pad</span>, <span class="s14">\slider</span>, <span class="s14">\noteOn</span>, <span class="s14">\noteOff</span>].<span class="Apple-converted-space"> </span></p>
+<p class="p6"><span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span>or if usesTops, also [<span class="s14">\topButton</span>, <span class="s14">\topNoteOn</span>, <span class="s14">\topNoteOff</span>].</p>
+<p class="p9"><span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span><b>key </b>- the key for e.g. the button whose function is to be removed</p>
+<p class="p7"><span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span></p>
+<p class="p8"><span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span>g.remove(<span class="s12">\pad</span>, 1);</p>
+<p class="p8"><span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span>g.remove(<span class="s12">\topButton</span>, 49);</p>
+<p class="p5"><br></p>
+<p class="p5"><br></p>
+<p class="p5"><br></p>
+<p class="p8"><span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span>g.add(<span class="s12">\slider</span>, 1, { <span class="s8">|val|</span> <span class="s16">"manta slider1: %\n"</span>.postf(val) });</p>
+<p class="p8"><span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span>g.remove(<span class="s12">\slider</span>, 1);</p>
+<p class="p5"><br></p>
+<p class="p8"><span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span>g.add(<span class="s12">\noteOn</span>, 1, { <span class="s8">|val|</span> <span class="s16">"manta noteOn 1: %\n"</span>.postf(val) });</p>
+<p class="p8"><span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span>g.remove(<span class="s12">\noteOn</span>, 1);</p>
+<p class="p7"><span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span></p>
+<p class="p8"><span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span>g.add(<span class="s12">\noteOff</span>, 1, { <span class="s8">|val|</span> <span class="s16">"manta noteOff 1: %\n"</span>.postf(val) });</p>
+<p class="p8"><span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span>g.remove(<span class="s12">\noteOff</span>, 1);</p>
+<p class="p7"><br></p>
+<p class="p7"><span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span></p>
+<p class="p13"><b><span class="Apple-tab-span">	</span>Adding globalActions for event types and individual keys</b></p>
+<p class="p6"><span class="s17"><b><span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span></b></span><b>globalActions are kept across changing setups, so they can<span class="Apple-converted-space"> </span></b></p>
+<p class="p6"><b><span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span>be used for switching between setups easily.</b></p>
+<p class="p5"><br></p>
+<p class="p6"><b><span class="Apple-tab-span">	</span>addMultiGlobal(key, func)</b></p>
+<p class="p6"><b><span class="Apple-tab-span">	</span>removeMultiGlobal(key)</b></p>
+<p class="p7"><b><span class="Apple-tab-span">	</span></b></p>
+<p class="p8"><span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span>g.free;<span class="Apple-tab-span">	</span>g = <span class="s8">Manta</span>.new; g.usesNoteOn = <span class="s8">true</span>;</p>
+<p class="p19"><span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span>g.addMultiGlobal(<span class="s12">\topNoteOn</span>, { <span class="s8">|key, val|</span> <span class="s16">"YOYO ... %\n"</span>.postf(key) });</p>
+<p class="p19"><span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span>g.addMultiGlobal(<span class="s12">\topNoteOff</span>, { <span class="s8">|key, val|</span> <span class="s16">"... oyoy %\n"</span>.postf(key) });</p>
+<p class="p3"><span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span></p>
+<p class="p19"><span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span>g.removeMultiGlobal([<span class="s12">\topNoteOn</span>, <span class="s12">\topNoteOff</span>]);</p>
+<p class="p3"><br></p>
+<p class="p6"><b><span class="Apple-tab-span">	</span>addGlobal(type, key, func)</b></p>
+<p class="p6"><b><span class="Apple-tab-span">	</span>removeMultiGlobal(type, key)</b></p>
+<p class="p3"><br></p>
+<p class="p19"><span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span>g.addGlobal(<span class="s12">\slider</span>, 1, { <span class="s8">|val|</span> <span class="s16">"slider 1 is at % now.\n"</span>.postf(val) });</p>
+<p class="p19"><span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span>g.addGlobal(<span class="s12">\slider</span>, 2, { <span class="s8">|val|</span> <span class="s16">"and slider 2 ... at %.\n"</span>.postf(val) });</p>
+<p class="p3"><br></p>
+<p class="p19"><span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span>g.removeGlobal(<span class="s12">\slider</span>, [1, 2]);</p>
+<p class="p3"><br></p>
+<p class="p20"><span class="s9"><span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span></span>// switch between setups - if they would exist</p>
+<p class="p19"><span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span>g.addGlobal(<span class="s12">\topNoteOn</span>, 49, { <span class="s8">|val|</span> g.setup(<span class="s12">\otto</span>.postln) });</p>
+<p class="p19"><span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span>g.addGlobal(<span class="s12">\topNoteOn</span>, 50, { <span class="s8">|val|</span> g.setup(<span class="s12">\siegfried</span>.postln) });</p>
+<p class="p3"><br></p>
+<p class="p19"><span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span>g.removeGlobal(<span class="s12">\topNoteOn</span>, 49);</p>
+<p class="p19"><span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span>g.removeGlobal(<span class="s12">\topNoteOn</span>, 50);</p>
+<p class="p5"><br></p>
+<p class="p5"><br></p>
+<p class="p13"><b><span class="Apple-tab-span">	</span>Adding functions to specific non-current setups</b></p>
+<p class="p6"><span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span>see examples for creating and editing setups below.</p>
+<p class="p2"><br></p>
+<p class="p1"><span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span>// multi functions:<span class="Apple-converted-space"> </span></p>
+<p class="p1"><b><span class="Apple-tab-span">	</span>addMultiToSetup( setupName, type, func)</b></p>
+<p class="p1"><b><span class="Apple-tab-span">	</span>removeMultiFromSetup(setupName, type)</b></p>
+<p class="p1"><b><span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span>setupName</b> - the name of the setup to add to / remove from</p>
+<p class="p1"><span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span><b>type</b> - the kind of event to add / remove</p>
+<p class="p1"><span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span><b>func</b> - the func to evaluate for that type of event</p>
+<p class="p2"><br></p>
+<p class="p1"><span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span>// individual funcs for pads, sliders etc</p>
+<p class="p1"><b><span class="Apple-tab-span">	</span>addToSetup(setupName, type, key, func)</b></p>
+<p class="p1"><b><span class="Apple-tab-span">	</span>removeFromSetup(setupName, type, key)</b></p>
+<p class="p1"><b><span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span>setupName</b> - the name of the setup to add to / remove from</p>
+<p class="p1"><span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span><b>type</b> - the kind of event to add / remove</p>
+<p class="p1"><span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span><b>key</b> - the individual pad/slider/top key for which to add/remove a function</p>
+<p class="p1"><span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span><b>func</b> - the func to evaluate for that type of event</p>
+<p class="p15"><br></p>
+<p class="p5"><span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span></p>
+<p class="p6"><b><span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span>// internal methods that may be useful for testing:<span class="Apple-converted-space"> </span></b></p>
+<p class="p5"><span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span></p>
+<p class="p6"><b><span class="Apple-tab-span">	</span></b>respond (name, key, val)</p>
+<p class="p7"><b><span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span></b></p>
+<p class="p9"><span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span><b>name </b>- the name of the message to respond to.<span class="Apple-converted-space"> </span></p>
+<p class="p9"><span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span>can be [\pad, \slider, \noteOn, \noteOff] etc.</p>
+<p class="p9"><span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span><b>key </b>- the<span class="Apple-converted-space">  </span>key to respond to; for the pads 1-48, or 1-52.<span class="Apple-converted-space"> </span></p>
+<p class="p9"><span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span><b>val </b>- the value for that kind of event at the key given.</p>
+<p class="p21"><span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span></p>
+<p class="p14"><span class="s9"><span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span></span>// respond to pad 12 being touched with a value of 50:</p>
+<p class="p8"><span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span>g.respond(<span class="s13">\pad</span>, 12, 50);</p>
+<p class="p7"><b><span class="Apple-tab-span">	</span></b></p>
+<p class="p13"><b><span class="Apple-tab-span">	</span>Accessing recent values and buses<span class="Apple-converted-space"> </span></b></p>
+<p class="p7"><b><span class="Apple-tab-span">	</span></b></p>
+<p class="p6"><b><span class="Apple-tab-span">	</span>values, buses</b></p>
+<p class="p6"><span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span>The Manta object remembers the last values for some controls,<span class="Apple-converted-space"> </span></p>
+<p class="p6"><span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span>and also writes them to buses, if buses were made on creation.</p>
+<p class="p6"><span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span><b>Note:</b> both buses and values are global for this Manta instance,<span class="Apple-converted-space"> </span></p>
+<p class="p6"><span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span>so they can be problematic if you try to run recorded controllers for<span class="Apple-converted-space"> </span></p>
+<p class="p6"><span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span>one Manta setup, and play another live. For this usage, it is better to<span class="Apple-converted-space"> </span></p>
+<p class="p6"><span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span>make buses for each setup separately.</p>
+<p class="p7"><span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span></p>
+<p class="p5"><span class="Apple-tab-span">	</span></p>
+<p class="p14"><span class="s9"><span class="Apple-tab-span">	</span>g.values<span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span></span>// where the current values live</p>
+<p class="p14"><span class="s9"><span class="Apple-tab-span">	</span>g.values[</span><span class="s13">\pad</span><span class="s9">] <span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span></span>// current button touch values<span class="Apple-converted-space"> </span></p>
+<p class="p14"><span class="s9"><span class="Apple-tab-span">	</span>g.values[</span><span class="s13">\slider</span><span class="s9">] <span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span></span>// current slider values (latched in the Manta controller)</p>
+<p class="p14"><span class="s9"><span class="Apple-tab-span">	</span>g.values[</span><span class="s13">\velocity</span><span class="s9">] <span class="Apple-tab-span">	</span></span>// last velocity values for each pad (latched after noteOn)<span class="Apple-converted-space"> </span></p>
+<p class="p14"><span class="s9"><span class="Apple-tab-span">	</span>g.values[</span><span class="s13">\note</span><span class="s9">] <span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span></span>// whether pad is currently touched - 0 or 1</p>
+<p class="p14"><span class="s9"><span class="Apple-tab-span">	</span>g.values[</span><span class="s13">\centroid</span><span class="s9">] <span class="Apple-tab-span">	</span></span>// current centroid - x, y, overall /last weight</p>
+<p class="p5"><br></p>
+<p class="p14"><span class="s9"><span class="Apple-tab-span">	</span>g.values[</span><span class="s13">\topButton</span><span class="s9">] <span class="Apple-tab-span">	</span></span>// like pad, but for topButtons</p>
+<p class="p8"><span class="Apple-tab-span">	</span>g.values[<span class="s13">\topNote</span>] <span class="Apple-tab-span">	</span><span class="s6">// like note<span class="Apple-converted-space"> </span></span></p>
+<p class="p14"><span class="s9"><span class="Apple-tab-span">	</span>g.values[</span><span class="s13">\topVelocity</span><span class="s9">] <span class="Apple-tab-span">	</span></span>// like velocity</p>
+<p class="p5"><span class="Apple-tab-span">	</span></p>
+<p class="p8"><span class="Apple-tab-span">	</span>g.values.keys;</p>
+<p class="p5"><span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span></p>
+<p class="p5"><br></p>
+<p class="p14"><span class="s9"><span class="Apple-tab-span">	</span>g.buses<span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span></span>// a dict with all the buses - same structure as values!</p>
+<p class="p5"><span class="Apple-tab-span">	</span></p>
+<p class="p14"><span class="s9"><span class="Apple-tab-span">	</span>g.buses[</span><span class="s13">\pad</span><span class="s9">]; <span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span></span>// 48 or 52 values, <span class="Apple-tab-span">	</span>0 - ca 200</p>
+<p class="p14"><span class="s9"><span class="Apple-tab-span">	</span>g.buses[</span><span class="s13">\slider</span><span class="s9">];<span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span></span>// 2 values<span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span>ca 12 - ca 4096<span class="Apple-tab-span">	</span></p>
+<p class="p14"><span class="s9"><span class="Apple-tab-span">	</span>g.buses[</span><span class="s13">\velocity</span><span class="s9">]; <span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span></span>// 48 or 52 values<span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span>0 - 127</p>
+<p class="p14"><span class="s9"><span class="Apple-tab-span">	</span>g.buses[</span><span class="s13">\note</span><span class="s9">]; <span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span></span>// 48 or 52 values<span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span>0 or 1</p>
+<p class="p5"><br></p>
+<p class="p14"><span class="s9"><span class="Apple-tab-span">	</span>g.buses[</span><span class="s13">\topButton</span><span class="s9">];<span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span></span>// 4 values if there<span class="Apple-tab-span">	</span>0 - ca 200</p>
+<p class="p14"><span class="s9"><span class="Apple-tab-span">	</span>g.buses[</span><span class="s13">\topNote</span><span class="s9">];<span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span></span>// 4 values if there<span class="Apple-tab-span">	</span>0 or 1</p>
+<p class="p14"><span class="s9"><span class="Apple-tab-span">	</span>g.buses[</span><span class="s13">\topVelocity</span><span class="s9">];<span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span></span>// 4 values<span class="Apple-tab-span">	</span>if there <span class="Apple-tab-span">	</span>0 - 127</p>
+<p class="p5"><br></p>
+<p class="p5"><br></p>
+<p class="p6"><b><span class="Apple-tab-span">	</span>Setting LEDs:<span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span>-- g.canSetLEDs_<span class="Apple-converted-space">  </span>currently crashes the MantaCocoa app (0.9.71)</b></p>
+<p class="p5"><span class="Apple-tab-span">	</span></p>
+<p class="p14"><span class="s9"><span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span></span>// a flag whether LEDs are controlled from SC3<span class="Apple-converted-space"> </span></p>
+<p class="p14"><span class="s9"><span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span></span>// (if not, they light up when touched)</p>
+<p class="p8"><span class="Apple-tab-span">	</span>g.canSetLEDs;<span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span><span class="s6">// false</span></p>
+<p class="p14"><span class="s9"><span class="Apple-tab-span">	</span>g.canSetLEDs_(</span><span class="s5">true</span><span class="s9">);<span class="Apple-tab-span">	</span></span>// make them settable</p>
+<p class="p14"><span class="s9"><span class="Apple-tab-span">	</span>g.listenAddr;<span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span></span>// listenAddr is made if needed</p>
+<p class="p5"><span class="Apple-tab-span">	</span></p>
+<p class="p14"><span class="s9"><span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span></span>// setLEDs(val ... indices) val: 1 is on, 0 is off.</p>
+<p class="p8"><span class="Apple-tab-span">	</span>g.setLEDs(1, 1, 2, 3);</p>
+<p class="p8"><span class="Apple-tab-span">	</span>g.setLEDs(1, *(1, 3 .. 48));</p>
+<p class="p8"><span class="Apple-tab-span">	</span>g.setLEDs(0, *(1 .. 52));</p>
+<p class="p8"><span class="Apple-tab-span">	</span>g.setLEDs(1, *(1 .. 52).scramble.keep(13));</p>
+<p class="p5"><span class="Apple-tab-span">	</span></p>
+<p class="p14"><span class="s9"><span class="Apple-tab-span">	</span>g.canSetLEDs_(</span><span class="s5">false</span><span class="s9">);<span class="Apple-tab-span">	</span></span>// back to auto mode</p>
+<p class="p5"><span class="Apple-tab-span">	</span></p>
+<p class="p5"><br></p>
+<p class="p13"><b>Examples</b></p>
+<p class="p22"><br></p>
+<p class="p1"><b>Pads are in harmonic table layout (turn the Manta so that the sliders are at right top):</b></p>
+<p class="p2"><br></p>
+<p class="p8">d<span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span>d#<span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span>e</p>
+<p class="p8"><span class="Apple-tab-span">	</span>b<span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span>c<span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span>c#</p>
+<p class="p8">g<span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span>g#<span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span>a</p>
+<p class="p8"><span class="Apple-tab-span">	</span>e<span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span>f<span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span>f#</p>
+<p class="p8">c<span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span>c#<span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span>d</p>
+<p class="p8"><span class="Apple-tab-span">	</span>a<span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span>Bb<span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span>b</p>
+<p class="p8">f<span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span>f#<span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span>g</p>
+<p class="p8"><span class="Apple-tab-span">	</span>d<span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span>eb<span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span>e</p>
+<p class="p8">Bb<span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span>B<span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span>C</p>
+<p class="p8"><span class="Apple-tab-span">	</span>G<span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span>G#<span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span>A</p>
+<p class="p8">Eb<span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span>E<span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span>F</p>
+<p class="p8"><span class="Apple-tab-span">	</span>C<span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span>C#<span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span>D</p>
+<p class="p8">As<span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span>A<span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span>Bb</p>
+<p class="p8"><span class="Apple-tab-span">	</span>F<span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span>F#<span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span>G</p>
+<p class="p8">Db<span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span>D<span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span>Eb</p>
+<p class="p8"><span class="Apple-tab-span">	</span>Bb<span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span>B<span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span>C</p>
+<p class="p5"><span class="Apple-tab-span">	</span></p>
+<p class="p8">[98, 95, 99, 96, 100, 97].collect { |x| x + (0, -7 .. -49) };</p>
+<p class="p5"><br></p>
+<p class="p8">Manta.start;</p>
+<p class="p8"><span class="Apple-tab-span">	</span>g.free; g = <span class="s5">Manta</span>.new;</p>
+<p class="p8">(</p>
+<p class="p8"><span class="Apple-tab-span">	</span>g.normed = <span class="s8">true</span>;<span class="Apple-converted-space"> </span></p>
+<p class="p5"><br></p>
+<p class="p11"><span class="s9"><span class="Apple-tab-span">	</span></span>Ndef<span class="s9">(</span><span class="s12">\</span><span class="s18">mantaHarm</span><span class="s9">, { </span>|lag=0.003|</p>
+<p class="p8"><span class="Apple-tab-span">	</span>//<span class="Apple-tab-span">	</span><span class="s8">var</span> freqs = (48 + (0..47)).midicps;<span class="Apple-converted-space"> </span></p>
+<p class="p8"><span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span>var freqs = ([98, 95, 99, 96, 100, 97].collect { |x| x + (0, -7 .. -49) }.flat).midicps;</p>
+<p class="p11"><span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span>var sliderBus = <span class="s9">g.buses[</span><span class="s12">\slider</span><span class="s9">].kr;<span class="Apple-converted-space"> </span></span></p>
+<p class="p8"><span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span>var padBus = g.buses[<span class="s12">\pad</span>].kr;</p>
+<p class="p5"><span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span></p>
+<p class="p10"><span class="s9"><span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span></span>// buses are normed, so simpler scaling here</p>
+<p class="p8"><span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span><span class="s8">var</span> modCtl = (<span class="s8">sliderBus</span>[0]).squared * 0.02;</p>
+<p class="p8"><span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span><span class="s8">var</span> volCtl = <span class="s8">sliderBus</span>[1].squared; <span class="s10">// top Slider</span></p>
+<p class="p8"><span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span><span class="s8">var</span> amps = (padBus * <span class="s8">AmpComp</span>.ir(freqs)).squared.lag(lag);<span class="Apple-converted-space"> </span></p>
+<p class="p5"><br></p>
+<p class="p8"><span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span>var mod = <span class="s8">SinOsc</span>.kr({ rrand(5.0, 6.0) }!48) * modCtl;</p>
+<p class="p8"><span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span><span class="s8">var</span> oscs = <span class="s8">SinOsc</span>.ar(freqs * (1+mod));<span class="Apple-converted-space"> </span></p>
+<p class="p10"><span class="s9"><span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span></span><span class="s8">Splay</span><span class="s9">.ar(oscs * amps)</span> // * volCtl // add optional master vol by slider</p>
+<p class="p8"><span class="Apple-tab-span">	</span>});</p>
+<p class="p8"><span class="Apple-tab-span">	</span><span class="s8">Ndef</span>(<span class="s12">\</span><span class="s18">mantaHarm</span>).play;</p>
+<p class="p8">)</p>
+<p class="p5"><br></p>
+<p class="p23"><span class="s5">Ndef</span><span class="s9">(</span><span class="s13">\</span>mantaHarm<span class="s9">).end;</span></p>
+<p class="p5"><br></p>
+<p class="p8"><span class="s8">Ndef</span>(<span class="s12">\</span><span class="s18">mantaHarm</span>).scope;<span class="Apple-converted-space"> </span></p>
+<p class="p5"><br></p>
+<p class="p6"><b><span class="Apple-tab-span">	</span>// a 6x6 feedback matrix patch:<span class="Apple-converted-space"> </span></b></p>
+<p class="p24"><span class="Apple-tab-span">	</span></p>
+<p class="p14"><span class="Apple-tab-span">	</span>// the sliders set root pitch and interval spread of the 6 oscs,</p>
+<p class="p14"><span class="Apple-tab-span">	</span>// the first 6 pads in every row control phasemod depth of osc1 + osc2 .. + osc 6 -&gt; osc1;</p>
+<p class="p14"><span class="Apple-tab-span">	</span>// the last two add pitch mod, 6 controls speed, 7 controls depth.<span class="Apple-converted-space"> </span></p>
+<p class="p14"><span class="Apple-tab-span">	</span>// the energy for each row is taken from the sum of all its controls;<span class="Apple-converted-space"> </span></p>
+<p class="p14"><span class="Apple-tab-span">	</span>// and when overall energy gets low, all pitches fall somewhat.</p>
+<p class="p5"><br></p>
+<p class="p8"><span class="Apple-tab-span">	</span>g.free; g = <span class="s5">Manta</span>.new;</p>
+<p class="p8">(</p>
+<p class="p25"><span class="s9"><span class="Apple-tab-span">	</span></span>Ndef<span class="s9">(</span><span class="s13">\mantaPM</span><span class="s9">, { </span>|lag=1, mod=0.5|</p>
+<p class="p14"><span class="s9"><span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span></span>// top slider shifts the root pitch,<span class="Apple-converted-space"> </span></p>
+<p class="p14"><span class="s9"><span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span></span>// lower slider the spread of the intervals</p>
+<p class="p8"><span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span><span class="s5">var</span> sliders = g.buses.slider.kr;<span class="Apple-converted-space"> </span></p>
+<p class="p8"><span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span><span class="s5">var</span> root = sliders[0].linlin(0, 1, 30, 60);</p>
+<p class="p8"><span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span><span class="s5">var</span> spread = sliders[1] * 12;<span class="Apple-converted-space"> </span></p>
+<p class="p5"><span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span></p>
+<p class="p14"><span class="s9"><span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span></span>// all the mod controls</p>
+<p class="p8"><span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span><span class="s5">var</span> padBus = <span class="s5">LagUD</span>.kr(g.buses[<span class="s13">\pad</span>].kr, lag * 0.1, lag) * 2;<span class="Apple-converted-space"> </span></p>
+<p class="p8"><span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span><span class="s5">var</span> padRows = padBus.clump(8);</p>
+<p class="p5"><span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span></p>
+<p class="p14"><span class="s9"><span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span></span>// the rightmost 2 controls in every row is pitch mod speed and depth<span class="Apple-converted-space"> </span></p>
+<p class="p8"><span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span><span class="s5">var</span> freqMods = padRows.collect { <span class="s5">|row|</span><span class="Apple-converted-space"> </span></p>
+<p class="p8"><span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span><span class="s5">var</span> modSpeed = row[6].linexp(0, 1.8, 0.3, 30);<span class="Apple-converted-space"> </span></p>
+<p class="p8"><span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span><span class="s5">var</span> modDepth = (row[7] * 2.5).squared;</p>
+<p class="p8"><span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span><span class="s5">LFDNoise0</span>.kr(modSpeed, modDepth);</p>
+<p class="p8"><span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span>};</p>
+<p class="p5"><span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span></p>
+<p class="p8"><span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span><span class="s5">var</span> sumBus = padRows.collect(_.sum);<span class="Apple-converted-space"> </span></p>
+<p class="p5"><span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span></p>
+<p class="p8"><span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span><span class="s5">var</span> freqs = ((0 .. 5) * spread + root + freqMods + LFNoise0.kr(0.3, 0.02)).midicps; <span class="s6">// 6 notes</span></p>
+<p class="p8"><span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span><span class="s5">var</span> phaseMods = <span class="s5">LocalIn</span>.ar(6);<span class="Apple-converted-space"> <span class="Apple-tab-span">	</span></span></p>
+<p class="p8"><span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span><span class="s5">var</span> oscs = <span class="s5">SinOsc</span>.ar(freqs<span class="s6"> * (LagUD.kr(sumBus, lag * 0.4, lag * 4) * 0.5)</span>.min(2).pow(0.1), phaseMods);<span class="Apple-converted-space"> </span></p>
+<p class="p5"><span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span></p>
+<p class="p8"><span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span>var allMods = padRows.collect { <span class="s5">|row|</span> (row.keep(6) * oscs); };</p>
+<p class="p8"><span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span><span class="s5">var</span> modOuts = allMods.collect(_.sum) * mod;</p>
+<p class="p5"><span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span></p>
+<p class="p8"><span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span><span class="s5">LocalOut</span>.ar(modOuts);<span class="Apple-converted-space"> </span></p>
+<p class="p5"><span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span></p>
+<p class="p8"><span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span><span class="s5">Splay</span>.ar(oscs * <span class="s5">AmpComp</span>.kr(freqs.max(50), exp: 0.25) * (<span class="s5">LagUD</span>.kr(sumBus, lag * 0.2, lag * 2) * 0.03).min(1)).softclip;</p>
+<p class="p5"><span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span></p>
+<p class="p8"><span class="Apple-tab-span">	</span>});</p>
+<p class="p8"><span class="Apple-tab-span">	</span><span class="s5">Ndef</span>(<span class="s13">\</span><span class="s14">mantaPM</span>).play;</p>
+<p class="p8">)</p>
+<p class="p5"><br></p>
+<p class="p26"><span class="s5">Ndef</span><span class="s9">(</span>\mantaPM<span class="s9">).end;</span></p>
+<p class="p5"><br></p>
+<p class="p6"><b><span class="Apple-tab-span">	</span>Storing setups:<span class="Apple-converted-space"> </span></b></p>
+<p class="p5"><span class="Apple-tab-span">	</span></p>
+<p class="p27">/*<span class="Apple-tab-span">	</span></p>
+<p class="p19"><span class="s5"><span class="Apple-tab-span">	</span>Manta</span>.start; g.free; g = <span class="s5">Manta</span>.new;</p>
+<p class="p19">*/</p>
+<p class="p3"><br></p>
+<p class="p28"><span class="s9">(<span class="Apple-tab-span">	</span></span>// Setup1: some actions for upper slider, all pads, top 2 buttons</p>
+<p class="p19">g.clearDicts;</p>
+<p class="p19">g.addMulti(<span class="s13">\pad</span>, { <span class="s5">|...args|</span> <span class="s16">"setup1 - Multi pad func: %\n"</span>.postf(args) });</p>
+<p class="p19">g.add(\topButton, 49, { <span class="s5">|... x|</span> <span class="s16">"setup1 - topButton 49: %\n"</span>.postf(x) });</p>
+<p class="p19">g.add(\topButton, 50, { <span class="s5">|... x|</span> <span class="s16">"setup1 - topButton 50: %\n"</span>.postf(x) });</p>
+<p class="p19">g.add(\slider, 1, { <span class="s5">|... x|</span> <span class="s16">"setup1 - slider 1: %\n"</span>.postf(x) });</p>
+<p class="p19">)</p>
+<p class="p3"><br></p>
+<p class="p28">// .. try what it does now, maybe add some more ...</p>
+<p class="p3"><br></p>
+<p class="p28">// then store that setup:</p>
+<p class="p19">g.store(<span class="s13">\setup1</span>);</p>
+<p class="p3"><br></p>
+<p class="p28"><span class="s9">(<span class="Apple-tab-span">	</span></span>// build a different setup - lower slider, lower topButtons, different pad action</p>
+<p class="p19">g.clearDicts;</p>
+<p class="p19">g.addMulti(<span class="s13">\pad</span>, { <span class="s5">|...args|</span> <span class="s16">"\t SETUP2 - Multi pad: %\n"</span>.postf(args) });</p>
+<p class="p19">g.add(\slider, 2, { <span class="s5">|... x|</span> <span class="s16">"\t SETUP2 - slider 2: %\n"</span>.postf(x) });</p>
+<p class="p19">g.add(\topButton, 51, { <span class="s5">|... x|</span> <span class="s16">"\t SETUP2 - topButton 51: %\n"</span>.postf(x) });</p>
+<p class="p19">g.add(\topButton, 52, { <span class="s5">|... x|</span> <span class="s16">"\t SETUP2 - topButton 51: %\n"</span>.postf(x) });</p>
+<p class="p3"><br></p>
+<p class="p19">g.store(<span class="s13">\SETUP2</span>);</p>
+<p class="p19">)</p>
+<p class="p3"><br></p>
+<p class="p28">// .. try what that setup does ... then switch back to setup1:</p>
+<p class="p3"><br></p>
+<p class="p19">g.setup(<span class="s13">\setup1</span>);</p>
+<p class="p3"><span class="Apple-tab-span">	</span></p>
+<p class="p19"><span class="Apple-tab-span">	</span>// the current setup is backed up:</p>
+<p class="p19">g.setup(<span class="s13">\backup</span>);</p>
+<p class="p3"><br></p>
+<p class="p3"><span class="Apple-tab-span">	</span></p>
+<p class="p3"><br></p>
+<p class="p28"><span class="s9">(<span class="Apple-tab-span">	</span></span>// use globalActions to switch between setups:<span class="Apple-converted-space"> </span></p>
+<p class="p28">g.usesNoteOn = true;</p>
+<p class="p19">g.addGlobal(<span class="s13">\topNoteOn</span>, 49, { "switch to phasemod.".postln; <span class="s5">Ndef</span>(<span class="s13">\mantaPM</span>).play; <span class="s5">Ndef</span>(<span class="s13">\mantaHarm</span>).end(2); });</p>
+<p class="p19">g.addGlobal(<span class="s13">\topNoteOn</span>, 50, { "switch to mantaharm.".postln; <span class="s5">Ndef</span>(<span class="s13">\mantaPM</span>).end(2); <span class="s5">Ndef</span>(<span class="s13">\mantaHarm</span>).play; });</p>
+<p class="p19">g.addGlobal(<span class="s13">\topNoteOn</span>, 51, {<span class="Apple-converted-space">  </span>"switch to <span class="s18">setup1</span>.".postln; <span class="s5">Ndef</span>(<span class="s13">\mantaPM</span>).end(2); <span class="s5">Ndef</span>(<span class="s13">\mantaHarm</span>).end(2); g.setup(<span class="s13">\setup1</span>) });</p>
+<p class="p19">g.addGlobal(<span class="s13">\topNoteOn</span>, 52, {<span class="Apple-converted-space">  </span>"switch to <span class="s18">SETUP2</span>.".postln; <span class="s5">Ndef</span>(<span class="s13">\mantaPM</span>).end(2); <span class="s5">Ndef</span>(<span class="s13">\mantaHarm</span>).end(2); g.setup(<span class="s13">\SETUP2</span>) });</p>
+<p class="p19">)</p>
+<p class="p3"><br></p>
+<p class="p1"><span class="s11"><span class="Apple-tab-span">	</span></span><b>IMPORTANT NOTE:</b></p>
+<p class="p1"><b><span class="Apple-tab-span">	</span>If you use buses, and want to play back recorded Manta actions while playing new ones live,<span class="Apple-converted-space"> </span></b></p>
+<p class="p1"><b><span class="Apple-tab-span">	</span>the buses of the Manta object will get the newly incoming values.<span class="Apple-converted-space"> </span></b></p>
+<p class="p1"><b><span class="Apple-tab-span">	</span>So for this usage, make your own buses for the patch/setup.</b></p>
+<p class="p1"><b><span class="Apple-tab-span">	</span></b>[example to follow]</p>
+<p class="p3"><br></p>
+<p class="p19"><span class="s5">Manta</span>.setups;</p>
+<p class="p8">Manta.setups.keys;</p>
+<p class="p5"><br></p>
+<p class="p6"><b><span class="Apple-tab-span">	</span>Questions, discussion, notes, to do</b></p>
+<p class="p5"><br></p>
+<p class="p8">* how/where to do flexible remapping of keyboard/pad layouts (accordion styles etc etc)?<span class="Apple-converted-space"> </span></p>
+<p class="p5"><br></p>
+<p class="p8">* try using CtLoop to do flexible gesture recording<span class="Apple-converted-space"> </span></p>
+<p class="p8"><span class="Apple-tab-span">	</span>- maybe support several layers;<span class="Apple-converted-space"> </span></p>
+<p class="p8"><span class="Apple-tab-span">	</span>record one layer for one instrument, loop it,</p>
+<p class="p8"><span class="Apple-tab-span">	</span>add layer 2, etc<span class="Apple-converted-space"> </span></p>
+<p class="p5"><br></p>
+</body>
+</html>

Added: Manta/Manta.sc
===================================================================
--- Manta/Manta.sc	                        (rev 0)
+++ Manta/Manta.sc	2009-12-18 13:29:15 UTC (rev 1296)
@@ -0,0 +1,422 @@
+	// This version of the Manta class implements the scaling and noteOn logic suggested by AdC in SC3.  
+	// It works with MantaCocoa 0.97 and 0.97.1, with unscaled data, centroid, 
+	// noteOn, velocity and centroid turned off,
+	// so that the Manta class does all the logic for these! 
+	
+	// this may revert to Manta as before when MantaCocoa does these directly.
+	
+Manta { 
+
+	classvar <>verbose = false; 
+	classvar <>appPath = "/Applications/manta*/MantaCocoa.app";
+	classvar <setups;
+	classvar <messageNames;
+	
+	var <addr, <responders, <globalActions, <actions, <multi, <indiv;
+	var <values, <buses;
+	var <usesTops, <numPads, <topNames;
+	var <listenAddr, <canSetLEDs = false;
+	var <padMaxima, <sliderMaxima, maxPath;
+	
+	var <>normed = true;
+	var <>usesNoteOn = true, <usesCentroid = false;
+	var <noteOnCounts,  <lastNValues, <resendTime; 
+	
+	var <centroid = #[0,0,0], <>centroidNeedsUpdate = true; 
+	var <centroidIndices, <centroidSkip;
+	
+	*initClass { 
+		messageNames = #[
+			'/manta/slider', '/manta/value', 
+			'/manta/noteOn', '/manta/noteOff', '/manta/velocityValue', 
+			'/manta/centroid'];
+			
+		setups = (); 
+	}
+	
+	*start { unixCmd("open" + appPath) }
+
+		// preferences get corrupted quite often, 
+		// then one gets an error with index: -1. 
+	*killPrefs { unixCmd("rm" + "~/Library/Application\\ Support/MantaCocoa/lastSettings.xml") }
+
+		// addr can be used for identifying multiple Mantas
+	*new { |addr, addResps = true, makeBuses = true, server, normed = true, 
+		usesTops = true, usesNoteOn = false, usesCentroid = false| 
+		
+		^super.newCopyArgs(addr).normed_(normed).usesNoteOn_(usesNoteOn)
+			.init(addResps, makeBuses, server, usesTops);
+	}
+	
+		// cleanup if multiple resps were added by accident
+	*removeAllResps { 
+		OSCresponder.all.copy.do { |x| 
+			if (messageNames.includes(x.cmdName)) { x.remove; "removed resp: %\n".postf(x.cmdName) } 
+		}
+	}
+
+	defaultPadMaxima { 
+		// measured with AdC's Manta - substitute your own.
+		^[ 	1, 
+			177, 184, 187, 188, 192, 192, 183, 180, 
+			188, 193, 197, 200, 201, 201, 193, 188, 
+			192, 197, 202, 205, 205, 204, 199, 191, 
+			201, 207, 210, 215, 215, 214, 209, 200, 
+			204, 210, 215, 219, 212, 218, 212, 203, 
+			211, 215, 221, 226, 222, 227, 221, 213, 
+			
+			219, 199, 199, 206 
+		];
+	}
+
+	defaultSliderMaxima { 
+		// my sliders go fram ca 5 minimum to ca 4090 max. 
+		// the top and bottom values can't be reached reproducibly, 
+		// so better cut them off a little earlier.
+		
+		// so these limits are hardcoded in the slider responder! 
+		// ^[ 1, 4096 - 10, 4096 - 10];
+	}
+	
+//		// later: measure, write, read manta data ... 
+//	measureMaxima { |clear = true, plot = true|
+//			// if clear, set maxima to 1!52, 1!2; 
+//			
+//			// if (plot) { make a plot view that is updated };
+//		this.addResps;
+//			// set their actions to overwrite old maxima
+//		this;
+//	}
+//	
+//	writeMaxima { |path| }
+//	
+//	readMaxima { |path| path = path ? maxPath; }
+	
+	init { |addResps, makeBuses, server, useTops| 
+	
+		usesTops = useTops; 
+		numPads = if (useTops, 48, 52); 
+
+		// safe against re-adding multiple responders
+		this.removeResps; 
+		
+		maxPath = Platform.userAppSupportDir +/+ "MantaMaxima.scd";
+		
+		padMaxima = this.defaultPadMaxima; 
+		sliderMaxima = this.defaultSliderMaxima; 
+		
+		responders = (
+			sliderResp: OSCresponderNode(addr, '/manta/slider', { |t, r, msg| 
+				var key = msg[1]; 
+				var val = msg[3]; 
+						// normal values hardcoded for efficiency
+				if (normed) { val = (val - 10 / 4070).clip(0, 1) };
+				this.respond(\slider, key, val) 
+			}),
+			padResp: OSCresponderNode(addr, '/manta/value', { |t, r, msg| 
+				var key = msg[1]; 
+				var val = msg[3];
+					// maxvalues vary quite a bit for the different pads
+				if (normed) { val = val / padMaxima[key] };
+				this.respond(\pad, key, val);
+			})
+				// off for the time being, until noteOnLogic and scaling are done in MantaCocoa
+//			,
+//			noteOnResp: OSCresponderNode(addr, '/manta/noteOn', { |t, r, msg| this.respond(\noteOn, msg[1], msg[3]) }),
+//			noteOffResp: OSCresponderNode(addr, '/manta/noteOff', { |t, r, msg| this.respond(\noteOff, msg[1], msg[3]) }),
+//			velocityResp: OSCresponderNode(addr, '/manta/velocityValue', { |t, r, msg| this.respond(\velocity, msg[1], msg[3]) }),
+//		
+//			centroidResp: OSCresponderNode(addr, '/manta/centroid', { |t, r, msg| this.respond(\centroid, \multiOnly, msg[1..3]) })
+		);
+		
+		globalActions = (
+			multi: (),
+			indiv: (
+				slider: (),
+				pad: (),
+				noteOn: (),
+				noteOff: (),
+				velocity: (),
+				centroid: ()
+			)
+		); 
+		
+		multi = ();
+
+		indiv = (
+			slider: (),
+			pad: (),
+			noteOn: (),
+			noteOff: (),
+			velocity: (), 
+			centroid: ()	// just a dummy to save one check for nil - centroid should not do any indiv actions.
+		);
+
+		actions = (multi: multi, indiv: indiv); 
+
+		values = (slider: 0!2, centroid: 0!3, pad: 0 ! numPads, note: 0 ! numPads, velocity: 0 ! numPads); 
+
+		if (usesTops) { 
+			topNames = (pad: \topButton, velocity: \topVelocity, noteOn: \topNoteOn, noteOff: \topNoteOff); 
+			indiv.putAll((topButton: (), topVelocity: (), topNoteOn: (), topNoteOff: ()));
+			values.putAll((topButton: 0!4, topVelocity: 0!4, topNote: 0!4));
+			
+			globalActions[\indiv].putAll((topButton: (), topVelocity: (), topNoteOn: (), topNoteOff: ()))
+		};
+		
+		if (addResps) { this.addResps };
+		if (makeBuses) { this.makeBuses(server) };
+		
+		noteOnCounts = 0 ! 53; 
+		lastNValues = [0,0,0] ! 53; 
+		
+		this.prepCentroid; 
+		if (usesCentroid) { centroidSkip.start; }; 
+		
+	}
+	
+	prepCentroid { 
+		centroidIndices = (1..6).collect { |i| (1..8).collect ([i, _]) }.flatten(1);
+		centroidSkip = centroidSkip ?? { 
+			SkipJack({ 
+				// "cent task.".postln; 
+				if (centroidNeedsUpdate, { this.calcCentroid; }) 
+			}, 0.008, false, 'MantaCentroid', 
+			autostart: false)
+		};
+	}
+	
+	calcCentroid { 
+		var weightSum = values[\pad].sum; 
+		var xy = [0,0]; 
+		
+		if (weightSum > 0) { 
+			xy = centroidIndices.sum { |pair, i| (pair * values[\pad][i]) } / weightSum; 
+			
+		} { 
+			// remember last xy, - or comment this out to get [0,0,0]
+			xy = xy ? centroid.keep(2);
+		};
+		centroidNeedsUpdate = false;
+		centroid = xy ++ (weightSum); 
+		if (verbose) { "			centroid: (x, y, weight) = %\n".postf(centroid) };
+		this.respond(\centroid, \multiOnly, centroid);
+	}
+	
+	usesCentroid_ { |flag| 
+		usesCentroid = flag;
+		if (flag) { centroidSkip.start } {  centroidSkip.stop };
+	}
+	
+	makeBuses { |server| 
+	
+		buses = (
+			pad: Bus.control(server, numPads), 
+			note: Bus.control(server, numPads),
+			slider: Bus.control(server, 2), 
+			velocity: Bus.control(server, numPads), 
+			centroid: Bus.control(server, 3)
+		);
+	
+		if (usesTops) { 
+			buses.putAll((
+				topButton: Bus.control(server, 4), 
+				topVelocity: Bus.control(server, 4),
+				topNote: Bus.control(server, 4)
+			))
+		};
+	}
+	
+		// add just some responders if needed - by default, add all.
+	addResps { |keys| 
+		if (keys.notNil) { keys.do { |key| responders[key].add } } { responders.do(_.add) };
+	}
+
+	removeResps { |keys|
+		if (keys.notNil) { keys.do { |key| responders[key].remove } } { responders.do(_.remove) };
+	}
+
+	free { 
+		this.removeResps;
+		buses.do(_.free);
+		try { listenAddr.disconnect };
+	}
+	
+	repeatPadFunc { |name, key, val, dt = 0.009| 
+		fork { 
+			var count = noteOnCounts[key]; 
+			dt.wait; 
+			
+			if (count == noteOnCounts[key]) { 
+			//	"noteOn - resending to replace repeated pad value!".postln; 
+				this.respond(name, key, val) 
+			}; 
+		};
+	}
+	
+	noteOnLogic { |name, key, val| 
+		var velocity = -1; 
+		var noteOnCount = noteOnCounts[key]; 
+		var lastN = lastNValues[key]; 
+		
+		if (val == 0) { // noteOff logic first: 
+		//	"noteOff: key % val %\n\n\n".postf(key, val);
+			lastNValues[key] = [0,0,0];
+			noteOnCounts[key] = 0;
+			this.respond(\noteOff, key, 0);
+			
+		} { 	
+			if (noteOnCount < 3) { 
+				lastNValues[key].put(noteOnCount, val);
+				
+				if (noteOnCount < 2) { this.repeatPadFunc(name, key, val) };
+				
+				if (noteOnCount == 2) { 
+					// ok, enough values for noteOn + velocity! 
+	
+					velocity = lastNValues[key].maxItem; 
+					this.respond(\noteOn, key, velocity);
+					 
+//					"\n **** NOTEON: key %, normVel % last 3 values %\n" 
+//						.postf(key, 
+//							lastNValues[key].maxItem, 
+//							lastNValues[key]);
+				};
+			}; 
+			
+			noteOnCounts[key] = noteOnCount + 1;
+		};
+		
+//		" post noteOnLogic: key %, val %, count %, lastN %, vel % \n---\n\n".postf(
+//			key, val.round(0.0001), 
+//			noteOnCounts[key], 
+//			lastNValues[key].round(0.0001), 
+//			velocity
+//		);
+
+	}
+	
+	respond { |name, key, val| 
+
+			// noteOn, noteOff logic only for pads:  
+		if (name == \pad and: usesNoteOn, { this.noteOnLogic(name, key, val) });
+		if (name == \pad and: usesCentroid, { centroidNeedsUpdate = true });
+				
+			// do redirection for topButtons here: 
+		if (usesTops and: { key > numPads }) { name = topNames[name] ? name }; 
+		
+		if (verbose) { "Manta %, % % \n".postf(name, key, val) };
+		
+			// remember current state
+		this.keepVals(name, key, val); 
+		
+			// do globalActions first
+		globalActions[\multi][name].value(key, val); 
+			// then indiv actions only for pad, slider etc
+		globalActions[\indiv][name][key].value(val); // centroid does nothing
+		
+			// then multi actions
+		multi[name].value(key, val); 		
+			// indiv only for pad, slider etc
+		indiv[name][key].value(val);
+	}
+	
+	keepVals { |name, index, val| 
+		var offset; 
+		
+		if (name == \centroid) { 
+			values[name] = val; 
+			if (buses.notNil) { buses[\centroid].setn(val) };
+			^this 
+		}; 
+
+		offset = if (#[\topButton, \topVelocity, \topNoteOn, \topNoteOff].any(_ == name), numPads + 1, 1); 
+		index = index - offset; 
+		name.switch( 
+			\noteOff, { name = \note; val = 0; },
+			\topNoteOff, { name = \topNote; val = 0; },
+			\noteOn, { 
+				values[\velocity].put(index, val); 
+				if (buses.notNil) { buses[\velocity].setAt(index, val) };
+				name = \note; val = 1; 
+			},
+			\topNoteOn, { 
+				values[\topVelocity].put(index, val); 
+				if (buses.notNil) { buses[\topVelocity].setAt(index, val) };
+				name = \topNote; val = 1; 
+			}
+		);
+
+		values[name].put(index, val); 
+		if (buses.notNil) { buses[name].setAt(index, val) };
+	}
+
+
+
+	// adding/removing functions on different levels: 
+		
+		// global multi functions: 
+	addMultiGlobal { |type, func| globalActions.multi.put(type, func) }
+	removeMultiGlobal { |type| type.asArray.do { |key| globalActions.multi.put(key, nil) } }
+	
+		// global functions for individual pads, sliders, events.
+	addGlobal { |type, key, func| globalActions.indiv[type].put(key, func) }
+	removeGlobal { |type, key| key.asArray.do { |key| globalActions.indiv[type].put(key, nil) } }
+
+		// multi functions: 
+	addMulti { |type, func| multi.put(type, func) }
+	removeMulti { |type| type.asArray.do (multi.put(_, nil)) }
+
+		// individual functions per buttons and slider
+	add { |type, key, func| indiv[type].put(key, func) }
+	remove { |type, key| indiv[type].put(key, nil) }
+
+		//add functionality to specific setups
+		// multi functions: 
+	addMultiToSetup { |setupName, type, func| setups[setupName].multi.put(type, func) }
+	removeMultiFromSetup { |setupName, type| var setup = setups[setupName]; type.asArray.do (multi.put(_, nil)) }
+
+		// individual funcs for pads, sliders etc
+	addToSetup {\xCA|setupName, type, key, func|\xCAsetups[setupName][\indiv][type].put(key, func) }
+	removeFromSetup {\xCA|setupName, type, key|\xCAsetups[setupName][\indiv][type].put(key,\xCAnil) }
+
+		// store setups - 
+	clearDicts { 
+		multi = (); 
+		indiv.keysDo { |k| indiv[k] = () };
+		actions.put(\multi, multi, \indiv, indiv);
+	}
+
+	store { |name| 
+		name = name.asSymbol; 
+		"Manta: storing current setup as %.\n".postf(name.asCompileString);
+		setups.put(name, actions.deepCopy);
+	}
+
+	setup { |name| 
+		var setup = setups.at(name.asSymbol); 
+		if (setup.isNil) { warn("Manta - no setup named %! Keeping current setup.\n".format(name.asSymbol)); ^this };
+		
+		if (name != \backup) { this.store(\backup) }; 
+		
+		"Manta: switching to setup %.\n".postf(name.asCompileString);
+		actions = setup.deepCopy;
+		multi = setup[\multi];
+		indiv = setup[\indiv]; 
+	}	
+
+		// set LEDs
+	makeListenAddr { |ip = "127.0.0.1", port = 8000|
+		listenAddr = NetAddr(ip, port); 
+	}
+			
+	canSetLEDs_ { |flag = true| 
+		if (listenAddr.isNil) { this.makeListenAddr };
+		canSetLEDs = flag; 
+		listenAddr.sendMsg("/manta/ledControlEnabled", flag.binaryValue);
+	}
+	setLEDs { |val = 1 ... indices| 
+		listenAddr.sendMsg("/manta/leds", indices.size, *(indices ++ val));
+	}
+}
+

Added: Manta/MantaNormal.html
===================================================================
--- Manta/MantaNormal.html	                        (rev 0)
+++ Manta/MantaNormal.html	2009-12-18 13:29:15 UTC (rev 1296)
@@ -0,0 +1,67 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd";>
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<meta http-equiv="Content-Style-Type" content="text/css">
+<title></title>
+<meta name="Generator" content="Cocoa HTML Writer">
+<meta name="CocoaVersion" content="1038.25">
+<style type="text/css">
+p.p1 {margin: 0.0px 0.0px 0.0px 0.0px; font: 18.0px Helvetica}
+p.p2 {margin: 0.0px 0.0px 0.0px 0.0px; font: 12.0px Helvetica; min-height: 14.0px}
+p.p3 {margin: 0.0px 0.0px 0.0px 0.0px; font: 12.0px Helvetica}
+p.p4 {margin: 0.0px 0.0px 0.0px 0.0px; font: 9.0px Monaco}
+p.p5 {margin: 0.0px 0.0px 0.0px 0.0px; font: 9.0px Monaco; min-height: 12.0px}
+p.p6 {margin: 0.0px 0.0px 0.0px 0.0px; font: 9.0px Monaco; color: #cd0b0b}
+p.p7 {margin: 0.0px 0.0px 0.0px 0.0px; font: 9.0px Monaco; color: #2024c7}
+span.s1 {color: #2024c7}
+span.s2 {color: #008417}
+span.s3 {color: #000000}
+span.Apple-tab-span {white-space:pre}
+</style>
+</head>
+<body>
+<p class="p1"><b>Manta - normalizing</b></p>
+<p class="p2"><br></p>
+<p class="p3">You can measure your own max controller values easily with this patch:</p>
+<p class="p2"><br></p>
+<p class="p4">(</p>
+<p class="p4">q = q ? ();</p>
+<p class="p4">q.maxima = 1 ! 53;</p>
+<p class="p4">o.remove;<span class="Apple-converted-space"> </span></p>
+<p class="p4">o = <span class="s1">OSCresponderNode</span>(<span class="s1">nil</span>, <span class="s2">'/manta/value'</span>, { <span class="s1">|t, r, msg|</span> msg.postln }).add;</p>
+<p class="p4">o.action = { <span class="s1">|t, r, msg|</span> <span class="s1">var</span> key = msg[1], val = msg[3];<span class="Apple-converted-space"> </span></p>
+<p class="p4"><span class="Apple-tab-span">	</span>[key, val].postln; q[<span class="s2">\maxima</span>].put(key, q[<span class="s2">\maxima</span>][key].max(val))<span class="Apple-converted-space"> </span></p>
+<p class="p4">};</p>
+<p class="p4">)</p>
+<p class="p5"><br></p>
+<p class="p6">// now measure maxima: ... touch every pad until it has maxed out ...<span class="Apple-converted-space"> </span></p>
+<p class="p5"><br></p>
+<p class="p4">// then, read your maxima:<span class="Apple-converted-space"> </span></p>
+<p class="p4">q.maxima.postln;<span class="Apple-converted-space"> </span></p>
+<p class="p5"><br></p>
+<p class="p6">// for my manta, the values are:<span class="Apple-converted-space"> </span></p>
+<p class="p4">q.maxima = [ 1, 177, 184, 187, 188, 192, 192, 183, 180, 188, 193, 197, 200, 201, 201, 193, 188, 192, 197, 202, 205, 205, 204, 199, 191, 201, 207, 210, 215, 215, 214, 209, 200, 204, 210, 215, 219, 212, 218, 212, 203, 211, 215, 221, 226, 222, 227, 221, 213, 219, 199, 199, 206 ];</p>
+<p class="p2"><br></p>
+<p class="p3">then, add your own defaultPadMaxima as an extension:<span class="Apple-converted-space"> </span></p>
+<p class="p2"><br></p>
+<p class="p4">// --- file extManta2.sc</p>
+<p class="p5"><br></p>
+<p class="p7"><span class="s3">+ </span>Manta2<span class="s3"> {<span class="Apple-converted-space"> </span></span></p>
+<p class="p4"><span class="Apple-tab-span">	</span>defaultPadMaxima {<span class="Apple-converted-space"> </span></p>
+<p class="p6"><span class="s3"><span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span></span>// measured with AdC' Manta.</p>
+<p class="p4"><span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span>^[ 1,<span class="Apple-converted-space"> </span></p>
+<p class="p4"><span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span>177, 184, 187, 188, 192, 192, 183, 180,<span class="Apple-converted-space"> </span></p>
+<p class="p4"><span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span>188, 193, 197, 200, 201, 201, 193, 188,<span class="Apple-converted-space"> </span></p>
+<p class="p4"><span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span>192, 197, 202, 205, 205, 204, 199, 191,<span class="Apple-converted-space"> </span></p>
+<p class="p4"><span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span>201, 207, 210, 215, 215, 214, 209, 200,<span class="Apple-converted-space"> </span></p>
+<p class="p4"><span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span>204, 210, 215, 219, 212, 218, 212, 203,<span class="Apple-converted-space"> </span></p>
+<p class="p4"><span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span>211, 215, 221, 226, 222, 227, 221, 213,<span class="Apple-converted-space"> </span></p>
+<p class="p5"><span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span></p>
+<p class="p4"><span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span>219, 199, 199, 206<span class="Apple-converted-space"> </span></p>
+<p class="p4"><span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span>];</p>
+<p class="p4"><span class="Apple-tab-span">	</span>}</p>
+<p class="p4">}</p>
+<p class="p4">// ---</p>
+</body>
+</html>


This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.

_______________________________________________
sc-dev mailing list

info (subscription, etc.): http://www.beast.bham.ac.uk/research/sc_mailing_lists.shtml
archive: https://listarc.bham.ac.uk/marchives/sc-dev/
search: https://listarc.bham.ac.uk/lists/sc-dev/search/