UNPKG

gibberish-dsp

Version:

Gibberish is designed to be an optimized API for audio synthesis using per-sample techniques.

158 lines (126 loc) 4.79 kB
const serialize = require('serialize-javascript') module.exports = function( Gibberish ) { const replaceObj = function( obj, shouldSerializeFunctions = true ) { if( typeof obj === 'object' && obj !== null && obj.id !== undefined ) { if( obj.__type !== 'seq' ) { // XXX why? return { id:obj.id, prop:obj.prop } }else{ // shouldn't I be serializing most objects, not just seqs? return serialize( obj ) } }else if( typeof obj === 'function' && shouldSerializeFunctions === true ) { return { isFunc:true, value:serialize( obj ) } } return obj } const makeAndSendObject = function( __name, values, obj ) { const properties = {} // object has already been sent through messageport... for( let key in values ) { const alreadyProcessed = (typeof values[ key ] === 'object' && values[ key ] !== null && values[ key ].__meta__ !== undefined) || (typeof values[key] === 'function' && values[ key ].__meta__ !== undefined ) if( alreadyProcessed ) { properties[ key ] = { id:values[ key ].__meta__.id } }else if( Array.isArray( values[ key ] ) ) { const arr = [] for( let i = 0; i < values[ key ].length; i++ ) { arr[ i ] = replaceObj( values[ key ][i], false ) } properties[ key ] = arr }else if( typeof values[key] === 'object' && values[key] !== null ){ properties[ key ] = replaceObj( values[ key ], false ) }else{ properties[ key ] = values[ key ] } } let serializedProperties = serialize( properties ) if( Array.isArray( __name ) ) { const oldName = __name[ __name.length - 1 ] __name[ __name.length - 1 ] = oldName[0].toUpperCase() + oldName.substring(1) }else{ __name = [ __name[0].toUpperCase() + __name.substring(1) ] } obj.__meta__ = { address:'add', name:__name, properties:serializedProperties, id:obj.id } Gibberish.worklet.ugens.set( obj.id, obj ) Gibberish.worklet.port.postMessage( obj.__meta__ ) } const doNotProxy = [ 'connected', 'input', 'wrap', 'callback', 'inputNames', 'on', 'off','publish' ] const __proxy = function( __name, values, obj ) { if( Gibberish.mode === 'worklet' && Gibberish.preventProxy === false ) { makeAndSendObject( __name, values, obj ) // proxy for all method calls to send to worklet const proxy = new Proxy( obj, { get( target, prop, receiver ) { if( typeof target[ prop ] === 'function' && prop.indexOf('__') === -1 && doNotProxy.indexOf( prop ) === -1 ) { const proxy = new Proxy( target[ prop ], { apply( __target, thisArg, args ) { if( Gibberish.proxyEnabled === true ) { const __args = args.map( __value => replaceObj( __value, true ) ) Gibberish.worklet.port.postMessage({ address:'method', object:obj.id, name:prop, args:__args }) } const temp = Gibberish.proxyEnabled Gibberish.proxyEnabled = false const out = __target.apply( thisArg, args ) Gibberish.proxyEnabled = temp return out } }) return proxy } return target[ prop ] }, set( target, prop, value, receiver ) { if( doNotProxy.indexOf( prop ) === -1 ) { if( Gibberish.proxyEnabled === true ) { const __value = replaceObj( value ) if( __value !== undefined ) { Gibberish.worklet.port.postMessage({ address:'set', object:obj.id, name:prop, value:__value }) } } } target[ prop ] = value // must return true for any ES6 proxy setter return true } }) // XXX XXX XXX XXX XXX XXX // REMEMBER THAT YOU MUST ASSIGN THE RETURNED VALUE TO YOUR UGEN, // YOU CANNOT USE THIS FUNCTION TO MODIFY A UGEN IN PLACE. // XXX XXX XXX XXX XXX XXX return proxy }else if( Gibberish.mode === 'processor' && Gibberish.preventProxy === false ) { const proxy = new Proxy( obj, { //get( target, prop, receiver ) { return target[ prop ] }, set( target, prop, value, receiver ) { let valueType = typeof value if( prop.indexOf('__') === -1 && valueType !== 'function' && valueType !== 'object' ) { if( Gibberish.processor !== undefined ) { Gibberish.processor.messages.push( obj.id, prop, value ) } } target[ prop ] = value // must return true for any ES6 proxy setter return true } }) return proxy } return obj } return __proxy }