Teclis01
Messages postés1423Date d'inscriptionmardi 14 décembre 2004StatutMembreDernière intervention29 décembre 2012
-
4 juil. 2005 à 20:30
syl20dies
Messages postés13Date d'inscriptionmardi 21 octobre 2008StatutMembreDernière intervention29 janvier 2009
-
20 mars 2009 à 22:13
Voilà en fait je me posais la question s'il etait possible d'editer un fichier midi en php et si cela existait deja
Merci d'avance
-------------------------------------------------------------------------------------------------------
Il vaut mieux poser une question et passer pour bête que le rester toute sa vie
cs_grandvizir
Messages postés1106Date d'inscriptionsamedi 8 novembre 2003StatutMembreDernière intervention 3 septembre 200622 4 juil. 2005 à 21:18
Déjà que sous développement Windows c'est chaud, alors PHP laisse tomber. Personnellement, je n'y crois pas.
1) Trop compliqué
2) PHP ne convient pas
3) Apache ne propose pas d'extensions adapatée
A la limite, tu peux faire des renommeurs de pistes, mais bof...
Si tu veux un bon éditeur simple en 16 bis Win3.1, débrouille toi pour trouver Midisoft Recording Session. C'est tellement bien qu'il n'y a en fait pas besoin d'installateur. Par contre, c'est tellement vieux qu'il ne doit plus être en vente.
Teclis01
Messages postés1423Date d'inscriptionmardi 14 décembre 2004StatutMembreDernière intervention29 décembre 20124 4 juil. 2005 à 21:43
ok merci je vais voir cke je peux faire de tt ce que tu as repondu!
Teclis
-------------------------------------------------------------------------------------------------------
Il vaut mieux poser une question et passer pour bête que le rester toute sa vie
syl20dies
Messages postés13Date d'inscriptionmardi 21 octobre 2008StatutMembreDernière intervention29 janvier 2009 20 mars 2009 à 22:04
Bonjour post tres ancien et accepté mais j'y suis tombé dessus parcque ca m'interessait pour une appli que je souhaite dévellopper,donc je pense que c'est le meilleur endroit pour donner ma contribution.
voilà mon but est de créer un algo pour composer de la musique à partir de l'analyse de gamme, accords intervalles et toutes notions de théorie musicale, bref vaste projet, mais bon voila avant d'en arriver là la premiere question que je me suis posé c'est que va sortir mon algo pour que je puisse voir(entendre plutot) le résultat.
j'ai un piano numerique et quelques soft d'edition midi, mais voila impossible de saisir une liste complete d'evenements de notes autrement que note par note
je me suis donc dis "et bien je croie que je vais pas avoir le choix que de générer mes propres fichiers midi contenant toutes les notes issues de mon algo".
je m'y suis donc collé et je vous propose donc ce code pour ecrire un fichier midi à partir d'un tableau de notes telles qu'on peut les trouver dans la vue liste d'evenement d'un sequenceur midi.
c'est une version tres simpliste dans mon cas puisque je ne traite que de note/on note/off velocity-in et placage temporel tres sommaire(16ieme de note au plus fin) mais ca peut donner des idées.
à voir pour plus de detail sur le codage d'un fichier midi que j'ai ici
simplifié à outrance pour ne garder que ce qui m'interessait : les note/on et note/off
4D 54 68 64 MThd
00 00 00 06 chunk length
00 00 format 0
00 01 one track
00 60 96 per quarter-note
Then, the
track chunk. Its header, followed by the events:
4D 54 72 6B MTrk
00 00 00 3B chunk length (44)
Delta-time(var-length hex) Event Comments
00 90 30 60
90:noteon ,30(hex)=48(dec) = +48 semitones from C0=C4, 60 hex val for
velocity in
60 90 43 40
60 90 4C 20
81 40 80 30 40
two-byte delta-time,80:noteoff ,30(hex)=48(dec) = +48 semitones from
C0=C4, 40 hex val for velocity off
00 80 43 40
00 80 4C 40
00 FF 2F 00 //fin de track
2) le code
<?
function completechaine($pstr,$d){
//formate la chaine $pstr en placant des "0" devant pour obtenir la longueur minimale donnée par $d
//utile pour obtenir un hexadecimal inferieur à 16(dec) sur 2 charactères
//ex :dechex(15)retourne F,
//completechaine(dechex(15),2) retourne "0F"
$newstr=$pstr;
while(strlen($newstr)<$d){$newstr="0".$newstr;}
return $newstr;
}
function varlen($hex){
//retourne une chaine hexadécimale sous forme de valeur à longueur variable (VLK) cf http://en.wikipedia.org/wiki/Variable_length_unsigned_integer $a=decbin(hexdec($hex));
$nbbytes=ceil(strlen($a)/7);
$a=completechaine($a,$nbbytes*7);
$mywords=array($nbbytes);
for($i=0;$i<$nbbytes;$i++){
$mywords[$i]=(($i<$nbbytes-1)?"1":"0").substr($a,$i*7,7);
}
$result=implode($mywords);
return completechaine(dechex(bindec($result)),2);
}
function findhexnote($strnote){
//retourne la valeur hexadécimale de la hauteur d'une note donnée en parametre
$notedecal=array("C"=>0,"D"=>2,"E"=>4,"F"=>5,"G"=>7,"A"=>9,"B"=>11,"C#"=>1,"D#"=>3,"F#"=>6,"G#"=>8,"A#"=>9,"B"=>11);
$decdies=intval(($strnote[1]=="#"))+1;//valeur booléenne entiere augmentée de 1 (si "#" : 2 sinon 1);
return completechaine(dechex($notedecal[substr($strnote,0,$decdies)]+intval(substr($strnote,$decdies,strlen($strnote-$decdies)))*12),2);
//multiplie le nombre de l'octave(souschaine de $strnote position 2 à fin si #, sinon position 1 à fin) par 12 et ajoute le decalage de la note dans l'octave, puis converti le tout en valeur hexadecimale sur 2 characteres
}
function convertnotes($mesnotes){
//pour obtenir le code sous la forme [decalage temporel(VLK)][noteon/noteoff(90/80)][hauteur note(hex)][velocité(hex)] à partir d'un tableau de note sous la forme :
// [note(string)][velocité(dec 0 -127)][time(M:1/4note:1/16note)][duree(M:1/4note:1/16note)]
$hexanotes="";
$timepassed=0;
$evts=array(count($mesnotes)*2);//initialise un tableu de longueur double à celui des notes donnée en parametre de sorte à obtenir un evenement note on et un evenenment noteoff
for($i=0;$i<count($mesnotes);$i++){
$tdeb=split(':',$mesnotes[$i][2]);
$tdur=split(':',$mesnotes[$i][3]);
//convertion de la chaine temps de la note en entier(96 batements par quart de note tel que defini dans l'entete du fichier midi);
$evts[$i*2]=$tdeb[0]*96*4+$tdeb[1]*96+$tdeb[2]*96/4;
//convertion de temps + duree en temps absolu entier comme precedement correspondant au temps absolu de l'evenement note off;
$evts[$i*2+1]=(intval($tdeb[2])+intval($tdur[2]))*96/4+(intval($tdeb[1])+intval($tdur[1]))*96+(intval($tdeb[0])+intval($tdur[0]))*96*4;
// j'ai ainsi affecté le temps absolu du debut de la note au indices pairs du tableau evts, le temps absolu de la fin de la note au indices impairs;
}
//tri selon le temps en conservant l'association avec les index
asort($evts,SORT_NUMERIC);
foreach ($evts as $key => $val) {
//constitution de la trame formatée, la correlation avec le tableau de note d'origine est donnée par floor($key/2) qui donne l'index de la note associée au temps $val
//j'utilise succesivement les fonctions definie avant pour obtenir le formatage correct des données:
//varlen(dechex($val-$timepassed)) pour obtenir un decalage par rapport à l'evenement precedant sous forme VLK,
//index pair ou impair pour evenement noteon ou noteoff
//findhexnote pour la hauteur de la note en hexa
//pour la velocité je n'utilise ici que la velocité-in et 0 pour la velocité off(pas de difference sur mon piano numerique)
$hexanotes.=varlen(dechex($val-$timepassed)).(($key%2==0)?"90":"80").findhexnote($mesnotes[floor($key/2)][0]).(($key%2==0)?completechaine(dechex($mesnotes[floor($key/2)][1]),2):"00");
$timepassed=$val;
}
return $hexanotes;
}
//entete typique de fichier midi (MTHD) au format 0 une piste 96beats/quarternote + entete de bloc MTrk
//il manque la checksum que je calculerais plus tard
$entete="4D546864000000060000000100604D54726B";
$fin="00FF2F00";
//exemple de notes, à récupérer d'un formulaire ou tout ce que vous voudrez
$mesnotes=array();
$mesnotes[0]=array("C4",127,"0:0:0","1:0:0");
$mesnotes[1]=array("C5",80,"0:2:0","0:1:0");
$mesnotes[2]=array("G4",80,"0:1:0","0:1:0");
$mesnotes[3]=array("D#4",80,"0:3:0","0:1:0");
$mesnotes[4]=array("G4",127,"1:0:0","1:0:0");
$mesnotes[5]=array("G5",127,"1:0:0","1:0:0");
//obtention de la liste d'evenements noteon et note off
$blocnotes=convertnotes($mesnotes);
//calcul de la checksum
// à verifier j'ai compté ici la fin de bloc et la checksum elle même mais pas l'entete de track
// ca ne pose pas de probleme à mon sequenceur j'assume donc ca comme juste
$checksum=completechaine(dechex((strlen($blocnotes)/2+8)),8)
// concatenation des elements du fichiers
$myhexdata=$entete.$checksum.$blocnotes.$fin;
//conversion du contenu string hexa en bytes ascii
$content="";
for($i=0;$i<strlen($myhexdata);$i+=2){
$content.=chr(hexdec($myhexdata[$i].$myhexdata[$i+1]));
}
//ecriture du fichier
$fp=fopen("myown.mid",'w');
fwrite($fp,$content);
fclose($fp);