/[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 1818 - (show annotations) (download)
Wed Dec 24 17:29:47 2008 UTC (15 years, 4 months ago) by iliev
File size: 39699 byte(s)
* Added support for controlling the global sampler-wide limit of
  maximum voices and disk streams
  (choose Edit/Preferences, then click the `General' tab)
* Fantasia: store the view configuration of audio/MIDI devices and sampler
  channels in the LSCP script when exporting sampler configuration
* Fantasia: Implemented multiple sampler channels' selection
* Fantasia: Added option to move sampler channels up and down
  in the channels list
* Fantasia: Added option to move sampler channels
  to another channels panels

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

  ViewVC Help
Powered by ViewVC