There are currently four ways to get audio out of the RPi:
- Use the audio out 3.5mm jack. It’s very easy to get it to work, but the sound quality is pretty bad, since it uses PWM to generate the sound. Due to that, its real resolution is in the neighbourhood of 11 bits. We have no use for that.
- Use the HDMI port. It works OK, but is useless to us audiophiles.
- Use a USB to I2S adapter, such as an Amanero or an XMOS-based device. Now we’re talking. They work quite well, and the quality of the I2S signal is dependent largely on the technology used (CPLD vs. XMOS, etc) as well as the quality of the on-board clocks. The problem is that they add another link to the audio chain, as well as increase the cost. Remember, the RPi is supposed to be a low cost solution.
- Use the GPIO pins of the RPi to get direct I2S output. This sounds way more interesting, right? Let’s try that!
According to several sources on the Net, this is the pin out:
You will probably notice that the RPi does not support MCLK output. This means in practice that your DAC will need to have its own on-board clock (or internal PLL / oscillator or whatever). We can live with that.
Luckily, my Buffalo III has its own clock (of course it does!) and thus can be connected quite easily. Let’s try that:
Now we have to configure the software for I2S output. For my distribution of choice, Archphile, it’s a piece of cake: http://archphile.org/howto/i2s-dacs-and-the-raspberry-pi/
Audio playback works just fine!
Well, almost fine..
You see, in theory the RPi has a bit of a problem with its I2S output. Since the only clock onboard the RPi is a 19.2MHz crystal, it should have trouble generating proper clocks for its I2S output. For example, for 44.1KHz audio, the LR Clock must be running at precisely 44.1KHz. That is not possible, since the frequency is not a multiple of 19.2MHz. Thus, the frequency can be either 19.200.000 / 435 = 44.138KHz or 19.200.000 / 436 = 44.0366KHz. This is a limitation of the Broadcom BCM2835 in conjunction with the 19.2MHz crystal and there is nothing that can be done.
In order to confirm the theory, I decided to run a few tests. I hooked up my logic analyzer to my RPi, set it up for I2S output, and fed it some 44.1KHz music.
I took 1 sec worth of samples with my logic analyzer, configuring it for I2S signal. I got this:
The PCM Clock is already appearing a little dodgy. Let’s zoom in:
As you can see, the pulses do not have the same duration. They appear to alternate between two values. So it is obvious that the signal has jitter. A lot of jitter. Since we’re here, let’s have a look at the LR Clock signal as well:
The duration of the pulses appears to alternate between 11.33μS and 11.38μS, giving respectively 44.12KHz and 44.04KHz, values very close to the ones I calculated previously.
So, the theory is sound and the RPi’s clock is not up to snuff by strict standards. What this means is that the RPi’s I2S output is not capable of “Hi End” audio transmission. It is essentially not bit perfect (edit: this is not correct, strictly speaking. It is in fact bit perfect, it is just not “proper”.).
In the real world, chances are that this problematic clocking will not be particularly audible under normal circumstances, say with a normal-specc’ed sound system. But an audiophile should definitely steer clear of the RPi’s I2S output, instead opting for a USB to I2S interface.
>The duration of the pulses appears to alternate between 11.33μS and 11.38μS
With Saleae 24Msps “logic analyzer”, you cannot expect better results – because sampling error of such “instrument” is 0.042μs. Using scope and you will see possibly much better picture.
You may have a point, and I have been meaning to investigate further with an oscilloscope, but I put it in the back burner since the findings seemed to (consistently) validate the theory. I will come back to this.
Did you close the loop ? Was it a measurment error or has the RP this kind of jitter ? I am experimenting right now with different SoCs…lools like I need to compile my own Kernel as tickless (NOHZ_FULL) is not supported by the normal images even though it is now a standard compile option…never did that before…but hey, lets have some fun…
Never closed the loop, I’m afraid.. Just moved over to quality USB to I2S interfaces instead..
Tickless kernels look very interesting, I believe Arch Linux Arm is by default compiled with tickless enabled..
Pingback: Raspberry PI and I2s output
Very interesting analysis! And definitely food for thought as I wanted to use I2S as a higher quality feed to an external dac. So it may not be worth it.
Do your conclusions change with the RPI2 board, or does it use the same clock?
I have not had the chance to try out the RPi 2, but AFAIK they use the exact same clocking scheme..
The Raspberry Pi can work a a clock slave completely eliminating the clock jitter issue. The easiest way to do this is using an HiFiBerry DAC+ Pro: http://support.hifiberry.com/hc/en-us/articles/205711451-DAC-Pro-connect-external-I2S-DACs
Are you sure about that? AFAIK there is no way to feed back to the RPi a master clock, so no way to run it as a slave. What I’m seeing on the DAC+ Pro is an I2S out with MCLK out, obviously generated by the DAC+ itself. This I2S output will have the same limitations as the RPi’s on-board I2S output, since I see no reference to reclocking being done on-board the DAC+. I may be wrong of course..
You are wrong. The so-called “Master clock” has nothing to do which chip is master or slave. It is usually just a clock that is uses to derive all other clocks. The master clock is not even part of I2S. There is no need to feed a master clock to the Raspberry Pi. The Raspberry Pi can be slave for BCK, LRCLK. These are the I2S clock signals.
We’re using the Raspberry Pi as a clock slave since years (the HiFiBerry Digi that does this has been released almost 2 years ago). Check out the driver source and you will clearly see that the Raspberry Pi runs in slave mode.
I remember reading in the RPi’s SoC datasheet that it was possible to slave it to an external BCK & LRCLK, but I did not know that it had been actually implemented by someone. Nice! 🙂 If I’m seeing right, the HiFiBerry Digi uses a WM8804 which is clocked by a single clock (usually 12MHz), so it is not 100% “flawless”, but still it is a big improvement over the RPi’s I2S lines. Your DAC+ Pro has two decent (Xpresso?) on-board clocks so should be OK for proper I2S output. I am curious as to how it performs, compared to a USB to I2S interface. I might give it a try. 🙂
Have a try. Almost all of the HiFiBerry users love the sound 🙂
True. SND_SOC_DAIFMT_CBS_CFS is parameter that does that. And mainly all DAC drivers have this set: RPI gets audio clock from DAC.
Which logic analyzer are you using? The 4 or the 8?
The cheapest one off of ebay.. http://www.ebay.com/itm/USB-Logic-Analyzer-Device-Set-USB-Cable-24MHz-8CH-24MHz-for-ARM-FPGA-M100-/201450276552?hash=item2ee75f46c8:g:8mUAAOSwl9BWIMdL
Thank you for putting together your research and the blog post, very interesting.
Thank you for putting together your research and the blog post, very interesting.
Have you tried the Digi+ or the Dac+ Pro ? Interested in your thoughts about Raspberry Pi using a separate master clock as in the Digi+ or Dac+ Pro versus the Amanero or XMOS USB to I2S. Thank you !
All the best
You are quite welcome Mark.
I’m afraid I haven’t gotten around to making such a comparison. So many things, so little time, etc.
But there does exist a very interesting thread about the DAC+ Pro over at diyaudio.com: http://www.diyaudio.com/forums/digital-line-level/285811-hifiberry-dac-pro-hw-mods-anybody.html
In my opinion with a soekris dam1021 dac all this problems are gone. It totally re-sample all the I2S segnal and the Raspberry will be a perfect low cost solution.
What do you think about?
Hi there Guglielmo,
In theory, that should be the case. However, in diyaudio.com (and in other forums) we have had people claiming to hear differences between different USB to I2S interfaces with the Soekris, so I’m keeping an open mind. There may be more factors at play here.
I myself have not actually done any such experiments.
Pingback: Tråden for DIY nettstrømming. - Side 10
Since 19.2 is a perfect multiple of 4.8, does that mean that this issue will not be seen with a sampling rate of 48kHz?
Exactly. But that will not be a solution for 44.1K material since it would have to be upsampled to 48K.
Very good reserch post
love it 🙂
Pingback: Kali FIFO Buffer & Reclocker for SBCs | Dimdim's Blog
Pingback: Mamboberry LS DAC+ vs. Boss DAC vs. Piano 2.1 Hi-Fi DAC with and without Kali FIFO Reclocker | Dimdim's Blog
Pingback: RPi to i2s DAC – Blog for my linux projects
I’m running openelec (7.0.1 on Raspberry Pi 3) and wanted to enable i2s to talk to my DAC (with I2s). Tried all the above but DAC is not locking on. Any advice ?
Additionally was testing another option of using USB to connect to DAC equipped with a Amanero card. Kodi on Openelec (7.0.1 on Raspberry Pi 3) has no option to select USB sound output despite the DAC locking on to the signal. What is wrong ?
I don’t use OpenElec or Kodi on my RPis so I can’t really help. You’d probably have better luck asking at their respective forums.
Best of luck!
Why is the HDMI port useless to us audiophiles? Can’t the HDMI port be used to transfer te signal to a proper HDMI receiver?
Eelco de Bode
First of all, there has to exist a proper HDMI receiver. AFAIK you can’t build such a receiver without getting a license from the HDMI “organization”. In practice to do that you need to be the size of Pioneer or Yamaha or Marantz (etc.). But even if you could find such a “proper HDMI receiver”, it would be inferior in audio quality to USB or perhaps even to the RPi’s I2S output because HDMI is by-design pretty bad when it comes to jitter.
This is probably a total-noob question, but doesn’t somebody make a replacement clock osc for the Rasberry that runs at 19.1835 MHz? At least then we’d know whether the jitter is deterministic or not.
Never mess with Chronos.
Pingback: Dùng Raspberry làm Music server và Transport - Blog chia sẻ kiến thức điện tử, tin học, lập trình
Shouldn’t FRAME (which is I2S_LRCL) signal be 44.1kHz, and CLOCK be 64xFs=64*44100=2822400?
And only FRAME defines a final jitter, cause FRAME signal edge loads data into DAC’s internal registers.