Improvement: import is now very error tolerantdds
| @@ -331,6 +331,52 @@ span.mainfunction {color: #993300; font-weight: bolder} | |||
| TODO: add "parameters" fields, to replace the form html stuff | |||
| --> | |||
| <script type="text/x-red" data-container-name="NodeDefinitions"> | |||
| {"nodes":[ | |||
| {"type":"AudioInputI2S","data":{"defaults":{"name":{"value":"new"}},"shortName":"i2s","inputs":0,"outputs":2,"category":"input-function","color":"#E6E0F8","icon":"arrow-in.png"}}, | |||
| {"type":"AudioInputAnalog","data":{"defaults":{"name":{"value":"new"}},"shortName":"adc","inputs":0,"outputs":1,"category":"input-function","color":"#E6E0F8","icon":"arrow-in.png"}}, | |||
| {"type":"AudioInputI2Sslave","data":{"defaults":{"name":{"value":"new"}},"shortName":"i2ss","inputs":0,"outputs":2,"category":"input-function","color":"#E6E0F8","icon":"arrow-in.png"}}, | |||
| {"type":"AudioOutputI2S","data":{"defaults":{"name":{"value":"new"}},"shortName":"i2s","inputs":2,"outputs":0,"category":"output-function","color":"#E6E0F8","icon":"arrow-in.png"}}, | |||
| {"type":"AudioOutputSPDIF","data":{"defaults":{"name":{"value":"new"}},"shortName":"spdif","inputs":2,"outputs":0,"category":"output-function","color":"#E6E0F8","icon":"arrow-in.png"}}, | |||
| {"type":"AudioOutputAnalog","data":{"defaults":{"name":{"value":"new"}},"shortName":"dac","inputs":1,"outputs":0,"category":"output-function","color":"#E6E0F8","icon":"arrow-in.png"}}, | |||
| {"type":"AudioOutputPWM","data":{"defaults":{"name":{"value":"new"}},"shortName":"pwm","inputs":1,"outputs":0,"category":"output-function","color":"#E6E0F8","icon":"arrow-in.png"}}, | |||
| {"type":"AudioOutputI2Sslave","data":{"defaults":{"name":{"value":"new"}},"shortName":"i2ss","inputs":2,"outputs":0,"category":"output-function","color":"#E6E0F8","icon":"arrow-in.png"}}, | |||
| {"type":"AudioMixer4","data":{"defaults":{"name":{"value":"new"}},"shortName":"mixer","inputs":4,"outputs":1,"category":"mixer-function","color":"#E6E0F8","icon":"arrow-in.png"}}, | |||
| {"type":"AudioPlayMemory","data":{"defaults":{"name":{"value":"new"}},"shortName":"playMem","inputs":0,"outputs":1,"category":"play-function","color":"#E6E0F8","icon":"arrow-in.png"}}, | |||
| {"type":"AudioPlaySdWav","data":{"defaults":{"name":{"value":"new"}},"shortName":"playSdWav","inputs":0,"outputs":2,"category":"play-function","color":"#E6E0F8","icon":"arrow-in.png"}}, | |||
| {"type":"AudioPlaySdRaw","data":{"defaults":{"name":{"value":"new"}},"shortName":"playSdRaw","inputs":0,"outputs":1,"category":"play-function","color":"#E6E0F8","icon":"arrow-in.png"}}, | |||
| {"type":"AudioPlaySerialflashRaw","data":{"defaults":{"name":{"value":"new"}},"shortName":"playFlashRaw","inputs":0,"outputs":1,"category":"play-function","color":"#E6E0F8","icon":"arrow-in.png"}}, | |||
| {"type":"AudioPlayQueue","data":{"defaults":{"name":{"value":"new"}},"shortName":"queue","inputs":0,"outputs":1,"category":"play-function","color":"#E6E0F8","icon":"arrow-in.png"}}, | |||
| {"type":"AudioRecordQueue","data":{"defaults":{"name":{"value":"new"}},"shortName":"queue","inputs":1,"outputs":0,"category":"record-function","color":"#E6E0F8","icon":"arrow-in.png"}}, | |||
| {"type":"AudioSynthWaveformSine","data":{"defaults":{"name":{"value":"new"}},"shortName":"sine","inputs":0,"outputs":1,"category":"synth-function","color":"#E6E0F8","icon":"arrow-in.png"}}, | |||
| {"type":"AudioSynthWaveformSineModulated","data":{"defaults":{"name":{"value":"new"}},"shortName":"sine_fm","inputs":1,"outputs":1,"category":"synth-function","color":"#E6E0F8","icon":"arrow-in.png"}}, | |||
| {"type":"AudioSynthWaveform","data":{"defaults":{"name":{"value":"new"}},"shortName":"waveform","inputs":0,"outputs":1,"category":"synth-function","color":"#E6E0F8","icon":"arrow-in.png"}}, | |||
| {"type":"AudioSynthToneSweep","data":{"defaults":{"name":{"value":"new"}},"shortName":"tonesweep","inputs":0,"outputs":1,"category":"synth-function","color":"#E6E0F8","icon":"arrow-in.png"}}, | |||
| {"type":"AudioSynthWaveformDc","data":{"defaults":{"name":{"value":"new"}},"shortName":"dc","inputs":0,"outputs":1,"category":"synth-function","color":"#E6E0F8","icon":"arrow-in.png"}}, | |||
| {"type":"AudioSynthNoiseWhite","data":{"defaults":{"name":{"value":"new"}},"shortName":"noise","inputs":0,"outputs":1,"category":"synth-function","color":"#E6E0F8","icon":"arrow-in.png"}}, | |||
| {"type":"AudioSynthNoisePink","data":{"defaults":{"name":{"value":"new"}},"shortName":"pink","inputs":0,"outputs":1,"category":"synth-function","color":"#E6E0F8","icon":"arrow-in.png"}}, | |||
| {"type":"AudioEffectFade","data":{"defaults":{"name":{"value":"new"}},"shortName":"fade","inputs":1,"outputs":1,"category":"effect-function","color":"#E6E0F8","icon":"arrow-in.png"}}, | |||
| {"type":"AudioEffectChorus","data":{"defaults":{"name":{"value":"new"}},"shortName":"chorus","inputs":1,"outputs":1,"category":"effect-function","color":"#E6E0F8","icon":"arrow-in.png"}}, | |||
| {"type":"AudioEffectFlange","data":{"defaults":{"name":{"value":"new"}},"shortName":"flange","inputs":1,"outputs":1,"category":"effect-function","color":"#E6E0F8","icon":"arrow-in.png"}}, | |||
| {"type":"AudioEffectEnvelope","data":{"defaults":{"name":{"value":"new"}},"shortName":"envelope","inputs":1,"outputs":1,"category":"effect-function","color":"#E6E0F8","icon":"arrow-in.png"}}, | |||
| {"type":"AudioEffectMultiply","data":{"defaults":{"name":{"value":"new"}},"shortName":"multiply","inputs":2,"outputs":1,"category":"effect-function","color":"#E6E0F8","icon":"arrow-in.png"}}, | |||
| {"type":"AudioEffectDelay","data":{"defaults":{"name":{"value":"new"}},"shortName":"delay","inputs":1,"outputs":8,"category":"effect-function","color":"#E6E0F8","icon":"arrow-in.png"}}, | |||
| {"type":"AudioEffectDelayExternal","data":{"defaults":{"name":{"value":"new"}},"shortName":"delayExt","inputs":1,"outputs":8,"category":"effect-function","color":"#E6E0F8","icon":"arrow-in.png"}}, | |||
| {"type":"AudioEffectBitcrusher","data":{"shortName":"bitcrusher","inputs":1,"outputs":1,"category":"effect-function","color":"#E6E0F8","icon":"arrow-in.png"}}, | |||
| {"type":"AudioFilterBiquad","data":{"defaults":{"name":{"value":"new"}},"shortName":"biquad","inputs":1,"outputs":1,"category":"filter-function","color":"#E6E0F8","icon":"arrow-in.png"}}, | |||
| {"type":"AudioFilterFIR","data":{"defaults":{"name":{"value":"new"}},"shortName":"fir","inputs":1,"outputs":1,"category":"filter-function","color":"#E6E0F8","icon":"arrow-in.png"}}, | |||
| {"type":"AudioFilterStateVariable","data":{"defaults":{"name":{"value":"new"}},"shortName":"filter","inputs":2,"outputs":3,"category":"filter-function","color":"#E6E0F8","icon":"arrow-in.png"}}, | |||
| {"type":"AudioAnalyzePeak","data":{"defaults":{"name":{"value":"new"}},"shortName":"peak","inputs":1,"outputs":0,"category":"analyze-function","color":"#E6E0F8","icon":"arrow-in.png"}}, | |||
| {"type":"AudioAnalyzeFFT256","data":{"defaults":{"name":{"value":"new"}},"shortName":"fft256","inputs":1,"outputs":0,"category":"analyze-function","color":"#E6E0F8","icon":"arrow-in.png"}}, | |||
| {"type":"AudioAnalyzeFFT1024","data":{"defaults":{"name":{"value":"new"}},"shortName":"fft1024","inputs":1,"outputs":0,"category":"analyze-function","color":"#E6E0F8","icon":"arrow-in.png"}}, | |||
| {"type":"AudioAnalyzeToneDetect","data":{"defaults":{"name":{"value":"new"}},"shortName":"tone","inputs":1,"outputs":0,"category":"analyze-function","color":"#E6E0F8","icon":"arrow-in.png"}}, | |||
| {"type":"AudioAnalyzePrint","data":{"defaults":{"name":{"value":"new"}},"shortName":"print","inputs":1,"outputs":0,"category":"analyze-function","color":"#E6E0F8","icon":"arrow-in.png"}}, | |||
| {"type":"AudioControlSGTL5000","data":{"defaults":{"name":{"value":"new"}},"shortName":"sgtl5000","inputs":0,"outputs":0,"category":"control-function","color":"#E6E0F8","icon":"arrow-in.png"}}, | |||
| {"type":"AudioControlWM8731","data":{"defaults":{"name":{"value":"new"}},"shortName":"wm8731","inputs":0,"outputs":0,"category":"control-function","color":"#E6E0F8","icon":"arrow-in.png"}}, | |||
| {"type":"AudioControlWM8731master","data":{"defaults":{"name":{"value":"new"}},"shortName":"wm8731m","inputs":0,"outputs":0,"category":"control-function","color":"#E6E0F8","icon":"arrow-in.png"}} | |||
| ]} | |||
| </script> | |||
| <script type="text/x-red" data-help-name="AudioInputI2S"> | |||
| <h3>Summary</h3> | |||
| <p>Receive 16 bit stereo audio from the | |||
| @@ -387,7 +433,7 @@ span.mainfunction {color: #993300; font-weight: bolder} | |||
| </p> | |||
| <p>I2S master objects can be used together with non-I2S input and output | |||
| objects, for simultaneous audio streaming on different hardware.</p> | |||
| </script> | |||
| </script>< | |||
| <script type="text/x-red" data-template-name="AudioInputI2S"> | |||
| <div class="form-row"> | |||
| <label for="node-input-name"><i class="fa fa-tag"></i> Name</label> | |||
| @@ -182,7 +182,7 @@ var RED = (function() { | |||
| // if the query string has ?info=className, populate info tab | |||
| var info = getQueryVariable("info"); | |||
| if (info) { | |||
| RED.sidebar.info.setHelpContent('', info); | |||
| RED.sidebar.info.setHelpContent('', info); | |||
| } | |||
| } | |||
| @@ -215,20 +215,39 @@ var RED = (function() { | |||
| $(function() { | |||
| $(".palette-spinner").show(); | |||
| $.ajaxSetup({beforeSend: function(xhr){ | |||
| if (xhr.overrideMimeType) { | |||
| xhr.overrideMimeType("application/json"); | |||
| } | |||
| }}); | |||
| $.getJSON( "resources/nodes_def.json", function( data ) { | |||
| // server test switched off - test purposes only | |||
| var patt = new RegExp(/^[http|https]/); | |||
| var server = false && patt.test(location.protocol); | |||
| if (!server) { | |||
| var data = $.parseJSON($("script[data-container-name|='NodeDefinitions']").html()); | |||
| var nodes = data["nodes"]; | |||
| $.each(nodes, function(key, val) { | |||
| $.each(nodes, function (key, val) { | |||
| RED.nodes.registerType(val["type"], val["data"]); | |||
| }); | |||
| RED.keyboard.add(/* ? */ 191,{shift:true},function(){showHelp();d3.event.preventDefault();}); | |||
| loadNodes(); | |||
| RED.keyboard.add(/* ? */ 191, {shift: true}, function () { | |||
| showHelp(); | |||
| d3.event.preventDefault(); | |||
| }); | |||
| loadNodes(); | |||
| $(".palette-spinner").hide(); | |||
| }) | |||
| } else { | |||
| $.ajaxSetup({beforeSend: function(xhr){ | |||
| if (xhr.overrideMimeType) { | |||
| xhr.overrideMimeType("application/json"); | |||
| } | |||
| }}); | |||
| $.getJSON( "resources/nodes_def.json", function( data ) { | |||
| var nodes = data["nodes"]; | |||
| $.each(nodes, function(key, val) { | |||
| RED.nodes.registerType(val["type"], val["data"]); | |||
| }); | |||
| RED.keyboard.add(/* ? */ 191,{shift:true},function(){showHelp();d3.event.preventDefault();}); | |||
| loadNodes(); | |||
| $(".palette-spinner").hide(); | |||
| }) | |||
| } | |||
| }); | |||
| return { | |||
| @@ -317,17 +317,23 @@ RED.nodes = (function() { | |||
| */ | |||
| function cppToJSON(newNodesStr) { | |||
| var nodes = []; | |||
| var newNodes = []; | |||
| var skipped = []; | |||
| var cables = []; | |||
| var words = []; | |||
| const CODE_START = "// GUItool: begin automatically generated code"; | |||
| const CODE_END = "// GUItool: end automatically generated code"; | |||
| const NODE_COMMENT = "//"; | |||
| const NODE_AC = "AudioConnection"; | |||
| var parseLine = function(line) { | |||
| var parts = line.match(/^(\S+)\s(.*)/).slice(1); | |||
| var parts = line.match(/^(\S+)\s(.*)/); | |||
| if (parts == null) { | |||
| return | |||
| } | |||
| parts = parts.slice(1); | |||
| if (parts == null || parts.length <= 1) { | |||
| return | |||
| } | |||
| var type = $.trim(parts[0]); | |||
| line = $.trim(parts[1]) + " "; | |||
| @@ -336,52 +342,50 @@ RED.nodes = (function() { | |||
| var conn = []; | |||
| parts = line.match(/^([^;]{0,});(.*)/); | |||
| if (parts) { | |||
| if (parts && parts.length >= 2) { | |||
| parts = parts.slice(1); | |||
| description = $.trim(parts[0]); | |||
| coords = $.trim(parts[1]); | |||
| parts = coords.match(/^([^\/]{0,})\/\/xy=(.*)/); | |||
| if (parts) { | |||
| parts = parts.slice(1); | |||
| coords = $.trim(parts[1]).split(","); | |||
| if (parts && parts.length >= 1) { | |||
| description = $.trim(parts[0]); | |||
| coords = $.trim(parts[1]); | |||
| parts = coords.match(/^([^\/]{0,})\/\/xy=(.*)/); | |||
| if (parts) { | |||
| parts = parts.slice(1); | |||
| coords = $.trim(parts[1]).split(","); | |||
| } | |||
| } | |||
| } | |||
| switch (type) { | |||
| case NODE_AC: | |||
| parts = description.match(/^([^\(]*\()([^\)]*)(.*)/); | |||
| if (parts) { | |||
| conn = $.trim(parts[2]).split(","); | |||
| cables.push(conn); | |||
| } | |||
| break; | |||
| case NODE_COMMENT: | |||
| // do nothing ... | |||
| break; | |||
| default: | |||
| var node = new Object({ | |||
| "id": description, | |||
| "type": type, | |||
| "x": parseInt(coords ? coords[0] : 0), | |||
| "y": parseInt(coords ? coords[1] : 0), | |||
| "z": 0, | |||
| "wires": [] | |||
| }); | |||
| // first solution: skip existing id | |||
| if (!RED.nodes.node(node.id)) { | |||
| nodes.push(node); | |||
| } else { | |||
| skipped.push(node.id); | |||
| } | |||
| break; | |||
| if (type == NODE_AC) { | |||
| parts = description.match(/^([^\(]*\()([^\)]*)(.*)/); | |||
| if (parts && parts.length > 1) { | |||
| conn = $.trim(parts[2]).split(","); | |||
| cables.push(conn); | |||
| } | |||
| } else if (type == NODE_COMMENT) { | |||
| // do nothing | |||
| } else { | |||
| var node = new Object({ | |||
| "id": description, | |||
| "type": type, | |||
| "x": parseInt(coords ? coords[0] : 0), | |||
| "y": parseInt(coords ? coords[1] : 0), | |||
| "z": 0, | |||
| "wires": [] | |||
| }); | |||
| // first solution: skip existing id | |||
| if (RED.nodes.node(node.id) !== null) { | |||
| skipped.push(node.id); | |||
| } else { | |||
| newNodes.push(node); | |||
| } | |||
| } | |||
| }; | |||
| var findNode = function(name) { | |||
| var len = nodes.length; | |||
| var len = newNodes.length; | |||
| for (var key = 0; key < len; key++) { | |||
| if (nodes[key].id == name) { | |||
| return nodes[key]; | |||
| if (newNodes[key].id == name) { | |||
| return newNodes[key]; | |||
| } | |||
| } | |||
| }; | |||
| @@ -414,15 +418,16 @@ RED.nodes = (function() { | |||
| var traverseLines = function(raw) { | |||
| var lines = raw.split("\n"); | |||
| var useLine = 0; | |||
| for (var i = 0; i < lines.length; i++) { | |||
| var line = lines[i]; | |||
| useLine += (line.indexOf(CODE_START) >= 0) ? (useLine ? 0 : 1) : 0; | |||
| if (useLine > 0) { | |||
| var parts = line.match(/^(\S+)\s(.*)/); | |||
| if (parts == null || parts.length == 1) { | |||
| continue; | |||
| } | |||
| var word = parts[1].trim(); | |||
| if (words.indexOf(word) >= 0) { | |||
| parseLine(line); | |||
| } | |||
| useLine -= (line.indexOf(CODE_END) >= 0) ? (useLine ? 1 : 0) : 0; | |||
| } | |||
| }; | |||
| @@ -446,14 +451,21 @@ RED.nodes = (function() { | |||
| } | |||
| }; | |||
| */ | |||
| function startImport() { | |||
| words = Array(NODE_AC); | |||
| $.each(node_defs, function (key, obj) { | |||
| words.push(key); | |||
| }); | |||
| traverseLines(newNodesStr); | |||
| linkCables(cables); | |||
| } | |||
| traverseLines(newNodesStr); | |||
| linkCables(cables); | |||
| startImport(); | |||
| return { | |||
| count: nodes.length, | |||
| count: newNodes.length, | |||
| skipped: skipped.length, | |||
| data: nodes.length > 0 ? JSON.stringify(nodes) : "" | |||
| data: newNodes.length > 0 ? JSON.stringify(newNodes) : "" | |||
| }; | |||
| } | |||
| @@ -30,7 +30,6 @@ RED.view = (function() { | |||
| moveTouchCenter = [], | |||
| touchStartTime = 0; | |||
| var activeWorkspace = 0; | |||
| var workspaceScrollPositions = {}; | |||
| @@ -191,38 +190,39 @@ RED.view = (function() { | |||
| .attr('height', space_height) | |||
| .attr('fill','#fff'); | |||
| //var gridScale = d3.scale.linear().range([0,2000]).domain([0,2000]); | |||
| //var grid = vis.append('g'); | |||
| // | |||
| //grid.selectAll("line.horizontal").data(gridScale.ticks(100)).enter() | |||
| // .append("line") | |||
| // .attr( | |||
| // { | |||
| // "class":"horizontal", | |||
| // "x1" : 0, | |||
| // "x2" : 2000, | |||
| // "y1" : function(d){ return gridScale(d);}, | |||
| // "y2" : function(d){ return gridScale(d);}, | |||
| // "fill" : "none", | |||
| // "shape-rendering" : "crispEdges", | |||
| // "stroke" : "#eee", | |||
| // "stroke-width" : "1px" | |||
| // }); | |||
| //grid.selectAll("line.vertical").data(gridScale.ticks(100)).enter() | |||
| // .append("line") | |||
| // .attr( | |||
| // { | |||
| // "class":"vertical", | |||
| // "y1" : 0, | |||
| // "y2" : 2000, | |||
| // "x1" : function(d){ return gridScale(d);}, | |||
| // "x2" : function(d){ return gridScale(d);}, | |||
| // "fill" : "none", | |||
| // "shape-rendering" : "crispEdges", | |||
| // "stroke" : "#eee", | |||
| // "stroke-width" : "1px" | |||
| // }); | |||
| var gridScale = d3.scale.linear().range([0,2000]).domain([0,2000]); | |||
| /* | |||
| var grid = vis.append('g'); | |||
| grid.selectAll("line.horizontal").data(gridScale.ticks(100)).enter() | |||
| .append("line") | |||
| .attr( | |||
| { | |||
| "class":"horizontal", | |||
| "x1" : 0, | |||
| "x2" : 2000, | |||
| "y1" : function(d){ return gridScale(d);}, | |||
| "y2" : function(d){ return gridScale(d);}, | |||
| "fill" : "none", | |||
| "shape-rendering" : "crispEdges", | |||
| "stroke" : "#eee", | |||
| "stroke-width" : "1px" | |||
| }); | |||
| grid.selectAll("line.vertical").data(gridScale.ticks(100)).enter() | |||
| .append("line") | |||
| .attr( | |||
| { | |||
| "class":"vertical", | |||
| "y1" : 0, | |||
| "y2" : 2000, | |||
| "x1" : function(d){ return gridScale(d);}, | |||
| "x2" : function(d){ return gridScale(d);}, | |||
| "fill" : "none", | |||
| "shape-rendering" : "crispEdges", | |||
| "stroke" : "#eee", | |||
| "stroke-width" : "1px" | |||
| }); | |||
| */ | |||
| var drag_line = vis.append("svg:path").attr("class", "drag_line"); | |||
| @@ -788,7 +788,6 @@ RED.view = (function() { | |||
| } | |||
| } | |||
| function calculateTextWidth(str) { | |||
| var sp = document.createElement("span"); | |||
| sp.className = "node_label"; | |||
| @@ -1453,7 +1452,12 @@ RED.view = (function() { | |||
| } | |||
| } | |||
| function arrangeAll() { | |||
| // TODO: arange all nodes optimized without collision | |||
| } | |||
| RED.keyboard.add(/* z */ 90,{ctrl:true},function(){RED.history.pop();}); | |||
| RED.keyboard.add(/* o */ 79,{ctrl:true},function(){arrangeAll();d3.event.preventDefault();}); | |||
| RED.keyboard.add(/* a */ 65,{ctrl:true},function(){selectAll();d3.event.preventDefault();}); | |||
| RED.keyboard.add(/* = */ 187,{ctrl:true},function(){zoomIn();d3.event.preventDefault();}); | |||
| RED.keyboard.add(/* - */ 189,{ctrl:true},function(){zoomOut();d3.event.preventDefault();}); | |||
| @@ -1485,7 +1489,7 @@ RED.view = (function() { | |||
| var useStorage = false; | |||
| if ($("#node-input-arduino").prop('checked') === true) { | |||
| nodesJSON = RED.nodes.cppToJSON(newNodesStr); | |||
| var nodesJSON = RED.nodes.cppToJSON(newNodesStr); | |||
| if (nodesJSON.count <= 0 || nodesJSON.skipped > 0) { | |||
| var note = "No (or not all) nodes imported, because some IDs existed already!"; | |||
| RED.notify("<strong>Note</strong>: " + note, "warning"); | |||
| @@ -1495,12 +1499,12 @@ RED.view = (function() { | |||
| createNewIds = false; | |||
| if (useStorage) { | |||
| RED.storage.clear(); | |||
| localStorage.setItem("audio_library_guitool", newNodesStr); | |||
| RED.storage.load(); | |||
| redraw(); | |||
| return; | |||
| } | |||
| RED.storage.clear(); | |||
| localStorage.setItem("audio_library_guitool", newNodesStr); | |||
| RED.storage.load(); | |||
| redraw(); | |||
| return; | |||
| } | |||
| } | |||
| try { | |||