Git Product home page Git Product logo

jsmidgen's People

Contributors

alex-wilmer avatar dingram avatar timmydoza avatar walmik avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar

jsmidgen's Issues

Drums

Hi,

I cant seem to program midi drums, can you help me which channel and instrument I should choose for it? Thanks a lot.

Best,
Cem

Large MIDI files cause `RangeError: Maximum call stack size exceeded` when writing to bytes

When writing a large midi file using File.prototype.toBytes(), an error is thrown::

/Users/me/node_modules/jsmidgen/lib/jsmidgen.js:122
			return String.fromCharCode.apply(null, byteArray);
			                           ^

RangeError: Maximum call stack size exceeded
    at Object.codes2Str (/Users/me/node_modules/jsmidgen/lib/jsmidgen.js:122:31)
    at /Users/me/node_modules/jsmidgen/lib/jsmidgen.js:658:18
    at Array.forEach (<anonymous>)
    at File.toBytes (/Users/me/node_modules/jsmidgen/lib/jsmidgen.js:657:15)
    at end (/Users/me/Desktop/mpp2midi/main.js:72:48)
    at ReadStream.<anonymous> (/Users/me/Desktop/mpp2midi/main.js:123:34)
    at emitOne (events.js:116:13)
    at ReadStream.emit (events.js:211:7)
    at addChunk (_stream_readable.js:263:12)
    at readableAddChunk (_stream_readable.js:250:11)

I personally solved it by replacing the following code

jsmidgen/lib/jsmidgen.js

Lines 121 to 123 in 97c1270

codes2Str: function(byteArray) {
return String.fromCharCode.apply(null, byteArray);
},

with this

		codes2Str: function(byteArray) {
			var string = "";
			byteArray.forEach(byte => string += String.fromCharCode(byte));
			return string;
		},

License file

Great library. I'd love to use it in a project, but you don't have a license file so i'm not sure if that'd be ok. Would you please add one or clarify? Thanks!

End of Track Event should have no data

This line assumes that a MetaEvent is invalid unless it has data; however, from what I understand the EOT event should not have any data.

Passing in any truthy data alongside a Midi.MetaEvent.END_OF_TRACK will result in a Error: fluidsynth: error: Invalid length for EndOfTrack event when using something like fluidsynth.

I am having trouble tracking down where this rule is defined in docs and am having trouble pinpointing it...

Do multiple tracks work?

I'm not having any luck getting multiple tracks to export, even though the track count and their corresponding events properties appear to match.

How to add note pauses?

I would like to add silent notes (pauses) directly just like I can add a d4 or any other note. I'm unable to find this in documentation. Any help would be appreciated.

What's the max of duration and time of the note?

At the index page of this project I've read:

Time and duration are specified in "ticks", and there is a hardcoded value of 128 ticks per beat. This means that a quarter note has a duration of 128.

But I successfully used this code:

let track3 = new midi.Track();
track3.setTempo( 60 );
track3
	.instrument( 1, 3 )

	.addNote( 1, 'c2', 1024 )

	.noteOn( 1, 'c4', 0 )
	.noteOn( 1, 'c4', 128 )
	.noteOn( 1, 'c4', 128 )
	.noteOff( 1, 'c4', 128 )

it sustains a note for duration equals to 1024. Why does it works then if the main page says that 128 is max? It works properly as expected! But what the max of a duration then?

Notes are rendered an octave lower

Execute the following script to create a MIDI file that contains a single C4 note. Import the MIDI file in a software like Garage Band or Ableton Live. The generated note will show C3.

var Midi = require('jsmidgen');
var fs = require('fs');

var file = new Midi.File();
var track = new Midi.Track();
file.addTrack(track);

track.addNote(0, 'c4', 64);

fs.writeFileSync('test.mid', file.toBytes(), 'binary');

Is that a bug with the durations in noteOn?

let pianoTrack = new midi.Track()
pianoTrack.setTempo( 120 )
pianoTrack.instrument( 0, 0 )

pianoTrack
	.noteOn( 0, 'c4', 0 )
	.noteOn( 0, 'e4', 256 )
	.noteOn( 0, 'g4', 512 )

	.noteOff( 0, 'c4', 512 )
	.noteOff( 0, 'e4', 512 )
	.noteOff( 0, 'g4', 512 )

It sounds wrong. Each new note should sounds in the same interval:

.noteOn( 0, 'c4', 0 )
.noteOn( 0, 'e4', 256 )
.noteOn( 0, 'g4', 512 )

Because here we have: 0, +256, +256. Intervals of delay should be equal but it's not. Is that a bug?

Allow Add System Exclusive Messages to Track

On one of projects I am working on, I want to add MIDI system exclusive messages for my custom need; however, there are no way of adding that (at least officially).

After reading the source code, I found it's able to pass a object with toBytes function. So, I am using this workaround:

// add GM reset
track.addEvent({
    toBytes() {
        // Channel 1 (1 byte), message start (1 byte), message length (1 byte), message (5 bytes)
        return [0x00, 0xF0, 0x05, 0x7E, 0x7F, 0x09, 0x01, 0xF7];
    },
}); // add `as any` before the right parentheses if you using TypeScript

It would be much appreciated to add this function officially, since sometimes MIDI sysex is still need to be used.

[feature request] - jsmidgen - idea for a project based in jsmidgen (automatic music generation)

Core Concept

  • Develop an AI system with a sophisticated understanding of music theory, akin to ChatGPT's language capabilities. This system aims to generate jsmidgen files, providing a formalized musical dialogue, which can themselves generat musescore projects that can be rendered with c++ and cuda or otherwise rendered in real time

