PNYQ Z2 - Change sample rate in AudioADAU1761 codec

Hello everyone,

I wanted to change the default sample rate 48000 Hz to 41000Hz with following code:

from pynq.overlays.base import BaseOverlay
base = BaseOverlay("base.bit")
pAudio = base.audio
pAudio.configure(44100,1,)

Then i checked if the sample rate has even changed:

from pprint import pprint
pprint(vars(base.audio))

{‘_ffi’: <cffi.api.FFI object at 0xae6f0fb0>,
‘_gpio’: {},
‘_interrupts’: {},
‘_libaudio’: <cffi.api._make_ffi_library..FFILibrary object at 0xae6f0750>,
‘_register_name’: ‘audio_codec_ctrl_0’,
‘_registers’: {},
‘buffer’: array(, dtype=int32),
‘device’: <pynq.pl_server.device.XlnkDevice object at 0xb0256550>,
‘iic_index’: 1,
‘mmio’: <pynq.mmio.MMIO object at 0xae6f0fd0>,
‘sample_len’: 0,
‘sample_rate’: 44100,
‘uio_index’: 0}

I played a test audio with:

pAudio.load("/home/xilinx/jupyter_notebooks/base/audio/test.wav")
pAudio.play()

It still sounds the same - even if i set the value to 2000 Hz where aliasing should occur.
What is necessary to update these values in the codec?

Kind regards

Currently as you can see in our API: PYNQ/audio.py at master · Xilinx/PYNQ · GitHub
Sample rate does not get configured into the ADAU chip.

You may want to check ADAU1761 data sheet to understand the parameter and update the corresponding values in PYNQ/audio_adau1761.cpp at master · Xilinx/PYNQ · GitHub.

I have changed the register adresses of ADAU1761 accordingly to
ADAU1761 Datasheet in /lib/_pynq/_audio/audio_adau1761.cpp.

I wanted to change the sampling rate to e.g. 12 kHz.

write_audio_reg(R0_CLOCK_CONTROL, 0x0E, iic_fd);
/* MCLK = 10 MHz
*
* Previous:
* R = 0100 = 4, N = 0x023C = 572, M = 0x0271 = 625
* PLL required output = 1024x48 KHz = 49.152 MHz
* PLLout/MCLK = 49.152 MHz/10 MHz = 4.9152 MHz
* = R + (N/M)
* = 4 + (572/625)
*
* PLL required output = 1024x12 KHz = 12.2880 MHz => 1.2288 MHz
* M = 0x0271 = 625, N = 0x008F = 143, R = 0010 = 2, X = 01 = 2 (DIVIDER)
*/
// Register write address [15:8]
u8TxData[0] = 0x40;
// Register write address [7:0]
u8TxData[1] = 0x02; // previous - u8TxData[2] = 0x02;
// byte 6 - M[15:8]
u8TxData[2] = 0x02; // previous - u8TxData[2] = 0x02;
// byte 5 - M[7:0]
u8TxData[3] = 0x71; // previous - u8TxData[4] = 0x71;
// byte 4 - N[15:8]
u8TxData[4] = 0x00; // previous - u8TxData[5] = 0x02;
// byte 3 - N[7:0]
u8TxData[5] = 0x8F; // previous - u8TxData[6] = 0x3C;
// byte 2 - 0 = reseved bit, 0010 = R[3:0], 01 = X[1:0], 0 = PLL operation mode
u8TxData[6] = 0x15; // previous - u8TxData[7] = 0x21;
// byte 1 - 1 = PLL Lock, 0 = Core clock enable
u8TxData[7] = 0x03; // previous - u8TxData[7] = 0x03;
// Write bytes to PLL control register R1 at 0x4002

After saving audio_adau1761.cpp the audio codec doesn’t adapt it even after restarting PYNQ.

How can I force the codec to adapt these adresses during runtime?
How can I call the method config_audio_pll in audio.py to update these values?

