Yahoo Groups archive

Lpc2000

Index last updated: 2026-04-28 23:31 UTC

Thread

D/A noise

D/A noise

2006-01-19 by tengelberth

I am trying to use the LPC2138 part as a simple voice device (play 16
khz voice).  Currently I am using a Keil MCB2130 eval board and
running a simple example program that plays 16 bit 8khz wav files via
the D/A port through a LM386 to the on board speaker (the wav file has
no hiss on my PC).  

The process works but there is a low level hiss or static in the
audio.  I have take the Aout and filtered it with a RLC filter to get
rid of the tinness from the audio but still has the hiss.  I also
tried using an off board amp and speaker but still have the
hiss/static in the audio.  

If the D/A is not changing then the hiss/static goes away so it does
not seem to be noise coupling over. 

I tried looking at the signal on the scope but can not see anything
above the scope noise. 

I am weak on audio stuff and am hoping to get some pointers. 

1. Is this hiss just from the D/A S/N ratio and I am stuck with it?? 

2. Is caused by the Vref and V3A being tied with the Digital Vcc?  (If
this I would assume it would still get the noise when the D/A is not
changing) 

3. Do I need to filter the Aout better? 

4. Any other test I should try??

Thanks 
Tom

Re: [lpc2000] D/A noise

2006-01-19 by Herbert Demmel

Hi Tom,

I made a similar application a long time ago (using a 8051 with an external 
audio DAC and unpacking 16-bit ADPCM in real time) and found out that these 
things are very, very sensitve to jitter. So a variation of about 1 uP 
cycle (about 1us) on playing a sound sampled at 11kHz definitely could be 
heard (!) so I could not rely on the timer interrupt but hat to poll the 
timer instead and insert a nop depending on the even / uneven state of the 
timer when I begun start polling. All this will not be as bad with the 
LPX2xxx, as this device is about 50 times faster, but you have to take care 
on jitter anyway.

The second very important thing is to have a good low-pass filter between 
the DAC output and the audio input. You may use a circuit with one or two 
op-amps (I don't remember, but I think it was a 4th or 6th order filter I 
used) otherwise you will hear the quantisation noice - a simple R/C 
combination will not be enough definitely.

I hope that helps.

Regards
Herbert


At 18:53 19.01.2006, you wrote:
>I am trying to use the LPC2138 part as a simple voice device (play 16
>khz voice).  Currently I am using a Keil MCB2130 eval board and
>running a simple example program that plays 16 bit 8khz wav files via
>the D/A port through a LM386 to the on board speaker (the wav file has
>no hiss on my PC).
>
>The process works but there is a low level hiss or static in the
>audio.  I have take the Aout and filtered it with a RLC filter to get
>rid of the tinness from the audio but still has the hiss.  I also
>tried using an off board amp and speaker but still have the
>hiss/static in the audio.
>
>If the D/A is not changing then the hiss/static goes away so it does
>not seem to be noise coupling over.
>
>I tried looking at the signal on the scope but can not see anything
>above the scope noise.
>
>I am weak on audio stuff and am hoping to get some pointers.
>
>1. Is this hiss just from the D/A S/N ratio and I am stuck with it??
>
>2. Is caused by the Vref and V3A being tied with the Digital Vcc?  (If
>this I would assume it would still get the noise when the D/A is not
>changing)
>
>3. Do I need to filter the Aout better?
>
>4. Any other test I should try??
>
>Thanks
>Tom




----------------------------------------------------------
demmel products
Radnitzkygasse 43
A-1100 Vienna / Austria / Europe
Voice: +43-1-6894700-0
Fax: +43-1-6894700-40
Email: dh@...
WWW: http://www.demmel.com


[Non-text portions of this message have been removed]

Re: [lpc2000] D/A noise

2006-01-19 by Karl Olsen

---- Original Message ----
Show quoted textHide quoted text
From: "tengelberth" <tengelberth@...>
To: <lpc2000@yahoogroups.com>
Sent: Thursday, January 19, 2006 6:53 PM
Subject: [lpc2000] D/A noise

> I am trying to use the LPC2138 part as a simple voice device (play 16
> khz voice).  Currently I am using a Keil MCB2130 eval board and
> running a simple example program that plays 16 bit 8khz wav files via
> the D/A port through a LM386 to the on board speaker (the wav file has
> no hiss on my PC).
>
> The process works but there is a low level hiss or static in the
> audio.  I have take the Aout and filtered it with a RLC filter to get
> rid of the tinness from the audio but still has the hiss.  I also
> tried using an off board amp and speaker but still have the
> hiss/static in the audio.
>
> If the D/A is not changing then the hiss/static goes away so it does
> not seem to be noise coupling over.
>
> I tried looking at the signal on the scope but can not see anything
> above the scope noise.
>
> I am weak on audio stuff and am hoping to get some pointers.
>
> 1. Is this hiss just from the D/A S/N ratio and I am stuck with it??

Probably not.


> 2. Is caused by the Vref and V3A being tied with the Digital Vcc?  (If
> this I would assume it would still get the noise when the D/A is not
> changing)

Yep, I'd assume that too.


> 3. Do I need to filter the Aout better?

When you output 8k samples/sec, you need to filter everything at 4 kHz and
above away.  Does the hiss sound high-frequency?

An analog filter with a sharp cut-off at just below 4 kHz is tricky.  The
early CD players had some very high-order analog filters to remove the 22050
Hz (half of the 44100 Hz sampling frequency) and above.

You can make it easier by oversampling: Create an AOUT signal with finer
steps that are easier to smooth out by outputting at 16 or 32 kHz (2x or 4x
oversampling), and create the intermediate values in software by
interpolating between the known samples.  At 2x, you can do linear
interpolation by simply outputting the average of the two neighboring known
samples.  At 4x or 8x, you might need something more advanced than linear
interpolation -- you want to synthesize a signal that has no frequency
content above 4 kHz.  At 4x oversampling, your analog filter just needs to
keep the signal below 4 kHz, and cut away above 16 kHz (half the output rate
of 32 kHz).  Such a filter is much easier to make.  At 8x oversampling, the
noise to filter away even gets above the human audible range.


