diff --git a/java/src/game/audio/AudioInterface.java b/java/src/game/audio/AudioInterface.java index 5266b5b..4448f8e 100644 --- a/java/src/game/audio/AudioInterface.java +++ b/java/src/game/audio/AudioInterface.java @@ -48,8 +48,6 @@ public class AudioInterface implements Runnable { private final Thread thread; private final List cmds = Lists.newArrayList(); private final short[] volumes = new short[Volume.values().length]; -// private final int[] mix = new int[Volume.values().length]; -// private final int[] attn = new int[Volume.values().length]; private final Channel[] channels = new Channel[32]; private SourceDataLine line; @@ -92,11 +90,9 @@ public class AudioInterface implements Runnable { private short generate() { long mix = 0; -// long attn = 0; // (32767 * 100) / 95); for(int z = 0; z < this.channels.length; z++) { Channel ch = this.channels[z]; if(ch.run) { -// attn += (long)ch.level * (long)this.volumes[ch.type]; // (this.attn[ch.type] * 95) / 100; mix += (long)ch.buffer[ch.pos] * (long)ch.level * (((long)this.volumes[ch.type] * (long)this.volumes[0]) / 32767); if(++ch.pos >= ch.buffer.length) { ch.pos = 0; @@ -105,10 +101,6 @@ public class AudioInterface implements Runnable { } } } -// for(int z = 1; z < this.volumes.length; z++) { -// if(this.attn[z] > 0) -// this.mix[0] += (short)(int)(((this.mix[z] * 32767 / this.attn[z]) * (int)this.volumes[z]) / 32767); -// } mix /= 32767L * 32767L; long amp = Math.abs(mix); if(amp > 32767L) @@ -116,7 +108,6 @@ public class AudioInterface implements Runnable { else if(this.peak > 32767L) this.peak = Math.max(this.peak - 3L, 32767L); return (short)((mix * 32767L) / this.peak); -// return attn == 0L ? 0 : (short)(mix / Math.min(attn, 32767L * 32767L * 2L)); } private void dispatch(Object buf, Cmd op, short addr, int param) { diff --git a/java/src/game/audio/Midi.java b/java/src/game/audio/Midi.java deleted file mode 100644 index 61da4ce..0000000 --- a/java/src/game/audio/Midi.java +++ /dev/null @@ -1,3000 +0,0 @@ -package game.audio; - -public class Midi { -/* - * - * -byte mid_nowait; -byte mid_bank; -byte mid_keep; -byte mid_unknown; -byte mid_visual; -int mid_velo; -int mid_voices; - * -#define BANK_MAX 64 -#define MID_DEFTEMPO 500000 -#define BANK_KEEP 0x01 -#define BANK_UNKN 0x02 -#define BANK_PBRANGE 2.0 -#define RSM_FRAC 10 - -#define BANK_VELOFUNC(x, n) (1.0-log(1.0+((1.0-pow(x,n))*(M_E-1.0)))) - -// input: [0, 256), output: [0, 65536] -#define OPL_SIN(x) ((int)(sin((x) * M_PI / 512.0) * 65536.0)) - - - -enum mid_event { - midev_noteoff = 0x80, - midev_noteon = 0x90, - midev_aftertouch = 0xa0, - midev_control = 0xb0, - midev_progchg = 0xc0, - midev_chnpressure = 0xd0, - midev_pitchbend = 0xe0, - midev_sysex = 0xf0, - midev_songpos = 0xf2, - midev_songsel = 0xf3, - midev_tunereq = 0xf6, - midev_endsysex = 0xf7, - midev_clock = 0xf8, - midev_start = 0xfa, - midev_continue = 0xfb, - midev_stop = 0xfc, - midev_actsense = 0xfe, - midev_meta = 0xff -}; - -enum mid_meta { - midmt_seqnum = 0x00, // nn nn - midmt_text = 0x01, // text... - midmt_copyright = 0x02, // text... - midmt_trackname = 0x03, // text... - midmt_instrname = 0x04, // text... - midmt_lyric = 0x05, // text... - midmt_marker = 0x06, // text... - midmt_cuepoint = 0x07, // text... - midmt_chnprefix = 0x20, // cc - midmt_endtrack = 0x2f, // - midmt_tempo = 0x51, // tt tt tt - midmt_smpte = 0x54, // hr mn se fr ff - midmt_timesig = 0x58, // nn dd cc bb - midmt_keysig = 0x59, // sf mi - midmt_seqspec = 0x7f // data... -}; - -enum bank_op { - b_op2, - b_op4, - b_op22, - b_op0 -}; - -enum opl3_op { - ch_2op = 0, - ch_4op = 1, - ch_4op2 = 2 -}; - -enum envelope_gen_num { - envelope_gen_num_attack = 0, - envelope_gen_num_decay = 1, - envelope_gen_num_sustain = 2, - envelope_gen_num_release = 3 -}; - -static const char *mid_hdr = "MThd"; -static const char *mid_trk = "MTrk"; - -static const uint bank_notes[] = { - 8175, 8661, 9177, 9722, 10300, 10913, 11562, 12249, - 12978, 13750, 14567, 15433, 16351, 17323, 18354, 19445, - 20601, 21826, 23124, 24499, 25956, 27500, 29135, 30867, - 32703, 34647, 36708, 38890, 41203, 43653, 46249, 48999, - 51913, 55000, 58270, 61735, 65406, 69295, 73416, 77781, - 82406, 87307, 92498, 97998, 103826, 110000, 116540, 123470, - 130812, 138591, 146832, 155563, 164813, 174614, 184997, 195997, - 207652, 220000, 233081, 246941, 261625, 277182, 293664, 311126, - 329627, 349228, 369994, 391995, 415304, 440000, 466163, 493883, - 523251, 554365, 587329, 622253, 659255, 698456, 739988, 783990, - 830609, 880000, 932327, 987766, 1046502, 1108730, 1174659, 1244507, - 1318510, 1396912, 1479977, 1567981, 1661218, 1760000, 1864655, 1975533, - 2093004, 2217461, 2349318, 2489015, 2637020, 2793825, 2959955, 3135963, - 3322437, 3520000, 3729310, 3951066, 4186009, 4434922, 4698636, 4978031, - 5274040, 5587651, 5919910, 6271926, 6644875, 7040000, 7458620, 7902132, - 8372018, 8869844, 9397272, 9956063, 10548081, 11175303, 11839821, 12543853 -}; - -static const uint opl3_maxfreq[] = { - 48503, - 97006, - 194013, - 388026, - 776053, - 1552107, - 3104215, - 6208431 -}; - -static const ushort logsinrom[256] = { - 0x859, 0x6c3, 0x607, 0x58b, 0x52e, 0x4e4, 0x4a6, 0x471, - 0x443, 0x41a, 0x3f5, 0x3d3, 0x3b5, 0x398, 0x37e, 0x365, - 0x34e, 0x339, 0x324, 0x311, 0x2ff, 0x2ed, 0x2dc, 0x2cd, - 0x2bd, 0x2af, 0x2a0, 0x293, 0x286, 0x279, 0x26d, 0x261, - 0x256, 0x24b, 0x240, 0x236, 0x22c, 0x222, 0x218, 0x20f, - 0x206, 0x1fd, 0x1f5, 0x1ec, 0x1e4, 0x1dc, 0x1d4, 0x1cd, - 0x1c5, 0x1be, 0x1b7, 0x1b0, 0x1a9, 0x1a2, 0x19b, 0x195, - 0x18f, 0x188, 0x182, 0x17c, 0x177, 0x171, 0x16b, 0x166, - 0x160, 0x15b, 0x155, 0x150, 0x14b, 0x146, 0x141, 0x13c, - 0x137, 0x133, 0x12e, 0x129, 0x125, 0x121, 0x11c, 0x118, - 0x114, 0x10f, 0x10b, 0x107, 0x103, 0x0ff, 0x0fb, 0x0f8, - 0x0f4, 0x0f0, 0x0ec, 0x0e9, 0x0e5, 0x0e2, 0x0de, 0x0db, - 0x0d7, 0x0d4, 0x0d1, 0x0cd, 0x0ca, 0x0c7, 0x0c4, 0x0c1, - 0x0be, 0x0bb, 0x0b8, 0x0b5, 0x0b2, 0x0af, 0x0ac, 0x0a9, - 0x0a7, 0x0a4, 0x0a1, 0x09f, 0x09c, 0x099, 0x097, 0x094, - 0x092, 0x08f, 0x08d, 0x08a, 0x088, 0x086, 0x083, 0x081, - 0x07f, 0x07d, 0x07a, 0x078, 0x076, 0x074, 0x072, 0x070, - 0x06e, 0x06c, 0x06a, 0x068, 0x066, 0x064, 0x062, 0x060, - 0x05e, 0x05c, 0x05b, 0x059, 0x057, 0x055, 0x053, 0x052, - 0x050, 0x04e, 0x04d, 0x04b, 0x04a, 0x048, 0x046, 0x045, - 0x043, 0x042, 0x040, 0x03f, 0x03e, 0x03c, 0x03b, 0x039, - 0x038, 0x037, 0x035, 0x034, 0x033, 0x031, 0x030, 0x02f, - 0x02e, 0x02d, 0x02b, 0x02a, 0x029, 0x028, 0x027, 0x026, - 0x025, 0x024, 0x023, 0x022, 0x021, 0x020, 0x01f, 0x01e, - 0x01d, 0x01c, 0x01b, 0x01a, 0x019, 0x018, 0x017, 0x017, - 0x016, 0x015, 0x014, 0x014, 0x013, 0x012, 0x011, 0x011, - 0x010, 0x00f, 0x00f, 0x00e, 0x00d, 0x00d, 0x00c, 0x00c, - 0x00b, 0x00a, 0x00a, 0x009, 0x009, 0x008, 0x008, 0x007, - 0x007, 0x007, 0x006, 0x006, 0x005, 0x005, 0x005, 0x004, - 0x004, 0x004, 0x003, 0x003, 0x003, 0x002, 0x002, 0x002, - 0x002, 0x001, 0x001, 0x001, 0x001, 0x001, 0x001, 0x001, - 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000 -}; - -static const ushort exprom[256] = { - 0x7fa, 0x7f5, 0x7ef, 0x7ea, 0x7e4, 0x7df, 0x7da, 0x7d4, - 0x7cf, 0x7c9, 0x7c4, 0x7bf, 0x7b9, 0x7b4, 0x7ae, 0x7a9, - 0x7a4, 0x79f, 0x799, 0x794, 0x78f, 0x78a, 0x784, 0x77f, - 0x77a, 0x775, 0x770, 0x76a, 0x765, 0x760, 0x75b, 0x756, - 0x751, 0x74c, 0x747, 0x742, 0x73d, 0x738, 0x733, 0x72e, - 0x729, 0x724, 0x71f, 0x71a, 0x715, 0x710, 0x70b, 0x706, - 0x702, 0x6fd, 0x6f8, 0x6f3, 0x6ee, 0x6e9, 0x6e5, 0x6e0, - 0x6db, 0x6d6, 0x6d2, 0x6cd, 0x6c8, 0x6c4, 0x6bf, 0x6ba, - 0x6b5, 0x6b1, 0x6ac, 0x6a8, 0x6a3, 0x69e, 0x69a, 0x695, - 0x691, 0x68c, 0x688, 0x683, 0x67f, 0x67a, 0x676, 0x671, - 0x66d, 0x668, 0x664, 0x65f, 0x65b, 0x657, 0x652, 0x64e, - 0x649, 0x645, 0x641, 0x63c, 0x638, 0x634, 0x630, 0x62b, - 0x627, 0x623, 0x61e, 0x61a, 0x616, 0x612, 0x60e, 0x609, - 0x605, 0x601, 0x5fd, 0x5f9, 0x5f5, 0x5f0, 0x5ec, 0x5e8, - 0x5e4, 0x5e0, 0x5dc, 0x5d8, 0x5d4, 0x5d0, 0x5cc, 0x5c8, - 0x5c4, 0x5c0, 0x5bc, 0x5b8, 0x5b4, 0x5b0, 0x5ac, 0x5a8, - 0x5a4, 0x5a0, 0x59c, 0x599, 0x595, 0x591, 0x58d, 0x589, - 0x585, 0x581, 0x57e, 0x57a, 0x576, 0x572, 0x56f, 0x56b, - 0x567, 0x563, 0x560, 0x55c, 0x558, 0x554, 0x551, 0x54d, - 0x549, 0x546, 0x542, 0x53e, 0x53b, 0x537, 0x534, 0x530, - 0x52c, 0x529, 0x525, 0x522, 0x51e, 0x51b, 0x517, 0x514, - 0x510, 0x50c, 0x509, 0x506, 0x502, 0x4ff, 0x4fb, 0x4f8, - 0x4f4, 0x4f1, 0x4ed, 0x4ea, 0x4e7, 0x4e3, 0x4e0, 0x4dc, - 0x4d9, 0x4d6, 0x4d2, 0x4cf, 0x4cc, 0x4c8, 0x4c5, 0x4c2, - 0x4be, 0x4bb, 0x4b8, 0x4b5, 0x4b1, 0x4ae, 0x4ab, 0x4a8, - 0x4a4, 0x4a1, 0x49e, 0x49b, 0x498, 0x494, 0x491, 0x48e, - 0x48b, 0x488, 0x485, 0x482, 0x47e, 0x47b, 0x478, 0x475, - 0x472, 0x46f, 0x46c, 0x469, 0x466, 0x463, 0x460, 0x45d, - 0x45a, 0x457, 0x454, 0x451, 0x44e, 0x44b, 0x448, 0x445, - 0x442, 0x43f, 0x43c, 0x439, 0x436, 0x433, 0x430, 0x42d, - 0x42a, 0x428, 0x425, 0x422, 0x41f, 0x41c, 0x419, 0x416, - 0x414, 0x411, 0x40e, 0x40b, 0x408, 0x406, 0x403, 0x400 -}; - -static const byte op_mt[16] = { - 1, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 20, 24, 24, 30, 30 -}; - -static const byte kslrom[16] = { - 0, 32, 40, 45, 48, 51, 53, 55, 56, 58, 59, 60, 61, 62, 63, 64 -}; - -static const byte kslshift[4] = { - 8, 1, 2, 0 -}; - -static const byte eg_incstep[4][4] = { - { 0, 0, 0, 0 }, - { 1, 0, 0, 0 }, - { 1, 0, 1, 0 }, - { 1, 1, 1, 0 } -}; - - -typedef struct _bank_voice bank_voice; -typedef struct _bank_key bank_key; -typedef struct _bank_channel bank_channel; -typedef struct _bank_handle bank_handle; -typedef struct _opl3_slot opl3_slot; -typedef struct _opl3_channel opl3_channel; -typedef struct _opl3_chip opl3_chip; -typedef short(*envelope_sinfunc)(ushort phase, ushort envelope); -typedef void(*envelope_genfunc)(opl3_slot *slott); - - -typedef struct { - byte *buffer; - uint size; - uint pos; - byte status; - byte ending; - uint wait; - ushort trknum; -} mid_track; - -typedef struct { - mid_track *track; - ushort tracks; - uint tpqn; - uint uspb; - uint ticktime; -} mid_handle; - -typedef struct { - byte tremolo; - byte vibrato; - byte sustaining; - byte ksr; - byte mult; - byte ksl; - byte level; - byte attack; - byte decay; - byte sustain; - byte release; - byte waveform; -} bank_operator; - -typedef struct { - bank_operator ops[2]; - short detune; - short offset; - byte feedback; - byte am; -} bank_pair; - -typedef struct { - bank_pair channels[2]; - byte op; - byte fixed; - byte percnum; - char name[32]; -} bank_instr; - -struct _bank_voice { - bank_channel *channel; - opl3_channel *opl; - byte note; - byte op; - short detune; - bank_voice *pair; -}; - -struct _bank_key { - byte note; - byte velocity; - bank_voice *voice; -}; - -struct _bank_channel { - bank_handle *bank; - bank_key keys[BANK_MAX]; - byte notes[128]; - byte keyindex; - byte active; - ushort pbank; - char pan; - byte volume; - short pitch; - byte program; - bank_instr *instr; - byte ch_num; -}; - -struct _bank_handle { - bank_channel channel[16]; - bank_voice *voices; - bank_instr *bdata; - ushort voiceindex; - ushort v_avail; - ushort v_used; - byte flags; - char velo_func; -}; - -struct _opl3_slot { - opl3_channel *channel; - opl3_chip *chip; - short out; - short fbmod; - short *mod; - short prout; - ushort eg_rout; - ushort eg_out; - byte eg_gen; - byte eg_ksl; - byte *trem; - byte reg_vib; - byte reg_type; - byte reg_ksr; - byte reg_mult; - byte reg_ksl; - byte reg_tl; - byte reg_ar; - byte reg_dr; - byte reg_sl; - byte reg_rr; - byte reg_wf; - byte key; - byte detrigger; - byte retrigger; - uint pg_reset; - uint pg_phase; - ushort pg_phase_out; - byte slot_num; -}; - -struct _opl3_channel { - opl3_slot *slots[2]; - opl3_channel *pair; - opl3_chip *chip; - short *out[4]; - - int level[2]; - - byte chtype; - ushort f_num; - byte block; - byte fb; - byte con; - byte alg; - byte ksv; - byte ch_num; -}; - -struct _opl3_chip { - opl3_channel *channel; - opl3_slot *slot; - ushort timer; - ulong eg_timer; - byte eg_timerrem; - byte eg_state; - byte eg_add; - byte nts; - byte vibpos; - byte vibshift; - byte tremolo; - byte tremolopos; - byte tremoloshift; - byte n_voices; - uint noise; - short zeromod; - int mixbuff[4]; - - int rateratio; - int samplecnt; - short oldsamples[2]; - short samples[2]; -}; - - - - - // OPL3 emulator - - // Envelope generator - - short OPL3_EnvelopeCalcExp(uint level) - { - if (level > 0x1fff) - { - level = 0x1fff; - } - return (exprom[level & 0xff] << 1) >> (level >> 8); - } - - short OPL3_EnvelopeCalcSin0(ushort phase, ushort envelope) - { - ushort out = 0; - ushort neg = 0; - phase &= 0x3ff; - if (phase & 0x200) - { - neg = 0xffff; - } - if (phase & 0x100) - { - out = logsinrom[(phase & 0xff) ^ 0xff]; - } - else - { - out = logsinrom[phase & 0xff]; - } - return OPL3_EnvelopeCalcExp(out + (envelope << 3)) ^ neg; - } - - short OPL3_EnvelopeCalcSin1(ushort phase, ushort envelope) - { - ushort out = 0; - phase &= 0x3ff; - if (phase & 0x200) - { - out = 0x1000; - } - else if (phase & 0x100) - { - out = logsinrom[(phase & 0xff) ^ 0xff]; - } - else - { - out = logsinrom[phase & 0xff]; - } - return OPL3_EnvelopeCalcExp(out + (envelope << 3)); - } - - short OPL3_EnvelopeCalcSin2(ushort phase, ushort envelope) - { - ushort out = 0; - phase &= 0x3ff; - if (phase & 0x100) - { - out = logsinrom[(phase & 0xff) ^ 0xff]; - } - else - { - out = logsinrom[phase & 0xff]; - } - return OPL3_EnvelopeCalcExp(out + (envelope << 3)); - } - - short OPL3_EnvelopeCalcSin3(ushort phase, ushort envelope) - { - ushort out = 0; - phase &= 0x3ff; - if (phase & 0x100) - { - out = 0x1000; - } - else - { - out = logsinrom[phase & 0xff]; - } - return OPL3_EnvelopeCalcExp(out + (envelope << 3)); - } - - short OPL3_EnvelopeCalcSin4(ushort phase, ushort envelope) - { - ushort out = 0; - ushort neg = 0; - phase &= 0x3ff; - if ((phase & 0x300) == 0x100) - { - neg = 0xffff; - } - if (phase & 0x200) - { - out = 0x1000; - } - else if (phase & 0x80) - { - out = logsinrom[((phase ^ 0xff) << 1) & 0xff]; - } - else - { - out = logsinrom[(phase << 1) & 0xff]; - } - return OPL3_EnvelopeCalcExp(out + (envelope << 3)) ^ neg; - } - - short OPL3_EnvelopeCalcSin5(ushort phase, ushort envelope) - { - ushort out = 0; - phase &= 0x3ff; - if (phase & 0x200) - { - out = 0x1000; - } - else if (phase & 0x80) - { - out = logsinrom[((phase ^ 0xff) << 1) & 0xff]; - } - else - { - out = logsinrom[(phase << 1) & 0xff]; - } - return OPL3_EnvelopeCalcExp(out + (envelope << 3)); - } - - short OPL3_EnvelopeCalcSin6(ushort phase, ushort envelope) - { - ushort neg = 0; - phase &= 0x3ff; - if (phase & 0x200) - { - neg = 0xffff; - } - return OPL3_EnvelopeCalcExp(envelope << 3) ^ neg; - } - - short OPL3_EnvelopeCalcSin7(ushort phase, ushort envelope) - { - ushort out = 0; - ushort neg = 0; - phase &= 0x3ff; - if (phase & 0x200) - { - neg = 0xffff; - phase = (phase & 0x1ff) ^ 0x1ff; - } - out = phase << 3; - return OPL3_EnvelopeCalcExp(out + (envelope << 3)) ^ neg; - } - - static const envelope_sinfunc envelope_sin[8] = { - OPL3_EnvelopeCalcSin0, - OPL3_EnvelopeCalcSin1, - OPL3_EnvelopeCalcSin2, - OPL3_EnvelopeCalcSin3, - OPL3_EnvelopeCalcSin4, - OPL3_EnvelopeCalcSin5, - OPL3_EnvelopeCalcSin6, - OPL3_EnvelopeCalcSin7, - }; - - void OPL3_EnvelopeCalc(opl3_slot *slot) - { - byte nonzero; - byte rate; - byte rate_hi; - byte rate_lo; - byte reg_rate = 0; - byte ks; - byte eg_shift, shift; - ushort eg_rout; - short eg_inc; - byte eg_off; - byte reset = 0; - if(slot->retrigger) { - slot->eg_rout = 0x1ff; - } - slot->eg_out = slot->eg_rout + (slot->reg_tl << 2) - + (slot->eg_ksl >> kslshift[slot->reg_ksl]) + *slot->trem; - if (slot->key && slot->eg_gen == envelope_gen_num_release) - { - reset = 1; - reg_rate = slot->reg_ar; - } - else - { - switch (slot->eg_gen) - { - case envelope_gen_num_attack: - reg_rate = slot->reg_ar; - break; - case envelope_gen_num_decay: - reg_rate = slot->reg_dr; - break; - case envelope_gen_num_sustain: - if (!slot->reg_type) - { - reg_rate = slot->reg_rr; - } - break; - case envelope_gen_num_release: - reg_rate = slot->reg_rr; - break; - } - } - slot->pg_reset = reset; - ks = slot->channel->ksv >> ((slot->reg_ksr ^ 1) << 1); - nonzero = (reg_rate != 0); - rate = ks + (reg_rate << 2); - rate_hi = rate >> 2; - rate_lo = rate & 0x03; - if (rate_hi & 0x10) - { - rate_hi = 0x0f; - } - eg_shift = rate_hi + slot->chip->eg_add; - shift = 0; - if (nonzero) - { - if (rate_hi < 12) - { - if (slot->chip->eg_state) - { - switch (eg_shift) - { - case 12: - shift = 1; - break; - case 13: - shift = (rate_lo >> 1) & 0x01; - break; - case 14: - shift = rate_lo & 0x01; - break; - default: - break; - } - } - } - else - { - shift = (rate_hi & 0x03) + eg_incstep[rate_lo][slot->chip->timer & 0x03]; - if (shift & 0x04) - { - shift = 0x03; - } - if (!shift) - { - shift = slot->chip->eg_state; - } - } - } - eg_rout = slot->eg_rout; - eg_inc = 0; - eg_off = 0; - // Instant attack - if (reset && rate_hi == 0x0f) - { - eg_rout = 0x00; - } - // Envelope off - if ((slot->eg_rout & 0x1f8) == 0x1f8) - { - eg_off = 1; - } - if (slot->eg_gen != envelope_gen_num_attack && !reset && eg_off) - { - eg_rout = 0x1ff; - } - switch (slot->eg_gen) - { - case envelope_gen_num_attack: - if (!(slot->eg_rout)) - { - slot->eg_gen = envelope_gen_num_decay; - } - else if (slot->key && shift > 0 && rate_hi != 0x0f) - { - eg_inc = ~slot->eg_rout >> (4 - shift); - } - break; - case envelope_gen_num_decay: - if ((slot->eg_rout >> 4) == slot->reg_sl) - { - slot->eg_gen = envelope_gen_num_sustain; - } - else if (!eg_off && !reset && shift > 0) - { - eg_inc = 1 << (shift - 1); - } - break; - case envelope_gen_num_sustain: - case envelope_gen_num_release: - if (!eg_off && !reset && shift > 0) - { - eg_inc = 1 << (shift - 1); - } - break; - } - slot->eg_rout = (eg_rout + eg_inc) & 0x1ff; - // Key off - if (reset) - { - slot->eg_gen = envelope_gen_num_attack; - } - if (!(slot->key)) - { - slot->eg_gen = envelope_gen_num_release; - } - slot->detrigger = 0; - slot->retrigger = 0; - } - - void OPL3_EnvelopeUpdateKSL(opl3_slot *slot) - { - short ksl = (kslrom[slot->channel->f_num >> 6] << 2) - - ((0x08 - slot->channel->block) << 5); - if (ksl < 0) - { - ksl = 0; - } - slot->eg_ksl = (byte)ksl; - } - - void OPL3_EnvelopeKeyOn(opl3_slot *slot) - { - slot->key = 0x01; - if(slot->detrigger) { - slot->eg_gen = envelope_gen_num_release; - // slot->eg_rout = 0x1ff; - // slot->eg_out = slot->eg_rout = 0x1ff; - slot->detrigger = 0; - } - slot->retrigger = 1; - } - - void OPL3_EnvelopeKeyOff(opl3_slot *slot) - { - slot->key = 0x00; - slot->detrigger = 1; - slot->retrigger = 0; - } - - void OPL3_PhaseGenerate(opl3_slot *slot) - { - opl3_chip *chip; - ushort f_num; - uint basefreq; - ushort phase; - - chip = slot->chip; - f_num = slot->channel->f_num; - if (slot->reg_vib) - { - char range; - byte vibpos; - - range = (f_num >> 7) & 7; - vibpos = slot->chip->vibpos; - - if (!(vibpos & 3)) - { - range = 0; - } - else if (vibpos & 1) - { - range >>= 1; - } - range >>= slot->chip->vibshift; - - if (vibpos & 4) - { - range = -range; - } - f_num += range; - } - basefreq = (f_num << slot->channel->block) >> 1; - phase = (ushort)(slot->pg_phase >> 9); - if (slot->pg_reset) - { - slot->pg_phase = 0; - } - slot->pg_phase += (basefreq * op_mt[slot->reg_mult]) >> 1; - slot->pg_phase_out = phase; - } - - void OPL3_SlotGenerate(opl3_slot *slot) - { - slot->out = envelope_sin[slot->reg_wf](slot->pg_phase_out + *slot->mod, slot->eg_out); - } - - void OPL3_SlotCalcFB(opl3_slot *slot) - { - if (slot->channel->fb != 0x00) - { - slot->fbmod = (slot->prout + slot->out) >> (0x09 - slot->channel->fb); - } - else - { - slot->fbmod = 0; - } - slot->prout = slot->out; - } - - void OPL3_ProcessSlot(opl3_slot *slot) - { - OPL3_SlotCalcFB(slot); - OPL3_EnvelopeCalc(slot); - OPL3_PhaseGenerate(slot); - OPL3_SlotGenerate(slot); - } - - short OPL3_ClipSampleOld(int sample) - { - if (sample > 32767) - { - sample = 32767; - } - else if (sample < -32768) - { - sample = -32768; - } - return (short)sample; - } - - short OPL3_ClipSample(int sample) - { - int sign = (sample < 0) ? -1 : 1; - sample = (sample < 0) ? -sample : sample; - sample *= 5; - sample /= 8; - sample = sample > 32767 ? 32767 : sample; - sample *= sign; - return (short)sample; - } - - void OPL3_Generate(opl3_chip *chip, short *buf) - { - opl3_channel *channel; - short **out; - int mix[2]; - byte ii; - short accm; - byte shift = 0; - - buf[0] = OPL3_ClipSample(chip->mixbuff[0]); - buf[1] = OPL3_ClipSample(chip->mixbuff[1]); - - for (ii = 0; ii < (chip->n_voices * 2); ii++) - { - OPL3_ProcessSlot(&chip->slot[ii]); - } - - mix[0] = mix[1] = 0; - for (ii = 0; ii < chip->n_voices; ii++) - { - channel = &chip->channel[ii]; - out = channel->out; - accm = *out[0] + *out[1] + *out[2] + *out[3]; - mix[0] += (short)((accm * channel->level[0]) >> 16); - mix[1] += (short)((accm * channel->level[1]) >> 16); - } - chip->mixbuff[0] = mix[0]; - chip->mixbuff[1] = mix[1]; - - if ((chip->timer & 0x3f) == 0x3f) - { - chip->tremolopos = (chip->tremolopos + 1) % 210; - } - if (chip->tremolopos < 105) - { - chip->tremolo = chip->tremolopos >> chip->tremoloshift; - } - else - { - chip->tremolo = (210 - chip->tremolopos) >> chip->tremoloshift; - } - - if ((chip->timer & 0x3ff) == 0x3ff) - { - chip->vibpos = (chip->vibpos + 1) & 7; - } - - chip->timer++; - - chip->eg_add = 0; - if (chip->eg_timer) - { - while (shift < 36 && ((chip->eg_timer >> shift) & 1) == 0) - { - shift++; - } - if (shift > 12) - { - chip->eg_add = 0; - } - else - { - chip->eg_add = shift + 1; - } - } - - if (chip->eg_timerrem || chip->eg_state) - { - if (chip->eg_timer == 0xfffffffff) - { - chip->eg_timer = 0; - chip->eg_timerrem = 1; - } - else - { - chip->eg_timer++; - chip->eg_timerrem = 0; - } - } - - chip->eg_state ^= 1; - } - - void OPL3_GenerateResampled(opl3_chip *chip, short *buf) - { - while (chip->samplecnt >= chip->rateratio) - { - chip->oldsamples[0] = chip->samples[0]; - chip->oldsamples[1] = chip->samples[1]; - OPL3_Generate(chip, chip->samples); - chip->samplecnt -= chip->rateratio; - } - buf[0] = (short)((chip->oldsamples[0] * (chip->rateratio - chip->samplecnt) - + chip->samples[0] * chip->samplecnt) / chip->rateratio); - buf[1] = (short)((chip->oldsamples[1] * (chip->rateratio - chip->samplecnt) - + chip->samples[1] * chip->samplecnt) / chip->rateratio); - chip->samplecnt += 1 << RSM_FRAC; - } - - // Operator - - void OPL3_SlotFlags(opl3_slot *slot, byte tremolo, byte vibrato, byte sustaining, byte ksr) { - if (tremolo) - { - slot->trem = &slot->chip->tremolo; - } - else - { - slot->trem = (byte*)&slot->chip->zeromod; - } - slot->reg_vib = vibrato & 0x01; - slot->reg_type = sustaining & 0x01; - slot->reg_ksr = ksr & 0x01; - } - - void OPL3_SlotMult(opl3_slot *slot, byte mult) { - slot->reg_mult = mult & 0x0f; - } - - void OPL3_SlotKSL(opl3_slot *slot, byte ksl) { - slot->reg_ksl = ksl & 0x03; - OPL3_EnvelopeUpdateKSL(slot); - } - - void OPL3_SlotLevel(opl3_slot *slot, byte level) { - slot->reg_tl = level & 0x3f; - } - - void OPL3_SlotADSR(opl3_slot *slot, byte attack, byte decay, byte sustain, byte release) { - slot->reg_ar = attack & 0x0f; - slot->reg_dr = decay & 0x0f; - slot->reg_sl = sustain & 0x0f; - if (slot->reg_sl == 0x0f) - { - slot->reg_sl = 0x1f; - } - slot->reg_rr = release & 0x0f; - if (slot->reg_rr == 0x00) - { - slot->reg_rr = 0x01; - } - } - - void OPL3_SlotWaveform(opl3_slot *slot, byte waveform) { - slot->reg_wf = waveform & 0x07; - } - - // Channel - - void OPL3_ChannelSetupAlg(opl3_channel *channel) - { - if (channel->alg & 0x08) - { - return; - } - if (channel->alg & 0x04) - { - channel->pair->out[0] = &channel->chip->zeromod; - channel->pair->out[1] = &channel->chip->zeromod; - channel->pair->out[2] = &channel->chip->zeromod; - channel->pair->out[3] = &channel->chip->zeromod; - switch (channel->alg & 0x03) - { - case 0x00: - channel->pair->slots[0]->mod = &channel->pair->slots[0]->fbmod; - channel->pair->slots[1]->mod = &channel->pair->slots[0]->out; - channel->slots[0]->mod = &channel->pair->slots[1]->out; - channel->slots[1]->mod = &channel->slots[0]->out; - channel->out[0] = &channel->slots[1]->out; - channel->out[1] = &channel->chip->zeromod; - channel->out[2] = &channel->chip->zeromod; - channel->out[3] = &channel->chip->zeromod; - break; - case 0x01: - channel->pair->slots[0]->mod = &channel->pair->slots[0]->fbmod; - channel->pair->slots[1]->mod = &channel->pair->slots[0]->out; - channel->slots[0]->mod = &channel->chip->zeromod; - channel->slots[1]->mod = &channel->slots[0]->out; - channel->out[0] = &channel->pair->slots[1]->out; - channel->out[1] = &channel->slots[1]->out; - channel->out[2] = &channel->chip->zeromod; - channel->out[3] = &channel->chip->zeromod; - break; - case 0x02: - channel->pair->slots[0]->mod = &channel->pair->slots[0]->fbmod; - channel->pair->slots[1]->mod = &channel->chip->zeromod; - channel->slots[0]->mod = &channel->pair->slots[1]->out; - channel->slots[1]->mod = &channel->slots[0]->out; - channel->out[0] = &channel->pair->slots[0]->out; - channel->out[1] = &channel->slots[1]->out; - channel->out[2] = &channel->chip->zeromod; - channel->out[3] = &channel->chip->zeromod; - break; - case 0x03: - channel->pair->slots[0]->mod = &channel->pair->slots[0]->fbmod; - channel->pair->slots[1]->mod = &channel->chip->zeromod; - channel->slots[0]->mod = &channel->pair->slots[1]->out; - channel->slots[1]->mod = &channel->chip->zeromod; - channel->out[0] = &channel->pair->slots[0]->out; - channel->out[1] = &channel->slots[0]->out; - channel->out[2] = &channel->slots[1]->out; - channel->out[3] = &channel->chip->zeromod; - break; - } - } - else - { - switch (channel->alg & 0x01) - { - case 0x00: - channel->slots[0]->mod = &channel->slots[0]->fbmod; - channel->slots[1]->mod = &channel->slots[0]->out; - channel->out[0] = &channel->slots[1]->out; - channel->out[1] = &channel->chip->zeromod; - channel->out[2] = &channel->chip->zeromod; - channel->out[3] = &channel->chip->zeromod; - break; - case 0x01: - channel->slots[0]->mod = &channel->slots[0]->fbmod; - channel->slots[1]->mod = &channel->chip->zeromod; - channel->out[0] = &channel->slots[0]->out; - channel->out[1] = &channel->slots[1]->out; - channel->out[2] = &channel->chip->zeromod; - channel->out[3] = &channel->chip->zeromod; - break; - } - } - } - - void OPL3_ChannelUpdateAlg(opl3_channel *channel) - { - channel->alg = channel->con; - if (channel->chtype == ch_4op) - { - channel->pair->alg = 0x04 | (channel->con << 1) | (channel->pair->con); - channel->alg = 0x08; - OPL3_ChannelSetupAlg(channel->pair); - } - else if (channel->chtype == ch_4op2) - { - channel->alg = 0x04 | (channel->pair->con << 1) | (channel->con); - channel->pair->alg = 0x08; - OPL3_ChannelSetupAlg(channel); - } - else - { - OPL3_ChannelSetupAlg(channel); - } - } - - void OPL3_ChannelFreq(opl3_channel *channel, byte block, ushort f_num) { - if (channel->chtype == ch_4op2) - { - return; - } - channel->f_num = f_num & 0x3ff; - channel->block = block & 0x07; - channel->ksv = (channel->block << 1) - | ((channel->f_num >> (0x09 - channel->chip->nts)) & 0x01); - OPL3_EnvelopeUpdateKSL(channel->slots[0]); - OPL3_EnvelopeUpdateKSL(channel->slots[1]); - if (channel->chtype == ch_4op) - { - channel->pair->f_num = channel->f_num; - channel->pair->block = channel->block; - channel->pair->ksv = channel->ksv; - OPL3_EnvelopeUpdateKSL(channel->pair->slots[0]); - OPL3_EnvelopeUpdateKSL(channel->pair->slots[1]); - } - } - - void OPL3_ChannelOutput(opl3_channel *channel, byte output, uint level) { - channel->level[output & 1] = level; - } - - void OPL3_Channel4Op(opl3_channel *channel, byte op4) { - if (op4) - { - channel->chtype = ch_4op; - channel->pair->chtype = ch_4op2; - OPL3_ChannelUpdateAlg(channel); - } - else - { - channel->chtype = ch_2op; - channel->pair->chtype = ch_2op; - OPL3_ChannelUpdateAlg(channel); - OPL3_ChannelUpdateAlg(channel->pair); - } - } - - void OPL3_ChannelFeedback(opl3_channel *channel, byte feedback) { - channel->fb = feedback & 0x07; - } - - void OPL3_ChannelAM(opl3_channel *channel, byte am) { - channel->con = am & 0x01; - OPL3_ChannelUpdateAlg(channel); - } - - void OPL3_ChannelKeyOn(opl3_channel *channel) - { - if (channel->chtype == ch_4op) - { - OPL3_EnvelopeKeyOn(channel->slots[0]); - OPL3_EnvelopeKeyOn(channel->slots[1]); - OPL3_EnvelopeKeyOn(channel->pair->slots[0]); - OPL3_EnvelopeKeyOn(channel->pair->slots[1]); - } - else if (channel->chtype == ch_2op) - { - OPL3_EnvelopeKeyOn(channel->slots[0]); - OPL3_EnvelopeKeyOn(channel->slots[1]); - } - } - - void OPL3_ChannelKeyOff(opl3_channel *channel) - { - if (channel->chtype == ch_4op) - { - OPL3_EnvelopeKeyOff(channel->slots[0]); - OPL3_EnvelopeKeyOff(channel->slots[1]); - OPL3_EnvelopeKeyOff(channel->pair->slots[0]); - OPL3_EnvelopeKeyOff(channel->pair->slots[1]); - } - else if (channel->chtype == ch_2op) - { - OPL3_EnvelopeKeyOff(channel->slots[0]); - OPL3_EnvelopeKeyOff(channel->slots[1]); - } - } - - void OPL3_Reset(opl3_chip *chip) - { - byte slotnum; - byte channum; - - int rateratio = chip->rateratio; - byte n_voices = chip->n_voices; - opl3_slot *slot = chip->slot; - opl3_channel *channel = chip->channel; - - memset(chip, 0, sizeof(opl3_chip) + (n_voices * (sizeof(opl3_slot) * 2 + sizeof(opl3_channel)))); - - chip->rateratio = rateratio; - chip->n_voices = n_voices; - chip->slot = slot; - chip->channel = channel; - - for (slotnum = 0; slotnum < (chip->n_voices * 2); slotnum++) - { - slot = &chip->slot[slotnum]; - slot->chip = chip; - slot->mod = &chip->zeromod; - slot->eg_rout = 0x1ff; - slot->eg_out = 0x1ff; - slot->eg_gen = envelope_gen_num_release; - slot->trem = (byte*)&chip->zeromod; - slot->slot_num = slotnum; - } - for (channum = 0; channum < chip->n_voices; channum++) - { - channel = &chip->channel[channum]; - channel->slots[0] = &chip->slot[channum * 2]; - channel->slots[1] = &chip->slot[channum * 2 + 1]; - chip->slot[channum * 2].channel = channel; - chip->slot[channum * 2 + 1].channel = channel; - channel->pair = &chip->channel[(channum & 1) ? (channum - 1) : (channum + 1)]; - channel->chip = chip; - channel->out[0] = &chip->zeromod; - channel->out[1] = &chip->zeromod; - channel->out[2] = &chip->zeromod; - channel->out[3] = &chip->zeromod; - channel->chtype = ch_2op; - channel->level[0] = 0x10000; - channel->level[1] = 0x10000; - channel->ch_num = channum; - OPL3_ChannelSetupAlg(channel); - } - chip->tremoloshift = 4; - chip->vibshift = 1; - } - - void OPL3_Rate(opl3_chip *chip, uint samplerate) { - chip->rateratio = (samplerate << RSM_FRAC) / 49716; - } - - void OPL3_ChipFlags(opl3_chip *chip, byte nts, byte vibrato, byte deeptremolo, byte deepvibrato) { - chip->nts = nts; - chip->tremoloshift = ((deeptremolo ^ 1) << 1) + 2; - chip->vibshift = deepvibrato ^ 1; - } - - opl3_chip *OPL3_Alloc(uint samplerate, byte voices) { - opl3_chip *chip = malloc(sizeof(opl3_chip) + (voices * (sizeof(opl3_slot) * 2 + sizeof(opl3_channel)))); - chip->channel = (opl3_channel*)(((byte*)chip) + sizeof(opl3_chip)); - chip->slot = (opl3_slot*)(((byte*)chip->channel) + (voices * sizeof(opl3_channel))); - chip->n_voices = voices; - OPL3_Rate(chip, samplerate); - OPL3_Reset(chip); - return chip; - } - - byte OPL3_Playing(opl3_chip *chip) { - opl3_slot *slot; - for(int z = 0; z < (chip->n_voices * 2); z++) { - slot = &chip->slot[z]; - if(slot->eg_out <= 0x100) { - return 1; - } - } - return 0; - } - - // instrument bank r/w - - // #ifndef DMX_STDMEM - #define DMX_MALLOC(s) mem_alloc(s, MEM_FILE) - #define DMX_FREE(p) mem_free(p) - // #else - // #define DMX_MALLOC(s) malloc(s) - // #define DMX_FREE(p) free(p) - // #endif - // #ifndef DMX_LOG - #define DMX_LOG(s, a...) loge(LOG_IO, s, a) - // #endif - - uint bnk_read_mhbank(byte **data, bank_instr **instr, const char *filename, uint minsize, uint maxsize, const char *hdr, uint hdrsize) { - int err; - FILE *fd = fopen(filename, "rb"); - if(fd == NULL) { - err = errno; - DMX_LOG("Fehler beim Öffnen von Bank-Datei '%s': %s (%d)", filename, strerror(err), err); - return 0; - } - if(fseek(fd, 0L, SEEK_END)) { - err = errno; - DMX_LOG("Fehler beim Lesen von Bank-Datei '%s': %s (%d)", filename, strerror(err), err); - fclose(fd); - return 0; - } - long size = ftell(fd); - if(size < 0L) { - err = errno; - DMX_LOG("Fehler beim Lesen von Bank-Datei '%s': %s (%d)", filename, strerror(err), err); - fclose(fd); - return 0; - } - if(fseek(fd, 0L, SEEK_SET)) { - err = errno; - DMX_LOG("Fehler beim Lesen von Bank-Datei '%s': %s (%d)", filename, strerror(err), err); - fclose(fd); - return 0; - } - if(size < (hdrsize+minsize)) { - DMX_LOG("Fehler beim Lesen von Bank-Datei '%s': Datei zu klein", filename); - fclose(fd); - return 0; - } - if(hdrsize > 0) { - byte header[hdrsize]; - if(fread(header, 1, hdrsize, fd) != hdrsize) { - err = feof(fd); - DMX_LOG(err == 0 ? "Fehler beim Lesen von Bank-Datei '%s': E/A-Fehler" : "Fehler beim Lesen von Bank-Datei '%s': Ende der Datei erreicht", filename); - fclose(fd); - return 0; - } - if(memcmp(header, hdr, hdrsize) != 0) { - DMX_LOG("Fehler beim Lesen von Bank-Datei '%s': Fehlerhafter Dateiheader oder falscher Dateityp", filename); - fclose(fd); - return 0; - } - size -= hdrsize; - } - size = ((maxsize > 0) && (size > maxsize)) ? maxsize : size; - *data = DMX_MALLOC(size); - if(fread(*data, 1, size, fd) != size) { - err = feof(fd); - DMX_LOG(err == 0 ? "Fehler beim Lesen von Bank-Datei '%s': E/A-Fehler" : "Fehler beim Lesen von Bank-Datei '%s': Ende der Datei erreicht", filename); - fclose(fd); - DMX_FREE(*data); - return 0; - } - fclose(fd); - *instr = DMX_MALLOC(sizeof(bank_instr)*256); - return size; - } - - uint bnk_read_mbank(byte **data, bank_instr **instr, const char *filename, uint minsize, uint maxsize) { - return bnk_read_mhbank(data, instr, filename, minsize, maxsize, NULL, 0); - } - - uint bnk_read_hbank(byte **data, bank_instr **instr, const char *filename, uint size, const char *hdr, uint hdrsize) { - return bnk_read_mhbank(data, instr, filename, size, size, hdr, hdrsize); - } - - uint bnk_read_sbank(byte **data, bank_instr **instr, const char *filename, uint size) { - return bnk_read_mhbank(data, instr, filename, size, size, NULL, 0); - } - - ushort dmx_read_uint16(byte *data) { - ushort value = 0; - for(int h = 0; h < 2; h++) { - value |= ((ushort)data[1-h]); - value <<= h < 1 ? 8 : 0; - } - return value; - } - - ushort dmx_read_uint16be(byte *data) { - ushort value = 0; - for(int h = 0; h < 2; h++) { - value |= ((ushort)data[h]); - value <<= h < 1 ? 8 : 0; - } - return value; - } - - void dmx_read_instr(bank_instr *instr, byte *data, byte drum) { - instr->fixed = ((data[0] & 0x01) > 0) | drum; - instr->op = ((data[0] & 0x04) > 0) ? b_op22 : b_op2; - instr->channels[0].detune = 0; - instr->channels[1].detune = ((short)data[2]) - 128; - instr->percnum = data[3] & 0x7f; - data += 4; - for(int ch = 0; ch < 2; ch++) { - for(int op = 0; op < 2; op++) { - instr->channels[ch].ops[op].tremolo = (data[op*7+0] & 0x80) > 0; - instr->channels[ch].ops[op].vibrato = (data[op*7+0] & 0x40) > 0; - instr->channels[ch].ops[op].sustaining = (data[op*7+0] & 0x20) > 0; - instr->channels[ch].ops[op].ksr = (data[op*7+0] & 0x10) > 0; - instr->channels[ch].ops[op].mult = data[op*7+0] & 0x0f; - instr->channels[ch].ops[op].attack = (data[op*7+1] >> 4) & 0x0f; - instr->channels[ch].ops[op].decay = data[op*7+1] & 0x0f; - instr->channels[ch].ops[op].sustain = (data[op*7+2] >> 4) & 0x0f; - instr->channels[ch].ops[op].release = data[op*7+2] & 0x0f; - instr->channels[ch].ops[op].waveform = data[op*7+3] & 0x07; - instr->channels[ch].ops[op].ksl = (data[op*7+4] >> 6) & 0x03; - instr->channels[ch].ops[op].level = data[op*7+5] & 0x3f; - } - instr->channels[ch].feedback = (data[6] >> 1) & 0x07; - instr->channels[ch].am = data[6] & 0x01; - instr->channels[ch].offset = ((short)dmx_read_uint16(data+14)) + 12; - data += 16; - } - } - - bank_instr *dmx_read_bank(const char *filename) { - byte *data; - bank_instr *instr; - uint size = bnk_read_hbank(&data, &instr, filename, 175*68, "#OPL_II#", 8); - if(size == 0) { - return NULL; - } - byte *odata = data; - for(int i = 0; i < 256; i++) { - instr[i].op = b_op0; - instr[i].name[0] = 0; - } - for(int i = 0; i < 175; i++) { - dmx_read_instr(&instr[(i < 128) ? i : (i + 35)], data, i >= 128); - data += 36; - } - for(int i = 0; i < 175; i++) { - bank_instr *ins = &instr[(i < 128) ? i : (i + 35)]; - memcpy(ins->name, data, 32); - ins->name[31] = 0; - data += 32; - } - DMX_FREE(odata); - return instr; - } - - void tmb_read_instr(bank_instr *instr, byte *data, byte drum) { - instr->name[0] = 0; - instr->fixed = drum; - instr->op = b_op2; - for(int op = 0; op < 2; op++) { - instr->channels[0].ops[op].tremolo = (data[op+0] & 0x80) > 0; - instr->channels[0].ops[op].vibrato = (data[op+0] & 0x40) > 0; - instr->channels[0].ops[op].sustaining = (data[op+0] & 0x20) > 0; - instr->channels[0].ops[op].ksr = (data[op+0] & 0x10) > 0; - instr->channels[0].ops[op].mult = data[op+0] & 0x0f; - instr->channels[0].ops[op].attack = (data[op+4] >> 4) & 0x0f; - instr->channels[0].ops[op].decay = data[op+4] & 0x0f; - instr->channels[0].ops[op].sustain = (data[op+6] >> 4) & 0x0f; - instr->channels[0].ops[op].release = data[op+6] & 0x0f; - instr->channels[0].ops[op].waveform = data[op+8] & 0x07; - instr->channels[0].ops[op].ksl = (data[op+2] >> 6) & 0x03; - instr->channels[0].ops[op].level = data[op+2] & 0x3f; - } - instr->channels[0].feedback = (data[10] >> 1) & 0x07; - instr->channels[0].am = data[10] & 0x01; - instr->percnum = drum ? (data[11] & 0x7f) : 0; - instr->channels[0].offset = drum ? 0 : ((char)data[11]); - instr->channels[0].detune = 0; - } - - bank_instr *tmb_read_bank(const char *filename) { - byte *data; - bank_instr *instr; - uint size = bnk_read_sbank(&data, &instr, filename, 256*13); - if(size == 0) { - return NULL; - } - byte *odata = data; - for(int i = 0; i < 256; i++) { - tmb_read_instr(&instr[i], data, i >= 128); - data += 13; - } - DMX_FREE(odata); - return instr; - } - - void ibk_read_instr(bank_instr *instr, byte *data, byte drum) { - instr->fixed = drum; - instr->op = b_op2; - for(int op = 0; op < 2; op++) { - instr->channels[0].ops[op].tremolo = (data[op+0] & 0x80) > 0; - instr->channels[0].ops[op].vibrato = (data[op+0] & 0x40) > 0; - instr->channels[0].ops[op].sustaining = (data[op+0] & 0x20) > 0; - instr->channels[0].ops[op].ksr = (data[op+0] & 0x10) > 0; - instr->channels[0].ops[op].mult = data[op+0] & 0x0f; - instr->channels[0].ops[op].attack = (data[op+4] >> 4) & 0x0f; - instr->channels[0].ops[op].decay = data[op+4] & 0x0f; - instr->channels[0].ops[op].sustain = (data[op+6] >> 4) & 0x0f; - instr->channels[0].ops[op].release = data[op+6] & 0x0f; - instr->channels[0].ops[op].waveform = data[op+8] & 0x07; - instr->channels[0].ops[op].ksl = (data[op+2] >> 6) & 0x03; - instr->channels[0].ops[op].level = data[op+2] & 0x3f; - } - instr->channels[0].feedback = (data[10] >> 1) & 0x07; - instr->channels[0].am = data[10] & 0x01; - instr->percnum = drum ? (data[13] & 0x7f) : 0; - instr->channels[0].offset = drum ? 0 : ((char)data[13]); - instr->channels[0].detune = 0; - } - - bank_instr *ibk_read_bank(const char *filename, byte drum) { - byte *data; - bank_instr *instr; - uint size = bnk_read_hbank(&data, &instr, filename, 128*25, "IBK\x1a", 4); - if(size == 0) { - return NULL; - } - byte *odata = data; - for(int i = 0; i < 128; i++) { - instr[i + (drum ? 0 : 128)].op = b_op0; - instr[i + (drum ? 0 : 128)].name[0] = 0; - } - for(int i = 0; i < 128; i++) { - ibk_read_instr(&instr[i + (drum ? 128 : 0)], data, drum); - data += 16; - } - for(int i = 0; i < 128; i++) { - bank_instr *ins = &instr[i + (drum ? 128 : 0)]; - memcpy(ins->name, data, 8); - ins->name[8] = 0; - data += 9; - } - DMX_FREE(odata); - return instr; - } - - void sb_read_instr(bank_instr *instr, byte *data, byte drum) { - for(int h = 0; h < 28; h++) { - instr->name[h] = (data[h] == 0x1a) ? ' ' : data[h]; - } - instr->name[28] = 0; - instr->percnum = data[35] & 0x7f; - instr->fixed = drum; - instr->op = b_op2; - data += 36; - for(int op = 0; op < 2; op++) { - instr->channels[0].ops[op].tremolo = (data[op+0] & 0x80) > 0; - instr->channels[0].ops[op].vibrato = (data[op+0] & 0x40) > 0; - instr->channels[0].ops[op].sustaining = (data[op+0] & 0x20) > 0; - instr->channels[0].ops[op].ksr = (data[op+0] & 0x10) > 0; - instr->channels[0].ops[op].mult = data[op+0] & 0x0f; - instr->channels[0].ops[op].attack = (data[op+4] >> 4) & 0x0f; - instr->channels[0].ops[op].decay = data[op+4] & 0x0f; - instr->channels[0].ops[op].sustain = (data[op+6] >> 4) & 0x0f; - instr->channels[0].ops[op].release = data[op+6] & 0x0f; - instr->channels[0].ops[op].waveform = data[op+8] & 0x07; - instr->channels[0].ops[op].ksl = (data[op+2] >> 6) & 0x03; - instr->channels[0].ops[op].level = data[op+2] & 0x3f; - } - instr->channels[0].feedback = (data[10] >> 1) & 0x07; - instr->channels[0].am = data[10] & 0x01; - instr->channels[0].offset = 0; - instr->channels[0].detune = 0; - } - - bank_instr *sb_read_bank(const char *filename, byte drum) { - byte *data; - bank_instr *instr; - uint size = bnk_read_sbank(&data, &instr, filename, 128*52); - if(size == 0) { - return NULL; - } - byte *odata = data; - for(int i = 0; i < 128; i++) { - instr[i + (drum ? 0 : 128)].op = b_op0; - instr[i + (drum ? 0 : 128)].name[0] = 0; - } - for(int i = 0; i < 128; i++) { - sb_read_instr(&instr[i + (drum ? 128 : 0)], data, drum); - data += 52; - } - DMX_FREE(odata); - return instr; - } - - void sb3_read_instr(bank_instr *instr, byte *data, byte drum) { - for(int h = 0; h < 28; h++) { - instr->name[h] = (data[h] == 0x1a) ? ' ' : data[h]; - } - instr->name[28] = 0; - instr->percnum = data[35] & 0x7f; - instr->fixed = drum; - instr->op = (data[0] == '4') ? b_op4 : b_op2; - data += 36; - for(int ch = 0; ch < 2; ch++) { - for(int op = 0; op < 2; op++) { - instr->channels[ch].ops[op].tremolo = (data[op+0] & 0x80) > 0; - instr->channels[ch].ops[op].vibrato = (data[op+0] & 0x40) > 0; - instr->channels[ch].ops[op].sustaining = (data[op+0] & 0x20) > 0; - instr->channels[ch].ops[op].ksr = (data[op+0] & 0x10) > 0; - instr->channels[ch].ops[op].mult = data[op+0] & 0x0f; - instr->channels[ch].ops[op].attack = (data[op+4] >> 4) & 0x0f; - instr->channels[ch].ops[op].decay = data[op+4] & 0x0f; - instr->channels[ch].ops[op].sustain = (data[op+6] >> 4) & 0x0f; - instr->channels[ch].ops[op].release = data[op+6] & 0x0f; - instr->channels[ch].ops[op].waveform = data[op+8] & 0x07; - instr->channels[ch].ops[op].ksl = (data[op+2] >> 6) & 0x03; - instr->channels[ch].ops[op].level = data[op+2] & 0x3f; - } - instr->channels[ch].feedback = (data[10] >> 1) & 0x07; - instr->channels[ch].am = data[10] & 0x01; - instr->channels[ch].offset = 0; - instr->channels[ch].detune = 0; - data += 11; - } - } - - bank_instr *sb3_read_bank(const char *filename, byte drum) { - byte *data; - bank_instr *instr; - uint size = bnk_read_sbank(&data, &instr, filename, 128*60); - if(size == 0) { - return NULL; - } - byte *odata = data; - for(int i = 0; i < 128; i++) { - instr[i + (drum ? 0 : 128)].op = b_op0; - instr[i + (drum ? 0 : 128)].name[0] = 0; - } - for(int i = 0; i < 128; i++) { - sb3_read_instr(&instr[i + (drum ? 128 : 0)], data, drum); - data += 60; - } - DMX_FREE(odata); - return instr; - } - - void op3_read_instr(bank_instr *instr, byte *data, byte drum) { - instr->percnum = data[1] & 0x7f; - instr->fixed = drum; - instr->op = ((data[0] & 0x01) > 0) ? b_op4 : b_op2; - data += 2; - for(int ch = 0; ch < 2; ch++) { - for(int op = 0; op < 2; op++) { - instr->channels[ch].ops[op].tremolo = (data[op*6+0] & 0x80) > 0; - instr->channels[ch].ops[op].vibrato = (data[op*6+0] & 0x40) > 0; - instr->channels[ch].ops[op].sustaining = (data[op*6+0] & 0x20) > 0; - instr->channels[ch].ops[op].ksr = (data[op*6+0] & 0x10) > 0; - instr->channels[ch].ops[op].mult = data[op*6+0] & 0x0f; - instr->channels[ch].ops[op].attack = (data[op*6+2] >> 4) & 0x0f; - instr->channels[ch].ops[op].decay = data[op*6+2] & 0x0f; - instr->channels[ch].ops[op].sustain = (data[op*6+3] >> 4) & 0x0f; - instr->channels[ch].ops[op].release = data[op*6+3] & 0x0f; - instr->channels[ch].ops[op].waveform = data[op*6+4] & 0x07; - instr->channels[ch].ops[op].ksl = (data[op*6+1] >> 6) & 0x03; - instr->channels[ch].ops[op].level = data[op*6+1] & 0x3f; - } - instr->channels[ch].feedback = (data[5] >> 1) & 0x07; - instr->channels[ch].am = data[5] & 0x01; - instr->channels[ch].offset = 0; - instr->channels[ch].detune = 0; - data += 11; - } - } - - bank_instr *op3_read_bank(const char *filename) { - byte *data; - bank_instr *instr; - uint size = bnk_read_mhbank(&data, &instr, filename, 16, 256*24+16, "Junglevision Patch File\x1a", 24); - if(size == 0) { - return NULL; - } - byte *odata = data; - for(int i = 0; i < 256; i++) { - instr[i].op = b_op0; - instr[i].name[0] = 0; - } - data += 8; - ushort nmelo = dmx_read_uint16(&data[0]); - ushort ndrum = dmx_read_uint16(&data[2]); - ushort omelo = dmx_read_uint16(&data[4]); - ushort odrum = dmx_read_uint16(&data[6]); - data += 8; - if((((nmelo+ndrum)*24+16) > size) || ((omelo+nmelo) > 128) || ((odrum+ndrum) > 128)) { - DMX_LOG("Fehler beim Verarbeiten von Bank-Datei '%s': Ende der Daten erreicht", filename); - DMX_FREE(odata); - DMX_FREE(instr); - return NULL; - } - for(int i = 0; i < nmelo; i++) { - op3_read_instr(&instr[i + omelo], data, 0); - data += 24; - } - for(int i = 0; i < ndrum; i++) { - op3_read_instr(&instr[i + odrum + 128], data, 1); - data += 24; - } - DMX_FREE(odata); - return instr; - } - - void ad_read_instr(bank_instr *instr, byte *data, byte drum, ushort isize) { - if(isize < 12) { - return; - } - instr->percnum = data[0] & 0x7f; - instr->fixed = drum; - instr->op = (isize >= 23) ? b_op4 : b_op2; - data += 1; - instr->channels[0].feedback = instr->channels[1].feedback = (data[5] >> 1) & 0x07; - instr->channels[0].am = data[5] & 0x01; - instr->channels[1].am = (data[5] & 0x80) > 0; - for(int ch = 0; ch < ((isize >= 23) ? 2 : 1); ch++) { - for(int op = 0; op < 2; op++) { - instr->channels[ch].ops[op].tremolo = (data[op*6+0] & 0x80) > 0; - instr->channels[ch].ops[op].vibrato = (data[op*6+0] & 0x40) > 0; - instr->channels[ch].ops[op].sustaining = (data[op*6+0] & 0x20) > 0; - instr->channels[ch].ops[op].ksr = (data[op*6+0] & 0x10) > 0; - instr->channels[ch].ops[op].mult = data[op*6+0] & 0x0f; - instr->channels[ch].ops[op].attack = (data[op*6+2] >> 4) & 0x0f; - instr->channels[ch].ops[op].decay = data[op*6+2] & 0x0f; - instr->channels[ch].ops[op].sustain = (data[op*6+3] >> 4) & 0x0f; - instr->channels[ch].ops[op].release = data[op*6+3] & 0x0f; - instr->channels[ch].ops[op].waveform = data[op*6+4] & 0x07; - instr->channels[ch].ops[op].ksl = (data[op*6+1] >> 6) & 0x03; - instr->channels[ch].ops[op].level = data[op*6+1] & 0x3f; - } - instr->channels[ch].offset = 0; - instr->channels[ch].detune = 0; - data += 11; - } - } - - bank_instr *ad_read_bank(const char *filename) { - byte *data; - bank_instr *instr; - uint size = bnk_read_mbank(&data, &instr, filename, 2, 256*20+2); - if(size == 0) { - return NULL; - } - byte *odata = data; - for(int i = 0; i < 256; i++) { - instr[i].op = b_op0; - instr[i].name[0] = 0; - } - for(int i = 0;; i++, data += 6) { - if((i*6) >= size) { - DMX_LOG("Fehler beim Verarbeiten von Bank-Datei '%s': Ende der Daten erreicht", filename); - DMX_FREE(odata); - DMX_FREE(instr); - return NULL; - } - byte prog = data[0]; - if(prog == 0xff) { - break; - } - if(prog >= 128) { - continue; - } - byte bank = data[1]; - if((bank != 0) && (bank != 127)) { - continue; - } - ushort offs = dmx_read_uint16(data+2); - ushort isize; - if(((offs+2) > size) || ((offs+(isize = dmx_read_uint16(odata+offs))) > size) || (isize < 2)) { - DMX_LOG("Fehler beim Verarbeiten von Bank-Datei '%s': Ende der Daten erreicht", filename); - DMX_FREE(odata); - DMX_FREE(instr); - return NULL; - } - ad_read_instr(&instr[prog + ((bank == 127) ? 128 : 0)], odata+(offs+2), bank == 127, isize-2); - } - DMX_FREE(odata); - return instr; - } - - void bk_read_instr(bank_instr *instr, byte *data, byte drum) { - instr->fixed = drum; - instr->op = b_op2; - for(int op = 0; op < 2; op++) { - instr->channels[0].ops[op].tremolo = data[op*13+9] & 0x01; - instr->channels[0].ops[op].vibrato = data[op*13+10] & 0x01; - instr->channels[0].ops[op].sustaining = data[op*13+5] & 0x01; - instr->channels[0].ops[op].ksr = data[op*13+11] & 0x01; - instr->channels[0].ops[op].mult = data[op*13+1] & 0x0f; - instr->channels[0].ops[op].attack = data[op*13+3] & 0x0f; - instr->channels[0].ops[op].decay = data[op*13+6] & 0x0f; - instr->channels[0].ops[op].sustain = data[op*13+4] & 0x0f; - instr->channels[0].ops[op].release = data[op*13+7] & 0x0f; - instr->channels[0].ops[op].waveform = data[26+op] & 0x07; - instr->channels[0].ops[op].ksl = data[op*13+0] & 0x03; - instr->channels[0].ops[op].level = data[op*13+8] & 0x3f; - } - instr->channels[0].feedback = data[2] & 0x07; - instr->channels[0].am = (data[25] & 0x01) ^ 1; - instr->channels[0].offset = 0; - instr->channels[0].detune = 0; - } - - bank_instr *bk_read_bank(const char *filename, byte drum) { - byte *data; - bank_instr *instr; - uint size = bnk_read_mbank(&data, &instr, filename, 28, 256*42+28); - if(size == 0) { - return NULL; - } - byte *odata = data; - if(memcmp(data+2, "ADLIB-", 6) != 0) { - DMX_LOG("Fehler beim Lesen von Bank-Datei '%s': Fehlerhafter Dateiheader oder falscher Dateityp", filename); - DMX_FREE(odata); - DMX_FREE(instr); - return NULL; - } - data += 8; - for(int i = 0; i < 256; i++) { - instr[i].op = b_op0; - instr[i].name[0] = 0; - } - // ushort nnorm = data[0]; - uint ninst = dmx_read_uint16(&data[2]); - data += 20; - if((ninst*42+28) > size) { - DMX_LOG("Fehler beim Verarbeiten von Bank-Datei '%s': Ende der Daten erreicht", filename); - DMX_FREE(odata); - DMX_FREE(instr); - return NULL; - } - data += ninst*12; - int pos = 0; - for(int i = 0; i < ninst; i++, data += 30) { - if(data[0] != 0) { - continue; - } - bk_read_instr(&instr[pos + (drum ? 128 : 0)], data+2, drum); - byte *ndata = odata+(i*12+28); - instr[pos + (drum ? 128 : 0)].percnum = ndata[2] & 0x7f; - memcpy(instr[pos + (drum ? 128 : 0)].name, ndata+3, 8); - instr[pos + (drum ? 128 : 0)].name[8] = 0; - if(++pos == 128) { - break; - } - } - DMX_FREE(odata); - return instr; - } - - void tim_read_instr(bank_instr *instr, byte *data) { - instr->percnum = 0; - instr->fixed = 0; - instr->op = b_op2; - for(int op = 0; op < 2; op++) { - instr->channels[0].ops[op].tremolo = dmx_read_uint16(&data[op*26+18]) & 0x01; - instr->channels[0].ops[op].vibrato = dmx_read_uint16(&data[op*26+20]) & 0x01; - instr->channels[0].ops[op].sustaining = dmx_read_uint16(&data[op*26+10]) & 0x01; - instr->channels[0].ops[op].ksr = dmx_read_uint16(&data[op*26+22]) & 0x01; - instr->channels[0].ops[op].mult = dmx_read_uint16(&data[op*26+2]) & 0x0f; - instr->channels[0].ops[op].attack = dmx_read_uint16(&data[op*26+6]) & 0x0f; - instr->channels[0].ops[op].decay = dmx_read_uint16(&data[op*26+12]) & 0x0f; - instr->channels[0].ops[op].sustain = dmx_read_uint16(&data[op*26+8]) & 0x0f; - instr->channels[0].ops[op].release = dmx_read_uint16(&data[op*26+14]) & 0x0f; - instr->channels[0].ops[op].waveform = dmx_read_uint16(&data[52+op*2]) & 0x07; - instr->channels[0].ops[op].ksl = dmx_read_uint16(&data[op*26+0]) & 0x03; - instr->channels[0].ops[op].level = dmx_read_uint16(&data[op*26+16]) & 0x3f; - } - instr->channels[0].feedback = dmx_read_uint16(&data[4]) & 0x07; - instr->channels[0].am = (dmx_read_uint16(&data[50]) & 0x01) ^ 1; - instr->channels[0].offset = 0; - instr->channels[0].detune = 0; - } - - bank_instr *tim_read_bank(const char *filename, byte drum) { - byte *data; - bank_instr *instr; - uint size = bnk_read_mbank(&data, &instr, filename, 6, 256*65+6); - if(size == 0) { - return NULL; - } - byte *odata = data; - for(int i = 0; i < 256; i++) { - instr[i].op = b_op0; - instr[i].name[0] = 0; - } - uint ninst = dmx_read_uint16(&data[2]); - data += 6; - if((ninst*65+6) > size) { - DMX_LOG("Fehler beim Verarbeiten von Bank-Datei '%s': Ende der Daten erreicht", filename); - DMX_FREE(odata); - DMX_FREE(instr); - return NULL; - } - data += ninst*9; - for(int i = 0; (i < ninst) && (i < 128); i++, data += 56) { - tim_read_instr(&instr[i + (drum ? 128 : 0)], data); - byte *ndata = odata+(i*9+6); - memcpy(instr[i + (drum ? 128 : 0)].name, ndata, 8); - instr[i + (drum ? 128 : 0)].name[8] = 0; - } - DMX_FREE(odata); - return instr; - } - - // SKB! - // OO-NNNNN NAME[N] FPPPPPPP AFFFAFFF - // DDDDDDDD OOOOOOOO TVSKMMMM KKLLLLLL AAAADDDD SSSSRRRR TVSKMMMM KKLLLLLL AAAADDDD SSSSRRRR -WWW-WWW - - uint skb_read_instr(bank_instr *instr, byte *data, uint pos, uint size) { - if((pos + 1) > size) { - return 0; - } - data += pos; - instr->op = (data[0] >> 6) & 0x03; - byte nlen = data[0] & 0x1f; - if((pos + 1 + nlen) > size) { - return 0; - } - memcpy(instr->name, data+1, nlen); - instr->name[nlen] = 0; - pos += 1 + nlen; - if(instr->op == b_op0) { - return pos; - } - int numch = (instr->op == b_op2) ? 1 : 2; - if((pos + 1 + (12 * numch)) > size) { - return 0; - } - data += 1 + nlen; - instr->fixed = (data[0] & 0x80) > 0; - instr->percnum = data[0] & 0x7f; - instr->channels[0].am = (data[1] & 0x08) > 0; - instr->channels[0].feedback = data[1] & 0x07; - if(numch == 2) { - instr->channels[1].am = (data[1] & 0x80) > 0; - instr->channels[1].feedback = (data[1] >> 4) & 0x07; - } - data += 2; - for(int ch = 0; ch < numch; ch++) { - instr->channels[ch].detune = ((short)data[0]) - 128; - instr->channels[ch].offset = ((short)data[1]) - 128; - data += 2; - for(int op = 0; op < 2; op++) { - instr->channels[ch].ops[op].tremolo = (data[0] & 0x80) > 0; - instr->channels[ch].ops[op].vibrato = (data[0] & 0x40) > 0; - instr->channels[ch].ops[op].sustaining = (data[0] & 0x20) > 0; - instr->channels[ch].ops[op].ksr = (data[0] & 0x10) > 0; - instr->channels[ch].ops[op].mult = data[0] & 0x0f; - instr->channels[ch].ops[op].ksl = (data[1] >> 6) & 0x03; - instr->channels[ch].ops[op].level = data[1] & 0x3f; - instr->channels[ch].ops[op].attack = (data[2] >> 4) & 0x0f; - instr->channels[ch].ops[op].decay = data[2] & 0x0f; - instr->channels[ch].ops[op].sustain = (data[3] >> 4) & 0x0f; - instr->channels[ch].ops[op].release = data[3] & 0x0f; - data += 4; - } - instr->channels[ch].ops[0].waveform = (data[0] >> 4) & 0x07; - instr->channels[ch].ops[1].waveform = data[0] & 0x07; - data += 1; - } - return pos + 2 + (11 * numch); - } - - bank_instr *skb_read_bank(const char *filename) { - byte *data; - bank_instr *instr; - uint size = bnk_read_mhbank(&data, &instr, filename, 256, 256*56, "SKB!", 4); - if(size == 0) { - return NULL; - } - uint pos = 0; - for(int i = 0; i < 256; i++) { - pos = skb_read_instr(&instr[i], data, pos, size); - if(pos == 0) { - DMX_LOG("Fehler beim Verarbeiten von Bank-Datei '%s': Ende der Daten erreicht", filename); - DMX_FREE(data); - DMX_FREE(instr); - return NULL; - } - } - DMX_FREE(data); - return instr; - } - - bank_instr *bnk_read_bank(const char *filename, byte drum) { - int len = 0; - int dp = 0; - char ch; - while(ch = filename[len++]) { - if(ch == '.') { - dp = len; - } - } - if(dp == 0) { - DMX_LOG("Format von Bank-Datei '%s' unbekannt", filename); - return NULL; - } - char ext[len -= dp]; - for(int c = 0; c < len; c++) { - ext[c] = filename[dp+c]; - if((ext[c] >= 'A') && (ext[c] <= 'Z')) { - ext[c] = ext[c] - 'A' + 'a'; - } - } - if(strcmp(ext, "skb") == 0) { - return skb_read_bank(filename); - } - else if((strcmp(ext, "dmx") == 0) || (strcmp(ext, "op2") == 0) || (strcmp(ext, "lmp") == 0)) { - return dmx_read_bank(filename); - } - else if(strcmp(ext, "tmb") == 0) { - return tmb_read_bank(filename); - } - else if(strcmp(ext, "ibk") == 0) { - return ibk_read_bank(filename, drum); - } - else if(strcmp(ext, "sb") == 0) { - return sb_read_bank(filename, drum); - } - else if(strcmp(ext, "o3") == 0) { - return sb3_read_bank(filename, drum); - } - else if(strcmp(ext, "op3") == 0) { - return op3_read_bank(filename); - } - else if((strcmp(ext, "ad") == 0) || (strcmp(ext, "opl") == 0)) { - return ad_read_bank(filename); - } - else if(strcmp(ext, "bnk") == 0) { - return bk_read_bank(filename, drum); - } - else if((strcmp(ext, "tim") == 0) || (strcmp(ext, "snd") == 0)) { - return tim_read_bank(filename, drum); - } - // else if(strcmp(ext, "wopl") == 0) { - // return wopl_read_bank(filename); - // } - DMX_LOG("Format von Bank-Datei '%s' unbekannt", filename); - return NULL; - } - - bank_instr *bnk_read_banks(const char *filename, const char *drumname, byte usedrum) { - bank_instr *ins1 = bnk_read_bank(filename, usedrum); - if((ins1 != NULL) && (drumname != NULL)) { - bank_instr *ins2 = bnk_read_bank(drumname, usedrum ^ 1); - if(ins2 != NULL) { - memcpy(ins1+128, ins2+128, sizeof(bank_instr)*128); - DMX_FREE(ins2); - } - else { - DMX_FREE(ins1); - ins1 = NULL; - } - } - return ins1; - } - - uint skb_write_instr(bank_instr *instr, byte *data, uint pos) { - data += pos; - byte nlen = strlen(instr->name); - data[0] = (instr->op << 6) | nlen; - memcpy(data+1, instr->name, nlen); - pos += 1 + nlen; - if(instr->op == b_op0) { - return pos; - } - int numch = (instr->op == b_op2) ? 1 : 2; - data += 1 + nlen; - data[0] = (instr->fixed << 7) | instr->percnum; - data[1] = ((numch == 2) ? ((instr->channels[1].am << 7) | (instr->channels[1].feedback << 4)) : 0) | (instr->channels[0].am << 3) | instr->channels[0].feedback; - data += 2; - for(int ch = 0; ch < numch; ch++) { - data[0] = (byte)((short)(instr->channels[ch].detune + 128)); - data[1] = (byte)((short)(instr->channels[ch].offset + 128)); - data += 2; - for(int op = 0; op < 2; op++) { - data[0] = (instr->channels[ch].ops[op].tremolo << 7) | (instr->channels[ch].ops[op].vibrato << 6) | (instr->channels[ch].ops[op].sustaining << 5) | - (instr->channels[ch].ops[op].ksr << 4) | instr->channels[ch].ops[op].mult; - data[1] = (instr->channels[ch].ops[op].ksl << 6) | instr->channels[ch].ops[op].level; - data[2] = (instr->channels[ch].ops[op].attack << 4) | instr->channels[ch].ops[op].decay; - data[3] = (instr->channels[ch].ops[op].sustain << 4) | instr->channels[ch].ops[op].release; - data += 4; - } - data[0] = (instr->channels[ch].ops[0].waveform << 4) | instr->channels[ch].ops[1].waveform; - data += 1; - } - return pos + 2 + (11 * numch); - } - - byte skb_write_bank(bank_instr *instr, const char *filename) { - int err; - FILE *fd = fopen(filename, "wb"); - if(fd == NULL) { - err = errno; - DMX_LOG("Fehler beim Öffnen von Bank-Datei '%s': %s (%d)", filename, strerror(err), err); - return 0; - } - if(fwrite("SKB!", 1, 4, fd) != 4) { - DMX_LOG("Fehler beim Schreiben nach Bank-Datei '%s': E/A-Fehler", filename); - fclose(fd); - return 0; - } - byte *data = DMX_MALLOC(256*56); - uint size = 0; - for(int i = 0; i < 256; i++) { - size = skb_write_instr(&instr[i], data, size); - } - if(fwrite(data, 1, size, fd) != size) { - DMX_LOG("Fehler beim Schreiben nach Bank-Datei '%s': E/A-Fehler", filename); - fclose(fd); - DMX_FREE(data); - return 0; - } - fclose(fd); - DMX_FREE(data); - return 1; - } - - // voice bank - - void bank_reset(opl3_chip *chip, bank_handle *bank) { - ushort voices = chip->n_voices; - byte flags = bank->flags; - char velo_func = bank->velo_func; - bank_instr *instr = bank->bdata; - byte *bankdata = (byte*)bank; - bankdata += sizeof(bank_handle); - memset(bank, 0, sizeof(bank_handle)); - bank->voices = (bank_voice*)bankdata; - bank->v_avail = voices; - bank->flags = flags; - bank->velo_func = velo_func; - bank->bdata = instr; - for(int h = 0; h < 16; h++) { - bank_channel *channel = &bank->channel[h]; - channel->bank = bank; - memset(channel->notes, 0xff, 128); - channel->volume = 127; - channel->pbank = (h == 9) ? 128 : 0; - channel->instr = &bank->bdata[(h == 9) ? 128 : 0]; - channel->ch_num = h; - } - for(int h = 0; h < voices; h++) { - bank_voice *voice = &bank->voices[h]; - voice->channel = NULL; - voice->opl = &chip->channel[h]; - voice->note = 0xff; - voice->op = b_op2; - voice->detune = 0; - voice->pair = &bank->voices[h+(((h & 1) == 0) ? 1 : -1)]; - } - } - - bank_handle *bank_alloc(opl3_chip *chip, bank_instr *instr, byte keep, byte useunkn, char velofunc) { - byte *bankdata = malloc(sizeof(bank_handle) + (sizeof(bank_voice) * chip->n_voices)); - bank_handle *bank = (bank_handle*)bankdata; - bank->flags = (keep ? BANK_KEEP : 0) | (useunkn ? BANK_UNKN : 0); - bank->velo_func = velofunc; - bank->bdata = instr; - bank_reset(chip, bank); - return bank; - } - - byte bank_getnote(bank_channel *ch, byte key, byte id, byte drum, bank_instr *instr) { - short note = (short)key; - if(instr->fixed) { - note = ((short)instr->percnum) + instr->channels[id].offset; - } - else { - note += instr->channels[id].offset; - } - note = note < 0 ? 0 : note; - note = note > 127 ? 127 : note; - return (byte)note; - } - - void OPL3_ChannelFreqHz(opl3_channel *channel, uint freq) { - uint block = 0; - while(opl3_maxfreq[block] < freq) { - block++; - if(block == 8) { - break; - } - } - if(block == 8) { - OPL3_ChannelFreq(channel, 7, 1023); - return; - } - double f_num = ((double)freq) / 1000.0 * pow(2.0, (20.0-((double)block))) / 49716.0; - OPL3_ChannelFreq(channel, block, (uint)f_num); - } - - uint bank_getfreq(byte key, short pitch, short detune) { - double pfrq = pow(2.0, ((((double)pitch) / 8191.0 * BANK_PBRANGE) + (((double)detune) / 100.0)) / 12.0); - double freq = ((double)bank_notes[key]) * pfrq; - return (uint)freq; - } - - void OPL3_ChannelNote(opl3_channel *channel, byte key, short pitch, short detune) { - OPL3_ChannelFreqHz(channel, bank_getfreq(key, pitch, detune)); - } - - uint bank_getlevel(char function, byte velocity, byte volume, char pan) { - double lvl = ((function == -128) ? 1.0 : - (function ? BANK_VELOFUNC(((double)velocity)/127.0, function < 0 ? (0.1+(1.0-((((double)(-function))-1.0)/126.0))*9.9) : (1.0+((((double)function)-1.0)/126.0)*9.0)) : - (((double)velocity)/127.0))) * (((double)volume)/127.0) * (1.0-(0.9*((double)pan)/63.0)); - // fprintf(stderr, "%d===%d-->%.2f\n", function, velocity, lvl); - lvl *= 65536.0; - return (uint)lvl; - } - - void OPL3_ChannelLevelPan(opl3_channel *channel, char function, byte velocity, byte volume, char pan) { - OPL3_ChannelOutput(channel, 0, bank_getlevel(function, velocity, volume, pan)); - OPL3_ChannelOutput(channel, 1, bank_getlevel(function, velocity, volume, -pan)); - } - - void bank_release_voice(bank_handle *bank, bank_channel *ch, bank_voice *voice) { - if(voice->note == 0xff) { - return; - } - OPL3_ChannelKeyOff(voice->opl); - voice->note = 0xff; - if(voice->op == b_op22) { - voice->pair->note = 0xff; - OPL3_ChannelKeyOff(voice->pair->opl); - bank->v_used -= 2; - } - else if(voice->op == b_op4) { - voice->pair->note = 0xff; - bank->v_used -= 2; - } - else { - bank->v_used -= 1; - } - } - - bank_voice *bank_release_key(bank_channel *ch, byte note) { - if(ch->active == 0) { - return NULL; - } - if(ch->notes[note] == 0xff) { - return NULL; - } - bank_key *key = &ch->keys[ch->notes[note]]; - ch->notes[note] = 0xff; - ch->active -= 1; - if(key->voice) { - bank_release_voice(ch->bank, ch, key->voice); - } - key->velocity = 0; - return key->voice; - } - - void bank_init_voice(opl3_channel *channel, bank_instr *instr, byte id) { - OPL3_Channel4Op(channel, instr->op == b_op4); - for(int o = 0; o < ((instr->op == b_op4) ? 4 : 2); o++) { - bank_pair *pair = &instr->channels[(instr->op == b_op4) ? (o >> 1) : id]; - bank_operator *op = &pair->ops[o & 1]; - opl3_slot *slot = (o >= 2) ? (channel->pair->slots[o & 1]) : (channel->slots[o & 1]); - OPL3_SlotFlags(slot, op->tremolo, op->vibrato, op->sustaining, op->ksr); - OPL3_SlotMult(slot, op->mult); - OPL3_SlotKSL(slot, op->ksl); - OPL3_SlotLevel(slot, op->level); - OPL3_SlotADSR(slot, op->attack, op->decay, op->sustain, op->release); - OPL3_SlotWaveform(slot, op->waveform); - if((o & 1) == 1) { - opl3_channel *chn = (o >= 2) ? channel->pair : channel; - OPL3_ChannelFeedback(chn, pair->feedback); - OPL3_ChannelAM(chn, pair->am); - } - } - } - - bank_voice *bank_get_voice(bank_handle *bank, bank_channel *ch, byte note, byte velocity) { - bank_instr *instr = ch->instr; - if(ch->pbank == 128) { - instr += note; - } - else if((ch->pbank != 0) && (!(bank->flags & BANK_UNKN))) { - return NULL; - } - if(instr->op == b_op0) { - return NULL; - } - if(bank->v_used == bank->v_avail) { - if(bank->flags & BANK_KEEP) { - return NULL; - } - if((instr->op != b_op2) && ((bank->voiceindex & 1) != 0)) { - bank->voiceindex += 1; - if(bank->voiceindex >= bank->v_avail) { - bank->voiceindex = 0; - } - } - bank_release_key(bank->voices[bank->voiceindex].channel, bank->voices[bank->voiceindex].note); - } - else if((instr->op != b_op2) && ((bank->voiceindex & 1) != 0)) { - bank->voiceindex += 1; - if(bank->voiceindex >= bank->v_avail) { - bank->voiceindex = 0; - } - } - byte vi = bank->voiceindex; - while((bank->voices[bank->voiceindex].note != 0xff) || ((instr->op != b_op2) && (bank->voices[bank->voiceindex+1].note != 0xff))) { - bank->voiceindex += (instr->op != b_op2) ? 2 : 1; - if(bank->voiceindex >= bank->v_avail) { - bank->voiceindex = 0; - } - if(vi == bank->voiceindex) { - if(bank->flags & BANK_KEEP) { - return NULL; - } - bank_release_key(bank->voices[bank->voiceindex].channel, bank->voices[bank->voiceindex].note); - if((instr->op != b_op2) && (bank->voices[bank->voiceindex+1].note != 0xff)) { - bank_release_key(bank->voices[bank->voiceindex+1].channel, bank->voices[bank->voiceindex+1].note); - } - break; - } - } - bank_voice *voice = &bank->voices[bank->voiceindex]; - if((instr->op == b_op2) && (voice->op == b_op4)) { - short offset = ((short)bank->voiceindex) + (((bank->voiceindex & 1) == 0) ? 1 : -1); - bank_voice *voice2 = &bank->voices[offset]; - if(voice2->note == 0xff) { - OPL3_ChannelOutput(voice2->opl, 0, 0); - OPL3_ChannelOutput(voice2->opl, 1, 0); - } - } - bank->voiceindex += (instr->op != b_op2) ? 2 : 1; - if(bank->voiceindex >= bank->v_avail) { - bank->voiceindex = 0; - } - voice->channel = ch; - voice->note = note; - voice->op = instr->op; - voice->detune = instr->channels[0].detune; - bank_init_voice(voice->opl, instr, 0); - if(voice->op == b_op22) { - voice->pair->channel = ch; - voice->pair->note = note; - voice->pair->op = b_op22; - voice->pair->detune = instr->channels[1].detune; - bank_init_voice(voice->pair->opl, instr, 1); - OPL3_ChannelNote(voice->opl, bank_getnote(ch, note, 0, ch->pbank == 128, instr), ch->pitch, voice->detune); - OPL3_ChannelNote(voice->pair->opl, bank_getnote(ch, note, 1, ch->pbank == 128, instr), ch->pitch, voice->pair->detune); - OPL3_ChannelLevelPan(voice->opl, bank->velo_func, velocity, ch->volume, ch->pan); - OPL3_ChannelLevelPan(voice->pair->opl, bank->velo_func, velocity, ch->volume, ch->pan); - OPL3_ChannelKeyOn(voice->opl); - OPL3_ChannelKeyOn(voice->pair->opl); - bank->v_used += 2; - } - else if(voice->op == b_op4) { - voice->pair->channel = ch; - voice->pair->note = note; - voice->pair->op = b_op4; - OPL3_ChannelNote(voice->opl, bank_getnote(ch, note, 0, ch->pbank == 128, instr), ch->pitch, voice->detune); - OPL3_ChannelLevelPan(voice->opl, bank->velo_func, velocity, ch->volume, ch->pan); - OPL3_ChannelKeyOn(voice->opl); - bank->v_used += 2; - } - else { - OPL3_ChannelNote(voice->opl, bank_getnote(ch, note, 0, ch->pbank == 128, instr), ch->pitch, voice->detune); - OPL3_ChannelLevelPan(voice->opl, bank->velo_func, velocity, ch->volume, ch->pan); - OPL3_ChannelKeyOn(voice->opl); - bank->v_used += 1; - } - return voice; - } - - bank_voice *bank_press_key(bank_channel *ch, byte note, byte velocity) { - if(ch->notes[note] != 0xff) { - bank_release_key(ch, note); - } - if(ch->active == BANK_MAX) { - return NULL; - } - byte ki = ch->keyindex; - while(ch->keys[ch->keyindex].velocity != 0) { - ch->keyindex += 1; - if(ch->keyindex == BANK_MAX) { - ch->keyindex = 0; - } - if(ki == ch->keyindex) { - return NULL; - } - } - bank_voice *voice = bank_get_voice(ch->bank, ch, note, velocity); - ch->notes[note] = ch->keyindex; - ch->active += 1; - bank_key *key = &ch->keys[ch->keyindex]; - key->note = note; - key->velocity = velocity; - key->voice = voice; - return voice; - } - - void bank_notesoff(bank_channel *ch) { - for(int h = 0; (h < BANK_MAX) && (ch->active > 0); h++) { - bank_release_key(ch, h); - } - } - - void bank_progupdate(bank_channel *ch, opl3_chip *chip) { - bank_notesoff(ch); - ushort id = ch->program; - if(ch->pbank == 128) { - id = 128; - } - else if((ch->pbank != 0) && (!(ch->bank->flags & BANK_UNKN))) { - id = 0; - } - ch->instr = (ch->bank->bdata)+id; - } - - void bank_levelupdate(bank_channel *ch, opl3_chip *chip) { - byte done = 0; - for(int h = 0; (h < BANK_MAX) && (done < ch->active); h++) { - bank_key *key = (ch->keys)+h; - if((key->velocity == 0) || (key->voice == NULL)) { - continue; - } - OPL3_ChannelLevelPan(key->voice->opl, ch->bank->velo_func, key->velocity, ch->volume, ch->pan); - if(key->voice->op == b_op22) { - OPL3_ChannelLevelPan(key->voice->pair->opl, ch->bank->velo_func, key->velocity, ch->volume, ch->pan); - } - done++; - } - } - - void bank_frequpdate(bank_channel *ch, opl3_chip *chip) { - byte done = 0; - for(int h = 0; (h < BANK_MAX) && (done < ch->active); h++) { - bank_key *key = (ch->keys)+h; - if((key->velocity == 0) || (key->voice == NULL)) { - continue; - } - OPL3_ChannelNote(key->voice->opl, bank_getnote(ch, key->note, 0, ch->pbank == 128, ch->instr), ch->pitch, key->voice->detune); - if(key->voice->op == b_op22) { - OPL3_ChannelNote(key->voice->pair->opl, bank_getnote(ch, key->note, 1, ch->pbank == 128, ch->instr), ch->pitch, key->voice->pair->detune); - } - done++; - } - } - - void bank_noteon(bank_handle *bank, opl3_chip *chip, byte channel, byte key, byte velocity) { - bank_channel *ch = &bank->channel[channel]; - // if((ch->pbank == 128) && ((key < 35) || (key > 81))) { - // return; - // } - bank_press_key(ch, key, velocity); - } - - void bank_noteoff(bank_handle *bank, opl3_chip *chip, byte channel, byte key, byte velocity) { - bank_channel *ch = &bank->channel[channel]; - // if((ch->pbank == 128) && ((key < 35) || (key > 81))) { - // return; - // } - bank_release_key(ch, key); - } - - void bank_progchange(bank_handle *bank, opl3_chip *chip, byte channel, byte program) { - bank_channel *ch = &bank->channel[channel]; - ch->program = program; - bank_progupdate(ch, chip); - } - - void bank_pitchbend(bank_handle *bank, opl3_chip *chip, byte channel, short pitch) { - bank_channel *ch = &bank->channel[channel]; - ch->pitch = pitch; - bank_frequpdate(ch, chip); - } - - void bank_control(bank_handle *bank, opl3_chip *chip, byte channel, byte control, byte value) { - bank_channel *ch = &bank->channel[channel]; - switch(control) { - case 0x00: // bank MSB - // if((channel == 9) && (value == 0)) { - // ch->pbank = 128; - // } - // else { - if(channel != 9) { - ch->pbank &= 0x007f; - ch->pbank |= (((ushort)value) << 7) & 0x3f80; - } - bank_progupdate(ch, chip); - break; - case 0x20: // bank LSB - // if((channel == 9) && (value == 0)) { - // ch->pbank = 128; - // } - // else { - if(channel != 9) { - ch->pbank &= 0x3f80; - ch->pbank |= ((ushort)value) & 0x007f; - } - bank_progupdate(ch, chip); - break; - case 0x07: // volume MSB - ch->volume = value; - bank_levelupdate(ch, chip); - break; - case 0x0a: // pan MSB - ch->pan = ((char)value) - 64; - bank_levelupdate(ch, chip); - break; - case 0x79: // reset - ch->pbank = (channel == 9) ? 128 : 0; - ch->volume = 127; - ch->pan = 0; - bank_progupdate(ch, chip); - bank_levelupdate(ch, chip); - break; - case 0x7b: // all off - bank_notesoff(ch); - break; - } - } - - void bank_alloff(bank_handle *bank) { - for(int h = 0; h < 16; h++) { - bank_notesoff(&bank->channel[h]); - } - } - - // midi logic - - void snd_logd(const char *fmt, ...); - void snd_loge(const char *fmt, ...); - // void snd_logx(const char *fmt, ...); - - void mid_dlog(const char *format, ...) { - if(sgt.log_debug) - snd_logd(format); - } - - void mid_settempo(mid_handle *mid, uint tempo) { - mid->uspb = tempo; - mid->ticktime = mid->uspb / mid->tpqn; - } - - uint mid_read_uint32(byte *data) { - uint value = 0; - for(int h = 0; h < 4; h++) { - value |= ((uint)data[h]); - value <<= h < 3 ? 8 : 0; - } - return value; - } - - ushort mid_read_uint16(byte *data) { - ushort value = 0; - for(int h = 0; h < 2; h++) { - value |= ((ushort)data[h]); - value <<= h < 1 ? 8 : 0; - } - return value; - } - - uint midt_read_uint32(mid_track *trk) { - uint value = 0; - for(int h = 0; h < 4; h++) { - if(trk->pos >= trk->size) { - break; - } - value |= ((uint)trk->buffer[trk->pos++]); - value <<= h < 3 ? 8 : 0; - } - return value; - } - - uint midt_read_uint24(mid_track *trk) { - uint value = 0; - for(int h = 0; h < 3; h++) { - if(trk->pos >= trk->size) { - break; - } - value |= ((uint)trk->buffer[trk->pos++]); - value <<= h < 2 ? 8 : 0; - } - return value; - } - - ushort midt_read_uint16(mid_track *trk) { - ushort value = 0; - for(int h = 0; h < 2; h++) { - if(trk->pos >= trk->size) { - break; - } - value |= ((ushort)trk->buffer[trk->pos++]); - value <<= h < 1 ? 8 : 0; - } - return value; - } - - byte midt_read_uint8(mid_track *trk) { - byte value = 0; - if(trk->pos < trk->size) { - value = trk->buffer[trk->pos++]; - } - return value; - } - - void midt_read_var(mid_track *trk, uint len, byte *chars) { - memset(chars, 0, len); - for(int h = 0; h < len; h++) { - if(trk->pos >= trk->size) { - break; - } - chars[h] = trk->buffer[trk->pos++]; - } - } - - uint mid_read_vlen(mid_track *trk) - { - uint value; - byte bt; - - if(trk->pos >= trk->size) { - return 0; - } - if((value = trk->buffer[trk->pos++]) & 0x80) - { - value &= 0x7f; - do { - if(trk->pos >= trk->size) { - break; - } - value = (value << 7) + ((bt = trk->buffer[trk->pos++]) & 0x7f); - } - while(bt & 0x80); - } - return value; - } - - uint mid_read(mid_handle *mid, const char *filename) { - int err; - FILE *fd = fopen(filename, "rb"); - if(fd == NULL) { - err = errno; - loge(LOG_IO, "Fehler beim Öffnen von MIDI-Datei '%s': %s (%d)", filename, strerror(err), err); - return 0; - } - if(fseek(fd, 0L, SEEK_END)) { - err = errno; - loge(LOG_IO, "Fehler beim Lesen von MIDI-Datei '%s': %s (%d)", filename, strerror(err), err); - fclose(fd); - return 0; - } - long size = ftell(fd); - if(size < 0L) { - err = errno; - loge(LOG_IO, "Fehler beim Lesen von MIDI-Datei '%s': %s (%d)", filename, strerror(err), err); - fclose(fd); - return 0; - } - if(fseek(fd, 0L, SEEK_SET)) { - err = errno; - loge(LOG_IO, "Fehler beim Lesen von MIDI-Datei '%s': %s (%d)", filename, strerror(err), err); - fclose(fd); - return 0; - } - - if(size < 14) { - loge(LOG_IO, "Fehler beim Lesen von MIDI-Datei '%s': Datei zu klein", filename); - fclose(fd); - return 0; - } - byte header[14]; - if(fread(header, 1, 14, fd) != 14) { - err = feof(fd); - loge(LOG_IO, err == 0 ? "Fehler beim Lesen von MIDI-Datei '%s': E/A-Fehler" : "Fehler beim Lesen von MIDI-Datei '%s': Ende der Datei erreicht", filename); - fclose(fd); - return 0; - } - if(memcmp(header, mid_hdr, 4) != 0) { - loge(LOG_IO, "Fehler beim Lesen von MIDI-Datei '%s': Fehlerhafter Dateiheader oder falscher Dateityp", filename); - fclose(fd); - return 0; - } - if(mid_read_uint32(header+4) != 6) { - loge(LOG_IO, "Fehler beim Lesen von MIDI-Datei '%s': Dateiheader mit falscher Länge", filename); - fclose(fd); - return 0; - } - byte mtrack; - ushort type = mid_read_uint16(header+8); - if(type == 0) { - mtrack = 0; - } - else if((type == 1) || (type == 2)) { - mtrack = 1; - } - else { - loge(LOG_IO, "Fehler beim Lesen von MIDI-Datei '%s': Fehlerhaftes Spurformat", filename); - fclose(fd); - return 0; - } - mid->tracks = mid_read_uint16(header+10); - if(mid->tracks == 0) { - loge(LOG_IO, "Fehler beim Lesen von MIDI-Datei '%s': Keine Spuren definiert", filename); - fclose(fd); - return 0; - } - else if((mtrack ^ 1) && (mid->tracks > 1)) { - loge(LOG_IO, "Fehler beim Lesen von MIDI-Datei '%s': Einzelspur-Format mit mehreren Spuren", filename); - fclose(fd); - return 0; - } - mid->tpqn = mid_read_uint16(header+12); - if((mid->tpqn & 0x8000) > 0) { - loge(LOG_IO, "Fehler beim Lesen von MIDI-Datei '%s': SMPTE-Zeitformat nicht unterstützt", filename); - fclose(fd); - return 0; - } - if(mid->tpqn == 0) { - loge(LOG_IO, "Fehler beim Lesen von MIDI-Datei '%s': Zeitformat teilt durch null", filename); - fclose(fd); - return 0; - } - uint esize = 0; - for(ushort trk = 0; trk < mid->tracks; trk++) { - if(fread(header, 1, 8, fd) != 8) { - err = feof(fd); - loge(LOG_IO, err == 0 ? "Fehler beim Lesen von MIDI-Datei '%s': E/A-Fehler" : "Fehler beim Lesen von MIDI-Datei '%s': Ende der Datei erreicht", filename); - fclose(fd); - return 0; - } - if(memcmp(header, mid_trk, 4) != 0) { - loge(LOG_IO, "Fehler beim Lesen von MIDI-Datei '%s': Fehlerhafter Spurheader", filename); - fclose(fd); - return 0; - } - uint trks = mid_read_uint32(header+4); - if((14 + esize + 8 + trks) > size) { - loge(LOG_IO, "Fehler beim Lesen von MIDI-Datei '%s': Spur #%d ausserhalb der Datei", filename, trk+1); - fclose(fd); - return 0; - } - if(fseek(fd, trks, SEEK_CUR)) { - err = errno; - loge(LOG_IO, "Fehler beim Lesen von MIDI-Datei '%s': %s (%d)", filename, strerror(err), err); - fclose(fd); - return 0; - } - esize += trks + 8; - } - if(fseek(fd, 14L, SEEK_SET)) { - err = errno; - loge(LOG_IO, "Fehler beim Lesen von MIDI-Datei '%s': %s (%d)", filename, strerror(err), err); - fclose(fd); - return 0; - } - esize -= (mid->tracks * 8); - byte *buf = mem_alloc((sizeof(mid_track) * mid->tracks) + esize, MEM_FILE); - mid->track = (mid_track*)buf; - buf += (sizeof(mid_track) * mid->tracks); - for(ushort trk = 0; trk < mid->tracks; trk++) { - memset((mid->track)+trk, 0, sizeof(mid_track)); - if(fread(header, 1, 8, fd) != 8) { - err = feof(fd); - loge(LOG_IO, err == 0 ? "Fehler beim Lesen von MIDI-Datei '%s': E/A-Fehler" : "Fehler beim Lesen von MIDI-Datei '%s': Ende der Datei erreicht", filename); - fclose(fd); - mem_free(mid->track); - return 0; - } - mid->track[trk].size = mid_read_uint32(header+4); - if(fread(buf, 1, mid->track[trk].size, fd) != mid->track[trk].size) { - err = feof(fd); - loge(LOG_IO, err == 0 ? "Fehler beim Lesen von MIDI-Datei '%s': E/A-Fehler" : "Fehler beim Lesen von MIDI-Datei '%s': Ende der Datei erreicht", filename); - fclose(fd); - mem_free(mid->track); - return 0; - } - mid->track[trk].buffer = buf; - mid->track[trk].pos = 0; - mid->track[trk].wait = 0; - mid->track[trk].trknum = trk; - buf += mid->track[trk].size; - } - fclose(fd); - mid_settempo(mid, MID_DEFTEMPO); - return (sizeof(mid_track) * mid->tracks) + esize; - } - - void mid_process_meta(mid_handle *mid, mid_track *trk) { - byte meta = midt_read_uint8(trk); - uint size = mid_read_vlen(trk); - switch(meta) { - case midmt_seqnum: - if(size == 0) { - mid_dlog("MIDI Spur #%d Sequenz-Nummer = %d (eigene)", trk->trknum, trk->trknum); - return; - } - else if(size != 2) { - trk->pos += size; - snd_loge("MIDI Spur #%d Meta-Event 0x%02x - erwartet %d, hat %d", trk->trknum, meta, 2, size); - return; - } - mid_dlog("MIDI Spur #%d Sequenz-Nummer = %d", trk->trknum, midt_read_uint16(trk)); - return; - case midmt_text: - case midmt_copyright: - case midmt_trackname: - case midmt_instrname: - case midmt_lyric: - case midmt_marker: - case midmt_cuepoint: { - byte dt[size+1]; - dt[size] = 0; - midt_read_var(trk, size, dt); - for(int n = 0; n < size; n++) { - if(dt[n] < 0x20) - dt[n] = ' '; - } - mid_dlog("MIDI Spur #%d Text (%d) '%s'", trk->trknum, meta, dt); - return; - } - case midmt_chnprefix: - if(size != 1) { - trk->pos += size; - snd_loge("MIDI Spur #%d Meta-Event 0x%02x - erwartet %d, hat %d", trk->trknum, meta, 1, size); - return; - } - mid_dlog("MIDI Spur #%d Kanal-Praefix = %d", trk->trknum, midt_read_uint8(trk)); - return; - case midmt_endtrack: - trk->pos += size; - trk->ending = 1; - mid_dlog("MIDI Spur #%d Ende erreicht", trk->trknum); - return; - case midmt_tempo: - if(size != 3) { - trk->pos += size; - snd_loge("MIDI Spur #%d Meta-Event 0x%02x - erwartet %d, hat %d", trk->trknum, meta, 3, size); - return; - } - mid_settempo(mid, midt_read_uint24(trk)); - mid_dlog("MIDI Tempo = %d", 60000000 / mid->uspb); - return; - case midmt_smpte: - if(size != 5) { - trk->pos += size; - snd_loge("MIDI Spur #%d Meta-Event 0x%02x - erwartet %d, hat %d", trk->trknum, meta, 5, size); - return; - } - trk->pos += 5; - mid_dlog("MIDI SMPTE-Event (nicht unterstützt)"); - return; - case midmt_timesig: { - if(size != 4) { - trk->pos += size; - snd_loge("MIDI Spur #%d Meta-Event 0x%02x - erwartet %d, hat %d", trk->trknum, meta, 4, size); - return; - } - byte n = midt_read_uint8(trk); - uint d = 1 << ((uint)midt_read_uint8(trk)); - byte c = midt_read_uint8(trk); - byte b = midt_read_uint8(trk); - mid_dlog("MIDI Takt-Signatur = %d/%d - %d CPC - %d 32PQ", n, d, c, b); - return; - } - case midmt_keysig: { - if(size != 2) { - trk->pos += size; - snd_loge("MIDI Spur #%d Meta-Event 0x%02x - erwartet %d, hat %d", trk->trknum, meta, 2, size); - return; - } - int8_t s = midt_read_uint8(trk); - byte m = midt_read_uint8(trk); - mid_dlog("MIDI Noten-Signatur = %d - %s", s, (m == 0) ? "MAJOR" : ((m == 1) ? "MINOR" : "- ? -")); - return; - } - case midmt_seqspec: { - trk->pos += size; - mid_dlog("MIDI Spur #%d Sequenzer-Daten empfangen - %d Bytes", trk->trknum, size); - return; - } - default: - trk->pos += size; - mid_dlog("MIDI Spur #%d Meta-Event 0x%02x (%d)", trk->trknum, meta, size); - return; - } - } - - #ifndef MID_NOEVT - void mid_process(mid_handle *mid, mid_track *trk, bank_handle *bank, opl3_chip *chip) { - #else - void mid_process(mid_handle *mid, mid_track *trk) { - #endif - if(trk->pos >= trk->size) { - return; - } - byte status = trk->buffer[trk->pos++]; - if((status & 0x80) == 0) { - status = trk->status; - trk->pos -= 1; - } - else { - trk->status = status; - } - if((status & 0xf0) != 0xf0) { - byte channel = status & 0x0f; - status &= 0xf0; - switch(status) { - case midev_noteoff: { - byte o_key = midt_read_uint8(trk); - byte o_velocity = midt_read_uint8(trk); - #ifndef MID_NOEVT - bank_noteoff(bank, chip, channel, o_key, o_velocity); - #endif - mid_dlog("MIDI Note-Aus - C%d N%d V%d", channel+1, o_key, o_velocity); - break; - } - case midev_noteon: { - byte key = midt_read_uint8(trk); - byte velocity = midt_read_uint8(trk); - #ifndef MID_NOEVT - if(velocity == 0) { - bank_noteoff(bank, chip, channel, key, velocity); - } - else { - bank_noteon(bank, chip, channel, key, velocity); - } - #endif - mid_dlog("MIDI Note-An - C%d N%d V%d", channel+1, key, velocity); - break; - } - case midev_aftertouch: { - byte pressure = midt_read_uint8(trk); - mid_dlog("MIDI Aftertouch - C%d P%d", channel+1, pressure); - break; - } - case midev_control: { - byte control = midt_read_uint8(trk); - byte value = midt_read_uint8(trk); - #ifndef MID_NOEVT - bank_control(bank, chip, channel, control, value); - #endif - mid_dlog("MIDI Controller - C%d N%d V%d", channel+1, control, value); - break; - } - case midev_progchg: { - byte program = midt_read_uint8(trk); - #ifndef MID_NOEVT - bank_progchange(bank, chip, channel, program); - #endif - mid_dlog("MIDI Programm - C%d P%d", channel+1, program); - break; - } - case midev_chnpressure: { - byte cpressure = midt_read_uint8(trk); - mid_dlog("MIDI Kanal-Druck - C%d P%d", channel+1, cpressure); - break; - } - case midev_pitchbend: { - ushort pb = ((ushort)midt_read_uint8(trk)) | (((ushort)midt_read_uint8(trk)) << 7); - short pitch = ((short)pb) - 0x2000; - #ifndef MID_NOEVT - bank_pitchbend(bank, chip, channel, pitch); - #endif - mid_dlog("MIDI Pitch-Bend - C%d P%d", channel+1, pitch); - break; - } - } - } - else { - switch(status) { - case midev_sysex: { - uint slen = mid_read_vlen(trk); - trk->pos += slen; - mid_dlog("MIDI Sysex (Normal) mit Länge = %d", slen); - break; - } - case midev_songpos: - mid_dlog("MIDI Song-Position = %d", ((ushort)midt_read_uint8(trk)) | (((ushort)midt_read_uint8(trk)) << 7)); - break; - case midev_songsel: - mid_dlog("MIDI Song-Auswahl = %d", midt_read_uint8(trk)); - break; - case midev_tunereq: - mid_dlog("MIDI Stimmung angefordert, nichts zu tun?!"); - break; - case midev_endsysex: { - uint elen = mid_read_vlen(trk); - trk->pos += elen; - mid_dlog("MIDI Sysex (Escape) mit Länge = %d", elen); - break; - } - case midev_clock: - case midev_start: - case midev_continue: - case midev_stop: - case midev_actsense: - mid_dlog("MIDI Status %d", status); - break; - case midev_meta: - mid_process_meta(mid, trk); - break; - default: - snd_loge("MIDI Status unbekannt: 0x%02x", status); - break; - } - } - } - - #ifndef MID_NOEVT - byte mid_tick(mid_handle *mid, bank_handle *bank, opl3_chip *chip) { - #else - byte mid_tick(mid_handle *mid) { - #endif - byte end = 1; - for(int trk = 0; trk < mid->tracks; trk++) { - mid_track *track = (mid->track)+trk; - if(track->ending) { - continue; - } - if(track->wait > 0) { - track->wait -= 1; - if(track->wait > 0) { - end = 0; - continue; - } - } - while(1) { - if(track->pos > 0) { - #ifndef MID_NOEVT - mid_process(mid, track, bank, chip); - #else - mid_process(mid, track); - #endif - if((track->ending ^ 1) && (track->pos >= track->size)) { - snd_loge("MIDI Spur #%d endete zu früh", track->trknum); - track->ending = 1; - } - if(track->ending) { - break; - } - } - track->wait = mid_read_vlen(track); - if(track->wait > 0) { - break; - } - } - end &= track->ending; - } - return end ^ 1; - } -*/ -} diff --git a/java/src/game/audio/MovingSoundMinecart.java b/java/src/game/audio/MovingSoundMinecart.java index 5401a4d..fc95eb3 100755 --- a/java/src/game/audio/MovingSoundMinecart.java +++ b/java/src/game/audio/MovingSoundMinecart.java @@ -14,7 +14,6 @@ public class MovingSoundMinecart extends MovingSound super(SoundEvent.CART); this.minecart = minecartIn; this.repeat = true; -// this.repeatDelay = 0; } /** diff --git a/java/src/game/audio/MovingSoundMinecartRiding.java b/java/src/game/audio/MovingSoundMinecartRiding.java index af9da1d..12521b1 100755 --- a/java/src/game/audio/MovingSoundMinecartRiding.java +++ b/java/src/game/audio/MovingSoundMinecartRiding.java @@ -17,7 +17,6 @@ public class MovingSoundMinecartRiding extends MovingSound this.minecart = minecart; this.attenuationType = false; this.repeat = true; -// this.repeatDelay = 0; } /** diff --git a/java/src/game/audio/Sound.java b/java/src/game/audio/Sound.java index 7ac1125..72b5ac9 100755 --- a/java/src/game/audio/Sound.java +++ b/java/src/game/audio/Sound.java @@ -7,7 +7,6 @@ public abstract class Sound protected final SoundEvent event; protected Volume type = Volume.SFX; protected float volume = 1.0F; -// protected float pitch = 1.0F; protected float xPosF; protected float yPosF; protected float zPosF; @@ -34,11 +33,6 @@ public abstract class Sound return this.volume; } -// public float getPitch() -// { -// return this.pitch; -// } - public float getXPosF() { return this.xPosF; diff --git a/java/src/game/audio/SoundManager.java b/java/src/game/audio/SoundManager.java index 9c028c5..198a16f 100755 --- a/java/src/game/audio/SoundManager.java +++ b/java/src/game/audio/SoundManager.java @@ -19,7 +19,6 @@ public class SoundManager { private class Source { private final boolean attModel; private final float distOrRoll; -// private final short[] buffer; private final int source; private float positionX; @@ -34,7 +33,6 @@ public class SoundManager { this.positionZ = z; this.attModel = attModel; this.distOrRoll = distOrRoll; -// this.buffer = buffer; this.volume = volume; this.source = SoundManager.this.getNextChannel(sourcename); updateGain();