Skip to content
Permalink
Browse files

refactor synth-chunk to use chromatic-chunk under the hood

  • Loading branch information...
mmckegg committed Nov 10, 2017
1 parent 13ef3b6 commit 541b54360bd5508e2c1bcd1133dc4d288897439d
@@ -4,7 +4,6 @@ var Property = require('lib/property')
var ArrayGrid = require('array-grid')
var computed = require('mutant/computed')
var extend = require('xtend/mutable')
var withResolved = require('lib/with-resolved')

module.exports = BaseChunk

@@ -1,10 +1,10 @@
var watch = require('mutant/watch')
var onceIdle = require('mutant/once-idle')

module.exports = function doubleBind (a, b) {
module.exports = function doubleBind (a, b, {idle = true} = {}) {
var updatingA = false
var updatingB = false
var initialized = false
var initialized = !idle // skip idle check if idle === false

// delay reverse binding until load queue has processed
onceIdle(() => { initialized = true })
@@ -4,7 +4,7 @@ var Param = require('lib/param')
module.exports = ProcessorNode

function ProcessorNode (context, input, output, params, releases) {
var obs = ObservStruct(params)
var obs = ObservStruct(params, {merge: true})

obs.input = input
obs.output = output
@@ -7,8 +7,6 @@ var extend = require('xtend')
module.exports = RoutableSlot

function RoutableSlot (context, properties, input, output, releases) {
var audioContext = context.audio

output = output || input

var refreshingConnections = false
@@ -19,7 +17,7 @@ function RoutableSlot (context, properties, input, output, releases) {
id: Observ(),
output: Observ(),
volume: Property(1)
}, properties))
}, properties), {merge: true})

obs._type = 'RoutableSlot'
obs.context = context
@@ -0,0 +1,34 @@
var deepEqual = require('deep-equal')
var computed = require('mutant/computed')

module.exports = ShapeSlots

function ShapeSlots (shape) {
var result = []
return computed(deepMatch(shape), (shape) => {
var newLength = (Array.isArray(shape) && shape[0] * shape[1]) || 0
var currentLength = result.length
if (currentLength !== newLength) {
for (var i = currentLength; i < newLength; i++) {
result[i] = i
}
result.length = newLength
return result
} else {
return computed.NO_CHANGE
}
})
}

function deepMatch (obs) {
var lastValue = null
return computed(obs, function (value) {
value = value == null ? null : value
if (!deepEqual(lastValue, value)) {
lastValue = JSON.parse(JSON.stringify(value))
return value
} else {
return computed.NO_CHANGE
}
})
}
@@ -1,18 +1,16 @@
var Value = require('mutant/value')
var MutantMap = require('mutant/map')
var MutantArray = require('mutant/array')
var watch = require('mutant/watch')
var watchAll = require('mutant/watch-all')
var computed = require('mutant/computed')
var deepEqual = require('deep-equal')
var doubleBind = require('lib/double-bind')
var resolveNode = require('lib/resolve-node')
var throttle = require('mutant/throttle')
var ShapeSlots = require('lib/shape-slots')
var Event = require('geval')

module.exports = TemplateSlot