> 4. Any other test I should try??

Since the AOUT is only 10 bit, you remove some information from the 16-bit
signal.  You thereby introduce a rounding error, or distortion, that is
heard as quantisation noise.  The brain perceives the distorted signal as
the ideal signal plus some hiss noise.  Each bit gives 6 dB of signal/noise
ratio, so with 16 bit you can get ~96 dB, with 10 bit ~60 dB of S/N, because
of quantisation.  You obviously only hear this noise when you output a real
signal, not when outputting silence.  60 dB is pretty good, so it is
probably not that you are hearing.

While outputting values with rounding errors gives quantisation noise, just
as bad is it to output them at the wrong time.  Outputting a sample a little
too early or late will also introduce distortion to the smoothed analog
signal.  So you want to output them with as little jitter as possible.

If you output them from a timer interrupt, you'll get a jitter typically a
few clocks, depending on whether the foreground program had just started a
multi-cycle instruction that needed to be completed.  In the foreground
program, you should of course avoid disabling interrupts that could delay
the interrupt handler excessively.  The best case would probably be if the
foreground program could be in idle mode every time the interrupt fired,
this should give zero jitter.  This can of course be difficult if the CPU
has other tasks than outputting sound.  Try something like this in your
foreground program:

while (1)
{
  /* Enter idle mode, and re-enter it after each interrupt */
  PCON = 0x01;
}

To remove jitter you could also try making an external analog sample-hold
circuit, see http://groups.yahoo.com/group/lpc2000/message/12460 .


Karl Olsen

Re: [lpc2000] D/A noise

2006-01-19 by Peter Jakacki

As I sit here typing-up this message I am listening to Pachabels Canon 
being played over a monitor's speakers from an LPC2138. I am not using 
any filtering at all, just feeding the signal as it is directly to the 
monitor. The signal is being sampled a fraction slower than it needs to 
be as I derive the sampling from the VGA interrupts.

Now I can be a bit fussy but I don't have a problem with the sound I 
hear, it's clear and undistorted. Mind you, I have removed most of the 
jitter already because I use a two-stage interrupt process, first time 
to save registers and then sit in an idle loop, then the second a short 
time later which jumps straight into the actual ISR.

The audio playback rate is a simple prescaler off the 31.46KHz 
interrupt. So for 11K samples I divide by 3, for 32K samples just 1. I 
feed both 16-bit or 8-bit signals, both with volume (shifts) adjustment.

BTW, this is running off SD memory as the files are quite large.

When the music stops there is no hiss, I have everything turned-up and 
it is dead quiet.

My analog reference is filtered by a 10K and a 10uf. While the 10K is a 
little large and could definitely be lower it "doesn't hurt things 
none". The analog reference voltage is sitting around 2.5V.

*Peter*


Karl Olsen wrote:
Show quoted textHide quoted text
> ---- Original Message ----
> From: "tengelberth" <tengelberth@...>
> To: <lpc2000@yahoogroups.com>
> Sent: Thursday, January 19, 2006 6:53 PM
> Subject: [lpc2000] D/A noise
>
>> I am trying to use the LPC2138 part as a simple voice device (play 16
>> khz voice).  Currently I am using a Keil MCB2130 eval board and
>> running a simple example program that plays 16 bit 8khz wav files via
>> the D/A port through a LM386 to the on board speaker (the wav file has
>> no hiss on my PC).
>>
>> The process works but there is a low level hiss or static in the
>> audio.  I have take the Aout and filtered it with a RLC filter to get
>> rid of the tinness from the audio but still has the hiss.  I also
>> tried using an off board amp and speaker but still have the
>> hiss/static in the audio.
>>
>> If the D/A is not changing then the hiss/static goes away so it does
>> not seem to be noise coupling over.
>>
>> I tried looking at the signal on the scope but can not see anything
>> above the scope noise.
>>
>> I am weak on audio stuff and am hoping to get some pointers.
>>
>> 1. Is this hiss just from the D/A S/N ratio and I am stuck with it??
>
> Probably not.
>
>
>> 2. Is caused by the Vref and V3A being tied with the Digital Vcc?  (If
>> this I would assume it would still get the noise when the D/A is not
>> changing)
>
> Yep, I'd assume that too.
>
>
>> 3. Do I need to filter the Aout better?
>
> When you output 8k samples/sec, you need to filter everything at 4 kHz and
> above away.  Does the hiss sound high-frequency?
>
> An analog filter with a sharp cut-off at just below 4 kHz is tricky.  The
> early CD players had some very high-order analog filters to remove the 22050
> Hz (half of the 44100 Hz sampling frequency) and above.
>
> You can make it easier by oversampling: Create an AOUT signal with finer
> steps that are easier to smooth out by outputting at 16 or 32 kHz (2x or 4x
> oversampling), and create the intermediate values in software by
> interpolating between the known samples.  At 2x, you can do linear
> interpolation by simply outputting the average of the two neighboring known
> samples.  At 4x or 8x, you might need something more advanced than linear
> interpolation -- you want to synthesize a signal that has no frequency
> content above 4 kHz.  At 4x oversampling, your analog filter just needs to
> keep the signal below 4 kHz, and cut away above 16 kHz (half the output rate
> of 32 kHz).  Such a filter is much easier to make.  At 8x oversampling, the
> noise to filter away even gets above the human audible range.
>
>
>> 4. Any other test I should try??
>
> Since the AOUT is only 10 bit, you remove some information from the 16-bit
> signal.  You thereby introduce a rounding error, or distortion, that is
> heard as quantisation noise.  The brain perceives the distorted signal as
> the ideal signal plus some hiss noise.  Each bit gives 6 dB of signal/noise
> ratio, so with 16 bit you can get ~96 dB, with 10 bit ~60 dB of S/N, because
> of quantisation.  You obviously only hear this noise when you output a real
> signal, not when outputting silence.  60 dB is pretty good, so it is
> probably not that you are hearing.
>
> While outputting values with rounding errors gives quantisation noise, just
> as bad is it to output them at the wrong time.  Outputting a sample a little
> too early or late will also introduce distortion to the smoothed analog
> signal.  So you want to output them with as little jitter as possible.
>
> If you output them from a timer interrupt, you'll get a jitter typically a
> few clocks, depending on whether the foreground program had just started a
> multi-cycle instruction that needed to be completed.  In the foreground
> program, you should of course avoid disabling interrupts that could delay
> the interrupt handler excessively.  The best case would probably be if the
> foreground program could be in idle mode every time the interrupt fired,
> this should give zero jitter.  This can of course be difficult if the CPU
> has other tasks than outputting sound.  Try something like this in your
> foreground program:
>
> while (1)
> {
>   /* Enter idle mode, and re-enter it after each interrupt */
>   PCON = 0x01;
> }
>
> To remove jitter you could also try making an external analog sample-hold
> circuit, see http://groups.yahoo.com/group/lpc2000/message/12460 .
>
>
> Karl Olsen

