!WIDTH 78

;------------------------------------------
!TOPIC 2 Contents
!INDEX 1
;------------------------------------------
Units in help file MAKEHELP.TXT:


3UltraDrv        

;------------------------------------------
!TOPIC 3 UltraDrv
;------------------------------------------
Unit UltraDrv (in 2MAKEHELP.TXT help file)


Gravis Ultrasound driver unit.

This unit provides functions and procedures for programming the
Gravis UltraSound 16-bit 44Khz stereo sound card.  Simply
include this unit in your USES clause.

Constants:

11Khz_11                   
12Khz_22                   
13Khz_44                   
15Loop_Volume              
16Bi_Directional_Volume    
17Enable_Volume_Handler    
19Voice_Data_16Bit         
20Loop_Voice               
21Bi_Directional_Voice     
22Enable_VoiceEnd_Handler  
24DMA_Data_16Bit           
25Convert_Data             
26Ultra_Installed          

Types:

4PFV                      
5INT_PROC                 
6WORD_PROC                
7TWOWORD_PROC             
8Ultra_CFG                
9VOICE_DATA_3D            
10SOUND_3D                 

Variables:

27Ultra_Config             
28UltraOk                  
29UltraError               
30UltraErrorStr            

Functions and Procedures:

31UltraCalcRate            
32UltraClose               
33UltraDownLoad            
34UltraDRAMDMABusy         
35UltraGoRecord            
36UltraGoVoice             
37UltraDisableLineIn       
38UltraDisableMicIn        
39UltraDisableOutput       
40UltraEnableLineIn        
41UltraEnableMicIn         
42UltraEnableOutput        
43UltraGetLineIn           
44UltraGetMicIn            
45UltraGetOutput           
46UltraDRAMTcHandler       
47UltraMIDIXMitHandler     
48UltraMIDIRecvHandler     
49UltraTimer1Handler       
50UltraTimer2Handler       
51UltraWaveHandler         
52UltraVolumeHandler       
53UltraRecordHandler       
54UltraAuxHandler          
55UltraMaxAvail            
56UltraMaxAlloc            
57UltraMemAvail            
58UltraMemAlloc            
59UltraMemFree             
60UltraMIDIDisableRecv     
61UltraMIDIDisableXmit     
62UltraMIDIEnableRecv      
63UltraMIDIEnableXmit      
64UltraMIDIRecv            
65UltraMIDIReset           
66UltraMIDIStatus          
67UltraMIDIXmit            
68UltraOpen                
69UltraPeekData            
70UltraPing                
71UltraPokeData            
72UltraPrimeRecord         
73UltraPrimeVoice          
74UltraProbe               
75UltraRampVolume          
76UltraReadRecordPosition  
77UltraReadVoice           
78UltraReadVolume          
79UltraRecordData          
80UltraRecordDMABusy       
81UltraReset               
82UltraSetBalance          
83UltraSetFrequency        
84UltraSetLoopMode         
85UltraSetRecordFrequency  
86UltraSetVoice            
87UltraSetVoiceEnd         
88UltraSetVolume           
89UltraSizeDRAM            
90UltraStartTimer          
91UltraStartVoice          
92UltraStopTimer           
93UltraStopVoice           
94UltraStopVolume          
95UltraTimerStopped        
96UltraTrimJoystick        
97UltraUpLoad              
98UltraVectorVolume        
99UltraVersion             
100UltraVersionStr          
101UltraVoiceStopped        
102UltraVolumeStopped       
103UltraWaitDRAMDMA         
104UltraWaitRecordDMA       
105UltraVoiceOff            
106UltraVoiceOn             
107UltraSetLinearVolume     
108UltraReadLinearVolume    
109UltraRampLinearVolume    
110UltraVectorLinearVolume  
111UltraClearVoices         
112UltraAllocVoice          
113UltraFreeVoice           
116UltraAbsPosition3D       
117UltraAngPosition3D       
118UltraAngFltPosition3D    
119UltraCloseDup3D          
120UltraDup3D               
121UltraLoad3DEffect        
122UltraSetFreq3D           
123UltraRelease3DInterleave 
124UltraSetup3DInterleave   
125UltraStart3D             
126UltraStop3D              
127UltraUnLoad3DEffect      

Other:

14Volume_Control_Bits      
18Voice_Control_Bits       
23DMA_Control_Bits         
114Focal_Point_3d           
115ThreeD_data_format       

;------------------------------------------
!TOPIC 4 PFV
;------------------------------------------
3UltraDrv.PFV = PROCEDURE 

This type is used to designate procedures which can be called
by the interrupt service routine.  When the ISR finds that
a specific condition has occurred, it will call a processing
procedure that you specify.  If you do not specify a
processing procedure, a default routine is supplied which
does nothing.

Since PASCAL cannot return function or procedure type values
from functions, the equivalent routine was made into a
procedure which took a single VAR parameter.  Thus, when
you are going to change the address of a callback routine,
you put the new address into a variable, run it through the
procedure, and what will then be in the variable is the address
of the old handler:  
!LINE
!NOWRAP
 
VAR
  OldProc : PFV;
 
