/* Notes to Rests by Warren Porter "restStaff.js" After downloading this file, when setting it up in NWC User Tools create this command line: wscript "'Browse can insert the path for you' \restStaff.js" This can help create a new staff when one is needed for layering. First, copy an entire staff to the clipboard, create a new staff, then cut the clipboard to the new staff. Run this command on that new staff. Clefs, time signatures, and key signatures will be left alone on the new staff, but all notes, chords, and restchords will be replaced by rests. Bars with "full measures" (the norm, it has as many beats as the time signature dictates) will be replaced with whole rests, a measure with more or fewer (like a pickup) will be replaced with rests of the same durations (and order if necessary) or the original notes, rests, chords, or restchords. The new staff may then be used for layered notes for the original staff. It can be run through the MMR tool with the "LayerHide" option so unneeded parts won't display. This is not suited to creating a "tempo" or "conductor" staff. To create a tempo staff which could be layered into all other parts to print parts, the clef or keys should not be copied while tempos or tempo variences should be. */ var rc=0, errMsg="" function getNoteLength(notelet) { // Returns duration of note , whole = 768 var NoteLengths = { "16th":48, "32nd":24, "4th":192, "64th":12, "8th":96, "Half":384, "Whole":768 } parts = notelet.split(","); var noteLength= -1; noteLength = NoteLengths[parts[0]]; var noteLength = ( NoteLengths[parts[0]] === undefined ) ? -1 : NoteLengths[parts[0]]; if (noteLength == -1) return -1; for (var i = 1; i < parts.length; i++) { if (parts[i].substr(0,9) == "DblDotted") { noteLength = noteLength * 7 / 4; } else if (parts[i].substr(0,6) == "Dotted") { noteLength = noteLength * 3 / 2; } else if (parts[i].substr(0,7) == "Triplet") { noteLength = noteLength * 2 / 3; } } return noteLength; } function calculate(clip) { var i, j=0, dsi; var lines = new Array(), result = new Array(), nlines = new Array, mt=0, measureTab = new Array, beatletCount=0, targetMeasure = 768; var thisDur, thisNote, durSplit; lines = clip.split("\r\n"); for (i=0; i < lines.length; i++) { if (lines[i].slice(1,5) == "Text" || lines[i].slice(1,14) == "TempoVariance") continue; if (lines[i].slice(1,5) == "Fake" || lines[i].slice(1,8) == "Context" ) { // For these items, pass them thru and ignore them. nlines[j++] = lines[i]; continue; } if (lines[i].slice(1,8) == "TimeSig") { if (beatletCount == targetMeasure) // Measure exactly full nlines[j++] = "|Rest|Dur:Whole|Visibility:Never"; // Insert whole rest else { for (mt = 0; mt < measureTab.length; mt++) nlines[j++] = "|Rest|Dur:" + measureTab[mt] + "|Visibility:Never";} beatletCount = 0, measureTab.length = 0; mt=0; result = lines[i].match(/ture:(\d+)\/(\d+)/); // Read the time signature if (result == null) //In case it is C or cut time targetMeasure = 768; else targetMeasure = 768 * result[1] / result[2]; // Calculate length of measure nlines[j++] = lines[i]; continue; } if (/Grace/.test(lines[i])) continue; result = lines[i].match(/Dur:([^\|\r\n]+)/) // Looking for anything with a duration if (result != null) { // Duration loop thisDur = result[1]; thisNote = getNoteLength(thisDur); if (thisNote == -1) { errMsg += "Invalid duration of " + lines[i] + "\r\n"; rc=1; continue; } durSplit = thisDur.split(","); for (dsi=1; dsi < durSplit.length; dsi++) if (!(durSplit[dsi].substr(0,9) == "DblDotted" || durSplit[dsi].substr(0,6) == "Dotted" || durSplit[dsi].substr(0,7) == "Triplet")) { durSplit.length = dsi; break; } measureTab[mt++] = durSplit.join(","); if (lines[i].slice(1,15) == "Rest|Dur:Whole") //So existing whole rest in , e.g., 3/4 time won't be treated as having 4 beats. thisNote = targetMeasure; beatletCount += thisNote; continue; } // End duration loop if (lines[i].slice(1,4) == "Bar" || lines[i].slice(1,5) == "Flow" || lines[i].slice(1,7) == "Ending" || lines[i].slice(0,1) == "!"|| lines[i].slice(1,13) == "RestMultiBar" || lines[i].slice(1,9) == "Boundary" || lines[i].slice(1,11) == "Instrument" || lines[i].slice(1,4) == "MPC" || lines[i].slice(1,5) == "Clef" || lines[i].slice(1,4) == "Key" ) { //Bar loop, flow, & spec. endings if (beatletCount == targetMeasure) // Measure exactly full nlines[j++] = "|Rest|Dur:Whole|Visibility:Never"; // Insert whole rest else { for (mt = 0; mt < measureTab.length; mt++) nlines[j++] = "|Rest|Dur:" + measureTab[mt] + "|Visibility:Never";} beatletCount = 0, measureTab.length = 0; mt=0; // Get set up for next measure if (lines[i].slice(1,6) != "Tempo") nlines[j++] = lines[i]; } //End bar loop } //End main processing loop return nlines; } var myLines=calculate(WScript.StdIn.ReadAll()).join("\r\n"); if (rc == 0) WScript.StdOut.Write(myLines); else WScript.StdErr.Write(errMsg); WScript.quit(rc);