Skip to content

Commit

Permalink
Tings
Browse files Browse the repository at this point in the history
  • Loading branch information
stephband committed Feb 2, 2024
1 parent 7be1701 commit bec1bba
Show file tree
Hide file tree
Showing 8 changed files with 117 additions and 98 deletions.
43 changes: 19 additions & 24 deletions module.css
Original file line number Diff line number Diff line change
@@ -1,28 +1,23 @@

@import "../bolt/fonts/fira-mono.css";
@import "../bolt/css/html.css";
@import "../bolt/css/svg.css";
@import "../bolt/css/root.css";
@import "../bolt/css/body.css";
@import "../bolt/css/type.css";
@import "../bolt/css/code.css";
@import "../bolt/css/content.css";
@import "../bolt/css/input.css";
@import "../bolt/css/label.css";
@import "../bolt/css/button.css";
@import "../bolt/css/thumb.css";
@import "../bolt/css/index.css";
@import "../bolt/css/block.css";
@import "../bolt/css/color.css";
@import "../bolt/css/text.css";
@import "../bolt/css/modifiers.css";
@import "../bolt/css/respond.css";
@import "../bolt/css/grid.css";
@import "../bolt/components/toggle-block.css";
@import "../bolt/components/toggle-button.css";
@import "../bolt/css/device.css";
@import "../bolt/css/var.css";
@import "../dom/css/dom.css";
@import "../bolt/elements/html.css";
@import "../bolt/elements/svg.css";
@import "../bolt/elements/root.css";
@import "../bolt/elements/body.css";
@import "../bolt/elements/type.css";
@import "../bolt/elements/code.css";
@import "../bolt/classes/content.css";
@import "../bolt/elements/input.css";
@import "../bolt/elements/label.css";
@import "../bolt/classes/button.css";
@import "../bolt/classes/thumb.css";
@import "../bolt/classes/list.css";
@import "../bolt/classes/block.css";
@import "../bolt/classes/color.css";
@import "../bolt/classes/text.css";
@import "../bolt/classes/atoms.css";
@import "../bolt/classes/toggle-block.css";
@import "../bolt/classes/toggle-button.css";
@import "../bolt/classes/device.css";
@import "../fn/css/prism-cruncher.css";
@import "../fn/css/docs.css";
@import "../fn/css/tests.css";
Expand Down
59 changes: 19 additions & 40 deletions modules/graph/connector.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,64 +11,43 @@ const assign = Object.assign;
const define = Object.defineProperties;
const seal = Object.seal;
const properties = {
connectors: {}
connectors: {},
source: {},
target: {},
param: {},
length: {}
};

