This came about because I bought a box from Belkin to do AirPlay 2 for our patio speakers (which have an amplifier I built myself). That Belkin box's analog audio output is about 20 dB too low, but fortunately they include a TOSLINK output jack. Buying the aforementioned $10 box from Amazon solved my problem, but I kinda wanted to know how to build the equivalent, and having done so, try to do better.
The current design comes down to three separate subsections.
First is a TOSLINK receiver module. This is a little plastic thing that takes in 5 volt power and outputs a TTL level stream matching the optical input. There isn't a whole lot to say about this. It's self-contained and just needs a single bypass cap and series inductor for the supply pin. The optical signaling is biphase encoding. This makes for easy clock extraction. Between every clock period the signal changes state. If the input pulse train is the same bit level as the previous bit, then nothing else happens. If it's different, then at the 180º mark there is a second state change. So for an input clock frequency of 1 MHz (just an example), a series of either 00000... or 111111.... is represented by a 1 MHz square wave. A series of 01010101.... is represented by a 2 MHz square wave.
The next section is the digital data stream receiver. For this, I've gone through four different choices. The first iteration used the STA120. That worked, but it only comes as a SOIC28, which is rather large, and seemed to be heading towards obsolescence (did I mention that this whole project is at least 10 years out of fashion?). Replacing that was the DIR9001, which was a good choice, but like the STA120 was limited to 96 kHz sample rates. To go higher, I needed to find a better chip that was still capable of being configured purely with hardware strapping. The best choice I could find was the CS8416. It can go up to 200 kHz sample rates and can be strapped with 8 47 kΩ pull-up-or-down resistors. The CS8416 can take care of any pre-emphasis correction for us, allowing us to just strap the DAC for no pre-emphasis. In all 3 cases, the output was configured for i2s, with the receiver being the master and a master clock of 256x the L/R clock. The problem with the CS8416 is that without any input, it clocks the output at around 750 kHz, which is the minimum VCO clock for the PLL. Sending that slow a clock into the PCM1793 results in a low level hiss on the output even though MUTE is asserted by the error output. This prompted me to try the WM8804. That took care of the hiss, though it does require adding a 12 MHz crystal to the BOM. The other downside is that in hardware mode, there's no support for reporting or handling deemphasis, but so far I've not encountered a source that used it.
The original DAC was a CS4334. It takes i2s input. This consists of the master clock (SCK), bit clock (BCK), L/!R (LRCK), and DATA. Instead of the BCK signal, you can send a de-emphasis selection signal from the STA120, but when I attempted this with a prototype the audio sounded noisy. It would seem that when you don't send SCLK, the CS4334 makes assumptions about the relationship between SCK and the frequency of LRCK to derive an internal bit clock. This seems to not work for the output format of the STA120. That, and the !DEM signal was always high, which implies that emphasis on the digital signal is never used, so there's no harm in not supplying that signal to the DAC.
Along the way I decided to attempt to design something a bit better. This started with the PCM1793 192 kHz 24 bit DAC. That DAC has fairly impressive THD and S:N specs, and requires an external differential to single-ended converter and LPF. That uses the OPA2134 dual op amp, which is also an impressive part in and of itself. As before, the output DATA, BCK, LRCK and SCK (configured at the receiver for 256xFs) are fed directly. In addition, I decided to connect the ERR output of the decoder...Read more »