GUS Programmer's Digest Wed, 29 Sep 93 0:07 MDT Volume 4: Issue 18
Today's Topics:
How to avoid a recording pitfall
Standard Info:
- Meta-info about the GUS can be found at the end of the Digest.
- Before you ask a question, please READ THE FAQ.
----------------------------------------------------------------------
Date: Tue, 28 Sep 1993 14:26:37 -0400
From: davidm@marcam.com (David MacMahon)
Subject: How to avoid a recording pitfall
Message-ID: <9309281827.AA04507@ottawa.marcam.com>
Hello fellow GUS programmers,
This is a somewhat long message about a recording problem (best described as
distortion or noise) that I have in my program (GUSDELAY). I have found the
phenomenon I believe is the cause of the problem, but I have not yet been
able to test my theory. I have also thought about how to solve this problem
and have come to the conclusion that while there is no way to solve it
totally, it can be minimized so that (hopefully) it is negligible. I'm
pretty sure that this phenomenon exists for any program that attempts to do
continuous recording from the GUS. If anyone can prove me wrong, please do.
The problem I was experiencing was distortion (noise) in the recorded data.
I had attributed this to missing samples until I noticed that the problem
got worse at low sampling frequencies! I connected an o'scope to the record
DMA request line (DRQ) to see what was happening. I recorded in mono with a
sampling frequency of 7015 Hz (sample time of 143 uS). I measured the time
between DMA requests to be about 280 uS (I use a 16 bit DMA channel so in
mono the rate gets halved). So far so good. Then I noticed that the time
between the last DMA request of one buffer and the first DMA request of the
next buffer was only about 220 uS! In other words, everytime I started
recording into the next buffer I would start to sample the input at the
desired frequency, but the sampling started 60 uS before it should. The
impact of this is extra significant in GUSDELAY because the buffers are only
32 bytes long, so this 60 uS error occurred every 32 samples (4562 uS). For
a 1000 Hz input signal, 60 uS == 21 degrees. Here is an attempt to
represent this ascii-graphically:
0 0 0 0 0 0 01 1 1 1 1 1 1 1 1 1 1 1 1 1 1 10 0 0 0 <-Buffer number
9 A B C D E F0 1 2 3 4 5 6 7 8 9 A B C D E F0 1 2 3 <-DMA number
^^^ ^^
286 uS 220 uS
NOTE: There are sixteen 16-bit DMA transfers per 32 byte buffer.
The average sampling frequency is (32*1000000/(32*143-60)) (Hz). This works
out to 7086 Hz. This is 1.0% higher than the programmed frequency. If I
switch to a 32000 byte buffer, the equation becomes:
Average Sampling Frequency = (32000*1000000/(32000*143-60)) (Hz)
This works out to 6993 Hz. This is 0.3% lower than the programmed
frequency. This is clearly more desireable. Not only is the average
sampling frequency (ASF) closer to the programmed sampling frequency (PSF),
the irregularity in sample times happens every 32000 samples and not every
32 samples. It is also interesting to note that when I set up USS8 to do
mono recording at 7015 Hz, it would always display 6993 Hz as the sampling
frequency. I never knew where the 6993 figure came from, but now I do. It
may seem strange that the ASF is lower than the PSF when the sampling is
"early". This is due to integer math and the fact that the sample time is
not exacly 143 micrseconds. At higher sampling frequencies, when (if)
interrupt latency becomes a factor, the ASF may actually be slower than the PSF.
A better formula for the ASF would be:
ASF = N*1000000/((N-1)*Ts+Ti+Ta) (Hz)
Where: N = buffer size
Ts = Microseconds per sample at the PSF
Ti = Interrupt latency time (in microseconds)
This is the time from the interrupt to the time
the control registers on the GUS get hit.
Ta = The acquisition time of the first sample
(in microseconds)
Ti varies from system to system and from program to program (depending on
how the interrupt handler is structured) and could be a configuration option
of applications that desire a high level of precision.
Ta is probably a spec of the GUS itself. I will try to measure this as
accurately as possible, but if anyone (from Forte or AG) knows this value
please share it with us!!!
This phenomenon also explains something that I complained about in my first
message regarding simultaneous playback/record (see GUS Programmer's Digest
V3 #11, "Simultaneous recording/playback works!!!"). In that message I
referred to a strange behavior that I called "voice creep". My delay would
shrink over time until the voice passed the point where new data was being
written. I didn't know what was causing it, but worked around the problem
by regularly setting the voice back to where it should be. Now it is
apparrent that my ASF was slower than the PSF and I was using the PSF as the
playback frequency.
Well, that's all for now. Future versions of GUSDELAY will implement a
larger recording buffer and will also use the ASF as the playback frequency
instead of the PSF.
Dave
David MacMahon
Systems Administrator
davidm@marcam.com <---New address, use this one
davidm@opl.com <---Old address, don't use this one
------------------------------
End of GUS Programmer's Digest V4 #18
*************************************
To post to tomorrow's digest: <gus-sdk%itchy@dsd.es.com>
To (un)subscribe or get help: <gus-sdk-request%itchy@dsd.es.com>
To contact a human (last resort): <gus-sdk-owner%itchy@dsd.es.com>
FTP sites: archive.epas.utoronto.ca pub/pc/ultrasound
wuarchive.wustl.edu systems/msdos/ultrasound
Hints:
- Get the FAQ from the FTP sites or the request server.
- Mail to <gus-sdk-request%itchy@dsd.es.com> for info about
other GUS related mailing lists (UNIX, OS/2, GUS-MIDI, etc.)