Hello I'm new + too many ticks

642 views
Skip to first unread message

Martin Granger

unread,
Dec 9, 2018, 12:53:11 PM12/9/18
to vexflow
Hi everybody,
I'm new to this list, and I'm desperately trying to use VF but I guess I'm too bad at coding. I keep having trouble with two errors :
"too many ticks" and "IncompleteVoice:Voice does not have enough notes"
I'm looking for a way to display staves without bars, and without bothering about counting notes.
I've tried addTimeSignature('1/8') (since I don't use shorter notes) but I keep having "too many ticks".
After some googling I understood ".setStrict(false)" could help me, but I just don't know where to put that !
Here's my piece of code, i'll be thankful for any help or hint.

martin



const VF = Vex.Flow;

var vf = new VF.Factory({
  renderer: {elementId: 'boo', width: 800, height: 200}
});

var score = vf.EasyScore();
var system = vf.System();

system.addStave({
  voices: [
    score.voice(score.notes('E4/q, G4/q, E4/8, G4/8, G4/8/r, E4/8, E4/q, G4/q, G4/8, A4/8, G4/8/r, G4/8', {stem: 'up'})),
  ]
}).addClef('treble').addTimeSignature('2/4');

vf.draw();


Chris Blackwell

unread,
Jan 6, 2019, 4:47:55 AM1/6/19
to vexflow
Hopefully not too late to reply, but the answer is you can't do multiple measures of notes in one system. You need to break it up in to multiple systems. Also, you need to set a time signature on the score, not the "addTimeSignature" as that just puts the symbol on a staff. Here's a jsfiddle with what you are trying to do: https://jsfiddle.net/squidbot/0b6hcc69/540/

And the code in case you can't see the fiddle.


const VF = Vex.Flow;
var vf = new Vex.Flow.Factory({renderer: {elementId: 'boo', width: 800, height: 200}});
var score = vf.EasyScore();

score.set({ time: '2/4' });

var x = 0;
var y = 80;
function makeSystem(width) {
var system = vf.System({ x: x, y: y, width: width, spaceBetweenStaves: 10 });
x += width;
return system;
}

var system = makeSystem(220)
system.addStave({
  voices: [score.voice(score.notes('C#5/q, B4'))]
}).addClef('treble').addTimeSignature('2/4');

system = makeSystem(200)
system.addStave({
  voices: [score.voice(score.notes('E4/8, G4/8, G4/8/r, E4/8'))]
});

system = makeSystem(200)
system.addStave({
  voices: [score.voice(score.notes('E4/q, G4/q'))]
});

system = makeSystem(200)
system.addStave({
  voices: [score.voice(score.notes('G4/8, A4/8, G4/8/r, G4/8'))]
});

vf.draw();
Message has been deleted

Chris Blackwell

unread,
Jan 6, 2019, 4:56:37 AM1/6/19
to vexflow
And you know what, I just read this more carefully... you don't want bar lines.

In that case, I don't know that you can get away without counting because it seems the easyscore can only do a measure at a time.  I was able to get the effect you want by adding a time to the score of 8/4 but I did that by counting the beats :) https://jsfiddle.net/squidbot/0b6hcc69/543/

const VF = Vex.Flow;

var vf = new VF.Factory({
  renderer: {elementId: 'boo', width: 800, height: 200}
});

var score = vf.EasyScore();
var system = vf.System();

