atari-music-editor/createmidi.php

139 lines
4.8 KiB
PHP
Executable File

<?php
if (isset($_POST['submit']))
{
if (!empty($_POST['tempo']) && !empty($_POST['timesig_num']) && (!empty($_POST['c1_display']) || !empty($_POST['c2_display'])))
{
//create the midi file
$filename = "a2600song_".date("Y-m-d_His").".mid"; //unique filename
$filehandle = fopen("songs/".$filename,"wb"); //create the file, and open for writing
//----------------------------------------------//
$c1 = explode("\n",$_POST['c1_display']);
$c2 = explode("\n",$_POST['c2_display']);
$c1_data = array();
$c2_data = array();
for ($i = 0; $i < count($c1); $i++) //the -1 accounts for the last line, which just consists of a newline
if (str_word_count($c1[$i],0,"#.0123456789") == 4)
array_push($c1_data,explode(" ",$c1[$i]));
for ($i = 0; $i < count($c2); $i++) //the -1 accounts for the last line, which just consists of a newline
if (str_word_count($c2[$i],0,"#.0123456789") == 4)
array_push($c2_data,explode(" ",$c2[$i]));
$track_arr = array(
1 => array(0=>false,1=>false,2=>false,3=>false),
2 => array(0=>false,1=>false,2=>false,3=>false));
foreach ($c1_data as $i => $arr)
if ($arr[1] != "x")
$track_arr[1][$arr[1]] = true;
foreach ($c2_data as $i => $arr)
if ($arr[1] != "x")
$track_arr[2][$arr[1]] = true;
$numtracks = 1;
foreach ($track_arr as $var => $arr)
foreach ($arr as $val)
if ($val)
$numtracks++;
//----------------------------------------------//
//HEADER
fwrite($filehandle,pack("I",77),1);
fwrite($filehandle,pack("I",84),1);
fwrite($filehandle,pack("I",104),1);
fwrite($filehandle,pack("I",100),1);
fwrite($filehandle,pack("I",0),1);
fwrite($filehandle,pack("I",0),1);
//Size of header
fwrite($filehandle,pack("I",0),1);
fwrite($filehandle,pack("I",6),1);
//MIDI file format
fwrite($filehandle,pack("I",0),1);
fwrite($filehandle,pack("I",1),1);
//# of tracks
fwrite($filehandle,pack("I",0),1);
fwrite($filehandle,pack("I",$numtracks),1); //one for each voice for each channel, plus the default one to declare time signatures, etc.
//Time division
fwrite($filehandle,pack("I",0),1);
fwrite($filehandle,pack("I",240),1);
//END HEADER
//TRACK 1 DATA
//Header
fwrite($filehandle,pack("I",77),1);
fwrite($filehandle,pack("I",84),1);
fwrite($filehandle,pack("I",114),1);
fwrite($filehandle,pack("I",107),1);
//# of bytes in track data
fwrite($filehandle,pack("I",0),1);
fwrite($filehandle,pack("I",0),1);
fwrite($filehandle,pack("I",0),1);
fwrite($filehandle,pack("I",19),1);
//Tempo
$ms = round(60000000/$_POST['tempo']);
$ms = str_pad(dechex($ms),6,"0",STR_PAD_LEFT);
$byte1 = hexdec(substr($ms,0,2));
$byte2 = hexdec(substr($ms,2,2));
$byte3 = hexdec(substr($ms,4,2));
fwrite($filehandle,pack("I",0),1);
fwrite($filehandle,pack("I",255),1);
fwrite($filehandle,pack("I",81),1);
fwrite($filehandle,pack("I",3),1);
fwrite($filehandle,pack("I",$byte1),1); //microseconds per beat (variable, depending on tempo)
fwrite($filehandle,pack("I",$byte2),1); //microseconds per beat
fwrite($filehandle,pack("I",$byte3),1); //microseconds per beat
//Time signature
fwrite($filehandle,pack("I",0),1);
fwrite($filehandle,pack("I",255),1);
fwrite($filehandle,pack("I",88),1);
fwrite($filehandle,pack("I",4),1);
fwrite($filehandle,pack("I",$_POST['timesig_num']),1); //numerator (variable)
fwrite($filehandle,pack("I",log($_POST['timesig_de'],2)),1); //denominator^2 (variable)
fwrite($filehandle,pack("I",24),1); //Metronome
fwrite($filehandle,pack("I",8),1); //32nd notes per beat
//End track
fwrite($filehandle,pack("I",0),1);
fwrite($filehandle,pack("I",255),1);
fwrite($filehandle,pack("I",47),1);
fwrite($filehandle,pack("I",0),1);
//END TRACK 1 DATA
/* Array Format
* $c1_data[note][0] = note name
* $c1_data[note][1] = distortion #
* $c1_data[note][2] = atari note index
* $c1_data[note][3] = note value (quarter, eighth, etc.)
*/
if ($track_arr[1][0]) require("square_1.php");
if ($track_arr[1][1]) require("lead_1.php");
if ($track_arr[1][2]) require("saw_1.php");
if ($track_arr[1][3]) require("bass_1.php");
if ($track_arr[2][0]) require("square_2.php");
if ($track_arr[2][1]) require("lead_2.php");
if ($track_arr[2][2]) require("saw_2.php");
if ($track_arr[2][3]) require("bass_2.php");
fclose($filehandle);
header("Content-type: audio/midi");
header("Content-Disposition: attachment; filename=$filename");
readfile("songs/$filename");
}
else
{
echo "<script>alert('not enough data! argh!');</script>";
}
}
?>