/* The MIT License (MIT) Copyright (c) 2014-2020 Nikolai Suslov and the Krestianstvo.org project contributors. (https://github.com/NikolaySuslov/livecodingspace/blob/master/LICENSE.md) */ // VWF & ToneJS model driver import { Fabric } from '/core/vwf/fabric.js'; class ToneModel extends Fabric { constructor(module) { console.log("ToneModel constructor"); super(module, "Model"); } factory() { let _self_ = this; return this.load( this.module, { // == Module Definition ==================================================================== // -- pipeline ----------------------------------------------------------------------------- // pipeline: [ log ], // vwf <=> log <=> scene // -- initialize --------------------------------------------------------------------------- initialize: function() { var self = this; this.state = { nodes: {}, scenes: {}, prototypes: {}, createLocalNode: function (nodeID, childID, childExtendsID, childImplementsIDs, childSource, childType, childIndex, childName, callback) { return { "parentID": nodeID, "ID": childID, "extendsID": childExtendsID, "implementsIDs": childImplementsIDs, "source": childSource, "type": childType, "name": childName, "prototypes": undefined }; }, isToneNodeComponent: function (prototypes) { var found = false; if (prototypes) { for (var i = 0; i < prototypes.length && !found; i++) { found = (prototypes[i] === "proxy/tonejs/node.vwf"); } } return found; }, isToneClass: function (prototypes, classID) { if (prototypes) { for (var i = 0; i < prototypes.length; i++) { if (prototypes[i] === classID) { //console.info( "prototypes[ i ]: " + prototypes[ i ] ); return true; } } } return false; }, isSynthDefinition: function (prototypes) { var found = false; if (prototypes) { for (var i = 0; i < prototypes.length && !found; i++) { found = (prototypes[i] == "proxy/tonejs/synth.vwf"); } } return found; }, isMembraneSynthDefinition: function (prototypes) { var found = false; if (prototypes) { for (var i = 0; i < prototypes.length && !found; i++) { found = (prototypes[i] == "proxy/tonejs/membraneSynth.vwf"); } } return found; }, isNoiseSynthDefinition: function (prototypes) { var found = false; if (prototypes) { for (var i = 0; i < prototypes.length && !found; i++) { found = (prototypes[i] == "proxy/tonejs/noiseSynth.vwf"); } } return found; }, createToneObject: function (node, config) { var protos = node.prototypes; var toneObj = undefined; if (this.isToneClass(protos, "proxy/tonejs/synth.vwf")) { toneObj = new Tone.PolySynth(Tone.synth); } if (this.isToneClass(protos, "proxy/tonejs/membraneSynth.vwf")) { toneObj = new Tone.PolySynth(Tone.MembraneSynth); // toneObj.set({ // envelope: { // release: 0.1 // } // }); } if (this.isToneClass(protos, "proxy/tonejs/noiseSynth.vwf")) { toneObj = new Tone.NoiseSynth(); } if (this.isToneClass(protos, "proxy/tonejs/pluckSynth.vwf")) { toneObj = new Tone.PolySynth(Tone.PluckSynth); } return toneObj } }; this.state.kernel = this.kernel.kernel.kernel; //this.Tone = Tone; //this.state.kernel = this.kernel.kernel.kernel; }, // == Model API ============================================================================ // -- creatingNode ------------------------------------------------------------------------- creatingNode: function( nodeID, childID, childExtendsID, childImplementsIDs, childSource, childType, childIndex, childName, callback /* ( ready ) */ ) { // If the parent nodeID is 0, this node is attached directly to the root and is therefore either // the scene or a prototype. In either of those cases, save the uri of the new node var childURI = (nodeID === 0 ? childIndex : undefined); var appID = this.kernel.application(); // If the node being created is a prototype, construct it and add it to the array of prototypes, // and then return var prototypeID = _self_.utility.ifPrototypeGetId(appID, this.state.prototypes, nodeID, childID); if (prototypeID !== undefined) { this.state.prototypes[prototypeID] = { parentID: nodeID, ID: childID, extendsID: childExtendsID, implementsID: childImplementsIDs, source: childSource, type: childType, name: childName }; return; } var protos = _self_.getPrototypes(this.kernel, childExtendsID); //var kernel = this.kernel.kernel.kernel; var node; if (this.state.isToneNodeComponent(protos)) { // Create the local copy of the node properties if (this.state.nodes[childID] === undefined) { this.state.nodes[childID] = this.state.createLocalNode(nodeID, childID, childExtendsID, childImplementsIDs, childSource, childType, childIndex, childName, callback); } node = this.state.nodes[childID]; node.prototypes = protos; //this.state.createToneObject(node); let aframeDriver = vwf.views["/drivers/view/aframe"]; if(aframeDriver){ let parentNode = aframeDriver.state.nodes[nodeID]; if(parentNode.aframeObj){ let sceneEl = aframeDriver.state.nodes[nodeID].scene.sceneEl; if (!sceneEl.audioListener) { sceneEl.audioListener = new THREE.AudioListener(); sceneEl.camera && sceneEl.camera.add(sceneEl.audioListener); // sceneEl.addEventListener('camera-set-active', function (evt) { // evt.detail.cameraEl.getObject3D('camera').add(sceneEl.audioListener); // }); } node.sound = new THREE.PositionalAudio( sceneEl.audioListener ); Tone.setContext(node.sound.context); //node.sound.context.resume(); node.toneObj = this.state.createToneObject(node); node.sound.setNodeSource(node.toneObj); parentNode.aframeObj.object3D.add(node.sound); } } //addNodeToHierarchy(node); //notifyDriverOfPrototypeAndBehaviorProps(); } }, // -- initializingNode ------------------------------------------------------------------------- // initializingNode: function( nodeID, childID, childExtendsID, childImplementsIDs, // childSource, childType, childIndex, childName ) { // }, // -- deletingNode ------------------------------------------------------------------------- //deletingNode: function( nodeID ) { //}, // -- initializingProperty ----------------------------------------------------------------- initializingProperty: function( nodeID, propertyName, propertyValue ) { var value = undefined; var node = this.state.nodes[nodeID]; if (node !== undefined) { value = this.settingProperty(nodeID, propertyName, propertyValue); } return value; }, // -- creatingProperty --------------------------------------------------------------------- creatingProperty: function (nodeID, propertyName, propertyValue) { return this.initializingProperty(nodeID, propertyName, propertyValue); }, // -- settingProperty ---------------------------------------------------------------------- settingProperty: function( nodeID, propertyName, propertyValue ) { let self = this; let node = this.state.nodes[nodeID]; var value = undefined; if (node && node.toneObj && _self_.utility.validObject(propertyValue)) { let toneObject = node.toneObj; // if (self.state.isComponentNodeDefinition(node.prototypes)) { // value = propertyValue; // switch (propertyName) { // default: // value = undefined; // break; // } // } if (value === undefined && self.state.isSynthDefinition(node.prototypes)) { value = propertyValue; switch (propertyName) { case "type": toneObject.set({oscillator:{type: propertyValue}}) //"sine"; "square"; "triangle"; "sawtooth"; break; default: value = undefined; break; } } } return value; }, // -- gettingProperty ---------------------------------------------------------------------- gettingProperty: function( nodeID, propertyName, propertyValue ) { let self = this; let node = this.state.nodes[nodeID]; let value = undefined; if (node && node.toneObj) { let toneObject = node.toneObj; // if (self.state.isComponentNodeDefinition(node.prototypes)) { // switch (propertyName) { // } // } if (value === undefined && self.state.isSynthDefinition(node.prototypes)) { switch (propertyName) { case "type": value = toneObject.options.oscillator.type break; } } } if ( value !== undefined ) { propertyValue = value; } return value; } } ); } getPrototypes(kernel, extendsID) { var prototypes = []; var id = extendsID; while (id !== undefined) { prototypes.push(id); id = kernel.prototype(id); } return prototypes; } } export { ToneModel as default }