My Music Machine

Jan 'half/byte' Krutisch

@halfbyte

JSUnconf 2019

But first!

Human Beatboxing 101

Three fundamental sounds

Bass drum (Kick drum)

  • Boo
  • Dmm

Snare / Clap / Rimshot

  • Pfff
  • Kh
  • Krrr

Hihat / Cymbal

  • Tssss
  • Ts

Bootsssss ... Catssss

A couple of names to google

  • Kawehi
  • Beardyman
  • Sly the Mic Buddah
  • Romybeats

{live:js}

https://livejs.network/

Current lineup

  • Ruth John (@rumyra) 📺
  • Tim Pietrusky (@TimPietrusky) 💡📺
  • Martin Schuhfuss (@usefulthink) 💡📺
  • Sam Wray (@_2xAA)🎹📺
  • Matt McKegg (@MattMcKegg)🎹
  • Yours Truly (@halfbyte)🎹

Played at

  • JSConf.eu
  • JSConf.asia🎹💡📺
  • DOT.js
  • Coldfront
  • Ruhr.js
  • ...

improjam

halfbyte/improjam

Features

  • Quick workflows
  • Pattern based
  • Fully utilizes Ableton Push 2
  • Ideally no need to look at screen

Requirements

  • Web / JavaScript
  • No huge build pipeline

Ableton Push 2

fit

  • Buttons, Pads, Encoders, Touchstrip
  • LEDs
  • Display
  • Buttons, Pads, Encoders, Touchstrip => MIDI
  • LEDs => MIDI
  • Display => Uhm...About that...

From USB point of view, Push 2 is a composite device with a MIDI interface and a generic bulk data interface used to drive the display

USB

  • Storage
  • HID (Keyboard, Mouse, Game Controllers)
  • Audio
  • MIDI
  • etc. etc.
  • Generic Data (Aka vendor specific crap)

MIDI

[144, 36, 100]

[144 + 0, 36, 100]
  ^    ^   ^   ^
  |    |   |   `--> Velocity
  |    |   `------> Note (C)
  |    `----------> Channel 1 (0)
  `---------------> Cmd: Note On

Generic Bulk Data Interface

  • Send Frame Header
  • Send Frame Buffer
  • GOTO 10

The Frame Buffer

  • 16 Bit per Pixel [bbbbbggggggrrrrr]
  • (little endian)
  • XOR with 0xFFE7F3E7 (signal shaping)

NEED PIXELS

Canvas, my old friend

data = ctx.getImageData(0,0,960,160).data
r = data[pixel * 4 + 0]
g = data[pixel * 4 + 1]
b = data[pixel * 4 + 2]

The Magic (and danger) of Electron

const { initPush, sendFrame } = require('ableton-push-canvas-display')

initPush()
// DRAW STUFF
sendFrame(ctx)

Building a sequencer in JavaScript

Challenges

  • Timing (-Stability)
  • Latency

Solutions

  • Use WebMIDI scheduling
    • Uses performance timers
  • Use Workers for scheduling the scheduling
    • Prevents throttling on blur
    • Generally is more stable

WHY?

Because I can

Because learning

It's my Instrument

This actually makes a difference!

Also, {live:js}

One good thing about Music, when it hits, you feel no pain!

Thanks

❤️🎹❤️

@halfbyte

https://depfu.com