Hi Guys,
After a few days work, I have some good quality audio playing out of
my AVR into a telephone handset. The quality is great - the same as
playing the same file on my PC :-)
A few notes on how it is done:
1/ To test the system I have developed a way of playing audio on a
PC. the PC then transfers the 8 bit samples to the AVR via the AVRs
SPI port. I "built" a SPI port for the PC using the LPT port and bit-
bashing the SPI signal into existance. This works OK, but is limited
to about 20 kbytes/sec. It conveniently uses the same LPT port cable
used for flashing my AVR, although I had to an one wire for the SS
(SPI select) line.
2/ I am using a 32 kHz PWM frequency, and 8 bit samples. This means
the Fs/2 cutoff is 16kHz, and the 0-4kHz passband energy reappears as
an image in the 32-28kHz range - not a problem. As the SPI link can
only support 20kHz I actually send samples down the SPI link at 16 kHz
and repeat each sample twice in the AVR to get the 32 kHz sample
rate. This is a crude form of oversampling, I havent actually worked
out if this will cause any problems, but so far so good.
3/ The AVR fimrware (spipwm.c) accepts SPI samples, and places them in
a buffer. At the end of every 2nd PWM cycle, the sample is written to
the PWM output register.
4/ The PC (Linux) program spiplay.c takes a 8 bit unsigned file and
sends it to the AVR. There is a simple protocol to tell the PC to
stop sending samples when the AVR buffer is half full. This is
necessary as the PC sends samples at 20kHz, and we only need them at
16 kHz.
5/ To create the 8 bit unsigned files from wave files using sox (the
male.wav sample is from the Speex project):
$ sox male.wav -t raw -r 16000 -u -c 1 -b male.raw
To test you can play it back on your PC:
$ play -f u -r 16000 -s b male.raw
I play it through my AVR (via the SPI link) using the host PC:
# ./spiplay male.raw
There is some slight background noise, but this is exactly the same
when I play male/raw on my PC, ie the distortion was (I think)
introduced by sox during the converion to 8 bit unsigned.
6/ I have uploaded the spiplay.c (host PC) & spipwm.c (AVR) source
code to:
http://groups.google.com/group/low-cost-ata/files
7/ To test the audio on the phone I power the phone by connecting it
to a 8V power supply via a 1k resistor. At the junction of the
resistor and phone I connected a 1k resistor and 220uF capactior to
the PWM output of the AVR.
Next step is to track down where that distortion is coming from in the
sox conversion. Or perhaps it's better to add code for ulaw playback,
that will bypass the problem.
Then perhaps take a look at the A/D side. We will need something a
little more fancy for that, as the A/D operates on my AVR at a maximum
or around 15 kHz I think, so we need to convert that to 8 kHz.
Operating the A/D at rates > 8 kHz removes the need for complex analog
filters on the input, lowering the hardware cost. Flip side of course
is that the software complexity increases.
The goal of this test was to determine if the AVR was good enough for
audio playback. I am now convinced that it is :-)
In the final ATA software we will need 8 kHz alaw or ulaw to 32kHz 8
bit unsigned PCM conversion, and the samples might arrive via RS232 at
64 kbit/s (8 kbyte/sec).
Cheers,
David