Skip to main content

Notice

Please note that most of the software linked on this forum is likely to be safe to use. If you are unsure, feel free to ask in the relevant topics, or send a private message to an administrator or moderator. To help curb the problems of false positives, or in the event that you do find actual malware, you can contribute through the article linked here.
Topic: new article about noise shaping (Read 14824 times) previous topic - next topic
0 Members and 1 Guest are viewing this topic.

new article about noise shaping

Hi!

I've added a new article about noise shaping. I guess it doesn't fully qualify as a proper encyclopdia article due to the occasional personal/tutorial tone and lack of references but it's a start.

Noise shaping

Cheers!
SG

new article about noise shaping

Reply #1
Many, many thanks Sebastian!
lossyWAV -q X -a 4 -s h -A --feedback 2 --limit 15848 --scale 0.5 | FLAC -5 -e -p -b 512 -P=4096 -S- (having set foobar to output 24-bit PCM; scaling by 0.5 gives the ANS headroom to work)

new article about noise shaping

Reply #2
Darn!
I just wanted to fix a typo and pressed reply instead of edit.
Please ignore this.

new article about noise shaping

Reply #3
Is it „encyclopdia” you wanted to fix?

For me, typos are not relevant unless they completely change the meaning of a word. Then they are dangerous

Your wiki article is of very good quality!
If age or weaknes doe prohibyte bloudletting you must use boxing

new article about noise shaping

Reply #4
Many thanks indeed. Fascinating stuff!

Cheers, Slipstreem. 

new article about noise shaping

Reply #5
Thank you Sebastian!

The "Decoupling filtering and quantization" was particularly useful and clear.


Please mention somewhere appropriate that SACD is not dithered - or at least, not dither correctly, since this would leave no room for the signal! Hence SACD falls under the criticism you make within the first sentence of the "Limits & filter design restrictions" section. Its placement above implies that it does not have this problem.

Cheers,
David.

new article about noise shaping

Reply #6
Thank you for your kind responses.

As for the SACD dithering issue I think it's on the verge to being off-topic but I added it nonetheless because I covered "undithered quantization" and the SACD example as well.

Cheers!
SG

new article about noise shaping

Reply #7
Thx Sebastian for great article.

At the moment I'm adding dither routine based on your algoritm to mplayers ogg and mp3 decoder.
I implemented your article in integer only routine, which takes about 1% CPU on P3@1GHz for stereo 44.1kHz.
Haven't tested with music yet, but on a low amplitude sine generated in C, algoritm works like a charm!

#include "tgmath.h"
#include "stdlib.h"


int NoiseShapedDither(in,ch)
int ch;
long in;
{
    /* 32 bit integer in
    relation 32bit input sample <==> 16 bit audio output:  aud32=aud16<<11;
    This gives 11 bits resolution for dither, 5 bits peak headroom    */

    #define MAXCH 8 /* multi channel audio 8 ch should suffice.
                              CHANGING MAXCH breaks array initializations!!  */
    static unsigned long rnd=256;  /* 32bits fibonacci shift reg PRNG. Init at any value but 0....*/
    long wanted,quantized;
    static long h_out [5] [MAXCH] =
    { {0,0,0,0,0,0,0,0}, {0,0,0,0,0,0,0,0}, {0,0,0,0,0,0,0,0}, {0,0,0,0,0,0,0,0}, {0,0,0,0,0,0,0,0} };
    static long last_error [4] [MAXCH] =
    { {0,0,0,0,0,0,0,0}, {0,0,0,0,0,0,0,0}, {0,0,0,0,0,0,0,0}, {0,0,0,0,0,0,0,0} };
   
   
    h_out[4][ch]=h_out [3][ch];
    h_out[3][ch]=h_out [2][ch];
    h_out[2][ch]=h_out [1][ch];
    h_out[1][ch]=h_out [0][ch];
    /* based on 44.1k LAME ath IIR formula for hearing treshold */
    h_out[0][ch]= (-17346*h_out[1][ch] -1108*h_out[2][ch] + 9919*h_out[3][ch] + 4486*h_out[4][ch]
    +36145*last_error[0][ch] -7710*last_error[1][ch] -4152*last_error[2][ch] -10181*last_error[3][ch]) ;

    h_out[0][ch]= h_out[0][ch] >> 14 ; /* compensate for scaling in previous line */

    wanted=in-h_out[0][ch];

    /* GENERATE 22 new random bits. Generator based on 32 bit  Fibonacci shift register. */
    rnd= (rnd<<22) + (  0x003FFFFF & ( (rnd>>9) ^ (rnd>>7) ^ (rnd>>6) ^ rnd )  ); 
    /* from 32bits, use 2 11 bits parts as random numbers (=triangularPDF), offset and quantize ......*/
    quantized=0xFFFFF800 & ( wanted  - 1024 +  ( (rnd>>11)&0x000007FF ) + (rnd&0x000007FF)  );

    last_error[3][ch]=last_error[2][ch];
    last_error[2][ch]=last_error[1][ch];
    last_error[1][ch]=last_error[0][ch];
    last_error[0][ch]=quantized-wanted;
    quantized=quantized>>11;
    if ( quantized > 32767)
   return(32767);
    else if ( quantized < -32768 )
   return(-32768);
    else return(quantized);
}

