logue / sf2synth.js

JavaScriptで書かれたSoundFontによるMIDI音源。GM Level2およびXG Lite相当の音源に対応。※Developブランチが実際動いているプログラムです。
https://logue.github.io/sf2synth.js/
MIT License
26 stars 5 forks source link

this library without the userinterface? #5

Open coderofsalvation opened 1 year ago

coderofsalvation commented 1 year ago

Hi, thank you for all your great audio-work. I need a sf2 player which supports CC data (basically the sf2 modulators) so I can send webmidi-in or a midi-file to my sf2. Is there a simple library you recommend for this (without userinterface)?

logue commented 1 year ago

Is it a story that you want to send MIDI signals to sf2synth.js using the Web Midi API?

I don't know if it will be helpful, but there is a program that converts MIDI signals sent by Web Midi Link (the MIDI transmission/reception standard used by smfplayer.js and sf2synth.js) to Web MIDI API. https://github.com/logue/Wml2WebMidiApi

coderofsalvation commented 1 year ago

thank you for that link (and thinking with me). What I basically want is:

                                             [sf2 file with modulators inside]
                                                     |      
[webmidi-in device]----(cc/notes)----+               |
                                     |-------> [javascript sf2-player] ---> audio output                                     
[midi-file]-------------(cc/notes)---+

I'm looking at this js-wrapper of libfluidsynth.js but it does not work in my browser :/

UPDATE: I think the wasm-version of csound will allow me to do this

logue commented 1 year ago

sf2synth.js is the receiver. In this case, all you have to do is implement a process that converts Web MIDI Api to Web Midi Link signals.

I haven't read the specification properly, but convert the Uint8Array format of MIDIMessageEvent.data to comma-separated hexadecimal numbers like F0,43,10,4C,... add midi to the beginning, "midi,F0,43,10, 4C,..." and send it with postMessage for wml.html, I think that sound will come out.

coderofsalvation commented 1 year ago

thanks for your comment, I will have a look! Greetings from Budapest to Tokyo.

logue commented 1 year ago

I don't have a real MIDI device anymore, so I don't know if it will work, but I think it would be better to implement it by creating a class derived from wml.js.

export default class WebMidiApi extends WebMidiLink {
  /**
   * Constructor
   */
  constructor() {
    super();
    /** @type {MIDIAccess?} */
    this.midi = undefined;
  }

  /** セットアップ */
  async setup(url) {
    /** @type {MIDIAccess} */
    const midi = new Promise((resolve, reject) => {
      this.window.navigator
        .requestMIDIAccess(/** @type {MIDIOptions} */ { sysex: true })
        .then(
          access => {
            this.success(access);
            resolve(this);
            parent.setup(url);
          },
          err => {
            reject(err);
          }
        );
    });

    this.midi = midi;
    parent.setup(url);
  }

  /** Web Midi API Ready */
  onReady() {
    if (this.loadCallback) {
      // コールバック実行
      this.loadCallback();
    }
    this.midi.onmidimessage = (/** @type {Uint8Array} */ msg) =>
      parent.processMidiMessage(msg);
  }
}