export default function Connector(connectors, source, target, srcChan, tgtChan) {
// Get source node
//const sourceParts = sourceId.split('.');
/*const sourceNode = typeof sourceId === 'object' ?
nodes.find((entry) => entry === sourceId || entry.node === sourceId).node :
nodes.find(matches({ id: sourceId })) ;
// Get target node or param
//const targetParts = targetId.split('.');
const targetNode = typeof targetId === 'object' ?
nodes.find((entry) => entry === targetId || entry.node === targetId).node :
nodes.find(matches({ id: targetId })) ;*/

if (window.DEBUG && !source) {
throw new Error('Connector - missing source ' + source);
}

if (window.DEBUG && !target) {
throw new Error('Connector - missing target ' + target);
}
if (!source) { throw new Error('Connector - missing source object ' + source); }
if (!target) { throw new Error('Connector - missing target object ' + target); }

// Define properties
properties.connectors.value = connectors;
define(this, properties);
properties.source.value = source;
properties.target.value = target;

const tgtParam = tgtChan
&& !/^\d/.test(tgtChan)
&& tgt.node[tgtChan] ;
properties.param.value = tgtChan
&& !/^\d/.test(tgtChan)
&& tgt.node[tgtChan] ;

this.source = source;
this.target = target;
this.tgtParam = tgtParam;
this.length = 2;
properties.length.value = srcChan || tgtChan ?
4 :
2 ;

define(this, properties);

if (srcChan || tgtChan) {
this[2] = srcChan && parseInt(srcChan, 10) || 0;
this[3] = tgtChan && /^\d/.test(tgtChan) && parseInt(tgtChan, 10) || 0;
this.length = 4;
}

// Make immutable
seal(this);

// Connect them up
if (!connect(this.source.node, this.tgtParam || this.target.node, this[2], this[3])) {
if (!connect(source.node, this.param || target.node, this[2], this[3])) {
return false;
}
}

assign(Connector, {
/*from: function(data) {
return new Connector(data.connectors, data.source, data.target, data[2], data[3]);
}*/
});

define(Connector.prototype, {
0: {
get: function() { return this.source.id; },
Expand All @@ -84,7 +63,7 @@ define(Connector.prototype, {
assign(Connector.prototype, {
remove: function() {
// Disconnect them
if (disconnect(this.source.node, this.tgtParam || this.target.node, this[2], this[3])) {
if (disconnect(this.source.node, this.param || this.target.node, this[2], this[3])) {
// Splice this out of connectors
let n = -1;
while (this.connectors[++n] !== this);
Expand Down
10 changes: 10 additions & 0 deletions modules/graph/connectors.js
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,16 @@ export default function Connectors(nodes, connectors = []) {
log('Connectors', n + ' connections');
}

define(Connectors.prototype, {
length: {
get: function() {
let n = -1;
while (this[++n]);
return n;
}
}
});

assign(Connectors.prototype, {
create: overload(function(){ return arguments.length; }, {
1: function(data) {
Expand Down
42 changes: 22 additions & 20 deletions modules/graph/node.js
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@

import get from '../../../../fn/modules/get.js';
import matches from '../../../../fn/modules/matches.js';
import Stream from '../../../../fn/modules/stream/stream.js';
import nothing from '../../../../fn/modules/nothing.js';
import overload from '../../../../fn/modules/overload.js';
//import Privates from '../../../../fn/modules/privates.js';
import Privates from '../../../../fn/modules/privates.js';
import remove from '../../../../fn/modules/remove.js';
import { floatToFrequency, toNoteNumber } from '../../../../midi/modules/data.js';

Expand Down Expand Up @@ -42,34 +43,35 @@ const properties = {
}
};

const ids = {};

function assignId(node, id) {
if (id) {
// if (id in ids) {
// throw new Error('GraphNode: Attempt to create node with id of existing node');
// }
function assignId(stage, object, id) {
if (stage.find(matches({ id }))) {
throw new Error('GraphNode: stage already has object with id ' + id);
}
else {

// TODO: Cheeky, move this to graph.js? Hmm, circular dependency if we do.
const ids = Privates(stage).ids || (Privates(stage).ids = {});

if (id === undefined) {
id = 0;
while (ids[++id]);
}

ids[id] = node;
node.id = id;
ids[id] = object;
object.id = id;
return object;
}

function warnNoPlayable(node, type, name) {
console.warn('Soundstage: dropping "' + type + '" event, node type "' + node.type + '" does not support start/stop');
function warnNoPlayable(object, type, name) {
console.warn('Soundstage: dropping "' + type + '" event, node type "' + object.type + '" does not support start/stop');
}

function warnNoParam(node, type, name) {
console.warn('Soundstage: dropping "' + type + '" event, node type "' + node.type + '" does not support param "' + name + '"');
function warnNoParam(object, type, name) {
console.warn('Soundstage: dropping "' + type + '" event, node type "' + object.type + '" does not support param "' + name + '"');
}

export default function GraphNode(stage, type, id, data = {}, events = [], context, merger, transport) {
// Define identity in the graph
assignId(this, id);
assignId(stage, this, id);

this.type = type;
this.events = events;
Expand Down Expand Up @@ -110,7 +112,7 @@ assign(GraphNode.prototype, {
start: function(event) {
if (!this.node.start && !this.node.startWarningShown) {
this.node.startWarningShown = true;
warnNoPlayable(this.node, event[1], event[2])
warnNoPlayable(this, event[1], event[2])
return;
}

Expand All @@ -125,7 +127,7 @@ assign(GraphNode.prototype, {
stop: function(event) {
if (!this.node.stop && !this.node.stopWarningShown) {
this.node.stopWarningShown = true;
warnNoPlayable(this.node, event[1], event[2])
warnNoPlayable(this, event[1], event[2])
return;
}

Expand All @@ -141,7 +143,7 @@ assign(GraphNode.prototype, {
const type = event[1];
const name = event[2];
//console.log(this.context.currentTime.toFixed(3), 'param ', time.toFixed(3), name, event[3], event[4], event[5]);
return !(name in this.node) ? warnNoParam(this.node, type, name) :
return !(name in this.node) ? warnNoParam(this, type, name) :
isAudioParam(this.node[name]) ? automateParamAtTime(this.node[name], time, event[3], event[4], event[5]) :
automatePropertyAtTime(this.node, time, name, event[3]) ;
},
Expand All @@ -151,7 +153,7 @@ assign(GraphNode.prototype, {
const time = event[0];
const type = event[1];
console.log(this.context.currentTime.toFixed(3), 'default ', time.toFixed(3), type);
return !(type in this.node) ? warnNoParam(this.node, type, type) :
return !(type in this.node) ? warnNoParam(this, type, type) :
isAudioParam(this.node[type]) ? automateParamAtTime(this.node[type], time, event[2], event[3], event[4]) :
automatePropertyAtTime(this.node, time, name, event[2]) ;
}
Expand Down
22 changes: 14 additions & 8 deletions modules/graph/nodes.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,9 @@ GraphNodes()
const assign = Object.assign;
const define = Object.defineProperties;
const properties = {
stage: {
/*stage: {
value: undefined
},
},*/

status: {
value: undefined,
Expand All @@ -38,7 +38,7 @@ export default function GraphNodes(stage, data = [], context, merger, transport)
privates.transport = transport;

// Define properties
properties.stage.value = stage;
//properties.stage.value = stage;
define(this, properties);

// Loop through nodes in data and create entries for them
Expand All @@ -57,6 +57,16 @@ assign(GraphNodes, {
}
});

define(GraphNodes.prototype, {
length: {
get: function() {
let n = -1;
while (this[++n]);
return n;
}
}
});

assign(GraphNodes.prototype, {
create: overload((object) => typeof object, {
object: function(data) {
Expand All @@ -78,10 +88,6 @@ assign(GraphNodes.prototype, {
pipe: Tree.prototype.pipe,

toJSON: function() {
// Turn this object to array
const array = [];
let n = -1;
while (this[++n]) node.push(this[n]);
return array;
return Array.from(this);
}
});
9 changes: 9 additions & 0 deletions modules/soundstage.js
Original file line number Diff line number Diff line change
Expand Up @@ -298,6 +298,13 @@ assign(Soundstage.prototype, Sequencer.prototype, Graph.prototype, {
return new Control(this.controls, source, target, options, privates.notify);
},*/

find: function(fn) {
let object = this.nodes && this.nodes.find(fn);
if (object) { return object; }
object = this.sequences && this.sequences.find(fn);
return object;
},

/* Receive events */

automate: function(address, name, value, curve, duration, time) {
Expand Down Expand Up @@ -402,6 +409,7 @@ assign(Soundstage.prototype, Sequencer.prototype, Graph.prototype, {
Returns the beat of this sequence given a context `time`.
**/
beatAtTime: function(time) {
const privates = Privates(this);
return privates.playhead ?
privates.playhead.beatAtTime(time) :
0 ;
Expand All @@ -412,6 +420,7 @@ assign(Soundstage.prototype, Sequencer.prototype, Graph.prototype, {
Returns the context time that `beat` of the sequence plays at.
**/
timeAtBeat: function(beat) {
const privates = Privates(this);
return privates.playhead ?
privates.playhead.timeAtBeat(time) :
0 ;
Expand Down
20 changes: 15 additions & 5 deletions modules/test/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -35,24 +35,33 @@ <h1>Test Soundstage</h1>
nodes: [{
id: 1,
type: 'tone',
node: { type: 'sine' },
events: [
[0, 'sequence', 9, 0, 2]
]
],
node: {
type: 'sine'
}
}, {
id: 'output',
type: 'output',
node: { channels: [0,1] }
node: {
channels: [0,1]
}
}],

connectors: [
[1, 'output']
],

events: [
// 180bpm
[0, 'rate', 3]
],

sequences: [{
id: 9,
events: [
// Should never be played
// TODO: Should never be played - or should we play the tail end of it?
[-0.1, 'note', 80, 0, 0.2],
// Should be played
[0, 'note', 100, 0, 0.05],
Expand All @@ -62,9 +71,10 @@ <h1>Test Soundstage</h1>
}]
});

window.stage = stage;

events('click', document.getElementById('start')).each((e) => {
stage.start(context.currentTime + 1).stop(context.currentTime + 5);
window.stage = stage;
});
</script>
</body>
Expand Down
Loading

0 comments on commit bec1bba

Please sign in to comment.