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

sf2 player #6

Closed JanVeb closed 1 year ago

JanVeb commented 1 year ago

Hi there, I'm using sf2-player that is fork of this library

https://github.com/enjikaka/sf2-player

It works rather well, but it introduces some annoying noise from time to time, so I'm looking to find another player. Can this library be used to play multiple single notes and to stop them similar like https://github.com/enjikaka/sf2-player.

Was thinking that your original project could work better as you seem to be more active on it.

You can check the noise in question in the video https://youtu.be/-HAq6WN-BaY

Thank

logue commented 1 year ago

Is it a problem that the sound cuts out? I'm having a lot of trouble with this issue. Probably, I think that the processing drop has occurred because AudioContext is being played on the same thread. In order to fix it, I think that it is necessary to devise measures such as implementing the processing of sound_font_synth_note.js in the worker. The same goes for panpot processing, but I think that it is necessary to drastically change the design.

JanVeb commented 1 year ago

Don't think sound is getting cut, though not sure, noise I hear sounds like something is tearing apart, cracking, though its not that loud and obvious. You can hear example of it on second 10-11. So its not that big of a deal, but I'm listening my app playing all the time, so I notice it a lot. https://youtu.be/-HAq6WN-BaY

Also sometimes sound will just go completely nuts, frequency of it will get reduced so it sounds terrible, so then just need to restart the app.

logue commented 1 year ago

Hmm, I don't know why.

How about merging with the latest version? From 0.4.0 onwards, processing to overwrite the default values defined in the standard was added to the SoundFont loading process, and in 0.4.1 the reverb effect algorithm was changed.

JanVeb commented 1 year ago

Hm, to merge with latest version, I'm not that familiar with Github. Didn't know I can merge others people projects with previous "branches" of their projects.

Maybe it would be easier for me if I could try your sf2synth.js library directly in my project. Think if its able to play midi files, then it should be easy to have it play specified notes on demand?

But I didn't notice this code in your project.

How could I play notes with sf2synth.js if posible?

import SoundFont2 from 'sf2-player';

const sf2 = new SoundFont2();
  sf2.loadSoundFontFromURL('assets/piano/Giga_Piano.sf2').then(() => {
    // sf2.loadSoundFontFromURL('assets/piano/MasonHamlin-A-v7.sf2').then(() => {
    sf2.bank = sf2.banks[0].id;
    sf2.program = sf2.programs[0].id;
    setSoundFont(true);
  });

  function TestNoteDuration(dur) {
    sf2.noteOn(60, 127, 0);

    setTimeout(() => sf2.noteOff(60, 127, 0), dur);
  }

This is how I do it with this enjikaka/sf2-player library.

and this is how I play and stop play of notes:

    sf2.noteOn(60, 127, 0);
    setTimeout(() => sf2.noteOff(60, 127, 0), dur);

Could you point me to how to play notes with your library if possible?

Thank

logue commented 1 year ago

sf2.js simply parses the SoundFont, converts it to a format suitable for WebAudio with sound_font_synth.js, and throws it into sound_font_synth_note.js to produce sound.

So https://github.com/logue/sf2synth.js/blob/8b1b5e6b5c66f54addb0a9f9af90c87de86e917a/src/sound_font_synth.js#L381-L529 hack around.

Currently, I'm thinking about implementing a function to receive WebMIDI signals, but I'm not thinking much about implementing a process that acquires the sound of a single SoundFont.

The SoundFont parsing process of this program is based on yoya's sf2.js. There is a source that has been rewritten in a modern style, so it may be better to refer to that.

https://logue.dev/smfplayer.js/debug.html

JanVeb commented 1 year ago

How do you do this, play notes when you press piano keys on virtual piano? This virtual piano comes already with yoga's sf2 or you do that with your code?

https://user-images.githubusercontent.com/93236084/187712525-3459bb25-500e-4a8a-9869-2b6e6461a179.mp4

import SoundFont from '@logue/sf2synth';

// Url to SoundFont file.
const sf2 = './Yamaha XG Sound Set.sf2';

const option = {
  // attach dom id
  placeholder: 'placeholder',
  // If you not nessesaly to draw keyboad, set false.
  drawSynth: true,
  // Cache Soundfont
  cache: true,
};

const wml = new SoundFont.WebMidiLink(option);
wml.setLoadCallback(() => {
  // When ready to load.
});
wml.setup(sf2);

This is code from your readMe, now just need to figure out how to issue commands to play certain notes

synth.noteOn(ch, k, 127);
synth.noteOff(ch, k, 127);

This code is from sound_font_synth.js, this is what I'm missing in your documentation.

Think I could figure out how to make it work, thank, will let you know how it went

logue commented 1 year ago

WebMidiLink contains a process to initialize the synthesizer, so I think it would be better to create a derived class of WebMidiLink class and operate from this.synth.

JanVeb commented 1 year ago

Hi, sorry I went with howler for now, seems more stable than sf2 player.

Will review this at later stage, but for now have more important work so will go with howler for now.

Thank for your help