Code appli midi

Programmation d'applications complexes
Avatar de l’utilisateur
microdevweb
Messages : 1798
Inscription : mer. 29/juin/2011 14:11
Localisation : Belgique

Code appli midi

Message par microdevweb »

Voici un code pour obtenir ceci

Image

Le lien pour le fichier midi

https://www.mediafire.com/?17wr783jnfmu9i7

Et enfin le code

Code : Tout sélectionner

; ***************************************************************************************************************
; Easy-musique 1.0
; 
; Debut: 21 mars 2014
; Fin :
; Version PB: 5.22
;  © www.AllDev.be  Dévellopeur Bielen Pierre
; ***************************************************************************************************************
midiFile$="Fly.mid"
Declare AttachProcess(Instance)
Declare DetachProcess(Instance)
Declare AttachThread(Instance)
Declare DetachThread(Instance)
Declare LOAD_MIDI(midiFile$)
Declare Decode_Midi(file_name.s)
Declare ReadHexa(Nb_Octet)
Declare Get_Delai()
Declare Get_Action()
Declare Get_Premier_Octave()
Declare Get_Dernier_Octave()
Declare Decode_Note(Note_On.b,Num_Piste.l)
Declare Dessine_Clavier(Premier_Octave,Nbr_Octave,Pourcentage_Hauteur.f)
Declare Get_Position_Touche(Note.s,Octave.l)
Declare Get_Num_Note()
Declare Affiche_Clavier()
Declare SendMIDIMessage(nStatus.l,nCanal.l,nData1.l,nData2.l)
Declare MIDIOpen()
Declare PlayNoteMIDI(Canal.b,Note.b,VelociteDown.b,VelociteUp.b)
Declare ChargeInstrument(Canal.b,Instrument.b)
Declare Init_partition()
Declare Affiche_Info_Partition()
Declare Positionne_Note()
Declare Affiche_Sprite()
Declare Colorise_Clavier()
Declare Teste_Fin_Partition ()
Declare ErazeData()
Declare Open_Windows_Play()
Global TxtRetour$

Structure Midi_File
      Type_Midi.l
      Nbr_Piste.l
      Division_Noir.l
      Longueur_piste.l
      Titre.s
      Duree.l
EndStructure
Global monMidi_File.Midi_File
Structure Note_Musique
      Depart.l
      Duree.l
      Octave.l
      Velocite.l
      Note.s
      OnOf.b
      Piste.l
      PosX.l
      PosY.l
      Hauteur.l
      ID_Sprite.l
      Play.b
      Note_Valeur.l
EndStructure
Global NewList mesNote_Musique.Note_Musique()
Structure Signature_Temps
      Depart.l
      Numerateur.l
      Denominateur.l
      Metronome.l
      Nb_triple_Croche.l
EndStructure
Global NewList mesSignature_de_temps.Signature_Temps()
Structure Armature
      Depart.l
      Armature_portee.l
EndStructure
Structure Tempo
      Depart.l
      Tempo.l
EndStructure
Global NewList mesTempos.Tempo()
Global Total_Delai.l
Global Delai_En_Cour.l
Structure Clavier
      Nbr_Octave.l
      Premier_Octave.l
      Pourcentage_Hauteur.f
      Pourcentage_Hauteur_Noire.f
      Pourcentage_Largueur_Noire.f
      Nbr_Touches_Blanche.l
      Nbr_Touches_Noir.l
      Largeur_Blanche.l
      Largueur_Noir.l
      Hauteur_Blanche.l
      Hauteur_Noir.l
EndStructure
Global monclavier.Clavier
Structure Touches
      Blanche.b
      TouchePosX.l
      TouchePosY.l
      Octave.l
      ValeurNote.s
EndStructure
Global NewList MesTouches.Touches()
Structure Partition
      Marge_Haut.l
      Hauteur_Exploitable.l
      Tempo.l
      Deplacement_Y.f
      Hauteur_Noir.l
      Numerateur.l
      Denominateur.l
      Nb_Mesures.l
