No luck with S/PDIF output

Hi,

I recently grabbed a Teensy 4.1 in hopes of using it as a S/PDIF tone generator. Unfortunately I am not having any luck, so hopefully somebody can help me figure out what's going wrong.

My initial goal is to play a WAV file on loop with a GLITS test tone. I created the test tone in Audacity, and have verified that it is 44.1KHz and 16 bit. The file is loaded onto a FAT32 partition on a micro SD card.

I am using the following code (which is basically just the WavFilePlayer example, with the output substituted to be AudioOutputSPDIF3 which I understand is the built in S/PDIF output on pin 14).

C-like:
#include <Audio.h>
#include <Wire.h>
#include <SPI.h>
#include <SD.h>
#include <SerialFlash.h>

AudioPlaySdWav           playWav1;
AudioOutputSPDIF3       audioOutput;

AudioConnection          patchCord1(playWav1, 0, audioOutput, 0);
AudioConnection          patchCord2(playWav1, 1, audioOutput, 1);

#define SDCARD_CS_PIN    BUILTIN_SDCARD
#define SDCARD_MOSI_PIN  11
#define SDCARD_SCK_PIN   13

void setup() {
  Serial.begin(9600);

  AudioMemory(8);

  SPI.setMOSI(SDCARD_MOSI_PIN);
  SPI.setSCK(SDCARD_SCK_PIN);
  if (!(SD.begin(SDCARD_CS_PIN))) {
    // stop here, but print a message repetitively
    while (1) {
      Serial.println("Unable to access the SD card");
      delay(500);
    }
  }
}

void playFile(const char *filename)
{
  Serial.print("Playing file: ");
  Serial.println(filename);

  playWav1.play(filename);

  delay(25);

  while (playWav1.isPlaying()) {
  }
}


void loop() {
  playFile("GLITS16.WAV");  // filenames are always uppercase 8.3 format
  delay(500);
}

I am using the following circuit to drop the output level down to get about 0.6V max. This was based off a few other forum threads I saw here.

1755914245351.png


I bought a cheap S/PDIF to analog converter off Amazon in order to test the output.

Unfortunately I have had no luck getting any audio out. I did try the other two S/PDIF output modes and their respective pins, and also got absolutely nothing. I also tried substituting the WAV file for a sine block and got nothing as well.

What might I be doing wrong here?

Thanks
 
Try using AudioOutputSPDIF3 with this line added to the end of setup():
SPDIF_STCSCH = 1 << 21;

Let me know if that gets output working from your converter...
 
No luck with that.

(I did actually bump into your thread where you discussed the copy flag, and I had already stuck that line into the output_spdif3.cpp file in following with your patch.)

I also know it's not pretty, but here is a photo of the current setup, just in case something jumps out at folks. (I apologize for the sloppy capacitor, that was a late addition.)

20250822_225130.jpg


Other thoughts or things to try?
 
I believe your passive voltage divider is not correctly impedance-matched.
From the WM8804 datasheet:

1755945148525.png


See this post for more info.
Paul
 
That will draw more current than the Teensy is rated for. I’ve had good results using Toslink, either via a proper transmitter or a simple resistor+LED.
 
Yeah, an optical transmitter is the easy way (they Just Work(tm)) or failing that I'd suggest controlling a transistor connected to appropriate resistor dividers; the type of transistor (NPN or PNP) wouldn't matter since an inverted signal should work just as well as a normal one.
 
That will draw more current than the Teensy is rated for.
Agree. But it does actually work. The RME ADI-2 Pro FS does recognize the RCA signal [using an SPDIF coax/optical breakout board with 220Ω/100Ω divider]:
IMG_20250823_162038.jpg


However, when I built the 4K7/1K divider + capacitor circuit from the first post, the RME does not recognize the signal.
The oscilloscope shows that the signal is too small:
SDS00098.png


I did use a 75Ω load on the scope input.

Paul
 
Alright, I think I see where I messed up. I calculated those resistor values with no load. I don't think there is a way to change those values while still staying under the 4mA current limit of the output pins, so a transistor might be the way to go then.

