3 * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___
4 * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\
5 * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \
6 * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/
7 * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/
12 * Stub GUS driver. This is just a placeholder: the real code isn't
18 #error This file should only be used by the djgpp version of Allegro
28 static char gus_desc[80] = "not initialised";
30 static int gus_detect();
32 static int gus_digi_init();
33 static void gus_digi_exit();
36 DIGI_DRIVER digi_gus = /* GUS driver for playing digital sfx */
40 0, 0, MIXER_MAX_SFX, MIXER_DEF_SFX,
70 static int gus_midi_init();
71 static void gus_midi_exit();
72 static int gus_load_patches(char *patches, char *drums);
73 static void gus_key_on(int inst, int note, int bend, int vol, int pan);
74 static void gus_key_off(int voice);
75 static void gus_set_volume(int voice, int vol);
76 static void gus_set_pitch(int voice, int note, int bend);
79 MIDI_DRIVER midi_gus = /* GUS driver for playing MIDI music */
90 _dummy_adjust_patches,
100 static void gus_lock_data();
105 * GUS detection routine. Returns TRUE if a GUS exists, otherwise FALSE.
106 * It shouldn't do anything that drastically alters the state of the
107 * card, since it is likely to get called more than once.
109 static int gus_detect()
111 strcpy(allegro_error, "GUS driver not written yet");
113 /* if (no GUS present) */
116 sprintf(gus_desc, "Some info about the GUS hardware");
123 * Called once at startup to initialise the digital sample playing code.
125 static int gus_digi_init()
129 #if GOT_SOME_GUS_CODE_TO_PUT_IN_HERE
130 /* Allocate conventional memory buffers for the DMA transfer. Pass the
131 * size of the buffer in bytes, an int pointer which will be set to the
132 * protected mode selector to free the buffer with, and a pointer to a
133 * long which will be set to the linear address of the buffer in
134 * conventional memory.
136 if (_dma_allocate_mem(buffer_size, &(int)selector, &(long)address) != 0)
139 /* Initialise the sample mixing module. Pass the size of each buffer
140 * (in samples, not bytes: if you pass 1024 for this parameter you would
141 * need a _dma_allocate_mem of 1024 bytes if you are using 8 bit data, but
142 * of 2048 if in 16 bit mode. Don't double the size for stereo modes
143 * though: in an 8 bit stereo mode passing 1024 will still cause it to
144 * mix 1024 bytes into each buffer, just the buffer will only last for
145 * half as long...). Also pass the sample frequency the GUS is running at,
146 * and whether you want stereo and/or 16 bit data.
148 if (_mixer_init(buffer_size, gus_frequency, stereo, 16bit) != 0)
152 Apart from those calls, do whatever GUS-type stuff you need to do, set
153 the dma transfer going (_dma_start(channel, addr, size, auto_init_flag)),
154 and whenever a buffer needs filling with some more samples, call
155 _mix_some_samples(linear_address_of_buffer_in_conventional_memory);
156 btw. the 16 bit sample mixing and 16 bit DMA transfer modes are not
157 tested, since I only have an 8 bit SB. If they don't work, it might well
168 * gus driver cleanup routine, removes ints, stops dma, frees buffers, etc.
170 static void gus_digi_exit()
172 #if GOT_SOME_GUS_CODE_TO_PUT_IN_HERE
174 _dma_stop(whatever_dma_channel_you_are_using);
175 __dpmi_free_dos_memory(the selector returned by _dma_allocate_mem());
186 * Called once at startup to setup the GUS MIDI driver.
188 static int gus_midi_init()
200 * Cleanup the MIDI driver. I ought to have turned off all the active
201 * voices by the time this gets called, but it wouldn't hurt to reset
204 static void gus_midi_exit()
211 * Called before starting to play a MIDI file, to load all the patches it
212 * uses into GUS ram. No MIDI voices will be active when this is called,
213 * so you are free to unload whatever old data you want. Patches points
214 * to an array of 128 flags indicating which GM sounds are used in the
215 * piece, and drums to an array of 128 flags indicating which drum sounds
216 * are used (the GM standard only defines drum sounds 35 (base drum) to
217 * 81 (open triangle), so flags outside that range are guarranteed to be
218 * zero). Should return 0 for success, -1 on failure.
220 * What should we do if there isn't enough GUS ram to load all the samples?
221 * Return an error code and not play the midi file? Or replace some patches
222 * with others? And if so, should this routine do those replacements, or
223 * should you just return an error code to me, and me call you again with
224 * a reduced list of requirements? If we are going to do patch replacements,
225 * it would seem sensible to do it at a higher level than the GUS driver,
226 * so at a later date any other wavetable drivers could use the same code.
229 static int gus_load_patches(char *patches, char *drums)
234 static END_OF_FUNCTION(gus_load_patches);
239 * Triggers the specified MIDI voice. The instrument is specified as a
240 * GM patch number. Drums are indicated by passing an instrument greater
241 * than 128, in which case you should trigger the GM percussion sound
242 * normally mapped to drum key (inst-128). Drum sounds can ignore the
243 * pitch, bend, and pan parameters, but should respond to volume. The
244 * pitch is a midi note number (60=middle C, I think...). Pan and
245 * volume are from 0 (left/min) to 127 (right/max). The bend isn't a midi
246 * pitch bend value: it ranges from 0 (normal pitch) to 0xFFF (just a
247 * fraction flatter than a semitone up).
249 static void gus_key_on(int inst, int note, int bend, int vol, int pan)
251 int voice = _midi_allocate_voice(-1, -1);
255 /* after you set the sample to play and trigger the note, this is pretty
256 * much equivelant to:
258 gus_set_pitch(voice, note, bend);
259 gus_set_volume(voice, vol);
262 static END_OF_FUNCTION(gus_key_on);
267 * Hey, guess what this does :-)
269 static void gus_key_off(int voice)
274 static END_OF_FUNCTION(gus_key_off);
279 * Alters the volume of the specified voice (vol range 0-127). Should only
280 * ever be called while the voice is playing...
282 static void gus_set_volume(int voice, int vol)
287 static END_OF_FUNCTION(gus_set_volume);
292 * Alters the pitch of the specified voice. Should only be called while
293 * the voice is playing...
295 static void gus_set_pitch(int voice, int note, int bend)
300 static END_OF_FUNCTION(gus_set_pitch);
305 * Locks all the memory touched by parts of the GUS code that are executed
306 * in an interrupt context.
308 static void gus_lock_data()
310 LOCK_VARIABLE(digi_gus);
311 LOCK_VARIABLE(midi_gus);
312 LOCK_FUNCTION(gus_load_patches);
313 LOCK_FUNCTION(gus_key_on);
314 LOCK_FUNCTION(gus_key_off);
315 LOCK_FUNCTION(gus_set_volume);
316 LOCK_FUNCTION(gus_set_pitch);