| 
							- <!-- vim: set ts=4: -->
 - <!-- 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/javascript">
 - 	RED.nodes.registerType('AudioInputI2S',{
 - 	shortName: "i2s",
 - 		inputs:0,
 - 		outputs:2,
 - 		category: 'input-function',
 - 		color:"#E6E0F8",
 - 		icon: "arrow-in.png"
 - 	});
 - </script>
 - <script type="text/x-red" data-help-name="AudioInputI2S">
 - 	<h3>Summary</h3>
 - 	<p>Receive 16 bit stereo audio from the
 - 	<a href="http://www.pjrc.com/store/teensy3_audio.html" target="_blank">audio shield</a>
 - 		or another I2S device, using I2S master mode.</p>
 - 	<p align=center><img src="audioshield_inputs.jpg"></p>
 - 	<h3>Audio Connections</h3>
 - 	<table class=doc align=center cellpadding=3>
 - 		<tr class=top><th>Port</th><th>Purpose</th></tr>
 - 		<tr class=odd><td align=center>Out 0</td><td>Left Channel</td></tr>
 - 		<tr class=odd><td align=center>Out 1</td><td>Right Channel</td></tr>
 - 	</table>
 - 	<h3>Functions</h3>
 - 	<p>This object has no functions to call from the Arduino sketch.  It
 - 		simply streams data from the I2S hardware to its 2 output ports.</p>
 - 	<h3>Hardware</h3>
 - 	<p align=center><img src="audioshield_backside.jpg"></p>
 - 	<p>The I2S signals are used in "master" mode, where Teensy creates
 - 		all 3 clock signals and controls all data timing.</p>
 - 	<table class=doc align=center cellpadding=3>
 - 		<tr class=top><th>Pin</th><th>Signal</th><th>Direction</th></tr>
 - 		<tr class=odd><td align=center>9</td><td>BCLK</td><td>Output</td></tr>
 - 		<tr class=odd><td align=center>11</td><td>MCLK</td><td>Output</td></tr>
 - 		<tr class=odd><td align=center>13</td><td>RX</td><td>Input</td></tr>
 - 		<tr class=odd><td align=center>23</td><td>LRCLK</td><td>Output</td></tr>
 - 	</table>
 - 	<p>Audio from
 - 		master mode I2S may be used in the same project as ADC, DAC and
 - 		PWM signals, because all remain in sync to Teensy's timing</p>
 - 	<h3>Notes</h3>
 - 	<p>Normally, this object is used with the Audio Shield, which
 - 		is controlled separately by the "sgtl5000" object.</p>
 - 	<p>Only one I2S input and one I2S output object may be used.  Master
 - 		and slave modes may not be mixed (both must be of the same type).
 - 	</p>
 - 	<p>I2S master objects can be used together with non-I2S input and output
 - 		objects, for simultaneous audio streaming on different hardware.</p>
 - </script>
 - <script type="text/x-red" data-template-name="AudioInputI2S">
 - 	<div class="form-row">
 - 		<label for="node-input-name"><i class="fa fa-tag"></i> Name</label>
 - 		<input type="text" id="node-input-name" placeholder="Name">
 - 	</div>
 - </script>
 - 
 - 
 - <script type="text/javascript">
 - 	RED.nodes.registerType('AudioInputI2Sslave',{
 - 	shortName: "i2ss",
 - 		inputs:0,
 - 		outputs:2,
 - 		category: 'input-function',
 - 		color:"#E6E0F8",
 - 		icon: "arrow-in.png"
 - 	});
 - </script>
 - <script type="text/x-red" data-help-name="AudioInputI2Sslave">
 - 	<h3>Summary</h3>
 - 	<p>Receive 16 bit stereo audio from an I2S device using I2S slave mode.</p>
 - 	<h3>Audio Connections</h3>
 - 	<table class=doc align=center cellpadding=3>
 - 		<tr class=top><th>Port</th><th>Purpose</th></tr>
 - 		<tr class=odd><td align=center>Out 0</td><td>Left Channel</td></tr>
 - 		<tr class=odd><td align=center>Out 1</td><td>Right Channel</td></tr>
 - 	</table>
 - 	<h3>Functions</h3>
 - 	<p>This object has no functions to call from the Arduino sketch.  It
 - 		simply streams data from the I2S hardware to its 2 output ports.</p>
 - 	<h3>Hardware</h3>
 - 	<p>The I2S signals are used in "slave" mode, where the I2S device controls
 - 		data timing.</p>
 - 	<table class=doc align=center cellpadding=3>
 - 		<tr class=top><th>Pin</th><th>Signal</th><th>Direction</th></tr>
 - 		<tr class=odd><td align=center>9</td><td>BCLK</td><td>Input</td></tr>
 - 		<tr class=odd><td align=center>13</td><td>RX</td><td>Input</td></tr>
 - 		<tr class=odd><td align=center>23</td><td>LRCLK</td><td>Input</td></tr>
 - 	</table>
 - 	<h3>Notes</h3>
 - 	<p>Slave mode I2S <b>should not used in the same project as ADC, DAC and
 - 		PWM</b> signals.  Differences in timing between the I2S device and
 - 		Teensy's clock can cause occasional audio glitches when I2S slave mode
 - 		is used together with other input or output objects based on Teensy's
 - 		timing.</p>
 - 	<p>Only one I2S input and one I2S output object may be used.  Master
 - 		and slave modes may not be mixed (both must be of the same type).
 - 	</p>
 - </script>
 - <script type="text/x-red" data-template-name="AudioInputI2Sslave">
 - 	<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/javascript">
 - 	RED.nodes.registerType('AudioInputADC',{
 - 	shortName: "adc",
 - 		inputs:0,
 - 		outputs:1,
 - 		category: 'input-function',
 - 		color:"#E6E0F8",
 - 		icon: "arrow-in.png"
 - 	});
 - </script>
 - <script type="text/x-red" data-help-name="AudioInputADC">
 - 	<h3>Summary</h3>
 - 	<p>Receive audio using the built-in analog to digital converter.</p>
 - 	<h3>Audio Connections</h3>
 - 	<table class=doc align=center cellpadding=3>
 - 		<tr class=top><th>Port</th><th>Purpose</th></tr>
 - 		<tr class=odd><td align=center>Out 0</td><td>Audio Channel</td></tr>
 - 	</table>
 - 	<h3>Parameters</h3>
 - 	<table class=doc align=center cellpadding=3>
 - 		<tr class=top><th>Name</th><th>Type</th><th>Function</th></tr>
 - 		<tr class=odd><td align=center>Pin</td><td>Integer</td><td>Analog Pin To Use</td></tr>
 - 	</table>
 - 	<p>The pin number should be specified as "A0" to "A20"</p>
 - 	<p align=center><img src="adcpins2.jpg"></p>
 - 	<p align=center><img src="adcpins1.jpg"></p>
 - 	<h3>Functions</h3>
 - 	<p>This object has no functions to call from the Arduino sketch.  It
 - 		simply streams data from the ADC to its output port.</p>
 - 	<h3>Hardware</h3>
 - 	<p>Signal range is 0 to 1.2V</p>
 - 	<p>Need for DC bias, approx 0.6V</p>
 - 	<p>TODO: suggested circuity for signal input</p>
 - 	<h3>Notes</h3>
 - 	<p>Algorithm for automatic DC bias tracking</p>
 - 	<p>Noise due to high source impedance</p>
 - 	<p>Power Supply rejection issue with simple DC bias</p>
 - 	<p>TODO: actual noise measurements with different input circuitry
 - 		(it's not nearly as quiet as the audio shield)</p>
 - </script>
 - <script type="text/x-red" data-template-name="AudioInputADC">
 - 	<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/javascript">
 - 	RED.nodes.registerType('AudioOutputI2S',{
 - 	shortName: "i2s",
 - 		inputs:2,
 - 		outputs:0,
 - 		category: 'output-function',
 - 		color:"#E6E0F8",
 - 		icon: "arrow-in.png"
 - 	});
 - </script>
 - <script type="text/x-red" data-help-name="AudioOutputI2S">
 - 	<h3>Summary</h3>
 - 	<p>Transmit 16 bit stereo audio to the
 - 	<a href="http://www.pjrc.com/store/teensy3_audio.html" target="_blank">audio shield</a>
 - 		or another I2S device, using I2S master mode.</p>
 - 	<p align=center><img src="audioshield_outputs.jpg"></p>
 - 	<h3>Audio Connections</h3>
 - 	<table class=doc align=center cellpadding=3>
 - 		<tr class=top><th>Port</th><th>Purpose</th></tr>
 - 		<tr class=odd><td align=center>In 0</td><td>Left Channel</td></tr>
 - 		<tr class=odd><td align=center>In 1</td><td>Right Channel</td></tr>
 - 	</table>
 - 	<h3>Functions</h3>
 - 	<p>This object has no functions to call from the Arduino sketch.  It
 - 		simply streams data from its 2 input ports to the I2S hardware.</p>
 - 	<h3>Hardware</h3>
 - 	<p align=center><img src="audioshield_backside.jpg"></p>
 - 	<p>The I2S signals are used in "master" mode, where Teensy creates
 - 		all 3 clock signals and controls all data timing.</p>
 - 	<table class=doc align=center cellpadding=3>
 - 		<tr class=top><th>Pin</th><th>Signal</th><th>Direction</th></tr>
 - 		<tr class=odd><td align=center>9</td><td>BCLK</td><td>Output</td></tr>
 - 		<tr class=odd><td align=center>11</td><td>MCLK</td><td>Output</td></tr>
 - 		<tr class=odd><td align=center>22</td><td>TX</td><td>Output</td></tr>
 - 		<tr class=odd><td align=center>23</td><td>LRCLK</td><td>Output</td></tr>
 - 	</table>
 - 	<p>Audio from
 - 		master mode I2S may be used in the same project as ADC, DAC and
 - 		PWM signals, because all remain in sync to Teensy's timing</p>
 - 	<h3>Notes</h3>
 - 	<p>Normally, this object is used with the Audio Shield, which
 - 		is controlled separately by the "sgtl5000" object.</p>
 - 	<p>Only one I2S input and one I2S output object may be used.  Master
 - 		and slave modes may not be mixed (both must be of the same type).
 - 	</p>
 - </script>
 - <script type="text/x-red" data-template-name="AudioOutputI2S">
 - 	<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/javascript">
 - 	RED.nodes.registerType('AudioOutputI2Sslave',{
 - 	shortName: "i2ss",
 - 		inputs:2,
 - 		outputs:0,
 - 		category: 'output-function',
 - 		color:"#E6E0F8",
 - 		icon: "arrow-in.png"
 - 	});
 - </script>
 - <script type="text/x-red" data-help-name="AudioOutputI2Sslave">
 - 	<h3>Summary</h3>
 - 	<p>Transmit 16 bit stereo audio to an I2S device using I2S slave mode.</p>
 - 	<h3>Audio Connections</h3>
 - 	<table class=doc align=center cellpadding=3>
 - 		<tr class=top><th>Port</th><th>Purpose</th></tr>
 - 		<tr class=odd><td align=center>In 0</td><td>Left Channel</td></tr>
 - 		<tr class=odd><td align=center>In 1</td><td>Right Channel</td></tr>
 - 	</table>
 - 	<h3>Functions</h3>
 - 	<p>This object has no functions to call from the Arduino sketch.  It
 - 		simply streams data from its 2 input ports to the I2S hardware.</p>
 - 	<h3>Hardware</h3>
 - 	<p>The I2S signals are used in "slave" mode, where the I2S device controls
 - 		data timing.</p>
 - 	<table class=doc align=center cellpadding=3>
 - 		<tr class=top><th>Pin</th><th>Signal</th><th>Direction</th></tr>
 - 		<tr class=odd><td align=center>9</td><td>BCLK</td><td>Input</td></tr>
 - 		<tr class=odd><td align=center>22</td><td>TX</td><td>Output</td></tr>
 - 		<tr class=odd><td align=center>23</td><td>LRCLK</td><td>Input</td></tr>
 - 	</table>
 - 	<h3>Notes</h3>
 - 	<p>Slave mode I2S <b>should not used in the same project as ADC, DAC and
 - 		PWM</b> signals.  Differences in timing between the I2S device and
 - 		Teensy's clock can cause occasional audio glitches when I2S slave mode
 - 		is used together with other input or output objects based on Teensy's
 - 		timing.</p>
 - 	<p>Only one I2S input and one I2S output object may be used.  Master
 - 		and slave modes may not be mixed (both must be of the same type).
 - 	</p>
 - </script>
 - <script type="text/x-red" data-template-name="AudioOutputI2Sslave">
 - 	<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/javascript">
 - 	RED.nodes.registerType('AudioOutputAnalog',{
 - 	shortName: "dac",
 - 		inputs:1,
 - 		outputs:0,
 - 		category: 'output-function',
 - 		color:"#E6E0F8",
 - 		icon: "arrow-in.png"
 - 	});
 - </script>
 - <script type="text/x-red" data-help-name="AudioOutputAnalog">
 - 	<h3>Summary</h3>
 - 	<p>Transmit 12 bit audio using Teensy 3.1's built-in digital to analog converter.</p>
 - 	<h3>Audio Connections</h3>
 - 	<table class=doc align=center cellpadding=3>
 - 		<tr class=top><th>Port</th><th>Purpose</th></tr>
 - 		<tr class=odd><td align=center>In 0</td><td>Audio Channel</td></tr>
 - 	</table>
 - 	<h3>Functions</h3>
 - 	<p>This object has no functions to call from the Arduino sketch.  It
 - 		simply streams data from the ADC to its output port.</p>
 - 	<h3>Hardware</h3>
 - 	<p align=center><img src="dacpin.jpg"></p>
 - 	<p>Signal range is 0 to 1.2V</p>
 - 	<p>Most applications require at least a 10µF DC-blocking capacitor.</p>
 - 	<p>TODO: photo of Teensy 3.1 with 10µF capacitor and 3.5mm jack.</p>
 - 	<h3>Notes</h3>
 - 	<p>The output rate is 44.1 kHz (no oversampling).  Ultrasonic noise present if
 - 		not filtered.  This may not
 - 		be an issue for many uses, but care should be used if amplified and driven
 - 		to high power tweeters.</p>
 - </script>
 - <script type="text/x-red" data-template-name="AudioOutputAnalog">
 - 	<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/javascript">
 - 	RED.nodes.registerType('AudioOutputPWM',{
 - 	shortName: "pwm",
 - 		inputs:1,
 - 		outputs:0,
 - 		category: 'output-function',
 - 		color:"#E6E0F8",
 - 		icon: "arrow-in.png"
 - 	});
 - </script>
 - <script type="text/x-red" data-help-name="AudioOutputPWM">
 - 	<h3>Summary</h3>
 - 	<p>Transmit audio using Teensy 3.1's PWM pins.  Two pins are
 - 		used for coarse and fine pulses, to be combined by scaled
 - 		resistors.</p>
 - 	<h3>Audio Connections</h3>
 - 	<table class=doc align=center cellpadding=3>
 - 		<tr class=top><th>Port</th><th>Purpose</th></tr>
 - 		<tr class=odd><td align=center>In 0</td><td>Audio Channel</td></tr>
 - 	</table>
 - 	<h3>Functions</h3>
 - 	<p>This object has no functions to call from the Arduino sketch.  It
 - 		simply streams data from the its input port to the PWM pins.</p>
 - 	<h3>Hardware</h3>
 - 	<p>The following circuit is recommended.</p>
 - 	<p align=center><img src="pwmdualcircuit.jpg"></p>
 - 	<p>Signal range is approx 1.55 Vp-p.</p>
 - 	<p>These resistor values assume approx 20 ohms output impedance
 - 		on the digital pins.  The 127K resistor may be adjusted or
 - 		trimmed for variation in output drive and tolerance on the
 - 		475 ohm resistor.</p>
 - 	<p>A plastic film (Polypropylene, Polyethylene, Polyester, etc) or
 - 		C0G/NPO ceramic capacitor should be used for filtering.  Low
 - 		quality ceramic (X7R, Y5V, Z5U, etc) can cause signal distortion.</p>
 - 	<h3>Notes</h3>
 - 	<p>The PWM carrier frequency is 88.2 kHz.  The suggested circuit
 - 		will only slightly filter the carrier.  Extra filtering will be
 - 		required for a clean signal without the ultrasonic PWM carrier.
 - 		</p>
 - 	<p>Analog signals created by filtering PWM waveforms use the digital
 - 		power supply as their reference voltage.  Any noise on the digital
 - 		power line can directly couple to the output signal.  The built-in DAC or
 - 		<a href="http://www.pjrc.com/store/teensy3_audio.html" target="_blank">audio shield</a>
 - 		should be used when higher quality signals are needed.</p>
 - </script>
 - <script type="text/x-red" data-template-name="AudioOutputPWM">
 - 	<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/javascript">
 - 	RED.nodes.registerType('AudioMixer4',{
 - 	shortName: "mixer",
 - 		inputs:4,
 - 		outputs:1,
 - 		category: 'mixer-function',
 - 		color:"#E6E0F8",
 - 		icon: "arrow-in.png"
 - 	});
 - </script>
 - <script type="text/x-red" data-help-name="AudioMixer4">
 - 	<h3>Summary</h3>
 - 	<p>Combine up to 4 audio signals together, each with adjustable gain.
 - 		All channels support signal attenuation or amplification.</p>
 - 	<h3>Audio Connections</h3>
 - 	<table class=doc align=center cellpadding=3>
 - 		<tr class=top><th>Port</th><th>Purpose</th></tr>
 - 		<tr class=odd><td align=center>In 0</td><td>Input signal #1</td></tr>
 - 		<tr class=odd><td align=center>In 1</td><td>Input signal #2</td></tr>
 - 		<tr class=odd><td align=center>In 2</td><td>Input signal #3</td></tr>
 - 		<tr class=odd><td align=center>In 3</td><td>Input signal #4</td></tr>
 - 		<tr class=odd><td align=center>Out 0</td><td>Sum of all inputs</td></tr>
 - 	</table>
 - 	<h3>Functions</h3>
 - 	<p class=func><span class=keyword>gain</span>(channel, level);</p>
 - 	<p class=desc>Adjust the amplification or attenuation.  "channel" must
 - 		be 0 to 3.  "level" may be any floating point number from 0 to 32767.
 - 		1.0 passes the signal through directly.  Level of 0 shuts the channel
 - 		off completely.  Between 0 to 1.0 attenuates the signal, and above
 - 		1.0 amplifies it.  All 4 channels have separate settings.
 - 	</p>
 - 	<h3>Notes</h3>
 - 	<p>Signal clipping can occur when any channel has gain greater than 1.0,
 - 		or when multiple signals add together to greater than 1.0.</p>
 - 	<p>More than 4 channels may be combined by connecting multiple mixers
 - 		in tandem.  For example, a 16 channel mixer may be built using 5
 - 		mixers, where the fifth mixer combines the outputs of the first 4.
 - 	</p>
 - </script>
 - <script type="text/x-red" data-template-name="AudioMixer4">
 - 	<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/javascript">
 - 	RED.nodes.registerType('AudioPlayMemory',{
 - 	shortName: "playMem",
 - 		inputs:0,
 - 		outputs:1,
 - 		category: 'play-function',
 - 		color:"#E6E0F8",
 - 		icon: "arrow-in.png"
 - 	});
 - </script>
 - <script type="text/x-red" data-help-name="AudioPlayMemory">
 - 	<h3>Summary</h3>
 - 	<p>Play a short sound clip, stored directly in memory.
 - 		Data files are created with the
 - 		<a href="https://github.com/PaulStoffregen/Audio/tree/master/examples/PlayFromSketch/wav2sketch" target="_blank">wav2sketch program</a>,
 - 		and copied to the sketch folder to become part of your sketch.</p>
 - 	<h3>Audio Connections</h3>
 - 	<table class=doc align=center cellpadding=3>
 - 		<tr class=top><th>Port</th><th>Purpose</th></tr>
 - 		<tr class=odd><td align=center>Out 0</td><td>Sound Output</td></tr>
 - 	</table>
 - 	<h3>Functions</h3>
 - 	<p class=func><span class=keyword>play</span>(data);</p>
 - 	<p class=desc>Begin playing a sound clip.  If already playing, the
 - 		currently playing clip is stopped and this new data begins
 - 		playing from the beginning.
 - 	</p>
 - 	<p class=func><span class=keyword>stop</span>();</p>
 - 	<p class=desc>Stop playing.  If not playing, this function has no effect.
 - 	</p>
 - 	<p class=func><span class=keyword>isPlaying</span>();</p>
 - 	<p class=desc>Return true (non-zero) if playing, or false (zero)
 - 		when not playing.
 - 	</p>
 - 	<p class=func><span class=keyword>positionMillis</span>();</p>
 - 	<p class=desc>While playing, return the current time offset, in
 - 		milliseconds.  When not playing, the return from this function
 - 		is undefined.
 - 	</p>
 - 	<p class=func><span class=keyword>lengthMillis</span>();</p>
 - 	<p class=desc>Return the total length of the current sound clip,
 - 		in milliseconds.  When not playing, the return from this function
 - 		is undefined.
 - 	</p>
 - 	<h3>Notes</h3>
 - 	<p>TODO: supported sample rates: 11.025, 22.05, 44.1</p>
 - 	<p>TODO: ulaw vs uncompressed encoding</p>
 - 	<p>Polyphonic playback can be built by creating multiple
 - 		objects, with their output combined by mixers.</p>
 - </script>
 - <script type="text/x-red" data-template-name="AudioPlayMemory">
 - 	<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/javascript">
 - 	RED.nodes.registerType('AudioPlaySdWav',{
 - 	shortName: "playWav",
 - 		inputs:0,
 - 		outputs:2,
 - 		category: 'play-function',
 - 		color:"#E6E0F8",
 - 		icon: "arrow-in.png"
 - 	});
 - </script>
 - <script type="text/x-red" data-help-name="AudioPlaySdWav">
 - 	<h3>Summary</h3>
 - 	<p>Play a WAV file, stored on a SD card.</p>
 - 	<h3>Audio Connections</h3>
 - 	<table class=doc align=center cellpadding=3>
 - 		<tr class=top><th>Port</th><th>Purpose</th></tr>
 - 		<tr class=odd><td align=center>Out 0</td><td>Left Channel Output</td></tr>
 - 		<tr class=odd><td align=center>Out 1</td><td>Right Channel Output</td></tr>
 - 	</table>
 - 	<h3>Functions</h3>
 - 	<p class=func><span class=keyword>play</span>(filename);</p>
 - 	<p class=desc>Begin playing a WAV file.  If a file is already playing,
 - 		it is stopped and this file starts playing from the beginning.
 - 	</p>
 - 	<p class=func><span class=keyword>stop</span>();</p>
 - 	<p class=desc>Stop playing.  If not playing, this function has no effect.
 - 	</p>
 - 	<p class=func><span class=keyword>isPlaying</span>();</p>
 - 	<p class=desc>Return true (non-zero) if playing, or false (zero)
 - 		when not playing.  See the note below about delayed start.
 - 	</p>
 - 	<p class=func><span class=keyword>positionMillis</span>();</p>
 - 	<p class=desc>While playing, return the current time offset, in
 - 		milliseconds.  When not playing, the return from this function
 - 		is undefined.
 - 	</p>
 - 	<p class=func><span class=keyword>lengthMillis</span>();</p>
 - 	<p class=desc>Return the total length of the current sound clip,
 - 		in milliseconds.  When not playing, the return from this function
 - 		is undefined.
 - 	</p>
 - 	<h3>Notes</h3>
 - 	<p>Only 16 bit PCM, 44100 Hz WAV files are supported.  When mono
 - 		files are played, both output ports transmit a copy of the
 - 		single sound.  Of course, stereo WAV files play with the left
 - 		channel on port 0 and the right channel on port 1.
 - 	</p>
 - 	<p>A brief delay after calling play() will usually occur before
 - 		isPlaying() returns true and positionMillis() returns valid
 - 		time offset.  WAV files have a header at the beginning of the
 - 		file, which the audio library must read and parse before
 - 		playing can begin.
 - 	</p>
 - 	<p>While playing, the audio library accesses the SD card automatically.
 - 		If card access is required, you must
 - 		<a href="http://www.pjrc.com/teensy/td_libs_AudioProcessorUsage.html" target="_blank">use AudioNoInterrupts()</a>
 - 		to prevent the library from accessing the SD card while you use it.
 - 		Disabling the audio library interrupt for too long may cause audible
 - 		dropouts or glitches.
 - 	</p>
 - </script>
 - <script type="text/x-red" data-template-name="AudioPlaySdWav">
 - 	<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/javascript">
 - 	RED.nodes.registerType('AudioPlaySdRaw',{
 - 	shortName: "playRaw",
 - 		inputs:0,
 - 		outputs:1,
 - 		category: 'play-function',
 - 		color:"#E6E0F8",
 - 		icon: "arrow-in.png"
 - 	});
 - </script>
 - <script type="text/x-red" data-help-name="AudioPlaySdRaw">
 - 	<h3>Summary</h3>
 - 	<p>Play a RAW data file, stored on a SD card.  RAW format is simpler
 - 		than WAV and begins playing immediately, without parsing WAV file
 - 		header info.</p>
 - 	<h3>Audio Connections</h3>
 - 	<table class=doc align=center cellpadding=3>
 - 		<tr class=top><th>Port</th><th>Purpose</th></tr>
 - 		<tr class=odd><td align=center>Out 0</td><td>Sound Output</td></tr>
 - 	</table>
 - 	<h3>Functions</h3>
 - 	<p class=func><span class=keyword>play</span>(filename);</p>
 - 	<p class=desc>Begin playing a RAW data file.  If a file is already playing,
 - 		it is stopped and this file starts playing from the beginning.
 - 	</p>
 - 	<p class=func><span class=keyword>stop</span>();</p>
 - 	<p class=desc>Stop playing.  If not playing, this function has no effect.
 - 	</p>
 - 	<p class=func><span class=keyword>isPlaying</span>();</p>
 - 	<p class=desc>Return true (non-zero) if playing, or false (zero)
 - 		when not playing.
 - 	</p>
 - 	<p class=func><span class=keyword>positionMillis</span>();</p>
 - 	<p class=desc>While playing, return the current time offset, in
 - 		milliseconds.  When not playing, the return from this function
 - 		is undefined.
 - 	</p>
 - 	<p class=func><span class=keyword>lengthMillis</span>();</p>
 - 	<p class=desc>Return the total length of the current sound clip,
 - 		in milliseconds.  When not playing, the return from this function
 - 		is undefined.
 - 	</p>
 - 	<h3>Notes</h3>
 - 	<p>The data file must be RAW 16 bit signed integers in LSB-first format.
 - 	</p>
 - 	<p>While playing, the audio library accesses the SD card automatically.
 - 		If card access is required, you must
 - 		<a href="http://www.pjrc.com/teensy/td_libs_AudioProcessorUsage.html" target="_blank">AudioNoInterrupts()</a>
 - 		to prevent the library from accessing the SD card while you use it.
 - 		Disabling the audio library interrupt for too long may cause audible
 - 		dropouts or glitches.
 - 	</p>
 - </script>
 - <script type="text/x-red" data-template-name="AudioPlaySdRaw">
 - 	<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/javascript">
 - 	RED.nodes.registerType('AudioPlayQueue',{
 - 	shortName: "queue",
 - 		inputs:0,
 - 		outputs:1,
 - 		category: 'play-function',
 - 		color:"#E6E0F8",
 - 		icon: "arrow-in.png"
 - 	});
 - </script>
 - <script type="text/x-red" data-help-name="AudioPlayQueue">
 - 	<h3>Summary</h3>
 - 	<p>Play audio data provided by the Arduino sketch.  This object provides
 - 		functions to allow the sketch code to push data into the audio system.</p>
 - 	<h3>Audio Connections</h3>
 - 	<table class=doc align=center cellpadding=3>
 - 		<tr class=top><th>Port</th><th>Purpose</th></tr>
 - 		<tr class=odd><td align=center>Out 0</td><td>Sound Output</td></tr>
 - 	</table>
 - 	<h3>Functions</h3>
 - 	<p class=func><span class=keyword>play</span>(int16);</p>
 - 	<p class=desc>not yet implemented
 - 	</p>
 - 	<p class=func><span class=keyword>play</span>(int16[], length);</p>
 - 	<p class=desc>not yet implemented
 - 	</p>
 - 	<p class=func><span class=keyword>getBuffer</span>();</p>
 - 	<p class=desc>Returns a pointer to an array of 128 int16.  This buffer
 - 		is within the audio library memory pool, providing the most efficient
 - 		way to input data to the audio system.  The buffer is likely to be
 - 		populated by previously used data, so the entire 128 words should be
 - 		written before calling playBuffer().  Only a single buffer should be
 - 		requested at a time.  This function may return NULL if no memory is
 - 		available.
 - 	</p>
 - 	<p class=func><span class=keyword>playBuffer</span>();</p>
 - 	<p class=desc>Transmit the buffer previously obtained from getBuffer().
 - 	</p>
 - 	<h3>Notes</h3>
 - 	<p>TODO: many caveats....</p>
 - 	<p>
 - 	</p>
 - </script>
 - <script type="text/x-red" data-template-name="AudioPlayQueue">
 - 	<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/javascript">
 - 	RED.nodes.registerType('AudioSynthWaveformSine',{
 - 	shortName: "sine",
 - 		inputs:0,
 - 		outputs:1,
 - 		category: 'synth-function',
 - 		color:"#E6E0F8",
 - 		icon: "arrow-in.png"
 - 	});
 - </script>
 - <script type="text/x-red" data-help-name="AudioSynthWaveformSine">
 - 	<h3>Summary</h3>
 - 	<p>Create a sine wave signal</p>
 - 	<h3>Audio Connections</h3>
 - 	<table class=doc align=center cellpadding=3>
 - 		<tr class=top><th>Port</th><th>Purpose</th></tr>
 - 		<tr class=odd><td align=center>Out 0</td><td>Sine Wave Output</td></tr>
 - 	</table>
 - 	<h3>Functions</h3>
 - 	<p class=func><span class=keyword>amplitude</span>(level);</p>
 - 	<p class=desc>Set the amplitude, from 0 to 1.0.
 - 	</p>
 - 	<p class=func><span class=keyword>frequency</span>(freq);</p>
 - 	<p class=desc>Set the frequency, from 0 to 22000.  Very low values may
 - 		be used to create a LFO (Low Frequency Oscillator) for objects
 - 		with modulation signal inputs.
 - 	</p>
 - 	<p class=func><span class=keyword>phase</span>(angle);</p>
 - 	<p class=desc>
 - 		Cause the generated waveform to jump to a specific point within
 - 		its cycle.  Angle is from 0 to 360 degrees.  When multiple objects
 - 		are configured,
 - 		<a href="http://www.pjrc.com/teensy/td_libs_AudioProcessorUsage.html" target="_blank">AudioNoInterrupts()</a>
 - 		should be used to guarantee all new settings take effect together.
 - 	</p>
 - 	<h3>Notes</h3>
 - 	<p></p>
 - </script>
 - <script type="text/x-red" data-template-name="AudioSynthWaveformSine">
 - 	<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/javascript">
 - 	RED.nodes.registerType('AudioSynthWaveformSineModulated',{
 - 	shortName: "sine_fm",
 - 		inputs:1,
 - 		outputs:1,
 - 		category: 'synth-function',
 - 		color:"#E6E0F8",
 - 		icon: "arrow-in.png"
 - 	});
 - </script>
 - <script type="text/x-red" data-help-name="AudioSynthWaveformSineModulated">
 - 	<h3>Summary</h3>
 - 	<p>Create a modulated sine wave, using any audio signal to continuously
 - 		modulate the sine wave frequency.</p>
 - 	<h3>Audio Connections</h3>
 - 	<table class=doc align=center cellpadding=3>
 - 		<tr class=top><th>Port</th><th>Purpose</th></tr>
 - 		<tr class=odd><td align=center>In 0</td><td>Modulation Signal</td></tr>
 - 		<tr class=odd><td align=center>Out 0</td><td>Sine Wave Output</td></tr>
 - 	</table>
 - 	<h3>Functions</h3>
 - 	<p class=func><span class=keyword>amplitude</span>(level);</p>
 - 	<p class=desc>Set the amplitude, from 0 to 1.0.
 - 	</p>
 - 	<p class=func><span class=keyword>frequency</span>(freq);</p>
 - 	<p class=desc>Set the center frequency, from 0 to 11000.  The output will
 - 		be this center frequency when the input modulation signal is zero.
 - 		Modulation input 1.0 causes the frequency to double, and input -1.0
 - 		causes zero Hz (DC) output.  For less modulation, attenuate the input
 - 		signal (perhaps with a mixer object) before it arrives here.
 - 	</p>
 - 	<p class=func><span class=keyword>phase</span>(angle);</p>
 - 	<p class=desc>
 - 		Cause the generated waveform to jump to a specific point within
 - 		its cycle.  Angle is from 0 to 360 degrees.  When multiple objects
 - 		are configured,
 - 		<a href="http://www.pjrc.com/teensy/td_libs_AudioProcessorUsage.html" target="_blank">AudioNoInterrupts()</a>
 - 		should be used to guarantee all new settings take effect together.
 - 	</p>
 - 	<h3>Notes</h3>
 - 	<p></p>
 - </script>
 - <script type="text/x-red" data-template-name="AudioSynthWaveformSineModulated">
 - 	<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/javascript">
 - 	RED.nodes.registerType('AudioSynthWaveform',{
 - 	shortName: "waveform",
 - 		inputs:0,
 - 		outputs:1,
 - 		category: 'synth-function',
 - 		color:"#E6E0F8",
 - 		icon: "arrow-in.png"
 - 	});
 - </script>
 - <script type="text/x-red" data-help-name="AudioSynthWaveform">
 - 	<h3>Summary</h3>
 - 	<p>Create a waveform: sine, sawtooth, square, or triangle</p>
 - 	<h3>Audio Connections</h3>
 - 	<table class=doc align=center cellpadding=3>
 - 		<tr class=top><th>Port</th><th>Purpose</th></tr>
 - 		<tr class=odd><td align=center>Out 0</td><td>Waveform Output</td></tr>
 - 	</table>
 - 	<h3>Functions</h3>
 - 	<p class=func><span class=keyword>begin</span>(waveform);</p>
 - 	<p class=desc>Configure the waveform type to create.
 - 	</p>
 - 	<p class=func><span class=keyword>begin</span>(level, frequency, waveform);</p>
 - 	<p class=desc>Output a waveform, and set the amplitude and frequency.
 - 	</p>
 - 	<p class=func><span class=keyword>frequency</span>(freq);</p>
 - 	<p class=desc>Change the frequency.
 - 	</p>
 - 	<p class=func><span class=keyword>amplitude</span>(level);</p>
 - 	<p class=desc>Change the amplitude.  Set to 0 to turn the signal off.
 - 	</p>
 - 	<p class=func><span class=keyword>phase</span>(angle);</p>
 - 	<p class=desc>
 - 		Cause the generated waveform to jump to a specific point within
 - 		its cycle.  Angle is from 0 to 360 degrees.  When multiple objects
 - 		are configured,
 - 		<a href="http://www.pjrc.com/teensy/td_libs_AudioProcessorUsage.html" target="_blank">AudioNoInterrupts()</a>
 - 		should be used to guarantee all new settings take effect together.
 - 	</p>
 - 	<p class=func><span class=keyword>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>Notes</h3>
 - 	<p>Supported Waveforms:<br>
 - 		<ul>
 - 		<li><span class=literal>WAVEFORM_SINE</span></li>
 - 		<li><span class=literal>WAVEFORM_SAWTOOTH</span></li>
 - 		<li><span class=literal>WAVEFORM_SQUARE</span></li>
 - 		<li><span class=literal>WAVEFORM_TRIANGLE</span></li>
 - 		<li><span class=literal>WAVEFORM_ARBITRARY</span></li>
 - 		</ul>
 - 	</p>
 - </script>
 - <script type="text/x-red" data-template-name="AudioSynthWaveform">
 - 	<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/javascript">
 - 	RED.nodes.registerType('AudioSynthToneSweep',{
 - 	shortName: "tonesweep",
 - 		inputs:0,
 - 		outputs:1,
 - 		category: 'synth-function',
 - 		color:"#E6E0F8",
 - 		icon: "arrow-in.png"
 - 	});
 - </script>
 - <script type="text/x-red" data-help-name="AudioSynthToneSweep">
 - 	<h3>Summary</h3>
 - 	<p>Create a continuously varying (in frequency) sine wave</p>
 - 	<h3>Audio Connections</h3>
 - 	<table class=doc align=center cellpadding=3>
 - 		<tr class=top><th>Port</th><th>Purpose</th></tr>
 - 		<tr class=odd><td align=center>Out 0</td><td>Continuously varying tone</td></tr>
 - 	</table>
 - 	<h3>Functions</h3>
 - 	<p class=func><span class=keyword>play</span>(level, lowFreq, highFreq, time);</p>
 - 	<p class=desc>Start generating frequency sweep output.  The time is specified
 - 		in milliseconds.  Level is 0 to 1.0.
 - 	</p>
 - 	<p class=func><span class=keyword>isPlaying</span>();</p>
 - 	<p class=desc>Returns true (non-zero) while the output is active.
 - 	</p>
 - 	<h3>Notes</h3>
 - 	<p>Uses excessive CPU time</p>
 - </script>
 - <script type="text/x-red" data-template-name="AudioSynthToneSweep">
 - 	<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/javascript">
 - 	RED.nodes.registerType('AudioSynthWaveformDc',{
 - 	shortName: "dc",
 - 		inputs:0,
 - 		outputs:1,
 - 		category: 'synth-function',
 - 		color:"#E6E0F8",
 - 		icon: "arrow-in.png"
 - 	});
 - </script>
 - <script type="text/x-red" data-help-name="AudioSynthWaveformDc">
 - 	<h3>Summary</h3>
 - 	<p>Create constant (DC) signal, useful for control of objects that take
 - 		a modulation or control input signal.  This constant level can be
 - 		used to modify other waveforms using mixer or multiplier objects</p>
 - 	<h3>Audio Connections</h3>
 - 	<table class=doc align=center cellpadding=3>
 - 		<tr class=top><th>Port</th><th>Purpose</th></tr>
 - 		<tr class=odd><td align=center>Out 0</td><td>Output constant DC level</td></tr>
 - 	</table>
 - 	<h3>Functions</h3>
 - 	<p class=func><span class=keyword>amplitude</span>(level);</p>
 - 	<p class=desc>Set the output.  Level is -1.0 to 1.0.  The output is
 - 		changed immediately.
 - 	</p>
 - 	<p class=func><span class=keyword>amplitude</span>(level, milliseconds);</p>
 - 	<p class=desc>Set the output.  Level is -1.0 to 1.0.  The output is
 - 		gradually changed over a "milliseconds" time period.  Any time may
 - 		be specified, but periods longer than 1 second may be automatically
 - 		shortened for small level changes, due to numerical precision limits.
 - 	</p>
 - 	<h3>Notes</h3>
 - 	<p>Of course, the term "DC", for Direct Current, doesn't properly apply
 - 		to a pure digital stream of numerical values.  But the term is widely
 - 		understood in audio applications, so hopefully it's not too confusing?</p>
 - </script>
 - <script type="text/x-red" data-template-name="AudioSynthWaveformDc">
 - 	<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/javascript">
 - 	RED.nodes.registerType('AudioSynthNoiseWhite',{
 - 	shortName: "noise",
 - 		inputs:0,
 - 		outputs:1,
 - 		category: 'synth-function',
 - 		color:"#E6E0F8",
 - 		icon: "arrow-in.png"
 - 	});
 - </script>
 - <script type="text/x-red" data-help-name="AudioSynthNoiseWhite">
 - 	<h3>Summary</h3>
 - 	<div>
 - 	<p>Create white noise.
 - 		</p>
 - 	<p align=center><img src="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>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">
 - 	<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/javascript">
 - 	RED.nodes.registerType('AudioSynthNoisePink',{
 - 	shortName: "pink",
 - 		inputs:0,
 - 		outputs:1,
 - 		category: 'synth-function',
 - 		color:"#E6E0F8",
 - 		icon: "arrow-in.png"
 - 	});
 - </script>
 - <script type="text/x-red" data-help-name="AudioSynthNoisePink">
 - 	<h3>Summary</h3>
 - 	<div>
 - 	<p>Create pink noise, using Stefan Stenzel's "New Shade Of Pink" algorithm.
 - 		</p>
 - 	<!--<p align=center><img src="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>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">
 - 	<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/javascript">
 - 	RED.nodes.registerType('AudioEffectFade',{
 - 	shortName: "fade",
 - 		inputs:1,
 - 		outputs:1,
 - 		category: 'effect-function',
 - 		color:"#E6E0F8",
 - 		icon: "arrow-in.png"
 - 	});
 - </script>
 - <script type="text/x-red" data-help-name="AudioEffectFade">
 - 	<h3>Summary</h3>
 - 	<p>Gradually increase or decrease audio level.</p>
 - 	<h3>Audio Connections</h3>
 - 	<table class=doc align=center cellpadding=3>
 - 		<tr class=top><th>Port</th><th>Purpose</th></tr>
 - 		<tr class=odd><td align=center>In 0</td><td>Signal Input</td></tr>
 - 		<tr class=odd><td align=center>Out 0</td><td>Signal Output</td></tr>
 - 	</table>
 - 	<h3>Functions</h3>
 - 	<p class=func><span class=keyword>fadeIn</span>(milliseconds);</p>
 - 	<p class=desc>Begin increasing the audio level, to reach 1.0 (input passed
 - 		directly to the output) after "milliseconds" time.
 - 	</p>
 - 	<p class=func><span class=keyword>fadeOut</span>(milliseconds);</p>
 - 	<p class=desc>Begin decreasing the audio level, to reach 0 (no output)
 - 		after "milliseconds" time.
 - 	</p>
 - 	<h3>Notes</h3>
 - 	<p>Cross fading can be built with 2 fade objects fed into a mixer.
 - 		When one fade object is off (fully faded out) and the other on
 - 		(fully faded in), if both are started at the same moment for the
 - 		same time duration, their signal gains always add to 1.0.  This
 - 		allows 2 fade objects to work together for a smooth transition
 - 		between a pair of signals.
 - 	</p>
 - 	<p><a href="http://www.pjrc.com/teensy/td_libs_AudioProcessorUsage.html" target="_blank">AudioNoInterrupts()</a>
 - 		should be used when changing
 - 		settings on multiple objects, so all changes always take effect
 - 		at the same moment.
 - 	</p>
 - </script>
 - <script type="text/x-red" data-template-name="AudioEffectFade">
 - 	<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/javascript">
 - 	RED.nodes.registerType('AudioEffectChorus',{
 - 	shortName: "chorus",
 - 		inputs:2,
 - 		outputs:2,
 - 		category: 'effect-function',
 - 		color:"#E6E0F8",
 - 		icon: "arrow-in.png"
 - 	});
 - </script>
 - <script type="text/x-red" data-help-name="AudioEffectChorus">
 - 	<h3>Summary</h3>
 - 	<p>description</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></td><td></td></tr>
 - 	</table>
 - 	<!--<h3>Parameters</h3>
 - 	<table class=doc align=center cellpadding=3>
 - 		<tr class=top><th>Name</th><th>Type</th><th>Function</th></tr>
 - 		<tr class=odd><td align=center></td><td>Integer</td><td></td></tr>
 - 	</table>
 - 	<p>Extra description...  Section only present if object has params</p>-->
 - 	<h3>Functions</h3>
 - 	<p class=func><span class=keyword>begin</span>(delayBuffer, length, n_chorus);</p>
 - 	<p class=desc>blah blah blah blah
 - 	</p>
 - 	<p class=func><span class=keyword>stop</span>();</p>
 - 	<p class=desc>blah blah blah blah
 - 	</p>
 - 	<p class=func><span class=keyword>modify</span>(n_chorus);</p>
 - 	<p class=desc>blah blah blah blah
 - 	</p>
 - 	<h3>Notes</h3>
 - 	<p></p>
 - </script>
 - <script type="text/x-red" data-template-name="AudioEffectChorus">
 - 	<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/javascript">
 - 	RED.nodes.registerType('AudioEffectFlange',{
 - 	shortName: "flange",
 - 		inputs:2,
 - 		outputs:2,
 - 		category: 'effect-function',
 - 		color:"#E6E0F8",
 - 		icon: "arrow-in.png"
 - 	});
 - </script>
 - <script type="text/x-red" data-help-name="AudioEffectFlange">
 - 	<h3>Summary</h3>
 - 	<p>description</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></td><td></td></tr>
 - 	</table>
 - 	<!--<h3>Parameters</h3>
 - 	<table class=doc align=center cellpadding=3>
 - 		<tr class=top><th>Name</th><th>Type</th><th>Function</th></tr>
 - 		<tr class=odd><td align=center></td><td>Integer</td><td></td></tr>
 - 	</table>
 - 	<p>Extra description...  Section only present if object has params</p>-->
 - 	<h3>Functions</h3>
 - 	<p class=func><span class=keyword>begin</span>(delayBuffer, length, offset, depth, delayRate);</p>
 - 	<p class=desc>blah blah blah blah
 - 	</p>
 - 	<p class=func><span class=keyword>modify</span>(offset, depth, delayRate);</p>
 - 	<p class=desc>blah blah blah blah
 - 	</p>
 - 	<p class=func><span class=keyword>stop</span>();</p>
 - 	<p class=desc>blah blah blah blah
 - 	</p>
 - 	<h3>Notes</h3>
 - 	<p></p>
 - </script>
 - <script type="text/x-red" data-template-name="AudioEffectFlange">
 - 	<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/javascript">
 - 	RED.nodes.registerType('AudioEffectEnvelope',{
 - 	shortName: "envelope",
 - 		inputs:1,
 - 		outputs:1,
 - 		category: 'effect-function',
 - 		color:"#E6E0F8",
 - 		icon: "arrow-in.png"
 - 	});
 - </script>
 - <script type="text/x-red" data-help-name="AudioEffectEnvelope">
 - 	<h3>Summary</h3>
 - 	<div>
 - 	<p>Modify a signal with a DAHDSR (Delay Attack Hold Decay Sustain
 - 		Release) envelope.
 - 	</p>
 - 	<p align=center><img src="dahdsr.png"></p>
 - 	</div>
 - 	<h3>Audio Connections</h3>
 - 	<table class=doc align=center cellpadding=3>
 - 		<tr class=top><th>Port</th><th>Purpose</th></tr>
 - 		<tr class=odd><td align=center>In 0</td><td>Signal Input</td></tr>
 - 		<tr class=odd><td align=center>Out 0</td><td>Signal with Envelope Applied</td></tr>
 - 	</table>
 - 	<h3>Functions</h3>
 - 	<p class=func><span class=keyword>noteOn</span>();</p>
 - 	<p class=desc>Begin the delay to attack, or the attack phase is
 - 		delay is zero.
 - 	</p>
 - 	<p class=func><span class=keyword>noteOff</span>();</p>
 - 	<p class=desc>Begin the release phase.
 - 	</p>
 - 	<p class=func><span class=keyword>delay</span>(milliseconds);</p>
 - 	<p class=desc>Set the delay from noteOn to the attach phase.  The
 - 		default is zero, for no delay.
 - 	</p>
 - 	<p class=func><span class=keyword>attack</span>(milliseconds);</p>
 - 	<p class=desc>Set the attack time.  The default is 1.5 milliseconds.
 - 	</p>
 - 	<p class=func><span class=keyword>hold</span>(milliseconds);</p>
 - 	<p class=desc>Set the hold time.  The default is 0.5 milliseconds.
 - 	</p>
 - 	<p class=func><span class=keyword>decay</span>(milliseconds);</p>
 - 	<p class=desc>Set the decay time.  The default is 15 milliseconds.
 - 	</p>
 - 	<p class=func><span class=keyword>sustain</span>(level);</p>
 - 	<p class=desc>Set the sustain level.  The range is 0 to 1.0.  The
 - 		gain will be maintained at this level after the decay phase,
 - 		until noteOff() is called.
 - 	</p>
 - 	<p class=func><span class=keyword>release</span>(milliseconds);</p>
 - 	<p class=desc>Set the release time.  The default is 30 millisecond.
 - 	</p>
 - 	<h3>Notes</h3>
 - 	<p>To achieve the more common ADSR shape, simply
 -         set delay and hold to zero.</p>
 - 	<p>The recommended range for each of the 5 timing inputs is 0 to 50
 - 		milliseconds.  Up to 200 ms can be used, with somewhat reduced
 - 		accuracy</p>
 - </script>
 - <script type="text/x-red" data-template-name="AudioEffectEnvelope">
 - 	<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/javascript">
 - 	RED.nodes.registerType('AudioEffectMultiply',{
 - 	shortName: "multiply",
 - 		inputs:2,
 - 		outputs:1,
 - 		category: 'effect-function',
 - 		color:"#E6E0F8",
 - 		icon: "arrow-in.png"
 - 	});
 - </script>
 - <script type="text/x-red" data-help-name="AudioEffectMultiply">
 - 	<h3>Summary</h3>
 - 	<div>
 - 	<p>Multiply two signals together, useful for amplitude modulation
 - 		or "voltage controlled amplification".
 - 	</p>
 - 	<p align=center><img src="multiply.png"><br><small>56 Hz and 1 kHz sine waves multiplied.</small></p>
 - 	</div>
 - 	<h3>Audio Connections</h3>
 - 	<table class=doc align=center cellpadding=3>
 - 		<tr class=top><th>Port</th><th>Purpose</th></tr>
 - 		<tr class=odd><td align=center>In 0</td><td>Signal Input</td></tr>
 - 		<tr class=odd><td align=center>In 1</td><td>Signal Input</td></tr>
 - 		<tr class=odd><td align=center>Out 0</td><td>Signal with Envelope Applied</td></tr>
 - 	</table>
 - 	<h3>Functions</h3>
 - 	<p>There are no functions to call from the Arduino sketch.
 - 		This object simply multiplies the 2 signals to create
 - 		a continuous output
 - 	</p>
 - 	<h3>Notes</h3>
 - 	<p>
 -     </p>
 - </script>
 - <script type="text/x-red" data-template-name="AudioEffectMultiply">
 - 	<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/javascript">
 - 	RED.nodes.registerType('AudioEffectDelay',{
 - 	shortName: "delay",
 - 		inputs:1,
 - 		outputs:8,
 - 		category: 'effect-function',
 - 		color:"#E6E0F8",
 - 		icon: "arrow-in.png"
 - 	});
 - </script>
 - <script type="text/x-red" data-help-name="AudioEffectDelay">
 - 	<h3>Summary</h3>
 - 	<div>
 - 	<p>Delay a signal.  Up to 8 separate delay taps can be used.</p>
 - 	<p align=center><img src="delay.png"><br><small>1 kHz burst, delayed 5.2 ms.</small></p>
 - 	</div>
 - 	<h3>Audio Connections</h3>
 - 	<table class=doc align=center cellpadding=3>
 - 		<tr class=top><th>Port</th><th>Purpose</th></tr>
 - 		<tr class=odd><td align=center>In 0</td><td>Signal Input</td></tr>
 - 		<tr class=odd><td align=center>Out 0</td><td>Delay Tap #1</td></tr>
 - 		<tr class=odd><td align=center>Out 1</td><td>Delay Tap #2</td></tr>
 - 		<tr class=odd><td align=center>Out 2</td><td>Delay Tap #3</td></tr>
 - 		<tr class=odd><td align=center>Out 3</td><td>Delay Tap #4</td></tr>
 - 		<tr class=odd><td align=center>Out 4</td><td>Delay Tap #5</td></tr>
 - 		<tr class=odd><td align=center>Out 5</td><td>Delay Tap #6</td></tr>
 - 		<tr class=odd><td align=center>Out 6</td><td>Delay Tap #7</td></tr>
 - 		<tr class=odd><td align=center>Out 7</td><td>Delay Tap #8</td></tr>
 - 	</table>
 - 	<h3>Functions</h3>
 - 	<p class=func><span class=keyword>delay</span>(channel, milliseconds);</p>
 - 	<p class=desc>Set output channel (0 to 7) to delay the signals by
 - 		milliseconds.  The maximum delay is approx 333 ms.  The actual delay
 - 		is rounded to the nearest sample.  Each channel can be configured for
 - 		any delay.  There is no requirement to configure the "taps" in increasing
 - 		delay order.
 - 	</p>
 - 	<p class=func><span class=keyword>disable</span>(channel);</p>
 - 	<p class=desc>Disable a channel.  The output of this channel becomes
 - 		silent.  If this channel is the longest delay, memory usage is
 - 		automatically reduced to accomodate only the remaining channels used.
 - 	</p>
 - 	<h3>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">
 - 	<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/javascript">
 - 	RED.nodes.registerType('AudioFilterBiquad',{
 - 	shortName: "biquad",
 - 		inputs:1,
 - 		outputs:1,
 - 		category: 'filter-function',
 - 		color:"#E6E0F8",
 - 		icon: "arrow-in.png"
 - 	});
 - </script>
 - <script type="text/x-red" data-help-name="AudioFilterBiquad">
 - 	<h3>Summary</h3>
 - 	<p>description</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></td><td></td></tr>
 - 	</table>
 - 	<h3>Parameters</h3>
 - 	<table class=doc align=center cellpadding=3>
 - 		<tr class=top><th>Name</th><th>Type</th><th>Function</th></tr>
 - 		<tr class=odd><td align=center></td><td>Integer</td><td></td></tr>
 - 	</table>
 - 	<p>Extra description...  Section only present if object has params</p>
 - 	<h3>Functions</h3>
 - 	<p class=func><span class=keyword>function</span>(parm1, parm2);</p>
 - 	<p class=desc>blah blah blah blah
 - 	</p>
 - 	<h3>Notes</h3>
 - 	<p></p>
 - </script>
 - <script type="text/x-red" data-template-name="AudioFilterBiquad">
 - 	<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/javascript">
 - 	RED.nodes.registerType('AudioFilterFIR',{
 - 	shortName: "fir",
 - 		inputs:1,
 - 		outputs:1,
 - 		category: 'filter-function',
 - 		color:"#E6E0F8",
 - 		icon: "arrow-in.png"
 - 	});
 - </script>
 - <script type="text/x-red" data-help-name="AudioFilterFIR">
 - 	<h3>Summary</h3>
 - 	<p>description</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></td><td></td></tr>
 - 	</table>
 - 	<!--<h3>Parameters</h3>
 - 	<table class=doc align=center cellpadding=3>
 - 		<tr class=top><th>Name</th><th>Type</th><th>Function</th></tr>
 - 		<tr class=odd><td align=center></td><td>Integer</td><td></td></tr>
 - 	</table>
 - 	<p>Extra description...  Section only present if object has params</p>-->
 - 	<h3>Functions</h3>
 - 	<p class=func><span class=keyword>function</span>(parm1, parm2);</p>
 - 	<p class=desc>blah blah blah blah
 - 	</p>
 - 	<h3>Notes</h3>
 - 	<p></p>
 - </script>
 - <script type="text/x-red" data-template-name="AudioFilterFIR">
 - 	<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/javascript">
 - 	RED.nodes.registerType('AudioFilterStateVariable',{
 - 	shortName: "filter",
 - 		inputs:2,
 - 		outputs:3,
 - 		category: 'filter-function',
 - 		color:"#E6E0F8",
 - 		icon: "arrow-in.png"
 - 	});
 - </script>
 - <script type="text/x-red" data-help-name="AudioFilterStateVariable">
 - 	<h3>Summary</h3>
 - 	<p>A State Variable (Chamberlin) Filter with 12 dB/octave roll-off,
 - 		adjustable resonance, and optional signal control of corner
 - 		frequency.</p>
 - 	<h3>Audio Connections</h3>
 - 	<table class=doc align=center cellpadding=3>
 - 		<tr class=top><th>Port</th><th>Purpose</th></tr>
 - 		<tr class=odd><td align=center>In 0</td><td>Signal to Filter</td></tr>
 - 		<tr class=odd><td align=center>In 1</td><td>Frequency Control</td></tr>
 - 		<tr class=odd><td align=center>Out 0</td><td>Low Pass Output</td></tr>
 - 		<tr class=odd><td align=center>Out 1</td><td>Band Pass Output</td></tr>
 - 		<tr class=odd><td align=center>Out 2</td><td>High Pass Output</td></tr>
 - 	</table>
 - 	<h3>Functions</h3>
 - 	<p class=func><span class=keyword>frequency</span>(freq);</p>
 - 	<p class=desc>Set the filter's corner frequency.  When a signal is
 - 		connected to the control input, the filter will implement this
 - 		frequency when the signal is zero.
 - 	</p>
 - 	<p class=func><span class=keyword>resonance</span>(Q);</p>
 - 	<p class=desc>Set the filter's resonance.  Q ranges from 0.7 to 5.0.
 - 		Resonance greater than 0.707 will amplify the signal near the
 - 		corner frequency.  You must attenuate the signal before input
 - 		to this filter, to prevent clipping.
 - 	</p>
 - 	<p class=func><span class=keyword>octaveControl</span>(octaves);</p>
 - 	<p class=desc>Set how much (in octaves) the control signal can alter
 - 		the filter's corner freqency.  Range is 0 to 7 octaves.  For
 - 		example, when set to 2.5, a full scale positive signal (1.0) will
 - 		shift the filter frequency up 2.5 octaves, and a full scale negative
 - 		signal will shift it down 2.5 octaves.
 - 	</p>
 - 	<h3>Notes</h3>
 - 	<p>
 - 		When controlled by a signal, the equation for the filter
 - 		frequency is:
 - 	</p>
 - 	<p>
 - 		F = Fcenter * 2^<sup>(signal * octaves)</sup>
 - 		<br><small>If anyone knows how to do HTML equations, please
 - 		help me improve this.....</small>
 - 	</p>
 - 	<p>When operating with signal control of corner frequency, this
 - 		object uses approximately 4% of the CPU time on Teensy 3.1.
 - 	</p>
 - </script>
 - <script type="text/x-red" data-template-name="AudioFilterFIR">
 - 	<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/javascript">
 - 	RED.nodes.registerType('AudioAnalyzePeak',{
 - 	shortName: "peak",
 - 		inputs:1,
 - 		outputs:0,
 - 		category: 'analyze-function',
 - 		color:"#E6E0F8",
 - 		icon: "arrow-in.png"
 - 	});
 - </script>
 - <script type="text/x-red" data-help-name="AudioAnalyzePeak">
 - 	<h3>Summary</h3>
 - 	<p>description</p>
 - 	<h3>Audio Connections</h3>
 - 	<table class=doc align=center cellpadding=3>
 - 		<tr class=top><th>Port</th><th>Purpose</th></tr>
 - 		<tr class=odd><td align=center>In 0</td><td>Signal to analyze</td></tr>
 - 	</table>
 - 	<h3>Functions</h3>
 - 	<p class=func><span class=keyword>available</span>();</p>
 - 	<p class=desc>Returns true each time new peak data is available.
 - 	</p>
 - 	<p class=func><span class=keyword>read</span>();</p>
 - 	<p class=desc>Read the highest peak value since the last read.
 - 		Return is from 0.0 to 1.0.
 - 	</p>
 - 	<h3>Notes</h3>
 - 	<p></p>
 - </script>
 - <script type="text/x-red" data-template-name="AudioAnalyzePeak">
 - 	<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/javascript">
 - 	RED.nodes.registerType('AudioAnalyzeFFT256',{
 - 	shortName: "fft256",
 - 		inputs:1,
 - 		outputs:0,
 - 		category: 'analyze-function',
 - 		color:"#E6E0F8",
 - 		icon: "arrow-in.png"
 - 	});
 - </script>
 - <script type="text/x-red" data-help-name="AudioAnalyzeFFT256">
 - 	<h3>Summary</h3>
 - 	<p>Compute a 256 point Fast Fourier Transform (FFT) frequency analysis,
 - 		with real value (magnitude) output.  The frequency resolution is
 - 		172 Hz, useful for simple audio visualization.</p>
 - 	<h3>Audio Connections</h3>
 - 	<table class=doc align=center cellpadding=3>
 - 		<tr class=top><th>Port</th><th>Purpose</th></tr>
 - 		<tr class=odd><td align=center>In 0</td><td>Signal to convert to frequency bins</td></tr>
 - 	</table>
 - 	<h3>Functions</h3>
 - 	<p class=func><span class=keyword>available</span>();</p>
 - 	<p class=desc>Returns true each time the FFT analysis produces new output data.
 - 	</p>
 - 	<p class=func><span class=keyword>read</span>(binNumber);</p>
 - 	<p class=desc>Read a single frequency bin, from 0 to 127.  The result is scaled
 - 		so 1.0 represents a full scale sine wave.
 - 	</p>
 - 	<p class=func><span class=keyword>read</span>(firstBin, lastBin);</p>
 - 	<p class=desc>Read several frequency bins, returning their sum.  The higher
 - 		audio octaves are represented by many bins, which are typically read
 - 		as a group for audio visualization.
 - 	</p>
 - 	<p class=func><span class=keyword>averageTogether</span>(number);</p>
 - 	<p class=desc>New data is produced very radidly, approximately 344 times
 - 		per second.  Multiple outputs can be averaged together, so available()
 - 		returns true at a slower rate.
 - 	</p>
 - 	<p class=func><span class=keyword>windowFunction</span>(window);</p>
 - 	<p class=desc>Set the window function to be used.  AudioWindowHanning256
 - 		is the default.  Windowing may be disabled by NULL, but windowing
 - 		should be used for all non-periodic (music) signals, and all periodic
 - 		signals that are not exact integer division of the sample rate.
 - 	</p>
 - 
 - 	<h3>Notes</h3>
 - 	<p>The raw 16 bit output data bins may be access with myFFT.output[num], where
 - 		num is 0 to 127.</p>
 - 	<p>TODO: caveats about spectral leakage vs frequency precision for arbitrary signals</p>
 - 	<p>Window Types:
 - 		<ul>
 - 		<li><span class=literal>AudioWindowHanning256</span> (default)</li>
 - 		<li><span class=literal>AudioWindowBartlett256</span></li>
 - 		<li><span class=literal>AudioWindowBlackman256</span></li>
 - 		<li><span class=literal>AudioWindowFlattop256</span></li>
 - 		<li><span class=literal>AudioWindowBlackmanHarris256</span></li>
 - 		<li><span class=literal>AudioWindowNuttall256</span></li>
 - 		<li><span class=literal>AudioWindowBlackmanNuttall256</span></li>
 - 		<li><span class=literal>AudioWindowWelch256</span></li>
 - 		<li><span class=literal>AudioWindowHamming256</span></li>
 - 		<li><span class=literal>AudioWindowCosine256</span></li>
 - 		<li><span class=literal>AudioWindowTukey256</span></li>
 - 		</ul>
 - 	</p>
 - </script>
 - <script type="text/x-red" data-template-name="AudioAnalyzeFFT256">
 - 	<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/javascript">
 - 	RED.nodes.registerType('AudioAnalyzeFFT1024',{
 - 	shortName: "fft1024",
 - 		inputs:1,
 - 		outputs:0,
 - 		category: 'analyze-function',
 - 		color:"#E6E0F8",
 - 		icon: "arrow-in.png"
 - 	});
 - </script>
 - <script type="text/x-red" data-help-name="AudioAnalyzeFFT1024">
 - 	<h3>Summary</h3>
 - 	<p>Compute a 1024 point Fast Fourier Transform (FFT) frequency analysis,
 - 		with real value (magnitude) output.  The frequency resolution is
 - 		43 Hz, useful detailed for audio visualization.</p>
 - 	<h3>Audio Connections</h3>
 - 	<table class=doc align=center cellpadding=3>
 - 		<tr class=top><th>Port</th><th>Purpose</th></tr>
 - 		<tr class=odd><td align=center>In 0</td><td>Signal to convert to frequency bins</td></tr>
 - 	</table>
 - 	<h3>Functions</h3>
 - 	<p class=func><span class=keyword>available</span>();</p>
 - 	<p class=desc>Returns true each time the FFT analysis produces new output data.
 - 	</p>
 - 	<p class=func><span class=keyword>read</span>(binNumber);</p>
 - 	<p class=desc>Read a single frequency bin, from 0 to 511.  The result is scaled
 - 		so 1.0 represents a full scale sine wave.
 - 	</p>
 - 	<p class=func><span class=keyword>read</span>(firstBin, lastBin);</p>
 - 	<p class=desc>Read several frequency bins, returning their sum.  The higher
 - 		audio octaves are represented by many bins, which are typically read
 - 		as a group for audio visualization.
 - 	</p>
 - 	<p class=func><span class=keyword>averageTogether</span>(number);</p>
 - 	<p class=desc>This function does nothing.  The 1024 point FFT always
 - 		updates at approximately 86 times per second.
 - 	</p>
 - 	<p class=func><span class=keyword>windowFunction</span>(window);</p>
 - 	<p class=desc>Set the window function to be used.  AudioWindowHanning1024
 - 		is the default.  Windowing may be disabled by NULL, but windowing
 - 		should be used for all non-periodic (music) signals, and all periodic
 - 		signals that are not exact integer division of the sample rate.
 - 	</p>
 - 	<h3>Notes</h3>
 - 	<p>The raw 16 bit output data bins may be access with myFFT.output[num], where
 - 		num is 0 to 511.</p>
 - 	<p>TODO: caveats about spectral leakage vs frequency precision for arbitrary signals</p>
 - 	<p>Window Types:
 - 		<ul>
 - 		<li><span class=literal>AudioWindowHanning1024</span> (default)</li>
 - 		<li><span class=literal>AudioWindowBartlett1024</span></li>
 - 		<li><span class=literal>AudioWindowBlackman1024</span></li>
 - 		<li><span class=literal>AudioWindowFlattop1024</span></li>
 - 		<li><span class=literal>AudioWindowBlackmanHarris1024</span></li>
 - 		<li><span class=literal>AudioWindowNuttall1024</span></li>
 - 		<li><span class=literal>AudioWindowBlackmanNuttall1024</span></li>
 - 		<li><span class=literal>AudioWindowWelch1024</span></li>
 - 		<li><span class=literal>AudioWindowHamming1024</span></li>
 - 		<li><span class=literal>AudioWindowCosine1024</span></li>
 - 		<li><span class=literal>AudioWindowTukey1024</span></li>
 - 		</ul>
 - 	</p>
 - 	<p>1024 point FFT has a peak CPU usage of approx 52% on Teensy 3.1.
 - 		Average usage is much lower.  Future versions might distribute the
 - 		load more evenly over time....
 - 	</p>
 - </script>
 - <script type="text/x-red" data-template-name="AudioAnalyzeFFT1024">
 - 	<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/javascript">
 - 	RED.nodes.registerType('AudioAnalyzeToneDetect',{
 - 	shortName: "tone",
 - 		inputs:1,
 - 		outputs:0,
 - 		category: 'analyze-function',
 - 		color:"#E6E0F8",
 - 		icon: "arrow-in.png"
 - 	});
 - </script>
 - <script type="text/x-red" data-help-name="AudioAnalyzeToneDetect">
 - 	<h3>Summary</h3>
 - 	<p>Detect the level of a single tone</p>
 - 	<h3>Audio Connections</h3>
 - 	<table class=doc align=center cellpadding=3>
 - 		<tr class=top><th>Port</th><th>Purpose</th></tr>
 - 		<tr class=odd><td align=center>In 0</td><td>Signal to analyze</td></tr>
 - 	</table>
 - 	<h3>Functions</h3>
 - 	<p class=func><span class=keyword>frequency</span>(freq);</p>
 - 	<p class=desc>Set the frequency to detect.  The default detection time
 - 		will be 10 cycles of this frequency.
 - 	</p>
 - 	<p class=func><span class=keyword>frequency</span>(freq, cycles);</p>
 - 	<p class=desc>Set the frequency to detect, and the number of cycles.
 - 		Longer detection time (more cycles) will give higher precision,
 - 		but of course slower response.
 - 	</p>
 - 	<p class=func><span class=keyword>available</span>();</p>
 - 	<p class=desc>Returns true (non-zero) each time a detection interval
 - 		(number of cycles) completed and a new level is detected.
 - 	</p>
 - 	<p class=func><span class=keyword>read</span>();</p>
 - 	<p class=desc>Read the detected signal level.  Range is 0 to 1.0.
 - 	</p>
 - 	<p class=func><span class=keyword>threshold</span>(level);</p>
 - 	<p class=desc>Set a detection threshold, where the bool test operation
 - 		will return true if at or above this level, or false when below.
 - 	</p>
 - 	<p class=func>(bool)</p>
 - 	<p class=desc>By testing the object as a boolean value, you can respond
 - 		to detection of a tone.
 - 	</p>
 - 	<h3>Notes</h3>
 - 	<p>Low frequency detection has trouble with numerical precision.
 - 		Works really well for all 8 DTMF frequencies, but fails for
 - 		detecting "sub audible tones" used in some control applications.</p>
 - 	<p>The (bool) test continues to return true until the next detection
 - 		interval (the configured number of cycles).  This behavior may
 - 		change in future versions, for a single true each time the signal
 - 		is detected, and then false for the remainder of that interval.</p>
 - </script>
 - <script type="text/x-red" data-template-name="AudioAnalyzeToneDetect">
 - 	<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/javascript">
 - 	RED.nodes.registerType('AudioAnalyzePrint',{
 - 	shortName: "print",
 - 		inputs:1,
 - 		outputs:0,
 - 		category: 'analyze-function',
 - 		color:"#E6E0F8",
 - 		icon: "arrow-in.png"
 - 	});
 - </script>
 - <script type="text/x-red" data-help-name="AudioAnalyzePrint">
 - 	<h3>Summary</h3>
 - 	<p>Print raw audio data to the Arduino Serial Monitor.  This
 - 		object creates massive output quickly, and should not normall be used.</p>
 - 	<h3>Audio Connections</h3>
 - 	<table class=doc align=center cellpadding=3>
 - 		<tr class=top><th>Port</th><th>Purpose</th></tr>
 - 		<tr class=odd><td align=center></td><td></td></tr>
 - 	</table>
 - 	<!--<h3>Parameters</h3>
 - 	<table class=doc align=center cellpadding=3>
 - 		<tr class=top><th>Name</th><th>Type</th><th>Function</th></tr>
 - 		<tr class=odd><td align=center></td><td>Integer</td><td></td></tr>
 - 	</table>
 - 	<p>Extra description...  Section only present if object has params</p>-->
 - 	<h3>Functions</h3>
 - 	<p class=func><span class=keyword>name</span>(string);</p>
 - 	<p class=desc>blah blah blah blah
 - 	</p>
 - 	<p class=func><span class=keyword>trigger</span>();</p>
 - 	<p class=desc>blah blah blah blah
 - 	</p>
 - 	<p class=func><span class=keyword>trigger</span>(level, edge);</p>
 - 	<p class=desc>blah blah blah blah
 - 	</p>
 - 	<p class=func><span class=keyword>delay</span>(samples);</p>
 - 	<p class=desc>blah blah blah blah
 - 	</p>
 - 	<p class=func><span class=keyword>length</span>(samples);</p>
 - 	<p class=desc>blah blah blah blah
 - 	</p>
 - 	<h3>Notes</h3>
 - 	<p></p>
 - </script>
 - <script type="text/x-red" data-template-name="AudioAnalyzePrint">
 - 	<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/javascript">
 - 	RED.nodes.registerType('AudioControlSGTL5000',{
 - 	shortName: "sgtl5000",
 - 		inputs:0,
 - 		outputs:0,
 - 		category: 'control-function',
 - 		color:"#E6E0F8",
 - 		icon: "arrow-in.png"
 - 	});
 - </script>
 - <script type="text/x-red" data-help-name="AudioControlSGTL5000">
 - 	<h3>Summary</h3>
 - 	<p>Control the SGTL5000 chip on the audio shield
 - 		<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="sgtl5000closeup.jpg"></p>
 - 	<h3>Audio Connections</h3>
 - 	<p>This object has no audio inputs or outputs.  Separate i2s objects
 - 		are used to send and receive audio data.  I2S master mode objects
 - 		must be used, because this object configures the SGTL5000 in slave
 - 		mode, where it depends on Teensy to provide all I2S clocks.
 - 		This object controls
 - 		how the SGTL5000 will use those I2S audio streams.</p>
 - 
 - 	<h3>Functions</h3>
 - 	<p>These are the most commonly used SGTL5000 functions.</p>
 - 	<p class=func><span class=keyword>enable</span>();</p>
 - 	<p class=desc>Start the SGTL5000.  This function should be called first.
 - 	</p>
 - 	<p class=func><span class=keyword>volume</span>(level);</p>
 - 	<p class=desc>Set the headphone volume level.  Range is 0 to 1.0, but
 - 		0.8 corresponds to the maximum undistorted output for a full scale
 - 		signal.  Usually 0.5 is a comfortable listening level.  The line
 - 		level outputs are not 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 outout 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 DC component is still substracted, but
 - 		the filter stops tracking any DC or low frequency changes.
 - 	</p>
 - 	<p class=func><span class=keyword>adcHighPassFilterDisable</span>();</p>
 - 	<p class=desc>Completely disable the analog input filter.  DC and sub-audible
 - 		low frequencies are allowed to enter the digital signal.
 - 	</p>
 - 	<p class=func><span class=keyword>adcHighPassFilterEnable</span>();</p>
 - 	<p class=desc>Turn the DC-blocking filter back on, if disabled, or
 - 		allows it to resume tracking DC and low frequency changes, if
 - 		previously frozen.
 - 	</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
 - 		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 at 1.0.
 - 	</p>
 - 	<p class=func><span class=keyword>dacVolume</span>(left, right);</p>
 - 	<p class=desc>Adjust the digital output volume separately on left and
 - 		right channels.
 - 	</p>
 - 
 - 
 - 	<h3>Audio Processor</h3>
 - 
 - 	<p>The optional digital audio processor is capable of implementing 
 - 		automatic volume control, a
 - 		simple equalizer, filtering, bass enhancement and surround sound
 - 		is available.
 - 	</p>
 - 	<p>These signal processing features are implemented in the SGTL5000 chip,
 - 		so they do not consume CPU time on Teensy.
 - 	</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>eqFilterCount</span>(n);</p>
 - 	<p class=desc>blah blah blah blah
 - 	</p>
 - 	<p class=func><span class=keyword>eqSelect</span>(n);</p>
 - 	<p class=desc>blah blah blah blah
 - 	</p>
 - 	<p class=func><span class=keyword>eqBand</span>(bandNum, n);</p>
 - 	<p class=desc>blah blah blah blah
 - 	</p>
 - 	<p class=func><span class=keyword>eqBands</span>(bass, mid_bass, midrange, mid_treble, treble);</p>
 - 	<p class=desc>blah blah blah blah
 - 	</p>
 - 	<p class=func><span class=keyword>eqBands</span>(bass, treble);</p>
 - 	<p class=desc>blah blah blah blah
 - 	</p>
 - 	<p class=func><span class=keyword>eqFilter</span>(filterNum, filterParameters);</p>
 - 	<p class=desc>blah blah blah blah
 - 	</p>
 - 	<p class=func><span class=keyword>autoVolumeControl</span>(maxGain, response, hardLimit, threshold, attack, decay);</p>
 - 	<p class=desc>blah blah blah blah
 - 	</p>
 - 	<p class=func><span class=keyword>autoVolumeEnable</span>();</p>
 - 	<p class=desc>blah blah blah blah
 - 	</p>
 - 	<p class=func><span class=keyword>autoVolumeDisable</span>();</p>
 - 	<p class=desc>blah blah blah blah
 - 	</p>
 - 	<p class=func><span class=keyword>enhanceBass</span>(lr_lev, bass_lev);</p>
 - 	<p class=desc>blah blah blah blah
 - 	</p>
 - 	<p class=func><span class=keyword>enhanceBass</span>(lr_lev, bass_lev, hpf_bypass, cutoff);</p>
 - 	<p class=desc>blah blah blah blah
 - 	</p>
 - 	<p class=func><span class=keyword>enhanceBassEnable</span>();</p>
 - 	<p class=desc>blah blah blah blah
 - 	</p>
 - 	<p class=func><span class=keyword>enhanceBassDisable</span>();</p>
 - 	<p class=desc>blah blah blah blah
 - 	</p>
 - 	<p class=func><span class=keyword>surroundSound</span>(width);</p>
 - 	<p class=desc>blah blah blah blah
 - 	</p>
 - 	<p class=func><span class=keyword>surroundSound</span>(width, select);</p>
 - 	<p class=desc>blah blah blah blah
 - 	</p>
 - 	<p class=func><span class=keyword>surroundSoundEnable</span>();</p>
 - 	<p class=desc>blah blah blah blah
 - 	</p>
 - 	<p class=func><span class=keyword>surroundSoundDisable</span>();</p>
 - 	<p class=desc>blah blah blah blah
 - 	</p>
 - 	<h3>Notes</h3>
 - 	<p>TODO: document the many audio processor features & functions!
 - 	</p>
 - </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/javascript">
 - 	RED.nodes.registerType('AudioControlWM8731',{
 - 	shortName: "wm8731",
 - 		inputs:0,
 - 		outputs:0,
 - 		category: 'control-function',
 - 		color:"#E6E0F8",
 - 		icon: "arrow-in.png"
 - 	});
 - </script>
 - <script type="text/x-red" data-help-name="AudioControlWM8731">
 - 	<h3>Summary</h3>
 - 	<p>Control a WM8731 chip in slave mode, where it receives all clocks from Teensy</p>
 - 	<h3>Audio Connections</h3>
 - 	<p>This object has no audio inputs or outputs.  Separate i2s objects
 - 		are used to send and receive audio data.  I2S master mode objects
 - 		must be used, since this control object configures the WM8731 into 
 - 		slave mode.
 - 	</p>
 - 	<h3>Functions</h3>
 - 	<p class=func><span class=keyword>enable</span>();</p>
 - 	<p class=desc>blah blah blah blah
 - 	</p>
 - 	<p class=func><span class=keyword>disable</span>();</p>
 - 	<p class=desc>not implemented
 - 	</p>
 - 	<p class=func><span class=keyword>volume</span>(level);</p>
 - 	<p class=desc>blah blah blah blah
 - 	</p>
 - 	<p class=func><span class=keyword>inputLevel</span>(level);</p>
 - 	<p class=desc>not implemented
 - 	</p>
 - 	<p class=func><span class=keyword>inputSelect</span>(input);</p>
 - 	<p class=desc>not implemented
 - 	</p>
 - 	<h3>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/javascript">
 - 	RED.nodes.registerType('AudioControlWM8731master',{
 - 	shortName: "wm8731m",
 - 		inputs:0,
 - 		outputs:0,
 - 		category: 'control-function',
 - 		color:"#E6E0F8",
 - 		icon: "arrow-in.png"
 - 	});
 - </script>
 - <script type="text/x-red" data-help-name="AudioControlWM8731master">
 - 	<h3>Summary</h3>
 - 	<p>Control a WM8731 chip in master mode, where it controls all I2S timing.</p>
 - 	<h3>Audio Connections</h3>
 - 	<p>This object has no audio inputs or outputs.  Separate i2s objects
 - 		are used to send and receive audio data.  I2S slave mode objects
 - 		must be used, since this control object configures the WM8731 into
 - 		master mode.
 - 	</p>
 - 	<h3>Functions</h3>
 - 	<p class=func><span class=keyword>enable</span>();</p>
 - 	<p class=desc>blah blah blah blah
 - 	</p>
 - 	<p class=func><span class=keyword>disable</span>();</p>
 - 	<p class=desc>not implemented
 - 	</p>
 - 	<p class=func><span class=keyword>volume</span>(level);</p>
 - 	<p class=desc>blah blah blah blah
 - 	</p>
 - 	<p class=func><span class=keyword>inputLevel</span>(level);</p>
 - 	<p class=desc>not implemented
 - 	</p>
 - 	<p class=func><span class=keyword>inputSelect</span>(input);</p>
 - 	<p class=desc>not implemented
 - 	</p>
 - 	<h3>Notes</h3>
 - 	<p></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>
 - 
 - 
 - 
 - 
 - 
 - 
 - 
 - 
 
 
  |