Re: D/A noise

2006-01-19 by Guillermo Prandi

Tom, if you're chopping out the lower bits, try instead rounding up 
from the 11th bit (i.e: treat 20 to 5f as 40, 60 to 9f as 80, etc.). 
This should give you 1/2 bit more accuracy, if I'm not wrong.

Something like this:

unsigned short x;

x = NextSample();
if( x >= 0x8000 ) // Provided 0x8000 is the 'center' value
   x += 0x20; // D/A will chop the lower bits
else
   x -= 0x20; // D/A will chop the lower bits

Guille

PS: Also, a sine wave function could give you some more hints. Try 
using a sine table.

--- In lpc2000@yahoogroups.com, "Karl Olsen" <kro@p...> wrote:
>
> ---- Original Message ----
> From: "tengelberth" <tengelberth@y...>
> To: <lpc2000@yahoogroups.com>
> Sent: Thursday, January 19, 2006 6:53 PM
> Subject: [lpc2000] D/A noise
> 
> > I am trying to use the LPC2138 part as a simple voice device 
(play 16
> > khz voice).  Currently I am using a Keil MCB2130 eval board and
> > running a simple example program that plays 16 bit 8khz wav files 
via
> > the D/A port through a LM386 to the on board speaker (the wav 
file has
> > no hiss on my PC).
> >
> > The process works but there is a low level hiss or static in the
> > audio.  I have take the Aout and filtered it with a RLC filter to 
get
> > rid of the tinness from the audio but still has the hiss.  I also
> > tried using an off board amp and speaker but still have the
> > hiss/static in the audio.
> >
> > If the D/A is not changing then the hiss/static goes away so it 
does
> > not seem to be noise coupling over.
> >
> > I tried looking at the signal on the scope but can not see 
anything
> > above the scope noise.
> >
> > I am weak on audio stuff and am hoping to get some pointers.
> >
> > 1. Is this hiss just from the D/A S/N ratio and I am stuck with 
it??
> 
> Probably not.
> 
> 
> > 2. Is caused by the Vref and V3A being tied with the Digital 
Vcc?  (If
> > this I would assume it would still get the noise when the D/A is 
not
> > changing)
> 
> Yep, I'd assume that too.
> 
> 
> > 3. Do I need to filter the Aout better?
> 
> When you output 8k samples/sec, you need to filter everything at 4 
kHz and
> above away.  Does the hiss sound high-frequency?
> 
> An analog filter with a sharp cut-off at just below 4 kHz is 
tricky.  The
> early CD players had some very high-order analog filters to remove 
the 22050
> Hz (half of the 44100 Hz sampling frequency) and above.
> 
> You can make it easier by oversampling: Create an AOUT signal with 
finer
> steps that are easier to smooth out by outputting at 16 or 32 kHz 
(2x or 4x
> oversampling), and create the intermediate values in software by
> interpolating between the known samples.  At 2x, you can do linear
> interpolation by simply outputting the average of the two 
neighboring known
> samples.  At 4x or 8x, you might need something more advanced than 
linear
> interpolation -- you want to synthesize a signal that has no 
frequency
> content above 4 kHz.  At 4x oversampling, your analog filter just 
needs to
> keep the signal below 4 kHz, and cut away above 16 kHz (half the 
output rate
> of 32 kHz).  Such a filter is much easier to make.  At 8x 
oversampling, the
> noise to filter away even gets above the human audible range.
> 
> 
> > 4. Any other test I should try??
> 
> Since the AOUT is only 10 bit, you remove some information from the 
16-bit
> signal.  You thereby introduce a rounding error, or distortion, 
that is
> heard as quantisation noise.  The brain perceives the distorted 
signal as
> the ideal signal plus some hiss noise.  Each bit gives 6 dB of 
signal/noise
> ratio, so with 16 bit you can get ~96 dB, with 10 bit ~60 dB of 
S/N, because
> of quantisation.  You obviously only hear this noise when you 
output a real
> signal, not when outputting silence.  60 dB is pretty good, so it is
> probably not that you are hearing.
> 
> While outputting values with rounding errors gives quantisation 
noise, just
> as bad is it to output them at the wrong time.  Outputting a sample 
a little
> too early or late will also introduce distortion to the smoothed 
analog
> signal.  So you want to output them with as little jitter as 
possible.
> 
> If you output them from a timer interrupt, you'll get a jitter 
typically a
> few clocks, depending on whether the foreground program had just 
started a
> multi-cycle instruction that needed to be completed.  In the 
foreground
> program, you should of course avoid disabling interrupts that could 
delay
> the interrupt handler excessively.  The best case would probably be 
if the
> foreground program could be in idle mode every time the interrupt 
fired,
> this should give zero jitter.  This can of course be difficult if 
the CPU
> has other tasks than outputting sound.  Try something like this in 
your
> foreground program:
> 
> while (1)
> {
>   /* Enter idle mode, and re-enter it after each interrupt */
>   PCON = 0x01;
> }
> 
> To remove jitter you could also try making an external analog 
sample-hold
Show quoted textHide quoted text
> circuit, see http://groups.yahoo.com/group/lpc2000/message/12460 .
> 
> 
> Karl Olsen
>

Re: D/A noise

2006-01-20 by brendanmurphy37

