457 lines
		
	
	
		
			22 KiB
		
	
	
	
		
			PHP
		
	
	
		
			Executable File
		
	
	
	
	
			
		
		
	
	
			457 lines
		
	
	
		
			22 KiB
		
	
	
	
		
			PHP
		
	
	
		
			Executable File
		
	
	
	
	
| <?php
 | |
| 	/*
 | |
| 		array format:
 | |
| 			the ID of each button is the distortion and note number (from the Atari)
 | |
| 				noteArray[distortion][atari note index][0] = MIDI file
 | |
| 				noteArray[distortion][atari note index][1] = note name
 | |
| 				noteArray[distortion][atari note index][2] = octave
 | |
| 				noteArray[distortion][atari note index][3] = frequency
 | |
| 				noteArray[distortion][atari note index][4] = error
 | |
| 				noteArray[distortion][atari note index][5] = MIDI note index		*these last three values are used when creating the new MIDI file
 | |
| 				noteArray[distortion][atari note index][6] = pitch bend- left bits
 | |
| 				noteArray[distortion][atari note index][7] = pitch bend- right bits
 | |
| 				noteArray[distortion][atari note index][8] = color
 | |
| 	*/
 | |
| 
 | |
| 	if (isset($_POST['format']))
 | |
| 	{
 | |
| 		$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++)
 | |
| 			if (str_word_count($c1[$i],0,"#.0123456789") == 4)
 | |
| 				array_push($c1_data,explode(" ",$c1[$i]));
 | |
| 
 | |
| 		for ($i = 0; $i < count($c2); $i++)
 | |
| 			if (str_word_count($c2[$i],0,"#.0123456789") == 4)
 | |
| 				array_push($c2_data,explode(" ",$c2[$i]));
 | |
| 
 | |
| 		$total = 0;
 | |
| 		$measureval = $_POST['timesig_num']/$_POST['timesig_de'];
 | |
| 		$measure = 1;
 | |
| 		$newvalue1 = "-------$measure-------\n"; //the value of the textarea gets set to this after the formatting is complete
 | |
| 		$newvalue2 = "-------$measure-------\n";
 | |
| 
 | |
| 		foreach ($c1_data as $i => $arr)
 | |
| 		{
 | |
| 			$total += 1/$arr[3];
 | |
| 			$newvalue1 .= $arr[0]." ".$arr[1]." ".$arr[2]." ".$arr[3];
 | |
| 			//echo $i." ".$total."<br />";
 | |
| 			if ($total >= $measureval)
 | |
| 			{
 | |
| 				$total -= $measureval;
 | |
| 				//add a bar and a measure number to the display
 | |
| 				$measure++;
 | |
| 				$newvalue1 .= "-------$measure-------\n";
 | |
| 			}
 | |
| 		}
 | |
| 		//exit;
 | |
| 		$measure = 1;
 | |
| 		$total = 0;
 | |
| 
 | |
| 		foreach ($c2_data as $i => $arr)
 | |
| 		{
 | |
| 			$total += 1/$arr[3];
 | |
| 			$newvalue2 .= $arr[0]." ".$arr[1]." ".$arr[2]." ".$arr[3];
 | |
| 			if ($total >= $measureval)
 | |
| 			{
 | |
| 				$total -= $measureval;
 | |
| 				//add a bar and a measure number to the display
 | |
| 				$measure++;
 | |
| 				$newvalue2 .= "-------$measure-------\n";
 | |
| 			}
 | |
| 		}
 | |
| 	}
 | |
| 
 | |
| 	$dir = opendir("midi");
 | |
| 	$note_array = array("square"=>array(),"lead"=>array(),"saw"=>array(),"bass"=>array());
 | |
| 
 | |
| 	while (($file = readdir($dir)) != null)
 | |
