1 //=========================================================
2 // MusE
3 // Linux Music Editor
4 // $Id: drummap.cpp,v 1.3.2.6 2009/10/29 02:14:37 terminator356 Exp $
5 //
6 // (C) Copyright 1999/2000 Werner Schweer (ws@seh.de)
7 // (C) Copyright 2016 Tim E. Real (terminator356 on users dot sourceforge dot net)
8 //
9 // This program is free software; you can redistribute it and/or
10 // modify it under the terms of the GNU General Public License
11 // as published by the Free Software Foundation; version 2 of
12 // the License, or (at your option) any later version.
13 //
14 // This program is distributed in the hope that it will be useful,
15 // but WITHOUT ANY WARRANTY; without even the implied warranty of
16 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 // GNU General Public License for more details.
18 //
19 // You should have received a copy of the GNU General Public License
20 // along with this program; if not, write to the Free Software
21 // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
22 //
23 //=========================================================
24
25 #include "audio.h"
26 #include "drummap.h"
27 #include "xml.h"
28 #include "song.h"
29
30 #include "helper.h"
31
32 #include <QSet>
33
34 namespace MusEGlobal {
35 char drumOutmap[DRUM_MAPSIZE];
36 char drumInmap[128];
37 MusECore::DrumMap drumMap[DRUM_MAPSIZE];
38 }
39
40 namespace MusECore {
41
42 //---------------------------------------------------------
43 // GM default drum map
44 //---------------------------------------------------------
45
46 // Default to track port if -1 and track channel if -1. (These used to say 9, 0 for chan, port).
47 const DrumMap blankdm = { QString(""), 100, 16, 32, -1, -1, 70, 90, 110, 127, 127, 127, false, false };
48
49 // this map should have 128 entries, as it's used for initialising iNewDrumMap as well.
50 // iNewDrumMap only has 128 entries. also, the every "out-note" ("anote") should be
51 // represented exactly once in idrumMap, and there shall be no duplicate or unused
52 // "out-notes".
53 // reason: iNewDrumMap is inited as follows: iterate through the full idrumMap[],
54 // iNewDrumMap[ idrumMap[i].anote ] = idrumMap[i]
55 // if you ever want to change this, you will need to fix the initNewDrumMap() function.
56 const DrumMap idrumMap[DRUM_MAPSIZE] = {
57 { QString("Acoustic Bass Drum"), 100, 16, 32, -1, -1, 70, 90, 110, 127, 35, 35, false, false },
58 { QString("Bass Drum 1"), 100, 16, 32, -1, -1, 70, 90, 110, 127, 36, 36, false, false },
59 { QString("Side Stick"), 100, 16, 32, -1, -1, 70, 90, 110, 127, 37, 37, false, false },
60 { QString("Acoustic Snare"), 100, 16, 32, -1, -1, 70, 90, 110, 127, 38, 38, false, false },
61 { QString("Hand Clap"), 100, 16, 32, -1, -1, 70, 90, 110, 127, 39, 39, false, false },
62 { QString("Electric Snare"), 100, 16, 32, -1, -1, 70, 90, 110, 127, 40, 40, false, false },
63 { QString("Low Floor Tom"), 100, 16, 32, -1, -1, 70, 90, 110, 127, 41, 41, false, false },
64 { QString("Closed Hi-Hat"), 100, 16, 32, -1, -1, 70, 90, 110, 127, 42, 42, false, false },
65 { QString("High Floor Tom"), 100, 16, 32, -1, -1, 70, 90, 110, 127, 43, 43, false, false },
66 { QString("Pedal Hi-Hat"), 100, 16, 32, -1, -1, 70, 90, 110, 127, 44, 44, false, false },
67 { QString("Low Tom"), 100, 16, 32, -1, -1, 70, 90, 110, 127, 45, 45, false, false },
68 { QString("Open Hi-Hat"), 100, 16, 32, -1, -1, 70, 90, 110, 127, 46, 46, false, false },
69 { QString("Low-Mid Tom"), 100, 16, 32, -1, -1, 70, 90, 110, 127, 47, 47, false, false },
70 { QString("Hi-Mid Tom"), 100, 16, 32, -1, -1, 70, 90, 110, 127, 48, 48, false, false },
71 { QString("Crash Cymbal 1"), 100, 16, 32, -1, -1, 70, 90, 110, 127, 49, 49, false, false },
72 { QString("High Tom"), 100, 16, 32, -1, -1, 70, 90, 110, 127, 50, 50, false, false },
73
74 { QString("Ride Cymbal 1"), 100, 16, 32, -1, -1, 70, 90, 110, 127, 51, 51, false, false },
75 { QString("Chinese Cymbal"), 100, 16, 32, -1, -1, 70, 90, 110, 127, 52, 52, false, false },
76 { QString("Ride Bell"), 100, 16, 32, -1, -1, 70, 90, 110, 127, 53, 53, false, false },
77 { QString("Tambourine"), 100, 16, 32, -1, -1, 70, 90, 110, 127, 54, 54, false, false },
78 { QString("Splash Cymbal"), 100, 16, 32, -1, -1, 70, 90, 110, 127, 55, 55, false, false },
79 { QString("Cowbell"), 100, 16, 32, -1, -1, 70, 90, 110, 127, 56, 56, false, false },
80 { QString("Crash Cymbal 2"), 100, 16, 32, -1, -1, 70, 90, 110, 127, 57, 57, false, false },
81 { QString("Vibraslap"), 100, 16, 32, -1, -1, 70, 90, 110, 127, 58, 58, false, false },
82 { QString("Ride Cymbal 2"), 100, 16, 32, -1, -1, 70, 90, 110, 127, 59, 59, false, false },
83 { QString("Hi Bongo"), 100, 16, 32, -1, -1, 70, 90, 110, 127, 60, 60, false, false },
84 { QString("Low Bongo"), 100, 16, 32, -1, -1, 70, 90, 110, 127, 61, 61, false, false },
85 { QString("Mute Hi Conga"), 100, 16, 32, -1, -1, 70, 90, 110, 127, 62, 62, false, false },
86 { QString("Open Hi Conga"), 100, 16, 32, -1, -1, 70, 90, 110, 127, 63, 63, false, false },
87 { QString("Low Conga"), 100, 16, 32, -1, -1, 70, 90, 110, 127, 64, 64, false, false },
88 { QString("High Timbale"), 100, 16, 32, -1, -1, 70, 90, 110, 127, 65, 65, false, false },
89 { QString("Low Timbale"), 100, 16, 32, -1, -1, 70, 90, 110, 127, 66, 66, false, false },
90
91 { QString("High Agogo"), 100, 16, 32, -1, -1, 70, 90, 110, 127, 67, 67, false, false },
92 { QString("Low Agogo"), 100, 16, 32, -1, -1, 70, 90, 110, 127, 68, 68, false, false },
93 { QString("Cabasa"), 100, 16, 32, -1, -1, 70, 90, 110, 127, 69, 69, false, false },
94 { QString("Maracas"), 100, 16, 32, -1, -1, 70, 90, 110, 127, 70, 70, false, false },
95 { QString("Short Whistle"), 100, 16, 32, -1, -1, 70, 90, 110, 127, 71, 71, false, false },
96 { QString("Long Whistle"), 100, 16, 32, -1, -1, 70, 90, 110, 127, 72, 72, false, false },
97 { QString("Short Guiro"), 100, 16, 32, -1, -1, 70, 90, 110, 127, 73, 73, false, false },
98 { QString("Long Guiro"), 100, 16, 32, -1, -1, 70, 90, 110, 127, 74, 74, false, false },
99 { QString("Claves"), 100, 16, 32, -1, -1, 70, 90, 110, 127, 75, 75, false, false },
100 { QString("Hi Wood Block"), 100, 16, 32, -1, -1, 70, 90, 110, 127, 76, 76, false, false },
101 { QString("Low Wood Block"), 100, 16, 32, -1, -1, 70, 90, 110, 127, 77, 77, false, false },
102 { QString("Mute Cuica"), 100, 16, 32, -1, -1, 70, 90, 110, 127, 78, 78, false, false },
103 { QString("Open Cuica"), 100, 16, 32, -1, -1, 70, 90, 110, 127, 79, 79, false, false },
104 { QString("Mute Triangle"), 100, 16, 32, -1, -1, 70, 90, 110, 127, 80, 80, false, false },
105 { QString("Open Triangle"), 100, 16, 32, -1, -1, 70, 90, 110, 127, 81, 81, false, false },
106 { QString(""), 100, 16, 32, -1, -1, 70, 90, 110, 127, 82, 82, false, false },
107
108 { QString(""), 100, 16, 32, -1, -1, 70, 90, 110, 127, 83, 83, false, false },
109 { QString(""), 100, 16, 32, -1, -1, 70, 90, 110, 127, 84, 84, false, false },
110 { QString(""), 100, 16, 32, -1, -1, 70, 90, 110, 127, 85, 85, false, false },
111 { QString(""), 100, 16, 32, -1, -1, 70, 90, 110, 127, 86, 86, false, false },
112 { QString(""), 100, 16, 32, -1, -1, 70, 90, 110, 127, 87, 87, false, false },
113 { QString(""), 100, 16, 32, -1, -1, 70, 90, 110, 127, 88, 88, false, false },
114 { QString(""), 100, 16, 32, -1, -1, 70, 90, 110, 127, 89, 89, false, false },
115 { QString(""), 100, 16, 32, -1, -1, 70, 90, 110, 127, 90, 90, false, false },
116 { QString(""), 100, 16, 32, -1, -1, 70, 90, 110, 127, 91, 91, false, false },
117 { QString(""), 100, 16, 32, -1, -1, 70, 90, 110, 127, 92, 92, false, false },
118 { QString(""), 100, 16, 32, -1, -1, 70, 90, 110, 127, 93, 93, false, false },
119 { QString(""), 100, 16, 32, -1, -1, 70, 90, 110, 127, 94, 94, false, false },
120 { QString(""), 100, 16, 32, -1, -1, 70, 90, 110, 127, 95, 95, false, false },
121 { QString(""), 100, 16, 32, -1, -1, 70, 90, 110, 127, 96, 96, false, false },
122 { QString(""), 100, 16, 32, -1, -1, 70, 90, 110, 127, 97, 97, false, false },
123 { QString(""), 100, 16, 32, -1, -1, 70, 90, 110, 127, 98, 98, false, false },
124
125 { QString(""), 100, 16, 32, -1, -1, 70, 90, 110, 127, 99, 99, false, false },
126 { QString(""), 100, 16, 32, -1, -1, 70, 90, 110, 127, 100, 100, false, false },
127 { QString(""), 100, 16, 32, -1, -1, 70, 90, 110, 127, 101, 101, false, false },
128 { QString(""), 100, 16, 32, -1, -1, 70, 90, 110, 127, 102, 102, false, false },
129 { QString(""), 100, 16, 32, -1, -1, 70, 90, 110, 127, 103, 103, false, false },
130 { QString(""), 100, 16, 32, -1, -1, 70, 90, 110, 127, 104, 104, false, false },
131 { QString(""), 100, 16, 32, -1, -1, 70, 90, 110, 127, 105, 105, false, false },
132 { QString(""), 100, 16, 32, -1, -1, 70, 90, 110, 127, 106, 106, false, false },
133 { QString(""), 100, 16, 32, -1, -1, 70, 90, 110, 127, 107, 107, false, false },
134 { QString(""), 100, 16, 32, -1, -1, 70, 90, 110, 127, 108, 108, false, false },
135 { QString(""), 100, 16, 32, -1, -1, 70, 90, 110, 127, 109, 109, false, false },
136 { QString(""), 100, 16, 32, -1, -1, 70, 90, 110, 127, 110, 110, false, false },
137 { QString(""), 100, 16, 32, -1, -1, 70, 90, 110, 127, 111, 111, false, false },
138 { QString(""), 100, 16, 32, -1, -1, 70, 90, 110, 127, 112, 112, false, false },
139 { QString(""), 100, 16, 32, -1, -1, 70, 90, 110, 127, 113, 113, false, false },
140 { QString(""), 100, 16, 32, -1, -1, 70, 90, 110, 127, 114, 114, false, false },
141
142 { QString(""), 100, 16, 32, -1, -1, 70, 90, 110, 127, 115, 115, false, false },
143 { QString(""), 100, 16, 32, -1, -1, 70, 90, 110, 127, 116, 116, false, false },
144 { QString(""), 100, 16, 32, -1, -1, 70, 90, 110, 127, 117, 117, false, false },
145 { QString(""), 100, 16, 32, -1, -1, 70, 90, 110, 127, 118, 118, false, false },
146 { QString(""), 100, 16, 32, -1, -1, 70, 90, 110, 127, 119, 119, false, false },
147 { QString(""), 100, 16, 32, -1, -1, 70, 90, 110, 127, 120, 120, false, false },
148 { QString(""), 100, 16, 32, -1, -1, 70, 90, 110, 127, 121, 121, false, false },
149 { QString(""), 100, 16, 32, -1, -1, 70, 90, 110, 127, 122, 122, false, false },
150 { QString(""), 100, 16, 32, -1, -1, 70, 90, 110, 127, 123, 123, false, false },
151 { QString(""), 100, 16, 32, -1, -1, 70, 90, 110, 127, 124, 124, false, false },
152 { QString(""), 100, 16, 32, -1, -1, 70, 90, 110, 127, 125, 125, false, false },
153 { QString(""), 100, 16, 32, -1, -1, 70, 90, 110, 127, 126, 126, false, false },
154 { QString(""), 100, 16, 32, -1, -1, 70, 90, 110, 127, 127, 127, false, false },
155 { QString(""), 100, 16, 32, -1, -1, 70, 90, 110, 127, 0, 0, false, false },
156 { QString(""), 100, 16, 32, -1, -1, 70, 90, 110, 127, 1, 1, false, false },
157 { QString(""), 100, 16, 32, -1, -1, 70, 90, 110, 127, 2, 2, false, false },
158
159 { QString(""), 100, 16, 32, -1, -1, 70, 90, 110, 127, 3, 3, false, false },
160 { QString(""), 100, 16, 32, -1, -1, 70, 90, 110, 127, 4, 4, false, false },
161 { QString(""), 100, 16, 32, -1, -1, 70, 90, 110, 127, 5, 5, false, false },
162 { QString(""), 100, 16, 32, -1, -1, 70, 90, 110, 127, 6, 6, false, false },
163 { QString(""), 100, 16, 32, -1, -1, 70, 90, 110, 127, 7, 7, false, false },
164 { QString(""), 100, 16, 32, -1, -1, 70, 90, 110, 127, 8, 8, false, false },
165 { QString(""), 100, 16, 32, -1, -1, 70, 90, 110, 127, 9, 9, false, false },
166 { QString(""), 100, 16, 32, -1, -1, 70, 90, 110, 127, 10, 10, false, false },
167 { QString(""), 100, 16, 32, -1, -1, 70, 90, 110, 127, 11, 11, false, false },
168 { QString(""), 100, 16, 32, -1, -1, 70, 90, 110, 127, 12, 12, false, false },
169 { QString(""), 100, 16, 32, -1, -1, 70, 90, 110, 127, 13, 13, false, false },
170 { QString(""), 100, 16, 32, -1, -1, 70, 90, 110, 127, 14, 14, false, false },
171 { QString(""), 100, 16, 32, -1, -1, 70, 90, 110, 127, 15, 15, false, false },
172 { QString(""), 100, 16, 32, -1, -1, 70, 90, 110, 127, 16, 16, false, false },
173 { QString(""), 100, 16, 32, -1, -1, 70, 90, 110, 127, 17, 17, false, false },
174 { QString(""), 100, 16, 32, -1, -1, 70, 90, 110, 127, 18, 18, false, false },
175
176 { QString(""), 100, 16, 32, -1, -1, 70, 90, 110, 127, 19, 19, false, false },
177 { QString(""), 100, 16, 32, -1, -1, 70, 90, 110, 127, 20, 20, false, false },
178 { QString(""), 100, 16, 32, -1, -1, 70, 90, 110, 127, 21, 21, false, false },
179 { QString(""), 100, 16, 32, -1, -1, 70, 90, 110, 127, 22, 22, false, false },
180 { QString(""), 100, 16, 32, -1, -1, 70, 90, 110, 127, 23, 23, false, false },
181 { QString(""), 100, 16, 32, -1, -1, 70, 90, 110, 127, 24, 24, false, false },
182 { QString(""), 100, 16, 32, -1, -1, 70, 90, 110, 127, 25, 25, false, false },
183 { QString(""), 100, 16, 32, -1, -1, 70, 90, 110, 127, 26, 26, false, false },
184 { QString(""), 100, 16, 32, -1, -1, 70, 90, 110, 127, 27, 27, false, false },
185 { QString(""), 100, 16, 32, -1, -1, 70, 90, 110, 127, 28, 28, false, false },
186 { QString(""), 100, 16, 32, -1, -1, 70, 90, 110, 127, 29, 29, false, false },
187 { QString(""), 100, 16, 32, -1, -1, 70, 90, 110, 127, 30, 30, false, false },
188 { QString(""), 100, 16, 32, -1, -1, 70, 90, 110, 127, 31, 31, false, false },
189 { QString(""), 100, 16, 32, -1, -1, 70, 90, 110, 127, 32, 32, false, false },
190 { QString(""), 100, 16, 32, -1, -1, 70, 90, 110, 127, 33, 33, false, false },
191 { QString(""), 100, 16, 32, -1, -1, 70, 90, 110, 127, 34, 34, false, false }
192 };
193
194 DrumMap iNewDrumMap[128];
195
initNewDrumMap()196 void initNewDrumMap()
197 {
198 bool done[128];
199 for (int i=0;i<128;i++) done[i]=false;
200
201 for (int i=0;i<DRUM_MAPSIZE;i++)
202 {
203 int idx=idrumMap[i].anote;
204 if (idx < 0 || idx >= 128)
205 fprintf(stderr, "ERROR: THIS SHOULD NEVER HAPPEN: idrumMap[%i].anote is not within 0..127!\n", idx);
206 else
207 {
208 if (done[idx]==true)
209 {
210 fprintf(stderr, "ERROR: iNewDrumMap[%i] is already initialized!\n"
211 " this will be probably not a problem, but some programmer didn't read\n"
212 " flo's comment at drummap.cpp, above idrumMap[].\n", idx);
213 }
214 else
215 {
216 iNewDrumMap[idx]=idrumMap[i];
217 done[idx]=true;
218 }
219 }
220 }
221
222 for (int i=0;i<128;i++)
223 {
224 if (done[i]==false)
225 {
226 fprintf(stderr, "ERROR: iNewDrumMap[%i] is uninitialized!\n"
227 " this will be probably not a problem, but some programmer didn't read\n"
228 " flo's comment at drummap.cpp, above idrumMap[].\n", i);
229 iNewDrumMap[i].name="";
230 iNewDrumMap[i].vol=100;
231 iNewDrumMap[i].quant=16;
232 iNewDrumMap[i].len=32;
233 iNewDrumMap[i].lv1=70;
234 iNewDrumMap[i].lv2=90;
235 iNewDrumMap[i].lv3=127;
236 iNewDrumMap[i].lv4=110;
237 iNewDrumMap[i].enote=i;
238 iNewDrumMap[i].anote=i;
239 iNewDrumMap[i].mute=false;
240 iNewDrumMap[i].hide=false;
241 }
242 }
243 }
244
245 //---------------------------------------------------------
246 // clearDrumMap
247 // One-time only early init
248 //---------------------------------------------------------
249
clearDrumMap()250 void clearDrumMap()
251 {
252 for (int i = 0; i < DRUM_MAPSIZE; ++i) {
253 DrumMap& d = MusEGlobal::drumMap[i];
254 d.vol = d.len = d.channel = d.port = d.lv1 = d.lv2 = d.lv3 = d.lv4 = d.enote = d.anote = 0;
255 d.mute = d.hide = false;
256 }
257 }
258 //---------------------------------------------------------
259 // initDrumMap
260 // populate Inmap and Outmap
261 //---------------------------------------------------------
262
initDrumMap()263 void initDrumMap()
264 {
265 for (int i = 0; i < DRUM_MAPSIZE; ++i) {
266 DrumMap& d = MusEGlobal::drumMap[i];
267 //Make sure we're not overwriting any values loaded
268 //On init, all these values are zero. If so, just set the drummap entry to the initial drummap entry.
269 if (!(d.vol || d.len || d.channel || d.port || d.lv1 || d.lv2 || d.lv3 || d.lv4 || d.enote || d.anote || d.mute || d.hide))
270 MusEGlobal::drumMap[i] = idrumMap[i];
271 }
272 //Finally, setup the inMap, outMap-values
273 memset(MusEGlobal::drumInmap, 0, sizeof(MusEGlobal::drumInmap));
274 memset(MusEGlobal::drumOutmap, 0, sizeof(MusEGlobal::drumOutmap));
275 for (int i = 0; i < DRUM_MAPSIZE; ++i) {
276 MusEGlobal::drumInmap[(unsigned int)(MusEGlobal::drumMap[i].enote)] = i;
277 MusEGlobal::drumOutmap[(unsigned int)(MusEGlobal::drumMap[i].anote)] = i;
278 }
279 }
280
281 //---------------------------------------------------------
282 // resetGMDrumMap
283 //---------------------------------------------------------
284
resetGMDrumMap()285 void resetGMDrumMap()
286 {
287 for(int i = 0; i < DRUM_MAPSIZE; ++i)
288 MusEGlobal::drumMap[i] = idrumMap[i];
289 memset(MusEGlobal::drumInmap, 0, sizeof(MusEGlobal::drumInmap));
290 memset(MusEGlobal::drumOutmap, 0, sizeof(MusEGlobal::drumOutmap));
291 for (int i = 0; i < DRUM_MAPSIZE; ++i) {
292 MusEGlobal::drumInmap[(unsigned int)(MusEGlobal::drumMap[i].enote)] = i;
293 MusEGlobal::drumOutmap[(unsigned int)(MusEGlobal::drumMap[i].anote)] = i;
294 }
295 }
296
297 //---------------------------------------------------------
298 // operator ==
299 //---------------------------------------------------------
300
operator ==(const DrumMap & map) const301 bool DrumMap::operator==(const DrumMap& map) const
302 {
303 // Everything equal, including mute and hide settings?
304 return almost_equals(map) &&
305 mute == map.mute &&
306 hide == map.hide;
307 }
308
almost_equals(const DrumMap & map) const309 bool DrumMap::almost_equals(const DrumMap& map) const
310 {
311 // Disregarding mute and hide settings.
312 return
313 name == map.name
314 && vol == map.vol
315 && quant == map.quant
316 && len == map.len
317 && channel == map.channel
318 && port == map.port
319 && lv1 == map.lv1
320 && lv2 == map.lv2
321 && lv3 == map.lv3
322 && lv4 == map.lv4
323 && enote == map.enote
324 && anote == map.anote;
325 }
326
dump()327 void DrumMap::dump()
328 {
329 fprintf(stderr, "%s\t\t%d\t%d\t%d\t%d\t%d\t%d\t%d\t%d\t%d\t%d(%s)\t\t%d(%s)\t\t%d\t%d\t\n",
330 name.toLatin1().constData(),
331 vol,
332 quant,
333 len,
334 channel,
335 port,
336 lv1, lv2, lv3, lv4,
337 enote, pitch2string(enote).toLatin1().constData(),
338 anote, pitch2string(anote).toLatin1().constData(),
339 mute,
340 hide);
341 }
342
343 //---------------------------------------------------------
344 // writeDrumMap
345 //---------------------------------------------------------
346
writeDrumMap(int level,Xml & xml,bool external)347 void writeDrumMap(int level, Xml& xml, bool external)
348 {
349 xml.tag(level++, "drummap");
350 for (int i = 0; i < DRUM_MAPSIZE; ++i) {
351 DrumMap* dm = &MusEGlobal::drumMap[i];
352 const DrumMap* idm = &idrumMap[i];
353
354 if (external) {
355 xml.tag(level++, "entry");
356 xml.strTag(level, "name", dm->name);
357 xml.intTag(level, "vol", dm->vol);
358 xml.intTag(level, "quant", dm->quant);
359 xml.intTag(level, "len", dm->len);
360 xml.intTag(level, "channel", dm->channel);
361 xml.intTag(level, "port", dm->port);
362 xml.intTag(level, "lv1", dm->lv1);
363 xml.intTag(level, "lv2", dm->lv2);
364 xml.intTag(level, "lv3", dm->lv3);
365 xml.intTag(level, "lv4", dm->lv4);
366 xml.intTag(level, "enote", dm->enote);
367 xml.intTag(level, "anote", dm->anote);
368 xml.intTag(level, "hide", dm->hide);
369 }
370 else {
371 // write only, if entry is different from initial entry
372 if (!external && *dm == *idm)
373 continue;
374 xml.tag(level++, "entry idx=\"%d\"", i);
375 if (dm->name != idm->name)
376 xml.strTag(level, "name", dm->name);
377 if (dm->vol != idm->vol)
378 xml.intTag(level, "vol", dm->vol);
379 if (dm->quant != idm->quant)
380 xml.intTag(level, "quant", dm->quant);
381 if (dm->len != idm->len)
382 xml.intTag(level, "len", dm->len);
383 if (dm->channel != idm->channel)
384 xml.intTag(level, "channel", dm->channel);
385 if (dm->port != idm->port)
386 xml.intTag(level, "port", dm->port);
387 if (dm->lv1 != idm->lv1)
388 xml.intTag(level, "lv1", dm->lv1);
389 if (dm->lv2 != idm->lv2)
390 xml.intTag(level, "lv2", dm->lv2);
391 if (dm->lv3 != idm->lv3)
392 xml.intTag(level, "lv3", dm->lv3);
393 if (dm->lv4 != idm->lv4)
394 xml.intTag(level, "lv4", dm->lv4);
395 if (dm->enote != idm->enote)
396 xml.intTag(level, "enote", dm->enote);
397 if (dm->anote != idm->anote)
398 xml.intTag(level, "anote", dm->anote);
399 if (dm->mute != idm->mute)
400 xml.intTag(level, "mute", dm->mute);
401 if (dm->hide != idm->hide)
402 xml.intTag(level, "hide", dm->hide);
403 }
404 xml.tag(level--, "/entry");
405 }
406 xml.tag(level--, "/drummap");
407 }
408
409 //---------------------------------------------------------
410 // readDrummapEntry
411 //---------------------------------------------------------
412
readDrummapEntry(Xml & xml,DrumMap * dm)413 static void readDrummapEntry(Xml& xml, DrumMap* dm)
414 {
415
416 for (;;) {
417 Xml::Token token = xml.parse();
418 const QString& tag = xml.s1();
419 switch (token) {
420 case Xml::Error:
421 case Xml::End:
422 return;
423 case Xml::TagStart:
424 if (tag == "name")
425 dm->name = xml.parse(QString("name"));
426 else if (tag == "vol")
427 dm->vol = (unsigned char)xml.parseInt();
428 else if (tag == "quant")
429 dm->quant = xml.parseInt();
430 else if (tag == "len")
431 dm->len = xml.parseInt();
432 else if (tag == "channel")
433 dm->channel = xml.parseInt();
434 else if (tag == "port")
435 dm->port = xml.parseInt();
436 else if (tag == "lv1")
437 dm->lv1 = xml.parseInt();
438 else if (tag == "lv2")
439 dm->lv2 = xml.parseInt();
440 else if (tag == "lv3")
441 dm->lv3 = xml.parseInt();
442 else if (tag == "lv4")
443 dm->lv4 = xml.parseInt();
444 else if (tag == "enote")
445 dm->enote = xml.parseInt();
446 else if (tag == "anote")
447 dm->anote = xml.parseInt();
448 else if (tag == "mute")
449 dm->mute = xml.parseInt();
450 else if (tag == "hide")
451 dm->hide = xml.parseInt();
452 else if (tag == "selected")
453 //; // dm->selected = xml.parseInt();
454 xml.skip(tag);
455 else
456 xml.unknown("entry");
457 break;
458 case Xml::Attribut:
459 if (tag == "idx") {
460 int idx = xml.s2().toInt() & 0x7f;
461 dm = &MusEGlobal::drumMap[idx];
462
463 }
464 break;
465 case Xml::TagEnd:
466 if (tag == "entry")
467 {
468 return;
469 }
470 default:
471 break;
472 }
473 }
474 }
475
476 //---------------------------------------------------------
477 // readDrummap
478 //---------------------------------------------------------
479
readDrumMap(Xml & xml,bool external)480 void readDrumMap(Xml& xml, bool external)
481 {
482 if (external) {
483 for (int i = 0; i < DRUM_MAPSIZE; ++i)
484 MusEGlobal::drumMap[i] = blankdm;
485 }
486 else {
487 for (int i = 0; i < DRUM_MAPSIZE; ++i)
488 MusEGlobal::drumMap[i] = idrumMap[i];
489 }
490 int i = 0;
491 for (;;) {
492 Xml::Token token = xml.parse();
493 const QString& tag = xml.s1();
494 switch (token) {
495 case Xml::Error:
496 case Xml::End:
497 // goto read_drummap_end;
498 return;
499 case Xml::TagStart:
500 if (tag == "entry") {
501 if(i >= DRUM_MAPSIZE)
502 // goto read_drummap_end;
503 return;
504 readDrummapEntry(xml, external ? &MusEGlobal::drumMap[i] : 0);
505 ++i;
506 }
507 else if (tag == "comment")
508 xml.parse();
509 else
510 xml.unknown("DrumMap");
511 break;
512 case Xml::Attribut:
513 break;
514 case Xml::TagEnd:
515 if (tag == "drummap") {
516 memset(MusEGlobal::drumInmap, 0, sizeof(MusEGlobal::drumInmap));
517 memset(MusEGlobal::drumOutmap, 0, sizeof(MusEGlobal::drumOutmap));
518 for (int i = 0; i < DRUM_MAPSIZE; ++i) {
519 MusEGlobal::drumInmap[(unsigned int)(MusEGlobal::drumMap[i].enote)] = i;
520 MusEGlobal::drumOutmap[(unsigned int)(MusEGlobal::drumMap[i].anote)] = i;
521 }
522 // goto read_drummap_end;
523 return;
524 }
525 default:
526 break;
527 }
528 }
529 }
530
531 } // namespace MusECore
532
533