You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
6040 lines
292 KiB
6040 lines
292 KiB
<!DOCTYPE html>
|
|
<!-- vim: set ts=4: -->
|
|
<html>
|
|
|
|
<meta charset="utf-8">
|
|
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=0"/>
|
|
<meta name="apple-mobile-web-app-capable" content="yes">
|
|
<meta name="mobile-web-app-capable" content="yes">
|
|
|
|
<!--
|
|
Modified from original Node-Red source, for audio system visualization
|
|
|
|
Copyright 2013 IBM Corp.
|
|
|
|
Licensed under the Apache License, Version 2.0 (the "License");
|
|
you may not use this file except in compliance with the License.
|
|
You may obtain a copy of the License at
|
|
|
|
http://www.apache.org/licenses/LICENSE-2.0
|
|
|
|
Unless required by applicable law or agreed to in writing, software
|
|
distributed under the License is distributed on an "AS IS" BASIS,
|
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
See the License for the specific language governing permissions and
|
|
limitations under the License.
|
|
|
|
*** NODES FOR OPENAUDIO_ARDUINOLIBRARY 1 March 2021 RSL ***
|
|
-->
|
|
<head>
|
|
<title>Audio System Design Tool for Open Audio F32 Library for Teensy</title>
|
|
<link href="bootstrap/css/bootstrap.min.css" rel="stylesheet" media="screen">
|
|
<link href="jquery/css/smoothness/jquery-ui-1.10.3.custom.min.css" rel="stylesheet" media="screen">
|
|
<link rel="stylesheet" type="text/css" href="orion/built-editor.css"/>
|
|
<link rel="stylesheet" type="text/css" href="font-awesome/css/font-awesome.min.css"/>
|
|
<link rel="stylesheet" href="style.css">
|
|
<style>
|
|
table.doc {border-spacing:3px; border-collapse:separate; font-size: 80%}
|
|
tr.top {background-color:#C0C0C0}
|
|
tr.odd {background-color:#F0F0F0}
|
|
tr.even {background-color:#E0E0E0}
|
|
p.func {padding-bottom:0; margin:0px}
|
|
p.desc {padding-left:2em; margin:0px; padding-top:0.2em; padding-bottom:0.8em; font-size:0.75em}
|
|
p.exam {padding-left:2em; text-indent:-1.2em; margin:0px; padding-top:0; padding-bottom:0.5em; font-size:0.75em; font-weight:bold}
|
|
pre.desc {padding-left:3em; margin:0px; padding-top:0em; padding-bottom:0.8em; font-size:0.75em;
|
|
background-color:#FFFFFF; border:0px; line-height:100%;
|
|
}
|
|
span.indent {padding-left:2em}
|
|
span.literal {color: #006699}
|
|
span.comment {color: #777755}
|
|
span.keyword {color: #cc6600}
|
|
span.function {color: #996600}
|
|
span.mainfunction {color: #993300; font-weight: bolder}
|
|
</style>
|
|
</head>
|
|
<body spellcheck="false">
|
|
<div class="navbar navbar-inverse navbar-fixed-top">
|
|
<div class="navbar-inner">
|
|
<div class="container-fluid">
|
|
<span class="brand">Audio Design Tool for OpenAudio F32 Library for Teensy</a></span>
|
|
<div class="btn-group pull-right">
|
|
<a class="btn dropdown-toggle" data-toggle="dropdown" href="#"><i class="icon-align-justify"></i> <span class="caret"></span></a>
|
|
<ul class="dropdown-menu">
|
|
<li><a id="btn-sidebar" tabindex="-1" href="#"><i class="icon-ok pull-right"></i><i class="icon-list-alt"></i> Sidebar</a></li>
|
|
<li class="divider"></li>
|
|
<!-- <li><a id="btn-node-status" tabindex="-1" href="#"><i class="icon-ok pull-right"></i><i class="icon-info-sign"></i> Node Status</a></li>
|
|
<li class="divider"></li>
|
|
-->
|
|
<!--
|
|
<li class="dropdown-submenu pull-left"><a tabindex="-1" href="#"><i class="icon-edit"></i> Import from...</a>
|
|
<ul class="dropdown-menu">
|
|
<li><a id="btn-import" tabindex="-1" href="#"><i class="icon-edit"></i> Clipboard...</a></li>
|
|
<li id="flow-menu-parent" class="dropdown-submenu pull-left">
|
|
<a tabindex="-1" href="#"><i class="icon-book"></i> Library</a>
|
|
<ul class="dropdown-menu"></ul>
|
|
</li>
|
|
</ul>
|
|
</li>
|
|
<li id="li-menu-export" class="dropdown-submenu disabled pull-left"><a tabindex="-1" href="#"><i class="icon-share"></i> Export to...</a>
|
|
<ul class="dropdown-menu">
|
|
<li id="li-menu-export-clipboard" class="disabled"><a id="btn-export-clipboard" tabindex="-1" href="#"><i class="icon-share"></i> Clipboard...</a></li>
|
|
<li id="li-menu-export-library" class="disabled"><a id="btn-export-library" tabindex="-1" href="#"><i class="icon-book"></i> Library...</a></li>
|
|
</ul>
|
|
</li>
|
|
<li class="divider"></li>
|
|
-->
|
|
<!--
|
|
<li><a id="btn-config-nodes" tabindex="-1" href="#"><i class="icon-th-list"></i> Configuration nodes...</a></li>
|
|
<li class="divider"></li>
|
|
-->
|
|
<!--
|
|
<li class="dropdown-submenu pull-left"><a tabindex="-1" href="#"><i class="icon-th-large"></i> Workspaces</a>
|
|
<ul id="workspace-menu-list" class="dropdown-menu">
|
|
<li><a id="btn-workspace-add" tabindex="-1" href="#"><i class="icon-plus"></i> Add</a></li>
|
|
<li><a id="btn-workspace-edit" tabindex="-1" href="#"><i class="icon-edit"></i> Rename</a></li>
|
|
<li><a id="btn-workspace-delete" tabindex="-1" href="#"><i class="icon-minus"></i> Delete</a></li>
|
|
<li class="divider"></li>
|
|
</ul>
|
|
</li>
|
|
<li class="divider"></li>-->
|
|
<li><a id="btn-keyboard-shortcuts" tabindex="-1" href="#"><i class="icon-question-sign"></i> Keyboard Shortcuts</a></li>
|
|
<li><a id="btn-help" tabindex="-1" href="http://node-red.github.io/docs" target="_blank"><i class="icon-question-sign"></i> Help...</a></li>
|
|
</ul>
|
|
</div>
|
|
<div class="btn-group pull-left">
|
|
<a id="btn-deploy" class="btn action-deploy disabled" href="#"><i id="btn-icn-deploy" class="icon-upload"></i>Export</a>
|
|
<a id="btn-import" class="btn action-import disabled" href="#"><i id="btn-icn-download" class="icon-download"></i>Import</a>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div id="main-container" class="sidebar-closed">
|
|
<div id="palette">
|
|
<img src="img/spin.svg" class="palette-spinner"/>
|
|
<div id="palette-container" class="palette-scroll">
|
|
</div>
|
|
<div id="palette-search">
|
|
<i class="icon-search"></i><input id="palette-search-input" type="text" placeholder="filter"><a href="#" id="palette-search-clear"><i class="icon-remove"></i></a></input>
|
|
</div>
|
|
</div><!-- /palette -->
|
|
|
|
<div id="workspace">
|
|
<ul id="workspace-tabs"></ul>
|
|
<!--<div id="workspace-add-tab"><a id="btn-workspace-add-tab" href="#"><i class="icon-plus"></i></a></div>-->
|
|
<div id="chart"></div>
|
|
<div id="workspace-toolbar">
|
|
<div class="btn-group">
|
|
<a class="btn btn-small" href="#"><i class="icon-zoom-out"></i></a>
|
|
<a class="btn btn-small" href="#"><i class="icon-th"></i></a>
|
|
<a class="btn btn-small" href="#"><i class="icon-zoom-in"></i></a>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div id="chart-zoom-controls">
|
|
<div class="btn-group">
|
|
<a class="btn btn-mini" id="btn-zoom-out" href="#"><i class="icon-zoom-out"></i></a>
|
|
<a class="btn btn-mini" id="btn-zoom-zero" href="#"><i class="icon-th"></i></a>
|
|
<a class="btn btn-mini" id="btn-zoom-in" href="#"><i class="icon-zoom-in"></i></a>
|
|
</div>
|
|
</div>
|
|
|
|
<div id="sidebar">
|
|
<ul id="sidebar-tabs"></ul>
|
|
<div id="sidebar-content"></div>
|
|
</div>
|
|
|
|
<div id="sidebar-separator"></div>
|
|
|
|
</div>
|
|
|
|
<div id="notifications"></div>
|
|
<div id="dropTarget"><div>Drop the flow here</div></div>
|
|
|
|
<div id="dialog" class="hide"><form id="dialog-form" class="form-horizontal"></form></div>
|
|
<div id="node-config-dialog" class="hide"><form id="dialog-config-form" class="form-horizontal"></form><div class="form-tips" id="node-config-dialog-user-count"></div></div>
|
|
|
|
<div id="node-dialog-confirm-deploy" class="hide">
|
|
<form class="form-horizontal">
|
|
<div id="node-dialog-confirm-deploy-config" style="text-align: center; padding-top: 30px;">
|
|
Some of the nodes are not properly configured. Are you sure you want to deploy?
|
|
</div>
|
|
<div id="node-dialog-confirm-deploy-unknown" style="text-align: center; padding-top: 10px;">
|
|
The workspace contains some unknown node types:
|
|
<ul style="width: 300px; margin: auto; text-align: left;" id="node-dialog-confirm-deploy-unknown-list"></ul>
|
|
Are you sure you want to deploy?
|
|
</div>
|
|
</form>
|
|
</div>
|
|
|
|
<div id="node-dialog-error-deploy" class="hide">
|
|
<form class="form-horizontal">
|
|
<div id="node-dialog-error-deploy-noio" style="text-align: center; padding-top: 10px;">
|
|
<p>The workspace contains no input/output nodes!</p>
|
|
<p>You need an input or an output to export the data!</p>
|
|
<p>Without such a input/output function the exported
|
|
code will not run properly!</p>
|
|
</div>
|
|
</form>
|
|
</div>
|
|
|
|
<div id="node-help" class="modal hide fade" tabindex="-1" role="dialog" aria-labelledby="node-help-label" aria-hidden="true">
|
|
<div class="modal-header">
|
|
<h5 id="node-help-label">Keyboard Shortcuts <span style="float: right;"><a href="http://node-red.github.io/docs" target="_blank">Open help in new window »</a></span></h5>
|
|
</div>
|
|
<div class="modal-body">
|
|
<table>
|
|
<tr>
|
|
<td><span class="help-key">?</span></td><td>Help</td>
|
|
<td><span class="help-key">Ctrl</span> <span class="help-key">a</span></td><td>Select all nodes</td>
|
|
</tr>
|
|
<tr>
|
|
<td><span class="help-key">Ctrl</span> <span class="help-key">Space</span></td><td>Toggle sidebar</td>
|
|
<td><span class="help-key">Shift</span> <span class="help-key">Click</span></td><td>Select all connected nodes</td>
|
|
</tr>
|
|
<tr>
|
|
<td><span class="help-key">Ctrl</span> <span class="help-key">z</span></td><td>Undo</td>
|
|
<td><span class="help-key">Ctrl</span> <span class="help-key">Click</span></td><td>Add/remove node from selection</td>
|
|
</tr>
|
|
<tr>
|
|
<td></td><td></td>
|
|
<td><span class="help-key">Delete</span></td><td>Delete selected nodes or link</td>
|
|
</tr>
|
|
<tr>
|
|
<td><span class="help-key">Ctrl</span> <span class="help-key">x</span></td><td>Cut selected nodes</td>
|
|
<td></td><td></td>
|
|
</tr>
|
|
<tr>
|
|
<td><span class="help-key">Ctrl</span> <span class="help-key">c</span></td><td>Copy selected nodes</td>
|
|
<td><span class="help-key">Ctrl</span> <span class="help-key">v</span></td><td>Paste nodes</td>
|
|
</tr>
|
|
<tr>
|
|
<td><span class="help-key">Ctrl</span> <span class="help-key">i</span></td><td>Import nodes</td>
|
|
<td><span class="help-key">Ctrl</span> <span class="help-key">e</span></td><td>Export selected nodes</td>
|
|
</tr>
|
|
<tr>
|
|
<td colspan="2"></td>
|
|
</tr>
|
|
<tr>
|
|
<td><span class="help-key">Ctrl</span> <span class="help-key">+</span></td><td>Zoom in</td>
|
|
<td><span class="help-key">Ctrl</span> <span class="help-key">-</span></td><td>Zoom out</td>
|
|
</tr>
|
|
</table>
|
|
</div>
|
|
<div class="modal-footer">
|
|
<button class="btn" data-dismiss="modal" aria-hidden="true">Close</button>
|
|
</div>
|
|
</div>
|
|
|
|
<div id="node-dialog-library-save-confirm" class="hide">
|
|
<form class="form-horizontal">
|
|
<div style="text-align: center; padding-top: 30px;">
|
|
A <span id="node-dialog-library-save-type"></span> called <span id="node-dialog-library-save-name"></span> already exists. Overwrite?
|
|
</div>
|
|
</form>
|
|
</div>
|
|
|
|
<div id="node-dialog-library-save" class="hide">
|
|
<form class="form-horizontal">
|
|
<div class="form-row">
|
|
<label for="node-dialog-library-save-folder"><i class="icon-folder-open"></i> Folder</label>
|
|
<input type="text" id="node-dialog-library-save-folder" placeholder="Folder">
|
|
</div>
|
|
<div class="form-row">
|
|
<label for="node-dialog-library-save-filename"><i class="icon-file"></i> Filename</label>
|
|
<input type="text" id="node-dialog-library-save-filename" placeholder="Filename">
|
|
</div>
|
|
</form>
|
|
</div>
|
|
|
|
<div id="node-dialog-library-lookup" class="hide">
|
|
<form class="form-horizontal">
|
|
<div class="form-row">
|
|
<ul id="node-dialog-library-breadcrumbs" class="breadcrumb">
|
|
<li class="active"><a href="#">Library</a></li>
|
|
</ul>
|
|
</div>
|
|
<div class="form-row">
|
|
<div style="vertical-align: top; display: inline-block; height: 100%; width: 30%; padding-right: 20px;">
|
|
<div id="node-select-library" style="border: 1px solid #999; width: 100%; height: 100%; overflow:scroll;"><ul></ul></div>
|
|
</div>
|
|
<div style="vertical-align: top; display: inline-block;width: 65%; height: 100%;">
|
|
<div style="height: 100%; width: 95%;" class="node-text-editor" id="node-select-library-text" ></div>
|
|
</div>
|
|
</div>
|
|
</form>
|
|
</div>
|
|
<div id="node-dialog-rename-workspace" class="hide">
|
|
<form class="form-horizontal">
|
|
<div class="form-row">
|
|
<label for="node-input-workspace-name" ><i class="icon-tag"></i> Name:</label>
|
|
<input type="text" id="node-input-workspace-name">
|
|
</div>
|
|
</form>
|
|
</div>
|
|
<div id="node-dialog-delete-workspace" class="hide">
|
|
<form class="form-horizontal">
|
|
<div style="text-align: center; padding-top: 30px;">
|
|
Are you sure you want to delete '<span id="node-dialog-delete-workspace-name"></span>'?
|
|
</div>
|
|
</form>
|
|
</div>
|
|
|
|
<script type="text/x-red" data-template-name="export-clipboard-dialog">
|
|
<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">
|
|
<a id="download-INO" target="_blank">Click to Download Zipped Code</a>
|
|
</div>
|
|
</script>
|
|
<script type="text/x-red" data-template-name="export-library-dialog">
|
|
<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>
|
|
</script>
|
|
<script type="text/x-red" data-template-name="import-dialog">
|
|
<div class="form-row">
|
|
<label for="node-input-import"><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. When importing Arduino code, the whole flow will be replaced."></textarea>
|
|
</div>
|
|
<div class="form-tips">
|
|
<label for="node-input-arduino" style="font-size: 13px; padding: 2px 0px 0px 4px;">
|
|
<input style="margin-bottom: 4px; margin-right: 4px;" type="checkbox" id="node-input-arduino" checked="checked" class="input-block-level" />
|
|
Import copied code from the Arduino IDE
|
|
</label>
|
|
</div>
|
|
</script>
|
|
|
|
<script src="jquery/js/jquery-1.9.1.js"></script>
|
|
<script src="bootstrap/js/bootstrap.min.js"></script>
|
|
<script src="jquery/js/jquery-ui-1.10.3.custom.min.js"></script>
|
|
<script src="jquery/js/jquery.ui.touch-punch.min.js"></script>
|
|
<script src="jszip/dist/jszip.min.js"></script>
|
|
<script src="orion/built-editor.min.js"></script>
|
|
<script src="red/d3/d3.v3.min.js"></script>
|
|
<script src="red/main.js"></script>
|
|
<script src="red/ui/state.js"></script>
|
|
<script src="red/nodes.js"></script>
|
|
<script src="red/storage.js"></script>
|
|
<script src="red/history.js"></script>
|
|
<script src="red/ui/keyboard.js"></script>
|
|
<script src="red/ui/tabs.js"></script>
|
|
<script src="red/ui/view.js"></script>
|
|
<script src="red/ui/sidebar.js"></script>
|
|
<script src="red/ui/palette.js"></script>
|
|
<script src="red/ui/tab-info.js"></script>
|
|
<script src="red/ui/tab-config.js"></script>
|
|
<script src="red/ui/editor.js"></script>
|
|
<script src="red/ui/library.js"></script>
|
|
<script src="red/ui/notifications.js"></script>
|
|
<script src="red/ui/touch/radialMenu.js"></script>
|
|
|
|
<!--
|
|
TODO: generate some or all of this automatically from the C++ source
|
|
-->
|
|
|
|
<!--
|
|
TODO: add a field for maximum instance count
|
|
-->
|
|
<!--
|
|
TODO: add a field for exclusive to other objects (not allowed if they're used)
|
|
-->
|
|
<!--
|
|
TODO: add "parameters" fields, to replace the form html stuff
|
|
-->
|
|
|
|
<script type="text/x-red" data-container-name="NodeDefinitions">
|
|
{"nodes":[
|
|
{"type":"AudioAnalyzePhase_F32","data":{"defaults":{"name":{"value":"new"}},"shortName":"phaseDet","inputs":"1","output":"0","category":"analyze-function","color":"#E6E0F8","icon":"arrow-in.png","outputs":"1"}},
|
|
{"type":"AudioAnalyzePeak_F32","data":{"defaults":{"name":{"value":"new"}},"shortName":"peak","inputs":1,"outputs":0,"category":"analyze-function","color":"#E6E0F8","icon":"arrow-in.png"}},
|
|
{"type":"AudioAnalyzeRMS_F32","data":{"defaults":{"name":{"value":"new"}},"shortName":"rms","inputs":1,"outputs":0,"category":"analyze-function","color":"#E6E0F8","icon":"arrow-in.png"}},
|
|
{"type":"AudioAnalyzeFFT1024_F32","data":{"defaults":{"name":{"value":"new"}},"shortName":"FFT1024","inputs":1,"outputs":0,"category":"analyze-function","color":"#E6E0F8","icon":"arrow-in.png","outputs":"0"}},
|
|
{"type":"AudioAnalyzeFFT256_IQ_F32","data":{"defaults":{"name":{"value":"new"}},"shortName":"FFT256iq","inputs":2,"outputs":0,"category":"analyze-function","color":"#E6E0F8","icon":"arrow-in.png","outputs":"4"}},
|
|
{"type":"AudioAnalyzeFFT1024_IQ_F32","data":{"defaults":{"name":{"value":"new"}},"shortName":"FFT1024iq","inputs":2,"outputs":0,"category":"analyze-function","color":"#E6E0F8","icon":"arrow-in.png","outputs":"4"}},
|
|
{"type":"AudioAnalyzeFFT2048_IQ_F32","data":{"defaults":{"name":{"value":"new"}},"shortName":"FFT2048iq","inputs":2,"outputs":0,"category":"analyze-function","color":"#E6E0F8","icon":"arrow-in.png","outputs":"4"}},
|
|
{"type":"AudioAnalyzeFFT4096_IQ_F32","data":{"defaults":{"name":{"value":"new"}},"shortName":"FFT4096iq","inputs":2,"outputs":0,"category":"analyze-function","color":"#E6E0F8","icon":"arrow-in.png","outputs":"0"}},
|
|
|
|
{"type":"AudioAnalyzeFFT4096_IQem_F32","data":{"defaults":{"name":{"value":"new"}},"shortName":"FFT4096IQem","inputs":2,"outputs":0,"category":"analyze-function","color":"#E6E0F8","icon":"arrow-in.png","outputs":"0"}},
|
|
|
|
{"type":"AudioAnalyzeToneDetect_F32","data":{"defaults":{"name":{"value":"new"}},"shortName":"toneDetect","inputs":"1","output":"0","category":"analyze-function","color":"#E6E0F8","icon":"arrow-in.png","outputs":"0"}},
|
|
{"type":"analyze_CTCSS_F32","data":{"defaults":{"name":{"value":"new"}},"shortName":"toneCTCSS","inputs":"1","output":"1","category":"analyze-function","color":"#E6E0F8","icon":"arrow-in.png","outputs":"1"}},
|
|
{"type":"AudioCalcEnvelope_F32","data":{"defaults":{"name":{"value":"new"}},"shortName":"calcEnvelope","inputs":"1","output":"0","category":"calc-function","color":"#E6E0F8","icon":"arrow-in.png","outputs":"1"}},
|
|
{"type":"AudioCalcGainWDRC_F32","data":{"defaults":{"name":{"value":"new"}},"shortName":"calcGainWDRC","inputs":"1","output":"0","category":"calc-function","color":"#E6E0F8","icon":"arrow-in.png","outputs":"1"}},
|
|
{"type":"AudioCalcLevel_F32","data":{"defaults":{"name":{"value":"new"}},"shortName":"calcLevel","inputs":"NaN","output":"0","category":"calc-function","color":"#E6E0F8","icon":"arrow-in.png","outputs":"NaN"}},
|
|
{"type":"AudioCalcGainWDRC_F32","data":{"defaults":{"name":{"value":"new"}},"shortName":"calcGainWDRC","inputs":"NaN","output":"0","category":"calc-function","color":"#E6E0F8","icon":"arrow-in.png","outputs":"1"}},
|
|
{"type":"AudioConvert_I16toF32","data":{"defaults":{"name":{"value":"new"}},"shortName":"convert_I16toF32","inputs":"0","output":"0","category":"convert-function","color":"#E6E0F8","icon":"arrow-in.png","outputs":"1"}},
|
|
{"type":"AudioConvert_F32toI16","data":{"defaults":{"name":{"value":"new"}},"shortName":"convert_F32toI16","inputs":"1","output":"0","category":"convert-function","color":"#E6E0F8","icon":"arrow-in.png","outputs":"0"}},
|
|
{"type":"AudioEffectCompWDRC_F32","data":{"defaults":{"name":{"value":"new"}},"shortName":"compWDRC","inputs":"1","output":"0","category":"effect-function","color":"#E6E0F8","icon":"arrow-in.png","outputs":"1"}},
|
|
{"type":"AudioEffectCompressor_F32","data":{"defaults":{"name":{"value":"new"}},"shortName":"compressor","inputs":"1","output":"0","category":"effect-function","color":"#E6E0F8","icon":"arrow-in.png","outputs":"1"}},
|
|
{"type":"AudioEffectDelay_OA_F32","data":{"defaults":{"name":{"value":"new"}},"shortName":"delay","inputs":"1","output":"0","category":"effect-function","color":"#E6E0F8","icon":"arrow-in.png","outputs":"1"}},
|
|
{"type":"AudioEmpty_F32","data":{"defaults":{"name":{"value":"new"}},"shortName":"empty","inputs":"1","output":"0","category":"effect-function","color":"#E6E0F8","icon":"arrow-in.png","outputs":"1"}},
|
|
{"type":"AudioEffectCompressor2_F32","data":{"defaults":{"name":{"value":"new"}},"shortName":"compressor2","inputs":"1","output":"0","category":"effect-function","color":"#E6E0F8","icon":"arrow-in.png","outputs":"1"}},
|
|
{"type":"AudioEffectNoiseGate_F32","data":{"defaults":{"name":{"value":"new"}},"shortName":"noiseGate","inputs":"1","output":"0","category":"effect-function","color":"#E6E0F8","icon":"arrow-in.png","outputs":"1"}},
|
|
{"type":"AudioEffectFreqShiftFD_F32","data":{"defaults":{"name":{"value":"new"}},"shortName":"freqShift","inputs":"1","output":"0","category":"effect-function","color":"#E6E0F8","icon":"arrow-in.png","outputs":"1"}},
|
|
{"type":"AudioEffectGain_F32","data":{"defaults":{"name":{"value":"new"}},"shortName":"gain","inputs":"1","output":"0","category":"effect-function","color":"#E6E0F8","icon":"arrow-in.png","outputs":"1"}},
|
|
{"type":"AudioFilterFIRGeneral_F32","data":{"defaults":{"name":{"value":"new"}},"shortName":"filterFIRgeneral","inputs":"1","output":"0","category":"filter-function","color":"#E6E0F8","icon":"arrow-in.png","outputs":"1"}},
|
|
{"type":"AudioFilterEqualizer_F32","data":{"defaults":{"name":{"value":"new"}},"shortName":"filterEqualizer","inputs":"1","output":"0","category":"filter-function","color":"#E6E0F8","icon":"arrow-in.png","outputs":"1"}},
|
|
{"type":"AudioFilter90Deg_F32","data":{"defaults":{"name":{"value":"new"}},"shortName":"filter90deg","inputs":"2","output":"2","category":"filter-function","color":"#E6E0F8","icon":"arrow-in.png","outputs":"2"}},
|
|
{"type":"AudioFilterBiquad_F32","data":{"defaults":{"name":{"value":"new"}},"shortName":"biquad","inputs":"1","output":"0","category":"filter-function","color":"#E6E0F8","icon":"arrow-in.png","outputs":"1"}},
|
|
{"type":"AudioFilterFIR_F32","data":{"defaults":{"name":{"value":"new"}},"shortName":"fir","inputs":"1","output":"0","category":"filter-function","color":"#E6E0F8","icon":"arrow-in.png","outputs":"1"}},
|
|
{"type":"AudioFilterConvolution_F32","data":{"defaults":{"name":{"value":"new"}},"shortName":"convFilt","inputs":"1","output":"0","category":"filter-function","color":"#E6E0F8","icon":"arrow-in.png","outputs":"1"}},
|
|
{"type":"AudioLMSDenoiseNotch_F32","data":{"defaults":{"name":{"value":"new"}},"shortName":"LMS","inputs":"1","output":"0","category":"filter-function","color":"#E6E0F8","icon":"arrow-in.png","outputs":"1"}},
|
|
{"type":"AudioSpectralDenoise_F32","data":{"defaults":{"name":{"value":"new"}},"shortName":"Spectral","inputs":"1","output":"0","category":"filter-function","color":"#E6E0F8","icon":"arrow-in.png","outputs":"1"}},
|
|
{"type":"AudioFilterFreqWeighting_F32","data":{"defaults":{"name":{"value":"new"}},"shortName":"freqWeight","inputs":"NaN","output":"0","category":"filter-function","color":"#E6E0F8","icon":"arrow-in.png","outputs":"NaN"}},
|
|
{"type":"AudioFilterTimeWeighting_F32","data":{"defaults":{"name":{"value":"new"}},"shortName":"timeWeight","inputs":"1","output":"0","category":"filter-function","color":"#E6E0F8","icon":"arrow-in.png","outputs":"1"}},
|
|
{"type":"AudioMathAdd_F32","data":{"defaults":{"name":{"value":"new"}},"shortName":"mathAdd","inputs":"2","output":"0","category":"math-function","color":"#E6E0F8","icon":"arrow-in.png","outputs":"1"}},
|
|
{"type":"AudioMathMultiply_F32","data":{"defaults":{"name":{"value":"new"}},"shortName":"mathMultiply","inputs":"2","output":"0","category":"math-function","color":"#E6E0F8","icon":"arrow-in.png","outputs":"1"}},
|
|
{"type":"AudioMathOffset_F32","data":{"defaults":{"name":{"value":"new"}},"shortName":"mathOffset","inputs":"1","output":"0","category":"math-function","color":"#E6E0F8","icon":"arrow-in.png","outputs":"1"}},
|
|
{"type":"AudioMathConstant_F32","data":{"defaults":{"name":{"value":"new"}},"shortName":"mathConstant","inputs":"0","output":"0","category":"math-function","color":"#E6E0F8","icon":"arrow-in.png","outputs":"1"}},
|
|
{"type":"AudioMathScale_F32","data":{"defaults":{"name":{"value":"new"}},"shortName":"mathScale","inputs":"1","output":"0","category":"math-function","color":"#E6E0F8","icon":"arrow-in.png","outputs":"1"}},
|
|
{"type":"AudioMixer4_F32","data":{"defaults":{"name":{"value":"new"}},"shortName":"mixer4","inputs":"4","output":"0","category":"mixer-function","color":"#E6E0F8","icon":"arrow-in.png","outputs":"1"}},
|
|
{"type":"AudioMixer8_F32","data":{"defaults":{"name":{"value":"new"}},"shortName":"mixer8","inputs":"8","output":"0","category":"mixer-function","color":"#E6E0F8","icon":"arrow-in.png","outputs":"1"}},
|
|
{"type":"AudioSDPlayer_F32","data":{"defaults":{"name":{"value":"new"}},"shortName":"playSdWav","inputs":0,"outputs":2,"category":"play-function","color":"#E6E0F8","icon":"arrow-in.png","outputs":"2"}},
|
|
{"type":"AudioSwitch4_OA_F32","data":{"defaults":{"name":{"value":"new"}},"shortName":"switch4","inputs":"1","output":"0","category":"mixer-function","color":"#E6E0F8","icon":"arrow-in.png","outputs":"4"}},
|
|
{"type":"AudioSwitch8_OA_F32","data":{"defaults":{"name":{"value":"new"}},"shortName":"switch8","inputs":"1","output":"0","category":"mixer-function","color":"#E6E0F8","icon":"arrow-in.png","outputs":"8"}},
|
|
{"type":"FFT_Overlapped_F32","data":{"defaults":{"name":{"value":"new"}},"shortName":"blockwiseFFT","inputs":"NaN","output":"0","category":"analyze-function","color":"#E6E0F8","icon":"arrow-in.png","outputs":"NaN"}},
|
|
{"type":"IFFT_Overlapped_F32","data":{"defaults":{"name":{"value":"new"}},"shortName":"blockwiseIFFT","inputs":"NaN","output":"0","category":"analyze-function","color":"#E6E0F8","icon":"arrow-in.png","outputs":"NaN"}},
|
|
{"type":"AudioInputI2S_F32","data":{"defaults":{"name":{"value":"new"}},"shortName":"audioInI2S","inputs":"0","output":"0","category":"input-function","color":"#E6E0F8","icon":"arrow-in.png","outputs":"2"}},
|
|
{"type":"AudioOutputI2S_F32","data":{"defaults":{"name":{"value":"new"}},"shortName":"audioOutI2S","inputs":"2","output":"0","category":"output-function","color":"#E6E0F8","icon":"arrow-in.png","outputs":"0"}},
|
|
|
|
{"type":"AudioInputSPDIF3_F32","data":{"defaults":{"name":{"value":"new"}},"shortName":"spdif3","inputs":0,"outputs":2,"category":"input-function","color":"#E6E0F8","icon":"arrow-in.png"}},
|
|
{"type":"AsyncAudioInputSPDIF3_F32","data":{"defaults":{"name":{"value":"new"}},"shortName":"spdif_async","inputs":0,"outputs":2,"category":"input-function","color":"#E6E0F8","icon":"arrow-in.png"}},
|
|
{"type":"AudioInputUSB_F32","data":{"defaults":{"name":{"value":"new"}},"shortName":"audioInUSB","inputs":"0","output":"0","category":"input-function","color":"#E6E0F8","icon":"arrow-in.png","outputs":"2"}},
|
|
{"type":"AudioOutputUSB_F32","data":{"defaults":{"name":{"value":"new"}},"shortName":"audioOutUSB","inputs":"2","output":"0","category":"output-function","color":"#E6E0F8","icon":"arrow-in.png","outputs":"0"}},
|
|
{"type":"AudioOutputSPDIF3_F32","data":{"defaults":{"name":{"value":"new"}},"shortName":"spdif3Out","inputs":2,"outputs":0,"category":"output-function","color":"#E6E0F8","icon":"arrow-in.png"}},
|
|
{"type":"AudioPlayQueue_F32","data":{"defaults":{"name":{"value":"new"}},"shortName":"playQueue","inputs":"0","output":"0","category":"play-function","color":"#E6E0F8","icon":"arrow-in.png","outputs":"1"}},
|
|
{"type":"AudioRecordQueue_F32","data":{"defaults":{"name":{"value":"new"}},"shortName":"recordQueue","inputs":"1","output":"0","category":"record-function","color":"#E6E0F8","icon":"arrow-in.png","outputs":"0"}},
|
|
{"type":"AudioSynthNoisePink_F32","data":{"defaults":{"name":{"value":"new"}},"shortName":"noisePink","inputs":"0","output":"0","category":"synth-function","color":"#E6E0F8","icon":"arrow-in.png","outputs":"1"}},
|
|
{"type":"AudioSynthWaveformSine_F32","data":{"defaults":{"name":{"value":"new"}},"shortName":"sine","inputs":"0","output":"0","category":"synth-function","color":"#E6E0F8","icon":"arrow-in.png","outputs":"1"}},
|
|
{"type":"AudioSynthSineCosine_F32","data":{"defaults":{"name":{"value":"new"}},"shortName":"sine-cos","inputs":"0","output":"0","category":"synth-function","color":"#E6E0F8","icon":"arrow-in.png","outputs":"2"}},
|
|
{"type":"AudioSynthWaveform_F32","data":{"defaults":{"name":{"value":"new"}},"shortName":"waveform","inputs":"0","output":"0","category":"synth-function","color":"#E6E0F8","icon":"arrow-in.png","outputs":"1"}},
|
|
{"type":"AudioSynthNoiseWhite_F32","data":{"defaults":{"name":{"value":"new"}},"shortName":"noiseWhite","inputs":"0","output":"0","category":"synth-function","color":"#E6E0F8","icon":"arrow-in.png","outputs":"1"}},
|
|
{"type":"AudioSynthGaussian_F32","data":{"defaults":{"name":{"value":"new"}},"shortName":"GaussianWhiteNoise","inputs":"0","output":"0","category":"synth-function","color":"#E6E0F8","icon":"arrow-in.png","outputs":"1"}},
|
|
{"type":"AudioAlignLR_F32","data":{"defaults":{"name":{"value":"new"}},"shortName":"alignLR","inputs":"2","output":"0","category":"input-function","color":"#E6E0F8","icon":"arrow-in.png","outputs":"3"}},
|
|
{"type":"RadioFMDetector_F32","data":{"defaults":{"name":{"value":"new"}},"shortName":"FMDetector","inputs":"1","output":"0","category":"radio-function","color":"#E6E0F8","icon":"arrow-in.png","outputs":"2"}},
|
|
{"type":"radioModulatedGenerator_F32","data":{"defaults":{"name":{"value":"new"}},"shortName":"Modulator","inputs":"2","output":"0","category":"radio-function","color":"#E6E0F8","icon":"arrow-in.png","outputs":"2"}},
|
|
{"type":"radioNoiseBlanker_F32","data":{"defaults":{"name":{"value":"new"}},"shortName":"NoiseBlank","inputs":"2","output":"0","category":"radio-function","color":"#E6E0F8","icon":"arrow-in.png","outputs":"2"}},
|
|
|
|
{"type":"radioCESSBtransmit_F32","data":{"defaults":{"name":{"value":"new"}},"shortName":"CESSB_Mod","inputs":"1","output":"0","category":"radio-function","color":"#E6E0F8","icon":"arrow-in.png","outputs":"2"}},
|
|
{"type":"radioCESSB_Z_transmit_F32","data":{"defaults":{"name":{"value":"new"}},"shortName":"CESSB_Z_Mod","inputs":"1","output":"0","category":"radio-function","color":"#E6E0F8","icon":"arrow-in.png","outputs":"2"}},
|
|
{"type":"radioVoiceClipper_F32","data":{"defaults":{"name":{"value":"new"}},"shortName":"Clipper","inputs":"1","output":"0","category":"radio-function","color":"#E6E0F8","icon":"arrow-in.png","outputs":"2"}},
|
|
|
|
{"type":"RadioFMDiscriminator_F32","data":{"defaults":{"name":{"value":"new"}},"shortName":"FMDiscrim","inputs":"1","output":"0","category":"radio-function","color":"#E6E0F8","icon":"arrow-in.png","outputs":"2"}},
|
|
{"type":"RadioBFSKModulator_F32","data":{"defaults":{"name":{"value":"new"}},"shortName":"BFSKMod","inputs":"0","output":"0","category":"radio-function","color":"#E6E0F8","icon":"arrow-in.png","outputs":"1"}},
|
|
{"type":"UART_F32","data":{"defaults":{"name":{"value":"new"}},"shortName":"UART","inputs":"1","output":"0","category":"radio-function","color":"#E6E0F8","icon":"arrow-in.png","outputs":"0"}},
|
|
|
|
{"type":"RadioFT8Modulator_F32","data":{"defaults":{"name":{"value":"new"}},"shortName":"FT8Mod","inputs":"0","output":"0","category":"radio-function","color":"#E6E0F8","icon":"arrow-in.png","outputs":"1"}},
|
|
{"type":"RadioFT8Demodulator_F32","data":{"defaults":{"name":{"value":"new"}},"shortName":"FT8Demod","inputs":"1","output":"0","category":"radio-function","color":"#E6E0F8","icon":"arrow-in.png","outputs":"0"}},
|
|
|
|
{"type":"RadioIQMixer_F32","data":{"defaults":{"name":{"value":"new"}},"shortName":"I-QMixer","inputs":"2","output":"0","category":"radio-function","color":"#E6E0F8","icon":"arrow-in.png","outputs":"2"}},
|
|
{"type":"AudioControlSGTL5000","data":{"defaults":{"name":{"value":"new"}},"shortName":"sgtl5000","inputs":0,"outputs":0,"category":"control-function","color":"#E6E0F8","icon":"arrow-in.png"}},
|
|
{"type":"AudioControlAK4558","data":{"defaults":{"name":{"value":"new"}},"shortName":"ak4558","inputs":0,"outputs":0,"category":"control-function","color":"#E6E0F8","icon":"arrow-in.png"}},
|
|
{"type":"AudioControlCS4272","data":{"defaults":{"name":{"value":"new"}},"shortName":"cs4272","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"}},
|
|
{"type":"AudioControlCS42448","data":{"defaults":{"name":{"value":"new"}},"shortName":"cs42448","inputs":0,"outputs":0,"category":"control-function","color":"#E6E0F8","icon":"arrow-in.png"}}
|
|
|
|
]}
|
|
</script>
|
|
|
|
<script type="text/x-red" data-help-name="AudioCalcEnvelope_F32">
|
|
<p> AudioCalcEnvelope_F32</p>
|
|
<p> Created: Chip Audette, Feb 2017</p>
|
|
<p> Purpose: This module extracts the envelope of the audio signal.</p>
|
|
<p> Derived From: Core envelope extraction algorithm is from "smooth_env"</p>
|
|
<p> WDRC_circuit from CHAPRO from BTNRC: https://github.com/BTNRH/chapro</p>
|
|
<p> As of Feb 2017, CHAPRO license is listed as "Creative Commons?"</p>
|
|
<p> This processes a single stream fo audio data (ie, it is mono)</p>
|
|
<p>Used in support of other classes. Deprecated for use in an INO.
|
|
See Compressor and Compressor2 for complete, ready to use classes.</p>
|
|
<p> MIT License. use at your own risk.</p>
|
|
</script>
|
|
<script type="text/x-red" data-template-name="AudioCalcEnvelope_F32 ">
|
|
<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>
|
|
</script>
|
|
|
|
<script type="text/x-red" data-help-name="AudioCalcGainWDRC_F32">
|
|
<p> AudioCalcGainWDRC_F32</p>
|
|
<p> Created: Chip Audette, Feb 2017</p>
|
|
<p> Purpose: This module calculates the gain needed for wide dynamic range compression.</p>
|
|
<p> Derived From: Core algorithm is from "WDRC_circuit"</p>
|
|
<p> WDRC_circuit from CHAPRO from BTNRC: https://github.com/BTNRH/chapro</p>
|
|
<p> As of Feb 2017, CHAPRO license is listed as "Creative Commons?"</p>
|
|
<p> This processes a single stream of audio data (ie, it is mono)</p>
|
|
<p>Used in support of other classes. Deprecated for use in an INO.
|
|
See Compressor and Compressor2 for complete, ready to use classes.</p>
|
|
<p> MIT License. use at your own risk.</p>
|
|
</script>
|
|
<script type="text/x-red" data-template-name="AudioCalcGainWDRC_F32 ">
|
|
<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>
|
|
</script>
|
|
<script type="text/x-red" data-help-name="AudioCalcLevel_F32">
|
|
<p>Time weighting for sound level meter. Defaults to SLOW</p>
|
|
</script>
|
|
<script type="text/x-red" data-template-name="AudioCalcLevel_F32 ">
|
|
<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>
|
|
</script>
|
|
|
|
<script type="text/x-red" data-help-name="AudioCalcGainWDRC_F32">
|
|
<p> AudioCalcGainWDRC_F32: Wide Dynamic Rnage Compressor</p>
|
|
<p> Created: Chip Audette (OpenAudio) Feb 2017</p>
|
|
<p> Derived From: WDRC_circuit from CHAPRO from BTNRC: https://github.com/BTNRH/chapro</p>
|
|
<p> As of Feb 2017, CHAPRO license is listed as "Creative Commons?"</p>
|
|
<p> MIT License. Use at your own risk.</p>
|
|
</script>
|
|
<script type="text/x-red" data-template-name="AudioCalcGainWDRC_F32 ">
|
|
<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>
|
|
</script>
|
|
<script type="text/x-red" data-help-name="AudioEffectCompWDRC_F32">
|
|
<p> AudioCalcGainWDRC_F32: Wide Dynamic Rnage Compressor</p>
|
|
<p> Created: Chip Audette (OpenAudio) Feb 2017</p>
|
|
<p> Derived From: WDRC_circuit from CHAPRO from BTNRC: https://github.com/BTNRH/chapro</p>
|
|
<p> As of Feb 2017, CHAPRO license is listed as "Creative Commons?"</p>
|
|
<p> MIT License. Use at your own risk.</p>
|
|
</script>
|
|
<script type="text/x-red" data-template-name="AudioEffectCompWDRC_F32 ">
|
|
<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>
|
|
</script>
|
|
|
|
<div>
|
|
<script type="text/x-red" data-help-name="AudioConvert_I16toF32">
|
|
<!-- ============ AudioConvert_I16toF32 ========= -->
|
|
<h3>Summary</h3>
|
|
<div class=tooltipinfo>
|
|
<p>Takes daudio data in conventional Teensy Audio integer format,
|
|
and converts it to floating point data suitable for this F32 Audio library.</p>
|
|
</div>
|
|
<h3>Boards Supported</h3>
|
|
<ul>
|
|
<li>Teensy 3.2
|
|
<li>Teensy 3.5
|
|
<li>Teensy 3.6
|
|
<li>Teensy 4.0
|
|
<li>Teensy 4.1
|
|
</ul>
|
|
<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 F32 format</td></tr>
|
|
</table>
|
|
<h3>Functions</h3>
|
|
<p>There are no parameters to be modified and this class has no functions.
|
|
|
|
<h3>Examples</h3>
|
|
<p class=exam>File > Examples > OpenAudio_ArduinoLibrary > MyAudioEffect_Float
|
|
</p>
|
|
|
|
<h3>Notes</h3>
|
|
<p>This is the Teensy Audio I16 to OpenAudio_F32 data cconverter. The 16-bit signed
|
|
integer input can range from -32768 to 32767 in level The floating point (F32)
|
|
output scales this same range to -1.0 to 0.9999695 usually called "-1 to +1."
|
|
There are no limits of signal range on the floating point side, so -1 to +1
|
|
is chosen for convenience. The integer data has a dynamic range that is 8-bits
|
|
less than that of the floating point side, so no loss of precision
|
|
occurs with this conversion. The integer value 0 converts to the floating point
|
|
value, 0.0.</p>
|
|
|
|
<p>Only an output is shown for this converter because this Design Tool only follows
|
|
the flow of F32 floating point data. Work is in progress to allow
|
|
a mix of I16 and F32 in the same Design Tool.</p>
|
|
|
|
</script>
|
|
<script type="text/x-red" data-template-name="AudioConvert_I16toF32">>
|
|
<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>
|
|
</script>
|
|
|
|
|
|
|
|
<div>
|
|
<script type="text/x-red" data-help-name="AudioConvert_F32toI16">
|
|
<!-- ============ AudioConvert_F32toI16 ========= -->
|
|
<h3>Summary</h3>
|
|
<div class=tooltipinfo>
|
|
<p>Takes audio data in F32 Audio library floating point format conventional
|
|
and converts it to Teensy Audio integer I16 format.</p>
|
|
</div>
|
|
<h3>Boards Supported</h3>
|
|
<ul>
|
|
<li>Teensy 3.2
|
|
<li>Teensy 3.5
|
|
<li>Teensy 3.6
|
|
<li>Teensy 4.0
|
|
<li>Teensy 4.1
|
|
</ul>
|
|
<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 F32 format</td></tr>
|
|
</table>
|
|
<h3>Functions</h3>
|
|
<p>There are no parameters to be modified and this class has no functions.
|
|
|
|
<h3>Examples</h3>
|
|
<p class=exam>File > Examples > OpenAudio_ArduinoLibrary > MyAudioEffect_Float
|
|
</p>
|
|
|
|
<h3>Notes</h3>
|
|
<p>This is the OpenAudio_F32 to Teensy Audio I16 data cconverter.
|
|
The floating point (F32) range must be limited to
|
|
a range of -1.0 to 0.9999695, usually called "-1 to +1," or
|
|
clipping will occur with this conversion. The 16-bit signed
|
|
integer output can only range from -32768 to 32767. Values outside
|
|
these limits will be clipped. The integer data will have a dynamic range
|
|
that is 8-bits less than that of the floating point side, and so a loss of precision
|
|
occurs with this conversion. The floating point vaue 0.0 converts
|
|
to an integer value of 0.
|
|
value, 0.0.</p>
|
|
|
|
|
|
<p>Only an input is shown for this converter because this Design Tool only follows
|
|
the flow of F32 floating point data. Work is in progress to allow
|
|
a mix of I16 and F32 in the same Design Tool.</p>
|
|
</script>
|
|
<script type="text/x-red" data-template-name="AudioConvert_F32toI16">>
|
|
<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>
|
|
</script>
|
|
|
|
|
|
<div>
|
|
<script type="text/x-red" data-help-name="AudioFilterEqualizer_F32">
|
|
<!-- ============ AudioFilterEqualizer_F32 ========= -->
|
|
<h3>Summary</h3>
|
|
<div class=tooltipinfo>
|
|
<p>Uses flat-delay FIR filtering to generate a filter with
|
|
arbitrary amplitude response.</p>
|
|
</div>
|
|
<h3>Boards Supported</h3>
|
|
<ul>
|
|
<li>Teensy 3.6
|
|
<li>Teensy 4.0
|
|
<li>Teensy 4.1
|
|
</ul>
|
|
<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</td></tr>
|
|
<tr class=odd><td align=center>Out 0</td><td>Output Equalized Signal</td></tr>
|
|
</table>
|
|
<h3>Functions</h3>
|
|
|
|
<p class=func><span class=keyword>equalizerNew</span>(<strong>uint16_t</strong> nBands, <strong>float</strong> *feq, <strong>float</strong> *adb, <strong>uint16_t</strong> nFIR, <strong>float</strong> *cf32f, <strong>float</strong> kdb);</p>
|
|
<p class=desc>Does the design of the equalizer and enables it for audio updates.
|
|
nBands is the number of frequecy bands,
|
|
feq points to an array of band tops in Hz,
|
|
adb points to an array of dB levels for the bands,
|
|
nFIR is the number of FIR coefficients being used and
|
|
kdb is the Kaiser window parameter that sets the sidelobe response.
|
|
</p>
|
|
|
|
<p class=func><span class=keyword>getResponse</span>(<strong>uint16_t</strong> nFreq, <strong>float</strong> *rdb);</p>
|
|
<p class=desc>Calculates the response of the equalizer in dB at nFreq equally spaced
|
|
frequencies. rdb is a pointer to an array of nFreq floats where the response can be put.
|
|
</p>
|
|
|
|
<h3>Examples</h3>
|
|
<p class=exam>File > Examples > OpenAudio_ArduinoLibrary > TestEqualizer1
|
|
</p>
|
|
|
|
<p class=exam>File > Examples > OpenAudio_ArduinoLibrary > TestEqualizer1Audio
|
|
</p>
|
|
|
|
<h3>Notes</h3>
|
|
<p>This equalizer is specified by an array of 'nBands' frequency bands
|
|
each of of arbitrary frequency span. The first band always starts at
|
|
0.0 Hz, and that value is not entered. Each band is specified by the upper
|
|
frequency limit to the band.
|
|
The last band always ends at half of the sample frequency, which for 44117 Hz
|
|
sample frequency would be 22058.5. Each band is specified by its upper
|
|
frequency in an .INO supplied array feq[]. The dB level of that band is
|
|
specified by a value, in dB, arranged in an .INO supplied array
|
|
aeq[]. Thus a trivial bass/treble control might look like:</p>
|
|
<pre class="desc">
|
|
nBands = 3;
|
|
feq[] = {300.0, 1500.0, 22058.5};
|
|
float32_t bass = -2.5; // in dB, relative to anything
|
|
float32_t treble = 6.0;
|
|
aeq[] = {bass, 0.0, treble};
|
|
</pre>
|
|
<p>Note that there is much, much more information in the
|
|
AudioFilterEqualizer_F32.h file at the OpenAudio_Arduino directory.
|
|
This includes more examples.</p>
|
|
</script>
|
|
<script type="text/x-red" data-template-name="AudioFilterEqualizer_F32">>
|
|
<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>
|
|
</script>
|
|
|
|
|
|
|
|
<div>
|
|
<script type="text/x-red" data-help-name="AudioFilterFIRGeneral_F32">
|
|
<!-- ============ AudioFilterFIRGeneral_F32 ========= -->
|
|
<h3>Summary</h3>
|
|
<div class=tooltipinfo>
|
|
<p>Uses flat-delay FIR filtering to generate Low Pass, High Pass,
|
|
Band Pas and Band Reject Filters, do the filtering and compute the
|
|
response.</p>
|
|
</div>
|
|
<h3>Boards Supported</h3>
|
|
<ul>
|
|
<li>Teensy 3.5
|
|
<li>Teensy 3.6
|
|
<li>Teensy 4.0
|
|
<li>Teensy 4.1
|
|
</ul>
|
|
<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</td></tr>
|
|
<tr class=odd><td align=center>Out 0</td><td>Output Filtered Signal</td></tr>
|
|
</table>
|
|
<h3>Functions</h3>
|
|
|
|
<p class=func><span class=keyword>FIRGeneralNew</span>(<strong>float</strong> *adb, <strong>uint16_t</strong> nFIR, <strong>float</strong> *cf32f, <strong>float</strong> kdb, <strong>float</strong> *pStateArray);</p>
|
|
<p class=desc>Does the design of the filter and enables it for audio updates.
|
|
adb points to an array of dB levels for the bands,
|
|
nFIR is the number of FIR coefficients being used,
|
|
cf32f is a pointer to an INO supplied array where the coefficients will be stored,
|
|
nBands is the number of frequecy bands,
|
|
feq points to an array of band tops in Hz,
|
|
kdb is the Kaiser window parameter that sets the sidelobe response, and
|
|
pStateArray is a pointer to an INO supplied 2*nFIR+128 array of floats for working space.
|
|
</p>
|
|
|
|
<p class=func><span class=keyword>LoadCoeffs</span>(<strong>uint16_t</strong> nFIR, <strong>float</strong> *cf32, <strong>float</strong> pStateArray);</p>
|
|
<p class=desc>Loads new filter coefficients that are INO supplied.
|
|
nFIR is the number of FIR coefficients being used,
|
|
cf32 is a pointer to an array of FIR coefficients (name of array)
|
|
pStateArray is a pointer to a 2*nFIR+128 array of floats for working space (name of array)
|
|
</p>
|
|
|
|
<p class=func><span class=keyword>getResponse</span>(<strong>uint16_t</strong> nFreq, <strong>float</strong> *rdb);</p>
|
|
<p class=desc>Calculates the response of the equalizer in dB at nFreq equally spaced
|
|
frequencies. rdb is a pointer to an array of nFreq floats where the response can be put.</p>
|
|
|
|
<h3>Examples</h3>
|
|
<p class=exam>File > Examples > OpenAudio_ArduinoLibrary > TestFIRGeneralLarge4
|
|
</p>
|
|
|
|
<p class=exam>File > Examples > OpenAudio_ArduinoLibrary > TestFIRGeneralLarge5
|
|
</p>
|
|
<h3>Notes</h3>
|
|
|
|
<p>For those new to C, when a pointer to an array is needed in a function call, just
|
|
supply the name of the array. See the examples to see how this works.</p>
|
|
|
|
<p>The frequency response of the filter is specfied by a series of ideal dB levels.
|
|
for instance, 0.0 dB for a pass band and -150.0 dB for a stop band.
|
|
IF nFIR is even, the response specification needs nFIR/2 points and if nFIR is odd,
|
|
it needs (nFIR+1)/2 points. The "to do" list has macros to specify the common
|
|
responses. Meanwhile, see the example INOs for methods of doing this. </p>
|
|
|
|
<p>The INO must supply memory that is used by the ARM FIR routine called workspace.
|
|
This is an array of float variables that is 2*nFIR+128 in size. The call to design and
|
|
use a filter need a pointer to this array, which for C is the name of the array.</p>
|
|
|
|
<p>The header file, AudioFilterFIRGeneral_F32.h in the OpenAudio_ArduinoLibrary directory
|
|
includes many notes, timing and examples. Be sure to look at those when getting
|
|
acquainted with this class.</p>
|
|
|
|
<p>FIR filters can be (and are here) implemented to have symmetrical coefficients. This
|
|
results in constant delay at all frequencies (linear phase). For some applications this can
|
|
be an important feature. Sometimes it is suggested that the FIR should not be
|
|
used because of the latency it creates. Note that if constant delay is needed, the FIR
|
|
implementation does this with minimum latency.</p>
|
|
|
|
<p>AudioFilterFIR_F32 in this OpenAudio_ArduinoLibrary handles 32-bit floating point
|
|
data and a maximum of 200 taps. This class requires the INO to provide the working
|
|
space and thereby puts no limit on the number of FIR taps (coefficients) being used.
|
|
The processor does run out of time, and that limits Teensy 3.6 to about 6000 taps
|
|
and Teensy 4.x to about 6000. As a starting spot for huge FIR filters, one might use
|
|
1/2 or 1/3 of those numbers.</p>
|
|
|
|
<p>It is practical to switch filter coefficient arrays on-the-fly.
|
|
See the LoadCoeffs() function. This class is initialized to a 4 coefficient
|
|
pass-through filter.</p>
|
|
|
|
</script>
|
|
<script type="text/x-red" data-template-name="AudioFilterFIRGeneral_F32">>
|
|
<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>
|
|
</script>
|
|
|
|
<div>
|
|
<script type="text/x-red" data-help-name="AudioFilterConvolution_F32">
|
|
<!-- ============ AudioFilterConvolution_F32 ========= -->
|
|
<h3>Summary</h3>
|
|
<div class=tooltipinfo>
|
|
<p> Convolutional filtering. Faster than a FIR if you want a 512 tap filter.</p>
|
|
</div>
|
|
<h3>Boards Supported</h3>
|
|
<ul>
|
|
<li>Teensy 3.5
|
|
<li>Teensy 3.6
|
|
<li>Teensy 4.0
|
|
<li>Teensy 4.1
|
|
</ul>
|
|
<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</td></tr>
|
|
<tr class=odd><td align=center>Out 0</td><td>Output Filtered Signal</td></tr>
|
|
</table>
|
|
<h3>Functions</h3>
|
|
|
|
<p class=func><span class=keyword>initFilter</span>(<strong>void</strong>);</p>
|
|
<p class=desc> Without parameters, the initFilter function does not design a filter, but rather
|
|
just uses whatever FIR coefficients are in place. These may have been
|
|
loaded by way of the getCoeffPtr() function or passThrough(1) may be in place. </p>
|
|
|
|
<p class=func><span class=keyword>initFilter</span>(<strong>float32_t</strong> fc,
|
|
<strong>float32_t</strong> Astop, <strong>int</strong> type, <strong>float32_t</strong> dfc);</p>
|
|
<p class=desc> Designs filters. fc is the edge frequency in Hz for LPF and HPF
|
|
and center frequency for BPF and BRF, Astop is the stopband attenuation in dB.
|
|
The parameter dfc is the filter bandwidth (only for bandpass and band reject).
|
|
The parameter type sets the filter per the following defines:
|
|
<pre class="desc">
|
|
LOWPASS Low pass with fc cutoff frequency
|
|
HIGHPASS High pass with fc cutoff frequency.
|
|
BANDPASS Band pass with fc center frequency and dfc pass band width.
|
|
BANDREJECT Band reject with fc center frequency and dfc reject band width.
|
|
HILBERT Hilbert transform. Not Currently Available
|
|
</pre>
|
|
</p>
|
|
|
|
<p class=func><span class=keyword>passThrough</span>(<strong>int</strong>stat)</p>
|
|
<p class=desc>passThrough(int stat) allows data for this filter object to be passed through
|
|
unchanged with stat=1. The default is stat=0.
|
|
</p>
|
|
|
|
<p class=func><span class=keyword>getCoeffPtr</span>(<strong>void</strong>);</p>
|
|
<p class=desc>Returns a pointer to the coefficient array. To use this, compute
|
|
the coefficients of a 512 tap FIR filter with the desired response. Then
|
|
load the 512 float32_t buffer with the coefficients.
|
|
</p>
|
|
|
|
<h3>Examples</h3>
|
|
<p class=exam>File > Examples > OpenAudio_ArduinoLibrary > TestConvolutionFilter_F32
|
|
</p>
|
|
|
|
|
|
<h3>Notes</h3>
|
|
|
|
<p>See the file AudioFilterConvolution_F32.h, as well as the example file, just above, for many notes,
|
|
hints and sample code.</p>.
|
|
|
|
</script>
|
|
<script type="text/x-red" data-template-name="AudioFilterConvolution_F32">>
|
|
<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>
|
|
</script>
|
|
|
|
<div>
|
|
<script type="text/x-red" data-help-name="AudioLMSDenoiseNotch_F32">
|
|
<!-- ============ AudioLMSDenoiseNotch_F32 ========= -->
|
|
<h3>Summary</h3>
|
|
<div class=tooltipinfo>
|
|
<p>Provides LMS denoise or auto-notch functions.</p>
|
|
</div>
|
|
<h3>Boards Supported</h3>
|
|
<ul>
|
|
<li>Teensy 3.6
|
|
<li>Teensy 4.0
|
|
<li>Teensy 4.1
|
|
</ul>
|
|
<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</td></tr>
|
|
<tr class=odd><td align=center>Out 0</td><td>Output Filtered Signal</td></tr>
|
|
</table>
|
|
<h3>Functions</h3>
|
|
<p class=func><span class=keyword>initializeLMS</span>(<strong>uint16_t</strong> what, <strong>uint16_t</strong> lengthDataF, <strong>uint16_t</strong> lengthDataD);</p>
|
|
<p class=desc>The parameter what must be either DENOISE or NOTCH. The lengthDataF buffer should
|
|
be a power of 2 between 2 and 128. It will be shifted down to a power of 2, if not. The delay
|
|
buffer size, lengthDataD can be any value between 1 and 16.
|
|
</p>
|
|
|
|
<p class=func><span class=keyword>setParameters</span>(<strong>float32_t</strong> beta, <strong>float32_t</strong> decay);</p>
|
|
<p class=desc>Sets the gain, beta, that varies the amount of denoise and notching. Adjust
|
|
for the desired sound.
|
|
</p>
|
|
|
|
<p class=func><span class=keyword>enable</span>(<strong>bool</strong> setEnable);</p>
|
|
<p class=desc>The parameter setEnable should be <strong>true</strong> or <strong>false.</strong>
|
|
If not enabled, the audio is passed through unchanged.
|
|
</p>
|
|
|
|
<h3>Examples</h3>
|
|
<p class=exam>File > Examples > OpenAudio_ArduinoLibrary > LMS1.ino
|
|
</p>
|
|
|
|
<h3>Notes</h3>
|
|
<p>This block can be changed at any time between denoise and auto-notching. Thus, usually
|
|
only one of these is used in a radio.</p>
|
|
<p>More notes are included in the file AudioLMSDenoiseNotch_F32.h</p>
|
|
|
|
</script>
|
|
<script type="text/x-red" data-template-name="AudioLMSDenoiseNotch_F32">>
|
|
<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>
|
|
</script>
|
|
|
|
<div>
|
|
<script type="text/x-red" data-help-name="AudioSpectralDenoise_F32">
|
|
<!-- ============ AudioSpectralDenoise_F32 ========= -->
|
|
<h3>Summary</h3>
|
|
<div class=tooltipinfo>
|
|
<p>Spectral Noise Reduction</p>
|
|
<p>Remove random noise, such as background noise or machine generated noise, and try
|
|
to leave voice intact.</p>
|
|
<p>Spectral NR does not try to remove constant tones or clicks and pops.</p>
|
|
<p>Spectral NR is generally not useful for cleaning up 'pure tone' sources, such as morse code.</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 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>setup</span>(<strong>AudioSettings_F32 &</strong>settings, <strong>int</strong> n_fft);</p>
|
|
<p class=desc>Setup the filter. Must be called if parameters not passed in to the
|
|
constructor. Can be re-called if other parameters have been changed to have
|
|
the changes take effect.
|
|
The maximum FFT size is dictated by the underlying FFT_OA code.
|
|
</p>
|
|
<p class=func><span class=keyword>enable</span>(<strong>bool</strong> start);</p>
|
|
<p class=desc>Turn on or offthe filter. The filter is enabled by default upon
|
|
creation.
|
|
</p>
|
|
<p class=func><span class=keyword>enabled</span>();</p>
|
|
<p class=desc>Return the enabled state of the filter.</p>
|
|
<p class=func><span class=keyword>getAsnr</span>();</p>
|
|
<p class=desc>Return the current ASNR value.</p>
|
|
<p class=func><span class=keyword>setAsnr</span>(<strong>float32_t</strong> value);</p>
|
|
<p class=desc>Set the ASNR value. Active SNR.</p>
|
|
<p class=desc>Call <span class=keyword>setup()</span> for the change to take effect.</p>
|
|
<p class=func><span class=keyword>getVADHighFreq</span>();</p>
|
|
<p class=desc>Get the VAD band high frequency cutoff value.</p>
|
|
<p class=func><span class=keyword>setVADHighFreq</span>(<strong>float32_t</strong> value);</p>
|
|
<p class=desc>Set the VAD High Frequency cutoff value. Sets the high
|
|
frequency value of the Voice Activity Detector (VAD) window.
|
|
</p>
|
|
<p class=desc>Call <span class=keyword>setup()</span> for the change to take effect.</p>
|
|
<p class=func><span class=keyword>getVADLowFreq</span>();</p>
|
|
<p class=desc>Get the VAD band low frequency value.</p>
|
|
<p class=func><span class=keyword>setVADLowFreq</span>(<strong>float32_t</strong> value);</p>
|
|
<p class=desc>Set the VAD band low frequency value.</p>
|
|
<p class=desc>Call <span class=keyword>setup()</span> for the change to take effect.</p>
|
|
<p class=func><span class=keyword>getNRAlpha</span>();</p>
|
|
<p class=desc>get the NRalpha value. NR alpha is the time smoothing constant. It's
|
|
range is clipped between 0.9 and 0.9999 in the code. Settings >0.95
|
|
generally recommended, or you can get strong reverb and 'watery' effects.
|
|
</p>
|
|
<p class=func><span class=keyword>setNRAlpha</span>(<strong>float32_t</strong> value);</p>
|
|
<p class=desc>Set the NRalpha value.</p>
|
|
<p class=desc>The change takes effect immediately.</p>
|
|
<p class=func><span class=keyword>getSNRPrioMin</span>();</p>
|
|
<p class=desc>Get the SNR prior value.</p>
|
|
<p class=func><span class=keyword>setSNRPrioMin</span>(<strong>float32_t</strong> value);</p>
|
|
<p class=desc>Set the SNR prior value.</p>
|
|
<p class=desc>The change takes effect immediately.</p>
|
|
<p class=func><span class=keyword>getNRWidth</span>();</p>
|
|
<p class=desc>Get the NR width. Used for the measuring 'span' in the musical note
|
|
reduction code.
|
|
</p>
|
|
<p class=func><span class=keyword>setNRWidth</span>(<strong>int16_t</strong> value);</p>
|
|
<p class=desc>Set the NR width.</p>
|
|
<p class=desc>The change takes effect immediately.</p>
|
|
<p class=func><span class=keyword>getPowerThreshold</span>();</p>
|
|
<p class=desc>Get the power threshold. Used to limit the effects of the musical
|
|
note reduction code.
|
|
</p>
|
|
<p class=func><span class=keyword>setPowerThreshold</span>(<strong>float32_t</strong> value);</p>
|
|
<p class=desc>Set the power threshold.</p>
|
|
<p class=desc>The change takes effect immediately.</p>
|
|
<p class=func><span class=keyword>getTaxFactor</span>();</p>
|
|
<p class=desc>Get the noise output smoothing factor.</p>
|
|
<p class=func><span class=keyword>setTaxFactor</span>(<strong>float32_t</strong> value);</p>
|
|
<p class=desc>Set the noise output smoothing factor. Typical values are around 0.8.</p>
|
|
<p class=desc>Call <span class=keyword>setup()</span> for the change to take effect.</p>
|
|
<p class=func><span class=keyword>getTapFactor</span>();</p>
|
|
<p class=desc>Get the speech probability smoothing factor.</p>
|
|
<p class=func><span class=keyword>setTapFactor</span>(<strong>float32_t</strong> value);</p>
|
|
<p class=desc>Set the speech probability smoothing factor. Typical values are around 0.9.</p>
|
|
<p class=desc>Call <span class=keyword>setup()</span> for the change to take effect.</p>
|
|
<h3>Examples</h3>
|
|
<p class=exam>File > Examples > OpenAudio_ArduinoLibrary > SpectralDenoise.ino
|
|
</p>
|
|
<h3>Notes</h3>
|
|
<p> The defaults work OK, but it is worth experimenting with the adjustable
|
|
parameters for your specific situation. Try adjusting NRAlpha, NRWidth and Asnr.
|
|
</p>
|
|
<p> The default FFT size is 256. You may wish to make this larger, which will allow
|
|
a finer granularity of 'buckets' to potentially improve the noise reduction, but,
|
|
will cost both processor time and memory overheads.
|
|
</p>
|
|
<p> The maximum FFT size is set by the underlying <strong>FFT_OA</strong> code, which at
|
|
time of writing limits the maximum to 2048.
|
|
</p>
|
|
<p> The code is written to account for the <strong>sample_rate_Hz</strong> passed in with
|
|
the audio settings, <strong>but</strong>, this has not been tested. If you do test,
|
|
either with a higher or lower sample rate, please report back and consider fixing
|
|
this documentation.
|
|
</p>
|
|
<h3>References</h3>
|
|
<p>The best reference on how the Spectral code was designed and works can be found on the
|
|
<a href="https://github.com/df8oe/UHSDR/wiki/Noise-reduction"> UHSDR wiki </a>
|
|
</p>
|
|
</script>
|
|
</div>
|
|
|
|
<div>
|
|
<script type="text/x-red" data-help-name="AudioFilter90Deg_F32">
|
|
<!-- ============ AudioFilter90Deg_F32 ========= -->
|
|
<h3>Summary</h3>
|
|
<div class=tooltipinfo>
|
|
<p>Creates two uncoupled paths that almost have the same amplitude gain
|
|
but differ in phase by exactly 90 degrees. </p>
|
|
</div>
|
|
<h3>Boards Supported</h3>
|
|
<ul>
|
|
<li>Teensy 3.6
|
|
<li>Teensy 4.0
|
|
<li>Teensy 4.1
|
|
</ul>
|
|
<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 Hilbert Filtered</td></tr>
|
|
<tr class=odd><td align=center>In 1</td><td>Input Signal Delayed</td></tr>
|
|
<tr class=odd><td align=center>Out 0</td><td>Output Signal Hilbert Filtered</td></tr>
|
|
<tr class=odd><td align=center>Out 1</td><td>Output Signal Delayed</td></tr>
|
|
</table>
|
|
<h3>Functions</h3>
|
|
|
|
<p class=func><span class=keyword>begin</span>(<strong>float</strong> *pCoeff, <strong>int</strong> nCoeff);</p>
|
|
<p class=desc>Initializes this block, with pCoeff being a pointer to array of F32 Hilbert Transform coefficients,
|
|
and nCoeff being the number of Hilbert transform coefficients (odd).
|
|
</p>
|
|
|
|
<h3>Examples</h3>
|
|
<p class=exam>File > Examples > OpenAudio_ArduinoLibrary > ReceiverPart1
|
|
</p>
|
|
|
|
<p class=exam>File > Examples > OpenAudio_ArduinoLibrary > ReceiverPart2
|
|
</p>
|
|
|
|
<h3>Notes</h3>
|
|
<p>This consists of two uncoupled paths that almost have the same amplitude gain
|
|
but differ in phase by exactly 90 degrees.
|
|
The number of coefficients is an odd number for the FIR Hilbert transform
|
|
as that produces an easily achievable integer sample period delay.</p>
|
|
|
|
<p>No default Hilbert Transform is provided, as it is highly application dependent.
|
|
The number of coefficients is an odd number with a maximum of 250. The Iowa
|
|
Hills program can design such a Hilbert Transform filter.</p>
|
|
</script>
|
|
<script type="text/x-red" data-template-name="AudioFilter90Deg_F32">>
|
|
<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>
|
|
</script>
|
|
|
|
|
|
<!-- ============ AudioEffectCompressor_F32 ========= -->
|
|
<script type="text/x-red" data-help-name="AudioEffectCompressor_F32">
|
|
<p> AudioEffectCompressor</p>
|
|
<p> Created: Chip Audette, Dec 2016 - Jan 2017</p>
|
|
<p> Purpose; Apply dynamic range compression to the audio stream.</p>
|
|
<p> Assumes floating-point data.</p>
|
|
<p> This processes a single stream fo audio data (ie, it is mono)</p>
|
|
<p> MIT License. use at your own risk.</p>
|
|
<p> Note: This help documentation is incomplete. See AudioEffectCompressor2_F32
|
|
for a similar block, with documentation. Compressor2 includes up to 5 segments and
|
|
look ahead delay, as well.</p>
|
|
</script>
|
|
<script type="text/x-red" data-template-name="AudioEffectCompressor_F32 ">
|
|
<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>
|
|
</script>
|
|
|
|
<!-- ============ AudioEffectDelay_OA_F32 ========= -->
|
|
<script type="text/x-red" data-help-name="AudioEffectDelay_OA_F32">
|
|
<h3>Summary</h3>
|
|
<div class=tooltipinfo>
|
|
<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 425 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>
|
|
</script>
|
|
<script type="text/x-red" data-template-name="AudioEffectDelay_OA_F32">
|
|
<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>
|
|
</script>
|
|
|
|
|
|
<div>
|
|
<script type="text/x-red" data-help-name="AudioEffectFreqShiftFD_F32">
|
|
<!-- ============ AudioEffectFreqShiftFD_F32 ========= -->
|
|
<h3>Summary</h3>
|
|
<div class=tooltipinfo>
|
|
<p>This shifts frequencies of entire audio spectrums by use of FFT and IFFT
|
|
with bin shifting. </p>
|
|
</div>
|
|
<h3>Boards Supported</h3>
|
|
<ul>
|
|
<li>Teensy 3.6
|
|
<li>Teensy 4.0
|
|
<li>Teensy 4.1
|
|
</ul>
|
|
<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</td></tr>
|
|
<tr class=odd><td align=center>Out 0</td><td>Shifted Output Signal</td></tr>
|
|
</table>
|
|
<h3>Functions</h3>
|
|
|
|
<p class=func><span class=keyword>setup</span>(<strong>AudioSettings_F32 </strong> &settings, <strong>int</strong> N_FFT);</p>
|
|
<p class=desc>Initializes the needed FFTs. Returns the size of FFT achieved
|
|
or a negative number if unsuccessful. See example below for determining N_FFT.
|
|
</p>
|
|
|
|
<p class=func><span class=keyword>setShift_bins</span>(<strong>int</strong> nBins);</p>
|
|
<p class=desc>Sets nBins, the number of FFT bins of frequency shift.
|
|
</p>
|
|
|
|
<h3>Examples</h3>
|
|
<p class=exam>File > Examples > OpenAudio_ArduinoLibrary > FrequencyShifter_FD_OA
|
|
</p>
|
|
|
|
<h3>Notes</h3>
|
|
<p>Created: Chip Audette (OpenAudio) Aug 2019</p>
|
|
|
|
<p>This processing is performed in the frequency domain.
|
|
Frequencies can only be shifted by an integer number of bins,
|
|
so small frequency shifts are not possible. For example, for
|
|
a sample rate of 44.1kHz, and when using N=256, one can only
|
|
shift frequencies in multiples of 44.1/256 = 172.3 Hz.</p>
|
|
|
|
<p>This processing is performed in the frequency domain where
|
|
we take the FFT, shift the bins upward or downward, take
|
|
the IFFT, and listen to the results. In effect, this is
|
|
single sideband modulation, which will sound very unnatural
|
|
(like robot voices!). Maybe you'll like it, or maybe not.
|
|
Probably not, unless you like weird. ;) </p>
|
|
|
|
<p>You can shift frequencies upward or downward with this algorithm.</p>
|
|
<p>This class supports changes in block size by AudioSettings_F32.</p>
|
|
<p> Also see an I-Q mixing approach with fine tuning in the example: </p>
|
|
<p class=exam>File > Examples > OpenAudio_ArduinoLibrary > FineFreqShift_OA
|
|
</p>
|
|
|
|
</script>
|
|
<script type="text/x-red" data-template-name="AudioEffectFreqShiftFD_F32">>
|
|
<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>
|
|
</script>
|
|
|
|
|
|
|
|
<div>
|
|
<script type="text/x-red" data-help-name="AudioSwitch4_OA_F32">
|
|
<!-- ============ AudioSwitch4_OA_F32 ========= -->
|
|
<h3>Summary</h3>
|
|
<div class=tooltipinfo>
|
|
<p>Switch one input to 4 outputs, which only triggers 1 of the 4
|
|
audio processing paths (thus saving computation on paths that you aren't
|
|
using). Use with mixer-4 for up to 4 paths of alternate processing.</p>
|
|
</div>
|
|
<h3>Boards Supported</h3>
|
|
<ul>
|
|
<li>Teensy 3.2
|
|
<li>Teensy 3.5
|
|
<li>Teensy 3.6
|
|
<li>Teensy 4.0
|
|
<li>Teensy 4.1
|
|
</ul>
|
|
<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 0</td></tr>
|
|
<tr class=odd><td align=center>Out 0</td><td>Switch Output Signal 0</td></tr>
|
|
<tr class=odd><td align=center>Out 1</td><td>Switch Output Signal 1</td></tr>
|
|
<tr class=odd><td align=center>Out 2</td><td>Switch Output Signal 2</td></tr>
|
|
<tr class=odd><td align=center>Out 3</td><td>Switch Output Signal 3</td></tr>
|
|
</table>
|
|
|
|
<h3>Functions</h3>
|
|
<p class=func><span class=keyword>setChannel</span>(<strong>int</strong> channel);</p>
|
|
<p class=desc>Selects the output path that will be active, 0 to 7. Returns the selected path, if valid.
|
|
</p>
|
|
|
|
<h3>Examples</h3>
|
|
<p class=exam>File > Examples > OpenAudio_ArduinoLibrary > Switches_float
|
|
</p>
|
|
|
|
<h3>Notes</h3>
|
|
<p>If you have two audio paths, like a SSB receiver path and an AM receiver path, you can
|
|
shut off the data going to the unused path with this AudioSwitch4_F32 class.
|
|
The AudioStream will not supply the packet to the next
|
|
object and that, in turn, will cause it to not request a transmission to the next
|
|
thing down the chain. The AudioStream routines do not create errors, it turns out,
|
|
and you save all the processing time and memory usage for the unused paths.</p>
|
|
|
|
<p>There is an 8 output version in the palette, if you need more outputs.</p>
|
|
|
|
<p>Created: Chip Audette, OpenAudio, April 2019</p>
|
|
|
|
</script>
|
|
<script type="text/x-red" data-template-name="AudioSwitch4_OA_F32">>
|
|
<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>
|
|
</script>
|
|
|
|
<div>
|
|
<script type="text/x-red" data-help-name="AudioSwitch8_OA_F32">
|
|
<!-- ============ AudioSwitch8_OA_F32 ========= -->
|
|
<h3>Summary</h3>
|
|
<div class=tooltipinfo>
|
|
<p>Switch one input to 8 outputs, which only triggers 1 of the 8
|
|
audio processing paths (thus saving computation on paths that you aren't
|
|
using). Use with mixer-8 for up to 8 paths of alternate processing.</p>
|
|
</div>
|
|
<h3>Boards Supported</h3>
|
|
<ul>
|
|
<li>Teensy 3.2
|
|
<li>Teensy 3.5
|
|
<li>Teensy 3.6
|
|
<li>Teensy 4.0
|
|
<li>Teensy 4.1
|
|
</ul>
|
|
<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 0</td></tr>
|
|
<tr class=odd><td align=center>Out 0</td><td>Switch Output Signal 0</td></tr>
|
|
<tr class=odd><td align=center>Out 1</td><td>Switch Output Signal 1</td></tr>
|
|
<tr class=odd><td align=center>Out 2</td><td>Switch Output Signal 2</td></tr>
|
|
<tr class=odd><td align=center>Out 3</td><td>Switch Output Signal 3</td></tr>
|
|
<tr class=odd><td align=center>Out 4</td><td>Switch Output Signal 4</td></tr>
|
|
<tr class=odd><td align=center>Out 5</td><td>Switch Output Signal 5</td></tr>
|
|
<tr class=odd><td align=center>Out 6</td><td>Switch Output Signal 6</td></tr>
|
|
<tr class=odd><td align=center>Out 7</td><td>Switch Output Signal 7</td></tr>
|
|
</table>
|
|
|
|
<h3>Functions</h3>
|
|
<p class=func><span class=keyword>setChannel</span>(<strong>int</strong> channel);</p>
|
|
<p class=desc>Selects the output path that will be active, 0 to 7. Returns the selected path, if valid.
|
|
</p>
|
|
|
|
<h3>Examples</h3>
|
|
<p class=exam>File > Examples > OpenAudio_ArduinoLibrary > Switches_float
|
|
</p>
|
|
|
|
<h3>Notes</h3>
|
|
<p>If you have multiple audio paths, like 5 different demodulators, you can
|
|
shut off the data going to the unused paths with this AudioSwitch8_F32 class.
|
|
The AudioStream will not supply the packet to the next
|
|
object and that, in turn, will cause it to not request a transmission to the next
|
|
thing down the chain. The AudioStream routines do not create errors, it turns out,
|
|
and you save all the processing time and memory usage for the unused paths.</p>
|
|
|
|
<p>There is an 4 output version in the palette, if you need less outputs.</p>
|
|
|
|
<p>Created: Chip Audette, OpenAudio, April 2019</p>
|
|
|
|
</script>
|
|
<script type="text/x-red" data-template-name="AudioSwitch8_OA_F32">>
|
|
<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>
|
|
</script>
|
|
|
|
|
|
|
|
<div>
|
|
<script type="text/x-red" data-help-name="AudioAnalyzePhase_F32">
|
|
<!-- <h2> ============ AudioAnalyzePhase_F32 AudioAnalyzePhase_F32 =========</h2> -->
|
|
<h3>AudioAnalyzePhase_F32</h3>
|
|
<h3>Summary</h3>
|
|
<div class=tooltipinfo>
|
|
<p>This block can be used to measure phase between two sinusoid inputs.
|
|
The default output IIR filter, 4-cascaded stages of BiQuad,
|
|
is suitable for this with a cut-off
|
|
frequency of 100 Hz. As an alternative, a linear phase
|
|
FIR filter can be set up with the begin function. The built in FIR
|
|
LP filter has a cutoff frequency of 4 kHz when used
|
|
at a 44.1 kHz sample rate. Any FIR filter can be used
|
|
with the setAnalyzeConfig function.
|
|
</div>
|
|
<h3>Boards Supported</h3>
|
|
<ul>
|
|
<li>Teensy 3.2
|
|
<li>Teensy 3.5
|
|
<li>Teensy 3.6
|
|
<li>Teensy 4.0
|
|
<li>Teensy 4.1
|
|
</ul>
|
|
<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>Reference Sinewave</td></tr>
|
|
<tr class=odd><td align=center>In 1</td><td>Measure Sinewave</td></tr>
|
|
<tr class=odd><td align=center>Out 0</td><td>Measured Phase Angle</td></tr>
|
|
</table>
|
|
<h3>Functions</h3>
|
|
<p class=func><span class=keyword>setAnalyzePhaseConfig</span>(<strong>uint16_t</strong> LPType, <strong>float32_t</strong> *pCoeffs, <strong>uint16_t</strong> nCoeffs);</p>
|
|
<p class=desc> </p>
|
|
<p>Changes the output filter from the IIR default, where:
|
|
<ul>
|
|
<li>LPType is NO_LP_FILTER, IIR_LP_FILTER, FIR_LP_FILTER to select the output filter</li>
|
|
<li>pCoeffs is a pointer to filter coefficients, either IIR or FIR</li>
|
|
<li>nCoeffs is the number of filter coefficients</li>
|
|
</ul>
|
|
</p>
|
|
<p class=func><span class=keyword>setAnalyzePhaseConfig</span>(<strong>uint16_t</strong> LPType, <strong>float32_t</strong> *pCoeffs, <strong>uint16_t</strong> nCoeffs, <strong>uint16_t</strong> pdConfig);</p>
|
|
<p class=desc>Is the same as above, but controls pdConfig which is a bitwiseconfiguration selection selection:</li>
|
|
<pre class="desc">
|
|
Bit 0: 0=No Limiter (default) 1=Use limiter
|
|
Bit 2,1: 00=Use no acos linearizer
|
|
01=undefined
|
|
10=Fast, math-continuous acos() (default)
|
|
11=Accurate acosf()
|
|
Bit 3: 0=No scale of multiplier 1=scale to min-max (default)
|
|
Bit 4: 0=Output in degrees 1=Output in radians (default)
|
|
</pre>
|
|
</p>
|
|
<p class=func><span class=keyword>showError</span>(<strong>uint16_t</strong> e);</p>
|
|
<p class=desc>sets whether error printing comes from update (e=1) or not (e=0)
|
|
</p>
|
|
<p>This class supports programmable block size and sample rate via Settings_F32.</p>
|
|
|
|
<h3>Examples</h3>
|
|
<p class=exam>File > Examples > OpenAudio_ArduinoLibrary > AudioTestAnalyzePhase
|
|
</p>
|
|
<p class=exam>File > Examples > OpenAudio_ArduinoLibrary > AudioTestSinCos
|
|
</p>
|
|
|
|
<h3>Notes</h3>
|
|
<p>There are two inputs, 0 and 1 (Left and Right)
|
|
There is one output, the phase angle between 0 & 1 expressed in
|
|
radians (180 degrees is Pi radians) or degrees. This is a 180-degree
|
|
type of phase detector. See RadioIQMixer_F32 for a 360 degree type.
|
|
</p>
|
|
|
|
<p><strong>Defaults:</strong> 100 Hz IIR LP, output is in radians, and this does not need a call to begin().</p>
|
|
|
|
<p> A FIR LP is available where linear phase is needed, or NO_LP_FILTER that leaves
|
|
harmonics of the input frequency. A limiter is available to remove amplitude effects. Scaling of the output
|
|
levels can be done. Many more details are available from AudioAnalyzePhase_F32.h in
|
|
the OpenAudio_ArduinoLibrary. </p>
|
|
|
|
</script>
|
|
<script type="text/x-red" data-template-name="AudioAnalyzePhase_F32">>
|
|
<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>
|
|
</script>
|
|
|
|
|
|
<div> <!-- Audio Input category -->
|
|
<script type="text/x-red" data-help-name="AudioEffectNoiseGate_F32">
|
|
<!-- ============ AudioEffectNoiseGate_F32 ======= -->
|
|
<h3>Summary</h3>
|
|
<div class=tooltipinfo>
|
|
<p>Apply envelope controlled threshold to a signal.
|
|
Inputs below a given level are removed.</p>
|
|
</div>
|
|
<h3>Boards Supported</h3>
|
|
<ul>
|
|
<li>Teensy 3.2
|
|
<li>Teensy 3.5
|
|
<li>Teensy 3.6
|
|
<li>Teensy 4.0
|
|
<li>Teensy 4.1
|
|
</ul>
|
|
<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 In</td></tr>
|
|
<tr class=odd><td align=center>Out 0</td><td>Gated Signal Out</td></tr>
|
|
</table>
|
|
<h3>Functions</h3>
|
|
|
|
<p class=func><span class=keyword>setThreshold</span>(<strong>float </strong>dBFS);</p>
|
|
<p class=desc>Sets threshold to mute below, in dBFS (relative to full scale input),
|
|
such as -40.0.</p>
|
|
|
|
<p class=func><span class=keyword>setOpeningTime</span>(<strong>float </strong>tOpen);</p>
|
|
<p class=desc>In units of seconds, such as 0.02.</p>
|
|
|
|
<p class=func><span class=keyword>setClosingTime</span>(<strong>float </strong>tClose);</p>
|
|
<p class=desc>In units of seconds, such as 0.05.</p>
|
|
|
|
<p class=func><span class=keyword>setHoldTime</span>(<strong>float </strong>tHold);</p>
|
|
<p class=desc>In units of seconds, such as 0.10.</p>
|
|
|
|
<h3>Examples</h3>
|
|
<p class=exam>File > Examples > OpenAudio_ArduinoLibrary > NoiseGate
|
|
</p>
|
|
|
|
<h3>Notes</h3>
|
|
<p>Created: Max Huster, Feb 2021 </p>
|
|
<p>Purpose: This module mutes the Audio completly, when it's below a given threshold.</p>
|
|
<p>This processes a single stream fo audio data (i.e., it is mono)</p>
|
|
</script>
|
|
|
|
<script type="text/x-red" data-template-name="_AudioEffectNoiseGate_F32">
|
|
<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>
|
|
</script>
|
|
|
|
|
|
<div> <!-- Audio Input category -->
|
|
<script type="text/x-red" data-help-name="AudioEffectCompressor2_F32">
|
|
<!-- ============ AudioEffectCompressor2_F32 ======= -->
|
|
<h3>Summary</h3>
|
|
<div class=tooltipinfo>
|
|
<p>Apply envelope controlled gain to a signal.
|
|
Up to five independent "k dB per dB" segments. Includes expansion
|
|
(squelch) compression (AGC) and limiting.</p>
|
|
</div>
|
|
<h3>Boards Supported</h3>
|
|
<ul>
|
|
<li>Teensy 3.2
|
|
<li>Teensy 3.5
|
|
<li>Teensy 3.6
|
|
<li>Teensy 4.0
|
|
<li>Teensy 4.1
|
|
</ul>
|
|
<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 In</td></tr>
|
|
<tr class=odd><td align=center>Out 0</td><td>Signal Out</td></tr>
|
|
</table>
|
|
<h3>Functions</h3>
|
|
|
|
<p class=func><span class=keyword>begin</span>();</p>
|
|
<p class=desc>Enables the compressor using parameters set
|
|
by the functon setCompressionCurve().
|
|
</p>
|
|
|
|
<p class=func><span class=keyword>setCompressionCurve</span>(<strong>struct</strong> compressionCurve*);</p>
|
|
<p class=desc>This defines the compression curve and needs an INO defined structure of type
|
|
compressionCurve. That structure is defined in AudioEffectCompressor2_F32.h.
|
|
</p> <!-- ADD INFO HERE <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< -->
|
|
|
|
<p class=func><span class=keyword>getCurrentInputDB</span>();</p>
|
|
<p class=desc>Returns the last input level in <strong>float</strong> dBFS.
|
|
</p>
|
|
|
|
<p class=func><span class=keyword>getvInMaxDB</span>();</p>
|
|
<p class=desc>Returns the maximum input level in <strong>float</strong> dBFS.
|
|
This is reset upon reading.
|
|
</p>
|
|
|
|
<p class=func><span class=keyword>getCurrentGainDB</span>();</p>
|
|
<p class=desc>Returns the current gain in <strong>float</strong> dB.
|
|
</p>
|
|
|
|
<p class=func><span class=keyword>setDelayBufferSize</span>(<strong>int16</strong> delay);</p>
|
|
<p class=desc>The input envelope detector can run ahead of the input
|
|
signal by use of this delay. This give improved transient response. The
|
|
parameter "delay" can be any power of 2 such as 64, 128 or 256.
|
|
A delay of 256 samples is 256/44100 = 0.0058 sec = 5.8 mSec.
|
|
</p>
|
|
|
|
<h3>Macros</h3>
|
|
<p>These are macros and not functions. They simplify getting a working compressor
|
|
and provide their own compressionCurve structure and are called with
|
|
a pointer to the compressor object (not to the structure) named "pobject" here.
|
|
This means the macro is invoked
|
|
without a preceeding object name. These macros replace the begin() function.
|
|
See the example program testCompressor2.ino below.</p>
|
|
|
|
<p class=func><span class=keyword>basicCompressorBegin</span>(pobject, linearInDB, compressionRatio);</p>
|
|
<p class=desc>The compression curve for basicCompressorBegin() has a 3 segments.
|
|
It is linear up to an input linearInDB
|
|
and then decreases gain according to compressionRatioDB up to an input -10 dB where it
|
|
is almost limited, with an increase of output level of 1 dB for a 10 dB increase
|
|
in input level. The output level at full input is 1 dB below full output.</p>
|
|
|
|
<p class=func><span class=keyword>limiterBegin</span>(pointerObject, float marDB, float linearInDB);</p>
|
|
<p class=desc>The compression curve for limiterBegin() has a 2 segments.
|
|
It is linear up to an input of linearInDB (typically -15.0f) and
|
|
then virtually limits for higher input levels. The output level at
|
|
this point is marDB, the margin to prevent clipping, like -2 dB.
|
|
This is not a clipper with waveform distortion, but rather decreases
|
|
the gain, dB for dB, as the input increases in the limiter region.</p>
|
|
|
|
<p class=func><span class=keyword>squelchCompressorBegin</span>(pobject, squelchInDB, linearInDB, compressionInDB, compressionRatio);</p>
|
|
<p class=desc>The compression curve for squelchCompressorBegin() has a 3 segments.
|
|
and is similar to basicCompression above, except that there is
|
|
an expansion region for low levels. So, the call defines the four regions in
|
|
terms of the input levels. squelchInDB sets the lowest input level
|
|
before the squelching effect starts.</p>
|
|
|
|
<h3>Examples</h3>
|
|
<p class=exam>File > Examples > OpenAudio_ArduinoLibrary > testCompressor2
|
|
</p>
|
|
|
|
<h3>Notes</h3>
|
|
<p>This is a general purpose audio compressor block (C++ class). It works by determining
|
|
the average input of the input signal, and based on a pre-determined curve,
|
|
changes the gain going through the block.
|
|
A good discussion is the Wikipedia page:
|
|
https://en.wikipedia.org/wiki/Dynamic_range_compression
|
|
This compressor includes up to 5 dB/dB line segments. allowing
|
|
considerable flexibility including:<ul>
|
|
<li> Multi segment compression curves, up to 5</li>
|
|
<li> Limiting</li>
|
|
<li> Approximation to "soft knees"</li>
|
|
<li> Expansion for suppressing low-level artifacts</li>
|
|
<li> Anticipation</li>
|
|
<li> Scale offset for use such as hearing-aid audiology</li>
|
|
</ul>
|
|
This is derived from the WDRC compressor. Chip Audette (OpenAudio) Feb 2017
|
|
Which was derived From: WDRC_circuit from CHAPRO from BTNRC: https://github.com/BTNRH/chapro</p>
|
|
</script>
|
|
|
|
<script type="text/x-red" data-template-name="_AudioCompressor2_F32">
|
|
<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>
|
|
</script>
|
|
|
|
|
|
<script type="text/x-red" data-help-name="AudioEffectEmpty_F32">
|
|
<h3>Summary</h3>
|
|
<div class=tooltipinfo>
|
|
<p>This module does nothing. It passes through the signal with no
|
|
changes. If you open up the code, you can copy it to use as a template
|
|
to build your own audio processing block.
|
|
</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>Input Signal</td></tr>
|
|
<tr class=odd><td align=center>Out 0</td><td>Output Signal</td></tr>
|
|
</table>
|
|
<h3>Functions</h3>
|
|
<p>Being an empty block, it has no functions.</p>
|
|
<!--
|
|
<h3>Examples</h3>
|
|
<p class=exam>File > Examples > Audio >
|
|
</p>
|
|
-->
|
|
|
|
</script>
|
|
<script type="text/x-red" data-template-name="AudioEffectEmpty_F32">
|
|
<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>
|
|
</script>
|
|
|
|
<script type="text/x-red" data-help-name="AudioEffectGain_F32">
|
|
<h3>Summary</h3>
|
|
<div class=tooltipinfo>
|
|
<p>Scale the signal by a fixed amount. The gain is applied on a per-block
|
|
(as opposed to a per-sample) basis.
|
|
</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>Result of Input Times Gain</td></tr>
|
|
</table>
|
|
<h3>Functions</h3>
|
|
<p>There are two functions for setting the gain of this block:</p>
|
|
<p class=func><span class=keyword>setGain</span>(gain);</p>
|
|
<p class=desc>Set the gain as a linear value. A value between 0.0 and 1.0
|
|
attenuates the signal while a value above 1.0 amplifies the signal. Negative
|
|
values will invert the signal.</p>
|
|
<p class=func><span class=keyword>setGain_dB</span>(gain_dB);</p>
|
|
<p class=desc>Set the gain using a decibel value (gain_dB = 20*log10(gain)).
|
|
A value less than zero attenuates the signal and a value greater than zero
|
|
amplifies the signal. Phase inversion is not available.</p>
|
|
<!--
|
|
<h3>Examples</h3>
|
|
<p class=exam>File > Examples > Audio >
|
|
</p>
|
|
-->
|
|
|
|
</script>
|
|
<script type="text/x-red" data-template-name="AudioEffectGain_F32">
|
|
<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>
|
|
</script>
|
|
|
|
|
|
<script type="text/x-red" data-help-name="AudioFilterBiquad_F32">
|
|
<h3>Summary</h3>
|
|
<div class=tooltipinfo>
|
|
<p>Biquadratic cascaded IIR filters, useful for all sorts of
|
|
frequency 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>begin</span>();</p>
|
|
<p class=desc> This <b>required</b> function initializes
|
|
the BiQuad instance using the ARM DSP Math Library. There are no
|
|
calling parameters.
|
|
</p>
|
|
<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>setLowShelf</span>(stage, frequency, gain, slope);</p>
|
|
<p class=desc>Configure one stage of the filter (0 to 3) with low shelf response.
|
|
A low shelf filter attenuates or amplifies signals below the specified frequency.
|
|
Frequency controls the slope midpoint, gain is in dB and can be both
|
|
positive or negative. The slope parameter controls steepness of gain transition.
|
|
A slope of 1 yields maximum steepness without overshoot,
|
|
lower values yield a less steep slope. See the picture below for a visualization
|
|
of the slope parameter's effect.
|
|
Be careful with positive gains and slopes higher than 1 as they introduce gain
|
|
(see warning below).
|
|
</p>
|
|
</p>
|
|
<p class=func><span class=keyword>setHighShelf</span>(stage, frequency, gain, slope);</p>
|
|
<p class=desc>Configure one stage of the filter (0 to 3) with high shelf response.
|
|
A high shelf filter attenuates or amplifies signals above the specified frequency.
|
|
Frequency controls the slope midpoint, gain is in dB and can be both
|
|
positive or negative. The slope parameter controls steepness of gain transition.
|
|
A slope of 1 yields maximum steepness without overshoot,
|
|
lower values yield a less steep slope. See the picture below for a visualization
|
|
of the slope parameter's effect.
|
|
Be careful with positive gains and slopes higher than 1 as they introduce gain
|
|
(see warning below).
|
|
</p>
|
|
<p align=center><img src="img/shelf_filter.png"></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. </p>
|
|
<p class=func><span class=keyword><strong>double* </strong>getCoefficients</span>();</p>
|
|
<p class=desc>Returns a pointer to the array of double precision coefficients. For
|
|
up to four stages, each stage is arranged in order B0, B1, B2, A1, A2. This is a
|
|
maximum of 20 coefficients with unused stages showing a 1.0 and four zeros. </p>
|
|
<h3>Examples</h3>
|
|
<p class=exam>File > Examples > Audio > Effects > Filter
|
|
</p>
|
|
<h3>Notes</h3>
|
|
<p>Each instance of the Biquad filter class can have 0 to 4 cascaded biquad filters,
|
|
with each independent. These can mix filter types, such as Low Pass and High Pass
|
|
or they can be multiples of the same type. Note that, in general, cascading identical
|
|
Biquad IIR filters will not be the most useful. Check the Internet for discussions
|
|
of cascading filters to achieve specific responses, such as Butterworth
|
|
or Chebychev.
|
|
</p>
|
|
<p>This object implements up to 4 cascaded stages. The four biquads per instance
|
|
can each be used, or not used, and the unused
|
|
ones will be treated as pass throughs.
|
|
</p>
|
|
<p>These IIR filters do not provide flat time delay with frequency as provided
|
|
by symmetrical FIR filters. If this is important, the extra complexity of the FIR
|
|
type may be justified.</p>
|
|
<p>These IIR filters generally do not have the degrees of freedom that FIR filters easily provide.
|
|
That means the response shapes are generally more constrained. This can be overcome
|
|
by adding many more biquad sections, with properly chosen frequencies and Qs, but
|
|
then it becomes easier to just use the FIR. Thus, most applications where the Biquad IIR
|
|
is appropriate will fit into this 4-filter object.</p>
|
|
</script>
|
|
<script type="text/x-red" data-template-name="AudioFilterBiquad_F32">
|
|
<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>
|
|
</script>
|
|
|
|
<script type="text/x-red" data-help-name="AudioFilterFIR_F32">
|
|
<h3>Summary</h3>
|
|
<div class=tooltipinfo>
|
|
<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>(filter_coeff, filter_length, block_size);</p>
|
|
<p class=desc>Initialize the filter. The filter_coeff must be an array of 32-bit floats (the
|
|
filter's impulse response), the filter_length indicates the number of points in the array,
|
|
and block_size is the length of the audio block that will be passed to this filtering
|
|
object during operation. The filter_coeff array may also be set as
|
|
FIR_PASSTHRU (with filter_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>Known Issues</h3>
|
|
<p>Your filter's impulse response array must have an even length. If you have
|
|
add odd number of taps, you must add an extra zero to increase the length
|
|
to an even number.
|
|
</p>
|
|
<p>The minimum number of taps is 4. If you use less, add extra zeros to increase
|
|
the length to 4.
|
|
</p>
|
|
<p>The impulse response must be given in reverse order. Many filters have
|
|
symetrical impluse response, making this a non-issue. If your filter has
|
|
a non-symetrical response, make sure the data is in reverse time order.
|
|
</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>The free
|
|
<a href="http://t-filter.engineerjs.com/" target="_blank"> TFilter Design Tool</a>
|
|
can be used to create the impulse response array. Be sure to choose the desired sampling
|
|
frequency (that tool defaults to only 2000 Hz whereas Teensy defaults to 44117) and
|
|
for this library the output type should be "float" (32 bit).
|
|
</p>
|
|
</script>
|
|
<script type="text/x-red" data-template-name="AudioFilterFIR_F32">
|
|
<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>
|
|
</script>
|
|
|
|
<script type="text/x-red" data-help-name="AudioFilterFreqWeighting_F32">
|
|
<p>Frequency weighting. Defaults to A-Weighting</p>
|
|
</script>
|
|
<script type="text/x-red" data-template-name="AudioFilterFreqWeighting_F32 ">
|
|
<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>
|
|
</script>
|
|
<script type="text/x-red" data-help-name="AudioFilterTimeWeighting_F32">
|
|
<p>Time weighting for sound level meter. Defaults to SLOW</p>
|
|
</script>
|
|
<script type="text/x-red" data-template-name="AudioFilterTimeWeighting_F32 ">
|
|
<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>
|
|
</script>
|
|
<script type="text/x-red" data-help-name="AudioMathAdd_F32">
|
|
<p> AudioMathAdd_F32</p>
|
|
<p> Created: Chip Audette, Open Audio, July 2018</p>
|
|
<p> Purpose: Add together two channels (vectors) of audio data on a point-by-point basis</p>
|
|
<p> (like AudioMathMutiply, but addition). Assumes floating-point data.</p>
|
|
<p> This processes a single stream fo audio data (ie, it is mono)</p>
|
|
<p> MIT License. use at your own risk.</p>
|
|
</script>
|
|
<script type="text/x-red" data-template-name="AudioMathAdd_F32 ">
|
|
<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>
|
|
</script>
|
|
<script type="text/x-red" data-help-name="AudioMathMultiply_F32">
|
|
<p> AudioMathMultiply</p>
|
|
<p> Created: Patrick Radius, December 2016</p>
|
|
<p> Purpose: Multiply two channels of audio data. Can be used for example as 'vca' or amplitude modulation.</p>
|
|
<p> Assumes floating-point data.</p>
|
|
<p> This processes a single stream fo audio data (ie, it is mono)</p>
|
|
<p> MIT License. use at your own risk.</p>
|
|
</script>
|
|
<script type="text/x-red" data-template-name="AudioMathMultiply_F32 ">
|
|
<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>
|
|
</script>
|
|
<script type="text/x-red" data-help-name="AudioMathOffset_F32">
|
|
<p> AudioMathOffset_F32</p>
|
|
<p> Created: Chip Audette, Open Audio, June 2018</p>
|
|
<p> Purpose: Add a constant DC value to all audio samples</p>
|
|
<p> Assumes floating-point data.</p>
|
|
<p> This processes a single stream fo audio data (ie, it is mono)</p>
|
|
<p> MIT License. use at your own risk.</p>
|
|
</script>
|
|
<script type="text/x-red" data-template-name="AudioMathOffset_F32 ">
|
|
<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>
|
|
</script>
|
|
|
|
<script type="text/x-red" data-help-name="AudioMathScale_F32">
|
|
<p> AudioMathScale_F32</p>
|
|
<p> Created: Chip Audette, Open Audio, June 2018</p>
|
|
<p> Purpose: Multiply all audio samples by a single value (not vector)</p>
|
|
<p> Assumes floating-point data.</p>
|
|
<p> This processes a single stream fo audio data (ie, it is mono)</p>
|
|
<p> MIT License. use at your own risk.</p>
|
|
</script>
|
|
<script type="text/x-red" data-template-name="AudioMathScale_F32 ">
|
|
<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>
|
|
</script>
|
|
|
|
<script type="text/x-red" data-help-name="AudioMathConstant_F32">
|
|
<h3>Summary</h3>
|
|
<div class=tooltipinfo>
|
|
<p>Generates all audio samples at a single value.
|
|
Assumes floating-point data. The default value is 0.0f.</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>Constant Output</td></tr>
|
|
</table>
|
|
<h3>Functions</h3>
|
|
<p class=func><span class=keyword>setConstant</span>(<strong>float32_t</strong> constant);</p>
|
|
<p class=desc>This same value will be transmitted out for all data in a block.
|
|
Any float32_t is valid.</p>
|
|
</script>
|
|
<script type="text/x-red" data-template-name="AudioMathConstant_F32 ">
|
|
<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>
|
|
</script>
|
|
|
|
<script type="text/x-red" data-help-name="AudioMixer4_F32">
|
|
<h3>Summary</h3>
|
|
<div class=tooltipinfo>
|
|
<p>Combine up to 4 audio signals together, each with adjustable gain.
|
|
All channels support signal attenuation or amplification.</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>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. A level value of
|
|
1.0 passes the signal through directly. Between 0 to 1.0 attenuates the signal, and above
|
|
1.0 amplifies it. A level value of 0 shuts the channel
|
|
off completely. 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>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>
|
|
</script>
|
|
<script type="text/x-red" data-template-name="AudioMixer4_F32">
|
|
<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>
|
|
</script>
|
|
|
|
<script type="text/x-red" data-help-name="AudioMixer8_F32">
|
|
<h3>Summary</h3>
|
|
<div class=tooltipinfo>
|
|
<p>Combine up to 8 audio signals together, each with adjustable gain.
|
|
All channels support signal attenuation or amplification.</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>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>In 4</td><td>Input signal #5</td></tr>
|
|
<tr class=odd><td align=center>In 5</td><td>Input signal #6</td></tr>
|
|
<tr class=odd><td align=center>In 6</td><td>Input signal #7</td></tr>
|
|
<tr class=odd><td align=center>In 7</td><td>Input signal #8</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 7. "level" may be any floating point number. A level value of
|
|
1.0 passes the signal through directly. Between 0 to 1.0 attenuates the signal, and above
|
|
1.0 amplifies it. A level value of 0 shuts the channel
|
|
off completely. 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>More than 8 channels may be combined by connecting multiple mixers
|
|
in tandem. For example, a 16 channel mixer may be built using three
|
|
mixers, where the third mixer combines the outputs of the first two.
|
|
</p>
|
|
</script>
|
|
<script type="text/x-red" data-template-name="AudioMixer8_F32">
|
|
<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>
|
|
</script>
|
|
|
|
<script type="text/x-red" data-help-name="FFT_Overlapped_F32">
|
|
<p> FFT_Overrlapped_F32</p>
|
|
<p> Purpose: Encapsulate the ARM floating point FFT/IFFT functions</p>
|
|
<p> in a way that naturally interfaces to my float32</p>
|
|
<p> extension of the Teensy Audio Library.</p>
|
|
<p> Provides functionality to do overlapped FFT/IFFT where</p>
|
|
<p> each audio block is a fraction (1, 1/2, 1/4) of the</p>
|
|
<p> totaly FFT length. This class handles all of the</p>
|
|
<p> data shuffling to composite the previous data blocks</p>
|
|
<p> with the current data block to provide the full FFT.</p>
|
|
<p> Does similar data shuffling (overlapp-add) for IFFT.</p>
|
|
<p> Created: Chip Audette (openaudio.blogspot.com)</p>
|
|
<p> Jan-Jul 2017</p>
|
|
<p> Typical Usage as FFT:</p>
|
|
<p> //setup the audio stuff</p>
|
|
<p> float sample_rate_Hz = 44100.0; //define sample rate</p>
|
|
<p> int audio_block_samples = 32; //define size of audio blocks</p>
|
|
<p> AudioSettings_F32 audio_settings(sample_rate_Hz, audio_block_samples);</p>
|
|
<p> // ... continue creating all of your Audio Processing Blocks ...</p>
|
|
<p> // within a custom audio processing algorithm that you've written</p>
|
|
<p> // you'd create the FFT and IFFT elements</p>
|
|
<p> int NFFT = 128; //define length of FFT that you want (multiple of audio_block_samples)</p>
|
|
<p> FFT_Overrlapped_F32 FFT_obj(audio_settings,NFFT); //Creare FFT object</p>
|
|
<p> FFT_Overrlapped_F32 IFFT_obj(audio_settings,NFFT); //Creare IFFT object</p>
|
|
<p> float complex_2N_buffer[2*NFFT]; //create buffer to hold the FFT output</p>
|
|
<p> // within your own algorithm's "update()" function (which is what</p>
|
|
<p> // is called automatically by the Teensy Audio Libarary approach</p>
|
|
<p> // to audio processing), you can execute the FFT and IFFT</p>
|
|
<p> // First, get the audio and convert to frequency-domain using an FFT</p>
|
|
<p> audio_block_f32_t *in_audio_block = AudioStream_F32::receiveReadOnly_f32();</p>
|
|
<p> FFT_obj.execute(in_audio_block, complex_2N_buffer); //output is in complex_2N_buffer</p>
|
|
<p> AudioStream_F32::release(in_audio_block); //We just passed ownership to FFT_obj, so release it here.</p>
|
|
<p> // Next do whatever processing you'd like on the frequency domain data</p>
|
|
<p> // that is held in complex_2N_buffer</p>
|
|
<p> // Finally, you can convert back to the time domain via IFFT</p>
|
|
<p> audio_block_f32_t *out_audio_block = IFFT_obj.execute(complex_2N_buffer);</p>
|
|
<p> //note that the "out_audio_block" is mananged by IFFT_obj, so don't worry about releasing it.</p>
|
|
<p> License: MIT License</p>
|
|
</script>
|
|
<script type="text/x-red" data-template-name="FFT_Overlapped_F32 ">
|
|
<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>
|
|
</script>
|
|
<script type="text/x-red" data-help-name="IFFT_Overlapped_F32">
|
|
<p> FFT_Overrlapped_F32</p>
|
|
<p> Purpose: Encapsulate the ARM floating point FFT/IFFT functions</p>
|
|
<p> in a way that naturally interfaces to my float32</p>
|
|
<p> extension of the Teensy Audio Library.</p>
|
|
<p> Provides functionality to do overlapped FFT/IFFT where</p>
|
|
<p> each audio block is a fraction (1, 1/2, 1/4) of the</p>
|
|
<p> totaly FFT length. This class handles all of the</p>
|
|
<p> data shuffling to composite the previous data blocks</p>
|
|
<p> with the current data block to provide the full FFT.</p>
|
|
<p> Does similar data shuffling (overlapp-add) for IFFT.</p>
|
|
<p> Created: Chip Audette (openaudio.blogspot.com)</p>
|
|
<p> Jan-Jul 2017</p>
|
|
<p> Typical Usage as FFT:</p>
|
|
<p> //setup the audio stuff</p>
|
|
<p> float sample_rate_Hz = 44100.0; //define sample rate</p>
|
|
<p> int audio_block_samples = 32; //define size of audio blocks</p>
|
|
<p> AudioSettings_F32 audio_settings(sample_rate_Hz, audio_block_samples);</p>
|
|
<p> // ... continue creating all of your Audio Processing Blocks ...</p>
|
|
<p> // within a custom audio processing algorithm that you've written</p>
|
|
<p> // you'd create the FFT and IFFT elements</p>
|
|
<p> int NFFT = 128; //define length of FFT that you want (multiple of audio_block_samples)</p>
|
|
<p> FFT_Overrlapped_F32 FFT_obj(audio_settings,NFFT); //Creare FFT object</p>
|
|
<p> FFT_Overrlapped_F32 IFFT_obj(audio_settings,NFFT); //Creare IFFT object</p>
|
|
<p> float complex_2N_buffer[2*NFFT]; //create buffer to hold the FFT output</p>
|
|
<p> // within your own algorithm's "update()" function (which is what</p>
|
|
<p> // is called automatically by the Teensy Audio Libarary approach</p>
|
|
<p> // to audio processing), you can execute the FFT and IFFT</p>
|
|
<p> // First, get the audio and convert to frequency-domain using an FFT</p>
|
|
<p> audio_block_f32_t *in_audio_block = AudioStream_F32::receiveReadOnly_f32();</p>
|
|
<p> FFT_obj.execute(in_audio_block, complex_2N_buffer); //output is in complex_2N_buffer</p>
|
|
<p> AudioStream_F32::release(in_audio_block); //We just passed ownership to FFT_obj, so release it here.</p>
|
|
<p> // Next do whatever processing you'd like on the frequency domain data</p>
|
|
<p> // that is held in complex_2N_buffer</p>
|
|
<p> // Finally, you can convert back to the time domain via IFFT</p>
|
|
<p> audio_block_f32_t *out_audio_block = IFFT_obj.execute(complex_2N_buffer);</p>
|
|
<p> //note that the "out_audio_block" is mananged by IFFT_obj, so don't worry about releasing it.</p>
|
|
<p> License: MIT License</p>
|
|
</script>
|
|
<script type="text/x-red" data-template-name="IFFT_Overlapped_F32 ">
|
|
<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>
|
|
</script>
|
|
|
|
<script type="text/x-red" data-help-name="AudioInputI2S_F32">
|
|
<h3>Summary</h3>
|
|
<div class=tooltipinfo>
|
|
<p>Receive float32 stereo audio from the
|
|
<a href="http://www.pjrc.com/store/teensy3_audio.html" target="_blank">Teensy Audio Board</a>,
|
|
the <a href="https://www.tympan.org/">Tympan Audio Board</a>,
|
|
or another I2S device.</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>Left Channel</td></tr>
|
|
<tr class=odd><td align=center>Out 1</td><td>Right Channel</td></tr>
|
|
</table>
|
|
<h3>Constructor</h3>
|
|
<p>Objects of this class can be created using the typical, minimal constructor using no arguments.
|
|
Or, to control the sample rate and block size, the constructor can be passed an AudioSettings_F32
|
|
object that has been configured with your desired settings.</p>
|
|
<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 "master" mode, where the 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 Most examples use the Audio card with I2S transfer.</p>
|
|
|
|
<h3>Notes</h3>
|
|
<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>As of May 2022, the I2S input and output objects can handle 24 or 32-bit
|
|
data transfer, if that is supported by the audio hardware device.
|
|
No class functions are needed. It is "automagic".</p>
|
|
|
|
</script>
|
|
<script type="text/x-red" data-template-name="AudioInputI2S_F32">
|
|
<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>
|
|
</script>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<script type="text/x-red" data-help-name="AudioInputSPDIF3_F32">
|
|
<h3>Summary</h3>
|
|
<div class=tooltipinfo>
|
|
<p>Receive S/PDIF digital audio, at the rate of the external digital audio source.</p>
|
|
<p><span style="color:red">This input is incompatible with most other inputs and outputs</span>
|
|
which run at a speed controlled by Teensy's internal sample rate.</p>
|
|
</div>
|
|
<h3>Boards Supported</h3>
|
|
<ul>
|
|
<li>Teensy 4.0
|
|
<li>Teensy 4.1
|
|
</ul>
|
|
<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 class=func><span class=keyword>pllLocked</span>();</p>
|
|
<p class=desc>Returns true if the S/PDIF phase locked loop is tracking
|
|
the sample rate of incoming digital audio data.
|
|
</p>
|
|
<p class=func><span class=keyword>sampleRate</span>();</p>
|
|
<p class=desc>Returns the sample rate of incoming data, if the PLL has locked,
|
|
or returns 0 if the audio sample rate is unknown.
|
|
</p>
|
|
<h3>Hardware</h3>
|
|
<p>
|
|
<table class=doc align=center cellpadding=3>
|
|
<tr class=top><th>T4.x<br>Pin</th><th>Signal</th><th>Direction</th></tr>
|
|
<tr class=odd><td align=center>15</td><td>S/PDIF Data</td><td>Output</td></tr>
|
|
</table>
|
|
</p>
|
|
<h3>Examples</h3>
|
|
<!--<p class=exam>File > Examples > Audio > HardwareTesting > PassThroughAsyncSpdif
|
|
</p>-->
|
|
<h3>Notes</h3>
|
|
<p>This input tries to force the entire audio library to run at the
|
|
sample rate of the incoming data. It usually can not be combined
|
|
with most other inputs and outputs which run at specific speeds.</p>
|
|
</script>
|
|
<script type="text/x-red" data-template-name="AudioInputSPDIF3_F32">
|
|
<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>
|
|
</script>
|
|
|
|
<script type="text/x-red" data-help-name="AsyncAudioInputSPDIF3_F32">
|
|
<h3>Summary</h3>
|
|
<div class=tooltipinfo>
|
|
<p>Receive S/PDIF digital audio and resample to Teensy's audio sample rate.</p>
|
|
<p>Asynchronous resampling contributed by <a href="https://github.com/alex6679">Alex Walch</a>.</p>
|
|
</div>
|
|
<h3>Boards Supported</h3>
|
|
<ul>
|
|
<li>Teensy 4.0
|
|
<li>Teensy 4.1
|
|
</ul>
|
|
<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 class=func><span class=keyword>getBufferedTime</span>();</p>
|
|
<p class=desc>Returns the buffered time in seconds. The buffered time is the duration of the incoming samples which are not resampled yet. The step width of the resampling algorithm is constantly slightly adjusted to keep the buffered time closely to the target latency. The difference between the target latency and the buffered time is typically smaller than 1 microsecond.
|
|
</p>
|
|
<!--<p class=func><span class=keyword>getInputFrequency</span>();</p>
|
|
<p class=desc>TODO: documentation needed here
|
|
</p>-->
|
|
<p class=func><span class=keyword>isLocked</span>();</p>
|
|
<p class=desc>Returns true if the S/PDIF phase locked loop is tracking
|
|
the sample rate of incoming digital audio data.
|
|
</p>
|
|
<p class=func><span class=keyword>getInputFrequency</span>();</p>
|
|
<p class=desc>Returns the sample rate of incoming data, if the PLL has locked, or returns 0 if the audio sample rate is unknown.
|
|
</p>
|
|
<p class=func><span class=keyword>getTargetLantency</span>();</p>
|
|
<p class=desc>Returns the target latency in seconds. The latency is the time from the moment a sample is received by the Teensy SPDIF hardware receiver until it is transmitted by the asrc intput. The audio samples arrive at the asrc input in chunks of 32 samples per channel. The target latency consists of these 32 samples + some buffer that is needed to compensate for timing variations.
|
|
</p>
|
|
<p class=func><span class=keyword>getAttenuation</span>();</p>
|
|
<p class=desc>Returns the actual achieved attenuation of the
|
|
anti-aliasing filter. If the input sampling rate is smaller or equal
|
|
to 44.1kHz, no low pass filtering is needed and zero is returned.</p>
|
|
<p class=func><span class=keyword>getHalfFilterLength</span>();</p>
|
|
<p class=desc>Returns the half length of the resampling filter. Its complete length is 2*(the returned value)+1.
|
|
</p>
|
|
<h3>Hardware</h3>
|
|
<p>
|
|
<table class=doc align=center cellpadding=3>
|
|
<tr class=top><th>T4.x<br>Pin</th><th>Signal</th><th>Direction</th></tr>
|
|
<tr class=odd><td align=center>15</td><td>S/PDIF Data</td><td>Output</td></tr>
|
|
</table>
|
|
</p>
|
|
<h3>Examples</h3>
|
|
<p class=exam>File > Examples > Audio > HardwareTesting > PassThroughAsyncSpdif
|
|
</p>
|
|
<h3>Notes</h3>
|
|
<p>AsyncAudioInputSPDIF3 is not able to clock the audio pipline (never has the 'update_responsibility'). At least 1 other input or output must be used to cause the entire Audio library to update.
|
|
</p>
|
|
|
|
<p>AsyncAudioInputSPDIF3 can optionally take parameters to alter its resampling behavior.
|
|
</p>
|
|
<p><span class=keyword>AsyncAudioInputSPDIF3_F32</span> spdif_async1(<i>dither</i>, <i>noiseshaping</i>, <i>attenuation</i>, <i>minHalfFilterLength</i>, <i>maxHalfFilterLength</i>);
|
|
</p>
|
|
<p class=desc><i>dither</i>: triangular shaped dither is added at the transition from 32bit float to 16bit integer if true (default: true)
|
|
</p>
|
|
<p class=desc><i>noiseshaping</i>: noise shaping is applied at the aforementioned transition if true (default: true)
|
|
</p>
|
|
<p class=desc><i>attenuation</i>: target attenuation of the anti-aliasing filter (default: 100dB). The attenuation is not reached if a filter longer than 161 is needed.
|
|
</p>
|
|
<p class=desc><i>minHalfFilterLength</i>: half of the guaranteed resampling filter (internally restricted to 80, default: 20). The filter might be longer if needed to achieve the requested attenuation.
|
|
</p>
|
|
<p class=desc><i>maxHalfFilterLength</i>: Restricts the maximum length of the resampling filter. The maximum half filter length is 80. This parameter can be used to further restrict the length in order to limit the processor usage.
|
|
</p>
|
|
<p>The windowed (Kaiser window) sinc-function is used as resample filter (i.e. to interpolate the incoming signal). The longer the filter, the better the quality of the resampled signal. However, a longer filter has a higher group delay and increases the processor usage. The sinc- filter also serves as anti-aliasing filter if the input sample rate is larger than 44.1kHz. The filter length is automatically increased at high input sample rates to reach the specified attenuation. However its half length is restricted to 80. 32bit floating point arithmetic is used at the resampling stage and the resampled signal is transformed to 16 bit integers afterwards. Here it is possible to apply triangular shaped dither and noise shaping to increase the perceived signal-to-noise-ratio.</p>
|
|
</script>
|
|
<script type="text/x-red" data-template-name="AsyncAudioInputSPDIF3_F32">
|
|
<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>
|
|
</script>
|
|
|
|
<script type="text/x-red" data-help-name="AudioOutputI2S_F32">
|
|
<h3>Summary</h3>
|
|
<div class=tooltipinfo>
|
|
<p>Transmit float32 stereo audio to the various I2S Codec boards, such as
|
|
<a href="http://www.pjrc.com/store/teensy3_audio.html" target="_blank">Teensy Audio Board</a>.
|
|
</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>Left Channel</td></tr>
|
|
<tr class=odd><td align=center>In 1</td><td>Right Channel</td></tr>
|
|
</table>
|
|
<h3>Constructor</h3>
|
|
<p>Objects of this class can be created using the typical, minimal constructor using no arguments.
|
|
Or, to control the sample rate and block size, the constructor can be passed an AudioSettings_F32
|
|
object that has been configured with your desired settings.</p>
|
|
<h3>Functions</h3>
|
|
<p class=func><span class=keyword>setGain</span>(<strong>float </strong>Gain);</p>
|
|
<p class=desc>Sets the output gain of both left and right channels. Values are unconstrained, but
|
|
normally range from 0.0 to 1.0 (default 1.0). A setting of exactly 1.0 results in
|
|
no scaling and saves a small amount of processor. </p>
|
|
<h3>Hardware</h3>
|
|
<p>A control Codec object, such as the SGTL5000 must be included.</p>
|
|
<p>Audio from
|
|
master mode I2S may be used in the same project as ADC, DAC (not T4.x) 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>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>Being an "_F32" object, audio is passed into this class using F32 memory
|
|
that was allocated using an AudioMemory_F32() call in your sketch's setup()
|
|
routine. But, internally, this class still uses some Int16 data handling,
|
|
so be sure to also include an AudioMemory() call in addition to AudioMemory_F32()
|
|
to allocate the Int16 memory.</p>
|
|
</script>
|
|
<script type="text/x-red" data-template-name="AudioOutputI2S_F32">
|
|
<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>
|
|
</script>
|
|
|
|
|
|
<script type="text/x-red" data-help-name="AudioOutputSPDIF3_F32">
|
|
<h3>Summary</h3>
|
|
<div class=tooltipinfo>
|
|
<p>Transmit 16 bit stereo audio as Digital S/PDIF by use of the
|
|
native S/PDIF port.</p>
|
|
</div>
|
|
<h3>Boards Supported</h3>
|
|
<ul>
|
|
<li>Teensy 4.0
|
|
<li>Teensy 4.1
|
|
</ul>
|
|
<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 14 (Teensy 4.x).</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>Teensy<br>4.x Pin</th><th>Signal</th><th>Direction</th></tr>
|
|
<tr class=odd><td align=center>14</td><td>S/PDIF</td><td>Output</td></tr>
|
|
</table>
|
|
<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 AudioOutputSPDIF3 code.
|
|
<h3>Notes</h3>
|
|
<p>Native S/PDIF hardware is used, which is more efficient that use of I2S ports.</p>
|
|
</p>
|
|
</script>
|
|
<script type="text/x-red" data-template-name="AudioOutputSPDIF3_F32">
|
|
<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>
|
|
</script>
|
|
|
|
|
|
|
|
|
|
<script type="text/x-red" data-help-name="AudioAlignLR_F32">
|
|
<h3>Summary</h3>
|
|
<div class=tooltipinfo>
|
|
<p>Measure Codec L-R time misalignment at startup and make
|
|
time shift corrections during regular operation. ** BETA TEST **</p>
|
|
</div>
|
|
<h3>Boards Supported</h3>
|
|
<ul>
|
|
<li>Teensy 3.5
|
|
<li>Teensy 3.6
|
|
<li>Teensy 4.0
|
|
<li>Teensy 4.1
|
|
</ul>
|
|
|
|
<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>
|
|
<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>
|
|
<tr class=odd><td align=center>Out 2</td><td>Test Signal (Beta)</td></tr>
|
|
</table>
|
|
|
|
<h3>Functions</h3>
|
|
<p class=func><span class=keyword>read</span>(<strong>void</strong>);</p>
|
|
<p class=desc>This returns a pointer to a <strong>TPinfo</strong> structure
|
|
containing information on the operation of the time alignment. The structure
|
|
members are:</p>
|
|
<table class=doc align=center cellpadding=3>
|
|
<tr class=odd><td align=center><strong>uint16_t</strong></td><td> TPstate</td></tr>
|
|
<tr class=odd><td align=center><strong>uint32_t</strong></td><td> nMeas</td></tr>
|
|
<tr class=odd><td align=center><strong>float32_t</strong></td><td> xNorm</td></tr>
|
|
<tr class=odd><td align=center><strong>float32_t</strong></td><td> xcVal[4]</td></tr>
|
|
<tr class=odd><td align=center><strong>int16_t</strong></td><td> neededShift</td></tr>
|
|
<tr class=odd><td align=center><strong>int16_t</strong></td><td> TPerror</td></tr>
|
|
<tr class=odd><td align=center><strong>uint16_t</strong></td><td> TPsignalHardware</td></tr>
|
|
</table>
|
|
|
|
<p class=func><span class=keyword>stateTwinPeaks</span>(<strong>uint16_t</strong> TPstate);</p>
|
|
<p class=desc>This process comes up set to TP_IDLE. To start the alignment detection,
|
|
use this function to set TPstate to TP_MEASURE. If detection is successful,
|
|
the state will automatically move to TP_RUN. Correction of the alignment error will
|
|
then continue without requiring any function calls.</p>
|
|
|
|
<!--
|
|
<p class=func><span class=keyword>setThreshold</span>(<strong>float32_t</strong> TPthreshold);</p>
|
|
<p class=desc>The L-R cross correlation signal must exceed this threshold to indicate
|
|
detection. To set this value run the process with any
|
|
value for the threshold. Examine the three -1, 0, 1 output data around update #15.
|
|
Then set the threshold to about half of maximum positive value of the three.</p>
|
|
-->
|
|
|
|
<h3>Examples</h3>
|
|
<p class=exam>File > Examples > TestTwinPeaks
|
|
</p>
|
|
<h3>Notes</h3>
|
|
<p>The object construction takes parameters, the first three being
|
|
required:
|
|
</p>
|
|
<table class=doc align=center cellpadding=3>
|
|
<tr class=odd><td align=center><strong>uint16_t</strong></td><td>Hardware</td></tr>
|
|
<tr class=odd><td align=center><strong>uint16_t</strong></td><td>Pin</td></tr>
|
|
<tr class=odd><td align=center><strong>bool</strong></td><td>Invert</td></tr>
|
|
</table>
|
|
<p>See AudioAlignLR.h and the example INO for details on the parameters.
|
|
A fourth parameter, settings, is optional.</p>
|
|
|
|
<p>There are two different methods for generating a test signal. Both
|
|
require a small amount of hardware to be contructed. The first, and recommended,
|
|
(Hardware=TP_SIGNAL_IO_PIN) method uses a dedicated Teensy digital I/O pin to generate an 11.4 kHz square wave that
|
|
is permanently connected by two 10K to 100K resistors to the L&R ADC inputs. The second,
|
|
(Hardware=TP_SIGNAL_CODEC), method briefly borrows the
|
|
Codec R channel output to produce an 11 kHz square wave that is coupled via analog
|
|
switches to the L&R ADC inputs. Both methods seem to work very well. The first method's
|
|
hardware is simpler. The third audio output from the AlignLR block is not used for
|
|
the first method.</p>
|
|
|
|
<p>The resistor values, referred to above, depend on the impedance that
|
|
the ADC is being driven from. As a general rule, they should be (very) roughly 200
|
|
times the driving point impedance. Too high a value reults in noise in the
|
|
measurement. Too low can cause digital noise to get into the audio. It is
|
|
also possible to use a pair of NPN transistors, such as a 2N3904, to shunt the resistor
|
|
paths to the Codecanalog ground. For that case the resistor would be divided into two
|
|
parts, the sum of which equaled the desired resistor value.</p>
|
|
|
|
<p>To DO: 1 - See if anybody needs the Codec DAC method.
|
|
Remove if not needed.</p>
|
|
|
|
</script>
|
|
<script type="text/x-red" data-template-name="AudioAlignLR_F32">
|
|
<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>
|
|
</script>
|
|
|
|
<script type="text/x-red" data-help-name="AudioInputUSB_F32">
|
|
<h3>Summary</h3>
|
|
<div class=tooltipinfo>
|
|
<p>Receive stereo audio from a PC or Mac. Teensy appears as a USB
|
|
sound device.</p>
|
|
<p align=center><img src="img/usbtype_audio_in.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>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 USB to its 2 output ports.</p>
|
|
<!--
|
|
<h3>Hardware</h3>
|
|
-->
|
|
<h3>Examples</h3>
|
|
<p class=exam>File > Examples > Audio > HardwareTesting > PassThroughUSB</p>
|
|
</p>
|
|
<h3>Notes</h3>
|
|
<p>Arduino's <b>Tools > USB Type</b> menu must be set to <b>Audio</b>.
|
|
</p>
|
|
<p align=center><img src="img/usbtype_audio.png"></p>
|
|
<p>USB input & output does not cause the Teensy Audio Library to
|
|
update. At least one non-USB input or output object must be
|
|
present for the entire library to update properly.</p>
|
|
<p>A known problem exists with USB audio from Macintosh computers.
|
|
An imperfect <a href="https://forum.pjrc.com/threads/34855-Distorted-audio-when-using-USB-input-on-Teensy-3-1?p=110392&viewfull=1#post110392">workaround
|
|
can be enabled by editing usb_audio.cpp</a>.
|
|
Find and uncomment "#define MACOSX_ADAPTIVE_LIMIT".</p>
|
|
</script>
|
|
<script type="text/x-red" data-template-name="AudioInputUSB_F32">
|
|
<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>
|
|
</script>
|
|
|
|
<script type="text/x-red" data-help-name="AudioOutputUSB_F32">
|
|
<h3>Summary</h3>
|
|
<div class=tooltipinfo>
|
|
<p>Send stereo audio to a PC or Mac. Teensy appears as a USB
|
|
sound device.</p>
|
|
<p align=center><img src="img/usbtype_audio_out.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>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 from it's 2 input ports to the USB.</p>
|
|
<!--
|
|
<h3>Hardware</h3>
|
|
-->
|
|
<h3>Examples</h3>
|
|
<p class=exam>File > Examples > Audio > HardwareTesting > WavFilePlayerUSB</p>
|
|
</p>
|
|
<h3>Notes</h3>
|
|
<p>Arduino's <b>Tools > USB Type</b> menu must be set to <b>Audio</b>.
|
|
</p>
|
|
<p align=center><img src="img/usbtype_audio.png"></p>
|
|
<p>USB input & output does not cause the Teensy Audio Library to
|
|
update. At least one non-USB input or output object must be
|
|
present for the entire library to update properly.</p>
|
|
<p>A known problem exists with USB audio from Macintosh computers.
|
|
An imperfect <a href="https://forum.pjrc.com/threads/34855-Distorted-audio-when-using-USB-input-on-Teensy-3-1?p=110392&viewfull=1#post110392">workaround
|
|
can be enabled by editing usb_audio.cpp</a>.
|
|
Find and uncomment "#define MACOSX_ADAPTIVE_LIMIT".</p>
|
|
</script>
|
|
<script type="text/x-red" data-template-name="AudioOutputUSB_F32">
|
|
<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>
|
|
</script>
|
|
|
|
|
|
<script type="text/x-red" data-help-name="AudioSDPlayer_F32">
|
|
<h3>Summary</h3>
|
|
<div class=tooltipinfo>
|
|
<p>Plays a WAV file, stored on an SD card.</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>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.
|
|
No return value.</p>
|
|
<p class=func><span class=keyword>stop</span>();</p>
|
|
<p class=desc>Stop playing. If not playing, this function has no effect.
|
|
No return value.</p>
|
|
|
|
<p class=func><span class=keyword>togglePlayPause</span>();</p>
|
|
<p class=desc>Used to Pause the playing of a file, or to un-Pause
|
|
depending on which applies. No return value. </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>isPaused</span>();</p>
|
|
<p class=desc>Return true (non-zero) if paused (see
|
|
togglePlayPause above).
|
|
|
|
<p class=func><span class=keyword>isStopped</span>();</p>
|
|
<p class=desc>Return true (non-zero) if not playing and
|
|
not paused.</p>
|
|
|
|
|
|
<p class=func><span class=keyword>setSubMult</span>(subMult* pStruct)
|
|
</span>();</p>
|
|
<p class=desc>Used if the WAV file is to be run at a lower sample rate
|
|
than the audio sample rate. The two rates must be related by an integer.
|
|
The calling parameter is a pointer to a structure of type subMult.
|
|
That is defined as:
|
|
<pre>
|
|
struct subMult {
|
|
uint16_t rateRatio; // Should be 1 for no rate change, else an integer
|
|
uint16_t numCoeffs; // FIR filter
|
|
float32_t* firCoeffs; // FIR Filter Coeffs
|
|
float32_t* firBufferL; // pointer to 127 + numCoeffs float32_t, left ch
|
|
float32_t* firBufferR; // pointer to 127 + numCoeffs float32_t, right ch
|
|
};</pre>
|
|
The struct is declared in the INO and this function transmits the selected
|
|
information. Note that the FIR filters can be used, even if the rateRatio
|
|
is 1. There is no need for this caused by rateRatio = 1, but
|
|
the filter function may be useful for other reasons. If the WAV file
|
|
and the Audio are both using the same sample rate, this function
|
|
is not needed and the rateRatio defaults to 1 and no FIR filters
|
|
are involked. The left and right FIR filters use the same coefficients
|
|
but need separate firBuffer. For monaural files, the firBufferR pointer can be
|
|
a NULL.</p>
|
|
|
|
<p class=func><span class=keyword>getCurrentWavData</span>();</p>
|
|
This returns a pointer to a structure containing data about the
|
|
WAV file currently selected for play. The structure is:
|
|
<pre>
|
|
struct wavData {
|
|
uint16_t audio_format; // Should be 1 for PCM
|
|
uint16_t num_channels; // 1 for mono, 2 for stereo
|
|
uint32_t sample_rate; // 44100, 48000, etc
|
|
uint16_t bits; // Number of bits per sample, should be 16
|
|
};</pre>
|
|
</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 class=exam>File > Examples > Audio > WavFilePlayer2
|
|
</p>
|
|
<h3>Notes</h3>
|
|
<p>Only 16 bit PCM 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 needed for other purposes, you must
|
|
<a href="http://www.pjrc.com/teensy/td_libs_AudioProcessorUsage.html"
|
|
target="_blank">use AudioNoInterrupts()</a>
|
|
to prevent AudioSDPlayer from accessing the SD card while you use it.
|
|
Disabling the audio library interrupt for too long may cause audible
|
|
dropouts or glitches.
|
|
</p>
|
|
|
|
</script>
|
|
<script type="text/x-red" data-template-name="AudioSDPlayer_F32">
|
|
<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>
|
|
</script>
|
|
|
|
<div>
|
|
<script type="text/x-red" data-help-name="AudioPlayQueue_F32">
|
|
<!-- ============ AudioPlayQueue_F32 ========= -->
|
|
<h3>Summary</h3>
|
|
<div class=tooltipinfo>
|
|
<p>Play audio data provided by the Arduino sketch. This object provides
|
|
functions to allow the sketch code to push floating point data into
|
|
the audio system.</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>setMaxBuffers</span>(<strong>uint8_t</strong> maxBuf);</p>
|
|
<p class=desc>Set the maximum buffer block count for the queue to limit its size - by default 32 blocks are used on Teensy 3.x
|
|
and 80 on Teensy 4.x - this allows the value to be reduced so that the queue cannot get too far ahead, nor use up lots of
|
|
audio blocks you might want for other purposes. The minimum number of buffer blocks is 2.
|
|
</p>
|
|
<p class=func><span class=keyword>play</span>(<strong>float32_t</strong> data);</p>
|
|
<p class=desc>add a single sample to the queue - no need to use getBuffer() or playBuffer() as this
|
|
method does the necessary handling.
|
|
</p>
|
|
<p class=desc>If the behaviour is set to ORIGINAL then this method may block waiting for a spare buffer if the queue is full.
|
|
</p>
|
|
<p class=desc>If the behaviour is set to NON_STALLING then this method may return a non-zero value:
|
|
in this case the call must be re-tried, passing in the original sample value.
|
|
</p>
|
|
<p class=func><span class=keyword>play</span>(<strong>float32_t[]</strong> pdata,
|
|
<strong> uint32_t</strong> length);</p>
|
|
<p class=desc>add multiple samples to the queue - no need to use getBuffer() or playBuffer() as this
|
|
method does the necessary handling.
|
|
The length should be the number of samples in the array, which need not be a multiple of AUDIO_BLOCK_SAMPLES.
|
|
<p class=desc>If the behaviour is set to ORIGINAL then this method may block waiting for a spare buffer if the queue is full.
|
|
</p>
|
|
<p class=desc>If the behaviour is set to NON_STALLING then this method will return the number of samples unused (due to unavailable
|
|
audio blocks or queue space): if non-zero then the call must be re-tried, with an updated array pointer and length.
|
|
</p>
|
|
</p>
|
|
<p class=func><span class=keyword>getBuffer</span>();</p>
|
|
<p class=desc>Returns a pointer to an array of AUDIO_BLOCK_SAMPLES (usually 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 AUDIO_BLOCK_SAMPLES samples should be
|
|
written before calling playBuffer(). Only a single buffer is allocated at any one time:
|
|
repeated calls to getBuffer() without calling playBuffer() will yield the same address.
|
|
<p class=desc>
|
|
If the behaviour is set to ORIGINAL then this function will wait (possibly forever) for memory to become available.
|
|
If set to NON_STALLING then function may return NULL if no memory is available.
|
|
</p>
|
|
</p>
|
|
<p>You may find it easier to use the play() methods unless performance is crucial.
|
|
</p>
|
|
<p class=func><span class=keyword>playBuffer</span>();</p>
|
|
<p class=desc>Transmit the buffer previously obtained from getBuffer(). If you use the play() methods you should not use this.
|
|
</p>
|
|
<p class=desc>
|
|
If the behaviour is set to ORIGINAL then this function will wait (up to 128 sample periods)
|
|
for a queue space to become available.
|
|
If set to NON_STALLING then function may return a non-zero value if no queue space is free:
|
|
in this case the call must be re-tried later, before any further call to getBuffer() is made.
|
|
</p>
|
|
<p class=func><span class=keyword>setBehaviour</span>(<strong>value</strong>);</p>
|
|
<p class=desc>Value should be AudioPlayQueue::ORIGINAL to preserve the original behaviour of getBuffer() and playBuffer(),
|
|
which can both stall until audio blocks or queue entries become available, with consequences for system performance.
|
|
Setting the value to AudioPlayQueue::NON_STALLING results in all the above functions returning promptly, but possibly
|
|
with a status indicating failure or a need to re-try. See the PlayQueueDemo example.
|
|
</p>
|
|
<p class=func><span class=keyword>playAudioBlock</span>
|
|
(<strong>audio_block_f32_t *</strong>audio_block);</p>
|
|
<p class=desc>This assumes that you already have an audio_block that was NOT allocated by
|
|
playBuffer. You hand it your buffer. This object takes ownership
|
|
of it and puts it into the queue. This function is not in I16 library.
|
|
</p>
|
|
|
|
<h3>Examples</h3>
|
|
<p>Examples are available at https://github.com/chipaudette/OpenAudio_ArduinoLibrary/tree/master/examples</p>
|
|
<p class=exam>Examples > PlayQueueDemo
|
|
</p>
|
|
|
|
<h3>Notes</h3>
|
|
<p>February 2023 this whole class was updated to include the Teensy I16 library additions
|
|
of Jonathan Oakley. The functions are the same as the Teensy Audio (I16) library
|
|
except for the data type.</p>
|
|
|
|
<p>The maximum buffering is the same as used by the I16 library
|
|
This is at 32 buffers for Teensy 3.x and 80 for Teensy 4.x.
|
|
But floating point variables are 4-bytes, not 2.
|
|
So it is believed that these higher levels are useable, but if memory is tight,
|
|
consider using setMaxBuffers().
|
|
</p>
|
|
</script>
|
|
<script type="text/x-red" data-template-name="AudioPlayQueue_F32">
|
|
<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>
|
|
</script>
|
|
|
|
<script type="text/x-red" data-help-name="AudioRecordQueue_F32">
|
|
<h3>Summary</h3>
|
|
<div class=tooltipinfo>
|
|
<p>Record audio data by sending to the Arduino sketch. This object allows
|
|
sketch code to receive audio packets.</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>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>
|
|
</script>
|
|
<script type="text/x-red" data-template-name="AudioRecordQueue_F32">
|
|
<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>
|
|
</script>
|
|
|
|
<script type="text/x-red" data-help-name="AudioSynthNoisePink_F32">
|
|
<h3>Summary</h3>
|
|
<div class=tooltipinfo>
|
|
<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>
|
|
</script>
|
|
<script type="text/x-red" data-template-name="AudioSynthNoisePink_F32">
|
|
<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>
|
|
</script>
|
|
|
|
<script type="text/x-red" data-help-name="AudioSynthWaveformSine_F32">
|
|
<h3>Summary</h3>
|
|
<div class=tooltipinfo>
|
|
<p>Create a sine wave signal</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>Sine Wave Output</td></tr>
|
|
</table>
|
|
<h3>Functions</h3>
|
|
<p class=func><span class=keyword>amplitude</span>(level);</p>
|
|
<p class=desc> <p class=desc>The amplitude, level, is the peak, as in
|
|
zero-to-peak. This produces an output ranging from -a to +a.
|
|
</p>
|
|
Negative values do a 180-degree phase reversal.
|
|
</p>
|
|
<p class=func><span class=keyword>frequency</span>(freq);</p>
|
|
<p class=desc>Set the frequency, from 0.0 to half of the sampling
|
|
frequency. This is a floating point number and thus not limited to integers.
|
|
Values such as 123.456 will be set properly.
|
|
</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.0 to 360.0 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>setSampleRate_Hz</span>(float &fs_Hz);</p>
|
|
<p class=desc>Sets sample rate for this class only. Default 44.1 kHz.</p>
|
|
<p class=func><span class=keyword>begin</span>(void);</p>
|
|
<p class=desc>Defaults to sine running. But, along with the end() function
|
|
can be used to turn the wave on and off.
|
|
</p>
|
|
<p class=func><span class=keyword>end</span>(void);</p>
|
|
<p class=func><span class=keyword>pureSpectrum</span>(bool _setPure);</p>
|
|
<p class=desc>The function pureSpectrum(true) enables two stages of
|
|
biquad filtering putting the harmonics generally below -135 dBc. This filter
|
|
tracks the frequency() entry, and is available above a few hundred Hz,
|
|
depending on the sample rate.
|
|
</p>
|
|
<h3>Examples</h3>
|
|
<p class=exam>File > Examples > ReceiverPart1
|
|
</p>
|
|
<p class=exam>File > Examples > AudioTestPeakRMS
|
|
</p>
|
|
<p class=exam>File > Examples > LowpassFilter_FD_OA
|
|
</p>
|
|
<h3>Notes</h3>
|
|
<p></p>
|
|
</script>
|
|
<script type="text/x-red" data-template-name="AudioSynthWaveformSine_F32">
|
|
<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>
|
|
</script>
|
|
|
|
|
|
|
|
<script type="text/x-red" data-help-name="AudioSynthSineCosine_F32">
|
|
<h3>Summary</h3>
|
|
<div class=tooltipinfo>
|
|
<p>Creates both a sine wave and cosine signals with 90 degree
|
|
phase difference. 90 degree difference can be adjusted. Both have the
|
|
same adjustable amplitude. </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>Sine Wave Output</td></tr>
|
|
<tr class=odd><td align=center>Out 0</td><td>Cosine Wave Output</td></tr>
|
|
</table>
|
|
<h3>Functions</h3>
|
|
<p class=func><span class=keyword>amplitude</span>(<strong>float </strong>level);</p>
|
|
<p class=desc>The amplitude, a, is the peak, as in zero-to-peak. This produces outputs
|
|
ranging from -a to +a. Both outputs are the same amplitude.
|
|
</p>
|
|
|
|
<p class=func><span class=keyword>frequency</span>(<strong>float </strong>freq);</p>
|
|
<p class=desc>Set the frequency of the sine and cosine waveforms, in Hz. Both
|
|
are the same.</p>
|
|
|
|
<p class=func><span class=keyword>phase</span>(<strong>float </strong>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>phase_r</span>(<strong>float </strong> phr)
|
|
<p class=desc>Externally, phase comes in the range (0,2*M_PI) keeping with C math functions
|
|
Internally, the full circle is represented as (0.0, 512.0). This is
|
|
convenient for finding the entry to the sine table.</p>
|
|
|
|
|
|
|
|
<p class=func><span class=keyword>phaseS_C_r</span>(<strong>float </strong> phsc)
|
|
<p class=desc>phaseS_C_r is the number of radians that the cosine output leads the
|
|
sine output. The default is M_PI_2 = pi/2 = 1.57079633 radians,
|
|
corresponding to 90.00 degrees cosine leading sine.</p>
|
|
|
|
|
|
<p class=func><span class=keyword>void simple</span>(<strong>bool </strong> s)
|
|
<p class=desc>Speed up calculations by setting phaseS_C=90deg, amplitude=1
|
|
Note, s=true will override any setting of phaseS_C_r or amplitude.</p>
|
|
|
|
<p class=func><span class=keyword>pureSpectrum</span>(bool _setPure);</p>
|
|
<p class=desc>The function pureSpectrum(true) enables two stages of
|
|
biquad filtering on each output, putting the harmonics generally below -135 dBc.
|
|
This filter tracks the frequency() entry, and is available above a few hundred Hz,
|
|
depending on the sample rate.
|
|
</p>
|
|
|
|
<p class=func><span class=keyword>setSampleRate_Hz</span>(<strong>float </strong> fs_Hz)
|
|
<p class=desc>Sets sample rate for this class only. Default 44.1 kHz.</p>
|
|
|
|
|
|
<p class=func><span class=keyword>setBlockLength</span>(<strong>uint16_t </strong> bl)
|
|
<p class=desc>Sets block length for this class only. Default 128.</p>
|
|
|
|
|
|
|
|
</p>
|
|
<h3>Examples</h3>
|
|
<p class=exam>File > Examples > Audio > MemoryAndCpuUsage
|
|
</p>
|
|
<p class=exam>File > Examples > Audio > Analysis > ---
|
|
</p>
|
|
<p class=exam>File > Examples > Audio > Analysis > ---
|
|
</p>
|
|
<h3>Notes</h3>
|
|
<p></p>
|
|
</script>
|
|
<script type="text/x-red" data-template-name="AudioSynthSineCosine_F32">
|
|
<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>
|
|
</script>
|
|
|
|
|
|
|
|
<script type="text/x-red" data-help-name="AudioSynthWaveform_F32">
|
|
<h3>Summary</h3>
|
|
<div class=tooltipinfo>
|
|
<p>Create a waveform: sine, sawtooth, square, triangle, pulse or arbitrary.</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>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_SAWTOOTH_REVERSE</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>
|
|
<li><span class=literal>WAVEFORM_SAMPLE_HOLD</span></li>
|
|
</ul>
|
|
</p>
|
|
</script>
|
|
<script type="text/x-red" data-template-name="AudioSynthWaveform_F32">
|
|
<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>
|
|
</script>
|
|
|
|
<div>
|
|
<script type="text/x-red" data-help-name="AudioSynthGaussian_F32">
|
|
<!-- ============ AudioSynthGaussian_F32 ========= -->
|
|
<h3>Summary</h3>
|
|
<div class=tooltipinfo>
|
|
<p>Generates Gaussian White Noise of known power.</p>
|
|
</div>
|
|
<h3>Boards Supported</h3>
|
|
<ul>
|
|
<li>Teensy 3.2
|
|
<li>Teensy 3.5
|
|
<li>Teensy 3.6
|
|
<li>Teensy 4.0
|
|
<li>Teensy 4.1
|
|
</ul>
|
|
<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 Noise Signal</td></tr>
|
|
</table>
|
|
|
|
<h3>Functions</h3>
|
|
<p class=func><span class=keyword>amplitude</span>(<strong>float</strong> sd);</p>
|
|
<p class=desc>Sets the amplitude of the noise. This is the 1-sima or standard
|
|
deviation level. Since this is Gaussian distributed noise, the same number is also
|
|
the RMS level (square root of power).
|
|
|
|
<h3>Examples</h3>
|
|
<p class=exam>File > Examples > OpenAudio_ArduinoLibrary > TestNoiseBlanker1
|
|
</p>
|
|
|
|
<h3>Notes</h3>
|
|
<p>This noise source is a Gaussian distribution with mean of
|
|
zero and a standard deviation specified by amplitude(). Default amlitude
|
|
is 0.0 (off). Individual samples are fully uncorrelated, meaning that
|
|
the spectrum of the noise is flat (White Noise).</p>
|
|
|
|
<p>Time requirements for generating a block of 128, Teensy 3.6,
|
|
is 121 microseconds and for the Teensy 4.0 is 36 microseconds.</p>
|
|
|
|
</script>
|
|
<script type="text/x-red" data-template-name="AudioSynthGaussian_F32">>
|
|
<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>
|
|
</script>
|
|
|
|
|
|
|
|
|
|
<script type="text/x-red" data-help-name="AudioSynthNoiseWhite_F32">
|
|
<h3>Summary</h3>
|
|
<div class=tooltipinfo>
|
|
<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>
|
|
</script>
|
|
<script type="text/x-red" data-template-name="AudioSynthNoiseWhite_F32">
|
|
<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>
|
|
</script>
|
|
|
|
|
|
|
|
<div>
|
|
<script type="text/x-red" data-help-name="RadioFMDetector_F32">
|
|
<!-- ============ RadioFMDetector_F32 ========= -->
|
|
<h3>Summary</h3>
|
|
<div class=tooltipinfo>
|
|
<p>An FM Detector sutable for work at an low frequency such
|
|
as 15 kHz. An output low-pass filter is included. A squelch
|
|
allows for silencing noise when signals are not present.
|
|
For deviations in the 10 kHz range or less. Not for wideband
|
|
broadcast FM.
|
|
</p>
|
|
</div>
|
|
<h3>Boards Supported</h3>
|
|
<ul>
|
|
<li>Teensy 3.2
|
|
<li>Teensy 3.5
|
|
<li>Teensy 3.6
|
|
<li>Teensy 4.0
|
|
<li>Teensy 4.1
|
|
</ul>
|
|
<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</td></tr>
|
|
<tr class=odd><td align=center>Out 0</td><td>De-modulated Output Signal</td></tr>
|
|
<tr class=odd><td align=center>Out 1</td><td>De-modulated Output Signal, squelched</td></tr>
|
|
</table>
|
|
|
|
<h3>Functions</h3>
|
|
<p class=func><span class=keyword>frequency</span>(<strong>float</strong> fCenter);</p>
|
|
<p class=desc></p>
|
|
<p>Sets the center frequency, in Hz.</p>
|
|
|
|
<p class=func><span class=keyword>filterOut</span>(<strong>float</strong> *firCoeffs, <strong>uint</strong> nFIR, <strong>float</strong> Kdem);</p>
|
|
<p>This sets output filtering where:
|
|
<pre class="desc">
|
|
float32_t* firCoeffs pointer to array of coefficients
|
|
uint nFIR is the number of coefficients
|
|
float32_t Kdem is the de-emphasis frequency factor
|
|
Kdem = 1/(0.5+(tau*fsample))
|
|
tau is the de-emphasis time constant,
|
|
typically 0.0005 second and fsample
|
|
the sample frequency, typically 44117.
|
|
</pre>
|
|
<p class=func><span class=keyword>filterIQ</span>(<strong>float</strong> *fir_IQ_Coeffs, <strong>uint</strong> nFIR_IQ);</p>
|
|
<p>This sets the detector output filtering where:
|
|
<pre class="desc">
|
|
float32_t* fir_IQ_Coeffs is an array of coefficients
|
|
uint nFIR_IQ is the number of coefficients, max 60
|
|
</pre>
|
|
|
|
<p class=func><span class=keyword>setSquelchThreshold</span>(<strong>float</strong> sqThresh);</p>
|
|
<p class=desc></p>
|
|
<p>Sets the squelch threshold ranging 0.0 to 1.0 where
|
|
0.0 always lets audio through.</p>
|
|
|
|
<p class=func><span class=keyword>setSquelchDecay </span>(<strong>float</strong> sqDecay);</p>
|
|
<p class=desc></p>
|
|
<p>Sets the decay rate of the output of the squelch detector. This produces the "squelch tail."
|
|
The range is 0.9 (no real tail) to 0.9999 (very slow decay and a long squelch tail.)
|
|
The default value is 0.99.</p>
|
|
|
|
<p class=func><span class=keyword>getSquelchLevel</span>();</p>
|
|
<p class=desc></p>
|
|
<p>Returns the current measured squelch level as a <strong>float. </strong>
|
|
Higher levels, towards 1.0, are no signal. A low return value indicates presence of
|
|
a signal.</p>
|
|
|
|
<p class=func><span class=keyword>setSquelchFilter</span>(<strong>float* </strong>Coefficients);</p>
|
|
<p class=desc></p>
|
|
<p>This allows changing the 2-section (4-pole) bandpass BiQuad filter used before the
|
|
squelch detector. This passes high-frequency noise and attenuates lower frequency voice. The
|
|
parameter "Coefficients" points to an array of 10 floating point numbers. A Coefficient value
|
|
of NULL restores the default 3 to 5 kHz filter. See the example ReceiverFM.ino for using this.</p>
|
|
|
|
<p class=func><span class=keyword>returnInitializeFMError</span>();</p>
|
|
<p>This returns the initialization errors, for debug use.
|
|
<pre class="desc">
|
|
B0001 (value 1) error in IQ FIR Coefficients or qty
|
|
B0010 (value 2) error in Output FIR Coefficients or qty
|
|
B0100 (value 4) error in de-emphasis constant
|
|
B1000 (value 8) errors center frequency to high
|
|
</pre>
|
|
|
|
<h3>Examples</h3>
|
|
<p class=exam>File > Examples > OpenAudio_ArduinoLibrary > ReceiverFM
|
|
</p>
|
|
|
|
<p class=exam>File > Examples > OpenAudio_ArduinoLibrary > ReceiverPart2
|
|
</p>
|
|
|
|
<h3>Notes</h3>
|
|
<p>This consists of a single input at some frequency, such as 10 to 20 kHz and
|
|
an output, such as 0 to 5 kHz. The output level is linearly dependent on the
|
|
frequency of the input sine wave frequency, i.e., an it is an FM detector.
|
|
The input needs to be band limited below the lower frequency side of the
|
|
input, typically 10 kHz. This is not part of this block.</p>
|
|
|
|
<p>This uses 430 microseconds for an 128 point update with Teensy 3.6. With the
|
|
Teensy 4.x, 97 microseconds is used.</p>
|
|
|
|
<P>The output can be FIR filtered using default parameters,
|
|
or using coefficients from an array. A separate single pole de-emphasis filer
|
|
is included that again can be programmed.</P>
|
|
|
|
<p><strong>Output:</strong>Float, sensitivity is 2*pi*(f - fCenter)*sample_rate_Hz
|
|
For 44117Hz sample rate, this is 0.000142421 per Hz.</p>
|
|
|
|
<p><strong>Accuracy</strong>The function used is precise. However, the approximations, such
|
|
as fastAtan2, slightly limit the accuracy. A 200 point sample of a
|
|
14 kHz input had an average error of 0.03 Hz
|
|
and a standard deviation of 0.81 Hz.</p>
|
|
|
|
<p>The RadioFMDetector_F32.h file has much more information including details
|
|
of the arc-tangent method of computation.</p>
|
|
|
|
</script>
|
|
<script type="text/x-red" data-template-name="RadioFMDetector_F32">>
|
|
<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>
|
|
</script>
|
|
|
|
|
|
|
|
|
|
|
|
<div>
|
|
<script type="text/x-red" data-help-name="RadioFMDiscriminator_F32">
|
|
<!-- ============ RadioFMDiscriminator_F32 ========= -->
|
|
<h3>Summary</h3>
|
|
<div class=tooltipinfo>
|
|
<p>An FM Discriminator suitable for work at an low frequency, such
|
|
as 15 kHz. The DSP functionality is the same as that of a classic
|
|
2-tuned circuit analog discrimiator. The center frequenct of the tuned circuits
|
|
and their Q is programmable. An output low-pass filter is included. A squelch
|
|
allows for silencing noise when signals are not present.
|
|
For deviations in the 10 kHz range or less. Not for wideband
|
|
broadcast FM. No bandpass filtering is supplied for the input signals and noise.
|
|
That filtering is often desireable and may be added using AudioFilterFIRGeneral_F32.
|
|
</p>
|
|
</div>
|
|
<h3>Boards Supported</h3>
|
|
<ul>
|
|
<li>Teensy 3.2
|
|
<li>Teensy 3.5
|
|
<li>Teensy 3.6
|
|
<li>Teensy 4.0
|
|
<li>Teensy 4.1
|
|
</ul>
|
|
<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</td></tr>
|
|
<tr class=odd><td align=center>Out 0</td><td>De-modulated Output Signal</td></tr>
|
|
<tr class=odd><td align=center>Out 1</td><td>De-modulated Output Signal, squelched</td></tr>
|
|
</table>
|
|
<h3>Functions</h3>
|
|
<p class=func><span class=keyword>initializeFMDiscriminator</span>
|
|
(<strong>float</strong> f1,<strong> float</strong> f2,<strong> float</strong> q1,<strong> float</strong> q2);</p>
|
|
<p class=desc></p>
|
|
<p>Designs the discriminator "circuit" where f1 and f2
|
|
are the resonant frequencies of the two resonators and q1 and q2 are the associated Q factors.
|
|
The Q factors control the width of the peaks at frequencies f1 and f2.</p>
|
|
|
|
<p class=func><span class=keyword>filterOut
|
|
</span>(<strong>float32_t</strong> *firCoeffs, <strong>uint</strong> nFIR,
|
|
<strong>float32_t</strong> *firCoeffs,<strong>float32_t</strong> Kdem);</p>
|
|
<p>This sets output filtering where:
|
|
<pre class="desc">
|
|
float32_t* firCoeffs pointer to array of coefficients
|
|
uint nFIR is the number of coefficients
|
|
float32_t* fir_State_Out pointer to float32_t array
|
|
float32_t Kdem is the de-emphasis frequency factor
|
|
Kdem = 1/(0.5+(tau*fsample))
|
|
tau is the de-emphasis time constant,
|
|
typically 0.0005 second and fsample
|
|
the sample frequency, typically 44117.
|
|
</pre>
|
|
<p>Calling this function enables the use of a FIR output filter
|
|
and will cancel any IIR output filter. firCoeffs points to an INO supplied array
|
|
of FIR coefficients. fir_State_Out points to a float32_t storage area, again
|
|
supplied by the INO. The size of this array is 128+nFIR. If the block size
|
|
in settings has been changed from 128, then that new size should replace 128.</p>
|
|
<p class=func><span class=keyword>filterOutIIR
|
|
</span>(<strong>float</strong> frequency, <strong>float32_t</strong> q, <strong>float32_t</strong> kdem);</p>
|
|
<p>This sets the detector output filtering where:
|
|
<pre class="desc">
|
|
float32_t frequency is the LPF cutoff in Hz.
|
|
float32_t q is the loss factor for the LPF, typically 0.7.
|
|
</pre>
|
|
<p>Calling this function enables the use of a IIR output filter
|
|
and will cancel any FIR output filter.</p>
|
|
|
|
<p class=func><span class=keyword>setSquelchThreshold</span>(<strong>float</strong> sqThresh);</p>
|
|
<p class=desc></p>
|
|
<p>Sets the squelch threshold ranging 0.0 to 1.0 where
|
|
0.0 always lets audio through.</p>
|
|
|
|
<p class=func><span class=keyword>setSquelchDecay </span>(<strong>float</strong> sqDecay);</p>
|
|
<p class=desc></p>
|
|
<p>Sets the decay rate of the output of the squelch detector. This produces the "squelch tail."
|
|
The range is 0.9 (no real tail) to 0.9999 (very slow decay and a long squelch tail.)
|
|
The default value is 0.99.</p>
|
|
|
|
<p class=func><span class=keyword>getSquelchLevel</span>();</p>
|
|
<p class=desc></p>
|
|
<p>Returns the current measured squelch level as a <strong>float. </strong>
|
|
Higher levels, towards 1.0, are no signal. A low return value indicates presence of
|
|
a signal.</p>
|
|
|
|
<p class=func><span class=keyword>setSquelchFilter</span>(<strong>float* </strong>Coefficients);</p>
|
|
<p class=desc></p>
|
|
<p>This allows changing the 2-section (4-pole) bandpass BiQuad filter used before the
|
|
squelch detector. This passes high-frequency noise and attenuates lower frequency voice. The
|
|
parameter "Coefficients" points to an array of 10 floating point numbers. A Coefficient value
|
|
of NULL restores the default 3 to 5 kHz filter. See the example ReceiverFM.ino for using this.</p>
|
|
|
|
<h3>Examples</h3>
|
|
<p class=exam>File > Examples > OpenAudio_ArduinoLibrary > BFSK
|
|
</p>
|
|
|
|
<p class=exam>File > Examples > OpenAudio_ArduinoLibrary > BFSK_random
|
|
</p>
|
|
|
|
<p class=exam>File > Examples > OpenAudio_ArduinoLibrary > BFSK_snr
|
|
</p>
|
|
|
|
<h3>Notes</h3>
|
|
<p>No input bandpass filtering is included. This may be desireable and should
|
|
be provided as a separate FIR filter block. The input level is non-critical
|
|
as a limiter is provided at the discriminator input. Limiting is centered on
|
|
a 0.0 input level.</p>
|
|
|
|
<p>This uses 45 microseconds for an 128 point update with Teensy 4.x.</p>
|
|
|
|
<P>The output can be FIR filtered using default parameters,
|
|
or using coefficients from an array. A separate single pole de-emphasis filter
|
|
is included that again can be programmed.</P>
|
|
|
|
<p>Two forms of object creation are possible.
|
|
RadioFMDiscriminator_F32() uses default sample rate and block size.
|
|
Non-standard values are possible with
|
|
RadioFMDiscriminator_F32(AudioSettings_F32 &settings).</p>
|
|
|
|
<p>The RadioFMDiscriminator_F32.h file has more information.</p>
|
|
</script>
|
|
<script type="text/x-red" data-template-name="RadioFMDiscriminator_F32">>
|
|
<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>
|
|
</script>
|
|
|
|
<script type="text/x-red" data-help-name="UART_F32">
|
|
<h3>Summary</h3>
|
|
<div class=tooltipinfo>
|
|
<p>Receive base-band digital data as audio samples and convert these to digital
|
|
0,1 data. Using Universal Asynchronous Receive Transmit (UART) receive
|
|
rules, generate data words. These data words are available to the INO
|
|
via a 16-word FIFO buffer</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>Baseband signal to be digitized</td></tr>
|
|
</table>
|
|
<h3>Functions</h3>
|
|
<p class=func><span class=keyword>setUART</span>
|
|
(<strong>uint32_t</strong> cTauI, <strong>uint32_t</strong> cTauHalfI,
|
|
<strong>uint16_t</strong> nBits, <strong>uint16_t</strong> nParity,
|
|
<strong>uint16_t</strong> nStop);</p>
|
|
<p class=desc>This sets the UART parameters. The cTauI is the number of
|
|
audio samples for each bit period. This is normally found
|
|
as the bit sample rate divided by the UART bit rate. cTauHalfI
|
|
is half that number. Both are quantized to integer values.</p>
|
|
<p class=func><span class=keyword>getNDataBuffer</span>();</p>
|
|
<p class=desc>Returns the number of unread data words as uint32_t. </p>
|
|
<p class=func><span class=keyword>readUartData</span>();</p>
|
|
<p class=desc>returns a pointer to the uartData structure.
|
|
This increments the index and thus can only be called once per
|
|
successful UART output word. If no data is available, a NULL
|
|
pointer is returned. The structure is as follows:
|
|
<pre class="desc">
|
|
struct uartData {
|
|
uint32_t data;
|
|
uint8_t status;
|
|
int32_t timeCrossings;
|
|
};
|
|
</pre>
|
|
</p>
|
|
<p class=func><span class=keyword>setInputOffset</span>(<strong>float32_t</strong> inputOffset);</p>
|
|
<p class=desc>The input is a floating point value, centered on 0.0. One source of this
|
|
could be a discriminator base-band output. If the input signal is offset
|
|
from zero, it can be corrected with this function. This inputOffset is
|
|
added to the input and can be + or - in value.
|
|
</p>
|
|
<p class=func><span class=keyword>setSampleRate_Hz</span>
|
|
(<strong>float32_t</strong> sampleRate_Hz)</p>
|
|
<p class=desc>Enter sample rate, for this class only, as float32_t.
|
|
</p>
|
|
<h3>Examples</h3>
|
|
<p class=exam>File > Examples > OpenAudio_ArduinoLibrary > BFSK
|
|
</p>
|
|
<p class=exam>File > Examples > OpenAudio_ArduinoLibrary > BFSK_random
|
|
</p>
|
|
<p class=exam>File > Examples > OpenAudio_ArduinoLibrary > BFSK_snr
|
|
</p>
|
|
<h3>Notes</h3>
|
|
<p>This is only the receive portion of the UART. The transmit function is often
|
|
best integrated with the transmit modulator. This UART parallels the receive
|
|
functions of common devices going back to fully hardware implementations. To support
|
|
play with the function, the data words can be any length up to 32 bits.
|
|
</p>
|
|
<p>Parity is not yet implemented.</p>
|
|
</script>
|
|
<script type="text/x-red" data-template-name="UART_F32">
|
|
<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>
|
|
</script>
|
|
|
|
|
|
<script type="text/x-red" data-help-name="radioCESSBtransmit_F32">
|
|
<!-- ============ radioCESSBtransmit_F32 ========= -->
|
|
<h3>Summary</h3>
|
|
<div class=tooltipinfo>
|
|
<p>Converts audio into Weaver SSB and then applies Dave Hershberger, W9GR,
|
|
CESSB controlled clipping and
|
|
filtering. This prevents the SSB peaks from exceeding a maximum level.
|
|
This increases the peak limited average power by 3 or more dB. The output
|
|
can be converted to conventional SSB by a RadioIQMixer_F32 object.
|
|
</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>Input Audio Signal</td></tr>
|
|
<tr class=odd><td align=center>Out 0</td><td>Weaver SSB I Signal</td></tr>
|
|
<tr class=odd><td align=center>Out 1</td><td>Weaver SSB Q Signal</td></tr>
|
|
</table>
|
|
<h3>Functions</h3>
|
|
<p class=func><span class=keyword>setSampleRate_Hz</span>
|
|
(<strong>float32_t</strong> fs_Hz bitRate);</p>
|
|
<p class=desc>Specifically, this sets the sample rate, in samples per second,
|
|
that is used by CESSB. It also sets other parameters, such as
|
|
decimation ratios and filter cutoff frequencies. Thus this function
|
|
is <strong>required.</strong> At this time, the design is centered
|
|
on 48000 sps, but can be used with other close values such as
|
|
44100 or 50000. The plan is to eventually support 96000 sps if users
|
|
are needing it. There is no default value and the CESSB objects will not run if
|
|
this function is not called.</p>
|
|
|
|
|
|
<p class=func><span class=keyword>getLevels</span>(<strong>int</strong> what);</p>
|
|
<p class=desc>Returns a pointer to a structure of type levels. This allows
|
|
knowledge of the average and peak levels at both the input and output sides
|
|
of the SSB clipper and overshoot compensator. If what==0 the pointer is returned
|
|
but no updating is done. That is used to setup the process before data is
|
|
available. If what != 0, the contents of the structure are updated and measuring
|
|
is reset. The function levelDataCount() below can be used to set the time
|
|
between updates. The stucture is part of the object and is defined as:
|
|
<pre>
|
|
struct levels {
|
|
float32_t pwr0; // Average power at input
|
|
float32_t peak0; // Peak voltage at input
|
|
float32_t pwr1; // Average power at output
|
|
float32_t peak1; // Peak voltage at output
|
|
uint32_t countP; // Number of averaged samples for pwr0.
|
|
};
|
|
</pre></p>
|
|
|
|
<p class=func><span class=keyword>levelDataCount</span>();</p>
|
|
<p class=desc>Returns an uint32_t with the number of averaged samples
|
|
of the input power. See getLevels() above. The number of output
|
|
samples may differ by an integer factor because of decimation inside
|
|
the object.</p>
|
|
|
|
<p class=func><span class=keyword>setGains</span>(
|
|
<strong>float32_t</strong> gainIn,
|
|
<strong>float32_t</strong> gainCompensate,
|
|
<strong>float32_t</strong> gainOut);</p>
|
|
<p class=desc> These are the controls for the CESSB class. gainIn sets
|
|
the amount of clipping by setting the input level to the clipper.
|
|
gainCompensate sets the amount of correction applied to prevent
|
|
overshoot. A value of 2.0 or slightly less is normally used. gainOut is
|
|
for convenience and sets the drive level to the next block. </p>
|
|
|
|
|
|
<p class=func><span class=keyword>setSideband</span>(<strong>bool</strong> sbReverse);</p>
|
|
<p class=desc>The LSB/USB selection depends on the processing of the
|
|
IQ outputs of this class. But, what we can do here is to reverse the
|
|
selection by reversing the phase of one of the Weaver LO's. </p>
|
|
|
|
<h3>Examples</h3>
|
|
<p class=exam>File > Examples > OpenAudio_ArduinoLibrary > CESSB
|
|
</p>
|
|
|
|
<h3>Notes</h3>
|
|
<p>The technical description, implementation and test results are in references
|
|
listed in the include file for this class,
|
|
<a href="https://github.com/chipaudette/OpenAudio_ArduinoLibrary/blob/master/radioCESSBtransmit_F32.h"
|
|
target="_blank">available from Github</a>
|
|
These should be used to understand the details of CESSB. The notes at the top of
|
|
that include file has information relating to this Teensy Audio implementation, as well.
|
|
</p>
|
|
|
|
<p>This class may not be suitable for directly driving external I-Q hardware
|
|
mixers. The limited LO-RF isolation of those mixers can introduce a midband tone
|
|
that will be transmitted. To work around this problem, use the companion
|
|
class radioCESSB_Z_transmit_F32 that uses the phasing method of SSB generation.</p>
|
|
|
|
<p>The first activity for CESSB is to limit or clip the amplitude of the SSB signal. Internally
|
|
this always occurs when the envelope of the SSB signal exceeds 1.0. This is all done
|
|
with floating point arithmetic so values may exceed 1.0. The input level where this occurs
|
|
depends on the setting for gainIn, described above. The maximum level seen ahead of the clipper
|
|
is measured by getLevels() as described above. One way to control the input to the CESSB block
|
|
is with
|
|
<a href="http://www.janbob.com/electron/OpenAudio_Design_Tool/index.html?info=AudioEffectCompressor2_F32"
|
|
target="_blank">Compressor2 Library block.</a> Note that Compressor2
|
|
is not a clipper, but is rather an automatic gain control that uses look-ahead
|
|
processing to allow gradual gain changes.
|
|
</p>
|
|
|
|
<p>The output of the CESSB processing is two sampled data signals representing
|
|
Weaver SSB. This uses the in-phase and quadratuere components of the SSB signal
|
|
that has been converted to frequencies of -1350 to +1350 Hz. Wow, if that seems
|
|
confusing, take a look at the CESSB example and see how this can be translated
|
|
into either an Upper Sideband (USB) or a Lower Sideband (LSB) signal. Implemented
|
|
in DSP, the Weaver Method of SSB generation has some interesting and good features.
|
|
It is worth considering as an alternative to the phasing method, with or without CESSB.
|
|
By lowering the input level, this CESSB block can be used as a Weaver Method SSB
|
|
generator.</p>
|
|
|
|
<p>CESSB as implemented here is intended for voice input, and also filters the voice
|
|
to a communications bandwidth of around 2700 Hz.</p>
|
|
|
|
</script>
|
|
<script type="text/x-red" data-template-name="radioCESSBtransmit_F32">
|
|
<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>
|
|
</script>
|
|
|
|
|
|
<script type="text/x-red" data-help-name="radioCESSB_Z_transmit_F32">
|
|
<!-- ============ radioCESSB_Z_transmit_F32 ========= -->
|
|
<h3>Summary</h3>
|
|
<div class=tooltipinfo>
|
|
<p>Converts audio into SSB and then applies Dave Hershberger, W9GR,
|
|
CESSB controlled clipping and
|
|
filtering. This prevents the SSB peaks from exceeding a maximum level.
|
|
This increases the peak limited average power by 3 or more dB. The output
|
|
can be up converted by a RadioIQMixer_F32 object or sent via DAC's as
|
|
I-Q baseband, ready for quadrature mixer transmit.
|
|
</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>Input Audio Signal</td></tr>
|
|
<tr class=odd><td align=center>Out 0</td><td>Baseband SSB I Signal</td></tr>
|
|
<tr class=odd><td align=center>Out 1</td><td>Baseband SSB Q Signal</td></tr>
|
|
</table>
|
|
<h3>Functions</h3>
|
|
<p class=func><span class=keyword>setSampleRate_Hz</span>
|
|
(<strong>float32_t</strong> fs_Hz bitRate);</p>
|
|
<p class=desc>Specifically, this sets the sample rate, in samples per second,
|
|
that is used by CESSB. It also sets other parameters, such as
|
|
decimation ratios and filter cutoff frequencies. Thus this function
|
|
is <strong>required.</strong> At this time, the design is centered
|
|
on 48000 sps, but can be used with other close values such as
|
|
44100 or 50000. The plan is to eventually support 96000 sps if users
|
|
are needing it. There is no default value and the CESSB objects will not run if
|
|
this function is not called.</p>
|
|
|
|
|
|
<p class=func><span class=keyword>getLevels</span>(<strong>int</strong> what);</p>
|
|
<p class=desc>Returns a pointer to a structure of type levels. This allows
|
|
knowledge of the average and peak levels at both the input and output sides
|
|
of the SSB clipper and overshoot compensator. If what==0 the pointer is returned
|
|
but no updating is done. That is used to setup the process before data is
|
|
available. If what != 0, the contents of the structure are updated and measuring
|
|
is reset. The function levelDataCount() below can be used to set the time
|
|
between updates. The stucture is part of the object and is defined as:
|
|
<pre>
|
|
struct levels {
|
|
float32_t pwr0; // Average power at input
|
|
float32_t peak0; // Peak voltage at input
|
|
float32_t pwr1; // Average power at output
|
|
float32_t peak1; // Peak voltage at output
|
|
uint32_t countP; // Number of averaged samples for pwr0.
|
|
};
|
|
</pre></p>
|
|
|
|
<p class=func><span class=keyword>levelDataCount</span>();</p>
|
|
<p class=desc>Returns an uint32_t with the number of averaged samples
|
|
of the input power. See getLevels() above. The number of output
|
|
samples may differ by an integer factor because of decimation inside
|
|
the object.</p>
|
|
|
|
<p class=func><span class=keyword>setGains</span>(
|
|
<strong>float32_t</strong> gainIn,
|
|
<strong>float32_t</strong> gainCompensate,
|
|
<strong>float32_t</strong> gainOut);</p>
|
|
<p class=desc> These are the controls for the CESSB class. gainIn sets
|
|
the amount of clipping by setting the input level to the clipper.
|
|
gainCompensate sets the amount of correction applied to prevent
|
|
overshoot. A value of 1.4 is normally used. gainOut is
|
|
for convenience and sets the drive level to the next block. </p>
|
|
|
|
|
|
<p class=func><span class=keyword>setSideband</span>(<strong>bool</strong> sbReverse);</p>
|
|
<p class=desc>The LSB/USB selection depends on the processing of the
|
|
IQ outputs of this class. But, what we can do here is to reverse the
|
|
selection by reversing the phase of the Q signal. </p>
|
|
|
|
|
|
<p class=func><span class=keyword>setIQCorrections</span>
|
|
(<strong>bool</strong> useIQCorrection, <strong>float32_t</strong> gainI,
|
|
<strong>float32_t</strong> crossIQ,<strong>float32_t</strong> crossQI);</p>
|
|
<p class=desc>This allows small corrections at the output end of the
|
|
CESSB object, to patch up hardware flaws. The variable useIQCorrection should be
|
|
<strong>true</strong> to use the corrections. gainI corrects for gain errors between
|
|
the I and Q channels and should be close to 1.0.
|
|
The variables, crossIQ and crossQI correct for phase errors and should
|
|
be close to 0.0. There is interaction between the 3 variables, but
|
|
converging adjustment to null the unwanted sideband is doable. Either crossIQ or crossQI
|
|
should end up as 0.0. If use IQCorrection is false, there is no processor
|
|
load for corrections.</p>
|
|
|
|
|
|
<h3>Examples</h3>
|
|
<p class=exam>File > Examples > OpenAudio_ArduinoLibrary > CESSB_ZeroIF
|
|
</p>
|
|
|
|
<h3>Notes</h3>
|
|
<p>The technical description, implementation and test results are in references
|
|
listed in the include file for this class,
|
|
<a href="https://github.com/chipaudette/OpenAudio_ArduinoLibrary/blob/master/radioCESSBtransmit_F32.h"
|
|
target="_blank">available from Github</a>
|
|
These should be used to understand the details of CESSB. The notes at the top of
|
|
that include file has information relating to this Teensy Audio implementation, as well.
|
|
</p>
|
|
|
|
<p>The first activity for CESSB is to limit or clip the amplitude of the SSB signal. Internally
|
|
this always occurs when the envelope of the SSB signal exceeds 1.0. This is all done
|
|
with floating point arithmetic so values may exceed 1.0. The input level where this occurs
|
|
depends on the setting for gainIn, described above. The maximum level seen ahead of the clipper
|
|
is measured by getLevels() as described above. One way to control the input to the CESSB block
|
|
is with
|
|
<a href="http://www.janbob.com/electron/OpenAudio_Design_Tool/index.html?info=AudioEffectCompressor2_F32"
|
|
target="_blank">Compressor2 Library block.</a> Note that Compressor2
|
|
is not a clipper, but is rather an automatic gain control that uses look-ahead
|
|
processing to allow gradual gain changes.
|
|
</p>
|
|
|
|
<p>The output of the CESSB processing is the in-phase and quadratuere components
|
|
(I-Q) of the SSB signal that has the suppressed carrier at zero frequency.
|
|
This can be translated to higher frequencies, either by a RadioIQMixer_F32
|
|
object, or by feeding through a pair of DAC's to quadrature hardware mixers. This
|
|
produces either an Upper Sideband (USB) or a Lower Sideband (LSB) signal. The sideband
|
|
can be selected in various ways, including the function for this class, setSideband()
|
|
described above.</p>
|
|
|
|
<p>Note the companion class, RadioCESSBtransmit_F32, that uses the Weaver-method
|
|
as is done used
|
|
in the referenced Hershberger documents. The performance of the two classes is
|
|
very similar. This version removes concerns about mid-band spurious tone generation
|
|
when used with hardware mixers.</p>
|
|
|
|
<p>CESSB as implemented here is intended for voice input, and also filters the voice
|
|
to a communications bandwidth of around 2800 Hz.</p>
|
|
|
|
<p>The Hilbert filter used with this class will provide high opposite
|
|
sideband rejection down to about 150 Hz. It is using 201 coefficients at a sample
|
|
rate of 12000. Still, for some situations it may be desireable to use an IIR
|
|
high pass filter on the input audio.</p>
|
|
|
|
</script>
|
|
<script type="text/x-red" data-template-name="radioCESSB_Z_transmit_F32">
|
|
<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>
|
|
</script>
|
|
|
|
<script type="text/x-red" data-help-name="radioVoiceClipper_F32">
|
|
<!-- ============ radioVoiceClipper_F32 ========= -->
|
|
<h3>Summary</h3>
|
|
<div class=tooltipinfo>
|
|
<p>Applies controlled clipping and filtering for uses such as AM, FM and NBFM.
|
|
This prevents modulation peaks from exceeding a maximum level without increasing the
|
|
spectral width.
|
|
This can increase the power density of the modulation by 3 or more dB. The output
|
|
is ready to be applied to an AM or FM modulator..
|
|
</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>Input Audio Signal</td></tr>
|
|
<tr class=odd><td align=center>Out 0</td><td>Clipped Audio Signal</td></tr>
|
|
</table>
|
|
<h3>Functions</h3>
|
|
<p class=func><span class=keyword>setSampleRate_Hz</span>
|
|
(<strong>float32_t</strong> fs_Hz bitRate);</p>
|
|
<p class=desc>Specifically, this sets the sample rate, in samples per second,
|
|
that is used by the clipper. It also sets other parameters, such as
|
|
decimation ratios and filter cutoff frequencies. Thus this function
|
|
is <strong>required.</strong> Two ranges of sampling rate are currently
|
|
supported. These are 11 to 12 ksps and 44 to 50 ksps. There is no default value
|
|
and the VoiceClipper objects will not run if this function is not called.</p>
|
|
|
|
|
|
<p class=func><span class=keyword>getLevels</span>(<strong>int</strong> what);</p>
|
|
<p class=desc>Returns a pointer to a structure of type levels. This allows
|
|
knowledge of the average and peak levels at both the input and output sides
|
|
of the clipper and overshoot compensator. If what==0 the pointer is returned
|
|
but no updating is done. That is used to setup the process before data is
|
|
available. If what != 0, the contents of the structure are updated and measuring
|
|
is reset. The function levelDataCount() below can be used to set the time
|
|
between updates. The stucture is part of the object and is defined as:
|
|
<pre>
|
|
struct levels {
|
|
float32_t pwr0; // Average power at input
|
|
float32_t peak0; // Peak voltage at input
|
|
float32_t pwr1; // Average power at output
|
|
float32_t peak1; // Peak voltage at output
|
|
uint32_t countP; // Number of averaged samples for pwr0.
|
|
};
|
|
</pre></p>
|
|
|
|
<p class=func><span class=keyword>levelDataCount</span>();</p>
|
|
<p class=desc>Returns an uint32_t with the number of averaged samples
|
|
of the input power. See getLevels() above. The number of output
|
|
samples may differ by an integer factor because of decimation inside
|
|
the object.</p>
|
|
|
|
<p class=func><span class=keyword>setGains</span>(
|
|
<strong>float32_t</strong> gainIn,
|
|
<strong>float32_t</strong> gainCompensate,
|
|
<strong>float32_t</strong> gainOut);</p>
|
|
<p class=desc> These are the controls for the ViceCipper class. gainIn sets
|
|
the amount of clipping by setting the input level to the clipper.
|
|
gainCompensate sets the amount of correction applied to prevent
|
|
overshoot. A value of 1.8 is normally used. gainOut is
|
|
for convenience and sets the drive level to the next block. </p>
|
|
|
|
<h3>Examples</h3>
|
|
<p class=exam>File > Examples > OpenAudio_ArduinoLibrary > VoiceClipper
|
|
</p>
|
|
<p class=exam>File > Examples > OpenAudio_ArduinoLibrary > VoiceClipper12
|
|
</p>
|
|
|
|
<h3>Notes</h3>
|
|
<p>The technical description is in the include file for this class,
|
|
<a href="https://github.com/chipaudette/OpenAudio_ArduinoLibrary/blob/master/radioVoiceClipper_F32.h"
|
|
target="_blank">available from Github</a>
|
|
These should be used to understand the details of the Voice Clipper.
|
|
</p>
|
|
|
|
<p>The first activity for the Voice Clipper is to limit or clip the amplitude of the input signal.
|
|
Internally this always occurs when the magnitude of the input signal exceeds 1.0. This is all done
|
|
with floating point arithmetic so values may exceed 1.0. The input level where this occurs
|
|
depends on the setting for gainIn, described above. The maximum level seen ahead of the clipper
|
|
is measured by getLevels() as described above. One way to control the input to the
|
|
Voice Clipper block is with
|
|
<a href="http://www.janbob.com/electron/OpenAudio_Design_Tool/index.html?info=AudioEffectCompressor2_F32"
|
|
target="_blank">Compressor2 Library block.</a> Note that Compressor2
|
|
is not a clipper, but is rather an automatic gain control that uses look-ahead
|
|
processing to allow gradual gain changes.
|
|
</p>
|
|
|
|
<p>Voice Clipping as implemented here is intended for voice input, and so filters the voice
|
|
to a communications bandwidth of around 3000 Hz.</p>
|
|
|
|
</script>
|
|
<script type="text/x-red" data-template-name="radioCESSBtransmit_F32">
|
|
<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>
|
|
</script>
|
|
|
|
<script type="text/x-red" data-help-name="RadioBFSKModulator_F32">
|
|
<h3>Summary</h3>
|
|
<div class=tooltipinfo>
|
|
<p>Transmits Binary (2-frequency) Frequency Shift Keyed signals (BFSK).
|
|
The data words are supplied by the INO via a 64-word FIFO transmit buffer.
|
|
Optional FIR filtering of the input to the modulator is provided.
|
|
</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>BFSK transmit audio or I-F</td></tr>
|
|
</table>
|
|
<h3>Functions</h3>
|
|
<p class=func><span class=keyword>setBFSK</span>
|
|
(<strong>float32_t</strong> bitRate, <strong>uint16_t</strong> numBits,
|
|
<strong>float32_t</strong> f0, <strong>float32_t</strong> f1);</p>
|
|
<p class=desc>This sets the BFSK modulator parameters. The bitRate is
|
|
obvious, but numBits includes start and stop bits so that to
|
|
transmit 8N1 numBits should be 10.
|
|
The tone frequencies are in Hz and can be any values up to fs/2.
|
|
IMPORTANT: Before calling this initialize function, call any functions
|
|
that set filters.</p>
|
|
|
|
<p class=func><span class=keyword>bufferHasSpace</span>();</p>
|
|
<p class=desc>Returns a bool value true if another data word can be sent. </p>
|
|
|
|
<p class=func><span class=keyword>sendData</span>(<strong>uint32_t</strong> data);</p>
|
|
<p class=desc>Empties the FIFO transmit buffer.</p>
|
|
|
|
<p class=func><span class=keyword>clearBuffer</span>();</p>
|
|
<p class=desc>Clears the send buffer. Does not stop a character being sent. No return value.</p>
|
|
|
|
<p class=func><span class=keyword>amplitude</span>(<strong>float32_t</strong> a);</p>
|
|
<p class=desc>Sets a, the zero-to-peak amplitude of the transmit signal.
|
|
No return value, i.e., void. </p>
|
|
|
|
<p class=func><span class=keyword>setLPF
|
|
</span>(<strong>float32_t*</strong> FIRdata, <strong>float32_t*</strong> FIRcoeff, <strong>uint16_t</strong> numCoeffs);</p>
|
|
<p>This sets output filtering where:
|
|
<pre class="desc">
|
|
float32_t* FIRdata is a pointer to array data storage
|
|
float32_t* firCoeffs is a pointer to array of coefficients
|
|
uint numCoeffs is the number of FIR filter coefficients
|
|
</pre>
|
|
To omit the FIR filter, enter the pointer to the coefficients as NULL.
|
|
<p class=func><span class=keyword>setSampleRate_Hz</span>(<strong>float32_t</strong> sampleRate_Hz)</p>
|
|
<p class=desc>Enter sample rate, as float32_t.
|
|
It applies to this class only.
|
|
</p>
|
|
<h3>Examples</h3>
|
|
<p class=exam>File > Examples > OpenAudio_ArduinoLibrary > BFSK
|
|
</p>
|
|
<p class=exam>File > Examples > OpenAudio_ArduinoLibrary > BFSK_random
|
|
</p>
|
|
<p class=exam>File > Examples > OpenAudio_ArduinoLibrary > BFSK_snr
|
|
</p>
|
|
<h3>Notes</h3>
|
|
<p>This modulator includes a lowpass filter on the input bit data.
|
|
This can be very effective in restricting the bandwidth of the BFSK output.
|
|
This filter can be None (default) or an arbitrary FIR filter.
|
|
</p>
|
|
<p>Parity is not yet implemented.</p>
|
|
</script>
|
|
<script type="text/x-red" data-template-name="RadioBFSKModulator_F32">
|
|
<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>
|
|
</script>
|
|
|
|
|
|
<script type="text/x-red" data-help-name="RadioFT8Modulator_F32">
|
|
<!-- ============ RadioFT8Modulator_F32 ========= -->
|
|
<h3>Summary</h3>
|
|
<div class=tooltipinfo>
|
|
<p>Generates and transmits the eight-tone frequency shift keyed waveform
|
|
for the WSJT mode called FT8.
|
|
The data is provided by an ASCII string. A subset of possible FT8
|
|
messages is supported. All elements of the FT8 waveform are provided
|
|
including spectral confinement.
|
|
</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>FT8 transmit audio or I-F</td></tr>
|
|
</table>
|
|
|
|
<h3>Functions</h3>
|
|
|
|
<p class=func><span class=keyword>setSampleRate_Hz</span>
|
|
(<strong>const float32_t</strong> &fs_Hz);</p>
|
|
<p class=desc>The two values are 48000.0 and 96000.0. </p>
|
|
|
|
<p class=func><span class=keyword>ft8Initialize</span>();</p>
|
|
<p class=desc>This computes several filters that are needed.
|
|
IMPORTANT: Before calling this initialize function, set the audio sampling rate.</p>
|
|
|
|
<p class=func><span class=keyword>FT8TransmitBusy</span>();</p>
|
|
<p class=desc>Returns <strong>bool</strong> true if transmission is still active (a 12.96 second period).
|
|
Returns false if new data can be loaded.</p>
|
|
|
|
<p class=func><span class=keyword>sendData</span>
|
|
(<strong>char*</strong> data, <strong>int16_t</strong> i3, <strong>int16_t</strong> n3,
|
|
<strong>int16_t</strong> specialCase);</p>
|
|
<p class=desc> This defines the data to be sent and also triggers the starting time.
|
|
The parameter data takes a string, such as
|
|
"K1ABC W9XYZ RR73". The descriptors, i3 and n3 are needed to define all possible FT8 messages.
|
|
Because of the current message capability (standard QSO and free text)
|
|
the i3 and n3 are not needed. The specialCase are:
|
|
specialCase==0 is not special at all. It converts the message to
|
|
tones and transmits the 81 tones in FT8 format.
|
|
specialCase==1 allows running of the message-to-tone conversion without
|
|
starting the transmission of tones. Results are in tones[].
|
|
specialCase==2 starts the transmission of tones[]
|
|
without doing a message-to-tone conversion as part of the function call. </p>
|
|
|
|
<p class=func><span class=keyword>amplitude</span>(<strong>float32_t</strong> a);</p>
|
|
<p class=desc>Sets a, the zero-to-peak amplitude of the transmit signal.
|
|
No return value.</p>
|
|
|
|
<p class=func><span class=keyword>frequency</span>(<strong>float32_t</strong> f);</p>
|
|
<p class=desc>Sets f, the base, lowest, frequency of the FT8 waveform.
|
|
The occupied bandwidth is a few Hz below f and about 50 Hz above f.
|
|
No return value.</p>
|
|
|
|
<p class=func><span class=keyword>cancelTransmit</span>();</p>
|
|
<p class=desc>Cancels the current transmission, following the current 128 sample period,
|
|
if active. This, of course, does not control PTT. No return value.</p>
|
|
|
|
|
|
<p class=func><span class=keyword>setSampleRate_Hz</span>(<strong>float32_t</strong> sampleRate_Hz)</p>
|
|
<p class=desc>Enter sample rate, as float32_t.
|
|
It applies to this class only.
|
|
</p>
|
|
|
|
<p class=func><span class=keyword>getPayload</span>()</p>
|
|
<p class=desc>Returns pointer to an array of 10 uint8_t holding the 77 bit payload.
|
|
</p>
|
|
|
|
<p class=func><span class=keyword>getTones</span>()</p>
|
|
<p class=desc>Returns pointer to an array of 81 uint8_t holding the
|
|
tones to be transmitted (0, 7).
|
|
</p>
|
|
|
|
<h3>Examples</h3>
|
|
<p class=exam>File > Examples > OpenAudio_ArduinoLibrary > FT8Transmit</p>
|
|
<p class=exam>File > Examples > OpenAudio_ArduinoLibrary > FT8Transmit7</p>
|
|
<p class=exam>File > Examples > OpenAudio_ArduinoLibrary > FT8Transmit7HP</p>
|
|
|
|
<h3>Notes</h3>
|
|
<p>See the library file radioFT8Modulator.h for much more information,
|
|
references, sample data, and most importantly, credits to the many contributors
|
|
upon which these FT8 library classes are based.</p>
|
|
|
|
<p> This class does not provide true (absolute) clock timing. The sendData() function
|
|
should be called when it is time for a new 15-sec period transmission.
|
|
Audio output will start at the next 128 audio sample period. This
|
|
class does not control push-to-talk (PTT).</p>
|
|
|
|
<p>This runs on T4.x only. The library class could run on T3.6, say, but the
|
|
end-of-receive-period processing would require many compromises to run
|
|
there. The reasonable path is to just use T4.0 or T4.1.</p>
|
|
|
|
</script>
|
|
<script type="text/x-red" data-template-name="RadioFT8Modulator_F32">
|
|
<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>
|
|
</script>
|
|
|
|
|
|
<script type="text/x-red" data-help-name="RadioFT8Demodulator_F32">
|
|
<!-- ============ RadioFT8Demodulator_F32 ========= -->
|
|
<h3>Summary</h3>
|
|
<div class=tooltipinfo>
|
|
<p>Receives audio, containing multiple FT8 signals, and bundles them
|
|
up into 2048 sample float arrays, ready for an FFT. The system audio
|
|
sample rate is decimated to 6400 Hz and high rejection filtering is
|
|
provided with a final audio upper limit at 2800 Hz.
|
|
The full data array is updated and available every 0.16 second
|
|
to support 50% overlap for FFT windowing. The class also includes a
|
|
broad-band power detector for noise measurement.
|
|
</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>FT8 receive audio</td></tr>
|
|
</table>
|
|
|
|
<h3>Functions</h3>
|
|
|
|
<p class=func><span class=keyword>setSampleRate_Hz</span>
|
|
(<strong>const float32_t</strong> &fs_Hz);</p>
|
|
<p class=desc>The two values are 48000.0 and 96000.0. </p>
|
|
|
|
<p class=func><span class=keyword>initialize</span>();</p>
|
|
<p class=desc>This computes several filters that are needed.</p>
|
|
|
|
<p class=func><span class=keyword>getDataPtr</span>()</p>
|
|
<p class=desc>Returns pointer to an array of 2048 float32_t (aka float)
|
|
holding latest received audio data. To support windowed FFT's,
|
|
this data provides 50% overlap. This means that, even though the
|
|
2048 data points require 0.32 seconds to acquire, a new set of data is
|
|
available every 0.16 seconds. </p>
|
|
|
|
<p class=func><span class=keyword>startDataCollect</span>();</p>
|
|
<p class=desc>Begins a 14.7 second data collection period with 194
|
|
2048 float data arrays being made available.
|
|
No return value.</p>
|
|
|
|
<p class=func><span class=keyword>cancelDataCollect</span>();</p>
|
|
<p class=desc>Cancels the 14.7 second data collection period.
|
|
No return value.</p>
|
|
|
|
<p class=func><span class=keyword>receivingData</span>();</p>
|
|
<p class=desc>Returns <strong>bool</strong> true if the 14.7 data collection
|
|
is in progress.</p>
|
|
|
|
<p class=func><span class=keyword>powerAvailable</span>();</p>
|
|
<p class=desc>See the next function. Returns <strong>bool</strong>
|
|
true if the power measurement is available. </p>
|
|
|
|
<p class=func><span class=keyword>readPower</span>();</p>
|
|
<p class=desc>Returns the dB power level <strong>once</strong>
|
|
per 128 samples at the 6.4kHz rate.
|
|
This can be used to provide a noise level measurement when signals are not
|
|
being transmitted. See the receive example listed below.</p>
|
|
|
|
<p>Note that there are other fuctions available to support the W5BAA 128-int
|
|
data transfer. The details are in the radioFT8Demodulator_F32.h file.
|
|
Use of those functions requires compiling with "#define W5BAA_INTERFACE" in
|
|
the .h file.</p>
|
|
|
|
<h3>Examples</h3>
|
|
<p class=exam>File > Examples > OpenAudio_ArduinoLibrary > FT8Receive
|
|
</p>
|
|
|
|
<h3>Notes</h3>
|
|
<p>See the library file radioFT8Demodulator.h for much more information,
|
|
references, sample data, and most importantly, credits to the many contributors
|
|
upon which these FT8 library classes are based.</p>
|
|
|
|
<p> This class does not provide true (absolute) clock timing.
|
|
The startDataCollect() function
|
|
should be called when it is time for a new 15-sec receive period.</p>
|
|
|
|
<p>This runs on T4.x only. The library class could run on T3.6, say, but the
|
|
end-of-receive-period processing would require many compromises to run
|
|
there. The reasonable path is to just use T4.0 or T4.1.</p>
|
|
|
|
<p>The receive example, along with the corresponding transmit examples
|
|
for radioFT8Modulator_F32, are complete basic capabilities, but
|
|
do not serve as a ham radio controller. The
|
|
<a href="https://github.com/WB2CBA/W5BAA-FT8-POCKET-TERMINAL"
|
|
target="_blank">W5BAA Pocket project</a>
|
|
https://github.com/WB2CBA/W5BAA-FT8-POCKET-TERMINAL
|
|
is an example of a complete control app. It does not use this library.</p>
|
|
|
|
</script>
|
|
<script type="text/x-red" data-template-name="RadioFT8Demodulator_F32">
|
|
<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>
|
|
</script>
|
|
|
|
<div>
|
|
<script type="text/x-red" data-help-name="radioModulatedGenerator_F32">
|
|
<!-- ============ radioModulatedGenerator_F32 ========= -->
|
|
<h3>Summary</h3>
|
|
<div class=tooltipinfo>
|
|
<p>A modulator to apply AM, PM or FM to a carrier sine wave. Outputs
|
|
can be single waveform, or a pair of waveforms of I and Q form for
|
|
external quadrature up conversion. The latter includes corrections for
|
|
amplitude and phase errors.
|
|
</p>
|
|
</div>
|
|
<h3>Boards Supported</h3>
|
|
<ul>
|
|
<li>Teensy 3.2
|
|
<li>Teensy 3.5
|
|
<li>Teensy 3.6
|
|
<li>Teensy 4.0
|
|
<li>Teensy 4.1
|
|
</ul>
|
|
<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>AM Modulating Signal</td></tr>
|
|
<tr class=odd><td align=center>In 1</td><td>PM or FM Modulating Signal</td></tr>
|
|
<tr class=odd><td align=center>Out 0</td><td>Single or I Output Signal</td></tr>
|
|
<tr class=odd><td align=center>Out 1</td><td>Q Output Signal</td></tr>
|
|
</table>
|
|
|
|
<h3>Functions</h3>
|
|
<p class=func><span class=keyword>frequency</span>(<strong>float</strong> fCarrier);</p>
|
|
<p class=desc></p>
|
|
<p>Sets the center carrier frequency, in Hz.</p>
|
|
|
|
<p class=func><span class=keyword>amplitude</span>(<strong>float</strong> ampl);</p>
|
|
<p class=desc></p>
|
|
<p>Sets the carrier amplitude level. For AM, the peak output will be greater than this
|
|
level, reaching twice level at 100% modulation.</p>
|
|
|
|
<p class=func><span class=keyword>phase_r</span>(<strong>float</strong> ph);</p>
|
|
<p class=desc></p>
|
|
<p>Sets the carrier starting phase in radians, 0 to 2*pi. Used with multiple
|
|
modulated generators to initialize the relative phase values. Stop interrupts before setting.</p>
|
|
|
|
<p class=func><span class=keyword>doModulation_AM_PM_FM</span>(<strong>bool</strong> doAM, <strong>bool</strong> doPM, <strong>bool</strong> doFM, <strong>bool</strong> bothIQ);</p>
|
|
<p class=desc></p>
|
|
<p>Selects modulation format. PM and FM cannot be used together. Otherwise the selection is flexible.
|
|
For instance, AM and PM can be used together for QAM modulation. bothIQ selects whether there is a single
|
|
modulated output (false) or a pair of quadrature outputs to drive external hardware (true).</p>
|
|
|
|
<p class=func><span class=keyword>phaseQ_I_r(</span>(<strong>float</strong> ph_IQ);</p>
|
|
<p class=desc></p>
|
|
<p>Used with bothIQ==true to set the relative phase of the outputs. The default
|
|
is PI/2 corresponding to 90 degrees. This can correct for phase errors in external hardware.</p>
|
|
|
|
<p class=func><span class=keyword>amplitudeQI(</span>(<strong>float</strong> ampl_IQ);</p>
|
|
<p class=desc></p>
|
|
<p>Used with bothIQ==true to set the relative amplitude of the outputs. The default
|
|
is 1.0. This can correct for amplitude errors in external hardware.</p>
|
|
|
|
<h3>Examples</h3>
|
|
<p class=exam>File > Examples > OpenAudio_ArduinoLibrary > AM_PM_FM.ino
|
|
</p>
|
|
|
|
<h3>Notes</h3><p>For AM, 100% AM modulation corresponds
|
|
an input of -1.0 to 1.0, regardless of the
|
|
carrier amplitude setting. Overmodulation (more that 100%) results in peak
|
|
increases beyond twice amplitude, but full abrupt clipping at the
|
|
bottom zero point. Clipping on the top would be in an external block,
|
|
if desired.</p>
|
|
|
|
<p> <pre class="desc">
|
|
Times: T3.6 update() block of 128 is about 53 microseconds, AM Single output.
|
|
T4.x update() block of 128 is about 20 microseconds AM Single output
|
|
T4.x update() block of 128 is about 35 microseconds AM I + Q outputs
|
|
For T4.x, FM is 1 or 2 microseconds faster than AM.
|
|
</pre>
|
|
|
|
</script>
|
|
<script type="text/x-red" data-template-name="radioModulatedGenerator_F32">>
|
|
<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>
|
|
</script>
|
|
|
|
<div>
|
|
<script type="text/x-red" data-help-name="RadioIQMixer_F32">
|
|
<!-- ============ RadioIQMixer_F32 ========= -->
|
|
<h3>Summary</h3>
|
|
<div class=tooltipinfo>
|
|
<p>This quadrature mixer block is for both transmit and receive.
|
|
It is a basic building block with a pair of mixers along with a sin/cose
|
|
LO going to the mixers at the same frequency, but differing in phase
|
|
by 90 degrees (programmable). The LO's are included
|
|
in the block, but there are no post-mixing filters. Hardware
|
|
phase and amplitude error correction is included. </p>
|
|
</div>
|
|
<h3>Boards Supported</h3>
|
|
<ul>
|
|
<li>Teensy 3.5
|
|
<li>Teensy 3.6
|
|
<li>Teensy 4.0
|
|
<li>Teensy 4.1
|
|
</ul>
|
|
<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 I Signal</td></tr>
|
|
<tr class=odd><td align=center>In 1</td><td>Input Q Signal</td></tr>
|
|
<tr class=odd><td align=center>Out 0</td><td>I In-Phase Out</td></tr>
|
|
<tr class=odd><td align=center>Out 1</td><td>Q Quadrature Output</td></tr>
|
|
</table>
|
|
|
|
<h3>Functions</h3>
|
|
|
|
<p class=func><span class=keyword>frequency</span>(<strong>float</strong> fr);</p>
|
|
<p class=desc>Sets Mixer LO frequency in Hz. The default is 1000 Hz.</p>
|
|
|
|
<p class=func><span class=keyword>iqmPhaseS</span>(<strong>float</strong> ps);</p>
|
|
<p class=desc>This phase comes in the range (0, 2PI radians) keeping with C math functions.
|
|
This function allows multiple mixers to be phase coordinated (stop
|
|
interrupts when setting).</p>
|
|
|
|
<p class=func><span class=keyword>phaseS_C_r</span>(<strong>float</strong> pc);</p>
|
|
<p class=desc> Sets the number of radians that the cosine LO leads the
|
|
sine LO. The default is PI/2 radians. This is used to correct hardware phase unbalance.
|
|
Not changeable if doSimple==true. </p>
|
|
|
|
<p class=func><span class=keyword>amplitudeC</span>(<strong>float</strong> g);</p>
|
|
<p class=desc> Sets the gain, g, for the I channel.
|
|
The Q channel is always 1.0. This is used to correct hardware amplitude unbalance.
|
|
Not changeable if doSimple==true. The default is g=1.0.</p>
|
|
|
|
|
|
<p class=func><span class=keyword>void useTwoChannel</span>(<strong>float32_t</strong> gainOut);</p>
|
|
<p class=desc>
|
|
Channel 0 (left) is the in-phase input I for twoCh true of false. Channel 1 (right) is Q for
|
|
complex 2-channel input (twoCh==true) and not used for twoChannel==false. Caution, never
|
|
use twoCh=false with two inputs. The default is twoCh==false.
|
|
</p>
|
|
|
|
<p class=func><span class=keyword>setGainOut</span>(<strong>float</strong> g);</p>
|
|
<p class=desc> Sets the gain, g, for both the I and Q channels.
|
|
The default value is 1.0. It is available for either doSimple or not doSimple. The reason for this
|
|
function is that, is that the I and Q mixers have a gain of 0.5 for either sideband output. This function
|
|
can bring the net gain of the object to unity by setting gainOut to 2.0f. It can
|
|
also be used as a general gain control.
|
|
</p>
|
|
|
|
<p class=func><span class=keyword>useSimple</span>(<strong>bool</strong> simple);</p>
|
|
<p class=desc>Faster if true, but no phase/amplitude adjustment. Default is doSimple = true.</p>
|
|
|
|
<h3>Examples</h3>
|
|
<p class=exam>File > Examples > OpenAudio_ArduinoLibrary > ReceiverPart1
|
|
</p>
|
|
|
|
<p class=exam>File > Examples > OpenAudio_ArduinoLibrary > ReceiverPart2
|
|
</p>
|
|
|
|
<p class=exam>File > Examples > OpenAudio_ArduinoLibrary > ReceiverSSB
|
|
</p>
|
|
|
|
<p class=exam>File > Examples > OpenAudio_ArduinoLibrary > CESSB
|
|
</p>
|
|
|
|
<h3>Notes</h3>
|
|
<p>There is provision for varying
|
|
the phase between the sine and cosine oscillators. The relative gain in the
|
|
I and Q channels is also programmable. This can be used to correct for errors in the
|
|
response of real hardware.</p>
|
|
|
|
<P>The output levels are 0.5 times the input level, for each sideband. </P>
|
|
|
|
<p>Time: T3.6, For an update of a 128 sample block, doSimple=1, 46 microseconds;
|
|
T4.0, For an update of a 128 sample block, doSimple=1, 20 microseconds</p>
|
|
|
|
</script>
|
|
<script type="text/x-red" data-template-name="RadioIQMixer_F32">>
|
|
<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>
|
|
</script>
|
|
|
|
|
|
<div>
|
|
<script type="text/x-red" data-help-name="radioNoiseBlanker_F32">
|
|
<!-- ============ radioNoiseBlanker_F32 ========= -->
|
|
<h3>Summary</h3>
|
|
<div class=tooltipinfo>
|
|
<p>Looks for wideband impulse noise and cuts off the flow of audio when an impulse
|
|
is detected. A delay in the audio allows anticipation of impulse noise.
|
|
The threshold of impulse detection is adjusted by the averaged
|
|
audio level. Parameters are programmable. Single Path or I-Q.</p>
|
|
</div>
|
|
<h3>Boards Supported</h3>
|
|
<ul>Teensy 3.5
|
|
<li>Teensy 3.6
|
|
<li>Teensy 4.0
|
|
<li>Teensy 4.1
|
|
</ul>
|
|
<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 0</td></tr>
|
|
<tr class=odd><td align=center>In 1</td><td>Input Signal 1 (optional)</td></tr>
|
|
<tr class=odd><td align=center>Out 0</td><td>Output Signal 0 with Blanking</td></tr>
|
|
<tr class=odd><td align=center>Out 1</td><td>Output Sig 1 for Input 1</td></tr>
|
|
</table>
|
|
|
|
<h3>Functions</h3>
|
|
<p class=func><span class=keyword>setNoiseBlanker</span>(<strong>float</strong> threshold, <strong>uint16_t</strong> nAnticipation, <strong>uint16_t</strong> nDecay);</p>
|
|
<p class=desc>Sets the three parameters of the noise blanker.
|
|
The variable threshold adjusts the minimum level considered to be an impulse.
|
|
Anticipation is the number of samples of delay for the signal (1, 125)
|
|
and nDecay is the number of samples that are included in the blanked
|
|
period after the impulse has dropped below the threshold (1, 10).</p>
|
|
|
|
<p class=func><span class=keyword>enable</span>(<strong>bool</strong> e);</p>
|
|
<p class=desc>If e==true the noise blanker is on and if e==false it
|
|
is off (default). This is the on/off switch.</p>
|
|
|
|
<p class=func><span class=keyword>useTwoChannel</span>(<strong>bool</strong> twoCh);</p>
|
|
<p class=desc>If twoCh==true, input 1 becomes active and is blanked at the same
|
|
time as the signal of input 0. This is for I-Q receivers.</p>
|
|
}
|
|
|
|
<h3>Examples</h3>
|
|
<p class=exam>File > Examples > OpenAudio_ArduinoLibrary > TestNoiseBlanker1
|
|
</p>
|
|
|
|
<h3>Notes</h3>
|
|
<p>An intermediate frequency (I-F signal) comes in with occassional
|
|
noise pulses. This block watches for
|
|
the pulses and turns off the I-F while the pulse exists. In order to
|
|
be as smart as possible this looks ahead by a number of samples, nAnticipation.
|
|
Likewise, the I-F is left off for nDecay samples after the pulse ends.
|
|
Various methods could be to be used to "turn off" the I-F,
|
|
including replacement with waveforms.
|
|
As of this initial write, zeros are used in the waveform. </p>
|
|
|
|
<p>A threshold can be adjusted via setNoiseBlanker(). This is compared with the
|
|
average rectified voltage being received. If this is too small, like 1.5
|
|
or 2.0, we will be loosing good signals by blanking. If we set it too high, like 20.0,
|
|
we will not blank noise pulses. Experiments will find a good setting.
|
|
With a sine wave input and no impulse noise, the average rectified signal
|
|
should be about 0.637. To catch the top of that requires a threshold of
|
|
1/0.637 = 1.57. That would seem to be a very minimal threshold setting.</p>
|
|
|
|
</script>
|
|
<script type="text/x-red" data-template-name="radioNoiseBlanker_F32">>
|
|
<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>
|
|
</script>
|
|
|
|
|
|
<div>
|
|
<script type="text/x-red" data-help-name="AudioAnalyzeFFT1024_F32">
|
|
<!-- ============ AudioAnalyzeFFT1024_F32 ========= -->
|
|
<h3>Summary</h3>
|
|
<div class=tooltipinfo>
|
|
<p>Does real input FFT of 1024 points. Output is magnitude
|
|
only in formats of RMS (same as I16 version,
|
|
power or dBFS (full scale). Output can be bin by bin or by a pointer to
|
|
the full output array. Multiple windowing options. Uses half-lenght FFT</p>
|
|
</div>
|
|
<p>March 2021: Streamlined processing and memory useage by going to half-lenght FFT.</p>
|
|
<h3>Boards Supported</h3>
|
|
<ul>Teensy 3.5
|
|
<li>Teensy 3.6
|
|
<li>Teensy 4.0
|
|
<li>Teensy 4.1
|
|
</ul>
|
|
<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</td></tr>
|
|
</table>
|
|
|
|
<h3>Functions</h3>
|
|
<p class=func><span class=keyword>available</span>();</p>
|
|
<p class=desc>returns <strong>bool</strong> true if the FFT is complete,
|
|
otherwise returns false.</p>
|
|
|
|
<p class=func><span class=keyword>read</span>(<strong>int</strong> nBin);</p>
|
|
<p class=desc>Returns the output level for the specified nBin (0, 1023).
|
|
Bin 0 is DC and the bins are spaced at the sampling frequency divided
|
|
by 1024 Hz.</p>
|
|
|
|
<p class=func><span class=keyword>read</span>(<strong>int</strong> nBinFirst, <strong>int</strong> nBinLast);</p>
|
|
<p class=desc>Returns the power sum for the specified range of bins
|
|
numbered (0, 1023). This has the effect of creating a new bin with greater
|
|
width.</p>
|
|
|
|
<p class=func><span class=keyword>windowFunction</span>(<strong>int</strong> win);</p>
|
|
<p class=desc>Sets the windowing function. Instead of calling by number,
|
|
these can be called by the following defined names: </p>
|
|
<pre class="desc">
|
|
AudioWindowNone
|
|
AudioWindowHanning1024 (default)
|
|
AudioWindowBlackmanHarris1024
|
|
</pre>
|
|
|
|
<p class=func><span class=keyword>windowFunction</span>(AudioWindowKaiser1024, <strong>float</strong> kdb);</p>
|
|
<p class=desc>Sets the Kaiser window with the first sidelobe kdb
|
|
below the peak. The sidelobes continue to drop going away from a sine-wave
|
|
carrier. This is a very flexible and useful windowing function. </p>
|
|
|
|
<p class=func><span class=keyword>putWindow</span>(<strong>float</strong> *pWin);</p>
|
|
<p class=desc>Activates an INO provided window of 256 float numbers. This replaces
|
|
any window from WindowFunction(). pWin is a pointer to the window array.
|
|
|
|
<p class=func><span class=keyword>setNAverage</span>(<strong>int</strong> nAverage);</p>
|
|
<p class=desc>Sets the number of output powers that arre averaged for a single data set.
|
|
This is "non-coherent integration," or averaging. nAverage must be at least
|
|
1 with no reasonable upper limit.</p>
|
|
|
|
<p class=func><span class=keyword>getData</span>();</p>
|
|
<p class=desc>Returns a pointer to an array of 512 float outputs. This
|
|
can save 511 calls to read(). The data remains for about 10 milliseconds.</p>
|
|
|
|
<p class=func><span class=keyword>getWindow</span>();</p>
|
|
<p class=desc>Returns a pointer to an array of 1024 float points
|
|
that is the windowing function in use.</p>
|
|
|
|
<p class=func><span class=keyword>setOutputType</span>(<strong>int</strong> nType);</p>
|
|
<p class=desc>Selects the output form:</p>
|
|
<pre class="desc">
|
|
FFT_RMS 0 (default)
|
|
FFT_POWER 1
|
|
FFT_DBFS 2
|
|
</pre>
|
|
|
|
<h3>Examples</h3>
|
|
<p class=exam>File > Examples > OpenAudio_ArduinoLibrary > TestFFT1024
|
|
</p>
|
|
|
|
<h3>Notes</h3>
|
|
<p><strong>Scaling - </strong>
|
|
Full scale for floating point DSP is a nebulous concept. Normally the
|
|
full scale is -1.0 to +1.0. This is an unscaled FFT and for a sine
|
|
wave centered in frequency on a bin and of FS amplitude, the power
|
|
at that center bin will grow by 1024^2/4 = 262144 without windowing.
|
|
Windowing loss cuts this down. The RMS level can grow to sqrt(262144)
|
|
or 512. The dBFS has been scaled to make this max value 0 dBFS by
|
|
removing 54.2 dB. With floating point, the dynamic range is maintained
|
|
no matter how it is scaled, but scaling needs to be considered
|
|
when building the INO.</p>
|
|
|
|
<p>For a 44.1 kHz sample rate, it takes 2903 microseconds (uSec) to
|
|
collect 128 data points. The sum total of all Audio processing
|
|
must be less than this for every update cycle, or overrun will occur
|
|
with severe consequences. For the FFT, the processing time used per
|
|
udate varies cyclicly. The following times are for the most time
|
|
consuming of the updates, i.e., the "max" value.</p>
|
|
<pre class="desc">
|
|
T3.6 Windowed, Power Out, 682 uSec
|
|
T3.6 Windowed, dBFS out, 834 uSec
|
|
T4.0 Windowed, Power Out, 54 uSec
|
|
T4.0 Windowed, dBFS Out, 203 uSec
|
|
</pre>
|
|
<p>This class was improved in March 2021 by using a single 512-point
|
|
FFT to process the 1024 point "real" input to the FFT. This speeds the
|
|
process and also reduces the memory requirements for the FFT. Input and output
|
|
formats and functions remain unchanged.</p>
|
|
</script>
|
|
<script type="text/x-red" data-template-name="AudioAnalyzeFFT1024_F32">>
|
|
<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>
|
|
</script>
|
|
|
|
|
|
<div>
|
|
<script type="text/x-red" data-help-name="AudioAnalyzeFFT256_IQ_F32">
|
|
<!-- ============ AudioAnalyzeFFT256_IQ_F32 ========= -->
|
|
<h3>Summary</h3>
|
|
<div class=tooltipinfo>
|
|
<p>Does complex (I-Q) input FFT of 256 points. Output is magnitude
|
|
only in formats of RMS (same as I16 version,
|
|
power or dBFS (full scale). Output can be bin by bin or by a pointer to
|
|
the output array. Multiple windowing options are available.</p>
|
|
</div>
|
|
<h3>Boards Supported</h3>
|
|
<ul>
|
|
<li>Teensy 3.2</li>
|
|
<li>Teensy 3.5</li>
|
|
<li>Teensy 3.6</li>
|
|
<li>Teensy 4.0</li>
|
|
<li>Teensy 4.1</li>
|
|
</ul>
|
|
|
|
<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>I Input Signal</td></tr>
|
|
<tr class=odd><td align=center>In 1</td><td>Q Input Signal</td></tr>
|
|
<tr class=odd><td align=center>Out 0</td><td>Overlap 0, I Signal</td></tr>
|
|
<tr class=odd><td align=center>Out 1</td><td>Overlap 0, Q Signal</td></tr>
|
|
<tr class=odd><td align=center>Out 2</td><td>Overlap 1, I Signal</td></tr>
|
|
<tr class=odd><td align=center>Out 3</td><td>Overlap 1, Q Signal</td></tr>
|
|
</table>
|
|
<p>Note: Audio outputs are not yet implemented. RMS, Power and dBFS outputs via
|
|
functions, below, are fully implemented.</p>
|
|
|
|
<h3>Functions</h3>
|
|
<p class=func><span class=keyword>available</span>();</p>
|
|
<p class=desc>returns <strong>bool</strong> true if the FFT is complete,
|
|
otherwise returns false.</p>
|
|
|
|
<p class=func><span class=keyword>read</span>(<strong>int</strong> nBin);</p>
|
|
<p class=desc>Returns the output level for the specified nBin (0, 255).
|
|
Bin 0 is DC and the bins are spaced at the sampling frequency divided
|
|
by 256 Hz.</p>
|
|
|
|
<p class=func><span class=keyword>read</span>(<strong>int</strong> nBinFirst, <strong>int</strong> nBinLast);</p>
|
|
<p class=desc>Returns the power sum for the specified range of bins
|
|
numbered (0, 255). This has the effect of creating a new bin with greater
|
|
width.</p>
|
|
|
|
<p class=func><span class=keyword>windowFunction</span>(<strong>int</strong> win);</p>
|
|
<p class=desc>Sets the windowing function. Instead of calling by number,
|
|
these can be called by the following defined names: </p>
|
|
<pre class="desc">
|
|
AudioWindowNone
|
|
AudioWindowHanning256
|
|
AudioWindowBlackmanHarris256
|
|
</pre>
|
|
|
|
<p class=func><span class=keyword>windowFunction</span>(AudioWindowKaiser256, <strong>float</strong> kdb);</p>
|
|
<p class=desc>Sets the Kaiser window with the first sidelobe kdb
|
|
below the peak. The sidelobes continue to drop going away from a sine-wave
|
|
carrier. This is a very flexible and useful windowing function. </p>
|
|
|
|
<p class=func><span class=keyword>putWindow</span>(<strong>float</strong> *pWin);</p>
|
|
<p class=desc>Activates an INO provided window of 256 float numbers. This replaces
|
|
any window from WindowFunction(). pWin is a pointer to the INO provided window array.
|
|
|
|
<p class=func><span class=keyword>getData</span>();</p>
|
|
<p class=desc>Returns a pointer to an array of 256 float outputs. This
|
|
can save 255 calls to read(). The data remains for about 10 milliseconds.</p>
|
|
|
|
<p class=func><span class=keyword>getWindow</span>();</p>
|
|
<p class=desc>Returns a pointer to an array of 256 floating point numbers
|
|
that is the windowing function in use. This is mostly for diagnostics,
|
|
and not normally needed.</p>
|
|
|
|
<p class=func><span class=keyword>setOutputType</span>(<strong>int</strong> nType);</p>
|
|
<p class=desc>Selects the output form, for example, myFFT.setOutputType(FFT_DBFS); The
|
|
options are</p>
|
|
<pre class="desc">
|
|
FFT_RMS
|
|
FFT_POWER
|
|
FFT_DBFS
|
|
</pre>
|
|
|
|
<p class=func><span class=keyword>setNAverage</span>(<strong>int</strong> nAverage);</p>
|
|
<p class=desc>Selects number of FFT outputs that are power averaged before
|
|
becoming available. This "non-coherent integration."</p>
|
|
|
|
<p class=func><span class=keyword>setXAxis</span>(<strong>uint8_t</strong> xAxis);</p>
|
|
<p class=desc>Re arranges the output order of the frequencies corresponding
|
|
to the various bins. The least significant 2 bit are used. For sin input to
|
|
I and cosine input to Q, the following apply:
|
|
<pre class="desc">
|
|
If xAxis=0 f=fs/2 in middle, f=0 on right edge
|
|
If xAxis=1 f=fs/2 in middle, f=0 on left edge
|
|
If xAxis=2 f=fs/2 on left edge, f=0 in middle
|
|
If xAxis=3 f=fs/2 on right edgr, f=0 in middle
|
|
</pre>
|
|
</p>
|
|
|
|
<h3>Examples</h3>
|
|
<p class=exam>File > Examples > OpenAudio_ArduinoLibrary > TestFFT256iq
|
|
</p>
|
|
|
|
<h3>Notes</h3>
|
|
<p><strong>Scaling - </strong>
|
|
Full scale for floating point DSP is a nebulous concept. Normally the
|
|
full scale is -1.0 to +1.0. This is an unscaled FFT and for a sine
|
|
wave centered in frequency on a bin and of FS amplitude, the power
|
|
at that center bin will grow by 256^2/4 = 65536 without windowing.
|
|
Windowing loss cuts this down. The RMS level can grow to sqrt(65536)
|
|
or 256. The dBFS has been scaled to make this max value 0 dBFS by
|
|
removing 42.1 dB. With floating point, the dynamic range is maintained
|
|
no matter how it is scaled, but scaling needs to be considered
|
|
when building the INO.</p>
|
|
|
|
<p>The only block size supported by this FFT is 128 which is the normal
|
|
default block size.</p>
|
|
|
|
<!--
|
|
<p>For a 44.1 kHz sample rate, it takes 2903 microseconds (uSec) to
|
|
collect 128 data points. The sum total of all Audio processing
|
|
must be less than this for every update cycle, or overrun will occur
|
|
with severe consequences. For the FFT, the processing time used per
|
|
udate varies cyclicly. The following times are for the most time
|
|
consuming of the updates, i.e., the "max" value.</p>
|
|
<pre class="desc">
|
|
T3.6 Windowed, RMS out, - uSec max
|
|
T3.6 Windowed, Power Out, - uSec max
|
|
T3.6 Windowed, dBFS out, - uSec max
|
|
No Window saves 60 uSec on T3.6 for any output.
|
|
T4.0 Windowed, RMS Out, - uSec
|
|
</pre>
|
|
-->
|
|
|
|
</script>
|
|
<script type="text/x-red" data-template-name="AudioAnalyzeFFT256_IQ_F32">>
|
|
<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>
|
|
</script>
|
|
|
|
<div>
|
|
<script type="text/x-red" data-help-name="AudioAnalyzeFFT1024_IQ_F32">
|
|
<!-- ============ AudioAnalyzeFFT1024_IQ_F32 ========= -->
|
|
<h3>Summary</h3>
|
|
<div class=tooltipinfo>
|
|
<p>Does complex (I-Q) input FFT of 1024 points. Output is magnitude
|
|
only in formats of RMS (same as I16 version,
|
|
power or dBFS (full scale). Output can be bin by bin or by a pointer to
|
|
the output array. Multiple windowing options are available.</p>
|
|
</div>
|
|
<h3>Boards Supported</h3>
|
|
<ul>
|
|
<li>Teensy 3.5</li>
|
|
<li>Teensy 3.6</li>
|
|
<li>Teensy 4.0</li>
|
|
<li>Teensy 4.1</li>
|
|
</ul>
|
|
|
|
<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>I Input Signal</td></tr>
|
|
<tr class=odd><td align=center>In 1</td><td>Q Input Signal</td></tr>
|
|
<tr class=odd><td align=center>Out 0</td><td>Overlap 0, I Signal</td></tr>
|
|
<tr class=odd><td align=center>Out 1</td><td>Overlap 0, Q Signal</td></tr>
|
|
<tr class=odd><td align=center>Out 2</td><td>Overlap 1, I Signal</td></tr>
|
|
<tr class=odd><td align=center>Out 3</td><td>Overlap 1, Q Signal</td></tr>
|
|
</table>
|
|
<p>Note: Audio outputs are not yet implemented. RMS, Power and dBFS outputs via
|
|
functions, below, are fully implemented.</p>
|
|
|
|
<h3>Functions</h3>
|
|
<p class=func><span class=keyword>available</span>();</p>
|
|
<p class=desc>returns <strong>bool</strong> true if the FFT is complete,
|
|
otherwise returns false.</p>
|
|
|
|
<p class=func><span class=keyword>read</span>(<strong>int</strong> nBin);</p>
|
|
<p class=desc>Returns the output level for the specified nBin (0, 1023).
|
|
Bin 0 is DC and the bins are spaced at the sampling frequency divided
|
|
by 1024 Hz.</p>
|
|
|
|
<p class=func><span class=keyword>read</span>(<strong>int</strong> nBinFirst, <strong>int</strong> nBinLast);</p>
|
|
<p class=desc>Returns the power sum for the specified range of bins
|
|
numbered (0, 1023). This has the effect of creating a new bin with greater
|
|
width.</p>
|
|
|
|
<p class=func><span class=keyword>windowFunction</span>(<strong>int</strong> win);</p>
|
|
<p class=desc>Sets the windowing function. Instead of calling by number,
|
|
these can be called by the following defined names: </p>
|
|
<pre class="desc">
|
|
AudioWindowNone
|
|
AudioWindowHanning1024
|
|
AudioWindowBlackmanHarris1024
|
|
</pre>
|
|
|
|
<p class=func><span class=keyword>windowFunction</span>(AudioWindowKaiser1024, <strong>float</strong> kdb);</p>
|
|
<p class=desc>Sets the Kaiser window with the first sidelobe kdb
|
|
below the peak. The sidelobes continue to drop going away from a sine-wave
|
|
carrier. This is a very flexible and useful windowing function. </p>
|
|
|
|
<p class=func><span class=keyword>putWindow</span>(<strong>float</strong> *pWin);</p>
|
|
<p class=desc>Activates an INO provided window of 1024 float numbers. This replaces
|
|
any window from WindowFunction(). pWin is a pointer to the INO provided window array.
|
|
|
|
<p class=func><span class=keyword>getData</span>();</p>
|
|
<p class=desc>Returns a pointer to an array of 1024 float outputs. This
|
|
can save 255 calls to read(). The data remains for about 10 milliseconds.</p>
|
|
|
|
<p class=func><span class=keyword>getWindow</span>();</p>
|
|
<p class=desc>Returns a pointer to an array of 1024 floating point numbers
|
|
that is the windowing function in use. This is mostly for diagnostics,
|
|
and not normally needed.</p>
|
|
|
|
<p class=func><span class=keyword>setOutputType</span>(<strong>int</strong> nType);</p>
|
|
<p class=desc>Selects the output form, for example, myFFT.setOutputType(FFT_DBFS); The
|
|
options are:
|
|
<pre class="desc">
|
|
FFT_RMS
|
|
FFT_POWER
|
|
FFT_DBFS
|
|
</pre>
|
|
</p>
|
|
|
|
<p class=func><span class=keyword>setNAverage</span>(<strong>int</strong> nAverage);</p>
|
|
<p class=desc>Selects number of FFT outputs that are power averaged before
|
|
becoming available. This "non-coherent integration."</p>
|
|
|
|
<p class=func><span class=keyword>setXAxis</span>(<strong>uint8_t</strong> xAxis);</p>
|
|
<p class=desc>Re arranges the output order of the frequencies corresponding
|
|
to the various bins. The least significant 2 bit are used. For sin input to
|
|
I and cosine input to Q, the following apply:
|
|
<pre class="desc">
|
|
If xAxis=0 f=fs/2 in middle, f=0 on right edge
|
|
If xAxis=1 f=fs/2 in middle, f=0 on left edge
|
|
If xAxis=2 f=fs/2 on left edge, f=0 in middle
|
|
If xAxis=3 f=fs/2 on right edgr, f=0 in middle
|
|
</pre>
|
|
</p>
|
|
|
|
<h3>Examples</h3>
|
|
<p class=exam>File > Examples > OpenAudio_ArduinoLibrary > TestFFT1024iq
|
|
</p>
|
|
|
|
<h3>Notes</h3>
|
|
<p><strong>Scaling - </strong>
|
|
Full scale for floating point DSP is a nebulous concept. Normally the
|
|
full scale is -1.0 to +1.0. This is an unscaled FFT and for a sine
|
|
wave centered in frequency on a bin and of FS amplitude, the power
|
|
at that center bin will grow by 1024^2/4 = 262144 without windowing.
|
|
Windowing loss cuts this down some. The RMS level can grow to sqrt(262144)
|
|
or 512. The dBFS has been scaled to make this max value 0 dBFS by
|
|
removing 54.2 dB. With floating point, the dynamic range is maintained
|
|
no matter how it is scaled, but scaling needs to be considered
|
|
when building the INO.</p>
|
|
|
|
<p>The only block size supported by this FFT is 128 which is the normal
|
|
default block size.</p>
|
|
|
|
<!--
|
|
<p>For a 44.1 kHz sample rate, it takes 2903 microseconds (uSec) to
|
|
collect 128 data points. The sum total of all Audio processing
|
|
must be less than this for every update cycle, or overrun will occur
|
|
with severe consequences. For the FFT, the processing time used per
|
|
udate varies cyclicly. The following times are for the most time
|
|
consuming of the updates, i.e., the "max" value.</p>
|
|
<pre class="desc">
|
|
T3.6 Windowed, RMS out, - uSec max
|
|
T3.6 Windowed, Power Out, - uSec max
|
|
T3.6 Windowed, dBFS out, - uSec max
|
|
No Window saves 60 uSec on T3.6 for any output.
|
|
T4.0 Windowed, RMS Out, - uSec
|
|
</pre>
|
|
-->
|
|
</script>
|
|
<script type="text/x-red" data-template-name="AudioAnalyzeFFT1024_IQ_F32">>
|
|
<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>
|
|
</script>
|
|
|
|
|
|
<div>
|
|
<script type="text/x-red" data-help-name="AudioAnalyzeFFT2048_IQ_F32">
|
|
<!-- ============ AudioAnalyzeFFT2048_IQ_F32 ========= -->
|
|
<h3>Summary</h3>
|
|
<div class=tooltipinfo>
|
|
<p>Does complex (I-Q) input FFT of 2048 points. Output is magnitude
|
|
only in formats of RMS (same as I16 version,
|
|
power or dBFS (full scale). Output can be bin by bin or by a pointer to
|
|
the output array. Multiple windowing options are available.</p>
|
|
</div>
|
|
<h3>Boards Supported</h3>
|
|
<p><strong>Note: Teensy 3.x will NOT compile or run this class.</strong></p>
|
|
<ul>
|
|
<li>Teensy 4.0</li>
|
|
<li>Teensy 4.1</li>
|
|
</ul>
|
|
|
|
<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>I Input Signal</td></tr>
|
|
<tr class=odd><td align=center>In 1</td><td>Q Input Signal</td></tr>
|
|
<tr class=odd><td align=center>Out 0</td><td>Overlap 0, I Signal</td></tr>
|
|
<tr class=odd><td align=center>Out 1</td><td>Overlap 0, Q Signal</td></tr>
|
|
<tr class=odd><td align=center>Out 2</td><td>Overlap 1, I Signal</td></tr>
|
|
<tr class=odd><td align=center>Out 3</td><td>Overlap 1, Q Signal</td></tr>
|
|
</table>
|
|
<p>Note: Audio outputs are not yet implemented. RMS, Power and dBFS outputs via
|
|
functions, below, are fully implemented.</p>
|
|
|
|
<h3>Functions</h3>
|
|
<p class=func><span class=keyword>available</span>();</p>
|
|
<p class=desc>returns <strong>bool</strong> true if the FFT is complete,
|
|
otherwise returns false.</p>
|
|
|
|
<p class=func><span class=keyword>read</span>(<strong>int</strong> nBin);</p>
|
|
<p class=desc>Returns the output level for the specified nBin (0, 2047).
|
|
Bin 0 is DC and the bins are spaced at the sampling frequency divided
|
|
by 2048 Hz.</p>
|
|
|
|
<p class=func><span class=keyword>read</span>(<strong>int</strong> nBinFirst, <strong>int</strong> nBinLast);</p>
|
|
<p class=desc>Returns the power sum for the specified range of bins
|
|
numbered (0, 2047). This has the effect of creating a new bin with greater
|
|
width.</p>
|
|
|
|
<p class=func><span class=keyword>windowFunction</span>(<strong>int</strong> win);</p>
|
|
<p class=desc>Sets the windowing function. Instead of calling by number,
|
|
these can be called by the following defined names: </p>
|
|
<pre class="desc">
|
|
AudioWindowNone
|
|
AudioWindowHanning2048
|
|
AudioWindowBlackmanHarris2048
|
|
</pre>
|
|
|
|
<p class=func><span class=keyword>windowFunction</span>(AudioWindowKaiser2048, <strong>float</strong> kdb);</p>
|
|
<p class=desc>Sets the Kaiser window with the first sidelobe kdb
|
|
below the peak. The sidelobes continue to drop going away from a sine-wave
|
|
carrier. This is a very flexible and useful windowing function. </p>
|
|
|
|
<p class=func><span class=keyword>putWindow</span>(<strong>float</strong> *pWin);</p>
|
|
<p class=desc>Activates an INO provided window of 2048 float numbers. This replaces
|
|
any window from WindowFunction(). pWin is a pointer to the INO provided window array.
|
|
|
|
<p class=func><span class=keyword>getData</span>();</p>
|
|
<p class=desc>Returns a pointer to an array of 2048 float outputs. This
|
|
can save 255 calls to read(). The data remains for about 10 milliseconds.</p>
|
|
|
|
<p class=func><span class=keyword>getWindow</span>();</p>
|
|
<p class=desc>Returns a pointer to an array of 2048 floating point numbers
|
|
that is the windowing function in use. This is mostly for diagnostics,
|
|
and not normally needed.</p>
|
|
|
|
<p class=func><span class=keyword>setOutputType</span>(<strong>int</strong> nType);</p>
|
|
<p class=desc>Selects the output form, for example, myFFT.setOutputType(FFT_DBFS); The
|
|
options are:
|
|
<pre class="desc">
|
|
FFT_RMS
|
|
FFT_POWER
|
|
FFT_DBFS
|
|
</pre>
|
|
</p>
|
|
|
|
<p class=func><span class=keyword>setNAverage</span>(<strong>int</strong> nAverage);</p>
|
|
<p class=desc>Selects number of FFT outputs that are power averaged before
|
|
becoming available. This "non-coherent integration."</p>
|
|
|
|
<p class=func><span class=keyword>setXAxis</span>(<strong>uint8_t</strong> xAxis);</p>
|
|
<p class=desc>Re arranges the output order of the frequencies corresponding
|
|
to the various bins. The least significant 2 bit are used. For sin input to
|
|
I and cosine input to Q, the following apply:
|
|
<pre class="desc">
|
|
If xAxis=0 f=fs/2 in middle, f=0 on right edge
|
|
If xAxis=1 f=fs/2 in middle, f=0 on left edge
|
|
If xAxis=2 f=fs/2 on left edge, f=0 in middle
|
|
If xAxis=3 f=fs/2 on right edgr, f=0 in middle
|
|
</pre>
|
|
</p>
|
|
|
|
<h3>Examples</h3>
|
|
<p class=exam>File > Examples > OpenAudio_ArduinoLibrary > TestFFT2048iq
|
|
</p>
|
|
|
|
<h3>Notes</h3>
|
|
<p><strong>Scaling - </strong>
|
|
Full scale for floating point DSP is a nebulous concept. Normally the
|
|
full scale is -1.0 to +1.0. This is an unscaled FFT and for a sine
|
|
wave centered in frequency on a bin and of FS amplitude, the power
|
|
at that center bin will grow by about a million.
|
|
The dBFS has been scaled to make this max value 0 dBFS by
|
|
removing 60.2 dB. With floating point, the dynamic range is maintained
|
|
no matter how it is scaled, but scaling needs to be considered
|
|
when building the INO.</p>
|
|
|
|
<p>The only block size supported by this FFT is 128 which is the normal
|
|
default block size. Any sampling rate can be supported,
|
|
within maximum available time constraints.</p>
|
|
|
|
<p>For a 44.1 kHz sample rate, it takes 2903 microseconds (uSec) to
|
|
collect 128 data points. The sum total of all Audio processing
|
|
must be less than this for every update cycle, or overrun will occur
|
|
with severe consequences. For the FFT, the processing time used per
|
|
udate varies cyclicly. The Teensy 4.x was measured at 987 microseconds
|
|
per update with windowing and dBFS output. This can probably run with
|
|
96 kHz sample rates, but not 192 kHz.</p>
|
|
</script>
|
|
<script type="text/x-red" data-template-name="AudioAnalyzeFFT2048_IQ_F32">>
|
|
<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>
|
|
</script>
|
|
|
|
|
|
<div>
|
|
<script type="text/x-red" data-help-name="AudioAnalyzeFFT4096_IQ_F32">
|
|
<!-- ============ AudioAnalyzeFFT4096_IQ_F32 ========= -->
|
|
<h3>Summary</h3>
|
|
<div class=tooltipinfo>
|
|
<p>Does complex (I-Q) input FFT of 4096 points. Output is magnitude
|
|
only in formats of RMS, power or dBFS (full scale).
|
|
Output can be bin by bin or by a pointer to
|
|
the output array. Multiple windowing options are available.</p>
|
|
</div>
|
|
<h3>Boards Supported</h3>
|
|
<p><strong>Note: Teensy 3.x will NOT compile or run this class.</strong></p>
|
|
<ul>
|
|
<li>Teensy 4.0</li>
|
|
<li>Teensy 4.1</li>
|
|
</ul>
|
|
|
|
<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>I Input Signal</td></tr>
|
|
<tr class=odd><td align=center>In 1</td><td>Q Input Signal</td></tr>
|
|
</table>
|
|
|
|
<h3>Functions</h3>
|
|
<p class=func><span class=keyword>available</span>();</p>
|
|
<p class=desc>returns <strong>bool</strong> true if the FFT is complete,
|
|
otherwise returns false.</p>
|
|
|
|
<p class=func><span class=keyword>read</span>(<strong>int</strong> nBin);</p>
|
|
<p class=desc>Returns the output level for the specified nBin (0, 4095).
|
|
Bin 0 is DC and the bins are spaced at the sampling frequency divided
|
|
by 4096 Hz.</p>
|
|
|
|
<p class=func><span class=keyword>read</span>(<strong>int</strong> nBinFirst, <strong>int</strong> nBinLast);</p>
|
|
<p class=desc>Returns the power sum for the specified range of bins
|
|
numbered (0, 4095). This has the effect of creating a new bin with greater
|
|
width.</p>
|
|
|
|
<p class=func><span class=keyword>windowFunction</span>(<strong>int</strong> win);</p>
|
|
<p class=desc>Sets the windowing function. Instead of calling by number,
|
|
these can be called by the following defined names: </p>
|
|
<pre class="desc">
|
|
AudioWindowNone
|
|
AudioWindowHanning4096
|
|
AudioWindowBlackmanHarris4096
|
|
</pre>
|
|
|
|
<p class=func><span class=keyword>windowFunction</span>(AudioWindowKaiser4096, <strong>float</strong> kdb);</p>
|
|
<p class=desc>Sets the Kaiser window with the first sidelobe kdb
|
|
below the peak. The sidelobes continue to drop going away from a sine-wave
|
|
carrier. This is a very flexible and useful windowing function. </p>
|
|
|
|
<p class=func><span class=keyword>putWindow</span>(<strong>float</strong> *pWin);</p>
|
|
<p class=desc>Activates an INO provided window of 4096 float numbers. This replaces
|
|
any window from WindowFunction(). pWin is a pointer to the INO provided window array.
|
|
|
|
<p class=func><span class=keyword>getData</span>();</p>
|
|
<p class=desc>Returns a pointer to an array of 4096 float outputs. This
|
|
can save 255 calls to read(). The data remains for about 10 milliseconds.</p>
|
|
|
|
<p class=func><span class=keyword>getWindow</span>();</p>
|
|
<p class=desc>Returns a pointer to an array of 4096 floating point numbers
|
|
that is the windowing function in use. This is mostly for diagnostics,
|
|
and not normally needed.</p>
|
|
|
|
<p class=func><span class=keyword>setOutputType</span>(<strong>int</strong> nType);</p>
|
|
<p class=desc>Selects the output form, for example, myFFT.setOutputType(FFT_DBFS); The
|
|
options are:
|
|
<pre class="desc">
|
|
FFT_RMS
|
|
FFT_POWER
|
|
FFT_DBFS
|
|
</pre>
|
|
</p>
|
|
|
|
<p class=func><span class=keyword>setNAverage</span>(<strong>int</strong> nAverage);</p>
|
|
<p class=desc>Selects number of FFT outputs that are power averaged before
|
|
becoming available. This "non-coherent integration."</p>
|
|
|
|
<p class=func><span class=keyword>setXAxis</span>(<strong>uint8_t</strong> xAxis);</p>
|
|
<p class=desc>Re arranges the output order of the frequencies corresponding
|
|
to the various bins. The least significant 2 bit are used. For sin input to
|
|
I and cosine input to Q, the following apply:
|
|
<pre class="desc">
|
|
If xAxis=0 f=fs/2 in middle, f=0 on right edge
|
|
If xAxis=1 f=fs/2 in middle, f=0 on left edge
|
|
If xAxis=2 f=fs/2 on left edge, f=0 in middle
|
|
If xAxis=3 f=fs/2 on right edgr, f=0 in middle
|
|
</pre>
|
|
</p>
|
|
|
|
<h3>Examples</h3>
|
|
<p class=exam>File > Examples > OpenAudio_ArduinoLibrary > TestFFT4096iq
|
|
</p>
|
|
|
|
<h3>Notes</h3>
|
|
<p><strong>Memory needs - </strong>As FFTs get bigger they need more memory. This
|
|
4096 point FFT needs 64 F32 memories. Be sure to allocate more than this
|
|
in your INO sketch. In addition, at linking time, 98 kByte of RAM is added.
|
|
The T4.x can support this, but it is a major memory user. </p>
|
|
|
|
<p><strong>Scaling - </strong>
|
|
Full scale for floating point DSP is a nebulous concept. Normally the
|
|
full scale is -1.0 to +1.0. This is an unscaled FFT and for a sine
|
|
wave centered in frequency on a bin and of FS amplitude, the power
|
|
at that center bin will grow by about a million.
|
|
The dBFS has been scaled to make this max value 0 dBFS by
|
|
removing 66.2 dB. With floating point, the dynamic range is maintained
|
|
no matter how it is scaled, but scaling needs to be considered
|
|
when building the INO.</p>
|
|
|
|
<p>The only block size supported by this FFT is 128 which is the normal
|
|
default block size. Any sampling rate can be supported,
|
|
within maximum available time constraints.</p>
|
|
|
|
<p>For a 44.1 kHz sample rate, it takes 2903 microseconds (uSec) to
|
|
collect 128 data points. The sum total of all Audio processing
|
|
must be less than this for every update cycle, or overrun will occur
|
|
with severe consequences. For the FFT, the processing time used per
|
|
udate varies cyclicly. The Teensy 4.x was measured at 710 microseconds
|
|
per update with windowing and dBFS output. This can run with
|
|
96 kHz sample rates, but not 192 kHz. By using FFT_POWER output the maximum
|
|
processor time per update() is only 510 microseconds and, depending on other
|
|
processing, 192 kHz sample rate could be possible.</p>
|
|
</script>
|
|
<script type="text/x-red" data-template-name="AudioAnalyzeFFT4096_IQ_F32">>
|
|
<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>
|
|
</script>
|
|
|
|
<div>
|
|
<script type="text/x-red" data-help-name="AudioAnalyzeFFT4096_IQem_F32">
|
|
<!-- ============ AudioAnalyzeFFT4096_IQem_F32 ========= -->
|
|
<h3>Summary</h3>
|
|
<div class=tooltipinfo>
|
|
<p>Does complex (I-Q) input FFT of 4096 points. Output is magnitude
|
|
only in formats of RMS, power or dBFS (full scale).
|
|
Output can be bin by bin. Multiple windowing options are available.
|
|
This EM version obtains all memory arrays from the INO.</p>
|
|
</div>
|
|
<p><strong>As of 20 Feb 2022 this is Beta Test and changes may occur in the structure of the calls.</strong></p>
|
|
<h3>Boards Supported</h3>
|
|
<p><strong>Note: Teensy 3.x will NOT compile or run this class.</strong></p>
|
|
<ul>
|
|
<li>Teensy 4.0</li>
|
|
<li>Teensy 4.1</li>
|
|
</ul>
|
|
|
|
<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>I Input Signal</td></tr>
|
|
<tr class=odd><td align=center>In 1</td><td>Q Input Signal</td></tr>
|
|
</table>
|
|
|
|
<h3>Functions</h3>
|
|
<p class=func><span class=keyword>available</span>();</p>
|
|
<p class=desc>returns <strong>bool</strong> true if the FFT is complete,
|
|
otherwise returns false.</p>
|
|
|
|
<p class=func><span class=keyword>read</span>(<strong>int</strong> nBin);</p>
|
|
<p class=desc>Returns the output level for the specified nBin (0, 4095).
|
|
Bin 0 is DC and the bins are spaced at the sampling frequency divided
|
|
by 4096 in Hz.</p>
|
|
|
|
<p class=func><span class=keyword>read</span>(<strong>int</strong> nBinFirst, <strong>int</strong> nBinLast);</p>
|
|
<p class=desc>Returns the power sum for the specified range of bins
|
|
numbered (0, 4095). This has the effect of creating a new bin with greater
|
|
width.</p>
|
|
|
|
<p class=func><span class=keyword>windowFunction</span>(<strong>int</strong> win);</p>
|
|
<p class=desc>Sets the windowing function. Instead of calling by number,
|
|
these can be called by the following defined names: </p>
|
|
<pre class="desc">
|
|
AudioWindowNone
|
|
AudioWindowHanning4096
|
|
AudioWindowBlackmanHarris4096
|
|
</pre>
|
|
|
|
<p class=func><span class=keyword>windowFunction</span>(AudioWindowKaiser4096, <strong>float</strong> kdb);</p>
|
|
<p class=desc>Sets the Kaiser window with the first sidelobe kdb
|
|
below the peak. The sidelobes continue to drop going away from a sine-wave
|
|
carrier. This is a very flexible and useful windowing function. </p>
|
|
|
|
<p class=func><span class=keyword>setOutputType</span>(<strong>int</strong> nType);</p>
|
|
<p class=desc>Selects the output form, for example, myFFT.setOutputType(FFT_DBFS); The
|
|
options are:
|
|
<pre class="desc">
|
|
FFT_RMS
|
|
FFT_POWER
|
|
FFT_DBFS
|
|
</pre>
|
|
</p>
|
|
|
|
<p class=func><span class=keyword>setNAverage</span>(<strong>int</strong> nAverage);</p>
|
|
<p class=desc>Selects number of FFT outputs that are power averaged before
|
|
becoming available. This "non-coherent integration."</p>
|
|
|
|
<p class=func><span class=keyword>setXAxis</span>(<strong>uint8_t</strong> xAxis);</p>
|
|
<p class=desc>Re arranges the output order of the frequencies corresponding
|
|
to the various bins. The least significant 2 bit are used. For sin input to
|
|
I and cosine input to Q, the following apply:
|
|
<pre class="desc">
|
|
If xAxis=0 f=0 in middle, f=fs/2 on left edge
|
|
If xAxis=1 f=0 in middle, f=fs/2 on right edge
|
|
If xAxis=2 f=0 on right edge, f=fs/2 in middle
|
|
If xAxis=3 f=0 on left edge, f=fs/2 in middle
|
|
</pre>
|
|
</p>
|
|
|
|
<h3>Examples</h3>
|
|
<p class=exam>File > Examples > OpenAudio_ArduinoLibrary > TestFFT4096iqEM
|
|
</p>
|
|
|
|
<h3>Notes</h3>
|
|
<p><strong>Memory needs - </strong>As FFTs get bigger they need more memory. This
|
|
4096 point FFT needs 64 F32 memories. Be sure to allocate more than this
|
|
in your INO sketch. In addition, at linking time, 58 kByte of .INO supplied
|
|
RAM is added without use of power averaging and 74 kBytes if it is used.
|
|
The T4.x can support this, but it is a major memory user. </p>
|
|
|
|
<p><strong>Scaling - </strong>
|
|
Full scale for floating point DSP is a nebulous concept. Normally the
|
|
full scale is -1.0 to +1.0. This is an unscaled FFT and for a sine
|
|
wave centered in frequency on a bin and of FS amplitude, the power
|
|
at that center bin will grow by about a million.
|
|
The dBFS has been scaled to make this max value 0 dBFS by
|
|
removing 66.2 dB. With floating point, the dynamic range is maintained
|
|
no matter how it is scaled, but scaling needs to be considered
|
|
when building the INO.</p>
|
|
|
|
<p>The only block size supported by this FFT is 128 which is the normal
|
|
default block size. Any sampling rate can be supported,
|
|
within maximum available time constraints.</p>
|
|
|
|
<p>For a 44.1 kHz sample rate, it takes 2903 microseconds (uSec) to
|
|
collect 128 data points. The sum total of all Audio processing
|
|
must be less than this for every update cycle, or overrun will occur
|
|
with severe consequences. For the FFT, the processing time used per
|
|
udate varies cyclicly. The Teensy 4.x was measured at 710 microseconds
|
|
per update with windowing and dBFS output. This can run with
|
|
96 kHz sample rates, but not 192 kHz. By using FFT_POWER output the maximum
|
|
processor time per update() is only 510 microseconds and, depending on other
|
|
processing, 192 kHz sample rate could be possible.</p>
|
|
</script>
|
|
<script type="text/x-red" data-template-name="AudioAnalyzeFFT4096em_IQ_F32">>
|
|
<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>
|
|
</script>
|
|
|
|
|
|
|
|
<div>
|
|
<script type="text/x-red" data-help-name="AudioAnalyzeToneDetect_F32">
|
|
<!-- ============ AudioAnalyzeToneDetect_F32 ========= -->
|
|
<h3>Summary</h3>
|
|
<div class=tooltipinfo>
|
|
<p>Parallels the Teensy Audio class that detects sine wave tones. Uses the Goertzel
|
|
algorithm and has programmable tone detection time.</p>
|
|
</div>
|
|
<h3>Boards Supported</h3>
|
|
<ul>
|
|
<li>Teensy 3.2</li>
|
|
<li>Teensy 3.5</li>
|
|
<li>Teensy 3.6</li>
|
|
<li>Teensy 4.0</li>
|
|
<li>Teensy 4.1</li>
|
|
</ul>
|
|
<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>I Input Signal</td></tr>
|
|
</table>
|
|
|
|
<h3>Functions</h3>
|
|
<p class=func><span class=keyword>frequency</span>(<strong>float</strong> freq, <strong>int</strong> cycles);</p>
|
|
<p class=desc>Sets the frequency fr for tone detection, in Hz, and the number of cycles to be analyzed.</p>
|
|
|
|
<p class=func><span class=keyword>setGain</span>(<strong>float</strong> gain);</p>
|
|
<p class=desc>Sets the voltage gain to equalize multiple toneDetect's such as in DTMF (Mar 2023).</p>
|
|
|
|
<p class=func><span class=keyword>available</span>();</p>
|
|
<p class=desc>returns <strong>bool</strong> true if the tone detection is complete,
|
|
otherwise returns false.</p>
|
|
|
|
<p class=func><span class=keyword>read</span>();</p>
|
|
<p class=desc>Returns the output rms level.</p>
|
|
|
|
<p class=func><span class=keyword>threshold</span>(<strong>float</strong> thresh);</p>
|
|
<p class=desc>Sets the threshold for the bool() function. Range of 0.0 to 1.0.</p>
|
|
|
|
<p class=func><span class=keyword>bool</span>();</p>
|
|
<p class=desc>Returns true if rms level is above threshold..</p>
|
|
|
|
<h3>Examples</h3>
|
|
<p class=exam>File > Examples > OpenAudio_ArduinoLibrary > ToneDetect1
|
|
</p>
|
|
|
|
<h3>Notes</h3>
|
|
|
|
</script>
|
|
<script type="text/x-red" data-template-name="AudioAnalyzeToneDetect_F32">>
|
|
<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>
|
|
</script>
|
|
|
|
<div>
|
|
<script type="text/x-red" data-help-name="analyze_CTCSS_F32">
|
|
<!-- ============ analyze_CTCSS_F32 ========= -->
|
|
<h3>Summary</h3>
|
|
<div class=tooltipinfo>
|
|
<p>Specific to the CTCSS sub-audible tone detection. Uses the Goertzel
|
|
algorithm, can be programmed for any tone in the 67 to 254 Hz range.
|
|
See analyze_CTCSS_F32.h for much information.
|
|
</p>
|
|
</div>
|
|
<h3>Boards Supported</h3>
|
|
<ul>
|
|
<li>Teensy 3.2</li>
|
|
<li>Teensy 3.5</li>
|
|
<li>Teensy 3.6</li>
|
|
<li>Teensy 4.0</li>
|
|
<li>Teensy 4.1</li>
|
|
</ul>
|
|
<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>I Input Signal</td></tr>
|
|
<tr class=odd><td align=center>Out 0</td><td>O Output Signal</td></tr>
|
|
</table>
|
|
|
|
<h3>Functions</h3>
|
|
<p class=func><span class=keyword>initCTCSS</span>(<strong>void</strong>);</p>
|
|
<p class=desc>Run this to initialize the CTCSS tone detector This function is <strong>required.</strong>
|
|
|
|
<p class=func><span class=keyword>frequency</span>(<strong>float</strong> freq, <strong>int</strong> tMeas);</p>
|
|
<p class=desc>Sets the frequency freq for tone detection, in Hz between
|
|
67.0 and 254.1 Hz, and the number of milliseconds to be analyzed. The defaults are
|
|
103.5 Hz and 300 milliseconds. The parameter tMeas is optional.</p>
|
|
|
|
<p class=func><span class=keyword>readTonePower</span>(<strong>void</strong>);</p>
|
|
<p class=desc>Returns the power measured for the narrow-band Goertzel tone filter as a <strong>float</strong>.</p>
|
|
|
|
<p class=func><span class=keyword>readRefPower</span>(<strong>void</strong>);</p>
|
|
<p class=desc>Returns the power measured for the 67 to 254 Hz filter as a <strong>float</strong>. The
|
|
tone frequency is notched out for this measurement.</p>
|
|
|
|
|
|
<p class=func><span class=keyword>readTonePresent</span>(<strong>uint16_t</strong> what);</p>
|
|
<p class=desc>Returns a <strong>bool</strong> true or false to indicate whether thecurrent reading
|
|
is above or below the threshold condition set by "what". Values for <strong>uint16_t</strong>
|
|
parameter "what" are the following pre-defined values:</p>
|
|
<pre class="desc">
|
|
isAbsThreshold
|
|
isRelThreshold
|
|
isBothThreshold
|
|
</pre>
|
|
|
|
<p class=func><span class=keyword>thresholds</span>(<strong>float</strong> levelAbs, <strong>float</strong> levelRel);</p>
|
|
<p class=desc>The parameter levelAbs sets the threshold for comparing pTone with to estimate the presence
|
|
of a CTCSS tone. The parameter levelRel sets a similar threshold on the quotient PowerTone/PowerRef.
|
|
Setting either threshold to 0.0f disables that threshold test.</p>
|
|
|
|
<p class=func><span class=keyword>available</span>(<strong>void</strong>);</p>
|
|
<p class=desc>returns <strong>bool</strong> true if the tone detection is complete,
|
|
otherwise returns false.</p>
|
|
|
|
<p class=func><span class=keyword>setCTCSS_BP</span>(<strong>float*</strong> filterCoeffs);</p>
|
|
<p class=desc>This function sets the IIR coefficients for the 67 to 254 Hz bandpass filter.
|
|
Set filterCoeffs to NULL to use pre-determined coefficients for 44, 48,96 or 100 KHz.
|
|
Alternatively build your own using info in analyze_CTCSS_F32.h. </p>
|
|
|
|
<h3>Examples</h3>
|
|
<p class=exam>File > Examples > OpenAudio_ArduinoLibrary > ToneDetect3
|
|
</p>
|
|
|
|
<h3>Notes</h3>
|
|
<p>Two outputs are available, TonePower and RefPower. TonePower is the output
|
|
of the Goertzel sharply tuned filter and is the conventional CTCSS output
|
|
that is compared to a threshold. RefPower measures the power in the entire
|
|
67 to 254 Hz sub-audible band, except at the tone frequency. </p>
|
|
|
|
<p>Measurements are repeated every tMeas milliseconds, automatically
|
|
and decisions of tone presence are updated.</p>
|
|
|
|
<p>Each update of an 128-input block takes about 42 uSec on a Teensy 3.6.</p>
|
|
</script>
|
|
<script type="text/x-red" data-template-name="analyze_CTCSS_F32">>
|
|
<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>
|
|
</script>
|
|
<!-- ============ AudioAnalyzePeak_F32 ========= -->
|
|
<script type="text/x-red" data-help-name="AudioAnalyzePeak_F32">
|
|
<h3>Summary</h3>
|
|
<div class=tooltipinfo>
|
|
<p>Track the signal peak amplitude. Very useful for simple
|
|
audio level response projects, and general troubleshooting.
|
|
Almost same class as in Teensy Library but this uses F32 floating point audio input.</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 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 amplitude value since the last read.
|
|
</p>
|
|
<p class=func><span class=keyword>readPeakToPeak</span>();</p>
|
|
<p class=desc>Read the highest peak-to-peak amplitude since the last read.
|
|
</p>
|
|
<h3>Examples</h3>
|
|
<p class=exam>File > Examples > OpenAudio_ArduinoLibrary > AudioTestPeakRMS
|
|
</p>
|
|
|
|
<h3>Notes</h3>
|
|
<p>With floating point, F32, audio, there is generally no maximum level that
|
|
represents full scale, as there is with Teensy Audio I16. The
|
|
exception is at the input and output points where there is
|
|
an interface with an integer device. The F32 scaling at these points is set to
|
|
-1.0 and +1.0 corresponding to I16 -32768 and 32767.</p>
|
|
</script>
|
|
<script type="text/x-red" data-template-name="AudioAnalyzePeak_F32">
|
|
<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>
|
|
</script>
|
|
|
|
<!-- ============ AudioAnalyzeRMS_F32 ========= -->
|
|
<script type="text/x-red" data-help-name="AudioAnalyzeRMS_F32">
|
|
<h3>Summary</h3>
|
|
<div class=tooltipinfo>
|
|
<p>Track the signal RMS amplitude. Useful for
|
|
audio level response projects, and general troubleshooting.
|
|
Almost same class as in Teensy Library but this uses F32 floating point audio input.</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 analyze</td></tr>
|
|
</table>
|
|
<h3>Functions</h3>
|
|
<p class=func><span class=keyword>available</span>();</p>
|
|
<p class=desc>Returns true if new RMS data is available.
|
|
</p>
|
|
<p class=func><span class=keyword>read</span>();</p>
|
|
<p class=desc>Read the new RMS value.
|
|
|
|
</p>
|
|
<h3>Examples</h3>
|
|
<p class=exam>File > Examples > OpenAudio_ArduinoLibrary > AudioTestPeakRMS
|
|
</p>
|
|
<h3>Notes</h3>
|
|
<p>With floating point, F32, audio, there is generally no maximum level that
|
|
represents full scale, as there is with Teensy Audio I16. The
|
|
exception is at the input and output points where there is
|
|
an interface with an integer device. The F32 scaling at these points is set to
|
|
-1.0 and +1.0 corresponding to I16 -32768 and 32767.</p>
|
|
</script>
|
|
<script type="text/x-red" data-template-name="AudioAnalyzeRMS_F32">
|
|
<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>
|
|
</script>
|
|
|
|
|
|
<!-- ========== AudioControlSGTL5000 ============= -->
|
|
<script type="text/x-red" data-help-name="AudioControlSGTL5000">
|
|
<h3>Summary</h3>
|
|
<div class=tooltipinfo>
|
|
<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>
|
|
</div>
|
|
<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. This
|
|
<a href="http://openaudio.blogspot.com/2017/03/teensy-audio-board-self-noise.html">may
|
|
reduce noise</a> in some cases.
|
|
</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 graceful
|
|
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>
|
|
<p class=func><span class=keyword>dacVolumeRamp</span>();</p>
|
|
<p class=desc>Enable graceful volume ramping. The dacVolume adjusts gradually using
|
|
an exponential curve. Pops or loud clicks are avoided when making large
|
|
changes in volume level.
|
|
</p>
|
|
<p class=func><span class=keyword>dacVolumeRampLinear</span>();</p>
|
|
<p class=desc>Enable faster volume ramping. A slight click may be heard during a
|
|
large volume change.
|
|
</p>
|
|
<p class=func><span class=keyword>dacVolumeRampDisable</span>();</p>
|
|
<p class=desc>Do not use any gradual ramping. The zero cross feature still helps
|
|
for small changes, but large volume changes may produce a pop or click.
|
|
</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 Teensy Audio and OpenAudio_ArduinoLibrary (F32 floating point)
|
|
library's examples use this object. These examples
|
|
for the Teensy Audio Library 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>
|
|
<p class=exam>File > Examples > Audio > HardwareTesting > SGTL5000 > VolumeRamp
|
|
</p>
|
|
|
|
<h3>Notes</h3>
|
|
</script>
|
|
<script type="text/x-red" data-template-name="AudioControlSGTL5000">
|
|
<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>
|
|
</script>
|
|
|
|
<script type="text/x-red" data-help-name="AudioControlWM8731">
|
|
<h3>Summary</h3>
|
|
<div class=tooltipinfo>
|
|
<p>Control a WM8731 chip in slave mode, where it receives all clocks from Teensy</p>
|
|
</div>
|
|
<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>Turn on the WS8731.
|
|
</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>Set the headphone volume level. Range is 0 to 1.0.
|
|
</p>
|
|
<p class=func><span class=keyword>inputLevel</span>(level);</p>
|
|
<p class=desc>Adjust the line level input gain. Range is 0 to 1.0.
|
|
</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>
|
|
<!--
|
|
<h3>Examples</h3>
|
|
<p class=exam>File > Examples > Audio >
|
|
</p>
|
|
-->
|
|
<h3>Notes</h3>
|
|
<p></p>
|
|
</script>
|
|
<script type="text/x-red" data-template-name="AudioControlWM8731">
|
|
<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>
|
|
</script>
|
|
|
|
<script type="text/x-red" data-help-name="AudioControlWM8731master">
|
|
<h3>Summary</h3>
|
|
<div class=tooltipinfo>
|
|
<p>Control a WM8731 chip in master mode, where it controls all I2S timing.</p>
|
|
</div>
|
|
<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>Turn on the WS8731, in I2S Master mode. I2S slave mode
|
|
communication must be used by Teensy.
|
|
</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>Set the headphone volume level. Range is 0 to 1.0.
|
|
</p>
|
|
<p class=func><span class=keyword>inputLevel</span>(level);</p>
|
|
<p class=desc>Adjust the line level input gain. Range is 0 to 1.0.
|
|
</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>
|
|
<h3>Examples</h3>
|
|
<p class=exam>File > Examples > Audio > HardwareTesting > WM8731MikroSine
|
|
</p>
|
|
<h3>Notes</h3>
|
|
<p>The WM8731 will implement a sample rate of its crystal frequency divided by 256.
|
|
To get the 44.1 kHz sample rate the Teensy Audio Library expects, an
|
|
11.2896 MHz crystal should be used.
|
|
</p>
|
|
</script>
|
|
<script type="text/x-red" data-template-name="AudioControlWM8731master">
|
|
<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>
|
|
</script>
|
|
|
|
<script type="text/x-red" data-help-name="AudioControlAK4558">
|
|
<h3>Summary</h3>
|
|
<div class=tooltipinfo>
|
|
<p>Control the AK4558 chip on the <a href="https://hackaday.io/project/8567-hifi-audio-codec-module" target="_blank">HiFi Audio CODEC Module</a>
|
|
in slave mode, where the Teensy controls all I2S timing.</p>
|
|
</div>
|
|
<h3>Audio Connections</h3>
|
|
<p>This object has no audio inputs or outputs. Separate I2S objects
|
|
are used to send and receive audio data.
|
|
</p>
|
|
<h3>Functions</h3>
|
|
<p class=func><span class=keyword>enable</span>();</p>
|
|
<p class=desc>Enables the CODEC to work with 44.1 KHz - 16 bit data. This function does not enable the ADC/DAC modules.
|
|
</p>
|
|
<p class=func><span class=keyword>enableIn</span>();</p>
|
|
<p class=desc>Enables the ADC module.
|
|
</p>
|
|
<p class=func><span class=keyword>enableOut</span>();</p>
|
|
<p class=desc>Enables the DAC module.
|
|
</p>
|
|
<p class=func><span class=keyword>disable</span>();</p>
|
|
<p class=desc>Disables the ADC and the DAC modules.
|
|
</p>
|
|
<p class=func><span class=keyword>disableIn</span>();</p>
|
|
<p class=desc>Disable the ADC module.
|
|
</p>
|
|
<p class=func><span class=keyword>disableOut</span>();</p>
|
|
<p class=desc>Disable the DAC module.
|
|
</p>
|
|
<p class=func><span class=keyword>volume</span>(level);</p>
|
|
<p class=desc>Accepts a float in range 0.0-1.0 and sets the line output volume accordingly.
|
|
</p>
|
|
<p class=func><span class=keyword>volumeLeft</span>(level);</p>
|
|
<p class=desc>Accepts a float in range 0.0-1.0 and sets the left line output volume accordingly.
|
|
</p>
|
|
<p class=func><span class=keyword>volumeRight</span>(level);</p>
|
|
<p class=desc>Accepts a float in range 0.0-1.0 and sets the right line output volume accordingly.
|
|
</p>
|
|
<p class=func><span class=keyword>inputLevel</span>(level);</p>
|
|
<p class=desc>NOT SUPPORTED BY THE AK4558
|
|
</p>
|
|
<p class=func><span class=keyword>inputSelect</span>(input);</p>
|
|
<p class=desc>not implemented yet
|
|
</p>
|
|
<h3>Examples</h3>
|
|
<p class=exam>File > Examples > Audio > HardwareTesting > AK4558 > PassthroughTest
|
|
</p>
|
|
<p class=exam>File > Examples > Audio > HardwareTesting > AK4558 > SineOutTest
|
|
</p>
|
|
<h3>Notes</h3>
|
|
<p>TODO: Implement inputSelect() function to enable mono left, mono right, stereo operation.</p>
|
|
<p>TODO: Implement ADC and DAC filters control.</p>
|
|
<p>TODO: Implement DAC level attenuator attack rate modifier.</p>
|
|
</script>
|
|
<script type="text/x-red" data-template-name="AudioControlAK4558">
|
|
<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>
|
|
</script>
|
|
|
|
<script type="text/x-red" data-help-name="AudioControlCS4272">
|
|
<h3>Summary</h3>
|
|
<div class=tooltipinfo>
|
|
<p>Control the CS4272 chip on the <a href="https://hackaday.io/project/5912-teensy-super-audio-board" target="_blank">Super Audio Board</a>.
|
|
</p>
|
|
<p>TODO: does this control object put the CS4272 into I2S master or slave mode</p>
|
|
</div>
|
|
<h3>Audio Connections</h3>
|
|
<p>This object has no audio inputs or outputs. Separate I2S objects
|
|
are used to send and receive audio data.
|
|
</p>
|
|
<h3>Functions</h3>
|
|
<p class=func><span class=keyword>enable</span>();</p>
|
|
<p class=desc>Enables the CODEC to work with 44.1 KHz - 16 bit data. This function does not enable the ADC/DAC modules.
|
|
</p>
|
|
<p class=func><span class=keyword>volume</span>(vol);</p>
|
|
<p class=desc>Set the volume level. Range is 0 to 1.0.
|
|
</p>
|
|
<p class=func><span class=keyword>volume</span>(left, right);</p>
|
|
<p class=desc>Set the volume level. Range is 0 to 1.0.
|
|
</p>
|
|
<p class=func><span class=keyword>dacVolume</span>(vol);</p>
|
|
<p class=desc>Set the volume level. Range is 0 to 1.0. TODO: what's the
|
|
distinction between volume() and dacVolume()?
|
|
</p>
|
|
<p class=func><span class=keyword>dacVolume</span>(left, right);</p>
|
|
<p class=desc>Set the volume level. Range is 0 to 1.0.
|
|
</p>
|
|
|
|
<p class=func><span class=keyword>muteOutput</span>();</p>
|
|
<p class=desc>TODO: description
|
|
</p>
|
|
<p class=func><span class=keyword>unmuteOutput</span>();</p>
|
|
<p class=desc>TODO: description
|
|
</p>
|
|
<p class=func><span class=keyword>muteInput</span>();</p>
|
|
<p class=desc>TODO: description
|
|
</p>
|
|
<p class=func><span class=keyword>unmuteInput</span>();</p>
|
|
<p class=desc>TODO: description
|
|
</p>
|
|
<p class=func><span class=keyword>enableDither</span>();</p>
|
|
<p class=desc>TODO: description
|
|
</p>
|
|
<p class=func><span class=keyword>disableDither</span>();</p>
|
|
<p class=desc>TODO: description
|
|
</p>
|
|
|
|
<h3>Hardware</h3>
|
|
<p>Pin 2 must be connected to the CS4272 reset. SDA & SCL are used for all control.
|
|
</p>
|
|
|
|
<h3>Notes</h3>
|
|
</script>
|
|
<script type="text/x-red" data-template-name="AudioControlCS4272">
|
|
<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>
|
|
</script>
|
|
|
|
<script type="text/x-red" data-help-name="AudioControlCS42448">
|
|
<h3>Summary</h3>
|
|
<div class=tooltipinfo>
|
|
<p>Control the CS42448 chip in TDM mode, for 6 inputs and 8 outputs.
|
|
</p>
|
|
<p align=center><img src="img/cs42448.jpg"></p>
|
|
</div>
|
|
</div>
|
|
<h3>Audio Connections</h3>
|
|
<p>This object has no audio inputs or outputs. Separate TDM objects
|
|
are used to send and receive audio data.
|
|
</p>
|
|
<h3>Functions</h3>
|
|
<p class=func><span class=keyword>enable</span>();</p>
|
|
<p class=desc>Enables the CS42448 to work in TDM mode.
|
|
</p>
|
|
<p class=func><span class=keyword>volume</span>(level);</p>
|
|
<p class=desc>Set the volume level for all output channels. Range is 0 to 1.0.
|
|
</p>
|
|
<p class=func><span class=keyword>volume</span>(channel, level);</p>
|
|
<p class=desc>Set the volume level for a single output. Channel is 1 to 8. Range is 0 to 1.0.
|
|
</p>
|
|
<p class=func><span class=keyword>inputLevel</span>(level);</p>
|
|
<p class=desc>Set the input gain level for all input channels. Range is 0 to 15.85.
|
|
</p>
|
|
<p class=func><span class=keyword>inputLevel</span>(channel, level);</p>
|
|
<p class=desc>Set the input gain level for a single input. Channel is 1 to 6. Range is 0 to 15.85.
|
|
</p>
|
|
<h3>Hardware</h3>
|
|
<p>Tested with this <a href="https://oshpark.com/shared_projects/2Yj6rFaW">
|
|
CS42448 Circuit Board</a>.
|
|
</p>
|
|
<p align=center><img src="img/tdm.jpg"></p>
|
|
</div>
|
|
<h3>Notes</h3>
|
|
</script>
|
|
<script type="text/x-red" data-template-name="AudioControlCS42448">
|
|
<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>
|
|
</script>
|
|
|
|
|
|
</body>
|
|
</html>
|
|
|