EndStructure
Global maPartiton.Partition
Global m_hMidiOut.l                   ; handle du périphérique de sortie MIDI
Global m_MIDIOpen.b               ; 1 = périphérique de sortie MIDI ouvert      0 = non ouvert
Global Dim NomInstrument.s(127)
NomInstrument(0) = "Piano à queue"
NomInstrument(1) = "Piano"
NomInstrument(2) = "Electric grand piano"
NomInstrument(3) = "Honky-Tonk"
NomInstrument(4) = "Electric Piano 1"
NomInstrument(5) = "Electric Piano 2"
NomInstrument(6) = "Harpsichord"
NomInstrument(7) = "Clavinet"
NomInstrument(8) = "Celesta"
NomInstrument(9) = "Glockenspiel"
NomInstrument(10) = "Music Box"
NomInstrument(11) = "Vibraphone"
NomInstrument(12) = "Marimba"
NomInstrument(13) = "Xylophone"
NomInstrument(14) = "Tubular Bells"
NomInstrument(15) = "Dulcimer"
NomInstrument(16) = "Drawbar Organ"
NomInstrument(17) = "Percussive Organ"
NomInstrument(18) = "Rock Organ"
NomInstrument(19) = "Chuch Organ"
NomInstrument(20) = "Reed Organ"
NomInstrument(21) = "Accordion"
NomInstrument(22) = "Harmonica"
NomInstrument(23) = "Tango Accordion"
NomInstrument(24) = "Acoustic Guitar (Nylon)"
NomInstrument(25) = "Acoustic Guitar (Acier)"
NomInstrument(26) = "Electric Guitar"
NomInstrument(27) = "Electric Guitar (Clean)"
NomInstrument(28) = "Electric Guitar (Muted)"
NomInstrument(29) = "Overdriven Guitar"
NomInstrument(30) = "Distortion Guitar"
NomInstrument(31) = "Guitar harmonics"
NomInstrument(32) = "Acoustic Bass"
NomInstrument(33) = "Electric Bass"
NomInstrument(34) = "Electric Bass (Finger)"
NomInstrument(35) = "Fretless Bass"
NomInstrument(36) = "Slap Bass 1"
NomInstrument(37) = "Slap Bass 2"
NomInstrument(38) = "Synth Bass 1"
NomInstrument(39) = "Synth Bass 2"
NomInstrument(40) = "Violon"
NomInstrument(41) = "Viola"
NomInstrument(42) = "Cello"
NomInstrument(43) = "Contrebass"
NomInstrument(44) = "Tremolo Strings"
NomInstrument(45) = "Pizzicato Strings"
NomInstrument(46) = "Orchestral Harp"
NomInstrument(47) = "Timpani"
NomInstrument(48) = "String Ensemble 1"
NomInstrument(49) = "String Ensemble 2"
NomInstrument(50) = "SynthString 1"
NomInstrument(51) = "SynthString 2"
NomInstrument(52) = "Choir Aahs"
NomInstrument(53) = "Voice Oohs"
NomInstrument(54) = "Synth Voice"
NomInstrument(55) = "Orchestra Hit"
NomInstrument(56) = "Trumpet"
NomInstrument(57) = "Trombone"
NomInstrument(58) = "Tuba"
NomInstrument(59) = "Muted Trumpet"
NomInstrument(60) = "French Horn"
NomInstrument(61) = "Brass Section"
NomInstrument(62) = "SynthBass 1"
NomInstrument(63) = "SynthBass 2"
NomInstrument(64) = "Soprano Sax"
NomInstrument(65) = "Alto Sax"
NomInstrument(66) = "Tenor Sax"
NomInstrument(67) = "Bartone Sax"
NomInstrument(68) = "Oboe"
NomInstrument(69) = "English Horn"
NomInstrument(70) = "Bassoon"
NomInstrument(71) = "Clarinet"
NomInstrument(72) = "Piccolo"
NomInstrument(73) = "Flute"
NomInstrument(74) = "Recorder"
NomInstrument(75) = "Pan Flute"
NomInstrument(76) = "Blown Bottle"
NomInstrument(77) = "Shakuhachi"
NomInstrument(78) = "Whistle"
NomInstrument(79) = "Ocarina"
NomInstrument(80) = "Square"
NomInstrument(81) = "Sawtooth"
NomInstrument(82) = "Calliop"
NomInstrument(83) = "Chiff"
NomInstrument(84) = "Charang"
NomInstrument(85) = "Voice"
NomInstrument(86) = "Fifths"
NomInstrument(87) = "Bass + Lead"
NomInstrument(88) = "New Age"
NomInstrument(89) = "Warm"
NomInstrument(90) = "Polysynth"
NomInstrument(91) = "Choir"
NomInstrument(92) = "Bowed"
NomInstrument(93) = "Metallic"
NomInstrument(94) = "Halo"
NomInstrument(95) = "Sweep"
NomInstrument(96) = "Rain"
NomInstrument(97) = "Soundtrack"
NomInstrument(98) = "Crystal"
NomInstrument(99) = "Atmosphere"
NomInstrument(100) = "Brightness"
NomInstrument(101) = "Goblins"
NomInstrument(102) = "Echoes"
NomInstrument(103) = "Sci-Fi"
NomInstrument(104) = "Sitar Ethnik"
NomInstrument(105) = "Banjo"
NomInstrument(106) = "Shamisen"
NomInstrument(107) = "Koto"
NomInstrument(108) = "Kalimba"
NomInstrument(109) = "Bag Pipe"
NomInstrument(110) = "Fiddle"
NomInstrument(111) = "Shanai"
NomInstrument(112) = "Tinkle Bell"
NomInstrument(113) = "Agogo"
NomInstrument(114) = "Steel Drums"
NomInstrument(115) = "Woodblock"
NomInstrument(116) = "Taiko Drum"
NomInstrument(117) = "Melodic Tom"
NomInstrument(118) = "Synth Drum"
NomInstrument(119) = "Reverse Cymbal"
NomInstrument(120) = "Guitar Fret. Noise"
NomInstrument(121) = "Breath Noise"
NomInstrument(122) = "Seashore"
NomInstrument(123) = "Bird Tweet"
NomInstrument(124) = "Telephone Ring"
NomInstrument(125) = "Helicopter"
NomInstrument(126) = "Applause"
NomInstrument(127) = "Gun Shot"
Global Dim Couleur_Note.l(6)
Global PartitionStart.b=#True
Global Init_Temps.f
Global Current_Time.f
Global Partition_Play.b=#False  
Global Largeur_Ecran.l
Global Haut_Ecran.l
Global Couleur_Note_Prejoue.l
Global Fin_Programme.b=#False
Global Premier_Octave.l
Global Dernier_Octave.l
Global SoundON.b=#True
Global Premiere_Note_Vue.L=0
Global Dernier_Note_Vue.L=127
Global Mesure_En_Cours.l=1
Global Fin_Musique.b=#False
Enumeration
      #Clavier_img
      #Touche_Noir
      #Partition_img
      #Grab_Partition_img
      #PLAY_Windows
EndEnumeration
#Nbr_Blanche_par_Octave =7
#Nbr_Noir_Par_Octave=5
#Microseconde_Par_Minute=60000000

If LOAD_MIDI(midiFile$)
      Open_Windows_Play()
EndIf

Procedure LOAD_MIDI(midiFile$)
      If Not Decode_Midi(midiFile$)
            ErazeData()
            ProcedureReturn #False
      EndIf
      ProcedureReturn #True
EndProcedure

