ASRC on Cortex M4 44.1KHz example

4 posts / 0 new
Last post
Terry Shultz
Offline
Last seen: 7 months 2 weeks ago
Joined: 01/09/2017 - 9:07pm
ASRC on Cortex M4 44.1KHz example

So digging into all your examples, BSPs, and the ASRC library itself I cannot seem to see how converting from 44.1k will work.

The way your examples show conversion, buffering, DMA, etc. is all setup for sample rates divisible within the 1ms USB period (ie. 48k, 32k, 16k), but I do not see anything related to non 1ms divisible sample rates (44.1k).

Do you have any examples and  documentation showing the use of 44.1k systems (whether using the ASRC or just generic 44.1k based systems)?

Right I cannot see how, the way your examples are setup, they can handle 44.1k.

Axel Nilsson
Offline
Last seen: 1 hour 35 min ago
Joined: 12/19/2016 - 2:02pm

We do not have an example for this specific configuration, but the basic idea is that our ASRC can link up any number of supported from/to samples rates. The clocking is up to the firmware author.

 

 

Example:

 

Suppose you have on input device running at 44.1KHz with an audio frame size of 30 samples. You wish to play back these samples to an output device running at 48KHz with an audio frame size of 32 samples. You then setup the ASRC with input SR 44.1 and input block size 30, output SR 48 and output block size 32. Then, every 680 us the firmware inserts 30 samples into the ASRC buffer and every 666 us the firmware reads 32 samples from the ASRC buffer.

sgarcia_1564
Offline
Last seen: 1 month 1 week ago
Joined: 10/23/2017 - 6:43pm

Thanks for your reply Alex.

To clarify, I'm using the ASRC to convert audio streaming over USB (with 1 packet coming in every 1 ms) from 44.1k to 48k, then out to my I2S bus that is at 48k. Using the ASRC to convert 32k to 48k works just fine, because there are 32 samples per packet coming in every 1 ms at 32k, so my input block size is 32 and my output block size is 48.

The problem happens with 44.1k, where every 1 ms there are 44 samples per packet, but on the 10th packet there are 45 samples. So this is an irregular packet size of samples, and in the documentation for the ASRC, it says this under dsp_asrc_write() "In order for the jitter buffer regulator to function properly, numSamples should always be the same". So it looks like I cannot insert 44 samples into the ASRC buffer and then every 10th packet insert 45 samples. 

My solution that I have been experimenting with is buffering 10 ms worth of audio at the USB input, which gives a nice clean number of 441 samples. I then every 10 ms insert 441 samples into the ASRC buffer, and every 1 ms read 48 samples from the ASRC buffer into the my I2S output. This is almost working, but when I play a tone from the USB running at 44.1k, after converting to 48k, you can hear a modulated high pitch of that tone that is not supposed to be there (around 4kHz to 5 kHz buzzy tone, depending on the input tone). I am not sure if it something wrong with my buffering which looks ok, or the ASRC module cannot handle that high of an input block size (441) versus the output block size (48). 

There might be a better way to do this I just don't see how yet. Please let me know your thoughts. 

CleveTripp
Offline
Last seen: 6 days 54 min ago
Joined: 09/25/2019 - 12:29pm

Hi... A "regular" sample rate converter is synchronous and converts between two fixed sample rates.  For example, converting from 8 kHz to 32 kHz.  Synchronous conversion is most efficient when the rates are related by small integers.  Going from 8 to 32 kHz is a fixed increase of 4x.  Converting an audio file from 44.1 kHz to a fixed output rate of 48 kHz can be accomplished using synchronous conversion but the factors aren't that nice any more.  You need a ratio of 160/147.

https://www.7pcb.com/