Hoe detecteer ik Midi signalen? 1 mogelijkheid is met de RolandUM One MK2,
Triton lijst.
https://ccrma.stanford.edu/~craig/articles/linuxmidi/misc/essenmidi.html
Midi kretologie |
Apparaat |
Kanaal |
Channel |
Poort |
Port |
Track |
Spoor |
Triton Global P1 |
|
Midi Channel 01-16: 01 |
|
|
|
|
Karma Com Status |
|
|
|
Input: 2
Output: 3 |
|
|
Hardware midi keten |
Korg Triton |
midi USB |
《-》 |
Laptop |
midi USB |
FCB1010 |
midi in/uit |
《-》 |
Laptop |
midi USB |
Korg Triton |
audio uit |
-》 |
Server |
mic in |
Software |
KaT midi uit -》Seq midi in
Seq midi uit -》KTE midi in
KTE sound uit -》 Serv sound in
LGF midi uit -》FCB midi in
|
Protocol |
- Events
Een event is dat er 1 Midi master een bericht verstuurd naar een cliënt. Een Midi (wiki, Arduino.cc) Master verstuurt dit bericht als een groepje bytes over een seriële verbinding. Een dergelijk groepje bytes wordt in Midi termen een event genoemd. Een event bestaat afhankelijk van het soort bericht dat wordt verzonden uit minimaal 2 bytes, maar vaker nog uit 3 bytes. MIDI data is usually notated in hexadecimal because MIDI banks and instruments are grouped in groups of 16. Een event begint altijd met een commandobyte (ook wel statusbyte genoemd), gevolgd door 1 of meer databytes:
- De commandobyte
De commando byte is altijd 128 of groter, oftewel 0x80 t/m 0xFF in hexadecimaal. Commands include things such as note on, note off, pitch bend, and so forth. STATUS byte (bit 7 = 1)
- Note Off 0x80
Bijvoorbeeld voor muziek. De 2de nibble bevat het kanaalnummer. Dat is dus van 0 t/m F. Vervolgens luisteren enkel alle instrumenten die op dit kanaal zijn afgestemd. Zo kan ieder instrument zijn eigen muziek krijgen.
- Note On 0x90
Bijvoorbeeld voor muzie?.
- Key Pressure 0xA0
Bijvoorbeeld voor muzie?.
- Control Change 0xB0
Bank change
De meeste apparaten hebben dikwijls meer dan 128 klanken aan boord. Het bereik van een Program Change is dus niet altijd voldoende. Dit bereik kan echter aanzienlijk worden vergroot door het gebruik van banken. Een bank is een verzameling van maximaal 128 verschillende klanken. MIDI verleent ruimte voor 16.384 banken. Met behulp van Control Change met controllernummer 0 (MSB – most significant byte) en 32 (LSB – least significant byte) kan een bank worden gekozen. De tweede parameter bepaalt dan om welke bank het gaat. Het apparaat, dat de bankchange ontvangt, wacht nu op een Program Change. (?Oh ja, welke dan?) Zodra ook die is verstuurd, schakelt het ontvangende apparaat over naar de gevraagde klank, in de gevraagde bank. Dus welke bytes verzenden we nu? In other words, to select Program D025 from an external sequencer, you would send CC 000 “000” followed by CC032 “003” followed by Program Change 025. Combi veranderen werkt zonder problemen.
- Program Change 0xC0
Bijvoorbeeld voor muzie?.
- Channel Pressure 0xD0
Bijvoorbeeld voor muzie?.
- Pitch Bend 0xE0
Bijvoorbeeld voor muzie?.
- Bestaat niet? 0xF0
- De databyte
Data bytes are always less than 127, or 0x00 to 0x7F in hex. Data bytes include things like the pitch of the note to play, the velocity, or loudness of the note, amount of pitch bend and so forth. DATA bytes (Bit 7 = 0).
- Luisteraars
The messages from 0x80 to 0xEF are called Channel Messages because the second four bits of the command specify which channel the message affects. The messages from 0xF0 to 0xFF are called System Messages; they do not affect any particular channel. . De verstuurde Midi berichten zijn in te delen in 2 groepen, afhankelijk van wie er meeluisterd naar de berichten:
- Channel
Deze berichten worden alleen maar gehoord door de apparaten die dit kanaal ook daadwerkelijk gebruiken als input. Channel messages contain a four bit channel number encoded into the Status byte which addresses the message specifically to one of sixteen channels. For Channel messages only, the Status byte may be omitted if it would otherwise repeat the last Status byte sent. This is commonly used to reduce the length of Note On / Note Off sequences (where Note On with zero velocity is used for Note Off) or Continuous Controller movements.
- Channel Voice
Bijvoorbeeld voor muziek. Dit gaat naar alle instrumenten die op dit kanaal zijn afgestemd.
- Channel Mode
0x80 Note-off 2 key velocity
0x90 Note-on 2 key veolcity
0xA0 Aftertouch 2 key touch
0xB0 Continuous controller 2 controller # controller value
0xC0 Patch change 2 instrument #
0xD0 Channel Pressure 1 pressure
0xE0 Pitch bend 2 lsb (7 bits) msb (7 bits)
0xF0 (non-musical commands) .
- System
System messages are not encoded with channel numbers and are divided into three main types: System Common, System Real Time and System Exclusive.
- System Common
0xF0 start of system exclusive message
0xF1 MIDI Time Code Quarter Frame (Sys Common)
0xF2 Song Position Pointer (Sys Common)
0xF3 Song Select (Sys Common)
0xF4 ???
0xF5 ???
0xF6 Tune Request (Sys Common)
0xF7 end of system exclusive message 0
0xF8 Timing Clock (Sys Realtime)
0xFA Start (Sys Realtime)
0xFB Continue (Sys Realtime)
0xFC Stop (Sys Realtime)
0xFD ???
0xFE Active Sensing (Sys Realtime)
0xFF System Reset (Sys Realtime)
Bijvoorbeeld voor muziek?
- System Real-Time
System Real Time messages are all single bytes and may be interleaved between any other messages (including System Exclusive). Any Status byte except System Real Time may terminate a System Exclusive Block.
- System Exclusive
SysEx messages can include functionality beyond what the MIDI standard provides. They target a specific instrument, and are ignored by all other devices on the system. Volledige compatibiliteit is echter nog steeds niet gewaarborgd. Daar zijn verschillende redenen voor. In de eerste plaats wordt MIDI doorgaans gebruikt om synthesizers aan te sturen, en iedere synthesizer heeft zijn eigen functionaliteit met talloze filters en opties voor bijvoorbeeld de aanslag en het wegsterven van tonen. De MIDI-standaard voorziet daarin met System Exclusive-boodschappen, die een fabrikantcodeveld bevatten en die door fabrikanten naar eigen goeddunken kunnen worden ingevuld. Worden zulke boodschappen naar een synthesizer van een ander merk verstuurd, dan worden deze genegeerd. Het resultaat kan al dan niet aanvaardbaar zijn.
|
Hardware |
- De kabels
Een MIDI IN dient altijd verbonden te worden met de MIDI OUT of MIDI THRU van een ander apparaat. Dit gebeurt door middel van een MIDI-kabel. Deze kabel bevat aan beide uiteinden een mannelijke 180° 5-pin DIN-connector en mag niet langer zijn dan 15 meter. Er vindt seriële communicatie plaats, die voor iedere aansluiting eenzijdig (simplex) verloopt. De OUT verstuurt stroompulsjes (5Vdc) die in de IN via een optocoupler ingelezen worden om storing door aardlussen te voorkomen. De gebruikte bandbreedte is 31,25 kbit/s, wat voor de meeste toepassingen afdoende is, maar wat bij "volle" multitimbrale orkestraties tot kleine, maar storende vertragingen leidt. MIDI is a serial protocol that operates at 31,250 bits per second. The board built-in serial port (all of them on the Mega as well) can send data at that rate.
|
//This is an include, so no parsing needed
$qry2 = ("SELECT onderdelen.*,
soortonderdeel.id
FROM onderdelen
JOIN soortonderdeel ON onderdelen.idsrtodd = soortonderdeel.id
WHERE onderdelen.partid = $idpart
;");
$result2 = pg_query($con1, $qry2);
$row4 = pg_fetch_array($result2); //Make the fields accesible
foreach( $row4 AS $key => $val ){
$$key = stripslashes( $val );
}
$jaar = substr($changeddate,0,4);
$maand = substr($changeddate,5,2);
$dag = substr($changeddate,8,2);
$lastupdate = ("$jaar $maand $dag");
$prtsrttxt = get_txt($con1, 26, 1, $idsrtodd);
$jaar = substr($createddate,0,4);
$maand = substr($createddate,5,2);
$dag = substr($createddate,8,2);
$create_stamp = ("$dag $maand $jaar");
//GENERAL INFO FOR EVERY USER **************************************************
echo (" ");
echo (""); //Header
$tmp = get_txt($con1, 9, $koekje[2], 3923); //Fieldname at screen
if ($koekje[3]=="1") { //If this user wants to translate then
echo ("$tmp"); //If desired
}else{ echo ("$tmp"); } //Else just show if no need to translate
if ($koekje[0]>0 and $koekje[3]>0){ //User is logged in and translates
echo (" (edit)");
}
echo ("Algemene informatie test | ");
if ($codetext) { //Code like KY-026 or NA-41
echo ("");
$tmp = get_txt($con1, 9, $koekje[2], 3739); //Fieldname at screen
if ($koekje[3]=="1") { //If this user wants to translate then
echo ("$tmp"); //Class for colour
}else{ //So you are not allowed to translate
echo $tmp; //Show screenname of this field in user language
} //End of If you want to translate this fieldname at screen
echo ("  | ");
if ($codelink) {
echo ("$codetext");
}else{
echo ("$codetext");
} //End of if ($pinoutlink)
echo (" | ");
} //End of if ($codetext)
$tmp = get_txt($con1, 9, $koekje[2], 3741); //Fieldname at screen
if ($prijseurinclbtw > 0){ //Show price indication
$prijs_formatted = number_format($prijseurinclbtw / 100, 2, ',', '.');
echo ("$tmp   | ");
echo ("");
if ($urlprijs){
echo ("€  $prijs_formatted");
}else{
echo ("€  $prijs_formatted");
} //End of if ($urlprijs > "")
echo (" | ");
} //End of if ($prijseurinclbtw > 0)
if ($sketchtext) { //Link to OWN SOFTWARE
$tmp = get_txt($con1, 9, $koekje[2], 3738); //Fieldname at screen
echo ("$tmp   | ");
if ($sketchlink) {
echo ("$sketchtext");
}else{
echo ("$sketchtext");
} //End of if ($sketchlink)
echo (" | ");
} //End of if ($sketchtext)
$tmp = get_txt($con1, 9, $koekje[2], 3744); //Fieldname at screen
if ($pinouttext) { //Pinout
echo ("$tmp   | ");
if ($pinoutlink) {
echo ("$pinouttext");
}else{
echo ("$pinouttext");
} //End of if ($pinoutlink)
echo (" | ");
}
$tmp = get_txt($con1, 9, 1, 3735); //Fieldname at screen
$tmp2 = get_txt($con1, 26, 1, $row4[16]); //Group name in its language
echo ("$tmp   | "); //MENU GROUP
echo ("");
echo ("$tmp2 | ");
if ($koekje[0]>0 and $koekje[3]>0){ //User is logged in and translates
$tmp = get_txt($con1, 9, $koekje[2], 3918); //Fieldname at screen LANGUAGE
if ($row4[26] == 1) {$imgname = "nederland.png";}
if ($row4[26] == 2) {$imgname = "deutschland.png";}
if ($row4[26] == 3) {$imgname = "uk.png";}
if ($row4[26] == 4) {$imgname = "france.png";}
echo ("$tmp | ");
echo ("");
echo (" | ");
$tmp = get_txt($con1, 9, $row4[27], 3919); //Fieldname at screen
$statuskey = get_status_key($con1, $status);
$tmp2 = get_txt($con1, 61, $koekje[2], $statuskey); //Fieldname at screen
echo ("$tmp   | "); //STATUS
echo ("$status $tmp2 | ");
}
$tmp = get_txt($con1, 9, 1, 3966); //Fieldname at screen
echo ("$tmp   | "); //LAST CHANGED
$tmp = substr($changeddate, 0, 10);
echo ("$tmp | ");
echo (" ");
return;
////////////////////////////////////////////////////////////////////////////////
function get_status_key($con, $num){
$qry = ("SELECT id FROM status WHERE nr = $num ;");
$result = pg_query($con, $qry);
$row = pg_fetch_array($result);
return ("$row[0]");
}
// LIST ALL SOFTWARE THAT WILL RUN OM THIS PART *****************************
// INCLUDED IN ALL ROBOTS TO CHECK THEIR DIRECTORY
$qry2=("SELECT tblsystext.txtname
, software.urlmain
, software.sftname
, software.sftid
, software.controller
FROM software
LEFT JOIN tblsystext ON software.controller = tblsystext.recordid
WHERE position(' $idpart ' in software.prtlst) > 0
AND software.rstid = 2
AND tblsystext.lanid = $koekje[2]
AND tblsystext.txlid = 19
ORDER BY sftname ASC
, controller ASC
;");
$result = pg_query($con1, $qry2);
if (pg_num_rows($result)>0) { //Only if at least 1 program exists
echo (' ');
echo (""); //Header
$tmp = get_txt($con1, 9, $koekje[2], 3922); //Fieldname at screen
if ($koekje[3]=="1") { //If this user wants to translate then
echo ("$tmp"); //If desired
}else{ echo ("$tmp"); } //Else just show if no need to translate
echo (" |
---|
");
while($col = pg_fetch_array($result)){
$col[0] = ("$col[0]");
echo (" ");
echo ("$col[2]   | ");
echo ("$col[0] | ");
if ($koekje[0] > 0 and $koekje[3]>0){ //User is logged in and translates
echo ("");
echo ("(Edit) | ");
}
echo (' ');
}
echo (' ');
}
?>
// LIST ALL ROBOTS THAT INCLUDE THIS PART ***********************************
// $idpart
// INCLUDED IN ALL ROBOTS TO CHECK THEIR DIRECTORY
$qry_bpp=("SELECT farmbotversie.id
, farmbotversie.part_list
, tblsystext.txtname
FROM farmbotversie
LEFT JOIN tblsystext ON farmbotversie.id = tblsystext.recordid
WHERE tblsystext.txlid = 27
AND tblsystext.lanid = $koekje[2]
ORDER BY tblsystext.txtname ASC
;");
$result_bpp = pg_query($con1, $qry_bpp);
$header = 0;
while($colbpp = pg_fetch_array($result_bpp)){ //Only if at least 1 robot exists
if(substr_count($colbpp[1], " $idpart ") > 0){
if ($header == 0) {
echo ("");
echo (""); //Header
$tmp = get_txt($con1, 9, $koekje[2], 3879); //Fieldname at screen
if ($koekje[3]=="1") { //If this user wants to translate then
echo ("$tmp"); //If desired
}else{ echo ("$tmp"); } //Else just show if no need to translate
echo (" | ");
$header++;
} //End of if ($header == 0)
echo ("");
echo ("$colbpp[2]");
//Show software van deze bot
$qry=("SELECT software_basedir
FROM farmbotversie
WHERE id = $colbpp[0];");
$result = pg_query($con1, $qry);
$col = pg_fetch_array ($result ,0);
$dir1 = "/var/www/html/robotigs/software/$col[0]";
$arr1 = glob($dir1, GLOB_ONLYDIR);
if (isset($arr1[0])){
$folder = $arr1[0];
$countertmp = 0;
echo ("");
foreach (scandir($folder, 1) as $filename) {
if ($filename<>"." AND $filename <>".."){
if ($countertmp == 0){
$countertmp++;
} //End of if ($countertmp == 0)
$tmp = "/";
$dir = substr($folder, 14) ."/";
$link = $tmp .$dir .$filename;
$showname = substr($filename, 0 ,-4);
echo ("- ");
echo "$showname";
echo ("
");
} //End of if ($filename<>"." AND $filename <>".."){
} //End of foreach (scandir($folder, 1) as $filename)
echo ("");
} //End of if (isset($arr1[0]))
echo (" | ");
}
}
if ($header > 0){
echo (" ");
}
?>
Warning: include(/var/www/html/robotigs/includes/wishlistperpart.php): Failed to open stream: No such file or directory in /var/www/html/robotigs/includes/parts_header.php on line 128
Warning: include(): Failed opening '/var/www/html/robotigs/includes/wishlistperpart.php' for inclusion (include_path='.:/usr/share/php') in /var/www/html/robotigs/includes/parts_header.php on line 128
| //Location:/robotigs/includes/ picts_show.php
// Requieres: $pict_list and several picture handling javascript routines
//*** FROM HERE ON THE PICTURE CORNER STARTS -----------------------------------
if ($pict_list){ //There are 1 or more pictures to be printed
echo ("");
$counter = 0;
$aantal = str_word_count($pict_list, 0, "0123456789");
$lijst = str_word_count($pict_list, 1, "0123456789");
while($counter < $aantal){
$pictkey = $lijst[$counter];
$qryy1 = ("SELECT *
FROM illustrations
WHERE ill_id = $pictkey
;");
$resulty1 = pg_query($con1, $qryy1);
while($row = pg_fetch_array($resulty1)){ //Fields accesible by their name
foreach( $row AS $key => $val ){
$$key = stripslashes( $val );
}
}
$image = ("/robotigs/documentatie/plaatjes/$ill_name");
$pictfull = str_replace('_small', '', $image); //Pictfull=biggest version
$alt = ("Just wait till your 57....");
$txtname = get_txt($con1, 18, $koekje[2], $ill_id); //Robot illustrations subtitles
echo ("");
echo (' ');
$nummer = $counter + 1;
$txtAfb = get_txt($con1, 9, $koekje[2], 3865); //Pic Afb
if ($koekje[0]>0 and $koekje[3]>0){ //User is logged in and translates
echo ("$txtAfb $nummer: ");
echo ("$txtname");
echo (" ");
echo ("Ontkoppelen ");
if ($counter==0){
echo ("Up ");
}else{
echo ("Up ");
}
if ($nummer == $aantal){
echo ("Down");
}else{
echo ("Down");
}
}else{ //Else of if Meaning the current useer is logged in
echo ("$txtAfb $nummer: $txtname");
}
echo (''); //End of this picture
$counter++; //Prepair for next picture
}
echo (' | '); //All pictures are printed
} //End of if there are 1 or more pictures to be printed ----------------------
?>