Thank you in advance.

You just changed the source code, you will need to recompile it to take effect - The libaudio.so file has to be recompiled. Leverage this Makefile: PYNQ/Makefile at master · Xilinx/PYNQ · GitHub

Thanks,
but there is still an issue with audio playback, which is my origin reason for changing the sampling rate.
If you listen to the audio playback you will notice a difference in pitch. The pitch of the playback will sound higher than the origin soundfile, if you compare it with playback on PC.

So i want to share all steps for reproduction of this phenomenon.

  1. Change sampling rate to 44.1kHz: /lib/_pynq/_audio/audio_adau1761.cpp:
  • PLL required output = 1024x44.1 KHz = 45.1584 MHz => 4.51584 MHz
  • X = 00 = 0 (DIVIDER), R = 0100 = 4, M = 0x0C35 = 3125, N = 0x064C = 1612,
    */
    // Register write address [15:8]
    u8TxData[0] = 0x40;
    // Register write address [7:0]
    u8TxData[1] = 0x02;
    // byte 6 - M[15:8]
    u8TxData[2] = 0x0C;
    // byte 5 - M[7:0]
    u8TxData[3] = 0x35;
    // byte 4 - N[15:8]
    u8TxData[4] = 0x06;
    // byte 3 - N[7:0]
    u8TxData[5] = 0x4C;
    // byte 2 - bits 6:3 = R[3:0], 2:1 = X[1:0], 0 = PLL operation mode
    u8TxData[6] = 0x21;
    // byte 1 - 1 = PLL Lock, 0 = Core clock enable
    u8TxData[7] = 0x03;
    // Write bytes to PLL control register R1 at 0x4002
  1. Recompile Makefile in /lib/_pynq/_audio/Makefile to generate new libaudio.so file.
  • Use PuTTY and log on COM port
  • Enter following commands:
    cd pynq/lib/_pynq/_audio
    make
  • Backup previous libaudio.so (sampling rate = 48kHz) and copy new libaudio.so (44.1kHz) into: /lib
  1. Change sampling_rate to 44100 in /lib/audio.py

  2. Run Jupyter

  3. Enter following code:

from pynq.overlays.base import BaseOverlay
base = BaseOverlay("base.bit")
pAudio = base.audio
from pprint import pprint
pprint(vars(base.audio))
pAudio.load("/home/xilinx/jupyter_notebooks/base/audio/recording_0.wav")
pAudio.play()
  1. Compare with different 44.1kHz and 48kHz soundfiles

Is this a common issue of the PYNQ audio board?

Kind regards

The jupyter notebook code you have entered looks like you only loaded the old sample, but I am not sure if you have recorded that sample also using the 48KHz sample rate. The reason why you have seen higher pitch might be: you played a 44KHz recorded sample using 48KHz sample rate.

Hello rock,

i have just mentioned the testfile as reference in my code. I’ve tested this several files as well. If i compare the playback of this test file on pynq with playback on PC via network there will be the same pitch difference noticable. If you playback 44.1khz soundfile on PYNQ you will notice a much higher difference in pitch. So there must be something which we have not considered. Maybe you can test it by yourself and give me feedback.

Kind regards

The reason is because the microsoft wav file is really 44.1KHz and you cannot change that easily I suppose. Check: https://www.isip.piconepress.com/projects/speech/software/tutorials/production/fundamentals/v1.0/section_02/s02_01_p05.html#:~:text=The%20WAV%20audio%20format%20was,quality%2016-bit%20audio%20format.

My guess is that you need some additional tool / techniques to change the default sample rate on Windows machine.

You said Pynq-Z2 has a higher pitch, but which one is correct? Which of the two, between Pynq-z2 and windows, is the one you want to have eventually?

Hello,

Thanks for your reply. I’m already familiar with the most common effects of audio codecs and formats.

I can change the sampling rate easily with windows audio driver or my external audio interface for comparison. I will explain it in detail:

