Bap is a toolkit for making beats and composing sequences with Javascript and Web Audio for playback in modern browsers. It is inspired by the classic "MPC workflow" and built to make all aspects of beatmaking completely modular and reusable.
Made by Adam Renklint, Berlin april 2015
Install and import
From npm
$ npm install --save bap
From rawgit CDN
<script src="https://cdn.rawgit.com/adamrenklint/bap/v0.8.0/bap.min.js"></script>
Usage
var bap = require('bap'); // or window.bap
// a kit is like an instrument, or program in mpc terms
var kit = bap.kit();
var oscillator = bap.oscillator({
frequency: 440
});
// a kit connects infinite slots with infinite layers
kit.slot('Q').layer(oscillator);
kit.slot('W').layer(oscillator.with({ frequency: 330 }));
kit.slot('E').layer(bap.sample('foo.wav'));
// a pattern is a loop made up of channels and notes
var pattern = bap.pattern();
pattern.channel(1).add(
['1.*.01', '1Q', 48, 70, 0, -50],
['1.2.01', '1W', 96, 100, 0, 50],
['1.4.01', '1E']
);
// connect the kit, and play
pattern.kit(1, kit).start();
Basic concepts
- Bap runs at 96 ticks per beat, with a position signature like MPC:
bar.beat.tick
- Kits are like instruments (programs in MPC terms) and contains infinite slots, each with infinite layers of samples and oscillators
- Patterns are playable collections of channels containing notes, and connect with kits
- Notes are defined by six main parameters: position, target, duration, volume, pan and pitch
- Only position and target params are required, all others can be null/falsy/undefined
- Positions containing expressions are automatically expanded
- When a layer is played, it merges the params of the note, channel, layer, slot and kit
Known issues
- Creating effect nodes on-the-fly is not performing well in Firefox, resulting in clipping on the initial run of a pattern
Resources
API
- All objects are based on ampersand-state
on(name, callback)
register event callbackoff(name, [callback])
unregister event callbackonce(name, callback)
register single-run event callbackwith(params)
return a clone of itself with paramstoJSON()
return current params as JSON
bap
clock
reference to clock singletonvolume
number between 0 and 999, master volume setting, defaults to 100kit(params)
returns a new kitslot(params)
returns a new slotlayer(params)
returns a new layeroscillator(params)
returns a new oscillatorsample(params)
returns a new samplepattern(params)
returns a new patternsequence(sequence..., params)
returns a new sequencechannel(params)
returns a new channelnote(params)
returns a new notereverb(params)
returns a new reverbdelay(params)
returns a new delaycompressor(params)
returns a new compressoroverdrive(params)
returns a new overdrivefilter(params)
returns a new filterchorus(params)
returns a new chorusphaser(params)
returns a new phaserpingpong(params)
returns a new [ping pong delay](#ping pong delay)new()
returns a new instance of Bap, with its clock and event bus separated from other instances
params
mute
boolean, defaults tofalse
volume
number between0
and999
, defaults to100
length
number, length in seconds, overriden by duration if shorterduration
number, duration in ticks, overriden by length if shorterattack
number, attack in secondsrelease
number, release in secondspitch
number between-999
and999
representing the pitch shift in semitones, defaults to0
pan
number between-100
and100
, defaults to0
events
started
triggered on Note, Channel, Pattern, Kit, Slot and Layer when sound source starts playingstopped
triggered on Note, Channel, Pattern, Kit, Slot and Layer when sound source stops playing
clock
playing
boolean, current state of playback, can be changed to start or pauseposition
string in formatbar.beat.tick
, can be set to move playback positionbar
,beat
,tick
numbers, equal and bound to position, can be set to move playback positiontempo
number, current tempo of playback, read onlystep
function, called on each step with note and time as arguments, able to cancel step by returning falsesequence
pattern or sequence currently playingstart()
start playback, if current pattern is setstart(pattern)
set current pattern and start playbackpause()
stop playbackstop()
stop playback and set position to1.1.01
kit
slot()
returns blank slot assigned to next idslot(id)
returns existing or blank slot with idslot(id, slot)
assign slot instance to idslot(slot)
assign slot instance to next idconnect(effect)
route output signal to destination via effect or chainbypass
boolean to bypass all effects, effect type string or array of strings to bypass specific effect types, defaults to false
slot
layer()
returns a blank layer assigned to next idlayer(id)
returns existing or blank layer with idlayer(id, layer)
assign layer instance to idlayer(layer)
assign layer instance to next idlayer(sampleSrc)
returns a new sample layer, assigned to next idstart(time, [params])
start playback of slot at (AudioContext) timestart([params])
start playback of slot immediatelystop(time, [params])
stop playback of slot at (AudioContext) timestop([params])
stop playback of slot immediatelyconnect(effect)
route output signal to destination via effect or chainbypass
boolean to bypass all effects, effect type string or array of strings to bypass specific effect types, defaults to false
layer
start(time, [params])
start playback of slot at (AudioContext) timestart([params])
start playback of slot immediatelyconnect(effect)
route output signal to destination via effect or chainbypass
boolean to bypass all effects, effect type string or array of strings to bypass specific effect types, defaults to false
oscillator
frequency
number, frequency of oscillation in hertz, defaults to0
note
string, note identifier likeC3
ora4
- if set, overrides frequencyshape
string, shape of waveform, defaults tosine
, other values aresquare
,sawtooth
,triangle
andcustom
sample
src
string, url used to load sample bufferoffset
number, starting point offset in seconds, defaults to0
channel
string, defines how to handle stereo buffers:left
orright
uses a single channel,merge
anddiff
combines or differentates between channels, default isnull
and does nothingreverse
boolean, reverse buffer or slice of bufferloop
number, loop length in seconds, defaults to0
i.e. not loopingslice(pieces)
returns a kit with the sample sliced into even-sized sectionsbitcrush
number between 0 and 16, resamples waveform to defined bit depth, defaults to0
, i.e. no resamplingbitcrushFrequency
number between 20 and 22050, normalization frequency at which to apply the bitcrusher effect, defaults to 6500bitcrushMix
number between 0 and 100, ratio of wet bitcrushed signal to mix with dry signal, defaults to 50trimToZeroCrossingPoint
boolean, automatically trim sample start and end to zero crossing point to avoid clipping, defaults to true
pattern
playing
boolean, current state of playback, can be changed to start or pausetempo
number, playback tempo in bpm, defaults to 120bars
number, length of pattern in bars, defaults to 1beatsPerBar
number, amount of beats per bar, defaults to 4loop
boolean, define if pattern should loop, defaults to truevolume
number between 0 and 999, master volume for pattern, defaults to 100transform
function to be called after expanding position expressions into notes, called afterchannel.transform
channel()
returns a blank channel assigned to next idchannel(id)
returns existing or blank channel with idchannel(id, channel)
assign channel instance to idchannel(channel)
assign channel instance to next idstart()
start playback of patternpause()
stop playbackstop()
stop playback and set position to1.1.01
kit(id, kit)
connect kit to idkit(id)
return kit connected to idthen(sequence, ...)
return new sequence with passed sequences and patterns after patternafter(sequence, ...)
return new sequence with passed sequences and patterns before patternand(sequence, ...)
return new sequence with passed sequences and patterns layered with pattern
sequence
constructor(sequence, ..., [params])
the sequence constructor optionally takes any number of sequences and patterns as argument before the usual paramsplaying
boolean, current state of playback, can be changed to start or pauseloop
boolean, define if sequence should loop, defaults to falsesequences
an array of sequences, patterns or arrays of sequences and patternsbars
number, length in bars, read-onlythen(sequence, ...)
return new sequence with passed sequences and patterns after sequenceafter(sequence, ...)
return new sequence with passed sequences and patterns before sequenceand(sequence, ...)
return new sequence with passed sequences and patterns layered with sequence
channel
transform
function to be called after expanding position expressions into notes, called afternote.transform
, can returnfalse
to not executepattern.transform
add(note, note, ...)
schedule note(s) to be played within context of channelconnect(effect)
route output signal to destination via effect or chainbypass
boolean to bypass all effects, effect type string or array of strings to bypass specific effect types, defaults to false
note
transform
function to be called after expanding position expressions into notes, called beforechannel.transform
, can returnfalse
to not executechannel.transform
start([time])
start playback of note at (AudioContext) time or immediatelystop([time])
stop playback of note at (AudioContext) time or immediatelyconnect(effect)
route output signal to destination via effect or chainbypass
boolean to bypass all effects, effect type string or array of strings to bypass specific effect types, defaults to false
reverb
wet
number between 0 and 999, amount of wet signal, defaults to 30dry
number between 0 and 999, amount of dry signal, defaults to 100time
number, impulse time in seconds, defaults to 1decay
number, drop off time in seconds, defaults to 3filter
string, type of filter (highpass, lowpass, bandpass, lowshelf, highshelf, peaking, notch, allpass), defaults to highpasscutoff
number, frequency where filter is applied, defaults to 2000reverse
boolean, defaults to falsebypass
boolean, defaults to false
delay
wet
number between 0 and 999, amount of wet signal, defaults to 50dry
number between 0 and 999, amount of dry signal, defaults to 100sync
boolean, sync delay with current tempo, defaults to falsetime
number between 0.001 and 4, delay time in seconds (or beats if sync is true), defaults to 0.3feedback
number between 0 and 999, amount of regeneration from processed signal, defaults to 50filter
string, type of filter (highpass, lowpass, bandpass, lowshelf, highshelf, peaking, notch, allpass), defaults to highpasscutoff
number, frequency where filter is applied, defaults to 2000bypass
boolean, defaults to false
compressor
threshold
number between -100 and 0, decibel value above which the compression will start taking effect, defaults to -12knee
number between 0 and 40, decibel value representing the range above the threshold where the curve smoothly transitions to the compressed portion, defaults to 30ratio
number between 0 and 20, amount of change in dB needed in input for 1 dB change in the output, defaults to 12attack
number, seconds required to reduce the gain by 10 dB, defaults to 0release
number, seconds required to increase the gain by 10 dB, defaults to 0.25gain
number between 0 and 999, amount of gain to processed signal, defaults to 100bypass
boolean, defaults to false
overdrive
wet
number between 0 and 999, amount of wet signal, defaults to 50dry
number between 0 and 999, amount of dry signal, defaults to 50preBand
number between 0 and 100, amount of preband filtering, defaults to 50color
number between 20 and 22050, frequency cutoff for preband filtering, defaults to 800postCut
number between 20 and 22050, frequency cutoff for post filter, defaults to 3000gain
number between 0 and 999, amount of gain to processed signal, defaults to 100bypass
boolean, defaults to false
filter
- based on BiquadFilterNode
wet
number between 0 and 999, amount of wet signal, defaults to 50dry
number between 0 and 999, amount of dry signal, defaults to 50shape
string, type of filter (highpass, lowpass, bandpass, lowshelf, highshelf, peaking, notch, allpass), defaults to highpassfrequency
number between 20 and 22050, frequency at which to apply effect, defaults to 440q
number between 0.001 and 100, controls the frequency band width or peak at cutoff, defaults to 1value
number between -999 and 999, amount of gain to affected frequency band, defaults to 0gain
number between 0 and 999, amount of gain to processed signal, defaults to 100bypass
boolean, defaults to false
chorus
wet
number between 0 and 999, amount of wet signal, defaults to 50dry
number between 0 and 999, amount of dry signal, defaults to 50rate
number between 0.01 and 99, defaults to 1.5feedback
number between 0 and 999, defaults to 0.2delay
number between 0 and 1, defaults to 0.005gain
number between 0 and 999, amount of gain to processed signal, defaults to 100bypass
boolean, defaults to false
phaser
wet
number between 0 and 999, amount of wet signal, defaults to 50dry
number between 0 and 999, amount of dry signal, defaults to 50rate
number between 0.01 and 99, defaults to 1.5depth
number between 0 and 1, defaults to 0.3feedback
number between 0 and 999, defaults to 0.2stereoPhase
number between 0 and 180, defaults to 45modulationFrequency
number between 500 and 1500, defaults to 750gain
number between 0 and 999, amount of gain to processed signal, defaults to 100bypass
boolean, defaults to false
ping pong delay
wet
number between 0 and 999, amount of wet signal, defaults to 50dry
number between 0 and 999, amount of dry signal, defaults to 50feedback
number between 0 and 1, defaults to 0.2left
number between 0.001 and 10, left channel delay in seconds, defaults to 0.15right
number between 0.001 and 10, right channel delay in seconds, defaults to 0.2gain
number between 0 and 999, amount of gain to processed signal, defaults to 100bypass
boolean, defaults to false
Feedback and issues
- Report bugs with Github Issues
- Ask questions on Gitter
- Send shoutouts on Twitter
- Or just email me
Develop
npm install
install all dependenciesnpm start
run examples development servernpm test
run testsnpm run test:watch
run and watch testsnpm run coverage
generate coverage report with Istanbulnpm publish
run tests, publish to npm, build minified version, tag and deploy examples
Contribute
- Check the roadmap and open issues
- Fork the repo
- Add tests and/or examples
- Submit a pull request
Props
- Roger Linn for making MPC60
- Marley Marl for innovating the art of sampling
- DJ Premier, J Dilla, Pete Rock, Damu the Fudgemunk, Black Milk, Large Professor and Apollo Brown for making dope beats to be inspired from
- Matt McKegg for building Bopper and Ditty, which are used in this project since version 0.1
License
MIT ยฉ 2015 Adam Renklint
Generated with redok @ Thursday July 23rd, 2020 - 11:44:40 PM