system.addStave({
  voices: [
    score.voice(score.notes('E4/q, G4/q, E4/8, G4/8, G4/8/r, E4/8, E4/q, G4/q, G4/8, A4/8, G4/8/r, G4/8'), {time: '8/4'}),

Martin Granger

unread,
Jan 7, 2019, 4:06:32 AM1/7/19
to vex...@googlegroups.com
Thanks a lot for your examples and explanations.
What I'm trying to do is translate a sequence of sounds/letters into a sequence of notes (like some musical languages like the silbo, or some percussion languages in Africa).
That's why I can't know in advance how many beats I'll get (for it depends on the input notes).
I suppose I could count the beats with some regex after generating the sequence of notes, but this is a matter of javascript, not vexflow. I'll try and have a look at that.
regards

martin

--
--
You received this message because you are subscribed to the Google
Groups "vexflow" group.
To post to this group, send email to vex...@googlegroups.com
To unsubscribe from this group, send email to
vexflow+u...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/vexflow?hl=en

---
You received this message because you are subscribed to the Google Groups "vexflow" group.
To unsubscribe from this group and stop receiving emails from it, send an email to vexflow+u...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Dave Walters

unread,
Jan 8, 2019, 2:16:14 PM1/8/19
to vex...@googlegroups.com
 Hi Martin, 

Would VF without easy score be more useful in your case? I’m writing notes without worrying  about time signatures. I found easy score too limiting. I’m writing an app for piano scales without bar lines and there were no errors of that kind.
Dave

Sent from my iPhone

Chris Blackwell

unread,
Jan 9, 2019, 12:51:43 AM1/9/19
to vexflow
OK, I think I got it then.  You can change the note string which still uses the EasyScore format and set the beat duration (it doesn't matter much except for formatting so 4/quarter note is probably always fine.) I pulled out the render width and div name since they are repeated. This could easily be turned in to a function and reused. What happens is the string gets parsed by EasyScore, the beats are counted and then the parsed notes are sent to the basic formatting and rendering API's so the need to make measures is bypassed. I'm pretty new to this code base so I'm not sure if this is the best way to do all this, but it seems to work.

var notes = 'E4/q, G4/q, E4/8, G4/8, G4/8/r, E4/8, E4/q, G4/q, G4/8, A4/8, G4/8/r, G4/8, F4/8, E4/8';
const beatDuration = 4;

const renderWidth = 500;
const divName = 'boo';

const VF = Vex.Flow;

var div = document.getElementById(divName);
var renderer = new VF.Renderer(div, VF.Renderer.Backends.SVG);

var factory = new Vex.Flow.Factory({renderer: {elementId: divName}});

renderer.resize(renderWidth + 20, 200);
var context = renderer.getContext();
context.setFont("Arial", 10, "").setBackgroundFillStyle("#eed");

var staff = new VF.Stave(20, 0, renderWidth);
staff.addClef('treble');
staff.setContext(context).draw();

var score = factory.EasyScore();
var parsedNotes = score.notes(notes);

const durationMap = {
'q': '4',
'h': '2',
'w': '1'
}

const durationFractionMap = {
'1': 1,
'2': 1/2,
'4': 1/4,
'8': 1/8,
'16': 1/16,
'32' : 1/32,
'64' : 1/64
}

var beatAccumulator = 0;

for(const staveNote of parsedNotes)
{
var durationStr = staveNote.duration;
if(durationMap.hasOwnProperty(durationStr))
{
durationStr = durationMap[durationStr];
}
beatAccumulator += durationFractionMap[durationStr];
}

var totalBeats = beatAccumulator / (1 / beatDuration);

var voice = new VF.Voice({num_beats: totalBeats, beat_value: beatDuration});
voice.addTickables(parsedNotes);

var formatter = new VF.Formatter().joinVoices([voice]).format([voice], renderWidth)
voice.draw(context, staff);

Martin Granger

unread,
Jan 11, 2019, 6:04:01 PM1/11/19
to vex...@googlegroups.com
Thanks very much Chris, your code fits perfectly my needs (although I can't really figure out what's happening inside !).
In french, we say that "you chewed the work for me". Merci :-)

Andrew Pask

unread,
Jul 10, 2019, 5:27:19 PM7/10/19
to vexflow
Thank you for this code, it has really helped me.


One thing I can't figure out is how to "erase" the notes I have drawn so I can draw some new ones.

Any help much appreciated

Cheers

Andrew

Andrew Pask

unread,
Jul 11, 2019, 10:28:40 AM7/11/19
to vexflow
Reply all
Reply to author
Forward
0 new messages