
Show HN: Drum machine in 100 lines of HTML/JS - siggy
http://sig.gy/beatboxer/
======
omgmog
I had a go at rewriting this to use requestAnimationFrame, and provide more
instruments and some random/clear buttons:
[https://blog.omgmog.net/beatmaker/](https://blog.omgmog.net/beatmaker/)

Including whitespace it's 102 lines:
[https://github.com/omgmog/beatmaker/blob/master/js/index.js](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.

~~~
siggy
Really like your changes! I've incorporated your use of requestAnimationFrame
and AudioContext back into mine:
[https://github.com/siggy/beatboxer/commit/dccff243474b17ca34...](https://github.com/siggy/beatboxer/commit/dccff243474b17ca347583b3919fbf17b625a46b)

------
kowdermeister
Never use setInterval for audio based applications. It's just totally
unreliable. WebAudio has nice built in features for high precision timing.

~~~
yAnonymous
When the goal is showing off what you can do with 100 lines of code, what's
wrong with it?

I doubt high precision timing can be done with the same amount of code.

~~~
iammyIP
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.

~~~
aroman
Not sure why this is down voted — the demo literally does not work in my
browser (Safari 10) because of the (mis)use of setInterval.

~~~
yAnonymous
>Safari

Try a better browser first. You might as well be using IE 8. I could write a
book about the things that don't work in Safari.

------
rsiqueira
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/](http://js.do/blog/sound-
waves-with-javascript/)

~~~
leviathant
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.

Grab the whole thing at
[https://github.com/leviathant/BossDR110/tree/feature/synthes...](https://github.com/leviathant/BossDR110/tree/feature/synthesized-
sounds) or just play around with it yourself at
[http://bitrotten.com/dr110/webaudio/](http://bitrotten.com/dr110/webaudio/)

~~~
louthy
Looking at the source, yours appears to be sample based too. I think the GP
was interested in an oscillator based sound engine.

~~~
heuermh
These appear to be the synthesized versions:

[https://github.com/leviathant/BossDR110/blob/feature/synthes...](https://github.com/leviathant/BossDR110/blob/feature/synthesized-
sounds/dr110_synth.js)

To the parent, what did you use as the reference for the synthesis patches and
parameters? I wouldn't mind trying something similar in ChucK.

~~~
leviathant
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](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.

~~~
heuermh
Thanks!

I added a sample-based ChucK class with examples here
[https://github.com/heuermh/lick/commit/be60769ae32ca955b35b9...](https://github.com/heuermh/lick/commit/be60769ae32ca955b35b9c14209876d78760feff).

I'll dig into the docs you linked to and see if I can come up with a
synthesized version as well!

------
BHSPitMonkey
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.

[0]
[http://stepheneisenhauer.com/demos/drummachine/](http://stepheneisenhauer.com/demos/drummachine/)

------
jonwot
The last 2 sequence boxes for each type of hit wrap around to a new line
(firefox). Pretty cool for 100 lines of HTML and JS.

------
the_other
Fun! I like the interface and the URL pattern encoding.

Here's mine: [http://wa-101.net/](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.

------
alz
[http://imgur.com/a/O1dy8](http://imgur.com/a/O1dy8)

~~~
kaeluka
[http://imgur.com/a/zEj4w](http://imgur.com/a/zEj4w)

~~~
bambax
[http://www.bambax.com/beatboxer/#||||||x||||||||||||||x|||||...](http://www.bambax.com/beatboxer/#||||||x||||||||||||||x||||||||x||||x||||||||x||x||||||||||||||||||||x||120)

------
bambax
With a slider to change bpm:

[http://www.bambax.com/beatboxer/](http://www.bambax.com/beatboxer/)

~~~
omgmog
Nice, but your slider is blocking interaction with most of the boxes
[http://i.imgur.com/Ae4uyoJ.png](http://i.imgur.com/Ae4uyoJ.png)

~~~
bambax
Yes, corrected, can you check?

(height problem since the slider is rotated to make it vertical).

------
prashnts
Very cool! It'd be great if you could also serialize the notes to the url, so
people can share these.

~~~
bambax
An implementation:

[http://www.bambax.com/beatboxer/index.html#x||||x||||x||||x|...](http://www.bambax.com/beatboxer/index.html#x||||x||||x||||x||||||x||x||x||||||||||||||||||||x|x|||x||||||||||||||x||||)

Edit: now also saves bpm value:
[http://www.bambax.com/beatboxer/#x||||x||||x||||x||||||x||x|...](http://www.bambax.com/beatboxer/#x||||x||||x||||x||||||x||x||x||||||||||||||||||||x||||x||||||||||||||||||150)

------
cyberferret
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.

I wrote an Ionic specific example of using the browser's WebAudio
functionality to write a metronome app here: [https://www.airpair.com/ionic-
framework/posts/using-web-audi...](https://www.airpair.com/ionic-
framework/posts/using-web-audio-api-for-precision-audio-in-ionic)

------
sdrothrock
Nice! A little feature suggestion -- it would be really cool if the current
pattern were encoded in a URL so you could link it to friends. :)

~~~
bambax
With pattern encoding and history change:

[http://www.bambax.com/beatboxer/index.html#x||||x||||x||||x|...](http://www.bambax.com/beatboxer/index.html#x||||x||||x||||x||||||x||x||x||||||||||||||||||||x|x|||x||||||||||||||x||||)

------
sandebert
I can change color of the boxes. Something animates from left to right. But I
can't hear anything. (Android 7, latest Chrome.)

~~~
sandebert
Tried it on my desktop computer now - works just fine, nicely done. Needs more
cowbell, though.

------
iammyIP
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?

------
GoToRO
Cool! when tab is not active, the rhythm slows down in Chrome/win7.

~~~
nprescott
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:

    
    
        setInterval(function() {...}, 1 / (4*BPM/(60*1000)));
    

[https://codereview.chromium.org/6577021](https://codereview.chromium.org/6577021)

------
deanclatworthy
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.

------
jfornear
Cool! It would be cool to have more instruments to create little loops to
share with friends.

------
sakri
hehe.. I was just a few squares short of recreating drop it like it's hot :D

------
scottydelta
it behaves weirdly when you change the tabs, must be because of setInterval?

~~~
yAnonymous
JS intervals are limited to one per second for background tabs.

------
nichochar
This is really fun, FYI. Social features would be fun.

------
paublyrne
Very nice. Could you add a hi-hat?

------
scriptnull
Super fun.

