0
$\begingroup$

Given a sequence of real numbers that represent a sound signal i.e [1.8, 2.2, 2.2, 1.9, -1.5, -0.7], we must quantize this sequence by dividing the range [-4, 4] to 32 equal parts.

If we had to do this with the traditional way we would need to write 32 different ranges

[-4 , -3.75]

[-3.75, 3.5]

. . .

and check in which one the real value is in.

Is there an another way to achieve this? Maybe with a normalization function or what?

$\endgroup$
  • 1
    $\begingroup$ Have you considered rounding (after dividing by the quantization interval)? $\endgroup$ – Florian Jun 11 at 7:15
  • $\begingroup$ @Florian Not sure If I understand correctly. Can you provide an example? $\endgroup$ – Theof Jun 11 at 7:47
0
$\begingroup$

As hinted by Florian, to quantise any $x[n] \in \mathbb{R}$ to a $y[n] \in \mathbb{Z}$ with $K$ levels you can apply the function:

$$y[n] = round\left( \frac{x[n]-min(x)}{range(x)} (K-1) \right)$$

Where $n \in [0,1,2..|x|]$ and $|.|$ denotes the length of the sequence.

This will map your $x$ from its $min(x)..max(x)$ range to a $[0..K)$ discrete steps range.

For example (in Octave):

Fs = 100; #Sampling frequency (in Hz)
f = 4; # Frequency of a simple sinusoidal signal (in Hz)
T = 1; # Timeframe length (in seconds)
K = 5; # Number of levels to quantise to
t = 0:(1./Fs):(T-(1./Fs));
p = 2.0 * pi * t;
x = sin(f*p);
y = round(((x-min(x))/2.0) * (K-1));
plot(y);
xlabel("Discrete time (sample)");
ylabel("Amplitude");
grid on;

Which produces:

enter image description here

You might also like to see uencode

Hope this helps.

$\endgroup$
  • $\begingroup$ Thanks for the answer. Is there also a way to find in which level a number has been quantized? $\endgroup$ – Theof Jun 11 at 8:56
  • $\begingroup$ @Theof ...for example? You mean find out what the limits that correspond to each level are? (0 is between -4.0 and -3.85, 1 is less than -3.85 to... and so on...Is that what you mean?) $\endgroup$ – A_A Jun 11 at 16:56
0
$\begingroup$

The input to quantization is a vector of floating point numbers, the output are integer numbers so there needs to be a type conversion step.

An efficient quantization algorithm is the following

  1. Calculate the ratio of quantization levels (32 in your case) to the value range (-4 to 4, so 8 in your case. Result would be $32/8 =4$
  2. Multiply the sequence with that ratio
  3. Add 0.5
  4. Convert to integer using "truncation" (which is the default behavior for most languages)

So basically you scale the floating point vector to the same range as your quantization levels (from -16 .. 15) and then simply convert to integer using appropriate rounding methods. That's done here by adding 0.5 and then truncation or "round towards -infinity". That's often a lot cheaper than suing a built-in rounding function.

The one remaining problem here is that the quantization gird is asymmetric, i.e. it goes from -16 to +15. Given the quantization method above, you will also get +16 occasionally, so you either need to clip off these values or increase the value range to accommodate the overshoot. This is only a problem for very low bit quantization (like 5 bits as you have here)

$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.