/[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 1880 - (show annotations) (download)
Sun Mar 29 19:10:49 2009 UTC (15 years ago) by iliev
File size: 39777 byte(s)
* fixed bug in the sampler channel number notifications

1 /*
2 * JSampler - a java front-end for LinuxSampler
3 *
4 * Copyright (C) 2005-2009 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;
757 model = (channel == null) ? null : new DefaultSamplerChannelModel(channel);
758 if(model != null) channelModels.add(model);
759 fireSamplerChannelAdded(model);
760 }
761
762 /**
763 * Updates the settings of the specified channel.
764 * @param channel A <code>SamplerChannel</code> instance containing the new settings
765 * for the channel.
766 */
767 @Override
768 public void
769 updateChannel(SamplerChannel channel) {
770 for(SamplerChannelModel m : channelModels) {
771 if(m.getChannelId() == channel.getChannelId()) {
772 m.setChannelInfo(channel);
773 return;
774 }
775 }
776
777 CC.getLogger().log (
778 Level.WARNING, "DefaultSamplerModel.unknownChannel!", channel.getChannelId()
779 );
780 }
781
782 /**
783 * Determines whether there are known upcoming changes to the
784 * channel list, which should be considered as part of a single action.
785 */
786 @Override
787 public synchronized boolean
788 getChannelListIsAdjusting() { return channelListIsAdjusting; }
789
790 /**
791 * Sets whether the upcoming changes to the
792 * channel list should be considered part of a single action.
793 */
794 @Override
795 public synchronized void
796 setChannelListIsAdjusting(boolean b) {
797 channelListIsAdjusting = b;
798 }
799
800 /**
801 * Removes the specified sampler channel.
802 * Note that this method doesn't remove the channel in the backend,
803 * it is used to remove the channel from the model when those channel
804 * is removed in the backend.
805 * @param channelId The ID of the channel to be removed.
806 * @return <code>true</code> if the channel is removed successfully, <code>false</code>
807 * if the channel's list does not contain channel with ID <code>channelId</code>.
808 */
809 @Override
810 public boolean
811 removeChannelById(int channelId) {
812 for(int i = 0; i < channelModels.size(); i++) {
813 SamplerChannelModel m = channelModels.get(i);
814 if(m.getChannelId() == channelId) {
815 channelModels.remove(i);
816 fireSamplerChannelRemoved(m);
817 return true;
818 }
819 }
820
821 return false;
822 }
823
824 /**
825 * Removes all sampler channels.
826 * Note that this method doesn't remove the channel in the backend.
827 */
828 @Override
829 public void
830 removeAllChannels() {
831 if(channelModels.size() == 0) return;
832
833 setChannelListIsAdjusting(true);
834 for(int i = channelModels.size() - 1; i > 0; i--) {
835 SamplerChannelModel m = channelModels.get(i);
836 channelModels.remove(i);
837 fireSamplerChannelRemoved(m);
838 }
839 setChannelListIsAdjusting(false);
840
841 SamplerChannelModel m = channelModels.get(0);
842 channelModels.remove(0);
843 fireSamplerChannelRemoved(m);
844 }
845
846 /**
847 * Schedules a new task for removing the specified sampler channel on the backend side.
848 * @param channelId The ID of the channel to be removed.
849 */
850 @Override
851 public void
852 removeBackendChannel(int channelId) {
853 CC.getTaskQueue().add(new Channel.Remove(channelId));
854 }
855
856 /**
857 * Schedules a new task for starting an instrument editor for editing
858 * the loaded instrument on the specified sampler channel.
859 * @param channelId The sampler channel number.
860 */
861 @Override
862 public void
863 editBackendInstrument(int channelId) {
864 CC.getTaskQueue().add(new Channel.EditInstrument(channelId));
865 }
866
867 /**
868 * Determines whether there is at least one solo channel in the current list
869 * of sampler channels.
870 * @return <code>true</code> if there is at least one solo channel in the current list of
871 * sampler channels, <code>false</code> otherwise.
872 */
873 @Override
874 public boolean
875 hasSoloChannel() {
876 for(SamplerChannelModel m : channelModels)
877 if(m.getChannelInfo().isSoloChannel()) return true;
878
879 return false;
880 }
881
882 /**
883 * Gets the number of solo channels in the current list of sampler channels.
884 * @return The number of solo channels in the current list of sampler channels.
885 */
886 @Override
887 public int
888 getSoloChannelCount() {
889 int count = 0;
890 for(SamplerChannelModel m : channelModels)
891 if(m.getChannelInfo().isSoloChannel()) count++;
892
893 return count;
894 }
895
896 /**
897 * Gets the number of muted channels in the current list of sampler channels.
898 * This number includes the channels muted because of the presence of a solo channel.
899 * @return The number of muted channels in the current list of sampler channels.
900 */
901 @Override
902 public int
903 getMutedChannelCount() {
904 int count = 0;
905 for(SamplerChannelModel m : channelModels)
906 if(m.getChannelInfo().isMuted()) count++;
907
908 return count;
909 }
910
911 /**
912 * Gets the number of channels muted because of the presence of a solo channel.
913 * @return The number of channels muted because of the presence of a solo channel.
914 */
915 @Override
916 public int
917 getMutedBySoloChannelCount() {
918 int count = 0;
919 for(SamplerChannelModel m : channelModels)
920 if(m.getChannelInfo().isMutedBySolo()) count++;
921
922 return count;
923 }
924
925 /**
926 * Gets the total number of active streams.
927 * @return The total number of active streams.
928 */
929 @Override
930 public int
931 getTotalStreamCount() { return totalStreamCount; }
932
933 /**
934 * Gets the total number of active voices.
935 * @return The total number of active voices.
936 */
937 @Override
938 public int
939 getTotalVoiceCount() { return totalVoiceCount; }
940
941 /**
942 * Gets the maximum number of active voices.
943 * @return The maximum number of active voices.
944 */
945 @Override
946 public int
947 getTotalVoiceCountMax() { return totalVoiceCountMax; }
948
949 /**
950 * Gets the golobal volume of the sampler.
951 * @return The golobal volume of the sampler.
952 */
953 @Override
954 public float
955 getVolume() { return volume; }
956
957 /**
958 * Sets the global volume.
959 * @param volume The new volume value.
960 */
961 @Override
962 public void
963 setVolume(float volume) {
964 if(this.volume == volume) return;
965
966 this.volume = volume;
967 fireVolumeChanged();
968 }
969
970 /**
971 * Schedules a new task for setting the global volume on the backend side.
972 * @param volume The new volume value.
973 */
974 @Override
975 public void
976 setBackendVolume(float volume) {
977 CC.getTaskQueue().add(new Global.SetVolume(volume));
978 }
979
980 /**
981 * Schedules a new task for resetting the sampler.
982 */
983 @Override
984 public void
985 resetBackend() { CC.getTaskQueue().add(new org.jsampler.task.Global.ResetSampler()); }
986
987 /**
988 * Updates the current number of active disk streams in the sampler.
989 * @param count The new number of active streams.
990 */
991 @Override
992 public void
993 updateActiveStreamsInfo(int count) {
994 if(totalStreamCount == count) return;
995
996 totalStreamCount = count;
997 fireTotalStreamCountChanged();
998 }
999
1000 /**
1001 * Updates the current and the maximum number of active voices in the sampler.
1002 * @param count The new number of active voices.
1003 * @param countMax The maximum number of active voices.
1004 */
1005 @Override
1006 public void
1007 updateActiveVoiceInfo(int count, int countMax) {
1008 if(totalVoiceCount == count && totalVoiceCountMax == countMax) return;
1009
1010 totalVoiceCount = count;
1011 totalVoiceCountMax = countMax;
1012 fireTotalVoiceCountChanged();
1013 }
1014
1015 /**
1016 * Determines whether the sampler configuration is modified.
1017 */
1018 @Override
1019 public boolean
1020 isModified() { return modified; }
1021
1022 /**
1023 * Sets whether the sampler configuration is modified.
1024 */
1025 @Override
1026 public void
1027 setModified(boolean b) { modified = b; }
1028
1029 /** Resets the model. */
1030 @Override
1031 public void
1032 reset() {
1033 removeAllMidiInstrumentMaps();
1034
1035 for(int i = channelModels.size() - 1; i >= 0; i--) {
1036 SamplerChannelModel m = channelModels.get(i);
1037 channelModels.remove(i);
1038 fireSamplerChannelRemoved(m);
1039 }
1040
1041 for(int i = midiDeviceModels.size() - 1; i >= 0; i--) {
1042 MidiDeviceModel m = midiDeviceModels.get(i);
1043 midiDeviceModels.remove(i);
1044 fireMidiDeviceRemoved(m);
1045 }
1046
1047 for(int i = audioDeviceModels.size() - 1; i >= 0; i--) {
1048 AudioDeviceModel m = audioDeviceModels.get(i);
1049 audioDeviceModels.remove(i);
1050 fireAudioDeviceRemoved(m);
1051 }
1052
1053 setServerInfo(null);
1054 setAudioOutputDrivers(null);
1055 setMidiInputDrivers(null);
1056 setEngines(null);
1057
1058 setVolume(0);
1059 setModified(false);
1060
1061 totalStreamCount = 0;
1062 totalVoiceCount = 0;
1063 totalVoiceCountMax = 0;
1064
1065 fireTotalStreamCountChanged();
1066 fireTotalVoiceCountChanged();
1067 fireDefaultMapChanged();
1068 }
1069
1070 /**
1071 * Notifies listeners that a sampler channel has been added.
1072 * This method can be invoked outside the event-dispatching thread.
1073 * @param channelModel A <code>SamplerChannelModel</code> instance.
1074 */
1075 private void
1076 fireSamplerChannelAdded(SamplerChannelModel channelModel) {
1077 final SamplerChannelListEvent e = new SamplerChannelListEvent(this, channelModel);
1078
1079 SwingUtilities.invokeLater(new Runnable() {
1080 public void
1081 run() { fireSamplerChannelAdded(e); }
1082 });
1083 }
1084 /**
1085 * Notifies listeners that a sampler channel has been added.
1086 */
1087 private void
1088 fireSamplerChannelAdded(SamplerChannelListEvent e) {
1089 setModified(true);
1090 Object[] listeners = listenerList.getListenerList();
1091
1092 for(int i = listeners.length - 2; i >= 0; i -= 2) {
1093 if(listeners[i] == SamplerChannelListListener.class) {
1094 ((SamplerChannelListListener)listeners[i + 1]).channelAdded(e);
1095 }
1096 }
1097 }
1098
1099 /**
1100 * Notifies listeners that a sampler channel has been removed.
1101 * This method can be invoked outside the event-dispatching thread.
1102 * @param channelModel A <code>SamplerChannelModel</code> instance.
1103 */
1104 private void
1105 fireSamplerChannelRemoved(SamplerChannelModel channelModel) {
1106 final SamplerChannelListEvent e = new SamplerChannelListEvent(this, channelModel);
1107
1108 SwingUtilities.invokeLater(new Runnable() {
1109 public void
1110 run() { fireSamplerChannelRemoved(e); }
1111 });
1112 }
1113
1114 /**
1115 * Notifies listeners that a sampler channel has been removed.
1116 */
1117 private void
1118 fireSamplerChannelRemoved(SamplerChannelListEvent e) {
1119 setModified(true);
1120 Object[] listeners = listenerList.getListenerList();
1121
1122 for(int i = listeners.length - 2; i >= 0; i -= 2) {
1123 if(listeners[i] == SamplerChannelListListener.class) {
1124 ((SamplerChannelListListener)listeners[i + 1]).channelRemoved(e);
1125 }
1126 }
1127 }
1128
1129 /**
1130 * Notifies listeners that a MIDI device has been added.
1131 * This method can be invoked outside the event-dispatching thread.
1132 * @param model A <code>MidiDeviceModel</code> instance.
1133 */
1134 private void
1135 fireMidiDeviceAdded(MidiDeviceModel model) {
1136 final MidiDeviceListEvent e = new MidiDeviceListEvent(this, model);
1137
1138 SwingUtilities.invokeLater(new Runnable() {
1139 public void
1140 run() { fireMidiDeviceAdded(e); }
1141 });
1142 }
1143 /**
1144 * Notifies listeners that a MIDI device has been added.
1145 */
1146 private void
1147 fireMidiDeviceAdded(MidiDeviceListEvent e) {
1148 setModified(true);
1149 Object[] listeners = listenerList.getListenerList();
1150
1151 for(int i = listeners.length - 2; i >= 0; i -= 2) {
1152 if(listeners[i] == MidiDeviceListListener.class) {
1153 ((MidiDeviceListListener)listeners[i + 1]).deviceAdded(e);
1154 }
1155 }
1156 }
1157
1158 /**
1159 * Notifies listeners that a MIDI device has been removed.
1160 * This method can be invoked outside the event-dispatching thread.
1161 * @param model A <code>MidiDeviceModel</code> instance.
1162 */
1163 private void
1164 fireMidiDeviceRemoved(MidiDeviceModel model) {
1165 final MidiDeviceListEvent e = new MidiDeviceListEvent(this, model);
1166
1167 SwingUtilities.invokeLater(new Runnable() {
1168 public void
1169 run() { fireMidiDeviceRemoved(e); }
1170 });
1171 }
1172
1173 /**
1174 * Notifies listeners that a MIDI device has been removed.
1175 */
1176 private void
1177 fireMidiDeviceRemoved(MidiDeviceListEvent e) {
1178 setModified(true);
1179 Object[] listeners = listenerList.getListenerList();
1180
1181 for(int i = listeners.length - 2; i >= 0; i -= 2) {
1182 if(listeners[i] == MidiDeviceListListener.class) {
1183 ((MidiDeviceListListener)listeners[i + 1]).deviceRemoved(e);
1184 }
1185 }
1186 }
1187
1188 /**
1189 * Notifies listeners that an audio device has been added.
1190 * This method can be invoked outside the event-dispatching thread.
1191 * @param model A <code>AudioDeviceModel</code> instance.
1192 */
1193 private void
1194 fireAudioDeviceAdded(AudioDeviceModel model) {
1195 final ListEvent<AudioDeviceModel> e = new ListEvent<AudioDeviceModel>(this, model);
1196
1197 SwingUtilities.invokeLater(new Runnable() {
1198 public void
1199 run() { fireAudioDeviceAdded(e); }
1200 });
1201 }
1202
1203 /**
1204 * Notifies listeners that an audio device has been added.
1205 */
1206 private void
1207 fireAudioDeviceAdded(ListEvent<AudioDeviceModel> e) {
1208 setModified(true);
1209 Object[] listeners = listenerList.getListenerList();
1210
1211 for(int i = listeners.length - 2; i >= 0; i -= 2) {
1212 if(listeners[i] == ListListener.class) {
1213 ((ListListener<AudioDeviceModel>)listeners[i + 1]).entryAdded(e);
1214 }
1215 }
1216 }
1217
1218 /**
1219 * Notifies listeners that an audio device has been removed.
1220 * This method can be invoked outside the event-dispatching thread.
1221 * @param model A <code>AudioDeviceModel</code> instance.
1222 */
1223 private void
1224 fireAudioDeviceRemoved(AudioDeviceModel model) {
1225 final ListEvent<AudioDeviceModel> e = new ListEvent<AudioDeviceModel>(this, model);
1226
1227 SwingUtilities.invokeLater(new Runnable() {
1228 public void
1229 run() { fireAudioDeviceRemoved(e); }
1230 });
1231 }
1232
1233 /**
1234 * Notifies listeners that an audio device has been removed.
1235 * This method should be invoked from the event-dispatching thread.
1236 */
1237 private void
1238 fireAudioDeviceRemoved(ListEvent<AudioDeviceModel> e) {
1239 setModified(true);
1240 Object[] listeners = listenerList.getListenerList();
1241
1242 for(int i = listeners.length - 2; i >= 0; i -= 2) {
1243 if(listeners[i] == ListListener.class) {
1244 ((ListListener<AudioDeviceModel>)listeners[i + 1]).entryRemoved(e);
1245 }
1246 }
1247 }
1248
1249 /**
1250 * Notifies listeners that a MIDI instrument map has been added to the list.
1251 * This method can be invoked outside the event-dispatching thread.
1252 */
1253 private void
1254 fireMidiInstrumentMapAdded(MidiInstrumentMap map) {
1255 final ListEvent<MidiInstrumentMap> e = new ListEvent<MidiInstrumentMap>(this, map);
1256
1257 SwingUtilities.invokeLater(new Runnable() {
1258 public void
1259 run() { fireMidiInstrumentMapAdded(e); }
1260 });
1261 }
1262
1263 /** Notifies listeners that a MIDI instrument map has been added to the list. */
1264 private void
1265 fireMidiInstrumentMapAdded(ListEvent<MidiInstrumentMap> e) {
1266 setModified(true);
1267 for(ListListener<MidiInstrumentMap> l : mapsListeners) l.entryAdded(e);
1268 }
1269
1270 /**
1271 * Notifies listeners that a MIDI instrument map has been removed from the list.
1272 * This method can be invoked outside the event-dispatching thread.
1273 */
1274 private void
1275 fireMidiInstrumentMapRemoved(MidiInstrumentMap map) {
1276 final ListEvent<MidiInstrumentMap> e = new ListEvent<MidiInstrumentMap>(this, map);
1277
1278 SwingUtilities.invokeLater(new Runnable() {
1279 public void
1280 run() { fireMidiInstrumentMapRemoved(e); }
1281 });
1282 }
1283 /** Notifies listeners that a MIDI instrument map has been removed from the list. */
1284 private void
1285 fireMidiInstrumentMapRemoved(ListEvent<MidiInstrumentMap> e) {
1286 setModified(true);
1287 for(ListListener<MidiInstrumentMap> l : mapsListeners) l.entryRemoved(e);
1288 }
1289
1290 /**
1291 * Notifies listeners that the global volume has changed.
1292 * This method can be invoked outside the event-dispatching thread.
1293 */
1294 private void
1295 fireVolumeChanged() {
1296 final SamplerEvent e = new SamplerEvent(this);
1297
1298 SwingUtilities.invokeLater(new Runnable() {
1299 public void
1300 run() { fireVolumeChanged(e); }
1301 });
1302 }
1303
1304 /**
1305 * Notifies listeners that the global volume has changed.
1306 */
1307 private void
1308 fireVolumeChanged(SamplerEvent e) {
1309 setModified(true);
1310 for(SamplerListener l : listeners) l.volumeChanged(e);
1311 }
1312
1313 /*
1314 * Notifies listeners that the total number of active streams has changed.
1315 * This method can be invoked outside the event-dispatching thread.
1316 */
1317 private void
1318 fireTotalStreamCountChanged() {
1319 final SamplerEvent e = new SamplerEvent(this);
1320
1321 SwingUtilities.invokeLater(new Runnable() {
1322 public void
1323 run() { fireTotalStreamCountChanged(e); }
1324 });
1325 }
1326
1327 /**
1328 * Notifies listeners that the total number of active streams has changed.
1329 */
1330 private void
1331 fireTotalStreamCountChanged(SamplerEvent e) {
1332 for(SamplerListener l : listeners) l.totalStreamCountChanged(e);
1333 }
1334
1335 /*
1336 * Notifies listeners that the total number of active voices has changed.
1337 * This method can be invoked outside the event-dispatching thread.
1338 */
1339 private void
1340 fireTotalVoiceCountChanged() {
1341 final SamplerEvent e = new SamplerEvent(this);
1342
1343 SwingUtilities.invokeLater(new Runnable() {
1344 public void
1345 run() { fireTotalVoiceCountChanged(e); }
1346 });
1347 }
1348
1349 /**
1350 * Notifies listeners that the total number of active voices has changed.
1351 */
1352 private void
1353 fireTotalVoiceCountChanged(SamplerEvent e) {
1354 for(SamplerListener l : listeners) l.totalVoiceCountChanged(e);
1355 }
1356
1357 /**
1358 * Notifies listeners that the default MIDI instrument map is changed.
1359 */
1360 private void
1361 fireDefaultMapChanged() {
1362 SamplerEvent e = new SamplerEvent(this);
1363 for(SamplerListener l : listeners) l.defaultMapChanged(e);
1364 }
1365
1366 private final Handler handler = new Handler();
1367
1368 private Handler
1369 getHandler() { return handler; }
1370
1371 private class Handler implements ListListener<MidiInstrumentMap> {
1372 /** Invoked when a new map is added to a list. */
1373 @Override
1374 public void
1375 entryAdded(ListEvent<MidiInstrumentMap> e) { updateDefaultMap(); }
1376
1377 /** Invoked when a map is removed from a list. */
1378 @Override
1379 public void
1380 entryRemoved(ListEvent<MidiInstrumentMap> e) { updateDefaultMap(); }
1381
1382 private void
1383 updateDefaultMap() {
1384 if(getDefaultMidiInstrumentMap() != findDefaultMidiInstrumentMap()) {
1385 defaultMidiInstrumentMap = findDefaultMidiInstrumentMap();
1386 fireDefaultMapChanged();
1387 }
1388 }
1389 }
1390 }

  ViewVC Help
Powered by ViewVC