Aerospace



Citadel Forums

Home

Company Information

Information Request

Linux How-to Guides

ADSP 21xx
Digital Signal Processing
Tutorials

SW Utilities

On-line Order Form

Server Support


bonk

Have you found this site useful? Did we save you time? Did we cure your head-ache? Is your hair growing back now?

Please make a donation to help with maintenance.


Objective Real-Time Software on the ADSP21XX

PCM Audio

Pulse Code Modulation (PCM) is a essentially a fancy name to say that you sample the audio at a fixed rate, usually 8kHz for telephone quality audio and then transmit the digital samples over a wire line.  In order to cut down on the bandwidth requirements and still have acceptable voice quality, one of two audio compression schemes is commonly used and the loosely used term PCM audio, usually refers to compressed, 8 bit PCM, with a sample rate of 8 kHz, resulting in a 64kbps bit stream.

These compression techniques use a S curved graph, which means that a soft signal is almost not compressed at all, while a loud signal is squashed up severely.  This way, we can increase the apparant dynamic range of the audio signal without having to use many bits to represent the signal.  Think of it as providing soft clipping to loud signals, which can be undone again at the speaker, yielding the same loud signal.

This compression/decompression is usually performed in hardware, using a CODEC, short for coder/decoder, which is a logarithmic digital to analogue converter, with built-in anti-aliasing and reconstruction filters, thus reducing a PCM interface to a single chip.  As there are many millions of these chips in use, they are quite inexpensive.
 

Nobody is above the law

The logarithmic compression comes in two popular flavours: A law and Mu law.  The two compression curves are almost identical, but A law provides a little more compression than Mu law.  According to Mu law, 12 bits of audio can be compressed to 8 bits, while A law will squash 14 bits of audio to 8 bits of compressed PCM.  Mu law is used mainly in North America and Japan, while A law is used elsewhere.  I guess that Europeans like to talk louder and therefore need the extra bits...

However, there is an important thing that nobody ever tells you.  A law PCM is usually odd bit inverted, according to a CCITT recommendation.  Why? just to be inconvenient...  Well, actually, the idea was to ensure that a fixed level will still provide bit edge transitions, for a receiver Phase Locked Loop (PLL) to synchronize on, but this has become less important over the decades.

If you want to decode an A law signal yourself, without using a CODEC, it is important to XOR the 8 bit PCM byte with 0x55, to invert all odd bits, before trying to expand the audio. Odd bits??? Those are EVEN!  Well, CCITT starts numbering at the sign bit and on a wire line, data is usually transmitted LSB first, resulting in PCM audio being transmitted sign bit first, which all normal human beings will consider to be the MSB, but which according to CCITT is not. So it is important to remember that CCITT members are not normal...

Mu law also has a little known quirk, called zero code suppression.  While raw compressed A law audio souds horrible when played back on a speaker without doing the XOR thing, Mu law sounds almost acceptable.  For Mu law, the code is inverted and the zero code is suppressed, by inverting (or not inverting?) bit 6 (bit 1 to normal human beings) of the 8 bit PCM samples, turning 0 into -2.  This is an inaudible change, which cannot be corrected, since the zero code looks the same as a valid -2, so if you try an XOR trick here, all valid -2 codes will also become 0 and then you haven't really achieved anything useful.  Note that 0 is not zero audio, it is maximum negative deflection and -2 is also very loud!

We can therefore construct a kind of truth table to explain this crazy numbering system as shown in table 1.
 
 
Table 1. Mu / A Law
Deflection  Linear         Mu law      A law
-------------------------------------------------
+Maximum    1111 1111      1000 0000   1010 1010
+Zero       1000 0000      1111 1111   1101 0101
-Zero       0000 0000      0111 1111   0101 0101
-Maximum    0111 1111      0000 0010   0010 1010

You may now notice another strange thing.  In PCM parlance, positive numbers are negative deflection and vice versa.  This is just another irritating thing that doesn't really matter in practice.  Manually performing a law conversion is clearly a painful experience at best.  Basically, CCITT just went out of their way to mess things up - it is probably just a job preservation thing, to ensure permanent employment...
 

PCM Detection

It is interesting to note that when a telephone is off-hook, but idle, with nobody talking, the PCM will typically be fluctuating between +-zero (0xFF, 0x7F, 0xFF, 0x7F...) or some other small noise value, while when the phone is on-hook or muted, the PCM will typically hold the last value before it was cut off.  So, if you want to detect the presence of PCM audio, it is sufficient to look for changes in the sign bit, together with a hold timer of 500ms or so to prevent dropping out between words, when there is a noise gate somewhere in the system.  Some phone types have noise gates built in, so beware.  (In HF radio parlance a noise gate is known as squelch.  To anybody who ever had to endure HF hiss on a headphone, good squelching is a very satifying experience).


 

Log to Lin Conversion

Analog Devices was very thoughtful and provided some CODEC functions in the ADSP 21XX hardware.  Log to lin conversion therefore is a snap.  The SPORT hardware can be set to perform the conversions automatically when transmitting/receiving PCM.  It is also possible to use the SPORT hardware to convert signals for algorithmic use, for instance in a mixer, without actually transmitting anything.  This is done simply by disabling the SPORT, then writing/reading the Tx/Rx registers to do the conversion.
 

Example Code

In Example 1 is a simple routine to change SPORT1 between Mu and A law.  Note that no stack framing is required, since only the accumulator register is used.  Refer to the data book to see the SPORT control register details.


 
 