Objectives

  • Create an abstraction layer, inspired by ChatGPT, to express complex musical ideas and generate cascades of Musescore files.
  • Extend functionality beyond mere MIDI files, enabling the creation of intricate compositions using jsmidgen.
  • Implement CUDA and C++ for efficient rendering, allowing the generation of an extensive library of high-quality music files.

Problem Statement

  • The challenge lies in formalizing intricate musical concepts and leveraging an abstraction layer similar to ChatGPT. The goal is to produce an abundance of Musescore files using jsmidgen and efficiently render them with CUDA and C++.

Previous Work

  • Grounding upon Algorrithmic Composition thought coming from a rich history of AI experiments in music creation, spanning from early Koenig and Xenakis to the thoguht of Bach Palestrina and Guillaume de Machaut.

Contextual Relevance

  • Addressing the increasing demand for automated tools capable of generating vast amounts of music, particularly for virtual reality, augmented reality, mixed reality, and hybrid reality systems.

Fascinating Additional Insights

  • Integration flexibility extends across diverse environments, encompassing Unity, Unreal Engine, Cryengine, Godot, Processing, OpenFrameworks, Cinder, P5Js, Threejs, and more.
  • Seamless binding capabilities to a wide array of programming languages including C++, Java, Python, Nodejs, Ruby on Rails, Bash, PowerShell, and others.
  • Compatibility extends to music-oriented platforms such as Ableton, MaxMSP, Puredata, Csound, and Supercollider.
    The system's adaptability is highlighted by its capacity to be invoked through system commands, making it applicable across an extensive range of language libraries and framework APIs.

Support for decimal pitches?

Looks like a useful module, thank you.
Would it be a big deal to allow functions to use decimal pitches rather than c5/etc?
I'm about to use the module for the first time, and will have to use noteFromMidiPitch

Adding velocity or time parameter to .addNote() does nothing.

When calling this function the last two parameters are ignored:
track.addNote(0, 50, 32, 0, 32, 127);

The readme says these parameters are able to be given.
The jsmidgen code seems to suggest these parameters are not used.

Can you help me figure out what's going wrong?

Compatibility with FileSaver.js in the browser

I've tried this out, and it's currently working great with node. However, it doesn't work quite as well in the browser with FileSaver.js. I currently suspect Blob as the culprit.

Here's the code I've tested with:

var file = new Midi.File();
file
  .addTrack()
    .instrument(0, 0x13)
    .noteOn(0, 'c4', 0 , 64)
    .noteOff(0, 'c4', 127, 64)
    ;
saveAs( new Blob([file.toBytes()], {type: "application/x-midi"}) , "test.mid" );

Here's the comparison between the two files. The top is generated through Node. The second one is generated in Chrome using FileSaver.js

img

Overlapping notes

Hi,
Excellent library.
Is there any way to create a track with overlapping notes ?

It seems that the events are created one after the other (contiguously). I would like to be able to overlap the notes to be able to control legato instruments.

Thanks

Julian

timeSignature in header and controlChanges in Tracks missing after encoding

Hey, great module!
But I have an issue - wehen I read a midi File and directly encode it to a new file, the timeSiganture in the header and all controlChanges in the Tracks are gone. Also the timemal is gone. the sourcefile when imported into my DAW has a timemap and creates the BPM around it, with the encoded file there is no time map.

Can someone help?

Question: Writing file directly from MIDI device

Hope it's okay for me to ask this here. I'm using node-midi to catch input from usb devices, am I able to use this tool to directly write everything from device to file? I believe delta time is important here and I didn't notice it being mentioned in the readme, I suppose calling addNote automatically adds a timestamp. Would this be an accurate way to get a 1/1 recording of what is being played on a USB instrument?

Thanks in advance.

Naming a MIDI File

How would you assign a name to the MIDI file? The standard MIDI file is labeled "MIDI Region", and when I tried to add the below code, it takes away the "MIDI Region" label leaving it blank. I try to pass in my name through track.setName("some name") when I run the code but it is still leaving it blank when I import it to a DAW.

 Track.prototype.setName = Track.prototype.name = function(name) {
    this.events.push(new MetaEvent({
            type: MetaEvent.TRACK_NAME,
        data: name,
        time: 0, 
    }));
    return this;
};

set tempo not working?

Hi, I am using your library to create a midi file and then play it using midi-js.

I am finding that no matter how I set setTempo, the output midi in midi-js always plays very slowly. Here is my code snippet:

    var TICKS_PER_BEAT = 128;
    var beatsPerSecond = 2;
    var file = new Midi.File();
    var track = new Midi.Track();
    file.addTrack(track);
    track.setTempo(beatsPerSecond * 60, 0);

    console.log(sequence[0]["beat"], typeof sequence[0]["beat"])
    console.log(sequence[0]["midi_note"], typeof sequence[0]["midi_note"])

    for (var i = 0; i < sequence.length; ++i) {
        var midiPitch = sequence[i]['midi_note'],
            noteOnBeat = sequence[i]['beat'],
            noteOffBeat;
        if (i == sequence.length - 1) {
            noteOffBeat = sequence[i]['beat'] + 2;
        } else {
            noteOffBeat = sequence[i + 1]['beat'];
        }

        track.addNoteOn(0, midiPitch, TICKS_PER_BEAT * noteOnBeat, velocity);
        track.addNoteOff(0, midiPitch, TICKS_PER_BEAT * noteOffBeat, velocity);
    }

    return file;

I changed beatsPerSecond to be 5 and the output file sounded the same. Thanks for your time.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.