"; wc = window.open("","nocren","width=700,height=620,left=250,top=200") wc.document.write(html); wc.document.close(); } function startup() { document.penta.OptionList[0].checked=true; document.penta.DeBugging.checked=false; var dloc = document.location.toString(); if (dloc.slice(0,4) != "file") { document.penta.DeBugging.style.visibility = 'hidden'; } } function simpleDur(parm) { for (var i=0; i < NoteLengths.length; i++) { if (parm == NoteLengths[i]) return i; } return -1; // Didn't find a notelength } function doTuplets() { var result=new Array(); var tempoOrg, tempoNew, tempoTxt; result=document.penta.timesig.value.match(/(\|Tempo.*Tempo:)(\d+)/) if (result == null) { alert("Tempo missing or invalid, cannot continue"); return 1; } tempoTxt=result[1]; tempoOrg=Number(result[2]); tempoNew=Math.round(tempoOrg * nNum / nDom) var sumBatch=0; tempField=document.penta.IOField.value; tempField=tempField.replace(/\r/g,"") saveBuffer = tempField; var lines=tempField.split("\n"); // Insert new tempo after NWC Clip Header. lines[0] += "\n" + tempoTxt + tempoNew + "|Text:\"\"|Pos:11|Wide:N|Justify:Left|Placement:BestFit|Color:0|Visibility:Never"; for (i = lines.length; i--; i > 0) { if ((lines[i].indexOf("!NoteWorthyComposerClip-End")) > -1) { //Insert original tempo before NWC Clip End lines[i] = tempoTxt + tempoOrg + "|Text:\"\"|Pos:11|Wide:N|Justify:Left|Placement:BestFit|Color:0|Visibility:Never\n!NoteWorthyComposerClip-End"; break; } } if (i < 3) { alert("Could not find the end to insert original tempo"); return 1; } for (var i=0; i < lines.length; i++) { result=lines[i].match(/Dur:([^\|]*)/); if ((result != null) && (lines[i].indexOf("Grace") == -1)) { if (sumBatch == 0) var firstI= i; var durVal = result[1]; var durLen = getNoteLength(durVal); if (durLen == -1) { alert("Illegal length: " + lines[i]); return 1; } else { sumBatch += durLen; } // Keeping a running total of note durations in 768th notes // lines[i] = durLen + " " + lines[i] if ((sumBatch % (nNum*3)) == 0) { // When that total is divisible by tuple number, process a batch. var lastI = i; var midI = Math.floor((firstI + lastI) / 2); //I'll calculate the Pos: later, it's 11 for now. lines[midI] = "|Text|Text:\"" + nNum + "\"|Font:StaffItalic|Pos:11|Wide:N|Justify:Left|Placement:BestFit|Color:0|Visibility:Default\n" + lines[midI]; sumBatch = 0; } // Zero the running total for the next batch (if any). } else { if ((lines[i].slice(0,4) =="|Bar")) if (sumBatch > 0) { alert("Notes left over at end of measure"); return 1; } } } if (sumBatch != 0) { alert("Total note values not a multiple of "+ nNum); return 1; } document.penta.IOField.value=""; for (i=0; i < lines.length; i++) { document.penta.IOField.value+= lines[i]; if ((i + 1) < lines.length) document.penta.IOField.value+= "\n"; } return 0; } function doLengthen() { /* |Text|Text:"\|Note\|Dur:256th\|Pos:-2\|Opts:Stem=Up,Beam=End"|Font:PageSmallText|Pos:-15|Color:3 |Chord|Dur:4th,Slur|Pos:3o,8o^|Opts:Slur=Downward|Color:0|Visibility:Default |Note|Dur:Half,Dotted|Pos:0o|Opts:Stem=Down|Color:0|Visibility:Default */ var result = new Array(), linePart = new Array(), errPos=5; var tempField=document.penta.IOField.value; tempField=tempField.replace(/\r/g,"") saveBuffer = tempField; var lines=tempField.split("\n"); if (lines.length == 1) { lines[1] = lines[0]; lines[0] = "!NoteWorthyComposerClip(2.5,Single)" lines[2] = "!NoteWorthyComposerClip-End" r1=lines[1].match(/^(.*Pos:)([^\|]+)(.*)/) r1[2]=r1[2].replace(/o/g,""); lines[1]=r1[1]+r1[2]+r1[3]; } for (var i=0; i < lines.length; i++) { // Main processing loop tempField=lines[i].slice(0,6); if ((tempField.match(/\|Note|\|Rest|\|Chord/)) && (lines[i].indexOf("Grace") == -1)) { result=lines[i].match(/Chord\|Dur:([^,\|]*)\|.*Dur2:([^,\|]*)\|/) if ((result !=null) && (result[1] != result[2])) { alert("Different durations in a chord cannot be processed"); return 1; } result = lines[i].match(/Dur:([^,\|]*)/); var origDur = result[1]; var DurSub = simpleDur(origDur); if (DurSub == -1) { alert("Unexpected duration: " + origDur + ": " + lines[i]); return 1; } for (var j = 0; j < multArray.length; j++) { linePart[j] = lines[i]; if (j > 0) { // This is never done on the original object, but on everything else var newDur = DurSub + multArray[j]; if (newDur > 6) { if (document.penta.errtxt.checked) { errPos = (errPos > 10)? 5 : errPos + 2; linePart[j] = "|Text|Text:\"Dur:" + origDur + "\"|Font:PageSmallText|Pos:" + errPos + "|Color:3"; } else { alert("Can't create a 1/" + Math.pow(2,newDur) + " note.") return 1; } } linePart[j]=linePart[j].replace(origDur,NoteLengths[newDur]); linePart[j]=linePart[j].replace(origDur,NoteLengths[newDur]); //In case the same duration comes twice. linePart[j]=linePart[j].replace(/=First/g,""); //Remove first designation from copied note linePart[j]=linePart[j].replace(/,Accent/g,""); //Remove accent from copied note } if ((j+1) < multArray.length) { // Never done on the last new object linePart[j]=linePart[j].replace(/=End/g,"") //Remove end designation from original last note (left on copy) result=linePart[j].match(/(^.*Pos:)([^\|]*)/) if (result != null ) { var endLine = RegExp.rightContext; var posArea = result[2].replace(/o/g,""); tempField = result[1]; posArea = posArea.replace(/\^/g,"") //Remove any original tied notes posArea = posArea.replace(/,/g,"^,"); //Add the ^ symbol before any commas posArea+= "^" // and add one on the end (or only) linePart[j] = tempField + posArea + endLine; } result=linePart[j].match(/(^.*Pos2:)([^\|]*)/) //Used for chords with opposite stem directions. if (result != null ) { endLine = RegExp.rightContext; posArea = result[2]; tempField = result[1]; posArea = posArea.replace(/^/g,"") //Remove any original tied notes posArea = posArea.replace(/,/g,"^,"); //Add the ^ symbol before any commas posArea+= "^" // and add one on the end (or only) linePart[j] = tempField + posArea + endLine; } } } tempField = ""; for (j = 0; j < linePart.length; j++ ) { tempField += linePart[j]; if ((j + 1) < linePart.length) tempField += "\n"; } lines[i] = tempField; } } tempField = ""; for (i = 0; i < lines.length; i++ ) { tempField += lines[i]; if ((i + 1) < lines.length) tempField += "\n"; } document.penta.IOField.value=tempField; return 0; } function doRests() { // |Rest|Dur:32nd,Slur|Color:0|Visibility:Never // |Rest|Dur:16th|Opts:Slur=Downward,Lyric=Always|Color:0|Visibility:Default // |Chord|Dur:4th|Pos:1o|Opts:Stem=Up|Dur2:Half|Pos2:-3o|Color:0|Visibility:Default var result = new Array(), linePart= new Array(), errPos=5; var tempField=document.penta.IOField.value; tempField=tempField.replace(/\r/g,"") saveBuffer = tempField; var lines=tempField.split("\n"); if (lines.length == 1) { lines[1] = lines[0]; lines[0] = "!NoteWorthyComposerClip(2.5,Single)" lines[2] = "!NoteWorthyComposerClip-End" r1=lines[1].match(/^(.*Pos:)([^\|]+)(.*)/) r1[2]=r1[2].replace(/o/g,""); lines[1]=r1[1]+r1[2]+r1[3]; } for (var i=0; i < lines.length; i++) { // Main processing loop tempField=lines[i].slice(0,6); if ((tempField.match(/\|Note|\|Rest|\|Chord/)) && (lines[i].indexOf("Grace") == -1)) { result=lines[i].match(/Chord\|Dur:([^,\|]*)\|.*Dur2:([^,\|]*)\|/) if ((result !=null) && (result[1] != result[2])) { alert("Different durations in a chord cannot be processed"); return 1; } result = lines[i].match(/Dur:([^,\|]*)/); var origDur = result[1]; var DurSub = simpleDur(origDur); if (DurSub == -1) { alert("Unexpected duration: " + origDur + ": " + orgLine); return 1; } for (var j = 0; j < multArray.length; j++) { linePart[j] = lines[i]; if (j > 0) { // This is never done on the original object, but on everything else var newDur = DurSub + multArray[j]; if (newDur > 6) { if (document.penta.errtxt.checked) { errPos = (errPos > 10)? 5 : errPos + 2; linePart[j] = "|Text|Text:\"Dur:" + origDur + "\"|Font:PageSmallText|Pos:" + errPos + "Color:3"; } else { alert("Can't create a 1/" + Math.pow(2,newDur) + " note.") return 1; } } linePart[j]=linePart[j].replace(/\|Pos:[^\|]*/,"") //Will not need position linePart[j]=linePart[j].replace(/Note|Chord/g,"Rest") //Change notes or chords to rests linePart[j]=linePart[j].replace(",Accent","") //Remove any accents linePart[j]=linePart[j].replace(origDur,NoteLengths[newDur]); if (linePart[j].match("Triplet=First")) { linePart[j]=linePart[j].replace("Triplet=First","Triplet") } result=linePart[j].match(/Opts:(.*)/) if (result != null ) { tempField = result[1]; oldOps = tempField.split(","); newOps = new Array(); newOps.length = 0; //So code is reusable. var kk=0; for (var k = 0; k < oldOps.length; k++) { if (oldOps[k].match(/Stem|Beam|Accent/)) { // Not used in rests. continue; } newOps[kk++]=oldOps[k]; } linePart[j]=linePart[j].replace(/\|Opts.*/,""); if (newOps.length) { linePart[j]+="|Opts:" for (kk = 0; kk < newOps.length; kk++) { linePart[j]+=newOps[kk]; if ((kk + 1) < newOps.length) linePart[j]+= ","; } } } //More to come, separate with comma. if (newDur < 7) linePart[j]+="|Visibility:Never"; } if ((j+1) < multArray.length) { // Never done on the last new object if (linePart[j].match("Triplet=End")) { linePart[j]=linePart[j].replace("Triplet=End","Triplet") } } } tempField = ""; for (j = 0; j < linePart.length; j++ ) { tempField += linePart[j]; if ((j + 1) < linePart.length) tempField += "\n"; } lines[i] = tempField;} } tempField = ""; for (i = 0; i < lines.length; i++ ) { tempField += lines[i]; if ((i + 1) < lines.length) tempField += "\n"; } document.penta.IOField.value=tempField; return 0; } function doProcess() { var rc=0; readOption(); if (document.penta.OptionList[0].checked) rc=doTuplets(); else { if (document.penta.OptionList[1].checked) rc=doLengthen(); else rc=doRests(); } if (rc == 0) document.penta.IOField.select(); } function demo() { var txtArray = [ ['!NoteWorthyComposerClip(2.0,Single)'], ['|Clef|Type:Treble'], ['|TimeSig|Signature:4/4'], ['|Note|Dur:Whole|Pos:0'], ['|Bar'], ['|Note|Dur:Half|Pos:-1'], ['|Rest|Dur:4th'], ['|Note|Dur:4th|Pos:-2'], ['|Bar'], ['|Note|Dur:4th|Pos:-6'], ['|Note|Dur:4th|Pos:-7'], ['|Note|Dur:16th,Grace|Pos:-7'], ['|Note|Dur:4th,Triplet=First|Pos:-5^'], ['|Note|Dur:4th,Triplet|Pos:-5'], ['|Note|Dur:4th,Triplet=End|Pos:-3'], ['|Bar'], ['|Chord|Dur:16th|Pos:-2,1|Opts:Stem=Up,Beam=First'], ['|Chord|Dur:16th|Pos:-3,0|Opts:Stem=Up,Beam'], ['|Note|Dur:16th,Slur|Pos:-1|Opts:Stem=Up,Beam'], ['|Note|Dur:16th|Pos:-2|Opts:Stem=Up,Beam=End'], ['|Note|Dur:Half,Dotted|Pos:-1'], ['!NoteWorthyComposerClip-End'] ] document.penta.timesig.value = "|Tempo|Base:Quarter|Tempo:76|Text:\"Andante religioso\"|Pos:11|Wide:N|Justify:Left|Placement:AsStaffSignature|Color:0|Visibility:Default" document.penta.IOField.value=""; for (var i = 0; i < txtArray.length; i++) { document.penta.IOField.value+=txtArray[i]; if ((i+1) < txtArray.length) {document.penta.IOField.value+="\n";} } }

Tuplet Assistant

 

Tempo Here:

Tuplet Staff

Played (hidden) Staff

Displayed (muted) Staff

      Select tuplet value:    Errors as text:

Cut Section of NWC file into here.

 

 

To use this page, copy the current tempo indication into the Tempo Here: field.  A hidden faster tempo indication will be inserted before the first note and reset at the end.  The tuplet number will be inserted over the middle of each group of notes.
All non-tuplets in other staves must be lengthened while tuplets are active.  All notes, chords, and rests will be tied (except rests) to the same object with an additional duration.
Takes same input as above (can click on "Restore Last") to insert hidden rests instead of tied notes on displayed/muted staff.

This Web Page Created with PageBreeze Free HTML Editor

Creative Commons License
This work is licensed under a Creative Commons Attribution 3.0 Unported License 2011 by Warren Porter