Hi,

I'll preface these comments by stating I've limited h/w knowledge, so 
can't comment on the analog stage.

However, I can confirm Karl's observations below on the effects of 
both quantisation noise (i.e. using 10- rather than 16-bit samples), 
and most especially the effects of jitter. See a recent message post 
(message 12456) on this: it's an unfortunate design feature of the 
DAC that there's no clock signal that can be fed into it to clock out 
the samples at a precise (well to 1/60Mhz resolution) time.

We had a similar issue with a software modem: we initially couldn't 
get it to work at V.22bis speeds (2400 bps) because of these issues.

To reduce effects of quantsaition, you can upsample: we use a simple 
4-tap interpolating filter to upsample from 8Kz to 40Khz.

To get rid of jitter, you should code your o/p interrupt so that the 
code from the start of the interrupt through to where the sample is 
o/p has no "if" statements or similar (i.e. it must execute the same 
number of instructions for each interrupt). You then have to try and 
ensure that the program being interrupted is always on an instruction 
that takes the same number of cycles to execute. One way of doing 
this is to set up a timer interrupt to happen just before the o/p 
time. We use this approach, and jump to a (lot of "nops"). Karrl's 
suggestion (go to idle mode) is probably better than this, as it 
saves code space). The "real" interrupt can then be used to knock you 
out of this to o/p the sample. This will not remove jitter entireley, 
but it makes a significant difference.

Unfortuntely I don't have any figures to hand that give the level of 
noise reduction each of these achieves, but I do recall it was 
significant.

It's a lot of messing to do to get good results, but it does work.

Hope this is of some help!

Brendan Murphy

--- In lpc2000@yahoogroups.com, "Karl Olsen" <kro@p...> wrote:
>
> ---- Original Message ----
> From: "tengelberth" <tengelberth@y...>
> To: <lpc2000@yahoogroups.com>
> Sent: Thursday, January 19, 2006 6:53 PM
> Subject: [lpc2000] D/A noise
> 
> > I am trying to use the LPC2138 part as a simple voice device 
(play 16
> > khz voice).  Currently I am using a Keil MCB2130 eval board and
> > running a simple example program that plays 16 bit 8khz wav files 
via
> > the D/A port through a LM386 to the on board speaker (the wav 
file has
> > no hiss on my PC).
> >
> > The process works but there is a low level hiss or static in the
> > audio.  I have take the Aout and filtered it with a RLC filter to 
get
> > rid of the tinness from the audio but still has the hiss.  I also
> > tried using an off board amp and speaker but still have the
> > hiss/static in the audio.
> >
> > If the D/A is not changing then the hiss/static goes away so it 
does
> > not seem to be noise coupling over.
> >
> > I tried looking at the signal on the scope but can not see 
anything
> > above the scope noise.
> >
> > I am weak on audio stuff and am hoping to get some pointers.
> >
> > 1. Is this hiss just from the D/A S/N ratio and I am stuck with 
it??
> 
> Probably not.
> 
> 
> > 2. Is caused by the Vref and V3A being tied with the Digital 
Vcc?  (If
> > this I would assume it would still get the noise when the D/A is 
not
> > changing)
> 
> Yep, I'd assume that too.
> 
> 
> > 3. Do I need to filter the Aout better?
> 
> When you output 8k samples/sec, you need to filter everything at 4 
kHz and
> above away.  Does the hiss sound high-frequency?
> 
> An analog filter with a sharp cut-off at just below 4 kHz is 
tricky.  The
> early CD players had some very high-order analog filters to remove 
the 22050
> Hz (half of the 44100 Hz sampling frequency) and above.
> 
> You can make it easier by oversampling: Create an AOUT signal with 
finer
> steps that are easier to smooth out by outputting at 16 or 32 kHz 
(2x or 4x
> oversampling), and create the intermediate values in software by
> interpolating between the known samples.  At 2x, you can do linear
> interpolation by simply outputting the average of the two 
neighboring known
> samples.  At 4x or 8x, you might need something more advanced than 
linear
> interpolation -- you want to synthesize a signal that has no 
frequency
> content above 4 kHz.  At 4x oversampling, your analog filter just 
needs to
> keep the signal below 4 kHz, and cut away above 16 kHz (half the 
output rate
> of 32 kHz).  Such a filter is much easier to make.  At 8x 
oversampling, the
> noise to filter away even gets above the human audible range.
> 
> 
> > 4. Any other test I should try??
> 
> Since the AOUT is only 10 bit, you remove some information from the 
16-bit
> signal.  You thereby introduce a rounding error, or distortion, 
that is
> heard as quantisation noise.  The brain perceives the distorted 
signal as
> the ideal signal plus some hiss noise.  Each bit gives 6 dB of 
signal/noise
> ratio, so with 16 bit you can get ~96 dB, with 10 bit ~60 dB of 
S/N, because
> of quantisation.  You obviously only hear this noise when you 
output a real
> signal, not when outputting silence.  60 dB is pretty good, so it is
> probably not that you are hearing.
> 
> While outputting values with rounding errors gives quantisation 
noise, just
> as bad is it to output them at the wrong time.  Outputting a sample 
a little
> too early or late will also introduce distortion to the smoothed 
analog
> signal.  So you want to output them with as little jitter as 
possible.
> 
> If you output them from a timer interrupt, you'll get a jitter 
typically a
> few clocks, depending on whether the foreground program had just 
started a
> multi-cycle instruction that needed to be completed.  In the 
foreground
> program, you should of course avoid disabling interrupts that could 
delay
> the interrupt handler excessively.  The best case would probably be 
if the
> foreground program could be in idle mode every time the interrupt 
fired,
> this should give zero jitter.  This can of course be difficult if 
the CPU
> has other tasks than outputting sound.  Try something like this in 
your
> foreground program:
> 
> while (1)
> {
>   /* Enter idle mode, and re-enter it after each interrupt */
>   PCON = 0x01;
> }
> 
> To remove jitter you could also try making an external analog 
sample-hold
Show quoted textHide quoted text
> circuit, see http://groups.yahoo.com/group/lpc2000/message/12460 .
> 
> 
> Karl Olsen
>