| 	{
 | |
| 		//format: distortion_atari note index_note name_octave_freq_error_MIDI note index_pitch bend left bits_pitch bend right bits
 | |
| 		if (strpos($file,".ogg"))
 | |
| 		{
 | |
| 			$info = explode("_",$file);
 | |
| 			$info[2] = str_replace("+","#",$info[2]);
 | |
| 			$info[count($info)-1] = substr($info[count($info)-1],0,strpos($info[count($info)-1],".ogg"));
 | |
| 
 | |
| 			if (!isset($note_array[$info[0]][$info[1]]))
 | |
| 				$note_array[$info[0]][$info[1]] = array();
 | |
| 
 | |
| 			array_push($note_array[$info[0]][$info[1]],$file);
 | |
| 			for ($i = 2; $i < count($info); $i++)
 | |
| 				array_push($note_array[$info[0]][$info[1]],$info[$i]);
 | |
| 
 | |
| 
 | |
| 			$red = str_pad(dechex(100+2*$note_array[$info[0]][$info[1]][4]),2,"0",STR_PAD_LEFT);
 | |
| 			$green = str_pad(dechex(150),2,"0",STR_PAD_LEFT);
 | |
| 			$blue = str_pad(dechex(100-2*$note_array[$info[0]][$info[1]][4]),2,"0",STR_PAD_LEFT);
 | |
| 			$color = $red.$green.$blue;
 | |
| 			$note_array[$info[0]][$info[1]][8] = '#' . $color;
 | |
| 		}
 | |
| 	}
 | |
| 
 | |
| 	require ("createmidi.php");
 | |
| ?>
 | |
| <!doctype html>
 | |
| <html>
 | |
|   <head>
 | |
|     <title>Atari 2600 Music Utility</title>
 | |
|     <meta name='description' content='Enables easier composing of Atari 2600 music.' />
 | |
|     <meta name='keywords' content='atari, 2600, music, composing, midi' />
 | |
|     <link rel='stylesheet' type='text/css' href='style.css' />
 | |
| 	 <script type='text/javascript'>
 | |
| 		var noteValue = 4;
 | |
| 		var channel = 1;
 | |
| 		var showColor = false;
 | |
| 		var dotted = false;
 | |
| 		var bufferCount = 1;
 | |
| 		<?php
 | |
| 			if (isset($_POST['format']))
 | |
| 				echo "var bufferMin = 3;";
 | |
| 			else
 | |
| 				echo "var bufferMin = 2;";
 | |
| 		?>
 | |
| 
 | |
| 		//these were made global because javascript annoys me
 | |
| 		var activeKeyID = 0;
 | |
| 		var mouseX = 0;
 | |
| 		var mouseY = 0;
 | |
| 
 | |
| 		var bufferArray = new Array(2);
 | |
| 		bufferArray[0] = new Array();
 | |
| 		bufferArray[1] = new Array();
 | |
| 		bufferArray[0][0] = "";
 | |
| 		bufferArray[1][0] = "";
 | |
| 
 | |
| 
 | |
| 		var noteArray = new Array(4);
 | |
| 		for (i = 0; i < 4; i++)
 | |
| 		{
 | |
| 			noteArray[i] = new Array(32);
 | |
| 			for (j = 0; j < 32; j++)
 | |
| 			{
 | |
| 				noteArray[i][j] = new Array(8);
 | |
| 				for (k = 0; k < 8; k++)
 | |
| 					noteArray[i][j][k] = null;
 | |
| 			}
 | |
| 		}
 | |
| 
 | |
| 		//populate noteArray, copying values from $note_array
 | |
| 		<?php
 | |
| 			foreach ($note_array as $dist => $a)
 | |
| 				foreach ($a as $atariIndex => $b)
 | |
| 					foreach ($b as $i => $c)
 | |
| 					{
 | |
| 						if ($i == 0 || $i == 1 || $i == 8)
 | |
| 							$c = "'$c'"; //convert to string
 | |
| 
 | |
| 						if ($dist == "square")
 | |
| 							echo "noteArray[0][$atariIndex][$i] = $c;\n\t\t";
 | |
| 						else if ($dist == "lead")
 | |
| 							echo "noteArray[1][$atariIndex][$i] = $c;\n\t\t";
 | |
| 						else if ($dist == "saw")
 | |
| 							echo "noteArray[2][$atariIndex][$i] = $c;\n\t\t";
 | |
| 						else if ($dist == "bass")
 | |
| 							echo "noteArray[3][$atariIndex][$i] = $c;\n\t\t";
 | |
| 					}
 | |
| 		?>
 | |
| 	 </script>
 | |
| 	 <script type='text/javascript' src='functions.js'></script>
 | |
|   </head>
 | |
| 
 | |
|   <body>
 | |
|     <?php
 | |
| 
 | |
|       $xstart = 10;
 | |
|       $ystart = 33;
 | |
|       $numoctaves = 7;
 | |
|       $octavestart = 1;
 | |
