In telecommunications devices that use pulse code modulation, it's necessary to compute the power of analog signals. Here's a handy way to do that without the use of floating-point hardware.
In order for telecommunications equipment to translate audio signals into digital data, the equipment must measure the power level of an analog signal, which is encoded as a set of pulse code modulation (PCM) samples. Once encoded, these samples are decoded on the receiving equipment back into audio signals. Since many telecommunications systems are built without floating-point processors, it's useful to make these signal-level calculations with integer-only mathematics. In this article, I'll explain how you can use a fixed-point signal-level calculator to compute the power of analog signals.
Before we move into the computations, keep in mind that telephony systems in North America and Japan use the μ-law standard to encode speech, while most of the rest of the world uses A-law encoding. Both encoding methods sample at 8kHz and use logarithmic compression, which results in an 8-bit sign-magnitude representation of each sample. When these samples are decoded back into their linear representations, however, μ-law produces a 13-bit plus sign number and A-law produces a 12-bit plus sign number.
When making a telephone call from North America to Europe, the μ-law and A-law samples must be translated back and forth between each other. The International Telecommunication Union (ITU) provides a lookup table for both of these translations. These translations always guarantee that a 0dBm0 reference signal in one format is translated into the 0dBm0 reference signal in the other format.
The computations for finding the power level of a sampled signal are straightforward when implemented with floating-point numbers. A few manipulations of the basic equations give a result that's easily implemented using fixed-point arithmetic.
In the field of telephony, the power level of an audio signal is generally expressed in dBm0 units. That is, the number of decibels relative to a 1mW transmission. This can be expressed as:
20 log(rms/ref )
where rms is the root-mean-square of the sampled signal and ref is the voltage of the reference 1mW transmission. This can be rewritten thus:
20 log(rms ) – 20 log(ref )
in which the latter half is a constant:
20 log(rms ) – m0
You can compute the constant m0 ahead of time and store this value in ROM for later use.
Let's now turn our attention to the efficient computation of the rms term. In a discrete sampled system, the RMS value of the sampled signal can be computed as:
The average of the sum of the squares can be performed using integer arithmetic. For ease of discussion let:
The signal level, in dBm0 units, can be then expressed simply as:
10 log(avesq ) – m0
Thus the computations for finding the power level of a sampled signal boil down to computing the logarithm of a large integer and precomputing the offset, m0 , for the reference signal.
The ITU has specified a standard sequence of samples for a 0dBm0 reference signal at 1kHz under each encoding scheme. When decoded into linear sample values, these are as shown in Table 1. The sample sequences in Table 1 can be used to compute the reference constant, m0 .
Table 1: Sample sequences for 0dBm0 reference signals
A basic logarithm computation algorithm can be found in Donald E. Knuth's book, The Art of Computer Programming, Volume 1: Fundamental Algorithms . (Reading, Massachusetts: Addison-Wesley, 1997). This algorithm was originally designed to compute a floating-point result, but can be easily modified to produce an integer result by scaling the result into a large multiple of the floating-point value.
Listing 1 shows how all of this comes together. Two look-up tables, named LOG10_2NM1 and LOG10_2N , hold scaled versions of the constants provided with the Knuth log algorithm. The multiplier, SCALE , has been set to 131,072 (217 ), which retains 17 bits of accuracy after the (assumed) floating-point. The constants in the lookup tables have also been premultiplied by 10 (for the constant in front of the log in our formula) and 100 (to cause the result to be reported to the nearest 1/100th of a dB).
Note that if you want a floating-point implementation, simply change the two lookup tables and the local variable y to floating-point numbers. In recomputing the array values, simply remove the scaling factor of 131,072,000.
The m0 reference constants for A-law and μ-law encoding are precomputed and included as macros. Comments in the listing show how these values were derived from the sample values in Table 1.
To compute the level of a signal in dBm0 units, first calculate the avesq of a sequence of samples, then call function dBm0() with that and the appropriate m0 constant as arguments. The result is an integer value, in units of 1/100th of a dB.
Can you hear me?
By precomputing two small tables and a couple of constants, you can implement a fixed-point logarithm function. Using this fixed-point logarithm function, you can quickly compute the power level of a digitized analog signal without the use of floating-point hardware or floating-point software libraries. esp
Geoff Probert is a consulting telecommunications engineer who has been developing telephony systems for 31 years. Geoff holds a masters degree in electrical engineering from the University of Colorado. His e-mail address is .