Hardware components | ||||||
| × | 1 | ||||
| × | 2 | ||||
| × | 2 | ||||
| × | 2 | ||||
| × | 1 |
You can play a harmonized song with two stepper motors connected to a PHPoC board and stepper motor smart expansion boards (PES-2403). Depending on the speed of the stepper motor, the frequency changes which influences the sound level.
Library
PHPFor this project, it needs 2 libraries.
One is sd_spc.php from PSP library, the other is se_step_play.php for playing music.
Library must be included in the lib folder.
- se_step_play.php
One is sd_spc.php from PSP library, the other is se_step_play.php for playing music.
Library must be included in the lib folder.
- se_step_play.php
<?php
include_once "/lib/sd_spc.php";
$step_play_speed = 1000; // ms per bar
$step_play_dir = +1;
$step_play_sid = array(0, 0, 0, 0);
function step_play_setup($play_id, $sid, $vref = 8, $mode = "half", $accel = 10000)
{
global $step_play_sid;
if(spc_request_sys($sid, "get did") != "40002403")
exit("step_play_setup: expansion not found\r\n");
spc_request_dev($sid, "set vref stop 2");
spc_request_dev($sid, "set vref drive $vref");
spc_request_dev($sid, "set mode $mode");
spc_request_dev($sid, "set accel $accel");
$step_play_sid[$play_id] = $sid;
}
function step_play_tempo($tempo)
{
global $step_play_speed;
$step_play_speed = (int)(1000.0 / ($tempo / 60.0));
}
function step_play_dir($dir)
{
global $step_play_dir;
if($dir >= 0)
$step_play_dir = +1;
else
$step_play_dir = -1;
}
function step_play_encode($score)
{
global $step_play_speed;
$score_array = explode(" ", $score);
$score_count = count($score_array);
$score_encoded = "";
for($i = 0; $i < $score_count; $i++)
{
if(!($note = $score_array[$i]))
continue;
if(strtoupper($note[0]) == "R")
{ /* rest */
$dur_fp = (float)substr($note, 1);
$dur_ms = (int)round($step_play_speed / $dur_fp);
$score_encoded .= int2bin(0, 2);
$score_encoded .= int2bin($dur_ms, 2);
}
else
{ /* tone */
$tone = (int)$note[0] * 12; // octave * 12
// C C# D D# E F F# G G# A A# B
// 0 1 2 3 4 5 6 7 8 9 10 11
switch(strtoupper($note[1]))
{
case "C":
$tone += 0;
break;
case "D":
$tone += 2;
break;
case "E":
$tone += 4;
break;
case "F":
$tone += 5;
break;
case "G":
$tone += 7;
break;
case "A":
$tone += 9;
break;
case "B":
$tone += 11;
break;
default:
exit("encode_score: unknown tone '" . $note[1] . "'\r\n");
break;
}
if($note[2] == "#")
{
$tone++;
$dur_fp = (float)substr($note, 3);
}
else
if($note[2] == "b")
{
$tone--;
$dur_fp = (float)substr($note, 3);
}
else
$dur_fp = (float)substr($note, 2);
$dur_ms = (int)($step_play_speed / $dur_fp);
$octave = $tone / 12;
$tone = $tone % 12;
$freqA = 440.0 * pow(2, ($octave - 4));
$freq = (int)round($freqA * pow(2, ($tone - 9) / 12.0));
$score_encoded .= int2bin($freq, 2);
$score_encoded .= int2bin($dur_ms, 2);
}
}
return $score_encoded;
}
function step_play_melody($melody)
{
global $step_play_dir;
global $step_play_sid;
while($melody)
{
$freq = bin2int($melody, 0, 2);
$dur_ms = bin2int($melody, 2, 2);
if($freq)
{
if($step_play_dir > 0)
spc_request_dev($step_play_sid[0], "goto +1000000 $freq");
else
spc_request_dev($step_play_sid[0], "goto -1000000 $freq");
usleep($dur_ms * 1000);
spc_request_dev($step_play_sid[0], "stop 0");
}
else // zero frequency is 'rest'
usleep($dur_ms * 1000);
$melody = substr($melody, 4);
}
}
function step_play_harmony($melody1, $melody2)
{
global $step_play_dir;
global $step_play_sid;
$pid_st0 = pid_open("/mmap/st0");
pid_ioctl($pid_st0, "start");
$melody = array($melody1, $melody2);
$melody_next_ms = array(0, 0);
while($melody[0] || $melody[1] || $melody_next_ms[0] || $melody_next_ms[1])
{
for($i = 0; $i < 2; $i++)
{
if($melody_next_ms[$i])
{
if($melody_next_ms[$i] <= pid_ioctl($pid_st0, "get count"))
{
spc_request_dev($step_play_sid[$i], "stop 0");
$melody_next_ms[$i] = 0;
}
}
else
{
if($melody[$i])
{
$freq = bin2int($melody[$i], 0, 2);
$dur_ms = bin2int($melody[$i], 2, 2);
$melody[$i] = substr($melody[$i], 4);
if($freq)
{
if($step_play_dir > 0)
spc_request_dev($step_play_sid[$i], "goto +1000000 $freq");
else
spc_request_dev($step_play_sid[$i], "goto -1000000 $freq");
}
$melody_next_ms[$i] = pid_ioctl($pid_st0, "get count") + $dur_ms;
}
}
}
}
pid_close($pid_st0);
}
?>
Source code for playing music
PHPSource code for playing Santa Claus is Coming to Town.
- step_play_santa.php
- step_play_santa.php
<?php
include_once "/lib/se_step_play.php";
function play_santa_claus()
{
global $step_play_dir;
// Santa Claus is Coming to Town
$melody1a = step_play_encode("4E8 4F8 4G4 4G2.67 4G8 4A8 4B8 5C4 5C2");
$melody1b = step_play_encode("4E8 4F8 4G8 4G8 4G8 4G8 4G4 4A8 4G8 4F4 4F2");
$melody1c = step_play_encode("4E4 4G4 4C4 4E4 4D4 4F4 4F4 3B4");
$melody1d = step_play_encode("4C1 4C1");
$melody2a = step_play_encode("4E8 4F8 4G8 4G8 4G8 4G8 4G4 4A8 4B8 5C8 5C8 5C2");
$melody2b = step_play_encode("4E8 4F8 4G8 4G8 4G4 4G4 4A8 4G8 4F4 4F2");
$melody2c = step_play_encode("4E4 4G4 4C4 4E4 4D4 4F4 4F4 3B4");
$melody2d = step_play_encode("4C1 4C1");
$melody3a = step_play_encode("5D4 5C4 4B4 5C4 4A8 4A8 4A4 4A2");
$melody3b = step_play_encode("5D4 5C4 4B4 5C4 4A8 4A8 4A8 4A8 4A2");
$melody3c = step_play_encode("5E4 5D4 5C#4 5D4 4B4 4B4 4B4 4B8 5C8");
$melody3d = step_play_encode("5D8 5D8 5C8 5C8 4B4 4A4 4G2 4G2");
$melody4a = step_play_encode("4E8 4F8 4G4 4G2.67 4G8 4A8 4B8 5C4 5C2");
$melody4b = step_play_encode("4E8 4F8 4G8 4G8 4G8 4G8 4G4 4A8 4G8 4F4 4F2");
$melody4c = step_play_encode("4E4 4G4 4C4 4E4 4D4 4F4 4G4 5D4");
$melody4d = step_play_encode("5C1 5C1");
$chord1a = step_play_encode("3C4 3E4 3C4 3E4 3F4 3A4 3F4 3A4"); // C F
$chord1b = step_play_encode("3C4 3E4 3C4 3E4 3F4 3A4 3F4 3A4"); // C F
$chord1c = step_play_encode("3C4 3E4 3C4 3A4 3D4 3F4 3G4 3F4"); // C Am Dm G7
$chord1d = step_play_encode("3C4 3E4 3C4 3E4 3F4 3A4 3G4 3F4"); // C F G7
$chord2a = step_play_encode("3C4 3E4 3C4 3E4 3F4 3A4 3F4 3A4"); // C F
$chord2b = step_play_encode("3C4 3E4 3C4 3E4 3F4 3A4 3F4 3A4"); // C F
$chord2c = step_play_encode("3C4 3E4 3C4 3A4 3D4 3F4 3G4 3F4"); // C Am Dm G7
$chord2d = step_play_encode("3C4 3E4 3C4 3E4 3C1"); // C C
$chord3a = step_play_encode("3D8 3B8 3G8 3B8 3D8 3B8 3G8 3B8"); // G
$chord3a .= step_play_encode("3C8 3A8 3F8 3A8 3C8 3A8 3F8 3A8"); // F
$chord3b = step_play_encode("3D8 3A8 3F8 3A8 3D8 3A8 3F8 3A8"); // Dm
$chord3b .= step_play_encode("3C8 3A8 3F8 3A8 3C8 3A8 3F8 3A8"); // F
$chord3c = step_play_encode("3C#8 3A8 3C#8 3E8 3C#8 3A8 3C#8 3E8"); // A
$chord3c .= step_play_encode("3D8 3B8 3G8 3B8 3D8 3B8 3G8 3B8"); // G
$chord3d = step_play_encode("3C8 3A8 3F#8 3A8 3C8 3A8 3F#8 3A8"); // D7
$chord3d .= step_play_encode("3D8 3B8 3F8 3B8 3D8 3B8 3F8 3B8"); // G7
$chord4a = step_play_encode("3C4 3E4 3C4 3E4 3F4 3A4 3F4 3A4"); // C F
$chord4b = step_play_encode("3C4 3E4 3C4 3E4 3F4 3A4 3F4 3A4"); // C F
$chord4c = step_play_encode("3C4 3E4 3C4 3A4 3D4 3F4 3G4 3F4"); // C Am Dm G7
$chord4d = step_play_encode("3C4 3E4 3F4 3A4 3C1"); // C F C
step_play_dir(+1);
step_play_harmony($melody1a, $chord1a);
step_play_dir(-1);
step_play_harmony($melody1b, $chord1b);
step_play_dir(+1);
step_play_harmony($melody1c, $chord1c);
step_play_dir(-1);
step_play_harmony($melody1d, $chord1d);
step_play_dir(+1);
step_play_harmony($melody2a, $chord2a);
step_play_dir(-1);
step_play_harmony($melody2b, $chord2b);
step_play_dir(+1);
step_play_harmony($melody2c, $chord2c);
step_play_dir(-1);
step_play_harmony($melody2d, $chord2d);
step_play_dir(+1);
step_play_harmony($melody3a, $chord3a);
step_play_dir(-1);
step_play_harmony($melody3b, $chord3b);
step_play_dir(+1);
step_play_harmony($melody3c, $chord3c);
step_play_dir(-1);
step_play_harmony($melody3d, $chord3d);
step_play_dir(+1);
step_play_harmony($melody4a, $chord4a);
step_play_dir(-1);
step_play_harmony($melody4b, $chord4b);
step_play_dir(+1);
step_play_harmony($melody4c, $chord4c);
step_play_dir(-1);
step_play_harmony($melody4d, $chord4d);
}
spc_reset();
spc_sync_baud(460800);
step_play_setup(0, 13);
step_play_setup(1, 14);
step_play_tempo(30);
play_santa_claus();
?>
Comments