struct

(**

Descripton

Le foncteur Clavier.Make permet d'interpréter les signaux MIDI de contrôleurs provenant de divers fabricants.

Cette interprétation des signaux MIDI ne tient compte ni des canaux MIDI ni de la valeur de la vélocité.

Le résultat est un vecteur de 180 caractères dont les cent-vingt-huit premiers donnent l'état de chaque note/touche de clavier : 0 pour haut, 127 pour bas. Le suivant donne la valeur d'excursion de diapason (pitch bend). Les neuf caractères suivants donnent la position des tirettes (127 au fond, 0 vers l'interprète) ; la première tirette est la molette de modulation quand seulement huit curseurs sont disponibles. Les huit autres sont les curseurs dans l'ordre. Les neuf caractères suivants sont les valeurs des tirettes en mode spécial. Les caractères suivants donnent les valeurs des boutons rotatifs (de 0 à 127) suivant les modes (2+5*6 puisque swell et saturation sont toujours présents). Le caractère qui reste indique l'activité du bouton-poussoir boucle (bouton de transport de style magnétophone).

Copyright Stéphane Grognet
IREM des Pays de la Loire - Université de Nantes
Laboratoire de mathématiques Jean Leray UMR 6629 CNRS
version 0.8
@version 0.8 @author Stéphane Grognet @since 2014, 2015 *)



(**

Constantes locales

*)



type select =
 | Vide
 | Rappel
 | Rappel_boutons
 | Sauvegarde
 | Sauvegarde_boutons
 | Forme
 | Percussion
 | Vibrato
 | Filtrage
 | Reverb
 | Special
 | Rembobine
 | Avance_rapide
 | Arret
 | Lecture ;;


let vide = 0 ;;
let plein = 127 ;;
let milieu = 64 ;;
let haut = 0 ;;
let bas = 127 ;;


(**

Fonctions utilitaires

*)



let pourcent_cpu = fun () ->
 let x = Sys.command "exit `ps -ro %cpu | head -n 2 | tail -n 1 | cut -d. -f 1`" in
  ( string_of_int x ) ^ "% " ;;

let detricote = fun (sigma:int) (delta:int) ->
 let s = 2 * sigma in
  ( ( s  + delta ) / 2 , ( s - delta ) / 2 ) ;;

let aux = fun (adresse:string) (decalage:int) (c:int) ->
 let oc = open_out_gen [Open_binary ; Open_wronly] 0o644 adresse in
  seek_out oc decalage ;
  output_byte oc c ;
  flush_all () ;
  close_out_noerr oc ;;

let rappel_boutons = fun (decalage:int ref) (pred_facteur_decalage:int) (facteur_decalage:int) (reglages:int array) (note:int) ->
 let ict = open_in_gen [Open_binary ; Open_rdonly] 0o400 Data.adresse_etat_reglages in
  decalage := facteur_decalage * note ;
  seek_in ict !decalage ;
  for i = 0 to pred_facteur_decalage do
   reglages.(i) <- input_byte ict ;
  done ;
  close_in_noerr ict ;
  let oc = open_out_gen [Open_binary ; Open_wronly] 0o644 Data.adresse_etat_clavier in
   seek_out oc ( 128 + Data.succ_nombre_de_curseurs ) ;
   for i = 0 to pred_facteur_decalage do
    output_byte oc reglages.(i) ;
   done ;
   flush_all () ;
   close_out_noerr oc ;
   prerr_int note ;
   prerr_newline () ;
   prerr_endline ( ( pourcent_cpu () ) ^ "mode vide" ) ;;

let sauvegarde_boutons = fun (decalage:int ref) (pred_facteur_decalage:int) (facteur_decalage:int) (reglages:int array) (note:int) ->
 let oc = open_out_gen [Open_binary ; Open_wronly] 0o644 Data.adresse_etat_reglages in
  decalage := facteur_decalage * note ;
  seek_out oc !decalage ;
  for i = 0 to pred_facteur_decalage do
   output_byte oc reglages.(i) ;
  done ;
  flush_all () ;
  close_out_noerr oc ;
  prerr_int note ;
  prerr_newline () ;
  prerr_endline ( ( pourcent_cpu () ) ^ "mode vide" ) ;;

let demande_rappel_boutons = function (selection:select ref) ->
 selection := Rappel_boutons ;
 prerr_endline ( ( pourcent_cpu () ) ^ "rappel de reglages" ) ;;

let demande_sauvegarde_boutons = function (selection:select ref) ->
 selection := Sauvegarde_boutons ;
 prerr_endline ( ( pourcent_cpu () ) ^ "enregistrement de reglages" ) ;;

let vc = fun (poussoir_mono:int ref) (reglages:int array) ->
 poussoir_mono := ( succ !poussoir_mono ) mod Data.modulo_vibrato_mono ;
 reglages.( Data.poussoir_vibrato_mono_chorus - Data.succ_nombre_de_curseurs ) <- !poussoir_mono ;
 aux Data.adresse_etat_clavier ( 128 + Data.poussoir_vibrato_mono_chorus ) !poussoir_mono ;
 let chaine = match !poussoir_mono with
 | 0 -> "son mono droit"
 | 1 -> "vibrato mono 1"
 | 2 -> "chorus mono 1"
 | 3 -> "vibrato mono 2"
 | 4 -> "chorus mono 2"
 | 5 -> "vibrato mono 3"
 | _ -> "chorus mono 3" in
 prerr_endline ( ( pourcent_cpu () ) ^ chaine ) ;;

let pouss_mono = fun (poussoir_mono:int ref) (reglages:int array) (indice:int) ->
 if !poussoir_mono <> 0 then
  begin
   let chaine = ref "" in
    poussoir_mono := if !poussoir_mono mod 2 = 0 then ( chaine := "chorus" ; 2 * indice ) else ( chaine := "vibrato" ; pred ( 2 * indice ) ) ;
    reglages.(33) <- !poussoir_mono ;
    aux Data.adresse_etat_clavier ( 128 + Data.poussoir_vibrato_mono_chorus ) !poussoir_mono ;
    prerr_endline ( ( pourcent_cpu () ) ^ !chaine ^ " mono " ^ ( string_of_int indice ) )
  end ;;

let frein = fun (selection:select ref) (poussoir:int ref) (demi_lune:int ref) (reglages:int array) ->
 selection := Vibrato ;
 if !poussoir = 0 then
  poussoir := 1 ;
 demi_lune := 2 ;
 reglages.(32) <- !poussoir ;
 reglages.(34) <- !demi_lune ;
 aux Data.adresse_etat_clavier ( 128 + Data.poussoir_vibrato_chorus ) !poussoir ;
 aux Data.adresse_etat_clavier ( 128 + Data.demi_lune ) !demi_lune ;
 prerr_endline ( ( pourcent_cpu () ) ^ "vibrato frein" ) ;;

let lent = fun (selection:select ref) (poussoir:int ref) (demi_lune:int ref) (reglages:int array) ->
 selection := Vibrato ;
 if !poussoir = 0 then
  poussoir := 1 ;
 demi_lune := 1 ;
 reglages.(32) <- !poussoir ;
 reglages.(34) <- !demi_lune ;
 aux Data.adresse_etat_clavier ( 128 + Data.poussoir_vibrato_chorus ) !poussoir ;
 aux Data.adresse_etat_clavier ( 128 + Data.demi_lune ) !demi_lune ;
 reglages.(Data.bouton_excursion_vibrato - Data.succ_nombre_de_curseurs) <- Data.excursion_vibrato_stereo ;
 reglages.(Data.bouton_diff_excursion_vibrato - Data.succ_nombre_de_curseurs) <- Data.diff_excursion_vibrato_stereo ;
 aux Data.adresse_etat_clavier ( 128 + Data.bouton_excursion_vibrato ) Data.excursion_vibrato_stereo ;
 aux Data.adresse_etat_clavier ( 128 + Data.bouton_diff_excursion_vibrato ) Data.diff_excursion_vibrato_stereo ;
 reglages.(Data.bouton_dephasage_rotation - Data.succ_nombre_de_curseurs) <- Data.dephasage_rotation_vibrato_stereo ;
 reglages.(Data.bouton_diff_dephasage_rotation - Data.succ_nombre_de_curseurs) <- Data.diff_dephasage_rotation_vibrato_stereo ;
 aux Data.adresse_etat_clavier ( 128 + Data.bouton_dephasage_rotation ) Data.dephasage_rotation_vibrato_stereo ;
 aux Data.adresse_etat_clavier ( 128 + Data.bouton_diff_dephasage_rotation ) Data.diff_dephasage_rotation_vibrato_stereo ;
 reglages.(Data.bouton_tremolo - Data.succ_nombre_de_curseurs) <- Data.tremolo_vibrato_stereo ;
 reglages.(Data.bouton_diff_tremolo - Data.succ_nombre_de_curseurs) <- Data.diff_tremolo_vibrato_stereo ;
 aux Data.adresse_etat_clavier ( 128 + Data.bouton_tremolo ) Data.tremolo_vibrato_stereo ;
 aux Data.adresse_etat_clavier ( 128 + Data.bouton_diff_tremolo ) Data.diff_tremolo_vibrato_stereo ;
 prerr_endline ( ( pourcent_cpu () ) ^ "vibrato lent" ) ;;

let rapide = fun (selection:select ref) (poussoir:int ref) (demi_lune:int ref) (reglages:int array) ->
 selection := Vibrato ;
 if !poussoir = 0 then
  poussoir := 1 ;
 demi_lune := 3 ;
 reglages.(32) <- !poussoir ;
 reglages.(34) <- !demi_lune ;
 aux Data.adresse_etat_clavier ( 128 + Data.poussoir_vibrato_chorus ) !poussoir ;
 aux Data.adresse_etat_clavier ( 128 + Data.demi_lune ) !demi_lune ;
 reglages.(Data.bouton_excursion_vibrato - Data.succ_nombre_de_curseurs) <- Data.excursion_vibrato_stereo ;
 reglages.(Data.bouton_diff_excursion_vibrato - Data.succ_nombre_de_curseurs) <- Data.diff_excursion_vibrato_stereo ;
 aux Data.adresse_etat_clavier ( 128 + Data.bouton_excursion_vibrato ) Data.excursion_vibrato_stereo ;
 aux Data.adresse_etat_clavier ( 128 + Data.bouton_diff_excursion_vibrato ) Data.diff_excursion_vibrato_stereo ;
 reglages.(Data.bouton_dephasage_rotation - Data.succ_nombre_de_curseurs) <- Data.dephasage_rotation_vibrato_stereo ;
 reglages.(Data.bouton_diff_dephasage_rotation - Data.succ_nombre_de_curseurs) <- Data.diff_dephasage_rotation_vibrato_stereo ;
 aux Data.adresse_etat_clavier ( 128 + Data.bouton_dephasage_rotation ) Data.dephasage_rotation_vibrato_stereo ;
 aux Data.adresse_etat_clavier ( 128 + Data.bouton_diff_dephasage_rotation ) Data.diff_dephasage_rotation_vibrato_stereo ;
 reglages.(Data.bouton_tremolo - Data.succ_nombre_de_curseurs) <- Data.tremolo_vibrato_stereo ;
 reglages.(Data.bouton_diff_tremolo - Data.succ_nombre_de_curseurs) <- Data.diff_tremolo_vibrato_stereo ;
 aux Data.adresse_etat_clavier ( 128 + Data.bouton_tremolo ) Data.tremolo_vibrato_stereo ;
 aux Data.adresse_etat_clavier ( 128 + Data.bouton_diff_tremolo ) Data.diff_tremolo_vibrato_stereo ;
 prerr_endline ( ( pourcent_cpu () ) ^ "vibrato rapide" ) ;;

let mono = fun (selection:select ref) (poussoir:int ref) (demi_lune:int ref) (reglages:int array) ->
 selection := Vibrato ;
 poussoir := 0 ;
 demi_lune := 0 ;
 reglages.(32) <- !poussoir ;
 reglages.(34) <- !demi_lune ;
 aux Data.adresse_etat_clavier ( 128 + Data.poussoir_vibrato_chorus ) !poussoir ;
 aux Data.adresse_etat_clavier ( 128 + Data.demi_lune ) !demi_lune ;
 prerr_endline ( ( pourcent_cpu () ) ^ "son droit" ) ;;

let clic = fun (poussoir_clic:int ref) (reglages:int array) (valeurs_clic:int array) ->
 poussoir_clic := ( succ !poussoir_clic ) mod ( succ ( Array.length valeurs_clic / 2 ) ) ;
 match !poussoir_clic with
 | 0 ->
  begin
   reglages.(Data.bouton_niveau_clic - Data.succ_nombre_de_curseurs) <- 0 ;
   aux Data.adresse_etat_clavier ( 128 + Data.bouton_niveau_clic ) 0 ;
   prerr_endline ( ( pourcent_cpu () ) ^ "arret du clic" ) ;
  end
 | x when x > 0 ->
  begin
   let i = ref ( 2 * ( pred x ) ) in
    reglages.(Data.bouton_niveau_clic - Data.succ_nombre_de_curseurs) <- valeurs_clic.(!i) ;
    aux Data.adresse_etat_clavier ( 128 + Data.bouton_niveau_clic ) valeurs_clic.(!i) ;
    incr i ;
    reglages.(Data.bouton_longueur_clic - Data.succ_nombre_de_curseurs) <- valeurs_clic.(!i) ;
    aux Data.adresse_etat_clavier ( 128 + Data.bouton_longueur_clic ) valeurs_clic.(!i) ;
    prerr_endline ( ( pourcent_cpu () ) ^ "clic " ^ ( string_of_int x ) ) ;
  end
 | _ -> () ;;

let percu = fun (poussoir_percu:int ref) (reglages:int array) (valeurs_percu:int array) ->
 poussoir_percu := ( succ !poussoir_percu ) mod ( succ ( Array.length valeurs_percu / 4 ) ) ;
 match !poussoir_percu with
 | 0 ->
  begin
   reglages.(Data.bouton_remanence - Data.succ_nombre_de_curseurs) <- 0 ;
   aux Data.adresse_etat_clavier ( 128 + Data.bouton_remanence ) 0 ;
   reglages.(Data.bouton_pente_remanence - Data.succ_nombre_de_curseurs) <- 0 ;
   aux Data.adresse_etat_clavier ( 128 + Data.bouton_pente_remanence ) 0 ;
   reglages.(Data.bouton_nervosite - Data.succ_nombre_de_curseurs) <- 64 ;
   aux Data.adresse_etat_clavier ( 128 + Data.bouton_nervosite ) 64 ;
   reglages.(Data.bouton_traine - Data.succ_nombre_de_curseurs) <- 64 ;
   aux Data.adresse_etat_clavier ( 128 + Data.bouton_traine ) 64 ;
   prerr_endline ( ( pourcent_cpu () ) ^ "percussion standard" ) ;
  end
 | x when x > 0 ->
  begin
   let i = ref ( 4 * ( pred x ) ) in
    reglages.(Data.bouton_remanence - Data.succ_nombre_de_curseurs) <- valeurs_percu.(!i) ;
    aux Data.adresse_etat_clavier ( 128 + Data.bouton_remanence ) valeurs_percu.(!i) ;
    incr i ;
    reglages.(Data.bouton_pente_remanence - Data.succ_nombre_de_curseurs) <- valeurs_percu.(!i) ;
    aux Data.adresse_etat_clavier ( 128 + Data.bouton_pente_remanence ) valeurs_percu.(!i) ;
    incr i ;
    reglages.(Data.bouton_nervosite - Data.succ_nombre_de_curseurs) <- valeurs_percu.(!i) ;
    aux Data.adresse_etat_clavier ( 128 + Data.bouton_nervosite ) valeurs_percu.(!i) ;
    incr i ;
    reglages.(Data.bouton_traine - Data.succ_nombre_de_curseurs) <- valeurs_percu.(!i) ;
    aux Data.adresse_etat_clavier ( 128 + Data.bouton_traine ) valeurs_percu.(!i) ;
    prerr_endline ( ( pourcent_cpu () ) ^ "percussion " ^ ( string_of_int x ) ) ;
  end
 | _ -> () ;;

let reverb = fun (poussoir_reverb:int ref) (reglages:int array) (valeurs_reverb:int array) ->
 poussoir_reverb := ( succ !poussoir_reverb ) mod ( succ ( Array.length valeurs_reverb / 2 ) ) ;
 match !poussoir_reverb with
 | 0 ->
  begin
   reglages.(Data.bouton_niveau_reverb - Data.succ_nombre_de_curseurs) <- 0 ;
   reglages.(Data.bouton_delai_reverb - Data.succ_nombre_de_curseurs) <- 127 ;
   aux Data.adresse_etat_clavier ( 128 + Data.bouton_niveau_reverb ) 0 ;
   aux Data.adresse_etat_clavier ( 128 + Data.bouton_delai_reverb ) 127 ;
   prerr_endline ( ( pourcent_cpu () ) ^ "arret de la reverberation" ) ;
  end
 | x when x > 0 ->
  begin
   let i = ref ( 2 * ( pred x ) ) in
    reglages.(Data.bouton_niveau_reverb - Data.succ_nombre_de_curseurs) <- valeurs_reverb.(!i) ;
    aux Data.adresse_etat_clavier ( 128 + Data.bouton_niveau_reverb ) valeurs_reverb.(!i) ;
    incr i ;
    reglages.(Data.bouton_delai_reverb - Data.succ_nombre_de_curseurs) <- valeurs_reverb.(!i) ;
    aux Data.adresse_etat_clavier ( 128 + Data.bouton_delai_reverb ) valeurs_reverb.(!i) ;
    prerr_endline ( ( pourcent_cpu () ) ^ "reverberation " ^ ( string_of_int x ) ) ;
  end
 | _ -> () ;;

let forme = fun (poussoir_forme:int ref) (reglages:int array) (valeurs_forme:int array) ->
 poussoir_forme := ( succ !poussoir_forme ) mod ( succ ( Array.length valeurs_forme / 6 ) ) ;
 match !poussoir_forme with
 | 0 ->
  begin
   reglages.(Data.bouton_niveau_inflexion - Data.succ_nombre_de_curseurs) <- 0 ;
   reglages.(Data.bouton_niveau_triangle - Data.succ_nombre_de_curseurs) <- 0 ;
   reglages.(Data.bouton_niveau_creneaux - Data.succ_nombre_de_curseurs) <- 0 ;
   aux Data.adresse_etat_clavier ( 128 + Data.bouton_niveau_inflexion ) 0 ;
   aux Data.adresse_etat_clavier ( 128 + Data.bouton_niveau_triangle ) 0 ;
   aux Data.adresse_etat_clavier ( 128 + Data.bouton_niveau_creneaux ) 0 ;
   prerr_endline ( ( pourcent_cpu () ) ^ "forme sinus" ) ;
  end
 | x when x > 0 ->
  begin
   let i = ref ( 6 * ( pred x ) ) in
    reglages.(Data.bouton_niveau_inflexion - Data.succ_nombre_de_curseurs) <- valeurs_forme.(!i) ;
    aux Data.adresse_etat_clavier ( 128 + Data.bouton_niveau_inflexion ) valeurs_forme.(!i) ;
    incr i ;
    reglages.(Data.bouton_inflexion - Data.succ_nombre_de_curseurs) <- valeurs_forme.(!i) ;
    aux Data.adresse_etat_clavier ( 128 + Data.bouton_inflexion ) valeurs_forme.(!i) ;
    incr i ;
    reglages.(Data.bouton_dephasage_inflexion - Data.succ_nombre_de_curseurs) <- valeurs_forme.(!i) ;
    aux Data.adresse_etat_clavier ( 128 + Data.bouton_dephasage_inflexion ) valeurs_forme.(!i) ;
    incr i ;
    reglages.(Data.bouton_niveau_triangle - Data.succ_nombre_de_curseurs) <- valeurs_forme.(!i) ;
    aux Data.adresse_etat_clavier ( 128 + Data.bouton_niveau_triangle ) valeurs_forme.(!i) ;
    incr i ;
    reglages.(Data.bouton_niveau_creneaux - Data.succ_nombre_de_curseurs) <- valeurs_forme.(!i) ;
    aux Data.adresse_etat_clavier ( 128 + Data.bouton_niveau_creneaux ) valeurs_forme.(!i) ;
    incr i ;
    reglages.(Data.bouton_dephasage_creneaux - Data.succ_nombre_de_curseurs) <- valeurs_forme.(!i) ;
    aux Data.adresse_etat_clavier ( 128 + Data.bouton_dephasage_creneaux ) valeurs_forme.(!i) ;
    prerr_endline ( ( pourcent_cpu () ) ^ "forme " ^ ( string_of_int x ) ) ;
  end
 | _ -> () ;;



(**

Foncteur d'absorption des données des fabricants

*)



module type Type_clavier = sig

val nom_clavier : string ;;

(** Prend la valeur true si la pédale sustain donne 0 à l'enfoncement et 127 au relâchement ; false dans le cas inverse. *)

val tenue : bool ;;

val alter_swell : int ;;
val alter_modulation : int ;;

val curseur_0 : int ;;
val curseur_1 : int ;;
val curseur_2 : int ;;
val curseur_3 : int ;;
val curseur_4 : int ;;
val curseur_5 : int ;;
val curseur_6 : int ;;
val curseur_7 : int ;;
val curseur_8 : int ;;
val curseur_9 : int ;;

val bouton_1 : int ;;
val bouton_2 : int ;;
val bouton_3 : int ;;
val bouton_4 : int ;;
val bouton_5 : int ;;
val bouton_6 : int ;;
val bouton_7 : int ;;
val bouton_8 : int ;;
val bouton_8bis : int ;;
val bouton_p1 : int ;;
val bouton_p2 : int ;;
val bouton_p3 : int ;;
val bouton_p4 : int ;;
val bouton_p5 : int ;;
val bouton_p6 : int ;;
val bouton_p7 : int ;;
val bouton_p8 : int ;;
val bouton_p9 : int ;;
val bouton_p10 : int ;;

val poussoir_boucle : int ;;
val poussoir_rembobine : int ;;
val poussoir_avance_rapide : int ;;
val poussoir_arret : int ;;
val poussoir_lecture : int ;;
val poussoir_enregistrement : int ;;
val poussoir_debut : int ;;
val poussoir_fin : int ;;

val poussoir_1 : int ;;
val poussoir_2 : int ;;
val poussoir_3 : int ;;
val poussoir_4 : int ;;
val poussoir_5 : int ;;
val poussoir_6 : int ;;
val poussoir_7 : int ;;
val poussoir_8 : int ;;
val poussoir_9 : int ;;
val poussoir_10 : int ;;
val poussoir_11 : int ;;
val poussoir_12 : int ;;

val pad_5 : int ;;
val pad_6 : int ;;
val pad_7 : int ;;
val pad_8 : int ;;

val vers_instru : int ;;

val pad1 : int ;;
val pad2 : int ;;
val pad3 : int ;;
val pad4 : int ;;
val pad5 : int ;;
val pad6 : int ;;
val pad7 : int ;;
val pad8 : int ;;

end ;;



module Make ( C:Type_clavier ) = struct


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

(** Note off event *)

let touche_relachee = 0x80 ;;

(** Note on event *)

let touche_appuyee = 0x90 ;;

(** Polyphonic key pressure/aftertouch *)

let poly_press = 0xA0 ;;

(** Controle change *)

let mode = 0xB0 ;;

(** Program change *)

let instru = 0xC0 ;;

(** Channel pressure/aftertouch *)

let can_press = 0xD0 ;;

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

let pitch = 0xE0 ;;
let pitch_mot_vide = 0x00

(** System messages *)

let sys = 0xF0 ;;


(**

Numéros de modes

*)



let modulation = 0x01 ;;
let swell = 0x0B ;;

(** Prend la valeur 0 à l'enfoncement et 127 au relâchement pour le réglage habituel : court-circuit au repos, pour une source M-audio ou Alesis. Pour une source Roland, c'est l'inverse. Les valeurs sont échangées pour le réglage inverse de la pédale. *)

let sustain_pedal = 0x40 ;;


(**

Scrutation de l'entrée MIDI

*)



let all_notes_off = function () ->
 let oc = open_out_gen [Open_binary ; Open_wronly] 0o644 Data.adresse_etat_clavier
 and chaine = String.make 128 ( char_of_int haut ) in
  output oc chaine 0 128 ;
  flush_all () ;
  close_out_noerr oc ;;



let scrute = fun ic ->
 let oc = open_out Data.adresse_etat_clavier
 and tirettes = Array.make 18 0
 and not_sustain = ref true
 and facteur_decalage = Data.nombre_de_parametres_clavier - Data.succ_nombre_de_curseurs
 and pred_facteur_decalage = Data.nombre_de_parametres_clavier - Data.succ_nombre_de_curseurs - 1
 and poussoir = ref 0
 and poussoir_mono = ref 0
 and poussoir_clic = ref 0
 and valeurs_clic = Data.valeurs_clic
 and poussoir_percu = ref 0
 and valeurs_percu = Data.valeurs_percu
 and poussoir_reverb = ref 0
 and valeurs_reverb = Data.valeurs_reverb
 and poussoir_forme = ref 0
 and valeurs_forme = Data.valeurs_forme
 and demi_lune = ref 0
 and c = ref 0
 and entete = ref 0
 and canal = ref 0
 and note = ref 0
 and controleur = ref 0
 and decalage = ref 0
 and selection = ref Vide in
  let reglages = Array.make facteur_decalage 0 in
   for i = 0 to 127 do
    output_byte oc haut ;
   done ;

(** pitch *)


   output_byte oc milieu ;

(** tirettes : modulation et curseurs *)


   for i = 0 to 8 do
    output_byte oc plein ;
   done ;
   for i = 0 to 8 do
    output_byte oc milieu ;
   done ;

(** bouton rotatifs swell et saturation *)


   for i = 0 to 1 do
    output_byte oc vide ;
   done ;

(** bouton rotatif inflexion *)


   output_byte oc milieu ;

(** boutons rotatifs *)


   for i = 3 to 8 do
    output_byte oc vide ;
   done ;

(** boutons rotatifs *)


   for i = 9 to 11 do
    output_byte oc vide ;
   done ;
   for j = 12 to 13 do
    output_byte oc milieu ;
   done ;
   for i = 14 to 19 do
    output_byte oc vide ;
   done ;

(** bouton rotatif diapason *)


   output_byte oc milieu ;

(** bouton rotatif octave *)


   output_byte oc vide ;

(** boutons rotatifs *)


   for i = 22 to 25 do
    output_byte oc milieu ;
   done ;
   for i = 26 to 27 do
    output_byte oc plein ;
   done ;

(** boutons rotatifs et poussoirs *)


   for i = 28 to 34 do
    output_byte oc vide ;
   done ;
   output_byte oc milieu ;

   close_out_noerr oc ;
    begin
     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 = touche_appuyee ->
        begin
         note := input_byte ic ;

(** vélocité *)


         c := input_byte ic ;
         if !c > 0 then
          begin
           if !canal = 9 then
            begin
             match !note with
             | z when z = C.pad1 ->
              begin
               if !selection = Special then
                begin
                 pouss_mono poussoir_mono reglages 1 ;
                 selection := Special ;
                end
               else if !selection = Lecture then
                clic poussoir_clic reglages valeurs_clic
               else
                lent selection poussoir demi_lune reglages
              end
             | z when z = C.pad2 ->
              begin
               if !selection = Special then
                begin
                 pouss_mono poussoir_mono reglages 2 ;
                 selection := Special ;
                end
               else if !selection = Lecture then
                percu poussoir_percu reglages valeurs_percu
               else
                frein selection poussoir demi_lune reglages
              end
             | z when z = C.pad3 ->
              begin
               if !selection = Special then
                begin
                 pouss_mono poussoir_mono reglages 3 ;
                 selection := Special ;
                end
               else if !selection = Lecture then
                reverb poussoir_reverb reglages valeurs_reverb
               else
                rapide selection poussoir demi_lune reglages
              end
             | z when z = C.pad4 ->
              begin
               if !selection = Special then
                begin
                 vc poussoir_mono reglages ;
                 selection := Special ;
                end
               else if !selection = Lecture then
                forme poussoir_forme reglages valeurs_forme
               else
                mono selection poussoir demi_lune reglages
              end
             | z when z = C.pad5 -> clic poussoir_clic reglages valeurs_clic
             | z when z = C.pad6 -> percu poussoir_percu reglages valeurs_percu
             | z when z = C.pad7 -> reverb poussoir_reverb reglages valeurs_reverb
             | z when z = C.pad8 -> forme poussoir_forme reglages valeurs_forme
             | _ -> () ;
            end
           else
            match !selection with
            | Rappel ->
             begin
              selection := Vide ;
              let ict = open_in_gen [Open_binary ; Open_rdonly] 0o400 Data.adresse_etat_jeux in
               decalage := 18 * !note ;
               seek_in ict !decalage ;
               for i = 0 to 17 do
                tirettes.(i) <- input_byte ict ;
               done ;
               close_in_noerr ict ;
               let oc = open_out_gen [Open_binary ; Open_wronly] 0o644 Data.adresse_etat_clavier in
                seek_out oc 129 ;
                for i = 0 to 17 do
                 output_byte oc tirettes.(i) ;
                done ;
                flush_all () ;
                close_out_noerr oc ;
                prerr_int !note ;
                prerr_newline () ;
                prerr_endline ( ( pourcent_cpu () ) ^ "mode vide" ) ;
             end
            | Rappel_boutons -> ( selection := Vide ; rappel_boutons decalage pred_facteur_decalage facteur_decalage reglages !note )
            | Sauvegarde ->
             begin
              selection := Vide ;
              let oc = open_out_gen [Open_binary ; Open_wronly] 0o644 Data.adresse_etat_jeux in
               decalage := 18 * !note ;
               seek_out oc !decalage ;
               for i = 0 to 17 do
                output_byte oc tirettes.(i) ;
               done ;
               flush_all () ;
               close_out_noerr oc ;
               prerr_int !note ;
               prerr_newline () ;
               prerr_endline ( ( pourcent_cpu () ) ^ "mode vide" ) ;
             end
            | Sauvegarde_boutons -> ( selection := Vide ; sauvegarde_boutons decalage pred_facteur_decalage facteur_decalage reglages !note )
            | _ ->
             begin
              if !not_sustain then
               aux Data.adresse_etat_clavier !note !c
              else

(** Quand la pédale sustain est enfoncée il faut signaler spécialement l'enfoncement d'une touche au cas où ce serait une répétition. *)


               aux Data.adresse_etat_clavier !note ( 255 - !c ) ;
             end ;
           end

(** vélocité nulle *)


         else if ( !canal <> 9 ) && !not_sustain then
          aux Data.adresse_etat_clavier !note haut ;
        end
       | x when x = touche_relachee ->
        begin
         note := input_byte ic ;

(** vélocité *)


         c := input_byte ic ;
         if ( !canal <> 9 ) && !not_sustain then
          aux Data.adresse_etat_clavier !note haut ;
        end
       | x when x = pitch ->
        begin

(** valeur nulle *)


         c := input_byte ic ;
         c := input_byte ic ;
         aux Data.adresse_etat_clavier 128 !c ;
        end
       | x when x = mode ->
        begin
         controleur := input_byte ic ;

(** valeur *)


         c := input_byte ic ;
         match !controleur with

(** all notes off *)


         | y when ( 123 <= y ) && ( y <= 127 ) -> all_notes_off ()

(** sustain pedal *)


         | y when y = sustain_pedal ->
          begin
           if C.tenue then
            begin
             if !c = 0 then
              not_sustain := false
             else
              begin
               not_sustain := true ;
               all_notes_off () ;
              end
            end
           else
            begin
             if !c = 0 then
              begin
               not_sustain := true ;
               all_notes_off () ;
              end
             else
              not_sustain := false
            end
          end

(** boutons curseurs *)


         | y when y = C.curseur_1 ->
          begin
           if !selection = Special then
            begin
             tirettes.(9) <- !c ;
             aux Data.adresse_etat_clavier 138 !c ;
            end
           else
            begin
             tirettes.(0) <- !c ;
             aux Data.adresse_etat_clavier 129 !c ;
            end
          end
         | y when y = C.curseur_2 ->
          begin
           if !selection = Special then
            begin
             tirettes.(10) <- !c ;
             aux Data.adresse_etat_clavier 139 !c ;
            end
           else
            begin
             tirettes.(1) <- !c ;
             aux Data.adresse_etat_clavier 130 !c ;
            end
          end
         | y when y = C.curseur_3 ->
          begin
           if !selection = Special then
            begin
             tirettes.(11) <- !c ;
             aux Data.adresse_etat_clavier 140 !c ;
            end
           else
            begin
             tirettes.(2) <- !c ;
             aux Data.adresse_etat_clavier 131 !c ;
            end
          end
         | y when y = C.curseur_4 ->
          begin
           if !selection = Special then
            begin
             tirettes.(12) <- !c ;
             aux Data.adresse_etat_clavier 141 !c ;
            end
           else
            begin
             tirettes.(3) <- !c ;
             aux Data.adresse_etat_clavier 132 !c ;
            end
          end
         | y when y = C.curseur_5 ->
          begin
           if !selection = Special then
            begin
             tirettes.(13) <- !c ;
             aux Data.adresse_etat_clavier 142 !c ;
            end
           else
            begin
             tirettes.(4) <- !c ;
             aux Data.adresse_etat_clavier 133 !c ;
            end
          end
         | y when y = C.curseur_6 ->
          begin
           if !selection = Special then
            begin
             tirettes.(14) <- !c ;
             aux Data.adresse_etat_clavier 143 !c ;
            end
           else
            begin
             tirettes.(5) <- !c ;
             aux Data.adresse_etat_clavier 134 !c ;
            end
          end
         | y when y = C.curseur_7 ->
          begin
           if !selection = Special then
            begin
             tirettes.(15) <- !c ;
             aux Data.adresse_etat_clavier 144 !c ;
            end
           else
            begin
             tirettes.(6) <- !c ;
             aux Data.adresse_etat_clavier 135 !c ;
            end
          end
         | y when y = C.curseur_8 ->
          begin
           if !selection = Special then
            begin
             tirettes.(16) <- !c ;
             aux Data.adresse_etat_clavier 145 !c ;
            end
           else
            begin
             tirettes.(7) <- !c ;
             aux Data.adresse_etat_clavier 136 !c ;
            end
          end
         | y when y = C.curseur_9 ->
          begin
           if !selection = Special then
            begin
             tirettes.(17) <- !c ;
             aux Data.adresse_etat_clavier 146 !c ;
            end
           else
            begin
             tirettes.(8) <- !c ;
             aux Data.adresse_etat_clavier 137 !c ;
            end
          end

(** swell *)


         | y when y = C.bouton_1 || y = swell || y = C.alter_swell || y = C.alter_modulation ->
          begin
           if !selection = Special then
            begin
             reglages.( Data.bouton_accent_spectral - Data.succ_nombre_de_curseurs ) <- !c ;
             aux Data.adresse_etat_clavier ( 128 + Data.bouton_accent_spectral ) !c
            end
           else
            begin
             reglages.(0) <- !c ;
             aux Data.adresse_etat_clavier ( 128 + Data.bouton_swell ) !c
            end
          end

(** saturation *)


         | y when y = C.bouton_8 || y = C.bouton_p10 ->
          begin
           reglages.(1) <- !c ;
           aux Data.adresse_etat_clavier ( 128 + Data.bouton_saturation ) !c
          end

(** boutons rotatifs *)


         | y when y = C.bouton_2 || y = C.bouton_p1 ->
          begin
           match !selection with
           | Forme -> ( reglages.(2) <- !c ; aux Data.adresse_etat_clavier ( 128 + Data.bouton_inflexion ) !c )
           | Percussion -> ( reglages.(8) <- !c ; aux Data.adresse_etat_clavier ( 128 + Data.bouton_longueur_clic ) !c )
           | Vibrato -> ( reglages.(14) <- !c ; aux Data.adresse_etat_clavier ( 128 + Data.bouton_diff_excursion_vibrato ) !c )
           | Filtrage -> ( reglages.(20) <- !c ; aux Data.adresse_etat_clavier ( 128 + Data.bouton_diapason ) !c )
           | Reverb -> ( reglages.(26) <- !c ; aux Data.adresse_etat_clavier ( 128 + Data.bouton_delai_reverb ) !c )
           | _ -> () ;
          end
         | y when y = C.bouton_3 || y = C.bouton_p2 ->
          begin
           match !selection with
           | Forme -> ( reglages.(3) <- !c ; aux Data.adresse_etat_clavier ( 128 + Data.bouton_dephasage_inflexion ) !c )
           | Percussion -> ( reglages.(9) <- !c ; aux Data.adresse_etat_clavier ( 128 + Data.bouton_remanence ) !c )
           | Vibrato -> ( reglages.(15) <- !c ; aux Data.adresse_etat_clavier ( 128 + Data.bouton_diff_basse_frequence ) !c )
           | Filtrage -> ( reglages.(21) <- !c ; aux Data.adresse_etat_clavier ( 128 + Data.bouton_octave ) !c )
           | Reverb -> ( reglages.(27) <- !c ; aux Data.adresse_etat_clavier ( 128 + Data.bouton_pli_haut ) !c )
           | _ -> () ;
          end
         | y when y = C.bouton_4 || y = C.bouton_p3 ->
          begin
           match !selection with
           | Forme -> ( reglages.(4) <- !c ; aux Data.adresse_etat_clavier ( 128 + Data.bouton_dephasage_creneaux ) !c )
           | Percussion -> ( reglages.(10) <- !c ; aux Data.adresse_etat_clavier ( 128 + Data.bouton_pente_remanence ) !c )
           | Vibrato -> ( reglages.(16) <- !c ; aux Data.adresse_etat_clavier ( 128 + Data.bouton_diff_dephasage_rotation ) !c )
           | Filtrage -> ( reglages.(22) <- !c ; aux Data.adresse_etat_clavier ( 128 + Data.bouton_rose ) !c )
           | Reverb -> ( reglages.(28) <- !c ; aux Data.adresse_etat_clavier ( 128 + Data.bouton_diff_tremolo ) !c )
           | _ -> () ;
          end
         | y when y = C.bouton_5 || y = C.bouton_p6 ->
          begin
           match !selection with
           | Forme -> ( reglages.(5) <- !c ; aux Data.adresse_etat_clavier ( 128 + Data.bouton_niveau_inflexion ) !c )
           | Percussion -> ( reglages.(11) <- !c ; aux Data.adresse_etat_clavier ( 128 + Data.bouton_niveau_clic ) !c )
           | Vibrato -> ( reglages.(17) <- !c ; aux Data.adresse_etat_clavier ( 128 + Data.bouton_excursion_vibrato ) !c )
           | Filtrage -> ( reglages.(23) <- !c ; aux Data.adresse_etat_clavier ( 128 + Data.bouton_coupure ) !c )
           | Reverb -> ( reglages.(29) <- !c ; aux Data.adresse_etat_clavier ( 128 + Data.bouton_niveau_reverb ) !c )
           | _ -> () ;
          end
         | y when y = C.bouton_6 || y = C.bouton_p7 ->
          begin
           match !selection with
           | Forme -> ( reglages.(6) <- !c ; aux Data.adresse_etat_clavier ( 128 + Data.bouton_niveau_triangle ) !c )
           | Percussion -> ( reglages.(12) <- !c ; aux Data.adresse_etat_clavier ( 128 + Data.bouton_nervosite ) !c )
           | Vibrato -> ( reglages.(18) <- !c ; aux Data.adresse_etat_clavier ( 128 + Data.bouton_basse_frequence ) !c )
           | Filtrage -> ( reglages.(24) <- !c ; aux Data.adresse_etat_clavier ( 128 + Data.bouton_timbre ) !c )
           | Reverb -> ( reglages.(30) <- !c ; aux Data.adresse_etat_clavier ( 128 + Data.bouton_pli_bas ) !c )
           | _ -> () ;
          end
         | y when y = C.bouton_7 || y = C.bouton_p8 ->
          begin
           match !selection with
           | Forme -> ( reglages.(7) <- !c ; aux Data.adresse_etat_clavier ( 128 + Data.bouton_niveau_creneaux ) !c )
           | Percussion -> ( reglages.(13) <- !c ; aux Data.adresse_etat_clavier ( 128 + Data.bouton_traine ) !c )
           | Vibrato -> ( reglages.(19) <- !c ; aux Data.adresse_etat_clavier ( 128 + Data.bouton_dephasage_rotation ) !c )
           | Filtrage -> ( reglages.(25) <- !c ; aux Data.adresse_etat_clavier ( 128 + Data.bouton_equilibre ) !c )
           | Reverb -> ( reglages.(31) <- !c ; aux Data.adresse_etat_clavier ( 128 + Data.bouton_tremolo ) !c )
           | _ -> () ;
          end
         | y when y = C.bouton_8bis || y = C.curseur_0 ->
          begin
           if !selection = Special then
            begin
             let position = ( min 125 !c ) / 18 in
              if !poussoir_mono <> position then
               begin
                poussoir_mono := ( 6 + position ) mod 7 ;
                vc poussoir_mono reglages ;
               end ;
            end
           else
            begin
             let position = !c / 32 in
              if !demi_lune <> position then
               match position with
               | 0 -> mono selection poussoir demi_lune reglages
               | 1 -> lent selection poussoir demi_lune reglages
               | 2 -> frein selection poussoir demi_lune reglages
               | _ -> rapide selection poussoir demi_lune reglages
            end
          end

(** Les claviers Arturia offrent plus de boutons. *)


         | y when y = C.bouton_p4 ->
          begin
           match !selection with
           | Percussion -> ( reglages.(26) <- !c ; aux Data.adresse_etat_clavier ( 128 + Data.bouton_delai_reverb ) !c )
           | Vibrato -> ( reglages.(28) <- !c ; aux Data.adresse_etat_clavier ( 128 + Data.bouton_diff_tremolo ) !c )
           | Forme -> ( reglages.(20) <- !c ; aux Data.adresse_etat_clavier ( 128 + Data.bouton_diapason ) !c )
           | Filtrage -> ( reglages.(27) <- !c ; aux Data.adresse_etat_clavier ( 128 + Data.bouton_pli_haut ) !c )
           | _ -> () ;
          end
         | y when y = C.bouton_p5 ->
          begin
           match !selection with
           | Vibrato -> ( reglages.(25) <- !c ; aux Data.adresse_etat_clavier ( 128 + Data.bouton_equilibre ) !c )
           | Percussion -> ( reglages.(23) <- !c ; aux Data.adresse_etat_clavier ( 128 + Data.bouton_coupure ) !c )
           | Forme -> ( reglages.(22) <- !c ; aux Data.adresse_etat_clavier ( 128 + Data.bouton_rose ) !c )
           | _ -> () ;
          end
         | y when y = C.bouton_p9 ->
          begin
           match !selection with
           | Percussion -> ( reglages.(29) <- !c ; aux Data.adresse_etat_clavier ( 128 + Data.bouton_niveau_reverb ) !c )
           | Vibrato -> ( reglages.(31) <- !c ; aux Data.adresse_etat_clavier ( 128 + Data.bouton_tremolo ) !c )
           | Forme -> ( reglages.(24) <- !c ; aux Data.adresse_etat_clavier ( 128 + Data.bouton_timbre ) !c )
           | Filtrage -> ( reglages.(30) <- !c ; aux Data.adresse_etat_clavier ( 128 + Data.bouton_pli_bas ) !c )
           | _ -> () ;
          end

(** Les claviers Arturia offrent des coussinets percussifs (pads) qui envoient des trains de messages de contrôleurs. Un unique mot par manipulation du coussinet contient la valeur 0. *)


         | y when y = C.pad_5 && !c = 0 -> clic poussoir_clic reglages valeurs_clic
         | y when y = C.pad_6 && !c = 0 -> percu poussoir_percu reglages valeurs_percu
         | y when y = C.pad_7 && !c = 0 -> reverb poussoir_reverb reglages valeurs_reverb
         | y when y = C.pad_8 && !c = 0 -> forme poussoir_forme reglages valeurs_forme
(** boutons-poussoirs de transport *)


         | y when y = C.poussoir_boucle ->
          begin
           if !c > 0 then
            begin
             if !selection = Rembobine then
              begin
               prerr_endline "Le pianel est arrete." ;
               ignore ( Sys.command ( "killall PIANEL & killall " ^ C.nom_clavier ) ) ;
              end
             else if !selection = Special then
              begin
               selection := Reverb ;
               prerr_endline ( ( pourcent_cpu () ) ^ "mode reverberation" ) ;
              end
             else if !selection = Lecture then
              vc poussoir_mono reglages
             else
              begin
               selection := Vibrato ;
               demi_lune := 0 ;
               poussoir := ( succ !poussoir ) mod Data.modulo_vibrato ;
               reglages.(32) <- !poussoir ;
               reglages.(34) <- !demi_lune ;
               aux Data.adresse_etat_clavier ( 128 + Data.poussoir_vibrato_chorus ) !poussoir ;
               aux Data.adresse_etat_clavier ( 128 + Data.demi_lune ) !demi_lune ;
               let chaine = match !poussoir with
               | 0 -> "son droit"
               | 1 -> "vibrato"
               | _ -> "chorus" in
                prerr_endline ( ( pourcent_cpu () ) ^ chaine ) ;
              end ;
            end ;
          end
         | y when y = C.poussoir_rembobine ->
          begin
           if !c > 0 then
            begin
             if !selection = Avance_rapide then
              begin
               selection := Rembobine ;
               prerr_endline "Arret du pianel : taper sur BOUCLE." ;
              end
             else if !selection = Special then
              begin
               selection := Rappel_boutons ;
               prerr_endline ( ( pourcent_cpu () ) ^ "rappel de reglages" ) ;
              end
             else
              begin
               selection := Rappel ;
               prerr_endline ( ( pourcent_cpu () ) ^ "rappel de jeux" ) ;
              end
            end
          end
         | y when y = C.poussoir_avance_rapide ->
          begin
           if !c > 0 then
            begin
             if !selection = Arret then
              begin
               selection := Avance_rapide ;
               prerr_endline "Arret du pianel : taper sur REMBOBINAGE." ;
              end
             else if !selection = Special then
              begin
               selection := Sauvegarde_boutons ;
               prerr_endline ( ( pourcent_cpu () ) ^ "enregistrement de reglages" ) ;
              end
             else
              begin
               selection := Sauvegarde ;
               prerr_endline ( ( pourcent_cpu () ) ^ "enregistrement de jeux" ) ;
              end
            end
          end
         | y when y = C.poussoir_debut ->
          if !c > 0 then demande_rappel_boutons selection ;
         | y when y = C.poussoir_fin ->
          if !c > 0 then demande_sauvegarde_boutons selection ;
         | y when y = C.poussoir_arret ->
          begin
           if !c > 0 then
            begin
             if !selection = Lecture then
              begin
               selection := Arret ;
               prerr_endline "Arret du pianel : taper sur AVANCE RAPIDE." ;
              end
             else if !selection = Special then
              begin
               selection := Filtrage ;
               prerr_endline ( ( pourcent_cpu () ) ^ "mode filtrage-equilibrage" ) ;
              end
             else
              begin
               selection := Forme ;
               prerr_endline ( ( pourcent_cpu () ) ^ "mode forme" ) ;
              end
            end
          end
         | y when y = C.poussoir_lecture ->
          begin
           if !c > 0 then
            begin
             if !selection = Special then
              begin
               selection := Lecture ;
               prerr_endline ( ( pourcent_cpu () ) ^ "Mode lecture.\n Arret du pianel : taper sur ARRET.\n Vibrato/chorus mono 1, 2 ou 3 : taper sur BOUCLE.\n Clic : Pad1 ou bouton-poussoir 1 ; percussion : Pad2 ou bouton-poussoir 2 ; reverberation : Pad3 ou bouton-poussoir 3 ; forme : Pad4 ou bouton-poussoir 4." ) ;
              end
             else
              begin
               selection := Percussion ;
               prerr_endline ( ( pourcent_cpu () ) ^ "mode percussion" ) ;
              end
            end
          end
         | y when y = C.poussoir_enregistrement ->
          if !c > 0 then
           begin
            if !selection = Special then
             begin
              selection := Vide ;
              prerr_endline ( ( pourcent_cpu () ) ^ "mode vide" ) ;
             end
            else
             begin
              selection := Special ;
              prerr_endline ( ( pourcent_cpu () ) ^ "mode special" ) ;
             end
           end

(** boutons-poussoirs numérotés *)


         | y when y = C.poussoir_4 ->
          begin
           if !c > 0 then
            begin
             if !selection = Special then
              begin
               mono selection poussoir demi_lune reglages ;
               selection := Special ;
              end
             else if !selection = Lecture then
              forme poussoir_forme reglages valeurs_forme
             else
              vc poussoir_mono reglages
            end
          end
         | y when y = C.poussoir_1 ->
          begin
           if !c > 0 then
            begin
             if !selection = Special then
              begin
               lent selection poussoir demi_lune reglages ;
               selection := Special ;
              end
             else if !selection = Lecture then
              clic poussoir_clic reglages valeurs_clic
             else
              pouss_mono poussoir_mono reglages 1
            end
          end
         | y when y = C.poussoir_2 ->
          begin
           if !c > 0 then
            begin
             if !selection = Special then
              begin
               frein selection poussoir demi_lune reglages ;
               selection := Special ;
              end
             else if !selection = Lecture then
              percu poussoir_percu reglages valeurs_percu
             else
              pouss_mono poussoir_mono reglages 2
            end
          end
         | y when y = C.poussoir_3 ->
          begin
           if !c > 0 then
            begin
             if !selection = Special then
              begin
               rapide selection poussoir demi_lune reglages ;
               selection := Special ;
              end
             else if !selection = Lecture then
              reverb poussoir_reverb reglages valeurs_reverb
             else
              pouss_mono poussoir_mono reglages 3
            end
          end
         | y when y = C.poussoir_5 ->
          begin
           if !c > 0 then
            clic poussoir_clic reglages valeurs_clic
          end
         | y when y = C.poussoir_6 ->
          begin
           if !c > 0 then
            percu poussoir_percu reglages valeurs_percu
          end
         | y when y = C.poussoir_7 ->
          begin
           if !c > 0 then
            reverb poussoir_reverb reglages valeurs_reverb
          end
         | y when y = C.poussoir_8 ->
          begin
           if !c > 0 then
            forme poussoir_forme reglages valeurs_forme
          end
         | _ -> ()
        end
       | x when x = instru ->
        begin
         c := input_byte ic ;
         match !c with
         | 0 ->
          begin
           if !selection = Special then
            begin
             lent selection poussoir demi_lune reglages ;
             selection := Special ;
            end
           else if !selection = Lecture then
            clic poussoir_clic reglages valeurs_clic
           else
            pouss_mono poussoir_mono reglages 1
          end
         | 1 ->
          begin
           if !selection = Special then
            begin
             frein selection poussoir demi_lune reglages ;
             selection := Special ;
            end
           else if !selection = Lecture then
            percu poussoir_percu reglages valeurs_percu
           else
            pouss_mono poussoir_mono reglages 2
          end
         | 2 ->
          begin
           if !selection = Special then
            begin
             rapide selection poussoir demi_lune reglages ;
             selection := Special ;
            end
           else if !selection = Lecture then
            reverb poussoir_reverb reglages valeurs_reverb
           else
            pouss_mono poussoir_mono reglages 3
          end
         | 3 ->
          begin
           if !selection = Special then
            begin
             mono selection poussoir demi_lune reglages ;
             selection := Special ;
            end
           else if !selection = Lecture then
            forme poussoir_forme reglages valeurs_forme
           else
            vc poussoir_mono reglages
          end
         | 4 -> clic poussoir_clic reglages valeurs_clic
         | 5 -> percu poussoir_percu reglages valeurs_percu
         | 6 -> reverb poussoir_reverb reglages valeurs_reverb
         | 7 -> demande_rappel_boutons selection
         | 8 -> demande_sauvegarde_boutons selection
         | _ -> () ;
        end
       | _ -> ()
      done
     with End_of_file -> close_in_noerr ic ;
    end ;
    Sys.remove Data.adresse_etat_clavier ;;



end ;;



end