00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028 #ifdef HAVE_CONFIG_H
00029 # include <config.h>
00030 #endif
00031
00032 #ifdef USE_FMOPL_MIDI
00033
00034 #include <cmath>
00035 #include "common_types.h"
00036 #ifndef PENTAGRAM
00037 #include "game.h"
00038 #endif
00039 #include "Flex.h"
00040 #include "xmidi.h"
00041 #include "exceptions.h"
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082 #define VEL_FUDGE 4
00083
00084 #include "fmopldrv.h"
00085 #include "fmopl.h"
00086 #include "utils.h"
00087 #include "databuf.h"
00088
00089
00090 const char *OplDriver::get_error_name(int error_code)
00091 {
00092 static const char *const midi_errors[] = {
00093 "No error",
00094 "Cannot connect",
00095 "Streaming not available",
00096 "Device not available",
00097 "Driver already open"
00098 };
00099
00100 if ((uint32) error_code >= sizeof(midi_errors))
00101 return "Unknown Error";
00102 return midi_errors[error_code];
00103 }
00104
00105
00106
00107
00108
00109
00110 static unsigned char midi_fm_instruments_table[128][11] = {
00111
00112
00113 {0x21, 0x21, 0x8f, 0x0c, 0xf2, 0xf2, 0x45, 0x76, 0x00, 0x00, 0x08},
00114 {0x31, 0x21, 0x4b, 0x09, 0xf2, 0xf2, 0x54, 0x56, 0x00, 0x00, 0x08},
00115 {0x31, 0x21, 0x49, 0x09, 0xf2, 0xf2, 0x55, 0x76, 0x00, 0x00, 0x08},
00116 {0xb1, 0x61, 0x0e, 0x09, 0xf2, 0xf3, 0x3b, 0x0b, 0x00, 0x00, 0x06},
00117 {0x01, 0x21, 0x57, 0x09, 0xf1, 0xf1, 0x38, 0x28, 0x00, 0x00, 0x00},
00118 {0x01, 0x21, 0x93, 0x09, 0xf1, 0xf1, 0x38, 0x28, 0x00, 0x00, 0x00},
00119 {0x21, 0x36, 0x80, 0x17, 0xa2, 0xf1, 0x01, 0xd5, 0x00, 0x00, 0x08},
00120 {0x01, 0x01, 0x92, 0x09, 0xc2, 0xc2, 0xa8, 0x58, 0x00, 0x00, 0x0a},
00121 {0x0c, 0x81, 0x5c, 0x09, 0xf6, 0xf3, 0x54, 0xb5, 0x00, 0x00, 0x00},
00122 {0x07, 0x11, 0x97, 0x89, 0xf6, 0xf5, 0x32, 0x11, 0x00, 0x00, 0x02},
00123 {0x17, 0x01, 0x21, 0x09, 0x56, 0xf6, 0x04, 0x04, 0x00, 0x00, 0x02},
00124 {0x18, 0x81, 0x62, 0x09, 0xf3, 0xf2, 0xe6, 0xf6, 0x00, 0x00, 0x00},
00125 {0x18, 0x21, 0x23, 0x09, 0xf7, 0xe5, 0x55, 0xd8, 0x00, 0x00, 0x00},
00126 {0x15, 0x01, 0x91, 0x09, 0xf6, 0xf6, 0xa6, 0xe6, 0x00, 0x00, 0x04},
00127 {0x45, 0x81, 0x59, 0x89, 0xd3, 0xa3, 0x82, 0xe3, 0x00, 0x00, 0x0c},
00128 {0x03, 0x81, 0x49, 0x89, 0x74, 0xb3, 0x55, 0x05, 0x01, 0x00, 0x04},
00129 {0x71, 0x31, 0x92, 0x09, 0xf6, 0xf1, 0x14, 0x07, 0x00, 0x00, 0x02},
00130 {0x72, 0x30, 0x14, 0x09, 0xc7, 0xc7, 0x58, 0x08, 0x00, 0x00, 0x02},
00131 {0x70, 0xb1, 0x44, 0x09, 0xaa, 0x8a, 0x18, 0x08, 0x00, 0x00, 0x04},
00132 {0x23, 0xb1, 0x93, 0x09, 0x97, 0x55, 0x23, 0x14, 0x01, 0x00, 0x04},
00133 {0x61, 0xb1, 0x13, 0x89, 0x97, 0x55, 0x04, 0x04, 0x01, 0x00, 0x00},
00134 {0x24, 0xb1, 0x48, 0x09, 0x98, 0x46, 0x2a, 0x1a, 0x01, 0x00, 0x0c},
00135 {0x61, 0x21, 0x13, 0x09, 0x91, 0x61, 0x06, 0x07, 0x01, 0x00, 0x0a},
00136 {0x21, 0xa1, 0x13, 0x92, 0x71, 0x61, 0x06, 0x07, 0x00, 0x00, 0x06},
00137 {0x02, 0x41, 0x9c, 0x89, 0xf3, 0xf3, 0x94, 0xc8, 0x01, 0x00, 0x0c},
00138 {0x03, 0x11, 0x54, 0x09, 0xf3, 0xf1, 0x9a, 0xe7, 0x01, 0x00, 0x0c},
00139 {0x23, 0x21, 0x5f, 0x09, 0xf1, 0xf2, 0x3a, 0xf8, 0x00, 0x00, 0x00},
00140 {0x03, 0x21, 0x87, 0x89, 0xf6, 0xf3, 0x22, 0xf8, 0x01, 0x00, 0x06},
00141 {0x03, 0x21, 0x47, 0x09, 0xf9, 0xf6, 0x54, 0x3a, 0x00, 0x00, 0x00},
00142 {0x23, 0x21, 0x4a, 0x0e, 0x91, 0x84, 0x41, 0x19, 0x01, 0x00, 0x08},
00143 {0x23, 0x21, 0x4a, 0x09, 0x95, 0x94, 0x19, 0x19, 0x01, 0x00, 0x08},
00144 {0x09, 0x84, 0xa1, 0x89, 0x20, 0xd1, 0x4f, 0xf8, 0x00, 0x00, 0x08},
00145 {0x21, 0xa2, 0x1e, 0x09, 0x94, 0xc3, 0x06, 0xa6, 0x00, 0x00, 0x02},
00146 {0x31, 0x31, 0x12, 0x09, 0xf1, 0xf1, 0x28, 0x18, 0x00, 0x00, 0x0a},
00147 {0x31, 0x31, 0x8d, 0x09, 0xf1, 0xf1, 0xe8, 0x78, 0x00, 0x00, 0x0a},
00148 {0x31, 0x32, 0x5b, 0x09, 0x51, 0x71, 0x28, 0x48, 0x00, 0x00, 0x0c},
00149 {0x01, 0x21, 0x8b, 0x49, 0xa1, 0xf2, 0x9a, 0xdf, 0x00, 0x00, 0x08},
00150 {0x21, 0x21, 0x8b, 0x11, 0xa2, 0xa1, 0x16, 0xdf, 0x00, 0x00, 0x08},
00151 {0x31, 0x31, 0x8b, 0x09, 0xf4, 0xf1, 0xe8, 0x78, 0x00, 0x00, 0x0a},
00152 {0x31, 0x31, 0x12, 0x09, 0xf1, 0xf1, 0x28, 0x18, 0x00, 0x00, 0x0a},
00153 {0x31, 0x21, 0x15, 0x09, 0xdd, 0x56, 0x13, 0x26, 0x01, 0x00, 0x08},
00154 {0x31, 0x21, 0x16, 0x09, 0xdd, 0x66, 0x13, 0x06, 0x01, 0x00, 0x08},
00155 {0x71, 0x31, 0x49, 0x09, 0xd1, 0x61, 0x1c, 0x0c, 0x01, 0x00, 0x08},
00156 {0x21, 0x23, 0x4d, 0x89, 0x71, 0x72, 0x12, 0x06, 0x01, 0x00, 0x02},
00157 {0xf1, 0xe1, 0x40, 0x09, 0xf1, 0x6f, 0x21, 0x16, 0x01, 0x00, 0x02},
00158 {0x02, 0x01, 0x1a, 0x89, 0xf5, 0x85, 0x75, 0x35, 0x01, 0x00, 0x00},
00159 {0x02, 0x01, 0x1d, 0x89, 0xf5, 0xf3, 0x75, 0xf4, 0x01, 0x00, 0x00},
00160 {0x10, 0x11, 0x41, 0x09, 0xf5, 0xf2, 0x05, 0xc3, 0x01, 0x00, 0x02},
00161 {0x21, 0xa2, 0x9b, 0x0a, 0xb1, 0x72, 0x25, 0x08, 0x01, 0x00, 0x0e},
00162 {0xa1, 0x21, 0x98, 0x09, 0x7f, 0x3f, 0x03, 0x07, 0x01, 0x01, 0x00},
00163 {0xa1, 0x61, 0x93, 0x09, 0xc1, 0x4f, 0x12, 0x05, 0x00, 0x00, 0x0a},
00164 {0x21, 0x61, 0x18, 0x09, 0xc1, 0x4f, 0x22, 0x05, 0x00, 0x00, 0x0c},
00165 {0x31, 0x72, 0x5b, 0x8c, 0xf4, 0x8a, 0x15, 0x05, 0x00, 0x00, 0x00},
00166 {0xa1, 0x61, 0x90, 0x09, 0x74, 0x71, 0x39, 0x67, 0x00, 0x00, 0x00},
00167 {0x71, 0x72, 0x57, 0x09, 0x54, 0x7a, 0x05, 0x05, 0x00, 0x00, 0x0c},
00168 {0x90, 0x41, 0x00, 0x09, 0x54, 0xa5, 0x63, 0x45, 0x00, 0x00, 0x08},
00169 {0x21, 0x21, 0x92, 0x0a, 0x85, 0x8f, 0x17, 0x09, 0x00, 0x00, 0x0c},
00170 {0x21, 0x21, 0x94, 0x0e, 0x75, 0x8f, 0x17, 0x09, 0x00, 0x00, 0x0c},
00171 {0x21, 0x61, 0x94, 0x09, 0x76, 0x82, 0x15, 0x37, 0x00, 0x00, 0x0c},
00172 {0x31, 0x21, 0x43, 0x09, 0x9e, 0x62, 0x17, 0x2c, 0x01, 0x01, 0x02},
00173 {0x21, 0x21, 0x9b, 0x09, 0x61, 0x7f, 0x6a, 0x0a, 0x00, 0x00, 0x02},
00174 {0x61, 0x22, 0x8a, 0x0f, 0x75, 0x74, 0x1f, 0x0f, 0x00, 0x00, 0x08},
00175 {0xa1, 0x21, 0x86, 0x8c, 0x72, 0x71, 0x55, 0x18, 0x01, 0x00, 0x00},
00176 {0x21, 0x21, 0x4d, 0x09, 0x54, 0xa6, 0x3c, 0x1c, 0x00, 0x00, 0x08},
00177 {0x31, 0x61, 0x8f, 0x09, 0x93, 0x72, 0x02, 0x0b, 0x01, 0x00, 0x08},
00178 {0x31, 0x61, 0x8e, 0x09, 0x93, 0x72, 0x03, 0x09, 0x01, 0x00, 0x08},
00179 {0x31, 0x61, 0x91, 0x09, 0x93, 0x82, 0x03, 0x09, 0x01, 0x00, 0x0a},
00180 {0x31, 0x61, 0x8e, 0x09, 0x93, 0x72, 0x0f, 0x0f, 0x01, 0x00, 0x0a},
00181 {0x21, 0x21, 0x4b, 0x09, 0xaa, 0x8f, 0x16, 0x0a, 0x01, 0x00, 0x08},
00182 {0x31, 0x21, 0x90, 0x09, 0x7e, 0x8b, 0x17, 0x0c, 0x01, 0x01, 0x06},
00183 {0x31, 0x32, 0x81, 0x09, 0x75, 0x61, 0x19, 0x19, 0x01, 0x00, 0x00},
00184 {0x32, 0x21, 0x90, 0x09, 0x9b, 0x72, 0x21, 0x17, 0x00, 0x00, 0x04},
00185 {0xe1, 0xe1, 0x1f, 0x09, 0x85, 0x65, 0x5f, 0x1a, 0x00, 0x00, 0x00},
00186 {0xe1, 0xe1, 0x46, 0x09, 0x88, 0x65, 0x5f, 0x1a, 0x00, 0x00, 0x00},
00187 {0xa1, 0x21, 0x9c, 0x09, 0x75, 0x75, 0x1f, 0x0a, 0x00, 0x00, 0x02},
00188 {0x31, 0x21, 0x8b, 0x09, 0x84, 0x65, 0x58, 0x1a, 0x00, 0x00, 0x00},
00189 {0xe1, 0xa1, 0x4c, 0x09, 0x66, 0x65, 0x56, 0x26, 0x00, 0x00, 0x00},
00190 {0x62, 0xa1, 0xcb, 0x09, 0x76, 0x55, 0x46, 0x36, 0x00, 0x00, 0x00},
00191 {0x62, 0xa1, 0xa2, 0x09, 0x57, 0x56, 0x07, 0x07, 0x00, 0x00, 0x0b},
00192 {0x62, 0xa1, 0x9c, 0x09, 0x77, 0x76, 0x07, 0x07, 0x00, 0x00, 0x0b},
00193 {0x22, 0x21, 0x59, 0x09, 0xff, 0xff, 0x03, 0x0f, 0x02, 0x00, 0x00},
00194 {0x21, 0x21, 0x0e, 0x09, 0xff, 0xff, 0x0f, 0x0f, 0x01, 0x01, 0x00},
00195 {0x22, 0x21, 0x46, 0x89, 0x86, 0x64, 0x55, 0x18, 0x00, 0x00, 0x00},
00196 {0x21, 0xa1, 0x45, 0x09, 0x66, 0x96, 0x12, 0x0a, 0x00, 0x00, 0x00},
00197 {0x21, 0x22, 0x8b, 0x09, 0x92, 0x91, 0x2a, 0x2a, 0x01, 0x00, 0x00},
00198 {0xa2, 0x61, 0x9e, 0x49, 0xdf, 0x6f, 0x05, 0x07, 0x00, 0x00, 0x02},
00199 {0x20, 0x60, 0x1a, 0x09, 0xef, 0x8f, 0x01, 0x06, 0x00, 0x02, 0x00},
00200 {0x21, 0x21, 0x8f, 0x86, 0xf1, 0xf4, 0x29, 0x09, 0x00, 0x00, 0x0a},
00201 {0x77, 0xa1, 0xa5, 0x09, 0x53, 0xa0, 0x94, 0x05, 0x00, 0x00, 0x02},
00202 {0x61, 0xb1, 0x1f, 0x89, 0xa8, 0x25, 0x11, 0x03, 0x00, 0x00, 0x0a},
00203 {0x61, 0x61, 0x17, 0x09, 0x91, 0x55, 0x34, 0x16, 0x00, 0x00, 0x0c},
00204 {0x71, 0x72, 0x5d, 0x09, 0x54, 0x6a, 0x01, 0x03, 0x00, 0x00, 0x00},
00205 {0x21, 0xa2, 0x97, 0x09, 0x21, 0x42, 0x43, 0x35, 0x00, 0x00, 0x08},
00206 {0xa1, 0x21, 0x1c, 0x09, 0xa1, 0x31, 0x77, 0x47, 0x01, 0x01, 0x00},
00207 {0x21, 0x61, 0x89, 0x0c, 0x11, 0x42, 0x33, 0x25, 0x00, 0x00, 0x0a},
00208 {0xa1, 0x21, 0x15, 0x09, 0x11, 0xcf, 0x47, 0x07, 0x01, 0x00, 0x00},
00209 {0x3a, 0x51, 0xce, 0x09, 0xf8, 0x86, 0xf6, 0x02, 0x00, 0x00, 0x02},
00210 {0x21, 0x21, 0x15, 0x09, 0x21, 0x41, 0x23, 0x13, 0x01, 0x00, 0x00},
00211 {0x06, 0x01, 0x5b, 0x09, 0x74, 0xa5, 0x95, 0x72, 0x00, 0x00, 0x00},
00212 {0x22, 0x61, 0x92, 0x8c, 0xb1, 0xf2, 0x81, 0x26, 0x00, 0x00, 0x0c},
00213 {0x41, 0x42, 0x4d, 0x09, 0xf1, 0xf2, 0x51, 0xf5, 0x01, 0x00, 0x00},
00214 {0x61, 0xa3, 0x94, 0x89, 0x11, 0x11, 0x51, 0x13, 0x01, 0x00, 0x06},
00215 {0x61, 0xa1, 0x8c, 0x89, 0x11, 0x1d, 0x31, 0x03, 0x00, 0x00, 0x06},
00216 {0xa4, 0x61, 0x4c, 0x09, 0xf3, 0x81, 0x73, 0x23, 0x01, 0x00, 0x04},
00217 {0x02, 0x07, 0x85, 0x0c, 0xd2, 0xf2, 0x53, 0xf6, 0x00, 0x01, 0x00},
00218 {0x11, 0x13, 0x0c, 0x89, 0xa3, 0xa2, 0x11, 0xe5, 0x01, 0x00, 0x00},
00219 {0x11, 0x11, 0x06, 0x09, 0xf6, 0xf2, 0x41, 0xe6, 0x01, 0x02, 0x04},
00220 {0x93, 0x91, 0x91, 0x09, 0xd4, 0xeb, 0x32, 0x11, 0x00, 0x01, 0x08},
00221 {0x04, 0x01, 0x4f, 0x09, 0xfa, 0xc2, 0x56, 0x05, 0x00, 0x00, 0x0c},
00222 {0x21, 0x22, 0x49, 0x09, 0x7c, 0x6f, 0x20, 0x0c, 0x00, 0x01, 0x06},
00223 {0x31, 0x21, 0x85, 0x09, 0xdd, 0x56, 0x33, 0x16, 0x01, 0x00, 0x0a},
00224 {0x20, 0x21, 0x04, 0x8a, 0xda, 0x8f, 0x05, 0x0b, 0x02, 0x00, 0x06},
00225 {0x05, 0x03, 0x6a, 0x89, 0xf1, 0xc3, 0xe5, 0xe5, 0x00, 0x00, 0x06},
00226 {0x07, 0x02, 0x15, 0x09, 0xec, 0xf8, 0x26, 0x16, 0x00, 0x00, 0x0a},
00227 {0x05, 0x01, 0x9d, 0x09, 0x67, 0xdf, 0x35, 0x05, 0x00, 0x00, 0x08},
00228 {0x18, 0x12, 0x96, 0x09, 0xfa, 0xf8, 0x28, 0xe5, 0x00, 0x00, 0x0a},
00229 {0x10, 0x00, 0x86, 0x0c, 0xa8, 0xfa, 0x07, 0x03, 0x00, 0x00, 0x06},
00230 {0x11, 0x10, 0x41, 0x0c, 0xf8, 0xf3, 0x47, 0x03, 0x02, 0x00, 0x04},
00231 {0x01, 0x10, 0x8e, 0x09, 0xf1, 0xf3, 0x06, 0x02, 0x02, 0x00, 0x0e},
00232 {0x0e, 0xc0, 0x00, 0x09, 0x1f, 0x1f, 0x00, 0xff, 0x00, 0x03, 0x0e},
00233 {0x06, 0x03, 0x80, 0x91, 0xf8, 0x56, 0x24, 0x84, 0x00, 0x02, 0x0e},
00234 {0x0e, 0xd0, 0x00, 0x0e, 0xf8, 0x34, 0x00, 0x04, 0x00, 0x03, 0x0e},
00235 {0x0e, 0xc0, 0x00, 0x09, 0xf6, 0x1f, 0x00, 0x02, 0x00, 0x03, 0x0e},
00236 {0xd5, 0xda, 0x95, 0x49, 0x37, 0x56, 0xa3, 0x37, 0x00, 0x00, 0x00},
00237 {0x35, 0x14, 0x5c, 0x11, 0xb2, 0xf4, 0x61, 0x15, 0x02, 0x00, 0x0a},
00238 {0x0e, 0xd0, 0x00, 0x09, 0xf6, 0x4f, 0x00, 0xf5, 0x00, 0x03, 0x0e},
00239 {0x26, 0xe4, 0x00, 0x09, 0xff, 0x12, 0x01, 0x16, 0x00, 0x01, 0x0e},
00240 {0x00, 0x00, 0x00, 0x09, 0xf3, 0xf6, 0xf0, 0xc9, 0x00, 0x02, 0x0e}
00241
00242 };
00243
00244
00245 static int my_midi_fm_vol_table[128] = {
00246 0, 11, 16, 19, 22, 25, 27, 29, 32, 33, 35, 37, 39, 40, 42, 43,
00247 45, 46, 48, 49, 50, 51, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62,
00248 64, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 75, 76, 77,
00249 78, 79, 80, 80, 81, 82, 83, 83, 84, 85, 86, 86, 87, 88, 89, 89,
00250 90, 91, 91, 92, 93, 93, 94, 95, 96, 96, 97, 97, 98, 99, 99, 100,
00251 101, 101, 102, 103, 103, 104, 104, 105, 106, 106, 107, 107, 108,
00252 109, 109, 110, 110, 111, 112, 112, 113, 113, 114, 114, 115, 115,
00253 116, 117, 117, 118, 118, 119, 119, 120, 120, 121, 121, 122, 122,
00254 123, 123, 124, 124, 125, 125, 126, 126, 127
00255 };
00256
00257
00258 static int lucas_fm_vol_table[128];
00259
00260 static unsigned char adlib_opadd[] = { 0x00, 0x01, 0x02, 0x08, 0x09, 0x0A, 0x10, 0x11, 0x12 };
00261
00262
00263
00264
00265 OplDriver::OplDriver()
00266 {
00267 int i, j;
00268
00269 for (i = 0; i < 128; i++) {
00270 for (j = 0; j < 11; j++)
00271 myinsbank[i][j] = midi_fm_instruments_table[i][j];
00272
00273 myinsbank[i][INDEX_PERC] = 0x80;
00274
00275
00276 lucas_fm_vol_table[i] = (int)((double)std::sqrt((double)my_midi_fm_vol_table[i]) * 11);
00277
00278
00279 xmidibanks[i] = 0;
00280 }
00281 for (i = 0; i < 16; i++) {
00282 ch[i].inum = 0;
00283 ch[i].xmidi = false;
00284 ch[i].xmidi_bank = 0;
00285 ch[i].vol = 127;
00286 ch[i].expression = 127;
00287 ch[i].nshift = -13;
00288 ch[i].on = 1;
00289 ch[i].pitchbend = 0x2000;
00290 }
00291
00292
00293 for (i = 0; i < 9; i++) {
00294 chp[i][CHP_CHAN] = -1;
00295 chp[i][CHP_COUNTER] = 0;
00296 chp[i][CHP_VEL] = 0;
00297 }
00298 }
00299
00300
00301
00302
00303 OplDriver::~OplDriver()
00304 {
00305 close();
00306 }
00307
00308
00309
00310
00311 int OplDriver::open(int sample_rate)
00312 {
00313 _opl = OPLCreate(OPL_TYPE_YM3812, 3579545, sample_rate);
00314 return 0;
00315 }
00316
00317
00318
00319
00320 void OplDriver::close()
00321 {
00322
00323 if (_opl) OPLDestroy(_opl);
00324
00325
00326 _opl = 0;
00327
00328
00329 for (int i = 0; i < 128; i++) {
00330 delete xmidibanks[i];
00331 xmidibanks[i] = 0;
00332 }
00333
00334 }
00335
00336
00337
00338
00339 void OplDriver::generate_samples(sint16 *data, uint32 len)
00340 {
00341 if (!_opl) {
00342 memset(data, 0, len * sizeof(*data));
00343 } else {
00344 YM3812UpdateOne(_opl, data, len);
00345 }
00346 }
00347
00348 int OplDriver::midi_calc_volume(int channel, int vel)
00349 {
00350 vel += (VEL_FUDGE-1)*128;
00351
00352 int nv = (ch[channel].vol * ch[channel].expression * vel) / (16129*VEL_FUDGE);
00353
00354 #ifdef LUCAS_MODE
00355
00356 #endif
00357 if (nv > 127)
00358 nv = 127;
00359 #ifndef LUCAS_MODE
00360 nv = my_midi_fm_vol_table[nv];
00361 #else
00362 nv = lucas_fm_vol_table[nv];
00363 #endif
00364
00365 return nv;
00366 }
00367
00368
00369
00370
00371
00372 void OplDriver::send(uint32 b)
00373 {
00374 unsigned char channel = (char)(b & 0x0F);
00375
00376
00377 if (channel == 9 && !xmidibanks[127]) return;
00378
00379 switch (b & 0xF0) {
00380 case 0x80:
00381
00382 b &= 0xFFFF;
00383 case 0x90:{
00384 unsigned char note = (unsigned char)((b >> 8) & 0x7F);
00385 unsigned char vel = (unsigned char)((b >> 16) & 0x7F);
00386 int i, j;
00387 int onl, on, nv;
00388 on = -1;
00389
00390
00391 for (i = 0; i < 9; i++)
00392 if ((chp[i][CHP_CHAN] == channel) && (chp[i][CHP_NOTE] == note)) {
00393 midi_fm_endnote(i);
00394 chp[i][CHP_CHAN] = -1;
00395 }
00396
00397 if (vel != 0 && ch[channel].on != 0) {
00398
00399
00400 for (i = 0; i < 9; i++) chp[i][CHP_COUNTER]++;
00401
00402
00403 j = 0; onl = 0;
00404 for (i = 0; i < 9; i++)
00405 if ((chp[i][CHP_CHAN] == -1) && (chp[i][CHP_COUNTER] > onl)) {
00406 onl = chp[i][CHP_COUNTER];
00407 on = i;
00408 j = 1;
00409 }
00410
00411
00412 if (on == -1) {
00413 onl = 0;
00414 for (i = 0; i < 9; i++)
00415 if (chp[i][CHP_COUNTER] > onl) {
00416 onl = chp[i][CHP_COUNTER];
00417 on = i;
00418 }
00419 }
00420
00421
00422 if (j == 0) midi_fm_endnote(on);
00423
00424
00425 if ((ch[channel].inum >= 0) && (ch[channel].inum < 128)) {
00426 if (channel == 9 && xmidibanks[127])
00427 midi_fm_instrument(on, xmidibanks[127]->insbank[note]);
00428 else
00429 midi_fm_instrument(on, ch[channel].ins);
00430 }
00431
00432
00433 nv = midi_calc_volume(channel, vel);
00434
00435
00436 midi_fm_playnote(on, note + ch[channel].nshift, nv * 2, ch[channel].pitchbend);
00437
00438
00439 chp[on][CHP_CHAN] = channel;
00440 chp[on][CHP_NOTE] = note;
00441 chp[on][CHP_COUNTER] = 0;
00442 chp[on][CHP_VEL] = vel;
00443 }
00444 }
00445 break;
00446
00447 case 0xa0:{
00448 unsigned char note = (unsigned char)((b >> 8) & 0x7F);
00449 unsigned char vel = (unsigned char)((b >> 16) & 0x7F);
00450 int nv = midi_calc_volume(channel, vel);
00451
00452 for (int i = 0; i < 9; i++)
00453 if ((chp[CHP_CHAN][0] == channel) & (chp[i][CHP_NOTE] == note)) {
00454 chp[i][CHP_VEL] = vel;
00455 midi_fm_volume(i, nv * 2);
00456 }
00457 }
00458 break;
00459
00460 case 0xb0:{
00461 int i;
00462 unsigned char ctrl = (unsigned char)((b >> 8) & 0x7F);
00463 unsigned char vel = (unsigned char)((b >> 16) & 0x7F);
00464
00465
00466
00467 switch (ctrl) {
00468 case 0x00:
00469 if (vel == 127) {
00470 ch[channel].xmidi = true;
00471 COUT ("Setting XMIDI Mode on channel " << ((int) channel) << " Bank " << (int) ch[channel].xmidi_bank);
00472
00473 }
00474 else {
00475 ch[channel].xmidi = false;
00476 COUT ("Setting General Midi Mode on channel " << ((int) channel));
00477 }
00478 break;
00479 case 0x01:
00480 for (i = 0; i < 9; i++)
00481 if (chp[i][CHP_CHAN] == channel)
00482 midi_write_adlib(0x20 + adlib_opadd[i], vel);
00483 break;
00484 case 0x07:
00485 ch[channel].vol = vel;
00486 midi_update_volume(channel);
00487 break;
00488 case 0x0A:
00489
00490
00491 break;
00492 case 0x0B:
00493 ch[channel].expression = vel;
00494 midi_update_volume(channel);
00495 break;
00496 case 0x40:
00497
00498
00499
00500 break;
00501 case 0x5B:
00502
00503
00504
00505 break;
00506 case 0x5D:
00507
00508
00509
00510 break;
00511
00512
00513
00514 case XMIDI_CONTROLLER_CHAN_LOCK:
00515 CERR("Uh oh. Detected a XMIDI Channel Lock (" << (int) vel << ") on channel " << (int) channel << ", but we don't support them");
00516 break;
00517 case XMIDI_CONTROLLER_CHAN_LOCK_PROT:
00518 CERR("Uh oh. Detected a XMIDI Channel Lock Protect (" << (int) vel << ") on channel " << (int) channel << ", but we don't support them");
00519 break;
00520 case XMIDI_CONTROLLER_VOICE_PROT:
00521 CERR("Uh oh. Detected a XMIDI Voice Protect (" << (int) vel << ") on channel " << (int) channel << ", but we don't support them");
00522 break;
00523 case XMIDI_CONTROLLER_TIMBRE_PROT:
00524 CERR("Uh oh. Detected a XMIDI Timbre Protect (" << (int) vel << ") on channel " << (int) channel << ", but we don't support them");
00525 break;
00526 case XMIDI_CONTROLLER_BANK_CHANGE:
00527 COUT("Detected a XMIDI Bank Change (" << (int) vel << ") on channel " << (int) channel);
00528
00529 ch[channel].xmidi_bank = vel;
00530 break;
00531 case XMIDI_CONTROLLER_IND_CTRL_PREFIX:
00532 CERR("Uh oh. Detected a XMIDI Indirect Controller Prefix (" << (int) vel << ") on channel " << (int) channel << ", but we don't support them");
00533 break;
00534 case XMIDI_CONTROLLER_CLEAR_BB_COUNT:
00535 CERR("Uh oh. Detected a XMIDI Clear Beat/Bar Count (" << (int) vel << ") on channel " << (int) channel << ", but we don't support them");
00536 break;
00537 case XMIDI_CONTROLLER_CALLBACK_TRIG:
00538 CERR("Uh oh. Detected a XMIDI Callback Trigger (" << (int) vel << ") on channel " << (int) channel << ", but we don't support them");
00539 break;
00540 case XMIDI_CONTROLLER_SEQ_BRANCH_INDEX:
00541 CERR("Uh oh. Detected a XMIDI Sequence Branch Index (" << (int) vel << ") on channel " << (int) channel << ", but we don't support them");
00542 break;
00543
00544
00545
00546 case 0x7B:
00547 for (i = 0; i < 9; i++) {
00548 if (chp[i][CHP_CHAN] == channel) {
00549 midi_fm_endnote(i);
00550 chp[i][CHP_CHAN] = -1;
00551 }
00552 }
00553 break;
00554 default:
00555 CERR("MIDI sub-command 0xB0 (Control Change) case 0x" << std::hex << (int) ctrl << std::dec << " not handled in MIDIEMU driver.");
00556 break;
00557 }
00558 }
00559 break;
00560
00561 case 0xc0:{
00562 unsigned char instrument = (unsigned char)((b >> 8) & 0x7F);
00563 ch[channel].inum = instrument;
00564
00565
00566 unsigned char *ins = 0;
00567 int b = -1;
00568
00569
00570 if (ch[channel].xmidi) for (b = ch[channel].xmidi_bank; b>=0; b--) {
00571 xmidibank *bank = xmidibanks[b];
00572 if (!bank) continue;
00573 if (bank->insbank[instrument][INDEX_PERC] &= 0x80) {
00574 ins = bank->insbank[instrument];
00575 break;
00576 }
00577 }
00578
00579 if (!ins) ins = myinsbank[instrument];
00580
00581 for (int j = 0; j < 12; j++)
00582 ch[channel].ins[j] = ins[j];
00583
00584 COUT("Detected a Patch Change (" << (int) instrument << ") on channel " << (int) channel << " xmidibank: " << b);
00585
00586 } break;
00587
00588 case 0xd0:
00589
00590 break;
00591
00592 case 0xe0:{
00593
00594 int pitchbend = ((b >> 8) & 0x7F) | (((b >> 16) & 0x7F) << 7);
00595 ch[channel].pitchbend = pitchbend;
00596 for (int i = 0; i < 9; i++) {
00597 if (chp[i][CHP_CHAN] == channel) {
00598 int nv = midi_calc_volume(channel, chp[i][CHP_VEL]);
00599 midi_fm_playnote(i, chp[i][CHP_NOTE] + ch[channel].nshift, nv * 2, pitchbend);
00600 }
00601 }
00602 }
00603 break;
00604
00605 default:
00606
00607 break;
00608 }
00609 }
00610
00611 void OplDriver::midi_write_adlib(unsigned int reg, unsigned char val)
00612 {
00613 OPLWrite(_opl, 0, reg);
00614 OPLWrite(_opl, 1, val);
00615 adlib_data[reg] = val;
00616 }
00617
00618
00619
00620
00621
00622
00623
00624
00625
00626
00627
00628
00629
00630
00631
00632
00633
00634
00635
00636
00637
00638
00639
00640
00641
00642 void OplDriver::midi_fm_instrument(int voice, unsigned char *inst)
00643 {
00644 #if 0
00645
00646 #endif
00647
00648
00649 #if 0 && defined(LUCAS_MODE)
00650 midi_write_adlib(OPL_REG_KSLTL_C + adlib_opadd[voice], 0x3f);
00651 if ((inst[INDEX_FB_C] & 1) == 0)
00652 midi_write_adlib(OPL_REG_KSLTL_M + adlib_opadd[voice], inst[INDEX_KSLTL_M]);
00653 else
00654 midi_write_adlib(OPL_REG_KSLTL_M + adlib_opadd[voice], 0x3f);
00655 #elif 0
00656 midi_write_adlib(OPL_REG_KSLTL_M + adlib_opadd[voice], inst[INDEX_KSLTL_M]);
00657 if ((inst[INDEX_FB_C] & 1) == 0)
00658 midi_write_adlib(OPL_REG_KSLTL_C + adlib_opadd[voice], inst[INDEX_KSLTL_C]);
00659 else
00660 midi_write_adlib(OPL_REG_KSLTL_C + adlib_opadd[voice], 0);
00661 #else
00662 #endif
00663
00664 midi_write_adlib(OPL_REG_AVEKM_M + adlib_opadd[voice], inst[INDEX_AVEKM_M]);
00665 midi_write_adlib(OPL_REG_KSLTL_M + adlib_opadd[voice], inst[INDEX_KSLTL_M]);
00666 midi_write_adlib(OPL_REG_AD_M + adlib_opadd[voice], inst[INDEX_AD_M]);
00667 midi_write_adlib(OPL_REG_SR_M + adlib_opadd[voice], inst[INDEX_SR_M]);
00668 midi_write_adlib(OPL_REG_WAVE_M + adlib_opadd[voice], inst[INDEX_WAVE_M]);
00669
00670 if (!(inst[INDEX_PERC] & 0x7f)) {
00671 midi_write_adlib(OPL_REG_AVEKM_C + adlib_opadd[voice], inst[INDEX_AVEKM_C]);
00672 midi_write_adlib(OPL_REG_KSLTL_C + adlib_opadd[voice], inst[INDEX_KSLTL_C]);
00673 midi_write_adlib(OPL_REG_AD_C + adlib_opadd[voice], inst[INDEX_AD_C]);
00674 midi_write_adlib(OPL_REG_SR_C + adlib_opadd[voice], inst[INDEX_SR_C]);
00675 midi_write_adlib(OPL_REG_WAVE_C + adlib_opadd[voice], inst[INDEX_WAVE_C]);
00676 midi_write_adlib(OPL_REG_FB_C + voice, inst[INDEX_FB_C]);
00677 midi_write_adlib(0xbd, 0);
00678
00679 if (!inst[INDEX_PERC]) {
00680 CERR("Tried setting an instruement that wasnt loaded");
00681 }
00682 }
00683 }
00684
00685 void OplDriver::midi_update_volume(int channel)
00686 {
00687 for (int i = 0; i < 9; i++)
00688 if ((chp[i][CHP_CHAN] == channel)) {
00689
00690 int nv = midi_calc_volume(channel, chp[i][CHP_VEL]);
00691 midi_fm_volume(i, nv * 2);
00692 }
00693 }
00694
00695 void OplDriver::midi_fm_volume(int voice, int volume)
00696 {
00697 volume >>= 2;
00698
00699 if ((adlib_data[0xc0 + voice] & 1) == 1)
00700 midi_write_adlib(0x40 + adlib_opadd[voice],
00701 (unsigned char)((63 - volume) |
00702 (adlib_data[0x40 + adlib_opadd[voice]] & 0xc0)));
00703 midi_write_adlib(0x43 + adlib_opadd[voice],
00704 (unsigned char)((63 - volume) | (adlib_data[0x43 + adlib_opadd[voice]] & 0xc0)));
00705 }
00706
00707 static int fnums[] =
00708 { 0x16b, 0x181, 0x198, 0x1b0, 0x1ca, 0x1e5, 0x202, 0x220, 0x241, 0x263, 0x287, 0x2ae };
00709
00710
00711
00712
00713
00714
00715 static float ex_bend_fine[256] = {
00716 1.0, 1.0002256593050698, 1.0004513695322617, 1.0006771306930664,
00717 1.0009029427989777, 1.0011288058614922, 1.0013547198921082, 1.0015806849023274,
00718 1.0018067009036538, 1.002032767907594, 1.0022588859256572, 1.0024850549693551,
00719 1.0027112750502025, 1.0029375461797159, 1.0031638683694153, 1.0033902416308227,
00720 1.0036166659754628, 1.0038431414148634, 1.0040696679605541, 1.0042962456240678,
00721 1.0045228744169397, 1.0047495543507072, 1.0049762854369111, 1.0052030676870944,
00722 1.0054299011128027, 1.0056567857255843, 1.00588372153699, 1.006110708558573,
00723 1.0063377468018897, 1.0065648362784985, 1.0067919769999607, 1.0070191689778405,
00724 1.0072464122237039, 1.0074737067491204, 1.0077010525656616, 1.0079284496849015,
00725 1.0081558981184175, 1.008383397877789, 1.008610948974598, 1.0088385514204294,
00726 1.0090662052268706, 1.0092939104055114, 1.0095216669679448, 1.0097494749257656,
00727 1.009977334290572, 1.0102052450739643, 1.0104332072875455, 1.0106612209429215,
00728 1.0108892860517005, 1.0111174026254934, 1.0113455706759138, 1.0115737902145781,
00729 1.0118020612531047, 1.0120303838031153, 1.0122587578762337, 1.012487183484087,
00730 1.0127156606383041, 1.0129441893505169, 1.0131727696323602, 1.0134014014954713,
00731 1.0136300849514894, 1.0138588200120575, 1.0140876066888203, 1.0143164449934257,
00732 1.0145453349375237, 1.0147742765327674, 1.0150032697908125, 1.0152323147233171,
00733 1.015461411341942, 1.0156905596583505, 1.0159197596842091, 1.0161490114311862,
00734 1.0163783149109531, 1.0166076701351838, 1.0168370771155553, 1.0170665358637463,
00735 1.0172960463914391, 1.0175256087103179, 1.0177552228320703, 1.0179848887683858,
00736 1.0182146065309567, 1.0184443761314785, 1.0186741975816487, 1.0189040708931674,
00737 1.0191339960777379, 1.0193639731470658, 1.0195940021128593, 1.0198240829868295,
00738 1.0200542157806898, 1.0202844005061564, 1.0205146371749483, 1.0207449257987866,
00739 1.0209752663893958, 1.0212056589585028, 1.0214361035178368, 1.0216666000791297,
00740 1.0218971486541166, 1.0221277492545349, 1.0223584018921241, 1.0225891065786274,
00741 1.0228198633257899, 1.0230506721453596, 1.023281533049087, 1.0235124460487257,
00742 1.0237434111560313, 1.0239744283827625, 1.0242054977406807, 1.0244366192415495,
00743 1.0246677928971357, 1.0248990187192082, 1.025130296719539, 1.0253616269099028,
00744 1.0255930093020766, 1.0258244439078401, 1.0260559307389761, 1.0262874698072693,
00745 1.0265190611245079, 1.0267507047024822, 1.0269824005529853, 1.027214148687813,
00746 1.0274459491187637, 1.0276778018576387, 1.0279097069162415, 1.0281416643063788,
00747 1.0283736740398595, 1.0286057361284953, 1.0288378505841009, 1.0290700174184932,
00748 1.0293022366434921, 1.0295345082709197, 1.0297668323126017, 1.0299992087803651,
00749 1.030231637686041, 1.0304641190414621, 1.0306966528584645, 1.0309292391488862,
00750 1.0311618779245688, 1.0313945691973556, 1.0316273129790936, 1.0318601092816313,
00751 1.0320929581168212, 1.0323258594965172, 1.0325588134325767, 1.0327918199368598,
00752 1.0330248790212284, 1.0332579906975481, 1.0334911549776868, 1.033724371873515,
00753 1.0339576413969056, 1.0341909635597348, 1.0344243383738811, 1.0346577658512259,
00754 1.034891246003653, 1.0351247788430489, 1.0353583643813031, 1.0355920026303078,
00755 1.0358256936019572, 1.0360594373081489, 1.0362932337607829, 1.0365270829717617,
00756 1.0367609849529913, 1.0369949397163791, 1.0372289472738365, 1.0374630076372766,
00757 1.0376971208186156, 1.0379312868297725, 1.0381655056826686, 1.0383997773892284,
00758 1.0386341019613787, 1.0388684794110492, 1.0391029097501721, 1.0393373929906822,
00759 1.0395719291445176, 1.0398065182236185, 1.0400411602399278, 1.0402758552053915,
00760 1.0405106031319582, 1.0407454040315787, 1.0409802579162071, 1.0412151647977996,
00761 1.0414501246883161, 1.0416851375997183, 1.0419202035439705, 1.0421553225330404,
00762 1.042390494578898, 1.042625719693516, 1.0428609978888699, 1.043096329176938,
00763 1.0433317135697009, 1.0435671510791424, 1.0438026417172486, 1.0440381854960086,
00764 1.0442737824274138, 1.044509432523459, 1.044745135796141, 1.0449808922574599,
00765 1.0452167019194181, 1.0454525647940205, 1.0456884808932754, 1.0459244502291931,
00766 1.0461604728137874, 1.0463965486590741, 1.046632677777072, 1.0468688601798024,
00767 1.0471050958792898, 1.047341384887561, 1.0475777272166455, 1.047814122878576,
00768 1.048050571885387, 1.0482870742491166, 1.0485236299818055, 1.0487602390954964,
00769 1.0489969016022356, 1.0492336175140715, 1.0494703868430555, 1.0497072096012419,
00770 1.0499440858006872, 1.0501810154534512, 1.050417998571596, 1.0506550351671864,
00771 1.0508921252522903, 1.0511292688389782, 1.0513664659393229, 1.0516037165654004,
00772 1.0518410207292894, 1.0520783784430709, 1.0523157897188296, 1.0525532545686513,
00773 1.0527907730046264, 1.0530283450388465, 1.0532659706834067, 1.0535036499504049,
00774 1.0537413828519411, 1.0539791694001188, 1.0542170096070436, 1.0544549034848243,
00775 1.0546928510455722, 1.0549308523014012, 1.0551689072644284, 1.0554070159467728,
00776 1.0556451783605572, 1.0558833945179062, 1.0561216644309479, 1.0563599881118126,
00777 1.0565983655726334, 1.0568367968255465, 1.0570752818826903, 1.0573138207562065,
00778 1.057552413458239, 1.0577910600009348, 1.0580297603964437, 1.058268514656918,
00779 1.0585073227945128, 1.0587461848213857, 1.058985100749698, 1.0592240705916123
00780 };
00781
00782 static float ex_bend_coarse[128] = {
00783 1.0, 1.0594630943592953, 1.122462048309373, 1.189207115002721,
00784 1.2599210498948732, 1.3348398541700344, 1.4142135623730951, 1.4983070768766815,
00785 1.5874010519681994, 1.681792830507429, 1.7817974362806785, 1.8877486253633868,
00786 2.0, 2.1189261887185906, 2.244924096618746, 2.3784142300054421,
00787 2.5198420997897464, 2.6696797083400687, 2.8284271247461903, 2.996614153753363,
00788 3.1748021039363992, 3.363585661014858, 3.5635948725613571, 3.7754972507267741,
00789 4.0, 4.2378523774371812, 4.4898481932374912, 4.7568284600108841,
00790 5.0396841995794928, 5.3393594166801366, 5.6568542494923806, 5.993228307506727,
00791 6.3496042078727974, 6.727171322029716, 7.1271897451227151, 7.5509945014535473,
00792 8.0, 8.4757047548743625, 8.9796963864749824, 9.5136569200217682,
00793 10.079368399158986, 10.678718833360273, 11.313708498984761, 11.986456615013454,
00794 12.699208415745595, 13.454342644059432, 14.25437949024543, 15.101989002907095,
00795 16.0, 16.951409509748721, 17.959392772949972, 19.027313840043536,
00796 20.158736798317967, 21.357437666720553, 22.627416997969522, 23.972913230026901,
00797 25.398416831491197, 26.908685288118864, 28.508758980490853, 30.203978005814196,
00798 32.0, 33.902819019497443, 35.918785545899944, 38.054627680087073,
00799 40.317473596635935, 42.714875333441107, 45.254833995939045, 47.945826460053802,
00800 50.796833662982394, 53.817370576237728, 57.017517960981706, 60.407956011628393,
00801 64.0, 67.805638038994886, 71.837571091799887, 76.109255360174146,
00802 80.63494719327187, 85.429750666882214, 90.509667991878089, 95.891652920107603,
00803 101.59366732596479, 107.63474115247546, 114.03503592196341, 120.81591202325679,
00804 128.0, 135.61127607798977, 143.67514218359977, 152.21851072034829,
00805 161.26989438654374, 170.85950133376443, 181.01933598375618, 191.78330584021521,
00806 203.18733465192958, 215.26948230495091, 228.07007184392683, 241.63182404651357,
00807 256.0, 271.22255215597971, 287.35028436719938, 304.43702144069658,
00808 322.53978877308765, 341.71900266752868, 362.03867196751236, 383.56661168043064,
00809 406.37466930385892, 430.53896460990183, 456.14014368785394, 483.26364809302686,
00810 512.0, 542.44510431195943, 574.70056873439876, 608.87404288139317,
00811 645.0795775461753, 683.43800533505737, 724.07734393502471, 767.13322336086128,
00812 812.74933860771785, 861.07792921980365, 912.28028737570787, 966.52729618605372,
00813 1024.0, 1084.8902086239189, 1149.4011374687975, 1217.7480857627863,
00814 1290.1591550923506, 1366.8760106701147, 1448.1546878700494, 1534.2664467217226
00815 };
00816
00817 void OplDriver::midi_fm_playnote(int voice, int note, int volume, int pitchbend)
00818 {
00819 int freq = fnums[note % 12];
00820 int oct = note / 12;
00821 int c;
00822 float pf;
00823
00824 pitchbend -= 0x2000;
00825 if (pitchbend != 0) {
00826 pitchbend *= 2;
00827 if (pitchbend >= 0)
00828 pf = (float)(ex_bend_fine[(pitchbend >> 5) & 0xFF] * ex_bend_coarse[(pitchbend >> 13) & 0x7F]);
00829 else {
00830 pitchbend = -pitchbend;
00831 pf =
00832 (float)(1.0 / (ex_bend_fine[(pitchbend >> 5) & 0xFF] * ex_bend_coarse[(pitchbend >> 13) & 0x7F]));
00833 }
00834 freq = (int)((float)freq * pf);
00835
00836 while (freq >= (fnums[0] * 2)) {
00837 freq /= 2;
00838 oct += 1;
00839 }
00840 while (freq < fnums[0]) {
00841 freq *= 2;
00842 oct -= 1;
00843 }
00844 }
00845
00846 midi_fm_volume(voice, volume);
00847 midi_write_adlib(0xa0 + voice, (unsigned char)(freq & 0xff));
00848
00849 c = ((freq & 0x300) >> 8) + (oct << 2) + (1 << 5);
00850 midi_write_adlib(0xb0 + voice, (unsigned char)c);
00851 }
00852
00853 void OplDriver::midi_fm_endnote(int voice)
00854 {
00855 midi_write_adlib(0xb0 + voice, (unsigned char)(adlib_data[0xb0 + voice] & (255 - 32)));
00856 }
00857
00858 void OplDriver::LoadMT32Bank(bool force_xmidi)
00859 {
00860 #ifdef PENTAGRAM
00861 LoadXMIDIBank("<SOUND>/music.flx");
00862 #else
00863 if (GAME_BG && !force_xmidi) {
00864 const char* u7vfn = "<STATIC>/u7voice.flx";
00865 if (!U7exists(u7vfn)) {
00866 u7vfn = "<BLACKGATE_STATIC>/u7voice.flx";
00867 }
00868 LoadU7VBank(u7vfn);
00869 }
00870 else {
00871 LoadXMIDIBank("<STATIC>/xmidi.ad");
00872 }
00873 #endif
00874 }
00875
00876
00877 void OplDriver::LoadXMIDIBank(const char *fn)
00878 {
00879 #ifdef PENTAGRAM
00880 Flex *flex;
00881 try {
00882 flex = new Flex(fn, false);
00883 }
00884 catch(file_open_exception &) {
00885 std::cerr << "Couldn't open " << fn << std::endl;
00886 return;
00887 }
00888
00889 BufferDataSource ds(flex->get_object_nodel(259), flex->get_size(259));
00890 #else
00891 FILE *xmidi_ad = U7open (fn, "rb");
00892
00893 if (!xmidi_ad) {
00894 std::cerr << "Warning: couldn't open " << get_system_path(fn)
00895 << std::endl;
00896 return;
00897 }
00898
00899 FileDataSource ds(xmidi_ad);
00900 #endif
00901
00902 COUT ("Reading " << fn);
00903
00904 bool read[128];
00905 std::memset(read, false, sizeof(read));
00906
00907
00908 if (0) for (uint32 i = 0; ds.getPos() < ds.getSize(); i++) {
00909 uint32 patch = (uint8) ds.read1();
00910 uint32 bank = (uint8) ds.read1();
00911
00912
00913 if (patch == 255 || bank == 255) {
00914 COUT ("Finished " << patch << ": ");
00915 break;
00916 }
00917
00918
00919 uint32 offset = ds.read4();
00920
00921 COUT ("Patch " << i << " = " << bank << ":" << patch << " @ " << offset << " " << ds.getPos());
00922 }
00923
00924
00925 uint32 i;
00926 for (i = 0; ds.getPos() < ds.getSize(); i++) {
00927
00928 ds.seek(i*6);
00929
00930 uint32 patch = (uint8) ds.read1();
00931 uint32 bank = (uint8) ds.read1();
00932
00933
00934 if (patch == 255 || bank == 255) {
00935 COUT ("Finished " << patch << ": ");
00936 break;
00937 }
00938
00939
00940 uint32 offset = ds.read4();
00941
00942 COUT ("Patch " << i << " = " << bank << ":" << patch << " @ " << offset);
00943
00944
00945 if (!xmidibanks[bank]) {
00946 xmidibanks[bank] = new xmidibank;
00947 std::memset (xmidibanks[bank], 0, sizeof (xmidibank));
00948 }
00949
00950
00951 ds.seek(offset);
00952
00953
00954 uint16 len = ds.read2();
00955
00956
00957 if (len != 0xE) {
00958 COUT ("Invalid Patch " << bank << ":" << patch << " len was " << len << " " << std::hex << len << std::dec);
00959
00960 }
00961
00962
00963 ds.skip(1);
00964
00965 struct
00966 {
00967 unsigned char mod_avekm;
00968 unsigned char mod_ksl_tl;
00969 unsigned char mod_ad;
00970 unsigned char mod_sr;
00971 unsigned char mod_ws;
00972
00973 unsigned char fb_c;
00974
00975 unsigned char car_avekm;
00976 unsigned char car_ksl_tl;
00977 unsigned char car_ad;
00978 unsigned char car_sr;
00979 unsigned char car_ws;
00980 } xmidi_ins;
00981
00982 ds.read((char*) (&xmidi_ins), 11);
00983
00984 unsigned char* ins = xmidibanks[bank]->insbank[patch];
00985
00986 ins[INDEX_AVEKM_M] = xmidi_ins.mod_avekm;
00987 ins[INDEX_KSLTL_M] = xmidi_ins.mod_ksl_tl;
00988 ins[INDEX_AD_M] = xmidi_ins.mod_ad;
00989 ins[INDEX_SR_M] = xmidi_ins.mod_sr;
00990 ins[INDEX_WAVE_M] = xmidi_ins.mod_ws;
00991 ins[INDEX_AVEKM_C] = xmidi_ins.car_avekm;
00992 ins[INDEX_KSLTL_C] = xmidi_ins.car_ksl_tl;
00993 ins[INDEX_AD_C] = xmidi_ins.car_ad;
00994 ins[INDEX_SR_C] = xmidi_ins.car_sr;
00995 ins[INDEX_WAVE_C] = xmidi_ins.car_ws;
00996 ins[INDEX_FB_C] = xmidi_ins.fb_c;
00997 ins[INDEX_PERC] = 0x80;
00998 }
00999
01000 COUT (i << " timbres read");
01001
01002 #ifdef PENTAGRAM
01003 delete flex;
01004 #else
01005 fclose (xmidi_ad);
01006 #endif
01007 }
01008
01009 void OplDriver::LoadU7VBank(const char *fn)
01010 {
01011 #ifndef PENTAGRAM
01012
01013 Flex *f;
01014 try {
01015 f = new Flex(fn);
01016 }
01017 catch(file_open_exception &) {
01018 std::cerr << "Warning: couldn't open " << get_system_path(fn)
01019 << std::endl;
01020 return;
01021 }
01022
01023 COUT ("Reading " << fn);
01024 std::size_t size;
01025 char *buf = f->retrieve(1, size);
01026 BufferDataSource ds(buf, size);
01027 delete f;
01028
01029 struct u7voice_adlib_ins {
01030 unsigned char mod_avekm;
01031 unsigned char mod_ksl_tl;
01032 unsigned char mod_ad;
01033 unsigned char mod_sr;
01034 unsigned char mod_ws;
01035
01036 unsigned char car_avekm;
01037 unsigned char car_ksl_tl;
01038 unsigned char car_ad;
01039 unsigned char car_sr;
01040 unsigned char car_ws;
01041
01042 unsigned char fb_c;
01043
01044
01045
01046 unsigned char perc_voice;
01047
01048
01049 unsigned char car_vel_sense;
01050 unsigned char mod_vel_sense;
01051 unsigned char bend_sense;
01052 unsigned char wheel_sense;
01053 unsigned char lfo_speed;
01054 unsigned char lfo_depth;
01055
01056 unsigned short pe_start_level;
01057 unsigned short pe_attack_rate1;
01058 unsigned short pe_attack_level1;
01059 unsigned short pe_attack_rate2;
01060 unsigned short pe_attack_level2;
01061 unsigned short pe_decay_rate;
01062 unsigned short pe_sustain_level;
01063 unsigned short pe_release_rate;
01064 unsigned short pe_end_level;
01065
01066 unsigned char deturn;
01067 unsigned char transpose;
01068 unsigned char next_partial;
01069 unsigned char key_follow;
01070 unsigned char reserved[7];
01071
01072 unsigned char prog_num;
01073
01074 void read(DataSource &ds) {
01075 mod_avekm = ds.read1();
01076 mod_ksl_tl = ds.read1();
01077 mod_ad = ds.read1();
01078 mod_sr = ds.read1();
01079 mod_ws = ds.read1();
01080 car_avekm = ds.read1();
01081 car_ksl_tl = ds.read1();
01082 car_ad = ds.read1();
01083 car_sr = ds.read1();
01084 car_ws = ds.read1();
01085 fb_c = ds.read1();
01086
01087
01088
01089 perc_voice = ds.read1();
01090
01091 car_vel_sense = ds.read1();
01092 mod_vel_sense = ds.read1();
01093 bend_sense = ds.read1();
01094 wheel_sense = ds.read1();
01095 lfo_speed = ds.read1();
01096 lfo_depth = ds.read1();
01097
01098 pe_start_level = ds.read2();
01099 pe_attack_rate1 = ds.read2();
01100 pe_attack_level1 = ds.read2();
01101 pe_attack_rate2 = ds.read2();
01102 pe_attack_level2 = ds.read2();
01103 pe_decay_rate = ds.read2();
01104 pe_sustain_level = ds.read2();
01105 pe_release_rate = ds.read2();
01106 pe_end_level = ds.read2();
01107
01108 deturn = ds.read1();
01109 transpose = ds.read1();
01110 next_partial = ds.read1();
01111 key_follow = ds.read1();
01112 ds.read((char *) reserved, 7);
01113
01114 prog_num = ds.read1();
01115 }
01116 } u7voice_ins;
01117
01118 COUT("Size of u7voice_adlib_ins " << sizeof(u7voice_adlib_ins));
01119
01120 int count = ds.read1() & 0xFF;
01121
01122
01123 int i;
01124 for (i = 0; i < count; i++) {
01125
01126
01127 u7voice_ins.read(ds);
01128
01129 uint32 patch = u7voice_ins.prog_num;
01130 uint32 bank = 0;
01131
01132 COUT ("Patch " << i << " = " << bank << ":" << patch);
01133
01134
01135 if (!xmidibanks[bank]) {
01136 xmidibanks[bank] = new xmidibank;
01137 std::memset (xmidibanks[bank], 0, sizeof (xmidibank));
01138 }
01139
01140 if (patch > 127) {
01141 CERR ("Don't know how to handle this");
01142 continue;
01143 }
01144
01145 unsigned char* ins = xmidibanks[bank]->insbank[patch];
01146
01147 ins[INDEX_AVEKM_M] = u7voice_ins.mod_avekm;
01148 ins[INDEX_KSLTL_M] = u7voice_ins.mod_ksl_tl;
01149 ins[INDEX_AD_M] = u7voice_ins.mod_ad;
01150 ins[INDEX_SR_M] = u7voice_ins.mod_sr;
01151 ins[INDEX_WAVE_M] = u7voice_ins.mod_ws;
01152 ins[INDEX_AVEKM_C] = u7voice_ins.car_avekm;
01153 ins[INDEX_KSLTL_C] = u7voice_ins.car_ksl_tl;
01154 ins[INDEX_AD_C] = u7voice_ins.car_ad;
01155 ins[INDEX_SR_C] = u7voice_ins.car_sr;
01156 ins[INDEX_WAVE_C] = u7voice_ins.car_ws;
01157 ins[INDEX_FB_C] = u7voice_ins.fb_c;
01158 ins[INDEX_PERC] = u7voice_ins.perc_voice | 0x80;
01159
01160 if (u7voice_ins.next_partial || u7voice_ins.key_follow) {
01161 COUT("next_partial " << (int) u7voice_ins.next_partial << " key_follow " << (int) u7voice_ins.key_follow);
01162 }
01163 }
01164
01165 COUT (i << " timbres read");
01166
01167 delete [] buf;
01168
01169 #endif
01170 }
01171
01172 #endif // USE_FMOPL_MIDI