danigb / smplr

A web audio sampler instrument
https://danigb.github.io/smplr/
188 stars 19 forks source link

When scheduling large number of notes, no sounds is being output #26

Closed sheunglaili closed 1 year ago

sheunglaili commented 1 year ago

Hi @danigb,

Thank you for such amazing library, I am using the piano sampler in one of my project and when I schedule more than 2000+ notes that scattered across mins, no sounds is being output.

I tried to schedule less notes and it worked - so I am wondering if this is a bug?

I also experiment with batch scheduling the notes using the onEnded callback but clean up is really messy. Would you mind please let me know if there's a workaround for this issue ? Thank you very much

danigb commented 1 year ago

Hi! Thanks for testing out the library. Is it possible you create and post here a reproducible example of the issue?

sheunglaili commented 1 year ago

Hi @danigb, for sure. Please have a look at https://codesandbox.io/s/sweet-hodgkin-qstdym?file=/src/index.js

you could try uncomment the portion with just 100 notes and play and it will work fine. when uncomment the code that plays all the note, it won't play anything

The example above is using 0.4.3 as 0.6.0 have a bug where if referencing window.fetch and throwing error

danigb commented 1 year ago

Thanks a lot! I'll take a look into the issue ASAP

danigb commented 1 year ago

Hi @sheunglaili

I've just tested the example you sent me and.. works OnMyComputer™️ 😵‍💫 (beautiful song, by the way...)

So, I don't know how to solve it... Any other error on the console? What machine or operating system are you using?

Also, can I use that notes.js to create a stress test on this library?

BTW: One idea behind smplr, which differentiates it from other libraries, is that you should be able to schedule 2000+ notes without scheduling (and cancellable with stop). So for me it's an important issue to find and fix

sheunglaili commented 1 year ago

Hi @danigb, I do not own that song (it's Golden Hour by JVKE) but feel free to use the notes 👍

I've tried using different browser but resulting the same issue for me, I don't see any error on the console. So this one could be a bit tricky

danigb commented 1 year ago

Thanks for the reference (of course, I won't use it). What is the browser and operating system?

sheunglaili commented 1 year ago

I was testing on Intel MacOS and on Chrome & Safari

Edit: actually Safari works fine for me but the initial notes maybe around 100 notes was a bit laggy

hylu-dev commented 1 year ago

OS: Windows 10

Hi, I'm also experiencing issues when scheduling a large number of notes on Chrome. At around 400-500 notes, I start to notice some light static in the playback. Above a thousand notes, the playback starts to lag and the sound becomes mostly static. I haven't run into the issue of no sound at all but the sound becomes pretty unintelligible.

Interestingly, I have little to no issues on Firefox when scheduling as much as ~3000 notes, though it eventually also gets bad at 5000+.

sheunglaili commented 1 year ago

Hi @danigb,

would you by any chance have any clue on this issue? I am happy to send MR fix if you are able to guide me to relevant area of the code

danigb commented 1 year ago

I was able to reproduce the issue in an older machine. Unfortunately Web Audio API does not support adding so many sources in advance (I can reproduce the test by using web audio api directly). I'll add a fix to the library, but it might take some time. Meanwhile you can use a Scheduler like this one: https://github.com/danigb/smplr/pull/29/files#diff-32f5328f940339eb551b20cd118b315b0ebfeb301ab3dccdbfb28ff5e32a558fR27

sheunglaili commented 1 year ago

Thank you for your swift response and testing @danigb!! I tried using setTimeout as scheduler in an attempt to workaround this issue. However, it appears that using setTimeout or setInterval is not recommended when comes to precise audio scheduling due to the nature of v8 event driven architecture thus timing are not wired to hardware clock like Web Audio API do.

Imho, I reckon a batching strategy might work in this case. for example: schedule the first 500 notes and play, when reaching let's say 3/4 / 4/5 or the durations of first 500 notes, the library could schedule the next 500... and so on until all notes are played.

danigb commented 1 year ago

Hi 👋 setInterval is not used for scheduling, but for batching. The scheduling is done when calling audioBufferSource.start, so this is the recommend strategy. You can read more here: https://loophole-letters.vercel.app/web-audio-scheduling#conclusion or the older, but usually mentioned as reference, https://web.dev/audio-scheduling/ post

sheunglaili commented 1 year ago

Sorry I misread the code! Thank you for the articles attached (they are good reads!). Will there chances that the scheduler would be build into the library ? would come in handy in the future! in the meantime, I will just use the schedular. Cheers!

danigb commented 1 year ago

I'll be built in soon 👌