| 
 | |
|       $wwidth = 20;
 | |
|       $wheight = 70;
 | |
|       $bwidth = 16;
 | |
|       $bheight = 45;
 | |
| 
 | |
|       $keyarr = array("C","C#","D","D#","E","F","F#","G","G#","A","A#","B");
 | |
| 
 | |
|       $wcount = 0;
 | |
|       $bcount = 0;
 | |
| 
 | |
|       for ($i = 0; $i < 12*$numoctaves; $i++)
 | |
|       {
 | |
|         $index = $i%12;
 | |
|         $octave = $octavestart+floor($i/12);
 | |
| 
 | |
|         if (strpos($keyarr[$index],"#"))
 | |
|         {
 | |
|           $space = 0;
 | |
|           switch ($bcount%5)
 | |
|           {
 | |
|             case 0: $space = ($wwidth-$bwidth/2)+($wwidth*7*floor($i/12));    break;
 | |
|             case 1: $space = ($wwidth*2-$bwidth/2)+($wwidth*7*floor($i/12));  break;
 | |
|             case 2: $space = ($wwidth*4-$bwidth/2)+($wwidth*7*floor($i/12));  break;
 | |
|             case 3: $space = ($wwidth*5-$bwidth/2)+($wwidth*7*floor($i/12));  break;
 | |
|             case 4: $space = ($wwidth*6-$bwidth/2)+($wwidth*7*floor($i/12));  break;
 | |
|           }
 | |
| 
 | |
|           $class = "bkey";
 | |
|           $top = $ystart;
 | |
|           $left = $xstart+$space;
 | |
|           $width = $bwidth;
 | |
|           $height = $bheight;
 | |
|           $bcount++;
 | |
|         }
 | |
|         else
 | |
|         {
 | |
|           $class = "wkey";
 | |
|           $top = $ystart;
 | |
|           $left = $xstart+$wwidth*$wcount;
 | |
|           $wcount++;
 | |
|           $width = $wwidth;
 | |
|           $height = $wheight;
 | |
|         }
 | |
| 
 | |
| 		  //determine the atari note index of the key in question for all four distortions
 | |
| 		  $noteName = $keyarr[$index].$octave;
 | |
| 		  $atariIndex = array("square"=>"nil","lead"=>"nil","saw"=>"nil","bass"=>"nil");
 | |
| 		  foreach ($note_array as $dist => $a)
 | |
| 				foreach ($a as $aIndex => $b)
 | |
| 					if ($b[1] == $noteName)
 | |
| 					{
 | |
| 						$atariIndex[$dist] = $aIndex;
 | |
| 						$color = "#".$b[8];
 | |
| 					}
 | |
| 
 | |
| 		  if ($noteName == "C4")
 | |
| 				$class .= " C4";
 | |
| 
 | |
|         echo "\t<button id='square_$atariIndex[square]' name='key' class='$class' style='position: absolute; top: $top"."px; left: $left"."px; height: $height"."px; width: $width"."px;' onclick='playNote(id)' oncontextmenu='return false;' onmousedown='if (event.button == 2) showFloatingDiv(id,event);'></button>\n";
 | |
|         echo "\t<button id='lead_$atariIndex[lead]' name='key' class='$class' style='position: absolute; top: ".($top+($wheight+$ystart))."px; left: $left"."px; height: $height"."px; width: $width"."px;' onclick='playNote(id)' oncontextmenu='return false;' onmousedown='if (event.button == 2) showFloatingDiv(id,event);'></button>\n";
 | |
|         echo "\t<button id='saw_$atariIndex[saw]' name='key' class='$class' style='position: absolute; top: ".($top+2*($wheight+$ystart))."px; left: $left"."px; height: $height"."px; width: $width"."px;' onclick='playNote(id)' oncontextmenu='return false;' onmousedown='if (event.button == 2) showFloatingDiv(id,event);'></button>\n";
 | |
|         echo "\t<button id='bass_$atariIndex[bass]' name='key' class='$class' style='position: absolute; top: ".($top+3*($wheight+$ystart))."px; left: $left"."px; height: $height"."px; width: $width"."px;' onclick='playNote(id)' oncontextmenu='return false;' onmousedown='if (event.button == 2) showFloatingDiv(id,event);'></button>\n";
 | |
| 		}
 | |
| 
 | |
