User Tools

Site Tools


hid_device_api

Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Both sides previous revision Previous revision
hid_device_api [2018/12/27 22:55]
simranjit94
hid_device_api [2018/12/28 03:05] (current)
be.ing old revision restored (2018/12/27 10:46)
Line 1: Line 1:
-**Xcelance Web Solutions- Advanced Marketing Management**+====== HID Device API ======
  
-In this fast-paced world, news now travels at a very high speed and due to which maintaining a positive image of a business is more important than ever - and moreover complicated ​to do. This also brings confront for all the features ​of advanced marketing managementIt is vital to get familiar with the concept and meaning of the term used in the business world. Moreover, it is also crucial to recognize how and when to apply this particular term. Best seo company in Chandigarh+An API to allow mapping/​scripting ​of HID devices in similar manner ​to MIDI devices, hiding ugly details ​of HID protocol as much as possible.
  
-When you dig deep to know about marketing management, the most important thing to know before it is the concept ​of marketing In simple words, marketing ​is to take care of customer relations, particularly those that are beneficialMajority of the people think that marketing is only limited to advertising ​and selling but the fact is that it is all about gratifying the wants of the customers.+Development ​of this API for Mixxx 1.11 is done by Hile in [[https://​code.launchpad.net/​~hile/​mixxx/​hidscripts|hidscripts]] branch. This branch will modify files only in the res/​controllers/​ directory ​and the files mostly are new scripts, not conflicting with existing files. 
 +===== Summary and Rationale =====
  
-Here are a few things ​to know about advance marketing management before you take any further step:+When data is //sent// from a hid controller multiple controls ​are aggregated into //packets// so common api is needed ​to allow the actual modified //​controls//​ to be processed without every mapping needing to parse these packets themselves. Similarly when the state of a hid device needs to be updated (leds or other feedback) one or more updates are aggregated into a packet which contains the new state for all the //​controls//​ within that packet regardless of whether each has changed or not. The common hid api should ​take care of this decoding/​parsing/​encoding.
  
-**1. What ​company has to offer?**+Ideally the API (and future XML device definition file) should abstract the hid layer in such way that a mapping written for a hid controller could also be used for a midi controller, possibly with no changes at all for a controller that can be used in both midi and hid modes).
  
-What a company is able to deliver ​to their customers in terms of products and services is the most important thing to consider. Your marketing efforts must include both the products as well as services. The most frequent blunder committed by most of the businesses ​is that they put all their energy and efforts into generating the products but they overlook the type of benefits customers will be receiving from the products. This is a distinctive case where all the concentration is transferred ​to the needs of the customers but not their requirements.+For the HID device mappings for 1.11 each mapping has to implement it's own parsing/​encoding of HID data. We would like to get some common code into the Javascript library that would later be ported ​to the C++ core. The concern ​is that if we add any functions now that mappers rely on we won'​t ​be able to change it later on, so even if the implementation ​is only in Javascript initially it needs to be well considered.
  
-**2. Satisfaction of the Customers**+===== Components =====
  
-Every customer has diverse prospects when it comes to a meticulous market. Your capability to bring on that prospect must never be too low neither ought to be high. Once you realize this you may be well on your path to set up enduring customer relations.+Current proposed API contains three javascript prototype classes:
  
-**3. Exchanges**+  ​* **HIDController** implements an abstract HID controller javascript class, which is expected to take care of all HID packet creation and parsing, including updating the field values in these packets. 
 +  ​* **HIDPacket** is a container used to both receive and parse HID packets from devices and to specify the format for packets sent to the device. 
 +  * **HIDBitVector** is initialized from HIDPacket automatically and should not be directly handled by user scripts. It's purpose is to combine bits in same HID packet field to group of independently parsed and updated bits. A new HIDBitVector is automatically created when a control or output is added to same  HID packet offset. ​
  
-The short-term goal of any organization ​must be to create a product which is attractive to a customer but the long-term goal must be to keep those customers ​in touch for a longer period. And, this can be achieved by exchanging an item for another. If a customer is not satisfied with the product, ​the company must be willing ​to exchange ​the product in order to make a customer satisfied.+Each controller script using the API must at least: 
 +  * Include hid-common-packet-parser.js ​in the XML file before ​the actual script 
 +  * Implement exactly one HIDController instance (instead of new Controller() in MIDI scripts) 
 +  * Create and register one HIDPacket //Input Packet// entry named '​control' ​to the HIDController instance
  
-**4. Final Words** +Optionally, each HID controller script often needs to: 
 +  ​Define other input packets to receive other than controller status from the device 
 +  ​Define output packets to control LEDs or other items on the device, according to device specific details 
 +  ​Define output packets to change HID device state, for example disable mouse, initialize HID mode or request details from device 
 +  * Add //Scaling Functions// to the HID controller values, which can be anything from single bit to 32bit integer numbers 
 +  * Add //Filtering Functions// to the HID data. The HID controllers are often too high resolution and may send meaningless minor changes which we want to filter out 
 +  ​Register a //Callback Function// to the control registered in a HID packet
  
-If any organization wants to be in the back in terms of advanced marketing management, it is very crucial ​to know the concepts ​and follow them after thatThese concepts moreover, are very easy to follow ​on condition that you have capable ​and helpful financial staff in your organization. If you are aware of such type of knowledge ​your organization ​is certain ​to get on a way to develop strong marketing management skills+All these details have been implemented by the HID common packet parser classes. 
-https://www.xcelance.com/+ 
 + 
 +==== Defining Controls ==== 
 + 
 +Signature for the function to add controls: 
 + 
 +  HIDPacket.prototype.addControl = function(group,​name,​offset,​pack,​bitmask,​isEncoder) {}; 
 + 
 +A //control// identifies the bits/bytes that relate to a specific element on the controller, whether incoming changes from controller or outgoing data to be sent to the controller. 
 + 
 +If a //control// were to be defined from within a [[hid_mapping_format]] xml file it should be possible to bind this //control// to a custom script function via something like a ''​scriptfunction="​myprefix.myfunction"''​ attribute or use the midi xml format method of //key// optionally representing the function name. This is not yet supported ​in Mixxx 1.11, all controls must be mapped in javascript for now. 
 + 
 +There are four types of controls supported by HIDPacket:​ 
 + 
 +=== Type === 
 + 
 +  * **button:** a binary on/off toggle from device. While some buttons may have multiple states (bitmask not bit)this is not yet supported and the fiedl must be manually processed from a byte. 
 +  * **fader:** a numeric value, size 1-4 bytes, from the device. Usually these control mixxx internal values like knobs, jogs or faders. Unlike MIDI, HID does not specify range of such controls and the values are often far off from mixxx ranges. A scaling function can be automatically applied to move the value to expected range (for example, fader from unsigned short value to -1..1 range of mixxx). 
 +  * **encoder:​** the physical control is an encoder that sends out continous data like a fader, but resets to zero once reaching ​it's maximum value (and conversely when moved in reverse). An encoder ​is processed and added exactly like a fader, only difference is setting of isEncoder variable ​to true. This will change ​the field parsing code to set the field '​delta'​ attribute to -1 or +1 offsets, ​and wrapping over minimum and maximum values automaticallyThe minimum and maximum values are deduced from the field sizefor example a '​byte'​ encoder wraps from 255 to 0 and from 0 to 255, giving delta -1 and 1 respectively. 
 +  * **LED/​Output** a bit or byte to be sent back to the controller, most commonly to control status LEDs. Current implementation does not support sending short or integer size values, and sending of bitmask of bits is possible but not yet supported by the API. HIDController takes care of updating only modified parts of the outgoing packet. Right now API is missing a function to set other types of data except LED, but this can be trivially added when we know what is exactly needed. 
 + 
 +=== Packet Header === 
 + 
 +On many devices, each HID packet has a prefix in the packet to recognize which packet this is: for example, EKS Otus '​control'​ packet first two bytes are 0x0 and 0x35 (id and length). The packet header is given as an array when creating new packet. If there is no header, pass empty array to the variable. 
 + 
 +=== Offset === 
 + 
 +The byte offset of the field within the packet, starting from 0. 
 + 
 +=== Packing === 
 + 
 +Instead of telling the packet field length, HIDPacket parses the fields based on //pack// attribute. The packing tells the size and numeric range for each field, and allows us to convert the input number to and from exactly correct value. Currently supported '​pack'​ values are 
 +| b / B | unsigned/​signed byte                    | 
 +| h / H | unsigned/​signed two byte value (short) ​ | 
 +| i / I | unsigned/​signed four byte value (int)   | 
 +A field containing bits still needs to be given valid '​pack'​ value, to calculate bit vector masks and check boundaries. 
 + 
 +=== Bitmask === 
 + 
 +Bitmask defines the bit to flip for bit controls ​in the packet: internally, a HIDBitVector packet field is created when bitmasks are seen. If multiple controls with same offset and packing ​are defined, they are mapped transparently as fields ​of same HIDBitVector field, which can be updated or read in one go. 
 + 
 +Bitmask can be used when defining both button bit inputs and LED output bits.  
 + 
 +In current implementation,​ fader and encoder controls must have bitmask attribute set to 0: we don't support controls like 'high four bits of this byte'​. 
 +It is not possible to have both fader/​encoder numeric fields and bits in same input packet field. 
 + 
 +=== Group === 
 + 
 +Used in the same way as for a midi mapping - the default //group// that this control will be bound to. 
 + 
 +For automatic deck assignment to dynamic controllers,​ special names '​deck',​ '​deck1'​ and '​deck2'​ can be used to assign to even/odd decks, or to currently selected deck. All internal controls and connections are updated automatically,​ when deck status is changed and such group names are used. You can also register some controls with virtual deck mappings and some fields hard coded to specific deck. 
 + 
 +For input and output controls not to mapped anywhere automatically,​ we suggest using using group name '​hid'​. All data from and to these fields must be manually scripted or assigned in custom script functions. One example ​of such variable could be 'deck chooser'​ control in EKS Otus, or '​modifier fields. 
 + 
 +=== Name === 
 + 
 +A name for the control. If the control is mapped without a script function directly to mixxx, this name must be valid control name in mixxx for the group where the control is attacked to.  
 + 
 +<​del>​=== Min Value === 
 + 
 +Lowest value of these bytes when the control is at its minimum setting. 0 is the default. ​  
 + 
 +=== Max Value === 
 + 
 +The highest value of these bits/bytes when the control is at its maximum setting. 0xFFFF is the default for two bytes 
 +</​del>​ 
 + 
 +**NOTE** Minimum and maximum values are calculated automatically for a field from the '​pack'​ attribute. 
 + 
 +Current control defination format is following:​ 
 +   
 +  packet.addControl('​[Master]','​crossfader',​34,'​H'​);​ 
 +  packet.addControl('​[Playlist]','​SelectTrackKnob',​15,'​B',​undefined,​true);​ 
 + 
 +==== Parsing Incoming Controls ==== 
 + 
 +HIDController implements parsing of incoming packet named '​control'​ automatically. Unfortunately due to namespace issues in current qtscript implementation we use, you still need to implement an incomingData function in your script. The standard wrapper to your script ​is following:​ 
 + 
 +  MyDevice.incomingData = function(data,​length) { 
 +    MyDevice.parsePacket(data,​length);​ 
 +  } 
 + 
 +The default parsePacket function has following side effects: 
 + 
 +  * Only modified input field values are processed by any callbacks or automated calls to engine 
 +  * If field has registered callback function, this function is called **without running** scaling functions or resolving correct decks. All other processing for fields with a custom callback is ignored. 
 +  * If field has no callback, it's scaling function is called (if defined), virtual deck mapping to actual deck is performed and the assigned control group and name are attempted to be update directly in mix with scaled value. If the field'​s group name does not match a known mixxx control group or virtual deck, this is not done and the field input is ignored. 
 +  * Finally, if a function called processDelta is defined, it is called with all modified fields in the packet. This is done after automated fields and callbacks already have been called, so don't handle same field twice! 
 + 
 +==== Binding Actions to Incoming Controls ==== 
 + 
 +After packets have been added to HIDController,​ the registered fields can be mapped to controls. It's not recommended to bind controls in the addControl call, while possible: we should keep the packet declaration separate from functional declarations. 
 + 
 +The callback function is called, whenever we receive a modified value for the given field from HID device. 
 + 
 +Example call to register a callback function (exactly same group and name must be defined in packets): 
 + 
 +   ​MyDevice.registerInputCallback('​control','​[Master]','​headphones_knob',​MyDevice.headphones);​ 
 + 
 +Note we need to specify the '​control'​ packet name, even if it's the default packet to receive. We must support multiple different input packets here! 
 + 
 +===== Loading of packets, scalers and callbacks in one call ===== 
 + 
 +It is recommended to group all input, output, scaling and callback declarations to following four functions and call these in this order in init(): 
 + 
 +    MyDevice.registerInputPackets();​ 
 +    MyDevice.registerOutputPackets();​ 
 +    MyDevice.registerScalers();​ 
 +    MyDevice.registerCallbacks();​ 
 +     
 + 
 +==== Sending Data to the HID Device ==== 
 + 
 +Currently only LED output control is implemented for the output packets in the HIDController APIs. Outgoing LED controls are defined with similar syntax to addControl: only big difference is outgoing packets are registered with '​MyDevice.registerOutputPacket()'​ and LED control adding function is called '​addLEDControl',​ the packet itself is initialized in exactly same way.  
 + 
 +LED controls packet declaration example (declaring two LEDs controller by whole byte not by bits): 
 + 
 +    packet = new HIDPacket('​test_leds',​[0x17,​0x16],​4);​ 
 +    packet.addLED('​hid',"​test_led_1",​2,'​B'​);​ 
 +    packet.addLED('​hid',"​test_led_1",​3,'​B'​);​ 
 +    MyDevice.registerOutputPacket(packet);​ 
 +     
 +LED in this packet can be set explicitly with call like: 
 + 
 +    setLED('​hid','​test_led_1',​MyDevice.LEDColors['​blue'​]);​ 
 + 
 +LEDs matching virtual decks can be automatically assigned ​to current deckTODO document this. 
 + 
 +Packets can also have packet level callbacks, so custom functions can be used to send arbitrary packets. In the custom function, you need to fill in the correct values to the packet fields before sending to construct the packet: see EKS Otus mapping for examples. 
 + 
 +Minimal example of output packet with just one field from Otus mapping: 
 + 
 +    packet = new HIDPacket('​set_ledcontrol_mode',​[0x1d,​0x3],​32);​ 
 +    packet.addControl('​hid','​mode',​2,'​B'​);​ 
 +    EksOtus.registerOutputPacket(packet);​ 
 +     
 +Example part of custom function to send this packet: 
 + 
 +    var packet = EksOtus.OutputPackets['​set_ledcontrol_mode'​];​ 
 +    var field = packet.lookupField('​hid','​mode'​);​ 
 +    if (field==undefined) { 
 +        script.HIDDebug("​EksOtus.setLEDControlMode error fetching field mode"​);​ 
 +        return; 
 +    } 
 +    field.value = mode; 
 +    packet.send();​ 
 +===== References ===== 
 + 
 +  * **Development branch by Hile for HID scripts** [[https://code.launchpad.net/~hile/​mixxx/​hidscripts]] 
 +  * **Hercules Console Mk2 HID Mapping** [[http://​mixxx.org/​forums/​viewtopic.php?​f=7&​t=3712]] ​
hid_device_api.txt · Last modified: 2018/12/28 03:05 by be.ing