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
When I installed this, I got a generic error message on a file with just a simple, two measure d major scale on the treble clef. Any ideas?
Bryan hasn't posted in over a year.
I only had "php.php.exe" .. close but no cigar.
After fixing it I took it's output to my gizmo--the generated line was almost identical to the original. The notes were fine but there were a few problems with slurs and beams on grace notes and I couldn't handle tenuto lines over some notes. Finally a major incentive to learn php.
Once again, many thanks for your help.
Welcome Back!
I got it working but haven't done too much with it yet. This is what it produced:
X:1
T:insert tune name here
M:4/4
L:1/8
Q:1/4=60
K:C
(^g4-gg) ((3g/a/g/^^f/g/)|(3a^c=d (3^e^fa (^c'=c') ({b/}{^c'/} b)a|^g2(g2-g3/2g/) (g3/2g/)|^g2(g2-g3/2g/) g3/2(g/|_a3/2a/) (a3/2a/) (a3/2=g/) (a3/2_b/)|(_a3/2g/) (a3/2_b/) (3_d'_c'b (3ag_g|(3f_ef (3_afa (3_c'ac' (3_e'c'e'|f'z Lb2Lb2Lb2
and the attachment shows the original NWC (created to avoid an awkward page turn) as well as my conversion back to NWC. My page can't handle tenutos yet, it missed a triplet and interpreted the
( as the beginning of a slur. Time for me to get tinkering again.
Please check out this thread (https://forum.noteworthycomposer.com/?topic=7586.0) if you haven't already.
Again, welcome back.