Re: D/A noise

2006-01-20 by Magnus Lundin

Hi

Another way to remove jitter is to read the timer in the interrupt 
routine and loop on this until a predefined value, the number of 
clock ticks when there is maximal latency at this point in the
interrupt routine, has passed since the timer rollover.  
This can be done just before outputing the samples or at the beginning.

This uses the interrupt to place the clock at almost the right time
and the a wait loop on the timer counter for precise adjustment.

Magnus

--- In lpc2000@yahoogroups.com, "brendanmurphy37"
<brendan.murphy@i...> wrote:
Show quoted textHide quoted text
> To get rid of jitter, you should code your o/p interrupt so that the 
> code from the start of the interrupt through to where the sample is 
> o/p has no "if" statements or similar (i.e. it must execute the same 
> number of instructions for each interrupt). You then have to try and 
> ensure that the program being interrupted is always on an instruction 
> that takes the same number of cycles to execute. One way of doing 
> this is to set up a timer interrupt to happen just before the o/p 
> time. We use this approach, and jump to a (lot of "nops"). Karrl's 
> suggestion (go to idle mode) is probably better than this, as it 
> saves code space). The "real" interrupt can then be used to knock you 
> out of this to o/p the sample. This will not remove jitter entireley, 
> but it makes a significant difference.
>

Re: D/A noise

2006-01-20 by brendanmurphy37

Magnus,

This will certainly give an improvement, but even the shortest 
possible loop will have a built-in jitter that cannot be removed, 
particularly if you take into account the additional cycles needed to 
access the timer peripheral.

Unfortunately, I don't have figures for this, as they've long since 
been discarded (we analysed the o/p signal for noise in various 
frequency bands), but from memory even a couple of clock cycles 
jitter had a significant effect.

Of course, a lot depends on what your trying to achieve: just reduce 
some annoying hiss in a self-build project it might be fine.

Brendan

-- In lpc2000@yahoogroups.com, "Magnus Lundin" <lundin@m...> wrote:
>
> Hi
> 
> Another way to remove jitter is to read the timer in the interrupt 
> routine and loop on this until a predefined value, the number of 
> clock ticks when there is maximal latency at this point in the
> interrupt routine, has passed since the timer rollover.  
> This can be done just before outputing the samples or at the 
beginning.
> 
> This uses the interrupt to place the clock at almost the right time
> and the a wait loop on the timer counter for precise adjustment.
> 
> Magnus
> 
> --- In lpc2000@yahoogroups.com, "brendanmurphy37"
> <brendan.murphy@i...> wrote:
> > To get rid of jitter, you should code your o/p interrupt so that 
the 
> > code from the start of the interrupt through to where the sample 
is 
> > o/p has no "if" statements or similar (i.e. it must execute the 
same 
> > number of instructions for each interrupt). You then have to try 
and 
> > ensure that the program being interrupted is always on an 
instruction 
> > that takes the same number of cycles to execute. One way of doing 
> > this is to set up a timer interrupt to happen just before the o/p 
> > time. We use this approach, and jump to a (lot of "nops"). 
Karrl's 
> > suggestion (go to idle mode) is probably better than this, as it 
> > saves code space). The "real" interrupt can then be used to knock 
you 
> > out of this to o/p the sample. This will not remove jitter 
entireley, 
Show quoted textHide quoted text
> > but it makes a significant difference.
> >
>

Re: D/A noise

2006-01-20 by Magnus Lundin

Brendan,

I'm not shure. This should look as follows in pseudo assembler after
the timer counter and the D/A adresses are loaded into processor
registers:
  one load from an on chip register (the counter)
  one compare to a fixed short (byte) value
  one conditional branch two instructions backwards
  [branch not taken]
  write to D/A
If the loop always runs at least once the the flash preload state
should be fixed as the instruction timings. Since there is no 
other cache or dynamic memory handling on the lpc2xxx chips
this can work if there are no interupts disturbing the instruction
flow. Of course this must be tested.
  
Magnus

--- In lpc2000@yahoogroups.com, "brendanmurphy37"
<brendan.murphy@i...> wrote:
Show quoted textHide quoted text
>
> 
> Magnus,
> 
> This will certainly give an improvement, but even the shortest 
> possible loop will have a built-in jitter that cannot be removed, 
> particularly if you take into account the additional cycles needed to 
> access the timer peripheral.
> 
> Unfortunately, I don't have figures for this, as they've long since 
> been discarded (we analysed the o/p signal for noise in various 
> frequency bands), but from memory even a couple of clock cycles 
> jitter had a significant effect.
> 
> Of course, a lot depends on what your trying to achieve: just reduce 
> some annoying hiss in a self-build project it might be fine.
> 
> Brendan
> 
> -- In lpc2000@yahoogroups.com, "Magnus Lundin" <lundin@m...> wrote:
> >
> > Hi
> > 
> > Another way to remove jitter is to read the timer in the interrupt 
> > routine and loop on this until a predefined value, the number of 
> > clock ticks when there is maximal latency at this point in the
> > interrupt routine, has passed since the timer rollover.  
> > This can be done just before outputing the samples or at the 
> beginning.
> > 
> > This uses the interrupt to place the clock at almost the right time
> > and the a wait loop on the timer counter for precise adjustment.
> > 
> > Magnus
> > 
> > --- In lpc2000@yahoogroups.com, "brendanmurphy37"
> > <brendan.murphy@i...> wrote:
> > > To get rid of jitter, you should code your o/p interrupt so that 
> the 
> > > code from the start of the interrupt through to where the sample 
> is 
> > > o/p has no "if" statements or similar (i.e. it must execute the 
> same 
> > > number of instructions for each interrupt). You then have to try 
> and 
> > > ensure that the program being interrupted is always on an 
> instruction 
> > > that takes the same number of cycles to execute. One way of doing 
> > > this is to set up a timer interrupt to happen just before the o/p 
> > > time. We use this approach, and jump to a (lot of "nops"). 
> Karrl's 
> > > suggestion (go to idle mode) is probably better than this, as it 
> > > saves code space). The "real" interrupt can then be used to knock 
> you 
> > > out of this to o/p the sample. This will not remove jitter 
> entireley, 
> > > but it makes a significant difference.
> > >
> >
>