| 	   echo "\n\n\t<span style='font-weight: bold; font-size: 14pt; position: absolute; top: ".($top-25)."px; left: ".(-20+($xstart+$wwidth*$numoctaves*7)/2)."px;'>Square</span>";
 | |
| 	   echo "\n\t<span style='font-weight: bold; font-size: 14pt; position: absolute; top: ".($top+($wheight+$ystart)-25)."px; left: ".(-20+($xstart+$wwidth*$numoctaves*7)/2)."px;'>Lead</span>";
 | |
| 	   echo "\n\t<span style='font-weight: bold; font-size: 14pt; position: absolute; top: ".($top+2*($wheight+$ystart)-25)."px; left: ".(-20+($xstart+$wwidth*$numoctaves*7)/2)."px;'>Saw</span>";
 | |
| 	   echo "\n\t<span style='font-weight: bold; font-size: 14pt; position: absolute; top: ".($top+3*($wheight+$ystart)-25)."px; left: ".(-20+($xstart+$wwidth*$numoctaves*7)/2)."px;'>Bass</span>\n\n";
 | |
| 		  echo "\n\t<div align='center' style='margin-top: ".(4 * ($wheight + $ystart))."px; width: ".($xstart+$wwidth*$numoctaves*7)."px'>\n";
 | |
| 
 | |
| 		echo "\n\t<span style='text-align: left; position: absolute; left: $xstart"."px; top:".(4*($wheight+$ystart))."px'>";
 | |
| 		echo "\n\t\t<label title='[c]'><input type='checkbox' accesskey='c' onclick='toggleColor()' autocomplete='off' />Color Me Blind</label>";
 | |
| 		echo "\n\t</span>";
 | |
| 		echo "\n\t<span style='text-align: left; position: absolute; left: ".(-35+$xstart+$numoctaves*7*$wwidth)."px; top:".(4*($wheight+$ystart))."px'>";
 | |
| 		echo "\n\t\t<a title='[q]' accesskey='q' onfocus='showFAQ()' href='javascript:void(0)'>FAQ</a>";
 | |
| 		echo "\n\t</span>";
 | |
| 	?>
 | |
| 
 | |
| 
 | |
| 		<table border='0' align='center'>
 | |
| 
 | |
| 			<tr><td colspan='2'>
 | |
| 				<table align='center'>
 | |
| 					<tr>
 | |
| 						<td><button accesskey='1' name='note-select' title='whole note [1]' class='note-select' onclick='selectNote(1)'><img src='img/1.gif' /></button></td>
 | |
| 						<td><button accesskey='2' name='note-select' title='half note [2]' class='note-select' onclick='selectNote(2)'><img src='img/2.gif' /></button></td>
 | |
| 						<td><button accesskey='3' name='note-select' title='quarter note [3]' class='note-select' onclick='selectNote(4)' disabled='disabled' style='cursor: default;'><img src='img/4.gif' /></button></td>
 | |
| 						<td><button accesskey='4' name='note-select' title='8th note [4]' class='note-select' onclick='selectNote(8)'><img src='img/8.gif' /></button></td>
 | |
| 						<td><button accesskey='5' name='note-select' title='16th note [5]' class='note-select' onclick='selectNote(16)'><img src='img/16.gif' /></button></td>
 | |
| 						<td><button accesskey='6' name='note-select' title='32nd note [6]' class='note-select' onclick='selectNote(32)'><img src='img/32.gif' /></button></td>
 | |
| 						<td><button accesskey='7' name='note-select' title='64th note [7]' class='note-select' onclick='selectNote(64)'><img src='img/64.gif' /></button></td>
 | |
| 						<td><label title='dot [w]'><input type='checkbox' accesskey='w' onclick='setDotted()' />Dotted</label></td>
 | |
| 					</tr>
 | |
| 					<tr>
 | |
| 						<td align='center'><button name='note-select' title='whole rest' class='rest-select' onclick='writeRestData(1)'><img src='img/r1.gif' /></button></td>
 | |
| 						<td align='center'><button name='note-select' title='half rest' class='rest-select' onclick='writeRestData(2)'><img src='img/r2.gif' /></button></td>
 | |
| 						<td align='center'><button name='note-select' title='quarter rest' class='rest-select' onclick='writeRestData(4)'><img src='img/r4.gif' /></button></td>
 | |
| 						<td align='center'><button name='note-select' title='8th rest' class='rest-select' onclick='writeRestData(8)'><img src='img/r8.gif' /></button></td>
 | |