new article about noise shaping

Reply #8
The noise shaping part looks good at the first glance.

If you like you could get rid of the last_error arrays when swithing from Direct Form I to Direct Form II for H(z). But this would also require to quantize twice to get the filter's output. The danger of getting overflows in DFII is also a bit higher when working with integers.

Your quantization part seems to introduce a bias towards negative infinity which makes the error samples unnecessarily large. I don't think you need the "-1024" here because the binarry "AND" with 0xFFFFF800 already leads to an average reduction of 1024.

inline int zero11LSBs(int x) { return (x+0x400) & (-0x800); } // correct rounding

So, the +1024 for the correct rounding and your -1024 to offset the dither cancel each other out.


Cheers,
SG

new article about noise shaping

Reply #9
The line having the -1024 in it needs some comment:
Basically, it performs this function (in floating point):
floor(input+0.5+TPDF)
where tpdf is trianguler PDF dither in range -1....+1
The 0.5 is needed to compensate for offset in floor function

However, my dither is triangular based in range 0....+2 so to compensate, I have to subtract 1, leading to
floor(input-0.5+TPDFoffset1)

I'll have to look into DirectFormII later on...

new article about noise shaping

Reply #10
However, my dither is triangular based in range 0....+2 so to compensate, I have to subtract 1, leading to
floor(input-0.5+TPDFoffset1)

You're right. I was mistakenly thinking about a rectangular dither with a range of 0...+1

Cheers,
SG

new article about noise shaping

Reply #11
Most textbooks mention 2LSB peak-peak TPD dither as dither source to fully get rid of quantization errors.
Previous code was based on this 2 LSB peak-peak value:
quantized=0xFFFFF800 & ( wanted - 1024 + ( (rnd>>11)&0x000007FF ) + (rnd&0x000007FF) );


However, with the noise shaping loop added, it seems you can get away with a lower value:
I just tried by halving this TPD white noise to 1 LSB peak-peak, and don't see any distorsion showing up on the spectrum using a two-tone test signal, but overall noise floor is lowered a couple of dBs!
quantized=0xFFFFF800 & ( wanted  +  ( (rnd>>11)&0x000003FF ) + (rnd&0x000003FF)    );

For this noise shaping, what's the optimal internal dither source? There's nothing about it in the topic-start wiki.

new article about noise shaping

Reply #12
However, with the noise shaping loop added, it seems you can get away with a lower value:
[...]
For this noise shaping, what's the optimal internal dither source? There's nothing about it in the topic-start wiki.

From what I know you still need 2 LSBs peak-to-peak to be able to guarantee that there won't be nasty distortions. My personal favorite dither method is a morphed PDF between rectangular and triangular:
Code: [Select]
dither_k = (random()-0.5) + s * (random()-0.5);

with random() returning random numbers between 0 and 1 (rectangular probability density) and 's' being a scalar between 0 (=> rectangular) and 1 (=> triangular). This way it's always at least as good as a rectangular dither (important feature!). I also noticed that when noise shaping is in use it's okay to use lower values for 's' like 0.6 without getting noise modulation. The noise floor wil be 1 dB below of what you'd expect from a full triangular dither. However, I know of no proof for it to work all the time. It just does in the cases I checked.

Cheers,
SG

new article about noise shaping

Reply #13
From what I know you still need 2 LSBs peak-to-peak to be able to guarantee that there won't be nasty distortions. My personal favorite dither method is a morphed PDF between rectangular and triangular:
Code: [Select]
dither_k = (random()-0.5) + s * (random()-0.5);

with random() returning random numbers between 0 and 1 (rectangular probability density) and 's' being a scalar between 0 (=> rectangular) and 1 (=> triangular). This way it's always at least as good as a rectangular dither (important feature!). I also noticed that when noise shaping is in use it's okay to use lower values for 's' like 0.6 without getting noise modulation. The noise floor wil be 1 dB below of what you'd expect from a full triangular dither. However, I know of no proof for it to work all the time. It just does in the cases I checked.

Cheers,
SG
Interesting, very interesting....
lossyWAV -q X -a 4 -s h -A --feedback 2 --limit 15848 --scale 0.5 | FLAC -5 -e -p -b 512 -P=4096 -S- (having set foobar to output 24-bit PCM; scaling by 0.5 gives the ANS headroom to work)

new article about noise shaping

Reply #14
Well seeing that I am writer and not much of a Mathmatician I did manage to add a few sources in your article in particular the one on SACD dithering. Cheers.  Excellent article btw. I think there are a few other ones that need to be rewritten in the Signal Processing section and we will be in good shape.
budding I.T professional

new article about noise shaping

Reply #15
Most textbooks mention 2LSB peak-peak TPD dither as dither source to fully get rid of quantization errors.
However, with the noise shaping loop added, it seems you can get away with a lower value:
I just tried by halving this TPD white noise to 1 LSB peak-peak, and don't see any distorsion showing up on the spectrum using a two-tone test signal, but overall noise floor is lowered a couple of dBs!


Here's an example of this causing a problem with a single test tone, though I suspect that away from test tones, you'd get away with it.

  -bandpass