Re: D/A noise

2006-01-20 by Karl Olsen

--- In lpc2000@yahoogroups.com, "Magnus Lundin" <lundin@m...> wrote:
> 
> I'm not shure. This should look as follows in pseudo assembler after
> the timer counter and the D/A adresses are loaded into processor
> registers:
>   one load from an on chip register (the counter)
>   one compare to a fixed short (byte) value
>   one conditional branch two instructions backwards
>   [branch not taken]
>   write to D/A
> If the loop always runs at least once the the flash preload state
> should be fixed as the instruction timings. Since there is no 
> other cache or dynamic memory handling on the lpc2xxx chips
> this can work if there are no interupts disturbing the instruction
> flow. Of course this must be tested.

Loading from the timer register takes at least 8 clocks since it is 
behind the APB bridge, a compare takes one clock, and a taken 
backwards jump takes at least 3 clocks, total 12 clocks per loop 
round.  You then have a jitter of 12 clocks when you terminate the 
loop.  That is a lot.

Another way to reduce jitter to ideally zero clocks could be to read 
the timer register once in the timer interrupt handler, and do a jump 
that skips a number of NOPs, depending on how much later than ideal 
the handler was entered.  Such as:

# Timer 0 = reset and interrupt at MRx match, so T0TC should now
# be near zero.  The larger the value, the fewer NOPs should we
# execute now, and the more NOPs should be skipped.
#
# r8 -> T0

