/[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 1467 - (show annotations) (download)
Sat Nov 3 13:14:31 2007 UTC (16 years, 5 months ago) by iliev
File size: 34702 byte(s)
* bugfix: The parameter changes were
  discarded when creating new audio/MIDI device
* bugfix: The orchestras changes were not saved for the next session
  when orchestras.xml does not exist in the JSampler's home directory
* bugfix: In some cases the sampler configuration was not exported
  properly to LSCP script
* Some minor bugfixes and enhancements

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

  ViewVC Help
Powered by ViewVC