// =====================================================================

// GeneralHIDSpec

// =====================================================================


GeneralHIDSpec is a class to create access by names to slots of a GeneralHIDDevice.



// Look for the devices that are attached:

GeneralHID.buildDeviceList;


// Get the list of devices:

d = GeneralHID.deviceList;


// Check which devices have been found:

GeneralHID.postDevices;


// Pick the 6th device and open it and create an instance of it:

a = GeneralHID.open( d[5] )


// Get info on the device to see if it is the right one:

a.info;


// Start eventloop:

GeneralHID.startEventLoop


// Get the capabilities of the device in a readable format:

a.caps;


// See if data is coming in:

a.debug_( true );


// make an instance of a spec:

b = GeneralHIDSpec.new( a );


( // defining the spec.

// trick: look at the debug output, by using each input thing on the gamepad and use the first two numbers posted as indexes

// example output of debug: [ 3, 2, 0.49803921568627, nil ]

// as a result of moving the y-axis of the right joystick.

// so we create this slot:

b.add( \ry, [3,2] );


// and so on...

b.add( \lx, [3,0] );

b.add( \ly, [3,1] );

b.add( \rx, [3,5] );


b.add( \b1, [1,288] );

b.add( \b2, [1,289] );

b.add( \b3, [1,290] );

b.add( \b4, [1,291] );

b.add( \b5, [1,292] );

b.add( \b6, [1,293] );

b.add( \b7, [1,294] );

b.add( \b8, [1,295] );


b.add( \b5, [1,292] );

b.add( \b6, [1,293] );

b.add( \b7, [1,294] );

b.add( \b8, [1,295] );


b.add( \cx, [3,16] );

b.add( \cy, [3,17] );


b.add( \bl, [1,296] );

b.add( \br, [1,297] );


b.add( \bj1, [1,298] );

b.add( \bj2, [1,299] );

)


// Stop it:

a.debug_( false );


// look at the map

b.map.postcs;


// store it with a name:

b.save( "Impact" );


// find matching, previously stored specs:

c = b.find;


// load from file:

b.fromFile( "Impact" );


// the loading and storing mechanism works across SC sessions, as they are stored to file, and GeneralHIDSpec loads the device info of all stored specs at startup of the language. 


/// A GeneralHIDDevice automatically has a spec, so we can access it even faster:


a.spec;


// there are shortcuts for the methods:

add( key, slotids ) // define a key to a slot

at( key ) // get the slot

value( key ) // get the value

value_( key, value ) // set the value 

action_( key, action ) // set the action

bus( key ) // get the bus

createBus( key, server ) // create the bus

freeBus( key ) // free the bus

createAllBuses( server ) // create buses for all defined slots

freeAllBuses // free all buses


// to find and set a spec:

a.findSpec;

a.setSpec( "Impact" );


// post the mapping

a.spec.map


// examples of use:

s = Server.local.boot;


// create a bus

b.createBus( \rx, s );

b.createBus( \b1, s );



// simple example:

(

SynthDef( \hidbus_help, { |out=0,amp=0.5|

Out.ar( out, SinOsc.ar( 300, 0, 0.2*(amp-0.5) ) );

}).load( s );

)


x = Synth.new( \hidbus_help );

x.map( \amp, b.at( \rx ).bus );

x.free;


( // a nicer version:

SynthDef( \hidbus_help, { |out=0,amp=0.5,amp2=0|

Out.ar( out, SinOsc.ar( 300, 0, 0.2*(amp-0.5).lag( 0.1 ) * amp2.lag(0.01,0.99)

) );

}).load( s );

)


x = Synth.new( \hidbus_help );

x.map( \amp, b.at( \rx ).bus );

x.map( \amp2, b.at( \b1 ).bus );

x.free;


( // an even nicer version:

SynthDef( \hidbus_help, { |out=0,freqadd=0,amp=0,fmmul=200|

Out.ar( out, SinOsc.ar( 300 + (freqadd.lag(0.2,1)*fmmul), 0, 0.2*amp.lag

(0.01,0.99) ) );

}).load( s );

)



// if you want to have buses for all the things defined in the spec, you can use:

b.createAllBuses( s );


(

x = [ Synth.new( \hidbus_help ), Synth.new( \hidbus_help ) ];

x[0].map( \freqadd, b.bus( \ly ) );

x[0].map( \amp, b.bus( \b6 ) );


x[1].map( \freqadd, b.bus( \lx ) );

x[1].map( \amp, b.bus( \b7 ) );


y = [ Synth.new( \hidbus_help, [\fmmul,400] ), Synth.new( \hidbus_help, [\fmmul,400] ) ];

y[0].map( \freqadd, b.bus( \ry ) );

y[0].map( \amp, b.bus( \b5 ) );


y[1].map( \freqadd, b.bus( \rx ) );

y[1].map( \amp, b.bus( \b6 ) );

)


// see what's going on on the server

s.queryAllNodes( true );


// free the synths

y.do{ |it| it.free; }; x.do{ |it| it.free; }; 




// To free all buses

b.freeAllBuses;


// Close the device after use:


a.close;


GeneralHID.stopEventLoop