An 48 kHz audio file on my pc with equivalent driver settings sounds normal. On PYNQ-Z2 the same file sounds a little bit higher pitched than on my pc.

An 44.1 kHz audio on my pc with equivalent driver settings also sounds normal. On PYNQ-Z2 the same file sounds much higher pitched and faster playback than on my pc.

So one could guess that the playback of audio is getting faster when using audio files with lower sample rates. My guess if you change the audio codec to another sampling rate - PYNQ’s overlay is however still calculating with the predefined 48 kHz. Normally when you convert between 44.1 to 48 kHz you have to interpolate the redundant or missing samples. So there could be something else i have to consider.

I will attach you all my material for reconstruction:

This is the recorded output of my PC at 48 kHz.

This is the recorded output of PYNQ at 48 kHz. Observe: Sounds a little bit higher

This is the recorded output of my PC at 44.1 kHz.

This is the recorded output of PYNQ at 44.1 kHz. Observe: Much shorter and high pitched

All code files - please rename the files for testing

code.zip (112.7 KB)

I have not noticed the difference for the 48KHz samples. For 44.1KHz I can tell the difference - so maybe let’s just focus on 44.1KHz samples.

First, I need to confirm a few things. For your 44.1KHz sample recorded on z2, did you play it back using z2, or using PC? Does it sound different on z2 / PC?

I checked your configurations in C program and they look good to me.

The 44.1 kHz sample files are recorded from pc and from pynq z2 line output. You have noticed the difference so i dont understand your last question…

So is there anything else in the pynq audio codes which we have to adapt?

So you are recording 44.1KHz sample from PC, and play it back on z2 audio output? You have two sources of audio input (PC, or Z2 audio-in), and two ways to play it back (PC, or Z2 audio-out). My question was “which one of the 4 combinations were you showing in your question?”

I wanted the compare the audio playback on PC with the audio playback on PYNQ Z2:

The first version is the original soundfile from PC storage which is recorded with PC audio interface and the soundfile of the second version was stored on PYNQ storage and played out with PYNQ Z2 line out into my PC audio interface line in and recorded with the same audio settings for comparison.

PN: You will notice the pitch difference of the two 48 kHz samples in the first 1-2 seconds. Observe how the tone of the piano sound and hiats is a little bit higher at the PYNQ version.

Sorry, I still cannot tell the difference for the two 48KHz samples…

For the 44.1KHz samples, can you try this thing: record your wav file using pynq-z2, and then play back that wav file in your PC. If the wav file is ok on your PC side, then at least we know the wav file has been recorded correctly.

Similarly, you can try to record the wav file from PC, and play it back on z2 to see if the playback side is working fine.

Also I think you need to look into the wav package that we use in audio.py. There might be some surprises that the sample rates are adjusted automatically by the package.

I’ve been debugging a similar issue – trying to reconfigure the audio codec on the PYNQ-Z2 to play at 44.1kHz. I found that writing to the appropriate I2C registers (as described above) didn’t seem to work.

Then I realized it was dependent on the actual I2S hardware. It is fixed at 48kHz. See PYNQ/user_logic.vhd at 7f4a3b92e09714d02545ffc8432124d5d9f1ad0d · Xilinx/PYNQ · GitHub

…and actually, it’s really sending samples at 48.828125 kHz, since it makes for nice division (100MHz / 2048 = 48.828125 KHz).

That 1.7% difference could be responsible for the slight pitch difference you’re hearing with the 48kHZ sound files.

2 Likes

Also, the PYNQ Z-2 uses that audio hardware while the PYNQ Z-1 does not, which is why you may be hearing a difference.

Hey Jeff,
thanks for your contribution on this issue. Did u manage to adjust the samplerate of the audio codec from 48 to 44.1kHz by changing the clockrates in user_logic.vhd?

No, we never tried. At that point it was just easier to resample our audio files.