/[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 1688 - (show annotations) (download)
Thu Feb 14 16:52:36 2008 UTC (16 years, 1 month ago) by iliev
File size: 37201 byte(s)
* Implemented a backend list with option to manually choose a backend
  to connect on startup(Edit/Preferences, then click the `Backend' tab)
  and option to change the backend without restarting JSampler
  (Actions/Change Backend or Ctrl + B)

* Added confirmation messages for removing sampler channels and
  audio/MIDI devices (Edit/Preferences, then click the `View' tab)

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

  ViewVC Help
Powered by ViewVC