I tried to play your drum machine in a musically timed rhythm and it seems to take too long to reload the sample before playing the sample again. Your code looks good and this is more how to use the audio tag.
I looked into the documentation for the audio tag and found this part relevant.
preload
This enumerated attribute is intended to provide a hint to the browser about what the author thinks will lead to the best user experience. It may have one of the following values:
-
none
: Indicates that the audio should not be preloaded.
-
metadata
: Indicates that only audio metadata (e.g. length) is fetched.
-
auto
: Indicates that the whole audio file can be downloaded, even if the user is not expected to use it.
-
empty string : A synonym of the
auto
value.
The default value is different for each browser. The spec advises it to be set to metadata
.
Usage notes:
- The
autoplay
attribute has precedence over preload
. If autoplay
is specified, the browser would obviously need to start downloading the audio for playback.
- The browser is not forced by the specification to follow the value of this attribute; it is a mere hint.
This enumerated attribute is intended to provide a hint to the browser about what the author thinks will lead to the best user experience. It may have one of the following values:
-
none
: Indicates that the audio should not be preloaded.
-
metadata
: Indicates that only audio metadata (e.g. length) is fetched.
-
auto
: Indicates that the whole audio file can be downloaded, even if the user is not expected to use it.
-
empty string : A synonym of the
auto
value.
The default value is different for each browser. The spec advises it to be set to metadata
.
Usage notes:
- The
autoplay
attribute has precedence over preload
. If autoplay
is specified, the browser would obviously need to start downloading the audio for playback.
- The browser is not forced by the specification to follow the value of this attribute; it is a mere hint.
Issues with web audio that have to be handled
- pre-loading into buffers after downloading all samples to be played
- getting samples to clip off playback when another event comes in.
i took a look at the output generated from your React code and looked at the <audio>
tag.
I found no preload attribute set
First thing I would try is to set that attribute somehow like this
<audio controls preload="auto">
<source src="horse.ogg" type="audio/ogg">
<source src="horse.mp3" type="audio/mpeg">
Your browser does not support the audio element.
</audio>
This might solve part of the issue.
Check out https://howlerjs.com/ as an alternative.
Take a look at how I used it in my drum sequencer (beyond the scope of the fcc project) to see how I consumed that library. I won’t plug my project here on yours but you can easily find it on the project feedback section.
Even with Howler.js my own drum sequencer has timing issues due the different implementation of the javascript engines across browsers and phones.
Using setInterval was the obvious choice but as it turns out setInterval is susceptible to timing issues due to it running on the main thread and sharing resources with the rest of the web browser. Audio programming is such a deep subject and I fell right into a rabbit hole while making it.
Check out the web audio api book http://www.allitebooks.org/web-audio-api/ if you’re interested in this stuff. Using web audio api is a bit more involved but worth it in the end. The engine runs in a separate thread completely untouched by the rest of the browser so it becomes immune to stuttering audio if used right.