Peter Kutak - Wed Feb 13 10:26:57 PST 2002
authorSam Lantinga <slouken@libsdl.org>
Wed, 13 Feb 2002 19:07:39 +0000
changeset 160c62666b42573
parent 159 01490534f9fe
child 161 2a4946fc5a62
Peter Kutak - Wed Feb 13 10:26:57 PST 2002
* Added native midi support on Linux, using GPL code
--enable-music-native-midi-gpl
CHANGES
Makefile.am
configure.in
native_midi_gpl/Makefile.am
native_midi_gpl/README
native_midi_gpl/awe_voice.h
native_midi_gpl/emumidi.c
native_midi_gpl/emumidi.h
native_midi_gpl/gmvoices.h
native_midi_gpl/gsvoices.h
native_midi_gpl/native_midi_gpl.c
native_midi_gpl/patchload.c
native_midi_gpl/playevents.c
native_midi_gpl/playmidi.h
native_midi_gpl/readmidi.c
     1.1 --- a/CHANGES	Thu Feb 07 17:40:36 2002 +0000
     1.2 +++ b/CHANGES	Wed Feb 13 19:07:39 2002 +0000
     1.3 @@ -1,5 +1,8 @@
     1.4  
     1.5  1.2.3:
     1.6 +Peter Kutak - Wed Feb 13 10:26:57 PST 2002
     1.7 + * Added native midi support on Linux, using GPL code
     1.8 +	--enable-music-native-midi-gpl
     1.9  Pete Shinners - Mon Jan 14 11:31:26 PST 2002
    1.10   * Added seek support for MP3 files
    1.11  Ryan Gordon - Mon Jan 14 11:30:44 PST 2002
     2.1 --- a/Makefile.am	Thu Feb 07 17:40:36 2002 +0000
     2.2 +++ b/Makefile.am	Wed Feb 13 19:07:39 2002 +0000
     2.3 @@ -3,7 +3,7 @@
     2.4  lib_LTLIBRARIES = libSDL_mixer.la
     2.5  
     2.6  SUBDIRS = @MUSIC_SUBDIRS@
     2.7 -DIST_SUBDIRS = mikmod timidity native_midi
     2.8 +DIST_SUBDIRS = mikmod timidity native_midi native_midi_gpl
     2.9  
    2.10  libSDL_mixerincludedir = $(includedir)/SDL
    2.11  libSDL_mixerinclude_HEADERS =	\
    2.12 @@ -38,7 +38,11 @@
    2.13  TIMIDITY_LIB =
    2.14  endif
    2.15  if USE_NATIVE_MIDI
    2.16 +if USE_NATIVE_MIDI_GPL
    2.17 +NATIVE_MIDI_LIB = native_midi_gpl/libnativemidi_gpl.la
    2.18 +else
    2.19  NATIVE_MIDI_LIB = native_midi/libnativemidi.la
    2.20 +endif
    2.21  else
    2.22  NATIVE_MIDI_LIB =
    2.23  endif
     3.1 --- a/configure.in	Thu Feb 07 17:40:36 2002 +0000
     3.2 +++ b/configure.in	Wed Feb 13 19:07:39 2002 +0000
     3.3 @@ -135,12 +135,38 @@
     3.4                  use_music_native_midi=yes
     3.5                  LIBS="$LIBS -framework QuickTime"
     3.6                  ;;
     3.7 +            *-*-linux* | *-*-freebsd*)
     3.8 +                if test x$enable_music_native_midi_gpl != xyes; then
     3.9 +                    AC_ERROR([the native midi code is GPL code, use --enable-music-native-midi-gpl])
    3.10 +                fi
    3.11 +                ;;
    3.12 +            *)
    3.13 +                AC_ERROR([native MIDI not supported on this platform])
    3.14 +                ;;
    3.15          esac
    3.16          if test x$use_music_native_midi = xyes; then
    3.17              CFLAGS="$CFLAGS -DUSE_NATIVE_MIDI -I\$(top_srcdir)/native_midi"
    3.18              MUSIC_SUBDIRS="$MUSIC_SUBDIRS native_midi"
    3.19          fi
    3.20      fi
    3.21 +    AC_ARG_ENABLE(music-native-midi-gpl,
    3.22 +[  --enable-music-native-midi-gpl  enable native MIDI on UNIX using GPL code [default=no]],
    3.23 +                  , enable_music_native_midi_gpl=no)
    3.24 +    if test x$enable_music_native_midi_gpl = xyes; then
    3.25 +        use_music_native_midi_gpl=no
    3.26 +        case "$target" in
    3.27 +            *-*-linux* | *-*-freebsd*)
    3.28 +                use_music_native_midi_gpl=yes
    3.29 +                ;;
    3.30 +            *)
    3.31 +                AC_ERROR([native MIDI not supported on this platform])
    3.32 +                ;;
    3.33 +        esac
    3.34 +        if test x$use_music_native_midi_gpl = xyes; then
    3.35 +            CFLAGS="$CFLAGS -DUSE_NATIVE_MIDI -I\$(top_srcdir)/native_midi"
    3.36 +            MUSIC_SUBDIRS="$MUSIC_SUBDIRS native_midi_gpl"
    3.37 +        fi
    3.38 +    fi
    3.39  fi
    3.40  AC_ARG_ENABLE(music-ogg,
    3.41  [  --enable-music-ogg      enable Ogg Vorbis music [default=yes]],
    3.42 @@ -176,7 +202,8 @@
    3.43  AC_SUBST(MUSIC_SUBDIRS)
    3.44  AM_CONDITIONAL(USE_MIKMOD, test x$enable_music_mod = xyes)
    3.45  AM_CONDITIONAL(USE_TIMIDITY, test x$enable_music_timidity_midi = xyes)
    3.46 -AM_CONDITIONAL(USE_NATIVE_MIDI, test x$use_music_native_midi = xyes)
    3.47 +AM_CONDITIONAL(USE_NATIVE_MIDI, test x$use_music_native_midi = xyes || test x$use_music_native_midi_gpl = xyes)
    3.48 +AM_CONDITIONAL(USE_NATIVE_MIDI_GPL, test x$use_music_native_midi_gpl = xyes)
    3.49  
    3.50  # Finally create all the generated files
    3.51  AC_OUTPUT([
    3.52 @@ -184,5 +211,6 @@
    3.53  mikmod/Makefile
    3.54  timidity/Makefile
    3.55  native_midi/Makefile
    3.56 +native_midi_gpl/Makefile
    3.57  SDL_mixer.spec
    3.58  ])
     4.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     4.2 +++ b/native_midi_gpl/Makefile.am	Wed Feb 13 19:07:39 2002 +0000
     4.3 @@ -0,0 +1,16 @@
     4.4 +
     4.5 +noinst_LTLIBRARIES = libnativemidi_gpl.la
     4.6 +
     4.7 +libnativemidi_gpl_la_SOURCES =	\
     4.8 +	awe_voice.h		\
     4.9 +	emumidi.c		\
    4.10 +	emumidi.h		\
    4.11 +	gmvoices.h		\
    4.12 +	gsvoices.h		\
    4.13 +	native_midi_gpl.c	\
    4.14 +	patchload.c		\
    4.15 +	playevents.c		\
    4.16 +	playmidi.h		\
    4.17 +	readmidi.c
    4.18 +
    4.19 +INCLUDES = -I$(top_srcdir)
     5.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     5.2 +++ b/native_midi_gpl/README	Wed Feb 13 19:07:39 2002 +0000
     5.3 @@ -0,0 +1,26 @@
     5.4 +
     5.5 +Unfortunately, the code for the native MIDI support on Linux is derived
     5.6 +from source under the GNU General Public License, and not the GNU LGPL.
     5.7 +Therefore, it's not built by default.
     5.8 +
     5.9 +Native Midi support for Linux should work on FreeBSD too ( I can not test it ).
    5.10 +
    5.11 +Midi device can be selected with enviroment variable SDL_NATIVE_MUSIC, there can have one of flowing vlues: 
    5.12 +GUS  - GravisUltrasound
    5.13 +AWE  - SoundBlaster AWE32
    5.14 +FM   - FreqentionModulation SoundBlaster Compatible
    5.15 +OPL3 - Yamaha OPL/3
    5.16 +EXT  - External MIDI port
    5.17 +
    5.18 +External MIDI port can be set with env. SDL_NATIVE_MUSIC_EXT (SDL_NATIVE_MUSIC_EXT="1").
    5.19 +
    5.20 +Autoselect priority:
    5.21 +1. GUS
    5.22 +2. AWE
    5.23 +3. use Timidity
    5.24 +4. FM
    5.25 +5. EXT
    5.26 +
    5.27 +Also if you want use FM befor Timidity set variable SDL_NATIVE_MUSIC="FM" or edit source code native_midi_lnx.c( return value in function synth_setup, by autoselect FM should return 1).
    5.28 +For using FM: files drums.sb drums.o3 std.sb std.o3 should be moved to /etc/ dir ( or symlink created ).
    5.29 +
     6.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     6.2 +++ b/native_midi_gpl/awe_voice.h	Wed Feb 13 19:07:39 2002 +0000
     6.3 @@ -0,0 +1,490 @@
     6.4 +/*
     6.5 + * sound/awe_voice.h
     6.6 + *
     6.7 + * Voice information definitions for the low level driver for the 
     6.8 + * AWE32/Sound Blaster 32 wave table synth.
     6.9 + *   version 0.4.2c; Oct. 7, 1997
    6.10 + *
    6.11 + * Copyright (C) 1996,1997 Takashi Iwai
    6.12 + *
    6.13 + * This program is free software; you can redistribute it and/or modify
    6.14 + * it under the terms of the GNU General Public License as published by
    6.15 + * the Free Software Foundation; either version 2 of the License, or
    6.16 + * (at your option) any later version.
    6.17 + *
    6.18 + * This program is distributed in the hope that it will be useful,
    6.19 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
    6.20 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    6.21 + * GNU General Public License for more details.
    6.22 + *
    6.23 + * You should have received a copy of the GNU General Public License
    6.24 + * along with this program; if not, write to the Free Software
    6.25 + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
    6.26 + */
    6.27 +
    6.28 +#ifndef AWE_VOICE_H
    6.29 +#define AWE_VOICE_H
    6.30 +
    6.31 +#ifndef SAMPLE_TYPE_AWE32
    6.32 +#define SAMPLE_TYPE_AWE32	0x20
    6.33 +#endif
    6.34 +
    6.35 +#ifndef _PATCHKEY
    6.36 +#define _PATCHKEY(id) ((id<<8)|0xfd)
    6.37 +#endif
    6.38 +
    6.39 +/*----------------------------------------------------------------
    6.40 + * patch information record
    6.41 + *----------------------------------------------------------------*/
    6.42 +
    6.43 +/* patch interface header: 16 bytes */
    6.44 +typedef struct awe_patch_info {
    6.45 +	short key;			/* use AWE_PATCH here */
    6.46 +#define AWE_PATCH	_PATCHKEY(0x07)
    6.47 +
    6.48 +	short device_no;		/* synthesizer number */
    6.49 +	unsigned short sf_id;		/* file id (should be zero) */
    6.50 +	short optarg;			/* optional argument */
    6.51 +	int len;			/* data length (without this header) */
    6.52 +
    6.53 +	short type;			/* patch operation type */
    6.54 +#define AWE_LOAD_INFO		0	/* awe_voice_rec */
    6.55 +#define AWE_LOAD_DATA		1	/* awe_sample_info */
    6.56 +#define AWE_OPEN_PATCH		2	/* awe_open_parm */
    6.57 +#define AWE_CLOSE_PATCH		3	/* none */
    6.58 +#define AWE_UNLOAD_PATCH	4	/* none */
    6.59 +#define AWE_REPLACE_DATA	5	/* awe_sample_info (optarg=#channels)*/
    6.60 +#define AWE_MAP_PRESET		6	/* awe_voice_map */
    6.61 +#define AWE_LOAD_CHORUS_FX	0x10	/* awe_chorus_fx_rec (optarg=mode) */
    6.62 +#define AWE_LOAD_REVERB_FX	0x11	/* awe_reverb_fx_rec (optarg=mode) */
    6.63 +
    6.64 +	short reserved;			/* word alignment data */
    6.65 +
    6.66 +	/* the actual patch data begins after this */
    6.67 +#if defined(AWE_COMPAT_030) && AWE_COMPAT_030
    6.68 +	char data[0];
    6.69 +#endif
    6.70 +} awe_patch_info;
    6.71 +
    6.72 +/*#define AWE_PATCH_INFO_SIZE	16*/
    6.73 +#define AWE_PATCH_INFO_SIZE	sizeof(awe_patch_info)
    6.74 +
    6.75 +
    6.76 +/*----------------------------------------------------------------
    6.77 + * open patch
    6.78 + *----------------------------------------------------------------*/
    6.79 +
    6.80 +#define AWE_PATCH_NAME_LEN	32
    6.81 +
    6.82 +typedef struct _awe_open_parm {
    6.83 +	unsigned short type;		/* sample type */
    6.84 +#define AWE_PAT_TYPE_MISC	0
    6.85 +#define AWE_PAT_TYPE_GM		1
    6.86 +#define AWE_PAT_TYPE_GS		2
    6.87 +#define AWE_PAT_TYPE_MT32	3
    6.88 +#define AWE_PAT_TYPE_XG		4
    6.89 +#define AWE_PAT_TYPE_SFX	5
    6.90 +#define AWE_PAT_TYPE_GUS	6
    6.91 +#define AWE_PAT_TYPE_MAP	7
    6.92 +
    6.93 +#define AWE_PAT_LOCKED		0x100	/* lock the samples */
    6.94 +
    6.95 +	short reserved;
    6.96 +	char name[AWE_PATCH_NAME_LEN];
    6.97 +} awe_open_parm;
    6.98 +
    6.99 +/*#define AWE_OPEN_PARM_SIZE	28*/
   6.100 +#define AWE_OPEN_PARM_SIZE	sizeof(awe_open_parm)
   6.101 +
   6.102 +
   6.103 +/*----------------------------------------------------------------
   6.104 + * raw voice information record
   6.105 + *----------------------------------------------------------------*/
   6.106 +
   6.107 +/* wave table envelope & effect parameters to control EMU8000 */
   6.108 +typedef struct _awe_voice_parm {
   6.109 +	unsigned short moddelay;	/* modulation delay (0x8000) */
   6.110 +	unsigned short modatkhld;	/* modulation attack & hold time (0x7f7f) */
   6.111 +	unsigned short moddcysus;	/* modulation decay & sustain (0x7f7f) */
   6.112 +	unsigned short modrelease;	/* modulation release time (0x807f) */
   6.113 +	short modkeyhold, modkeydecay;	/* envelope change per key (not used) */
   6.114 +	unsigned short voldelay;	/* volume delay (0x8000) */
   6.115 +	unsigned short volatkhld;	/* volume attack & hold time (0x7f7f) */
   6.116 +	unsigned short voldcysus;	/* volume decay & sustain (0x7f7f) */
   6.117 +	unsigned short volrelease;	/* volume release time (0x807f) */
   6.118 +	short volkeyhold, volkeydecay;	/* envelope change per key (not used) */
   6.119 +	unsigned short lfo1delay;	/* LFO1 delay (0x8000) */
   6.120 +	unsigned short lfo2delay;	/* LFO2 delay (0x8000) */
   6.121 +	unsigned short pefe;		/* modulation pitch & cutoff (0x0000) */
   6.122 +	unsigned short fmmod;		/* LFO1 pitch & cutoff (0x0000) */
   6.123 +	unsigned short tremfrq;		/* LFO1 volume & freq (0x0000) */
   6.124 +	unsigned short fm2frq2;		/* LFO2 pitch & freq (0x0000) */
   6.125 +	unsigned char cutoff;		/* initial cutoff (0xff) */
   6.126 +	unsigned char filterQ;		/* initial filter Q [0-15] (0x0) */
   6.127 +	unsigned char chorus;		/* chorus send (0x00) */
   6.128 +	unsigned char reverb;		/* reverb send (0x00) */
   6.129 +	unsigned short reserved[4];	/* not used */
   6.130 +} awe_voice_parm;
   6.131 +
   6.132 +#define AWE_VOICE_PARM_SIZE	48
   6.133 +
   6.134 +
   6.135 +/* wave table parameters: 92 bytes */
   6.136 +typedef struct _awe_voice_info {
   6.137 +	unsigned short sf_id;		/* file id (should be zero) */
   6.138 +	unsigned short sample;		/* sample id */
   6.139 +	int start, end;			/* sample offset correction */
   6.140 +	int loopstart, loopend;		/* loop offset correction */
   6.141 +	short rate_offset;		/* sample rate pitch offset */
   6.142 +	unsigned short mode;		/* sample mode */
   6.143 +#define AWE_MODE_ROMSOUND		0x8000
   6.144 +#define AWE_MODE_STEREO			1
   6.145 +#define AWE_MODE_LOOPING		2
   6.146 +#define AWE_MODE_NORELEASE		4	/* obsolete */
   6.147 +#define AWE_MODE_INIT_PARM		8
   6.148 +
   6.149 +	short root;			/* midi root key */
   6.150 +	short tune;			/* pitch tuning (in cents) */
   6.151 +	char low, high;			/* key note range */
   6.152 +	char vellow, velhigh;		/* velocity range */
   6.153 +	char fixkey, fixvel;		/* fixed key, velocity */
   6.154 +	char pan, fixpan;		/* panning, fixed panning */
   6.155 +	short exclusiveClass;		/* exclusive class (0 = none) */
   6.156 +	unsigned char amplitude;	/* sample volume (127 max) */
   6.157 +	unsigned char attenuation;	/* attenuation (0.375dB) */
   6.158 +	short scaleTuning;		/* pitch scale tuning(%), normally 100 */
   6.159 +	awe_voice_parm parm;		/* voice envelope parameters */
   6.160 +	short index;			/* internal index (set by driver) */
   6.161 +} awe_voice_info;
   6.162 +
   6.163 +/*#define AWE_VOICE_INFO_SIZE	92*/
   6.164 +#define AWE_VOICE_INFO_SIZE	sizeof(awe_voice_info)
   6.165 +
   6.166 +/*----------------------------------------------------------------*/
   6.167 +
   6.168 +/* The info entry of awe_voice_rec is changed from 0 to 1
   6.169 + * for some compilers refusing zero size array.
   6.170 + * Due to this change, sizeof(awe_voice_rec) becomes different
   6.171 + * from older versions.
   6.172 + * Use AWE_VOICE_REC_SIZE instead.
   6.173 + */
   6.174 +
   6.175 +/* instrument info header: 4 bytes */
   6.176 +typedef struct _awe_voice_rec_hdr {
   6.177 +	unsigned char bank;		/* midi bank number */
   6.178 +	unsigned char instr;		/* midi preset number */
   6.179 +	char nvoices;			/* number of voices */
   6.180 +	char write_mode;		/* write mode; normally 0 */
   6.181 +#define AWE_WR_APPEND		0	/* append anyway */
   6.182 +#define AWE_WR_EXCLUSIVE	1	/* skip if already exists */
   6.183 +#define AWE_WR_REPLACE		2	/* replace if already exists */
   6.184 +} awe_voice_rec_hdr;
   6.185 +
   6.186 +/*#define AWE_VOICE_REC_SIZE	4*/
   6.187 +#define AWE_VOICE_REC_SIZE	sizeof(awe_voice_rec_hdr)
   6.188 +
   6.189 +/* the standard patch structure for one sample */
   6.190 +typedef struct _awe_voice_rec_patch {
   6.191 +	awe_patch_info		patch;
   6.192 +	awe_voice_rec_hdr	hdr;
   6.193 +	awe_voice_info		info;
   6.194 +} awe_voice_rec_patch;
   6.195 +
   6.196 +
   6.197 +/* obsolete data type */
   6.198 +#if defined(AWE_COMPAT_030) && AWE_COMPAT_030
   6.199 +#define AWE_INFOARRAY_SIZE	0
   6.200 +#else
   6.201 +#define AWE_INFOARRAY_SIZE	1
   6.202 +#endif
   6.203 +
   6.204 +typedef struct _awe_voice_rec {
   6.205 +	unsigned char bank;		/* midi bank number */
   6.206 +	unsigned char instr;		/* midi preset number */
   6.207 +	short nvoices;			/* number of voices */
   6.208 +	/* voice information follows here */
   6.209 +	awe_voice_info info[AWE_INFOARRAY_SIZE];
   6.210 +} awe_voice_rec;
   6.211 +
   6.212 +
   6.213 +/*----------------------------------------------------------------
   6.214 + * sample wave information
   6.215 + *----------------------------------------------------------------*/
   6.216 +
   6.217 +/* wave table sample header: 32 bytes */
   6.218 +typedef struct awe_sample_info {
   6.219 +	unsigned short sf_id;		/* file id (should be zero) */
   6.220 +	unsigned short sample;		/* sample id */
   6.221 +	int start, end;			/* start & end offset */
   6.222 +	int loopstart, loopend;		/* loop start & end offset */
   6.223 +	int size;			/* size (0 = ROM) */
   6.224 +	short checksum_flag;		/* use check sum = 1 */
   6.225 +	unsigned short mode_flags;	/* mode flags */
   6.226 +#define AWE_SAMPLE_8BITS	1	/* wave data is 8bits */
   6.227 +#define AWE_SAMPLE_UNSIGNED	2	/* wave data is unsigned */
   6.228 +#define AWE_SAMPLE_NO_BLANK	4	/* no blank loop is attached */
   6.229 +#define AWE_SAMPLE_SINGLESHOT	8	/* single-shot w/o loop */
   6.230 +#define AWE_SAMPLE_BIDIR_LOOP	16	/* bidirectional looping */
   6.231 +#define AWE_SAMPLE_STEREO_LEFT	32	/* stereo left sound */
   6.232 +#define AWE_SAMPLE_STEREO_RIGHT	64	/* stereo right sound */
   6.233 +#define AWE_SAMPLE_REVERSE_LOOP 128	/* reverse looping */
   6.234 +	unsigned int checksum;		/* check sum */
   6.235 +#if defined(AWE_COMPAT_030) && AWE_COMPAT_030
   6.236 +	unsigned short data[0];		/* sample data follows here */
   6.237 +#endif
   6.238 +} awe_sample_info;
   6.239 +
   6.240 +/*#define AWE_SAMPLE_INFO_SIZE	32*/
   6.241 +#define AWE_SAMPLE_INFO_SIZE	sizeof(awe_sample_info)
   6.242 +
   6.243 +
   6.244 +/*----------------------------------------------------------------
   6.245 + * voice preset mapping
   6.246 + *----------------------------------------------------------------*/
   6.247 +
   6.248 +typedef struct awe_voice_map {
   6.249 +	int map_bank, map_instr, map_key;	/* key = -1 means all keys */
   6.250 +	int src_bank, src_instr, src_key;
   6.251 +} awe_voice_map;
   6.252 +
   6.253 +#define AWE_VOICE_MAP_SIZE	sizeof(awe_voice_map)
   6.254 +
   6.255 +
   6.256 +/*----------------------------------------------------------------
   6.257 + * awe hardware controls
   6.258 + *----------------------------------------------------------------*/
   6.259 +
   6.260 +#define _AWE_DEBUG_MODE			0x00
   6.261 +#define _AWE_REVERB_MODE		0x01
   6.262 +#define _AWE_CHORUS_MODE		0x02
   6.263 +#define _AWE_REMOVE_LAST_SAMPLES	0x03
   6.264 +#define _AWE_INITIALIZE_CHIP		0x04
   6.265 +#define _AWE_SEND_EFFECT		0x05
   6.266 +#define _AWE_TERMINATE_CHANNEL		0x06
   6.267 +#define _AWE_TERMINATE_ALL		0x07
   6.268 +#define _AWE_INITIAL_VOLUME		0x08
   6.269 +#define _AWE_INITIAL_ATTEN	_AWE_INITIAL_VOLUME
   6.270 +#define _AWE_RESET_CHANNEL		0x09
   6.271 +#define _AWE_CHANNEL_MODE		0x0a
   6.272 +#define _AWE_DRUM_CHANNELS		0x0b
   6.273 +#define _AWE_MISC_MODE			0x0c
   6.274 +#define _AWE_RELEASE_ALL		0x0d
   6.275 +#define _AWE_NOTEOFF_ALL		0x0e
   6.276 +#define _AWE_CHN_PRESSURE		0x0f
   6.277 +/*#define _AWE_GET_CURRENT_MODE		0x10*/
   6.278 +#define _AWE_EQUALIZER			0x11
   6.279 +/*#define _AWE_GET_MISC_MODE		0x12*/
   6.280 +/*#define _AWE_GET_FONTINFO		0x13*/
   6.281 +
   6.282 +#define _AWE_MODE_FLAG			0x80
   6.283 +#define _AWE_COOKED_FLAG		0x40	/* not supported */
   6.284 +#define _AWE_MODE_VALUE_MASK		0x3F
   6.285 +
   6.286 +/*----------------------------------------------------------------*/
   6.287 +
   6.288 +#define _AWE_SET_CMD(p,dev,voice,cmd,p1,p2) \
   6.289 +{((char*)(p))[0] = SEQ_PRIVATE;\
   6.290 + ((char*)(p))[1] = dev;\
   6.291 + ((char*)(p))[2] = _AWE_MODE_FLAG|(cmd);\
   6.292 + ((char*)(p))[3] = voice;\
   6.293 + ((unsigned short*)(p))[2] = p1;\
   6.294 + ((unsigned short*)(p))[3] = p2;}
   6.295 +
   6.296 +/* buffered access */
   6.297 +#define _AWE_CMD(dev, voice, cmd, p1, p2) \
   6.298 +{_SEQ_NEEDBUF(8);\
   6.299 + _AWE_SET_CMD(_seqbuf + _seqbufptr, dev, voice, cmd, p1, p2);\
   6.300 + _SEQ_ADVBUF(8);}
   6.301 +
   6.302 +/* direct access */
   6.303 +#define _AWE_CMD_NOW(seqfd,dev,voice,cmd,p1,p2) \
   6.304 +{struct seq_event_rec tmp;\
   6.305 + _AWE_SET_CMD(&tmp, dev, voice, cmd, p1, p2);\
   6.306 + ioctl(seqfd, SNDCTL_SEQ_OUTOFBAND, &tmp);}
   6.307 +
   6.308 +/*----------------------------------------------------------------*/
   6.309 +
   6.310 +/* set debugging mode */
   6.311 +#define AWE_DEBUG_MODE(dev,p1)	_AWE_CMD(dev, 0, _AWE_DEBUG_MODE, p1, 0)
   6.312 +/* set reverb mode; from 0 to 7 */
   6.313 +#define AWE_REVERB_MODE(dev,p1)	_AWE_CMD(dev, 0, _AWE_REVERB_MODE, p1, 0)
   6.314 +/* set chorus mode; from 0 to 7 */
   6.315 +#define AWE_CHORUS_MODE(dev,p1)	_AWE_CMD(dev, 0, _AWE_CHORUS_MODE, p1, 0)
   6.316 +
   6.317 +/* reset channel */
   6.318 +#define AWE_RESET_CHANNEL(dev,ch) _AWE_CMD(dev, ch, _AWE_RESET_CHANNEL, 0, 0)
   6.319 +#define AWE_RESET_CONTROL(dev,ch) _AWE_CMD(dev, ch, _AWE_RESET_CHANNEL, 1, 0)
   6.320 +
   6.321 +/* send an effect to all layers */
   6.322 +#define AWE_SEND_EFFECT(dev,voice,type,value) _AWE_CMD(dev,voice,_AWE_SEND_EFFECT,type,value)
   6.323 +#define AWE_ADD_EFFECT(dev,voice,type,value) _AWE_CMD(dev,voice,_AWE_SEND_EFFECT,((type)|0x80),value)
   6.324 +#define AWE_UNSET_EFFECT(dev,voice,type) _AWE_CMD(dev,voice,_AWE_SEND_EFFECT,((type)|0x40),0)
   6.325 +/* send an effect to a layer */
   6.326 +#define AWE_SEND_LAYER_EFFECT(dev,voice,layer,type,value) _AWE_CMD(dev,voice,_AWE_SEND_EFFECT,((layer+1)<<8|(type)),value)
   6.327 +#define AWE_ADD_LAYER_EFFECT(dev,voice,layer,type,value) _AWE_CMD(dev,voice,_AWE_SEND_EFFECT,((layer+1)<<8|(type)|0x80),value)
   6.328 +#define AWE_UNSET_LAYER_EFFECT(dev,voice,layer,type) _AWE_CMD(dev,voice,_AWE_SEND_EFFECT,((layer+1)<<8|(type)|0x40),0)
   6.329 +
   6.330 +/* terminate sound on the channel/voice */
   6.331 +#define AWE_TERMINATE_CHANNEL(dev,voice) _AWE_CMD(dev,voice,_AWE_TERMINATE_CHANNEL,0,0)
   6.332 +/* terminate all sounds */
   6.333 +#define AWE_TERMINATE_ALL(dev) _AWE_CMD(dev, 0, _AWE_TERMINATE_ALL, 0, 0)
   6.334 +/* release all sounds (w/o sustain effect) */
   6.335 +#define AWE_RELEASE_ALL(dev) _AWE_CMD(dev, 0, _AWE_RELEASE_ALL, 0, 0)
   6.336 +/* note off all sounds (w sustain effect) */
   6.337 +#define AWE_NOTEOFF_ALL(dev) _AWE_CMD(dev, 0, _AWE_NOTEOFF_ALL, 0, 0)
   6.338 +
   6.339 +/* set initial attenuation */
   6.340 +#define AWE_INITIAL_VOLUME(dev,atten) _AWE_CMD(dev, 0, _AWE_INITIAL_VOLUME, atten, 0)
   6.341 +#define AWE_INITIAL_ATTEN  AWE_INITIAL_VOLUME
   6.342 +/* relative attenuation */
   6.343 +#define AWE_SET_ATTEN(dev,atten)  _AWE_CMD(dev, 0, _AWE_INITIAL_VOLUME, atten, 1)
   6.344 +
   6.345 +/* set channel playing mode; mode=0/1/2 */
   6.346 +#define AWE_SET_CHANNEL_MODE(dev,mode) _AWE_CMD(dev, 0, _AWE_CHANNEL_MODE, mode, 0)
   6.347 +#define AWE_PLAY_INDIRECT	0	/* indirect voice mode (default) */
   6.348 +#define AWE_PLAY_MULTI		1	/* multi note voice mode */
   6.349 +#define AWE_PLAY_DIRECT		2	/* direct single voice mode */
   6.350 +#define AWE_PLAY_MULTI2		3	/* sequencer2 mode; used internally */
   6.351 +
   6.352 +/* set drum channel mask; channels is 32bit long value */
   6.353 +#define AWE_DRUM_CHANNELS(dev,channels) _AWE_CMD(dev, 0, _AWE_DRUM_CHANNELS, ((channels) & 0xffff), ((channels) >> 16))
   6.354 +
   6.355 +/* set bass and treble control; values are from 0 to 11 */
   6.356 +#define AWE_EQUALIZER(dev,bass,treble) _AWE_CMD(dev, 0, _AWE_EQUALIZER, bass, treble)
   6.357 +
   6.358 +/* remove last loaded samples */
   6.359 +#define AWE_REMOVE_LAST_SAMPLES(seqfd,dev) _AWE_CMD_NOW(seqfd, dev, 0, _AWE_REMOVE_LAST_SAMPLES, 0, 0)
   6.360 +/* initialize emu8000 chip */
   6.361 +#define AWE_INITIALIZE_CHIP(seqfd,dev) _AWE_CMD_NOW(seqfd, dev, 0, _AWE_INITIALIZE_CHIP, 0, 0)
   6.362 +
   6.363 +/* set miscellaneous modes; meta command */
   6.364 +#define AWE_MISC_MODE(dev,mode,value) _AWE_CMD(dev, 0, _AWE_MISC_MODE, mode, value)
   6.365 +/* exclusive sound off; 1=off */
   6.366 +#define AWE_EXCLUSIVE_SOUND(dev,mode) AWE_MISC_MODE(dev,AWE_MD_EXCLUSIVE_SOUND,mode)
   6.367 +/* default GUS bank number */
   6.368 +#define AWE_SET_GUS_BANK(dev,bank) AWE_MISC_MODE(dev,AWE_MD_GUS_BANK,bank)
   6.369 +/* change panning position in realtime; 0=don't 1=do */
   6.370 +#define AWE_REALTIME_PAN(dev,mode) AWE_MISC_MODE(dev,AWE_MD_REALTIME_PAN,mode)
   6.371 +
   6.372 +/* extended pressure controls; not portable with other sound drivers */
   6.373 +#define AWE_KEY_PRESSURE(dev,ch,note,vel) SEQ_START_NOTE(dev,ch,(note)+128,vel)
   6.374 +#define AWE_CHN_PRESSURE(dev,ch,vel) _AWE_CMD(dev,ch,_AWE_CHN_PRESSURE,vel,0)
   6.375 +
   6.376 +/*----------------------------------------------------------------*/
   6.377 +
   6.378 +/* reverb mode parameters */
   6.379 +#define	AWE_REVERB_ROOM1	0
   6.380 +#define AWE_REVERB_ROOM2	1
   6.381 +#define	AWE_REVERB_ROOM3	2
   6.382 +#define	AWE_REVERB_HALL1	3
   6.383 +#define	AWE_REVERB_HALL2	4
   6.384 +#define	AWE_REVERB_PLATE	5
   6.385 +#define	AWE_REVERB_DELAY	6
   6.386 +#define	AWE_REVERB_PANNINGDELAY 7
   6.387 +#define AWE_REVERB_PREDEFINED	8
   6.388 +/* user can define reverb modes up to 32 */
   6.389 +#define AWE_REVERB_NUMBERS	32
   6.390 +
   6.391 +typedef struct awe_reverb_fx_rec {
   6.392 +	unsigned short parms[28];
   6.393 +} awe_reverb_fx_rec;
   6.394 +
   6.395 +/*----------------------------------------------------------------*/
   6.396 +
   6.397 +/* chorus mode parameters */
   6.398 +#define AWE_CHORUS_1		0
   6.399 +#define	AWE_CHORUS_2		1
   6.400 +#define	AWE_CHORUS_3		2
   6.401 +#define	AWE_CHORUS_4		3
   6.402 +#define	AWE_CHORUS_FEEDBACK	4
   6.403 +#define	AWE_CHORUS_FLANGER	5
   6.404 +#define	AWE_CHORUS_SHORTDELAY	6
   6.405 +#define	AWE_CHORUS_SHORTDELAY2	7
   6.406 +#define AWE_CHORUS_PREDEFINED	8
   6.407 +/* user can define chorus modes up to 32 */
   6.408 +#define AWE_CHORUS_NUMBERS	32
   6.409 +
   6.410 +typedef struct awe_chorus_fx_rec {
   6.411 +	unsigned short feedback;	/* feedback level (0xE600-0xE6FF) */
   6.412 +	unsigned short delay_offset;	/* delay (0-0x0DA3) [1/44100 sec] */
   6.413 +	unsigned short lfo_depth;	/* LFO depth (0xBC00-0xBCFF) */
   6.414 +	unsigned int delay;	/* right delay (0-0xFFFFFFFF) [1/256/44100 sec] */
   6.415 +	unsigned int lfo_freq;		/* LFO freq LFO freq (0-0xFFFFFFFF) */
   6.416 +} awe_chorus_fx_rec;
   6.417 +
   6.418 +/*----------------------------------------------------------------*/
   6.419 +
   6.420 +/* misc mode types */
   6.421 +enum {
   6.422 +/* 0*/	AWE_MD_EXCLUSIVE_OFF,	/* obsolete */
   6.423 +/* 1*/	AWE_MD_EXCLUSIVE_ON,	/* obsolete */
   6.424 +/* 2*/	AWE_MD_VERSION,		/* read only */
   6.425 +/* 3*/	AWE_MD_EXCLUSIVE_SOUND,	/* ignored */
   6.426 +/* 4*/	AWE_MD_REALTIME_PAN,	/* 0/1: do realtime pan change (default=1) */
   6.427 +/* 5*/	AWE_MD_GUS_BANK,	/* bank number for GUS patches (default=0) */
   6.428 +/* 6*/	AWE_MD_KEEP_EFFECT,	/* 0/1: keep effect values, (default=0) */
   6.429 +/* 7*/	AWE_MD_ZERO_ATTEN,	/* attenuation of max volume (default=32) */
   6.430 +/* 8*/	AWE_MD_CHN_PRIOR,	/* 0/1: set MIDI channel priority mode (default=1) */
   6.431 +/* 9*/	AWE_MD_MOD_SENSE,	/* integer: modwheel sensitivity (def=18) */
   6.432 +/*10*/	AWE_MD_DEF_PRESET,	/* integer: default preset number (def=0) */
   6.433 +/*11*/	AWE_MD_DEF_BANK,	/* integer: default bank number (def=0) */
   6.434 +/*12*/	AWE_MD_DEF_DRUM,	/* integer: default drumset number (def=0) */
   6.435 +/*13*/	AWE_MD_TOGGLE_DRUM_BANK, /* 0/1: toggle drum flag with bank# (def=0) */
   6.436 +	AWE_MD_END,
   6.437 +};
   6.438 +
   6.439 +/*----------------------------------------------------------------*/
   6.440 +
   6.441 +/* effect parameters */
   6.442 +enum {
   6.443 +
   6.444 +/* modulation envelope parameters */
   6.445 +/* 0*/	AWE_FX_ENV1_DELAY,	/* WORD: ENVVAL */
   6.446 +/* 1*/	AWE_FX_ENV1_ATTACK,	/* BYTE: up ATKHLD */
   6.447 +/* 2*/	AWE_FX_ENV1_HOLD,	/* BYTE: lw ATKHLD */
   6.448 +/* 3*/	AWE_FX_ENV1_DECAY,	/* BYTE: lw DCYSUS */
   6.449 +/* 4*/	AWE_FX_ENV1_RELEASE,	/* BYTE: lw DCYSUS */
   6.450 +/* 5*/	AWE_FX_ENV1_SUSTAIN,	/* BYTE: up DCYSUS */
   6.451 +/* 6*/	AWE_FX_ENV1_PITCH,	/* BYTE: up PEFE */
   6.452 +/* 7*/	AWE_FX_ENV1_CUTOFF,	/* BYTE: lw PEFE */
   6.453 +
   6.454 +/* volume envelope parameters */
   6.455 +/* 8*/	AWE_FX_ENV2_DELAY,	/* WORD: ENVVOL */
   6.456 +/* 9*/	AWE_FX_ENV2_ATTACK,	/* BYTE: up ATKHLDV */
   6.457 +/*10*/	AWE_FX_ENV2_HOLD,	/* BYTE: lw ATKHLDV */
   6.458 +/*11*/	AWE_FX_ENV2_DECAY,	/* BYTE: lw DCYSUSV */
   6.459 +/*12*/	AWE_FX_ENV2_RELEASE,	/* BYTE: lw DCYSUSV */
   6.460 +/*13*/	AWE_FX_ENV2_SUSTAIN,	/* BYTE: up DCYSUSV */
   6.461 +	
   6.462 +/* LFO1 (tremolo & vibrato) parameters */
   6.463 +/*14*/	AWE_FX_LFO1_DELAY,	/* WORD: LFO1VAL */
   6.464 +/*15*/	AWE_FX_LFO1_FREQ,	/* BYTE: lo TREMFRQ */
   6.465 +/*16*/	AWE_FX_LFO1_VOLUME,	/* BYTE: up TREMFRQ */
   6.466 +/*17*/	AWE_FX_LFO1_PITCH,	/* BYTE: up FMMOD */
   6.467 +/*18*/	AWE_FX_LFO1_CUTOFF,	/* BYTE: lo FMMOD */
   6.468 +
   6.469 +/* LFO2 (vibrato) parameters */
   6.470 +/*19*/	AWE_FX_LFO2_DELAY,	/* WORD: LFO2VAL */
   6.471 +/*20*/	AWE_FX_LFO2_FREQ,	/* BYTE: lo FM2FRQ2 */
   6.472 +/*21*/	AWE_FX_LFO2_PITCH,	/* BYTE: up FM2FRQ2 */
   6.473 +
   6.474 +/* Other overall effect parameters */
   6.475 +/*22*/	AWE_FX_INIT_PITCH,	/* SHORT: pitch offset */
   6.476 +/*23*/	AWE_FX_CHORUS,		/* BYTE: chorus effects send (0-255) */
   6.477 +/*24*/	AWE_FX_REVERB,		/* BYTE: reverb effects send (0-255) */
   6.478 +/*25*/	AWE_FX_CUTOFF,		/* BYTE: up IFATN */
   6.479 +/*26*/	AWE_FX_FILTERQ,		/* BYTE: up CCCA */
   6.480 +
   6.481 +/* Sample / loop offset changes */
   6.482 +/*27*/	AWE_FX_SAMPLE_START,	/* SHORT: offset */
   6.483 +/*28*/	AWE_FX_LOOP_START,	/* SHORT: offset */
   6.484 +/*29*/	AWE_FX_LOOP_END,	/* SHORT: offset */
   6.485 +/*30*/	AWE_FX_COARSE_SAMPLE_START,	/* SHORT: upper word offset */
   6.486 +/*31*/	AWE_FX_COARSE_LOOP_START,	/* SHORT: upper word offset */
   6.487 +/*32*/	AWE_FX_COARSE_LOOP_END,		/* SHORT: upper word offset */
   6.488 +/*33*/	AWE_FX_ATTEN,		/* BYTE: lo IFATN */
   6.489 +
   6.490 +	AWE_FX_END,
   6.491 +};
   6.492 +
   6.493 +#endif /* AWE_VOICE_H */
     7.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     7.2 +++ b/native_midi_gpl/emumidi.c	Wed Feb 13 19:07:39 2002 +0000
     7.3 @@ -0,0 +1,390 @@
     7.4 +/************************************************************************
     7.5 +   emumidi.c  -- emulation of midi device for FM/OPL3/GUS
     7.6 +
     7.7 +   Copyright (C) 1994-1996 Nathan I. Laredo
     7.8 +
     7.9 +   This program is modifiable/redistributable under the terms
    7.10 +   of the GNU General Public Licence.
    7.11 +
    7.12 +   You should have received a copy of the GNU General Public License
    7.13 +   along with this program; if not, write to the Free Software
    7.14 +   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
    7.15 +   Send your comments and all your spare pocket change to
    7.16 +   laredo@gnu.ai.mit.edu (Nathan Laredo) or to PSC 1, BOX 709, 2401
    7.17 +   Kelly Drive, Lackland AFB, TX 78236-5128, USA.
    7.18 + *************************************************************************/
    7.19 +/*    edited by Peter Kutak         */
    7.20 +/*    email : kutak@stonline.sk     */
    7.21 +
    7.22 +#if defined(linux) || defined(__FreeBSD__)
    7.23 +
    7.24 +#include "emumidi.h"
    7.25 +
    7.26 +SEQ_USE_EXTBUF();
    7.27 +
    7.28 +extern int seqfd, play_ext, play_gus, play_fm, play_awe;
    7.29 +extern int gus_dev, sb_dev, ext_dev, awe_dev;
    7.30 +extern struct synth_info card_info[MAX_CARDS];
    7.31 +extern int chanmask, perc, ticks, dochan, wantopl3, MT32;
    7.32 +extern int patchloaded[256], fmloaded[256], useprog[16];
    7.33 +int note_vel[16][128];
    7.34 +struct voicestate voice[2][36];
    7.35 +struct chanstate channel[16];
    7.36 +#define C_GUS 0
    7.37 +#define C_FM 1
    7.38 +#define CN (ISGUS(chn) ? C_GUS : C_FM)
    7.39 +#define CHANNEL (dochan ? chn : 0)
    7.40 +
    7.41 +void load_sysex(length, data, type)
    7.42 +int length;
    7.43 +unsigned char *data;
    7.44 +int type;
    7.45 +{
    7.46 +    unsigned long int i, j;
    7.47 +
    7.48 +    /*
    7.49 +     * If the system exclusive is for roland, evaluate it.  More than
    7.50 +     * roland could be evaluated here if i had documentation.  Please
    7.51 +     * submit patches for any other hardware to laredo@gnu.ai.mit.edu
    7.52 +     * Complete emulation of all GS sysex messages in the works....
    7.53 +     */
    7.54 +    if (length > 7 && data[0] == 0x41 && data[2] == 0x42 && data[3] == 0x12) {
    7.55 +	/* GS DATA SET MESSAGES */
    7.56 +	if (data[4] == 0x40 && (data[5] & 0xf0) == 0x10 && data[6] == 0x15) {
    7.57 +		/* USE RHYTHM PART */
    7.58 +		if (!(i = (data[5] & 0xf)))
    7.59 +		    i = 0x09;
    7.60 +		else if (i < 10)
    7.61 +		    i--;
    7.62 +		i = 1<<i;
    7.63 +		if (data[7])
    7.64 +		    perc |= i;
    7.65 +		else
    7.66 +		    perc &= ~i;
    7.67 +	}
    7.68 +	if ((data[4] == 0x40 || data[4] == 0) &&
    7.69 +	    data[5] == 0x00 && data[6] == 0x7f) { /* GS RESET */
    7.70 +		perc = 0x0200;	/* percussion in channel 10 only */
    7.71 +		for (i = 0; i < 16; i++) {	/* set state info */
    7.72 +		    for (j = 0; j < 128; j++)
    7.73 +			note_vel[i][j] = 0;
    7.74 +		    channel[i].bender = channel[i].oldbend = 8192;
    7.75 +		    channel[i].bender_range = channel[i].oldrange = 2;
    7.76 +		    channel[i].controller[CTL_PAN] = 64;
    7.77 +		    channel[i].controller[CTL_SUSTAIN] = 0;
    7.78 +    		}
    7.79 +	}
    7.80 +    }
    7.81 +    if (!play_ext)
    7.82 +	return;
    7.83 +    if (type == MIDI_SYSTEM_PREFIX)
    7.84 +	SEQ_MIDIOUT(ext_dev, MIDI_SYSTEM_PREFIX);
    7.85 +    for (i = 0; i < length; i++)
    7.86 +	SEQ_MIDIOUT(ext_dev, data[i]);
    7.87 +}
    7.88 +
    7.89 +int seq_set_patch(chn, pgm)
    7.90 +int chn, pgm;
    7.91 +{
    7.92 +    if (MT32 && pgm < 128)
    7.93 +	pgm = mt32pgm[pgm];
    7.94 +    if (useprog[chn])
    7.95 +	pgm = useprog[chn] - 1;
    7.96 +    if (ISMIDI(chn)) {
    7.97 +	SEQ_MIDIOUT(ext_dev, MIDI_PGM_CHANGE + CHANNEL);
    7.98 +	SEQ_MIDIOUT(ext_dev, pgm);
    7.99 +    } else if (ISAWE(chn)) {
   7.100 +	SEQ_SET_PATCH(awe_dev, chn, pgm);
   7.101 +    } else if (ISPERC(chn)) {
   7.102 +	if (ISGUS(chn) && patchloaded[pgm] != 1)
   7.103 +	    return -1;
   7.104 +	else if (ISFM(chn) && !fmloaded[pgm])
   7.105 +	    return -1;
   7.106 +    } else if (ISGUS(chn) && patchloaded[pgm] != 1)
   7.107 +	/* find first loaded gus program to replace missing one */
   7.108 +	for (pgm = 0; patchloaded[pgm] != 1; pgm++);
   7.109 +    return (channel[chn].program = pgm);
   7.110 +}
   7.111 +
   7.112 +/* finetune returns exact frequency with bender applied.  Not used */
   7.113 +/*
   7.114 +int finetune(chn, note)
   7.115 +int chn, note;
   7.116 +{
   7.117 +    long int r, b, d;
   7.118 +
   7.119 +    r = channel[chn].bender_range;
   7.120 +    b = channel[chn].bender - 8192;
   7.121 +    if (!b || r + note > 127 || r - note < 0)
   7.122 +	return n_freq[note];
   7.123 +    r = n_freq[note + r] - n_freq[note - r];
   7.124 +    d = b * r;
   7.125 +    d /= 8192;
   7.126 +    return n_freq[note] + d;
   7.127 +
   7.128 +}
   7.129 +*/
   7.130 +extern int _seqbufptr;
   7.131 +
   7.132 +void seq_stop_note(dev, chn, note, vel)
   7.133 +int dev, chn, note, vel;
   7.134 +{
   7.135 +    int i, card = CN;
   7.136 +
   7.137 +    note_vel[chn][note] = 0;
   7.138 +    if (ISMIDI(chn)) {
   7.139 +	SEQ_MIDIOUT(dev, MIDI_NOTEOFF + CHANNEL);
   7.140 +	SEQ_MIDIOUT(dev, note);
   7.141 +	SEQ_MIDIOUT(dev, vel);
   7.142 +    } else if (ISAWE(chn)) {
   7.143 +	SEQ_STOP_NOTE(dev, chn, note, vel);
   7.144 +    } else
   7.145 +	for (i = 0; i < card_info[dev].nr_voices; i++)
   7.146 +	    if (voice[card][i].channel == chn &&
   7.147 +		voice[card][i].note == note) {
   7.148 +		voice[card][i].dead = 1;
   7.149 +		voice[card][i].timestamp /= 2;
   7.150 +		if (!channel[chn].controller[CTL_SUSTAIN] && !ISPERC(chn))
   7.151 +		    SEQ_STOP_NOTE(dev, i, note, vel);
   7.152 +	    }
   7.153 +}
   7.154 +
   7.155 +void seq_key_pressure(dev, chn, note, vel)
   7.156 +int dev, chn, note, vel;
   7.157 +{
   7.158 +    int i, card = CN;
   7.159 +
   7.160 +    if (ISMIDI(chn)) {
   7.161 +	SEQ_MIDIOUT(dev, MIDI_KEY_PRESSURE + CHANNEL);
   7.162 +	SEQ_MIDIOUT(dev, note);
   7.163 +	SEQ_MIDIOUT(dev, vel);
   7.164 +    } else if (ISAWE(chn)) {
   7.165 +	AWE_KEY_PRESSURE(dev, chn, note, vel);
   7.166 +    } else
   7.167 +	for (i = 0; i < card_info[dev].nr_voices; i++)
   7.168 +	    if (voice[card][i].channel == chn &&
   7.169 +		voice[card][i].note == note)
   7.170 +		SEQ_KEY_PRESSURE(dev, i, note, vel);
   7.171 +}
   7.172 +
   7.173 +int new_voice(dev, chn)
   7.174 +int dev, chn;
   7.175 +{
   7.176 +    int i, oldest, last, card = CN;
   7.177 +
   7.178 +    if (ISFM(chn) && fmloaded[channel[chn].program] == OPL3_PATCH)
   7.179 +	last = 6;		/* 4-op voice can only use first six voices */
   7.180 +    else
   7.181 +	last = card_info[dev].nr_voices;
   7.182 +
   7.183 +    for (i = oldest = 0; i < last; i++)
   7.184 +	if (voice[card][i].timestamp < voice[card][oldest].timestamp)
   7.185 +	    oldest = i;
   7.186 +    return oldest;
   7.187 +}
   7.188 +
   7.189 +void seq_start_note(dev, chn, note, vel)
   7.190 +int dev, chn, note, vel;
   7.191 +{
   7.192 +    int v, c, card = CN;
   7.193 +
   7.194 +    note_vel[chn][note] = vel;
   7.195 +    if (ISMIDI(chn)) {
   7.196 +	SEQ_MIDIOUT(dev, MIDI_NOTEON + CHANNEL);
   7.197 +	SEQ_MIDIOUT(dev, note);
   7.198 +	SEQ_MIDIOUT(dev, vel);
   7.199 +    } else if (vel == 0)
   7.200 +	seq_stop_note(dev, chn, note, 64);
   7.201 +    else if (ISAWE(chn)) {
   7.202 +	SEQ_START_NOTE(dev, chn, note, vel);
   7.203 +    } else {
   7.204 +	v = new_voice(dev, chn);
   7.205 +	SEQ_SET_PATCH(dev, v, channel[chn].program);
   7.206 +	SEQ_BENDER_RANGE(dev, v, (channel[chn].bender_range * 100));
   7.207 +	SEQ_BENDER(dev, v, channel[chn].bender);
   7.208 +	SEQ_CONTROL(dev, v, CTL_PAN,
   7.209 +		    channel[chn].controller[CTL_PAN]);
   7.210 +	SEQ_START_NOTE(dev, v, note, vel);
   7.211 +	voice[card][v].note = note;
   7.212 +	voice[card][v].channel = chn;
   7.213 +	voice[card][v].timestamp = ticks;
   7.214 +	voice[card][v].dead = 0;
   7.215 +	if ((c = channel[chn].controller[CTL_CHORUS_DEPTH] * 8)) {
   7.216 +	    if (channel[chn].bender_range)
   7.217 +		c /= channel[chn].bender_range;
   7.218 +	    v = new_voice(dev, chn);
   7.219 +	    SEQ_SET_PATCH(dev, v, channel[chn].program);
   7.220 +	    SEQ_BENDER_RANGE(dev, v, (channel[chn].bender_range * 100));
   7.221 +	    if (channel[chn].bender + c < 0x4000) {
   7.222 +		SEQ_BENDER(dev, v, channel[chn].bender + c);
   7.223 +	    } else {
   7.224 +		SEQ_BENDER(dev, v, channel[chn].bender - c);
   7.225 +	    }
   7.226 +	    /* put chorus note on the "extreme" side */
   7.227 +	    c = channel[chn].controller[CTL_PAN];
   7.228 +	    if (c < 64)
   7.229 +		c = 0;
   7.230 +	    else if (c > 64)
   7.231 +		c = 127;
   7.232 +	    SEQ_CONTROL(dev, v, CTL_PAN, c);
   7.233 +	    SEQ_START_NOTE(dev, v, note, vel);
   7.234 +	    voice[card][v].note = note;
   7.235 +	    voice[card][v].channel = chn;
   7.236 +	    /* allow chorus note to be stolen very quickly */
   7.237 +	    voice[card][v].timestamp = ticks / 2;
   7.238 +	    voice[card][v].dead = 0;
   7.239 +	}
   7.240 +    }
   7.241 +}
   7.242 +
   7.243 +static int rpn1[16] =
   7.244 +{127, 127, 127, 127, 127, 127, 127, 127,
   7.245 + 127, 127, 127, 127, 127, 127, 127, 127};
   7.246 +static int rpn2[16] =
   7.247 +{127, 127, 127, 127, 127, 127, 127, 127,
   7.248 + 127, 127, 127, 127, 127, 127, 127, 127};
   7.249 +
   7.250 +void seq_control(dev, chn, p1, p2)
   7.251 +int dev, chn, p1, p2;
   7.252 +{
   7.253 +    int i, card = CN;
   7.254 +
   7.255 +    channel[chn].controller[p1] = p2;
   7.256 +
   7.257 +    if (ISMIDI(chn)) {
   7.258 +	SEQ_MIDIOUT(dev, MIDI_CTL_CHANGE + CHANNEL);
   7.259 +	SEQ_MIDIOUT(dev, p1);
   7.260 +	SEQ_MIDIOUT(dev, p2);
   7.261 +    }
   7.262 +    if (p1 == 7 || p1 == 39)
   7.263 +	return;
   7.264 +    switch (p1) {
   7.265 +    case CTL_SUSTAIN:
   7.266 +	if (ISAWE(chn)) {
   7.267 +	    SEQ_CONTROL(dev, chn, p1, p2);
   7.268 +	} else if (!ISMIDI(chn))
   7.269 +	    if (p1 == CTL_SUSTAIN && !p2) {
   7.270 +		for (i = 0; i < card_info[card].nr_voices; i++)
   7.271 +		    if (voice[card][i].channel == chn
   7.272 +			&& voice[card][i].dead) {
   7.273 +			SEQ_STOP_NOTE(dev, i, voice[card][i].note, 64);
   7.274 +			voice[card][i].dead = 0;
   7.275 +		    }
   7.276 +	    }
   7.277 +	break;
   7.278 +    case CTL_REGIST_PARM_NUM_MSB:
   7.279 +	rpn1[chn] = p2;
   7.280 +	break;
   7.281 +    case CTL_REGIST_PARM_NUM_LSB:
   7.282 +	rpn2[chn] = p2;
   7.283 +	break;
   7.284 +    case CTL_DATA_ENTRY:
   7.285 +	if (rpn1[chn] == 0 && rpn2[chn] == 0) {
   7.286 +	    channel[chn].oldrange = channel[chn].bender_range;
   7.287 +	    channel[chn].bender_range = p2;
   7.288 +	    rpn1[chn] = rpn2[chn] = 127;
   7.289 +	    if (ISAWE(chn)) {
   7.290 +		SEQ_BENDER_RANGE(dev, chn, p2 * 100);
   7.291 +	    } else if (!ISMIDI(chn))
   7.292 +		for (i = 0; i < card_info[card].nr_voices; i++)
   7.293 +		    SEQ_BENDER_RANGE(dev, i, p2 * 100);
   7.294 +	}
   7.295 +	break;
   7.296 +    default:
   7.297 +	/* sent on the off chance the sound driver is enhanced */
   7.298 +	if (ISAWE(chn)) {
   7.299 +	    SEQ_CONTROL(dev, chn, p1, p2);
   7.300 +	} else if (!ISMIDI(chn) && (p1 < 0x10 || (p1 & 0xf0) == 0x50))
   7.301 +	    for (i = 0; i < card_info[card].nr_voices; i++)
   7.302 +		if (voice[card][i].channel == chn)
   7.303 +		    SEQ_CONTROL(dev, i, p1, p2);
   7.304 +	break;
   7.305 +    }
   7.306 +}
   7.307 +
   7.308 +void seq_chn_pressure(dev, chn, vel)
   7.309 +int dev, chn, vel;
   7.310 +{
   7.311 +    int card = CN, i;
   7.312 +
   7.313 +    channel[chn].pressure = vel;
   7.314 +    if (ISMIDI(chn)) {
   7.315 +	SEQ_MIDIOUT(dev, MIDI_CHN_PRESSURE + CHANNEL);
   7.316 +	SEQ_MIDIOUT(dev, vel);
   7.317 +    } else if (ISAWE(chn)) {
   7.318 +	AWE_CHN_PRESSURE(dev, chn, vel);
   7.319 +    } else
   7.320 +	for (i = 0; i < card_info[dev].nr_voices; i++)
   7.321 +	    if (voice[card][i].channel == chn)
   7.322 +		SEQ_KEY_PRESSURE(dev, i, voice[card][i].note, vel);
   7.323 +}
   7.324 +
   7.325 +void seq_bender(dev, chn, p1, p2)
   7.326 +int dev, chn, p1, p2;
   7.327 +{
   7.328 +    int card = CN, i, val;
   7.329 +
   7.330 +    val = (p2 << 7) + p1;
   7.331 +    channel[chn].oldbend = channel[chn].bender;
   7.332 +    channel[chn].bender = val;
   7.333 +
   7.334 +    if (ISMIDI(chn)) {
   7.335 +	SEQ_MIDIOUT(dev, MIDI_PITCH_BEND + CHANNEL);
   7.336 +	SEQ_MIDIOUT(dev, p1);
   7.337 +	SEQ_MIDIOUT(dev, p2);
   7.338 +    } else if (ISAWE(chn)) {
   7.339 +	SEQ_BENDER(dev, chn, val);
   7.340 +    } else
   7.341 +	for (i = 0; i < card_info[dev].nr_voices; i++)
   7.342 +	    if (voice[card][i].channel == chn)
   7.343 +		SEQ_BENDER(dev, i, val);
   7.344 +}
   7.345 +
   7.346 +void seq_reset()
   7.347 +{
   7.348 +    int i, j;
   7.349 +
   7.350 +    _seqbufptr = ticks = 0;
   7.351 +    ioctl(seqfd, SNDCTL_SEQ_RESET);
   7.352 +    for (i = 0; i < 16; i++) {
   7.353 +	if (ISMIDI(i)) {
   7.354 +	    seq_control(ext_dev,i,0,0);
   7.355 +	    seq_control(ext_dev,i,32,0);
   7.356 +	}
   7.357 +	seq_set_patch(i, 0);
   7.358 +	for (j = 0; j < 128; j++)
   7.359 +	    note_vel[i][j] = 0;
   7.360 +	channel[i].bender = channel[i].oldbend = 8192;
   7.361 +	channel[i].bender_range = channel[i].oldrange = 2;
   7.362 +	channel[i].controller[CTL_PAN] = 64;
   7.363 +	channel[i].controller[CTL_SUSTAIN] = 0;
   7.364 +    }
   7.365 +    if (play_gus)
   7.366 +	for (i = 0; i < card_info[gus_dev].nr_voices; i++) {
   7.367 +	    SEQ_CONTROL(gus_dev, i, SEQ_VOLMODE, VOL_METHOD_LINEAR);
   7.368 +	    if (voice[0][i].note)
   7.369 +		SEQ_STOP_NOTE(gus_dev, i, voice[0][i].note, 64);
   7.370 +	    voice[0][i].dead = voice[0][i].timestamp = -1;
   7.371 +	}
   7.372 +    if (play_fm) {
   7.373 +	if (wantopl3)
   7.374 +	    ioctl(seqfd, SNDCTL_FM_4OP_ENABLE, &sb_dev);
   7.375 +	for (i = 0; i < card_info[sb_dev].nr_voices; i++) {
   7.376 +	    SEQ_CONTROL(sb_dev, i, SEQ_VOLMODE, VOL_METHOD_LINEAR);
   7.377 +	    if (voice[1][i].note)
   7.378 +		SEQ_STOP_NOTE(sb_dev, i, voice[1][i].note, 64);
   7.379 +	    voice[1][i].dead = voice[1][i].timestamp = -1;
   7.380 +	}
   7.381 +    }
   7.382 +    if (play_awe) {
   7.383 +	AWE_SET_CHANNEL_MODE(awe_dev, 1);
   7.384 +	AWE_DRUM_CHANNELS(awe_dev, perc);
   7.385 +	AWE_TERMINATE_ALL(awe_dev);
   7.386 +	for (i = 0; i < card_info[awe_dev].nr_voices; i++) {
   7.387 +	    voice[0][i].dead = voice[0][i].timestamp = -1;
   7.388 +	}
   7.389 +    }
   7.390 +    SEQ_DUMPBUF();
   7.391 +}
   7.392 +
   7.393 +#endif /* linux || FreeBSD */
     8.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     8.2 +++ b/native_midi_gpl/emumidi.h	Wed Feb 13 19:07:39 2002 +0000
     8.3 @@ -0,0 +1,63 @@
     8.4 +/************************************************************************
     8.5 +   emumidi.h  -- tables and includes required by emumidi.c
     8.6 +
     8.7 +   Copyright (C) 1994-1996 Nathan I. Laredo
     8.8 +
     8.9 +   This program is modifiable/redistributable under the terms
    8.10 +   of the GNU General Public Licence.
    8.11 +
    8.12 +   You should have received a copy of the GNU General Public License
    8.13 +   along with this program; if not, write to the Free Software
    8.14 +   Foundation, Inc., 675 Mass Ave, Cambridge, MA  2139, USA.
    8.15 +   Send your comments and all your spare pocket change to
    8.16 +   laredo@gnu.ai.mit.edu (Nathan Laredo) or to PSC 1, BOX 709, 2401
    8.17 +   Kelly Drive, Lackland AFB, TX 78236-5128, USA.
    8.18 + *************************************************************************/
    8.19 +#include "playmidi.h"
    8.20 +#ifdef linux
    8.21 +#include <linux/ultrasound.h>
    8.22 +#else
    8.23 +#include <machine/ultrasound.h>
    8.24 +#endif
    8.25 +
    8.26 +/*
    8.27 + * TABLE OF NEARLY EXACT FREQUENCIES FOR ALL MIDI NOTES (A=440Hz)
    8.28 + * the whole table is really not necessary, but it prevents some
    8.29 + * rounding errors by having it complete, and the cost of 128
    8.30 + * integers is cheaper than the cpu cost of multiple right shifts
    8.31 + * of a table of twelve frequencies, and definately cheaper than
    8.32 + * calculating freq = 13.75 * 2^((n + 4)/12) for each note value,
    8.33 + * which is how this table was created.
    8.34 + */
    8.35 +
    8.36 +unsigned int n_freq[128] =
    8.37 +{
    8.38 +/* C     C#    D     D#    E     F     F#    G     G#    A     A#    B */
    8.39 +   16,   17,   18,   19,   21,   22,   23,   24,   26,   28,   29,   31,
    8.40 +   33,   34,   37,   39,   41,   44,   46,   49,   52,   55,   58,   62,
    8.41 +   65,   69,   73,   78,   82,   87,   92,   98,  103,  110,  117,  123,
    8.42 +  131,  139,  147,  156,  165,  175,  185,  195,  207,  220,  233,  247,
    8.43 +  262,  277,  294,  311,  330,  349,  370,  392,  415,  440,  466,  494,
    8.44 +  523,  554,  587,  622,  659,  698,  740,  784,  831,  880,  932,  988,
    8.45 + 1047, 1109, 1175, 1245, 1319, 1397, 1480, 1568, 1661, 1760, 1865, 1976,
    8.46 + 2093, 2217, 2349, 2489, 2637, 2794, 2960, 3136, 3322, 3520, 3729, 3951,
    8.47 + 4186, 4435, 4699, 4978, 5274, 5588, 5920, 6272, 6645, 7040, 7459, 7902,
    8.48 + 8372, 8870, 9397, 9956,10548,11175,11840,12544,13290,14080,14917,15804,
    8.49 +16744,17740,18795,19912,21096,22351,23680,25088
    8.50 +};
    8.51 +
    8.52 +/* MT-32 emulation translate table */
    8.53 +int mt32pgm[128] =
    8.54 +{
    8.55 +   0,   1,   2,   4,   4,   5,   5,   3,  16,  16,  16,  16,  19,
    8.56 +  19,  19,  21,   6,   6,   6,   7,   7,   7,   8,   8,  62,  57,
    8.57 +  63,  58,  38,  38,  39,  39,  88,  33,  52,  35,  97, 100,  38,
    8.58 +  39,  14, 102,  68, 103,  44,  92,  46,  80,  48,  49,  51,  45,
    8.59 +  40,  40,  42,  42,  43,  46,  46,  24,  25,  28,  27, 104,  32,
    8.60 +  32,  34,  33,  36,  37,  39,  35,  79,  73,  76,  72,  74,  75,
    8.61 +  64,  65,  66,  67,  71,  71,  69,  70,  60,  22,  56,  59,  57,
    8.62 +  63,  60,  60,  58,  61,  61,  11,  11,  99, 100,   9,  14,  13,
    8.63 +  12, 107, 106,  77,  78,  78,  76, 111,  47, 117, 127, 115, 118,
    8.64 + 116, 118, 126, 121, 121,  55, 124, 120, 125, 126, 127
    8.65 +};
    8.66 +
     9.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     9.2 +++ b/native_midi_gpl/gmvoices.h	Wed Feb 13 19:07:39 2002 +0000
     9.3 @@ -0,0 +1,106 @@
     9.4 +/********************************************************************
     9.5 +   gmvoices.h -- List of GM voice filenames for GUS.
     9.6 +
     9.7 +   Copyright (C) 1994-1996 Nathan I. Laredo
     9.8 +
     9.9 +   This program is modifiable/redistributable under the terms
    9.10 +   of the GNU General Public Licence.
    9.11 +
    9.12 +   You should have received a copy of the GNU General Public License
    9.13 +   along with this program; if not, write to the Free Software
    9.14 +   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
    9.15 +   Send your comments and all your spare pocket change to
    9.16 +   laredo@gnu.ai.mit.edu (Nathan Laredo) or to PSC 1, BOX 709, 2401
    9.17 +   Kelly Drive, Lackland AFB, TX 78236-5128, USA.
    9.18 +
    9.19 + ********************************************************************/
    9.20 +char *gmvoice[256] = {
    9.21 +/* [Melodic Patches] */
    9.22 + /* 000 */ "acpiano",	/* 001 */ "britepno",	/* 002 */ "synpiano",
    9.23 + /* 003 */ "honky",	/* 004 */ "epiano1",	/* 005 */ "epiano2",
    9.24 + /* 006 */ "hrpschrd",	/* 007 */ "clavinet",	/* 008 */ "celeste",
    9.25 + /* 009 */ "glocken",	/* 010 */ "musicbox",	/* 011 */ "vibes",
    9.26 + /* 012 */ "marimba",	/* 013 */ "xylophon",	/* 014 */ "tubebell",
    9.27 + /* 015 */ "santur",	/* 016 */ "homeorg",	/* 017 */ "percorg",
    9.28 + /* 018 */ "rockorg",	/* 019 */ "church",	/* 020 */ "reedorg",
    9.29 + /* 021 */ "accordn",	/* 022 */ "harmonca",	/* 023 */ "concrtna",
    9.30 + /* 024 */ "nyguitar",	/* 025 */ "acguitar",	/* 026 */ "jazzgtr",
    9.31 + /* 027 */ "cleangtr",	/* 028 */ "mutegtr",	/* 029 */ "odguitar",
    9.32 + /* 030 */ "distgtr",	/* 031 */ "gtrharm",	/* 032 */ "acbass",
    9.33 + /* 033 */ "fngrbass",	/* 034 */ "pickbass",	/* 035 */ "fretless",
    9.34 + /* 036 */ "slapbas1",	/* 037 */ "slapbas2",	/* 038 */ "synbass1",
    9.35 + /* 039 */ "synbass2",	/* 040 */ "violin",	/* 041 */ "viola",
    9.36 + /* 042 */ "cello",	/* 043 */ "contraba",	/* 044 */ "marcato",
    9.37 + /* 045 */ "pizzcato",	/* 046 */ "harp",	/* 047 */ "timpani",
    9.38 + /* 048 */ "marcato",	/* 049 */ "slowstr",	/* 050 */ "synstr1",
    9.39 + /* 051 */ "synstr2",	/* 052 */ "choir",	/* 053 */ "doo",
    9.40 + /* 054 */ "voices",	/* 055 */ "orchhit",	/* 056 */ "trumpet",
    9.41 + /* 057 */ "trombone",	/* 058 */ "tuba",	/* 059 */ "mutetrum",
    9.42 + /* 060 */ "frenchrn",	/* 061 */ "hitbrass",	/* 062 */ "synbras1",
    9.43 + /* 063 */ "synbras2",	/* 064 */ "sprnosax",	/* 065 */ "altosax",
    9.44 + /* 066 */ "tenorsax",	/* 067 */ "barisax",	/* 068 */ "oboe",
    9.45 + /* 069 */ "englhorn",	/* 070 */ "bassoon",	/* 071 */ "clarinet",
    9.46 + /* 072 */ "piccolo",	/* 073 */ "flute",	/* 074 */ "recorder",
    9.47 + /* 075 */ "woodflut",	/* 076 */ "bottle",	/* 077 */ "shakazul",
    9.48 + /* 078 */ "whistle",	/* 079 */ "ocarina",	/* 080 */ "sqrwave",
    9.49 + /* 081 */ "sawwave",	/* 082 */ "calliope",	/* 083 */ "chiflead",
    9.50 + /* 084 */ "charang",	/* 085 */ "voxlead",	/* 086 */ "lead5th",
    9.51 + /* 087 */ "basslead",	/* 088 */ "fantasia",	/* 089 */ "warmpad",
    9.52 + /* 090 */ "polysyn",	/* 091 */ "ghostie",	/* 092 */ "bowglass",
    9.53 + /* 093 */ "metalpad",	/* 094 */ "halopad",	/* 095 */ "sweeper",
    9.54 + /* 096 */ "aurora",	/* 097 */ "soundtrk",	/* 098 */ "crystal",
    9.55 + /* 099 */ "atmosphr",	/* 100 */ "freshair",	/* 101 */ "unicorn",
    9.56 + /* 102 */ "sweeper",	/* 103 */ "startrak",	/* 104 */ "sitar",
    9.57 + /* 105 */ "banjo",	/* 106 */ "shamisen",	/* 107 */ "koto",
    9.58 + /* 108 */ "kalimba",	/* 109 */ "bagpipes",	/* 110 */ "fiddle",
    9.59 + /* 111 */ "shannai",	/* 112 */ "carillon",	/* 113 */ "agogo",
    9.60 + /* 114 */ "steeldrm",	/* 115 */ "woodblk",	/* 116 */ "taiko",
    9.61 + /* 117 */ "toms",	/* 118 */ "syntom",	/* 119 */ "revcym",
    9.62 + /* 120 */ "fx-fret",	/* 121 */ "fx-blow",	/* 122 */ "seashore",
    9.63 + /* 123 */ "jungle",	/* 124 */ "telephon",	/* 125 */ "helicptr",
    9.64 + /* 126 */ "applause",	/* 127 */ "ringwhsl",
    9.65 +/* [Drum Patches] */
    9.66 + /* C 0 */ NULL,	/* C#0 */ NULL,		/* D 0 */ NULL,
    9.67 + /* D#0 */ NULL,	/* E 0 */ NULL,		/* F 0 */ NULL,
    9.68 + /* F#0 */ NULL,	/* G 0 */ NULL,		/* G#0 */ NULL,
    9.69 + /* A 0 */ NULL,	/* A#0 */ NULL,		/* B 0 */ NULL,
    9.70 + /* C 1 */ NULL,	/* C#1 */ NULL,		/* D 1 */ NULL,
    9.71 + /* D#1 */ NULL,	/* E 1 */ NULL,		/* F 1 */ NULL,
    9.72 + /* F#1 */ NULL,	/* G 1 */ NULL,		/* G#1 */ NULL,
    9.73 + /* A 1 */ NULL,	/* A#1 */ NULL,		/* B 1 */ NULL,
    9.74 + /* C 2 */ NULL,	/* C#2 */ NULL,		/* D 2 */ NULL,
    9.75 + /* D#2 */ "highq",	/* E 2 */ "slap",	/* F 2 */ "scratch1",
    9.76 + /* F#2 */ "scratch2",	/* G 2 */ "sticks",	/* G#2 */ "sqrclick",
    9.77 + /* A 2 */ "metclick",	/* A#2 */ "metbell",	/* B 2 */ "kick1",
    9.78 + /* C 3 */ "kick2",	/* C#3 */ "stickrim",	/* D 3 */ "snare1",
    9.79 + /* D#3 */ "claps",	/* E 3 */ "snare2",	/* F 3 */ "tomlo2",
    9.80 + /* F#3 */ "hihatcl",	/* G 3 */ "tomlo1",	/* G#3 */ "hihatpd",
    9.81 + /* A 3 */ "tommid2",	/* A#3 */ "hihatop",	/* B 3 */ "tommid1",
    9.82 + /* C 4 */ "tomhi2",	/* C#4 */ "cymcrsh1",	/* D 4 */ "tomhi1",
    9.83 + /* D#4 */ "cymride1",	/* E 4 */ "cymchina",	/* F 4 */ "cymbell",
    9.84 + /* F#4 */ "tamborin",	/* G 4 */ "cymsplsh",	/* G#4 */ "cowbell",
    9.85 + /* A 4 */ "cymcrsh2",	/* A#4 */ "vibslap",	/* B 4 */ "cymride2",
    9.86 + /* C 5 */ "bongohi",	/* C#5 */ "bongolo",	/* D 5 */ "congahi1",
    9.87 + /* D#5 */ "congahi2",	/* E 5 */ "congalo",	/* F 5 */ "timbaleh",
    9.88 + /* F#5 */ "timbalel",	/* G 5 */ "agogohi",	/* G#5 */ "agogolo",
    9.89 + /* A 5 */ "cabasa",	/* A#5 */ "maracas",	/* B 5 */ "whistle1",
    9.90 + /* C 6 */ "whistle2",	/* C#6 */ "guiro1",	/* D 6 */ "guiro2",
    9.91 + /* D#6 */ "clave",	/* E 6 */ "woodblk1",	/* F 6 */ "woodblk2",
    9.92 + /* F#6 */ "cuica1",	/* G 6 */ "cuica2",	/* G#6 */ "triangl1",
    9.93 + /* A 6 */ "triangl2",	/* A#6 */ "shaker",	/* B 6 */ "jingles",
    9.94 + /* C 7 */ "belltree",	/* C#7 */ "castinet",	/* D 7 */ "surdo1",
    9.95 + /* D#7 */ "surdo2",	/* E 7 */ NULL,		/* F 7 */ NULL,
    9.96 + /* F#7 */ NULL,	/* G 7 */ NULL,		/* G#7 */ NULL,
    9.97 + /* A 7 */ NULL,	/* A#7 */ NULL,		/* B 7 */ NULL,
    9.98 + /* C 8 */ NULL,	/* C#8 */ NULL,		/* D 8 */ NULL,
    9.99 + /* D#8 */ NULL,	/* E 8 */ NULL,		/* F 8 */ NULL,
   9.100 + /* F#8 */ NULL,	/* G 8 */ NULL,		/* G#8 */ NULL,
   9.101 + /* A 8 */ NULL,	/* A#8 */ NULL,		/* B 8 */ NULL,
   9.102 + /* C 9 */ NULL,	/* C#9 */ NULL,		/* D 9 */ NULL,
   9.103 + /* D#9 */ NULL,	/* E 9 */ NULL,		/* F 9 */ NULL,
   9.104 + /* F#9 */ NULL,	/* G 9 */ NULL,		/* G#9 */ NULL,
   9.105 + /* A 9 */ NULL,	/* A#9 */ NULL,		/* B 9 */ NULL,
   9.106 + /* C 10*/ NULL,	/* C#10*/ NULL,		/* D 10*/ NULL,
   9.107 + /* D#10*/ NULL,	/* E 10*/ NULL,		/* F 10*/ NULL,
   9.108 + /* F#10*/ NULL,	/* G 10*/ NULL
   9.109 +};
    10.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    10.2 +++ b/native_midi_gpl/gsvoices.h	Wed Feb 13 19:07:39 2002 +0000
    10.3 @@ -0,0 +1,39 @@
    10.4 +/**************************************************************
    10.5 + * gsvoices.h  -  list of gs voice names  -  all 654 of SC88  *
    10.6 + **************************************************************/
    10.7 +#ifndef GSVOICES_H
    10.8 +#define GSVOICES_H
    10.9 +char *gsvoice[128] = {
   10.10 +"Piano 1     ", "Piano 2     ", "Piano 3     ", "Honky-tonk  ",
   10.11 +"E.Piano 1   ", "E.Piano 2   ", "Harpsichord ", "Clav.       ",
   10.12 +"Celesta     ", "Glockenspl  ", "Music Box   ", "Vibraphone  ",
   10.13 +"Marimba     ", "Xylophone   ", "Tubularbell ", "Santur      ",
   10.14 +"Organ 1     ", "Organ 2     ", "Organ 3     ", "Church Org1 ",
   10.15 +"Reed Organ  ", "Accordion F ", "Harmonica   ", "Bandoneon   ",
   10.16 +"Nylon Gt.   ", "Steel Gt.   ", "Jazz Gt.    ", "Clean Gt.   ",
   10.17 +"Muted Gt.   ", "OverdriveGt ", "Dist.Gt.    ", "Gt.Harmonix ",
   10.18 +"Acoustic Bs ", "Fingered Bs ", "Picked Bass ", "Fretless Bs ",
   10.19 +"Slap Bass 1 ", "Slap Bass 2 ", "Syn.Bass 1  ", "Syn.Bass 2  ",
   10.20 +"Violin      ", "Viola       ", "Cello       ", "Contrabass  ",
   10.21 +"Tremolo Str ", "Pizzicato   ", "Harp        ", "Timpani     ",
   10.22 +"Strings     ", "SlowStrings ", "SynStrings1 ", "SynStrings2 ",
   10.23 +"Choir Aahs  ", "Voice Oohs  ", "SynVox      ", "Orchest.Hit ",
   10.24 +"Trumpet     ", "Trombone    ", "Tuba        ", "MuteTrumpet ",
   10.25 +"French Horn ", "Brass 1     ", "Syn.Brass 1 ", "Syn.Brass 2 ",
   10.26 +"Soprano Sax ", "Alto Sax    ", "Tenor Sax   ", "BaritoneSax ",
   10.27 +"Oboe        ", "EnglishHorn ", "Bassoon     ", "Clarinet    ",
   10.28 +"Piccolo     ", "Flute       ", "Recorder    ", "Pan Flute   ",
   10.29 +"Bottle Blow ", "Shakuhachi  ", "Whistle     ", "Ocarina     ",
   10.30 +"Square Wave ", "Saw Wave    ", "SynCalliope ", "ChifferLead ",
   10.31 +"Charang     ", "Solo Vox    ", "5th Saw     ", "Bass & Lead ",
   10.32 +"Fantasia    ", "Warm Pad    ", "Polysynth   ", "Space Voice ",
   10.33 +"Bowed Glass ", "Metal Pad   ", "Halo Pad    ", "Sweep Pad   ",
   10.34 +"Ice Rain    ", "Soundtrack  ", "Crystal     ", "Atmosphere  ",
   10.35 +"Brightness  ", "Goblin      ", "Echo Drops  ", "Star Theme  ",
   10.36 +"Sitar       ", "Banjo       ", "Shamisen    ", "Koto        ",
   10.37 +"Kalimba     ", "Bagpipe     ", "Fiddle      ", "Shanai      ",
   10.38 +"Tinkle Bell ", "Agogo       ", "Steel Drums ", "Woodblock   ",
   10.39 +"Taiko       ", "Melo. Tom 1 ", "Synth Drum  ", "Reverse Cym ",
   10.40 +"Gt.FretNoiz ", "BreathNoise ", "Seashore    ", "Bird        ",
   10.41 +"Telephone 1 ", "Helicopter  ", "Applause    ", "Gun Shot    " };
   10.42 +#endif
    11.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    11.2 +++ b/native_midi_gpl/native_midi_gpl.c	Wed Feb 13 19:07:39 2002 +0000
    11.3 @@ -0,0 +1,488 @@
    11.4 +/***************************************************************************
    11.5 +                           native_midi_lnx.c
    11.6 +			   -----------------
    11.7 +			   
    11.8 +    copyright            : (C) 2002 by Peter Kuȇk
    11.9 +    email                : kutak@stonline.sk
   11.10 + ***************************************************************************/
   11.11 +
   11.12 +/* in this file is used code from PlayMidi    Copyright (C) 1994-1996 Nathan I. Laredo */
   11.13 +
   11.14 +/***************************************************************************
   11.15 + *                                                                         *
   11.16 + *   This program is free software; you can redistribute it and/or modify  *
   11.17 + *   it under the terms of the GNU General Public License as published by  *
   11.18 + *   the Free Software Foundation; either version 2 of the License, or     *
   11.19 + *   (at your option) any later version.                                   *
   11.20 + *                                                                         *
   11.21 + ***************************************************************************/
   11.22 +
   11.23 +#if defined(linux) || defined(__FreeBSD__)
   11.24 +
   11.25 +#ifndef __FreeBSD__
   11.26 +#include <getopt.h>
   11.27 +#endif
   11.28 +#include <fcntl.h>
   11.29 +#include <ctype.h>
   11.30 +#include <unistd.h>
   11.31 +#include <sys/stat.h>
   11.32 +#include <string.h>
   11.33 +#include "SDL_thread.h"
   11.34 +#include "native_midi.h"
   11.35 +#include "playmidi.h"
   11.36 +
   11.37 +SEQ_DEFINEBUF(SEQUENCERBLOCKSIZE);
   11.38 +
   11.39 +int play_fm = 0, play_gus = 0, play_ext = 0, play_awe = 0;
   11.40 +int opl3_patch_aviable = 0, fm_patch_aviable = 0;
   11.41 +
   11.42 +struct miditrack seq[MAXTRKS];
   11.43 +struct synth_info card_info[MAX_CARDS];
   11.44 +
   11.45 +int FORCE_EXT_DEV = -1;
   11.46 +int chanmask = 0xffff, perc = PERCUSSION;
   11.47 +int dochan = 1, force8bit = 0, wantopl3 = FM_DEFAULT_MODE;
   11.48 +int patchloaded[256], fmloaded[256], useprog[16], usevol[16]={0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
   11.49 +int reverb = 0, chorus = 0, nrsynths, nrmidis;
   11.50 +int sb_dev = -1, gus_dev = -1, ext_dev = -1, awe_dev = -1, p_remap = 0;
   11.51 +int seqfd,  MT32 = 0;
   11.52 +FILE *mfd;
   11.53 +unsigned long int default_tempo;
   11.54 +float skew = 1.0;
   11.55 +char ImPlaying = 0;
   11.56 +SDL_Thread *playevents_thread=NULL;
   11.57 +
   11.58 +extern int ntrks;
   11.59 +extern char *gmvoice[256];
   11.60 +extern int mt32pgm[128];
   11.61 +extern int note_vel[16][128];
   11.62 +extern int playevents();
   11.63 +extern int gus_load(int);
   11.64 +extern int readmidi(unsigned char *, off_t);
   11.65 +extern void loadfm();
   11.66 +
   11.67 +void seqbuf_dump();
   11.68 +int synth_setup();
   11.69 +
   11.70 +struct _NativeMidiSong
   11.71 +{
   11.72 +    char *filebuf;
   11.73 +    unsigned long int file_size;
   11.74 +};
   11.75 +
   11.76 +int native_midi_detect()
   11.77 +{
   11.78 +
   11.79 +    int sbfd;
   11.80 +    int ret=0;    
   11.81 +
   11.82 +    /* Open sequencer device */
   11.83 +    if ((seqfd = open(SEQUENCER_DEV, O_WRONLY, 0)) < 0) 
   11.84 +    {
   11.85 +	perror("open " SEQUENCER_DEV);
   11.86 +	return 0;
   11.87 +    }
   11.88 +
   11.89 +    gus_dev = -1;
   11.90 +    sb_dev = -1;
   11.91 +    ext_dev = -1;
   11.92 +    awe_dev = -1;
   11.93 +    play_fm = 0;
   11.94 +    play_gus = 0;
   11.95 +    play_ext = 0;
   11.96 +    play_awe = 0;
   11.97 +    
   11.98 +    opl3_patch_aviable = 0;
   11.99 +    fm_patch_aviable = 0;
  11.100 +
  11.101 +    sbfd = open(SBMELODIC, O_RDONLY, 0);
  11.102 +    if (sbfd != -1)
  11.103 +    {
  11.104 +	close(sbfd);
  11.105 +	sbfd = open(SBDRUMS, O_RDONLY, 0);
  11.106 +	if (sbfd != -1)
  11.107 +	{
  11.108 +            close(sbfd);
  11.109 +	    fm_patch_aviable = 1;
  11.110 +	}
  11.111 +    }
  11.112 +
  11.113 +    sbfd = open(O3MELODIC, O_RDONLY, 0);
  11.114 +    if (sbfd != -1)
  11.115 +    {
  11.116 +        close(sbfd);
  11.117 +        sbfd = open(O3DRUMS, O_RDONLY, 0);
  11.118 +	if (sbfd != -1)
  11.119 +	{
  11.120 +            close(sbfd);
  11.121 +	    opl3_patch_aviable = 1;
  11.122 +	}
  11.123 +    }
  11.124 +
  11.125 +    ret=synth_setup();
  11.126 +
  11.127 +    /* Close sequencer device */
  11.128 +    close(seqfd);
  11.129 +
  11.130 +    return ret;
  11.131 +}
  11.132 +
  11.133 +NativeMidiSong *native_midi_loadsong(char *midifile)
  11.134 +{
  11.135 +    NativeMidiSong	*song = NULL;
  11.136 +    char 		*extra;
  11.137 +    int 		piped = 0;
  11.138 +    struct stat 	info;
  11.139 +
  11.140 +    song = malloc(sizeof(NativeMidiSong));
  11.141 +    if (!song)
  11.142 +    {
  11.143 +	return NULL;
  11.144 +    };
  11.145 +    if (stat(midifile, &info) == -1) 
  11.146 +    {
  11.147 +        if ((extra = malloc(strlen(midifile) + 4)) == NULL)
  11.148 +        {
  11.149 +	    goto end;
  11.150 +	}
  11.151 +	sprintf(extra, "%s.mid", midifile);
  11.152 +	if (stat(extra, &info) == -1)
  11.153 +	{
  11.154 +	    free(extra);
  11.155 +	    goto end;
  11.156 +	}
  11.157 +	if ((mfd = fopen(extra, "r")) == NULL)
  11.158 +	{
  11.159 +	    free(extra);
  11.160 +	    goto end;
  11.161 +	}
  11.162 +	free(extra);
  11.163 +    } else
  11.164 +    {
  11.165 +        char *ext = strrchr(midifile, '.');
  11.166 +        if (ext && strcmp(ext, ".gz") == 0) 
  11.167 +	{
  11.168 +	    char temp[1024];
  11.169 +	    piped = 1;
  11.170 +	    sprintf(temp, "gzip -l %s", midifile);
  11.171 +	    if ((mfd = popen(temp, "r")) == NULL)
  11.172 +	    {
  11.173 +	        goto end;
  11.174 +	    }
  11.175 +	    fgets(temp, sizeof(temp), mfd); /* skip 1st line */
  11.176 +	    fgets(temp, sizeof(temp), mfd);
  11.177 +	    strtok(temp, " "); /* compressed size */
  11.178 +	    info.st_size = atoi(strtok(NULL, " ")); /* original size */
  11.179 +	    pclose(mfd);
  11.180 +	    sprintf(temp, "gzip -d -c %s",midifile);
  11.181 +	    if ((mfd = popen(temp, "r")) == NULL)
  11.182 +	    {
  11.183 +	        goto end;
  11.184 +	    }
  11.185 +	}else if ((mfd = fopen(midifile, "r")) == NULL)
  11.186 +	{
  11.187 +	    goto end;
  11.188 +	}
  11.189 +    }
  11.190 +    if ((song->filebuf = malloc(info.st_size)) == NULL)
  11.191 +    {
  11.192 +        if (piped)
  11.193 +        {
  11.194 +	    pclose(mfd);
  11.195 +	}else
  11.196 +	{
  11.197 +	    fclose(mfd);
  11.198 +	}
  11.199 +	goto end;
  11.200 +    }
  11.201 +    song->file_size=info.st_size;
  11.202 +    fread(song->filebuf, 1, info.st_size, mfd);
  11.203 +    if (piped)
  11.204 +    {
  11.205 +        pclose(mfd);
  11.206 +    } else
  11.207 +    {
  11.208 +        fclose(mfd);
  11.209 +    }
  11.210 +    
  11.211 +  return song;
  11.212 +
  11.213 +end:
  11.214 +    free(song);
  11.215 +    return NULL;
  11.216 +}
  11.217 +
  11.218 +void native_midi_freesong(NativeMidiSong *song)
  11.219 +{
  11.220 +    free(song->filebuf);
  11.221 +    free(song);
  11.222 +}
  11.223 +
  11.224 +void native_midi_start(NativeMidiSong *song)
  11.225 +{
  11.226 +
  11.227 +    int i, error = 0, j;
  11.228 +
  11.229 +
  11.230 +    for (i = 0; i < 16; i++)
  11.231 +    {
  11.232 +	useprog[i] = 0;	/* reset options */
  11.233 +    }
  11.234 +    
  11.235 +    /* Open sequencer device */
  11.236 +    if ((seqfd = open(SEQUENCER_DEV, O_WRONLY, 0)) < 0) 
  11.237 +    {
  11.238 +	perror("open " SEQUENCER_DEV);
  11.239 +	goto eend;
  11.240 +    }
  11.241 +    if(!synth_setup()) { goto end;};
  11.242 +
  11.243 +
  11.244 +	    if (play_gus)
  11.245 +	    {
  11.246 +		gus_load(-1);
  11.247 +	    }
  11.248 +	    default_tempo = 500000;
  11.249 +	    /* error holds number of tracks read */
  11.250 +	    error = readmidi(song->filebuf, song->file_size);
  11.251 +	    if (play_gus && error > 0) 
  11.252 +	    {
  11.253 +		int i;		/* need to keep other i safe */
  11.254 +#define CMD (seq[i].data[j] & 0xf0)
  11.255 +#define CHN (seq[i].data[j] & 0x0f)
  11.256 +#define PGM (seq[i].data[j + 1])
  11.257 +		/* REALLY STUPID way to preload GUS, but it works */
  11.258 +		for (i = 0; i < ntrks; i++)
  11.259 +		    for (j = 0; j < seq[i].length - 5; j++)
  11.260 +			if (ISGUS(CHN) && !(PGM & 0x80) &&
  11.261 +			    ((CMD == MIDI_PGM_CHANGE && !ISPERC(CHN))
  11.262 +			     || (CMD == MIDI_NOTEON && ISPERC(CHN))))
  11.263 +			    gus_load(ISPERC(CHN) ? PGM + 128 :
  11.264 +				     useprog[CHN] ? useprog[CHN] - 1 :
  11.265 +				     MT32 ? mt32pgm[PGM] : PGM);
  11.266 +		/* make sure that some program was loaded to use */
  11.267 +		for (j = 0; patchloaded[j] != 1 && j < 128; j++);
  11.268 +		if (j > 127)
  11.269 +		    gus_load(0);
  11.270 +	    }
  11.271 +				/* if there's an error skip to next file */
  11.272 +	    if (error > 0)	/* error holds number of tracks read */
  11.273 +	    {
  11.274 +		ImPlaying=1;
  11.275 +	    	playevents_thread=SDL_CreateThread(playevents,NULL);
  11.276 +	    }
  11.277 +
  11.278 +end:
  11.279 +eend:
  11.280 +}
  11.281 +
  11.282 +void native_midi_stop()
  11.283 +{
  11.284 +    /* Close sequencer device */
  11.285 +    close(seqfd);
  11.286 +}
  11.287 +
  11.288 +int native_midi_active()
  11.289 +{
  11.290 +    return ImPlaying;
  11.291 +}
  11.292 +
  11.293 +void native_midi_setvolume(int volume)
  11.294 +{
  11.295 +}
  11.296 +
  11.297 +char *native_midi_error()
  11.298 +{
  11.299 +  return "stala sa chyba";
  11.300 +}
  11.301 +
  11.302 +void seqbuf_dump()
  11.303 +{
  11.304 +    if (_seqbufptr)
  11.305 +	if (write(seqfd, _seqbuf, _seqbufptr) == -1) {
  11.306 +	    perror("write " SEQUENCER_DEV);
  11.307 +	    return;
  11.308 +	}
  11.309 +    _seqbufptr = 0;
  11.310 +}
  11.311 +
  11.312 +int synth_setup()
  11.313 +{
  11.314 +    int i;
  11.315 +    char *nativemusicenv = getenv("SDL_NATIVE_MUSIC");
  11.316 +    char *extmidi=getenv("SDL_NATIVE_MUSIC_EXT");
  11.317 +
  11.318 +    if(extmidi)
  11.319 +    {
  11.320 +	
  11.321 +    	FORCE_EXT_DEV = atoi(extmidi);
  11.322 +	printf("EXT midi %s , %d \n",extmidi,FORCE_EXT_DEV);
  11.323 +    }
  11.324 +    
  11.325 +    if (ioctl(seqfd, SNDCTL_SEQ_NRSYNTHS, &nrsynths) == -1) 
  11.326 +    {
  11.327 +	fprintf(stderr, "there is no soundcard\n");
  11.328 +	return 0;
  11.329 +    }
  11.330 +    for (i = 0; i < nrsynths; i++) 
  11.331 +    {
  11.332 +	card_info[i].device = i;
  11.333 +	if (ioctl(seqfd, SNDCTL_SYNTH_INFO, &card_info[i]) == -1) 
  11.334 +	{
  11.335 +	    fprintf(stderr, "cannot get info on soundcard\n");
  11.336 +	    perror(SEQUENCER_DEV);
  11.337 +	    return 0;
  11.338 +	}
  11.339 +	card_info[i].device = i;
  11.340 +	if (card_info[i].synth_type == SYNTH_TYPE_SAMPLE
  11.341 +	    && card_info[i].synth_subtype == SAMPLE_TYPE_GUS)
  11.342 +	{
  11.343 +	    gus_dev = i;
  11.344 +	}else if (card_info[i].synth_type == SYNTH_TYPE_SAMPLE
  11.345 +	    && card_info[i].synth_subtype == SAMPLE_TYPE_AWE32)
  11.346 +	{
  11.347 +	    awe_dev = i;
  11.348 +	}else if (card_info[i].synth_type == SYNTH_TYPE_FM) 
  11.349 +	{
  11.350 +	    sb_dev = i;
  11.351 +	    if (play_fm)
  11.352 +		loadfm();
  11.353 +	    if (wantopl3) 
  11.354 +	    {
  11.355 +		card_info[i].nr_voices = 12;	/* we have 12 with 4-op */
  11.356 +	    }
  11.357 +	}
  11.358 +    }
  11.359 +
  11.360 +    if (gus_dev >= 0) {
  11.361 +	if (ioctl(seqfd, SNDCTL_SEQ_RESETSAMPLES, &gus_dev) == -1) 
  11.362 +	{
  11.363 +	    perror("Sample reset");
  11.364 +	    return 0;
  11.365 +	}
  11.366 +    }
  11.367 +    if (ioctl(seqfd, SNDCTL_SEQ_NRMIDIS, &nrmidis) == -1) 
  11.368 +    {
  11.369 +	fprintf(stderr, "can't get info about midi ports\n");
  11.370 +	return 0;
  11.371 +    }
  11.372 +    if (nrmidis > 0) {
  11.373 +	if (FORCE_EXT_DEV >= 0)
  11.374 +	    ext_dev = FORCE_EXT_DEV;
  11.375 +	else
  11.376 +	    ext_dev = nrmidis - 1;
  11.377 +    }
  11.378 +
  11.379 +    if( nativemusicenv ) /* select device by SDL_NATIVE_MUSIC */
  11.380 +    {
  11.381 +	if(strcasecmp(nativemusicenv,"GUS") == 0)
  11.382 +	{
  11.383 +    	    if( gus_dev >= 0 )
  11.384 +	    {
  11.385 +    		play_gus = 1;
  11.386 +	        awe_dev = -1;
  11.387 +		sb_dev  = -1;
  11.388 +	        ext_dev = -1;
  11.389 +	        return 1;
  11.390 +            }else
  11.391 +	    {
  11.392 +    		play_gus = 0;
  11.393 +		return 0;
  11.394 +	    }
  11.395 +	}else if(strcasecmp(nativemusicenv,"AWE") == 0)
  11.396 +	{
  11.397 +    	    if( awe_dev >= 0 )
  11.398 +	    {
  11.399 +    		play_awe = 1;
  11.400 +	        gus_dev = -1;
  11.401 +		sb_dev  = -1;
  11.402 +	        ext_dev = -1;
  11.403 +	        return 1;
  11.404 +            }else
  11.405 +	    {
  11.406 +    		play_awe = 0;
  11.407 +		return 0;
  11.408 +	    }
  11.409 +	}else if(strcasecmp(nativemusicenv,"FM") == 0)
  11.410 +	{
  11.411 +    	    if( sb_dev >= 0 && fm_patch_aviable )
  11.412 +	    {
  11.413 +    		play_fm = 1;
  11.414 +		gus_dev = -1;
  11.415 +	        awe_dev = -1;
  11.416 +	        ext_dev = -1;
  11.417 +	        wantopl3 = 0;
  11.418 +	        return 1;
  11.419 +            }else
  11.420 +	    {
  11.421 +    		play_fm = 0;
  11.422 +		return 0;
  11.423 +	    }
  11.424 +	}else if(strcasecmp(nativemusicenv,"OPL3") == 0)
  11.425 +	{
  11.426 +    	    if( sb_dev >= 0 && opl3_patch_aviable )
  11.427 +	    {
  11.428 +    		play_fm = 1;
  11.429 +		gus_dev = -1;
  11.430 +	        awe_dev = -1;
  11.431 +	        ext_dev = -1;
  11.432 +	        wantopl3 = 1;
  11.433 +	        return 1;
  11.434 +            }else
  11.435 +	    {
  11.436 +    		play_fm = 0;
  11.437 +		return 0;
  11.438 +	    }
  11.439 +	}else if(strcasecmp(nativemusicenv,"EXT") == 0)
  11.440 +	{
  11.441 +    	    if( ext_dev >= 0 )
  11.442 +	    {
  11.443 +    		play_ext = 1;
  11.444 +	        gus_dev = -1;
  11.445 +	        awe_dev = -1;
  11.446 +		sb_dev  = -1;
  11.447 +	        return 1;
  11.448 +            }else
  11.449 +	    {
  11.450 +    		play_ext = 0;
  11.451 +		return 0;
  11.452 +	    }
  11.453 +	}
  11.454 +    }
  11.455 +    /* autoselect best device */
  11.456 +    if( gus_dev >= 0 )
  11.457 +    {
  11.458 +        play_gus = 1;
  11.459 +        awe_dev = -1;
  11.460 +        sb_dev  = -1;
  11.461 +        ext_dev = -1;
  11.462 +        return 1;
  11.463 +        }
  11.464 +    if( awe_dev >= 0 )
  11.465 +    {
  11.466 +        play_awe = 1;
  11.467 +	gus_dev = -1;
  11.468 +        sb_dev  = -1;
  11.469 +        ext_dev = -1;
  11.470 +        return 1;
  11.471 +    }
  11.472 +    if( sb_dev >= 0 && fm_patch_aviable )
  11.473 +    {
  11.474 +        play_fm = 1;
  11.475 +	gus_dev = -1;
  11.476 +        awe_dev = -1;
  11.477 +        ext_dev = -1;
  11.478 +        return 2;	/* return 1 if use FM befor Timidity */
  11.479 +    }
  11.480 +    if( ext_dev >= 0 )
  11.481 +    {
  11.482 +        play_ext = 1;
  11.483 +	gus_dev = -1;
  11.484 +        awe_dev = -1;
  11.485 +        sb_dev  = -1;
  11.486 +        return 3;
  11.487 +    }
  11.488 +    return 0;
  11.489 +}
  11.490 +
  11.491 +#endif /* linux || FreeBSD */
    12.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    12.2 +++ b/native_midi_gpl/patchload.c	Wed Feb 13 19:07:39 2002 +0000
    12.3 @@ -0,0 +1,412 @@
    12.4 +/************************************************************************
    12.5 +   patchload.c  --  loads patches for playmidi package
    12.6 +   Some of this code was adapted from code written by Hannu Solovainen
    12.7 +
    12.8 +   Copyright (C) 1994-1996 Nathan I. Laredo
    12.9 +
   12.10 +   This program is modifiable/redistributable under the terms
   12.11 +   of the GNU General Public Licence.
   12.12 +
   12.13 +   You should have received a copy of the GNU General Public License
   12.14 +   along with this program; if not, write to the Free Software
   12.15 +   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
   12.16 +   Send your comments and all your spare pocket change to
   12.17 +   laredo@gnu.ai.mit.edu (Nathan Laredo) or to PSC 1, BOX 709, 2401
   12.18 +   Kelly Drive, Lackland AFB, TX 78236-5128, USA.
   12.19 + *************************************************************************/
   12.20 +/*    edited by Peter Kutak            */
   12.21 +/*    email : kutak@stonline.sk        */
   12.22 +
   12.23 +#if defined(linux) || defined(__FreeBSD__)
   12.24 +
   12.25 +#include "playmidi.h"
   12.26 +#ifdef linux
   12.27 +#include <linux/ultrasound.h>
   12.28 +#else
   12.29 +#include <machine/ultrasound.h>
   12.30 +#endif
   12.31 +#include <sys/stat.h>
   12.32 +#include <fcntl.h>
   12.33 +#include <unistd.h>
   12.34 +#include "gmvoices.h"
   12.35 +
   12.36 +SEQ_USE_EXTBUF();
   12.37 +extern int play_gus, play_sb, play_ext, playing, verbose, force8bit;
   12.38 +extern int reverb, fmloaded[256], patchloaded[256];
   12.39 +extern int gus_dev, sb_dev, ext_dev, seqfd, wantopl3;
   12.40 +extern struct synth_info card_info[MAX_CARDS];
   12.41 +
   12.42 +static int use8bit = 0;
   12.43 +
   12.44 +struct pat_header {
   12.45 +    char magic[12];
   12.46 +    char version[10];
   12.47 +    char description[60];
   12.48 +    unsigned char instruments;
   12.49 +    char voices;
   12.50 +    char channels;
   12.51 +    unsigned short nr_waveforms;
   12.52 +    unsigned short master_volume;
   12.53 +    unsigned int data_size;
   12.54 +};
   12.55 +
   12.56 +struct sample_header {
   12.57 +    char name[7];
   12.58 +    unsigned char fractions;
   12.59 +    int len;
   12.60 +    int loop_start;
   12.61 +    int loop_end;
   12.62 +    unsigned short base_freq;
   12.63 +    int low_note;
   12.64 +    int high_note;
   12.65 +    int base_note;
   12.66 +    short detune;
   12.67 +    unsigned char panning;
   12.68 +
   12.69 +    unsigned char envelope_rate[6];
   12.70 +    unsigned char envelope_offset[6];
   12.71 +
   12.72 +    unsigned char tremolo_sweep;
   12.73 +    unsigned char tremolo_rate;
   12.74 +    unsigned char tremolo_depth;
   12.75 +
   12.76 +    unsigned char vibrato_sweep;
   12.77 +    unsigned char vibrato_rate;
   12.78 +    unsigned char vibrato_depth;
   12.79 +
   12.80 +    char modes;
   12.81 +
   12.82 +    short scale_frequency;
   12.83 +    unsigned short scale_factor;
   12.84 +};
   12.85 +
   12.86 +struct patch_info *patch;
   12.87 +int spaceleft, totalspace;
   12.88 +
   12.89 +void gus_reload_8_bit();
   12.90 +
   12.91 +void gus_load(pgm)
   12.92 +int pgm;
   12.93 +{
   12.94 +    int i, j, patfd, offset;
   12.95 +    struct pat_header header;
   12.96 +    struct sample_header sample;
   12.97 +    char buf[256], name[256];
   12.98 +    struct stat info;
   12.99 +
  12.100 +    if (pgm < 0) {
  12.101 +	use8bit = force8bit;
  12.102 +	GUS_NUMVOICES(gus_dev, (card_info[gus_dev].nr_voices = 32));
  12.103 +	SEQ_DUMPBUF();
  12.104 +	for (i = 0; i < 256; i++)
  12.105 +	    patchloaded[i] = 0;
  12.106 +	if (ioctl(seqfd, SNDCTL_SEQ_RESETSAMPLES, &gus_dev) == -1)
  12.107 +	{
  12.108 +	    /* error: should quit */
  12.109 +	}
  12.110 +	spaceleft = gus_dev;
  12.111 +	ioctl(seqfd, SNDCTL_SYNTH_MEMAVL, &spaceleft);
  12.112 +	totalspace = spaceleft;
  12.113 +    }
  12.114 +
  12.115 +    if (patchloaded[pgm] < 0)
  12.116 +	return;
  12.117 +
  12.118 +    if (patchloaded[pgm] == 1)
  12.119 +	return;
  12.120 +
  12.121 +    if (gmvoice[pgm] == NULL) {
  12.122 +	patchloaded[pgm] = -1;
  12.123 +	return;
  12.124 +    }
  12.125 +    sprintf(name, PATCH_PATH1 "/%s.pat", gmvoice[pgm]);
  12.126 +
  12.127 +    if (stat(name, &info) == -1) {
  12.128 +	sprintf(name, PATCH_PATH2 "/%s.pat", gmvoice[pgm]);
  12.129 +	if (stat(name, &info) == -1)
  12.130 +	    return;
  12.131 +    }
  12.132 +    if ((patfd = open(name, O_RDONLY, 0)) == -1)
  12.133 +	return;
  12.134 +    if (spaceleft < info.st_size) {
  12.135 +	if (!use8bit)
  12.136 +	    gus_reload_8_bit();
  12.137 +	if (use8bit)
  12.138 +	    if (spaceleft < info.st_size / 2) {
  12.139 +		close(patfd);
  12.140 +		patchloaded[pgm] = -1;	/* no space for patch */
  12.141 +		return;
  12.142 +	    }
  12.143 +    }
  12.144 +    if (read(patfd, buf, 0xef) != 0xef) {
  12.145 +	close(patfd);
  12.146 +	return;
  12.147 +    }
  12.148 +    memcpy((char *) &header, buf, sizeof(header));
  12.149 +
  12.150 +    if (strncmp(header.magic, "GF1PATCH110", 12)) {
  12.151 +	close(patfd);
  12.152 +	return;
  12.153 +    }
  12.154 +    if (strncmp(header.version, "ID#000002", 10)) {
  12.155 +	close(patfd);
  12.156 +	return;
  12.157 +    }
  12.158 +    header.nr_waveforms = *(unsigned short *) &buf[85];
  12.159 +    header.master_volume = *(unsigned short *) &buf[87];
  12.160 +
  12.161 +    offset = 0xef;
  12.162 +
  12.163 +    for (i = 0; i < header.nr_waveforms; i++) {
  12.164 +
  12.165 +	if (lseek(patfd, offset, 0) == -1) {
  12.166 +	    close(patfd);
  12.167 +	    return;
  12.168 +	}
  12.169 +	if (read(patfd, &buf, sizeof(sample)) != sizeof(sample)) {
  12.170 +	    close(patfd);
  12.171 +	    return;
  12.172 +	}
  12.173 +	memcpy((char *) &sample, buf, sizeof(sample));
  12.174 +
  12.175 +	/*
  12.176 +	 * Since some fields of the patch record are not 32bit aligned, we must
  12.177 +	 * handle them specially.
  12.178 +	 */
  12.179 +	sample.low_note = *(int *) &buf[22];
  12.180 +	sample.high_note = *(int *) &buf[26];
  12.181 +	sample.base_note = *(int *) &buf[30];
  12.182 +	sample.detune = *(short *) &buf[34];
  12.183 +	sample.panning = (unsigned char) buf[36];
  12.184 +
  12.185 +	memcpy(sample.envelope_rate, &buf[37], 6);
  12.186 +	memcpy(sample.envelope_offset, &buf[43], 6);
  12.187 +
  12.188 +	sample.tremolo_sweep = (unsigned char) buf[49];
  12.189 +	sample.tremolo_rate = (unsigned char) buf[50];
  12.190 +	sample.tremolo_depth = (unsigned char) buf[51];
  12.191 +
  12.192 +	sample.vibrato_sweep = (unsigned char) buf[52];
  12.193 +	sample.vibrato_rate = (unsigned char) buf[53];
  12.194 +	sample.vibrato_depth = (unsigned char) buf[54];
  12.195 +	sample.modes = (unsigned char) buf[55];
  12.196 +	sample.scale_frequency = *(short *) &buf[56];
  12.197 +	sample.scale_factor = *(unsigned short *) &buf[58];
  12.198 +
  12.199 +	offset = offset + 96;
  12.200 +	patch = (struct patch_info *) malloc(sizeof(*patch) + sample.len);
  12.201 +
  12.202 +	if (patch == NULL) {
  12.203 +	    close(patfd);
  12.204 +	    return;
  12.205 +	}
  12.206 +	patch->key = GUS_PATCH;
  12.207 +	patch->device_no = gus_dev;
  12.208 +	patch->instr_no = pgm;
  12.209 +	patch->mode = sample.modes | WAVE_TREMOLO |
  12.210 +	    WAVE_VIBRATO | WAVE_SCALE;
  12.211 +	patch->len = (use8bit ? sample.len / 2 : sample.len);
  12.212 +	patch->loop_start =
  12.213 +	    (use8bit ? sample.loop_start / 2 : sample.loop_start);
  12.214 +	patch->loop_end = (use8bit ? sample.loop_end / 2 : sample.loop_end);
  12.215 +	patch->base_note = sample.base_note;
  12.216 +	patch->high_note = sample.high_note;
  12.217 +	patch->low_note = sample.low_note;
  12.218 +	patch->base_freq = sample.base_freq;
  12.219 +	patch->detuning = sample.detune;
  12.220 +	patch->panning = (sample.panning - 7) * 16;
  12.221 +
  12.222 +	memcpy(patch->env_rate, sample.envelope_rate, 6);
  12.223 +	for (j = 0; j < 6; j++)	/* tone things down slightly */
  12.224 +	    patch->env_offset[j] =
  12.225 +		(736 * sample.envelope_offset[j] + 384) / 768;
  12.226 +
  12.227 +	if (reverb)
  12.228 +	    if (pgm < 120)
  12.229 +		patch->env_rate[3] = (2 << 6) | (12 - (reverb >> 4));
  12.230 +	    else if (pgm > 127)
  12.231 +		patch->env_rate[1] = (3 << 6) | (63 - (reverb >> 1));
  12.232 +
  12.233 +	patch->tremolo_sweep = sample.tremolo_sweep;
  12.234 +	patch->tremolo_rate = sample.tremolo_rate;
  12.235 +	patch->tremolo_depth = sample.tremolo_depth;
  12.236 +
  12.237 +	patch->vibrato_sweep = sample.vibrato_sweep;
  12.238 +	patch->vibrato_rate = sample.vibrato_rate;
  12.239 +	patch->vibrato_depth = sample.vibrato_depth;
  12.240 +
  12.241 +	patch->scale_frequency = sample.scale_frequency;
  12.242 +	patch->scale_factor = sample.scale_factor;
  12.243 +
  12.244 +	patch->volume = header.master_volume;
  12.245 +
  12.246 +	if (lseek(patfd, offset, 0) == -1) {
  12.247 +	    close(patfd);
  12.248 +	    return;
  12.249 +	}
  12.250 +	if (read(patfd, patch->data, sample.len) != sample.len) {
  12.251 +	    close(patfd);
  12.252 +	    return;
  12.253 +	}
  12.254 +	if (patch->mode & WAVE_16_BITS && use8bit) {
  12.255 +	    patch->mode &= ~WAVE_16_BITS;
  12.256 +	    /* cut out every other byte to make 8-bit data from 16-bit */
  12.257 +	    for (j = 0; j < patch->len; j++)
  12.258 +		patch->data[j] = patch->data[1 + j * 2];
  12.259 +	}
  12.260 +	SEQ_WRPATCH(patch, sizeof(*patch) + patch->len);
  12.261 +	free(patch);
  12.262 +	offset = offset + sample.len;
  12.263 +    }
  12.264 +    close(patfd);
  12.265 +    spaceleft = gus_dev;
  12.266 +    ioctl(seqfd, SNDCTL_SYNTH_MEMAVL, &spaceleft);
  12.267 +    patchloaded[pgm] = 1;
  12.268 +    return;
  12.269 +}
  12.270 +
  12.271 +void gus_reload_8_bit()
  12.272 +{
  12.273 +    int i;
  12.274 +
  12.275 +    if (ioctl(seqfd, SNDCTL_SEQ_RESETSAMPLES, &gus_dev) == -1) 
  12.276 +    {
  12.277 +	/* error: should quit */
  12.278 +    }
  12.279 +    spaceleft = gus_dev;
  12.280 +    ioctl(seqfd, SNDCTL_SYNTH_MEMAVL, &spaceleft);
  12.281 +    totalspace = spaceleft;
  12.282 +    use8bit = 1;
  12.283 +    for (i = 0; i < 256; i++)
  12.284 +	if (patchloaded[i] > 0) {
  12.285 +	    patchloaded[i] = 0;
  12.286 +	    gus_load(i);
  12.287 +	}
  12.288 +}
  12.289 +
  12.290 +void adjustfm(buf, key)
  12.291 +char *buf;
  12.292 +int key;
  12.293 +{
  12.294 +    unsigned char pan = ((rand() % 3) + 1) << 4;
  12.295 +
  12.296 +    if (key == FM_PATCH) {
  12.297 +	buf[39] &= 0xc0;
  12.298 +	if (buf[46] & 1)
  12.299 +	    buf[38] &= 0xc0;
  12.300 +	buf[46] = (buf[46] & 0xcf) | pan;
  12.301 +	if (reverb) {
  12.302 +	    unsigned val;
  12.303 +	    val = buf[43] & 0x0f;
  12.304 +	    if (val > 0)
  12.305 +		val--;
  12.306 +	    buf[43] = (buf[43] & 0xf0) | val;
  12.307 +	}
  12.308 +    } else {
  12.309 +	int mode;
  12.310 +	if (buf[46] & 1)
  12.311 +	    mode = 2;
  12.312 +	else
  12.313 +	    mode = 0;
  12.314 +	if (buf[57] & 1)
  12.315 +	    mode++;
  12.316 +	buf[50] &= 0xc0;
  12.317 +	if (mode == 3)
  12.318 +	    buf[49] &= 0xc0;
  12.319 +	if (mode == 1)
  12.320 +	    buf[39] &= 0xc0;
  12.321 +	if (mode == 2 || mode == 3)
  12.322 +	    buf[38] &= 0xc0;
  12.323 +	buf[46] = (buf[46] & 0xcf) | pan;
  12.324 +	buf[57] = (buf[57] & 0xcf) | pan;
  12.325 +	if (mode == 1 && reverb) {
  12.326 +	    unsigned val;
  12.327 +	    val = buf[43] & 0x0f;
  12.328 +	    if (val > 0)
  12.329 +		val--;
  12.330 +	    buf[43] = (buf[43] & 0xf0) | val;
  12.331 +	    val = buf[54] & 0x0f;
  12.332 +	    if (val > 0)
  12.333 +		val--;
  12.334 +	    buf[54] = (buf[54] & 0xf0) | val;
  12.335 +	}
  12.336 +    }
  12.337 +}
  12.338 +
  12.339 +void loadfm()
  12.340 +{
  12.341 +    int sbfd, i, n, voice_size, data_size;
  12.342 +    char buf[60];
  12.343 +    struct sbi_instrument instr;
  12.344 +
  12.345 +    for (i = 0; i < 256; i++)
  12.346 +	fmloaded[i] = 0;
  12.347 +    srand(getpid());
  12.348 +    if (wantopl3) {
  12.349 +	voice_size = 60;
  12.350 +	sbfd = open(O3MELODIC, O_RDONLY, 0);
  12.351 +    } else {
  12.352 +	voice_size = 52;
  12.353 +	sbfd = open(SBMELODIC, O_RDONLY, 0);
  12.354 +    }
  12.355 +    if (sbfd == -1)
  12.356 +    {
  12.357 +        /* error: should quit */
  12.358 +    }
  12.359 +    instr.device = sb_dev;
  12.360 +
  12.361 +    for (i = 0; i < 128; i++) {
  12.362 +	if (read(sbfd, buf, voice_size) != voice_size)
  12.363 +	{
  12.364 +	    /* error: should quit */
  12.365 +	}
  12.366 +	instr.channel = i;
  12.367 +
  12.368 +	if (strncmp(buf, "4OP", 3) == 0) {
  12.369 +	    instr.key = OPL3_PATCH;
  12.370 +	    data_size = 22;
  12.371 +	} else {
  12.372 +	    instr.key = FM_PATCH;
  12.373 +	    data_size = 11;
  12.374 +	}
  12.375 +
  12.376 +	fmloaded[i] = instr.key;
  12.377 +
  12.378 +	adjustfm(buf, instr.key);
  12.379 +	for (n = 0; n < 32; n++)
  12.380 +	    instr.operators[n] = (n < data_size) ? buf[36 + n] : 0;
  12.381 +
  12.382 +	SEQ_WRPATCH(&instr, sizeof(instr));
  12.383 +    }
  12.384 +    close(sbfd);
  12.385 +
  12.386 +    if (wantopl3)
  12.387 +	sbfd = open(O3DRUMS, O_RDONLY, 0);
  12.388 +    else
  12.389 +	sbfd = open(SBDRUMS, O_RDONLY, 0);
  12.390 +
  12.391 +    for (i = 128; i < 175; i++) {
  12.392 +	if (read(sbfd, buf, voice_size) != voice_size)
  12.393 +	{
  12.394 +	    /* error: should quit */
  12.395 +	}
  12.396 +	instr.channel = i;
  12.397 +
  12.398 +	if (strncmp(buf, "4OP", 3) == 0) {
  12.399 +	    instr.key = OPL3_PATCH;
  12.400 +	    data_size = 22;
  12.401 +	} else {
  12.402 +	    instr.key = FM_PATCH;
  12.403 +	    data_size = 11;
  12.404 +	}
  12.405 +	fmloaded[i] = instr.key;
  12.406 +
  12.407 +	adjustfm(buf, instr.key);
  12.408 +	for (n = 0; n < 32; n++)
  12.409 +	    instr.operators[n] = (n < data_size) ? buf[n + 36] : 0;
  12.410 +
  12.411 +	SEQ_WRPATCH(&instr, sizeof(instr));
  12.412 +    }
  12.413 +    close(sbfd);
  12.414 +}
  12.415 +#endif /* linux || FreeBSD */
    13.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    13.2 +++ b/native_midi_gpl/playevents.c	Wed Feb 13 19:07:39 2002 +0000
    13.3 @@ -0,0 +1,217 @@
    13.4 +/************************************************************************
    13.5 +   playevents.c  -- actually sends sorted list of events to device
    13.6 +
    13.7 +   Copyright (C) 1994-1996 Nathan I. Laredo
    13.8 +
    13.9 +   This program is modifiable/redistributable under the terms
   13.10 +   of the GNU General Public Licence.
   13.11 +
   13.12 +   You should have received a copy of the GNU General Public License
   13.13 +   along with this program; if not, write to the Free Software
   13.14 +   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
   13.15 +   Send your comments and all your spare pocket change to
   13.16 +   laredo@gnu.ai.mit.edu (Nathan Laredo) or to PSC 1, BOX 709, 2401
   13.17 +   Kelly Drive, Lackland AFB, TX 78236-5128, USA.
   13.18 + *************************************************************************/
   13.19 +/*    edited by Peter Kutak           */
   13.20 +/*    email : kutak@stonline.sk       */
   13.21 +
   13.22 +#if defined(linux) || defined(__FreeBSD__)
   13.23 +
   13.24 +#include "playmidi.h"
   13.25 +#include <sys/time.h>
   13.26 +
   13.27 +extern int seq_set_patch(int, int);
   13.28 +extern void seq_key_pressure(int, int, int, int);
   13.29 +extern void seq_start_note(int, int, int, int);
   13.30 +extern void seq_stop_note(int, int, int, int);
   13.31 +extern void seq_control(int, int, int, int);
   13.32 +extern void seq_chn_pressure(int, int, int);
   13.33 +extern void seq_bender(int, int, int, int);
   13.34 +extern void seq_reset();
   13.35 +
   13.36 +SEQ_USE_EXTBUF();
   13.37 +extern int division, ntrks, format;
   13.38 +extern int gus_dev, ext_dev, sb_dev, awe_dev, perc, seqfd, p_remap;
   13.39 +extern int play_gus, play_fm, play_ext, play_awe, reverb, chorus, chanmask;
   13.40 +extern int usevol[16];
   13.41 +extern struct miditrack seq[MAXTRKS];
   13.42 +extern float skew;
   13.43 +extern unsigned long int default_tempo;
   13.44 +extern char ImPlaying,StopPlease;
   13.45 +extern void load_sysex(int, unsigned char *, int);
   13.46 +
   13.47 +unsigned long int ticks, tempo;
   13.48 +struct timeval start_time;
   13.49 +
   13.50 +unsigned long int rvl(s)
   13.51 +struct miditrack *s;
   13.52 +{
   13.53 +    register unsigned long int value = 0;
   13.54 +    register unsigned char c;
   13.55 +
   13.56 +    if (s->index < s->length && ((value = s->data[(s->index)++]) & 0x80)) {
   13.57 +	value &= 0x7f;
   13.58 +	do {
   13.59 +	    if (s->index >= s->length)
   13.60 +		c = 0;
   13.61 +	    else
   13.62 +		value = (value << 7) +
   13.63 +		    ((c = s->data[(s->index)++]) & 0x7f);
   13.64 +	} while (c & 0x80);
   13.65 +    }
   13.66 +    return (value);
   13.67 +}
   13.68 +
   13.69 +/* indexed by high nibble of command */
   13.70 +int cmdlen[16] =
   13.71 +{0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 2, 2, 1, 1, 2, 0};
   13.72 +
   13.73 +#define CMD		seq[track].running_st
   13.74 +#define TIME		seq[track].ticks
   13.75 +#define CHN		(CMD & 0xf)
   13.76 +#define NOTE		data[0]
   13.77 +#define VEL		data[1]
   13.78 +
   13.79 +int playevents()
   13.80 +{
   13.81 +    unsigned long int tempo = default_tempo, lasttime = 0;
   13.82 +    unsigned int lowtime, track, best, length, loaded;
   13.83 +    unsigned char *data;
   13.84 +    double current = 0.0, dtime = 0.0;
   13.85 +    int use_dev, play_status, playing = 1;
   13.86 +
   13.87 +    seq_reset();
   13.88 +    gettimeofday(&start_time, NULL);	/* for synchronization */
   13.89 +    for (track = 0; track < ntrks; track++) {
   13.90 +	seq[track].index = seq[track].running_st = 0;
   13.91 +	seq[track].ticks = rvl(&seq[track]);
   13.92 +    }
   13.93 +    for (best = 0; best < 16; best++) {
   13.94 +	if (ISAWE(best))
   13.95 +	    use_dev = awe_dev;
   13.96 +	else if (ISGUS(best))
   13.97 +	    use_dev = gus_dev;
   13.98 +	else if (ISFM(best))
   13.99 +	    use_dev = sb_dev;
  13.100 +	else
  13.101 +	    use_dev = ext_dev;
  13.102 +	seq_control(use_dev, best, CTL_BANK_SELECT, 0);
  13.103 +	seq_control(use_dev, best, CTL_EXT_EFF_DEPTH, reverb);
  13.104 +	seq_control(use_dev, best, CTL_CHORUS_DEPTH, chorus);
  13.105 +	seq_control(use_dev, best, CTL_MAIN_VOLUME, 127);
  13.106 +	seq_chn_pressure(use_dev, best, 127);
  13.107 +	seq_control(use_dev, best, 0x4a, 127);
  13.108 +    }
  13.109 +    SEQ_START_TIMER();
  13.110 +    SEQ_DUMPBUF();
  13.111 +    while (playing) {
  13.112 +	lowtime = ~0;
  13.113 +	for (best = track = 0; track < ntrks; track++)
  13.114 +	    if (seq[track].ticks < lowtime) {
  13.115 +		best = track;
  13.116 +		lowtime = TIME;
  13.117 +	    }
  13.118 +	if (lowtime == ~0)
  13.119 +	    break;		/* no more data to read */
  13.120 +	track = best;
  13.121 +	if (ISMIDI(CHN))
  13.122 +	    use_dev = ext_dev;
  13.123 +	else if (ISAWE(CHN))
  13.124 +	    use_dev = awe_dev;
  13.125 +	else if (ISGUS(CHN))
  13.126 +	    use_dev = gus_dev;
  13.127 +	else
  13.128 +	    use_dev = sb_dev;
  13.129 +
  13.130 +	/* this section parses data in midi file buffer */
  13.131 +	if ((seq[track].data[seq[track].index] & 0x80) &&
  13.132 +	    (seq[track].index < seq[track].length))
  13.133 +	    CMD = seq[track].data[seq[track].index++];
  13.134 +	if (CMD == 0xff && seq[track].index < seq[track].length)
  13.135 +	    CMD = seq[track].data[seq[track].index++];
  13.136 +	if (CMD > 0xf7)	/* midi real-time message (ignored) */
  13.137 +	    length = 0;
  13.138 +	else if (!(length = cmdlen[(CMD & 0xf0) >> 4]))
  13.139 +	    length = rvl(&seq[track]);
  13.140 +
  13.141 +	if (seq[track].index + length < seq[track].length) {
  13.142 +	    /* use the parsed midi data */
  13.143 +	    data = &(seq[track].data[seq[track].index]);
  13.144 +	    if (CMD == set_tempo)
  13.145 +		tempo = ((*(data) << 16) | (data[1] << 8) | data[2]);
  13.146 +	    if (TIME > lasttime) {
  13.147 +		if (division > 0) {
  13.148 +		    dtime = ((double) ((TIME - lasttime) * (tempo / 10000)) /
  13.149 +			     (double) (division)) * skew;
  13.150 +		    current += dtime;
  13.151 +		    lasttime = TIME;
  13.152 +		} else if (division < 0)
  13.153 +		    current = ((double) TIME /
  13.154 +			       ((double) ((division & 0xff00 >> 8) *
  13.155 +				   (division & 0xff)) * 10000.0)) * skew;
  13.156 +		/* stop if there's more than 40 seconds of nothing */
  13.157 +		if (dtime > 4096.0)
  13.158 +		    playing = 0;
  13.159 +		else if ((int) current > ticks) {
  13.160 +		    SEQ_WAIT_TIME((ticks = (int) current));
  13.161 +		    SEQ_DUMPBUF();
  13.162 +		}
  13.163 +	    }
  13.164 +	    if (CMD > 0x7f && CMD < 0xf0 && ISPERC(CHN) && p_remap) {
  13.165 +		CMD &= 0xf0;
  13.166 +		CMD |= (p_remap - 1);
  13.167 +	    }
  13.168 +	    loaded = 0;		/* for patch setting failures */
  13.169 +	    if (playing && CMD > 0x7f && ISPLAYING(CHN))
  13.170 +		switch (CMD & 0xf0) {
  13.171 +		case MIDI_KEY_PRESSURE:
  13.172 +		    if (ISPERC(CHN) && VEL && (!ISMIDI(CHN)&&!ISAWE(CHN)))
  13.173 +			loaded = seq_set_patch(CHN, NOTE + 128);
  13.174 +		    if (loaded != -1)
  13.175 +			seq_key_pressure(use_dev, CHN, NOTE, VEL);
  13.176 +		    break;
  13.177 +		case MIDI_NOTEON:
  13.178 +		    if (ISPERC(CHN) && VEL && (!ISMIDI(CHN)&&!ISAWE(CHN)))
  13.179 +			loaded = seq_set_patch(CHN, NOTE + 128);
  13.180 +		    if (VEL && usevol[CHN])
  13.181 +			VEL = usevol[CHN];
  13.182 +		    if (loaded != -1)
  13.183 +			seq_start_note(use_dev, CHN, NOTE, VEL);
  13.184 +		    break;
  13.185 +		case MIDI_NOTEOFF:
  13.186 +		    seq_stop_note(use_dev, CHN, NOTE, VEL);
  13.187 +		    break;
  13.188 +		case MIDI_CTL_CHANGE:
  13.189 +		    seq_control(use_dev, CHN, NOTE, VEL);
  13.190 +		    break;
  13.191 +		case MIDI_CHN_PRESSURE:
  13.192 +		    seq_chn_pressure(use_dev, CHN, NOTE);
  13.193 +		    break;
  13.194 +		case MIDI_PITCH_BEND:
  13.195 +		    seq_bender(use_dev, CHN, NOTE, VEL);
  13.196 +		    break;
  13.197 +		case MIDI_PGM_CHANGE:
  13.198 +		    if (ISMIDI(CHN) || ISAWE(CHN) || !ISPERC(CHN))
  13.199 +			NOTE = seq_set_patch(CHN, NOTE);
  13.200 +		    break;
  13.201 +		case MIDI_SYSTEM_PREFIX:
  13.202 +		    if (length > 1)
  13.203 +			load_sysex(length, data, CMD);
  13.204 +		    break;
  13.205 +		default:
  13.206 +		    break;
  13.207 +		}
  13.208 +	}
  13.209 +	/* this last little part queues up the next event time */
  13.210 +	seq[track].index += length;
  13.211 +	if (seq[track].index >= seq[track].length)
  13.212 +	    seq[track].ticks = ~0;	/* mark track complete */
  13.213 +	else
  13.214 +	    seq[track].ticks += rvl(&seq[track]);
  13.215 +    }
  13.216 +    SEQ_DUMPBUF();
  13.217 +    ImPlaying = 0;
  13.218 +    return 1;
  13.219 +}
  13.220 +#endif /* linux || FreeBSD */
    14.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    14.2 +++ b/native_midi_gpl/playmidi.h	Wed Feb 13 19:07:39 2002 +0000
    14.3 @@ -0,0 +1,107 @@
    14.4 +#define RELEASE "Playmidi 2.4"
    14.5 +/************************************************************************
    14.6 +   playmidi.h  --  defines and structures for use by playmidi package
    14.7 +
    14.8 +   Copyright (C) 1994-1996 Nathan I. Laredo
    14.9 +
   14.10 +   This program is modifiable/redistributable under the terms
   14.11 +   of the GNU General Public Licence.
   14.12 +
   14.13 +   You should have received a copy of the GNU General Public License
   14.14 +   along with this program; if not, write to the Free Software
   14.15 +   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
   14.16 +   Send your comments and all your spare pocket change to
   14.17 +   laredo@gnu.ai.mit.edu (Nathan Laredo) or to PSC 1, BOX 709, 2401
   14.18 +   Kelly Drive, Lackland AFB, TX 78236-5128, USA.
   14.19 + *************************************************************************
   14.20 +/*    edited by Peter Kutak          */
   14.21 +/*    email : kutak@stonline.sk      */
   14.22 +
   14.23 +
   14.24 +/* Default mask for percussion instruments.  Channels 16 and 10 = 0x8200 */
   14.25 +#define PERCUSSION	0x0200
   14.26 +/* change the following if you have lots of synth devices */
   14.27 +#define MAX_CARDS	5
   14.28 +/* the following definition is set by Configure */
   14.29 +#define FM_DEFAULT_MODE	0
   14.30 +/* the following definition is set by Configure */
   14.31 +#define PATCH_PATH1	"/dos/ultrasnd/midi"
   14.32 +/* the following definition is set by Configure */
   14.33 +#define PATCH_PATH2	"/usr/local/lib/Plib"
   14.34 +/* change this if you notice performance problems,  128 bytes by default */
   14.35 +#define SEQUENCERBLOCKSIZE 128
   14.36 +/* change this if you have really outrageous midi files > 128 tracks */
   14.37 +/* 128 tracks is approximately a 4K structure */
   14.38 +#define MAXTRKS		128
   14.39 +/* where to find fm patch libraries */
   14.40 +#define SEQUENCER_DEV	"/dev/sequencer"
   14.41 +#define O3MELODIC	"/etc/std.o3"
   14.42 +#define O3DRUMS		"/etc/drums.o3"
   14.43 +#define SBMELODIC	"/etc/std.sb"
   14.44 +#define SBDRUMS		"/etc/drums.sb"
   14.45 +#define ISPERC(x)	(perc & (1 << x))
   14.46 +#define ISGUS(x)	(play_gus & (1 << x))
   14.47 +#define ISFM(x)		(play_fm & (1 << x))
   14.48 +#define ISMIDI(x)	(play_ext & (1 << x))
   14.49 +#define ISAWE(x)	(play_awe & (1 << x))
   14.50 +#define ISPLAYING(x)	(chanmask & (1 << x))
   14.51 +#define NO_EXIT		100
   14.52 +
   14.53 +#include <stdio.h>
   14.54 +#include <string.h>
   14.55 +#include <stdlib.h>
   14.56 +#include <sys/soundcard.h>
   14.57 +#include <sys/ioctl.h>
   14.58 +#ifdef linux
   14.59 +#include <linux/awe_voice.h>
   14.60 +#else
   14.61 +#include <awe_voice.h>
   14.62 +#endif
   14.63 +
   14.64 +struct chanstate {
   14.65 +    int program;
   14.66 +    int bender;
   14.67 +    int oldbend;	/* used for graphics */
   14.68 +    int bender_range;
   14.69 +    int oldrange;	/* used for graphics */
   14.70 +    int controller[255];
   14.71 +    int pressure;
   14.72 +};
   14.73 +
   14.74 +struct voicestate {
   14.75 +    int note;
   14.76 +    int channel;
   14.77 +    int timestamp;
   14.78 +    int dead;
   14.79 +};
   14.80 +/* Non-standard MIDI file formats */
   14.81 +#define RIFF			0x52494646
   14.82 +#define CTMF			0x43544d46
   14.83 +/* Standard MIDI file format definitions */
   14.84 +#define MThd			0x4d546864
   14.85 +#define MTrk			0x4d54726b
   14.86 +#define	meta_event		0xff
   14.87 +#define	sequence_number 	0x00
   14.88 +#define	text_event		0x01
   14.89 +#define copyright_notice 	0x02
   14.90 +#define sequence_name    	0x03
   14.91 +#define instrument_name 	0x04
   14.92 +#define lyric	        	0x05
   14.93 +#define marker			0x06
   14.94 +#define	cue_point		0x07
   14.95 +#define channel_prefix		0x20
   14.96 +#define	end_of_track		0x2f
   14.97 +#define	set_tempo		0x51
   14.98 +#define	smpte_offset		0x54
   14.99 +#define	time_signature		0x58
  14.100 +#define	key_signature		0x59
  14.101 +#define	sequencer_specific	0x74
  14.102 +
  14.103 +struct miditrack {
  14.104 +   unsigned char *data;		/* data of midi track */
  14.105 +   unsigned long int length;	/* length of track data */
  14.106 +   unsigned long int index;	/* current byte in track */
  14.107 +   unsigned long int ticks;	/* current midi tick count */
  14.108 +   unsigned char running_st;	/* running status byte */
  14.109 +};
  14.110 +
    15.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    15.2 +++ b/native_midi_gpl/readmidi.c	Wed Feb 13 19:07:39 2002 +0000
    15.3 @@ -0,0 +1,188 @@
    15.4 +/************************************************************************
    15.5 +   readmidi.c -- last change: 1 Jan 96
    15.6 +
    15.7 +   Creates a linked list of each chunk in a midi file.
    15.8 +   ENTIRE MIDI FILE IS RETAINED IN MEMORY so that no additional malloc
    15.9 +   calls need be made to store the data of the events in the midi file.
   15.10 +
   15.11 +   Copyright (C) 1995-1996 Nathan I. Laredo
   15.12 +
   15.13 +   This program is modifiable/redistributable under the terms
   15.14 +   of the GNU General Public Licence.
   15.15 +
   15.16 +   You should have received a copy of the GNU General Public License
   15.17 +   along with this program; if not, write to the Free Software
   15.18 +   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
   15.19 +   Send your comments and all your spare pocket change to
   15.20 +   laredo@gnu.ai.mit.edu (Nathan Laredo) or to PSC 1, BOX 709, 2401
   15.21 +   Kelly Drive, Lackland AFB, TX 78236-5128, USA.
   15.22 + *************************************************************************/
   15.23 +/*    edited by Peter Kutak           */
   15.24 +/*    email : kutak@stonline.sk       */
   15.25 +
   15.26 +#if defined(linux) || defined(__FreeBSD__)
   15.27 +
   15.28 +#include "playmidi.h"
   15.29 +#include <unistd.h>
   15.30 +
   15.31 +int format, ntrks, division;
   15.32 +unsigned char *midifilebuf;
   15.33 +
   15.34 +/* the following few lines are needed for dealing with CMF files */
   15.35 +int reloadfm = 0;
   15.36 +extern void loadfm();
   15.37 +extern int seqfd, sb_dev, wantopl3, play_fm, fmloaded[256];
   15.38 +SEQ_USE_EXTBUF();
   15.39 +
   15.40 +extern struct miditrack seq[MAXTRKS];
   15.41 +extern unsigned long int default_tempo;
   15.42 +
   15.43 +unsigned short Read16()
   15.44 +{
   15.45 +    register unsigned short x;
   15.46 +
   15.47 +    x = (*(midifilebuf) << 8) | midifilebuf[1];
   15.48 +    midifilebuf += 2;
   15.49 +    return x;
   15.50 +}
   15.51 +
   15.52 +unsigned long Read32()
   15.53 +{
   15.54 +    register unsigned long x;
   15.55 +
   15.56 +    x = (*(midifilebuf) << 24) | (midifilebuf[1] << 16) |
   15.57 +	(midifilebuf[2] << 8) | midifilebuf[3];
   15.58 +    midifilebuf += 4;
   15.59 +    return x;
   15.60 +}
   15.61 +
   15.62 +int readmidi(filebuf, filelength)
   15.63 +unsigned char *filebuf;
   15.64 +off_t filelength;
   15.65 +{
   15.66 +    unsigned long int i = 0, track, tracklen;
   15.67 +
   15.68 +    midifilebuf = filebuf;
   15.69 +    /* allow user to specify header number in from large archive */
   15.70 +#if 0
   15.71 +    while (i != find_header && midifilebuf < (filebuf + filelength - 32)) {
   15.72 +	if (strncmp(midifilebuf, "MThd", 4) == 0) {
   15.73 +	    i++;
   15.74 +	    midifilebuf += 4;
   15.75 +	} else
   15.76 +	    midifilebuf++;
   15.77 +    }
   15.78 +    if (i != find_header) {	/* specified header was not found */
   15.79 +	midifilebuf = filebuf;
   15.80 +	return find_header = 0;
   15.81 +    }
   15.82 +#endif
   15.83 +    if (midifilebuf != filebuf)
   15.84 +	midifilebuf -= 4;
   15.85 +    i = Read32();
   15.86 +    if (i == RIFF) {
   15.87 +	midifilebuf += 16;
   15.88 +	i = Read32();
   15.89 +    }
   15.90 +    if (i == MThd) {
   15.91 +	tracklen = Read32();
   15.92 +	format = Read16();
   15.93 +	ntrks = Read16();
   15.94 +	division = Read16();
   15.95 +    } else if (i == CTMF) {
   15.96 +	/* load a creative labs CMF file, with instruments for fm */
   15.97 +	tracklen = midifilebuf[4] | (midifilebuf[5] << 8);
   15.98 +	format = 0;
   15.99 +	ntrks = 1;
  15.100 +	division = midifilebuf[6] | (midifilebuf[7] << 8);
  15.101 +	default_tempo = 1000000 * division /
  15.102 +		(midifilebuf[8] | (midifilebuf[9] << 8));
  15.103 +	seq[0].data = filebuf + tracklen;
  15.104 +	seq[0].length = filelength - tracklen;
  15.105 +	i = (unsigned long int) (*(short *) &midifilebuf[2]) - 4;
  15.106 +	/* if fm playback is enabled, load all fm patches from file */
  15.107 +	if (play_fm) {
  15.108 +	    struct sbi_instrument instr;
  15.109 +	    int j, k;
  15.110 +	    reloadfm = midifilebuf[32]; /* number of custom patches */
  15.111 +            instr.device = sb_dev;
  15.112 +	    for (j = 0; j < 32; j++)
  15.113 +		instr.operators[j] = 0x3f;
  15.114 +	    instr.key = FM_PATCH;
  15.115 +	    for (j = 0; j < reloadfm && j < 255; j++) {
  15.116 +                instr.channel = j;
  15.117 +		fmloaded[j] = instr.key;
  15.118 +                for (k = 0; k < 16; k++)
  15.119 +		    instr.operators[k] = midifilebuf[i + (16 * j) + k];
  15.120 +		SEQ_WRPATCH(&instr, sizeof(instr));
  15.121 +	    }
  15.122 +	}
  15.123 +	return ntrks;
  15.124 +    } else {
  15.125 +	int found = 0;
  15.126 +	while (!found && midifilebuf < (filebuf + filelength - 8))
  15.127 +	    if (strncmp(midifilebuf, "MThd", 4) == 0)
  15.128 +		found++;
  15.129 +	    else
  15.130 +		midifilebuf++;
  15.131 +	if (found) {
  15.132 +	    midifilebuf += 4;
  15.133 +	    tracklen = Read32();
  15.134 +	    format = Read16();
  15.135 +	    ntrks = Read16();
  15.136 +	    division = Read16();
  15.137 +	} else {
  15.138 +#ifndef DISABLE_RAW_MIDI_FILES
  15.139 +	    /* this allows playing ANY file, so watch out */
  15.140 +	    midifilebuf -= 4;
  15.141 +	    format = 0;		/* assume it's .mus file ? */
  15.142 +	    ntrks = 1;
  15.143 +	    division = 40;
  15.144 +#else
  15.145 +	    return -1;
  15.146 +#endif
  15.147 +	}
  15.148 +    }
  15.149 +    if (ntrks > MAXTRKS) {
  15.150 +	fprintf(stderr, "\nWARNING: %d TRACKS IGNORED!\n", ntrks - MAXTRKS);
  15.151 +	ntrks = MAXTRKS;
  15.152 +    }
  15.153 +    if (play_fm && reloadfm) {
  15.154 +	loadfm();	/* if custom CMF patches loaded, replace */
  15.155 +	reloadfm = 0;
  15.156 +    }
  15.157 +    for (track = 0; track < ntrks; track++) {
  15.158 +	if (Read32() != MTrk) {
  15.159 +	    /* MTrk isn't where it's supposed to be, search rest of file */
  15.160 +	    int fuzz, found = 0;
  15.161 +	    midifilebuf -= 4;
  15.162 +	    if (strncmp(midifilebuf, "MThd", 4) == 0)
  15.163 +		continue;
  15.164 +	    else {
  15.165 +		if (!track) {
  15.166 +		    seq[0].length = filebuf + filelength - midifilebuf;
  15.167 +		    seq[0].data = midifilebuf;
  15.168 +		    continue;	/* assume raw midi data file */
  15.169 +		}
  15.170 +		midifilebuf -= seq[track - 1].length;
  15.171 +		for (fuzz = 0; (fuzz + midifilebuf) <
  15.172 +		     (filebuf + filelength - 8) && !found; fuzz++)
  15.173 +		    if (strncmp(&midifilebuf[fuzz], "MTrk", 4) == 0)
  15.174 +			found++;
  15.175 +		seq[track - 1].length = fuzz;
  15.176 +		midifilebuf += fuzz;
  15.177 +		if (!found)
  15.178 +		    continue;
  15.179 +	    }
  15.180 +	}
  15.181 +	tracklen = Read32();
  15.182 +	if (midifilebuf + tracklen > filebuf + filelength)
  15.183 +	    tracklen = filebuf + filelength - midifilebuf;
  15.184 +	seq[track].length = tracklen;
  15.185 +	seq[track].data = midifilebuf;
  15.186 +	midifilebuf += tracklen;
  15.187 +    }
  15.188 +    ntrks = track;
  15.189 +    return ntrks;
  15.190 +}
  15.191 +#endif /* linux || FreeBSD */