Switching to optical isn't useful for me, since the device this will be plugged in to needs it on copper. I'll have to get some parts ordered and give this another whirl.
 
For a quick test, you could use a 330Ω resistor +100nF cap in series, between Teensy pin 14 and the RCA center pin.
With a load of 75Ω, about 8mA will be drawn from the Teensy pin. Just tried this and it works fine for a short test.

Paul
 
I just bodged together the resistor and capacitor as you suggested, and I successfully heard the audio in the WAV file on my cheap S/PDIF to analog converter.

When I do the work to figure out a proper circuit, should I assume a 75 ohm load on the receiver? I am much more used to working in the analog audio domain where outputs are low impedance, and inputs are high impedance.
 
I've been playing with some numbers in Falstad, and it appears to me that a 330 ohm resistor might actually be okay at the frequencies we're running at? (Graphing voltage at the divider, current at the square wave.) Is this simulation reasonably accurate for these purposes, or do I have a gross misunderstanding of what's going on?

I have adjusted my wiring to match, and the audio does pass. I may be able to get access to an oscilloscope on Monday to actually measure the current for real, unless somebody wants to beat me to the punch.

1756004957049.png
 
Square wave generator needs an offset so it generates a wave from 0 to 3.3v. You may have measured only half the current draw, I'm not sure if the "max" shown is taken from peak-to-peak or from zero.
 
The square wave shown there is set at 1.65v with a 1.65v offset, so it alternates between 0v and 3.3v.

The max values shown on the scopes appear to be from zero. (So it alternates from 288mv to -288mv, and 4.1mA to -4.1mA.)

Here is the text you can import if you would like to try for yourself.

Code:
$ 1 7.8125e-9 1.0312258501325766 50 5 50 5e-11
R 1072 336 1072 272 0 2 4000000 1.65 1.65 0 0.5
g 1072 624 1072 720 0 0
r 1072 416 1072 528 0 330
r 1072 528 1072 624 0 1000
w 1072 528 1184 528 0
r 1184 528 1184 640 0 75
g 1184 640 1184 720 0 0
c 1072 336 1072 416 4 0.0000022 1.6499632594990443 0.001 0
o 5 1 0 4098 2.5 0.025 0 2 5 3
o 0 1 0 4097 5 0.025 1 2 0 3
 
When I do the work to figure out a proper circuit, should I assume a 75 ohm load on the receiver?
That's what I did. This is the circuit I'm using:
circuit.png

This results in a Teensy output current of ~8mA max. Since the SPDIF signal is biphase-mark-coded data, the average current will be ~4mA.
And this is what it looks like on the scope:

SDS00100.png


For reference, this is the code I run on the Teensy 4.0:
C++:
#include <Audio.h>

float freq = 1000.0f;
float ampl = 0.1f;  // -20dB

AudioSynthWaveformSine sine1;

AudioOutputSPDIF3 spdif3_1;  // T4 pin 14
AudioConnection patchCord1(sine1, 0, spdif3_1, 0);
AudioConnection patchCord2(sine1, 0, spdif3_1, 1);

void setup() {
  pinMode(LED_BUILTIN, OUTPUT);
  digitalWrite(LED_BUILTIN, HIGH);

  AudioMemory(8);

  sine1.amplitude(ampl);
  sine1.frequency(freq);
}

void loop() {
}

Paul
 
After some more fiddling around, I finally settled on a 2.2uF capacitor followed by a 470 ohm resistor. (I removed the 1k resistor completely.) Testing with a 75 ohm load gives us a comfortable 0.55 V peak to peak (loaded), and drops the current close to 2mA (measured across a 10 ohm shunt resistor).

I also discovered that the cheap DAC I bought was overloading the circuit.

There are probably ways to optimize this further, but I think it's safe to call it good enough for the time being.

In the future I would like to investigate using I2S with a DIT4096 or similar, as that can generate AES/EBU which is more interesting to me.
 

Attachments

  • scope_0.png
    scope_0.png
    38 KB · Views: 40
  • scope_1.png
    scope_1.png
    22.2 KB · Views: 50
Back
Top