Tuesday, August 12, 2014

Gait Analysis as mapping strategy for Argentine tango.

After I deployed an initial prototype, it occurs to me that actual knowledge of steps (while, yes, walking) would be helpful in creating my mapping strategies (translation of dancer motion to music).

Right now, I am looking at RRACE:
http://www.researchgate.net/publication/257307889_RRACE_Robust_realtime_algorithm_for_cadence_estimation

It estimates cadence, which will be helpful. It introduced me to the Lomb normalized periodogram. It is like the FFT, but for non-uniformly sampled data.

I am also measuring stationary moments in each leg...Using these two tools, I hope to extrapolate with reasonable accuracy when people are stepping. I can then use the distance between steps (literal distance using dead-reckoning, using the algorithm from xIO technologies)... or simply the time between steps...  distance might be more interesting?)

Friday, August 1, 2014

I am back. More coding. More tango (not pictured).

Sooooo...

Supercollider Code to Compress a Control Signal (or do any ar - only UGEN thing to it) and then Forward it to Osculator which turns it into a MIDI ctrl signal to Change something in Ableton Live.

I. Kid. You. Not.

And yet, it was relatively simple to implement, and once I remembered that magic "SendReply" call I was able to send the modified signal on to Ableton. I know I know, I should just get Max4Live, but look, that costs money, and I'm spending all my money on sensors and stuff and also, I'm just... so much faster in other paradigms. I actually have a year's subscription to regular MAX/MSP, in case I really need it for this project, etc.

I hesitated using Ableton Live, but in terms of the project, I think it fits, and it lets me go faster. Tango is a popular song, and the whole Live paradigm isn't forcing me into a song structure that shouldn't already be there.... and I will need to loop and etc. At the very least, it is super valuable for prototyping.

//add this synth def
(
SynthDef('sendShimmerCompress', { 
| whichControlBus = 0, thresh1 = 0.8, makeUpAmp = 1, sID=1908 |

var cSig, kout, sigOut = In.kr(whichControlBus); 

cSig = K2A.ar(sigOut); 

cSig = Compander.ar(cSig, cSig,
thresh: thresh1,
slopeBelow: 1,
slopeAbove: 0.1,
clampTime: 0.01,
relaxTime: 0.01);

kout = A2K.kr(cSig * makeUpAmp); 

SendReply.kr(Impulse.kr(50), 'compressShimmer', [ kout ], sID);
}).add;

)

//call it, make sure to add your own sID for each different signal
v = Synth.new('sendShimmerCompress', [\sID, 2345]); 

//add the OSCResponder to forward the call on to wherever.
(
g.remove; 
g = OSCresponderNode(nil, '/compressShimmer', { |t, r, msg| 
var sID; 
var shimmer1X = 2345; 
var oscM; 
sID = msg[2]; //which shimmer & sensor value is it?
if(sID == shimmer1X, {    
oscM = "/1/fader1"
});

c = NetAddr.new("127.0.0.1", 8000); // create the NetAddr
c.sendMsg(oscM, msg[3]);

 }).add;
 )