djipco / webmidi

Tame the Web MIDI API. Send and receive MIDI messages with ease. Control instruments with user-friendly functions (playNote, sendPitchBend, etc.). React to MIDI input with simple event listeners (noteon, pitchbend, controlchange, etc.).
Apache License 2.0
1.53k stars 115 forks source link

Node.js: WebMidi not enabling #252

Closed PimTournaye closed 1 year ago

PimTournaye commented 2 years ago

Getting the following error: (note: I changed filepaths in this report)

ReferenceError: navigator is not defined
    at Object.enable (file:///FILE_PATH/node_modules/webmidi/dist/esm/webmidi.esm.min.js:447:754)
    at file:///FILE_PATH/resonance.js:16:2
    at ModuleJob.run (node:internal/modules/esm/module_job:195:25)
    at async Promise.all (index 0)
    at async ESMLoader.import (node:internal/modules/esm/loader:331:24)
    at async loadESM (node:internal/process/esm_loader:88:5)
    at async handleMainPromise (node:internal/modules/run_main:65:12)
WebMidi
.enable()
.then(onEnabled)
.catch(err => console.log(err));

// Function triggered when WebMidi.js is ready
function onEnabled() {
    console.log('WebMIDI enabled!');
    output = WebMidi.getOutputByName("IAC Driver Bus 1");
    channel = output.channels[1];

    console.log(channel);
    channel.playNote('C5', {duration: 5000})
    //active = true;
    //interactiveMode = true;
}

Environment: Specify the environment where you are witnessing the problem:

I'm using webmidi: "^3.0.0-alpha.26"

PimTournaye commented 2 years ago

I now realise I was using an outdated version, but in the most recent version on npm webmidi just doesn't want to enable

djipco commented 2 years ago

I cannot reproduce the problem. Can you provide a little more info? For instance, are you running this code in Node.js or in a browser?

Since you mentioned Node.js v17.2.0, I assume you are running it in Node.js. I just tried running the code below and it worked fine in Node.js v16.11.1 and v17.8.0.

This is using the module approach:

import {WebMidi} from "webmidi";

WebMidi
  .enable()
  .then(onEnabled)
  .catch(err => console.log(err));

function onEnabled() {
  console.log('WebMIDI enabled!');
  const output = WebMidi.outputs[0]
  const channel = output.channels[1];
  console.log(channel);
  channel.playNote('C5', {duration: 5000})
}

This is using the classic approach:

const {WebMidi} = require("webmidi");

WebMidi
  .enable()
  .then(onEnabled)
  .catch(err => console.log(err));

function onEnabled() {
  console.log('WebMIDI enabled!');
  const output = WebMidi.outputs[0]
  const channel = output.channels[1];
  console.log(channel);
  channel.playNote('C5', {duration: 5000})
}

I was using WEBMIDI.js v3.0.15.

PimTournaye commented 2 years ago

I'm running this in Node.js, yes, also running WEBMIDI.js v3.0.15. I've tried your snippet of the module approach above and sadly still get nothing in the console. I'll link my repo below if you want to dive deeper.

I think in the meantime I'll try to update my node version and try again.

https://github.com/PimTournaye/Resonance

djipco commented 2 years ago

I just ran your code and it was working fine for me (I only had to change the name of the MIDI device to match my own). Here's the output I got:

(base) jpcote@DjipBook Resonance-master % node resonance.js
undefined
WebMIDI enabled!
<ref *1> a {
  eventMap: {},
  eventsSuspended: false,
  _output: i {
    eventMap: {},
    eventsSuspended: false,
    _midiOutput: MIDIOutput {
      type: 'output',
      id: 'Apple DLS Synth',
      name: 'Apple DLS Synth',
      manufacturer: 'Apple',
      version: '1.0',
      state: [Getter],
      connection: [Getter],
      onstatechange: [Getter/Setter],
      open: [Function (anonymous)],
      close: [Function (anonymous)],
      clear: [Function (anonymous)],
      send: [Function (anonymous)]
    },
    _octaveOffset: 0,
    channels: [
      <1 empty item>, [Circular *1],
      [a],            [a],
      [a],            [a],
      [a],            [a],
      [a],            [a],
      [a],            [a],
      [a],            [a],
      [a],            [a],
      [a]
    ]
  },
  _number: 1,
  _octaveOffset: 0
}
creating new ball
got "keypress"  { sequence: '\x03', name: 'c', ctrl: true, meta: false, shift: false }
bang!
bang!
bang!
bang!
PimTournaye commented 2 years ago

Weird, it still doesn't output anything for me. Could it be another Apple Silicon ARM64 thing? What other information could I provide for you? I don't really know where to look myself but when I have the time I could dig around a bit

djipco commented 2 years ago

I don't know why it would be related to the new processor but who knows? Unfortunately, I only have an "old" Macbook to test it on.

Are you still getting the ReferenceError: navigator is not defined error? Do you at least see "WebMidi enabled!" ?

PimTournaye commented 2 years ago

The ReferenceError: navigator is not defined when away with updating, but no "WebMIDI enabled". When logging the WebMIDI import, it does log but it's like .enable() never even executes...

PimTournaye commented 2 years ago

After some more testing, I have a hunch it maybe be an issue on the JZZ-soft side of things. I tried running their test suite and unfortunately only passed one test out of the 28 or something. I've opened an issue on their repo.

https://github.com/jazz-soft/JZZ/issues/59

djipco commented 2 years ago

@PimTournaye Thanks for reporting back. If that is indeed the problem, it will most likely affect other users of WEBMIDI.js. Keep me posted!

PimTournaye commented 2 years ago

Will do! Running the script through a Rosetta terminal makes it work for now! I'll try to see if I can see what causes it to act out on Apple Silicon

djipco commented 2 years ago

Interesting. Maybe there is indeed a compatibility issue with Apple Silicon. Let's wait and see what the Jazz-Soft team says.

djipco commented 2 years ago

@PimTournaye Can you try out version 3.0.20 (available now on npm) and see if it fixes your issue. A regression problem has been uncovered (and fixed) and perhaps it relates to your problem.

PimTournaye commented 2 years ago

I've booted up my project again without Rosetta and WebMidi is unfortunately still not enabling. it is getting imported I think, logging WebMidi from import returns some things at least. I'll try to play around a bit more and report back if I find anything.

djipco commented 2 years ago

@PimTournaye Thanks for taking the time to check it out. An update from the Jazz-Soft team is expected soon. Maybe it'll help with Node.js compatibility...

PimTournaye commented 2 years ago

Found something weird, when using Vite in my project, WebMidi does enable on a non-Rosseta terminal. Will try to look into this more.

teropa commented 2 years ago

I'm also seeing this issue on Apple Silicon. As far as I can tell, jazz-midi does not include a build for darwin arm64, so it fails when trying to load up.

djipco commented 2 years ago

@teropa Thanks for the feedback. I guess we will have to wait for the jazz-midi team...

djipco commented 2 years ago

Issue #10 for the jazz-midi module concerns Apple M1 support. I am referencing it here so we can track the progress. As soon as support lands in the jazz-midi module, I will update the dependencies for WEBMIDI.js.

AMabona commented 1 year ago

Hi @djipco , I'm the one who opened the issue you referred to. It seems it should be closed after this commit https://github.com/jazz-soft/jazz-midi/commit/d67f8c38c0362f4ee1e82ea4972462ee80f6ed69 from two weeks ago.

djipco commented 1 year ago

@AMabona Thank you so much for letting me know!

I just released v3.0.24 of WEBMIDI.js which now depends on v1.5.6 of the jzz module which itself relies on v1.7.8 of the jazz-midi module (the one that is now natively compiled for Apple M1 ARM processor).

Unfortunately, I don't have an M1 to test it with. Perhaps @PimTournaye or @teropa could try it out and let me know?

Thanks!

PimTournaye commented 1 year ago

Did a quick test, so far everything is working from a non-Rosetta process. Thanks for the update! If anyone does experience issues, do keep reporting and feel free to reopen this issue.