top | item 12477296

Show HN: Drum machine in 100 lines of HTML/JS

134 points| siggy | 9 years ago |sig.gy

48 comments

order

omgmog|9 years ago

I had a go at rewriting this to use requestAnimationFrame, and provide more instruments and some random/clear buttons: https://blog.omgmog.net/beatmaker/

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.

mixedCase|9 years ago

Well your version doesn't crash shortly after toying around in it unlike OP's so good job!.

kowdermeister|9 years ago

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

yAnonymous|9 years ago

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.

rsiqueira|9 years ago

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/

leviathant|9 years ago

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... or just play around with it yourself at http://bitrotten.com/dr110/webaudio/

BHSPitMonkey|9 years ago

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/

jonwot|9 years ago

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|9 years ago

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.

cyberferret|9 years ago

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

sandebert|9 years ago

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

sandebert|9 years ago

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

djaychela|9 years ago

Me too - android 6,latest chrome. Works fine on Firefox on the same phone...

iammyIP|9 years ago

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|9 years ago

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

nprescott|9 years ago

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

deanclatworthy|9 years ago

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|9 years ago

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

sakri|9 years ago

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

scottydelta|9 years ago

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

yAnonymous|9 years ago

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

nichochar|9 years ago

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

paublyrne|9 years ago

Very nice. Could you add a hi-hat?