Procedure Open_Windows_Play()
      If InitSprite()=0 
            MessageRequester("Erreur","Le moteur de sprite n'a pas bien été initialisé...",#PB_MessageRequester_Ok)
      EndIf
      If InitKeyboard()=0
            MessageRequester("Erreur","Le moteur de clavier n'a pas bien été initialisé...",#PB_MessageRequester_Ok)
      EndIf
      Largeur_Ecran=800
      Haut_Ecran=600
      OpenWindow(#PLAY_Windows,0,0,Largeur_Ecran,Haut_Ecran,"Easy-musique 1.0",#PB_Window_ScreenCentered|#PB_Window_Maximize|#PB_Window_SystemMenu)
      Largeur_Ecran=WindowWidth(#PLAY_Windows,#PB_Window_InnerCoordinate)
      Haut_Ecran=WindowHeight(#PLAY_Windows,#PB_Window_InnerCoordinate)
      OpenWindowedScreen(WindowID(#PLAY_Windows),0,0,Largeur_Ecran,Haut_Ecran)
      StickyWindow(#PLAY_Windows,1)
      SetActiveWindow(#PLAY_Windows)
      ChargeInstrument(0,0)
      Couleur_Note(0)=$0A0AC2
      Couleur_Note(1)=$5EB5FF
      Couleur_Note(2)=$1EB565
      Couleur_Note(3)=$DE7DDB
      Couleur_Note(4)=$DED324
      Couleur_Note(5)=$C0C0C0
      Couleur_Note(6)=$E85C26
      Largeur_Ecran=WindowWidth(#PLAY_Windows,#PB_Window_InnerCoordinate)
      Haut_Ecran=WindowHeight(#PLAY_Windows,#PB_Window_InnerCoordinate)
      Premier_Octave=Get_Premier_Octave()
      Dernier_Octave=Get_Dernier_Octave()
      Dessine_Clavier(Premier_Octave,(Dernier_Octave-Premier_Octave)+1,0.2)
      Init_partition()
      If Not Positionne_Note()
            ErazeData()
            ProcedureReturn #False
      EndIf
      Val_deplacement.f=0
      maPartiton\Deplacement_Y=0-(maPartiton\Hauteur_Exploitable/2)
      Decalage.f=(15000/maPartiton\Tempo)
      Affiche_Sprite()
      Affiche_Clavier()
      Affiche_Info_Partition()
      FlipBuffers()
      Repeat
            ExamineKeyboard()
            If KeyboardPushed(#PB_Key_Escape)
                  Fin_Programme=#True
            EndIf
            If KeyboardPushed(#PB_Key_F10) Or KeyboardPushed(#PB_Key_Space) Or KeyboardPushed(#PB_Key_Return)
                  If Val_deplacement<>0
                        Val_deplacement=0
                        Partition_Play=#False   
                  Else
                        Val_deplacement=(maPartiton\Hauteur_Noir*Decalage)
                        Partition_Play=#True
                  EndIf
                  Delay(100)
            EndIf
            If  KeyboardPushed(#PB_Key_Pad0) 
                  Partition_Play=#False
                  Tempo_TMP.l=#Microseconde_Par_Minute/maPartiton\Tempo
                  Tempo_TMP-1
                  maPartiton\Tempo=Int(#Microseconde_Par_Minute/Tempo_TMP)
                  Decalage.f=(15000/maPartiton\Tempo)
                  Affiche_Info_Partition()
                  FlipBuffers()
                  Delay(100)
            EndIf
            If KeyboardPushed(#PB_Key_Pad1) 
                  Partition_Play=#False
                  Tempo_TMP.l=#Microseconde_Par_Minute/maPartiton\Tempo
                  Tempo_TMP+1
                  maPartiton\Tempo=Int(#Microseconde_Par_Minute/Tempo_TMP)
                  Decalage.f=(15000/maPartiton\Tempo)
                  Affiche_Info_Partition()
                  FlipBuffers()
                  Delay(100)
            EndIf
            If KeyboardPushed(#PB_Key_F2)  
                  Partition_Play=#False
                  maPartiton\Deplacement_Y=0-(maPartiton\Hauteur_Exploitable/2)
                  Positionne_Note()
                  ClearScreen(RGB(0,0,0))
                  Affiche_Sprite()
                  Affiche_Clavier()
                  Colorise_Clavier()
                  Affiche_Info_Partition()
                  FlipBuffers()
            EndIf
            If KeyboardPushed(#PB_Key_S)
                  If SoundON=#True
                        SoundON=#False
                  Else
                        SoundON=#True
                  EndIf
                  Delay(50)
            EndIf
            If KeyboardPushed(#PB_Key_N)
                  Partition_Play=#False  
                  MessageRequester("Info","Veuillez choisir la premiere note de la partie à jouer en cliquant sur le clavier",#PB_MessageRequester_Ok)
                  Repeat
                        Event_Windows=WaitWindowEvent()
                  Until  Event_Windows= #PB_Event_LeftClick
                  Premiere_Note_Vue=Get_Num_Note()
                  MessageRequester("Info","Veuillez choisir la dernière note de la partie à jouer en cliquant sur le clavier",#PB_MessageRequester_Ok)
                  Repeat
                        Event_Windows=WaitWindowEvent()
                  Until  Event_Windows= #PB_Event_LeftClick
                  Dernier_Note_Vue=Get_Num_Note()
                  If Premiere_Note_Vue >=Dernier_Note_Vue
                        MessageRequester("Info","Vous devez choisir la dernière note à droite de la première",#PB_MessageRequester_Ok)
                        Dernier_Note_Vue=127
                        Premiere_Note_Vue=0
                  Else 
                        MessageRequester("Info","Votre sélection est bien enregistrée",#PB_MessageRequester_Ok)
                  EndIf
            EndIf
            If KeyboardPushed(#PB_Key_A)
                  Partition_Play=#False  
                  Premiere_Note_Vue=0
                  Dernier_Note_Vue=127
                  MessageRequester("Info","Toutes les notes sont de nouveau activée",#PB_MessageRequester_Ok)
            EndIf
            Event=WindowEvent()
            Select Event
                  Case    #PB_Event_CloseWindow
                        Fin_Programme=#True  
                  Case #PB_Event_LeftClick
                        Partition_Play=#True
            EndSelect
            If Partition_Play=#True
                  FlipBuffers()
                  ClearScreen(RGB(0,0,0))
                  maPartiton\Deplacement_Y+Val_deplacement
                  Affiche_Sprite()
                  Affiche_Clavier()
                  Colorise_Clavier()
                  Affiche_Info_Partition()
                  Mesure_En_Cours=1+Int((maPartiton\Deplacement_Y/maPartiton\Hauteur_Noir)/4)
                  If Mesure_En_Cours>maPartiton\Nb_Mesures
                        Mesure_En_Cours=1
                        Partition_Play=#False
                        maPartiton\Deplacement_Y=0-(maPartiton\Hauteur_Exploitable/2)
                        Positionne_Note()
                        ClearScreen(RGB(0,0,0))
                        Affiche_Sprite()
                        Affiche_Clavier()
                        Colorise_Clavier()
                        Affiche_Info_Partition()
                        FlipBuffers()
                  EndIf
            EndIf
      Until Fin_Programme=#True
      ErazeData()
      CloseWindow(#PLAY_Windows)
EndProcedure

Procedure Decode_Midi(file_name.s)
      If Not ReadFile(0,file_name)
            MessageRequester("Erreur","Le fichier "+file_name+" n'a pas peu être ouvert...",#PB_MessageRequester_Ok)
            ProcedureReturn #False
      EndIf
      ;Teste l'entete du fichier
      Entete.s=ReadString(id_Fichier,#PB_Ascii,4)
      If Entete<>"MThd" 
            MessageRequester("Erreur","Fichier midi incompatible...",#PB_MessageRequester_Ok)
            CloseFile(0)
            ProcedureReturn #False
      EndIf
      ;Teste espace significatif
      Espace_Significatif.l=ReadHexa(4)
      If Espace_Significatif<>6
            MessageRequester("Erreur","Fichier midi incompatible...",#PB_MessageRequester_Ok)
            CloseFile(0)
            ProcedureReturn #False
      EndIf
      ;Lecture du type de fichier midi
      monMidi_File\Type_Midi=ReadHexa(2)
      If monMidi_File\Type_Midi<>0
            MessageRequester("Erreur","Seul les fichier midi de type 0 sont spportés...",#PB_MessageRequester_Ok)
            CloseFile(0)
            ProcedureReturn #False
      EndIf
      ;Lecture du nbr de piste
      monMidi_File\Nbr_Piste=ReadHexa(2)
      ;Lecture de la division de noir
      monMidi_File\Division_Noir=ReadHexa(2)
      ;Teste l'entete de la piste
      Entete_Piste.s=ReadString(0,#PB_Ascii,4)
      If Entete_Piste<>"MTrk"
            MessageRequester("Erreur","Fichier midi incompatible...",#PB_MessageRequester_Ok)
            CloseFile(0)
            ProcedureReturn #False
      EndIf
      ;Lecture de la longueur de piste
      monMidi_File\Longueur_piste=ReadHexa(4)
      Mode_Delai.b=#True
      Delai.l=0
      ;Parcour de toutes les pistes
      Fin_Piste.b=#False
      For N=1 To monMidi_File\Nbr_Piste     
            Repeat
                  If Mode_Delai=#True
                        Delai=Get_Delai()
                        If Delai>0
                              Total_Delai+Delai
                              monMidi_File\Duree=Total_Delai
                              Delai_En_Cour=Delai
                        EndIf
                        Mode_Delai=#False
                  EndIf
                  IndiceAction=Get_Action()
                  If IndiceAction=1
                        Fin_Piste=#True
                  EndIf
                  If IndiceAction=0
                        CloseFile(0)
                        ProcedureReturn #False
                  EndIf
                  Mode_Delai=#True
            Until Fin_Piste=#True
      Next
      CloseFile(0)
      ProcedureReturn #True
EndProcedure

Procedure ReadHexa(Nb_Octet)
      Resultat.l
      Select Nb_Octet
            Case 4
                  Resultat=(ReadAsciiCharacter(0)*256*256*256)+(ReadAsciiCharacter(0)*256*256)+(ReadAsciiCharacter(0)*256)+ReadAsciiCharacter(0)
            Case 3
                  Resultat=(ReadAsciiCharacter(0)*256*256)+(ReadAsciiCharacter(0)*256)+ReadAsciiCharacter(0)
            Case 2
                  Resultat=(ReadAsciiCharacter(0)*256)+ReadAsciiCharacter(0)
            Case 1
                  Resultat=ReadAsciiCharacter(0)
      EndSelect
      ProcedureReturn Resultat
EndProcedure

Procedure Get_Delai()
      Byte_Lu.l
      Nb_Delai.l
      Dim TableauOctet.l(3)
      Byte_Lu=ReadAsciiCharacter(0)
      If Byte_Lu<0 
            Byte_Lu=128 
      EndIf
      TableauOctet(0)=Byte_Lu
      While Byte_Lu>127
            Nb_Octet+1
            Byte_Lu=ReadAsciiCharacter(0)
            TableauOctet(Nb_Octet)=Byte_Lu
      Wend
      Select Nb_Octet
            Case 0 ;un octet
                  Nb_Delai=TableauOctet(0)
            Case 1 ;deux octets
                  Nb_Delai=((TableauOctet(0)-128)*128)+TableauOctet(1)
            Case 2 ;Trois octets
                  Nb_Delai=((TableauOctet(0)-128)*128*128)+((TableauOctet(1)-128)*128)+TableauOctet(2)
            Case 3 ;Quatre octets
                  Nb_Delai=((TableauOctet(0)-128)*128*128*128)+((TableauOctet(1)-128)*128*128)+((TableauOctet(2)-128)*128)+TableauOctet(3)
      EndSelect
      ProcedureReturn Nb_Delai
EndProcedure

Procedure Get_Action()
      Type_Action=ReadByte(0)
      If Type_Action<0 :Type_Action+256 :EndIf
      Meta_Donne.l
      Select Type_Action
            Case 255 ;Meta donnée
                  Meta_Donne=ReadByte(Id_File)
                  Select  Meta_Donne  
                        Case 0 ;Numéro de séquence
                              Nb_octets=ReadByte(0)
                              FileSeek(0,Loc(0)+Nb_octets)
                        Case 1 ;Texte
                              Nb_octets=ReadByte(0)
                              FileSeek(0,Loc(0)+Nb_octets)
                        Case 2 ;Copyright
                              Nb_octets=ReadByte(0)
                              FileSeek(0,Loc(0)+Nb_octets)
                        Case 3 ;Nom de la piste
                              Nb_octets=ReadByte(0)
                              monMidi_File\Titre=ReadString(0,#PB_Ascii,Nb_octets)
                        Case 4 ;Nom de l'instrument
                              Nb_octets=ReadByte(0)
                              FileSeek(0,Loc(0)+Nb_octets)
                        Case 7 ;Cue point
                              Nb_octets=ReadByte(0)
                              FileSeek(0,Loc(0)+Nb_octets)
                        Case 8  ;Program Name
                              ;Permet d'étiqueter le nom de l'instrument choisi, en conjonction avec le choix de la banque de son xB* - x00 - xnn ou 
                              ;du choix de l'instrument xC* - xnn  
                              Nb_octets=ReadByte(0)
                              FileSeek(0,Loc(0)+Nb_octets)
                        Case  9  ;Peripheric Name
                              ;Doit permettre d'étiqueter de façon unique le périphérique d'une piste, en précisant 
                              ;par exemple le nom de la boîte de son ou du clavier/synthétiseur. 
                              ;À placer en tout début de plage, avant le contrôle de la banque de son xB* - x00 - xnn 
                              ;ou du choix de l'instrument xC* - xnn , et avant tout envoi d'événement. 
                              ;Un nom d'instrument ne peut se retrouver qu'une fois dans le fichier: une seule piste pour les fichier SMF1"
                              Nb_octets=ReadByte(0)
                              FileSeek(0,Loc(0)+Nb_octets)
                        Case 47 ;Fin de piste
                              ProcedureReturn 1
                        Case 81 ;Tempo Setting
                              ;Par défaut, le tempo d'un fichier MIDI est de 120 battements par minute, 
                              ; donc d'une durée d'une demi-seconde par noire, soit 500.000 microsecondes (µs) 
                              ; codés en trois octets valant de 0 à 255."
                              Nb_octets=ReadByte(0)
                              If Nb_octets<>3 
                                    MessageRequester("Erreur","Le tempo ne peut être codé que sur 3 octets",#PB_MessageRequester_Ok)
                                    ProcedureReturn 0
                              EndIf
                              AddElement(mesTempos())
                              mesTempos()\Depart=Total_Delai
                              mesTempos()\Tempo=ReadHexa(Nb_octets)
                        Case 84  ;SMPTE Offset
                              ;Le marquage SMPTE, hérité de la vidéo, précise le décalage en nombre d'heures, de minutes, de secondes, 
                              ;d'images (frames) et encore de subdivision d'images (subframe)"
                              Nb_octets=ReadByte(0)
                              FileSeek(0,Loc(0)+Nb_octets)
                        Case 88 ;Time Signature
                              ;Définit la mesure (2/4, 3/4, 3/8, 4/4, 5/4, 7/8...)
                              Nb_octets=ReadByte(0)
                              If Nb_octets<>4
                                    MessageRequester("Erreur","La signature de temps ne peut être codé que sur 4 octets",#PB_MessageRequester_Ok)
                                    ProcedureReturn 0
                              EndIf
                              AddElement(mesSignature_de_temps())
                              mesSignature_de_temps()\Depart=Total_Delai
                              mesSignature_de_temps()\Numerateur=ReadByte(0)
                              mesSignature_de_temps()\Denominateur=ReadByte(0)
                              mesSignature_de_temps()\Metronome=ReadByte(0)
                              mesSignature_de_temps()\Nb_triple_Croche=ReadByte(0)
                        Case 89  ;Key Signature
                              ;Concerne la tonalité et le mode: nombre de dièses ou de bémols «à la clé», majeur ou mineur
                              ;Cela peut changer en cours de route."
                              Nb_octets=ReadByte(0)
                              FileSeek(0,Loc(0)+Nb_octets)
                        Case 127 ;Sequencer Specific Event
                              ;Permet l'envoi de commandes, spécifiques aux constructeurs d'appareils MIDI.
                              Nb_octets=ReadByte(0)
                              FileSeek(0,Loc(0)+Nb_octets)
                        Default
                              MessageRequester("Erreur","L'action 255 "+Meta_Donne+" n'est pas reconnue...",#PB_MessageRequester_Ok)
                              ProcedureReturn 0
                  EndSelect
            Case 144 To 159 ;Cet événement déclenche la production de la note précisée.
                  ; Le troisième octet «vélocité» permet de coder une rapidité, 
                  ; une force d'attaque: 1 est le plus lent/faible, 127 le plus rapide/forte. 
                  ; Les claviers non sensitifs codent normalement cette valeur à x40 (64). La valeur 0 est une façon d'éteindre une note."
                  Num_Piste.l=Abs(144-Type_Action)+1
                  Decode_Note(#True,Num_Piste)
            Case 128 To 143 ;Cet événement met fin à la note précisée. La fin de note est un événément qui doit être précisé.
                  ;Le troisième octet «vélocité» détermine la rapidité d'extinction (0 le plus lent, 127 le plus rapide)."
                  Decode_Note(#False,Num_Piste)
            Case 160 To 175 ;La fonction «aftertouch» donne un vibrato opéré par une variation de pression sur la touche.
                  
            Case 176 To 191 ;B0 / Control Change Permet de paramétrer chaque canal.
                  ReadHexa(2)
            Case 192 To 207 ;Program  Change
                  ReadHexa(1)
            Case 208 To 223 ;D0 / Canal Pressure
                  ;La valeur «aftertouch» s'applique ici l'ensemble des sons produits sur un canal, 
                  ; si c'est l'ensemble du clavier (et pas chacune des notes) qui est sensible à la pression. 
                  ;Aucune note ne devant être précisée, la fonction n'est codée que sur deux octets. 
                  ; Comme pour la fonction «aftertouch», la pression sur le canal 
                  ;contrôle le vibrato (LFO: Low Frequence Oscillator). 
                  ; Une réinitialisation du contrôle (voir ci-après) remet la pression sur le canal à 0" 
                  ReadHexa(1)
            Case 224 To 239 ;Canal Pressure
                  ;Le pitch bend est la molette servant à infléchir les notes en train d'être jouées sur un canal. 
                  ; Les deux octets admettent les valeurs de 0 à 127 (x7F), 
                  ;ce qui donne 128*128 valeurs possibles, de 0 à 16383. 
                  ;Pour la calculer: fort*128 + faible. Le premier octet contient la valeur de poids faible, 
                  ;le second de poids fort. 
                  ;Attention: la profondeur de l'infléchissement (un demi-ton, une octave?) 
                  ;dépend du matériel et rien ne dit qu'elle y soit paramétrable. 
                  ;Une réinitialisation du contrôle (voir ci-après) remet le pitch bend à 0 - 64"
                  ReadHexa(2)
            Default
                  MessageRequester("Erreur","L'action "+Type_Action+" n'est pas reconnue...",#PB_MessageRequester_Ok)
                  ProcedureReturn 0
      EndSelect
      ProcedureReturn 2
EndProcedure  

Procedure Get_Premier_Octave()
      Prem.l=12
      ForEach mesNote_Musique()
            If mesNote_Musique()\Octave<Prem
                  Prem=mesNote_Musique()\Octave
            EndIf
      Next
      ProcedureReturn Prem
EndProcedure

Procedure Get_Dernier_Octave()
      Dern.l=1
      ForEach mesNote_Musique()
            If mesNote_Musique()\Octave>Dern
                  Dern=mesNote_Musique()\Octave
            EndIf
      Next
      ProcedureReturn Dern
EndProcedure

Procedure Decode_Note(Note_On.b,Num_Piste.l)
      Octave.l
      Note_De_Musique.s
      Numero_Note=ReadAsciiCharacter(0)
      Velocite=ReadAsciiCharacter(0)
      Select Numero_Note
            Case 0 To 11
                  Octave=0
            Case 12 To 23
                  Octave=1
            Case 24 To 35
                  Octave=2
            Case 36 To 47
                  Octave=3
            Case 48 To 59
                  Octave=4
            Case 60 To 71
                  Octave=5
            Case 72 To 83
                  Octave=6 
            Case 84 To 95
                  Octave=7
            Case 96 To 107
                  Octave=8
            Case 108 To 119
                  Octave=9
            Case 120 To 127
                  Octave=10
      EndSelect
      Select Numero_Note-(12*Octave)
            Case 0
                  Note_De_Musique="C"
            Case 1
                  Note_De_Musique="C#"
            Case 2
                  Note_De_Musique="D"
            Case 3
                  Note_De_Musique="D#"
            Case 4
                  Note_De_Musique="E"
            Case 5
                  Note_De_Musique="F"
            Case 6
                  Note_De_Musique="F#"
            Case 7
                  Note_De_Musique="G"
            Case 8
                  Note_De_Musique="G#"
            Case 9
                  Note_De_Musique="A"
            Case 10
                  Note_De_Musique="A#"
            Case 11
                  Note_De_Musique="B"
      EndSelect
      If Note_On=#True
            ;Ajouter la Note
            AddElement(mesNote_Musique())
            mesNote_Musique()\Depart=Total_Delai
            mesNote_Musique()\Note=Note_De_Musique
            mesNote_Musique()\Octave=Octave
            mesNote_Musique()\Velocite=Velocite
            mesNote_Musique()\OnOf=#True
            mesNote_Musique()\Piste=Num_Piste
            mesNote_Musique()\Note_Valeur=Numero_Note
      Else
            ;Modife la durée de la note
            ForEach mesNote_Musique()
                  If  mesNote_Musique()\Note=Note_De_Musique And mesNote_Musique()\Octave=Octave And mesNote_Musique()\OnOf=#True
                        mesNote_Musique()\Duree=(Total_Delai-mesNote_Musique()\Depart)
                        mesNote_Musique()\OnOf=#False
                  EndIf
            Next
      EndIf
EndProcedure   

Procedure Dessine_Clavier(Premier_Octave,Nbr_Octave,Pourcentage_Hauteur.f)
      ;{ Initialisation
      monclavier\Premier_Octave=Premier_Octave
      monclavier\Nbr_Octave=Nbr_Octave
      monclavier\Pourcentage_Hauteur=Pourcentage_Hauteur
      monclavier\Pourcentage_Hauteur_Noire=0.65
      monclavier\Pourcentage_Largueur_Noire=0.7
      Larg.l=Largeur_Ecran
      Haut.l=Haut_Ecran
      ;}
      ;{ Calcul des tailles
      monclavier\Nbr_Touches_Blanche=monclavier\Nbr_Octave*#Nbr_Blanche_par_Octave
      monclavier\Nbr_Touches_Noir=monclavier\Nbr_Octave*#Nbr_Noir_Par_Octave
      monclavier\Largeur_Blanche=Larg/monclavier\Nbr_Touches_Blanche
      monclavier\Largueur_Noir=monclavier\Largeur_Blanche*monclavier\Pourcentage_Largueur_Noire
      monclavier\Hauteur_Blanche=Haut *monclavier\Pourcentage_Hauteur
      monclavier\Hauteur_Noir=monclavier\Hauteur_Blanche*monclavier\Pourcentage_Hauteur_Noire
      ;}
      ;{ Création de l'image
      CreateImage(#Clavier_img,Larg,monclavier\Hauteur_Blanche,24,$FFFFFF)
      ;}
      ;{ Dessin des blanches
      StartDrawing(ImageOutput(#Clavier_img))
      ;   StartDrawing(WindowOutput(MainWindows))
      Y=0
      ;Calcul de la marge de gauche
      marge_gauche=(Larg-(monclavier\Largeur_Blanche * monclavier\Nbr_Touches_Blanche))/2
      For N=1 To monclavier\Nbr_Touches_Blanche
            Note_Tmp+1
            Octave_Tmp=Int((N-1)/#Nbr_Blanche_par_Octave)
            X=(monclavier\Largeur_Blanche*(N-1))+marge_gauche
            Epaisseur_trait=2
            ;Colorise la note C4
            If (monclavier\Premier_Octave)+Octave_Tmp=4 And Note_Tmp=1
                  couleur_touche=$C0C0C0
            Else
                  couleur_touche=$FFFFFF
            EndIf
            Box(X,Y,monclavier\Largeur_Blanche,monclavier\Hauteur_Blanche,$000000)
            Box(X+Epaisseur_trait,Y+Epaisseur_trait, monclavier\Largeur_Blanche-Epaisseur_trait,
                monclavier\Hauteur_Blanche-Epaisseur_trait,couleur_touche)
            ;Ajoute le cercle de couleur
            Rayon=monclavier\Largeur_Blanche*0.3
            X1=X+(monclavier\Largeur_Blanche/2)
            Y1=(monclavier\Hauteur_Blanche*0.8)
            Select Note_Tmp
                  Case 1
                        Couleur_Cercle=Couleur_Note(0)
                  Case 2
                        couleur_cercle=Couleur_Note(1)
                  Case 3
                        couleur_cercle=Couleur_Note(2)
                  Case 4
                        couleur_cercle=Couleur_Note(3)
                  Case 5
                        couleur_cercle=Couleur_Note(4)
                  Case 6
                        couleur_cercle=Couleur_Note(5)
                  Case 7
                        couleur_cercle=Couleur_Note(6)
            EndSelect
            Circle(X1,Y1,Rayon,couleur_cercle)
            AddElement(MesTouches())
            With MesTouches()
                  \Blanche=#True
                  \TouchePosX=X
                  \TouchePosY=y
                  \Octave=monclavier\Premier_Octave+Octave_Tmp
                  Select Note_Tmp
                        Case 1
                              \ValeurNote="C"
                        Case 2
                              \ValeurNote="D"
                        Case 3
                              \ValeurNote="E"
                        Case 4
                              \ValeurNote="F"
                        Case 5
                              \ValeurNote="G"
                        Case 6
                              \ValeurNote="A"
                        Case 7
                              \ValeurNote="B"
                              Note_Tmp=0
                  EndSelect
            EndWith    
      Next
      ;}
      ;{ Dessin des noirs
      Note_Tmp=0
      Octave_Tmp=0
      For N=1 To monclavier\Nbr_Touches_Noir
            Note_Tmp+1
            Octave_Tmp=Int((N-1)/#Nbr_Noir_Par_Octave)
            If comteur_noir=2 Or comteur_noir=5 
                  decalage+monclavier\Largeur_Blanche
            EndIf
            If comteur_noir>#Nbr_Noir_Par_Octave 
                  comteur_noir=1
            EndIf
            comteur_noir+1
            X=marge_gauche+(monclavier\Largeur_Blanche*(N-1))
            X+monclavier\Largeur_Blanche
            X-(monclavier\Largueur_Noir/2)
            X+decalage
            Box(X,Y,monclavier\Largueur_Noir,monclavier\Hauteur_Noir,$000000)
            ;Dessiner les pastilles de couleur
            Rayon=monclavier\Largueur_Noir*0.3
            X1=X+(monclavier\Largueur_Noir/2)
            Y1=(monclavier\Hauteur_Noir*0.5)
            Select Note_Tmp
                  Case 1
                        couleur_cercle=Couleur_Note(0)
                  Case 2
                        couleur_cercle=Couleur_Note(1)
                  Case 3
                        couleur_cercle=Couleur_Note(3)
                  Case 4
                        couleur_cercle=Couleur_Note(4)
                  Case 5
                        couleur_cercle=Couleur_Note(5)
            EndSelect
            Circle(X1,Y1,Rayon,couleur_cercle)
            AddElement(MesTouches())
            With MesTouches()
                  \Blanche=#False
                  \TouchePosX=X
                  \TouchePosY=y
                  \Octave=monclavier\Premier_Octave+Octave_Tmp
                  Select Note_Tmp
                        Case 1
                              \ValeurNote="C#"
                        Case 2
                              \ValeurNote="D#"
                        Case 3
                              \ValeurNote="F#"
                        Case 4
                              \ValeurNote="G#"
                        Case 5
                              \ValeurNote="A#"
                              Note_Tmp=0
                  EndSelect
            EndWith    
      Next
      StopDrawing()
      
      ;}
EndProcedure

Procedure Get_Position_Touche(Note.s,Octave.l)
      ForEach MesTouches()
            If    MesTouches()\ValeurNote=Note And MesTouches()\Octave=Octave
                  ProcedureReturn(MesTouches()\TouchePosX)
            EndIf
      Next
EndProcedure  

Procedure Get_Num_Note()
      If WindowMouseY(0)>Haut_Ecran-monclavier\Hauteur_Blanche
            ForEach MesTouches()
                  If CountString(MesTouches()\ValeurNote,"#")>0
                        LargTMP=monclavier\Largueur_Noir
                  Else
                        LargTMP=monclavier\Largeur_Blanche
                  EndIf
                  
                  If WindowMouseX(0)>=MesTouches()\TouchePosX And WindowMouseX(0)<=(MesTouches()\TouchePosX+LargTMP) 
                        Select MesTouches()\ValeurNote
                              Case "C"
                                    Num_note=(12* MesTouches()\Octave)+1
                              Case "C#"
                                    Num_note=(12* MesTouches()\Octave)+2
                              Case "D"
                                    Num_note=(12* MesTouches()\Octave)+3
                              Case "D#"
                                    Num_note=(12* MesTouches()\Octave)+4
                              Case "E"
                                    Num_note=(12* MesTouches()\Octave)+5
                              Case "F"
                                    Num_note=(12* MesTouches()\Octave)+6
                              Case "F#"
                                    Num_note=(12* MesTouches()\Octave)+7
                              Case "G"
                                    Num_note=(12* MesTouches()\Octave)+8
                              Case "G#"
                                    Num_note=(12* MesTouches()\Octave)+9
                              Case "A"
                                    Num_note=(12* MesTouches()\Octave)+10
                              Case "A#"
                                    Num_note=(12* MesTouches()\Octave)+11
                              Case "B"
                                    Num_note=(12* MesTouches()\Octave)+12
                        EndSelect
                        ProcedureReturn Num_note
                  EndIf
            Next
      EndIf
EndProcedure

Procedure Affiche_Clavier()
      PosY=Haut_Ecran-monclavier\Hauteur_Blanche
      Larg=Largeur_Ecran
      StartDrawing(ScreenOutput())
      DrawImage(ImageID(#Clavier_img),0,PosY,Larg,monclavier\Hauteur_Blanche)
      StopDrawing()
EndProcedure

Procedure SendMIDIMessage(nStatus.l,nCanal.l,nData1.l,nData2.l)
      dwFlags.l = nStatus | nCanal | (nData1 << 8) | (nData2 << 16)
      temp.l = midiOutShortMsg_(m_hMidiOut,dwFlags);
      If temp<>0 
            MessageRequester("Problème", "Erreur dans l'envoi du message MIDI",0)
      EndIf
EndProcedure

Procedure MIDIOpen()
      If m_MIDIOpen = 0
            If midiOutOpen_(@m_hMidiOut,MIDIMAPPER,0,0,0) <> 0 
                  MessageRequester("Problème", "Impossible d'ouvrir le périphérique MIDI",0)
            Else
                  SendMIDIMessage($c0,0,0,0)
                  m_MIDIOpen = 1
            EndIf
      EndIf
EndProcedure

Procedure PlayNoteMIDI(Canal.b,Note.b,VelociteDown.b,VelociteUp.b)
      If m_MIDIOpen = 0
            MIDIOpen()
      EndIf
      If m_MIDIOpen = 1
            SendMIDIMessage($80 | Canal,0,Note,VelociteDown)
            SendMIDIMessage($90 | Canal,0,Note,VelociteUp)
      EndIf          
EndProcedure

Procedure ChargeInstrument(Canal.b,Instrument.b)
      If m_MIDIOpen = 0
            MIDIOpen()
      EndIf
      If m_MIDIOpen = 1
            SendMIDIMessage($c0 | Canal,0,Instrument,0)
      EndIf          
EndProcedure

Procedure Init_partition()
      maPartiton\Marge_Haut=60
      maPartiton\Hauteur_Exploitable=Haut_Ecran-(maPartiton\Marge_Haut+monclavier\Hauteur_Blanche)
      ForEach mesTempos()
            If mesTempos()\Depart=0
                  maPartiton\Tempo=mesTempos()\Tempo
                  Break
            EndIf
      Next
      ForEach mesSignature_de_temps()
            If    mesSignature_de_temps()\Depart=0
                  maPartiton\Numerateur=mesSignature_de_temps()\Numerateur
                  maPartiton\Denominateur=mesSignature_de_temps()\Denominateur
                  Break
            EndIf
      Next
      maPartiton\Hauteur_Noir=(maPartiton\Hauteur_Exploitable/2)/4
      maPartiton\Nb_Mesures=(monMidi_File\Duree/monMidi_File\Division_Noir)/maPartiton\Numerateur
EndProcedure

Procedure Affiche_Info_Partition()
      Texte$=monMidi_File\Titre
      LoadFont(0,"Arial",12,#PB_Font_Bold)
      StartDrawing(ScreenOutput())
      DrawingFont(FontID(0))
      DrawText(0,0,Texte$,$FFFFFF)
      ;       Debug(#Microseconde_Par_Minute/maPartiton\Tempo)
      Montempo$=Str(#Microseconde_Par_Minute/maPartiton\Tempo)
      maSignature$=Str(maPartiton\Numerateur)+" / "+Str(maPartiton\Denominateur)
      Texte$="Tempo : "+Montempo$+"   Mesures :   "+Str(Mesure_En_Cours)+" / "+Str(maPartiton\Nb_Mesures)+"   F1 pour l'aide sur les commandes  "
      Box(0,0,Largeur_Ecran,maPartiton\Marge_Haut,$000000)
      DrawText(0,20,Texte$,$FFFFFF)
      StopDrawing()
EndProcedure

Procedure Positionne_Note()
      FreeSprite(#PB_All)
      ForEach mesNote_Musique()
            mesNote_Musique()\Play=#False
            mesNote_Musique()\PosX=Get_Position_Touche(mesNote_Musique()\Note,mesNote_Musique()\Octave)
            DepartY=Haut_Ecran-monclavier\Hauteur_Blanche
            Haut_Note.f= maPartiton\Hauteur_Noir * (mesNote_Musique()\Duree/monMidi_File\Division_Noir)
            Decalge_Y.f=maPartiton\Hauteur_Noir * (mesNote_Musique()\Depart/monMidi_File\Division_Noir)
            mesNote_Musique()\Hauteur=Val(StrF(Haut_Note,2))
            mesNote_Musique()\PosY=DepartY-(Haut_Note+Decalge_Y)
            Hauteur.f=(maPartiton\Hauteur_Noir *(mesNote_Musique()\Duree/monMidi_File\Division_Noir))
            Select mesNote_Musique()\Note
                  Case "C","D","E","F","G","A","B"
                        Largueur=monclavier\Largeur_Blanche
                  Case "C#","D#","F#","G#","A#"
                        Largueur=monclavier\Largueur_Noir
            EndSelect
            Select mesNote_Musique()\Note
                  Case "C","C#"
                        couleur=Couleur_Note(0) 
                  Case "D","D#"
                        couleur=Couleur_Note(1)
                  Case "E"
                        couleur=Couleur_Note(2)
                  Case "F","F#"
                        couleur=Couleur_Note(3)
                  Case "G","G#"
                        couleur=Couleur_Note(4)
                  Case "A","A#"
                        couleur=Couleur_Note(5)
                  Case "B"
                        couleur=Couleur_Note(6)
            EndSelect
            mesNote_Musique()\ID_Sprite=CreateSprite(#PB_Any,Largueur,mesNote_Musique()\Hauteur)
            If IsSprite(mesNote_Musique()\ID_Sprite)=0
                  MessageRequester("Erreur","Le sprite "+Str(mesNote_Musique()\ID_Sprite)+" n'a pas été bien initialisé...",#PB_MessageRequester_Ok)
                  ProcedureReturn #False
            EndIf
            StartDrawing(SpriteOutput(mesNote_Musique()\ID_Sprite))
            Box(0,4,Largueur,mesNote_Musique()\Hauteur,couleur)
            If CountString(mesNote_Musique()\Note,"#")>0
                  Circle(Largueur/2,mesNote_Musique()\Hauteur/2,Largueur/3,$FFFFFF)
            EndIf
            StopDrawing()
      Next
      ProcedureReturn #True
EndProcedure

Procedure Affiche_Sprite()
      Limite=Haut_Ecran-monclavier\Hauteur_Blanche
      ForEach mesNote_Musique()
            Y.f=mesNote_Musique()\PosY+maPartiton\Deplacement_Y
            Y1.f=Y+mesNote_Musique()\Hauteur
            If mesNote_Musique()\Note_Valeur>=Premiere_Note_Vue And mesNote_Musique()\Note_Valeur<=Dernier_Note_Vue
                  DisplaySprite(mesNote_Musique()\ID_Sprite,mesNote_Musique()\PosX,Int(Y))
                  If SoundON=#True
                        If y1>Limite And Y<Limite And mesNote_Musique()\Play=#False
                              mesNote_Musique()\Play=#True
                              PlayNoteMIDI(0,mesNote_Musique()\Note_Valeur,mesNote_Musique()\Velocite,mesNote_Musique()\Velocite)
                        EndIf
                  EndIf
            EndIf
      Next    
EndProcedure

Procedure Colorise_Clavier()
      Protected Larg.l
      Protected Haut.l
      Protected  Couleur.l
      Protected XX
      Protected YY
      Protected Limite
      Protected Dep.f
      Limite=Haut_Ecran-monclavier\Hauteur_Blanche
      StartDrawing(ScreenOutput())
      ForEach mesNote_Musique()
            Y.f=mesNote_Musique()\PosY+maPartiton\Deplacement_Y
            Y1.f=Y+mesNote_Musique()\Hauteur
            If mesNote_Musique()\Note_Valeur>=Premiere_Note_Vue And mesNote_Musique()\Note_Valeur<=Dernier_Note_Vue
                  If y1>Limite And Y<Limite 
                        If CountString(mesNote_Musique()\Note,"#")>0
                              Larg=monclavier\Largueur_Noir
                              Haut=monclavier\Hauteur_Noir
                        Else
                              Larg=monclavier\Largeur_Blanche
                              Haut=monclavier\Hauteur_Blanche
                        EndIf 
                        Select mesNote_Musique()\Note
                              Case "C","C#"
                                    Couleur=Couleur_Note(0)
                              Case "D","D#"
                                    Couleur=Couleur_Note(1)
                              Case "E"
                                    Couleur=Couleur_Note(2)
                              Case "F","F#"
                                    Couleur=Couleur_Note(3)
                              Case "G","G#"
                                    Couleur=Couleur_Note(4)
                              Case "A","A#"
                                    Couleur=Couleur_Note(5)
                              Case "B"
                                    Couleur=Couleur_Note(6)
                        EndSelect
                        XX=Get_Position_Touche(mesNote_Musique()\Note,mesNote_Musique()\Octave)
                        YY=Largeur_Ecran-monclavier\Hauteur_Blanche
                        Box(XX,Limite,Larg,Haut,Couleur)
                        ;Redesine les noirs
                        Haut=monclavier\Hauteur_Noir
                        Larg=monclavier\Largueur_Noir
                        Select mesNote_Musique()\Note
                              Case "C"
                                    XXX=XX+(monclavier\Largeur_Blanche-(monclavier\Largueur_Noir/2))
                                    Box(XXX,Limite,Larg,Haut,$000000)
                                    Rayon=monclavier\Largueur_Noir*0.3
                                    XX2=XXX+(monclavier\Largueur_Noir/2)
                                    YY2=Limite+(monclavier\Hauteur_Noir*0.5)
                                    Circle(XX2,YY2,Rayon,Couleur_Note(0))
                              Case "D"
                                    XXX=XX+(monclavier\Largeur_Blanche-(monclavier\Largueur_Noir/2))
                                    Box(XXX,Limite,Larg,Haut,$000000)
                                    Rayon=monclavier\Largueur_Noir*0.3
                                    XX2=XXX+(monclavier\Largueur_Noir/2)
                                    YY2=Limite+(monclavier\Hauteur_Noir*0.5)
                                    Circle(XX2,YY2,Rayon,Couleur_Note(1))
                                    XXX=(XX-monclavier\Largeur_Blanche)+(monclavier\Largeur_Blanche-(monclavier\Largueur_Noir/2))
                                    Box(XXX,Limite,Larg,Haut,$000000)
                                    Rayon=monclavier\Largueur_Noir*0.3
                                    XX2=XXX+(monclavier\Largueur_Noir/2)
                                    YY2=Limite+(monclavier\Hauteur_Noir*0.5)
                                    Circle(XX2,YY2,Rayon,Couleur_Note(0))
                              Case "E"
                                    XXX=(XX-monclavier\Largeur_Blanche)+(monclavier\Largeur_Blanche-(monclavier\Largueur_Noir/2))
                                    Box(XXX,Limite,Larg,Haut,$000000)
                                    Rayon=monclavier\Largueur_Noir*0.3
                                    XX2=XXX+(monclavier\Largueur_Noir/2)
                                    YY2=Limite+(monclavier\Hauteur_Noir*0.5)
                                    Circle(XX2,YY2,Rayon,Couleur_Note(1))
                              Case "F"
                                    XXX=XX+(monclavier\Largeur_Blanche-(monclavier\Largueur_Noir/2))
                                    Box(XXX,Limite,Larg,Haut,$000000)
                                    Rayon=monclavier\Largueur_Noir*0.3
                                    XX2=XXX+(monclavier\Largueur_Noir/2)
                                    YY2=Limite+(monclavier\Hauteur_Noir*0.5)
                                    Circle(XX2,YY2,Rayon,Couleur_Note(3))
                              Case "G"
                                    XXX=XX+(monclavier\Largeur_Blanche-(monclavier\Largueur_Noir/2))
                                    Box(XXX,Limite,Larg,Haut,$000000)
                                    Rayon=monclavier\Largueur_Noir*0.3
                                    XX2=XXX+(monclavier\Largueur_Noir/2)
                                    YY2=Limite+(monclavier\Hauteur_Noir*0.5)
                                    Circle(XX2,YY2,Rayon,Couleur_Note(4))
                                    XXX=(XX-monclavier\Largeur_Blanche)+(monclavier\Largeur_Blanche-(monclavier\Largueur_Noir/2))
                                    Box(XXX,Limite,Larg,Haut,$000000)
                                    Rayon=monclavier\Largueur_Noir*0.3
                                    XX2=XXX+(monclavier\Largueur_Noir/2)
                                    YY2=Limite+(monclavier\Hauteur_Noir*0.5)
                                    Circle(XX2,YY2,Rayon,Couleur_Note(3))
                              Case "A"
                                    XXX=XX+(monclavier\Largeur_Blanche-(monclavier\Largueur_Noir/2))
                                    Box(XXX,Limite,Larg,Haut,$000000)
                                    Rayon=monclavier\Largueur_Noir*0.3
                                    XX2=XXX+(monclavier\Largueur_Noir/2)
                                    YY2=Limite+(monclavier\Hauteur_Noir*0.5)
                                    Circle(XX2,YY2,Rayon,Couleur_Note(5))
                                    XXX=(XX-monclavier\Largeur_Blanche)+(monclavier\Largeur_Blanche-(monclavier\Largueur_Noir/2))
                                    Box(XXX,Limite,Larg,Haut,$000000)
                                    Rayon=monclavier\Largueur_Noir*0.3
                                    XX2=XXX+(monclavier\Largueur_Noir/2)
                                    YY2=Limite+(monclavier\Hauteur_Noir*0.5)
                                    Circle(XX2,YY2,Rayon,Couleur_Note(4))
                              Case "B"
                                    XXX=(XX-monclavier\Largeur_Blanche)+(monclavier\Largeur_Blanche-(monclavier\Largueur_Noir/2))
                                    Box(XXX,Limite,Larg,Haut,$000000)
                                    Rayon=monclavier\Largueur_Noir*0.3
                                    XX2=XXX+(monclavier\Largueur_Noir/2)
                                    YY2=Limite+(monclavier\Hauteur_Noir*0.5)
                                    Circle(XX2,YY2,Rayon,Couleur_Note(5))
                        EndSelect
                  EndIf
            EndIf
      Next    
      StopDrawing()
EndProcedure

Procedure Teste_Fin_Partition ()
      ForEach mesNote_Musique()
            If mesNote_Musique()\Play=#False
                  ProcedureReturn #False
            EndIf
      Next
      ProcedureReturn #True
EndProcedure

Procedure ErazeData()
      Total_Delai=0
      Delai_En_Cour=0
      ClearStructure(monclavier,Clavier)
      ClearStructure(monMidi_File,Midi_File)
      ClearStructure(maPartiton,Partition)
      ClearList(mesNote_Musique())
      ClearList(mesTempos())
      ClearList(mesSignature_de_temps())
      ClearList(MesTouches())
      CloseWindow(#PLAY_Windows)
EndProcedure
Windows 10 64 bits PB: 5.70 ; 5.72 LST
Work at Centre Spatial de Liège