| 						<td align='center'><button name='note-select' title='16th rest' class='rest-select' onclick='writeRestData(16)'><img src='img/r16.gif' /></button></td>
 | |
| 						<td align='center'><button name='note-select' title='32nd rest' class='rest-select' onclick='writeRestData(32)'><img src='img/r32.gif' /></button></td>
 | |
| 						<td align='center'><button name='note-select' title='64th rest' class='rest-select' onclick='writeRestData(64)'><img src='img/r64.gif' /></button></td>
 | |
| 					</tr>
 | |
| 				</table>
 | |
| 			</td></tr>
 | |
| 
 | |
| 			<form name='createMidiForm' action='index.php' method='post' style='display: inline;'>
 | |
| 
 | |
| 			<tr>
 | |
| 				<td colspan='2' align='center'>
 | |
| 						Tempo:
 | |
| 						<input type='text' name='tempo' id='tempo' size='2' maxlength='3' value='<?php if (isset($_POST['tempo'])) echo $_POST['tempo']; else echo "120";?>' onblur='validateForm()' />
 | |
| 						Time Signature:
 | |
| 						<input type='text' name='timesig_num' id='timesig_num' size='1' maxlength='3' value='<?php if (isset($_POST['timesig_num'])) echo $_POST['timesig_num']; else echo "1";?>' onblur='validateForm()' />
 | |
| 							/ <select id='timesig_de' name='timesig_de'>
 | |
| 									<option value='1' <?php if (isset($_POST['timesig_de']) && $_POST['timesig_de'] == 1) echo "selected='selected'";?>>1</option>
 | |
| 									<option value='2' <?php if (isset($_POST['timesig_de']) && $_POST['timesig_de'] == 2) echo "selected='selected'";?>>2</option>
 | |
| 									<option value='4' <?php if (isset($_POST['timesig_de']) && $_POST['timesig_de'] == 4) echo "selected='selected'";?>>4</option>
 | |
| 									<option value='8' <?php if (isset($_POST['timesig_de']) && $_POST['timesig_de'] == 8) echo "selected='selected'";?>>8</option>
 | |
| 									<option value='16' <?php if (isset($_POST['timesig_de']) && $_POST['timesig_de'] == 16) echo "selected='selected'";?>>16</option>
 | |
| 									<option value='32' <?php if (isset($_POST['timesig_de']) && $_POST['timesig_de'] == 32) echo "selected='selected'";?>>32</option>
 | |
| 									<option value='64' <?php if (isset($_POST['timesig_de']) && $_POST['timesig_de'] == 64) echo "selected='selected'";?>>64</option>
 | |
| 								</select>
 | |
| 				</td>
 | |
| 			</tr>
 | |
| 
 | |
| 			<tr>
 | |
| 				<td align='center'>
 | |
| 					<label>
 | |
| 						<input type='radio' name='channel_select' checked='checked' onclick='toggleChannel(1)' />
 | |
| 						Channel 1
 | |
| 					</label>
 | |
| 				</td>
 | |
| 				<td align='center'>
 | |
| 					<label>
 | |
| 						<input type='radio' name='channel_select' onclick='toggleChannel(2)' />
 | |
| 						Channel 2
 | |
| 					</label>
 | |
| 				</td>
 | |
| 			</tr>
 | |
| 			<tr>
 | |
| 				<td>
 | |
| 					<textarea rows='20' cols='25' id='c1_display' name='c1_display'><?php if (isset($_POST['format']))	echo $newvalue1;	else if (isset($_POST['c1_display'])) echo $_POST['c1_display']; ?></textarea>
 | |
| 				</td>
 | |
| 				<td>
 | |
| 					<textarea rows='20' cols='25' id='c2_display' name='c2_display'><?php if (isset($_POST['format']))	echo $newvalue2;	else if (isset($_POST['c2_display'])) echo $_POST['c2_display'];?></textarea>
 | |
| 				</td>
 | |
| 			</tr>
 | |
| 			<tr>
 | |
| 				<td align='center'><input style='cursor: pointer;' type='button' value='Clear' onclick='clearChannelData(1)' title='Clear channel 1 data'></input></td>
 | |
| 				<td align='center'><input style='cursor: pointer;' type='button' value='Clear' onclick='clearChannelData(2)' title='Clear channel 2 data'></input></td>
 | |