ldr r9, [r8, #8]   /* Load T0TC */
add pc, pc, r9 lsl #2
nop
nop
nop
nop
nop
...


Karl Olsen

Re: D/A noise

2006-01-20 by brendanmurphy37

Wow! that's getting really esoteric!

Magnus: Karl is right about the jitter. Even without the delay 
introduced by the timer register being on the peripheral bus, you 
have to take into acount the timer could tick either imediately after 
you load it or any time from then until you load it again. Even if 
the number of instructions and clocks in this is always the same, the 
tick could happen anywhere in the sequence.

By the way, if you use the general approach of a timer interrupt just 
before the ideal time, you have to make it quite a bit before: 
although its called a RISC processor which ideally should have 
one "short" instructions, because of the "load multiple" and "store 
multiple" instructions (e.g. used on function entry/exit), the number 
of clocks per instruction in an ARM can vary a lot (I'm not sure what 
worse case is).

Brendan

--- In lpc2000@yahoogroups.com, "Karl Olsen" <kro@p...> wrote:
>
> --- In lpc2000@yahoogroups.com, "Magnus Lundin" <lundin@m...> wrote:
> > 
> > I'm not shure. This should look as follows in pseudo assembler 
after
> > the timer counter and the D/A adresses are loaded into processor
> > registers:
> >   one load from an on chip register (the counter)
> >   one compare to a fixed short (byte) value
> >   one conditional branch two instructions backwards
> >   [branch not taken]
> >   write to D/A
> > If the loop always runs at least once the the flash preload state
> > should be fixed as the instruction timings. Since there is no 
> > other cache or dynamic memory handling on the lpc2xxx chips
> > this can work if there are no interupts disturbing the instruction
> > flow. Of course this must be tested.
> 
> Loading from the timer register takes at least 8 clocks since it is 
> behind the APB bridge, a compare takes one clock, and a taken 
> backwards jump takes at least 3 clocks, total 12 clocks per loop 
> round.  You then have a jitter of 12 clocks when you terminate the 
> loop.  That is a lot.
> 
> Another way to reduce jitter to ideally zero clocks could be to 
read 
> the timer register once in the timer interrupt handler, and do a 
jump 
Show quoted textHide quoted text
> that skips a number of NOPs, depending on how much later than ideal 
> the handler was entered.  Such as:
> 
> # Timer 0 = reset and interrupt at MRx match, so T0TC should now
> # be near zero.  The larger the value, the fewer NOPs should we
> # execute now, and the more NOPs should be skipped.
> #
> # r8 -> T0
> 
> ldr r9, [r8, #8]   /* Load T0TC */
> add pc, pc, r9 lsl #2
> nop
> nop
> nop
> nop
> nop
> ...
> 
> 
> Karl Olsen
>

Re: [lpc2000] Re: D/A noise

2006-01-20 by Karl Olsen

---- Original Message ----
Show quoted textHide quoted text
From: "brendanmurphy37" <brendan.murphy@...>
To: <lpc2000@yahoogroups.com>
Sent: Friday, January 20, 2006 4:38 PM
Subject: [lpc2000] Re: D/A noise

> Wow! that's getting really esoteric!
>
> Magnus: Karl is right about the jitter. Even without the delay
> introduced by the timer register being on the peripheral bus, you
> have to take into acount the timer could tick either imediately after
> you load it or any time from then until you load it again. Even if
> the number of instructions and clocks in this is always the same, the
> tick could happen anywhere in the sequence.

You should have no pclk or timer prescaler so that the timer ticks at the
cclk rate.  So during a single load from T0TC, it actually increments eight
times.  Exactly in which of the eight clocks the T0TC value is latched
doesn't really matter jitterwise, as long as it is the same every time.

I just tried this program on my LPC2103:

/* Vector area relocated to RAM */
/* r8_fiq preloaded with T0 = 0xE0004000 */
/* r9_fiq preloaded with address of ram_fiqhandler */

/* 0x001C: */

/* Timer 0 has just generated an interrupt and been reset.  T0TC is now
 * a small positive number that tells how many clocks it took to enter the
 * FIQ handler. */
ldr  r10, [r8, #+8]   /* r10 = initial T0TC */

/* If it is not unreasonably large (indicating an unexpected big latency,
 * such as if somebody has had FIQs disabled), jump into ram_fiqhandler,
 * skipping as many nops as we have already spent clocks. */
cmp  r10, #32
addls pc, r9, r10, lsl #2

/* It was unreasonably large, jitter not completely eliminated.
 * Just skip all the nops. */
add  pc, r9, #4*32


ram_fiqhandler:    /* located in RAM */
nop
nop
... total 32 nops
nop
ldr  r11, [r8, #+8]   /* r11 = final T0TC */
...

At this time, r10 is the initial T0TC value, and r11 is the T0TC value after
jitter elimination.

The program showed that the initial T0TC value varied between 9 and 16, and
the final T0TC was always 44.  So the normal FIQ jitter of 7 clocks (which
could be larger if the foreground contained things like big ldm/stm's) was
reduced to a jitter of 0.

I think this method is simpler and wastes fewer clocks than multi-stage
interrupt handlers.  But I still think that Philips should have added some
hardware synchronisation to the DAC.

Karl Olsen

Re: D/A noise

2006-01-21 by brendanmurphy37

Karl,

When I said "wow!", I meant "neat": it's a good solution. As I'm 
sure you'll agree, having to come up with somethinkg like this, or 
milti-level interrupts, so something equally strange is a real pain: 
all the for lack of a single latch signal to the DAC.

I've pointed this out to Philips in the past: hopefully, they'll 
recognise from this that others have the same issue.

None of the work-arounds presented are ideal: a h/w fix is much more 
preferable.

Brendan

--- In lpc2000@yahoogroups.com, "Karl Olsen" <kro@p...> wrote:
>
> ---- Original Message ----
> From: "brendanmurphy37" <brendan.murphy@i...>
> To: <lpc2000@yahoogroups.com>
> Sent: Friday, January 20, 2006 4:38 PM
> Subject: [lpc2000] Re: D/A noise
> 
> > Wow! that's getting really esoteric!
> >
> > Magnus: Karl is right about the jitter. Even without the delay
> > introduced by the timer register being on the peripheral bus, you
> > have to take into acount the timer could tick either imediately 
after
> > you load it or any time from then until you load it again. Even 
if
> > the number of instructions and clocks in this is always the 
same, the
> > tick could happen anywhere in the sequence.
> 
> You should have no pclk or timer prescaler so that the timer ticks 
at the
> cclk rate.  So during a single load from T0TC, it actually 
increments eight
> times.  Exactly in which of the eight clocks the T0TC value is 
latched
> doesn't really matter jitterwise, as long as it is the same every 
time.
> 
> I just tried this program on my LPC2103:
> 
> /* Vector area relocated to RAM */
> /* r8_fiq preloaded with T0 = 0xE0004000 */
> /* r9_fiq preloaded with address of ram_fiqhandler */
> 
> /* 0x001C: */
> 
> /* Timer 0 has just generated an interrupt and been reset.  T0TC 
is now
>  * a small positive number that tells how many clocks it took to 
enter the
>  * FIQ handler. */
> ldr  r10, [r8, #+8]   /* r10 = initial T0TC */
> 
> /* If it is not unreasonably large (indicating an unexpected big 
latency,
>  * such as if somebody has had FIQs disabled), jump into 
ram_fiqhandler,
>  * skipping as many nops as we have already spent clocks. */
> cmp  r10, #32
> addls pc, r9, r10, lsl #2
> 
> /* It was unreasonably large, jitter not completely eliminated.
>  * Just skip all the nops. */
> add  pc, r9, #4*32
> 
> 
> ram_fiqhandler:    /* located in RAM */
> nop
> nop
> ... total 32 nops
> nop
> ldr  r11, [r8, #+8]   /* r11 = final T0TC */
> ...
> 
> At this time, r10 is the initial T0TC value, and r11 is the T0TC 
value after
> jitter elimination.
> 
> The program showed that the initial T0TC value varied between 9 
and 16, and
> the final T0TC was always 44.  So the normal FIQ jitter of 7 
clocks (which
> could be larger if the foreground contained things like big 
ldm/stm's) was
> reduced to a jitter of 0.
> 
> I think this method is simpler and wastes fewer clocks than multi-
stage
> interrupt handlers.  But I still think that Philips should have 
added some
Show quoted textHide quoted text
> hardware synchronisation to the DAC.
> 
> Karl Olsen
>

Re: [lpc2000] Re: D/A noise

2006-01-21 by Rob Jansen

Brendan,

> I've pointed this out to Philips in the past: hopefully, they'll
> recognise from this that others have the same issue.
>
> None of the work-arounds presented are ideal: a h/w fix is much more
> preferable.

Just thought of this when I saw "h/w fix" ...
That is the easy solution, use a sample&hold replaces the variable
software latencies with a fixed HW one.
Have an interrupt and a match output generated by the timer. On a match
trigger the S&H and write to the DAC from the interrupt routine.
This will introduce a delay of 1 sample time but I don't think that's a
big problem in this case.

A S&H can be easy: one gate of a CD4066 and a capacitor do the trick.
Use the other 3 and some more caps to create a switched capacitor filter :o)

Regards,

      Rob

Re: D/A noise

2006-01-21 by Guillermo Prandi

Perhaps a combination of IRQ/FIQ can be used?

Let's say FIQs are enabled inside IRQs. Then, one could set TIMER1 
with two match registers: "some time before" (e.g. at 80 µS for 11 
KHz) and "exactly" (at 90.9µS). Then, when the first interrupt is 
caught, make TIMER1 generate FIQs instead of IRQs and enter idle 
mode. Switch to IRQ afterwards. This way one can ensure that the FIQ 
is always served from idle mode. Of course this too uses too much CPU 
resources. A hardware solution is preferable.

Guille

--- In lpc2000@yahoogroups.com, "Rob Jansen" <rob@m...> wrote:
>
> Brendan,
> 
> > I've pointed this out to Philips in the past: hopefully, they'll
> > recognise from this that others have the same issue.
> >
> > None of the work-arounds presented are ideal: a h/w fix is much 
more
> > preferable.
> 
> Just thought of this when I saw "h/w fix" ...
> That is the easy solution, use a sample&hold replaces the variable
> software latencies with a fixed HW one.
> Have an interrupt and a match output generated by the timer. On a 
match
> trigger the S&H and write to the DAC from the interrupt routine.
> This will introduce a delay of 1 sample time but I don't think 
that's a
> big problem in this case.
> 
> A S&H can be easy: one gate of a CD4066 and a capacitor do the 
trick.
> Use the other 3 and some more caps to create a switched capacitor 
filter :o)
Show quoted textHide quoted text
> 
> Regards,
> 
>       Rob
>

Re: D/A noise

2006-01-23 by brendanmurphy37

Guillermo,

This is pretty much what we do - see message 12622.

I can confirm that (a) it works! and (b) it's pretty messy to get 
exactly right, and (c) it consumes a fair amount of MIPS in what's a 
MIPS-hungry system (it's fine if you're not doing much else). You 
have to be careful to have the 1st timer fire with enough time to 
take into account the worst-case interrupt latency (which is quite 
long).

By the way, I'd be curious to know how the instigator of this thread 
is getting on with these various suggestions.

Brendan

--- In lpc2000@yahoogroups.com, "Guillermo Prandi" 
<yahoo.messenger@m...> wrote:
>
> Perhaps a combination of IRQ/FIQ can be used?
> 
> Let's say FIQs are enabled inside IRQs. Then, one could set TIMER1 
> with two match registers: "some time before" (e.g. at 80 µS for 11 
> KHz) and "exactly" (at 90.9µS). Then, when the first interrupt is 
> caught, make TIMER1 generate FIQs instead of IRQs and enter idle 
> mode. Switch to IRQ afterwards. This way one can ensure that the 
FIQ 
> is always served from idle mode. Of course this too uses too much 
CPU 
Show quoted textHide quoted text
> resources. A hardware solution is preferable.
> 
> Guille
> 
> --- In lpc2000@yahoogroups.com, "Rob Jansen" <rob@m...> wrote:
> >
> > Brendan,
> > 
> > > I've pointed this out to Philips in the past: hopefully, they'll
> > > recognise from this that others have the same issue.
> > >
> > > None of the work-arounds presented are ideal: a h/w fix is much 
> more
> > > preferable.
> > 
> > Just thought of this when I saw "h/w fix" ...
> > That is the easy solution, use a sample&hold replaces the variable
> > software latencies with a fixed HW one.
> > Have an interrupt and a match output generated by the timer. On a 
> match
> > trigger the S&H and write to the DAC from the interrupt routine.
> > This will introduce a delay of 1 sample time but I don't think 
> that's a
> > big problem in this case.
> > 
> > A S&H can be easy: one gate of a CD4066 and a capacitor do the 
> trick.
> > Use the other 3 and some more caps to create a switched capacitor 
> filter :o)
> > 
> > Regards,
> > 
> >       Rob
> >
>

Re: D/A noise

2006-01-23 by Guillermo Prandi

> This is pretty much what we do - see message 12622.

You're right, Brendan. Sorry for the dup. ;)

Guille

--- In lpc2000@yahoogroups.com, "brendanmurphy37" 
<brendan.murphy@i...> wrote:
>
> 
> Guillermo,
> 
> This is pretty much what we do - see message 12622.
> 
> I can confirm that (a) it works! and (b) it's pretty messy to get 
> exactly right, and (c) it consumes a fair amount of MIPS in what's 
a 
> MIPS-hungry system (it's fine if you're not doing much else). You 
> have to be careful to have the 1st timer fire with enough time to 
> take into account the worst-case interrupt latency (which is quite 
> long).
> 
> By the way, I'd be curious to know how the instigator of this 
thread 
> is getting on with these various suggestions.
> 
> Brendan
> 
> --- In lpc2000@yahoogroups.com, "Guillermo Prandi" 
> <yahoo.messenger@m...> wrote:
> >
> > Perhaps a combination of IRQ/FIQ can be used?
> > 
> > Let's say FIQs are enabled inside IRQs. Then, one could set 
TIMER1 
> > with two match registers: "some time before" (e.g. at 80 µS for 
11 
> > KHz) and "exactly" (at 90.9µS). Then, when the first interrupt is 
> > caught, make TIMER1 generate FIQs instead of IRQs and enter idle 
> > mode. Switch to IRQ afterwards. This way one can ensure that the 
> FIQ 
> > is always served from idle mode. Of course this too uses too much 
> CPU 
> > resources. A hardware solution is preferable.
> > 
> > Guille
> > 
> > --- In lpc2000@yahoogroups.com, "Rob Jansen" <rob@m...> wrote:
> > >
> > > Brendan,
> > > 
> > > > I've pointed this out to Philips in the past: hopefully, 
they'll
> > > > recognise from this that others have the same issue.
> > > >
> > > > None of the work-arounds presented are ideal: a h/w fix is 
much 
> > more
> > > > preferable.
> > > 
> > > Just thought of this when I saw "h/w fix" ...
> > > That is the easy solution, use a sample&hold replaces the 
variable
> > > software latencies with a fixed HW one.
> > > Have an interrupt and a match output generated by the timer. On 
a 
> > match
> > > trigger the S&H and write to the DAC from the interrupt routine.
> > > This will introduce a delay of 1 sample time but I don't think 
> > that's a
> > > big problem in this case.
> > > 
> > > A S&H can be easy: one gate of a CD4066 and a capacitor do the 
> > trick.
> > > Use the other 3 and some more caps to create a switched 
capacitor 
Show quoted textHide quoted text
> > filter :o)
> > > 
> > > Regards,
> > > 
> > >       Rob
> > >
> >
>

Re: D/A noise

2006-01-23 by tengelberth

Thanks to all the great suggestions on my D/A noise.  

To start I am working on adding a Butterworth filter (8 order) to the
D/A output and will test again to see what it sounds like. Once that
is done I will look at any jitter issues.  

By the way,  I got the open source Speex wideband (16Khz) decoding
running on my LPC2138 board. I am using Speex to compress a 10 sec
file to about 25KB. 
I will be comparing speex's quality to just playing from a wav file.
Speex sounds good on my PC but need to see if any issue come up on the
 LPC2138.  My goal is to put 10 mins of speech on a 2MB serial flash
chip. 


Thanks again 
Tom

Move to quarantaine

This moves the raw source file on disk only. The archive index is not changed automatically, so you still need to run a manual refresh afterward.