MidiWriterJS
MidiWriterJS copied to clipboard
Two tracks with different instruments at the same time
I am attempting to create a MIDI file with multiple tracks with different instruments. It seems like when I call
track.addEvent(new MidiWriter.ProgramChangeEvent({instrument: 1}));
it changes the instrument of all the tracks, not just the one attached to.
Here is a small POC as a demo.
const MidiWriter = require('midi-writer-js');
const fs = require('fs')
// Whole note track
const track = new MidiWriter.Track();
track.addEvent(new MidiWriter.ProgramChangeEvent({instrument: 1}));
track.addEvent(new MidiWriter.NoteEvent({pitch: ['E4'], duration: '1', velocity: 100}));
// Metronome track
const metronomeTrack = new MidiWriter.Track();
metronomeTrack.addEvent(new MidiWriter.ProgramChangeEvent({ instrument: 115 }))
const quarterNote = new MidiWriter.NoteEvent({pitch: ['B4'], duration: '4', velocity: 100, channel: 2})
metronomeTrack.addEvent([ quarterNote, quarterNote, quarterNote, quarterNote])
// Build the file and output it:
const write = new MidiWriter.Writer([track, metronomeTrack]);
const file = write.buildFile()
fs.writeFile('myMidi.midi', file, (err) => {
console.log(err || 'success')
})
Expected: One whole note (piano) with four quarter notes (woodblock) in the background Result: One woodblock click followed by multiple piano quarter notes
Here is a working repo of the issue if it helps: https://github.com/jessgusclark/midi-writer-bug
Same here. Seems related to #79.
@jessgusclark did you figured it out since ?
@neoPix It does look like it might be related. but I haven't found a solution to it.
It seems like when you call MidiWriter.ProgramChangeEvent()
it changes it for the entire file which is incorrect. What should happen is the channel and instrument should be called together at the start.
A track should have a channel and instrument associated with it from the start that can't be changed. I would imagine something like this:
const track = new MidiWriter.Track({ channel: 1, instrument: 2 );
Then when converting it to the midi file it picks up the channel and instrument from the Track.
That being said, I haven't had a chance to dive into the conversion process to see.
Any updates on this? We have the same problem and honestly it's incredible how problems keep pilling up without solutions..
Hi @marian-simonca, pull requests are always welcome 👍
Hi @grimmdude ! I know they are welcome, and trust me, if I knew how to do it I would help. At the moment I'm just struggling to understand how/why things like this happen. Sorry if my previous comment was a bit acidic 🙏
I've added channel
support for the ProgramChangeEvent
. Setting different channels for the program change events should solve this, at least it did for me in GarageBand.
track.addEvent(new MidiWriter.ProgramChangeEvent({instrument: 1, channel: 2}));
I have a feeling the note events should technically be added using the same channel, but GarageBand doesn't seem to care. If that is necessary though, I think the ultimate fix will be to support setting the channel on the track level and have all events inherit from that.
@grimmdude thank you very much. This seems like a good solution!