[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 -> 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/