Skip to content

Instantly share code, notes, and snippets.

@shamansir
Last active August 29, 2015 14:14
Show Gist options
  • Select an option

  • Save shamansir/8d846f7c155a717c0b72 to your computer and use it in GitHub Desktop.

Select an option

Save shamansir/8d846f7c155a717c0b72 to your computer and use it in GitHub Desktop.
RPD Toolkit example
Rpd.channeltype('pd/t-num', {
show: function(t_num) { return t_num ? t_num.value : '?'; }
});
Rpd.channeltype('pd/spinner', {
adapt: function(val) {
return { value: val, time: Date.now() };
}
});
Rpd.channeltype('pd/t-wave', { });
Rpd.channeltype('pd/t-obj', { show: function(val) { return val ? '[Some]' : '[None]' } });
Rpd.nodetype('pd/number', {
name: 'num',
inlets: { 'in': { type: 'pd/t-num', default: T(0) },
'spinner': { type: 'pd/spinner', default: T(0), hidden: true } },
outlets: { 'out': { type: 'pd/t-num' } },
process: function(inlets) {
if (inlets.spinner) {
// if spinner was updated last, use spinner value instead of input
if ((Date.now() - inlets.spinner.time) < 50) {
return { 'out': inlets.spinner.value };
} else {
return { 'out': inlets.in };
}
} else return { 'out': inlets.in };
}
});
Rpd.nodetype('pd/osc', {
name: 'osc',
inlets: { 'wave': { type: 'pd/t-wave', default: "sin" },
'freq': { type: 'pd/t-num', default: T(440) } },
outlets: { 'sound': { type: 'pd/t-obj' } },
process: function(inlets) {
if (!inlets.wave || !inlets.freq) return null;
return { 'sound': T('osc', { wave: inlets.wave,
freq: inlets.freq }) };
}
});
Rpd.nodetype('pd/wave', {
name: 'wave',
inlets: { 'wave': { type: 'pd/t-wave', default: 'sin', hidden: true } },
outlets: { 'wave': { type: 'pd/t-wave' } },
process: function(inlets) { return { 'wave': inlets.wave } }
});
Rpd.nodetype('pd/plot', {
name: 'plot',
inlets: { 'sound': { type: 'pd/t-obj', default: null } },
process: function() {}
});
Rpd.nodetype('pd/play', function() {
var lastSound;
return {
name: 'play',
inlets: { 'sound': { type: 'pd/t-obj', default: null } },
tune: function(updates) { return updates.throttle(50); },
process: function(inlets, inlets_prev) {
if (inlets_prev.sound) inlets_prev.sound.pause();
if (inlets.sound) {
lastSound = inlets.sound;
inlets.sound.play();
}
},
handle: {
'node/turn-off': function() {
if (lastSound) lastSound.pause();
}
}
}
});
Rpd.noderenderer('pd/number', 'html', function() {
var change;
return {
first: function(bodyElm) {
var spinner = document.createElement('span');
change = attachSpinner(spinner, 0);
bodyElm.appendChild(spinner);
return { 'spinner':
{ default: function() { change.emit(0); return T(0); },
valueOut: change.map(function(val) { return T(parseFloat(val)); }) }
};
},
always: function(bodyElm, inlets) {
if (inlets.spinner && inlets.in && ((Date.now() - inlets.spinner.time) > 50)) {
change.emit(inlets.in.value);
}
}
};
});
Rpd.noderenderer('pd/osc', 'html', {
always: function(bodyElm, inlets) {
bodyElm.innerText = bodyElm.textContent =
inlets.wave + '/' + inlets.freq;
}
});
Rpd.noderenderer('pd/wave', 'html', {
first: function(bodyElm) {
var chooser = document.createElement('select');
chooser.appendChild(createOption('sin'));
chooser.appendChild(createOption('saw'));
chooser.appendChild(createOption('tri'));
chooser.appendChild(createOption('pulse'));
chooser.appendChild(createOption('fami'));
bodyElm.appendChild(chooser);
return {
'wave': {
default: function() { chooser.value = 'sin'; return 'sin'; },
valueOut: Kefir.fromEvent(chooser, 'change')
.map(function() {
return chooser.options[chooser.selectedIndex].value;
})
}
}
}
});
Rpd.noderenderer('pd/plot', 'html', function() {
var plotElm;
return {
first: function(bodyElm) {
plotElm = document.createElement('canvas');
plotElm.width = 100;
plotElm.height = 100;
bodyElm.appendChild(plotElm);
},
always: function(bodyElm, inlets) {
if (inlets.sound) {
inlets.sound.plot({ target: plotElm });
}
}
}
});
// utils
function createOption(value, selected) {
var option = document.createElement('option');
option.value = value;
option.innerText = option.textContent = value;
if (selected) option.selected = 'selected';
return option;
}
function extractPos(evt) { return { x: evt.clientX,
y: evt.clientY }; };
function stopPropagation(evt) { evt.stopPropagation(); }
function attachSpinner(target, initial) {
target.classList.add('rpd-pd-spinner');
var initial = initial || 0;
var state = { value: initial };
var change = Kefir.emitter();
change.onValue(function(val) {
state.value = val;
target.innerText = target.textContent = val;
});
change.emit(initial);
Kefir.fromEvent(target, 'mousedown')
.map(extractPos)
.flatMap(function(startPos) {
var start = state.value;
return Kefir.fromEvent(document.body, 'mousemove')
.map(extractPos)
.takeUntilBy(Kefir.fromEvent(document.body, 'mouseup'))
.onValue(function(value) {
change.emit(start + (value.x - startPos.x));
})
}).onEnd(function() {});
return change;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment