--- /dev/null
+diff -ur allegro-4.0.2/acconfig.h allegro-4.0.2.new/acconfig.h
+--- allegro-4.0.2/acconfig.h Sun Jun 16 21:22:15 2002
++++ allegro-4.0.2.new/acconfig.h Fri Jun 21 12:53:40 2002
+@@ -76,6 +76,12 @@
+ /* Define if ALSA MIDI driver is supported. */
+ #undef ALLEGRO_WITH_ALSAMIDI
+
++/* Define if ALSA9 DIGI driver is supported. */
++#undef ALLEGRO_WITH_ALSA9DIGI
++
++/* Define if ALSA9 MIDI driver is supported. */
++#undef ALLEGRO_WITH_ALSA9MIDI
++
+ /* Define if ESD DIGI driver is supported. */
+ #undef ALLEGRO_WITH_ESDDIGI
+
+diff -ur allegro-4.0.2/aclocal.m4 allegro-4.0.2.new/aclocal.m4
+--- allegro-4.0.2/aclocal.m4 Sun Jun 16 21:22:15 2002
++++ allegro-4.0.2.new/aclocal.m4 Fri Jun 21 14:23:44 2002
+@@ -366,6 +366,60 @@
+ fi])
+
+ dnl
++dnl Test for ALSA9 DIGI driver.
++dnl
++dnl Variables:
++dnl allegro_enable_alsa9digi=(yes|)
++dnl allegro_cv_support_alsa9digi=(yes|)
++dnl
++AC_DEFUN(ALLEGRO_ACTEST_ALSA9DIGI,
++[AC_ARG_ENABLE(alsa9digi,
++[ --enable-alsa9digi[=x] enable building ALSA9 DIGI driver [default=yes]],
++test "X$enableval" != "Xno" && allegro_enable_alsa9digi=yes,
++allegro_enable_alsa9digi=yes)
++
++if test -n "$allegro_enable_alsa9digi"; then
++ AC_CACHE_CHECK(for supported ALSA9 version for digital sound,
++ allegro_cv_support_alsa9digi,
++ AC_TRY_RUN([#include <alsa/asoundlib.h>
++ int main (void) { return SND_LIB_MAJOR != 0 || SND_LIB_MINOR != 9; }],
++ allegro_cv_support_alsa9digi=yes,
++ allegro_cv_support_alsa9digi=no,
++ allegro_cv_support_alsa9digi=no))
++ if test "X$allegro_cv_support_alsa9digi" = "Xyes" &&
++ test -z "$allegro_support_modules"; then
++ LIBS="-lasound $LIBS"
++ fi
++fi])
++
++dnl
++dnl Test for ALSA9 MIDI driver.
++dnl
++dnl Variables:
++dnl allegro_enable_alsa9midi=(yes|)
++dnl allegro_support_alsa9midi=(yes|)
++dnl
++AC_DEFUN(ALLEGRO_ACTEST_ALSA9MIDI,
++[AC_ARG_ENABLE(alsa9midi,
++[ --enable-alsa9midi[=x] enable building ALSA9 MIDI driver [default=yes]],
++test "X$enableval" != "Xno" && allegro_enable_alsa9midi=yes,
++allegro_enable_alsa9midi=yes)
++
++if test -n "$allegro_enable_alsa9midi"; then
++ AC_CACHE_CHECK(for supported ALSA9 version for MIDI,
++ allegro_cv_support_alsa9midi,
++ AC_TRY_RUN([#include <alsa/asoundlib.h>
++ int main (void) { return SND_LIB_MAJOR != 0 || SND_LIB_MINOR != 9; }],
++ allegro_cv_support_alsa9midi=yes,
++ allegro_cv_support_alsa9midi=no,
++ allegro_cv_support_alsa9midi=no))
++ if test "X$allegro_cv_support_alsa9midi" = "Xyes" &&
++ test -z "$allegro_support_modules"; then
++ LIBS="-lasound $LIBS"
++ fi
++fi])
++
++dnl
+ dnl Test for ESD DIGI driver.
+ dnl
+ dnl Variables:
+diff -ur allegro-4.0.2/allegro.mft allegro-4.0.2.new/allegro.mft
+--- allegro-4.0.2/allegro.mft Sun Jun 16 21:49:13 2002
++++ allegro-4.0.2.new/allegro.mft Fri Jun 21 12:48:18 2002
+@@ -647,6 +647,8 @@
+ allegro/src/unix/
+ allegro/src/unix/alsa.c
+ allegro/src/unix/alsamidi.c
++allegro/src/unix/alsa9.c
++allegro/src/unix/alsa9midi.c
+ allegro/src/unix/udjgpp.c
+ allegro/src/unix/udrvlist.c
+ allegro/src/unix/uesd.c
+diff -ur allegro-4.0.2/configure.in allegro-4.0.2.new/configure.in
+--- allegro-4.0.2/configure.in Sun Jun 16 21:22:15 2002
++++ allegro-4.0.2.new/configure.in Fri Jun 21 12:39:47 2002
+@@ -285,6 +285,17 @@
+ AC_DEFINE(ALLEGRO_WITH_ALSAMIDI)
+ fi
+
++dnl Test for ALSA9 drivers.
++ALLEGRO_ACTEST_ALSA9DIGI
++if test "$allegro_cv_support_alsa9digi" = yes; then
++ AC_DEFINE(ALLEGRO_WITH_ALSA9DIGI)
++fi
++
++ALLEGRO_ACTEST_ALSA9MIDI
++if test "$allegro_cv_support_alsa9midi" = yes; then
++ AC_DEFINE(ALLEGRO_WITH_ALSA9MIDI)
++fi
++
+ dnl Test for ESD drivers.
+ ALLEGRO_ACTEST_ESDDIGI
+ if test -n "$allegro_support_esddigi"; then
+@@ -447,6 +458,16 @@
+ ALLEGRO_MODULE_TARGETS="$ALLEGRO_MODULE_TARGETS lib/unix/alleg-alsamidi.so"
+ fi
+
++ dnl ALSA9 DIGI.
++ if test "X$allegro_cv_support_alsa9digi" = "Xyes"; then
++ ALLEGRO_MODULE_TARGETS="$ALLEGRO_MODULE_TARGETS lib/unix/alleg-alsa9digi.so"
++ fi
++
++ dnl ALSA9 MIDI.
++ if test "X$allegro_cv_support_alsa9midi" = "Xyes"; then
++ ALLEGRO_MODULE_TARGETS="$ALLEGRO_MODULE_TARGETS lib/unix/alleg-alsa9midi.so"
++ fi
++
+ dnl ESD DIGI.
+ if test "X$allegro_support_esddigi" = "Xyes"; then
+ ALLEGRO_MODULE_TARGETS="$ALLEGRO_MODULE_TARGETS lib/unix/alleg-esddigi.so"
+diff -ur allegro-4.0.2/makefile.in allegro-4.0.2.new/makefile.in
+--- allegro-4.0.2/makefile.in Fri Jun 21 14:39:28 2002
++++ allegro-4.0.2.new/makefile.in Fri Jun 21 14:31:28 2002
+@@ -506,6 +506,8 @@
+ $(SHELL) -c 'cd $(srcdir) && misc/depmod.sh fbcon -- $(ALLEGRO_MODULE_FBCON_FILES)' >>makefile.dep
+ $(SHELL) -c 'cd $(srcdir) && misc/depmod.sh alsadigi -lasound $(ALLEGRO_MODULE_ALSADIGI_FILES)' >>makefile.dep
+ $(SHELL) -c 'cd $(srcdir) && misc/depmod.sh alsamidi -lasound $(ALLEGRO_MODULE_ALSAMIDI_FILES)' >>makefile.dep
++ $(SHELL) -c 'cd $(srcdir) && misc/depmod.sh alsa9digi -lasound $(ALLEGRO_MODULE_ALSA9DIGI_FILES)' >>makefile.dep
++ $(SHELL) -c 'cd $(srcdir) && misc/depmod.sh alsa9midi -lasound $(ALLEGRO_MODULE_ALSA9MIDI_FILES)' >>makefile.dep
+ $(SHELL) -c 'cd $(srcdir) && misc/depmod.sh esddigi "\`esd-config --libs\`" $(ALLEGRO_MODULE_ESD_FILES)' >>makefile.dep
+ $(SHELL) -c 'cd $(srcdir) && misc/depmod.sh dga2 -lXxf86dga $(ALLEGRO_MODULE_DGA2_FILES)' >> makefile.dep
+ @echo "Generating dependencies for simple programs"
+diff -ur allegro-4.0.2/makefile.lst allegro-4.0.2.new/makefile.lst
+--- allegro-4.0.2/makefile.lst Sun Jun 16 21:43:10 2002
++++ allegro-4.0.2.new/makefile.lst Fri Jun 21 12:46:00 2002
+@@ -261,6 +261,8 @@
+ ALLEGRO_SRC_UNIX_FILES = \
+ src/unix/alsa.c \
+ src/unix/alsamidi.c \
++ src/unix/alsa9.c \
++ src/unix/alsa9midi.c \
+ src/unix/udjgpp.c \
+ src/unix/udrvlist.c \
+ src/unix/uesd.c \
+@@ -332,6 +334,12 @@
+ ALLEGRO_MODULE_ALSAMIDI_FILES = \
+ src/unix/alsamidi.c
+
++ALLEGRO_MODULE_ALSA9DIGI_FILES = \
++ src/unix/alsa9.c
++
++ALLEGRO_MODULE_ALSA9MIDI_FILES = \
++ src/unix/alsa9midi.c
++
+ ALLEGRO_MODULE_ESD_FILES = \
+ src/unix/uesd.c
+
+diff -ur allegro-4.0.2/modules.lst allegro-4.0.2.new/modules.lst
+--- allegro-4.0.2/modules.lst Sun Jun 16 21:22:15 2002
++++ allegro-4.0.2.new/modules.lst Fri Jun 21 12:47:13 2002
+@@ -7,3 +7,5 @@
+ alleg-esddigi.so
+ alleg-alsadigi.so
+ alleg-alsamidi.so
++alleg-alsa9digi.so
++alleg-alsa9midi.so
+diff -uNr allegro-4.0.2/src/unix/alsa9.c allegro-4.0.2.new/src/unix/alsa9.c
+--- allegro-4.0.2/src/unix/alsa9.c Thu Jan 1 01:00:00 1970
++++ allegro-4.0.2.new/src/unix/alsa9.c Fri Jun 21 14:35:09 2002
+@@ -0,0 +1,408 @@
++/* ______ ___ ___
++ * /\ _ \ /\_ \ /\_ \
++ * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___
++ * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\
++ * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \
++ * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/
++ * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/
++ * /\____/
++ * \_/__/
++ *
++ * ALSA sound driver.
++ *
++ * By Peter Wang (based heavily on uoss.c)
++ *
++ * See readme.txt for copyright information.
++ */
++
++
++#include "allegro.h"
++
++#if (defined DIGI_ALSA) && ((!defined ALLEGRO_WITH_MODULES) || (defined ALLEGRO_MODULE))
++
++#include "allegro/internal/aintern.h"
++#ifdef ALLEGRO_QNX
++#include "allegro/platform/aintqnx.h"
++#else
++#include "allegro/platform/aintunix.h"
++#endif
++
++#ifndef SCAN_DEPEND
++ #include <string.h>
++ #include <sys/asoundlib.h>
++#endif
++
++
++#ifndef SND_PCM_SFMT_S16_NE
++ #ifdef ALLEGRO_BIG_ENDIAN
++ #define SND_PCM_SFMT_S16_NE SND_PCM_SFMT_S16_BE
++ #else
++ #define SND_PCM_SFMT_S16_NE SND_PCM_SFMT_S16_LE
++ #endif
++#endif
++#ifndef SND_PCM_SFMT_U16_NE
++ #ifdef ALLEGRO_BIG_ENDIAN
++ #define SND_PCM_SFMT_U16_NE SND_PCM_SFMT_U16_BE
++ #else
++ #define SND_PCM_SFMT_U16_NE SND_PCM_SFMT_U16_LE
++ #endif
++#endif
++
++
++#define ALSA_DEFAULT_NUMFRAGS 16
++
++
++static snd_pcm_t *pcm_handle;
++static int alsa_bufsize;
++static unsigned char *alsa_bufdata;
++static int alsa_bits, alsa_signed, alsa_rate, alsa_stereo;
++static int alsa_fragments;
++
++static char alsa_desc[256] = EMPTY_STRING;
++
++
++
++static int alsa_detect(int input);
++static int alsa_init(int input, int voices);
++static void alsa_exit(int input);
++static int alsa_mixer_volume(int volume);
++static int alsa_buffer_size(void);
++
++
++
++DIGI_DRIVER digi_alsa =
++{
++ DIGI_ALSA,
++ empty_string,
++ empty_string,
++ "ALSA",
++ 0,
++ 0,
++ MIXER_MAX_SFX,
++ MIXER_DEF_SFX,
++
++ alsa_detect,
++ alsa_init,
++ alsa_exit,
++ alsa_mixer_volume,
++
++ NULL,
++ NULL,
++ alsa_buffer_size,
++ _mixer_init_voice,
++ _mixer_release_voice,
++ _mixer_start_voice,
++ _mixer_stop_voice,
++ _mixer_loop_voice,
++
++ _mixer_get_position,
++ _mixer_set_position,
++
++ _mixer_get_volume,
++ _mixer_set_volume,
++ _mixer_ramp_volume,
++ _mixer_stop_volume_ramp,
++
++ _mixer_get_frequency,
++ _mixer_set_frequency,
++ _mixer_sweep_frequency,
++ _mixer_stop_frequency_sweep,
++
++ _mixer_get_pan,
++ _mixer_set_pan,
++ _mixer_sweep_pan,
++ _mixer_stop_pan_sweep,
++
++ _mixer_set_echo,
++ _mixer_set_tremolo,
++ _mixer_set_vibrato,
++ 0, 0,
++ 0,
++ 0,
++ 0,
++ 0,
++ 0,
++ 0
++};
++
++
++
++/* alsa_buffer_size:
++ * Returns the current DMA buffer size, for use by the audiostream code.
++ */
++static int alsa_buffer_size()
++{
++ return alsa_bufsize * alsa_fragments / (alsa_bits / 8) / (alsa_stereo ? 2 : 1);
++}
++
++
++
++/* alsa_update:
++ * Update data.
++ */
++static void alsa_update(int threaded)
++{
++ int i;
++
++ for (i = 0; i < alsa_fragments; i++) {
++ if (snd_pcm_write(pcm_handle, alsa_bufdata, alsa_bufsize) != alsa_bufsize)
++ break;
++ _mix_some_samples((unsigned long) alsa_bufdata, 0, alsa_signed);
++ }
++}
++
++
++
++/* alsa_detect:
++ * Detect driver presence.
++ */
++static int alsa_detect(int input)
++{
++ snd_pcm_t *handle;
++ snd_pcm_info_t info;
++ int card, device;
++ char tmp1[128], tmp2[128];
++ int ret = FALSE;
++
++ card = get_config_int(uconvert_ascii("sound", tmp1),
++ uconvert_ascii("alsa_card", tmp2),
++ snd_defaults_card());
++
++ device = get_config_int(uconvert_ascii("sound", tmp1),
++ uconvert_ascii("alsa_pcmdevice", tmp2),
++ snd_defaults_pcm_device());
++
++ if (snd_pcm_open(&handle, card, device, (SND_PCM_OPEN_PLAYBACK
++ | SND_PCM_OPEN_NONBLOCK)) == 0) {
++ if ((snd_pcm_info(handle, &info) == 0)
++ && (info.flags & SND_PCM_INFO_PLAYBACK))
++ ret = TRUE;
++
++ snd_pcm_close(handle);
++ }
++
++ return ret;
++}
++
++
++
++/* alsa_init:
++ * ALSA init routine.
++ */
++static int alsa_init(int input, int voices)
++{
++ int card, device;
++ int format, bps, fragsize, numfrags;
++ snd_pcm_channel_params_t params;
++ snd_pcm_channel_setup_t setup;
++ char tmp1[128], tmp2[128];
++
++ if (input) {
++ ustrzcpy(allegro_error, ALLEGRO_ERROR_SIZE, get_config_text("Input is not supported"));
++ return -1;
++ }
++
++ /* Load config. */
++ card = get_config_int(uconvert_ascii("sound", tmp1),
++ uconvert_ascii("alsadigi_card", tmp2),
++ snd_defaults_card());
++
++ device = get_config_int(uconvert_ascii("sound", tmp1),
++ uconvert_ascii("alsadigi_pcmdevice", tmp2),
++ snd_defaults_pcm_device());
++
++ fragsize = get_config_int(uconvert_ascii("sound", tmp1),
++ uconvert_ascii("alsa_fragsize", tmp2),
++ -1);
++
++ numfrags = get_config_int(uconvert_ascii("sound", tmp1),
++ uconvert_ascii("alsa_numfrags", tmp2),
++ ALSA_DEFAULT_NUMFRAGS);
++
++ /* Open PCM device. */
++ if (snd_pcm_open(&pcm_handle, card, device, (SND_PCM_OPEN_PLAYBACK
++ | SND_PCM_OPEN_NONBLOCK)) < 0) {
++ ustrzcpy(allegro_error, ALLEGRO_ERROR_SIZE, get_config_text("Can not open card/pcm device"));
++ goto error;
++ }
++
++ /* Set format variables. */
++ alsa_bits = (_sound_bits == 8) ? 8 : 16;
++ alsa_stereo = (_sound_stereo) ? 1 : 0;
++ alsa_rate = (_sound_freq > 0) ? _sound_freq : 44100;
++
++ format = ((alsa_bits == 16) ? SND_PCM_SFMT_S16_NE : SND_PCM_SFMT_U8);
++
++ alsa_signed = 0;
++ bps = alsa_rate * (alsa_stereo ? 2 : 1);
++ switch (format) {
++ case SND_PCM_SFMT_S8:
++ alsa_signed = 1;
++ case SND_PCM_SFMT_U8:
++ alsa_bits = 8;
++ break;
++ case SND_PCM_SFMT_S16_NE:
++ alsa_signed = 1;
++ case SND_PCM_SFMT_U16_NE:
++ alsa_bits = 16;
++ bps <<= 1;
++ if (sizeof(short) != 2) {
++ ustrzcpy(allegro_error, ALLEGRO_ERROR_SIZE, get_config_text("Unsupported sample format"));
++ goto error;
++ }
++ break;
++ default:
++ ustrzcpy(allegro_error, ALLEGRO_ERROR_SIZE, get_config_text("Unsupported sample format"));
++ goto error;
++ }
++
++ if (fragsize < 0) {
++ bps >>= 9;
++ if (bps < 16)
++ bps = 16;
++ fragsize = 1;
++ while ((fragsize << 1) < bps)
++ fragsize <<= 1;
++ }
++ else {
++ fragsize = fragsize * (alsa_bits / 8) * (alsa_stereo ? 2 : 1);
++ }
++
++ /* Set PCM channel format. */
++ memset(¶ms, 0, sizeof(params));
++ params.mode = SND_PCM_MODE_BLOCK;
++ params.channel = SND_PCM_CHANNEL_PLAYBACK;
++ params.start_mode = SND_PCM_START_FULL;
++ params.stop_mode = SND_PCM_STOP_ROLLOVER;
++ params.format.interleave = 1;
++ params.format.format = format;
++ params.format.rate = alsa_rate;
++ params.format.voices = alsa_stereo + 1;
++ params.buf.block.frag_size = fragsize;
++ params.buf.block.frags_min = 1;
++ params.buf.block.frags_max = numfrags;
++
++ if (snd_pcm_channel_params(pcm_handle, ¶ms) < 0) {
++ ustrzcpy(allegro_error, ALLEGRO_ERROR_SIZE, get_config_text("Can not set channel parameters"));
++ goto error;
++ }
++
++ snd_pcm_channel_prepare(pcm_handle, SND_PCM_CHANNEL_PLAYBACK);
++
++ /* Read back fragments information. */
++ memset(&setup, 0, sizeof(setup));
++ setup.mode = SND_PCM_MODE_BLOCK;
++ setup.channel = SND_PCM_CHANNEL_PLAYBACK;
++
++ if (snd_pcm_channel_setup(pcm_handle, &setup) < 0) {
++ ustrzcpy(allegro_error, ALLEGRO_ERROR_SIZE, get_config_text("Can not get channel setup"));
++ goto error;
++ }
++
++ alsa_fragments = numfrags;
++ alsa_bufsize = setup.buf.block.frag_size;
++
++ /* Allocate mixing buffer. */
++ alsa_bufdata = malloc(alsa_bufsize);
++ if (!alsa_bufdata) {
++ ustrzcpy(allegro_error, ALLEGRO_ERROR_SIZE, get_config_text("Can not allocate audio buffer"));
++ goto error;
++ }
++
++ /* Initialise mixer. */
++ digi_alsa.voices = voices;
++
++ if (_mixer_init(alsa_bufsize / (alsa_bits / 8), alsa_rate,
++ alsa_stereo, ((alsa_bits == 16) ? 1 : 0),
++ &digi_alsa.voices) != 0) {
++ ustrzcpy(allegro_error, ALLEGRO_ERROR_SIZE, get_config_text("Can not init software mixer"));
++ goto error;
++ }
++
++ _mix_some_samples((unsigned long) alsa_bufdata, 0, alsa_signed);
++
++ /* Add audio interrupt. */
++ _unix_bg_man->register_func(alsa_update);
++
++ uszprintf(alsa_desc, sizeof(alsa_desc),
++ get_config_text("Card #%d, device #%d: %d bits, %s, %d bps, %s"),
++ card, device, alsa_bits,
++ uconvert_ascii((alsa_signed ? "signed" : "unsigned"), tmp1),
++ alsa_rate,
++ uconvert_ascii((alsa_stereo ? "stereo" : "mono"), tmp2));
++
++ digi_driver->desc = alsa_desc;
++
++ return 0;
++
++ error:
++
++ if (pcm_handle) {
++ snd_pcm_close(pcm_handle);
++ pcm_handle = NULL;
++ }
++
++ return -1;
++}
++
++
++
++/* alsa_exit:
++ * Shutdown ALSA driver.
++ */
++static void alsa_exit(int input)
++{
++ if (input) {
++ return;
++ }
++
++ _unix_bg_man->unregister_func(alsa_update);
++
++ free(alsa_bufdata);
++ alsa_bufdata = NULL;
++
++ _mixer_exit();
++
++ snd_pcm_close(pcm_handle);
++}
++
++
++
++/* alsa_mixer_volume:
++ * Set mixer volume (0-255)
++ */
++static int alsa_mixer_volume(int volume)
++{
++ /* TODO */
++#if 0
++ snd_mixer_t *handle;
++ int card, device;
++
++ if (snd_mixer_open(&handle, card, device) == 0) {
++ /* do something special */
++ snd_mixer_close(handle);
++ return 0;
++ }
++
++ return -1;
++#else
++ return 0;
++#endif
++}
++
++
++
++#ifdef ALLEGRO_MODULE
++
++/* _module_init:
++ * Called when loaded as a dynamically linked module.
++ */
++void _module_init(int system_driver)
++{
++ _unix_register_digi_driver(DIGI_ALSA, &digi_alsa, TRUE, TRUE);
++}
++
++#endif
++
++#endif
++
+diff -uNr allegro-4.0.2/src/unix/alsa9midi.c allegro-4.0.2.new/src/unix/alsa9midi.c
+--- allegro-4.0.2/src/unix/alsa9midi.c Thu Jan 1 01:00:00 1970
++++ allegro-4.0.2.new/src/unix/alsa9midi.c Sun Jun 16 21:22:31 2002
+@@ -0,0 +1,242 @@
++/* ______ ___ ___
++ * /\ _ \ /\_ \ /\_ \
++ * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___
++ * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\
++ * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \
++ * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/
++ * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/
++ * /\____/
++ * \_/__/
++ *
++ * ALSA RawMIDI Sound driver.
++ *
++ * By Tom Fjellstrom.
++ *
++ * See readme.txt for copyright information.
++ */
++
++#include "allegro.h"
++
++#if (defined MIDI_ALSA) && ((!defined ALLEGRO_WITH_MODULES) || (defined ALLEGRO_MODULE))
++
++#include "allegro/internal/aintern.h"
++#ifdef ALLEGRO_QNX
++#include "allegro/platform/aintqnx.h"
++#else
++#include "allegro/platform/aintunix.h"
++#endif
++
++#ifndef SCAN_DEPEND
++ #include <stdlib.h>
++ #include <stdio.h>
++ #include <string.h>
++ #include <errno.h>
++ #include <sys/asoundlib.h>
++#endif
++
++/* external interface to the ALSA rawmidi driver */
++static int alsa_rawmidi_detect(int input);
++static int alsa_rawmidi_init(int input, int voices);
++static void alsa_rawmidi_exit(int input);
++static void alsa_rawmidi_output(int data);
++
++static char alsa_rawmidi_desc[256];
++
++static snd_rawmidi_t *rawmidi_handle = NULL;
++
++MIDI_DRIVER midi_alsa =
++{
++ MIDI_ALSA, /* id */
++ empty_string, /* name */
++ empty_string, /* desc */
++ "ALSA RawMIDI", /* ASCII name */
++ 0, 0, 0xFFFF, 0, -1, -1, /* voices, basevoice, max_voices, def_voices, xmin, xmax */
++ alsa_rawmidi_detect, /* detect */
++ alsa_rawmidi_init, /* init */
++ alsa_rawmidi_exit, /* exit */
++ NULL, /* mixer_volume */
++ alsa_rawmidi_output, /* raw_midi */
++ _dummy_load_patches, /* load_patches */
++ _dummy_adjust_patches, /* adjust_patches */
++ _dummy_key_on, /* key_on */
++ _dummy_noop1, /* key_off */
++ _dummy_noop2, /* set_volume */
++ _dummy_noop3, /* set_pitch */
++ _dummy_noop2, /* set_pan */
++ _dummy_noop2 /* set_vibrato */
++};
++
++/* alsa_rawmidi_detect:
++ * ALSA RawMIDI detection.
++ */
++static int alsa_rawmidi_detect(int input)
++{
++ int card = -1;
++ int device = -1;
++ int ret = FALSE, err;
++ char tmp1[128], tmp2[128], temp[256];
++ snd_rawmidi_t *handle = NULL;
++
++ if(input) {
++ /* Input not supported.
++ card = get_config_int(uconvert_ascii("sound", tmp1),
++ uconvert_ascii("alsa_rawmidi_input_card", tmp2),
++ snd_defaults_rawmidi_card());
++
++ device = get_config_int(uconvert_ascii("sound", tmp1),
++ uconvert_ascii("alsa_rawmidi_input_device", tmp2),
++ snd_defaults_rawmidi_device());
++
++ if ((err = snd_rawmidi_open(&handle, card, device, SND_RAWMIDI_OPEN_INPUT)) < 0) {
++ snprintf(temp, sizeof(temp), "Could not open card/rawmidi device: %s", snd_strerror(err));
++ ustrzcpy(allegro_error, ALLEGRO_ERROR_SIZE, get_config_text(temp));
++ ret = FALSE;
++ }
++
++ snd_rawmidi_close(handle);
++ */
++ ret = FALSE;
++
++ }
++ else {
++
++ card = get_config_int(uconvert_ascii("sound", tmp1),
++ uconvert_ascii("alsa_rawmidi_card", tmp2),
++ snd_defaults_rawmidi_card());
++
++ device = get_config_int(uconvert_ascii("sound", tmp1),
++ uconvert_ascii("alsa_rawmidi_device", tmp2),
++ snd_defaults_rawmidi_device());
++
++ if ((err = snd_rawmidi_open(&handle, card, device, SND_RAWMIDI_OPEN_OUTPUT_APPEND)) < 0) {
++ snprintf(temp, sizeof(temp), "Could not open card/rawmidi device: %s", snd_strerror(err));
++ ustrzcpy(allegro_error, ALLEGRO_ERROR_SIZE, get_config_text(temp));
++ ret = FALSE;
++ }
++
++ snd_rawmidi_close(handle);
++
++ ret = TRUE;
++ }
++
++ return ret;
++}
++
++/* alsa_rawmidi_init:
++ * Setup the ALSA RawMIDI interface.
++ */
++static int alsa_rawmidi_init(int input, int voices)
++{
++ int card = -1;
++ int device = -1;
++ int ret = -1, err;
++ char tmp1[128], tmp2[128], temp[256];
++ snd_rawmidi_info_t info;
++
++ if(input) {
++ /* Input not supported
++ card = get_config_int(uconvert_ascii("sound", tmp1),
++ uconvert_ascii("alsa_rawmidi_input_card", tmp2),
++ snd_defaults_rawmidi_card());
++
++ device = get_config_int(uconvert_ascii("sound", tmp1),
++ uconvert_ascii("alsa_rawmidi_input_device", tmp2),
++ snd_defaults_rawmidi_device());
++
++ if ((err = snd_rawmidi_open(&rawmidi_handle, card, device, SND_RAWMIDI_OPEN_INPUT)) < 0) {
++ snprintf(temp, sizeof(temp), "Could not open card/rawmidi device: %s", snd_strerror(err));
++ ustrzcpy(allegro_error, ALLEGRO_ERROR_SIZE, get_config_text(temp));
++ ret = -1;
++ }
++ */
++ ret = -1;
++
++ }
++ else {
++
++ card = get_config_int(uconvert_ascii("sound", tmp1),
++ uconvert_ascii("alsa_rawmidi_card", tmp2),
++ snd_defaults_rawmidi_card());
++
++ device = get_config_int(uconvert_ascii("sound", tmp1),
++ uconvert_ascii("alsa_rawmidi_device", tmp2),
++ snd_defaults_rawmidi_device());
++
++ if ((err = snd_rawmidi_open(&rawmidi_handle, card, device, SND_RAWMIDI_OPEN_OUTPUT_APPEND)) < 0) {
++ snprintf(temp, sizeof(temp), "Could not open card/rawmidi device: %s", snd_strerror(err));
++ ustrzcpy(allegro_error, ALLEGRO_ERROR_SIZE, get_config_text(temp));
++ ret = -1;
++ }
++
++ ret = 0;
++ }
++
++ if(rawmidi_handle) {
++ snd_rawmidi_block_mode(rawmidi_handle, 1);
++ snd_rawmidi_info(rawmidi_handle, &info);
++
++ strcpy(alsa_rawmidi_desc, info.name);
++ midi_alsa.desc = alsa_rawmidi_desc;
++
++ LOCK_VARIABLE(alsa_rawmidi_desc);
++ LOCK_VARIABLE(rawmidi_handle);
++ LOCK_VARIABLE(midi_alsa);
++ LOCK_FUNCTION(alsa_rawmidi_output);
++ }
++
++ return ret;
++}
++
++/* alsa_rawmidi_exit:
++ * Clean up.
++ */
++static void alsa_rawmidi_exit(int input)
++{
++ if(rawmidi_handle) {
++ snd_rawmidi_output_drain(rawmidi_handle);
++ snd_rawmidi_close(rawmidi_handle);
++ }
++
++ rawmidi_handle = NULL;
++}
++
++/* alsa_rawmidi_output:
++ * Outputs MIDI data.
++ */
++static void alsa_rawmidi_output(int data)
++{
++ int err;
++
++ err = snd_rawmidi_write(rawmidi_handle, &data, sizeof(char));
++
++}
++END_OF_STATIC_FUNCTION(alsa_rawmidi_output);
++
++/* alsa_rawmidi_input:
++ * Reads MIDI data.
++ * not supported...
++static INLINE int alsa_rawmidi_input(void)
++{
++ char data = 0;
++
++ if(snd_rawmidi_read(rawmidi_handle, &data, sizeof(char)) > 0)
++ return data;
++ else
++ return 0;
++}
++*/
++
++#ifdef ALLEGRO_MODULE
++
++/* _module_init:
++ * Called when loaded as a dynamically linked module.
++ */
++void _module_init(int system_driver)
++{
++ _unix_register_midi_driver(MIDI_ALSA, &midi_alsa, TRUE, TRUE);
++}
++
++#endif /* ALLEGRO_MODULE */
++
++#endif /* MIDI_ALSA */
++