struct



(**

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




(**

Commande d'oisiveté

*)



let sommeil = ( 0 = Sys.command "TEST=`time -p sleep 0.5 2>&1 | head -n 1 | sed 's/real //'`
NOMBRE=`echo \"2 * $TEST < 1\" | bc`
exit $NOMBRE"
 ) ;;

let passe_temps = function () ->
 if sommeil then
  ignore ( Sys.command "sleep 0.001" )
 else
  ignore ( tan 2. ) ;;


(**

Données générales

*)



let adresse_forme = "../lib/forme"
let adresse_rotation = "/tmp/syntheBB/ROTATION" ;;
let adresse_etat_clavier = "/tmp/syntheBB/etatClavier" ;;
let adresse_etat_synthe = "/tmp/syntheBB/etatSynthe" ;;
let adresse_etat_jeux = "/tmp/syntheBB/etatJeux" ;;
let adresse_etat_reglages = "/tmp/syntheBB/etatReglages" ;;
let adresse_archive_jeux = "../syntheBBrc/etatJeux" ;;
let adresse_archive_reglages = "../syntheBBrc/etatReglages" ;;
let adresse_rotation_bf = "../syntheBBrc/rotation_bf" ;;
let adresse_entete = "../syntheBBrc/entete" ;;

let frequence_d_echantillonnage = 44100 ;; 
     (** 44100 = ( 2 * 3 * 5 * 7 ) ^ 2 *)


(** let taille_d_echantillon = 441 ;; let taille_d_echantillon = 882 ;; let taille_d_echantillon = 1536 ;; let taille_d_echantillon = 1764 ;; let taille_d_echantillon = 4410 ;; *)


let taille_d_echantillon = 882 ;;
let pred_taille_d_echantillon = pred taille_d_echantillon ;;
let taille_d_echantillon_reelle = float taille_d_echantillon ;;
let pred_taille_d_echantillon_reelle = float pred_taille_d_echantillon ;;
let duree_d_echantillon = taille_d_echantillon_reelle /. (float frequence_d_echantillonnage ) ;;
let duree_d_attaque = max 1 ( int_of_float ( 0.2 /. duree_d_echantillon ) ) ;;

let taille_de_forme = 6_000 ;;
let pred_taille_de_forme = pred taille_de_forme ;;
let coefficient_de_forme = 1e-3 ;;
let max_de_forme = ( 0.5 *. log 3. ) /. coefficient_de_forme ;;
let coeff_traine = 6. *. max_de_forme /. duree_d_echantillon ;;

(** Constantes de dosage entre deux quantités pour un paramètre variant de 0 à 127 avec une perception logarithmique. *)

let pas = 0.989228013193975464 ;; 
     (** 0.5 ^ ( 1/64 ) *)

let pas2 = 0.97857206208770009 ;; 
     (** 0.5 ^ ( 1/32 ) *)

let pas4 = 0.9576032806985737 ;; 
     (** 0.5 ^ ( 1/16 ) *)

let pas8 = 0.917004043204671215 ;; 
     (** 0.5 ^ ( 1/8 ) *)

let pas16 = 0.840896415253714613 ;; 
     (** 0.5 ^ ( 1/4 ) *)

let pas32 = 0.707106781186547573 ;; 
     (** 0.5 ^ ( 1/2 ) *)

let pas64 = 0.5 ;;
let antipas = 0.0107719868060245361 ;; 
     (** 1 - pas *)

let antipas2 = 0.0214279379122999103 ;; 
     (** 1 - pas2 *)

let antipas4 = 0.0423967193014263 ;; 
     (** 1 - pas4 *)

let antipas8 = 0.0829959567953287847 ;; 
     (** 1 - pas8 *)

let antipas16 = 0.159103584746285387 ;; 
     (** 1 - pas16 *)

let antipas32 = 0.292893218813452427 ;; 
     (** 1 - pas32 *)

let antipas64 = 0.5 ;; 
     (** 1 - pas64 *)


let coefficient_gain = 0.947463525655375394 ;; 
     (** coefficient_gain ^ 64 correspond à 10 ^ (-1.5) c'est-à-dire -30 dBV. *)

let coefficient_rapide = coefficient_gain *. coefficient_gain ;;
let coefficient_tirettes = sqrt coefficient_gain ;;
let coefficient_lent = 1. -. 1e-4 ;;

let coeff_excursion_vibrato = ( float frequence_d_echantillonnage ) *. 0.00898842822301309206 ;; 
          (** 300 microsecondes ou 22.05 points d'échantillonnage de retard pour la valeur MIDI 64 *)


let coefficient_coupure = 0.861328125 ;; 
     (** 44100. /. ( 800. *. 64. ) *)


(** Dans la norme general midi, le la du diapason (440 à 442 hz) porte le numéro 69, et le do en-dessous (do médian) le numéro 60. *)


let excursion_pitch = 1.00364273704211771 ;; 
     (** 2.01 ^ (1/(64*3)). La fréquence du la du diapason est excursion ^ ( parametres.(molette_pitch) - 64 ) * f0 où f0 est la fréquence du la du diapason (=~= 441hz). Ceci donne une excursion maximale de 2 tons du diapason (pitch bend). *)


let coefficient_diapason = 1.00090944287864625 ;; 
     (** 2.01 ^ (1/(64*12)). La fréquence du la du diapason avec molette de pitch au repos est coefficient_diapason ^ ( parametres.(bouton_diapason) - 64 ) * 441 hz. Ceci donne une excursion maximale d'un demi-ton. *)


(** L'octave correspond à une multiplication de la fréquence par une valeur proche de 2. Les coefficients multiplicateurs de la fréquence pour monter ou descendre d'un demi-ton en découlent. *)

let un_douzieme = 0.0833333333333333333 ;;
let inv_127 = 1. /. 127. ;;
let inv_16129 = 1. /. 16129. ;;

(** Avec 0.35 l'amplitude est limitée ; elle devrait rester entre -1 et 1 si aucun effet n'est rajouté. *)

let rose_zero = 0.35 ;;

let modulo_vibrato = 3 ;;
let modulo_vibrato_mono = 7 ;;
let angle_mini = 0.049473900056532176 ;; 
     (** 2 * pi / 127.0 *)


let pi_sur_quatre = atan 1. ;;
let pi_sur_deux = 2. *. pi_sur_quatre ;;
let pi = 4. *. pi_sur_quatre ;;

let facteur_pulsation = 2. *. pi /. ( float frequence_d_echantillonnage ) ;;
let facteur_triangle = 2. /. pi ;;
let cos_vc = cos ( facteur_pulsation *. 412. /. 60. ) ;;
let sin_vc = sin ( facteur_pulsation *. 412. /. 60. ) ;;

let nombre_de_parametres_clavier = 54 ;;
let nombre_de_curseurs = 18 ;;
let succ_nombre_de_curseurs = succ nombre_de_curseurs ;;

let coefficient_octave = 0.00015625 ;; 
     (** COEFFICIENT_OCTAVE = 1/6400. L'octave correspond à une multiplication de la fréquence par 2 + COEFFICIENT_OCTAVE * parametres.(bouton_octave). Ceci donne 2 pour 0 ; 2.01 pour 64 et 2.01984375 pour 127. *)


let coeff_delai = ( float taille_d_echantillon ) /. 127.0 ;;


(**

Numéros des paramètres de commande

*)


let molette_pitch = 0 ;;

(** molette modulation ou curseur 0 *)

let tirette0 = 1 ;;
let tirette9 = 10 ;;

(** curseur 1 *)

let tirette1 = 2 ;;
let tirette10 = 11 ;;

(** curseur 2 *)

let tirette2 = 3 ;;
let tirette11 = 12 ;;

(** curseur 3 *)

let tirette3 = 4 ;;
let tirette12 = 13 ;;

(** curseur 4 *)

let tirette4 = 5 ;;
let tirette13 = 14 ;;

(** curseur 5 *)

let tirette5 = 6 ;;
let tirette14 = 15 ;;

(** curseur 6 *)

let tirette6 = 7 ;;
let tirette15 = 16 ;;

(** curseur 7 *)

let tirette7 = 8 ;;
let tirette16 = 17 ;;

(** curseur 8 *)

let tirette8 = 9 ;;
let tirette17 = 18 ;;

(** bouton 1 *)

let bouton_swell = 19 ;;

(** bouton 8 *)

let bouton_saturation = 20 ;;

(** bouton 2 *)

let bouton_inflexion = 21 ;;

(** bouton 3 *)

let bouton_dephasage_inflexion = 22 ;;

(** bouton 4 *)

let bouton_dephasage_creneaux = 23 ;;

(** bouton 5 *)

let bouton_niveau_inflexion = 24 ;;

(** bouton 6 *)

let bouton_niveau_triangle = 25 ;;

(** bouton 7 *)

let bouton_niveau_creneaux = 26 ;;

(** bouton 2 *)

let bouton_longueur_clic = 27 ;;

(** Les boutons 3, 4, 6, 7 sont définis différemment de l'orgue. *)


(** bouton 3 *)

let bouton_remanence = 28 ;;

(** bouton 4 *)

let bouton_pente_remanence = 29 ;;

(** bouton 5 *)

let bouton_niveau_clic = 30 ;;

(** bouton 6 *)

let bouton_nervosite = 31 ;;

(** bouton 7 *)

let bouton_traine = 32 ;;

(** bouton 2 *)

let bouton_diff_excursion_vibrato = 33 ;;

(** bouton 3 *)

let bouton_diff_basse_frequence = 34 ;;

(** bouton 4 *)

let bouton_diff_dephasage_rotation = 35 ;;

(** bouton 5 *)

let bouton_excursion_vibrato = 36 ;;

(** bouton 6 *)

let bouton_basse_frequence = 37 ;;

(** bouton 7 *)

let bouton_dephasage_rotation = 38 ;;

(** bouton 2 *)

let bouton_diapason = 39 ;;

(** bouton 3 *)

let bouton_octave = 40 ;;

(** bouton 4 *)

let bouton_rose = 41 ;;

(** bouton 5 *)

let bouton_coupure = 42 ;;

(** bouton 6 *)

let bouton_timbre = 43 ;;

(** bouton 7 *)

let bouton_equilibre = 44 ;;

(** bouton 2 *)

let bouton_delai_reverb = 45 ;;

(** bouton 3 *)

let bouton_pli_haut = 46 ;;

(** bouton 4 *)

let bouton_diff_tremolo = 47 ;;

(** bouton 5 *)

let bouton_niveau_reverb = 48 ;;

(** bouton 6 *)

let bouton_pli_bas = 49 ;;

(** bouton 7 *)

let bouton_tremolo = 50 ;;

(** boucle ; modulo modulo_vibrato *)

let poussoir_vibrato_chorus = 51 ;;

(** boucle ; modulo modulo_vibrato_mono *)

let poussoir_vibrato_mono_chorus = 52 ;;

(** pads 1, 2, 3 ou poussoirs 5, 6, 7 ; annulation par Pad4 ( valeur modulo 4 ) *)

let demi_lune = 53 ;;


(**

Valeurs des tirettes en demi-tons d'écart par rapport à la fondamentale

*)



let tirettes = [| -12 ; 7 ; 0 ; 12 ; 19 ; 24 ; 28 ; 31 ; 36 |] ;;


(**

Fabrication des fréquences, décroissances d'amplitudes, rotations, enveloppes

*)



let pulsation = fun (diapason:float) (octave:float) (parametre_rose:float) (destination:string) ->
 let oc = open_out destination
 and excursion = parametre_rose -. 64.
 and sof = string_of_float
 and demi_ton = octave ** un_douzieme in
  let anti_demi_ton = 1. /. demi_ton
  and frequences = Array.make 128 0. in
   let coefficient_rose = anti_demi_ton ** ( 0.5 +. 0.0025 *. excursion )
   and k = ref 69
   and rose = ref ( rose_zero *. demi_ton ** ( 0.16 *. excursion  ) ) in
    frequences.(!k) <- diapason ;
    for i = 70 to 127 do
     frequences.(i) <- frequences.(!k) *. demi_ton ;
     k := i ;
    done ;
    k := 69 ;
    for i = 68 downto 0 do
     frequences.(i) <- frequences.(!k) *. anti_demi_ton ;
     k := i ;
    done ;
    for i = 0 to 127 do
     let pouls = facteur_pulsation *. frequences.(i) in
      let c0 =  cos ( pouls *. taille_d_echantillon_reelle )
      and s0 = sin ( pouls *. taille_d_echantillon_reelle )
      and c = cos ( pouls )
      and s = sin ( pouls ) in
       rose := !rose *. coefficient_rose ;
       output_string oc ( ( sof c0 ) ^ "\n" ^ ( sof s0 ) ^ "\n" ^ ( sof c ) ^ "\n" ^ ( sof s ) ^ "\n" ^ ( sof !rose ) ^ "\n" ^ ( sof pouls ) ^ "\n" ) ;
    done ;
    close_out_noerr oc ;;

let generation_bf = function (destination:string) ->
 let oc = open_out destination
 and k = ref 127
 and sof = string_of_float
 and anti_demi_ton = 0.5 ** un_douzieme
 and frequences = Array.make 128 0. in
  frequences.(!k) <- 1e3 ;
  for i = 126 downto 0 do
   frequences.(i) <- frequences.(!k) *. anti_demi_ton ;
   k := i ;
  done ;
  for i = 0 to 127 do
   let pouls = facteur_pulsation *. frequences.(i) in
    let c = cos ( pouls )
    and s = sin ( pouls ) in
     output_string oc ( ( sof c ) ^ "\n" ^ ( sof s ) ^ "\n" ) ;
  done ;
  close_out_noerr oc ;;

let enveloppe = fun (forme:float array) (decalage:float) (nervosite:float) (remanence:float) (age:float) ->
 if age <= 0. then
  0.
 else
  begin
   let u = age *. nervosite in
    let position_debut = ( u <= max_de_forme ) in
     let t = if position_debut then u else age +. decalage in
      let ii = int_of_float t in
       let i = min pred_taille_de_forme ii
       and z = t -. ( float ii ) in
        let x = forme.(i)
        and j = min pred_taille_de_forme ( succ i ) in
         let y = forme.(j) in
          remanence +. ( 1. -. remanence ) *. ( z *. y +. ( 1. -. z ) *. x )
  end ;;


(**

Préréglages

*)



let excursion_vibrato_stereo = 70 ;;
let diff_excursion_vibrato_stereo = 20 ;;
let dephasage_rotation_vibrato_stereo = 16 ;;
let diff_dephasage_rotation_vibrato_stereo = 0 ;;
let tremolo_vibrato_stereo = 100 ;;
let diff_tremolo_vibrato_stereo = 8 ;;
let basse_frequence_grave_vibrato_stereo_lent = 52. ;;
let basse_frequence_aigue_vibrato_stereo_lent = 52. ;;
let basse_frequence_grave_vibrato_stereo_rapide = 86. ;;
let basse_frequence_aigue_vibrato_stereo_rapide = 89. ;;
let valeurs_clic = [| 80 ; 100 ; 100 ; 48 ; 127 ; 32 |] ;;
let valeurs_percu = [| 64 ; 0 ; 64 ; 64 ; 96 ; 0 ; 64 ; 64 ; 127 ; 0 ; 64 ; 64 ; 64 ; 32 ; 64 ; 64 ; 96 ; 32 ; 64 ; 64 ; 127 ; 32 ; 64 ; 64 ; 64 ; 64 ; 64 ; 64 ; 96 ; 64 ; 64 ; 64 ; 127 ; 64 ; 64 ; 64 ;
 0 ; 0 ; 0 ; 85 ; 64 ; 0 ; 0 ; 85 ; 96 ; 0 ; 0 ; 85 ; 127 ; 0 ; 0 ; 85 ; 64 ; 32 ; 0 ; 85 ; 96 ; 32 ; 0 ; 85 ; 127 ; 32 ; 0 ; 85 ; 64 ; 64 ; 0 ; 85 ; 96 ; 64 ; 0 ; 85 ; 127 ; 64 ; 0 ; 85 ;
 0 ; 0 ; 127 ; 48 ; 64 ; 0 ; 127 ; 48 ; 96 ; 0 ; 127 ; 48 ; 127 ; 0 ; 127 ; 48 ; 64 ; 32 ; 127 ; 48 ; 96 ; 32 ; 127 ; 48 ; 127 ; 32 ; 127 ; 48 ; 64 ; 64 ; 127 ; 48 ; 96 ; 64 ; 127 ; 48 ; 127 ; 64 ; 127 ; 48 |] ;;
let valeurs_reverb = [| 108 ; 32 ; 102 ; 127 ; 115 ; 127 |] ;;
let valeurs_forme = [| 64 ; 64 ; 32 ; 0 ; 0 ; 0 ; 0 ; 0 ; 0 ; 127 ; 0 ; 0 ; 0 ; 0 ; 0 ; 0 ; 32 ; 16 ; 64 ; 64 ; 32 ; 64 ; 0 ; 0 ; 64 ; 32 ; 32 ; 0 ; 10 ; 16 ; 64 ; 96 ; 64 ; 84 ; 16 ; 16 |] ;;




end