UNPKG

vexflow

Version:

A JavaScript library for rendering music notation and guitar tablature

233 lines (187 loc) 7.67 kB
/** * VexFlow - Three Voices in single staff tests. * Copyright Mohit Muthanna 2010 <mohit@muthanna.com> */ VF.Test.ThreeVoices = (function() { function concat(a, b) { return a.concat(b); } function createThreeVoicesTest(noteGroup1, noteGroup2, noteGroup3, setup) { return function(options) { var vf = VF.Test.makeFactory(options, 600, 200); var stave = vf.Stave().addTrebleGlyph().addTimeSignature('4/4'); var score = vf.EasyScore(); var noteGroups = [noteGroup1, noteGroup2, noteGroup3].map(function(noteGroup) { return score.notes.apply(score, noteGroup); }); var voices = noteGroups.map(score.voice.bind(score)); setup(vf, voices); var beams = [ VF.Beam.applyAndGetBeams(voices[0], +1), VF.Beam.applyAndGetBeams(voices[1], -1), VF.Beam.applyAndGetBeams(voices[2], -1), ].reduce(concat); // Set option to position rests near the notes in each voice vf.Formatter() .joinVoices(voices) .formatToStave(voices, stave); vf.draw(); for (var i = 0; i < beams.length; i++) { beams[i].setContext(vf.getContext()).draw(); } ok(true); }; } var ThreeVoices = { Start: function() { var run = VF.Test.runTests; QUnit.module('Three Voice Rests'); run('Three Voices - #1', createThreeVoicesTest( ['e5/2, e5', { stem: 'up' }], ['(d4 a4 d#5)/8, b4, (d4 a4 c5), b4, (d4 a4 c5), b4, (d4 a4 c5), b4', { stem: 'down' }], ['b3/4, e3, f3, a3', { stem: 'down' }], function(vf, voices) { voices[0] .getTickables()[0] .addModifier(0, vf.Fingering({ number: '0', position: 'left' })); voices[1] .getTickables()[0] .addModifier(0, vf.Fingering({ number: '0', position: 'left' })) .addModifier(1, vf.Fingering({ number: '4', position: 'left' })); } )); run('Three Voices - #2 Complex', createThreeVoicesTest( ['(a4 e5)/16, e5, e5, e5, e5/8, e5, e5/2', { stem: 'up' }], ['(d4 d#5)/16, (b4 c5), d5, e5, (d4 a4 c5)/8, b4, (d4 a4 c5), b4, (d4 a4 c5), b4', { stem: 'down' }], ['b3/8, b3, e3/4, f3, a3', { stem: 'down' }], function(vf, voices) { voices[0] .getTickables()[0] .addModifier(0, vf.Fingering({ number: '2', position: 'left' })) .addModifier(1, vf.Fingering({ number: '0', position: 'above' })); voices[1] .getTickables()[0] .addModifier(0, vf.Fingering({ number: '0', position: 'left' })) .addModifier(1, vf.Fingering({ number: '4', position: 'left' })); } )); run('Three Voices - #3', createThreeVoicesTest( ['(g4 e5)/4, e5, (g4 e5)/2', { stem: 'up' }], ['c#5/4, b4/8, b4/8/r, a4/4., g4/8', { stem: 'down' }], ['c4/4, b3, a3, g3', { stem: 'down' }], function(vf, voices) { voices[0] .getTickables()[0] .addModifier(0, vf.Fingering({ number: '0', position: 'left' })) .addModifier(1, vf.Fingering({ number: '0', position: 'left' })); voices[1] .getTickables()[0] .addModifier(0, vf.Fingering({ number: '1', position: 'left' })); voices[2] .getTickables()[0] .addModifier(0, vf.Fingering({ number: '3', position: 'left' })); } )); run('Auto Adjust Rest Positions - Two Voices', ThreeVoices.autoRestTwoVoices); run('Auto Adjust Rest Positions - Three Voices #1', ThreeVoices.autorestthreevoices); run('Auto Adjust Rest Positions - Three Voices #2', ThreeVoices.autorestthreevoices2); }, autoRestTwoVoices: function(options) { var vf = VF.Test.makeFactory(options, 900, 200); var score = vf.EasyScore(); var x = 10; var beams = []; function createMeasure(measureTitle, width, alignRests) { var stave = vf.Stave({ x: x, y: 50, width: width }).setBegBarType(1); x += width; var voices = [ score.notes( 'b4/8/r, e5/16, b4/r, b4/8/r, e5/16, b4/r, b4/8/r, d5/16, b4/r, e5/4', { stem: 'up' } ), score.notes( 'c5/16, c4, b4/r, d4, e4, f4, b4/r, g4, g4[stem="up"], a4[stem="up"], b4/r, b4[stem="up"], e4/4', { stem: 'down' } ), [vf.TextNote({ text: measureTitle, line: -1, duration: '1', smooth: true })], ].map(score.voice.bind(score)); beams = beams .concat(VF.Beam.applyAndGetBeams(voices[0], 1)) .concat(VF.Beam.applyAndGetBeams(voices[1], -1)); vf.Formatter() .joinVoices(voices) .formatToStave(voices, stave, { align_rests: alignRests }); } createMeasure('Default Rest Positions', 400, false); createMeasure('Rests Repositioned To Avoid Collisions', 400, true); vf.draw(); for (var i = 0; i < beams.length; i++) { beams[i].setContext(vf.getContext()).draw(); } ok(true, 'Auto Adjust Rests - Two Voices'); }, autorestthreevoices: function(options) { var vf = VF.Test.makeFactory(options, 850, 200); var score = vf.EasyScore(); var x = 10; function createMeasure(measureTitle, width, alignRests) { var stave = vf.Stave({ x: x, y: 50, width: width }).setBegBarType(1); var voices = [ score.voice(score.notes( 'b4/4/r, e5, e5/r, e5/r, e5, e5, e5, e5/r', { stem: 'up' } ), { time: '8/4' }), score.voice(score.notes( 'b4/4/r, b4/r, b4/r, b4, b4/r, b4/r, b4, b4', { stem: 'down' } ), { time: '8/4' }), score.voice(score.notes( 'e4/4/r, e4/r, f4, b4/r, g4, c4, e4/r, c4', { stem: 'down' } ), { time: '8/4' }), score.voice([ vf.TextNote({ text: measureTitle, duration: '1', line: -1, smooth: true }), vf.TextNote({ text: '', duration: '1', line: -1, smooth: true }), ], { time: '8/4' }), ]; vf.Formatter() .joinVoices(voices) .formatToStave(voices, stave, { align_rests: alignRests }); x += width; } createMeasure('Default Rest Positions', 400, false); createMeasure('Rests Repositioned To Avoid Collisions', 400, true); vf.draw(); ok(true); }, autorestthreevoices2: function(options) { var vf = VF.Test.makeFactory(options, 850, 200); var score = vf.EasyScore(); var x = 10; function createMeasure(measureTitle, width, alignRests) { var stave = vf.Stave({ x: x, y: 50, width: width }).setBegBarType(1); var voices = [ score.voice(score.notes( 'b4/16/r, e5, e5/r, e5/r, e5, e5, e5, e5/r' ), { time: '2/4' }), score.voice(score.notes( 'b4/16/r, b4/r, b4/r, b4, b4/r, b4/r, b4, b4' ), { time: '2/4' }), score.voice(score.notes( 'e4/16/r, e4/r, f4, b4/r, g4, c4, e4/r, c4' ), { time: '2/4' }), score.voice([ vf.TextNote({ text: measureTitle, duration: 'h', line: -1, smooth: true }), ], { time: '2/4' }), ]; vf.Formatter() .joinVoices(voices) .formatToStave(voices, stave, { align_rests: alignRests }); x += width; } createMeasure('Default Rest Positions', 400, false); createMeasure('Rests Repositioned To Avoid Collisions', 400, true); vf.draw(); ok(true); }, }; return ThreeVoices; }());