More interaction - sound design (day 4 at APO33)
With the basic mapping from the pulling on the stretch sensors, I find that I need something more to detect the micro-movements that are happening, to create more movement within the wavetable sound. As I also have acceloremeters available on the sensor nodes - I use these; I use a mean value of the acceleration, and map this to another force that acts on the nodes in the physical model. The mapping is done in such a way, that it slowly rises to a maximum amount, and then recedes again: so little movement can have much impact up to a certain level - but then the influence will be gone again if movement gets too intense. To do this, I use the class SegWarp from the wslib quark.
The deviation in position of the nodes from their mean position is then used to detune the wavetable synthesis.
Mapping from acceleration to forces on the nodes
~accDevSpec = SegWarp( Env([0,1,0], [0.005,0.03], [-5,-7] ) );
~travForceMap = [1e-3, 1.0, \exponential].asSpec;
// radial forces go to (7,9), (4,5), (1,2)
// so traversal forces should go somewhere else
x.addExpected( 151, \travForce1, 3 );
x.addExpected( 152, \travForce2, 3 );
x.addExpected( 153, \travForce3, 3 );
x.nodes[141].action = { |data| x.setData(151, ( data.sign * ~travForceMap.map( ~accDevSpec.map( data.abs ) ) ) ) };
x.nodes[142].action = { |data| x.setData(152, ( data.sign * ~travForceMap.map( ~accDevSpec.map( data.abs ) ) ) ) };
x.nodes[143].action = { |data| x.setData(153, ( data.sign * ~travForceMap.map( ~accDevSpec.map( data.abs ) ) ) ) };
x.at( \travForce1 ).slots[0].action = { |data| ~physics.setParticleTraversalForce( 8, 1, data ); };
x.at( \travForce1 ).slots[1].action = { |data| ~physics.setParticleTraversalForce( 9, 8, data ); };
x.at( \travForce1 ).slots[2].action = { |data| ~physics.setParticleTraversalForce( 7, 5, data ); };
x.at( \travForce2 ).slots[0].action = { |data| ~physics.setParticleTraversalForce( 4, 0, data ); };
x.at( \travForce2 ).slots[1].action = { |data| ~physics.setParticleTraversalForce( 5, 7, data ); };
x.at( \travForce2 ).slots[2].action = { |data| ~physics.setParticleTraversalForce( 6, 4, data ) };
x.at( \travForce3 ).slots[0].action = { |data| ~physics.setParticleTraversalForce( 0, 9, data ); };
x.at( \travForce3 ).slots[1].action = { |data| ~physics.setParticleTraversalForce( 1, 6, data ); };
x.at( \travForce3 ).slots[2].action = { |data| ~physics.setParticleTraversalForce( 2, 3, data ); };
Mapping from deviation to detuning frequencies
~dposFSpec = [0.01,1,\exponential].asSpec;
~dfreqSpec = [0.001,0.35,\exponential].asSpec;
// at each update:
10.do{ |jt, j|
var dpos = 10.collect{ |it|
(~physics.getParticleParameter( jt, it, \position ) - ~restParticlePositions[jt][it]).collect{ |a| a*a }.sum;
};
~wavetables[j].setn( \dfreq, dpos.specMap( ~dposFSpec, ~dfreqSpec ) );
};
Adjusted wavetable synth
SynthDef( \wavetable, {
var bufSelect = Linen.kr( \gate.kr(1), \fade.kr(0.25), 1, \fade.kr );
var signal = VOsc.ar(
\bufnum.kr(0) + bufSelect,
\freq.kr(500).lag( \flag.kr(5) ) * (1 + \dfreq.kr( [0,0,0,0,0 ,0,0,0,0,0] ).lag( \dlag.kr(0.05) ) ),
\phase.kr(0)
);
Out.ar( \out.kr(0), Pan2.ar( signal, \pos.kr(0), \amp.kr(0.1) ) );
}).add;