!WIDTH 78

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


3UltraDrv        

;------------------------------------------
!TOPIC 3 UltraDrv
;------------------------------------------
Unit UltraDrv (in 2MAKEHELP.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:

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

Types:

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

Variables:

27Ultra_Config             
28UltraOk                  
29UltraError               
30UltraErrorStr            

Functions and Procedures:

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

Other:

14Volume_Control_Bits      
18Voice_Control_Bits       
23DMA_Control_Bits         
114Focal_Point_3d           
115ThreeD_data_format       

;------------------------------------------
!TOPIC 4 PFV
;------------------------------------------
3UltraDrv.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:

54UltraAuxHandler                                                           
46UltraDRAMTcHandler                                                        
53UltraRecordHandler                                                        
49UltraTimer1Handler                                                        
50UltraTimer2Handler                                                        

;------------------------------------------
!TOPIC 5 INT_PROC
;------------------------------------------
3UltraDrv.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:

52UltraVolumeHandler                                                        
51UltraWaveHandler                                                          

;------------------------------------------
!TOPIC 6 WORD_PROC
;------------------------------------------
3UltraDrv.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:

47UltraMIDIXMitHandler                                                      

;------------------------------------------
!TOPIC 7 TWOWORD_PROC
;------------------------------------------
3UltraDrv.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:

48UltraMIDIRecvHandler                                                      

;------------------------------------------
!TOPIC 8 Ultra_CFG
;------------------------------------------
3UltraDrv.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
;------------------------------------------
3UltraDrv.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:

0SOUND-3D                                                              

;------------------------------------------
!TOPIC 10 SOUND_3D
;------------------------------------------
3UltraDrv.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:

9VOICE_DATA_3D                                                         

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


Common recording and playback frequency for sound and voice.

 See also:

83UltraSetFrequency                                                        

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


Common recording and playback frequency for misc sounds.

 See also:

83UltraSetFrequency                                                        

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


Common frequency for CD quality recording and playback. 

 See also:

83UltraSetFrequency                                                        

;------------------------------------------
!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 3UltraDrv.Loop_Volume = 08; 


 See also:

14Volume_Control_Bits  

;------------------------------------------
!TOPIC 16 Bi_Directional_Volume
;------------------------------------------
Const 3UltraDrv.Bi_Directional_Volume = 16; 


 See also:

14Volume_Control_Bits  

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


 See also:

14Volume_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 3UltraDrv.Voice_Data_16Bit = 04; 


 See also:

18Voice_Control_Bits   

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


 See also:

18Voice_Control_Bits   

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


 See also:

18Voice_Control_Bits   

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


 See also:

18Voice_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 3UltraDrv.DMA_Data_16Bit = 64; 


 See also:

23DMA_Control_Bits     

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


 See also:

23DMA_Control_Bits     

;------------------------------------------
!TOPIC 26 Ultra_Installed
;------------------------------------------
Const 3UltraDrv.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:

8Ultra_CFG                                                                

;------------------------------------------
!TOPIC 27 Ultra_Config
;------------------------------------------
3UltraDrv.Ultra_Config: 8Ultra_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
68UltraOpen.


 See also:

8Ultra_CFG                                                               

;------------------------------------------
!TOPIC 28 UltraOk
;------------------------------------------
3UltraDrv.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:

29UltraError                                                              
30UltraErrorStr                                                           

;------------------------------------------
!TOPIC 29 UltraError
;------------------------------------------
3UltraDrv.UltraError: INTEGER; 

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

 See also:

30UltraErrorStr                                                           
28UltraOk                                                                 

;------------------------------------------
!TOPIC 30 UltraErrorStr
;------------------------------------------
3UltraDrv.UltraErrorStr: STRING; 

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

 See also:

29UltraError                                                              
28UltraOk                                                                 

;------------------------------------------
!TOPIC 31 UltraCalcRate
;------------------------------------------
FUNCTION 3UltraDrv.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 75UltraRampVolume.  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
75UltraRampVolume or 109UltraRampLinearVolume.

 See also:

109UltraRampLinearVolume                                                  
75UltraRampVolume                                                        

;------------------------------------------
!TOPIC 32 UltraClose
;------------------------------------------
FUNCTION 3UltraDrv.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:

68UltraOpen                                                              
81UltraReset                                                             

;------------------------------------------
!TOPIC 33 UltraDownLoad
;------------------------------------------
FUNCTION 3UltraDrv.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 30UltraErrorStr for the
reason.
#M

 See also:

23DMA_Control_Bits                                                       
34UltraDRAMDMABusy                                                       
97UltraUpload                                                            

;------------------------------------------
!TOPIC 34 UltraDRAMDMABusy
;------------------------------------------
FUNCTION 3UltraDrv.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                                                                       
33UltraDownload                                                          
97UltraUpload                                                            
103UltraWaitDRAMDMA                                                       

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

This routine will start up a pre-primed record (done
with 72UltraPrimeRecord).  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 30UltraErrorStr for the reason.


 See also:

0                                                                       
0                                                                       
72UltraPrimeRecord                                                       
79UltraRecordData                                                        
53UltraRecordHandler                                                     

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

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

 See also:

0                                                                       
73UltraPrimeVoice                                                        
91UltraStartVoice                                                        

;------------------------------------------
!TOPIC 37 UltraDisableLineIn
;------------------------------------------
PROCEDURE 3UltraDrv.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                                                                       
40UltraEnableLineIn                                                      
43UltraGetLineIn                                                         

;------------------------------------------
!TOPIC 38 UltraDisableMicIn
;------------------------------------------
PROCEDURE 3UltraDrv.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                                                                       
41UltraEnableMicIn                                                       
44UltraGetMicIn                                                          

;------------------------------------------
!TOPIC 39 UltraDisableOutput
;------------------------------------------
PROCEDURE 3UltraDrv.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                                                                       
42UltraEnableOutput                                                      
45UltraGetOutput                                                         

;------------------------------------------
!TOPIC 40 UltraEnableLineIn
;------------------------------------------
PROCEDURE 3UltraDrv.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                                                                       
37UltraDisableLineIn                                                     
43UltraGetLineIn                                                         

;------------------------------------------
!TOPIC 41 UltraEnableMicIn
;------------------------------------------
PROCEDURE 3UltraDrv.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                                                                       
38UltraDisableMicIn                                                      
44UltraGetMicIn                                                          

;------------------------------------------
!TOPIC 42 UltraEnableOutput
;------------------------------------------
PROCEDURE 3UltraDrv.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 39UltraDisableOutput.

 See also:

0                                                                       
39UltraDisableOutput                                                     
45UltraGetOutput                                                         

;------------------------------------------
!TOPIC 43 UltraGetLineIn
;------------------------------------------
FUNCTION 3UltraDrv.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                                                                       
37UltraDisableLineIn                                                     
40UltraEnableLineIn                                                      

;------------------------------------------
!TOPIC 44 UltraGetMicIn
;------------------------------------------
FUNCTION 3UltraDrv.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                                                                       
38UltraDisableMicIn                                                      
41UltraEnableMicIn                                                       

;------------------------------------------
!TOPIC 45 UltraGetOutput
;------------------------------------------
FUNCTION 3UltraDrv.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                                                                       
39UltraDisableOutput                                                     
42UltraEnableOutput                                                      

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

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:

4PFV                                                                    

;------------------------------------------
!TOPIC 47 UltraMIDIXMitHandler
;------------------------------------------
PROCEDURE 3UltraDrv.UltraMIDIXMitHandler(VAR Handler: 6WORD_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                                                                       
48UltraMIDIRecvHandler                                                   
6WORD_PROC                                                              

;------------------------------------------
!TOPIC 48 UltraMIDIRecvHandler
;------------------------------------------
PROCEDURE 3UltraDrv.UltraMIDIRecvHandler(VAR Handler: 7TWOWORD_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                                                                       
7TWOWORD_PROC                                                           
47UltraMIDIXmitHandler                                                   

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

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                                                                       
4PFV                                                                    
90UltraStartTimer                                                        
50UltraTimer2Handler                                                     

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

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                                                                       
4PFV                                                                    
90UltraStartTimer                                                        
49UltraTimer1Handler                                                     

;------------------------------------------
!TOPIC 51 UltraWaveHandler
;------------------------------------------
PROCEDURE 3UltraDrv.UltraWaveHandler(VAR Handler: 5INT_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                                                                       
5INT_PROC                                                               

;------------------------------------------
!TOPIC 52 UltraVolumeHandler
;------------------------------------------
PROCEDURE 3UltraDrv.UltraVolumeHandler(VAR Handler: 5INT_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:

4PFV                                                                    

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

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:

4PFV                                                                    

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

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                                                                       
4PFV                                                                    

;------------------------------------------
!TOPIC 55 UltraMaxAvail
;------------------------------------------
FUNCTION 3UltraDrv.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                                                                       
58UltraMemAlloc                                                          
57UltraMemAvail                                                          
59UltraMemFree                                                           

;------------------------------------------
!TOPIC 56 UltraMaxAlloc
;------------------------------------------
FUNCTION 3UltraDrv.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                                                                       
55UltraMaxAvail                                                          
58UltraMemAlloc                                                          
57UltraMemAvail                                                          
59UltraMemFree                                                           

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

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

 See also:

0                                                                       
56UltraMaxAlloc                                                          
55UltraMaxAvail                                                          
58UltraMemAlloc                                                          
59UltraMemFree                                                           

;------------------------------------------
!TOPIC 58 UltraMemAlloc
;------------------------------------------
FUNCTION 3UltraDrv.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 68UltraOpen.  '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 30UltraErrorStr for the reason.


 See also:

0                                                                       
56UltraMaxAlloc                                                          
55UltraMaxAvail                                                          
57UltraMemAvail                                                          
59UltraMemFree                                                           

;------------------------------------------
!TOPIC 59 UltraMemFree
;------------------------------------------
FUNCTION 3UltraDrv.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 30UltraErrorStr for the reason.


 See also:

0                                                                       
55UltraMaxAvail                                                          
58UltraMemAlloc                                                          
57UltraMemAvail                                                          
0UltraMemInit                                                           

;------------------------------------------
!TOPIC 60 UltraMIDIDisableRecv
;------------------------------------------
PROCEDURE 3UltraDrv.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                                                                       
62UltraMIDIEnableRecv                                                    
48UltraMIDIRecvHandler                                                   

;------------------------------------------
!TOPIC 61 UltraMIDIDisableXmit
;------------------------------------------
PROCEDURE 3UltraDrv.UltraMIDIDisableXmit; 

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

 See also:

0                                                                       
63UltraMIDIEnableXmit                                                    
47UltraMIDIXmitHandler                                                   

;------------------------------------------
!TOPIC 62 UltraMIDIEnableRecv
;------------------------------------------
PROCEDURE 3UltraDrv.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                                                                       
60UltraMIDIDisableRecv                                                   
48UltraMIDIRecvhandler                                                   

;------------------------------------------
!TOPIC 63 UltraMIDIEnableXmit
;------------------------------------------
PROCEDURE 3UltraDrv.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                                                                       
61UltraMIDIDisableXmit                                                   
47UltraMIDIXmitHandler                                                   

;------------------------------------------
!TOPIC 64 UltraMIDIRecv
;------------------------------------------
FUNCTION 3UltraDrv.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                                                                       
48UltraMIDIRecvHandler                                                   
66UltraMIDIStatus                                                        

;------------------------------------------
!TOPIC 65 UltraMIDIReset
;------------------------------------------
PROCEDURE 3UltraDrv.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                                                                       
0UltraEnableMIDIRecv                                                    
0UltraEnableMIDIXmit                                                    

;------------------------------------------
!TOPIC 66 UltraMIDIStatus
;------------------------------------------
FUNCTION 3UltraDrv.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                                                                       
64UltraMIDIRecv                                                          
67UltraMIDIXmit                                                          

;------------------------------------------
!TOPIC 67 UltraMIDIXmit
;------------------------------------------
PROCEDURE 3UltraDrv.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:

47UltraMIDIXmitHandler                                                   

;------------------------------------------
!TOPIC 68 UltraOpen
;------------------------------------------
FUNCTION 3UltraDrv.UltraOpen(VAR Config: 8Ultra_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 30UltraErrorStr for the reason.


 See also:

0                                                                       
32UltraClose                                                             
74UltraProbe                                                             

;------------------------------------------
!TOPIC 69 UltraPeekData
;------------------------------------------
FUNCTION 3UltraDrv.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                                                                       
71UltraPokeData                                                          
97UltraUpload                                                            

;------------------------------------------
!TOPIC 70 UltraPing
;------------------------------------------
FUNCTION 3UltraDrv.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.  74UltraProbe pulls a quick reset and
then calls 70UltraPing.

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


 See also:

74UltraProbe                                                             

;------------------------------------------
!TOPIC 71 UltraPokeData
;------------------------------------------
PROCEDURE 3UltraDrv.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                                                                       
33UltraDownload                                                          
69UltraPeekData                                                          

;------------------------------------------
!TOPIC 72 UltraPrimeRecord
;------------------------------------------
FUNCTION 3UltraDrv.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 30UltraErrorStr for the reason.


 See also:

35UltraGoRecord                                                          

;------------------------------------------
!TOPIC 73 UltraPrimeVoice
;------------------------------------------
FUNCTION 3UltraDrv.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 73UltraPrimeVoice to do all the necessary setup
and then use 36UltraGoVoice to start the voices.
91UltraStartVoice calls 73UltraPrimeVoice and then
immediately 36UltraGoVoice.

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 36UltraGoVoice.


 See also:

0                                                                       
36UltraGoVoice                                                           
91UltraStartVoice                                                        

;------------------------------------------
!TOPIC 74 UltraProbe
;------------------------------------------
FUNCTION 3UltraDrv.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 68UltraOpen to see if a card is
present.  68UltraOpen calls this routine also.  The
difference between 74UltraProbe and 70UltraPing is that
74UltraProbe will pull a reset to make sure the board is
running.  70UltraPing assumes this has already been done.

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


 See also:

0                                                                       
68UltraOpen                                                              
70UltraPing                                                              

;------------------------------------------
!TOPIC 75 UltraRampVolume
;------------------------------------------
PROCEDURE 3UltraDrv.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 31UltraCalcRate.  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
52UltraVolumeHandler.

 See also:

0                                                                       
31UltraCalcRate                                                          
52UltraVolumeHandler                                                     
14Volume_Control_Bits                                                    

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

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

The function returns Number of BYTES recorded so far.


 See also:

79UltraRecordData                                                        

;------------------------------------------
!TOPIC 77 UltraReadVoice
;------------------------------------------
FUNCTION 3UltraDrv.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:

86UltraSetVoice                                                          

;------------------------------------------
!TOPIC 78 UltraReadVolume
;------------------------------------------
FUNCTION 3UltraDrv.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 108UltraReadLinearVolume.

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


 See also:

0                                                                       
75UltraRampVolume                                                        
88UltraSetVolume                                                         

;------------------------------------------
!TOPIC 79 UltraRecordData
;------------------------------------------
FUNCTION 3UltraDrv.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 (35UltraGoRecord).  This will be very
quick since the PC DMA controller will not be re-
programmed.

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


 See also:

0                                                                       
35UltraGoRecord                                                          
85UltraSetRecordFrequency                                                
104UltraWaitRecordDMA                                                     

;------------------------------------------
!TOPIC 80 UltraRecordDMABusy
;------------------------------------------
FUNCTION 3UltraDrv.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:

79UltraRecordData                                                        

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

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

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


 See also:

0                                                                       
32UltraClose                                                             
68UltraOpen                                                              

;------------------------------------------
!TOPIC 82 UltraSetBalance
;------------------------------------------
PROCEDURE 3UltraDrv.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 3UltraDrv.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 3UltraDrv.UltraSetLoopMode(Voice: INTEGER; VMode: BYTE); 

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

 See also:

18Voice_Control_Bits                                                     

;------------------------------------------
!TOPIC 85 UltraSetRecordFrequency
;------------------------------------------
PROCEDURE 3UltraDrv.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 3UltraDrv.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 3UltraDrv.UltraSetVoiceEnd(Voice: INTEGER; VEnd: LONGINT); 

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

 See also:

84UltraSetLoopMode                                                       

;------------------------------------------
!TOPIC 88 UltraSetVolume
;------------------------------------------
PROCEDURE 3UltraDrv.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
107UltraSetLinearVolume to do linear volumes.

 See also:

107UltraSetLinearVolume                                                   

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

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

The function returns number of kilobytes found on the UltraSound.


 See also:

0UltraMemInit                                                           

;------------------------------------------
!TOPIC 90 UltraStartTimer
;------------------------------------------
PROCEDURE 3UltraDrv.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
92UltraStopTimer 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                                                                       
92UltraStopTimer                                                         
49UltraTimer1Handler                                                     
50UltraTimer2Handler                                                     
95UltraTimerStopped                                                      

;------------------------------------------
!TOPIC 91 UltraStartVoice
;------------------------------------------
PROCEDURE 3UltraDrv.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                                                                       
0UltraLoopMode                                                          
0UltraSetEnd                                                            
18Voice_Control_Bits                                                     

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

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

 See also:

90UltraStartTimer                                                        

;------------------------------------------
!TOPIC 93 UltraStopVoice
;------------------------------------------
PROCEDURE 3UltraDrv.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                                                                       
87UltraSetVoiceEnd                                                       
91UltraStartVoice                                                        

;------------------------------------------
!TOPIC 94 UltraStopVolume
;------------------------------------------
PROCEDURE 3UltraDrv.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                                                                       
109UltraRampLinearVolume                                                  
75UltraRampVolume                                                        

;------------------------------------------
!TOPIC 95 UltraTimerStopped
;------------------------------------------
FUNCTION 3UltraDrv.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                                                                       
90UltraStartTimer                                                        
92UltraStopTimer                                                         

;------------------------------------------
!TOPIC 96 UltraTrimJoystick
;------------------------------------------
PROCEDURE 3UltraDrv.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 3UltraDrv.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 30UltraErrorStr for the reason.


 See also:

0                                                                       
23DMA_Control_Bits                                                       
33UltraDownload                                                          
0UltraDRAMDMAWait                                                       

;------------------------------------------
!TOPIC 98 UltraVectorVolume
;------------------------------------------
PROCEDURE 3UltraDrv.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                                                                       
75UltraRampVolume                                                        
94UltraStopVolume                                                        

;------------------------------------------
!TOPIC 99 UltraVersion
;------------------------------------------
PROCEDURE 3UltraDrv.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:

100UltraVersionStr                                                        

;------------------------------------------
!TOPIC 100 UltraVersionStr
;------------------------------------------
FUNCTION 3UltraDrv.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:

99UltraVersion                                                           

;------------------------------------------
!TOPIC 101 UltraVoiceStopped
;------------------------------------------
FUNCTION 3UltraDrv.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 3UltraDrv.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                                                                       
109UltraRampLinearVolume                                                  
75UltraRampVolume                                                        

;------------------------------------------
!TOPIC 103 UltraWaitDRAMDMA
;------------------------------------------
PROCEDURE 3UltraDrv.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                                                                       
33UltraDownload                                                          
97UltraUpload                                                            

;------------------------------------------
!TOPIC 104 UltraWaitRecordDMA
;------------------------------------------
PROCEDURE 3UltraDrv.UltraWaitRecordDMA; 

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

 See also:

79UltraRecordData                                                        

;------------------------------------------
!TOPIC 105 UltraVoiceOff
;------------------------------------------
PROCEDURE 3UltraDrv.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.  77UltraReadVoice could be called afterwards if you
need to know where the loop finished.
If used with 87UltraSetVoiceEnd, 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                                                                       
77UltraReadVoice                                                         
87UltraSetVoiceEnd                                                       

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

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

 See also:

0                                                                       
83UltraSetFrequency                                                      
91UltraStartVoice                                                        

;------------------------------------------
!TOPIC 107 UltraSetLinearVolume
;------------------------------------------
PROCEDURE 3UltraDrv.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 88UltraSetVolume.

 See also:

88UltraSetVolume                                                         

;------------------------------------------
!TOPIC 108 UltraReadLinearVolume
;------------------------------------------
FUNCTION 3UltraDrv.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                                                                       
107UltraSetLinearVolume                                                   
88UltraSetVolume                                                         

;------------------------------------------
!TOPIC 109 UltraRampLinearVolume
;------------------------------------------
PROCEDURE 3UltraDrv.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
107UltraSetLinearVolume to determine the actual volume
settings to use, and then calls 75UltraRampVolume.

 See also:

0                                                                       
75UltraRampVolume                                                        
107UltraSetLinearVolume                                                   

;------------------------------------------
!TOPIC 110 UltraVectorLinearVolume
;------------------------------------------
PROCEDURE 3UltraDrv.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                                                                       
108UltraReadLinearVolume                                                  
107UltraSetLinearVolume                                                   

;------------------------------------------
!TOPIC 111 UltraClearVoices
;------------------------------------------
PROCEDURE 3UltraDrv.UltraClearVoices; 

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

 See also:

0                                                                       
112UltraAllocVoice                                                        
113UltraFreeVoice                                                         

;------------------------------------------
!TOPIC 112 UltraAllocVoice
;------------------------------------------
FUNCTION 3UltraDrv.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 68UltraOpen function.

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


 See also:

0                                                                       
111UltraClearVoices                                                       
0UltraFreeVoices                                                        

;------------------------------------------
!TOPIC 113 UltraFreeVoice
;------------------------------------------
PROCEDURE 3UltraDrv.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                                                                       
112UltraAllocVoice                                                        
111UltraClearVoices                                                       

;------------------------------------------
!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:

115ThreeD_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 3UltraDrv.UltraAbsPosition3D(VAR Sound: 10SOUND_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,
117UltraAngPosition3d 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:

114Focal_Point_3d                                                         
117UltraAngPosition3d                                                     

;------------------------------------------
!TOPIC 117 UltraAngPosition3D
;------------------------------------------
PROCEDURE 3UltraDrv.UltraAngPosition3D(VAR Sound: 10SOUND_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 118UltraAngFltPosition3D 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:

114Focal_Point_3d                                                         
116UltraAbsPosition3d                                                     

;------------------------------------------
!TOPIC 118 UltraAngFltPosition3D
;------------------------------------------
PROCEDURE 3UltraDrv.UltraAngFltPosition3D(VAR Sound: 10SOUND_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:

114Focal_Point_3d                                                         

;------------------------------------------
!TOPIC 119 UltraCloseDup3D
;------------------------------------------
PROCEDURE 3UltraDrv.UltraCloseDup3D(VAR Sound: 10SOUND_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
127UltraUnLoad3dEffect.

 See also:

0                                                                       
114Focal_Point_3d                                                         
120UltraDup3d                                                             
127UltraUnLoad3DEffect                                                    

;------------------------------------------
!TOPIC 120 UltraDup3D
;------------------------------------------
FUNCTION 3UltraDrv.UltraDup3D(VAR Current: 10SOUND_3D; VAR Sound: 10SOUND_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 119UltraCloseDup3d to free the
voices, NOT 127UltraUnLoad3dEffect - 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 30UltraErrorStr for the reason.


 See also:

114Focal_Point_3d                                                         
119UltraCloseDup3d                                                        

;------------------------------------------
!TOPIC 121 UltraLoad3DEffect
;------------------------------------------
FUNCTION 3UltraDrv.UltraLoad3DEffect(VAR Sound: 10SOUND_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 125UltraStart3D 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 127UltraUnLoad3dEffect.  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 30UltraErrorStr for the reason.


 See also:

0                                                                       
0                                                                       
114Focal_Point_3d                                                         
33UltraDownload                                                          
58UltraMemAlloc                                                          
0UltraVoiceAlloc                                                        

;------------------------------------------
!TOPIC 122 UltraSetFreq3D
;------------------------------------------
FUNCTION 3UltraDrv.UltraSetFreq3D(VAR Sound: 10SOUND_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 30UltraErrorStr for the reason.


 See also:

114Focal_Point_3d                                                         

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

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

 See also:

114Focal_Point_3d                                                         
124UltraSetup3dInterleave                                                 

;------------------------------------------
!TOPIC 124 UltraSetup3DInterleave
;------------------------------------------
FUNCTION 3UltraDrv.UltraSetup3DInterleave(VAR Sound: 10SOUND_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 30UltraErrorStr for the reason.


 See also:

114Focal_Point_3d                                                         
121UltraLoad3dEffect                                                      

;------------------------------------------
!TOPIC 125 UltraStart3D
;------------------------------------------
PROCEDURE 3UltraDrv.UltraStart3D(VAR Sound: 10SOUND_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:

114Focal_Point_3d                                                         
125UltraStart3d                                                           

;------------------------------------------
!TOPIC 126 UltraStop3D
;------------------------------------------
PROCEDURE 3UltraDrv.UltraStop3D(VAR Sound: 10SOUND_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:

114Focal_Point_3d                                                         

;------------------------------------------
!TOPIC 127 UltraUnLoad3DEffect
;------------------------------------------
PROCEDURE 3UltraDrv.UltraUnLoad3DEffect(VAR Sound: 10SOUND_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:

114Focal_Point_3d                                                         
121UltraLoad3dEffect                                                      