Example 1. Companding Law Configuration
/*********************************************************************
* Name:        pcm_configure
* Description: Select the Companding Law
* Constraints: ar = 0, Mu-Law
*                   1, A-Law
*********************************************************************/
pcm_configure_:
   ar = pass ar;
   ar = 0x402F;                     /* False = Mu law */
   if eq jump pcm_configure_mu;
   ar = 0x403f;                     /* True = A law */ 
pcm_configure_mu:
   dm ( 0x3FF2 ) = ar; 
   rts;

Cocktails anybody?

A PCM Mixer

If one wants to mix two PCM audio streams, it is important to note that one cannot simply add logarithmic signals together, as it will cause distortion. One first has to linearize the incoming audio, add it together, then compress it again before transmission.  When one adds two PCM streams together, the result may become bigger than the maximum deflection the CODEC can handle, which will sound bad as well.  It is therefore recommended to scale back the mixed signal by 3dB.  As the ADSP 21XX has a 16 bit accumulator, we can safely add two 14 bit A law signals together and scale back afterwards. Example 2 is the ADSP 21XX mixer code.


 
 
Example 2. PCM Mixer
/*********************************************************************
* Name:        pcm_mixer
* Description: Mix two compressed PCM samples
* Constraints: ar = PCM sample 1
*              ay0 = PCM sample 2
*              returns ar = mixed PCM
*********************************************************************/
pcm_mixer: 
   MAC_ENTER

   /* 
    * Convert Input
    * Convert from log to right justified sign extended linear 
    * using the SPORT1 rx register
    */
   rx1 = ar; 
   nop;                                     /* one clock cycle needed for conversion */
   ar = rx1; 
   rx1 = ay0; 
   nop;                                     /* one clock cycle needed for conversion */
   ay0 = rx1; 

   /* 
    * mix using signed addition of linear samples 
    */ 
   ar = ar + ay0; 

   /* 
    * signed scale down by -3 dB 
    */
   sr = ashift ar by - 1 ( LO ); 
   ar = sr0; 
   
   /* 
    * Convert Output
    * Convert signed value back to log value 
    * using the SPORT1 tx register
    */ 
   tx1 = ar; 
   nop;                                     /* one clock cycle needed for conversion */
   ar = tx1; 
   
   MAC_EXIT
   rts; 

A Multi Channel Mixer

Recently, some questions were raised on comp.dsp on how to handle multi channel mixing.  The obvious solution is to add everything together and then scale back, but this approach has serious repercussions when a large number of channels have to be mixed.  If one doesn't scale down, then noise which is almost always additive will build up and the mix will become very noisy.  Secondly, if one scales down to prevent clipping and noise build-up, the actual audio will become very soft.

The result is that either the noise level goes up, or the audio level comes down, so whatever one does, one can't hear a durn thing. So, how now brown cow?  There are a number of solutions to this dilemma.

The simplest way to avoid a dilemma, is to sidestep it. In a telephone conference call system, it is good to assume that only one person will be talking at any one time. Therefore, simply take the loudest sample of all the parties and transmit that one, discarding all other samples.  In a normal conference call, this will work well, while in case of an argument, he who shouteth the loudest will prevail, which is probably OK as well and perfectly in keeping with human nature.  This approach also saves you the log/lin conversions and is therefore computationally very efficient.  In effect, instead of a mixer, this is a data dependent switch and the actual mixing happens in the CODEC reconstruction filter.  So in this case, one can make a perfectly good mixer by doing almost nothing!

For a true mix, it is necessary to add a noise gate and to zero all really soft samples, to prevent noise build-up, thus blunting one half of the dilemma. Then, it can probably be assumed that only 2 or three people will ever talk at the same time (except maybe in a Latin country!), so you only need to scale down by 6dB, then limit (signed clip) the signal to the maximum range of the PCM lookup table and compress it again, thus fixing the other aspect of the dilemma.  This approach will be adequate for most applications.

For a high quality audio mixer, one should not use compressed PCM, but rather linear 16 or 18 bit  A/D converters.  In this case, it is prudent to add the signals together using signed integers large enough to handle the whole worst case sum without overflowing (e.g. 32bits), then compress the mixed signal using an S curve, much the same as for PCM, just a different scale, to fit the maximum range of the output D/A converter.
 

Overflows

It is very important to prevent numeric overflows during the mix.  Overflows will cause sudden sign changes which will cause loud pops/clicks - best avoided.


 

Curvacious Compression

The soft clipping of a S curve will introduce mostly even harmonic distortion, which sounds pleasant (The so called thermionic valve amplifier sound - that's a 'tube amp' in American English!).  If one would simply limit the signal, one would get predominantly odd harmonic distortion which causes a harsh sound (The so called cheap bipolar transistor amplifier sound, a.k.a. ghetto blaster sound), which is not good for quality audio.

What S curve to use?  If you feel nostalgic, then you can use an old RIAA or a Dolby curve or you can simply make your own. The H.Acker audio compression curve - why not?  Just keep it linear for most of the normal signal range, then bend it over flat at the limit.  Note that you can build a noise gate into the compression table, by transitioning horizontally at zero for a bit or two, thus killing two problems with one whack, which is another good reason to design your own compression curves.

Of course, if you really like the ghetto blaster sound, then never mind overflows, add some white noise and clip the signals...

Be inventive and have fun,

Herman



Copyright © 1996-2008, Aerospace Software Ltd., GPL.