grimmdude / midiwriterjs Goto Github PK
View Code? Open in Web Editor NEW♬ A JavaScript library which provides an API for programmatically generating and creating expressive multi-track MIDI files and JSON.
License: MIT License
♬ A JavaScript library which provides an API for programmatically generating and creating expressive multi-track MIDI files and JSON.
License: MIT License
track.addEvent(new MidiWriter.NoteEvent({
pitch : ['C4','B#4'],
duration : '4'
}));
writes as C4,C4 ; should be C4 C5
I suggest using tonal.note.midi given your claim to support tonal.note output.
hi
How to add note event with different lengths at the same time?
[MidiWriterJS]
new MidiWriter.NoteEvent({pitch:['C4', 'D4', 'E4'], duration: '4'});
[Tone js example]
poly.triggerAttackRelease(["Eb3", "G4", "C5"], "2n");
poly.triggerAttackRelease(["Eb3", "G4", "C5"], ["2n", "4n", "4n"]);
---> i need like this
Hello,
Is there a way to have more than 1 instrument play at a time?
For example with the zelda-main-theme I would like to have the Lead be a violin instead of a piano.
I have tried to change the instrument number as follows
// Lead Instrument
tracks[0] = new MidiWriter.Track();
tracks[0].addEvent(new MidiWriter.ProgramChangeEvent({instrument : 41}));
// Bass
tracks[1] = new MidiWriter.Track();
tracks[1].addEvent(new MidiWriter.ProgramChangeEvent({instrument : 1}));
With this change when I try to play the generated file the lead will start out as a violin but switch back over to a piano when the bass comes in.
Should I be trying to do this in a different way or is it just not possible right now?
This is one of the few meta events left to be implemented. I can take a walk through this the next week if you do not plan to implement it.
Using the npm package, trying to send a controller change message I get :
this.data = Utils.numberToVariableLength(0x00).concat(Constants.CONTROLLER_CHANGE_STATUS, fields.controllerNumber, fields.controllerValue);
^
ReferenceError: Utils is not defined
at new ControllerChangeEvent (/node_modules/midi-writer-js/build/index.js:89:15)
Changing Utils to Utils$1 works, I assume this is a build issue?
Thanks for a great lib.
hey,
i've tried to check out the demo but got a bunch of Blocked loading mixed activce content
Errors for your css and js files. i looked in your config file as well but couldn't find a github.url
variable there. Changing all links to https://
should fix it.
https://developer.mozilla.org/en-US/docs/Security/Mixed_content#Warnings_in_Web_Console
Would it be difficult to add support for:
If not, I could add those to the src file and wherever else determines it
If so, I can specify with ticks, correct?
Please document MidiWriter
's saveMIDI
method - I only found it through StackOverflow.
I am very interested in this project, would like to know more about the note event, especially the sequential option. I can get the point of wrapping note on/off in one note event, but the sequential is still a very ¨special uses case¨. There should be more wrappers of note event itself (chords, tuple, sequential), it should result in a more clear API. Or the pitch array could be an array of objects (note/duration etc)..
Not sure if it makes any sense (maybe i misunderstood the scope of the project), but, once you call an addEvent, there are no way to come back except re-executing the whole source.
What about keeping track of the chunks (related to its MidiWriterJS representation) so it can be possible to edit it?
Thanks
Here's my code (I'm using discord.js and node.js btw, the code is supposed to make a random midi)
no errors occur, it's just when i open the midi file, it has no sound
i did the same code with the example tracks (minus the random numbers and stuff) and the sound was fine. any fix?
Edit: There is sound, but it's really really quiet. How do i make it louder?
Hello. There are no data related to timing in Track.ControllerChange(cc#, val). Only one CC value is exported for each track at tick position 0. I would suggest moving ControlChange to Event type and adding startTick argument to it. In case there is some mechanic to store CC automation, it would be great to add it to documentation. Thank you!
It would be cool to be able to import MusicXML files and convert them to MIDI.
So, I have a "Uncaught ReferenceError: MidiWriter is not defined" , even though I imported on the front end.
There is a folder in node_modules for "Browser" index.min.js , I was hoping that could be used to read midi, modify it , then write midi back to a file blob on the front end/browser.
just trying :
// Start with a new track
var track = new MidiWriter.Track()
track.addEvent(new MidiWriter.NoteEvent({pitch: 'C5', duration: 'T4550'}))
var track = new MidiWriter.Track();
// Define an instrument (optional):
track.addEvent(new MidiWriter.ProgramChangeEvent({instrument : 1}));
// Add some notes:
var note = new MidiWriter.NoteEvent({pitch:['C4', 'D4', 'E4'], duration: '4'});
track.addEvent(note);
// Generate a data URI
var write = new MidiWriter.Writer([track]);
console.log(write.dataUri());`
does not work as I get the error.
I imported in the tag:
I am interested in adding some more functionality to the vexflow part, and was wondering if I could get some guidance on MidiWriter to handle grace notes?
Since a grace note comes right before its target note, what would be the best way to create a NoteEvent for that grace note. I was thinking of adding the grace note to a separate track from the target note? Something like:
Adding a 8th note grace note to a quarter note
var gracenote = new MidiWriter.NoteEvent({wait: '8', pitch:['E5'], duration: '8'});
tracks[2].addEvent(gracenote);
var targetnote = new MidiWriter.NoteEvent({pitch:['E5'], duration: '4'});
tracks[1].addEvent(targetnote);
Although I think that would just play the gracenote after the quarter an 8th of a beat later? Any thoughts on best way to do this?
An error occurs in v1.7.0 as shown below.
ERROR in ./node_modules/midi-writer-js/build/index.js Module not found: Error: Can't resolve 'fs' in '......./node_modules/midi-writer-js/build'
Perhaps, const fs = require('fs');
of saveMIDI function in Writer class is the problem.
Cool component. Can you add some sample code on defining instruments. I'm only able to get the Piano to play and would like to try out others and add custom ones.
Hi there,
I'm using MidiWriterJS for a small node project generating music via the wonder of MIDI files. Thanks very much for MidiWriterJS!
I'm interested in contributing to the codebase as and when I can, and was wondering what your feelings were on a PR adding linting to the project and doing some tidying as a first step?
Me again, was wondering whats the best way to handle doubling a note? Say for example I have a 16th note that needs to get doubled into two 32nd notes. Currently MidiWriter does not support 32nd notes as far as I can see? What would be the best way to do this?
Hello,
I seem to be getting some problems downloading files with a time signature denominator of 8. With Logic/Garageband, the the DAW doesn't even really recognize the file, but it imports the tempo and the time signature with a denominator of 4. Ableton imports it with the denominator 4 and an added note at C0 with a duration equal to the length of the file.
All DAWs I mentioned work just fine for denominators of 4 and 16.
Does this seem like it could be an error on your end of the code?
Thanks a lot!
While there is no support for dotted whole notes, dotted dotted whole notes, etc.
More generally support to override the string based duration specification and opt for purely a numerical value of quarter notes does not seem to be supported.
Hey, @grimmdude!
I have been checking the browser library and I couldn't make it work.
Code:
function createMidi(){
console.log('---------- CreateMidi ----------');
var MidiWriter = require('MidiWriter');
var track = MidiWriter.VexFlow.trackFromVoice(voice);
var writer = new MidiWriter.Writer([track]);
console.log(writer.dataUri());
[...]
}
Error:
TypeError: MidiWriter.VexFlow.trackFromVoice is not a function.
You can check it up here:
Thanks so much!
I checked basic demos with MIDI.js & it works well.
I played with example "chopin-prelude-e-minor", & tried to play this melody with different tempo, but
it always play with same tempo, for example tracks[0].setTempo(x); x=120 or 240 or 480.
Am I missing some information about usage of tempo? please guide
I find that setting NoteEvent
's duration
parameter to Tn
, where n
> 1, results in only some of the notes of the chord being sustained.
Am I doing something wrong?
const track = new MidiWriter.Track();
track.addTrackName('Colours ' + this._inputFilename);
track.setTimeSignature(1, 1);
track.addEvent(
new MidiWriter.NoteEvent({
velocity: 1,
duration: 'T3', // 'T15', // 'T1584'
pitch: ['D4', 'F4', 'A4'],
startTick: 0
})
);
new MidiWriter.Writer(track)
.saveMIDI('temp');
Hello!When i try to create a pattern with Triplets and export the generated MIDI file to the DAW (Ableton or Bitwig) they doesnt fit the Grid Subdivisions and begin to be little out of Project Tempo.
Thanks!
please example code :D
Need to add support for time signatures.
Tempo is rounded to 4 decimals, f.ex. 163.9998 instead of 164bpm. I can really only visualize this in logic (garageband rounds the number down and ableton rounds it up).
hi
how to write double dotted note and triple dotted note?
Is there any way of, in a single track, playing two notes, with different durations, simultaneously?
I mean, imagine an A4
and an E4
; One whole note, the other quarter note; Both starting together. Is there any way of producing it with this API?
The same for arpeggios: is it possible to start a note before stopping the previous one?
I set the channel to 9 for percussion midi, but it is not set.
i try it
new MidiWriter.NoteEvent({pitch:"C1", duration: '16', velocity:100, channel: 9});
and export midi file.
---- FILE START ----
---- FILE HEADER ----
format: 0
tracks: 1
time division: 128
---- TRACK 1 (2187 bytes) ----
delta: 0
Set Tempo: 130 BPM
delta: 0
Note On (channel 0): C1 with velocity 127
@shivrajsa
Please refer to this issue.
First of all I'm sorry if I'm gonna makes some mistakes, consider I do not know about Indian music a lot.
Think in quarter, consider the teentaal it's a 16 beats cycle, wrapped at 4 (4/4/4/4), so my suggestion is to start a time signature of 16/4 (the whola cycle). This mean that everyone of each
dhaa dhin dhin dhaa/ dhaa dhin dhin dhaa/ dhaa tin tin taa/ taa dhin dhin dhaa
is a quarter note.
Suppose the nth beat should contain two notes of melody (in Bhatkhande notation system something like: SaNi) so every notes of that beat would be the half of a quarter (in western notation it will be the eighth note). If you need to dived one single beat in an odd number of notes (3,5,7) so you will use triplet, quintet and so on.
Every single beat in your cycle counts of one quarter, and you can fill it with an amount of notes which the total duration equals to one quarter.
Think of the rupak: it is a 7 beats cylce made of 3 + 2 + 2
ti ti naa / dhi naa / dhi naa
, so your signature will be 7/4 and group them as three two and two.
Here follow the MidiWriterJS code to generate
bandish in Raag Kedar, set to the Teentaal rhythm cycle, sung or played at a lively (drut) tempo
please refer to this link http://raag-hindustani.com/Notation.html
THE FOLLOWING WILL NOT WORK (there are some works to do on MidiWriterJS to supports
more western music notation), but it still a valid example of how you can do it.
Also note that, because of the above sentence, this is only the 1st refrain.
var tracks = [];
tracks[0] = new MidiWriter.Track();
// Western equivalent for Standard Teental (16 beat cyle, 4 sections of 4 beats)
// In western 16/4 means that ONE single beat is the sum of 16 quarter notes
// which fits perfect a standard Teental
tracks[0].setTimeSignature(16, 4);
// Equivalent for Drut Laya
tracks[0].setTempo(160);
var notes;
// melody
tracks[1] = new MidiWriter.Track();
notes = new MidiWriter.NoteEvent({wait:'1.', pitch:['C4', 'D4', 'C4', 'G4', 'G4', 'G4', 'F#4', 'G4'], duration: '4', sequential: true});
tracks[1].addEvent(notes);
notes = new MidiWriter.NoteEvent({pitch:['A4', 'A#4', 'A4', 'G4'], duration: '4', sequential: true});
tracks[1].addEvent(notes);
notes = new MidiWriter.NoteEvent({pitch:['F#4', 'G4', 'A4', 'G4'], duration: '8', sequential: true});
tracks[1].addEvent(notes);
notes = new MidiWriter.NoteEvent({pitch:['F4', 'F4'], duration: '2', sequential: true});
tracks[1].addEvent(notes);
notes = new MidiWriter.NoteEvent({pitch:['G4', 'G4'], duration: '4', sequential: true});
tracks[1].addEvent(notes);
notes = new MidiWriter.NoteEvent({pitch:['C5'], duration: '2', sequential: true});
tracks[1].addEvent(notes);
notes = new MidiWriter.NoteEvent({pitch:['A4', 'G4'], duration: '4', sequential: true});
tracks[1].addEvent(notes);
notes = new MidiWriter.NoteEvent({pitch:['F4'], duration: '2', sequential: true});
tracks[1].addEvent(notes);
notes = new MidiWriter.NoteEvent({pitch:['A4', 'G4'], duration: '4', sequential: true});
tracks[1].addEvent(notes);
notes = new MidiWriter.NoteEvent({pitch:['F4', 'D4'], duration: '4', sequential: true});
tracks[1].addEvent(notes);
notes = new MidiWriter.NoteEvent({pitch:['C4'], duration: '2', sequential: true});
tracks[1].addEvent(notes);
Hi Garrett,
Would be a good idea to have a develop (or more, see git flow) branch(es), so the master branch will be always clean and stable.
-Mauro
It would be good to have the set tempo parameter as beats/minute instead of the plain midi format
I am trying to adapt part of the MidiWriterJS code to play with the VexTab data and I got a problem.
Uncaught ReferenceError: notes is not defined
in the notes[i] array:
if (tickable.noteType === 'n') {
notes[i].keys.forEach(function (key) {
pitches.push(key.replace('/', ''));
});
Where is notes defined?
Hi! thankful for this project -- ran into issues trying to use NoteOn / NoteOff!
Error: TypeError: _midiWriterJs.default.NoteOnEvent is not a constructor
or NoteOffEvent
.
Code:
const noteEvent = {
pitch: KEY_TO_NOTE[message.data[1]],
velocity: message.data[2],
startTick:
"158"
};
console.log(noteEvent);
events.push(new MidiWriter.NoteOnEvent(noteEvent));
I think this is a quick fix -- exporting the events in main.js?
Would be cool, and fairly trivial, to support MIDI export from VexFlow
oops wrong repo
Hi, thanks for this useful package!
I've some problems to set tracks name. I've tried the following:
var tracks = [];
tracks[0] = new MidiWriter.Track();
tracks[0].addEvent(new MidiWriter.ProgramChangeEvent({instrument : 1}));
tracks[0].addInstrumentName("piano");
but when importing in Ableton or converting as json at https://tonejs.github.io/MidiConvert/ the tracks name doesn't appear. Any hint?
Thanks, cheers!
I have tracks for several different notes on the same instrument that I'm constructing independently. I get the current sound when I export these tracks as an array. However, I want the output to have a single track. When I use mergeTracks
, I the tracks end up appearing one after the other. Is there any easy way to do this?
you write the Description for wait time:
1 : whole
2 : half
d2 : dotted half
4 : quarter
d4 : dotted quarter
8 : eighth
8t : eighth triplet
d8 : dotted eighth
16 : sixteenth
Tn : where n is an explicit number of ticks
But if I want to wait for longer,how can i do for this.
such i want to wait 8s. And I don't know what the mean of 'Tn(where n is an explicit number of ticks)'
are there any doc? because i found that your other project (MidiPlayer) , mentioned the sound_font.
so,I think that it may be can choose the other instrument not only the piano sound.
Hi, thanks for this library, much appreciated!
Perhaps I haven't completely understood how to use this.. but I'm trying to find how to add empty space between notes.
We have a simple grid editor here and in our model there are beats that are filled or empty. So my approach was to cycle through our song data and generate note events when there is a note, and leave gap when there is no note.
This is what I assumed would work:
let note = new MidiWriter.NoteEvent({ wait: 16 })
However it makes a following error. Any tips?
I am getting following error message when trying to use saveMIDI function.
I think that fs node module is not included properly in the library.
/xyz/node_modules/midi-writer-js/build/index.js:1005
fs.writeFile(filename + '.mid', buffer, function (err) {
^
ReferenceError: fs is not defined
at Writer.saveMIDI (/xyz/node_modules/midi-writer-js/build/index.js:1005:4)
at Object.<anonymous> (/xyz/example.js:27:7)
at Module._compile (module.js:573:30)
at Object.Module._extensions..js (module.js:584:10)
at Module.load (module.js:507:32)
at tryModuleLoad (module.js:470:12)
at Function.Module._load (module.js:462:3)
at Function.Module.runMain (module.js:609:10)
at startup (bootstrap_node.js:158:16)
at bootstrap_node.js:598:3
First off: fantastic work on this! Thank you for all the time you've put in, and for making it available for everyone to use. I've used it in many projects already.
One thing that has tripped me up a few times is the inability to add notes at specific points in time. Say, for instance, I already have all of my notes in some data structure somewhere and I already know where, exactly, I want all of them to go. I've always had to do awkward, hacky stuff with the wait
and duration
parameters in order to do this.
That being said, two questions:
Hi there!
I'm just starting to play around with MidiWriterJS. Many thanks for it, looks cool!
Am running in node not the browser. When I try to write.saveMIDI()
I get this error;
.../Projects/midi-maker/node_modules/midi-writer-js/build/index.js:1005
fs.writeFile(filename + '.mid', buffer, function (err) {
^
ReferenceError: fs is not defined
I just changed fs.writeFile(filename
to require('fs').writeFile(filename
to hack around it for now. I would do a PR but am unfamiliar with Bower, so no idea what's going on in yr source, sorry :)
This library seems very interesting.
Is it possible to give duration in milliseconds, or full control over duration instead of fix values.
It seems Pitch Bend was not implemented.
The following patch implements this by adding a new class :
PitchBendEvent
Using field "bend", containing a float ranging [-1,1], zero meaning no bend.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.