1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
|
#ifndef LOAD_EA_H
#define LOAD_EA_H
#include "../progs_cache.h"
#include "../midi_inst_list.h"
bool BankFormats::LoadEA(BanksDump &db, const char *fn, unsigned bank,
const std::string &bankTitle, const char *prefix)
{
FILE *fp = std::fopen(fn, "rb");
if(!fp)
return false;
size_t bankDb = db.initBank(bank, bankTitle, BanksDump::BankEntry::SETUP_CMF);
BanksDump::MidiBank bnkMelodic = db.midiBanks[db.banks[0].melodic[0]];
BanksDump::MidiBank bnkPercussion = db.midiBanks[db.banks[0].percussion[0]];
// Copy all instruments from bank 0
for(unsigned gmno = 0; gmno < 128; ++gmno)
progs[bank][gmno] = progs[0][gmno];
for(unsigned gmno = 35; gmno < 80; ++gmno)
progs[bank][0x80 + gmno] = progs[0][0x80 + gmno];
uint16_t sources[20 + 8];
// Copy also the unused instruments
sources[20] = 0x245;
sources[21] = 0x24F;
sources[22] = 0x263;
sources[23] = 0x277;
sources[24] = 0x281;
sources[25] = 0x28B;
sources[26] = 0x29F;
sources[27] = 0x2A9;
for(unsigned gmno = 0; gmno < 20; ++gmno)
{
std::fseek(fp, 0x150 + gmno, SEEK_SET);
uint8_t bytes[3] = {0};
if(std::fread(bytes, 1, 1, fp) != 1)
{
std::fclose(fp);
return false;
}
long insno = (long)bytes[0];
std::fseek(fp, 0x187 + insno * 2, SEEK_SET);
if(std::fread(bytes, 1, 2, fp) != 2)
{
std::fclose(fp);
return false;
}
uint16_t offset = (uint16_t)bytes[0];
offset += bytes[1] * 256;
sources[gmno] = offset;
}
for(unsigned gmno = 0; gmno < 20 + 8; ++gmno)
{
unsigned int offset = sources[gmno];
std::fseek(fp, (long)offset, SEEK_SET);
uint8_t bytes[10];
if(std::fread(bytes, 1, 10, fp) != 10)
{
std::fclose(fp);
return false;
}
BanksDump::InstrumentEntry inst;
BanksDump::Operator ops[5];
insdata tmp;
tmp.data[0] = bytes[0]; // reg 0x20: modulator AM/VIG/EG/KSR
tmp.data[8] = bytes[1]; // reg 0x40: modulator ksl/attenuation
tmp.data[2] = bytes[2]; // reg 0x60: modulator attack/decay
tmp.data[4] = bytes[3]; // reg 0x80: modulator sustain/release
tmp.data[1] = bytes[4]; // reg 0x20: carrier AM/VIG/EG/KSR
tmp.data[9] = bytes[5]; // reg 0x40: carrier ksl/attenuation
tmp.data[3] = bytes[6]; // reg 0x60: carrier attack/decay
tmp.data[5] = bytes[7]; // reg 0x80: carrier sustain/release
// bytes[1] will be written directly to register 0x40
// bytes[5] will be written directly to register 0x43
// When touching volume, register 0x43 <- bytes[5] - midivolume/4
tmp.data[10] = bytes[8]; // reg 0xC0 (feedback and connection)
tmp.finetune = int8_t(bytes[9] + 12); // finetune
tmp.data[6] = 0; // reg 0xE0: modulator, never seems to be set
tmp.data[7] = 0; // reg 0xE0: carrier, never seems to be set
ins tmp2;
tmp2.notenum = 0;
tmp2.pseudo4op = false;
tmp2.real4op = false;
tmp2.rhythmModeDrum = 0;
db.toOps(tmp, ops, 0);
inst.setFbConn(bytes[8]);
inst.noteOffset1 = int8_t(bytes[9] + 12);
std::string name;
char name2[512];
if(gmno < 20)
{
snprintf(name2, 512, "%sM%u", prefix, gmno);
}
else
{
snprintf(name2, 512, "%sunk%04X", prefix, offset);
}
size_t resno = InsertIns(tmp, tmp2, std::string(1, '\377') + name, name2);
SetBank(bank, gmno, resno);
db.addInstrument(bnkMelodic, gmno, inst, ops);
if(gmno == 10)
{
/*tmp.finetune=0;*/ tmp2.notenum = 0x49;
SetBank(bank, 0x80 + 0x36, InsertIns(tmp, tmp2, std::string(1, '\377') + MidiInsName[0x80 + 0x36 - 35], std::string(1, '\377') + prefix + "P54"));
inst.percussionKeyNumber = 0x49;
db.addInstrument(bnkPercussion, 0x36, inst, ops);
}
if(gmno == 18)
{
/*tmp.finetune=0;*/ tmp2.notenum = 0x17;
SetBank(bank, 0x80 + 0x2A, InsertIns(tmp, tmp2, std::string(1, '\377') + MidiInsName[0x80 + 0x2A - 35], std::string(1, '\377') + prefix + "P42"));
inst.percussionKeyNumber = 0x17;
db.addInstrument(bnkPercussion, 0x2A, inst, ops);
}
if(gmno == 16)
{
/*tmp.finetune=0;*/ tmp2.notenum = 0x0C;
SetBank(bank, 0x80 + 0x24, InsertIns(tmp, tmp2, std::string(1, '\377') + MidiInsName[0x80 + 0x24 - 35], std::string(1, '\377') + prefix + "P36"));
inst.percussionKeyNumber = 0x0C;
db.addInstrument(bnkPercussion, 0x24, inst, ops);
}
if(gmno == 17)
{
/*tmp.finetune=0;*/ tmp2.notenum = 0x01;
SetBank(bank, 0x80 + 0x26, InsertIns(tmp, tmp2, std::string(1, '\377') + MidiInsName[0x80 + 0x26 - 35], std::string(1, '\377') + prefix + "P38"));
inst.percussionKeyNumber = 0x01;
db.addInstrument(bnkPercussion, 0x26, inst, ops);
}
}
std::fclose(fp);
AdlBankSetup setup;
setup.volumeModel = VOLUME_CMF;
setup.deepTremolo = false;
setup.deepVibrato = false;
setup.scaleModulators = false;
SetBankSetup(bank, setup);
db.addMidiBank(bankDb, false, bnkMelodic);
db.addMidiBank(bankDb, true, bnkPercussion);
return true;
}
#endif // LOAD_EA_H
|