where is the name of a file (NWC assumes the path is relative to the NWC2 program folder) containing the following pairs on each line eg C#, Db, E, Fb, F## enharmonics are NOT equivalent! between -8192 and 8191 Note that if you are keen, this will provide up to 35 different pitches (7 notenames times 5 - double flat, flat, nat, sharp, double sharp) Assuming that your midi device is set to a global pitchbend range of +/- 2 semitones, -8192 is two semitones flat, and 8191 is two semitones sharp Assuming also that these values translate linearly to cents, (100 cents = 1 semitone) 1 cent = 40.96 pitchbend units eg for Werckmeister III, based on C (you\'d also want to define Db as C#, etc) you might like to create a file called werckiiic.txt with the following C# -410 D -328 Eb -246 E -410 F -82 F# -492 G -164 Ab -328 A -492 Bb -164 B -328 ' ; exit (NWC2RC_REPORT) ; } // // G l o b a l s, keeping track of state changes for note modifiers (sharps and flats) // $mostRecentClef = "Treble" ; // can be Treble, Bass, Alto or Tenor $mostRecentKeySig = array( ) ; // of form array("C"=>"#", "E"=>"b", etc) $mostRecentAccidentals = array( ) ; // of form array("C"=>"x", "D"=>"b", "E"=>"v" uses nwcs internal form $notesToModify = array( ) ; // array("C"=>-120, "D##"=>-7530 etc) $lastNote = "" ; // return the notename (eg C, D, E) without sharps etc, according to line on staff and clef function linePosToName($pos) { global $mostRecentClef ; $lineName = array( "B", "C", "D", "E", "F", "G", "A" ) ; $clefTranspose = array( "Treble" => 0, "Bass" => 2, "Tenor" => 6, "Alto" => 1, "Percussion" => 2 ) ; $linePos = $pos->Position + $clefTranspose[$mostRecentClef] ; return $lineName[($linePos + 7) % 7] ; } function fullNoteName($pos) { global $mostRecentAccidentals, $mostRecentKeySig; // converts nwc's accidentals to our accidental notation $nwcAccToFullAcc = array("v" => "bb", "b" => "b", "n" => "", "#" => "#", "x" => "##") ; // First, get the note name $noteName = linePosToName($pos) ; // Next, if there is a mostRecentAccidental, use that if (isset($mostRecentAccidentals[$noteName])) return $noteName.$nwcAccToFullAcc[$mostRecentAccidentals[$noteName]] ; else if (isset($mostRecentKeySig[$noteName])) return $noteName.$mostRecentKeySig[$noteName] ; else return $noteName ; } // Create a PitchBend command for the note // Returns empty string if no pitch bend required function getPitchBendFor($pos) { global $notesToModify ; $myFullNoteName = fullNoteName($pos) ; if (isset($notesToModify[$myFullNoteName])) return "|MPC|Controller:pitch|Style:Absolute|TimeRes:Quarter|SweepRes:32|Pt1:0,$notesToModify[$myFullNoteName]|Pos:9|Wide:Y|Justify:Left|Placement:BestFit|Color:0|Visibility:Default\n" ; else return "" ; } require_once("lib/nwc2clips.inc"); // THE MAIN ACTION STARTS HERE array_shift($argv) ; // don't need the program name foreach ($argv as $arg) { if ($arg == "help") help_msg_and_exit() ; else $temperfilename = $arg ; } if (!isset($temperfilename)) abort("Must provide a file name of the temperament file") ; if (file_exists($temperfilename)) $TEMPERFILE = @fopen($temperfilename, "r") ; else abort("Can't open $temperfilename. Check the spelling, and remember \nit is relative to \"".getcwd()."\"") ; $linenum = 0 ; while (!feof($TEMPERFILE)) { $linenum++ ; $line = fgets($TEMPERFILE) ; if (preg_match('/^\s*$/',$line)) continue ; if (!preg_match('/^\s*([a-gA-G](#{0,2}|b{0,2}))\s+(-?\d+)\s*$/', $line, $matches)) abort("Badly formed definition line \"$line\"\nat line $linenum of $temperfilename") ; $matches[1]{0} = strtoupper($matches[1]{0}) ; $notesToModify[ $matches[1] ] = $matches[3] + 8192 ; // adjust for dual controller tweaking } if ($linenum == 0 || count($notesToModify) == 0) abort("There are no temperaments defined in $temperfilename") ; $clip = new NWC2Clip('php://stdin'); // 1. Scan each line echo $clip->GetClipHeader()."\n"; $nothingToDo = TRUE ; foreach ($clip->Items as $item) { $nothingToDo = FALSE ; $o = new NWC2ClipItem($item); if ($o->GetObjType() == "Clef") $mostRecentClef = $o->GetTaggedOpt("Type") ; elseif ($o->GetObjType() == "Bar") $mostRecentAccidentals = array( ) ; elseif ($o->GetObjType() == "Key") { $nwckeysig = $o->GetTaggedOpt("Signature") ; // of form ("C#"=>"", "D#"=>"") foreach($nwckeysig as $key => $val) if ($key != "C") $mostRecentKeySig[$key{0}] = $key{1} ; } elseif ($o->GetObjType() == "Note") { $pos = new NWC2NotePitchPos($o->GetTaggedOpt("Pos")) ; $noteName = linePosToName($pos) ; if ($pos->Accidental != "") $mostRecentAccidentals[$noteName] = $pos->Accidental ; if ($lastNote == fullNoteName($pos)) $pb = "" ; else $pb = getPitchBendFor($pos) ; if ($pb) echo $pb."\n" ; $lastNote = fullNoteName($pos) ; } echo $item ; unset($o); } echo NWC2_ENDCLIP."\n"; if ($nothingToDo) abort("This tool requires a selection. Please select something on the staff before invoking transpose_chords.") ; exit (NWC2RC_SUCCESS) ; ?>