1 /*************************************************************************
2  *  musserver.h
3  *
4  *  update to lxdoom
5  *  Copyright (C) 1999 Rafael Reilova (rreilova@ececs.uc.edu)
6  *
7  *  Original code
8  *  Copyright (C) 1995 Michael Heasley (mheasley@hmc.edu)
9  *
10  *  This program is free software; you can redistribute it and/or modify
11  *  it under the terms of the GNU General Public License as published by
12  *  the Free Software Foundation; either version 2 of the License, or
13  *  (at your option) any later version.
14  *
15  *  This program is distributed in the hope that it will be useful,
16  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
17  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  *  GNU General Public License for more details.
19  *
20  *  You should have received a copy of the GNU General Public License
21  *  along with this program; if not, write to the Free Software
22  *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
23  *************************************************************************/
24 
25 #ifdef __linux__
26 #  include <sys/soundcard.h>
27 #  include <linux/version.h>
28 /* Seems AWE began to work on 2.1.64 */
29 #  if (LINUX_VERSION_CODE > 131392)
30 #    define ENABLE_AWE
31 #    include <linux/awe_voice.h>
32 #  endif
33 #elif defined(__FreeBSD__) || defined(__DragonFly__)
34 #  include <machine/soundcard.h>
35 #  include <awe_voice.h>
36 #endif
37 
38 #ifndef __PACKED__
39 #define __PACKED__
40 #endif
41 
42 extern char *progname;
43 extern int verbose;
44 extern int unknevents;
45 extern int timer_res;          /* sequencer timer resolution (tics/sec) */
46 extern int curtime;            /* current song time in sequencer tics   */
47 extern int voxware_octave_bug; /* increase octave by 1 when using FM    */
48 extern int dumpmus;            /* dump to disk music and FM-patches     */
49 
50 #define DFL_VOL 12      /* default volume when standalone 1-15 (0 == off) */
51 #define CLEAN_EXIT   0
52 #define IO_ERROR     1
53 #define MISC_ERROR   2  /* doesn't call perror() */
54 
55 #define MUS_LOOP     1
56 #define MUS_NOLOOP   0
57 #define MUS_NEWSONG  1
58 #define MUS_SAMESONG 0
59 
60 #define NO_PATCH_NEEDED 0
61 #define PATCH_NEEDED    1
62 
63 /* number of instruments   */
64 #define N_INTR          175
65 /* number of MIDI channels */
66 #define N_CHN            16
67 
68 
69 typedef char (instr_nam)[32];
70 
71 /*
72  * Note: gcc attribute "packed" is used to make sure the compiler doesn't
73  * try to optimize the structures by aligning elements to word boundaries, etc.
74  */
75 
76 struct OPL2instrument {
77   unsigned char trem_vibr_1;    /* OP 1: tremolo/vibrato/sustain/KSR/multi */
78   unsigned char att_dec_1;      /* OP 1: attack rate/decay rate */
79   unsigned char sust_rel_1;     /* OP 1: sustain level/release rate */
80   unsigned char wave_1;         /* OP 1: waveform select */
81   unsigned char scale_1;        /* OP 1: key scale level */
82   unsigned char level_1;        /* OP 1: output level */
83   unsigned char feedback;       /* feedback/AM-FM (both operators) */
84   unsigned char trem_vibr_2;    /* OP 2: tremolo/vibrato/sustain/KSR/multi */
85   unsigned char att_dec_2;      /* OP 2: attack rate/decay rate */
86   unsigned char sust_rel_2;     /* OP 2: sustain level/release rate */
87   unsigned char wave_2;         /* OP 2: waveform select */
88   unsigned char scale_2;        /* OP 2: key scale level */
89   unsigned char level_2;        /* OP 2: output level */
90   unsigned char unused;
91   short         basenote;       /* base note offset */
92 }  __PACKED__ ;
93 
94 
95 struct opl_instr {
96 	unsigned short        flags;
97 #define FL_FIXED_PITCH  0x0001          // note has fixed pitch (drum note)
98 #define FL_UNKNOWN      0x0002          // ??? (used in instrument #65 only)
99 #define FL_DOUBLE_VOICE 0x0004          // use two voices instead of one
100 
101 	unsigned char         finetune;
102 	unsigned char         note;
103 	struct OPL2instrument patchdata[2];
104 }  __PACKED__ ;
105 
106 
107 typedef struct OPLfile {
108      unsigned char     id[8];
109      struct opl_instr *opl_instruments;
110      instr_nam        *instrument_nam;
111 } OPLFILE;
112 
113 
114 struct MUSheader {
115 	char           id[4];          // identifier "MUS" 0x1A
116 	unsigned short scoreLen;
117 	unsigned short scoreStart;
118 	unsigned short channels;       // count of primary channels
119 	unsigned short sec_channels;   // count of secondary channels
120 	unsigned short instrCnt;
121 	unsigned short dummy;
122 }  __PACKED__ ;
123 
124 
125 typedef struct MUSfile {
126 	struct MUSheader  header;
127         unsigned short   *instr_pnum;
128 	unsigned char    *musdata;
129 } MUSFILE;
130 
131 typedef enum  {
132   USE_AWE_SYNTH, USE_MIDI_SYNTH, USE_FM_SYNTH,
133   USE_BEST_SYNTH, LIST_ONLY_SYNTH
134 } synthdev_t;
135 
136 typedef enum {
137   MIDI_START, MIDI_STOP, MIDI_PAUSE, MIDI_RESUME
138 } mid_timer_t;
139 
140 
141 extern void cleanup(int status, const char *msg) __attribute__ ((noreturn));
142 extern const MUSFILE *readmus(FILE *fp);
143 extern const OPLFILE *read_genmidi(FILE *fp);
144 extern void playmus(const struct MUSfile *mus, int newsong,
145 		    int looping, int monitor_fd);
146