- fixed: clear selected nodes, works with several or all selected nodes (reason: two counting variables with the same name "i" where used in two nested loops) - new: change node names (you can assign names to the nodes, these will be used as IDs if exported or re-imported to CPP (Arduino code) - fixed: import merges imported nodes to existings ones, skipping nodes with the same name - fixed: tooltips are now working, extracting the first paragraph of the HTML code - new: nodes definition extracted to JSON file - new: nodes help pages extracted to single HTML files - new: form pages extracted to single HTML files - new: asynchronous loading of JSON, help and form data, data will only be loaded when needed - style: adapted the size of the palette, labels had been partially hiddendds
if (node && (node.outputs > 0 || node._def.inputs > 0)) { | if (node && (node.outputs > 0 || node._def.inputs > 0)) { | ||||
cpp += n.type + " "; | cpp += n.type + " "; | ||||
for (var j=n.type.length; j<24; j++) cpp += " "; | for (var j=n.type.length; j<24; j++) cpp += " "; | ||||
cpp += n.id + "; "; | |||||
var name = (n.name ? n.name : n.id); | |||||
name = name.replace(" ", "_").replace("+", "_").replace("-", "_"); | |||||
cpp += name + "; "; | |||||
for (var j=n.id.length; j<14; j++) cpp += " "; | for (var j=n.id.length; j<14; j++) cpp += " "; | ||||
cpp += "//xy=" + n.x + "," + n.y + "\n"; | cpp += "//xy=" + n.x + "," + n.y + "\n"; | ||||
} | } | ||||
//console.log(cpp); | //console.log(cpp); | ||||
RED.view.state(RED.state.EXPORT); | RED.view.state(RED.state.EXPORT); | ||||
$("#dialog-form").html($("script[data-template-name='export-clipboard-dialog']").html()); | |||||
$("#node-input-export").val(cpp); | |||||
$("#node-input-export").focus(function() { | |||||
RED.view.getForm('dialog-form', 'export-clipboard-dialog', function (d, f) { | |||||
$("#node-input-export").val(cpp).focus(function() { | |||||
var textarea = $(this); | var textarea = $(this); | ||||
textarea.select(); | textarea.select(); | ||||
textarea.mouseup(function() { | textarea.mouseup(function() { | ||||
textarea.unbind("mouseup"); | textarea.unbind("mouseup"); | ||||
return false; | return false; | ||||
}); | }); | ||||
}); | |||||
}).focus(); | |||||
$( "#dialog" ).dialog("option","title","Export to Arduino").dialog( "open" ); | $( "#dialog" ).dialog("option","title","Export to Arduino").dialog( "open" ); | ||||
$("#node-input-export").focus(); | |||||
}); | |||||
//RED.view.dirty(false); | //RED.view.dirty(false); | ||||
} | } | ||||
} | } | ||||
} | } | ||||
function loadNodes() { | function loadNodes() { | ||||
//$.get('list.html', function(data) { | |||||
//$("body").append(data); | |||||
//setTimeout(function() { | |||||
$(".palette-spinner").hide(); | |||||
$(".palette-scroll").show(); | $(".palette-scroll").show(); | ||||
$("#palette-search").show(); | $("#palette-search").show(); | ||||
RED.storage.load(); | RED.storage.load(); | ||||
// if the query string has ?info=className, populate info tab | // if the query string has ?info=className, populate info tab | ||||
var info = getQueryVariable("info"); | var info = getQueryVariable("info"); | ||||
if (info) { | if (info) { | ||||
$("#tab-info").html('<div class="node-help">' | |||||
+($("script[data-help-name|='"+info+"']").html()||"")+"</div>"); | |||||
RED.sidebar.info.setHelpContent('', info); | |||||
} | } | ||||
//}, 100); | |||||
//}, "html"); | |||||
} | } | ||||
$('#btn-node-status').click(function() {toggleStatus();}); | $('#btn-node-status').click(function() {toggleStatus();}); | ||||
} | } | ||||
$(function() { | $(function() { | ||||
$(".palette-spinner").show(); | |||||
$.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();}); | RED.keyboard.add(/* ? */ 191,{shift:true},function(){showHelp();d3.event.preventDefault();}); | ||||
loadNodes(); | loadNodes(); | ||||
$(".palette-spinner").hide(); | |||||
}) | |||||
}); | }); | ||||
return { | return { |
var nodes = []; | var nodes = []; | ||||
var configNodes = {}; | var configNodes = {}; | ||||
var links = []; | var links = []; | ||||
var defaultWorkspace; | |||||
//var defaultWorkspace; | |||||
var workspaces = {}; | var workspaces = {}; | ||||
function registerType(nt,def) { | function registerType(nt,def) { | ||||
if (n._def.defaults.hasOwnProperty(d)) { | if (n._def.defaults.hasOwnProperty(d)) { | ||||
var property = n._def.defaults[d]; | var property = n._def.defaults[d]; | ||||
if (property.type) { | if (property.type) { | ||||
var type = getType(property.type) | |||||
var type = getType(property.type); | |||||
if (type && type.category == "config") { | if (type && type.category == "config") { | ||||
var configNode = configNodes[n[d]]; | var configNode = configNodes[n[d]]; | ||||
if (configNode) { | if (configNode) { | ||||
function addLink(l) { | function addLink(l) { | ||||
links.push(l); | links.push(l); | ||||
} | } | ||||
/* | |||||
function addConfig(c) { | function addConfig(c) { | ||||
configNodes[c.id] = c; | configNodes[c.id] = c; | ||||
} | } | ||||
*/ | |||||
function getNode(id) { | function getNode(id) { | ||||
if (id in configNodes) { | if (id in configNodes) { | ||||
if (node._def.defaults.hasOwnProperty(d)) { | if (node._def.defaults.hasOwnProperty(d)) { | ||||
var property = node._def.defaults[d]; | var property = node._def.defaults[d]; | ||||
if (property.type) { | if (property.type) { | ||||
var type = getType(property.type) | |||||
var type = getType(property.type); | |||||
if (type && type.category == "config") { | if (type && type.category == "config") { | ||||
var configNode = configNodes[node[d]]; | var configNode = configNodes[node[d]]; | ||||
if (configNode) { | if (configNode) { | ||||
*/ | */ | ||||
function cppToJSON(newNodesStr) { | function cppToJSON(newNodesStr) { | ||||
var data = ""; | |||||
var nodes = []; | var nodes = []; | ||||
var skipped = []; | |||||
var cables = []; | var cables = []; | ||||
const CODE_START = "// GUItool: begin automatically generated code"; | const CODE_START = "// GUItool: begin automatically generated code"; | ||||
const CODE_END = "// GUItool: end automatically generated code"; | const CODE_END = "// GUItool: end automatically generated code"; | ||||
const NODE_COMMENT = "//"; | const NODE_COMMENT = "//"; | ||||
const NODE_AC = "AudioConnection"; | const NODE_AC = "AudioConnection"; | ||||
const NODE_AI_I2S = "AudioInputI2S"; | |||||
const NODE_AM_4 = "AudioMixer4"; | |||||
const NODE_AC_SGTL = "AudioControlSGTL5000"; | |||||
var parseLine = function(line) { | var parseLine = function(line) { | ||||
var parts = line.match(/^(\S+)\s(.*)/).slice(1); | var parts = line.match(/^(\S+)\s(.*)/).slice(1); | ||||
"z": 0, | "z": 0, | ||||
"wires": [] | "wires": [] | ||||
}); | }); | ||||
// first solution: skip existing id | |||||
if (!RED.nodes.node(node.id)) { | |||||
nodes.push(node); | nodes.push(node); | ||||
} else { | |||||
skipped.push(node.id); | |||||
} | |||||
break; | break; | ||||
} | } | ||||
}; | }; | ||||
} | } | ||||
}; | }; | ||||
/* | |||||
var readCode = function() { | var readCode = function() { | ||||
var fileImport = $("#importInput")[0]; | var fileImport = $("#importInput")[0]; | ||||
alert("Please upload a valid INO or text file."); | alert("Please upload a valid INO or text file."); | ||||
} | } | ||||
}; | }; | ||||
*/ | |||||
traverseLines(newNodesStr); | traverseLines(newNodesStr); | ||||
linkCables(cables); | linkCables(cables); | ||||
return JSON.stringify(nodes); | |||||
return { | |||||
count: nodes.length, | |||||
skipped: skipped.length, | |||||
data: count > 0 ? JSON.stringify(nodes) : "" | |||||
}; | |||||
} | } | ||||
function importNodes(newNodesObj,createNewIds) { | function importNodes(newNodesObj,createNewIds) { |
$("#"+prefix+"-"+d).change(); | $("#"+prefix+"-"+d).change(); | ||||
} | } | ||||
} | } | ||||
} | |||||
}; | |||||
if (definition.credentials) { | if (definition.credentials) { | ||||
if (node.credentials) { | if (node.credentials) { | ||||
function showEditDialog(node) { | function showEditDialog(node) { | ||||
editing_node = node; | editing_node = node; | ||||
RED.view.state(RED.state.EDITING); | RED.view.state(RED.state.EDITING); | ||||
$("#dialog-form").html($("script[data-template-name='"+node.type+"']").html()); | |||||
prepareEditDialog(node,node._def,"node-input"); | |||||
$( "#dialog" ).dialog("option","title","Edit "+node.type+" node").dialog( "open" ); | |||||
//$("#dialog-form").html(RED.view.getForm(node.type)); | |||||
RED.view.getForm("dialog-form", node.type, function (d, f) { | |||||
prepareEditDialog(node,node._def,"node-input"); | |||||
$( "#dialog" ).dialog("option","title","Edit "+node.type+" node").dialog( "open" ); | |||||
}); | |||||
} | } | ||||
function showEditConfigNodeDialog(name,type,id) { | function showEditConfigNodeDialog(name,type,id) { | ||||
id: (1+Math.random()*4294967295).toString(16), | id: (1+Math.random()*4294967295).toString(16), | ||||
_def: node_def, | _def: node_def, | ||||
type: type | type: type | ||||
} | |||||
}; | |||||
for (var d in node_def.defaults) { | for (var d in node_def.defaults) { | ||||
if (node_def.defaults[d].value) { | if (node_def.defaults[d].value) { | ||||
configNode[d] = node_def.defaults[d].value; | configNode[d] = node_def.defaults[d].value; | ||||
} | } | ||||
} | } | ||||
$("#dialog-config-form").html($("script[data-template-name='"+type+"']").html()); | |||||
//$("#dialog-config-form").html(RED.view.getForm(type)); | |||||
RED.view.getForm("dialog-config-form", type, function (d, f) { | |||||
prepareEditDialog(configNode,node_def,"node-config-input"); | prepareEditDialog(configNode,node_def,"node-config-input"); | ||||
var buttons = $( "#node-config-dialog" ).dialog("option","buttons"); | var buttons = $( "#node-config-dialog" ).dialog("option","buttons"); | ||||
.dialog("option","node-type",type) | .dialog("option","node-type",type) | ||||
.dialog("option","title",(adding?"Add new ":"Edit ")+type+" config node") | .dialog("option","title",(adding?"Add new ":"Edit ")+type+" config node") | ||||
.dialog( "open" ); | .dialog( "open" ); | ||||
}); | |||||
} | } | ||||
function updateConfigNodeSelect(name,type,value) { | function updateConfigNodeSelect(name,type,value) { |
} | } | ||||
$("#palette-"+def.category).append(d); | $("#palette-"+def.category).append(d); | ||||
d.onmousedown = function(e) { e.preventDefault(); } | |||||
d.onmousedown = function(e) { e.preventDefault(); }; | |||||
setTooltipContent('', nt, d); | |||||
$(d).popover({ | |||||
title:d.type, | |||||
placement:"right", | |||||
trigger: "hover", | |||||
delay: { show: 750, hide: 50 }, | |||||
html: true, | |||||
container:'body', | |||||
content: $(($("script[data-help-name|='"+nt+"']").html()||"<h2>empty</h2><p>no information available</p>").trim())[2] // TODO: how to use jQuery to always select the first <p> within the html? | |||||
}); | |||||
$(d).click(function() { | $(d).click(function() { | ||||
RED.nodes.selectNode(d.type); | RED.nodes.selectNode(d.type); | ||||
var help = '<div class="node-help">'+($("script[data-help-name|='"+d.type+"']").html()||"")+"</div>"; | |||||
$("#tab-info").html(help); | |||||
RED.sidebar.info.setHelpContent('', d.type); | |||||
}); | }); | ||||
$(d).draggable({ | $(d).draggable({ | ||||
helper: 'clone', | helper: 'clone', | ||||
$(this).next().slideToggle(); | $(this).next().slideToggle(); | ||||
$(this).children("i").toggleClass("expanded"); | $(this).children("i").toggleClass("expanded"); | ||||
}); | }); | ||||
} | } | ||||
} | } | ||||
function setTooltipContent(empty, key, elem) { | |||||
$.get( "resources/help/" + key + ".html", function( data ) { | |||||
var firstP = $("<div/>").append(data).children("p").first().html(); | |||||
$(elem).popover({ | |||||
title: elem.type, | |||||
placement: "right", | |||||
trigger: "hover", | |||||
delay: { show: 750, hide: 50 }, | |||||
html: true, | |||||
container:'body', | |||||
content: firstP | |||||
}); | |||||
}); | |||||
} | |||||
function removeNodeType(type) { | function removeNodeType(type) { | ||||
$("#palette_node_"+type).remove(); | $("#palette_node_"+type).remove(); |
} | } | ||||
} | } | ||||
table += "</tbody></table><br/>"; | table += "</tbody></table><br/>"; | ||||
table += '<div class="node-help">'+($("script[data-help-name|='"+node.type+"']").html()||"")+"</div>"; | |||||
$("#tab-info").html(table); | |||||
this.setHelpContent(table, node.type); | |||||
} | |||||
function setHelpContent(empty, key) { | |||||
$.get( "resources/help/" + key + ".html", function( data ) { | |||||
$("#tab-info").html(empty + '<div class="node-help">' + data + '</div>'); | |||||
}).fail(function () { | |||||
$("#tab-info").html(empty); | |||||
}); | |||||
} | } | ||||
return { | return { | ||||
refresh:refresh, | refresh:refresh, | ||||
clear: function() { | clear: function() { | ||||
$("#tab-info").html(""); | $("#tab-info").html(""); | ||||
} | |||||
}, | |||||
setHelpContent: setHelpContent | |||||
} | } | ||||
})(); | })(); |
"yellow": "#F9DF31", | "yellow": "#F9DF31", | ||||
"blue": "#53A3F3", | "blue": "#53A3F3", | ||||
"grey": "#d3d3d3" | "grey": "#d3d3d3" | ||||
} | |||||
}; | |||||
var outer = d3.select("#chart") | var outer = d3.select("#chart") | ||||
.append("svg:svg") | .append("svg:svg") | ||||
moveTouchCenter = [ | moveTouchCenter = [ | ||||
touch1['pageX']+(b/2), | touch1['pageX']+(b/2), | ||||
touch1['pageY']+(a/2) | touch1['pageY']+(a/2) | ||||
] | |||||
]; | |||||
startTouchDistance = Math.sqrt((a*a)+(b*b)); | startTouchDistance = Math.sqrt((a*a)+(b*b)); | ||||
} else { | } else { | ||||
var obj = d3.select(document.body); | var obj = d3.select(document.body); | ||||
nn.type = selected_tool; | nn.type = selected_tool; | ||||
nn._def = RED.nodes.getType(nn.type); | nn._def = RED.nodes.getType(nn.type); | ||||
nn.id = RED.nodes.cppName(nn); | nn.id = RED.nodes.cppName(nn); | ||||
nn._def.defaults = nn._def.defaults ? nn._def.defaults : {}; | |||||
nn._def.defaults.name = { value: nn.id }; | |||||
nn.outputs = nn._def.outputs; | nn.outputs = nn._def.outputs; | ||||
nn.changed = true; | nn.changed = true; | ||||
node.x = 25 | node.x = 25 | ||||
} | } | ||||
var rmlinks = RED.nodes.remove(node.id); | var rmlinks = RED.nodes.remove(node.id); | ||||
for (var i=0; i < rmlinks.length; i++) { | |||||
var link = rmlinks[i]; | |||||
for (var j=0; j < rmlinks.length; j++) { | |||||
var link = rmlinks[j]; | |||||
//console.log("delete link: " + link.source.id + ":" + link.sourcePort | //console.log("delete link: " + link.source.id + ":" + link.sourcePort | ||||
// + " -> " + link.target.id + ":" + link.targetPort); | // + " -> " + link.target.id + ":" + link.targetPort); | ||||
if (link.source == node) { | if (link.source == node) { | ||||
.on("mouseup", (function(d,n){return function(d){portMouseUp(d,1,n);}})(rect, n)) | .on("mouseup", (function(d,n){return function(d){portMouseUp(d,1,n);}})(rect, n)) | ||||
.on("touchend", (function(d,n){return function(d){portMouseUp(d,1,n);}})(rect, n)) | .on("touchend", (function(d,n){return function(d){portMouseUp(d,1,n);}})(rect, n)) | ||||
.on("mouseover",function(d) { var port = d3.select(this); port.classed("port_hovered",(mouse_mode!=RED.state.JOINING || mousedown_port_type != 1 ));}) | .on("mouseover",function(d) { var port = d3.select(this); port.classed("port_hovered",(mouse_mode!=RED.state.JOINING || mousedown_port_type != 1 ));}) | ||||
.on("mouseout",function(d) { var port = d3.select(this); port.classed("port_hovered",false);}) | |||||
.on("mouseout",function(d) { var port = d3.select(this); port.classed("port_hovered",false);}); | |||||
RED.nodes.removeLink(selected_link); | RED.nodes.removeLink(selected_link); | ||||
removedLinks.push(selected_link); | removedLinks.push(selected_link); | ||||
setDirty(true); | setDirty(true); | ||||
node.attr("id",d.id); | node.attr("id",d.id); | ||||
//var l = d._def.label; | //var l = d._def.label; | ||||
//l = (typeof l === "function" ? l.call(d) : l)||""; | //l = (typeof l === "function" ? l.call(d) : l)||""; | ||||
var l = d.id; | |||||
var l = d.name ? d.name : d.id; | |||||
d.w = Math.max(node_width,calculateTextWidth(l)+(d._def.inputs>0?7:0) ); | d.w = Math.max(node_width,calculateTextWidth(l)+(d._def.inputs>0?7:0) ); | ||||
d.h = Math.max(node_height,(Math.max(d.outputs,d._def.inputs)||0) * 15); | d.h = Math.max(node_height,(Math.max(d.outputs,d._def.inputs)||0) * 15); | ||||
if ("right" == d._def.align) { | if ("right" == d._def.align) { | ||||
icon_group.attr('class','node_icon_group node_icon_group_'+d._def.align); | icon_group.attr('class','node_icon_group node_icon_group_'+d._def.align); | ||||
icon_shade_border.attr("d",function(d) { return "M 0 1 l 0 "+(d.h-2)}) | |||||
icon_shade_border.attr("d",function(d) { return "M 0 1 l 0 "+(d.h-2)}); | |||||
//icon.attr('class','node_icon node_icon_'+d._def.align); | //icon.attr('class','node_icon node_icon_'+d._def.align); | ||||
//icon.attr('class','node_icon_shade node_icon_shade_'+d._def.align); | //icon.attr('class','node_icon_shade node_icon_shade_'+d._def.align); | ||||
//icon.attr('class','node_icon_shade_border node_icon_shade_border_'+d._def.align); | //icon.attr('class','node_icon_shade_border node_icon_shade_border_'+d._def.align); | ||||
// icon_shade.attr("x",function(d){return d.w-30}); | // icon_shade.attr("x",function(d){return d.w-30}); | ||||
// icon_shade_border.attr("d",function(d){return "M "+(d.w-30)+" 1 l 0 "+(d.h-2);}); | // icon_shade_border.attr("d",function(d){return "M "+(d.w-30)+" 1 l 0 "+(d.h-2);}); | ||||
//} | //} | ||||
} | |||||
}; | |||||
//icon.style("pointer-events","none"); | //icon.style("pointer-events","none"); | ||||
icon_group.style("pointer-events","none"); | icon_group.style("pointer-events","none"); | ||||
if (d.resize) { | if (d.resize) { | ||||
//var l = d._def.label; | //var l = d._def.label; | ||||
//l = (typeof l === "function" ? l.call(d) : l)||""; | //l = (typeof l === "function" ? l.call(d) : l)||""; | ||||
var l = d.id; | |||||
var l = d.name ? d.name : d.id; | |||||
d.w = Math.max(node_width,calculateTextWidth(l)+(d._def.inputs>0?7:0) ); | d.w = Math.max(node_width,calculateTextWidth(l)+(d._def.inputs>0?7:0) ); | ||||
d.h = Math.max(node_height,(Math.max(d.outputs,d._def.inputs)||0) * 15); | d.h = Math.max(node_height,(Math.max(d.outputs,d._def.inputs)||0) * 15); | ||||
} | } | ||||
return d._def.label; | return d._def.label; | ||||
} | } | ||||
} | } | ||||
return ""; */ | |||||
return d.id; | |||||
return "n.a."; | |||||
*/ | |||||
return d.name ? d.name : d.id; | |||||
}) | }) | ||||
.attr('y', function(d){return (d.h/2)-1;}) | .attr('y', function(d){return (d.h/2)-1;}) | ||||
.attr('class',function(d){ | .attr('class',function(d){ | ||||
} | } | ||||
} | } | ||||
return ""; */ | return ""; */ | ||||
return d.id; | |||||
return d.name ? d.name : d.id; | |||||
}); | }); | ||||
if (!showStatus || !d.status) { | if (!showStatus || !d.status) { | ||||
thisNode.selectAll('.node_status_group').style("display","none"); | thisNode.selectAll('.node_status_group').style("display","none"); | ||||
link.exit().remove(); | link.exit().remove(); | ||||
var links = vis.selectAll(".link_path") | |||||
var links = vis.selectAll(".link_path"); | |||||
links.attr("d",function(d){ | links.attr("d",function(d){ | ||||
var numOutputs = d.source.outputs || 1; | var numOutputs = d.source.outputs || 1; | ||||
var sourcePort = d.sourcePort || 0; | var sourcePort = d.sourcePort || 0; | ||||
" C "+(d.x1+scale*node_width)+" "+(d.y1+scaleY*node_height)+" "+ | " C "+(d.x1+scale*node_width)+" "+(d.y1+scaleY*node_height)+" "+ | ||||
(d.x2-scale*node_width)+" "+(d.y2-scaleY*node_height)+" "+ | (d.x2-scale*node_width)+" "+(d.y2-scaleY*node_height)+" "+ | ||||
(d.x2)+" "+d.y2; | (d.x2)+" "+d.y2; | ||||
}) | |||||
}); | |||||
link.classed("link_selected", function(d) { return d === selected_link || d.selected; }); | link.classed("link_selected", function(d) { return d === selected_link || d.selected; }); | ||||
link.classed("link_unknown",function(d) { return d.target.type == "unknown" || d.source.type == "unknown"}); | link.classed("link_unknown",function(d) { return d.target.type == "unknown" || d.source.type == "unknown"}); | ||||
function importNodes(newNodesStr,touchImport) { | function importNodes(newNodesStr,touchImport) { | ||||
var createNewIds = true; | var createNewIds = true; | ||||
// TODO: solve this more elegant as the system expects | |||||
var useStorage = false; | |||||
if ($("#node-input-arduino").prop('checked') === true) { | if ($("#node-input-arduino").prop('checked') === true) { | ||||
newNodesStr = RED.nodes.cppToJSON(newNodesStr); | |||||
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"); | |||||
} | |||||
newNodesStr = nodesJSON.data; | |||||
createNewIds = false; | createNewIds = false; | ||||
if (useStorage) { | |||||
RED.storage.clear(); | RED.storage.clear(); | ||||
localStorage.setItem("audio_library_guitool", newNodesStr); | localStorage.setItem("audio_library_guitool", newNodesStr); | ||||
RED.storage.load(); | RED.storage.load(); | ||||
redraw(); | redraw(); | ||||
return; | return; | ||||
} | } | ||||
} | |||||
try { | try { | ||||
var result = RED.nodes.import(newNodesStr,createNewIds); | var result = RED.nodes.import(newNodesStr,createNewIds); | ||||
function showExportNodesDialog() { | function showExportNodesDialog() { | ||||
mouse_mode = RED.state.EXPORT; | mouse_mode = RED.state.EXPORT; | ||||
var nns = RED.nodes.createExportableNodeSet(moving_set); | var nns = RED.nodes.createExportableNodeSet(moving_set); | ||||
$("#dialog-form").html($("script[data-template-name='export-clipboard-dialog']").html()); | |||||
$("#node-input-export").val(JSON.stringify(nns)); | |||||
$("#node-input-export").focus(function() { | |||||
//$("#dialog-form").html(getForm("dialog-form", "export-clipboard-dialog")); | |||||
var frm = getForm("dialog-form", "export-clipboard-dialog", function (d, f) { | |||||
$("#node-input-export").val(JSON.stringify(nns)).focus(function() { | |||||
var textarea = $(this); | var textarea = $(this); | ||||
textarea.select(); | textarea.select(); | ||||
textarea.mouseup(function() { | textarea.mouseup(function() { | ||||
textarea.unbind("mouseup"); | textarea.unbind("mouseup"); | ||||
return false; | return false; | ||||
}); | }); | ||||
}); | |||||
}).focus(); | |||||
$( "#dialog" ).dialog("option","title","Export nodes to clipboard").dialog( "open" ); | $( "#dialog" ).dialog("option","title","Export nodes to clipboard").dialog( "open" ); | ||||
$("#node-input-export").focus(); | |||||
}); | |||||
} | } | ||||
function showExportNodesLibraryDialog() { | function showExportNodesLibraryDialog() { | ||||
mouse_mode = RED.state.EXPORT; | mouse_mode = RED.state.EXPORT; | ||||
var nns = RED.nodes.createExportableNodeSet(moving_set); | var nns = RED.nodes.createExportableNodeSet(moving_set); | ||||
$("#dialog-form").html($("script[data-template-name='export-library-dialog']").html()); | |||||
//$("#dialog-form").html(this.getForm('export-library-dialog')); | |||||
getForm("dialog-form", "export-library-dialog", function(d, f) { | |||||
$("#node-input-filename").attr('nodes',JSON.stringify(nns)); | $("#node-input-filename").attr('nodes',JSON.stringify(nns)); | ||||
$( "#dialog" ).dialog("option","title","Export nodes to library").dialog( "open" ); | $( "#dialog" ).dialog("option","title","Export nodes to library").dialog( "open" ); | ||||
}); | |||||
} | } | ||||
function showImportNodesDialog() { | function showImportNodesDialog() { | ||||
mouse_mode = RED.state.IMPORT; | mouse_mode = RED.state.IMPORT; | ||||
$("#dialog-form").html($("script[data-template-name='import-dialog']").html()); | |||||
//$("#dialog-form").html(this.getForm('import-dialog')); | |||||
getForm("dialog-form", "import-dialog", function(d, f) { | |||||
$("#node-input-import").val(""); | $("#node-input-import").val(""); | ||||
$( "#dialog" ).dialog("option","title","Import nodes").dialog( "open" ); | $( "#dialog" ).dialog("option","title","Import nodes").dialog( "open" ); | ||||
}); | |||||
} | } | ||||
function showRenameWorkspaceDialog(id) { | function showRenameWorkspaceDialog(id) { | ||||
$( "#node-dialog-rename-workspace" ).dialog("open"); | $( "#node-dialog-rename-workspace" ).dialog("open"); | ||||
} | } | ||||
function getForm(formId, key, callback) { | |||||
var form = $("<h2>No form found.</h2>"); | |||||
var frmPlugin = "resources/form/" + key + ".html"; | |||||
$.get(frmPlugin, function(data) { | |||||
form = $("#" + formId); | |||||
$(form).empty(); | |||||
$(form).append(data); | |||||
if(typeof callback == 'function') { | |||||
callback.call(this, form); | |||||
} | |||||
}); | |||||
return form; | |||||
} | |||||
$("#node-dialog-rename-workspace form" ).submit(function(e) { e.preventDefault();}); | $("#node-dialog-rename-workspace form" ).submit(function(e) { e.preventDefault();}); | ||||
$( "#node-dialog-rename-workspace" ).dialog({ | $( "#node-dialog-rename-workspace" ).dialog({ | ||||
modal: true, | modal: true, | ||||
RED.nodes.eachNode(function(n) { n.dirty = true;}); | RED.nodes.eachNode(function(n) { n.dirty = true;}); | ||||
//TODO: subscribe/unsubscribe here | //TODO: subscribe/unsubscribe here | ||||
redraw(); | redraw(); | ||||
} | |||||
}, | |||||
getForm: getForm | |||||
}; | }; | ||||
})(); | })(); |
<div class="form-row"> | |||||
<label for="node-input-name"><i class="fa fa-tag"></i> Name</label> | |||||
<input type="text" id="node-input-name" placeholder="Name"> | |||||
</div> |
<div class="form-row"> | |||||
<label for="node-input-name"><i class="fa fa-tag"></i> Name</label> | |||||
<input type="text" id="node-input-name" placeholder="Name"> | |||||
</div> |
<div class="form-row"> | |||||
<label for="node-input-name"><i class="fa fa-tag"></i> Name</label> | |||||
<input type="text" id="node-input-name" placeholder="Name"> | |||||
</div> |
<div class="form-row"> | |||||
<label for="node-input-name"><i class="fa fa-tag"></i> Name</label> | |||||
<input type="text" id="node-input-name" placeholder="Name"> | |||||
</div> |
<div class="form-row"> | |||||
<label for="node-input-name"><i class="fa fa-tag"></i> Name</label> | |||||
<input type="text" id="node-input-name" placeholder="Name"> | |||||
</div> |
<div class="form-row"> | |||||
<label for="node-input-name"><i class="fa fa-tag"></i> Name</label> | |||||
<input type="text" id="node-input-name" placeholder="Name"> | |||||
</div> |
<div class="form-row"> | |||||
<label for="node-input-name"><i class="fa fa-tag"></i> Name</label> | |||||
<input type="text" id="node-input-name" placeholder="Name"> | |||||
</div> |
<div class="form-row"> | |||||
<label for="node-input-name"><i class="fa fa-tag"></i> Name</label> | |||||
<input type="text" id="node-input-name" placeholder="Name"> | |||||
</div> |
<div class="form-row"> | |||||
<label for="node-input-name"><i class="fa fa-tag"></i> Name</label> | |||||
<input type="text" id="node-input-name" placeholder="Name"> | |||||
</div> |
<div class="form-row"> | |||||
<label for="node-input-name"><i class="fa fa-tag"></i> Name</label> | |||||
<input type="text" id="node-input-name" placeholder="Name"> | |||||
</div> |
<div class="form-row"> | |||||
<label for="node-input-name"><i class="fa fa-tag"></i> Name</label> | |||||
<input type="text" id="node-input-name" placeholder="Name"> | |||||
</div> |
<div class="form-row"> | |||||
<label for="node-input-name"><i class="fa fa-tag"></i> Name</label> | |||||
<input type="text" id="node-input-name" placeholder="Name"> | |||||
</div> |
<div class="form-row"> | |||||
<label for="node-input-name"><i class="fa fa-tag"></i> Name</label> | |||||
<input type="text" id="node-input-name" placeholder="Name"> | |||||
</div> |
<div class="form-row"> | |||||
<label for="node-input-name"><i class="fa fa-tag"></i> Name</label> | |||||
<input type="text" id="node-input-name" placeholder="Name"> | |||||
</div> |
<div class="form-row"> | |||||
<label for="node-input-name"><i class="fa fa-tag"></i> Name</label> | |||||
<input type="text" id="node-input-name" placeholder="Name"> | |||||
</div> |
<div class="form-row"> | |||||
<label for="node-input-name"><i class="fa fa-tag"></i> Name</label> | |||||
<input type="text" id="node-input-name" placeholder="Name"> | |||||
</div> |
<div class="form-row"> | |||||
<label for="node-input-name"><i class="fa fa-tag"></i> Name</label> | |||||
<input type="text" id="node-input-name" placeholder="Name"> | |||||
</div> |
<div class="form-row"> | |||||
<label for="node-input-name"><i class="fa fa-tag"></i> Name</label> | |||||
<input type="text" id="node-input-name" placeholder="Name"> | |||||
</div> |
<div class="form-row"> | |||||
<label for="node-input-name"><i class="fa fa-tag"></i> Name</label> | |||||
<input type="text" id="node-input-name" placeholder="Name"> | |||||
</div> |
<div class="form-row"> | |||||
<label for="node-input-name"><i class="fa fa-tag"></i> Name</label> | |||||
<input type="text" id="node-input-name" placeholder="Name"> | |||||
</div> |
<div class="form-row"> | |||||
<label for="node-input-name"><i class="fa fa-tag"></i> Name</label> | |||||
<input type="text" id="node-input-name" placeholder="Name"> | |||||
</div> |
<div class="form-row"> | |||||
<label for="node-input-name"><i class="fa fa-tag"></i> Name</label> | |||||
<input type="text" id="node-input-name" placeholder="Name"> | |||||
</div> |
<div class="form-row"> | |||||
<label for="node-input-name"><i class="fa fa-tag"></i> Name</label> | |||||
<input type="text" id="node-input-name" placeholder="Name"> | |||||
</div> |
<div class="form-row"> | |||||
<label for="node-input-name"><i class="fa fa-tag"></i> Name</label> | |||||
<input type="text" id="node-input-name" placeholder="Name"> | |||||
</div> |
<div class="form-row"> | |||||
<label for="node-input-name"><i class="fa fa-tag"></i> Name</label> | |||||
<input type="text" id="node-input-name" placeholder="Name"> | |||||
</div> |
<div class="form-row"> | |||||
<label for="node-input-name"><i class="fa fa-tag"></i> Name</label> | |||||
<input type="text" id="node-input-name" placeholder="Name"> | |||||
</div> |
<div class="form-row"> | |||||
<label for="node-input-name"><i class="fa fa-tag"></i> Name</label> | |||||
<input type="text" id="node-input-name" placeholder="Name"> | |||||
</div> |
<div class="form-row"> | |||||
<label for="node-input-name"><i class="fa fa-tag"></i> Name</label> | |||||
<input type="text" id="node-input-name" placeholder="Name"> | |||||
</div> |
<div class="form-row"> | |||||
<label for="node-input-name"><i class="fa fa-tag"></i> Name</label> | |||||
<input type="text" id="node-input-name" placeholder="Name"> | |||||
</div> |
<div class="form-row"> | |||||
<label for="node-input-name"><i class="fa fa-tag"></i> Name</label> | |||||
<input type="text" id="node-input-name" placeholder="Name"> | |||||
</div> |
<div class="form-row"> | |||||
<label for="node-input-name"><i class="fa fa-tag"></i> Name</label> | |||||
<input type="text" id="node-input-name" placeholder="Name"> | |||||
</div> |
<div class="form-row"> | |||||
<label for="node-input-name"><i class="fa fa-tag"></i> Name</label> | |||||
<input type="text" id="node-input-name" placeholder="Name"> | |||||
</div> |
<div class="form-row"> | |||||
<label for="node-input-name"><i class="fa fa-tag"></i> Name</label> | |||||
<input type="text" id="node-input-name" placeholder="Name"> | |||||
</div> |
<div class="form-row"> | |||||
<label for="node-input-name"><i class="fa fa-tag"></i> Name</label> | |||||
<input type="text" id="node-input-name" placeholder="Name"> | |||||
</div> |
<div class="form-row"> | |||||
<label for="node-input-name"><i class="fa fa-tag"></i> Name</label> | |||||
<input type="text" id="node-input-name" placeholder="Name"> | |||||
</div> |
<div class="form-row"> | |||||
<label for="node-input-name"><i class="fa fa-tag"></i> Name</label> | |||||
<input type="text" id="node-input-name" placeholder="Name"> | |||||
</div> |
<div class="form-row"> | |||||
<label for="node-input-name"><i class="fa fa-tag"></i> Name</label> | |||||
<input type="text" id="node-input-name" placeholder="Name"> | |||||
</div> |
<div class="form-row"> | |||||
<label for="node-input-name"><i class="fa fa-tag"></i> Name</label> | |||||
<input type="text" id="node-input-name" placeholder="Name"> | |||||
</div> |
<div class="form-row"> | |||||
<label for="node-input-name"><i class="fa fa-tag"></i> Name</label> | |||||
<input type="text" id="node-input-name" placeholder="Name"> | |||||
</div> |
<div class="form-row"> | |||||
<label for="node-input-name"><i class="fa fa-tag"></i> Name</label> | |||||
<input type="text" id="node-input-name" placeholder="Name"> | |||||
</div> |
<div class="form-row"> | |||||
<label for="node-input-export" style="display: block; width:100%;"><i class="icon-share"></i> Source Code:</label> | |||||
<textarea readonly style="font-family: monospace; font-size: 12px; background:rgb(226, 229, 255); padding-left: 0.5em;" class="input-block-level" id="node-input-export" rows="12"></textarea> | |||||
</div> | |||||
<div class="form-tips"> | |||||
Select the text above and copy to the clipboard with Ctrl-A Ctrl-C. | |||||
</div> |
<div class="form-row"> | |||||
<label for="node-input-filename" ><i class="icon-tag"></i> Filename:</label> | |||||
<input type="text" id="node-input-filename" placeholder="Filename"> | |||||
</div> |
<div class="form-row"> | |||||
<label for="node-input-export"><i class="icon-share"></i>Nodes:</label> | |||||
<textarea style="font-family: monospace; font-size: 12px; background:rgb(226, 229, 255); padding-left: 0.5em;" class="input-block-level" id="node-input-import" rows="5" placeholder="Paste nodes here, or lookup in the library"></textarea> | |||||
</div> |
<h3>Summary</h3> | |||||
<p>Compute a 1024 point Fast Fourier Transform (FFT) frequency analysis, | |||||
with real value (magnitude) output. The frequency resolution is | |||||
43 Hz, useful detailed for audio visualization.</p> | |||||
<h3>Audio Connections</h3> | |||||
<table class=doc align=center cellpadding=3> | |||||
<tr class=top><th>Port</th><th>Purpose</th></tr> | |||||
<tr class=odd><td align=center>In 0</td><td>Signal to convert to frequency bins</td></tr> | |||||
</table> | |||||
<h3>Functions</h3> | |||||
<p class=func><span class=keyword>available</span>();</p> | |||||
<p class=desc>Returns true each time the FFT analysis produces new output data. | |||||
</p> | |||||
<p class=func><span class=keyword>read</span>(binNumber);</p> | |||||
<p class=desc>Read a single frequency bin, from 0 to 511. The result is scaled | |||||
so 1.0 represents a full scale sine wave. | |||||
</p> | |||||
<p class=func><span class=keyword>read</span>(firstBin, lastBin);</p> | |||||
<p class=desc>Read several frequency bins, returning their sum. The higher | |||||
audio octaves are represented by many bins, which are typically read | |||||
as a group for audio visualization. | |||||
</p> | |||||
<p class=func><span class=keyword>averageTogether</span>(number);</p> | |||||
<p class=desc>This function does nothing. The 1024 point FFT always | |||||
updates at approximately 86 times per second. | |||||
</p> | |||||
<p class=func><span class=keyword>windowFunction</span>(window);</p> | |||||
<p class=desc>Set the window function to be used. AudioWindowHanning1024 | |||||
is the default. Windowing may be disabled by NULL, but windowing | |||||
should be used for all non-periodic (music) signals, and all periodic | |||||
signals that are not exact integer division of the sample rate. | |||||
</p> | |||||
<h3>Examples</h3> | |||||
<p class=exam>File > Examples > Audio > Analysis > FFT | |||||
</p> | |||||
<p class=exam>File > Examples > Audio > Analysis > SpectrumAnalyzerBasic | |||||
</p> | |||||
<h3>Notes</h3> | |||||
<p>The raw 16 bit output data bins may be access with myFFT.output[num], where | |||||
num is 0 to 511.</p> | |||||
<p>TODO: caveats about spectral leakage vs frequency precision for arbitrary signals</p> | |||||
<p>Window Types: | |||||
<ul> | |||||
<li><span class=literal>AudioWindowHanning1024</span> (default)</li> | |||||
<li><span class=literal>AudioWindowBartlett1024</span></li> | |||||
<li><span class=literal>AudioWindowBlackman1024</span></li> | |||||
<li><span class=literal>AudioWindowFlattop1024</span></li> | |||||
<li><span class=literal>AudioWindowBlackmanHarris1024</span></li> | |||||
<li><span class=literal>AudioWindowNuttall1024</span></li> | |||||
<li><span class=literal>AudioWindowBlackmanNuttall1024</span></li> | |||||
<li><span class=literal>AudioWindowWelch1024</span></li> | |||||
<li><span class=literal>AudioWindowHamming1024</span></li> | |||||
<li><span class=literal>AudioWindowCosine1024</span></li> | |||||
<li><span class=literal>AudioWindowTukey1024</span></li> | |||||
</ul> | |||||
</p> | |||||
<p>1024 point FFT has a peak CPU usage of approx 52% on Teensy 3.1. | |||||
Average usage is much lower. Future versions might distribute the | |||||
load more evenly over time.... | |||||
</p> |
<h3>Summary</h3> | |||||
<p>Compute a 256 point Fast Fourier Transform (FFT) frequency analysis, | |||||
with real value (magnitude) output. The frequency resolution is | |||||
172 Hz, useful for simple audio visualization.</p> | |||||
<h3>Audio Connections</h3> | |||||
<table class=doc align=center cellpadding=3> | |||||
<tr class=top><th>Port</th><th>Purpose</th></tr> | |||||
<tr class=odd><td align=center>In 0</td><td>Signal to convert to frequency bins</td></tr> | |||||
</table> | |||||
<h3>Functions</h3> | |||||
<p class=func><span class=keyword>available</span>();</p> | |||||
<p class=desc>Returns true each time the FFT analysis produces new output data. | |||||
</p> | |||||
<p class=func><span class=keyword>read</span>(binNumber);</p> | |||||
<p class=desc>Read a single frequency bin, from 0 to 127. The result is scaled | |||||
so 1.0 represents a full scale sine wave. | |||||
</p> | |||||
<p class=func><span class=keyword>read</span>(firstBin, lastBin);</p> | |||||
<p class=desc>Read several frequency bins, returning their sum. The higher | |||||
audio octaves are represented by many bins, which are typically read | |||||
as a group for audio visualization. | |||||
</p> | |||||
<p class=func><span class=keyword>averageTogether</span>(number);</p> | |||||
<p class=desc>New data is produced very radidly, approximately 344 times | |||||
per second. Multiple outputs can be averaged together, so available() | |||||
returns true at a slower rate. | |||||
</p> | |||||
<p class=func><span class=keyword>windowFunction</span>(window);</p> | |||||
<p class=desc>Set the window function to be used. AudioWindowHanning256 | |||||
is the default. Windowing may be disabled by NULL, but windowing | |||||
should be used for all non-periodic (music) signals, and all periodic | |||||
signals that are not exact integer division of the sample rate. | |||||
</p> | |||||
<h3>Examples</h3> | |||||
<p class=exam>File > Examples > Audio > MemoryAndCpuUsage | |||||
</p> | |||||
<h3>Notes</h3> | |||||
<p>The raw 16 bit output data bins may be access with myFFT.output[num], where | |||||
num is 0 to 127.</p> | |||||
<p>TODO: caveats about spectral leakage vs frequency precision for arbitrary signals</p> | |||||
<p>Window Types: | |||||
<ul> | |||||
<li><span class=literal>AudioWindowHanning256</span> (default)</li> | |||||
<li><span class=literal>AudioWindowBartlett256</span></li> | |||||
<li><span class=literal>AudioWindowBlackman256</span></li> | |||||
<li><span class=literal>AudioWindowFlattop256</span></li> | |||||
<li><span class=literal>AudioWindowBlackmanHarris256</span></li> | |||||
<li><span class=literal>AudioWindowNuttall256</span></li> | |||||
<li><span class=literal>AudioWindowBlackmanNuttall256</span></li> | |||||
<li><span class=literal>AudioWindowWelch256</span></li> | |||||
<li><span class=literal>AudioWindowHamming256</span></li> | |||||
<li><span class=literal>AudioWindowCosine256</span></li> | |||||
<li><span class=literal>AudioWindowTukey256</span></li> | |||||
</ul> | |||||
</p> |
<h3>Summary</h3> | |||||
<p>Track the signal peak amplitude. Very useful for simple | |||||
audio level response projects, and general troubleshooting.</p> | |||||
<h3>Audio Connections</h3> | |||||
<table class=doc align=center cellpadding=3> | |||||
<tr class=top><th>Port</th><th>Purpose</th></tr> | |||||
<tr class=odd><td align=center>In 0</td><td>Signal to analyze</td></tr> | |||||
</table> | |||||
<h3>Functions</h3> | |||||
<p class=func><span class=keyword>available</span>();</p> | |||||
<p class=desc>Returns true each time new peak data is available. | |||||
</p> | |||||
<p class=func><span class=keyword>read</span>();</p> | |||||
<p class=desc>Read the highest peak value since the last read. | |||||
Return is from 0.0 to 1.0. | |||||
</p> | |||||
<h3>Examples</h3> | |||||
<p class=exam>File > Examples > Audio > Analysis > PeakMeterMono | |||||
</p> | |||||
<p class=exam>File > Examples > Audio > Analysis > PeakMeterStereo | |||||
</p> | |||||
<h3>Notes</h3> | |||||
<p></p> |
<h3>Summary</h3> | |||||
<p>Print raw audio data to the Arduino Serial Monitor. This | |||||
object creates massive output quickly, and should not normally be used.</p> | |||||
<h3>Audio Connections</h3> | |||||
<table class=doc align=center cellpadding=3> | |||||
<tr class=top><th>Port</th><th>Purpose</th></tr> | |||||
<tr class=odd><td align=center>In 0</td><td>Signal to print</td></tr> | |||||
</table> | |||||
<h3>Functions</h3> | |||||
<p class=func><span class=keyword>name</span>(string);</p> | |||||
<p class=desc>blah blah blah blah | |||||
</p> | |||||
<p class=func><span class=keyword>trigger</span>();</p> | |||||
<p class=desc>blah blah blah blah | |||||
</p> | |||||
<p class=func><span class=keyword>trigger</span>(level, edge);</p> | |||||
<p class=desc>blah blah blah blah | |||||
</p> | |||||
<p class=func><span class=keyword>delay</span>(samples);</p> | |||||
<p class=desc>blah blah blah blah | |||||
</p> | |||||
<p class=func><span class=keyword>length</span>(samples);</p> | |||||
<p class=desc>blah blah blah blah | |||||
</p> | |||||
<!--<h3>Examples</h3> | |||||
<p class=exam>File > Examples > Audio > | |||||
</p>--> | |||||
<h3>Notes</h3> | |||||
<p>This object doesn't work very well and probably should not be used.</p> |
<h3>Summary</h3> | |||||
<p>Detect the level of a single tone</p> | |||||
<h3>Audio Connections</h3> | |||||
<table class=doc align=center cellpadding=3> | |||||
<tr class=top><th>Port</th><th>Purpose</th></tr> | |||||
<tr class=odd><td align=center>In 0</td><td>Signal to analyze</td></tr> | |||||
</table> | |||||
<h3>Functions</h3> | |||||
<p class=func><span class=keyword>frequency</span>(freq);</p> | |||||
<p class=desc>Set the frequency to detect. The default detection time | |||||
will be 10 cycles of this frequency. | |||||
</p> | |||||
<p class=func><span class=keyword>frequency</span>(freq, cycles);</p> | |||||
<p class=desc>Set the frequency to detect, and the number of cycles. | |||||
Longer detection time (more cycles) will give higher precision, | |||||
but of course slower response. | |||||
</p> | |||||
<p class=func><span class=keyword>available</span>();</p> | |||||
<p class=desc>Returns true (non-zero) each time a detection interval | |||||
(number of cycles) completed and a new level is detected. | |||||
</p> | |||||
<p class=func><span class=keyword>read</span>();</p> | |||||
<p class=desc>Read the detected signal level. Range is 0 to 1.0. | |||||
</p> | |||||
<p class=func><span class=keyword>threshold</span>(level);</p> | |||||
<p class=desc>Set a detection threshold, where the bool test operation | |||||
will return true if at or above this level, or false when below. | |||||
</p> | |||||
<p class=func>(bool)</p> | |||||
<p class=desc>By testing the object as a boolean value, you can respond | |||||
to detection of a tone. | |||||
</p> | |||||
<h3>Examples</h3> | |||||
<p class=exam>File > Examples > Audio > Analysis > DialTone_Serial | |||||
</p> | |||||
<p class=exam>File > Examples > Audio > Analysis > DialTone_7segment | |||||
</p> | |||||
<h3>Notes</h3> | |||||
<p>Low frequency detection has trouble with numerical precision. | |||||
Works really well for all 8 DTMF frequencies, but fails for | |||||
detecting "sub audible tones" used in some control applications.</p> | |||||
<p>The (bool) test continues to return true until the next detection | |||||
interval (the configured number of cycles). This behavior may | |||||
change in future versions, for a single true each time the signal | |||||
is detected, and then false for the remainder of that interval.</p> |
<h3>Summary</h3> | |||||
<p>Control the SGTL5000 chip on the | |||||
<a href="http://www.pjrc.com/store/teensy3_audio.html" target="_blank">audio shield</a>. | |||||
SGTL5000 is always used in slave mode, where Teensy controls | |||||
all I2S timing. | |||||
</p> | |||||
<p align=center><img src="img/sgtl5000closeup.jpg"></p> | |||||
<h3>Audio Connections</h3> | |||||
<p>This object has no audio inputs or outputs. Separate i2s objects | |||||
are used to send and receive audio data. I2S master mode objects | |||||
must be used, because this object configures the SGTL5000 in slave | |||||
mode, where it depends on Teensy to provide all I2S clocks. | |||||
This object controls | |||||
how the SGTL5000 will use those I2S audio streams.</p> | |||||
<h3>Functions</h3> | |||||
<p>These are the most commonly used SGTL5000 functions.</p> | |||||
<p class=func><span class=keyword>enable</span>();</p> | |||||
<p class=desc>Start the SGTL5000. This function should be called first. | |||||
</p> | |||||
<p class=func><span class=keyword>volume</span>(level);</p> | |||||
<p class=desc>Set the headphone volume level. Range is 0 to 1.0, but | |||||
0.8 corresponds to the maximum undistorted output for a full scale | |||||
signal. Usually 0.5 is a comfortable listening level. The line | |||||
level outputs are <em>not</em> changed by this function. | |||||
</p> | |||||
<p class=func><span class=keyword>inputSelect</span>(input);</p> | |||||
<p class=desc>Select which input to use: AUDIO_INPUT_LINEIN or AUDIO_INPUT_MIC. | |||||
</p> | |||||
<p class=func><span class=keyword>micGain</span>(dB);</p> | |||||
<p class=desc>When using the microphone input, set the amplifier gain. | |||||
The input number is in decibels, from 0 to 63. | |||||
</p> | |||||
<h3>Signal Levels</h3> | |||||
<p>The default signal levels should be used for most applications, | |||||
but these functions allow you to customize the analog signals.</p> | |||||
<p class=func><span class=keyword>muteHeadphone</span>();</p> | |||||
<p class=desc>Silence the headphone output. | |||||
</p> | |||||
<p class=func><span class=keyword>unmuteHeadphone</span>();</p> | |||||
<p class=desc>Turn the headphone output on. | |||||
</p> | |||||
<p class=func><span class=keyword>muteLineout</span>();</p> | |||||
<p class=desc>Silence the line level outputs. | |||||
</p> | |||||
<p class=func><span class=keyword>unmuteLineout</span>();</p> | |||||
<p class=desc>Turn the line level outputs on. | |||||
</p> | |||||
<p class=func><span class=keyword>lineInLevel</span>(both);</p> | |||||
<p class=desc style="padding-bottom:0.2em;">Adjust the sensitivity of the line-level inputs. | |||||
Fifteen settings are possible: | |||||
</p> | |||||
<pre class="desc"> | |||||
0: 3.12 Volts p-p | |||||
1: 2.63 Volts p-p | |||||
2: 2.22 Volts p-p | |||||
3: 1.87 Volts p-p | |||||
4: 1.58 Volts p-p | |||||
5: 1.33 Volts p-p (default) | |||||
6: 1.11 Volts p-p | |||||
7: 0.94 Volts p-p | |||||
8: 0.79 Volts p-p | |||||
9: 0.67 Volts p-p | |||||
10: 0.56 Volts p-p | |||||
11: 0.48 Volts p-p | |||||
12: 0.40 Volts p-p | |||||
13: 0.34 Volts p-p | |||||
14: 0.29 Volts p-p | |||||
15: 0.24 Volts p-p | |||||
</pre> | |||||
<p class=func><span class=keyword>lineInLevel</span>(left, right);</p> | |||||
<p class=desc>Adjust the sensitivity of the line-level inputs, with different | |||||
settings for left and right. The same 15 settings are available. | |||||
</p> | |||||
<p class=func><span class=keyword>lineOutLevel</span>(both);</p> | |||||
<p class=desc style="padding-bottom:0.2em;">Adjust the line level output | |||||
voltage range. The following settings are possible: | |||||
</p> | |||||
<pre class="desc"> | |||||
13: 3.16 Volts p-p | |||||
14: 2.98 Volts p-p | |||||
15: 2.83 Volts p-p | |||||
16: 2.67 Volts p-p | |||||
17: 2.53 Volts p-p | |||||
18: 2.39 Volts p-p | |||||
19: 2.26 Volts p-p | |||||
20: 2.14 Volts p-p | |||||
21: 2.02 Volts p-p | |||||
22: 1.91 Volts p-p | |||||
23: 1.80 Volts p-p | |||||
24: 1.71 Volts p-p | |||||
25: 1.62 Volts p-p | |||||
26: 1.53 Volts p-p | |||||
27: 1.44 Volts p-p | |||||
28: 1.37 Volts p-p | |||||
29: 1.29 Volts p-p (default) | |||||
30: 1.22 Volts p-p | |||||
31: 1.16 Volts p-p | |||||
</pre> | |||||
<p class=func><span class=keyword>lineOutLevel</span>(left, right);</p> | |||||
<p class=desc>Adjust the line level outout voltage range, with separate | |||||
settings for left and right. The same settings (13 to 31) are available. | |||||
</p> | |||||
<h3>Signal Conditioning</h3> | |||||
<p>Usually these digital signal conditioning features should be left at their | |||||
default settings. | |||||
</p> | |||||
<p class=func><span class=keyword>adcHighPassFilterFreeze</span>();</p> | |||||
<p class=desc>By default, the analog input (either line-level inputs or mic) | |||||
is high-pass filtered, to remove any DC component. This function | |||||
freezes the filter, so the current DC component is still substracted, but | |||||
the filter stops tracking any DC or low frequency changes. | |||||
</p> | |||||
<p class=func><span class=keyword>adcHighPassFilterDisable</span>();</p> | |||||
<p class=desc>Completely disable the analog input filter. DC and sub-audible | |||||
low frequencies are allowed to enter the digital signal. | |||||
</p> | |||||
<p class=func><span class=keyword>adcHighPassFilterEnable</span>();</p> | |||||
<p class=desc>Turn the DC-blocking filter back on, if disabled, or | |||||
allows it to resume tracking DC and low frequency changes, if | |||||
previously frozen. This is the default setting. | |||||
</p> | |||||
<p class=func><span class=keyword>dacVolume</span>(both);</p> | |||||
<p class=desc>Normally output volume should be used with volume(), which | |||||
changes the analog gain in the headphone amplifier. This function | |||||
on the other hand controls digital attenuation before conversion to analog, which | |||||
reduces resolution, but allows another fine control of output | |||||
signal level. The ranges is 0 to 1.0, with the default (no digital attenuation) | |||||
at 1.0. | |||||
</p> | |||||
<p class=desc>dacVolume uses zero-crossing detect to avoid clicks, and ramping is handled by | |||||
the chip so that a new volume may be set directly in a single call. | |||||
</p> | |||||
<p class=func><span class=keyword>dacVolume</span>(left, right);</p> | |||||
<p class=desc>Adjust the digital output volume separately on left and | |||||
right channels. | |||||
</p> | |||||
<h3>Audio Processor</h3> | |||||
<p>The optional digital audio processor is capable of implementing | |||||
one or more of: automatic volume control, surround sound control, | |||||
bass enhancement, and tonal adjustments (either a | |||||
simple tone control, or a parametric equalizer, or a graphic equalizer), | |||||
in that order. | |||||
</p> | |||||
<p>These signal processing features are implemented in the SGTL5000 chip, | |||||
so they do not consume CPU time on Teensy. However, the order of | |||||
these processes is fixed in the hardware. | |||||
</p> | |||||
<p>It is good practice to mute the outputs before enabling or disabling | |||||
the Audio Processor, to avoid clicks or thumps. | |||||
</p> | |||||
<p class=func><span class=keyword>audioPreProcessorEnable</span>();</p> | |||||
<p class=desc>Enable the audio processor to pre-process the input | |||||
(from either line-level inputs or microphone) before it's sent | |||||
to Teensy by I2S. | |||||
</p> | |||||
<p class=func><span class=keyword>audioPostProcessorEnable</span>();</p> | |||||
<p class=desc>Enable the audio processor to post-process Teensy's | |||||
I2S output before it's turned into analog signals for the | |||||
headphones and/or line level outputs. | |||||
</p> | |||||
<p class=func><span class=keyword>audioProcessorDisable</span>();</p> | |||||
<p class=desc>Disable the audio processor. | |||||
</p> | |||||
<p class=func><span class=keyword>autoVolumeControl</span>(maxGain, response, hardLimit, threshold, attack, decay);</p> | |||||
<p class=desc>Configures the auto volume control, which is implemented as a compressor/expander | |||||
or hard limiter. <em>maxGain</em> is the maximum gain that can be applied for expanding, and | |||||
can take one of three values: 0 (0dB), 1 (6.0dB) and 2 (12dB). Values greater than 2 are treated | |||||
as 2. <em>response</em> controls the integration time for the compressor and can take | |||||
four values: 0 (0ms), 1 (25ms), 2 (50ms) or 3 (100ms). Larger values average the volume | |||||
over a longer time, allowing short-term peaks through. | |||||
</p> | |||||
<p class=desc>If <em>hardLimit</em> is 0, a 'soft | |||||
knee' compressor is used to progressively compress louder values which are near to or above the | |||||
threashold (the louder they are, the greater the compression). If it is 1, a hard compressor | |||||
is used (all values above the threashold are the same loudness). The <em>threashold</em> is specified | |||||
as a float in the range 0dBFS to -96dBFS, where -18dBFS is a typical value. | |||||
<em>attack</em> is a float controlling the rate of decrease in gain when the signal is over | |||||
threashold, in dB/s. <em>decay</em> controls how fast gain is restored once the level | |||||
drops below threashold, again in dB/s. It is typically set to a longer value than attack. | |||||
</p> | |||||
<p class=func><span class=keyword>autoVolumeEnable</span>();</p> | |||||
<p class=desc>Enables auto volume control, using the previously specified settings. | |||||
</p> | |||||
<p class=func><span class=keyword>autoVolumeDisable</span>();</p> | |||||
<p class=desc>Disables auto volume control. | |||||
</p> | |||||
<p class=func><span class=keyword>surroundSoundEnable</span>();</p> | |||||
<p class=desc>Enable virtual surround processing, to give a broader and | |||||
deeper stereo image (even with mono input). | |||||
</p> | |||||
<p class=func><span class=keyword>surroundSoundDisable</span>();</p> | |||||
<p class=desc>Disable virtual surround processing. Before disabling, ramp up | |||||
the width to maximum to avoid pops. | |||||
</p> | |||||
<p class=func><span class=keyword>surroundSound</span>(width);</p> | |||||
<p class=desc>Configures virtual surround width from 0 (mono) to 7 (widest). | |||||
</p> | |||||
<p class=func><span class=keyword>surroundSound</span>(width, select);</p> | |||||
<p class=desc>Configures virtual surround width from 0 (mono) to 7 (widest). | |||||
<em>select</em> may be set to 1 (disable), 2 (mono input) or 3 (stereo input). | |||||
</p> | |||||
<p class=func><span class=keyword>enhanceBassEnable</span>();</p> | |||||
<p class=desc>Enable bass enhancement. A mono, low-pass filtered copy of | |||||
the original stereo signal has bass levels boosted and is then mixed back into | |||||
the stereo signal, which is then optionally high pass filtered (to remove | |||||
inaudible subsonic frequencies). | |||||
</p> | |||||
<p class=func><span class=keyword>enhanceBassDisable</span>();</p> | |||||
<p class=desc>Disable bass enhancement. Before disabling, ramp down the bass | |||||
enhancement level to zero. | |||||
</p> | |||||
<p class=func><span class=keyword>enhanceBass</span>(lr_lev, bass_lev);</p> | |||||
<p class=desc>Configures the bass enhancement by setting the levels of the | |||||
original stereo signal and the bass-enhanced mono level which will be mixed together. | |||||
There is no high-pass filter. | |||||
</p> | |||||
<p class=desc>When changing bass level, call this function repeatedly to ramp up or down the bass in | |||||
steps of 0.5dB, to avoid pops. | |||||
</p> | |||||
<p class=func><span class=keyword>enhanceBass</span>(lr_lev, bass_lev, hpf_bypass, cutoff);</p> | |||||
<p class=desc>Configures the bass enhancement by setting the levels of the | |||||
original stereo signal and the bass-enhanced mono level which will be mixed together. | |||||
The high-pass filter may be enabled (0) or bypassed (1). The cutoff frequency is specified | |||||
as follows: | |||||
</p> | |||||
<pre class="desc"> | |||||
value frequency | |||||
0 80Hz | |||||
1 100Hz | |||||
2 125Hz | |||||
3 150Hz | |||||
4 175Hz | |||||
5 200Hz | |||||
6 225Hz | |||||
</pre> | |||||
<p class=desc>When changing bass level, call this function repeatedly to ramp up or down the bass in | |||||
steps of 0.5dB, to avoid pops. | |||||
</p> | |||||
<p class=func><span class=keyword>eqSelect</span>(n);</p> | |||||
<p class=desc>Selects the type of frequency control, where <em>n</em> is | |||||
one of</p> | |||||
<p class=desc><b>FLAT_FREQUENCY (0)</b><br> | |||||
Equalizers and tone controls disabled, flat frequency response.</p> | |||||
<p class=desc><b>PARAMETRIC_EQUALIZER (1)</b><br> | |||||
Enables the 7-band parametric equalizer, thus disabling the | |||||
tone controls and graphic equalizer.</p> | |||||
<p class=desc><b>TONE_CONTROLS (2)</b><br> | |||||
Enables bass and treble tone controls, disabling the parametric | |||||
equalization and graphic equalizer.</p> | |||||
<p class=desc><b>GRAPHIC_EQUALIZER (3)</b><br> | |||||
Enables the five-band graphic equalizer, disabling the parametric | |||||
equalization and tone controls.</p> | |||||
<p class=func><span class=keyword>eqBands</span>(bass, treble);</p> | |||||
<p class=desc>Configures bass and treble tone controls, which are | |||||
implemented as one second order low pass filter (bass) in parallel with | |||||
one second order high pass filter (treble). | |||||
</p> | |||||
<p class=desc>When changing bass or treble level, call this function repeatedly to ramp | |||||
up or down the level in steps of 0.04 (=0.5dB) or so, to avoid pops. | |||||
</p> | |||||
<p class=func><span class=keyword>eqBands</span>(bass, mid_bass, midrange, mid_treble, treble);</p> | |||||
<p class=desc>Configures the graphic equalizer. It is implemented by five parallel, | |||||
second order biquad filters with fixed frequencies of 115Hz, 330Hz, 990Hz, 3kHz, | |||||
and 9.9kHz. Each band has a range of adjustment from 1.00 (+12dB) to -1.00 (-11.75dB). | |||||
</p> | |||||
<p class=func><span class=keyword>eqBand</span>(bandNum, n);</p> | |||||
<p class=desc>Configures the gain or cut on one band in the graphic equalizer. | |||||
<em>bandnum</em> can range from 1 to 5; <em>n</em> is a float in the range 1.00 to -1.00. | |||||
</p> | |||||
<p class=desc>When changing a band, call this function repeatedly to ramp up the gain in steps of 0.5dB, | |||||
to avoid pops. | |||||
</p> | |||||
<p class=func><span class=keyword>eqFilter</span>(filterNum, filterParameters);</p> | |||||
<p class=desc>Configurs the parametric equalizer. The number of filters (1 to 7) | |||||
is specified along with a pointer to an array of filter coefficients. | |||||
The parametric equalizer is implemented using 7 cascaded, second order bi-quad | |||||
filters whose frequencies, gain, and Q may be freely configured, but each filter | |||||
can only be specified as a set of filter coefficients. | |||||
</p> | |||||
<p class=func><span class=keyword>eqFilterCount</span>(n);</p> | |||||
<p class=desc>Enables zero or more of the already enabled parametric filters. | |||||
</p> | |||||
<h3>Examples</h3> | |||||
<p>Nearly all of the library's examples use this object. These | |||||
examples demonstrate its special features. | |||||
</p> | |||||
<p class=exam>File > Examples > Audio > HardwareTesting > PassThroughStereo | |||||
</p> | |||||
<p class=exam>File > Examples > Audio > HardwareTesting > SGTL5000 > dap_bass_enhance | |||||
</p> | |||||
<p class=exam>File > Examples > Audio > HardwareTesting > SGTL5000 > dap_avc_agc | |||||
</p> | |||||
<p class=exam>File > Examples > Audio > HardwareTesting > SGTL5000 > balanceDAC | |||||
</p> | |||||
<p class=exam>File > Examples > Audio > HardwareTesting > SGTL5000 > balanceHP | |||||
</p> | |||||
<p class=exam>File > Examples > Audio > HardwareTesting > SGTL5000 > CalcBiquadToneControlDAP | |||||
</p> | |||||
<h3>Notes</h3> | |||||
<p>TODO: add example with rock/classical/speech presets, where rock uses bass boost | |||||
and surround enhancement while speech uses bandpass filtering and auto volume control | |||||
compression. | |||||
</p> | |||||
<p>TODO: add example with two analogRead pots for bass and treble to demonstrate ramping. | |||||
</p> |
<h3>Summary</h3> | |||||
<p>Control a WM8731 chip in slave mode, where it receives all clocks from Teensy</p> | |||||
<h3>Audio Connections</h3> | |||||
<p>This object has no audio inputs or outputs. Separate i2s objects | |||||
are used to send and receive audio data. I2S master mode objects | |||||
must be used, since this control object configures the WM8731 into | |||||
slave mode. | |||||
</p> | |||||
<h3>Functions</h3> | |||||
<p class=func><span class=keyword>enable</span>();</p> | |||||
<p class=desc>blah blah blah blah | |||||
</p> | |||||
<p class=func><span class=keyword>disable</span>();</p> | |||||
<p class=desc>not implemented | |||||
</p> | |||||
<p class=func><span class=keyword>volume</span>(level);</p> | |||||
<p class=desc>blah blah blah blah | |||||
</p> | |||||
<p class=func><span class=keyword>inputLevel</span>(level);</p> | |||||
<p class=desc>not implemented | |||||
</p> | |||||
<p class=func><span class=keyword>inputSelect</span>(input);</p> | |||||
<p class=desc>not implemented | |||||
</p> | |||||
<!--<h3>Examples</h3> | |||||
<p class=exam>File > Examples > Audio > | |||||
</p>--> | |||||
<h3>Notes</h3> | |||||
<p></p> |
<h3>Summary</h3> | |||||
<p>Control a WM8731 chip in master mode, where it controls all I2S timing.</p> | |||||
<h3>Audio Connections</h3> | |||||
<p>This object has no audio inputs or outputs. Separate i2s objects | |||||
are used to send and receive audio data. I2S slave mode objects | |||||
must be used, since this control object configures the WM8731 into | |||||
master mode. | |||||
</p> | |||||
<h3>Functions</h3> | |||||
<p class=func><span class=keyword>enable</span>();</p> | |||||
<p class=desc>blah blah blah blah | |||||
</p> | |||||
<p class=func><span class=keyword>disable</span>();</p> | |||||
<p class=desc>not implemented | |||||
</p> | |||||
<p class=func><span class=keyword>volume</span>(level);</p> | |||||
<p class=desc>blah blah blah blah | |||||
</p> | |||||
<p class=func><span class=keyword>inputLevel</span>(level);</p> | |||||
<p class=desc>not implemented | |||||
</p> | |||||
<p class=func><span class=keyword>inputSelect</span>(input);</p> | |||||
<p class=desc>not implemented | |||||
</p> | |||||
<h3>Examples</h3> | |||||
<p class=exam>File > Examples > Audio > HardwareTesting > WM8731MikroSine | |||||
</p> | |||||
<h3>Notes</h3> | |||||
<p></p> |
<h3>Summary</h3> | |||||
<p>Reduce the samplerate and/or bitdepth of a source signal, resulting in | |||||
a distorted sound.</p> | |||||
<h3>Audio Connections</h3> | |||||
<table class=doc align=center cellpadding=3> | |||||
<tr class=top><th>Port</th><th>Purpose</th></tr> | |||||
<tr class=odd><td align=center>In 0</td><td>Signal Input</td></tr> | |||||
<tr class=odd><td align=center>Out 0</td><td>Signal Output</td></tr> | |||||
</table> | |||||
<h3>Parameters</h3> | |||||
<p class=func><span class=keyword>bits</span>(xcrushBits);</p> | |||||
<p class=desc>xcrushBits sets the bitdepth, from 1 to 16. A Value of 16 | |||||
does not crush the bitdepth, and is effectively a passthru for this part | |||||
of the function.</p> | |||||
<p class=func><span class=keyword>sampleRate</span>(xsampleRate);</p> | |||||
<p class=desc>xsampleRate sets the frequency, from 1 to 44100Hz, however it | |||||
works in integer steps so you will only really get a handful of results from | |||||
the many samplerates you can pass. 44100 is passthru.</p> | |||||
<p class=desc>set xbitDepth to 16 and xsampleRate to 44100 to pass audio | |||||
through without any Bitcrush effect.</p> | |||||
<h3>Examples</h3> | |||||
<p class=exam>File > Examples > Audio > Effects > Bitcrusher | |||||
</p> | |||||
<h3>Notes</h3> | |||||
<p>Needs a lot of improvement. Options for anti-aliasing would be nice in | |||||
the future, but for now, it's rough, it's dirty and it sounds a bit like | |||||
Nine Inch Nails. | |||||
</p> | |||||
<p><a href="http://www.pjrc.com/teensy/td_libs_AudioProcessorUsage.html" target="_blank">AudioNoInterrupts()</a> | |||||
should be used when changing | |||||
settings on multiple objects, so all changes always take effect | |||||
at the same moment. | |||||
</p> |
<h3>Summary</h3> | |||||
<p>The chorus effect simulates the richness of several nearly-identical | |||||
sound sources (like the way a choir sounds different to a single singer). | |||||
It does this by sampling from a delay line, so each voice is actually | |||||
the same but at a slightly different point in time. This is a type of | |||||
comb filtering.</p> | |||||
<p>Chorus combines one or more samples ranging from the most recent | |||||
sample back to about 50ms ago. The additional samples are evenly spread | |||||
through the supplied delay line, and there is no modulation.</p> | |||||
<p>If the number of voices is specified as 2, then the | |||||
effect combines the current sample and the oldest sample (the last one | |||||
in the delay line). If the number of voices is 3 then the effect combines | |||||
the most recent sample, the oldest sample and the sample in the middle of | |||||
the delay line.</p> | |||||
<p>For two voices the effect can be represented as:<br/> | |||||
result = (sample(0) + sample(dt))/2<br/> | |||||
where sample(0) represents the current sample and sample(dt) | |||||
is the sample in the delay line from dt milliseconds ago.</p> | |||||
<h3>Audio Connections</h3> | |||||
<table class=doc align=center cellpadding=3> | |||||
<tr class="top"><th>Port</th><th>Purpose</th></tr> | |||||
<tr class="odd"><td align="center">In 0</td><td>Signal Input</td></tr> | |||||
<tr class="odd"><td align="center">Out 0</td><td>Chorused Output</td></tr> | |||||
</table> | |||||
<h3>Functions</h3> | |||||
<p class=func><span class=keyword>begin</span>(delayBuffer, length, n_chorus);</p> | |||||
<p class=desc>Create a chorus by specifying the address of the delayline, the | |||||
total number of samples in the delay line (often done as an integer multiple of | |||||
AUDIO_BLOCK_SAMPLES) and the number of voices in the chorus <em>including</em> | |||||
the original voice (so, 2 and up to get a chorus effect, although you can | |||||
specify 1 if you want). | |||||
</p> | |||||
<p class=func><span class=keyword>modify</span>(n_chorus);</p> | |||||
<p class=desc>Alters the number of voices in a running chorus (previously started with begin). | |||||
</p> | |||||
<h3>Examples</h3> | |||||
<p class=exam>File > Examples > Audio > Effects > Chorus | |||||
</p> | |||||
<h3>Notes</h3> | |||||
<p>The longer the length of the chorus, the more memory blocks are used.</p> |
<h3>Summary</h3> | |||||
<div> | |||||
<p>Delay a signal. Up to 8 separate delay taps can be used.</p> | |||||
<p align=center><img src="img/delay.png"><br><small>1 kHz burst, delayed 5.2 ms.</small></p> | |||||
</div> | |||||
<h3>Audio Connections</h3> | |||||
<table class=doc align=center cellpadding=3> | |||||
<tr class=top><th>Port</th><th>Purpose</th></tr> | |||||
<tr class=odd><td align=center>In 0</td><td>Signal Input</td></tr> | |||||
<tr class=odd><td align=center>Out 0</td><td>Delay Tap #1</td></tr> | |||||
<tr class=odd><td align=center>Out 1</td><td>Delay Tap #2</td></tr> | |||||
<tr class=odd><td align=center>Out 2</td><td>Delay Tap #3</td></tr> | |||||
<tr class=odd><td align=center>Out 3</td><td>Delay Tap #4</td></tr> | |||||
<tr class=odd><td align=center>Out 4</td><td>Delay Tap #5</td></tr> | |||||
<tr class=odd><td align=center>Out 5</td><td>Delay Tap #6</td></tr> | |||||
<tr class=odd><td align=center>Out 6</td><td>Delay Tap #7</td></tr> | |||||
<tr class=odd><td align=center>Out 7</td><td>Delay Tap #8</td></tr> | |||||
</table> | |||||
<h3>Functions</h3> | |||||
<p class=func><span class=keyword>delay</span>(channel, milliseconds);</p> | |||||
<p class=desc>Set output channel (0 to 7) to delay the signals by | |||||
milliseconds. The maximum delay is approx 333 ms. The actual delay | |||||
is rounded to the nearest sample. Each channel can be configured for | |||||
any delay. There is no requirement to configure the "taps" in increasing | |||||
delay order. | |||||
</p> | |||||
<p class=func><span class=keyword>disable</span>(channel);</p> | |||||
<p class=desc>Disable a channel. The output of this channel becomes | |||||
silent. If this channel is the longest delay, memory usage is | |||||
automatically reduced to accomodate only the remaining channels used. | |||||
</p> | |||||
<h3>Examples</h3> | |||||
<p class=exam>File > Examples > Audio > Effects > Delay | |||||
</p> | |||||
<h3>Notes</h3> | |||||
<p>Memory for the delayed signal is take from the memory pool allocated by | |||||
<a href="http://www.pjrc.com/teensy/td_libs_AudioConnection.html" target="_blank">AudioMemory()</a>. | |||||
Each block allows about 3 milliseconds of delay, so AudioMemory | |||||
should be increased to allow for the longest delay tap. | |||||
</p> |
<h3>Summary</h3> | |||||
<div> | |||||
<p>Delay a signal, using external memory for longer delay times! Up to 8 separate delay taps can be used.</p> | |||||
<p align=center><img src="img/delay.png"><br><small>1 kHz burst, delayed 5.2 ms.</small></p> | |||||
</div> | |||||
<h3>Audio Connections</h3> | |||||
<table class=doc align=center cellpadding=3> | |||||
<tr class=top><th>Port</th><th>Purpose</th></tr> | |||||
<tr class=odd><td align=center>In 0</td><td>Signal Input</td></tr> | |||||
<tr class=odd><td align=center>Out 0</td><td>Delay Tap #1</td></tr> | |||||
<tr class=odd><td align=center>Out 1</td><td>Delay Tap #2</td></tr> | |||||
<tr class=odd><td align=center>Out 2</td><td>Delay Tap #3</td></tr> | |||||
<tr class=odd><td align=center>Out 3</td><td>Delay Tap #4</td></tr> | |||||
<tr class=odd><td align=center>Out 4</td><td>Delay Tap #5</td></tr> | |||||
<tr class=odd><td align=center>Out 5</td><td>Delay Tap #6</td></tr> | |||||
<tr class=odd><td align=center>Out 6</td><td>Delay Tap #7</td></tr> | |||||
<tr class=odd><td align=center>Out 7</td><td>Delay Tap #8</td></tr> | |||||
</table> | |||||
<h3>Functions</h3> | |||||
<p class=func><span class=keyword>delay</span>(channel, milliseconds);</p> | |||||
<p class=desc>Set output channel (0 to 7) to delay the signals by | |||||
milliseconds. The maximum delay is approx 333 ms. The actual delay | |||||
is rounded to the nearest sample. Each channel can be configured for | |||||
any delay. There is no requirement to configure the "taps" in increasing | |||||
delay order. | |||||
</p> | |||||
<p class=func><span class=keyword>disable</span>(channel);</p> | |||||
<p class=desc>Disable a channel. The output of this channel becomes | |||||
silent. If this channel is the longest delay, memory usage is | |||||
automatically reduced to accomodate only the remaining channels used. | |||||
</p> | |||||
<h3>Hardware</h3> | |||||
<p>By default, or when <span class=literal>AUDIO_MEMORY_23LC1024</span> is used (see below), | |||||
a single 23LC1024 RAM chip is used, with these pins: | |||||
<table class=doc align=center cellpadding=3> | |||||
<tr class=top><th>Pin</th><th>Signal</th></tr> | |||||
<tr class=odd><td align=center>6</td><td>CS</td></tr> | |||||
<tr class=odd><td align=center>7</td><td>MOSI</td></tr> | |||||
<tr class=odd><td align=center>12</td><td>MISO</td></tr> | |||||
<tr class=odd><td align=center>14</td><td>SCK</td></tr> | |||||
</table> | |||||
</p> | |||||
<p>When <span class=literal>AUDIO_MEMORY_MEMORYBOARD</span> is used, up to six | |||||
23LC1024 chips are used. | |||||
</p> | |||||
<p align=center><img src="img/memoryboard.jpg"><br><small><a href="https://oshpark.com/shared_projects/KZt5PaU7" target="_blank">Memoryboard 4</a></small></p> | |||||
<p> | |||||
<table class=doc align=center cellpadding=3> | |||||
<tr class=top><th>Pin</th><th>Signal</th></tr> | |||||
<tr class=odd><td align=center>2</td><td>CS0 (encoded)</td></tr> | |||||
<tr class=odd><td align=center>3</td><td>CS1 (encoded)</td></tr> | |||||
<tr class=odd><td align=center>4</td><td>CS2 (encoded)</td></tr> | |||||
<tr class=odd><td align=center>7</td><td>MOSI</td></tr> | |||||
<tr class=odd><td align=center>12</td><td>MISO</td></tr> | |||||
<tr class=odd><td align=center>14</td><td>SCK</td></tr> | |||||
</table> | |||||
</p> | |||||
<p> | |||||
If fewer than 6 chips are soldered, the optional parameter for maximum delay | |||||
must be used. See below for details. Each chip provides 1485 ms of delay | |||||
memory, so the total of all objects using AUDIO_MEMORY_MEMORYBOARD must not | |||||
exceed the amount of memory physically present. | |||||
</p> | |||||
<h3>Examples</h3> | |||||
<p> | |||||
<a href="https://www.youtube.com/watch?v=d80d1HWy5_s" target="_blank">Demo Video</a> (YouTube) | |||||
</p> | |||||
<!-- <p class=exam>File > Examples > Audio > Effects > Delay | |||||
</p> --> | |||||
<p> | |||||
<a href="https://forum.pjrc.com/threads/29276-Limits-of-delay-effect-in-audio-library?p=79436&viewfull=1#post79436" target="_blank">Forum Conversaton</a> (with sample code) | |||||
</p> | |||||
<h3>Notes</h3> | |||||
<p>External RAM allows for longer delays without consuming | |||||
limited internal RAM. However, SPI communication is required, | |||||
which consumes much more CPU time. The | |||||
<a href="http://www.pjrc.com/teensy/td_libs_AudioProcessorUsage.html">AudioProcessorUsageMax</a> | |||||
function may be used to monitor how much CPU time is consumed. | |||||
</p> | |||||
<p>You may specify the type of hardware to be used by editing the code. AUDIO_MEMORY_23LC1024 | |||||
specifies a single 23LC1024 chip. AUDIO_MEMORY_MEMORYBOARD allows using up to 6 of these | |||||
chips. | |||||
</p> | |||||
<p class=desc><span class=keyword>AudioEffectDelayExternal</span> delayExt1(<span class=literal>AUDIO_MEMORY_23LC1024</span>); | |||||
</p> | |||||
<p>You may also create more than one delay using the same hardware, where the memory is partitioned | |||||
by specifying a maximum delay in milliseconds. This can be useful if you wish to delay both | |||||
channels of a stereo signal. | |||||
<p class=desc><span class=keyword>AudioEffectDelayExternal</span> delayExt1(<span class=literal>AUDIO_MEMORY_23LC1024</span>, 700);<br><span class=keyword>AudioEffectDelayExternal</span> delayExt2(<span class=literal>AUDIO_MEMORY_23LC1024</span>, 700); | |||||
</p> |
<h3>Summary</h3> | |||||
<div> | |||||
<p>Modify a signal with a DAHDSR (Delay Attack Hold Decay Sustain | |||||
Release) envelope. | |||||
</p> | |||||
<p align=center><img src="img/dahdsr.png"></p> | |||||
</div> | |||||
<h3>Audio Connections</h3> | |||||
<table class=doc align=center cellpadding=3> | |||||
<tr class=top><th>Port</th><th>Purpose</th></tr> | |||||
<tr class=odd><td align=center>In 0</td><td>Signal Input</td></tr> | |||||
<tr class=odd><td align=center>Out 0</td><td>Signal with Envelope Applied</td></tr> | |||||
</table> | |||||
<h3>Functions</h3> | |||||
<p class=func><span class=keyword>noteOn</span>();</p> | |||||
<p class=desc>Begin the delay to attack, or the attack phase is | |||||
delay is zero. | |||||
</p> | |||||
<p class=func><span class=keyword>noteOff</span>();</p> | |||||
<p class=desc>Begin the release phase. | |||||
</p> | |||||
<p class=func><span class=keyword>delay</span>(milliseconds);</p> | |||||
<p class=desc>Set the delay from noteOn to the attach phase. The | |||||
default is zero, for no delay. | |||||
</p> | |||||
<p class=func><span class=keyword>attack</span>(milliseconds);</p> | |||||
<p class=desc>Set the attack time. The default is 1.5 milliseconds. | |||||
</p> | |||||
<p class=func><span class=keyword>hold</span>(milliseconds);</p> | |||||
<p class=desc>Set the hold time. The default is 0.5 milliseconds. | |||||
</p> | |||||
<p class=func><span class=keyword>decay</span>(milliseconds);</p> | |||||
<p class=desc>Set the decay time. The default is 15 milliseconds. | |||||
</p> | |||||
<p class=func><span class=keyword>sustain</span>(level);</p> | |||||
<p class=desc>Set the sustain level. The range is 0 to 1.0. The | |||||
gain will be maintained at this level after the decay phase, | |||||
until noteOff() is called. | |||||
</p> | |||||
<p class=func><span class=keyword>release</span>(milliseconds);</p> | |||||
<p class=desc>Set the release time. The default is 30 millisecond. | |||||
</p> | |||||
<h3>Examples</h3> | |||||
<p class=exam>File > Examples > Audio > Synthesis > PlaySynthMusic | |||||
</p> | |||||
<p class=exam>File > Examples > Audio > Synthesis > pulseWidth | |||||
</p> | |||||
<p class=exam>File > Examples > Audio > MemoryAndCpuUsage | |||||
</p> | |||||
<h3>Notes</h3> | |||||
<p>To achieve the more common ADSR shape, simply | |||||
set delay and hold to zero.</p> | |||||
<p>The recommended range for each of the 5 timing inputs is 0 to 50 | |||||
milliseconds. Up to 200 ms can be used, with somewhat reduced | |||||
accuracy</p> |
<h3>Summary</h3> | |||||
<p>Gradually increase or decrease audio level.</p> | |||||
<h3>Audio Connections</h3> | |||||
<table class=doc align=center cellpadding=3> | |||||
<tr class=top><th>Port</th><th>Purpose</th></tr> | |||||
<tr class=odd><td align=center>In 0</td><td>Signal Input</td></tr> | |||||
<tr class=odd><td align=center>Out 0</td><td>Signal Output</td></tr> | |||||
</table> | |||||
<h3>Functions</h3> | |||||
<p class=func><span class=keyword>fadeIn</span>(milliseconds);</p> | |||||
<p class=desc>Begin increasing the audio level, to reach 1.0 (input passed | |||||
directly to the output) after "milliseconds" time. | |||||
</p> | |||||
<p class=func><span class=keyword>fadeOut</span>(milliseconds);</p> | |||||
<p class=desc>Begin decreasing the audio level, to reach 0 (no output) | |||||
after "milliseconds" time. | |||||
</p> | |||||
<!--<h3>Examples</h3> | |||||
<p class=exam>File > Examples > Audio > | |||||
</p>--> | |||||
<h3>Notes</h3> | |||||
<p>Cross fading can be built with 2 fade objects fed into a mixer. | |||||
When one fade object is off (fully faded out) and the other on | |||||
(fully faded in), if both are started at the same moment for the | |||||
same time duration, their signal gains always add to 1.0. This | |||||
allows 2 fade objects to work together for a smooth transition | |||||
between a pair of signals. | |||||
</p> | |||||
<p><a href="http://www.pjrc.com/teensy/td_libs_AudioProcessorUsage.html" target="_blank">AudioNoInterrupts()</a> | |||||
should be used when changing | |||||
settings on multiple objects, so all changes always take effect | |||||
at the same moment. | |||||
</p> |
<h3>Summary</h3> | |||||
<p>Originally, flanging was produced by playing the same signal on two synchronized | |||||
reel-to-reel tape recorders and making one of the reels slow down and speed up by | |||||
pressing on the flange of the reel (hence the name). This is a type of | |||||
comb filtering, and produces a harmonically-related series of peaks and notches | |||||
in the audio spectrum.</p> | |||||
<p>This flanger uses a delay line, combining the original voice with only one sample from the delay | |||||
line, but the position of that sample varies sinusoidally.</p> | |||||
<p>The effect can be represented as:<br> | |||||
result = sample(0) + sample(dt + depth*sin(2*PI*Fe))</p> | |||||
<p>The value of the sine function is always a number from -1 to +1 and | |||||
so the result of depth*(sin(Fe)) is always a number from -depth to +depth. | |||||
Thus, the delayed sample will be selected from the range (dt-depth) to | |||||
(dt+depth). This selection will vary at whatever rate is specified as the | |||||
frequency of the effect, Fe. Typically a low frequency (a few Hertz) is used. | |||||
<h3>Audio Connections</h3> | |||||
<table class=doc align=center cellpadding=3> | |||||
<tr class="top"><th>Port</th><th>Purpose</th></tr> | |||||
<tr class="odd"><td align="center">In 0</td><td>Signal Input</td></tr> | |||||
<tr class="odd"><td align="center">Out 0</td><td>Flanged Output</td></tr> | |||||
</table> | |||||
<h3>Functions</h3> | |||||
<p class=func><span class=keyword>begin</span>(delayBuffer, length, offset, depth, delayRate);</p> | |||||
<p class=desc>Create a flanger by specifying the address of the delayline, the | |||||
total number of samples in the delay line (often done as an integer multiple of | |||||
AUDIO_BLOCK_SAMPLES), the offset (how far back the flanged sample is from the original voice), | |||||
the modulation depth (larger values give a greater variation) and the modulation | |||||
frequency, in Hertz. | |||||
</p> | |||||
<p class=func><span class=keyword>modify</span>(offset, depth, delayRate);</p> | |||||
<p class=desc>Alters the parameters in a running flanger (previously started with begin). | |||||
</p> | |||||
<h3>Examples</h3> | |||||
<p class=exam>File > Examples > Audio > Effects > Flange | |||||
</p> | |||||
<h3>Notes</h3> | |||||
<p>The longer the length of the delay buffer, the more memory blocks are used.</p> | |||||
<p>Try these settings:<br> | |||||
#define FLANGE_DELAY_LENGTH (2*AUDIO_BLOCK_SAMPLES)<br> | |||||
and<br> | |||||
int s_idx = 2*FLANGE_DELAY_LENGTH/4;<br> | |||||
int s_depth = FLANGE_DELAY_LENGTH/4;<br> | |||||
double s_freq = 3;</p> | |||||
<p>The flange effect can also produce a chorus-like effect if a longer | |||||
delay line is used with a slower modulation rate, for example try:<br> | |||||
#define FLANGE_DELAY_LENGTH (12*AUDIO_BLOCK_SAMPLES)<br> | |||||
and<br> | |||||
int s_idx = 3*FLANGE_DELAY_LENGTH/4;<br> | |||||
int s_depth = FLANGE_DELAY_LENGTH/8;<br> | |||||
double s_freq = .0625;</p> |
<h3>Summary</h3> | |||||
<div> | |||||
<p>Multiply two signals together, useful for amplitude modulation | |||||
or "voltage controlled amplification". | |||||
</p> | |||||
<p align=center><img src="img/multiply.png"><br><small>56 Hz and 1 kHz sine waves multiplied.</small></p> | |||||
</div> | |||||
<h3>Audio Connections</h3> | |||||
<table class=doc align=center cellpadding=3> | |||||
<tr class=top><th>Port</th><th>Purpose</th></tr> | |||||
<tr class=odd><td align=center>In 0</td><td>Signal Input</td></tr> | |||||
<tr class=odd><td align=center>In 1</td><td>Signal Input</td></tr> | |||||
<tr class=odd><td align=center>Out 0</td><td>Signal with Envelope Applied</td></tr> | |||||
</table> | |||||
<h3>Functions</h3> | |||||
<p>There are no functions to call from the Arduino sketch. | |||||
This object simply multiplies the 2 signals to create | |||||
a continuous output | |||||
</p> | |||||
<!--<h3>Examples</h3> | |||||
<p class=exam>File > Examples > Audio > | |||||
</p>--> | |||||
<h3>Notes</h3> | |||||
<p> | |||||
</p> |
<h3>Summary</h3> | |||||
<div> | |||||
<p>Biquadratic cascaded filter, useful for all sorts of filtering. | |||||
Up to 4 stages may be cascaded. | |||||
</p> | |||||
<p align=center><img src="img/biquad.png"></p> | |||||
</div> | |||||
<h3>Audio Connections</h3> | |||||
<table class=doc align=center cellpadding=3> | |||||
<tr class=top><th>Port</th><th>Purpose</th></tr> | |||||
<tr class=odd><td align=center>In 0</td><td>Signal to be filtered</td></tr> | |||||
<tr class=odd><td align=center>Out 0</td><td>Filtered Signal Output</td></tr> | |||||
</table> | |||||
<h3>Functions</h3> | |||||
<p class=func><span class=keyword>setLowpass</span>(stage, frequency, Q);</p> | |||||
<p class=desc>Configure one stage of the filter (0 to 3) with low pass | |||||
response, with the specified corner frequency and Q shape. If Q is | |||||
higher that 0.7071, be careful of filter gain (see below). | |||||
</p> | |||||
<p class=func><span class=keyword>setHighpass</span>(stage, frequency, Q);</p> | |||||
<p class=desc>Configure one stage of the filter (0 to 3) with high pass | |||||
response, with the specified corner frequency and Q shape. If Q is | |||||
higher that 0.7071, be careful of filter gain (see below). | |||||
</p> | |||||
<p class=func><span class=keyword>setBandpass</span>(stage, frequency, Q);</p> | |||||
<p class=desc>Configure one stage of the filter (0 to 3) with band pass | |||||
response. The filter has unity gain at the specified frequency. Q | |||||
controls the width of frequencies allowed to pass. | |||||
</p> | |||||
<p class=func><span class=keyword>setNotch</span>(stage, frequency, Q);</p> | |||||
<p class=desc>Configure one stage of the filter (0 to 3) with band reject (notch) | |||||
response. Q controls the width of rejected frequencies. | |||||
</p> | |||||
<p class=func><span class=keyword>setCoefficients</span>(stage, array[5]);</p> | |||||
<p class=desc>Configure one stage of the filter (0 to 3) with an arbitrary | |||||
filter response. The array of coefficients is in order: B0, B1, B2, A1, A2. | |||||
Each coefficient must be less than 2.0 and greater than -2.0. The array | |||||
should be type double. Alternately, it may be type int, where 1.0 is | |||||
represented with 1073741824 (2<sup>30</sup>). | |||||
</p> | |||||
<h3>Examples</h3> | |||||
<p class=exam>File > Examples > Audio > Effects > Filter | |||||
</p> | |||||
<h3>Notes</h3> | |||||
<p>Filters can with gain must have their input signals attenuated, so the | |||||
signal does not exceed 1.0. | |||||
</p> | |||||
<p>This object implements up to 4 cascaded stages. Unconfigured stages will | |||||
not pass any signal. | |||||
</p> | |||||
<p>Biquad filters with low corner frequency (under about 400 Hz) can run into | |||||
trouble with limited numerical precision, causing the filter to perform | |||||
poorly. For very low corner frequency, the State Variable (Chamberlin) | |||||
filter should be used. | |||||
</p> |
<h3>Summary</h3> | |||||
<div> | |||||
<p>Finite impulse response filter, useful for all sorts of filtering. | |||||
</p> | |||||
<p align=center><img src="img/fir_filter.png"></p> | |||||
</div> | |||||
<h3>Audio Connections</h3> | |||||
<table class=doc align=center cellpadding=3> | |||||
<tr class=top><th>Port</th><th>Purpose</th></tr> | |||||
<tr class=odd><td align=center>In 0</td><td>Signal to be filtered</td></tr> | |||||
<tr class=odd><td align=center>Out 0</td><td>Filtered Signal Output</td></tr> | |||||
</table> | |||||
<h3>Functions</h3> | |||||
<p class=func><span class=keyword>begin</span>(array, length);</p> | |||||
<p class=desc>Initialize the filter. The array must be 16 bit integers (the | |||||
filter's impulse response), and | |||||
length indicates the number of points in the array. Array may also be | |||||
FIR_PASSTHRU (length = 0), to directly pass the input to output without | |||||
filtering. | |||||
</p> | |||||
<p class=func><span class=keyword>end</span>();</p> | |||||
<p class=desc>Turn the filter off. | |||||
</p> | |||||
<h3>Examples</h3> | |||||
<p class=exam>File > Examples > Audio > Effects > Filter_FIR | |||||
</p> | |||||
<h3>Notes</h3> | |||||
<p>FIR filters requires more CPU time than Biquad (IIR), but they can | |||||
implement filters with better phase response. | |||||
</p> | |||||
<p>A 100 point filter requires 9% CPU time on Teensy 3.1. The maximum | |||||
supported filter length is 200 points. | |||||
</p> | |||||
<p>The free | |||||
<a href="http://t-filter.appspot.com/fir/index.html" target="_blank"> TFilter Design Tool</a> | |||||
can be used to create the impulse response array. Be sure to set the sampling | |||||
frequency to 44117 HZ (it defaults to only 2000 Hz) and the output type to "int" (16 bit). | |||||
</p> | |||||
<p> | |||||
If you use TFilter Design's "C/C++ array" option, it's output has "int" definition, which | |||||
is 32 bits on Teensy 3.1. Edit "int" to "short" for an array of 16 bit numbers, | |||||
and add "const" to avoid consuming extra RAM. | |||||
</p> |
<h3>Summary</h3> | |||||
<p>A State Variable (Chamberlin) Filter with 12 dB/octave roll-off, | |||||
adjustable resonance, and optional signal control of corner | |||||
frequency.</p> | |||||
<h3>Audio Connections</h3> | |||||
<table class=doc align=center cellpadding=3> | |||||
<tr class=top><th>Port</th><th>Purpose</th></tr> | |||||
<tr class=odd><td align=center>In 0</td><td>Signal to Filter</td></tr> | |||||
<tr class=odd><td align=center>In 1</td><td>Frequency Control</td></tr> | |||||
<tr class=odd><td align=center>Out 0</td><td>Low Pass Output</td></tr> | |||||
<tr class=odd><td align=center>Out 1</td><td>Band Pass Output</td></tr> | |||||
<tr class=odd><td align=center>Out 2</td><td>High Pass Output</td></tr> | |||||
</table> | |||||
<h3>Functions</h3> | |||||
<p class=func><span class=keyword>frequency</span>(freq);</p> | |||||
<p class=desc>Set the filter's corner frequency. When a signal is | |||||
connected to the control input, the filter will implement this | |||||
frequency when the signal is zero. | |||||
</p> | |||||
<p class=func><span class=keyword>resonance</span>(Q);</p> | |||||
<p class=desc>Set the filter's resonance. Q ranges from 0.7 to 5.0. | |||||
Resonance greater than 0.707 will amplify the signal near the | |||||
corner frequency. You must attenuate the signal before input | |||||
to this filter, to prevent clipping. | |||||
</p> | |||||
<p class=func><span class=keyword>octaveControl</span>(octaves);</p> | |||||
<p class=desc>Set how much (in octaves) the control signal can alter | |||||
the filter's corner freqency. Range is 0 to 7 octaves. For | |||||
example, when set to 2.5, a full scale positive signal (1.0) will | |||||
shift the filter frequency up 2.5 octaves, and a full scale negative | |||||
signal will shift it down 2.5 octaves. | |||||
</p> | |||||
<!--<h3>Examples</h3> | |||||
<p class=exam>File > Examples > Audio > | |||||
</p>--> | |||||
<h3>Notes</h3> | |||||
<p> | |||||
When controlled by a signal, the equation for the filter | |||||
frequency is: | |||||
</p> | |||||
<p> | |||||
F = Fcenter * 2^<sup>(signal * octaves)</sup> | |||||
<br><small>If anyone knows how to do HTML equations, please | |||||
help me improve this.....</small> | |||||
</p> | |||||
<p>When operating with signal control of corner frequency, this | |||||
object uses approximately 4% of the CPU time on Teensy 3.1. | |||||
</p> |
<h3>Summary</h3> | |||||
<p>Receive audio using the built-in analog to digital converter.</p> | |||||
<h3>Audio Connections</h3> | |||||
<table class=doc align=center cellpadding=3> | |||||
<tr class=top><th>Port</th><th>Purpose</th></tr> | |||||
<tr class=odd><td align=center>Out 0</td><td>Audio Channel</td></tr> | |||||
</table> | |||||
<h3>Functions</h3> | |||||
<p>This object has no functions to call from the Arduino sketch. It | |||||
simply streams data from the ADC to its output port.</p> | |||||
<h3>Hardware</h3> | |||||
<p>Pin A2 is used for audio input. This circuitry is recommended.</p> | |||||
<p align=center><img src="img/adccircuit.png"></p> | |||||
<p>Signal range is 0 to 1.2V</p> | |||||
<h3>Examples</h3> | |||||
<p class=exam>File > Examples > Audio > HardwareTesting > PassThroughMono | |||||
</p> | |||||
<p class=exam>File > Examples > Audio > Analysis > PeakMeterMono | |||||
</p> | |||||
<p class=exam>File > Examples > Audio > Analysis > DialTone_7segment | |||||
</p> | |||||
<h3>Notes</h3> | |||||
<p>A different pin may be used, but adding it as an parameter | |||||
to the AudioInputAnalog object definition. | |||||
</p> | |||||
<p>For example, to use pin A3: | |||||
</p> | |||||
<p class=desc><span class=keyword>AudioInputAnalog</span> adc1(<span class=literal>A3</span>); | |||||
</p> | |||||
<p>Noise due to high source impedance, which allows rapidly switching digital signals | |||||
to capacitively couple... avoiding higher analog impedance is the solution.</p> | |||||
<p>Power Supply rejection issue with simple DC bias (bigger capacitor may be needed if 3.3V has low frequency noise)</p> | |||||
<p>Algorithm for automatic DC bias tracking</p> | |||||
<p>TODO: actual noise measurements with different input circuitry | |||||
(it's not as quiet as the audio shield)</p> |
<h3>Summary</h3> | |||||
<p>Receive 16 bit stereo audio from the | |||||
<a href="http://www.pjrc.com/store/teensy3_audio.html" target="_blank">audio shield</a> | |||||
or another I2S device, using I2S master mode.</p> | |||||
<p align=center><img src="img/audioshield_inputs.jpg"></p> | |||||
<h3>Audio Connections</h3> | |||||
<table class=doc align=center cellpadding=3> | |||||
<tr class=top><th>Port</th><th>Purpose</th></tr> | |||||
<tr class=odd><td align=center>Out 0</td><td>Left Channel</td></tr> | |||||
<tr class=odd><td align=center>Out 1</td><td>Right Channel</td></tr> | |||||
</table> | |||||
<h3>Functions</h3> | |||||
<p>This object has no functions to call from the Arduino sketch. It | |||||
simply streams data from the I2S hardware to its 2 output ports.</p> | |||||
<h3>Hardware</h3> | |||||
<p align=center><img src="img/audioshield_backside.jpg"></p> | |||||
<p>The I2S signals are used in "master" mode, where Teensy creates | |||||
all 3 clock signals and controls all data timing.</p> | |||||
<table class=doc align=center cellpadding=3> | |||||
<tr class=top><th>Pin</th><th>Signal</th><th>Direction</th></tr> | |||||
<tr class=odd><td align=center>9</td><td>BCLK</td><td>Output</td></tr> | |||||
<tr class=odd><td align=center>11</td><td>MCLK</td><td>Output</td></tr> | |||||
<tr class=odd><td align=center>13</td><td>RX</td><td>Input</td></tr> | |||||
<tr class=odd><td align=center>23</td><td>LRCLK</td><td>Output</td></tr> | |||||
</table> | |||||
<p>Audio from | |||||
master mode I2S may be used in the same project as ADC, DAC and | |||||
PWM signals, because all remain in sync to Teensy's timing</p> | |||||
<h3>Examples</h3> | |||||
<p class=exam>File > Examples > Audio > HardwareTesting > PassThroughStereo | |||||
</p> | |||||
<p class=exam>File > Examples > Audio > Recorder | |||||
</p> | |||||
<p class=exam>File > Examples > Audio > Analysis > PeakMeterStereo | |||||
</p> | |||||
<p class=exam>File > Examples > Audio > Analysis > FFT | |||||
</p> | |||||
<p class=exam>File > Examples > Audio > Analysis > SpectrumAnalyzerBasic | |||||
</p> | |||||
<p class=exam>File > Examples > Audio > Effects > Chorus | |||||
</p> | |||||
<p class=exam>File > Examples > Audio > Effects > Flange | |||||
</p> | |||||
<p class=exam>File > Examples > Audio > Effects > Filter | |||||
</p> | |||||
<p class=exam>File > Examples > Audio > Effects > Filter_FIR | |||||
</p> | |||||
<h3>Notes</h3> | |||||
<p>Normally, this object is used with the Audio Shield, which | |||||
is controlled separately by the "sgtl5000" object.</p> | |||||
<p>Only one I2S input and one I2S output object may be used. Master | |||||
and slave modes may not be mixed (both must be of the same type). | |||||
</p> | |||||
<p>I2S master objects can be used together with non-I2S input and output | |||||
objects, for simultaneous audio streaming on different hardware.</p> |
<h3>Summary</h3> | |||||
<p>Receive 16 bit stereo audio from an I2S device using I2S slave mode.</p> | |||||
<h3>Audio Connections</h3> | |||||
<table class=doc align=center cellpadding=3> | |||||
<tr class=top><th>Port</th><th>Purpose</th></tr> | |||||
<tr class=odd><td align=center>Out 0</td><td>Left Channel</td></tr> | |||||
<tr class=odd><td align=center>Out 1</td><td>Right Channel</td></tr> | |||||
</table> | |||||
<h3>Functions</h3> | |||||
<p>This object has no functions to call from the Arduino sketch. It | |||||
simply streams data from the I2S hardware to its 2 output ports.</p> | |||||
<h3>Hardware</h3> | |||||
<p>The I2S signals are used in "slave" mode, where the I2S device controls | |||||
data timing.</p> | |||||
<table class=doc align=center cellpadding=3> | |||||
<tr class=top><th>Pin</th><th>Signal</th><th>Direction</th></tr> | |||||
<tr class=odd><td align=center>9</td><td>BCLK</td><td>Input</td></tr> | |||||
<tr class=odd><td align=center>13</td><td>RX</td><td>Input</td></tr> | |||||
<tr class=odd><td align=center>23</td><td>LRCLK</td><td>Input</td></tr> | |||||
</table> | |||||
<!--<h3>Examples</h3> | |||||
<p class=exam>File > Examples > Audio > | |||||
</p>--> | |||||
<h3>Notes</h3> | |||||
<p>Slave mode I2S <b>should not used in the same project as ADC, DAC and | |||||
PWM</b> signals. Differences in timing between the I2S device and | |||||
Teensy's clock can cause occasional audio glitches when I2S slave mode | |||||
is used together with other input or output objects based on Teensy's | |||||
timing.</p> | |||||
<p>Only one I2S input and one I2S output object may be used. Master | |||||
and slave modes may not be mixed (both must be of the same type). | |||||
</p> |
<h3>Summary</h3> | |||||
<p>Combine up to 4 audio signals together, each with adjustable gain. | |||||
All channels support signal attenuation or amplification.</p> | |||||
<h3>Audio Connections</h3> | |||||
<table class=doc align=center cellpadding=3> | |||||
<tr class=top><th>Port</th><th>Purpose</th></tr> | |||||
<tr class=odd><td align=center>In 0</td><td>Input signal #1</td></tr> | |||||
<tr class=odd><td align=center>In 1</td><td>Input signal #2</td></tr> | |||||
<tr class=odd><td align=center>In 2</td><td>Input signal #3</td></tr> | |||||
<tr class=odd><td align=center>In 3</td><td>Input signal #4</td></tr> | |||||
<tr class=odd><td align=center>Out 0</td><td>Sum of all inputs</td></tr> | |||||
</table> | |||||
<h3>Functions</h3> | |||||
<p class=func><span class=keyword>gain</span>(channel, level);</p> | |||||
<p class=desc>Adjust the amplification or attenuation. "channel" must | |||||
be 0 to 3. "level" may be any floating point number from 0 to 32767. | |||||
1.0 passes the signal through directly. Level of 0 shuts the channel | |||||
off completely. Between 0 to 1.0 attenuates the signal, and above | |||||
1.0 amplifies it. All 4 channels have separate settings. | |||||
</p> | |||||
<h3>Examples</h3> | |||||
<p class=exam>File > Examples > Audio > SamplePlayer | |||||
</p> | |||||
<p class=exam>File > Examples > Audio > Synthesis > PlaySynthMusic | |||||
</p> | |||||
<p class=exam>File > Examples > Audio > Analysis > SpectrumAnalyzerBasic | |||||
</p> | |||||
<p class=exam>File > Examples > Audio > Analysis > DialTone_Serial | |||||
</p> | |||||
<p class=exam>File > Examples > Audio > MemoryAndCpuUsage | |||||
</p> | |||||
<h3>Notes</h3> | |||||
<p>Signal clipping can occur when any channel has gain greater than 1.0, | |||||
or when multiple signals add together to greater than 1.0.</p> | |||||
<p>More than 4 channels may be combined by connecting multiple mixers | |||||
in tandem. For example, a 16 channel mixer may be built using 5 | |||||
mixers, where the fifth mixer combines the outputs of the first 4. | |||||
</p> |
<h3>Summary</h3> | |||||
<p>Transmit 12 bit audio using Teensy 3.1's built-in digital to analog converter.</p> | |||||
<h3>Audio Connections</h3> | |||||
<table class=doc align=center cellpadding=3> | |||||
<tr class=top><th>Port</th><th>Purpose</th></tr> | |||||
<tr class=odd><td align=center>In 0</td><td>Audio Channel</td></tr> | |||||
</table> | |||||
<h3>Functions</h3> | |||||
<p>This object has no functions to call from the Arduino sketch. It | |||||
simply streams data from the ADC to its output port.</p> | |||||
<h3>Hardware</h3> | |||||
<p align=center><img src="img/dacpin.jpg"></p> | |||||
<p>Signal range is 0 to 1.2V</p> | |||||
<p>Most applications require at least a 10µF DC-blocking capacitor.</p> | |||||
<p>TODO: photo of Teensy 3.1 with 10µF capacitor and 3.5mm jack.</p> | |||||
<h3>Examples</h3> | |||||
<p class=exam>File > Examples > Audio > HardwareTesting > PassThroughMono | |||||
</p> | |||||
<p class=exam>File > Examples > Audio > SamplePlayer | |||||
</p> | |||||
<h3>Notes</h3> | |||||
<p>The output rate is 44.1 kHz (no oversampling). Ultrasonic noise present if | |||||
not filtered. This may not | |||||
be an issue for many uses, but care should be used if amplified and driven | |||||
to high power tweeters.</p> |
<h3>Summary</h3> | |||||
<p>Transmit 16 bit stereo audio to the | |||||
<a href="http://www.pjrc.com/store/teensy3_audio.html" target="_blank">audio shield</a> | |||||
or another I2S device, using I2S master mode.</p> | |||||
<p align=center><img src="img/audioshield_outputs.jpg"></p> | |||||
<h3>Audio Connections</h3> | |||||
<table class=doc align=center cellpadding=3> | |||||
<tr class=top><th>Port</th><th>Purpose</th></tr> | |||||
<tr class=odd><td align=center>In 0</td><td>Left Channel</td></tr> | |||||
<tr class=odd><td align=center>In 1</td><td>Right Channel</td></tr> | |||||
</table> | |||||
<h3>Functions</h3> | |||||
<p>This object has no functions to call from the Arduino sketch. It | |||||
simply streams data from its 2 input ports to the I2S hardware.</p> | |||||
<h3>Hardware</h3> | |||||
<p align=center><img src="img/audioshield_backside.jpg"></p> | |||||
<p>The I2S signals are used in "master" mode, where Teensy creates | |||||
all 3 clock signals and controls all data timing.</p> | |||||
<table class=doc align=center cellpadding=3> | |||||
<tr class=top><th>Pin</th><th>Signal</th><th>Direction</th></tr> | |||||
<tr class=odd><td align=center>9</td><td>BCLK</td><td>Output</td></tr> | |||||
<tr class=odd><td align=center>11</td><td>MCLK</td><td>Output</td></tr> | |||||
<tr class=odd><td align=center>22</td><td>TX</td><td>Output</td></tr> | |||||
<tr class=odd><td align=center>23</td><td>LRCLK</td><td>Output</td></tr> | |||||
</table> | |||||
<p>Audio from | |||||
master mode I2S may be used in the same project as ADC, DAC and | |||||
PWM signals, because all remain in sync to Teensy's timing</p> | |||||
<h3>Examples</h3> | |||||
<p>Nearly all the examples use this object. Here are some of the highlights:</p> | |||||
<p class=exam>File > Examples > Audio > HardwareTesting > PassThroughStereo | |||||
</p> | |||||
<p class=exam>File > Examples > Audio > SamplePlayer | |||||
</p> | |||||
<p class=exam>File > Examples > Audio > Recorder | |||||
</p> | |||||
<p class=exam>File > Examples > Audio > WavFilePlayer | |||||
</p> | |||||
<p class=exam>File > Examples > Audio > Effects > Chorus | |||||
</p> | |||||
<p class=exam>File > Examples > Audio > Synthesis > PlaySynthMusic | |||||
</p> | |||||
<h3>Notes</h3> | |||||
<p>Normally, this object is used with the Audio Shield, which | |||||
is controlled separately by the "sgtl5000" object.</p> | |||||
<p>Only one I2S input and one I2S output object may be used. Master | |||||
and slave modes may not be mixed (both must be of the same type). | |||||
</p> |
<h3>Summary</h3> | |||||
<p>Transmit 16 bit stereo audio to an I2S device using I2S slave mode.</p> | |||||
<h3>Audio Connections</h3> | |||||
<table class=doc align=center cellpadding=3> | |||||
<tr class=top><th>Port</th><th>Purpose</th></tr> | |||||
<tr class=odd><td align=center>In 0</td><td>Left Channel</td></tr> | |||||
<tr class=odd><td align=center>In 1</td><td>Right Channel</td></tr> | |||||
</table> | |||||
<h3>Functions</h3> | |||||
<p>This object has no functions to call from the Arduino sketch. It | |||||
simply streams data from its 2 input ports to the I2S hardware.</p> | |||||
<h3>Hardware</h3> | |||||
<p>The I2S signals are used in "slave" mode, where the I2S device controls | |||||
data timing.</p> | |||||
<table class=doc align=center cellpadding=3> | |||||
<tr class=top><th>Pin</th><th>Signal</th><th>Direction</th></tr> | |||||
<tr class=odd><td align=center>9</td><td>BCLK</td><td>Input</td></tr> | |||||
<tr class=odd><td align=center>22</td><td>TX</td><td>Output</td></tr> | |||||
<tr class=odd><td align=center>23</td><td>LRCLK</td><td>Input</td></tr> | |||||
</table> | |||||
<h3>Examples</h3> | |||||
<p class=exam>File > Examples > Audio > HardwareTesting > WM8731MikroSine | |||||
</p> | |||||
<h3>Notes</h3> | |||||
<p>Slave mode I2S <b>should not used in the same project as ADC, DAC and | |||||
PWM</b> signals. Differences in timing between the I2S device and | |||||
Teensy's clock can cause occasional audio glitches when I2S slave mode | |||||
is used together with other input or output objects based on Teensy's | |||||
timing.</p> | |||||
<p>Only one I2S input and one I2S output object may be used. Master | |||||
and slave modes may not be mixed (both must be of the same type). | |||||
</p> |
<h3>Summary</h3> | |||||
<p>Transmit audio using Teensy 3.1's PWM pins. Two pins are | |||||
used for coarse and fine pulses, to be combined by scaled | |||||
resistors.</p> | |||||
<h3>Audio Connections</h3> | |||||
<table class=doc align=center cellpadding=3> | |||||
<tr class=top><th>Port</th><th>Purpose</th></tr> | |||||
<tr class=odd><td align=center>In 0</td><td>Audio Channel</td></tr> | |||||
</table> | |||||
<h3>Functions</h3> | |||||
<p>This object has no functions to call from the Arduino sketch. It | |||||
simply streams data from the its input port to the PWM pins.</p> | |||||
<h3>Hardware</h3> | |||||
<p>The following circuit is recommended.</p> | |||||
<p align=center><img src="img/pwmdualcircuit.jpg"></p> | |||||
<p>Signal range is approx 1.55 Vp-p.</p> | |||||
<p>These resistor values assume approx 20 ohms output impedance | |||||
on the digital pins. The 127K resistor may be adjusted or | |||||
trimmed for variation in output drive and tolerance on the | |||||
475 ohm resistor.</p> | |||||
<p>A plastic film (Polypropylene, Polyethylene, Polyester, etc) or | |||||
C0G/NPO ceramic capacitor should be used for filtering. Low | |||||
quality ceramic (X7R, Y5V, Z5U, etc) can cause signal distortion.</p> | |||||
<h3>Examples</h3> | |||||
<p class=exam>File > Examples > Audio > HardwareTesting > PassThroughMono | |||||
</p> | |||||
<h3>Notes</h3> | |||||
<p>This object only works properly when Tools > CPU_Speed is set to | |||||
48 or 96 MHz. Other speeds aren't supported and will likely fail | |||||
in strange ways.</p> | |||||
<p>The PWM carrier frequency is 88.2 kHz. The suggested circuit | |||||
will only slightly filter the carrier. Extra filtering will be | |||||
required for a clean signal without the ultrasonic PWM carrier. | |||||
</p> | |||||
<p>Analog signals created by filtering PWM waveforms use the digital | |||||
power supply as their reference voltage. Any noise on the digital | |||||
power line can directly couple to the output signal. The built-in DAC or | |||||
<a href="http://www.pjrc.com/store/teensy3_audio.html" target="_blank">audio shield</a> | |||||
should be used when higher quality signals are needed.</p> |
<h3>Summary</h3> | |||||
<p>Transmit 16 bit stereo audio as Digital S/PDIF.</p> | |||||
<p align=center><img src="img/spdif_proto.jpg"></p> | |||||
<h3>Audio Connections</h3> | |||||
<table class=doc align=center cellpadding=3> | |||||
<tr class=top><th>Port</th><th>Purpose</th></tr> | |||||
<tr class=odd><td align=center>In 0</td><td>Left Channel</td></tr> | |||||
<tr class=odd><td align=center>In 1</td><td>Right Channel</td></tr> | |||||
</table> | |||||
<h3>Functions</h3> | |||||
<p>This object has no functions to call from the Arduino sketch. It | |||||
simply streams data from its 2 input ports S/PDIF encoded digital | |||||
audio on pin 22.</p> | |||||
<h3>Hardware</h3> | |||||
<p>The S/PDIF output signal can be used to drive an optical TOSLINK | |||||
cable, or a standard (usually orange) RCA jack.</p> | |||||
<table class=doc align=center cellpadding=3> | |||||
<tr class=top><th>Pin</th><th>Signal</th><th>Direction</th></tr> | |||||
<tr class=odd><td align=center>22</td><td>S/PDIF</td><td>Output</td></tr> | |||||
</table> | |||||
<p>For optical TOSLINK output, this | |||||
<a href="https://www.oshpark.com/shared_projects/KcDBKHta" target="_blank">OSH Park board</a> | |||||
can be used with the inexpensive Everlight PLT133/T6A connector, available | |||||
at Digikey, 1080-1434-ND. | |||||
</p> | |||||
<h3>Examples</h3> | |||||
<p>The AudioOutputSPDIF object can be used in place of the AudioOutputI2S object, | |||||
<p>used in nearly all the examples. The WavFilePlayer shows how to substitute | |||||
output objects for different hardware types. | |||||
</p> | |||||
<p class=exam>File > Examples > Audio > WavFilePlayer | |||||
</p> | |||||
<h3>Credits</h3> | |||||
<p><a href="https://github.com/FrankBoesing" target="_blank">Frank Boesing</a> | |||||
developed the AudioOutputSPDIF code. The original | |||||
<a href="https://forum.pjrc.com/threads/28639-S-pdif" target="_blank">forum disussion</a> | |||||
included valuable input and code from "kpc". | |||||
<h3>Notes</h3> | |||||
<p>S/PDIF output uses the I2S hardware. This object can not be used | |||||
together with any of the I2S objects, because it requires the I2S | |||||
hardware with different internal settings.</p> | |||||
</p> |
<h3>Summary</h3> | |||||
<p>Play a short sound clip, stored directly in memory. | |||||
Data files are created with the | |||||
<a href="https://github.com/PaulStoffregen/Audio/tree/master/examples/SamplePlayer/wav2sketch" target="_blank">wav2sketch program</a>, | |||||
and copied to the sketch folder to become part of your sketch.</p> | |||||
<h3>Audio Connections</h3> | |||||
<table class=doc align=center cellpadding=3> | |||||
<tr class=top><th>Port</th><th>Purpose</th></tr> | |||||
<tr class=odd><td align=center>Out 0</td><td>Sound Output</td></tr> | |||||
</table> | |||||
<h3>Functions</h3> | |||||
<p class=func><span class=keyword>play</span>(data);</p> | |||||
<p class=desc>Begin playing a sound clip. If already playing, the | |||||
currently playing clip is stopped and this new data begins | |||||
playing from the beginning. | |||||
</p> | |||||
<p class=func><span class=keyword>stop</span>();</p> | |||||
<p class=desc>Stop playing. If not playing, this function has no effect. | |||||
</p> | |||||
<p class=func><span class=keyword>isPlaying</span>();</p> | |||||
<p class=desc>Return true (non-zero) if playing, or false (zero) | |||||
when not playing. | |||||
</p> | |||||
<p class=func><span class=keyword>positionMillis</span>();</p> | |||||
<p class=desc>While playing, return the current time offset, in | |||||
milliseconds. When not playing, the return from this function | |||||
is undefined. | |||||
</p> | |||||
<p class=func><span class=keyword>lengthMillis</span>();</p> | |||||
<p class=desc>Return the total length of the current sound clip, | |||||
in milliseconds. When not playing, the return from this function | |||||
is undefined. | |||||
</p> | |||||
<h3>Examples</h3> | |||||
<p class=exam>File > Examples > Audio > SamplePlayer | |||||
</p> | |||||
<h3>Notes</h3> | |||||
<p>TODO: supported sample rates: 11.025, 22.05, 44.1</p> | |||||
<p>TODO: ulaw vs uncompressed encoding</p> | |||||
<p>Polyphonic playback can be built by creating multiple | |||||
objects, with their output combined by mixers.</p> |
<h3>Summary</h3> | |||||
<p>Play audio data provided by the Arduino sketch. This object provides | |||||
functions to allow the sketch code to push data into the audio system.</p> | |||||
<h3>Audio Connections</h3> | |||||
<table class=doc align=center cellpadding=3> | |||||
<tr class=top><th>Port</th><th>Purpose</th></tr> | |||||
<tr class=odd><td align=center>Out 0</td><td>Sound Output</td></tr> | |||||
</table> | |||||
<h3>Functions</h3> | |||||
<p class=func><span class=keyword>play</span>(int16);</p> | |||||
<p class=desc>not yet implemented | |||||
</p> | |||||
<p class=func><span class=keyword>play</span>(int16[], length);</p> | |||||
<p class=desc>not yet implemented | |||||
</p> | |||||
<p class=func><span class=keyword>getBuffer</span>();</p> | |||||
<p class=desc>Returns a pointer to an array of 128 int16. This buffer | |||||
is within the audio library memory pool, providing the most efficient | |||||
way to input data to the audio system. The buffer is likely to be | |||||
populated by previously used data, so the entire 128 words should be | |||||
written before calling playBuffer(). Only a single buffer should be | |||||
requested at a time. This function may return NULL if no memory is | |||||
available. | |||||
</p> | |||||
<p class=func><span class=keyword>playBuffer</span>();</p> | |||||
<p class=desc>Transmit the buffer previously obtained from getBuffer(). | |||||
</p> | |||||
<h3>Examples</h3> | |||||
<p><a href="http://community.arm.com/groups/embedded/blog/2014/05/23/led-video-panel-at-maker-faire-2014" target="_blank">4320 LED Video+Sound Project</a> | |||||
</p> | |||||
<!--<p class=exam>File > Examples > Audio > | |||||
</p>--> | |||||
<h3>Notes</h3> | |||||
<p>TODO: many caveats....</p> | |||||
<p> | |||||
</p> |
<h3>Summary</h3> | |||||
<p>Play a RAW data file, stored on a SD card. RAW format is simpler | |||||
than WAV and begins playing immediately, without parsing WAV file | |||||
header info.</p> | |||||
<h3>Audio Connections</h3> | |||||
<table class=doc align=center cellpadding=3> | |||||
<tr class=top><th>Port</th><th>Purpose</th></tr> | |||||
<tr class=odd><td align=center>Out 0</td><td>Sound Output</td></tr> | |||||
</table> | |||||
<h3>Functions</h3> | |||||
<p class=func><span class=keyword>play</span>(filename);</p> | |||||
<p class=desc>Begin playing a RAW data file. If a file is already playing, | |||||
it is stopped and this file starts playing from the beginning. | |||||
</p> | |||||
<p class=func><span class=keyword>stop</span>();</p> | |||||
<p class=desc>Stop playing. If not playing, this function has no effect. | |||||
</p> | |||||
<p class=func><span class=keyword>isPlaying</span>();</p> | |||||
<p class=desc>Return true (non-zero) if playing, or false (zero) | |||||
when not playing. | |||||
</p> | |||||
<p class=func><span class=keyword>positionMillis</span>();</p> | |||||
<p class=desc>While playing, return the current time offset, in | |||||
milliseconds. When not playing, the return from this function | |||||
is undefined. | |||||
</p> | |||||
<p class=func><span class=keyword>lengthMillis</span>();</p> | |||||
<p class=desc>Return the total length of the current sound clip, | |||||
in milliseconds. When not playing, the return from this function | |||||
is undefined. | |||||
</p> | |||||
<h3>Examples</h3> | |||||
<p class=exam>File > Examples > Audio > Recorder | |||||
</p> | |||||
<h3>Notes</h3> | |||||
<p>The data file must be RAW 16 bit signed integers in LSB-first format. | |||||
</p> | |||||
<p>While playing, the audio library accesses the SD card automatically. | |||||
If card access is required, you must | |||||
<a href="http://www.pjrc.com/teensy/td_libs_AudioProcessorUsage.html" target="_blank">AudioNoInterrupts()</a> | |||||
to prevent the library from accessing the SD card while you use it. | |||||
Disabling the audio library interrupt for too long may cause audible | |||||
dropouts or glitches. | |||||
</p> |
<h3>Summary</h3> | |||||
<p>Play a WAV file, stored on a SD card.</p> | |||||
<h3>Audio Connections</h3> | |||||
<table class=doc align=center cellpadding=3> | |||||
<tr class=top><th>Port</th><th>Purpose</th></tr> | |||||
<tr class=odd><td align=center>Out 0</td><td>Left Channel Output</td></tr> | |||||
<tr class=odd><td align=center>Out 1</td><td>Right Channel Output</td></tr> | |||||
</table> | |||||
<h3>Functions</h3> | |||||
<p class=func><span class=keyword>play</span>(filename);</p> | |||||
<p class=desc>Begin playing a WAV file. If a file is already playing, | |||||
it is stopped and this file starts playing from the beginning. | |||||
</p> | |||||
<p class=func><span class=keyword>stop</span>();</p> | |||||
<p class=desc>Stop playing. If not playing, this function has no effect. | |||||
</p> | |||||
<p class=func><span class=keyword>isPlaying</span>();</p> | |||||
<p class=desc>Return true (non-zero) if playing, or false (zero) | |||||
when not playing. See the note below about delayed start. | |||||
</p> | |||||
<p class=func><span class=keyword>positionMillis</span>();</p> | |||||
<p class=desc>While playing, return the current time offset, in | |||||
milliseconds. When not playing, the return from this function | |||||
is undefined. | |||||
</p> | |||||
<p class=func><span class=keyword>lengthMillis</span>();</p> | |||||
<p class=desc>Return the total length of the current sound clip, | |||||
in milliseconds. When not playing, the return from this function | |||||
is undefined. | |||||
</p> | |||||
<h3>Examples</h3> | |||||
<p class=exam>File > Examples > Audio > WavFilePlayer | |||||
</p> | |||||
<h3>Notes</h3> | |||||
<p>Only 16 bit PCM, 44100 Hz WAV files are supported. When mono | |||||
files are played, both output ports transmit a copy of the | |||||
single sound. Of course, stereo WAV files play with the left | |||||
channel on port 0 and the right channel on port 1. | |||||
</p> | |||||
<p>A brief delay after calling play() will usually occur before | |||||
isPlaying() returns true and positionMillis() returns valid | |||||
time offset. WAV files have a header at the beginning of the | |||||
file, which the audio library must read and parse before | |||||
playing can begin. | |||||
</p> | |||||
<p>While playing, the audio library accesses the SD card automatically. | |||||
If card access is required, you must | |||||
<a href="http://www.pjrc.com/teensy/td_libs_AudioProcessorUsage.html" target="_blank">use AudioNoInterrupts()</a> | |||||
to prevent the library from accessing the SD card while you use it. | |||||
Disabling the audio library interrupt for too long may cause audible | |||||
dropouts or glitches. | |||||
</p> |
<h3>Summary</h3> | |||||
<div> | |||||
<p>Play a RAW data file, stored on a Serial Flash chip. These chips | |||||
are far more efficient than SD cards, allowing many files to be | |||||
played simultaneously by copies of this object. | |||||
</p> | |||||
<p align=center><img src="img/w25q128fv.jpg"><br><small>W25Q128FV Serial Flash</small></p> | |||||
</div> | |||||
<h3>Audio Connections</h3> | |||||
<table class=doc align=center cellpadding=3> | |||||
<tr class=top><th>Port</th><th>Purpose</th></tr> | |||||
<tr class=odd><td align=center>Out 0</td><td>Sound Output</td></tr> | |||||
</table> | |||||
<h3>Functions</h3> | |||||
<p class=func><span class=keyword>play</span>(filename);</p> | |||||
<p class=desc>Begin playing a RAW data file. If a file is already playing, | |||||
it is stopped and this file starts playing from the beginning. | |||||
</p> | |||||
<p class=func><span class=keyword>stop</span>();</p> | |||||
<p class=desc>Stop playing. If not playing, this function has no effect. | |||||
</p> | |||||
<p class=func><span class=keyword>isPlaying</span>();</p> | |||||
<p class=desc>Return true (non-zero) if playing, or false (zero) | |||||
when not playing. | |||||
</p> | |||||
<p class=func><span class=keyword>positionMillis</span>();</p> | |||||
<p class=desc>While playing, return the current time offset, in | |||||
milliseconds. When not playing, the return from this function | |||||
is undefined. | |||||
</p> | |||||
<p class=func><span class=keyword>lengthMillis</span>();</p> | |||||
<p class=desc>Return the total length of the current sound clip, | |||||
in milliseconds. When not playing, the return from this function | |||||
is undefined. | |||||
</p> | |||||
<h3>Examples</h3> | |||||
<!--<p class=exam>File > Examples > Audio > Recorder--> | |||||
<p class=exam>TODO: play example needed.... | |||||
</p> | |||||
<p class=exam>File > Examples > SerialFlash > CopyFromSD | |||||
</p> | |||||
<h3>Notes</h3> | |||||
<p>The data file must be RAW 16 bit signed integers in LSB-first format. | |||||
</p> | |||||
<p>The <a href="https://github.com/PaulStoffregen/SerialFlash" target="_blank">SerialFlash library</a> | |||||
is used to access the flash chip. You can also use SerialFlash's functions | |||||
to access the stored files, or add data to the flash chip. | |||||
</p> | |||||
<p>File names are case sensitive with SerialFlash. If your sound does | |||||
not play, use <b>File > Examples > SerialFlash > ListFiles</b> to | |||||
check the exact file names stored in the flash memory chip. |
<h3>Summary</h3> | |||||
<p>Record audio data by sending to the Arduino sketch. This object allows | |||||
sketch code to receive audio packets.</p> | |||||
<h3>Audio Connections</h3> | |||||
<table class=doc align=center cellpadding=3> | |||||
<tr class=top><th>Port</th><th>Purpose</th></tr> | |||||
<tr class=odd><td align=center>In 0</td><td>Sound To Access</td></tr> | |||||
</table> | |||||
<h3>Functions</h3> | |||||
<p class=func><span class=keyword>begin</span>();</p> | |||||
<p class=desc>Begin capturing incoming audio to the queue. After calling | |||||
begin, readBuffer() and freeBuffer(), or clear() must be used frequently | |||||
to prevent the queue from filling up. | |||||
</p> | |||||
<p class=func><span class=keyword>available</span>();</p> | |||||
<p class=desc>Returns the number of audio packets available to read. | |||||
</p> | |||||
<p class=func><span class=keyword>readBuffer</span>();</p> | |||||
<p class=desc>Read a single audio packet. A pointer to a 128 sample | |||||
array of 16 bit integers is returned. NULL is returned if no packets | |||||
are available. | |||||
</p> | |||||
<p class=func><span class=keyword>freeBuffer</span>();</p> | |||||
<p class=desc>Release the memory from the previously read packet returned | |||||
from readBuffer(). Only a single packet at a time may be read, and | |||||
each packet must be freed with this function, to return the memory to | |||||
the audio library. | |||||
</p> | |||||
<p class=func><span class=keyword>clear</span>();</p> | |||||
<p class=desc>Discard all audio held in the queue. | |||||
</p> | |||||
<p class=func><span class=keyword>end</span>();</p> | |||||
<p class=desc>Stop capturing incoming audio into the queue. Data already | |||||
captured remains in the queue and may be read with readBuffer(). | |||||
</p> | |||||
<h3>Examples</h3> | |||||
<p class=exam>File > Examples > Audio > Recorder | |||||
</p> | |||||
<h3>Notes</h3> | |||||
<p> | |||||
Up to 52 packets may be queued by this object, which allows approximately | |||||
150 ms of audio to be held in the queue, to allow time for the Arduino | |||||
sketch to write data to media or do other high-latency tasks. | |||||
The actual packets are taken | |||||
from the pool created by AudioMemory(). | |||||
</p> |
<h3>Summary</h3> | |||||
<div> | |||||
<p>Create pink noise, using Stefan Stenzel's "New Shade Of Pink" algorithm. | |||||
</p> | |||||
<!--<p align=center><img src="img/whitenoise.png"></p>--> | |||||
</div> | |||||
<h3>Audio Connections</h3> | |||||
<table class=doc align=center cellpadding=3> | |||||
<tr class=top><th>Port</th><th>Purpose</th></tr> | |||||
<tr class=odd><td align=center>Out 0</td><td>Pink Noise</td></tr> | |||||
</table> | |||||
<h3>Functions</h3> | |||||
<p class=func><span class=keyword>amplitude</span>(level);</p> | |||||
<p class=desc>Set the output peak level, from 0 (off) to 1.0. | |||||
The default is off. Noise is generated only after setting | |||||
to a non-zero level. | |||||
</p> | |||||
<h3>Examples</h3> | |||||
<p class=exam>File > Examples > Audio > MemoryAndCpuUsage | |||||
</p> | |||||
<h3>Notes</h3> | |||||
<p>Setting the amplitude to zero causes this object to stop using | |||||
CPU time. CPU usage is approx 3% on Teensy 3.1. | |||||
</p> | |||||
<p>Stefan Stenzel's | |||||
<a href="http://stenzel.waldorfmusic.de/post/pink/" target="_blank">New Shade Of Pink</a> | |||||
algorithm. Stefan's terms of use are "Use for any purpose. If used | |||||
in a commercial product, you should give me one." | |||||
</p> |
<h3>Summary</h3> | |||||
<div> | |||||
<p>Create white noise. | |||||
</p> | |||||
<p align=center><img src="img/whitenoise.png"></p> | |||||
</div> | |||||
<h3>Audio Connections</h3> | |||||
<table class=doc align=center cellpadding=3> | |||||
<tr class=top><th>Port</th><th>Purpose</th></tr> | |||||
<tr class=odd><td align=center>Out 0</td><td>White Noise</td></tr> | |||||
</table> | |||||
<h3>Functions</h3> | |||||
<p class=func><span class=keyword>amplitude</span>(level);</p> | |||||
<p class=desc>Set the output peak level, from 0 (off) to 1.0. | |||||
The default is off. Noise is generated only after setting | |||||
to a non-zero level. | |||||
</p> | |||||
<h3>Examples</h3> | |||||
<p class=exam>File > Examples > Audio > | |||||
</p> | |||||
<h3>Notes</h3> | |||||
<p>Setting the amplitude to zero causes this object to stop using | |||||
CPU time to generate random numbers. | |||||
</p> |
<h3>Summary</h3> | |||||
<p>Create a continuously varying (in frequency) sine wave</p> | |||||
<h3>Audio Connections</h3> | |||||
<table class=doc align=center cellpadding=3> | |||||
<tr class=top><th>Port</th><th>Purpose</th></tr> | |||||
<tr class=odd><td align=center>Out 0</td><td>Continuously varying tone</td></tr> | |||||
</table> | |||||
<h3>Functions</h3> | |||||
<p class=func><span class=keyword>play</span>(level, lowFreq, highFreq, time);</p> | |||||
<p class=desc>Start generating frequency sweep output. The time is specified | |||||
in milliseconds. Level is 0 to 1.0. | |||||
</p> | |||||
<p class=func><span class=keyword>isPlaying</span>();</p> | |||||
<p class=desc>Returns true (non-zero) while the output is active. | |||||
</p> | |||||
<h3>Examples</h3> | |||||
<p class=exam>File > Examples > Audio > HardwareTesting > ToneSweep | |||||
</p> | |||||
<h3>Notes</h3> | |||||
<p>Uses excessive CPU time</p> |
<h3>Summary</h3> | |||||
<p>Create a waveform: sine, sawtooth, square, triangle, pulse or arbitrary.</p> | |||||
<h3>Audio Connections</h3> | |||||
<table class=doc align=center cellpadding=3> | |||||
<tr class=top><th>Port</th><th>Purpose</th></tr> | |||||
<tr class=odd><td align=center>Out 0</td><td>Waveform Output</td></tr> | |||||
</table> | |||||
<h3>Functions</h3> | |||||
<p class=func><span class=keyword>begin</span>(waveform);</p> | |||||
<p class=desc>Configure the waveform type to create. | |||||
</p> | |||||
<p class=func><span class=keyword>begin</span>(level, frequency, waveform);</p> | |||||
<p class=desc>Output a waveform, and set the amplitude and frequency. | |||||
</p> | |||||
<p class=func><span class=keyword>frequency</span>(freq);</p> | |||||
<p class=desc>Change the frequency. | |||||
</p> | |||||
<p class=func><span class=keyword>amplitude</span>(level);</p> | |||||
<p class=desc>Change the amplitude. Set to 0 to turn the signal off. | |||||
</p> | |||||
<p class=func><span class=keyword>phase</span>(angle);</p> | |||||
<p class=desc> | |||||
Cause the generated waveform to jump to a specific point within | |||||
its cycle. Angle is from 0 to 360 degrees. When multiple objects | |||||
are configured, | |||||
<a href="http://www.pjrc.com/teensy/td_libs_AudioProcessorUsage.html" target="_blank">AudioNoInterrupts()</a> | |||||
should be used to guarantee all new settings take effect together. | |||||
</p> | |||||
<p class=func><span class=keyword>pulseWidth</span>(amount);</p> | |||||
<p class=desc>Change the width (duty cycle) of the pulse.</p> | |||||
<p class=func><span class=keyword>arbitraryWaveform</span>(array, maxFreq);</p> | |||||
<p class=desc> | |||||
Configure the waveform to be used with WAVEFORM_ARBITRARY. Array | |||||
must be an array of 256 samples. Currently, the data is used | |||||
without any filtering, which can cause aliasing with frequencies | |||||
above 172 Hz. For higher frequency output, you must bandwidth | |||||
limit your waveform data. Someday, "maxFreq" will be used to | |||||
do this automatically. | |||||
</p> | |||||
<h3>Examples</h3> | |||||
<p class=exam>File > Examples > Audio > Synthesis > PlaySynthMusic | |||||
</p> | |||||
<p class=exam>File > Examples > Audio > Synthesis > pulseWidth | |||||
</p> | |||||
<p class=exam>File > Examples > Audio > HardwareTesting > WM8731MikroSine | |||||
</p> | |||||
<h3>Notes</h3> | |||||
<p>Supported Waveforms:<br> | |||||
<ul> | |||||
<li><span class=literal>WAVEFORM_SINE</span></li> | |||||
<li><span class=literal>WAVEFORM_SAWTOOTH</span></li> | |||||
<li><span class=literal>WAVEFORM_SQUARE</span></li> | |||||
<li><span class=literal>WAVEFORM_TRIANGLE</span></li> | |||||
<li><span class=literal>WAVEFORM_ARBITRARY</span></li> | |||||
<li><span class=literal>WAVEFORM_PULSE</span></li> | |||||
</ul> | |||||
</p> |
<h3>Summary</h3> | |||||
<p>Create constant (DC) signal, useful for control of objects that take | |||||
a modulation or control input signal. This constant level can be | |||||
used to modify other waveforms using mixer or multiplier objects</p> | |||||
<h3>Audio Connections</h3> | |||||
<table class=doc align=center cellpadding=3> | |||||
<tr class=top><th>Port</th><th>Purpose</th></tr> | |||||
<tr class=odd><td align=center>Out 0</td><td>Output constant DC level</td></tr> | |||||
</table> | |||||
<h3>Functions</h3> | |||||
<p class=func><span class=keyword>amplitude</span>(level);</p> | |||||
<p class=desc>Set the output. Level is -1.0 to 1.0. The output is | |||||
changed immediately. | |||||
</p> | |||||
<p class=func><span class=keyword>amplitude</span>(level, milliseconds);</p> | |||||
<p class=desc>Set the output. Level is -1.0 to 1.0. The output is | |||||
gradually changed over a "milliseconds" time period. Any time may | |||||
be specified, but periods longer than 1 second may be automatically | |||||
shortened for small level changes, due to numerical precision limits. | |||||
</p> | |||||
<!--<h3>Examples</h3> | |||||
<p class=exam>File > Examples > Audio > | |||||
</p>--> | |||||
<h3>Notes</h3> | |||||
<p>Of course, the term "DC", for Direct Current, doesn't properly apply | |||||
to a pure digital stream of numerical values. But the term is widely | |||||
understood in audio applications, so hopefully it's not too confusing?</p> |
<h3>Summary</h3> | |||||
<p>Create a sine wave signal</p> | |||||
<h3>Audio Connections</h3> | |||||
<table class=doc align=center cellpadding=3> | |||||
<tr class=top><th>Port</th><th>Purpose</th></tr> | |||||
<tr class=odd><td align=center>Out 0</td><td>Sine Wave Output</td></tr> | |||||
</table> | |||||
<h3>Functions</h3> | |||||
<p class=func><span class=keyword>amplitude</span>(level);</p> | |||||
<p class=desc>Set the amplitude, from 0 to 1.0. | |||||
</p> | |||||
<p class=func><span class=keyword>frequency</span>(freq);</p> | |||||
<p class=desc>Set the frequency, from 0 to 22000. Very low values may | |||||
be used to create a LFO (Low Frequency Oscillator) for objects | |||||
with modulation signal inputs. | |||||
</p> | |||||
<p class=func><span class=keyword>phase</span>(angle);</p> | |||||
<p class=desc> | |||||
Cause the generated waveform to jump to a specific point within | |||||
its cycle. Angle is from 0 to 360 degrees. When multiple objects | |||||
are configured, | |||||
<a href="http://www.pjrc.com/teensy/td_libs_AudioProcessorUsage.html" target="_blank">AudioNoInterrupts()</a> | |||||
should be used to guarantee all new settings take effect together. | |||||
</p> | |||||
<h3>Examples</h3> | |||||
<p class=exam>File > Examples > Audio > MemoryAndCpuUsage | |||||
</p> | |||||
<p class=exam>File > Examples > Audio > Analysis > DialTone_Serial | |||||
</p> | |||||
<p class=exam>File > Examples > Audio > Analysis > FFT | |||||
</p> | |||||
<h3>Notes</h3> | |||||
<p></p> |
<h3>Summary</h3> | |||||
<p>Create a modulated sine wave, using any audio signal to continuously | |||||
modulate the sine wave frequency.</p> | |||||
<h3>Audio Connections</h3> | |||||
<table class=doc align=center cellpadding=3> | |||||
<tr class=top><th>Port</th><th>Purpose</th></tr> | |||||
<tr class=odd><td align=center>In 0</td><td>Modulation Signal</td></tr> | |||||
<tr class=odd><td align=center>Out 0</td><td>Sine Wave Output</td></tr> | |||||
</table> | |||||
<h3>Functions</h3> | |||||
<p class=func><span class=keyword>amplitude</span>(level);</p> | |||||
<p class=desc>Set the amplitude, from 0 to 1.0. | |||||
</p> | |||||
<p class=func><span class=keyword>frequency</span>(freq);</p> | |||||
<p class=desc>Set the center frequency, from 0 to 11000. The output will | |||||
be this center frequency when the input modulation signal is zero. | |||||
Modulation input 1.0 causes the frequency to double, and input -1.0 | |||||
causes zero Hz (DC) output. For less modulation, attenuate the input | |||||
signal (perhaps with a mixer object) before it arrives here. | |||||
</p> | |||||
<p class=func><span class=keyword>phase</span>(angle);</p> | |||||
<p class=desc> | |||||
Cause the generated waveform to jump to a specific point within | |||||
its cycle. Angle is from 0 to 360 degrees. When multiple objects | |||||
are configured, | |||||
<a href="http://www.pjrc.com/teensy/td_libs_AudioProcessorUsage.html" target="_blank">AudioNoInterrupts()</a> | |||||
should be used to guarantee all new settings take effect together. | |||||
</p> | |||||
<!--<h3>Examples</h3> | |||||
<p class=exam>File > Examples > Audio > | |||||
</p>--> | |||||
<h3>Notes</h3> | |||||
<p></p> |
{"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"}} | |||||
]} |
#palette { | #palette { | ||||
background: #f3f3f3; | background: #f3f3f3; | ||||
width: 140px; | |||||
width: 160px; | |||||
text-align: center; | text-align: center; | ||||
-webkit-user-select: none; | -webkit-user-select: none; | ||||
-khtml-user-select: none; | -khtml-user-select: none; | ||||
border: 2px solid #999; | border: 2px solid #999; | ||||
background-position: 5% 50%; | background-position: 5% 50%; | ||||
background-repeat: no-repeat; | background-repeat: no-repeat; | ||||
width: 90px; | |||||
width: 110px; | |||||
background-size: contain; | background-size: contain; | ||||
position: relative; | position: relative; | ||||
} | } | ||||
border: 1px solid #999; | border: 1px solid #999; | ||||
} | } | ||||
.palette_port_output { | .palette_port_output { | ||||
left:85px; | |||||
left:105px; | |||||
} | } | ||||
.palette_node:hover .palette_port { | .palette_node:hover .palette_port { |