Nerdy notes » History » Version 5

« Previous - Version 5/7 (diff) - Next » - Current version
Giulio Moro, 2016-03-08 12:54 AM

Nerdy notes

This is just a collection of notes from/for developers. Sometimes it is also useful to know the mistakes that others made so not to waste your time when we already wasted ours. Note that if you attempt any of the hacks here it might void your warranty. Do not do this, please.

Media clock on the Beaglebone Black with BeagleRT cape

The media clock is hardcoded to 44.1kHz. This can be changed by changing the PLL values in I2c_codec::startAudio.
Current settings are as follows

writeRegister(0x02, 0x00)    // Codec sample rate register: fs_ref / 1
writeRegister(0x03, 0x91)    // PLL register A: PLL enabled, Q=2, P=1
writeRegister(0x04, 0x1C)    // PLL register B: J= 7
writeRegister(0x05, 0x52)    // PLL register C: D=5264, part 1
writeRegister(0x06, 0x40)    // PLL register D: D=5264, part 2

For extensive reference check the TLV320AIC3104 Audio Codec reference manual, pages 45-46
Q is not relevant as PLL is disabled
J range is 1 to 63
D range is 0 to 9999
P range is 1 to 8
R range is 1 to 16
These values plugged in
f_{S(ref)} = (PLLCLK_IN × K × R)/(2048 × P)
will give 44100

The media clock can be changed setting different values for J and D. As it is currently structured, the PRU loop does not allow you to get much faster than 48000kHz (J.D=K=8.1920) as you will start getting underruns.

Measure media clock drift with respect to the CPU

On the BeagleRT cape the 12MHz clock is generated by the same master clock that drives the CPU, so these are going to be synced forever and ever (that is, do not expect any drift to occur between the media clock and the system clock).
To verify that this actually is the case, the follwing patch to PRU.cpp allows to log the time that takes for the PRU to get back to the ARM audio thread.

        static RTIME elapsedTime; // in nanoseconds
        static RTIME startTime=0;
        static long long int count=0;

        while(pru_buffer_comm[PRU_CURRENT_BUFFER] == lastPRUBuffer && !gShouldStop) {
        xenomai_gpio[GPIO_SETDATAOUT] = TEST_PIN_MASK;
        xenomai_gpio[GPIO_CLEARDATAOUT] = TEST_PIN_MASK;
        if((count&16383)==0 && count!=0){
            rt_printf("%llu\n", elapsedTime);

Ideally it should be elapsedTime==numAudioBufferSamples*16384.0/samplingRate*1e9 ±0.25*sleepTime
assuming that sleepTime==numAudioBufferSamples/SamplingRate/4.0
Experimental results show that it is the case (see attached files clockanalysis.m , logovernightInPru.m, error.png)

Preparing the board for building Supercollider
Updated 8/3/2016

  • Resize the partition so that you have at least 1GB available.
  • You need an internet connection from the Beaglebone. Good luck with it.
  • Run this to fix an error that you would encounter when apt-get update (Error: W: There is no public key available for the following key IDs:
    9D6D8F6BC857C906 )
    $ sudo apt-get install debian-keyring debian-archive-keyring
    $ sudo apt-key update
  • Try
    $ sudo apt-get update

    If you are getting an error like "Release file expired", make sure the date on your BeagleBone is set correctly (e.g.: by running)
    ntpdate -b -s -u
  • follow instructions here from step 3 onwards

clockanalysis.m 3.4 KB, downloaded 63 times Giulio Moro, 2015-07-30 04:42 PM

error.png 102 KB, downloaded 55 times Giulio Moro, 2015-07-30 04:42 PM

logovernightInPru.m 92 KB, downloaded 62 times Giulio Moro, 2015-07-30 04:42 PM