/[svn]/jsampler/trunk/src/org/jsampler/MidiInstrumentMap.java
ViewVC logotype

Contents of /jsampler/trunk/src/org/jsampler/MidiInstrumentMap.java

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1329 - (show annotations) (download)
Sat Sep 8 18:33:05 2007 UTC (16 years, 7 months ago) by iliev
File size: 9682 byte(s)
* Implemented some UI enhancements for speeding up
  the MIDI instrument mapping process
* some minor bugfixes

1 /*
2 * JSampler - a java front-end for LinuxSampler
3 *
4 * Copyright (C) 2005-2007 Grigor Iliev <grigor@grigoriliev.com>
5 *
6 * This file is part of JSampler.
7 *
8 * JSampler is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2
10 * as published by the Free Software Foundation.
11 *
12 * JSampler is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with JSampler; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
20 * MA 02111-1307 USA
21 */
22
23 package org.jsampler;
24
25 import java.util.TreeMap;
26 import java.util.Vector;
27
28 import javax.swing.SwingUtilities;
29
30 import org.jsampler.event.MidiInstrumentMapEvent;
31 import org.jsampler.event.MidiInstrumentMapListener;
32
33 import org.linuxsampler.lscp.MidiInstrumentEntry;
34 import org.linuxsampler.lscp.MidiInstrumentMapInfo;
35
36
37 /**
38 * Represents a MIDI instrument map used for mapping instruments
39 * to corresponding MIDI bank select and MIDI program change messages.
40 * @author Grigor Iliev
41 */
42 public class MidiInstrumentMap {
43 MidiInstrumentMapInfo info;
44
45 private final TreeMap<MidiInstrumentEntry, MidiInstrument> instrMap =
46 new TreeMap<MidiInstrumentEntry, MidiInstrument>();
47
48 private final Vector<MidiInstrumentMapListener> listeners =
49 new Vector<MidiInstrumentMapListener>();
50
51
52 /**
53 * Creates a new instance of <code>MidiInstrumentMap</code>.
54 * @param info Provides the map's properties.
55 */
56 public
57 MidiInstrumentMap(MidiInstrumentMapInfo info) { this.info = info; }
58
59 /**
60 * Registers the specified listener for receiving event messages.
61 * @param l The <code>MidiInstrumentMapListener</code> to register.
62 */
63 public void
64 addMidiInstrumentMapListener(MidiInstrumentMapListener l) { listeners.add(l); }
65
66 /**
67 * Removes the specified listener.
68 * @param l The <code>MidiInstrumentMapListener</code> to remove.
69 */
70 public void
71 removeMidiInstrumentMapListener(MidiInstrumentMapListener l) { listeners.remove(l); }
72
73 /*
74 * Creates a new instance of MidiInstrumentMap.
75 * @param mapId The ID of this MIDI instrument map.
76 * @param name The name of this MIDI instrument map.
77 *
78 public
79 MidiInstrumentMap(int mapId, String name) {
80 this.mapId = mapId;
81 setName(name);
82 }*/
83
84 /** Gets the ID of this MIDI instrument map. */
85 public int
86 getMapId() { return info.getMapId(); }
87
88 /**
89 * Gets the name of this MIDI instrument map.
90 * @return The name of this MIDI instrument map.
91 */
92 public String
93 getName() { return info.getName(); }
94
95 /**
96 * Sets the name of this MIDI instrument map.
97 * @param name The new name of this MIDI instrument map.
98 */
99 public void
100 setName(String name) {
101 if(info.getName().equals(name)) return;
102 info.setName(name);
103 fireNameChanged();
104 }
105
106 /**
107 * Gets the information about this MIDI instrument map.
108 * @return The information about this MIDI instrument map.
109 */
110 public MidiInstrumentMapInfo
111 getInfo() { return info; }
112
113 /**
114 * Sets the information about this MIDI instrument map.
115 * @param info The new information about this MIDI instrument map.
116 */
117 public void
118 setInfo(MidiInstrumentMapInfo info) {
119 this.info = info;
120 fireNameChanged();
121 }
122
123 /**
124 * Gets the indices of all MIDI banks that contain at least one instrument.
125 * @return The indices of all MIDI banks that contain at least one instrument.
126 */
127 public Integer[]
128 getMidiBanks() {
129 Vector<Integer> v = new Vector<Integer>();
130
131 for(MidiInstrumentEntry e : instrMap.keySet()) {
132 if(v.isEmpty()) v.add(e.getMidiBank());
133 else {
134 if(e.getMidiBank() < v.lastElement())
135 throw new RuntimeException("Unsorted map!");
136
137 if(e.getMidiBank() > v.lastElement()) v.add(e.getMidiBank());
138 }
139 }
140
141 return v.toArray(new Integer[v.size()]);
142 }
143
144 /**
145 * Gets the instrument in the specified MIDI bank with the specified program number.
146 * @param bank The index of the MIDI bank, containing the requested instrument.
147 * @param program The program number of the requested instrument.
148 * @return The instrument in MIDI bank <code>bank</code> with
149 * program number <code>program</code>, or <code>null</code> if
150 * there is no such instrument in the map.
151 */
152 public MidiInstrument
153 getMidiInstrument(int bank, int program) {
154 return instrMap.get(new MidiInstrumentEntry(bank, program));
155 }
156
157 /**
158 * Gets all instruments contained in the specified MIDI bank.
159 * @param bankIndex The index of the MIDI bank, whose instruments should be obtained.
160 * @return All instruments contained in the specified MIDI bank.
161 */
162 public MidiInstrument[]
163 getMidiInstruments(int bankIndex) {
164 Vector<MidiInstrument> v = new Vector<MidiInstrument>();
165
166 for(MidiInstrumentEntry e : instrMap.keySet()) {
167 if(e.getMidiBank() == bankIndex) v.add(instrMap.get(e));
168 }
169
170 return v.toArray(new MidiInstrument[v.size()]);
171 }
172
173 /**
174 * Gets all instruments contained in this MIDI instrument map.
175 * @return All instruments contained in this MIDI instrument map.
176 */
177 public MidiInstrument[]
178 getAllMidiInstruments() {
179 Vector<MidiInstrument> v = new Vector<MidiInstrument>();
180
181 for(MidiInstrument i : instrMap.values()) v.add(i);
182
183 return v.toArray(new MidiInstrument[v.size()]);
184 }
185
186 /**
187 * Creates a new or replaces an existing entry in this MIDI instrument map.
188 */
189 public void
190 mapMidiInstrument(MidiInstrumentEntry entry, MidiInstrument instrument) {
191 MidiInstrument mi = instrMap.remove(entry);
192 if(mi != null) fireInstrumentRemoved(entry, mi);
193 instrMap.put(entry, instrument);
194 fireInstrumentAdded(entry, instrument);
195 }
196
197 /**
198 * Removes an entry from this MIDI instrument map.
199 * @param entry The entry to remove.
200 * @return The MIDI instrument associated with the specified entry or
201 * <code>null</code> if there was no mapping for that entry.
202 */
203 public MidiInstrument
204 unmapMidiInstrument(MidiInstrumentEntry entry) {
205 MidiInstrument mi = instrMap.remove(entry);
206 if(mi != null) fireInstrumentRemoved(entry, mi);
207 return mi;
208 }
209
210 /**
211 * Gets a free entry.
212 */
213 public MidiInstrumentEntry
214 getAvailableEntry() {
215 int i = CC.getViewConfig().preferences().getIntProperty("lastUsedMidiBank", 0);
216 int firstFreePgm = -1, bank = -1, tmpBank = -1, tmpPgm = -1;
217
218 for(MidiInstrument instr : instrMap.values()) {
219 int p = instr.getInfo().getMidiProgram();
220 int b = instr.getInfo().getMidiBank();
221 if(b < i) continue;
222
223 if(firstFreePgm != -1) {
224 if(b > bank) {
225 if(tmpPgm < 127) {
226 return new MidiInstrumentEntry(bank, tmpPgm + 1);
227 } else {
228 return new MidiInstrumentEntry(bank, firstFreePgm);
229 }
230 }
231
232 tmpPgm = p;
233 } else {
234 if(tmpBank != b) {
235 if(tmpBank != -1 && tmpPgm < 127) {
236 return new MidiInstrumentEntry(tmpBank, tmpPgm + 1);
237 }
238 tmpPgm = -1;
239 tmpBank = b;
240 }
241
242 if(p - tmpPgm > 1) {
243 firstFreePgm = tmpPgm + 1;
244 bank = b;
245 }
246 tmpPgm = p;
247 }
248 }
249
250 if(tmpBank == -1) return new MidiInstrumentEntry(i, 0);
251
252 if(firstFreePgm != -1) {
253 if(tmpPgm < 127) return new MidiInstrumentEntry(bank, tmpPgm + 1);
254 else return new MidiInstrumentEntry(bank, firstFreePgm);
255 }
256
257 if(tmpBank == 16129 && tmpPgm == 127) return null;
258
259 if(tmpPgm < 127) return new MidiInstrumentEntry(tmpBank, tmpPgm + 1);
260 else return new MidiInstrumentEntry(tmpBank + 1, 0);
261 }
262
263 /**
264 * Returns the name of this map.
265 * @return The name of this map.
266 */
267 public String
268 toString() { return getName(); }
269
270 /**
271 * Notifies listeners that the name of the MIDI instrument map has changed.
272 * Note that this method can be invoked outside the event-dispatching thread.
273 */
274 private void
275 fireNameChanged() {
276 final MidiInstrumentMapEvent e = new MidiInstrumentMapEvent(this);
277
278 SwingUtilities.invokeLater(new Runnable() {
279 public void
280 run() { fireNameChanged(e); }
281 });
282 }
283
284 /** Notifies listeners that the name of the MIDI instrument map has changed. */
285 private void
286 fireNameChanged(MidiInstrumentMapEvent e) {
287 for(MidiInstrumentMapListener l : listeners) l.nameChanged(e);
288 }
289
290 /**
291 * Notifies listeners that a MIDI instrument has been
292 * added to this MIDI instrument map.
293 * Note that this method can be invoked outside the event-dispatching thread
294 */
295 private void
296 fireInstrumentAdded(MidiInstrumentEntry entry, MidiInstrument instrument) {
297 final MidiInstrumentMapEvent e =
298 new MidiInstrumentMapEvent(this, entry, instrument);
299
300 SwingUtilities.invokeLater(new Runnable() {
301 public void
302 run() { fireInstrumentAdded(e); }
303 });
304 }
305
306 /**
307 * Notifies listeners that a MIDI instrument has been
308 * added to this MIDI instrument map.
309 */
310 private void
311 fireInstrumentAdded(MidiInstrumentMapEvent e) {
312 for(MidiInstrumentMapListener l : listeners) l.instrumentAdded(e);
313 }
314
315 /**
316 * Notifies listeners that a MIDI instrument has been
317 * removed from this MIDI instrument map.
318 */
319 private void
320 fireInstrumentRemoved(MidiInstrumentEntry entry, MidiInstrument instrument) {
321 final MidiInstrumentMapEvent e =
322 new MidiInstrumentMapEvent(this, entry, instrument);
323
324 SwingUtilities.invokeLater(new Runnable() {
325 public void
326 run() { fireInstrumentRemoved(e); }
327 });
328 }
329
330 /**
331 * Notifies listeners that a MIDI instrument has been
332 * removed from this MIDI instrument map.
333 */
334 private void
335 fireInstrumentRemoved(MidiInstrumentMapEvent e) {
336 for(MidiInstrumentMapListener l : listeners) l.instrumentRemoved(e);
337 }
338 }

  ViewVC Help
Powered by ViewVC