Raspberry Pi: external I2S master clock (PCM_MCLK)

Status
This old topic is closed. If you want to reopen this topic, contact a moderator using the "Report Post" button.
Hi,

as far as I know, the I2S driver is using an internal PLL as master clock (PCM_MCLK). Would it be possible to use an external master clock (fed via GPIO)? Can't find PCM_MCLK source selection options in the "BCM2835 ARM Peripherals" datasheet.

Thanks!
 
Yep. That's what mine's doing:)
I don't remember off the top of my head, but there is a bit in a register to select the clock source - it's probably in the PCM register block.
There's a thread in the raspberry pi.org forum that's got most of the details - it's a bit long though.
 
Not sure I understand.
The pi is outputting basically NOS data, so is only interested in BCLK.
It has a completely different main clock source - not really linked to typical frequencies for audio, and so can do some clever division to get your 2.82mhz BCLK or you can provide it yourself. It has no need for the usual 11 or 16 mclk.

So, to clock the pi externally, you need to feed 2.82Mhz (if using 44.1khz for instance) into the pi, and onward to the next stage as the bclk line in the i2s signal.

I have a kwak clock with a divide by 4 stage to do this (and the main output of the kwak clock is used to feed mclk to my oversampler).
I thought you were more interested in the bits to twiddle in the pi to do this. That needs looking up, as I can't accurately quote the register off the top of my head. I've been meddling in this area for a while.

What are you using with your pi?

Phil
 
I'm also struggling with this at the moment, attempting to set up a raspberry pi as a source, by connecting it to an i2s DAC. In theory it's awesome. The problem is that the master clock is derived from the Pi which is not divisable by 44.1k, causing excessive jitter at cd-resolution (and in general its not the kind of clock you'd want to have timing your precious audio bits).

There are i2s DAC boards out there with on-board oscillators, but I think they still run as a slave to the Pi master clock.
It appears that to get truely low jitter using a Pi, one would need to use an external MCLOCK and have the Pi run as a slave to that instead of vice versa.

I'm still fairly fresh to this matter and currently researching it, so if philpoole or anyone else could shed some more light into this then that would be awesome :)

The most informative source I found on the subject so far is this https://hifiduino.wordpress.com/2014/11/13/raspberry-pi-b-digital-audio/
 
I have 2 Raspberry Pies set up for audio, one with an async USB DAC and one with a Wolfson audio card. I think the Wolfson gets its master clock from the Pi, but they use the WM8804 SPDIF transceiver which claims to have a "jitter scrubbing architecture" with an internal FIFO and PLL.

I use the SPDIF outputs of both of them, which kind of defeats the purpose of the async USB. I don't have anything that can measure jitter to the picosecond, but I doubt the jitter of the Wolfson SPDIF output is any worse than the jitter inherent in SPDIF itself.
 
Thanks for the link. It appears, the only way to get reasonable sound out of R-pi is still async usb. Or possibly a Fifo, such as Ian's.

Nonsense! Why do people keep saying this? Or maybe you're right. To get reasonable sound, use USB. However if you want something to sound decent, then use I2S :D

It might have improved since I implemented it, I understand kaolo's I2S driver was put into the mainstream kernel, but essentially you need to rebuild the kernel with it configured to build the I2S driver.
To get it working with an external clock, you will need to make a tweak the source code so that a register is poked to configure the pi to use an external clock. As I mentioned before the external clock needs to be BCLK frequency, so you take your master clock and divide it (if I recall, by four for my setup).
It is described in the link I mentioned above. You really need to read it. It has other links within it, like Kaolo's blog and github site for the code and build howtos etc.

If you've not played with kernels before, I'd recommend just getting the kernel to build first. Then reconfiguring it to build with your flavour of I2S turned on with the internal clock set. Then consider the move to the external clock.
 
Without digging too deep, an async usb, provided it also has an isolator and reclocker as most decent boards do these days will greatly reduce the jitter problem, wouldn't it?

After all, the output jitter will mostly depend upon the jitter induced by the clock oscillators, oscillator power supplies and whatever type of flip-flops do the reclocking.

The I2S alternative with clock divisions seems more exposed... and how is the actual reclocking performed? Surely not within the pi.

I have never seen a pi, merely trying to establish if it's likely to be superior to a bare bones PC soundwise, or it's just a geek's toy.
 
Don't confuse BCLK and MCLK. MCLK is the one that needs to be low jitter for a modern sigma-delta DAC. Ideally it comes straight from a crystal oscillator located next to the DAC chip and all of the other clocks are derived from that.

To support all sample rates, you need two crystals (one for multiples of 44.1, one for multiples of 48) and logic in the audio driver to switch between them.

The Raspberry Pi is equal in sound quality to a PC, cheaper, and fanless. But you pay for this in more difficult setup. It took me a lot of tweaking to get bit perfect async USB output at high sample rates. Reminded me of the good old days of ISA sound cards on Win95. :O
 
Last edited:
Surely, if you buy in a usb dac, it's not DIY? I admit I didn't build the pi, but have built everything else in my dac.

Not usb dac, but only usb/i2s board which also does proper reclocking and isolation.

Reading scopeboy's post it appears even this is not particularly easy to achieve for all sample rates. And DSD is out... Just trying to judge if this project has any attraction for myself.
 
This thread is exactly what I'm thinking about.
I use a B+ PI with Volumio and making an AD1865 DAC fed through Ian's I2S to PCM board. I also try to get the jitter reduction board, but would be much better, not to reduce jitter, but to generate the original clock with low jitter. Both bit and word clock.

I would be really interested in if you guys made it, how. Especially from sw point of view, I could generate low jitter signal for both bit and word clock, if the PI could tell the sample rate and could feed data as slave on the provided clock signals.

I woudl appreciate you guys could tell how far you realized it, or something different, but getting the PI as slave device.

Thanks,
JG
 
Guys, I'm not being funny, but the information is in this thread and the links I mentioned! You should consider reading it. Really.
Get a clock, divide it down to bclk and feed that to your pi.
Get the pi datasheet and poke the PCM MODE_A register to accept an external clock.
This divided clock is also the bclk to your next stage.
Eventually you will want to tweak the kernel for this, but a crude user space program you can sudo to do the poke would be a start.

Does this help? What have I missed?
 
You've missed the logic that allows the Pi to switch the MCLK between two external crystals depending on the sample rate requested from the audio driver. This is pretty non-trivial and a vital feature unless you only ever listen to 44.1kHz and its multiples.

The Pi probably doesn't care about MCLK except in so far as it is capable of generating it. The data coming out of the thing is regulated by BCLK. But it needs to be able to tell the external MCLK generator what frequency to go at, and what ratio the BCLK divider should use, so your tunes play at the correct speed.
 
Last edited:
Ah, no I only listen to FLACs from CD, so only care about 44.1KHz. I've not missed anything ;-)
So that's a bit more interesting. You'll need to control a GPIO or two to switch MCLKs - I'm guessing you'll need to tweak the kernel (although again, a simple utility program that makes the pokes to GPIOs would get you developing).
Or you could use I2C - but that seems markedly overkill.
 
Status
This old topic is closed. If you want to reopen this topic, contact a moderator using the "Report Post" button.