function TemplateSlot (context, shape, scale) {
function TemplateSlot (context, shape) {
var obs = Value({})

// handle defaultValue
@@ -32,35 +30,22 @@ function TemplateSlot (context, shape, scale) {
var broadcastAdd = null
var broadcastRemove = null

obs.nodeName = computed([obs], x => x && x.node || false)

var items = MutantArray([], {
fixedIndexing: true,
onListen: function () {
return watchAll([deepMatch(shape), deepMatch(scale)], function (shape, scale) {
var length = Array.isArray(shape) && shape[0] * shape[1] || 0
var result = []
for (var i = 0; i < length; i++) {
result.push({
id: String(i),
value: i,
scale: scale
})
}
items.set(result)
}, { nextTick: true })
}
})
obs.nodeName = computed([obs], x => (x && x.node) || false)

var ids = ShapeSlots(shape)
var throttledValue = throttle(obs, 40)

obs.slots = MutantMap(items, function (item, invalidateOn) {
obs.slots = MutantMap(ids, function (id, invalidateOn) {
var ctor = resolveNode(context.nodes, obs.nodeName())
invalidateOn(obs.nodeName)

if (ctor) {
var result = ctor(context)
var value = computed([throttledValue, item], obtainWithParams)
var value = computed([obs, {
id: String(id),
value: id,
scale: '$inherit'
}], obtainWithParams)
var releases = [ watch(value, result.set) ]
if (result.destroy) {
releases.push(result.destroy)
@@ -85,8 +70,8 @@ function TemplateSlot (context, shape, scale) {
}
})

obs.slots.onAdd = Event(b => broadcastAdd = b)
obs.slots.onRemove = Event(b => broadcastRemove = b)
obs.slots.onAdd = Event(b => { broadcastAdd = b })
obs.slots.onRemove = Event(b => { broadcastRemove = b })

obs.slots.onNodeChange = Event(function (broadcast) {
obs.slots.onAdd(broadcast)
@@ -108,7 +93,7 @@ function TemplateSlot (context, shape, scale) {

if (ctor) {
var instance = ctor(templateContext)
releases.push(doubleBind(obs, instance))
releases.push(doubleBind(obs, instance, {idle: false}))

if (instance.destroy) {
releases.push(instance.destroy)
@@ -141,16 +126,3 @@ function obtainWithParams (obj, params) {
}
}))
}

function deepMatch (obs) {
var lastValue = null
return computed(obs, function (value) {
value = value == null ? null : value
if (!deepEqual(lastValue, value)) {
lastValue = JSON.parse(JSON.stringify(value))
return value
} else {
return computed.NO_CHANGE
}
})
}
@@ -4,7 +4,7 @@ var Param = require('lib/param')
module.exports = Triggerable

function Triggerable (context, params, trigger, releases) {
var obs = ObservStruct(params)
var obs = ObservStruct(params, {merge: true})
var lastEvent = null

obs.getAttackDuration = Param.getAttackDuration.bind(this, obs)
@@ -0,0 +1,41 @@
var forEach = require('mutant/for-each')
var forEachPair = require('mutant/for-each-pair')

module.exports = watchNodesChanged

function watchNodesChanged (collectionOrLookup, fn) {
var nodes = new global.Set()
return collectionOrLookup(function (value) {
var currentItems = new global.Set()
var changed = false

if (Array.isArray(value)) {
forEach(collectionOrLookup, function (item) {
currentItems.add(item)
if (!nodes.has(item)) {
nodes.add(item)
changed = true
}
})
} else {
forEachPair(collectionOrLookup, function (key, item) {
currentItems.add(item)
if (!nodes.has(item)) {
nodes.add(item)
changed = true
}
})
}

Array.from(nodes.values()).forEach(function (node) {
if (!currentItems.has(node)) {
nodes.delete(node)
changed = true
}
})

if (changed) {
fn()
}
})
}
@@ -5,7 +5,6 @@ var Property = require('lib/property')
var Slots = require('lib/slots')
var TemplateSlot = require('lib/template-slot')

var computed = require('mutant/computed')
var lookup = require('mutant/lookup')
var merge = require('mutant/merge')

@@ -21,21 +20,11 @@ function ChromaticChunk (parentContext) {
notes: [0, 2, 4, 5, 7, 9, 11]
}

var scale = Property(defaultScale)

var computedScale = computed([scale, context.globalScale], function (scale, globalScale) {
if (scale === '$global' && globalScale) {
return globalScale
} else if (scale instanceof Object) {
return scale
} else {
return defaultScale
}
})
context.scale = Property(defaultScale)

var obs = ObservStruct({
scale: scale,
templateSlot: TemplateSlot(context, context.shape, computedScale),
scale: context.scale,
templateSlot: TemplateSlot(context, context.shape),
slots: Slots(context),
inputs: Property([]),
outputs: Property(['output']),
@@ -53,9 +42,11 @@ function ChromaticChunk (parentContext) {
obs.chokeAll = context.chokeAll
obs.context = context

window.thing = obs.templateSlot.slots

obs.slotLookup = merge([
lookup(obs.templateSlot.slots, 'id'),
lookup(obs.slots, 'id')
lookup(obs.templateSlot.slots, (x) => x && x['id']),
lookup(obs.slots, (y) => y && y['id'])
])

obs.spawnParam = function (id) {
@@ -19,7 +19,16 @@ function ScaleModulator (context) {
scale: Property(defaultScale)
})

obs.currentValue = computed([obs.value.currentValue, context.offset.currentValue || context.offset, obs.scale], lambda, {
var scale = computed([obs.scale, context.globalScale, context.scale], (scale, globalScale, scopeScale) => {
if (scale === '$inherit') scale = (scopeScale || globalScale)
if (scale === '$global') scale = globalScale
if (!scale) scale = defaultScale
return scale
})

var offset = (context.offset && (context.offset.currentValue || context.offset)) || 0

obs.currentValue = computed([obs.value.currentValue, offset, scale], lambda, {
context: { audioContext: context.audio },
comparer: ParamTransform.deepEqual
})
@@ -14,9 +14,7 @@ var BaseChunk = require('lib/base-chunk')
var extendParams = require('lib/extend-params')
var Param = require('lib/param')
var resolve = require('mutant/resolve')

var forEach = require('mutant/for-each')
var forEachPair = require('mutant/for-each-pair')
var watchNodesChanged = require('lib/watch-nodes-changed')

var Path = require('path')

@@ -239,40 +237,3 @@ function External (parentContext) {
function multiply (a, b) {
return a * b
}

function watchNodesChanged (collectionOrLookup, fn) {
var nodes = new global.Set()
return collectionOrLookup(function (value) {
var currentItems = new global.Set()
var changed = false

if (Array.isArray(value)) {
forEach(collectionOrLookup, function (item) {
currentItems.add(item)
if (!nodes.has(item)) {
nodes.add(item)
changed = true
}
})
} else {
forEachPair(collectionOrLookup, function (key, item) {
currentItems.add(item)
if (!nodes.has(item)) {
nodes.add(item)
changed = true
}
})
}

Array.from(nodes.values()).forEach(function (node) {
if (!currentItems.has(node)) {
nodes.delete(node)
changed = true
}
})

if (changed) {
fn()
}
})
}

0 comments on commit 541b543

Please sign in to comment.
You can’t perform that action at this time.