I had a go at rewriting this to use requestAnimationFrame, and provide more instruments and some random/clear buttons: https://blog.omgmog.net/beatmaker/
An interesting thing, after a short while the browser unloads the page (Chrome on Mac OS) -- probably due to memory usage, which I think this is down to creating a new Audio element each time, rather than initialising them once and then triggering .play() when needed.
update:
Alright I'm using AudioContext now rather than `new Audio`, seems to be performing a lot better. This puts us at about 144 lines.
First, it's an enourmous waste of computing resources.
Second, it doesn't even work, since the 'setinterval' is unusable for audio timing.
Third, what's there to show off? So Javascript got a 'PlayWav' function that you call in not so regular intervals depending on buttonstate. Simple beatbox is simple. Could aswell be 30 lines.
The problmem is that it's shaking like it has Parkinson's.
It can be be coded with webaudio with the same effort.
I've researched this in the past and it's nowehere near significant more complexity. In fact, a primitive solution is about the same as a setInterval call.
I thought the drum sounds would be generated using JS, but they are just pre-recorded samples (bass_drum.wav, snare_drum.wav, low_tom.wav, mid_tom.wav, hi hat, cymbal, cowbell, hand clap, hi tom, conga, claves).
I'm looking for drum-generated sounds using pure javascript, so I can make changes on them and create new kinds of sounds.
I already created some pure JS sounds (e.g. laser sounds, bass effect, white noise, achords, bell sounds, water drop) but I'm still looking for equations to generate more realistic drum sounds: http://js.do/blog/sound-waves-with-javascript/
I can't give you 'realistic' drum sounds, but I was working on an approximate recreation of a Roland analog drum machine using only Javascript. I got the sound engine down more or less, but kind of fell off the rails when I moved away from my earlier, crappier sequencer and started using a framework.
The sounds should work across browsers when you're manually playing (use the bottom row of your keyboard) but when sequenced playback happens, things get weird. Chrome more accurately reproduces the sounds as I'm imagining them.
My Boss DR-110, a probe, and oscilloscope software - Visual Analyser 2011. You can short the different individual oscillators to ground, and they'll come out the audio & headphone jack.
There's a great breakdown of how the circuitry works at http://www.sdiy.org/richardc64/new_drums/dr110/dr110a1.html - but some of the frequency values there (related to the cymbals) didn't sound right to me - though it's possible I misinterpreted what's going on at that page.
I started out with a sample-based version in 2011 or so, but the link I posted uses synthesized sounds, in updates I made last year. Have a closer look at the javascript as referenced in index.html and take a look at dr110_synth.js
This is probably most evident if you play a roll on the snare or the handclap. A free-running LFO on the noise sources for these instruments prevents "machine-gunning" like you get when you roll a sample.
Reminds me of one I made years ago (back before Web Audio, when the HTML5 <audio> tag was actually pretty new)[0]. It's not under 100 lines, but it's self-contained and (mostly) readable like this one is. These days I'd definitely go with Web Audio as the playback mechanism, of course.
Fun! I like the interface and the URL pattern encoding.
Here's mine: http://wa-101.net/. I used setInterval too, because I found the web audio api docs for the timing functions rather confusing, and I'd set myself a time-limit on getting something "attractive" working.
Nice work! Although from my experience with audio programming in the browser, setInterval() is always fraught with timing danger and inconsistencies.
Have you considered using WebAudio's streaming functionality to tighten up the timing to something more rock solid? Probably a bit more setup in the first part, but for a drum machine especially, you get much better control over timing and playback note length.
Unenjoyable, even as a gimmick, since the timing is all over the place. Either get timing right, or don't do a drum machine. Also this wastes resources like mad. What's the point of this?
This is due to a step taken by the browser to improve performance, namely, timers in Chrome are limited to 'ticking' at most once a second when a tab is backgrounded. The drum loop is at its core:
How peculiar you didn't use the webaudio API for this. I'm working on something similar right now for sun, but with a bank of generated sounds through the oscillator.
Including whitespace it's 102 lines: https://github.com/omgmog/beatmaker/blob/master/js/index.js
An interesting thing, after a short while the browser unloads the page (Chrome on Mac OS) -- probably due to memory usage, which I think this is down to creating a new Audio element each time, rather than initialising them once and then triggering .play() when needed.
update:
Alright I'm using AudioContext now rather than `new Audio`, seems to be performing a lot better. This puts us at about 144 lines.