struct

(**

Liste d'appareils testés

  1. Akai MPK mini
    Détection sous FreeBSD :
    ugen1.2: <AKAI PROFESSIONAL,LP> at usbus1
    uaudio0: <AKAI PROFESSIONAL,LP MPK mini, class 0/0, rev 1.10/1.00, addr 2> on usbus1
    uaudio0: No playback.
    uaudio0: No recording.
    uaudio0: MIDI sequencer.
    uaudio0: No HID volume keys found.
Copyright Stéphane Grognet
IREM des Pays de la Loire - Université de Nantes
Laboratoire de mathématiques Jean Leray UMR 6629 CNRS
version 0.9
@version 0.9 @author Stéphane Grognet @since 2014 *)



(** Il faut mettre ARPEGIATOR sur OFF.

Pour que les boutons rotatifs envoient des messages, il faut sélectionner un programme différent de PROG1.

Maintenir le poussoir PROGRAM enfoncé et appuyer sur une touche PROG2 ou PROG3 ou PROG4.

Pour que les pads n'envoient pas de notes mais des messages "control change", il faut appuyer sur la touche CC.

Les pads 9 à 16 correspondent aux pads 1 à 8 dans "PAD BANK 2". C'est eux qu'il faut activer.

DISPOSITION des pads 1 à 8 simulant les boutons de transport :

() << >> []

|< >| > O

*)





(**

Données universelles

*)



let masque_entete = 0xF0 ;;
let numero_de_canal = 0x0F ;;

(** Note off event *)

let touche_relachee = 0x80 ;;

(** Note on event *)

let touche_appuyee = 0x90 ;;

(** Controle change *)

let mode = 0xB0 ;;

(** Program change *)

let instru = 0xC0 ;;

(** Pitch bend change. La molette de pitch est centrée sur la valeur 64. *)

let pitch = 0xE0 ;;

(** System messages *)

let sys = 0xF0 ;;


(**

Numéros de controleurs

*)



let bank_select = 0x00 ;;
let modulation = 0x01 ;;
let swell = 0x0B ;;
let sustain_pedal = 0x40 ;;


(**

Données locales

*)



let message_vide = 0xFE ;;
let canal_vide = 0x0E ;;

let bouton1 = 0x01 ;;
let bouton2 = 0x02 ;;
let bouton3 = 0x03 ;;
let bouton4 = 0x04 ;;
let bouton5 = 0x05 ;;
let bouton6 = 0x06 ;;
let bouton7 = 0x07 ;;
let bouton8 = 0x08 ;;

(** Il y a un conflit entre les boutons rotatifs et la première banque de coussinets. *)


let pad_1 = 0x01 ;;
let pad_2 = 0x02 ;;
let pad_3 = 0x03 ;;
let pad_4 = 0x04 ;;
let pad_5 = 0x05 ;;
let pad_6 = 0x06 ;;
let pad_7 = 0x08 ;;
let pad_8 = 0x09 ;;
let pad_9 = 0x0A ;;
let pad_10 = 0x0B ;;
let pad_11 = 0x0C ;;
let pad_12 = 0x0D ;;
let pad_13 = 0x0E ;;
let pad_14 = 0x0F ;;
let pad_15 = 0x10 ;;
let pad_16 = 0x11 ;;



(**

Traduction

*)




let scrute = fun ic oc ->
 let c = ref 0
 and entete = ref 0
 and canal = ref 0
 and note = ref 0
 and controleur = ref 0
 and valeur = ref 0 in
  try
   while true do
    c := input_byte ic ;
    entete := !c land masque_entete ;
    canal := !c land numero_de_canal ;
    match !entete with
    | x when x = pitch || x = touche_relachee || x = touche_appuyee ->
     begin
      note := input_byte ic ;
      valeur := input_byte ic ;
      output_byte oc !c ;
      output_byte oc !note ;
      output_byte oc !valeur ;
      flush_all () ;
     end
    | x when x land mode = mode ->
     begin
      controleur := input_byte ic ;
      valeur := input_byte ic ;
      match !controleur with
      | y when y = bouton1 ->
       begin
        output_byte oc !c ;
        output_byte oc Omega.bouton_1 ;
        output_byte oc !valeur ;
        flush_all () ;
       end
      | y when y = bouton2 ->
       begin
        output_byte oc !c ;
        output_byte oc Omega.bouton_2 ;
        output_byte oc !valeur ;
        flush_all () ;
       end
      | y when y = bouton3 ->
       begin
        output_byte oc !c ;
        output_byte oc Omega.bouton_3 ;
        output_byte oc !valeur ;
        flush_all () ;
       end
      | y when y = bouton4 ->
       begin
        output_byte oc !c ;
        output_byte oc Omega.bouton_4 ;
        output_byte oc !valeur ;
        flush_all () ;
       end
      | y when y = bouton5 ->
       begin
        output_byte oc !c ;
        output_byte oc Omega.bouton_5 ;
        output_byte oc !valeur ;
        flush_all () ;
       end
      | y when y = bouton6 ->
       begin
        output_byte oc !c ;
        output_byte oc Omega.bouton_6 ;
        output_byte oc !valeur ;
        flush_all () ;
       end
      | y when y = bouton7 ->
       begin
        output_byte oc !c ;
        output_byte oc Omega.bouton_7 ;
        output_byte oc !valeur ;
        flush_all () ;
       end
      | y when y = bouton8 ->
       begin
        output_byte oc !c ;
        output_byte oc Omega.bouton_8 ;
        output_byte oc !valeur ;
        flush_all () ;
       end
      | y when y = pad_13 ->
       begin
        output_byte oc !c ;
        output_byte oc Omega.poussoir_boucle ;
        output_byte oc !valeur ;
        flush_all () ;
       end
      | y when y = pad_14 ->
       begin
        output_byte oc !c ;
        output_byte oc Omega.poussoir_rembobine ;
        output_byte oc !valeur ;
        flush_all () ;
       end
      | y when y = pad_15 ->
       begin
        output_byte oc !c ;
        output_byte oc Omega.poussoir_avance_rapide ;
        output_byte oc !valeur ;
        flush_all () ;
       end
      | y when y = pad_16 ->
       begin
        output_byte oc !c ;
        output_byte oc Omega.poussoir_arret ;
        output_byte oc !valeur ;
        flush_all () ;
       end
      | y when y = pad_9 ->
       begin
        output_byte oc !c ;
        output_byte oc Omega.poussoir_debut ;
        output_byte oc !valeur ;
        flush_all () ;
       end
      | y when y = pad_10 ->
       begin
        output_byte oc !c ;
        output_byte oc Omega.poussoir_fin ;
        output_byte oc !valeur ;
        flush_all () ;
       end
      | y when y = pad_11 ->
       begin
        output_byte oc !c ;
        output_byte oc Omega.poussoir_lecture ;
        output_byte oc !valeur ;
        flush_all () ;
       end
      | y when y = pad_12 ->
       begin
        output_byte oc !c ;
        output_byte oc Omega.poussoir_enregistrement ;
        output_byte oc !valeur ;
        flush_all () ;
       end
      | _ -> flush_all ()
     end
    | _ -> flush_all ()
   done
  with _ ->
   close_out_noerr oc ;;

scrute stdin stdout ;;

end