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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1743 - (show annotations) (download)
Sat May 31 23:04:01 2008 UTC (15 years, 10 months ago) by iliev
File size: 38179 byte(s)
* Renamed the column labels in the Channel Routing dialog: The column
  representing the sampler channel's audio channels is "Audio In" and
  the column representing the audio device's channels is "Audio Out"
* Remember the last used tab in the Preferences dialog
* Fantasia: The sampler channels are now referenced by their position
  in the list, not by their ID
* Fantasia: Implemented options to show the channel number and/or the MIDI
  input port/channel on the sampler channel screen when using Small View
  (choose Edit/Preferences, then click the `Channels' tab)
* Fantasia: Migrated to substance 5

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.Vector;
26
27 import java.util.logging.Level;
28
29 import javax.swing.SwingUtilities;
30
31 import javax.swing.event.EventListenerList;
32
33 import net.sf.juife.Task;
34 import net.sf.juife.event.TaskEvent;
35 import net.sf.juife.event.TaskListener;
36
37 import org.jsampler.event.ListEvent;
38 import org.jsampler.event.ListListener;
39 import org.jsampler.event.MidiDeviceListEvent;
40 import org.jsampler.event.MidiDeviceListListener;
41 import org.jsampler.event.SamplerChannelListEvent;
42 import org.jsampler.event.SamplerChannelListListener;
43 import org.jsampler.event.SamplerEvent;
44 import org.jsampler.event.SamplerListener;
45
46 import org.jsampler.task.Audio;
47 import org.jsampler.task.Channel;
48 import org.jsampler.task.Global;
49 import org.jsampler.task.Midi;
50
51 import org.linuxsampler.lscp.*;
52
53
54 /**
55 * This class provides default implementation of the <code>SamplerModel</code> interface.
56 * Note that the setter methods of this class does <b>not</b> alter any settings
57 * on the backend side unless otherwise specified.
58 * @author Grigor Iliev
59 */
60 public class DefaultSamplerModel implements SamplerModel {
61 private ServerInfo serverInfo = null;
62 private AudioOutputDriver[] aoDrvS = null;
63 private MidiInputDriver[] miDrvS = null;
64 private SamplerEngine[] engines = null;
65
66 private int totalStreamCount = 0;
67 private int totalVoiceCount = 0;
68 private int totalVoiceCountMax = 0;
69
70 private float volume = 1;
71 private MidiInstrumentMap defaultMidiInstrumentMap;
72
73 private final Vector<SamplerChannelModel> channelModels = new Vector<SamplerChannelModel>();
74 private final Vector<AudioDeviceModel> audioDeviceModels = new Vector<AudioDeviceModel>();
75 private final Vector<MidiDeviceModel> midiDeviceModels = new Vector<MidiDeviceModel>();
76 private final Vector<MidiInstrumentMap> midiInstrMaps = new Vector<MidiInstrumentMap>();
77
78 private final Vector<SamplerListener> listeners = new Vector<SamplerListener>();
79 private final Vector<ListListener<MidiInstrumentMap>> mapsListeners =
80 new Vector<ListListener<MidiInstrumentMap>>();
81
82 private final EventListenerList listenerList = new EventListenerList();
83
84 private boolean channelListIsAdjusting = false;
85
86 private boolean modified = false;
87
88
89 /** Creates a new instance of DefaultSamplerModel */
90 public
91 DefaultSamplerModel() {
92 addMidiInstrumentMapListListener(getHandler());
93 }
94
95 /**
96 * Registers the specified listener for receiving event messages.
97 * @param l The <code>SamplerListener</code> to register.
98 */
99 public void
100 addSamplerListener(SamplerListener l) { listeners.add(l); }
101
102 /**
103 * Removes the specified listener.
104 * @param l The <code>SamplerListener</code> to remove.
105 */
106 public void
107 removeSamplerListener(SamplerListener l) { listeners.remove(l); }
108
109 /**
110 * Registers the specified listener for receiving event messages.
111 * @param listener The <code>AudioDeviceListListener</code> to register.
112 */
113 public void
114 addAudioDeviceListListener(ListListener<AudioDeviceModel> listener) {
115 listenerList.add(ListListener.class, listener);
116 }
117
118 /**
119 * Removes the specified listener.
120 * @param listener The <code>AudioDeviceListListener</code> to remove.
121 */
122 public void
123 removeAudioDeviceListListener(ListListener<AudioDeviceModel> listener) {
124 listenerList.remove(ListListener.class, listener);
125 }
126
127 /**
128 * Registers the specified listener for receiving event messages.
129 * @param listener The <code>MidiDeviceListListener</code> to register.
130 */
131 public void
132 addMidiDeviceListListener(MidiDeviceListListener listener) {
133 listenerList.add(MidiDeviceListListener.class, listener);
134 }
135
136 /**
137 * Removes the specified listener.
138 * @param listener The <code>MidiDeviceListListener</code> to remove.
139 */
140 public void
141 removeMidiDeviceListListener(MidiDeviceListListener listener) {
142 listenerList.remove(MidiDeviceListListener.class, listener);
143 }
144
145 /**
146 * Registers the specified listener for receiving event messages.
147 * @param listener The <code>ListListener</code> to register.
148 */
149 public void
150 addMidiInstrumentMapListListener(ListListener<MidiInstrumentMap> listener) {
151 mapsListeners.add(listener);
152 }
153
154 /**
155 * Removes the specified listener.
156 * @param listener The <code>ListListener</code> to remove.
157 */
158 public void
159 removeMidiInstrumentMapListListener(ListListener<MidiInstrumentMap> listener) {
160 mapsListeners.remove(listener);
161 }
162
163 /**
164 * Registers the specified listener for receiving event messages.
165 * @param listener The <code>SamplerChannelListListener</code> to register.
166 */
167 public void
168 addSamplerChannelListListener(SamplerChannelListListener listener) {
169 listenerList.add(SamplerChannelListListener.class, listener);
170 }
171
172 /**
173 * Removes the specified listener.
174 * @param listener The <code>SamplerChannelListListener</code> to remove.
175 */
176 public void
177 removeSamplerChannelListListener(SamplerChannelListListener listener) {
178 listenerList.remove(SamplerChannelListListener.class, listener);
179 }
180
181 /**
182 * Gets information about the LinuxSampler instance the front-end is connected to.
183 *
184 * @return <code>ServerInfo</code> instance containing
185 * information about the LinuxSampler instance the front-end is connected to.
186 */
187 public ServerInfo
188 getServerInfo() { return serverInfo; }
189
190 /**
191 * Sets information about the LinuxSampler instance the front-end is connected to.
192 *
193 * @param serverInfo <code>ServerInfo</code> instance containing
194 * information about the LinuxSampler instance the front-end is connected to.
195 */
196 public void
197 setServerInfo(ServerInfo serverInfo) { this.serverInfo = serverInfo; }
198
199 /**
200 * Gets all audio output drivers currently available for the LinuxSampler instance.
201 *
202 * @return <code>AudioOutputDriver</code> array containing all audio output drivers
203 * currently available for the LinuxSampler instance.
204 */
205 public AudioOutputDriver[]
206 getAudioOutputDrivers() { return aoDrvS; }
207
208 /**
209 * Sets the currently available audio output drivers for the LinuxSampler instance.
210 *
211 * @param drivers <code>AudioOutputDriver</code> array containing all audio output drivers
212 * currently available for the LinuxSampler instance.
213 */
214 public void
215 setAudioOutputDrivers(AudioOutputDriver[] drivers) { aoDrvS = drivers; }
216
217 /**
218 * Gets the model of the audio device at the specified position.
219 * @param index The position of the audio device to return.
220 * @return The model of the audio device at the specified position.
221 * @see #getAudioDeviceCount
222 */
223 public AudioDeviceModel
224 getAudioDevice(int index) {
225 return audioDeviceModels.get(index);
226 }
227
228 /**
229 * Gets the model of the audio device with ID <code>deviceId</code>.
230 * @param deviceId The ID of the audio device whose model should be obtained.
231 * @return The model of the specified audio device or <code>null</code>
232 * if there is no audio device with ID <code>deviceId</code>.
233 */
234 public AudioDeviceModel
235 getAudioDeviceById(int deviceId) {
236 for(AudioDeviceModel m : audioDeviceModels)
237 if(m.getDeviceId() == deviceId) return m;
238
239 return null;
240 }
241
242 /**
243 * Gets the current number of audio devices.
244 * @return The current number of audio devices.
245 */
246 public int
247 getAudioDeviceCount() { return audioDeviceModels.size(); }
248
249 /**
250 * Gets the current list of audio device models.
251 * @return The current list of audio device models.
252 */
253 public AudioDeviceModel[]
254 getAudioDevices() {
255 return audioDeviceModels.toArray(new AudioDeviceModel[audioDeviceModels.size()]);
256 }
257
258 /**
259 * Adds the specified audio device.
260 * @param device The audio device to be added.
261 */
262 public void
263 addAudioDevice(AudioOutputDevice device) {
264 DefaultAudioDeviceModel model = new DefaultAudioDeviceModel(device);
265 audioDeviceModels.add(model);
266 fireAudioDeviceAdded(model);
267 }
268
269 /**
270 * Removes the specified audio device.
271 * @param deviceId The ID of the audio device to be removed.
272 * @return <code>true</code> if the audio device is removed successfully, <code>false</code>
273 * if the device list does not contain audio device with ID <code>deviceId</code>.
274 */
275 public boolean
276 removeAudioDeviceById(int deviceId) {
277 for(int i = 0; i < audioDeviceModels.size(); i++) {
278 AudioDeviceModel m = audioDeviceModels.get(i);
279 if(m.getDeviceId() == deviceId) {
280 audioDeviceModels.remove(i);
281 fireAudioDeviceRemoved(m);
282 return true;
283 }
284 }
285
286 return false;
287 }
288
289 /**
290 * Schedules a new task for removing the specified audio device on the backend side.
291 * @param deviceId The ID of the audio device to be removed.
292 */
293 public void
294 removeBackendAudioDevice(int deviceId) {
295 CC.getTaskQueue().add(new Audio.DestroyDevice(deviceId));
296 }
297
298 /**
299 * Gets all MIDI input drivers currently available for the LinuxSampler instance.
300 *
301 * @return <code>MidiInputDriver</code> array containing all MIDI input drivers currently
302 * available for the LinuxSampler instance.
303 */
304 public MidiInputDriver[]
305 getMidiInputDrivers() { return miDrvS; }
306
307 /**
308 * Sets the currently available MIDI input drivers for the LinuxSampler instance.
309 *
310 * @param drivers <code>MidiInputDriver</code> array containing all MIDI input drivers
311 * currently available for the LinuxSampler instance.
312 */
313 public void
314 setMidiInputDrivers(MidiInputDriver[] drivers) { miDrvS = drivers; }
315
316 /**
317 * Gets the model of the MIDI device at the specified position.
318 * @param index The position of the MIDI device to return.
319 * @return The model of the MIDI device at the specified position.
320 */
321 public MidiDeviceModel
322 getMidiDevice(int index) {
323 return midiDeviceModels.get(index);
324 }
325
326 /**
327 * Gets the model of the MIDI device with ID <code>deviceId</code>.
328 * @param deviceId The ID of the MIDI device whose model should be obtained.
329 * @return The model of the specified MIDI device or <code>null</code>
330 * if there is no MIDI device with ID <code>deviceId</code>.
331 */
332 public MidiDeviceModel
333 getMidiDeviceById(int deviceId) {
334 for(MidiDeviceModel m : midiDeviceModels)
335 if(m.getDeviceId() == deviceId) return m;
336
337 return null;
338 }
339
340 /**
341 * Gets the current number of MIDI input devices.
342 * @return The current number of MIDI input devices.
343 */
344 public int
345 getMidiDeviceCount() { return midiDeviceModels.size(); }
346
347 /**
348 * Gets the current list of MIDI device models.
349 * @return The current list of MIDI device models.
350 */
351 public MidiDeviceModel[]
352 getMidiDevices() {
353 return midiDeviceModels.toArray(new MidiDeviceModel[midiDeviceModels.size()]);
354 }
355
356 /**
357 * Adds the specified MIDI device.
358 * @param device The MIDI device to be added.
359 */
360 public void
361 addMidiDevice(MidiInputDevice device) {
362 DefaultMidiDeviceModel model = new DefaultMidiDeviceModel(device);
363 midiDeviceModels.add(model);
364 fireMidiDeviceAdded(model);
365 }
366
367 /**
368 * Schedules a new task for adding new MIDI device.
369 * @param driver The desired MIDI input system.
370 * @param parameters An optional list of driver specific parameters.
371 */
372 public void
373 addBackendMidiDevice(String driver, Parameter... parameters) {
374 CC.getTaskQueue().add(new Midi.CreateDevice(driver, parameters));
375 }
376
377 /**
378 * Removes the specified MIDI device.
379 * @param deviceId The ID of the MIDI device to be removed.
380 * @return <code>true</code> if the MIDI device is removed successfully, <code>false</code>
381 * if the device list does not contain MIDI device with ID <code>deviceId</code>.
382 */
383 public boolean
384 removeMidiDeviceById(int deviceId) {
385 for(int i = 0; i < midiDeviceModels.size(); i++) {
386 MidiDeviceModel m = midiDeviceModels.get(i);
387 if(m.getDeviceId() == deviceId) {
388 midiDeviceModels.remove(i);
389 fireMidiDeviceRemoved(m);
390 return true;
391 }
392 }
393
394 return false;
395 }
396
397 /**
398 * Schedules a new task for removing the specified MIDI device.
399 * @param deviceId The ID of the MIDI input device to be destroyed.
400 */
401 public void
402 removeBackendMidiDevice(int deviceId) {
403 CC.getTaskQueue().add(new Midi.DestroyDevice(deviceId));
404 }
405
406 /**
407 * Gets the MIDI instrument map with ID <code>mapId</code>.
408 * @param mapId The ID of the MIDI instrument map to obtain.
409 * @return The MIDI instrument map with the specified ID or <code>null</code>
410 * if there is no MIDI instrument map with ID <code>mapId</code>.
411 */
412 public MidiInstrumentMap
413 getMidiInstrumentMapById(int mapId) {
414 for(MidiInstrumentMap m : midiInstrMaps)
415 if(m.getMapId() == mapId) return m;
416
417 return null;
418 }
419
420 /**
421 * Gets the MIDI instrument map at the specified position.
422 * @param index The position of the MIDI instrument map to return.
423 * @return The MIDI instrument map at the specified position.
424 */
425 public MidiInstrumentMap
426 getMidiInstrumentMap(int index) {
427 return midiInstrMaps.get(index);
428 }
429
430 /**
431 * Gets the current number of MIDI instrument maps.
432 * @return The current number of MIDI instrument maps.
433 */
434 public int
435 getMidiInstrumentMapCount() { return midiInstrMaps.size(); }
436
437 /**
438 * Gets the current list of MIDI instrument maps.
439 * @return The current list of MIDI instrument maps.
440 */
441 public MidiInstrumentMap[]
442 getMidiInstrumentMaps() {
443 return midiInstrMaps.toArray(new MidiInstrumentMap[midiInstrMaps.size()]);
444 }
445
446 /**
447 * Gets the position of the specified MIDI instrument map in the list.
448 * @param map The map whose index should be returned.
449 * @return The position of the specified map in the list,
450 * or -1 if <code>map</code> is <code>null</code> or
451 * the map list does not contain the specified map.
452 */
453 public int
454 getMidiInstrumentMapIndex(MidiInstrumentMap map) {
455 if(map == null) return -1;
456
457 for(int i = 0; i < getMidiInstrumentMapCount(); i++) {
458 if(getMidiInstrumentMap(i) == map) return i;
459 }
460
461 return -1;
462 }
463
464 /**
465 * Adds the specified MIDI instrument map.
466 * @param map The MIDI instrument map to be added.
467 * @throws IllegalArgumentException If <code>map</code> is <code>null</code>.
468 */
469 public void
470 addMidiInstrumentMap(MidiInstrumentMap map) {
471 if(map == null) throw new IllegalArgumentException("map should be non-null!");
472
473 midiInstrMaps.add(map);
474 fireMidiInstrumentMapAdded(map);
475 }
476
477 /**
478 * Schedules a new task for creating a new MIDI instrument map on the backend side.
479 * @param name The name of the MIDI instrument map.
480 * @throws IllegalArgumentException If <code>name</code> is <code>null</code>.
481 */
482 public void
483 addBackendMidiInstrumentMap(String name) {
484 if(name == null) throw new IllegalArgumentException("name should be non-null!");
485
486 CC.getTaskQueue().add(new Midi.AddInstrumentMap(name));
487 }
488
489 /**
490 * Removes the specified MIDI instrument map.
491 * @param mapId The ID of the MIDI instrument map to be removed.
492 * @return <code>true</code> if the MIDI instrument map is removed successfully,
493 * <code>false</code> if the MIDI instrument map's list does not contain
494 * MIDI instrument map with ID <code>mapId</code>.
495 */
496 public boolean
497 removeMidiInstrumentMapById(int mapId) {
498 for(int i = 0; i < midiInstrMaps.size(); i++) {
499 MidiInstrumentMap m = getMidiInstrumentMap(i);
500 if(m.getMapId() == mapId) {
501 midiInstrMaps.remove(i);
502 fireMidiInstrumentMapRemoved(m);
503 return true;
504 }
505 }
506
507 return false;
508 }
509
510 /**
511 * Removes the specified MIDI instrument map.
512 * @param map The MIDI instrument map to remove.
513 * @return <code>true</code> if the specified MIDI instrument map was in the list,
514 * <code>false</code> otherwise.
515 */
516 public boolean
517 removeMidiInstrumentMap(MidiInstrumentMap map) {
518 boolean b = midiInstrMaps.removeElement(map);
519 if(b) fireMidiInstrumentMapRemoved(map);
520 return b;
521 }
522
523 /** Removes all MIDI instrument maps. */
524 public void
525 removeAllMidiInstrumentMaps() {
526 for(int i = midiInstrMaps.size() - 1; i >= 0; i--) {
527 MidiInstrumentMap map = midiInstrMaps.get(i);
528 midiInstrMaps.removeElementAt(i);
529 fireMidiInstrumentMapRemoved(map);
530 }
531 }
532
533 /**
534 * Schedules a new task for removing the
535 * specified MIDI instrument map on the backend side.
536 * @param mapId The numerical ID of the MIDI instrument map to remove.
537 */
538 public void
539 removeBackendMidiInstrumentMap(int mapId) {
540 CC.getTaskQueue().add(new Midi.RemoveInstrumentMap(mapId));
541 }
542
543 /**
544 * Schedules a new task for changing the name of
545 * the specified MIDI instrument map on the backend side.
546 * @param mapId The numerical ID of the MIDI instrument map.
547 * @param name The new name for the specified MIDI instrument map.
548 */
549 public void
550 setBackendMidiInstrumentMapName(final int mapId, String name) {
551 final Task t = new Midi.SetInstrumentMapInfo(mapId, name);
552
553 t.addTaskListener(new TaskListener() {
554 public void
555 taskPerformed(TaskEvent e) {
556 /*
557 * Because with the invokation of the method the task is considered
558 * to be done, if the task fails, we must update the settings.
559 */
560 if(t.doneWithErrors()) {
561 Task t2 = new Midi.UpdateInstrumentMapInfo(mapId);
562 CC.getTaskQueue().add(t2);
563 }
564 }
565 });
566 CC.getTaskQueue().add(t);
567 }
568
569 /**
570 * Gets the default MIDI instrument map.
571 * @return The default MIDI instrument map or <code>null</code>
572 * if there are no maps created.
573 */
574 public MidiInstrumentMap
575 getDefaultMidiInstrumentMap() {
576 return defaultMidiInstrumentMap;
577 }
578
579 /**
580 * Gets the default MIDI instrument map.
581 * @return The default MIDI instrument map or <code>null</code>
582 * if there are no maps created.
583 */
584 private MidiInstrumentMap
585 findDefaultMidiInstrumentMap() {
586 for(int i = 0; i < getMidiInstrumentMapCount(); i++) {
587 MidiInstrumentMap m = getMidiInstrumentMap(i);
588 if(m.getInfo().isDefault()) return m;
589 }
590
591 return null;
592 }
593
594 /**
595 * Schedules a new task for mapping a MIDI instrument on the backend side.
596 * @param mapId The id of the MIDI instrument map.
597 * @param bank The index of the MIDI bank, which shall contain the instrument.
598 * @param program The MIDI program number of the new instrument.
599 * @param instrInfo Provides the MIDI instrument settings.
600 */
601 public void
602 mapBackendMidiInstrument(int mapId, int bank, int program, MidiInstrumentInfo instrInfo) {
603 CC.getTaskQueue().add(new Midi.MapInstrument(mapId, bank, program, instrInfo));
604 }
605
606 /**
607 * Schedules a new task for removing a MIDI instrument on the backend side.
608 * @param mapId The id of the MIDI instrument map containing the instrument to be removed.
609 * @param bank The index of the MIDI bank containing the instrument to be removed.
610 * @param program The MIDI program number of the instrument to be removed.
611 */
612 public void
613 unmapBackendMidiInstrument(int mapId, int bank, int program) {
614 CC.getTaskQueue().add(new Midi.UnmapInstrument(mapId, bank, program));
615 }
616
617 /**
618 * Gets a list of all available engines.
619 * @return A list of all available engines.
620 */
621 public SamplerEngine[]
622 getEngines() { return engines; }
623
624 /**
625 * Sets the list of all available engines.
626 * @param engines The new list of all available engines.
627 */
628 public void
629 setEngines(SamplerEngine[] engines) { this.engines = engines; }
630
631 /**
632 * Gets the model of the sampler channel in the specified position.
633 * @param index The position of the channel to return.
634 * @return The model of the specified sampler channel.
635 * @see #getchannelCount
636 */
637 public SamplerChannelModel
638 getChannel(int index) {
639 return channelModels.get(index);
640 }
641
642 /**
643 * Gets the model of the sampler channel with ID <code>channelId</code>.
644 * @param channelId The ID of the sampler channel whose model should be obtained.
645 * @return The model of the specified sampler channel or <code>null</code>
646 * if there is no channel with ID <code>channelId</code>.
647 */
648 public SamplerChannelModel
649 getChannelById(int channelId) {
650 for(SamplerChannelModel m : channelModels)
651 if(m.getChannelId() == channelId) return m;
652
653 return null;
654 }
655
656 /**
657 * Gets the position of the specified channel.
658 * @param channel The model of the channel.
659 * @return The position of the specified channel in the channel list or -1
660 * if the channel is not in the list.
661 */
662 public int
663 getChannelIndex(SamplerChannelModel channel) {
664 if(channel == null) return -1;
665 for(int i = 0; i < channelModels.size(); i++) {
666 if(channelModels.get(i).getChannelId() == channel.getChannelId()) return i;
667 }
668
669 return -1;
670 }
671
672 /**
673 * Gets the current number of sampler channels.
674 * @return The current number of sampler channels.
675 */
676 public int
677 getChannelCount() { return channelModels.size(); }
678
679 /**
680 * Gets the current list of sampler channel models.
681 * @return The current list of sampler channel models.
682 */
683 public SamplerChannelModel[]
684 getChannels() {
685 return channelModels.toArray(new SamplerChannelModel[channelModels.size()]);
686 }
687
688 /**
689 * Schedules a new task for adding a new sampler channel on the
690 * backend side. The channel will be actually added to this model
691 * when the backend notifies for its creation.
692 * @see #addChannel
693 */
694 public void
695 addBackendChannel() {
696 CC.getTaskQueue().add(new Channel.Add());
697 // We leave this event to be notified by the LinuxSampler notification system.
698 }
699
700 /**
701 * Adds the specified sampler channel.
702 * @param channel The channel to be added.
703 */
704 public void
705 addChannel(SamplerChannel channel) {
706 DefaultSamplerChannelModel model = new DefaultSamplerChannelModel(channel);
707 channelModels.add(model);
708 fireSamplerChannelAdded(model);
709 }
710
711 /**
712 * Updates the settings of the specified channel.
713 * @param channel A <code>SamplerChannel</code> instance containing the new settings
714 * for the channel.
715 */
716 public void
717 updateChannel(SamplerChannel channel) {
718 for(SamplerChannelModel m : channelModels) {
719 if(m.getChannelId() == channel.getChannelId()) {
720 m.setChannelInfo(channel);
721 return;
722 }
723 }
724
725 CC.getLogger().log (
726 Level.WARNING, "DefaultSamplerModel.unknownChannel!", channel.getChannelId()
727 );
728 }
729
730 /**
731 * Determines whether there are known upcoming changes to the
732 * channel list, which should be considered as part of a single action.
733 */
734 public synchronized boolean
735 getChannelListIsAdjusting() { return channelListIsAdjusting; }
736
737 /**
738 * Sets whether the upcoming changes to the
739 * channel list should be considered part of a single action.
740 */
741 public synchronized void
742 setChannelListIsAdjusting(boolean b) {
743 channelListIsAdjusting = b;
744 }
745
746 /**
747 * Removes the specified sampler channel.
748 * @param channelId The ID of the channel to be removed.
749 * @return <code>true</code> if the channel is removed successfully, <code>false</code>
750 * if the channel's list does not contain channel with ID <code>channelId</code>.
751 */
752 public boolean
753 removeChannelById(int channelId) {
754 for(int i = 0; i < channelModels.size(); i++) {
755 SamplerChannelModel m = channelModels.get(i);
756 if(m.getChannelId() == channelId) {
757 channelModels.remove(i);
758 fireSamplerChannelRemoved(m);
759 return true;
760 }
761 }
762
763 return false;
764 }
765
766 /**
767 * Schedules a new task for removing the specified sampler channel on the backend side.
768 * @param channelId The ID of the channel to be removed.
769 */
770 public void
771 removeBackendChannel(int channelId) {
772 CC.getTaskQueue().add(new Channel.Remove(channelId));
773 }
774
775 /**
776 * Schedules a new task for starting an instrument editor for editing
777 * the loaded instrument on the specified sampler channel.
778 * @param channelId The sampler channel number.
779 */
780 public void
781 editBackendInstrument(int channelId) {
782 CC.getTaskQueue().add(new Channel.EditInstrument(channelId));
783 }
784
785 /**
786 * Determines whether there is at least one solo channel in the current list
787 * of sampler channels.
788 * @return <code>true</code> if there is at least one solo channel in the current list of
789 * sampler channels, <code>false</code> otherwise.
790 */
791 public boolean
792 hasSoloChannel() {
793 for(SamplerChannelModel m : channelModels)
794 if(m.getChannelInfo().isSoloChannel()) return true;
795
796 return false;
797 }
798
799 /**
800 * Gets the number of solo channels in the current list of sampler channels.
801 * @return The number of solo channels in the current list of sampler channels.
802 */
803 public int
804 getSoloChannelCount() {
805 int count = 0;
806 for(SamplerChannelModel m : channelModels)
807 if(m.getChannelInfo().isSoloChannel()) count++;
808
809 return count;
810 }
811
812 /**
813 * Gets the number of muted channels in the current list of sampler channels.
814 * This number includes the channels muted because of the presence of a solo channel.
815 * @return The number of muted channels in the current list of sampler channels.
816 */
817 public int
818 getMutedChannelCount() {
819 int count = 0;
820 for(SamplerChannelModel m : channelModels)
821 if(m.getChannelInfo().isMuted()) count++;
822
823 return count;
824 }
825
826 /**
827 * Gets the number of channels muted because of the presence of a solo channel.
828 * @return The number of channels muted because of the presence of a solo channel.
829 */
830 public int
831 getMutedBySoloChannelCount() {
832 int count = 0;
833 for(SamplerChannelModel m : channelModels)
834 if(m.getChannelInfo().isMutedBySolo()) count++;
835
836 return count;
837 }
838
839 /**
840 * Gets the total number of active streams.
841 * @return The total number of active streams.
842 */
843 public int
844 getTotalStreamCount() { return totalStreamCount; }
845
846 /**
847 * Gets the total number of active voices.
848 * @return The total number of active voices.
849 */
850 public int
851 getTotalVoiceCount() { return totalVoiceCount; }
852
853 /**
854 * Gets the maximum number of active voices.
855 * @return The maximum number of active voices.
856 */
857 public int
858 getTotalVoiceCountMax() { return totalVoiceCountMax; }
859
860 /**
861 * Gets the golobal volume of the sampler.
862 * @return The golobal volume of the sampler.
863 */
864 public float
865 getVolume() { return volume; }
866
867 /**
868 * Sets the global volume.
869 * @param volume The new volume value.
870 */
871 public void
872 setVolume(float volume) {
873 if(this.volume == volume) return;
874
875 this.volume = volume;
876 fireVolumeChanged();
877 }
878
879 /**
880 * Schedules a new task for setting the global volume on the backend side.
881 * @param volume The new volume value.
882 */
883 public void
884 setBackendVolume(float volume) {
885 CC.getTaskQueue().add(new Global.SetVolume(volume));
886 }
887
888 /**
889 * Schedules a new task for resetting the sampler.
890 */
891 public void
892 resetBackend() { CC.getTaskQueue().add(new org.jsampler.task.Global.ResetSampler()); }
893
894 /**
895 * Updates the current number of active disk streams in the sampler.
896 * @param count The new number of active streams.
897 */
898 public void
899 updateActiveStreamsInfo(int count) {
900 if(totalStreamCount == count) return;
901
902 totalStreamCount = count;
903 fireTotalStreamCountChanged();
904 }
905
906 /**
907 * Updates the current and the maximum number of active voices in the sampler.
908 * @param count The new number of active voices.
909 * @param countMax The maximum number of active voices.
910 */
911 public void
912 updateActiveVoiceInfo(int count, int countMax) {
913 if(totalVoiceCount == count && totalVoiceCountMax == countMax) return;
914
915 totalVoiceCount = count;
916 totalVoiceCountMax = countMax;
917 fireTotalVoiceCountChanged();
918 }
919
920 /**
921 * Determines whether the sampler configuration is modified.
922 */
923 public boolean
924 isModified() { return modified; }
925
926 /**
927 * Sets whether the sampler configuration is modified.
928 */
929 public void
930 setModified(boolean b) { modified = b; }
931
932 /** Resets the model. */
933 public void
934 reset() {
935 removeAllMidiInstrumentMaps();
936
937 for(int i = channelModels.size() - 1; i >= 0; i--) {
938 SamplerChannelModel m = channelModels.get(i);
939 channelModels.remove(i);
940 fireSamplerChannelRemoved(m);
941 }
942
943 for(int i = midiDeviceModels.size() - 1; i >= 0; i--) {
944 MidiDeviceModel m = midiDeviceModels.get(i);
945 midiDeviceModels.remove(i);
946 fireMidiDeviceRemoved(m);
947 }
948
949 for(int i = audioDeviceModels.size() - 1; i >= 0; i--) {
950 AudioDeviceModel m = audioDeviceModels.get(i);
951 audioDeviceModels.remove(i);
952 fireAudioDeviceRemoved(m);
953 }
954
955 setServerInfo(null);
956 setAudioOutputDrivers(null);
957 setMidiInputDrivers(null);
958 setEngines(null);
959
960 setVolume(0);
961 setModified(false);
962
963 totalStreamCount = 0;
964 totalVoiceCount = 0;
965 totalVoiceCountMax = 0;
966
967 fireTotalStreamCountChanged();
968 fireTotalVoiceCountChanged();
969 fireDefaultMapChanged();
970 }
971
972 /**
973 * Notifies listeners that a sampler channel has been added.
974 * This method can be invoked outside the event-dispatching thread.
975 * @param channelModel A <code>SamplerChannelModel</code> instance.
976 */
977 private void
978 fireSamplerChannelAdded(SamplerChannelModel channelModel) {
979 final SamplerChannelListEvent e = new SamplerChannelListEvent(this, channelModel);
980
981 SwingUtilities.invokeLater(new Runnable() {
982 public void
983 run() { fireSamplerChannelAdded(e); }
984 });
985 }
986 /**
987 * Notifies listeners that a sampler channel has been added.
988 */
989 private void
990 fireSamplerChannelAdded(SamplerChannelListEvent e) {
991 setModified(true);
992 Object[] listeners = listenerList.getListenerList();
993
994 for(int i = listeners.length - 2; i >= 0; i -= 2) {
995 if(listeners[i] == SamplerChannelListListener.class) {
996 ((SamplerChannelListListener)listeners[i + 1]).channelAdded(e);
997 }
998 }
999 }
1000
1001 /**
1002 * Notifies listeners that a sampler channel has been removed.
1003 * This method can be invoked outside the event-dispatching thread.
1004 * @param channelModel A <code>SamplerChannelModel</code> instance.
1005 */
1006 private void
1007 fireSamplerChannelRemoved(SamplerChannelModel channelModel) {
1008 final SamplerChannelListEvent e = new SamplerChannelListEvent(this, channelModel);
1009
1010 SwingUtilities.invokeLater(new Runnable() {
1011 public void
1012 run() { fireSamplerChannelRemoved(e); }
1013 });
1014 }
1015
1016 /**
1017 * Notifies listeners that a sampler channel has been removed.
1018 */
1019 private void
1020 fireSamplerChannelRemoved(SamplerChannelListEvent e) {
1021 setModified(true);
1022 Object[] listeners = listenerList.getListenerList();
1023
1024 for(int i = listeners.length - 2; i >= 0; i -= 2) {
1025 if(listeners[i] == SamplerChannelListListener.class) {
1026 ((SamplerChannelListListener)listeners[i + 1]).channelRemoved(e);
1027 }
1028 }
1029 }
1030
1031 /**
1032 * Notifies listeners that a MIDI device has been added.
1033 * This method can be invoked outside the event-dispatching thread.
1034 * @param model A <code>MidiDeviceModel</code> instance.
1035 */
1036 private void
1037 fireMidiDeviceAdded(MidiDeviceModel model) {
1038 final MidiDeviceListEvent e = new MidiDeviceListEvent(this, model);
1039
1040 SwingUtilities.invokeLater(new Runnable() {
1041 public void
1042 run() { fireMidiDeviceAdded(e); }
1043 });
1044 }
1045 /**
1046 * Notifies listeners that a MIDI device has been added.
1047 */
1048 private void
1049 fireMidiDeviceAdded(MidiDeviceListEvent e) {
1050 setModified(true);
1051 Object[] listeners = listenerList.getListenerList();
1052
1053 for(int i = listeners.length - 2; i >= 0; i -= 2) {
1054 if(listeners[i] == MidiDeviceListListener.class) {
1055 ((MidiDeviceListListener)listeners[i + 1]).deviceAdded(e);
1056 }
1057 }
1058 }
1059
1060 /**
1061 * Notifies listeners that a MIDI device has been removed.
1062 * This method can be invoked outside the event-dispatching thread.
1063 * @param model A <code>MidiDeviceModel</code> instance.
1064 */
1065 private void
1066 fireMidiDeviceRemoved(MidiDeviceModel model) {
1067 final MidiDeviceListEvent e = new MidiDeviceListEvent(this, model);
1068
1069 SwingUtilities.invokeLater(new Runnable() {
1070 public void
1071 run() { fireMidiDeviceRemoved(e); }
1072 });
1073 }
1074
1075 /**
1076 * Notifies listeners that a MIDI device has been removed.
1077 */
1078 private void
1079 fireMidiDeviceRemoved(MidiDeviceListEvent e) {
1080 setModified(true);
1081 Object[] listeners = listenerList.getListenerList();
1082
1083 for(int i = listeners.length - 2; i >= 0; i -= 2) {
1084 if(listeners[i] == MidiDeviceListListener.class) {
1085 ((MidiDeviceListListener)listeners[i + 1]).deviceRemoved(e);
1086 }
1087 }
1088 }
1089
1090 /**
1091 * Notifies listeners that an audio device has been added.
1092 * This method can be invoked outside the event-dispatching thread.
1093 * @param model A <code>AudioDeviceModel</code> instance.
1094 */
1095 private void
1096 fireAudioDeviceAdded(AudioDeviceModel model) {
1097 final ListEvent<AudioDeviceModel> e = new ListEvent<AudioDeviceModel>(this, model);
1098
1099 SwingUtilities.invokeLater(new Runnable() {
1100 public void
1101 run() { fireAudioDeviceAdded(e); }
1102 });
1103 }
1104
1105 /**
1106 * Notifies listeners that an audio device has been added.
1107 */
1108 private void
1109 fireAudioDeviceAdded(ListEvent<AudioDeviceModel> e) {
1110 setModified(true);
1111 Object[] listeners = listenerList.getListenerList();
1112
1113 for(int i = listeners.length - 2; i >= 0; i -= 2) {
1114 if(listeners[i] == ListListener.class) {
1115 ((ListListener<AudioDeviceModel>)listeners[i + 1]).entryAdded(e);
1116 }
1117 }
1118 }
1119
1120 /**
1121 * Notifies listeners that an audio device has been removed.
1122 * This method can be invoked outside the event-dispatching thread.
1123 * @param model A <code>AudioDeviceModel</code> instance.
1124 */
1125 private void
1126 fireAudioDeviceRemoved(AudioDeviceModel model) {
1127 final ListEvent<AudioDeviceModel> e = new ListEvent<AudioDeviceModel>(this, model);
1128
1129 SwingUtilities.invokeLater(new Runnable() {
1130 public void
1131 run() { fireAudioDeviceRemoved(e); }
1132 });
1133 }
1134
1135 /**
1136 * Notifies listeners that an audio device has been removed.
1137 * This method should be invoked from the event-dispatching thread.
1138 */
1139 private void
1140 fireAudioDeviceRemoved(ListEvent<AudioDeviceModel> e) {
1141 setModified(true);
1142 Object[] listeners = listenerList.getListenerList();
1143
1144 for(int i = listeners.length - 2; i >= 0; i -= 2) {
1145 if(listeners[i] == ListListener.class) {
1146 ((ListListener<AudioDeviceModel>)listeners[i + 1]).entryRemoved(e);
1147 }
1148 }
1149 }
1150
1151 /**
1152 * Notifies listeners that a MIDI instrument map has been added to the list.
1153 * This method can be invoked outside the event-dispatching thread.
1154 */
1155 private void
1156 fireMidiInstrumentMapAdded(MidiInstrumentMap map) {
1157 final ListEvent<MidiInstrumentMap> e = new ListEvent<MidiInstrumentMap>(this, map);
1158
1159 SwingUtilities.invokeLater(new Runnable() {
1160 public void
1161 run() { fireMidiInstrumentMapAdded(e); }
1162 });
1163 }
1164
1165 /** Notifies listeners that a MIDI instrument map has been added to the list. */
1166 private void
1167 fireMidiInstrumentMapAdded(ListEvent<MidiInstrumentMap> e) {
1168 setModified(true);
1169 for(ListListener<MidiInstrumentMap> l : mapsListeners) l.entryAdded(e);
1170 }
1171
1172 /**
1173 * Notifies listeners that a MIDI instrument map has been removed from the list.
1174 * This method can be invoked outside the event-dispatching thread.
1175 */
1176 private void
1177 fireMidiInstrumentMapRemoved(MidiInstrumentMap map) {
1178 final ListEvent<MidiInstrumentMap> e = new ListEvent<MidiInstrumentMap>(this, map);
1179
1180 SwingUtilities.invokeLater(new Runnable() {
1181 public void
1182 run() { fireMidiInstrumentMapRemoved(e); }
1183 });
1184 }
1185 /** Notifies listeners that a MIDI instrument map has been removed from the list. */
1186 private void
1187 fireMidiInstrumentMapRemoved(ListEvent<MidiInstrumentMap> e) {
1188 setModified(true);
1189 for(ListListener<MidiInstrumentMap> l : mapsListeners) l.entryRemoved(e);
1190 }
1191
1192 /**
1193 * Notifies listeners that the global volume has changed.
1194 * This method can be invoked outside the event-dispatching thread.
1195 */
1196 private void
1197 fireVolumeChanged() {
1198 final SamplerEvent e = new SamplerEvent(this);
1199
1200 SwingUtilities.invokeLater(new Runnable() {
1201 public void
1202 run() { fireVolumeChanged(e); }
1203 });
1204 }
1205
1206 /**
1207 * Notifies listeners that the global volume has changed.
1208 */
1209 private void
1210 fireVolumeChanged(SamplerEvent e) {
1211 setModified(true);
1212 for(SamplerListener l : listeners) l.volumeChanged(e);
1213 }
1214
1215 /*
1216 * Notifies listeners that the total number of active streams has changed.
1217 * This method can be invoked outside the event-dispatching thread.
1218 */
1219 private void
1220 fireTotalStreamCountChanged() {
1221 final SamplerEvent e = new SamplerEvent(this);
1222
1223 SwingUtilities.invokeLater(new Runnable() {
1224 public void
1225 run() { fireTotalStreamCountChanged(e); }
1226 });
1227 }
1228
1229 /**
1230 * Notifies listeners that the total number of active streams has changed.
1231 */
1232 private void
1233 fireTotalStreamCountChanged(SamplerEvent e) {
1234 for(SamplerListener l : listeners) l.totalStreamCountChanged(e);
1235 }
1236
1237 /*
1238 * Notifies listeners that the total number of active voices has changed.
1239 * This method can be invoked outside the event-dispatching thread.
1240 */
1241 private void
1242 fireTotalVoiceCountChanged() {
1243 final SamplerEvent e = new SamplerEvent(this);
1244
1245 SwingUtilities.invokeLater(new Runnable() {
1246 public void
1247 run() { fireTotalVoiceCountChanged(e); }
1248 });
1249 }
1250
1251 /**
1252 * Notifies listeners that the total number of active voices has changed.
1253 */
1254 private void
1255 fireTotalVoiceCountChanged(SamplerEvent e) {
1256 for(SamplerListener l : listeners) l.totalVoiceCountChanged(e);
1257 }
1258
1259 /**
1260 * Notifies listeners that the default MIDI instrument map is changed.
1261 */
1262 private void
1263 fireDefaultMapChanged() {
1264 SamplerEvent e = new SamplerEvent(this);
1265 for(SamplerListener l : listeners) l.defaultMapChanged(e);
1266 }
1267
1268 private final Handler handler = new Handler();
1269
1270 private Handler
1271 getHandler() { return handler; }
1272
1273 private class Handler implements ListListener<MidiInstrumentMap> {
1274 /** Invoked when a new map is added to a list. */
1275 public void
1276 entryAdded(ListEvent<MidiInstrumentMap> e) { updateDefaultMap(); }
1277
1278 /** Invoked when a map is removed from a list. */
1279 public void
1280 entryRemoved(ListEvent<MidiInstrumentMap> e) { updateDefaultMap(); }
1281
1282 private void
1283 updateDefaultMap() {
1284 if(getDefaultMidiInstrumentMap() != findDefaultMidiInstrumentMap()) {
1285 defaultMidiInstrumentMap = findDefaultMidiInstrumentMap();
1286 fireDefaultMapChanged();
1287 }
1288 }
1289 }
1290 }

  ViewVC Help
Powered by ViewVC