function CheckExtremes($o) { global $maximum, $minimum; if ($o === FALSE) { return; } // This might happen is called for Pos2 and there is no Pos2 if (!is_array($o)) { $o = array($o); } foreach ($o as $pos) { if (positionness($pos) > positionness($maximum)) { $maximum = $pos; } // see sub above if (positionness($pos) < positionness($minimum)) { $minimum = $pos; } } }
function &filterPart($action, $part, &$o) { global $single, $gobbleTime, $passTime; // convert eg part="pos=bb-4" to part="pos" and filterPos="v-4" ; if (substr($part, 0, 3) == 'pos') { // convert our double sharps and flats to NWC's x and v notation $part = preg_replace('/##/', 'x', $part); $part = preg_replace('/bb/', 'v', $part); $filterPos = substr($part, 4); // strip off 'pos=' $filterPosness = positionness($filterPos); // and convert to positionness units $part = 'pos'; // for ease of reference below } $oType =& $o->GetObjType(); // May need to modify either of these $opts =& $o->GetOpts(); // if ($oType == "Note") { if (!$single) { $oType = "Rest"; $opts = array("Dur" => $opts["Dur"]); // clear opts except for Dur return $o; } elseif ($part != 'pos') { return $o; } else { if (positionness($opts["Pos"]) == $filterPosness && $action == 'retain' || positionness($opts["Pos"]) != $filterPosness && $action == 'remove') { return $o; } else { $oType = "Rest"; $opts = array("Dur" => $opts["Dur"]); // clear opts except for Dur return $o; } } } // end $oType == Note // we need these so often, just get them once at the start $dur = $opts["Dur"]; if (isset($opts["Dur2"])) { $dur2 = $opts["Dur2"]; } else { $dur2 = NULL; } $topPos = findPos("Pos", $o, 'max'); // get both maxima $topPos2 = findPos("Pos2", $o, 'max'); $botPos = findPos("Pos", $o, 'min'); // and both minima $botPos2 = findPos("Pos2", $o, 'min'); if (isset($opts["Beam"])) { $beam = $opts["Beam"]; } else { $beam = NULL; } if (isset($opts["Color"])) { $color = $opts["Color"]; } else { $color = NULL; } if (isset($opts["Stem"])) { $stem = $opts["Stem"]; } else { $stem = NULL; } // Only chords and RestChords remaining if ($action == "retain") { if ($part == "top") { if ($oType == "Chord") { unset($opts["Pos"], $opts["Pos2"], $opts["Dur"], $opts["Dur2"]); // the following tests the obvious, whether the highest note is Pos or Pos2, // but also, if it is a shared note, in which case the stem up position is retained if (positionness($topPos) > positionness($topPos2) || positionness($topPos) == positionness($topPos2) && $opts["Opts"]["Stem"] == "Up") { // Using Pos. If duration of Pos2 was shorter, ... $opts["Pos"] = $topPos; $opts["Dur"] = $dur; if ($dur2 && durationness($dur) > durationness($dur2)) { // need to "swallow" following short notes $gobbleTime = durationness($dur) - durationness($dur2); } } else { // Using Pos2. If duration of Pos2 was shorter... $opts["Pos"] = $topPos2; $opts["Dur"] = $dur2; if (durationness($dur) < durationness($dur2)) { $gobbleTime = durationness($dur2) - durationness($dur); } // need to "swallow" following short notes } // and of course it's not a chord anymore, just a note $oType = "Note"; return $o; } // end retain, top, chord // Only RestChords left. If Stem is upwards, rest is on top. Get rid of Pos2 notes leaving a rest if ($opts["Opts"]["Stem"] == "Up") { $oType = "Rest"; $opts["Dur"] = $dur; unset($opts["Dur2"], $opts["Pos2"]); return $o; } // This restchord is stem down, meaning notes are on top. Return the top pos2 note. $oType = "Note"; $opts = array("Dur" => $dur2, "Pos" => $topPos2); // because we have removed the shorter duration rest, need to gobble the time difference $gobbleTime = durationness($dur2) - durationness($dur); return $o; } elseif ($part == "bottom") { if ($oType == "Chord") { unset($opts["Pos"], $opts["Pos2"], $opts["Dur"], $opts["Dur2"]); // the following tests the obvious, whether the lowest note is Pos or Pos2, // but also, if it is a shared note, in which case the stem down position is retained if (positionness($botPos) < positionness($botPos2) || positionness($botPos) == positionness($botPos2) && $opts["Opts"]["Stem"] == "Down") { // using Pos, so if we had a Dur2, and it is shorter, we need to set gobbleTime $opts["Pos"] = $botPos; $opts["Dur"] = $dur; if ($dur2 && durationness($dur) > durationness($dur2)) { $gobbleTime = durationness($dur) - durationness($dur2); } } else { $opts["Pos"] = $botPos2; $opts["Dur"] = $dur2; if (durationness($dur) < durationness($dur2)) { $gobbleTime = durationness($dur2) - durationness($dur); } // need to "swallow" following short notes } // and of course it's not a chord anymore, just a note $oType = "Note"; return $o; } // end retain bottom chord // Only RestChords left If Stem is downwards, rest is on bottom. Get rid of Pos2 notes leaving a rest if ($opts["Opts"]["Stem"] == "Down") { $oType = "Rest"; $opts["Dur"] = $dur; unset($opts["Dur2"], $opts["Pos2"]); return $o; } // This restchord is stem up, meaning notes are on bottom. Return the bot pos2 note. $oType = "Note"; $opts = array("Dur" => $dur2, "Pos" => $botPos2); // because we have removed the shorter duration rest, need to gobble the time difference $gobbleTime = durationness($dur2) - durationness($dur); return $o; } else { if ($oType == "Chord") { // search for a match foreach ($opts["Pos"] as $pos) { if (positionness($pos) == $filterPosness) { // return a single note of duration Dur $oType = "Note"; $opts = array("Dur" => $opts["Dur"], "Pos" => $pos); if (isset($beam)) { $opts["Beam"] = $beam; } if (isset($color)) { $opts["Color"] = $color; } if (isset($stem)) { $opts["Stem"] = $stem; } return $o; } } if (isset($opts["Pos2"])) { foreach ($opts["Pos2"] as $pos) { if (positionness($pos) == $filterPosness) { // return a single note of duration Dur $oType = "Note"; $opts = array("Dur" => $opts["Dur2"], "Pos" => $pos); if (isset($beam)) { $opts["Beam"] = $beam; } if (isset($color)) { $opts["Color"] = $color; } if (isset($stem)) { $opts["Stem"] = $stem; } if (durationness($dur) < durationness($dur2)) { $gobbleTime = durationness($dur2) - durationness($dur); } return $o; } } } // no matching pos to retain, so return a rest of the shortest duration (Dur) $oType = "Rest"; $opts = array("Dur" => $opts["Dur"]); return $o; } else { foreach ($opts["Pos2"] as $pos) { if (positionness($pos) == $filterPosness) { // return a restchord with only filterpos of duration Dur $opts["Pos"] = array($pos); return $o; } } // no matching pos to retain, so return a rest of the shortest duration (Dur) $oType = "Rest"; $opts = array("Dur" => $opts["Dur"]); return $o; } // end retain pos in restchord } // end retain pos } // and end retain // that's it for RETAINing. Now for REMOVing a single part // Just need to set gobbletime if removing the last of a shorter note if ($part == "top") { if ($oType == "Chord" && isset($opts["Pos2"])) { if (positionness($topPos) > positionness($topPos2) || positionness($topPos) == positionness($topPos2) && $opts["Opts"]["Stem"] == "Up") { // remove the top pos. filter_out_position_value(&$opts["Pos"], $topPos); if (!count($opts["Pos"])) { $opts["Pos"] = $opts["Pos2"]; $opts["Dur"] = $opts["Dur2"]; unset($opts["Pos2"], $opts["Dur2"]); if (durationness($dur) < durationness($dur2)) { $gobbleTime = durationness($dur2) - durationness($dur); } // need to "swallow" following short notes } if (durationness($dur) > durationness($dur2)) { $passTime = durationness($dur) - durationness($dur2); } // if we're removing a note that is longer than other notes in the chord, // what we really want to do is let the next $passtime worth of notes through unfiltered. // Do this in the main loop with 'if "retain" and gobbling then echo' return $o; } // end remove top pos in chord // remove the top pos2 filter_out_position_value(&$opts["Pos2"], $topPos2); if (!count($opts["Pos2"])) { unset($opts["Dur2"], $opts["Pos2"]); if (durationness($dur) > durationness($dur2)) { $gobbleTime = durationness($dur) - durationness($dur2); } } if (durationness($dur) < durationness($dur2)) { // I've removed the longer note $passTime = durationness($dur2) - durationness($dur); } // need to "swallow" following short notes return $o; // } // end remove top pos or pos2 in chord with both if ($oType == "Chord") { filter_out_position_value(&$opts["Pos"], $topPos); return $o; } // Only RestChords left. If Stem is upwards, rest is on top. Get rid of it if ($opts["Opts"]["Stem"] == "Up") { $oType = "Chord"; $opts["Dur"] = $dur2; $opts["Pos"] = $opts["Pos2"]; unset($opts["Dur2"], $opts["Pos2"]); // because we have removed the shorter duration rest, need to gobble the time difference $gobbleTime = durationness($dur2) - durationness($dur); return $o; } // This restchord is stem down, meaning notes are on top. Remove the top pos2 note. filter_out_position_value(&$opts["Pos2"], $topPos2); // just need to check that we haven't removed the last note if (!sizeof($opts["Pos2"])) { unset($opts["Pos2"]); } return $o; } // end remove top if ($part == "pos") { // remove a part (from a chord or restchord) described by pos if ($oType == "Chord") { filter_out_position_value(&$opts["Pos"], $filterPos); if (isset($opts["Pos2"])) { filter_out_position_value(&$opts["Pos2"], $filterPos); } if (empty($opts["Pos"])) { if (empty($opts["Pos2"])) { $oType = "Rest"; $opts = array("Dur" => $opts["Dur"]); return $o; } else { $gobbleTime = durationness($dur2) - durationness($dur); $opts["Dur"] = $opts["Dur2"]; // move Dur2 to Dur $opts["Pos"] = $opts["Pos2"]; // and Pos2 to Pos unset($opts["Dur2"]); unset($opts["Pos2"]); return $o; } } else { if (empty($opts["Pos2"])) { unset($opts["Pos2"]); unset($opts["Dur2"]); } return $o; } } // Wasn't a chord, must be a restchord. Notes are in pos2 filter_out_position_value(&$opts["Pos2"], $filterPos); if (empty($opts["Pos2"])) { unset($opts["Pos2"]); unset($opts["Dur2"]); unset($opts["Stem"]); $oType = "Rest"; } return $o; } // end remove pos // only removing of bottom part left to do if ($oType == "Chord" && isset($opts["Pos2"])) { if (positionness($botPos) < positionness($botPos2) || positionness($botPos) == positionness($botPos2) && $opts["Opts"]["Stem"] == "Down") { // remove the bot pos. filter_out_position_value(&$opts["Pos"], $botPos); if (!count($opts["Pos"])) { $opts["Pos"] = $opts["Pos2"]; $opts["Dur"] = $opts["Dur2"]; unset($opts["Pos2"], $opts["Dur2"]); if (durationness($dur) < durationness($dur2)) { $gobbleTime = durationness($dur2) - durationness($dur); } elseif (durationness($dur) > durationness($dur2)) { $passTime = durationness($dur) - durationness($dur2); } } return $o; } // end remove bot pos in chord // remove the bot pos2 filter_out_position_value(&$opts["Pos2"], $botPos2); if (!count($opts["Pos2"])) { unset($opts["Pos2"], $opts["Dur2"]); if (durationness($dur2) > durationness($dur)) { $passTime = durationness($dur2) - durationness($dur); } elseif (durationness($dur2) > durationness($dur)) { $gobbleTime = durationness($dur2) - durationness($dur); } } return $o; // can return a chord with only } // end remove bot pos or pos2 in chord with both if ($oType == "Chord") { filter_out_position_value(&$opts["Pos"], $botPos); return $o; } // Only RestChords left. If Stem is downwards, rest is on bottom. Get rid of it if ($opts["Opts"]["Stem"] == "Down") { $oType = "Chord"; $opts["Dur"] = $dur2; $opts["Pos"] = $opts["Pos2"]; unset($opts["Dur2"], $opts["Pos2"]); // because we have removed the shorter duration rest, need to gobble the time difference $gobbleTime = durationness($dur2) - durationness($dur); return $o; } // This restchord is stem up, meaning notes are on bottom. Remove the bot pos2 note. filter_out_position_value(&$opts["Pos2"], $botPos2); // just need to check that we haven't removed the last note if (!sizeof($opts["Pos2"])) { unset($opts["Pos2"]); } return $o; }