Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Make AudioOutputSPDIF3 sync to AudioInputSPDIF3 to avoid glitches #446

Open
wants to merge 20 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
0697e6d
Make AudioOutputSPDIF3 sync to AudioInputSPDIF3 to avoid glitches
h4yn0nnym0u5e Sep 18, 2022
6f7f2cf
Merge branch 'PaulStoffregen:master' into feature/sync-SPDIF-IO2
h4yn0nnym0u5e Sep 18, 2022
81a7262
Make syncToInput flag private
h4yn0nnym0u5e Sep 18, 2022
7bbbbbb
Merge branch 'feature/sync-SPDIF-IO2' of https://github.com/h4yn0nnym…
h4yn0nnym0u5e Sep 18, 2022
2bb4e53
Info pane update for SPDIF3 objects
h4yn0nnym0u5e Sep 19, 2022
25ab85e
Fix S/PDIF Tx clock to follow Rx clock
h4yn0nnym0u5e Oct 8, 2022
5df2c36
Correct internally-clocked S/PDIF output
h4yn0nnym0u5e Oct 8, 2022
3849eed
Fix issue with sensitivity to instantiation order
h4yn0nnym0u5e Oct 10, 2022
af4ea73
And some more instantiation order fixes!
h4yn0nnym0u5e Oct 10, 2022
5c8fe25
Remove resource clash indicators
h4yn0nnym0u5e Oct 12, 2022
e65310b
Document improved compatibility in info pane
h4yn0nnym0u5e Oct 16, 2022
2feb851
Merge branch 'feature/sync-SPDIF-IO2' of https://github.com/h4yn0nnym…
h4yn0nnym0u5e Oct 16, 2022
02dbac2
Merge branch 'feature/sync-SPDIF-IO2' of https://github.com/h4yn0nnym…
h4yn0nnym0u5e Oct 17, 2022
7e1d128
Various tries at getting S/PDIF MCLK master
h4yn0nnym0u5e Oct 19, 2022
3de0215
Fix issue with BCLK startup
h4yn0nnym0u5e Oct 19, 2022
168926e
Tidy up and update Design Tool info
h4yn0nnym0u5e Oct 21, 2022
d0f30cb
Updated documentation
h4yn0nnym0u5e Nov 14, 2022
07de5bd
Merge branch 'feature/sync-SPDIF-IO2' of https://github.com/h4yn0nnym…
h4yn0nnym0u5e Nov 14, 2022
64ac682
Merge branch 'PaulStoffregen:master' into feature/sync-SPDIF-IO2
h4yn0nnym0u5e Dec 29, 2022
8e47bb3
Merge branch 'PaulStoffregen:master' into feature/sync-SPDIF-IO2
h4yn0nnym0u5e Sep 13, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
88 changes: 76 additions & 12 deletions gui/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -345,19 +345,19 @@ <h5 id="node-help-label">Keyboard Shortcuts <span style="float: right;"><a href=
<script type="text/x-red" data-container-name="InputOutputCompatibilityMetadata">
{"requirements":[
{"type":"AudioInputI2S", "resource":"I2S Device", "shareable":true, "setting":"I2S Master"},
{"type":"AudioInputI2S", "resource":"Sample Rate", "shareable":true, "setting":"Teensy Control"},
{"type":"AudioInputI2S", "resource":"Sample Rate", "shareable":true, "setting":["Teensy Control", "SPDIF Control"]},
{"type":"AudioInputI2S", "resource":"IN1 Pin", "shareable":false},
{"type":"AudioInputI2SQuad", "resource":"I2S Device", "shareable":true, "setting":"I2S Master"},
{"type":"AudioInputI2SQuad", "resource":"Sample Rate", "shareable":true, "setting":"Teensy Control"},
{"type":"AudioInputI2SQuad", "resource":"Sample Rate", "shareable":true, "setting":["Teensy Control", "SPDIF Control"]},
{"type":"AudioInputI2SQuad", "resource":"IN1 Pin", "shareable":false},
{"type":"AudioInputI2SQuad", "resource":"OUT1D Pin", "shareable":false},
{"type":"AudioInputI2SHex", "resource":"I2S Device", "shareable":true, "setting":"I2S Master"},
{"type":"AudioInputI2SHex", "resource":"Sample Rate", "shareable":true, "setting":"Teensy Control"},
{"type":"AudioInputI2SHex", "resource":"Sample Rate", "shareable":true, "setting":["Teensy Control", "SPDIF Control"]},
{"type":"AudioInputI2SHex", "resource":"IN1 Pin", "shareable":false},
{"type":"AudioInputI2SHex", "resource":"OUT1D Pin", "shareable":false},
{"type":"AudioInputI2SHex", "resource":"OUT1C Pin", "shareable":false},
{"type":"AudioInputI2SOct", "resource":"I2S Device", "shareable":true, "setting":"I2S Master"},
{"type":"AudioInputI2SOct", "resource":"Sample Rate", "shareable":true, "setting":"Teensy Control"},
{"type":"AudioInputI2SOct", "resource":"Sample Rate", "shareable":true, "setting":["Teensy Control", "SPDIF Control"]},
{"type":"AudioInputI2SOct", "resource":"IN1 Pin", "shareable":false},
{"type":"AudioInputI2SOct", "resource":"OUT1D Pin", "shareable":false},
{"type":"AudioInputI2SOct", "resource":"OUT1C Pin", "shareable":false},
Expand Down Expand Up @@ -393,19 +393,19 @@ <h5 id="node-help-label">Keyboard Shortcuts <span style="float: right;"><a href=
{"type":"AudioInputTDM2", "resource":"IN2 Pin", "shareable":false},
{"type":"AudioInputUSB", "resource":"USB Rx Endpoint","shareable":false},
{"type":"AudioOutputI2S", "resource":"I2S Device", "shareable":true, "setting":"I2S Master"},
{"type":"AudioOutputI2S", "resource":"Sample Rate", "shareable":true, "setting":"Teensy Control"},
{"type":"AudioOutputI2S", "resource":"Sample Rate", "shareable":true, "setting":["Teensy Control", "SPDIF Control"]},
{"type":"AudioOutputI2S", "resource":"OUT1A Pin", "shareable":false},
{"type":"AudioOutputI2SQuad", "resource":"I2S Device", "shareable":true, "setting":"I2S Master"},
{"type":"AudioOutputI2SQuad", "resource":"Sample Rate", "shareable":true, "setting":"Teensy Control"},
{"type":"AudioOutputI2SQuad", "resource":"Sample Rate", "shareable":true, "setting":["Teensy Control", "SPDIF Control"]},
{"type":"AudioOutputI2SQuad", "resource":"OUT1A Pin", "shareable":false},
{"type":"AudioOutputI2SQuad", "resource":"OUT1B Pin", "shareable":false},
{"type":"AudioOutputI2SHex", "resource":"I2S Device", "shareable":true, "setting":"I2S Master"},
{"type":"AudioOutputI2SHex", "resource":"Sample Rate", "shareable":true, "setting":"Teensy Control"},
{"type":"AudioOutputI2SHex", "resource":"Sample Rate", "shareable":true, "setting":["Teensy Control", "SPDIF Control"]},
{"type":"AudioOutputI2SHex", "resource":"OUT1A Pin", "shareable":false},
{"type":"AudioOutputI2SHex", "resource":"OUT1B Pin", "shareable":false},
{"type":"AudioOutputI2SHex", "resource":"OUT1C Pin", "shareable":false},
{"type":"AudioOutputI2SOct", "resource":"I2S Device", "shareable":true, "setting":"I2S Master"},
{"type":"AudioOutputI2SOct", "resource":"Sample Rate", "shareable":true, "setting":"Teensy Control"},
{"type":"AudioOutputI2SOct", "resource":"Sample Rate", "shareable":true, "setting":["Teensy Control", "SPDIF Control"]},
{"type":"AudioOutputI2SOct", "resource":"OUT1A Pin", "shareable":false},
{"type":"AudioOutputI2SOct", "resource":"OUT1B Pin", "shareable":false},
{"type":"AudioOutputI2SOct", "resource":"OUT1C Pin", "shareable":false},
Expand All @@ -423,7 +423,7 @@ <h5 id="node-help-label">Keyboard Shortcuts <span style="float: right;"><a href=
{"type":"AudioOutputSPDIF2", "resource":"Sample Rate", "shareable":true, "setting":"Teensy Control"},
{"type":"AudioOutputSPDIF2", "resource":"OUT2 Pin", "shareable":false},
{"type":"AudioOutputSPDIF3", "resource":"SPDIF Device", "shareable":true, "setting":"SPDIF Protocol"},
{"type":"AudioOutputSPDIF3", "resource":"Sample Rate", "shareable":true, "setting":"Teensy Control"},
{"type":"AudioOutputSPDIF3", "resource":"Sample Rate", "shareable":true, "setting":["Teensy Control", "SPDIF Control"]},
{"type":"AudioOutputSPDIF3", "resource":"SPDIFOUT Pin", "shareable":false},
{"type":"AudioOutputPT8211", "resource":"I2S Device", "shareable":true, "setting":"PT8211 Protocol"},
{"type":"AudioOutputPT8211", "resource":"Sample Rate", "shareable":true, "setting":"Teensy Control"},
Expand Down Expand Up @@ -590,6 +590,13 @@ <h3>Hardware Teensy 3</h3>
<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>
<p>With some degradation in quality,
audio from master mode I2S may be used in the same project as
AudioInputSPDIF3 on a Teensy 4.x, in which case the audio update clock will derive from
the input S/PDIF sample rate. Note that this may also result in a pitch
shift for synth objects, and incorrect frequency response for filters,
if the sample rates are significantly different.
</p>
<p>Compatible CODEC Chips:
<ul>
<li><a href="https://www.pjrc.com/store/teensy3_audio.html">STGL5000</a>
Expand Down Expand Up @@ -689,6 +696,12 @@ <h3>Hardware</h3>
<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>
<p>With some degradation in quality, on a Teensy 4.x
audio from master mode I2S may be used in the same project as
AudioInputSPDIF3, in which case the audio update clock will derive from
the input S/PDIF sample rate. Note that this may also result in a pitch
shift if the sample rates are significantly different.
</p>
<h3>Examples</h3>
<p class=exam>File &gt; Examples &gt; Audio &gt; HardwareTesting &gt; PassThroughQuad
</p>
Expand Down Expand Up @@ -741,6 +754,13 @@ <h3>Hardware</h3>
<tr class=odd><td align=center>9</td><td>RX (ch 5+6)</td><td>Input</td></tr>
<tr class=odd><td align=center>20</td><td>LRCLK</td><td>Output</td></tr>
</table>
<p>With some degradation in quality,
audio from master mode I2S may be used in the same project as
AudioInputSPDIF3, in which case the audio update clock will derive from
the input S/PDIF sample rate. Note that this may also result in a pitch
shift for synth objects, and incorrect frequency response for filters,
if the sample rates are significantly different.
</p>
<h3>Examples</h3>
<!--<p class=exam>File &gt; Examples &gt; Audio &gt; HardwareTesting &gt; PassThroughQuad
</p>-->
Expand Down Expand Up @@ -786,6 +806,13 @@ <h3>Functions</h3>
<h3>Hardware</h3>
<p>The I2S signals are used in "master" mode, where Teensy creates
all 3 clock signals and controls all data timing.</p>
<p>With some degradation in quality,
audio from master mode I2S may be used in the same project as
AudioInputSPDIF3, in which case the audio update clock will derive from
the input S/PDIF sample rate. Note that this may also result in a pitch
shift for synth objects, and incorrect frequency response for filters,
if the sample rates are significantly different.
</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>21</td><td>BCLK</td><td>Output</td></tr>
Expand Down Expand Up @@ -860,6 +887,8 @@ <h3>Summary</h3>
<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>
<p>It is compatible with the AudioOutputSPDIF3 output and the I2S (but not I2S2) objects: when used together the audio system
will run at the external source's sample rate. See the AudioOutputI2S documentation for more detail.</p>
</div>
<h3>Boards Supported</h3>
<ul>
Expand Down Expand Up @@ -894,7 +923,8 @@ <h3>Examples</h3>
<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>
with most other inputs and outputs which run at specific speeds. I2S and
the SPDIF3 output can be used.</p>
</script>
<script type="text/x-red" data-template-name="AudioInputSPDIF3">
<div class="form-row">
Expand Down Expand Up @@ -1532,6 +1562,13 @@ <h3>Hardware</h3>
<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>
<p>With some degradation in quality,
audio from master mode I2S may be used in the same project as
AudioInputSPDIF3 on a Teensy 4.x, in which case the audio update clock will derive from
the input S/PDIF sample rate. Note that this may also result in a pitch
shift for synth objects, and incorrect frequency response for filters,
if the sample rates are significantly different.
</p>
<p>Compatible CODEC Chips:
<ul>
<li><a href="https://www.pjrc.com/store/teensy3_audio.html">STGL5000</a>
Expand Down Expand Up @@ -1619,6 +1656,13 @@ <h3>Hardware</h3>
<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>
<p>With some degradation in quality,
audio from master mode I2S may be used in the same project as
AudioInputSPDIF3 on a Teensy 4.x, in which case the audio update clock will derive from
the input S/PDIF sample rate. Note that this may also result in a pitch
shift for synth objects, and incorrect frequency response for filters,
if the sample rates are significantly different.
</p>
<h3>Examples</h3>
<p class=exam>File &gt; Examples &gt; Audio &gt; HardwareTesting &gt; PassThroughQuad
</p>
Expand Down Expand Up @@ -1661,6 +1705,13 @@ <h3>Functions</h3>
<h3>Hardware</h3>
<p>The I2S signals are used in "master" mode, where Teensy creates
all 3 clock signals and controls all data timing.</p>
<p>With some degradation in quality,
audio from master mode I2S may be used in the same project as
AudioInputSPDIF3, in which case the audio update clock will derive from
the input S/PDIF sample rate. Note that this may also result in a pitch
shift for synth objects, and incorrect frequency response for filters,
if the sample rates are significantly different.
</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>21</td><td>BCLK</td><td>Output</td></tr>
Expand Down Expand Up @@ -1713,6 +1764,13 @@ <h3>Functions</h3>
<h3>Hardware</h3>
<p>The I2S signals are used in "master" mode, where Teensy creates
all 3 clock signals and controls all data timing.</p>
<p>With some degradation in quality,
audio from master mode I2S may be used in the same project as
AudioInputSPDIF3, in which case the audio update clock will derive from
the input S/PDIF sample rate. Note that this may also result in a pitch
shift for synth objects, and incorrect frequency response for filters,
if the sample rates are significantly different.
</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>21</td><td>BCLK</td><td>Output</td></tr>
Expand Down Expand Up @@ -1894,7 +1952,13 @@ <h3>Notes</h3>
<script type="text/x-red" data-help-name="AudioOutputSPDIF3">
<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>
<p>Transmit 16 bit stereo audio as Digital S/PDIF by use of the native S/PDIF port.</p>
<p>It is compatible with the AudioInputSPDIF3 input (and I2S, but not I2S2, objects): when used together the audio system
will run at the external source's sample rate, in which case other audio input or output
objects which use the internal clock should not be used. See the AudioOutputI2S documentation for more detail.</p>
<p>If AudioInputSPDIF3 is not used then the S/PDIF sample rate will be governed
by the audio system clock as usual, and other I/O objects can be used.
In this case S/PDIF input can still be achieved by use of the AsyncAudioInputSPDIF3 object.</p>
</div>
<h3>Boards Supported</h3>
<ul>
Expand Down Expand Up @@ -1929,7 +1993,7 @@ <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>Native S/PDIF hardware is used, which is more efficient than use of I2S ports.</p>
</p>
</script>
<script type="text/x-red" data-template-name="AudioOutputSPDIF3">
Expand Down
40 changes: 33 additions & 7 deletions gui/red/ui/view.js
Original file line number Diff line number Diff line change
Expand Up @@ -990,6 +990,38 @@ RED.view = (function() {
resetMouseVars();
}

function markConflict(d,n2,s,s2) {
var msg = "Conflict: "+ d.name + " setting['"+s+"'] and "+n2.name+" setting['"+s2+"']";
console.log(msg);
msg = n2.name + " has different settings: " + s + " ./. " + s2;
d.conflicts.push(msg);
d.requirementError = true;
}

function matchSettings(s,s2) {
var gotMatch = false;
if (Array.isArray(s)) {
for (let i=0; i < s.length && !gotMatch;i++) {
gotMatch = matchSettings(s[i],s2);
}
}
else {
if (Array.isArray(s2)) {
for (let i=0; i < s2.length && !gotMatch;i++) {
gotMatch = matchSettings(s,s2[i]);
}
}
else
gotMatch = s == s2;
}

return gotMatch;
}

function checkSetting(d,n2,s,s2) {

if (!matchSettings(s,s2)) markConflict(d,n2,s,s2);
}

function checkRequirements(d) {
//Add requirements
Expand All @@ -1014,13 +1046,7 @@ RED.view = (function() {
d.requirementError = true;
}
//else
if (r["setting"] != r2["setting"]) {
var msg = "Conflict: "+ d.name + " setting['"+r["setting"]+"'] and "+n2.name+" setting['"+r2["setting"]+"']";
console.log(msg);
msg = n2.name + " has different settings: " + r["setting"] + " ./. " + r2["setting"];
d.conflicts.push(msg);
d.requirementError = true;
}
checkSetting(d,n2,r["setting"],r2["setting"]);
}
});
}
Expand Down
2 changes: 1 addition & 1 deletion input_spdif3.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ void AudioInputSPDIF3::begin(void)
{
dma.begin(true); // Allocate the DMA channel first

AudioOutputSPDIF3::config_spdif3();
AudioOutputSPDIF3::config_spdif3(true); // force output (if any) to sync to this

const int nbytes_mlno = 2 * 4; // 8 Bytes per minor loop
dma.TCD->SADDR = &SPDIF_SRL;
Expand Down
Loading