Vexflow: Export MIDI?

Created on 12 Jun 2016  路  16Comments  路  Source: 0xfe/vexflow

Is it possible to export MIDI from vexflow?

question

Most helpful comment

I've started a basic implementation this which works pretty well as a proof of concept:
https://github.com/grimmdude/MidiWriterJS#vexflow-integration

I'll be dialing it in as time allows.

-Garrett

All 16 comments

No it does not, consider looking at tonal, teoria, jsmidgen, MIDI.js depending on your needs

Thanks, I was looking for something that's already tied into VexFlow. I've written a similar library (MidiWriterJS) and was thinking about writing a bridge so it can be used to generate a MIDI file from VexFlow renders.

As @Silverwolf90, Vexflow does not natively support MIDI, but a lot of VexFlow players work by attaching audio events to the tickables in the voices. This actually works quite well, so I don't think it would be hard to generate MIDI from VexFlow voices.

The things you'll need to track are the places where written notation is different from the played notes (e.g., implied accidentals.) You can use setPlayNote to do that (which is what VexTab does.)

Thanks for the info @0xfe. When working with a tickable object what's the best way to determine if it's a rest or a note? The only indicator is glyph.rest as far as I can tell. Or is that a scenario where using setPlayNote is needed? I guess I'm not understanding how to use that method.

-Garrett

I believe there will be a staveNote.noteType property which will be set to 'r'

Yes, you can use staveNote.noteType. However, ideally, you would use setPlayNote on all the notes in your voices and not rely on the internals for sound. The data provided can be completely arbitrary, so you can really attach anything to the elements.

For example:

note.setPlayNote({midiNote: 61, velocity: 100, rest: false, cursor: [45, 20]});

Very interesting.

My initial thought was to create a MIDI export from the voices of existing VexFlow code; but wouldn't using setPlayNote require any notation to be re-written using this method for every 'playable' note? Apologies if I'm not understanding the usage.

You can do what you're saying without using setPlayNote -- but you'll have to rely on some of the internal details for things like rests. You also won't know about implied accidentals (because they're not rendered.)

So, a better approach is to call setPlayNote as you build the notes and voices, so later on when you're exporting, you can simply use the data from getPlayNote, instead of peeking into VexFlow structures.

Using staveNote.noteType seems to work fine for me. I can handle the logic of tracking implied accidentals separately. With setPlayNote it just feels like needing to pass extra information is a bit redundant since all the information I need (for now) is already specified when the StaveNote was created. If more information is needed later (such as velocity options) I could use getPlayNote for that.

Thanks @0xfe and @Silverwolf90

I've started a basic implementation this which works pretty well as a proof of concept:
https://github.com/grimmdude/MidiWriterJS#vexflow-integration

I'll be dialing it in as time allows.

-Garrett

@grimmdude I have been exploring your code. Good work. I am trying to develop a basic webtool to parse from VexTab plain-text to a downloadable MIDI file.
I hope it finally works by using MidiWriterJS in between. It is an awesome lib.
The point is how I can go from the Vextab object (that I populate parsing a String of plain vextab) to the Voice object that you use in your vexflow-integration. Do you have any idea?

Hi @dgrmunch,

Thanks for your message. To be honest, I'm not sure. Maybe @Silverwolf90 or @0xfe can help with an answer to that.

In fact, my progress on this integration is sort of suspended because of a lack of understanding of VexFlow. I'm not sure my current approach is the best, I need to spend time to familiarize myself with it more and I haven't had the chance to do that much yet. As it stands the documentation here is all I've got for current integration with MidiWriterJS: https://github.com/grimmdude/MidiWriterJS#vexflow-integration

As you can see in previous comments, @0xfe has provided his recommended solution for integration with VexFlow but, as I mentioned, I haven't had a chance to really dive deep into it. I would love to make more progress on integrating the two libraries though, perhaps I will spend some time this weekend on it if time allows. Pull requests are always welcome!

-Garrett

@dgrmunch The Artist class of VexTab has a method called getPlayerData which will return the voices in the result (inside the voices field of the result.)

Cool @grimmdude @0xfe! Thank you guys, I am gonna play a little bit :-)

Hi @0xfe,

I'm changing my approach to be more aligned with your original suggestion of using setPlayNote. Could you give me an example of how I would access this data once set? Would I access it from voice.tickables directly, or is there a better way? Thanks,

-Garrett

Was this page helpful?
0 / 5 - 0 ratings

Related issues

sug1no picture sug1no  路  6Comments

Silverwolf90 picture Silverwolf90  路  4Comments

gristow picture gristow  路  5Comments

HollyJHuber picture HollyJHuber  路  5Comments

jeroenlammerts picture jeroenlammerts  路  3Comments