

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.)



