Audio PLL rocking :-)

User avatar
Jakobsen
Posts: 89
Joined: Mon Jan 16, 2017 8:12 am

Audio PLL rocking :-)

Postby Jakobsen » Fri Sep 29, 2017 11:00 am

Found time and a rev_1 ESP32 module to test out the fixed audio PLL - and heads up for Espressif - Performing just perfect :D

Image

Small background story:
In any audio streaming system, the receiving end needs to sync up to the sample pace that the source is transmitting. Between transmitter and receiver we expect to have TCP/IP infrastructure - that will results in unknown delay over time, but a buffer in the receiving end typical overcome that issue.
But we still need to sync to the source sample rate, if not we run out of buffer space or samples.

There are two ways to handle that. Skip or add samples. If that happens at a low rate it can be masked by the audio signal. But as tx/rx pace gets to far form each other, it will start to be audible.
Alternative the clock at receiver end can be locked to the transmitted sample rate. That is where the audio PLL come into play.

Fractional PLL
First of all we need a high resolution PLL to get exactly the clock frequency we want, secondly we need low clock jitter. Until the now we have used a fractional PLL to generate the master clock for the I2S audio sub system. The fractional PLL has limited resolution and lots of clock jitter.
Image
Here we call the init_i2s function call to setup a 44100 samples pr second system. The driver calculate the best match from the fractional PLL and in this setup it will do a 44642 samples pr second output rate. Each second we consume 542 samples that the source did has not provide on average. On top of that a fractional PLL has a lot of clock to clock jitter on the generated i2s_bck aka audio bit clock.
Codec/integrated class D amplifier are more or less insensitive to audio bit clock jitter. But to do a god job here the Codec/Amplifier require a higher clock or its own wide band pll to clean up the clock. If not, the audio bit clock jitter turns into phase noise in the audio spectra.

Image
Image

Until now my work has been on rev_0 chips and been working late night at very low volume setting due to daytime job and a sleeping family. In such conditions phase noise floor is very audible and will not pass in commercial products.

My end goal is to do a high performing audio streaming system using esp32 with our own designed fully integrated audio amplifier. ESP32 is the sweep spot on price, performance and size. And our amplifier has the flexibility to cover use cases from small battery driven portable speakers to battery powered PA systems that will keep the party rocking all night long. Check out what http://soundboks.com made using our technology.

ESP32 Audio PLL

The ESP32 Audio PLL is a 350-500MHz oscillator with a wide bandwidth phase look loop around. Slow lock-in, high resolution and low clock to clock jitter. To use the APLL as clock source for the i2s subsystem one must do:
1. Setup sdm0,sdm1,sdm2 and odir in the clock system APLL section to generate the wanted frequency for i2s module.
2. In i2s module select APLL as clock source and bypass fractional N divider.

Starting with 2. Select APLL and bypass fractional N divider:

In esp-idf/components/driver/i2s.c

Code: Select all

// 20.10.2017/JKJ: Dirty hack to use APLL for i2s audio clock 
I2S[i2s_num]->clkm_conf.clka_en = 1;      // was 0
I2S[i2s_num]->clkm_conf.clkm_div_a = 1;   // was 63;
I2S[i2s_num]->clkm_conf.clkm_div_b = 0;   // was clkmDecimals;
I2S[i2s_num]->clkm_conf.clkm_div_num = 1; // was clkmInteger;
Image

With a review of figure 50 from the hardware ref. we see that APLL_CLK is passed select and passed direct to I2Sn_CLK. We keep M = 4 and get i2SnO_BCK_out to be 4 times less then APLL_SCK. So for 32 bits stereo 44100 samples pr sec:
clock APLL = (2*32*44100) * 4 Hz = 2822400 * 4 Hz = 11289600 Hz

For step 2. Setup APLL
Here we need to review section 3.2.7 in hardware ref. and call rtc_clk_apll_enable(...) to enable and set sdm and divider parameter correctly. One approach is to calculate back from clock APLL = 11289600 Hz to somewhere in the 350-500 MHz range of the APLL oscillator.
Was not able to get the calculation correct - need odir value of 8 to work and doing so I am miss a magic factor (mf) 2 :
clock APLL oscillator = clock APLL * mf * 2 * ( odir + 2 )) = 11,288,960 * 2 * 2 * ( 8 + 2 ) = 451,584,000 Hz

clk xtal * (sdm2 + sdm1/256 + sdm0/(256*256) + 4 ) = 40 Mhz * mf * ( 7 + 73/256 + 0/(256*256) + 4 ) = 445,700,000 Hz

Code: Select all

   
i2s_driver_install(I2S_NUM, &i2s_config, 0, NULL);
i2s_set_pin(I2S_NUM, &pin_config);
rtc_clk_apll_enable(1,0,73,7,8);                     // enable, sdm0 = 0, sdm1 = 73, sdm2 = 7, odir = 8 
My only problem is the magic factor mf of 2 - But I have a stable APLL clock that I can control and there by more the happy.

Clock jitter is gone, I have more then enough resolution to get the i2c_bck I want. The noise floor on our amplifier is around 25 dB lower compared to fracN clock and it just sounds awesome.

Image

Next step
Now i just need some one to help figuring out why my magic factor is needed. When understood, I suggest that we patch the i2s driver to use the APLL if on rev_1 chips. And we all can start to do cool new awesome sounding audio application with ESP32 and cheap class D amplifiers. (please let me know if you want to look in to our technology)

Well done at Espressif and a big thanks to all the hang-around hackers
/Jakobsen
Analog Digital IC designer / DevOps @ Merus Audio, Copenhagen, Denmark.
We do novel and best in class Audio amplifiers for consumer products.
Programmed assembler for C-64 back in 1980's, learned some electronics - hacking since then

BuddyCasino
Posts: 263
Joined: Sun Jun 19, 2016 12:00 am

Re: Audio PLL rocking :-)

Postby BuddyCasino » Fri Sep 29, 2017 12:24 pm

Good to have you back, and thanks for the detailed explanation!

@Espressif: any chance we'll get automatic I2S APLL on rev1 chips?

ESP_Sprite
Posts: 8921
Joined: Thu Nov 26, 2015 4:08 am

Re: Audio PLL rocking :-)

Postby ESP_Sprite » Fri Sep 29, 2017 12:38 pm

We actually have code for that in progress in a MR somewhere. No idea when that's going to be finished and merged, however.

User avatar
Jakobsen
Posts: 89
Joined: Mon Jan 16, 2017 8:12 am

Re: Audio PLL rocking :-)

Postby Jakobsen » Fri Sep 29, 2017 2:15 pm

@buddy - Yeeees -so Happy that I have time to do this stuff again.
@Sprite - Cool if you stumble on some updated i2s.c, I will be very curious to find out what my magic factor (mf=2) is made of.
I have dived into some of the DSP /filter stuff I had to put on hold due to daytime job and other personal stuff.
/jakobsen
Analog Digital IC designer / DevOps @ Merus Audio, Copenhagen, Denmark.
We do novel and best in class Audio amplifiers for consumer products.
Programmed assembler for C-64 back in 1980's, learned some electronics - hacking since then

ionultd
Posts: 1
Joined: Thu Mar 15, 2018 7:38 am

Re: Audio PLL rocking :-)

Postby ionultd » Thu Mar 15, 2018 7:42 am

I know this an old post but I am wanting to implement Wifi audio streaming and need some pointers on how to do this using the latest ESP32 wroom

Who is online

Users browsing this forum: pubsub and 32 guests