| 			</tr>
 | |
| 
 | |
| 
 | |
| 			<tr><td colspan='2' align='center'>
 | |
| 				<input style='color:#339966; font-family: Georgia; font-size: 150%; cursor: pointer;' type='submit' name='submit' value='Listen' title='Download the MIDI file'></input>
 | |
| 				<input accesskey='f' style='color:#339966; font-family: Georgia; font-size: 150%; cursor: pointer;' type='submit' name='format' value='Format' title='Partition the measures [f]'></input>
 | |
| 				<input accesskey='z' style='color:#339966; font-family: Georgia; font-size: 150%; cursor: pointer;' type='button' name='undo' value='Undo' onclick='undoLastKeypress()' title='Undo last keypress [z]'></input>
 | |
| 			</td></tr>
 | |
| 
 | |
| 			</form>
 | |
| 		</table>
 | |
| 	</div>
 | |
| 
 | |
| 	<div id='floatDiv' class='floater' onclick='hideFloatingDiv()'></div>
 | |
| 
 | |
| 	<!-- FAQ -->
 | |
| 	<div id='faq' class='faq' onclick='hideFAQ()'>
 | |
| 		<h3>Shut the FAQ up</h3><br />
 | |
| 		<span class='faq_q'>How do I close this pink window?</span>
 | |
| 		<blockquote class='faq_a'>Click anywhere inside it.</blockquote>
 | |
| 		<span class='faq_q'>Who? | What? | When? | Where? | Why?</span>
 | |
| 		<blockquote class='faq_a'>
 | |
| 			Tommy Montgomery |
 | |
| 			Atari 2600 Music Composing Utility |
 | |
| 			January, 2007 |
 | |
| 			On the internet |
 | |
| 			Why not
 | |
| 		</blockquote>
 | |
| 		<span class='faq_q'>How?</span>
 | |
| 		<blockquote class='faq_a'>
 | |
| 			An unholy union of PHP, Javascript and the HTML DOM.  The MIDI files used to
 | |
| 			play the sounds were created using Java because I didn't know PHP
 | |
| 			could write to binary files at the time. 15 years later in April 2022
 | |
| 			I converted them to OGG.
 | |
| 		</blockquote>
 | |
| 		<span class='faq_q'>Why is this useful?</span>
 | |
| 		<blockquote class='faq_a'>
 | |
| 			Writing music for the 2600 is difficult, because of the variations in
 | |
| 			pitch.  The frequencies don't conform to any sort of useful or intelligible
 | |
| 			scale, so we have to approximate to get what we want.  This utility makes
 | |
| 			that process easier, by supplying a visual and aural cue of the
 | |
| 			(musical) limitations of the 2600.
 | |
| 		</blockquote>
 | |
| 		<span class='faq_q'>Why are there four keyboards?</span>
 | |
| 		<blockquote class='faq_a'>
 | |
