Here is my first attempt at a UserTool to generate ABC from Noteworthy 2. It is not fully functional but covers my basic needs as a folk musician.
<?php
/*******************************************************************************
kbsc_ABCgen.php Version 1.01
This script generates abc code from the selected Noteworthy code
Copyright © 2009 by K.B.S. Creer.
All Rights Reserved
HISTORY:
================================================================================
[2009-01-13] Version 1.00: Initial release
*******************************************************************************/
require_once("lib/nwc2clips.inc");
$keySorF = array ("Fb", "Cb", "Gb", "Db", "Ab", "Eb", "Bb", "F#", "C#" , "G#" , "D#", "A#", "E#", "B#");
$keyName = array ("BEADGCF" => "Cb", "BEADGC" => "Gb", "BEADG" => "Db", "BEAD" => "Ab", "BEA" => "Eb", "BE" => "Bb", "B" => "F", "C" => "C", "F" => "G", "FC" => "D", "FCG" => "A", "FCGD" => "E", "FCGDA" => "B", "FCGDAE" => "F#", "FCGDAEB" => "C#");
$noteName = array ("C,,", "D,,", "E,,", "F,,", "G,,", "A,,", "B,,", "C,", "D,", "E,", "F,", "G,", "A,", "B,", "C", "D", "E", "F", "G", "A", "B", "c", "d", "e", "f", "g", "a", "b", "c'", "d'", "e'", "f'", "g'", "a'", "b'");
$durArray = array ( "Whole" => 64*4, "Half" => 32*4, "4th" => 16*4, "8th" => 8*4, "16th" => 4*4, "32nd" => 2*4, "64th" => 4 ) ;
$durCodeArray = array ( 448 => "14", 384 => "12", 256 => "8", 224 => "7", 192 => "6", 128 => "4", 112 => "7/2", 96 => "3", 64 => "2", 56 => "7/4", 48 => "3/2", 32 => "", 28 => "7/8", 24 => "3/4", 16 => "/", 14 => "7/16", 12 => "3/8", 8 => "//", 7 => "7/32", 6 => "3/16", 4 => "///");
$Accidentals = array ("x" => "^^", "#" => "^", "n" => "=", "b" => "_", "v" => "__");
$knownTypes = array ("Clef", "Key", "TimeSig", "Bar", "Note", "Chord", "Ending", "Tempo", "Rest");
$tempoValue = array ("Eighth" => "1/8", "Eighth Dotted" => "3/16", "Quarter" => "1/4", "Quarter Dotted" => "3/8", "Half" => "1/2", "Half Dotted" => "3/4");
$clef="";
$timeSig="";
$keySig="C";
$tempo="1/4=120";
$beamOn=TRUE;
$slurStart=FALSE;
$slurOn=FALSE;
$slurEnd=FALSE;
$noteDuration=0;
$item=null;
$afterNewLine=TRUE;
$clip = new NWC2Clip('php://stdin');
function nextItem() {
global $knownTypes, $item, $clip;
$oType = "";
while (!in_array($oType, $knownTypes)) {
$item=array_shift($clip->Items);
$o = new NWC2ClipItem($item);
$oType = $o->GetObjType();
}
return $o;
}
function buildNote2 ($src, $dur) {
global $durArray, $durCodeArray, $clef, $noteName, $Accidentals, $beamOn, $slurStart, $slurOn, $slurEnd, $noteDuration;
$noteFactor=1;
$noteBase=1;
$graceNote=FALSE;
$triplet="";
$modifiers="";
foreach ($dur as $key => $val) {
switch ($key) {
case "Triplet":
if ($val=="First") $triplet="(3";
break;
case "Grace":
$graceNote=TRUE;
break;
case "Dotted":
$noteFactor=3/2;
break;
case "DblDotted":
$noteFactor=7/4;
break;
case "Staccato":
$modifiers.=".";
break;
case "Tenuto":
break;
case "Accent":
$modifiers.="L";
break;
case "Slur":
if (!$slurOn) {
$slurStart=TRUE;
$slurOn=TRUE;
}
$slurEnd=FALSE;
break;
default:
$noteBase=$durArray[$key];
break;
}
}
$noteDuration=$noteBase*$noteFactor;
$noteDurChars=$durCodeArray[$noteDuration];
if (!is_array($src)) $src = array($src);
$noteString="";
foreach ($src as $pos) {
$n = new NWC2NotePitchPos($pos);
switch ($clef) {
case "Treble":
$posShift=20;
break;
case "Bass":
$posShift=8;
break;
case "Alto":
$posShift=14;
break;
case "Tenor":
$posShift=12;
break;
default:
$posShift=20;
break;
}
if ($graceNote) $noteString.="{";
$noteString.=$modifiers . $triplet;
if ($n->Accidental!="") $noteString.=$Accidentals[$n->Accidental];
$noteString.=$noteName[$n->Position+$posShift] . $noteDurChars;
if ($graceNote) $noteString.="}";
if ($n->Tied=="^") $noteString.="-";
}
return $noteString;
}
function buildNote ($opts) {
global $durArray, $durCodeArray, $clef, $noteName, $beamOn, $slurStart, $slurOn, $slurEnd, $noteDuration;
$slurEnd=TRUE;
$src=$opts["Pos"];
$dur=$opts["Dur"];
$noteString=buildNote2 ($src, $dur);
if (isset($opts["Pos2"])) {
$src=$opts["Pos2"];
$dur=$opts["Dur2"];
$noteString.=buildNote2 ($src, $dur);
}
if ($slurStart) {$noteString="(" . $noteString; $slurStart=FALSE;}
if (!$beamOn) $noteString=" " . $noteString;
if ($noteDuration>=64) {
$beamOn=TRUE;
} else {
$beamOn=FALSE;
}
if (isset($opts["Opts"])) {
$opts2=$opts["Opts"];
foreach ($opts2 as $key => $val) {
switch ($key) {
case "Beam":
if ($val=="End") {
$beamOn=FALSE;
} else {
$beamOn=TRUE;
}
break;
default:
break;
}
}
}
if ($slurEnd && $slurOn) {$noteString=$noteString . ")"; $slurOn=FALSE;}
return $noteString;
}
function buildRest ($opts) {
global $durArray, $durCodeArray;
$dur=$opts["Dur"];
$restFactor=1;
$restBase=1;
$triplet="";
foreach ($dur as $key => $val) {
switch ($key) {
case "Triplet":
if ($val=="First") $triplet="(3";
break;
case "Dotted":
$restFactor=3/2;
break;
case "DblDotted":
$restFactor=7/4;
break;
default:
$restBase=$durArray[$key];
break;
}
}
$restDuration=$restBase*$restFactor;
$restDurChars=$durCodeArray[$restDuration];
$restString=$triplet . "z" . $restDurChars;
return $restString;
}
echo "X:1\n".
"T:insert tune name here\n";
$o=nextItem();
$oType = $o->GetObjType();
$opts = $o->GetOpts();
while (($oType == "Clef") || ($oType == "Key") || ($oType == "TimeSig") || ($oType == "Tempo")) {
switch ($oType) {
case "Clef":
$clef=$opts["Type"];
break;
case "Key":
$keyNotes="";
foreach ($opts["Signature"] as $key => $val) {
$keyNotes .= substr($key, 0, 1);
}
$keySig=$keyName[$keyNotes];
break;
case "TimeSig":
$timeSig = $o->GetTaggedOpt("Signature") ;
break;
case "Tempo":
if (isset($opts["Base"])) {
$base=$opts["Base"];
} else {
$base="Quarter";
}
$baseTrans=$tempoValue[$base];
$tempoCount=$opts["Tempo"];
$tempo=$baseTrans . "=" . $tempoCount;
break;
}
$o=nextItem();
$oType = $o->GetObjType();
$opts = $o->GetOpts();
}
if ($timeSig != "") echo "M:" . $timeSig . " \n";
echo "L:1/8" . " \n";
echo "Q:" . $tempo . "\n";
$Kcommand="K:" . $keySig;
if ($clef != "" && $clef != "Treble") $Kcommand .= "clef=" . $clef;
$Kcommand .= " \n";
echo $Kcommand;
array_unshift ($clip->Items, $item);
$clef="";
$keySig = "";
foreach ($clip->Items as $item) {
$o = new NWC2ClipItem($item);
$oType = $o->GetObjType();
if ($oType!="Clef" && $oType!="Key") {
if ($clef!="" || $keySig!="") {
if ($afterNewLine) {
$Kcode = "K:";
} else {
$Kcode = "[K:";
}
if ($keySig!="") {
$Kcode .= $keySig;
}
if ($clef!="") {
$Kcode .= " clef=" . $clef;
}
if ($afterNewLine) {
$Kcode .= "\n";
} else {
$Kcode .= "]";
}
echo $Kcode;
$clef="";
$keySig = "";
}
}
switch ($oType) {
case "Bar":
$opts = $o->GetOpts();
if (isset($opts["Style"])) {
switch ($opts["Style"]) {
case "Double":
echo "||";
break;
case "SectionOpen":
echo "[|";
break;
case "SectionClose":
echo "|]";
break;
case "MasterRepeatOpen":
echo "|:";
break;
case "MasterRepeatClose":
echo ":|";
break;
case "LocalRepeatOpen":
break;
case "LocalRepeatClose":
break;
default:
echo "|";
break;
}
} else {
echo "|";
}
if (isset($opts["SysBreak"])) {echo "\n"; $afterNewLine=TRUE;}
$beamOn=TRUE;
break;
case "Note":
$afterNewLine=FALSE;
$opts = $o->GetOpts();
echo buildNote($opts);
break;
case "Chord":
$afterNewLine=FALSE;
$opts = $o->GetOpts();
echo "[" . buildNote($opts) . "]";
break;
case "Ending":
$afterNewLine=FALSE;
$opts = $o->GetOpts();
$endingCode="[";
foreach ($opts["Endings"] as $key => $val) {
$endingCode .= $key . ",";
}
$endingCode = substr($endingCode, 0, -1) . " ";
echo $endingCode;
break;
case "Rest":
$afterNewLine=FALSE;
$opts = $o->GetOpts();
echo buildRest($opts);
break;
case "Clef":
$clef=$o->GetTaggedOpt("Type");
break;
case "Key":
$opts = $o->GetOpts();
$keyNotes="";
foreach ($opts["Signature"] as $key => $val) {
$keyNotes .= substr($key, 0, 1);
}
$keySig = $keyName[$keyNotes];
break;
case "TimeSig":
if ($afterNewLine) {
echo "M:" . $o->GetTaggedOpt("Signature") . "\n";
} else {
echo "[M:" . $o->GetTaggedOpt("Signature") . "]";
}
break;
case "Tempo":
$opts = $o->GetOpts();
if (isset($opts["Base"])) {
$base=$opts["Base"];
} else {
$base="Quarter";
}
$baseTrans=$tempoValue[$base];
$tempoCount=$opts["Tempo"];
if ($afterNewLine) {
echo "Q:" . $baseTrans . "=" . $tempoCount . "\n";
} else {
echo "[Q:" . $baseTrans . "=" . $tempoCount . "]";
}
break;
default:
break;
}
unset($o);
}
exit(NWC2RC_REPORT);
?>
Bug reports, comments and suggestions for what functionality to add next are very welcome. I'm on a fairly steep learning curve for php and object oriented programming.
Bryan