/[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 2288 - (show annotations) (download)
Wed Nov 23 21:19:44 2011 UTC (12 years, 4 months ago) by iliev
File size: 40471 byte(s)
* Added option to select a sampler engine in Add/Edit Instrument dialog
* Moved all Swing dependent code outside the JSampler core

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

  ViewVC Help
Powered by ViewVC