the audio streaming series

the converter

The decision If or If-Not to run Sample Rate Conversion (SRC) on your precious data, depends on your environment and expectations. There are scenarios where SRC makes sense, other scenarios where it does not add any benefit and third where things even get worse. You'll be your own judge when listening to the final result.

Keep in mind. Any DSP task, such as SRC, causes losses. (see SRC - If you can't avoid it). And then there is no such thing as the perfect SRC setting. There are infinite ways to configure a SRC.

Let's give it a positive spin. You can't do much wrong by just trying it. Very easily you'll be able to play around with this or that parameter. And if you own a DAC that performs better with higher and/or different sample rates, this part of the project will be a winner tweak. The goal basically is to beat the quality of your DACs internal SRC/DSP by doing a better job on the outside.  

Let's have a look @ Sample Rate Conversion (SRC) with squeezelite. I'd like to give you quick intro, of how to configure a quality SRC by using the embedded libsox SRC of squeezelite. 





Squeezelite SRC

Lucky us. squeezelite offers excellent samplerate conversion - if enabled. We can achieve highest quality SRC based on the library libsoxr (sox). libsoxr is a special purpose library of sox and had been developed having highest efficiency while still delivering highest quality in mind.

Which binary ?

The default pCP squeezelite binary comes with SRC (libsoxr) enabled. It'll do.
However. You better use the SRC enabled custom binary with MultiProcessor support.  (see: the custom engine)

Which SRC settings ?

Let's first have a look at what's available.
I reshaped the squeezelite help output and added some more info if been taking from the library sources and sox manual. To be honest. I was never able to make sense of any of the help functions you'll find out there.

Let's try mine. It'll outline the SRC playground in a much more detailed way. The top line shows the
options squeezelite expects. Below are the available options. Confusing? Yep. I know. Further down 
you'll find an example. My preferred settings.

----------------------------------------------------------------------------------------------------------------
 

-R <recipe>:<flags>:<att>:<precision>:<passb_end>:<stopb_start>:<phase>



recipe         = (v|h|m|l|q)(L|I|M)(s) [E|X]

                                             default          min|max   
E              = unsupported rates SRC        all SR

X              = async SRC                    sync
flags          = byte code in hex             0
attenuation    = in dB                        1                 0|6
precision      = noise rejection (1bit~6dB)   20               16|20|24|28|32
passband_end   = in % of Nyquist              91.3           74.0|99.7
stopband_start = in % from Nyquist            100             100|200-passband_end
phase_response = in %                         50                0|50


recipe aliases break down

                                  prec    noise-reject/dB
v = very high quality         =    28    ~   175
h = high quality              =    20    ~   125
m = medium quality            =    16    ~   100            (medium rolloff)
l = low quality               =    16    ~   100            (larger rolloff) 
q = quick                     =    n/a   ~    30            (cubic interpolation)

                                  phase
L = linear phase              =    50
I = intermediate phase        =    25
M = minimum phase             =     0

                                 pb-end/%
s = steep filter              =    99


flags


                          decimal      bin       hex
ROLLOFF SMALL                0      0000 0000     0  (default)
ROLLOFF MEDIUM               1      0000 0001     1
ROLLOFF NONE                 2      0000 0010     2
High Precision Clock         8      0000 1000     8
Double Precision (64-bit)   16      0001 0000    10

-----------------------------------------------------------------------------------------------------------

Note1 

All options that come after the <recipe> block option are characterized as override options. These will override all settings done in the recipe block. Keep in mind all blocks must be separated by a colon.

Example for override:

v::20:::: 
v  selects 28bit first, and now in this example it gets overridden with precision 20

I hope that explains the logic.


Note2

You only have to enter the preceding colons. There's no need to enter the succeeding colons.
The example of Note1 could also be entered:

v::20

Make sure you count the colons properly!

Note3

squeezelite expects the <flags> field input in hexadecimal format. To set the above listed flags bits you can simply add up the shown hex values.  Or you can add the decimal values and convert them to hex.
The idea behind the flags field is to set multiple features by a single byte. That's highly efficient. Not very user friendly though.

Example:

We're choosing 3 flags out of 5. 

flags/hex = Rolloff None + High Prec Clock + Double Prec = 2 + 8+ 10 = 1A
flags/dec = Rolloff None + High Prec Clock + Double Prec = 2 + 8+ 16 = 26  >> hex = 1A

Important: Only one out of the 3 ROLLOFF flags should be selected.



The Menu

 Let's have a look at some examples.


You can skip below examples if you like to use some presets I put together, as part of soundcheck's tuning kit, These presets can easily be installed with the sKit-src-manager.sh tool . And they'll work.


Of course you can further tune these presets once they are installed. That's why I leave below examples online.


1. soundcheck's settings 

  • max sample rate 384000 (limited by the DAC of choice )
  • synchronous resampling (44.1 > x*44.1 and 48>x*48)
  • 64 bit processing, high precision clock, rolloff none
  • 32 bit noise rejection
  • 1 dB attenuation
  • 95.4 %  passband end
          (50% of  Nyquist = 44100/2 * 0.954 = @21036 >> -3dB down)
  • 104.6 % stopband start  
          allow aliasing (stopb start=200 - 95.4 (passband end) = 104.6 )
          this usually reduces the ringing, adds some aliasing in the upper range
  • 46 % phase
          slightly away from linear (50%) towards minimum phase (0%)
          lowers pre-ringing, while accepting small phase issues at the end of the spectrum
This leads to following pCP mask entries:
 

 384000

v:1A:1:32:95.4:104.6:46


Note: Even though my USB DAC supports up to 748kHz I limit the SRC to do resampling to 384kHz max. Simply because I don't get sound above 384kHz yet. I havn't figured out yet what's going on. Values and logs seem to be OK. With above setting 44.1kHz would be upsampled to 352.8 (synchronous upsampling). And that's what I wanted. 

Here's the pCP screenshot of above setting:



And here's the Alsa trace showing the 352.8kHz samplrate on its way to the DAC.



Warning: squeezelite doesn't verify the entered values properly - if SL checks them at all! You better check twice what you're entering. Try to be right on spot with your settings, within above mentioned limits.

2. A linear filter without aliasing


Let's construct a variant of my preferred solution. Just to show you how it works:

  • linear phase
  • no aliasing
  • ~175dB noise rejection
  • the DAC can handle 192kHz max.
These choices would increase the pre- and post-ringing a bit. Noise rejection would be worse, still we'd look at more than sufficient -175dB noise rejection. And our sample rate would be limited.
On the pro side, we'd get rid of any phase shift, aliasing would be gone and CPU load goes down a bit.

Just try it.


This example would lead to following pCP mask entries:
 

 192000

v:1A:1:28:95.4:100:50



3. The default settings

Unfortunately pCP won't allow yet to just enable the SRC with its default settings. I talked to Paul about introducing a radio button in the WEB-UI To accomplish this. Let see if he does something about it.

The default settings would look like this:

::1:20:91.4:100:50

You can achieve the same by just adding a simple parameter of the <recipe> block, matching above default settings, simply to enable the resampler. Below shown  "h" option would equal 20bit precision, which is part of the default filter settings.

h



4. Your settings can end up here 


Send me you preferred settings, I'll check them out and list them here.

Summary

Of course there'd be a lot more to talk about. You can discuss all kind of settings forever.
I havn't transferred any other of my "SRC - if you can't avoid it" examples. These IMO simply sound much worse then above to me.  

I hope this article, which took me quite a while to create, puts you in a position to create your own highest quality SRC based one squeezelite sox/libsoxr.  

Once more let me know your preferred settings . That'd be highly appreciated.
As usually getting feedback about my own SRC proposal is also highly appreciated.


Enjoy.











Leer


No comments:

Post a Comment