loop-grid
Version:
An observable collection of looped event sequences shaped to a grid.
253 lines (142 loc) • 5.92 kB
Markdown
loop-grid
===
An observable collection of looped event sequences shaped to a grid.
## Install via [npm](https://npmjs.org/package/loop-grid)
```js
$ npm install loop-grid
```
## API
```js
var LoopGrid = require('loop-grid')
```
### `var loopGrid = LoopGrid(options)`
Returns an [observable](https://github.com/raynos/observ) instance of LoopGrid.
#### options:
- **scheduler**: (required) instance of [Bopper](https://github.com/mmckegg/bopper)
- **triggerEvent**: (required) `function(event)` called for every event to be triggered
- **audio**: (required) instance of [AudioContext](https://developer.mozilla.org/en-US/docs/Web/API/AudioContext)
### `loopGrid()`
Return the current object descriptor (state).
### `loopGrid.set(descriptor)`
Set the current object descriptor (state).
### `loopGrid.shape` (`Observ([rows, cols])`)
Included in state.
### `loopGrid.loops` (`Observ([ { length: 8, events: [] }, ... ])`)
Included in state.
### `loopGrid.targets` (`Observ([ids])`)
Mapping of grid loops to ids.
Included in state.
### `loopGrid.loopLength` (`Observ(8)`)
Included in state.
### `var removeListener = loopGrid.onEvent(listener)`
```js
var event = {
id: String,
event: 'start' | 'stop',
position: Number, // beat
time: Number, // based on
args: Array
}
```
### `var value = loopGrid.loopPosition()`
### `var removeListener = loopGrid.loopPosition(listener)`
### `var arrayGrid = loopGrid.grid()`
Returns [ArrayGrid](https://github.com/mmckegg/array-grid) based on `loopGrid.targets` and `loopGrid.shape`.
### `var removeListener = loopGrid.grid(listener)
### `var grid = loopGrid.playing()`
Returns ArrayGrid of `true` values where target is currently being triggered.
### `var removeListener = loopGrid.playing(listener)`
### `var grid = loopGrid.active()`
Returns ArrayGrid of `true` values where target has a current loop.
### `var removeListener = loopGrid.active(listener)`
### `loopGrid.destroy()`
## Looper
```js
var Looper = require('loop-grid/looper')
```
### `var looper = Looper(loopGrid)`
### `var loops = looper()`
### `var removeListener = looper(listener)`
### `var currentlyRecording = looper.recording()`
### `var removeListener = looper.recording(listener)`
### `looper.store()`
### `looper.flaten()`
### `var releaseTransform = looper.transform(func(input, args..), args)`
Pass in a function to add to transform stack. `input` is an instance of [ArrayGrid](https://github.com/mmckegg/array-grid) and should return either the modified `input` or a new instance of `ArrayGrid`.
### `looper.undo()`
### `looper.redo()`
### `looper.isTransforming()`
## Computed Flags
```js
var computeFlags = require('loop-grid/compute-flags')
```
## Computed Targets
```js
var computeTargets = require('loop-grid/compute-targets')
```
## Selector
Range selector for [loop-grid](https://github.com/mmckegg/loop-grid).
## API
```js
var Selector = require('loop-grid/selector')
```
### `var selection = Selector(shape)`
Returns an extended instance of ObservGrid with `shape` specified.
### `selector.start(inputGrid, done)`
Pass in an observable ArrayGrid. `done` will be called on `stop` or before subsequent `start`.
Any truthy values will trigger a selection. Simultaneous true values will trigger range selection. `selection` will have `.set(selectedIndexes)` called on every change.
### `selector.clear()`
Sets `selection` to an empty array.
### `selector.stop()`
Release watch of `inputGrid` and call `done`.
# Transforms
## Holder
Beat stutter/looper
```js
var Holder = require('loop-grid/transforms/holder')
```
### `var holder = Holder(transform)`
Pass `loopGrid.transform` to this constructor.
### `holder.setLength(length)`
Choose the length (in beat decimal) of the stutter effect.
### `holder.start(position[, indexes, done])`
Loop events in specified `indexes` (or all if not specified) from `position` to `position + length`. Ensure each event length is no longer than specified `length` (truncating if necessary).
Automatically calls `holder.stop()` first if there is a current hold in progress.
### `holder.stop()`
Release `transform` and call `done` if specified.
## Mover
Move selected ranges of loops to new origin.
```js
var Mover = require('loop-grid/transforms/mover')
```
### `var mover = Mover(transform)`
Pass `loopGrid.transform` to this constructor.
### `mover.start(inputGrid, selectedIndexes, done)`
Finds the top-left most coordinates in `selectedIndexes`, and uses this as the start origin. Any true values in `inputGrid` will call `transform` with a function that moves the values from selectedIndexes to the new origin. Multiple true values will cause the selectedIndexes to be duplicated.
### `mover.stop()`
Release any pending `transform` and stop watching `inputGrid`.
## Repeater
```js
var Repeater = require('loop-grid/transforms/repeater')
```
### `var repeater = Repeater(transform)
Pass `loopGrid.transform` to this constructor.
### `repeater.start(inputGrid, length)`
Held notes will call `transform` with a function that creates a repeating note with length `length / 2` at the rate of specified `length`.
### `repeater.setLength(length)`
### `repeater.stop()`
Release the `inputGrid`.
## Suppressor
Suppress selected loops
```js
var Suppressor = require('loop-grid/transforms/suppressor')
```
### `var suppressor = Suppressor(transform, shape[, stride])`
Pass `loopGrid.transform` to this constructor.
Returns an extended [observ](https://github.com/raynos/observ) instance containing instances of [array-grid](https://github.com/mmckegg/array-grid) with `true` values at coords where currently suppressed.
### `suppressor.start(indexes, done)`
Calls `transform` with a function that suppresses all `indexes` specified.
### `suppressor.stop()`
Release suppression `transform`.
## License
[AGPL-3.0](https://www.gnu.org/licenses/agpl-3.0.html)