Procedure MyNewProc; (* The new handler *)
  {  begin
    ...
  end;
 
...somewhere else... 
 Set OldProc to address of new handler 
OldProc := MyNewProc;
 Now set the new handler and return the old one 
UltraDRAMTcHandler(OldProc);
...
 
!LINE
!WRAP
At this point, OldProc holds the address of the old routine.
Therefore, to chain to the old routine, you would simply have
to call OldProc from your handler.



 See also:

54UltraAuxHandler                                                           
46UltraDRAMTcHandler                                                        
53UltraRecordHandler                                                        
49UltraTimer1Handler                                                        
50UltraTimer2Handler                                                        

;------------------------------------------
!TOPIC 5 INT_PROC
;------------------------------------------
3UltraDrv.INT_PROC = PROCEDURE (Voice: INTEGER)

This type is used to designate procedures which can be called
by the interrupt service routine.  When the ISR finds that
a specific condition has occurred, it will call a processing
procedure that you specify.  If you do not specify a
processing procedure, a default routine is supplied which
does nothing.

Since PASCAL cannot return function or procedure type values
from functions, the equivalent routine was made into a
procedure which took a single VAR parameter.  Thus, when
you are going to change the address of a callback routine,
you put the new address into a variable, run it through the
procedure, and what will then be in the variable is the address
of the old handler: 
!LINE
!NOWRAP
 
VAR
  OldProc : INT_PROC;
 
Procedure MyNewProc(I : INTEGER); (* The new handler *)
  {  begin
    ...
  end;
 
...somewhere else... 
 Set OldProc to address of new handler 
OldProc := MyNewProc;
 Now set the new handler and return the old one 
UltraWaveHandler(OldProc);
...
 
!LINE
!WRAP
At this point, OldProc holds the address of the old routine.
Therefore, to chain to the old routine, you would simply have
to call OldProc from your handler.



 See also:

52UltraVolumeHandler                                                        
51UltraWaveHandler                                                          

;------------------------------------------
!TOPIC 6 WORD_PROC
;------------------------------------------
3UltraDrv.WORD_PROC = PROCEDURE (MIDI_Send: WORD)

This type is used to designate procedures which can be called
by the interrupt service routine.  When the ISR finds that
a specific condition has occurred, it will call a processing
procedure that you specify.  If you do not specify a
processing procedure, a default routine is supplied which
does nothing.

Since PASCAL cannot return function or procedure type values
from functions, the equivalent routine was made into a
procedure which took a single VAR parameter.  Thus, when
you are going to change the address of a callback routine,
you put the new address into a variable, run it through the
procedure, and what will then be in the variable is the address
of the old handler: 
!LINE
!NOWRAP
 
VAR
  OldProc : WORD_PROC;
 
Procedure MyNewProc(W : WORD); (* The new handler *)
  {  begin
    ...
  end;
 
...somewhere else... 
 Set OldProc to address of new handler 
OldProc := MyNewProc;
 Now set the new handler and return the old one 
UltraMIDIXMitHandler(OldProc);
...
 
!LINE
!WRAP
At this point, OldProc holds the address of the old routine.
Therefore, to chain to the old routine, you would simply have
to call OldProc from your handler.



 See also:

47UltraMIDIXMitHandler                                                      

;------------------------------------------
!TOPIC 7 TWOWORD_PROC
;------------------------------------------
3UltraDrv.TWOWORD_PROC = PROCEDURE (MIDI_Status: WORD; MIDI_Data: WORD)

This type is used to designate procedures which can be called
by the interrupt service routine.  When the ISR finds that
a specific condition has occurred, it will call a processing
procedure that you specify.  If you do not specify a
processing procedure, a default routine is supplied which
does nothing.

Since PASCAL cannot return function or procedure type values
from functions, the equivalent routine was made into a
procedure which took a single VAR parameter.  Thus, when
you are going to change the address of a callback routine,
you put the new address into a variable, run it through the
procedure, and what will then be in the variable is the address
of the old handler: 
!LINE
!NOWRAP
 
VAR
  OldProc : TWOWORD_PROC;
 
Procedure MyNewProc(W1 : WORD; W2 : WORD); (* The new handler *)
  {  begin
    ...
  end;
 
...somewhere else... 
 Set OldProc to address of new handler 
OldProc := MyNewProc;
 Now set the new handler and return the old one 
UltraWaveHandler(OldProc);
...
 
!LINE
!WRAP
At this point, OldProc holds the address of the old routine.
Therefore, to chain to the old routine, you would simply have
to call OldProc from your handler.



 See also:

48UltraMIDIRecvHandler                                                      

;------------------------------------------
!TOPIC 8 Ultra_CFG
;------------------------------------------
3UltraDrv.Ultra_CFG = RECORD

This record holds the configuration found in the DOS Environment
string ULTRASND, if it can be read.  If the string cannot be
read, the fields will contain default values. 
!LINE
!NOWRAP
 
   Base_Port      : WORD;  default $220
   Dram_DMA_Chan  : WORD;  default    1
   ADC_DMA_Chan   : WORD;  default    1
   GF1_IRQ_Num    : WORD;  default   11
   MIDI_IRQ_Num   : WORD;  default    5
 
!LINE
!WRAP

;------------------------------------------
!TOPIC 9 VOICE_DATA_3D
;------------------------------------------
3UltraDrv.VOICE_DATA_3D = RECORD

This record holds the data for one of the six voices used to produce
a 3-D sound.  The fields are typical values needed to play a voice.
!LINE
!NOWRAP
 
   VoiceNum : INTEGER; 
   CurVol   : INTEGER; 
   VBegin   : LONGINT; 
   VStart   : LONGINT; 
   VEnd     : LONGINT; 
 
!LINE
!WRAP


 See also:

0SOUND-3D                                                              

;------------------------------------------
!TOPIC 10 SOUND_3D
;------------------------------------------
3UltraDrv.SOUND_3D = RECORD

This record holds the data for a 3-D sound, including the sound type
(interleaved or blocked), the hemisphere flags, the ramping speed,
the 0-0-0 (maximum) volume, the number of independent tracks for
the sound, as well as voice and DMA mode bytes.

Specific data for each voice is held in an array at the bottom of
the record. 
!LINE
!NOWRAP
 
    SType      : BYTE;                         
    Flags      : INTEGER;                      
    Rate       : BYTE;                         
    MaxVol     : INTEGER;                      
    Num_Tracks : INTEGER;                      
    Freq       : LONGINT;                      
    VMode      : BYTE;                         
    DMode      : BYTE;                         
    VData      : ARRAY[0..5] OF VOICE_DATA_3D; 
!LINE
!WRAP


 See also:

9VOICE_DATA_3D                                                         

;------------------------------------------
!TOPIC 11 Khz_11
;------------------------------------------
Const 3UltraDrv.Khz_11 = 11025; 


Common recording and playback frequency for sound and voice.

 See also:

83UltraSetFrequency                                                        

;------------------------------------------
!TOPIC 12 Khz_22
;------------------------------------------
Const 3UltraDrv.Khz_22 = 22050; 


Common recording and playback frequency for misc sounds.

 See also:

83UltraSetFrequency                                                        

;------------------------------------------
!TOPIC 13 Khz_44
;------------------------------------------
Const 3UltraDrv.Khz_44 = 44100; 


Common frequency for CD quality recording and playback. 

 See also:

83UltraSetFrequency                                                        

;------------------------------------------
!TOPIC 14 Volume_Control_Bits
;------------------------------------------


Volume Control Bits:

You can OR together the following constants to produce a volume
ramp mode byte: 
!LINE
!NOWRAP
 
   Loop_Volume           = 08; 
   Bi_Directional_Volume = 16; 
   Enable_Volume_Handler = 32; 
!LINE
!WRAP

;------------------------------------------
!TOPIC 15 Loop_Volume
;------------------------------------------
Const 3UltraDrv.Loop_Volume = 08; 


 See also:

14Volume_Control_Bits  

;------------------------------------------
!TOPIC 16 Bi_Directional_Volume
;------------------------------------------
Const 3UltraDrv.Bi_Directional_Volume = 16; 


 See also:

14Volume_Control_Bits  

;------------------------------------------
!TOPIC 17 Enable_Volume_Handler
;------------------------------------------
Const 3UltraDrv.Enable_Volume_Handler = 32; 


 See also:

14Volume_Control_Bits  

;------------------------------------------
!TOPIC 18 Voice_Control_Bits
;------------------------------------------


Voice Control Bits:

You can OR together the following constants to produce a voice
control byte: 
!LINE
!NOWRAP
 
   Voice_Data_16Bit        = 04;  
   Loop_Voice              = 08;  
   Bi_Directional_Voice    = 16;  
   Enable_VoiceEnd_Handler = 32;  
!LINE
!WRAP

;------------------------------------------
!TOPIC 19 Voice_Data_16Bit
;------------------------------------------
Const 3UltraDrv.Voice_Data_16Bit = 04; 


 See also:

18Voice_Control_Bits   

;------------------------------------------
!TOPIC 20 Loop_Voice
;------------------------------------------
Const 3UltraDrv.Loop_Voice = 08; 


 See also:

18Voice_Control_Bits   

;------------------------------------------
!TOPIC 21 Bi_Directional_Voice
;------------------------------------------
Const 3UltraDrv.Bi_Directional_Voice = 16; 


 See also:

18Voice_Control_Bits   

;------------------------------------------
!TOPIC 22 Enable_VoiceEnd_Handler
;------------------------------------------
Const 3UltraDrv.Enable_VoiceEnd_Handler = 32; 


 See also:

18Voice_Control_Bits   

;------------------------------------------
!TOPIC 23 DMA_Control_Bits
;------------------------------------------


DMA Control Bits:

You can OR together the following constants to produce a DMA
control byte: 
!LINE
!NOWRAP
 
   DMA_Data_16Bit = 64;  
   Convert_Data   = 128; 
!LINE
!WRAP

;------------------------------------------
!TOPIC 24 DMA_Data_16Bit
;------------------------------------------
Const 3UltraDrv.DMA_Data_16Bit = 64; 


 See also:

23DMA_Control_Bits     

;------------------------------------------
!TOPIC 25 Convert_Data
;------------------------------------------
Const 3UltraDrv.Convert_Data = 128; 


 See also:

23DMA_Control_Bits     

;------------------------------------------
!TOPIC 26 Ultra_Installed
;------------------------------------------
Const 3UltraDrv.Ultra_Installed: BOOLEAN = FALSE; 


This constant is initially set to FALSE to signify that the card
has not yet been found.  In the initialization section of the unit,
which is executed BEFORE your application, this constant is changed
to TRUE if the 'ULTRASND' environment variable can successfully
be read from the DOS environment.

 See also:

8Ultra_CFG                                                                

;------------------------------------------
!TOPIC 27 Ultra_Config
;------------------------------------------
3UltraDrv.Ultra_Config: 8Ultra_CFG; 

This variable holds the current configuration.  If the configuration
can successfully be read at program start-up, this variable will hold
the values found in the environment string.

If the environment variable cannot be found, you may wish to specify
values other than the defaults prior to opening the card with
68UltraOpen.


 See also:

8Ultra_CFG                                                               

;------------------------------------------
!TOPIC 28 UltraOk
;------------------------------------------
3UltraDrv.UltraOk: BOOLEAN; 

If there is an error while executing any of the procedures or functions
in this driver unit, this BOOLEAN will be set to FALSE.  Otherwise, it
will remain TRUE. 

 See also:

29UltraError                                                              
30UltraErrorStr                                                           

;------------------------------------------
!TOPIC 29 UltraError
;------------------------------------------
3UltraDrv.UltraError: INTEGER; 

This reports the error number if an error occurs in any procedure or
function in the driver unit.  Check 30UltraErrorStr for a string
description of the error. 

 See also:

30UltraErrorStr                                                           
28UltraOk                                                                 

;------------------------------------------
!TOPIC 30 UltraErrorStr
;------------------------------------------
3UltraDrv.UltraErrorStr: STRING; 

This string reports a description of the error if an error occurs in
any procedure or function in the driver unit.  Check 29UltraError for
the error's number. 

 See also:

29UltraError                                                              
28UltraOk                                                                 

;------------------------------------------
!TOPIC 31 UltraCalcRate
;------------------------------------------
FUNCTION 3UltraDrv.UltraCalcRate(StartV: WORD; EndV: WORD; Mil_Secs: LONGINT): BYTE; 

This routine calculates the rate necessary to ramp the
volume from StartV volume (logarithmic) to EndV volume
(logarithmic) in a desired number of milliseconds.  This value
should be passed to 75UltraRampVolume.  This is only an
approximation.  The longer the time span, the less
precise the result is likely to be.

The function returns a value which can be passed to
75UltraRampVolume or 109UltraRampLinearVolume.

 See also:

109UltraRampLinearVolume                                                  
75UltraRampVolume                                                        

;------------------------------------------
!TOPIC 32 UltraClose
;------------------------------------------
FUNCTION 3UltraDrv.UltraClose: BOOLEAN; 

This routine should be called before your application
exits.  It shuts down all audio and puts the card in a
stable state.  It also puts the PC back to the state
prior to running your application (resets interrupt
vectors etc).

The function returns TRUE if Close was successful, FALSE otherwise. 


 See also:

68UltraOpen                                                              
81UltraReset                                                             

;------------------------------------------
!TOPIC 33 UltraDownLoad
;------------------------------------------
FUNCTION 3UltraDrv.UltraDownLoad(DataPtr: POINTER; Control: BYTE; DRAM_Loc: LONGINT; Len: WORD; Wait: BOOLEAN): BOOLEAN; 

This routine will transfer a chunk of data from the PC's
RAM to the UltraSound's DRAM.  It will transfer 'Len' number
of bytes from DataPtr (in PC) to DRAM_Loc (in
UltraSound).  If 'Wait' is TRUE, then it will wait until
the transfer is complete.  If 'Wait' is FALSE, it will
return as soon as transfer is started.  In some cases
where you need to get output quickly, you can start the
download and then immediately start a voice playing the
data.  The DMA transfer is MUCH faster than the voice
playback, so it will be able to download data ahead of
the playback.  For obvious reasons, this will not work if
you want to play the data backwards.

The function returns TRUE if transfer was successful, FALSE
otherwise.  If unsuccessful, check 30UltraErrorStr for the
reason.
#M

 See also:

23DMA_Control_Bits                                                       
34UltraDRAMDMABusy                                                       
97UltraUpload                                                            

;------------------------------------------
!TOPIC 34 UltraDRAMDMABusy
;------------------------------------------
FUNCTION 3UltraDrv.UltraDRAMDMABusy: BOOLEAN; 

This routine will check to see if the to/from DRAM DMA
channel is busy.  It might be useful so your application
doesn't hang around while waiting for a DMA transfer to
complete.

The function returns TRUE if the channel is still busy,  FALSE if it's free.


 See also:

0                                                                       
0                                                                       
33UltraDownload                                                          
97UltraUpload                                                            
103UltraWaitDRAMDMA                                                       

;------------------------------------------
!TOPIC 35 UltraGoRecord
;------------------------------------------
FUNCTION 3UltraDrv.UltraGoRecord(Control: BYTE): BOOLEAN; 

This routine will start up a pre-primed record (done
with 72UltraPrimeRecord).  It can also be used to restart a
indefinite recording process from the recording handler
callback.

The function returns TRUE if Record started ok.  FALSE otherwise.
If FALSE check the 30UltraErrorStr for the reason.


 See also:

0                                                                       
0                                                                       
72UltraPrimeRecord                                                       
79UltraRecordData                                                        
53UltraRecordHandler                                                     

;------------------------------------------
!TOPIC 36 UltraGoVoice
;------------------------------------------
PROCEDURE 3UltraDrv.UltraGoVoice(Voice: INTEGER; VMode: BYTE); 

This routine will start up a voice that has already been
primed with set-up values by 73UltraPrimeVoice.  This can
be useful if you need to start multiple voices as close
together as possible.

 See also:

0                                                                       
73UltraPrimeVoice                                                        
91UltraStartVoice                                                        

;------------------------------------------
!TOPIC 37 UltraDisableLineIn
;------------------------------------------
PROCEDURE 3UltraDrv.UltraDisableLineIn; 

If line level input is enabled and output is enabled,
the input is routed directly to the output and audio will
be heard.  If this is not desired, use this to disable
line in.

 See also:

0                                                                       
40UltraEnableLineIn                                                      
43UltraGetLineIn                                                         

;------------------------------------------
!TOPIC 38 UltraDisableMicIn
;------------------------------------------
PROCEDURE 3UltraDrv.UltraDisableMicIn; 


If microphone input is enabled and output is enabled,
the input is routed directly to the output and audio will
be heard.  If this is not desired, use this to disable
microphone in.

 See also:

0                                                                       
41UltraEnableMicIn                                                       
44UltraGetMicIn                                                          

;------------------------------------------
!TOPIC 39 UltraDisableOutput
;------------------------------------------
PROCEDURE 3UltraDrv.UltraDisableOutput; 

This routine will disable all output from the
UltraSound.  This can be used during recording so that
the input will not be looped back to the output.  It is
also useful to disable output during resets since that
will help eliminate 'pops' during initialization.

 See also:

0                                                                       
42UltraEnableOutput                                                      
45UltraGetOutput                                                         

;------------------------------------------
!TOPIC 40 UltraEnableLineIn
;------------------------------------------
PROCEDURE 3UltraDrv.UltraEnableLineIn; 

Turns on the line level input.  If you are not recording
from the line input, it is probably not desirable to have
this enabled since it will be looped back to the output
(if output is enabled).

 See also:

0                                                                       
37UltraDisableLineIn                                                     
43UltraGetLineIn                                                         

;------------------------------------------
!TOPIC 41 UltraEnableMicIn
;------------------------------------------
PROCEDURE 3UltraDrv.UltraEnableMicIn; 

This routine should be called when you want to record
from the microphone.  It is possible to have both the
microphone input enabled and line level input enabled.
If you are not recording from the microphone, it is
recommended that it be disabled, since it will reduce
noise on the output.

 See also:

0                                                                       
38UltraDisableMicIn                                                      
44UltraGetMicIn                                                          

;------------------------------------------
!TOPIC 42 UltraEnableOutput
;------------------------------------------
PROCEDURE 3UltraDrv.UltraEnableOutput; 

This routine must be called to enable any output from
the UltraSound.  This can be used to turn on output after
muting it with 39UltraDisableOutput.

 See also:

0                                                                       
39UltraDisableOutput                                                     
45UltraGetOutput                                                         

;------------------------------------------
!TOPIC 43 UltraGetLineIn
;------------------------------------------
FUNCTION 3UltraDrv.UltraGetLineIn: BOOLEAN; 

This can be useful if you want to change the state of
the line level input and then restore it back to the
original state.

The function returns TRUE if LineIn is Enabled, FALSE otherwise.


 See also:

0                                                                       
37UltraDisableLineIn                                                     
40UltraEnableLineIn                                                      

;------------------------------------------
!TOPIC 44 UltraGetMicIn
;------------------------------------------
FUNCTION 3UltraDrv.UltraGetMicIn: BOOLEAN; 

This can be useful if you want to change the state of
the microphone input and then restore it back to the
original state.

The function returns TRUE if Output is Enabled, FALSE otherwise.


 See also:

0                                                                       
38UltraDisableMicIn                                                      
41UltraEnableMicIn                                                       

;------------------------------------------
!TOPIC 45 UltraGetOutput
;------------------------------------------
FUNCTION 3UltraDrv.UltraGetOutput: BOOLEAN; 

This can be useful if you want to change the state of
the output and then restore it back to the original
state.

The function returns TRUE if Output is Enabled, FALSE otherwise.


 See also:

0                                                                       
39UltraDisableOutput                                                     
42UltraEnableOutput                                                      

;------------------------------------------
!TOPIC 46 UltraDRAMTcHandler
;------------------------------------------
PROCEDURE 3UltraDrv.UltraDRAMTcHandler(VAR Handler: 4PFV); 

This procedure defines a callback for a DMA
transfer to the UltraSound has been completed.  The
routine address passed as a parameter is set as the new
handler.  No parameters are passed to your new handler.

 See also:

4PFV                                                                    

;------------------------------------------
!TOPIC 47 UltraMIDIXMitHandler
;------------------------------------------
PROCEDURE 3UltraDrv.UltraMIDIXMitHandler(VAR Handler: 6WORD_PROC); 

This procedure defines a callback for a MIDI
transmit empty interrupt occurs.  This can be used to
send out MIDI data under interrupt control.  The routine
address passed as a parameter is set as the new handler.
The MIDI Status Byte is passed to the new handler
defined.

 See also:

0                                                                       
48UltraMIDIRecvHandler                                                   
6WORD_PROC                                                              

;------------------------------------------
!TOPIC 48 UltraMIDIRecvHandler
;------------------------------------------
PROCEDURE 3UltraDrv.UltraMIDIRecvHandler(VAR Handler: 7TWOWORD_PROC); 

This procedure defines a callback for a byte is
received in the MIDI input port.  This can be used to get
data from the MIDI port under interrupt contol.  The
routine address passed as a parameter is set as the new
handler.  The MIDI port status and MIDI data are passed
to your handler.

 See also:

0                                                                       
7TWOWORD_PROC                                                           
47UltraMIDIXmitHandler                                                   

;------------------------------------------
!TOPIC 49 UltraTimer1Handler
;------------------------------------------
PROCEDURE 3UltraDrv.UltraTimer1Handler(VAR Handler: 4PFV); 

This procedure defines a callback for the
UltraSound's Timer 1 'Ticks'.  The routine address passed
as a parameter is set as the new handler.  No parameters
are passed to this handler.

 See also:

0                                                                       
0                                                                       
4PFV                                                                    
90UltraStartTimer                                                        
50UltraTimer2Handler                                                     

;------------------------------------------
!TOPIC 50 UltraTimer2Handler
;------------------------------------------
PROCEDURE 3UltraDrv.UltraTimer2Handler(VAR Handler: 4PFV); 

This procedure defines a callback for the
UltraSound's Timer 2 'Ticks'.  The routine address passed
as a parameter is set as the new handler.  No parameters
are passed to this handler.

 See also:

0                                                                       
0                                                                       
4PFV                                                                    
90UltraStartTimer                                                        
49UltraTimer1Handler                                                     

;------------------------------------------
!TOPIC 51 UltraWaveHandler
;------------------------------------------
PROCEDURE 3UltraDrv.UltraWaveHandler(VAR Handler: 5INT_PROC); 

This procedure defines a callback for a voice
generates a wavetable interrupt.  This happens when a
voice hits it's end and interrupts are enabled.  It will
happen even if looping is on (i.e.  the voice keeps
playing).  The routine address passed as a parameter is
set as the new handler.

Normally, This procedure is used to signify that a voice
is done playing.  This handler can be useful for starting
another voice or counting the number of times that a voice
goes through a loop.  The voice number that generated the
interrupt is passed back to your handler.

 See also:

0                                                                       
5INT_PROC                                                               

;------------------------------------------
!TOPIC 52 UltraVolumeHandler
;------------------------------------------
PROCEDURE 3UltraDrv.UltraVolumeHandler(VAR Handler: 5INT_PROC); 

This procedure defines a callback for a volume
ramp ends.  The routine address passed as a parameter is
set as the new handler.  This routine can be used to
generate a volume envelope (attack, decay, sustain,
release).  This is done by changing to the appropriate
volume ramps in the handler to handle the next part of
the envelope.  The voice number causing the interrupt will be
passed back to your handler.

 See also:

4PFV                                                                    

;------------------------------------------
!TOPIC 53 UltraRecordHandler
;------------------------------------------
PROCEDURE 3UltraDrv.UltraRecordHandler(VAR Handler: 4PFV); 

This routine is called when a buffer that was being
recorded into is full.  The routine address passed as a
parameter is set as the new handler.  Normally, this
procedure would be used to let the application start up
another record.  A double buffering scheme could be used
to record data continuously.  No parameters are passed to
this handler.

As long as the DMA channels for recording and playback
are different, the UltraSound is capable of
simultaneously recording and playback.  At high data
rates your application may have a problem with
throughput.

 See also:

4PFV                                                                    

;------------------------------------------
!TOPIC 54 UltraAuxHandler
;------------------------------------------
PROCEDURE 3UltraDrv.UltraAuxHandler(VAR Handler: 4PFV); 

This handler will be called at the end of ALL interrupts
that happen on the UltraSound.  Its primary purpose is
for use with the new UltraMax card since its shares its
IRQ with the GF1.

 See also:

0                                                                       
4PFV                                                                    

;------------------------------------------
!TOPIC 55 UltraMaxAvail
;------------------------------------------
FUNCTION 3UltraDrv.UltraMaxAvail: LONGINT; 

This routine will return the largest block of DRAM (in
bytes) that can still be allocated.  This can be useful
for determining whether or not a patch or sample can be
loaded.  The maximum size of a block is 256K.  This
routine is included to provide consistency of naming for
PASCAL Programmers.

The function returns number of bytes in largest available block.


 See also:

0                                                                       
58UltraMemAlloc                                                          
57UltraMemAvail                                                          
59UltraMemFree                                                           

;------------------------------------------
!TOPIC 56 UltraMaxAlloc
;------------------------------------------
FUNCTION 3UltraDrv.UltraMaxAlloc: LONGINT; 

This routine will return the largest block of DRAM (in
bytes) that can still be allocated.  This can be useful
for determining whether or not a patch or sample can be
loaded.  The maximum size of a block is 256K.

The function returns number of bytes in largest available block.


 See also:

0                                                                       
55UltraMaxAvail                                                          
58UltraMemAlloc                                                          
57UltraMemAvail                                                          
59UltraMemFree                                                           

;------------------------------------------
!TOPIC 57 UltraMemAvail
;------------------------------------------
FUNCTION 3UltraDrv.UltraMemAvail: LONGINT; 

This will return the total amount of
DRAM still available for use on the UltraSound.

 See also:

0                                                                       
56UltraMaxAlloc                                                          
55UltraMaxAvail                                                          
58UltraMemAlloc                                                          
59UltraMemFree                                                           

;------------------------------------------
!TOPIC 58 UltraMemAlloc
;------------------------------------------
FUNCTION 3UltraDrv.UltraMemAlloc(Size: LONGINT; VAR Location: LONGINT): BOOLEAN; 

This routine allocates a chunk of DRAM of 'Size' bytes
from the UltraSound's DRAM.  The memory allocation
structures are set up by 68UltraOpen.  'Location' is filled
in with the DRAM location of the start of the chunk of
memory.  The memory address returned will ALWAYS be
aligned on a 32 byte boundary so that the DRAM can be
DMA'ed into without error.  Also, the size will be
rounded UP to the next 32 byte boundary.  PASCAL users
can reference section 1.8.3 for a detailed look at how
the memory is managed.

The function returns TRUE if the allocation was successful.
If FALSE, check 30UltraErrorStr for the reason.


 See also:

0                                                                       
56UltraMaxAlloc                                                          
55UltraMaxAvail                                                          
57UltraMemAvail                                                          
59UltraMemFree                                                           

;------------------------------------------
!TOPIC 59 UltraMemFree
;------------------------------------------
FUNCTION 3UltraDrv.UltraMemFree(Size: LONGINT; Location: LONGINT): BOOLEAN; 

Frees a previously allocated chunk of UltraSound memory.
The size will automatically be rounded UP to the next 32
byte boundary.

The function returns TRUE if deallocation was successful.
If FALSE, check 30UltraErrorStr for the reason.


 See also:

0                                                                       
55UltraMaxAvail                                                          
58UltraMemAlloc                                                          
57UltraMemAvail                                                          
0UltraMemInit                                                           

;------------------------------------------
!TOPIC 60 UltraMIDIDisableRecv
;------------------------------------------
PROCEDURE 3UltraDrv.UltraMIDIDisableRecv; 

This routine will disable the receive data interrupts
from the MIDI.  If the interrupt is enabled, it should be
disabled before leaving your application.

 See also:

0                                                                       
62UltraMIDIEnableRecv                                                    
48UltraMIDIRecvHandler                                                   

;------------------------------------------
!TOPIC 61 UltraMIDIDisableXmit
;------------------------------------------
PROCEDURE 3UltraDrv.UltraMIDIDisableXmit; 

This routine will turn off MIDI transmit interrupts.  It
MUST be called when you are through sending data.

 See also:

0                                                                       
63UltraMIDIEnableXmit                                                    
47UltraMIDIXmitHandler                                                   

;------------------------------------------
!TOPIC 62 UltraMIDIEnableRecv
;------------------------------------------
PROCEDURE 3UltraDrv.UltraMIDIEnableRecv; 

This routine will enable receive data interrupts from
the MIDI port.  It is necessary to set up a callback
routine for your application to process the data.

 See also:

0                                                                       
60UltraMIDIDisableRecv                                                   
48UltraMIDIRecvhandler                                                   

;------------------------------------------
!TOPIC 63 UltraMIDIEnableXmit
;------------------------------------------
PROCEDURE 3UltraDrv.UltraMIDIEnableXmit; 

This routine will enable transmit data interrupts to be
generated as each byte is transmitted out the MIDI port.
Note that a transmit interrupt will be generated as soon
as the IRQ is enabled unless a byte is sent out
immediately prior to enabling it.  This is because the
xmit buffer is initially empty (unless primed) so it will
pop an interrupt.  Also note that you MUST disable this
interrupt when you are not sending any more data or else
you will be hung up getting transmit ready interrupts.

 See also:

0                                                                       
61UltraMIDIDisableXmit                                                   
47UltraMIDIXmitHandler                                                   

;------------------------------------------
!TOPIC 64 UltraMIDIRecv
;------------------------------------------
FUNCTION 3UltraDrv.UltraMIDIRecv: BYTE; 

This routine is used to read a byte from the MIDI port.
It assumes that the byte is waiting.  The Byte is there
if it got to the MIDI receive interrupt callback routine
or if you have polled the status and determined the
receive buffer is full.

The function returns MIDI data byte.


 See also:

0                                                                       
48UltraMIDIRecvHandler                                                   
66UltraMIDIStatus                                                        

;------------------------------------------
!TOPIC 65 UltraMIDIReset
;------------------------------------------
PROCEDURE 3UltraDrv.UltraMIDIReset; 

This routine should be used to ensure that the MIDI port
is ready to use.  All MIDI interrupts will be disabled by
this call.

 See also:

0                                                                       
0UltraEnableMIDIRecv                                                    
0UltraEnableMIDIXmit                                                    

;------------------------------------------
!TOPIC 66 UltraMIDIStatus
;------------------------------------------
FUNCTION 3UltraDrv.UltraMIDIStatus: BYTE; 

This routine returns the current MIDI port status bits.
This can be used to determine if an error has occurred or
if the port is ready to be read or written.
The function returns The MIDI status byte.


 See also:

0                                                                       
64UltraMIDIRecv                                                          
67UltraMIDIXmit                                                          

;------------------------------------------
!TOPIC 67 UltraMIDIXmit
;------------------------------------------
PROCEDURE 3UltraDrv.UltraMIDIXmit(Data: BYTE); 

This routine will send the 'Data' byte out the MIDI data
port.  If interrupts are enabled, an interrupt will be
generated when the Byte has been transmitted.

 See also:

47UltraMIDIXmitHandler                                                   

;------------------------------------------
!TOPIC 68 UltraOpen
;------------------------------------------
FUNCTION 3UltraDrv.UltraOpen(VAR Config: 8Ultra_CFG; Voices: INTEGER): BOOLEAN; 

This routine should ALWAYS be called to initialize the
UltraSound.  It will probe for the card and program the
IRQ and DMA latches.  It will then disable line and
microphone input and enable output.  It also initializes
the memory structures.  The number of active voices is an
important parameter to the UltraSound: the fewer the number of
voices, the more oversampling that occurs on playback.
This will make the sound much 'cleaner'.  If you specify
a number of voices less than 14, the card will still be
initialized to use 14 voices.  Likewise, if you select
larger than 32 voices, you will still only have 32.

The function returns TRUE if the card was successfully opened.
If FALSE, check 30UltraErrorStr for the reason.


 See also:

0                                                                       
32UltraClose                                                             
74UltraProbe                                                             

;------------------------------------------
!TOPIC 69 UltraPeekData
;------------------------------------------
FUNCTION 3UltraDrv.UltraPeekData(PPort: INTEGER; Address: LONGINT): BYTE; 

This routine is used to allow an application to look at
any location in UltraSound's DRAM.  This can be handy for
obtaining VU information or any other time it is nice to
know what is in DRAM.  Be aware that if the data is
playable it will be in twos compliment form.  If the data
that you want is 16 bit data, you will need to peek both
locations and do any appropriate conversions.  The data
will be in low/high format.  That means that the low byte
of the data will be in the even byte and the high byte
will be in the odd byte.

The function returns Data byte at location specified.


 See also:

0                                                                       
71UltraPokeData                                                          
97UltraUpload                                                            

;------------------------------------------
!TOPIC 70 UltraPing
;------------------------------------------
FUNCTION 3UltraDrv.UltraPing(PPort: WORD): BOOLEAN; 

This routine will determine if an UltraSound is present
by attempting to read and write to its DRAM.  This
routine assumes that at least a simple reset has been
done since power-up so that the board is no longer in a
reset state.  If it is on a reset state, this routine
will ALWAYS fail.  74UltraProbe pulls a quick reset and
then calls 70UltraPing.

The function returns TRUE if the card was found.
If FALSE, check 30UltraErrorStr for the reason.


 See also:

74UltraProbe                                                             

;------------------------------------------
!TOPIC 71 UltraPokeData
;------------------------------------------
PROCEDURE 3UltraDrv.UltraPokeData(PPort: INTEGER; Address: LONGINT; Data: BYTE); 

Poke an 8 bit value directly into UltraSound DRAM.  This
can be useful to set the value of the location that a
voice is pointing to.  It is often desirable to point a
voice to a known value since its output is ALWAYS summed
in to the output even if the voice is not running.  Be
aware that there is no automatic conversion of data poked
into DRAM.  Since the UltraSound can only play twos
compliment data, make sure that the data you are poking
is in that format.  Also be careful with 16 bit data.

 See also:

0                                                                       
33UltraDownload                                                          
69UltraPeekData                                                          

;------------------------------------------
!TOPIC 72 UltraPrimeRecord
;------------------------------------------
FUNCTION 3UltraDrv.UltraPrimeRecord(PC_Ptr: POINTER; Size: WORD; RRepeat: BOOLEAN): BOOLEAN; 

This routine will setup the DMA channel to do a record,
but does not start it.  This can be used to help
synchronize events.  Programming the DMA channel can take
enough time so that a few samples may be lost.
(Depending on sample rate).  This routine will help
alleviate this problem by doing the programming ahead of
time.

The function returns TRUE if setup was successful.
If FALSE, check 30UltraErrorStr for the reason.


 See also:

35UltraGoRecord                                                          

;------------------------------------------
!TOPIC 73 UltraPrimeVoice
;------------------------------------------
FUNCTION 3UltraDrv.UltraPrimeVoice(Voice: INTEGER; VBegin: LONGINT; VStart: LONGINT; VEnd: LONGINT; VMode: BYTE): BYTE; 

This routine is used to do all the setup necessary to
start a voice but does NOT start it up.  This can be
useful if you want to start more than 1 voice at the same
time.  Use 73UltraPrimeVoice to do all the necessary setup
and then use 36UltraGoVoice to start the voices.
91UltraStartVoice calls 73UltraPrimeVoice and then
immediately 36UltraGoVoice.

The function returns An updated mode value.  The mode may be modified on the
basis of the location parameters.  This altered value
should be the one passed to 36UltraGoVoice.


 See also:

0                                                                       
36UltraGoVoice                                                           
91UltraStartVoice                                                        

;------------------------------------------
!TOPIC 74 UltraProbe
;------------------------------------------
FUNCTION 3UltraDrv.UltraProbe(PPort: WORD): BOOLEAN; 

This routine probes for the existence of an UltraSound
card at the specified base port.  An application could
call this before calling 68UltraOpen to see if a card is
present.  68UltraOpen calls this routine also.  The
difference between 74UltraProbe and 70UltraPing is that
74UltraProbe will pull a reset to make sure the board is
running.  70UltraPing assumes this has already been done.

The function returns TRUE if the card is found.
If FALSE, check 30UltraErrorStr for the reason.


 See also:

0                                                                       
68UltraOpen                                                              
70UltraPing                                                              

;------------------------------------------
!TOPIC 75 UltraRampVolume
;------------------------------------------
PROCEDURE 3UltraDrv.UltraRampVolume(Voice: INTEGER; StartV: WORD; EndV: WORD; VRate: BYTE; VMode: BYTE); 

Start a volume ramp from a starting volume to the ending
volume.  The rate at which the ramp occurs can be
calculated using 31UltraCalcRate.  The mode determines the
looping and interrupting characteristics of the ramp.  If
you choose to have it interrupt at the end of the ramp,
you should set up an routine to call for a volume
interrupt.  This is done with the routine
52UltraVolumeHandler.

 See also:

0                                                                       
31UltraCalcRate                                                          
52UltraVolumeHandler                                                     
14Volume_Control_Bits                                                    

;------------------------------------------
!TOPIC 76 UltraReadRecordPosition
;------------------------------------------
FUNCTION 3UltraDrv.UltraReadRecordPosition: WORD; 

This routine can be used to monitor the amount data
recorded.

The function returns Number of BYTES recorded so far.


 See also:

79UltraRecordData                                                        

;------------------------------------------
!TOPIC 77 UltraReadVoice
;------------------------------------------
FUNCTION 3UltraDrv.UltraReadVoice(Voice: INTEGER): LONGINT; 

This routine can be used to monitor a voice's progress.

The function returns The voice's current position in DRAM.


 See also:

86UltraSetVoice                                                          

;------------------------------------------
!TOPIC 78 UltraReadVolume
;------------------------------------------
FUNCTION 3UltraDrv.UltraReadVolume(Voice: INTEGER): WORD; 

This routine returns the current volume of a voice.
This can be useful when used in conjunction with volume
ramps.  The value returned is logarithmic, not linear.
PASCAL users can use 108UltraReadLinearVolume.

The function returns 0-4095 value, the current logarithmic volume.


 See also:

0                                                                       
75UltraRampVolume                                                        
88UltraSetVolume                                                         

;------------------------------------------
!TOPIC 79 UltraRecordData
;------------------------------------------
FUNCTION 3UltraDrv.UltraRecordData(PC_Ptr: POINTER; Control: BYTE; Size: WORD; Wait: BOOLEAN; RRepeat: BOOLEAN): BOOLEAN; 

This routine will record a buffer of data from
UltraSound.  It can be in either 8-bit mono or stereo.
In stereo, there are two bytes and the left byte is
first.  If mono is being used, the left channel is the
one that is sampled.  If 'wait' is
set to a non-zero value, then this routine will not
return until the buffer has been filled.  If 'repeat' is
TRUE, then the DMA channel will be set up in auto-init
mode so that the recording is done indefinitely.  If this
is done, then the buffer MUST reside completely in 1 64K
page of PC RAM.  Also, it is probably necessary that your
application hooks to the record handler so that the
control register on the UltraSound can be hit to restart
the recording process (35UltraGoRecord).  This will be very
quick since the PC DMA controller will not be re-
programmed.

The function returns TRUE if successful.
If FALSE, check 30UltraErrorStr for the reason.


 See also:

0                                                                       
35UltraGoRecord                                                          
85UltraSetRecordFrequency                                                
104UltraWaitRecordDMA                                                     

;------------------------------------------
!TOPIC 80 UltraRecordDMABusy
;------------------------------------------
FUNCTION 3UltraDrv.UltraRecordDMABusy: BOOLEAN; 

This routine checks to see if the record DMA channel is
busy.  It might be busy doing a record (or playback if
the record & playback channels are the same).

The function returns TRUE if the channel is busy, FALSE otherwise.


 See also:

79UltraRecordData                                                        

;------------------------------------------
!TOPIC 81 UltraReset
;------------------------------------------
FUNCTION 3UltraDrv.UltraReset(Voices: INTEGER): BOOLEAN; 

This routine is called by 68UltraOpen to make sure the
card is in a known state.  32UltraClose also calls this
routine.

The function returns TRUE if card is successfully reset.
If FALSE, check 30UltraErrorStr for the reason.


 See also:

0                                                                       
32UltraClose                                                             
68UltraOpen                                                              

;------------------------------------------
!TOPIC 82 UltraSetBalance
;------------------------------------------
PROCEDURE 3UltraDrv.UltraSetBalance(Voice: INTEGER; Data: BYTE); 

This routine sets the voice's position between right and
left speakers.  A 0 will place the audio all the way to
the left whereas a 15 will put the sound all the way to
the right.  Values that are out of range will move the
balance to the nearest extreme.

;------------------------------------------
!TOPIC 83 UltraSetFrequency
;------------------------------------------
PROCEDURE 3UltraDrv.UltraSetFrequency(Voice: INTEGER; Speed_Khz: LONGINT); 

This routine sets the voice's playback rate to the
specified absolute frequency.  The number of active
voices is taken into account when making the appropriate
calculations.

;------------------------------------------
!TOPIC 84 UltraSetLoopMode
;------------------------------------------
PROCEDURE 3UltraDrv.UltraSetLoopMode(Voice: INTEGER; VMode: BYTE); 

This routine will set this voice's looping mode to the
specified mode.

 See also:

18Voice_Control_Bits                                                     

;------------------------------------------
!TOPIC 85 UltraSetRecordFrequency
;------------------------------------------
PROCEDURE 3UltraDrv.UltraSetRecordFrequency(Rate: LONGINT); 

This routine sets the record rate to the specified
frequency.  Since the UltraSound uses the PC DMA channel
to do the sampling directly into PC RAM, no voice
specification is necessary.

;------------------------------------------
!TOPIC 86 UltraSetVoice
;------------------------------------------
PROCEDURE 3UltraDrv.UltraSetVoice(Voice: INTEGER; Location: LONGINT); 

This routine sets a voice's current position to an
absolute location.  This can be useful to set a voice to
a location with a known value since all voices' current
locations are summed in to the output even if the voice
is not running.  'Pops' in the audio may result if a
voice is set to a location that contains a significant
value.

;------------------------------------------
!TOPIC 87 UltraSetVoiceEnd
;------------------------------------------
PROCEDURE 3UltraDrv.UltraSetVoiceEnd(Voice: INTEGER; VEnd: LONGINT); 

This routine sets a new endpoint for the specified
voice.  Used in conjunction with 84UltraSetLoopMode to turn
looping off, a sampled decay can be implemented.

 See also:

84UltraSetLoopMode                                                       

;------------------------------------------
!TOPIC 88 UltraSetVolume
;------------------------------------------
PROCEDURE 3UltraDrv.UltraSetVolume(Voice: INTEGER; Volume: WORD); 

This routine sets the volume of the voice to a specific
logarithmic value.  The range is from 0 to 4095.  Use
107UltraSetLinearVolume to do linear volumes.

 See also:

107UltraSetLinearVolume                                                   

;------------------------------------------
!TOPIC 89 UltraSizeDRAM
;------------------------------------------
FUNCTION 3UltraDrv.UltraSizeDRAM: INTEGER; 

This routine will always return the same value,
which is the amount of DRAM that has been installed on
the card.  Use 57UltraMemAvail to see how much DRAM is
still free.

The function returns number of kilobytes found on the UltraSound.


 See also:

0UltraMemInit                                                           

;------------------------------------------
!TOPIC 90 UltraStartTimer
;------------------------------------------
PROCEDURE 3UltraDrv.UltraStartTimer(Timer: INTEGER; Time: BYTE); 

This routine can be used to start up one of two
available hardware timers.  Timer #1 is an 80 microsecond
(.00008s) timer.  Timer #2 is a 320 microsecond (.00032s)
timer.  When starting either timer, you supply the number of
counts before the timer 'ticks'.  When the timer 'ticks',
it ALWAYS calls the callback routine defined for it.  If
you don't supply one, a default is used.
These timers can be used to trigger various real time
events.  They are used extensively in music compostition
programs.  Please remember that the callback routine is
called directly from the interrupt handler, so you must
be careful what you do in the callback routine.
Note that the specified timer is automatically restarted
after it ticks.  Your application must explicitly call
92UltraStopTimer to shut it off.

Example: 

Giving Timer 1 a duration of 10 counts would make the
timer tick every 800 microseconds (.0008s).  This would
mean your callback routine is called 1250 times a second.


 See also:

0                                                                       
0                                                                       
0                                                                       
92UltraStopTimer                                                         
49UltraTimer1Handler                                                     
50UltraTimer2Handler                                                     
95UltraTimerStopped                                                      

;------------------------------------------
!TOPIC 91 UltraStartVoice
;------------------------------------------
PROCEDURE 3UltraDrv.UltraStartVoice(Voice: INTEGER; VBegin: LONGINT; VStart: LONGINT; VEnd: LONGINT; VMode: BYTE); 

This routine will set up and start up a voice.  The
voice will begin playback at the 'begin' and continue to
'end'.  If looping is enabled for this voice, then it
will then jump to 'start' and then continue to 'end'.
The method of looping is determined by 'mode'.

 See also:

0                                                                       
0UltraLoopMode                                                          
0UltraSetEnd                                                            
18Voice_Control_Bits                                                     

;------------------------------------------
!TOPIC 92 UltraStopTimer
;------------------------------------------
PROCEDURE 3UltraDrv.UltraStopTimer(Timer: INTEGER); 

If you have started a timer with 90UltraStartTimer, you
will probably want to shut it off before shutting down
your application.  If you forget, 32UltraClose
automatically shuts it down.

 See also:

90UltraStartTimer                                                        

;------------------------------------------
!TOPIC 93 UltraStopVoice
;------------------------------------------
PROCEDURE 3UltraDrv.UltraStopVoice(Voice: INTEGER); 

This routine will stop a voice which is playing at it's
current position.  Don't forget that if a voice is left
at an unknown position, the data that is at that position
will still be summed into the final output.

 See also:

0                                                                       
87UltraSetVoiceEnd                                                       
91UltraStartVoice                                                        

;------------------------------------------
!TOPIC 94 UltraStopVolume
;------------------------------------------
PROCEDURE 3UltraDrv.UltraStopVolume(Voice: INTEGER); 

You can use this routine if you wish to stop an volume
ramp after a specified period of time, or you wish to
make sure that a volume ramp has stopped.

 See also:

0                                                                       
109UltraRampLinearVolume                                                  
75UltraRampVolume                                                        

;------------------------------------------
!TOPIC 95 UltraTimerStopped
;------------------------------------------
FUNCTION 3UltraDrv.UltraTimerStopped(Timer: INTEGER): BOOLEAN; 

This routine can be used to see if a timer is currently
being used.

The function returns FALSE if still running, TRUE if stopped.


 See also:

0                                                                       
90UltraStartTimer                                                        
92UltraStopTimer                                                         

;------------------------------------------
!TOPIC 96 UltraTrimJoystick
;------------------------------------------
PROCEDURE 3UltraDrv.UltraTrimJoystick(JoyVal: BYTE); 

This routine is used to set the speed compensation value
on the joystick port on the UltraSound.  The faster the
computer, the smaller this value should be.  This allows
all software that reads the joystick to return consistent
joystick positions regardless of the speed of the
machine.  This is normally not needed and probably should
never be used in your application.  The utility
ULTRAJOY.EXE which is included with all UltraSound stock
software is used to set this value up in your
AUTOEXEX.BAT file.

;------------------------------------------
!TOPIC 97 UltraUpLoad
;------------------------------------------
FUNCTION 3UltraDrv.UltraUpLoad(DataPtr: POINTER; Control: BYTE; DRAM_Loc: LONGINT; Len: WORD; Wait: BOOLEAN): BOOLEAN; 

This routine will retrieve a chunk of data from the
UltraSound's DRAM.  It will transfer 'len' number of bytes to
DataPtr (in PC) from DRAM_loc (in UltraSound).  If 'Wait'
is TRUE, then it will wait until the transfer is
complete.  If 'Wait' is FALSE, it will return as soon as
transfer is started.

The function returns TRUE if transfer was successful.
If FALSE, check 30UltraErrorStr for the reason.


 See also:

0                                                                       
23DMA_Control_Bits                                                       
33UltraDownload                                                          
0UltraDRAMDMAWait                                                       

;------------------------------------------
!TOPIC 98 UltraVectorVolume
;------------------------------------------
PROCEDURE 3UltraDrv.UltraVectorVolume(Voice: INTEGER; VEnd: WORD; VRate: BYTE; VMode: BYTE); 

This routine can be used to ramp from an unknown volume
value to a new value.  It is useful if you are doing
volume envelopes and need to restart the attack/decay
sequence at any time.

 See also:

0                                                                       
75UltraRampVolume                                                        
94UltraStopVolume                                                        

;------------------------------------------
!TOPIC 99 UltraVersion
;------------------------------------------
PROCEDURE 3UltraDrv.UltraVersion(VAR Major: BYTE; VAR Minor: BYTE); 

This routine can be useful to track the version of the
SDK that was used in compiling your source code.

The function returns Major (1 digit) and minor (2 digits)
version of the unit.


 See also:

100UltraVersionStr                                                        

;------------------------------------------
!TOPIC 100 UltraVersionStr
;------------------------------------------
FUNCTION 3UltraDrv.UltraVersionStr: STRING; 

This routine can be useful to track the version of the
SDK that was used in compiling your source code.

The function returns Major and minor version of the unit,
in string format.


 See also:

99UltraVersion                                                           

;------------------------------------------
!TOPIC 101 UltraVoiceStopped
;------------------------------------------
FUNCTION 3UltraDrv.UltraVoiceStopped(Voice: INTEGER): BOOLEAN; 

This routine can be used to see if a sample has finished
playing .

The function returns TRUE if the voice is stopped, FALSE otherwise.

;------------------------------------------
!TOPIC 102 UltraVolumeStopped
;------------------------------------------
FUNCTION 3UltraDrv.UltraVolumeStopped(Voice: INTEGER): BOOLEAN; 

This routine is used to determine the current state of
the volume of the voice.  It can be used to see if a
volume ramp is still running.

The function returns TRUE if no volume ramp is running, FALSE otherwise.


 See also:

0                                                                       
109UltraRampLinearVolume                                                  
75UltraRampVolume                                                        

;------------------------------------------
!TOPIC 103 UltraWaitDRAMDMA
;------------------------------------------
PROCEDURE 3UltraDrv.UltraWaitDRAMDMA; 

If a DMA transfer to/from DRAM is started but told not
to wait for it to complete, this routine can be used to
wait until it has completed.

 See also:

0                                                                       
33UltraDownload                                                          
97UltraUpload                                                            

;------------------------------------------
!TOPIC 104 UltraWaitRecordDMA
;------------------------------------------
PROCEDURE 3UltraDrv.UltraWaitRecordDMA; 

This can be used to let an application wait until a
complete sample is finished being acquired.

 See also:

79UltraRecordData                                                        

;------------------------------------------
!TOPIC 105 UltraVoiceOff
;------------------------------------------
PROCEDURE 3UltraDrv.UltraVoiceOff(Voice: INTEGER; VEnd: BOOLEAN); 

This routine will either stop a voice immediately or let
it finish its current loop.  If 'VEnd' is FALSE then it
will stop abruptly, otherwise it will finish the current
loop.  77UltraReadVoice could be called afterwards if you
need to know where the loop finished.
If used with 87UltraSetVoiceEnd, you could implement a
sampled decay on the end of your sample.  This would
occur if your loop point was not at the end of your data,
and you changed the end point to the real end point of
your data and then called this routine with VEnd set to
TRUE.

 See also:

0                                                                       
77UltraReadVoice                                                         
87UltraSetVoiceEnd                                                       

;------------------------------------------
!TOPIC 106 UltraVoiceOn
;------------------------------------------
PROCEDURE 3UltraDrv.UltraVoiceOn(Voice: INTEGER; VBegin: LONGINT; Start_Loop: LONGINT; End_Loop: LONGINT; Control: BYTE; Freq: LONGINT); 

This routine just sets the frequency with
83UltraSetFrequency and then calls 91UltraStartVoice.

 See also:

0                                                                       
83UltraSetFrequency                                                      
91UltraStartVoice                                                        

;------------------------------------------
!TOPIC 107 UltraSetLinearVolume
;------------------------------------------
PROCEDURE 3UltraDrv.UltraSetLinearVolume(Voice: INTEGER; Index: INTEGER); 

This routine indexes into a table to translate a linear
volume (0-511) to a logarithmic one (0-4095), and then
calls 88UltraSetVolume.

 See also:

88UltraSetVolume                                                         

;------------------------------------------
!TOPIC 108 UltraReadLinearVolume
;------------------------------------------
FUNCTION 3UltraDrv.UltraReadLinearVolume(Voice: INTEGER): INTEGER; 

This routine indexes into a table to translate a 0-4095
logarithmic volume to a 0-511 linear volume.

The function returns Linear Volume Value (0-511).


 See also:

0                                                                       
107UltraSetLinearVolume                                                   
88UltraSetVolume                                                         

;------------------------------------------
!TOPIC 109 UltraRampLinearVolume
;------------------------------------------
PROCEDURE 3UltraDrv.UltraRampLinearVolume(Voice: INTEGER; Start_Idx: WORD; End_Idx: WORD; Msecs: LONGINT; VMode: BYTE); 

This routine is used to ramp between linear volume
settings.  It uses the same method as
107UltraSetLinearVolume to determine the actual volume
settings to use, and then calls 75UltraRampVolume.

 See also:

0                                                                       
75UltraRampVolume                                                        
107UltraSetLinearVolume                                                   

;------------------------------------------
!TOPIC 110 UltraVectorLinearVolume
;------------------------------------------
PROCEDURE 3UltraDrv.UltraVectorLinearVolume(Voice: INTEGER; End_Idx: WORD; VRate: BYTE; VMode: BYTE); 

This routine can be used to ramp from an unknown volume
to a new linear volume.  It is useful if you are doing
volume envelopes and need to restart the attack/decay
sequence at any time.  It can also produce a smoother
ramp from one volume to another, since arbitrarily
setting a volume that is far away from the current volume
can cause 'pops'.

 See also:

0                                                                       
108UltraReadLinearVolume                                                  
107UltraSetLinearVolume                                                   

;------------------------------------------
!TOPIC 111 UltraClearVoices
;------------------------------------------
PROCEDURE 3UltraDrv.UltraClearVoices; 

This routine will deallocate all previously allocated
voices.  It would be advisable to call this before using
either 112UltraAllocVoice or 113UltraFreeVoice.

 See also:

0                                                                       
112UltraAllocVoice                                                        
113UltraFreeVoice                                                         

;------------------------------------------
!TOPIC 112 UltraAllocVoice
;------------------------------------------
FUNCTION 3UltraDrv.UltraAllocVoice(VAR Voice_Num: INTEGER): BOOLEAN; 

This routine will return a voice for your application to
use.  If you supply a voice number, it will attempt to
allocate that particular voice.  If you pass a -1 for the
voice number, it will return the next free voice.  This
routine will only allocate voices up to the number of active
voices specified in the 68UltraOpen function.

The function returns TRUE if there was no problem
allocating the voice.  If FALSE, check 30UltraErrorStr
for the reason.


 See also:

0                                                                       
111UltraClearVoices                                                       
0UltraFreeVoices                                                        

;------------------------------------------
!TOPIC 113 UltraFreeVoice
;------------------------------------------
PROCEDURE 3UltraDrv.UltraFreeVoice(Voice_Num: INTEGER); 

This routine will free up a previously allocated voice.
This should be used when your application no longer needs
the voice so it can be re-allocated at another time.

 See also:

0                                                                       
112UltraAllocVoice                                                        
111UltraClearVoices                                                       

;------------------------------------------
!TOPIC 114 Focal_Point_3d
;------------------------------------------


Focal point 3-d sound

Three dimensional audio on the UltraSound is achieved by a
technique called binaural representation.  Basically, this means
that a mono sound is 'shaped' in such a way that when it is
presented to the right and left ears properly, the sound seems to
come from the proper place in space.  This technique is also
called convolution.  This is done thru algorithms developed by
Focal Point(tm) 3D Audio.  Focal Point has provided a utility
(called FP3D.EXE) to convert a mono sound file to a 3D file
capable of being played on an UltraSound.  The basic concept is
that the mono sound is processed in such a way that the file that
is output contains up to 6 tracks of sound.  When the sound is
played back, the volumes and balances are adjusted to make the
sound appear to originate from anywhere in the 3D space.  It is
possible to create files that only have 4 tracks and can therefore
only be positioned in 2 dimensions.  This may be adequate for many
applications and it will make the resultant file smaller.

There are 2 types of 3D sound that an application might want to
use.  The first is a sound effect.  This is a sound that can be
completely loaded into DRAM and played and positioned at any time.
It is used for things like gunshots, cars etc.  These can be
looped or non-looped.  The other type of sound is a sound track.
This is for a very long sound that cannot be loaded in DRAM all at
once.  The implementation of each of these methods is very
different.  A sound effect is implemented using a blocked data
format.  This means that each track's data is in a block of its
own.  A sound track uses interleaved data.  This means that all
the track's data is interleaved together.


 See also:

115ThreeD_data_format                                                       

;------------------------------------------
!TOPIC 115 ThreeD_data_format
;------------------------------------------



3-D file data formats:

A blocked file would look like this:

HEADER FFFFFRRRRRBBBBBLLLLLUUUUUDDDDD....

whereas an interleaved file would look like this:

HEADER FRBLUDFRBLUDFRBLUDFRBLUDFRBLUD...

where

F = Front Track
R = Right Track
B = Behind Track
L = Left Track
U = Up Track
D = Down Track

Both of these methods have their individual advantages and
disadvantages.  First, the interleaved method makes it very easy
to read in the data in a continuous stream since it will look the
same all the way through the file.  It is also faster to read 60K
of data once rather than 6 10K reads.  This makes it very useful
for a sound track.  However, one drawback is that it has a very
limited number of frequencies that it will run at.  The reason for
this is rather difficult to explain, but it pertains to getting
the UltraSound's voices to play every 4th (or 5th, etc) sample.
The UltraSound normally would interpolate between data points but
it can't do that here because the adjacent data points are not in
the same track.  If you want to run at 22050 Hz, then you need to
have only 28 active voices to accomplish this.  If you want to
play a track at 44100 Hz, you must have only 14 active voices.
Blocked data doesn't have this problem.  Since the data is NOT
interleaved, but in a block of contiguous DRAM, its frequency can
be adjusted to any value.  This is usually very useful for sound
effects (rev'ing engines etc).  Also, since the data is blocked,
each track's data can be allocated separately and can therefore be
up to 256K.  An interleaved file must fit into 1 256K bank since
we cannot play 16bit data across a 256K bank.  See the two example
3D programs provided (PLAY3D and PLAY3DI) for ideas on how to
implement 3D sound into you applications.


;------------------------------------------
!TOPIC 116 UltraAbsPosition3D
;------------------------------------------
PROCEDURE 3UltraDrv.UltraAbsPosition3D(VAR Sound: 10SOUND_3D; XPos: INTEGER; YPos: INTEGER; ZPos: INTEGER); 

This routine will position a sound using standard
cartesian coordinates.  The X position range is from -511
(left) to +511 (right).  The Y position is from -511
(below) to +511 (above).  The Z position is from -511
(behind) to +511 (ahead).  The X and Z positions determine
the azimuth position and Y determines the elevation.  The
distance away from the listener is determined using
trigonometry.  Once these are determined,
117UltraAngPosition3d is called.

If the distance is calculated to be greater than 511, it
is clipped to 511.  Also, if the distance is calculated to
be 0, no positioning is done since the origin is
undefined.  (i.e.  A sound cannot be generated INSIDE your
head (origin)).

 See also:

114Focal_Point_3d                                                         
117UltraAngPosition3d                                                     

;------------------------------------------
!TOPIC 117 UltraAngPosition3D
;------------------------------------------
PROCEDURE 3UltraDrv.UltraAngPosition3D(VAR Sound: 10SOUND_3D; AZIMuth: INTEGER; Elevation: INTEGER; Vol_Dist: INTEGER); 

This routine will position a 3D sound using polar
coordinates.  The azimuth and elevation are specified in
degrees.  Azimuth is the angle in the horizontal plane.
Straight ahead is 0 degrees, 90 degrees is to the right,
-90 degrees is to the left and 180 (or -180) is directly
behind you.  If an angle larger than 180 or smaller that -
180 is specified, it is converted to its -180 to 180
equivalent.  For example, 270 degrees is equivalent to -90
degrees.  Elevation is the angle of elevation above or
below the horizontal plane.  0 degrees is no elevation, 90
degrees is straight up, and -90 is straight down.  Any
angle larger than 90 or smaller that -90 is ignored.

If more precision is needed, use 118UltraAngFltPosition3D so
that floating point arithmetic is used.  Since that
routine uses floating point functions (slow), your
application may not want to use it.

 See also:

114Focal_Point_3d                                                         
116UltraAbsPosition3d                                                     

;------------------------------------------
!TOPIC 118 UltraAngFltPosition3D
;------------------------------------------
PROCEDURE 3UltraDrv.UltraAngFltPosition3D(VAR Sound: 10SOUND_3D; AZIMuth: DOUBLE; Elevation: DOUBLE; Vol_Dist: INTEGER); 

This routine will position a 3D sound using polar
coordinates.  The azimuth and elevation are specified as
floating point numbers in degrees.  For example, 45 and
one half degrees would be specified as 45.5.  Azimuth is
the angle in the horizontal plane.  Straight ahead is 0
degrees, 90 degrees is to the right, -90 degrees is to
the left and 180 (or -180) is directly behind you.  If an
angle larger than 180 or smaller that -180 is specified,
it is converted to its -180 to 180 equivalent.  For
example, 270 degrees is equivalent to -90 degrees.
Elevation is the angle above or below the horizontal
plane.  0 degrees is no elevation, 90 degrees is straight
up, and -90 is straight down.  Any angle larger than 90 or
smaller that -90 is ignored.

If your application does not need to use the floating
point routine, it is advisable to use UltraAngPosition
because it avoids using some floating-point functions
(which are slow).

 See also:

114Focal_Point_3d                                                         

;------------------------------------------
!TOPIC 119 UltraCloseDup3D
;------------------------------------------
PROCEDURE 3UltraDrv.UltraCloseDup3D(VAR Sound: 10SOUND_3D); 

This routine must be used to free up the resources
associated with a duplicated 3d effect.  This routine will
only release the voices used by the duplicated effect,
not the DRAM allocated by the original effect.  The
original effect should be closed with
127UltraUnLoad3dEffect.

 See also:

0                                                                       
114Focal_Point_3d                                                         
120UltraDup3d                                                             
127UltraUnLoad3DEffect                                                    

;------------------------------------------
!TOPIC 120 UltraDup3D
;------------------------------------------
FUNCTION 3UltraDrv.UltraDup3D(VAR Current: 10SOUND_3D; VAR Sound: 10SOUND_3D): BOOLEAN; 

This routine is very useful if you want to use the same
sound effect in multiple places at once.  This allows you
to use the same DRAM data and just allocate some more
voices to move the sound.  This helps to save DRAM space.
Make sure that you use 119UltraCloseDup3d to free the
voices, NOT 127UltraUnLoad3dEffect - that will
release all the DRAM for the sound.  This new effect can
be passed to any other routines the same way the original
effect is.

The function returns TRUE if duplication successful.
If FALSE, check 30UltraErrorStr for the reason.


 See also:

114Focal_Point_3d                                                         
119UltraCloseDup3d                                                        

;------------------------------------------
!TOPIC 121 UltraLoad3DEffect
;------------------------------------------
FUNCTION 3UltraDrv.UltraLoad3DEffect(VAR Sound: 10SOUND_3D; VAR FileName: STRING; PC_Buffer: POINTER; Size: WORD): BOOLEAN; 

This routine is used to load a 3D sound into the DRAM on
the UltraSound.  It will allocate all necessary resources
so that 125UltraStart3D can be called later.  As many buffers
of DRAM as needed will be allocated along with the proper
number of voices.  These resources will be freed up when
you call 127UltraUnLoad3dEffect.  The file specified MUST be
a properly formatted or the routine will fail.  This means
that it must have the proper header and 3D data in it.
The 'pc_buffer' is a buffer supplied by your application
for this routine's use to download data into the
UltraSound.  The 'size' parameter is the size of the
'pc_buffer'.  The larger this buffer is, the faster it
will download.

The function returns TRUE if the file could be loaded.
If FALSE check 30UltraErrorStr for the reason.


 See also:

0                                                                       
0                                                                       
114Focal_Point_3d                                                         
33UltraDownload                                                          
58UltraMemAlloc                                                          
0UltraVoiceAlloc                                                        

;------------------------------------------
!TOPIC 122 UltraSetFreq3D
;------------------------------------------
FUNCTION 3UltraDrv.UltraSetFreq3D(VAR Sound: 10SOUND_3D; Frequency: LONGINT): BOOLEAN; 

This routine will allow you to alter the frequency that
the 3D sound is using.  This allows you to do pitch
shifting to get a doppler shift type effect.  This routine
can only be done on blocked data.

The function returns TRUE if the frequency was changed ok.
If FALSE, check 30UltraErrorStr for the reason.


 See also:

114Focal_Point_3d                                                         

;------------------------------------------
!TOPIC 123 UltraRelease3DInterleave
;------------------------------------------
PROCEDURE 3UltraDrv.UltraRelease3DInterleave(VAR Sound: 10SOUND_3D); 

This routines will release the DRAM and voices allocated
for an interleaved sound track.

 See also:

114Focal_Point_3d                                                         
124UltraSetup3dInterleave                                                 

;------------------------------------------
!TOPIC 124 UltraSetup3DInterleave
;------------------------------------------
FUNCTION 3UltraDrv.UltraSetup3DInterleave(VAR Sound: 10SOUND_3D; VAR FileName: STRING; Size: LONGINT): BOOLEAN; 

This routine will allocate the voices and memory
necessary to play back an interleaved 3D sound.  It will
NOT load any of the file data into DRAM.  Your application
is responsible for that.  It will open the file, read the
header, allocate the appropriate resources, and set up
the begin, start and end loop points for each voice.
Since the sound is interleaved, the loop points are
staggared appropriately.

The function returns TRUE if the file could be read successfully.
If FALSE, check 30UltraErrorStr for the reason.


 See also:

114Focal_Point_3d                                                         
121UltraLoad3dEffect                                                      

;------------------------------------------
!TOPIC 125 UltraStart3D
;------------------------------------------
PROCEDURE 3UltraDrv.UltraStart3D(VAR Sound: 10SOUND_3D); 

This routine will start a 3D sound.  If you want it to
begin at a specific point in space, be sure that you
position it first.  It is not necessary to stop the sound
before starting it again.

 See also:

114Focal_Point_3d                                                         
125UltraStart3d                                                           

;------------------------------------------
!TOPIC 126 UltraStop3D
;------------------------------------------
PROCEDURE 3UltraDrv.UltraStop3D(VAR Sound: 10SOUND_3D; Abruptly: BOOLEAN); 

This routine will stop a 3D sound.  There are two ways to
stop a sound: if the 'abruptly' flag is TRUE, then the
sound will shut off immediately; if it is FALSE, then the
sound will be ramped down very quickly.  The second method
will give a smoother transition.

 See also:

114Focal_Point_3d                                                         

;------------------------------------------
!TOPIC 127 UltraUnLoad3DEffect
;------------------------------------------
PROCEDURE 3UltraDrv.UltraUnLoad3DEffect(VAR Sound: 10SOUND_3D); 

This routine is used to free up all the resources
(voices & DRAM) that a 3D sound uses.  Since a 3D sound
can use a lot of the voices & DRAM, you should free up
the resources you can.

 See also:

114Focal_Point_3d                                                         
121UltraLoad3dEffect                                                      