| 			The four keyboards correspond to the four "melodic" distortions (meaning
 | |
| 			the ones that don't sound like noise). They are labeled for your
 | |
| 			convenience.  The grayed keys are notes whose frequencies are
 | |
| 			unavailable in that distortion. Middle C is outlined in red.
 | |
| 		</blockquote>
 | |
| 		<span class='faq_q'>What about the other distortions?</span>
 | |
| 		<blockquote class='faq_a'>
 | |
| 			The primary reason I didn't include them is because there aren't any
 | |
| 			MIDI voices that can approximate them. The secondary reason is because
 | |
| 			this utility is for making <em>music</em>, not <em>noise</em>, which is
 | |
| 			generally what the other distortions are used for; making noise is generally
 | |
| 			much easier and doesn't need a fancy tool.
 | |
| 		</blockquote>
 | |
| 		<span class='faq_q'>How do I write songs?</span>
 | |
| 		<blockquote class='faq_a'>
 | |
| 			The Atari 2600 has two sound channels available (or so I've heard). The
 | |
| 			two textareas at the bottom of the screen correspond to each channel.  They are
 | |
| 			labeled for your convenience. When you click on a key, you will hear its sound and the
 | |
| 			data will be written to the channel's textarea (that data can also be typed in
 | |
| 			manually). To listen to your song, press "Listen."  The best way to learn how
 | |
| 			to use this is to experiment.  Use the "Format" and "Listen" buttons liberally.
 | |
| 		</blockquote>
 | |
| 		<span class='faq_q'>What does "Format" do?</span>
 | |
| 		<blockquote class='faq_a'>
 | |
| 			Pressing this button formats each channel's data into something more
 | |
| 			comprehensible.  It groups all the data into measures (this is dependent
 | |
| 			on the time signature).
 | |
| 		</blockquote>
 | |
| 		<span class='faq_q'>How do I change the note value/channel/tempo/time signature?</span>
 | |
| 		<blockquote class='faq_a'>
 | |
| 			Find the labels and/or pictures and click something until it does what you want.
 | |
| 		</blockquote>
 | |
| 		<span class='faq_q'>How do I insert a rest in my song?</span>
 | |
| 		<blockquote class='faq_a'>
 | |
| 			See above.
 | |
| 		</blockquote>
 | |
| 		<span class='faq_q'>What does "Dotted" do?</span>
 | |
| 		<blockquote class='faq_a'>
 | |
| 			Checking this elongates the note by 50%.
 | |
| 		</blockquote>
 | |
| 		<span class='faq_q'>What do all the numbers in the textareas mean?</span>
 | |
| 		<blockquote class='faq_a'>
 | |
| 			<ul>
 | |
| 				<li>The first thing is the note name and octave (e.g. <code>E3</code>).</li>
 | |
| 				<li>The second thing is the distortion (<code>0</code> = square, <code>1</code> =
 | |
| 				lead, <code>2</code> = saw, <code>3</code> = bass. Note that these do <em>not</em>
 | |
| 				correspond to the distortion numbers in the text file linked to below).</li>
 | |
| 				<li>The third thing is the pitch index, mentioned below.</li>
 | |
| 				<li>The last thing is the note value (<code>1</code> = whole note, <code>2</code> =
 | |
| 				half note, <code>4</code> = quarter note, etc.).</li>
 | |
| 			</ul>
 | |
| 		</blockquote>
 | |
| 		<span class='faq_q'>I know stuff about some stuff. How do I look at this stuff?</span>
 | |
| 		<blockquote class='faq_a'>
 | |
| 			Right click on a key to view info about that note (doesn't work in Opera). <code>Pitch</code> is the
 | |
| 			Atari 2600 pitch index (see <a href='http://home.arcor.de/estolberg/texts/freqform.txt'>here</a>
 | |
| 			for details); <code>Freq</code> is the note's frequency; <code>Error</code> is the
 | |
| 			distance in cents from "perfect" pitch. If you don't know what that means, the closer
 | |
| 			to 0 is better. Unless you're doing something weird and/or painful, you'll want
 | |
| 			all the notes in your song to have approximately the same error.
 | |
| 		</blockquote>
 | |
| 		<span class='faq_q'>What does "Exchange" mean?</span>
 | |
| 		<blockquote class='faq_a'>
 | |
| 			Some notes have more than one frequency that approximates that note. Clicking on
 | |
| 			"Exchange" toggles between the two. Such notes are generally in the lower half
 | |
| 			of the keyboard.
 | |
| 		</blockquote>
 | |
| 		<span class='faq_q'>What does "Color Me Blind" do?</span>
 | |
| 		<blockquote class='faq_a'>
 | |
| 			Checking this color codes all the keys.  Keys with the same color are in tune
 | |
| 			with each other.  Keys that are different colors probably shouldn't be used in
 | |
| 			succession.
 | |
| 		</blockquote>
 | |
| 		<span class='faq_q'>Dude, seriously. Using the mouse is a bother. Are there any keyboard shortcuts?</span>
 | |
| 		<blockquote class='faq_a'>
 | |
| 			Glad you asked. If you hover the cursor over various objects on the page, you'll notice
 | |
| 			a single character in square brackets in the tooltip for some of them (try one of the
 | |
| 			note value buttons, for example). Check
 | |
| 			<a href="https://developer.mozilla.org/en-US/docs/Web/HTML/Global_attributes/accesskey">here</a>
 | |
| 			to see your access key combination (generally <code>ALT</code> or <code>ALT+SHIFT</code>).
 | |
| 		</blockquote>
 | |
| 	</div>
 | |
| 	<!-- END FAQ -->
 | |
| 
 | |
| 	<script type='text/javascript'>disableNils();</script>
 | |
| 	<audio id='sound'></audio>
 | |
| 
 | |
| 	</body>
 | |
| </html>
 |