/[svn]/jsampler/trunk/src/org/jsampler/CC.java
ViewVC logotype

Annotation of /jsampler/trunk/src/org/jsampler/CC.java

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1737 - (hide annotations) (download)
Thu May 8 17:26:19 2008 UTC (16 years ago) by iliev
File size: 39780 byte(s)
* Major memory optimizations when too many sampler channels are present

1 iliev 787 /*
2     * JSampler - a java front-end for LinuxSampler
3     *
4 iliev 1143 * Copyright (C) 2005-2007 Grigor Iliev <grigor@grigoriliev.com>
5 iliev 787 *
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.awt.event.ActionEvent;
26     import java.awt.event.ActionListener;
27    
28 iliev 911 import java.io.ByteArrayOutputStream;
29 iliev 1143 import java.io.File;
30     import java.io.FileInputStream;
31 iliev 787 import java.io.FileOutputStream;
32 iliev 1143 import java.io.InputStream;
33 iliev 787
34 iliev 911 import java.util.Vector;
35    
36 iliev 787 import java.util.logging.Handler;
37     import java.util.logging.Level;
38     import java.util.logging.Logger;
39     import java.util.logging.SimpleFormatter;
40     import java.util.logging.StreamHandler;
41    
42     import javax.swing.Timer;
43    
44 iliev 1688 import javax.swing.event.ChangeEvent;
45     import javax.swing.event.ChangeListener;
46    
47 iliev 911 import net.sf.juife.Task;
48     import net.sf.juife.TaskQueue;
49    
50     import net.sf.juife.event.TaskEvent;
51     import net.sf.juife.event.TaskListener;
52     import net.sf.juife.event.TaskQueueEvent;
53     import net.sf.juife.event.TaskQueueListener;
54    
55 iliev 1143 import org.jsampler.event.ListEvent;
56     import org.jsampler.event.ListListener;
57 iliev 911 import org.jsampler.event.OrchestraEvent;
58     import org.jsampler.event.OrchestraListener;
59    
60 iliev 787 import org.jsampler.task.*;
61    
62     import org.jsampler.view.JSMainFrame;
63     import org.jsampler.view.JSProgress;
64 iliev 1285 import org.jsampler.view.JSViewConfig;
65 iliev 1204 import org.jsampler.view.InstrumentsDbTreeModel;
66 iliev 787
67 iliev 1143 import org.linuxsampler.lscp.AudioOutputChannel;
68     import org.linuxsampler.lscp.AudioOutputDevice;
69 iliev 787 import org.linuxsampler.lscp.Client;
70 iliev 1143 import org.linuxsampler.lscp.FxSend;
71     import org.linuxsampler.lscp.MidiInputDevice;
72     import org.linuxsampler.lscp.MidiPort;
73     import org.linuxsampler.lscp.Parameter;
74     import org.linuxsampler.lscp.SamplerChannel;
75    
76 iliev 787 import org.linuxsampler.lscp.event.*;
77    
78 iliev 911 import org.w3c.dom.Document;
79     import org.w3c.dom.Node;
80 iliev 787
81 iliev 1143 import static org.jsampler.JSI18n.i18n;
82 iliev 787
83 iliev 1143
84 iliev 787 /**
85 iliev 911 * This class serves as a 'Control Center' of the application.
86     * It also provides some fundamental routines and access to most used objects.
87 iliev 787 * @author Grigor Iliev
88     */
89     public class CC {
90     private static Handler handler;
91 iliev 911 private static FileOutputStream fos;
92 iliev 787
93 iliev 1285 private static JSViewConfig viewConfig = null;
94 iliev 787 private static JSMainFrame mainFrame = null;
95     private static JSProgress progress = null;
96    
97     private final static Client lsClient = new Client();
98    
99 iliev 1143 private static String jSamplerHome = null;
100    
101 iliev 787 private final static TaskQueue taskQueue = new TaskQueue();
102 iliev 911 private final static Timer timer = new Timer(2000, null);
103 iliev 787
104 iliev 1143 /** Forbits the instantiation of this class. */
105     private
106     CC() { }
107 iliev 787
108 iliev 911 /**
109     * Returns the logger to be used for logging events.
110     * @return The logger to be used for logging events.
111     */
112 iliev 787 public static Logger
113     getLogger() {
114     return Logger.getLogger (
115     "org.jsampler",
116     "org.jsampler.langprops.LogsBundle"
117     );
118     }
119    
120 iliev 911 /**
121     * Returns the task queue to be used for scheduling tasks
122     * for execution out of the event-dispatching thread.
123     * @return The task queue to be used for scheduling tasks
124     * for execution out of the event-dispatching thread.
125     */
126 iliev 787 public static TaskQueue
127     getTaskQueue() { return taskQueue; }
128    
129 iliev 911 /**
130 iliev 1204 * Adds the specified task to the task queue. All task in the
131     * queue equal to the specified task are removed from the queue.
132     */
133     public static void
134     scheduleTask(Task t) {
135     while(getTaskQueue().removeTask(t)) { }
136    
137     getTaskQueue().add(t);
138     }
139    
140     /**
141 iliev 1734 * Adds the specified task to the task queue only if the last
142     * task in the is not equal to <code>t</code>.
143     */
144     public static void
145     addTask(Task t) {
146     Task[] tasks = getTaskQueue().getPendingTasks();
147     if(tasks.length > 0 && tasks[tasks.length - 1].equals(t)) return;
148     getTaskQueue().add(t);
149     }
150    
151     /**
152 iliev 1285 * Gets the configuration of the current view.
153     */
154     public static JSViewConfig
155     getViewConfig() { return viewConfig; }
156    
157 iliev 1688 private static JSPrefs
158     preferences() { return getViewConfig().preferences(); }
159    
160 iliev 1285 /**
161     * Sets the configuration of the current view.
162     */
163     public static void
164     setViewConfig(JSViewConfig viewConfig) { CC.viewConfig = viewConfig; }
165    
166     /**
167 iliev 911 * Returns the main window of this application.
168     * @return The main window of this application.
169     */
170 iliev 787 public static JSMainFrame
171     getMainFrame() { return mainFrame; }
172    
173 iliev 911 /**
174     * Sets the main window of this application.
175     * @param mainFrame The main window of this application.
176     */
177 iliev 787 public static void
178     setMainFrame(JSMainFrame mainFrame) { CC.mainFrame = mainFrame; }
179    
180 iliev 911 /**
181     * Gets the progress indicator of this application.
182     * @return The progress indicator of this application.
183     */
184 iliev 787 public static JSProgress
185     getProgressIndicator() { return progress; }
186    
187 iliev 911 /**
188     * Sets the progress indicator to be used by this application.
189     * @param progress The progress indicator to be used by this application.
190     */
191 iliev 787 public static void
192     setProgressIndicator(JSProgress progress) { CC.progress = progress; }
193    
194 iliev 911 /**
195 iliev 1143 * Gets the absolute path to the JSampler's home location.
196     * @return The absolute path to the JSampler's home location
197     * or <code>null</code> if the JSampler's home location is not specified yet.
198     */
199     public static String
200     getJSamplerHome() { return jSamplerHome; }
201    
202     /**
203     * Sets the location of the JSampler's home.
204     * @param path The new absolute path to the JSampler's home location.
205     */
206     public static void
207     setJSamplerHome(String path) {
208     jSamplerHome = path;
209     Prefs.setJSamplerHome(jSamplerHome);
210     }
211    
212     /**
213 iliev 911 * This method does the initial preparation of the application.
214     */
215 iliev 787 protected static void
216     initJSampler() {
217     fos = null;
218 iliev 1143 setJSamplerHome(Prefs.getJSamplerHome());
219     String s = getJSamplerHome();
220     try {
221     if(s != null) {
222     s += File.separator + "jsampler.log";
223     File f = new File(s);
224     if(f.isFile()) HF.createBackup("jsampler.log", "jsampler.log.0");
225     fos = new FileOutputStream(s);
226     }
227     } catch(Exception x) { x.printStackTrace(); }
228 iliev 787
229     if(fos == null) handler = new StreamHandler(System.out, new SimpleFormatter());
230     else handler = new StreamHandler(fos, new SimpleFormatter());
231    
232     handler.setLevel(Level.FINE);
233     getLogger().addHandler(handler);
234     getLogger().setLevel(Level.FINE);
235 iliev 1204 Logger.getLogger("org.linuxsampler.lscp").setLevel(Level.FINE);
236 iliev 787 Logger.getLogger("org.linuxsampler.lscp").addHandler(handler);
237    
238     // Flushing logs on every second
239     new java.util.Timer().schedule(new java.util.TimerTask() {
240     public void
241     run() { if(handler != null) handler.flush(); }
242     }, 1000, 1000);
243    
244     CC.getLogger().fine("CC.jsStarted");
245    
246     HF.setUIDefaultFont(Prefs.getInterfaceFont());
247    
248     timer.setRepeats(false);
249    
250     timer.addActionListener(new ActionListener() {
251     public void
252     actionPerformed(ActionEvent e) { CC.getProgressIndicator().start(); }
253     });
254    
255 iliev 911 taskQueue.addTaskQueueListener(getHandler());
256 iliev 787
257     taskQueue.start();
258    
259 iliev 1143 getClient().removeChannelCountListener(getHandler());
260 iliev 911 getClient().addChannelCountListener(getHandler());
261 iliev 1143
262     getClient().removeChannelInfoListener(getHandler());
263 iliev 911 getClient().addChannelInfoListener(getHandler());
264 iliev 1143
265     getClient().removeFxSendCountListener(getHandler());
266     getClient().addFxSendCountListener(getHandler());
267    
268     getClient().removeFxSendInfoListener(getHandler());
269     getClient().addFxSendInfoListener(getHandler());
270    
271     getClient().removeStreamCountListener(getHandler());
272 iliev 911 getClient().addStreamCountListener(getHandler());
273 iliev 1143
274     getClient().removeVoiceCountListener(getHandler());
275 iliev 911 getClient().addVoiceCountListener(getHandler());
276 iliev 1143
277 iliev 1545 getClient().removeTotalStreamCountListener(getHandler());
278     getClient().addTotalStreamCountListener(getHandler());
279    
280 iliev 1143 getClient().removeTotalVoiceCountListener(getHandler());
281 iliev 911 getClient().addTotalVoiceCountListener(getHandler());
282    
283 iliev 1143 getClient().removeAudioDeviceCountListener(audioDeviceCountListener);
284     getClient().addAudioDeviceCountListener(audioDeviceCountListener);
285 iliev 911
286 iliev 1143 getClient().removeAudioDeviceInfoListener(audioDeviceInfoListener);
287     getClient().addAudioDeviceInfoListener(audioDeviceInfoListener);
288    
289     getClient().removeMidiDeviceCountListener(midiDeviceCountListener);
290     getClient().addMidiDeviceCountListener(midiDeviceCountListener);
291    
292     getClient().removeMidiDeviceInfoListener(midiDeviceInfoListener);
293     getClient().addMidiDeviceInfoListener(midiDeviceInfoListener);
294    
295     getClient().removeMidiInstrumentMapCountListener(midiInstrMapCountListener);
296     getClient().addMidiInstrumentMapCountListener(midiInstrMapCountListener);
297    
298     getClient().removeMidiInstrumentMapInfoListener(midiInstrMapInfoListener);
299     getClient().addMidiInstrumentMapInfoListener(midiInstrMapInfoListener);
300    
301     getClient().removeMidiInstrumentCountListener(getHandler());
302     getClient().addMidiInstrumentCountListener(getHandler());
303    
304     getClient().removeMidiInstrumentInfoListener(getHandler());
305     getClient().addMidiInstrumentInfoListener(getHandler());
306    
307     getClient().removeGlobalInfoListener(getHandler());
308     getClient().addGlobalInfoListener(getHandler());
309     }
310    
311     /**
312     * Checks whether the JSampler home directory is specified and exist.
313     * If the JSampler home directory is not specifed, or is specified
314     * but doesn't exist, a procedure of specifying a JSampler home
315     * directory is initiated.
316     * @see org.jsampler.view.JSMainFrame#installJSamplerHome
317     */
318     public static void
319     checkJSamplerHome() {
320     if(getJSamplerHome() != null) {
321     File f = new File(getJSamplerHome());
322 iliev 1285 if(f.exists() && f.isDirectory()) {
323     return;
324     }
325 iliev 911 }
326 iliev 1143
327     CC.getMainFrame().installJSamplerHome();
328 iliev 787 }
329    
330 iliev 1143 /**
331     * Changes the JSampler's home directory and moves all files from
332     * the old JSampler's home directory to the new one. If all files are
333     * moved succesfully, the old directory is deleted.
334     * @param path The location of the new JSampler's home directory. If
335     * the last directory in the path doesn't exist, it is created.
336     */
337     public static void
338     changeJSamplerHome(String path) {
339     File fNew = new File(path);
340 iliev 1285 if(fNew.exists() && fNew.isFile()) {
341 iliev 1143 HF.showErrorMessage(i18n.getError("CC.JSamplerHomeIsNotDir!"));
342     return;
343     }
344    
345 iliev 1285 if(!fNew.exists()) {
346 iliev 1143 if(!fNew.mkdir()) {
347     String s = fNew.getAbsolutePath();
348     HF.showErrorMessage(i18n.getError("CC.mkdirFailed", s));
349     return;
350     }
351     }
352    
353 iliev 1285 if(getJSamplerHome() == null || path.equals(getJSamplerHome())) {
354 iliev 1143 setJSamplerHome(fNew.getAbsolutePath());
355     return;
356     }
357    
358     File fOld = new File(getJSamplerHome());
359 iliev 1285 if(!fOld.exists() || !fOld.isDirectory()) {
360 iliev 1143 setJSamplerHome(fNew.getAbsolutePath());
361     return;
362     }
363    
364     File[] files = fOld.listFiles();
365     boolean b = true;
366     if(files != null) {
367     String s = fNew.getAbsolutePath() + File.separator;
368     for(File f : files) if(!f.renameTo(new File(s + f.getName()))) b = false;
369     }
370    
371     if(b) fOld.delete();
372     setJSamplerHome(fNew.getAbsolutePath());
373     }
374    
375 iliev 911 private final static OrchestraListModel orchestras = new DefaultOrchestraListModel();
376    
377     /**
378     * Returns a list containing all available orchestras.
379     * @return A list containing all available orchestras.
380     */
381     public static OrchestraListModel
382     getOrchestras() { return orchestras; }
383    
384 iliev 1688 private final static ServerList servers = new ServerList();
385    
386     /** Returns the server list. */
387     public static ServerList
388     getServerList() { return servers; }
389    
390     private static ServerListListener serverListListener = new ServerListListener();
391    
392     private static class ServerListListener implements ChangeListener {
393     public void
394     stateChanged(ChangeEvent e) {
395     saveServerList();
396     }
397     }
398    
399     private static final Vector<ChangeListener> idtmListeners = new Vector<ChangeListener>();
400 iliev 1204 private static InstrumentsDbTreeModel instrumentsDbTreeModel = null;
401 iliev 1688
402 iliev 1143 /**
403 iliev 1204 * Gets the tree model of the instruments database.
404     * If the currently used view doesn't have instruments
405     * database support the tree model is initialized on first use.
406     * @return The tree model of the instruments database or
407     * <code>null</code> if the backend doesn't have instruments database support.
408 iliev 1327 * @see org.jsampler.view.JSViewConfig#getInstrumentsDbSupport
409 iliev 1204 */
410     public static InstrumentsDbTreeModel
411     getInstrumentsDbTreeModel() {
412 iliev 1729 if(CC.getSamplerModel().getServerInfo() == null) return null;
413 iliev 1204 if(!CC.getSamplerModel().getServerInfo().hasInstrumentsDbSupport()) return null;
414    
415     if(instrumentsDbTreeModel == null) {
416     instrumentsDbTreeModel = new InstrumentsDbTreeModel();
417 iliev 1688 for(ChangeListener l : idtmListeners) l.stateChanged(null);
418 iliev 1204 }
419    
420     return instrumentsDbTreeModel;
421     }
422    
423 iliev 1688 public static void
424     addInstrumentsDbChangeListener(ChangeListener l) {
425     idtmListeners.add(l);
426     }
427    
428     public static void
429     removeInstrumentsDbChangeListener(ChangeListener l) {
430     idtmListeners.remove(l);
431     }
432    
433 iliev 1729 private static final LostFilesModel lostFilesModel = new LostFilesModel();
434    
435     public static LostFilesModel
436     getLostFilesModel() { return lostFilesModel; }
437    
438 iliev 1204 /**
439 iliev 1143 * Loads the orchestras described in <code>&lt;jsampler_home&gt;/orchestras.xml</code>.
440     * If file with name <code>orchestras.xml.bkp</code> exist in the JSampler's home
441     * directory, this means that the last save has failed. In that case a recovery file
442     * <code>orchestras.xml.rec</code> is created and a recovery procedure
443     * will be initiated.
444     */
445     public static void
446     loadOrchestras() {
447     if(getJSamplerHome() == null) return;
448    
449     try {
450     String s = getJSamplerHome();
451    
452     File f = new File(s + File.separator + "orchestras.xml.bkp");
453     if(f.isFile()) HF.createBackup("orchestras.xml.bkp", "orchestras.xml.rec");
454    
455     FileInputStream fis;
456     fis = new FileInputStream(s + File.separator + "orchestras.xml");
457    
458     loadOrchestras(fis);
459     fis.close();
460     } catch(Exception x) {
461     getLogger().log(Level.INFO, HF.getErrorMessage(x), x);
462     }
463 iliev 1688
464     getOrchestras().addOrchestraListListener(getHandler());
465 iliev 1143 }
466    
467    
468 iliev 911 private static void
469 iliev 1143 loadOrchestras(InputStream in) {
470     Document doc = DOMUtils.readObject(in);
471    
472     try { getOrchestras().readObject(doc.getDocumentElement()); }
473     catch(Exception x) {
474     HF.showErrorMessage(x, "Loading orchestras: ");
475     return;
476     }
477    
478     for(int i = 0; i < getOrchestras().getOrchestraCount(); i++) {
479     getOrchestras().getOrchestra(i).addOrchestraListener(getHandler());
480     }
481     }
482    
483     private static void
484 iliev 911 saveOrchestras() {
485 iliev 1143 try {
486     String s = getJSamplerHome();
487     if(s == null) return;
488    
489     HF.createBackup("orchestras.xml", "orchestras.xml.bkp");
490    
491     FileOutputStream fos;
492     fos = new FileOutputStream(s + File.separator + "orchestras.xml", false);
493    
494     Document doc = DOMUtils.createEmptyDocument();
495 iliev 911
496 iliev 1143 Node node = doc.createElement("temp");
497     doc.appendChild(node);
498    
499     getOrchestras().writeObject(doc, doc.getDocumentElement());
500    
501     doc.replaceChild(node.getFirstChild(), node);
502 iliev 911
503 iliev 1143 DOMUtils.writeObject(doc, fos);
504    
505     fos.close();
506    
507     HF.deleteFile("orchestras.xml.bkp");
508     } catch(Exception x) {
509     HF.showErrorMessage(x, "Saving orchestras: ");
510     return;
511     }
512 iliev 911 }
513    
514     /**
515 iliev 1688 * Loads the servers' info described in <code>&lt;jsampler_home&gt;/servers.xml</code>.
516     * If file with name <code>servers.xml.bkp</code> exist in the JSampler's home
517     * directory, this means that the last save has failed. In that case a recovery file
518     * <code>servers.xml.rec</code> is created and a recovery procedure
519     * will be initiated.
520     */
521     public static void
522     loadServerList() {
523     if(getJSamplerHome() == null) return;
524    
525     try {
526     String s = getJSamplerHome();
527    
528     File f = new File(s + File.separator + "servers.xml.bkp");
529     if(f.isFile()) HF.createBackup("servers.xml.bkp", "servers.xml.rec");
530    
531     FileInputStream fis;
532     fis = new FileInputStream(s + File.separator + "servers.xml");
533    
534     loadServerList(fis);
535     fis.close();
536     } catch(Exception x) {
537     getLogger().log(Level.INFO, HF.getErrorMessage(x), x);
538     }
539    
540     getServerList().addChangeListener(serverListListener);
541    
542     /* We should have at least one server to connect. */
543     if(getServerList().getServerCount() == 0) {
544     Server server = new Server();
545     server.setName("127.0.0.1:8888");
546     server.setAddress("127.0.0.1");
547     server.setPort(8888);
548     getServerList().addServer(server);
549     }
550     }
551    
552    
553     private static void
554     loadServerList(InputStream in) {
555     Document doc = DOMUtils.readObject(in);
556    
557     try { getServerList().readObject(doc.getDocumentElement()); }
558     catch(Exception x) {
559     HF.showErrorMessage(x, "Loading server list: ");
560     return;
561     }
562     }
563    
564     private static void
565     saveServerList() {
566     try {
567     String s = getJSamplerHome();
568     if(s == null) return;
569    
570     HF.createBackup("servers.xml", "servers.xml.bkp");
571    
572     FileOutputStream fos;
573     fos = new FileOutputStream(s + File.separator + "servers.xml", false);
574    
575     Document doc = DOMUtils.createEmptyDocument();
576    
577     Node node = doc.createElement("temp");
578     doc.appendChild(node);
579    
580     getServerList().writeObject(doc, doc.getDocumentElement());
581    
582     doc.replaceChild(node.getFirstChild(), node);
583    
584     DOMUtils.writeObject(doc, fos);
585    
586     fos.close();
587    
588     HF.deleteFile("servers.xml.bkp");
589     } catch(Exception x) {
590     HF.showErrorMessage(x, "Saving server list: ");
591     return;
592     }
593     }
594    
595     /**
596 iliev 911 * The exit point of the application which ensures clean exit with default exit status 0.
597     * @see #cleanExit(int i)
598     */
599 iliev 787 public static void
600     cleanExit() { cleanExit(0); }
601    
602 iliev 911 /**
603     * The exit point of the application which ensures clean exit.
604     * @param i The exit status.
605     */
606 iliev 787 public static void
607     cleanExit(int i) {
608     CC.getLogger().fine("CC.jsEnded");
609     System.exit(i);
610     }
611    
612 iliev 911 /**
613     * Gets the <code>Client</code> object that is used to communicate with the backend.
614     * @return The <code>Client</code> object that is used to communicate with the backend.
615     */
616 iliev 787 public static Client
617     getClient() { return lsClient; }
618    
619 iliev 911 private static final Vector<ActionListener> listeners = new Vector<ActionListener>();
620 iliev 787
621 iliev 911 /**
622     * Registers the specified listener to be notified when reconnecting to LinuxSampler.
623     * @param l The <code>ActionListener</code> to register.
624     */
625     public static void
626     addReconnectListener(ActionListener l) { listeners.add(l); }
627    
628     /**
629     * Removes the specified listener.
630     * @param l The <code>ActionListener</code> to remove.
631     */
632     public static void
633     removeReconnectListener(ActionListener l) { listeners.remove(l); }
634    
635     private static void
636     fireReconnectEvent() {
637     ActionEvent e = new ActionEvent(CC.class, ActionEvent.ACTION_PERFORMED, null);
638     for(ActionListener l : listeners) l.actionPerformed(e);
639     }
640    
641 iliev 787 private static final SamplerModel samplerModel = new DefaultSamplerModel();
642    
643     /**
644     * Gets the sampler model.
645     * @return The sampler model.
646     */
647     public static SamplerModel
648     getSamplerModel() { return samplerModel; }
649    
650 iliev 911 /**
651 iliev 1688 * Connects to LinuxSampler.
652     */
653     public static void
654     connect() { initSamplerModel(); }
655    
656     /**
657 iliev 911 * Reconnects to LinuxSampler.
658     */
659 iliev 787 public static void
660 iliev 1688 reconnect() { initSamplerModel(getCurrentServer()); }
661    
662     private static Server currentServer = null;
663    
664     /**
665     * Gets the server, to which the frontend is going to connect
666     * or is already connected.
667     */
668     public static Server
669     getCurrentServer() { return currentServer; }
670    
671     /**
672     * Sets the current server.
673     */
674     public static void
675     setCurrentServer(Server server) { currentServer = server; }
676    
677     /**
678     * This method updates the information about the backend state.
679     */
680     private static void
681     initSamplerModel() {
682     Server srv = getMainFrame().getServer();
683     if(srv == null) return;
684     initSamplerModel(srv);
685 iliev 911 }
686    
687     /**
688     * This method updates the information about the backend state.
689     */
690 iliev 1688 private static void
691     initSamplerModel(Server srv) {
692     setCurrentServer(srv);
693     final SetServerAddress ssa = new SetServerAddress(srv.getAddress(), srv.getPort());
694    
695 iliev 787 final DefaultSamplerModel model = (DefaultSamplerModel)getSamplerModel();
696    
697 iliev 1204 final Global.GetServerInfo gsi = new Global.GetServerInfo();
698 iliev 787 gsi.addTaskListener(new TaskListener() {
699     public void
700     taskPerformed(TaskEvent e) {
701 iliev 1204 if(gsi.doneWithErrors()) return;
702    
703     model.setServerInfo(gsi.getResult());
704    
705 iliev 1285 if(CC.getViewConfig().getInstrumentsDbSupport()) {
706 iliev 1204 getInstrumentsDbTreeModel();
707     }
708 iliev 787 }
709     });
710    
711 iliev 1143 final Audio.GetDrivers gaod = new Audio.GetDrivers();
712 iliev 787 gaod.addTaskListener(new TaskListener() {
713     public void
714     taskPerformed(TaskEvent e) {
715     if(!gaod.doneWithErrors())
716     model.setAudioOutputDrivers(gaod.getResult());
717     }
718     });
719    
720     final GetEngines ge = new GetEngines();
721     ge.addTaskListener(new TaskListener() {
722     public void
723     taskPerformed(TaskEvent e) {
724     if(!ge.doneWithErrors()) model.setEngines(ge.getResult());
725     }
726     });
727    
728 iliev 1143 final Midi.GetDrivers gmid = new Midi.GetDrivers();
729 iliev 787 gmid.addTaskListener(new TaskListener() {
730     public void
731     taskPerformed(TaskEvent e) {
732     if(!gmid.doneWithErrors())
733     model.setMidiInputDrivers(gmid.getResult());
734     }
735     });
736    
737 iliev 1143 final Global.GetVolume gv = new Global.GetVolume();
738     gv.addTaskListener(new TaskListener() {
739     public void
740     taskPerformed(TaskEvent e) {
741     if(!gv.doneWithErrors())
742     model.setVolume(gv.getResult());
743     }
744     });
745    
746     final Midi.GetInstrumentMaps mgim = new Midi.GetInstrumentMaps();
747     mgim.addTaskListener(new TaskListener() {
748     public void
749     taskPerformed(TaskEvent e) {
750     if(mgim.doneWithErrors()) return;
751     model.removeAllMidiInstrumentMaps();
752    
753     for(MidiInstrumentMap map : mgim.getResult()) {
754     model.addMidiInstrumentMap(map);
755     }
756     }
757     });
758    
759     final UpdateChannels uc = new UpdateChannels();
760     uc.addTaskListener(new TaskListener() {
761     public void
762     taskPerformed(TaskEvent e) {
763 iliev 1204 for(SamplerChannelModel c : model.getChannels()) {
764 iliev 1143 if(c.getChannelInfo().getEngine() == null) continue;
765    
766     Channel.GetFxSends gfs = new Channel.GetFxSends();
767     gfs.setChannel(c.getChannelId());
768     gfs.addTaskListener(new GetFxSendsListener());
769     getTaskQueue().add(gfs);
770     }
771 iliev 1567
772     // TODO: This should be done after the fx sends are set
773     //CC.getSamplerModel().setModified(false);
774 iliev 1143 }
775     });
776    
777    
778 iliev 787 final Connect cnt = new Connect();
779     cnt.addTaskListener(new TaskListener() {
780     public void
781     taskPerformed(TaskEvent e) {
782 iliev 1688 if(cnt.doneWithErrors()) {
783     setCurrentServer(null);
784     retryToConnect();
785     return;
786     }
787 iliev 787
788     getTaskQueue().add(gsi);
789     getTaskQueue().add(gaod);
790     getTaskQueue().add(gmid);
791     getTaskQueue().add(ge);
792 iliev 1143 getTaskQueue().add(gv);
793     getTaskQueue().add(mgim);
794     getTaskQueue().add(new Midi.UpdateDevices());
795     getTaskQueue().add(new Audio.UpdateDevices());
796 iliev 1734 addTask(uc);
797 iliev 787 }
798     });
799 iliev 1688
800     ssa.addTaskListener(new TaskListener() {
801     public void
802     taskPerformed(TaskEvent e) {
803     CC.getTaskQueue().add(cnt);
804     }
805     });
806    
807     getSamplerModel().reset();
808     if(instrumentsDbTreeModel != null) {
809     instrumentsDbTreeModel.reset();
810     instrumentsDbTreeModel = null;
811     }
812    
813     getTaskQueue().removePendingTasks();
814     getTaskQueue().add(ssa);
815    
816     fireReconnectEvent();
817 iliev 787 }
818    
819 iliev 1688 private static void
820     retryToConnect() {
821     javax.swing.SwingUtilities.invokeLater(new Runnable() {
822     public void
823     run() { changeBackend(); }
824     });
825     }
826    
827     public static void
828     changeBackend() {
829     Server s = getMainFrame().getServer(true);
830     if(s != null) initSamplerModel(s);
831     }
832    
833 iliev 1143 private static class GetFxSendsListener implements TaskListener {
834     public void
835     taskPerformed(TaskEvent e) {
836     Channel.GetFxSends gfs = (Channel.GetFxSends)e.getSource();
837     if(gfs.doneWithErrors()) return;
838 iliev 1204 SamplerChannelModel m = getSamplerModel().getChannelById(gfs.getChannel());
839 iliev 1143 m.removeAllFxSends();
840    
841     for(FxSend fxs : gfs.getResult()) m.addFxSend(fxs);
842     }
843     }
844    
845     public static String
846     exportInstrMapsToLscpScript() {
847     StringBuffer sb = new StringBuffer("# Exported by: ");
848     sb.append("JSampler - a java front-end for LinuxSampler\r\n# Version: ");
849     sb.append(JSampler.VERSION).append("\r\n");
850     sb.append("# Date: ").append(new java.util.Date().toString()).append("\r\n\r\n");
851    
852     Client lscpClient = new Client(true);
853     ByteArrayOutputStream out = new ByteArrayOutputStream();
854     lscpClient.setPrintOnlyModeOutputStream(out);
855    
856     exportInstrMapsToLscpScript(lscpClient);
857     sb.append(out.toString());
858     out.reset();
859    
860     return sb.toString();
861     }
862    
863     private static void
864     exportInstrMapsToLscpScript(Client lscpClient) {
865     try {
866     lscpClient.removeAllMidiInstrumentMaps();
867     MidiInstrumentMap[] maps = CC.getSamplerModel().getMidiInstrumentMaps();
868     for(int i = 0; i < maps.length; i++) {
869     lscpClient.addMidiInstrumentMap(maps[i].getName());
870     exportInstrumentsToLscpScript(i, maps[i], lscpClient);
871     }
872     } catch(Exception e) {
873     CC.getLogger().log(Level.FINE, HF.getErrorMessage(e), e);
874     HF.showErrorMessage(e);
875     }
876     }
877    
878     private static void
879     exportInstrumentsToLscpScript(int mapId, MidiInstrumentMap map, Client lscpClient)
880     throws Exception {
881    
882     for(MidiInstrument i : map.getAllMidiInstruments()) {
883     lscpClient.mapMidiInstrument(mapId, i.getInfo().getEntry(), i.getInfo());
884     }
885     }
886    
887     public static String
888     exportSessionToLscpScript() {
889 iliev 1567 CC.getSamplerModel().setModified(false);
890    
891 iliev 1143 StringBuffer sb = new StringBuffer("# Exported by: ");
892     sb.append("JSampler - a java front-end for LinuxSampler\r\n# Version: ");
893     sb.append(JSampler.VERSION).append("\r\n");
894     sb.append("# Date: ").append(new java.util.Date().toString()).append("\r\n\r\n");
895    
896     Client lscpClient = new Client(true);
897     ByteArrayOutputStream out = new ByteArrayOutputStream();
898     lscpClient.setPrintOnlyModeOutputStream(out);
899    
900     try {
901     lscpClient.resetSampler();
902     sb.append(out.toString());
903     out.reset();
904     sb.append("\r\n");
905     lscpClient.setVolume(CC.getSamplerModel().getVolume());
906     sb.append(out.toString());
907     out.reset();
908     sb.append("\r\n");
909     } catch(Exception e) { CC.getLogger().log(Level.FINE, HF.getErrorMessage(e), e); }
910    
911 iliev 1204 MidiDeviceModel[] mDevs = getSamplerModel().getMidiDevices();
912 iliev 1143 for(int i = 0; i < mDevs.length; i++) {
913     exportMidiDeviceToLscpScript(mDevs[i].getDeviceInfo(), i, lscpClient);
914     sb.append(out.toString());
915     out.reset();
916     sb.append("\r\n");
917     }
918    
919 iliev 1204 AudioDeviceModel[] aDevs = getSamplerModel().getAudioDevices();
920 iliev 1143 for(int i = 0; i < aDevs.length; i++) {
921     exportAudioDeviceToLscpScript(aDevs[i].getDeviceInfo(), i, lscpClient);
922     sb.append(out.toString());
923     out.reset();
924     sb.append("\r\n");
925     }
926    
927 iliev 1708 exportInstrMapsToLscpScript(lscpClient);
928     sb.append(out.toString());
929     out.reset();
930 iliev 1719 sb.append("\r\n");
931 iliev 1708
932 iliev 1204 SamplerChannelModel[] channels = getSamplerModel().getChannels();
933 iliev 1143
934     for(int i = 0; i < channels.length; i++) {
935 iliev 1467 SamplerChannelModel scm = channels[i];
936 iliev 1143 exportChannelToLscpScript(scm.getChannelInfo(), i, lscpClient);
937     sb.append(out.toString());
938     out.reset();
939    
940     sb.append("\r\n");
941    
942     exportFxSendsToLscpScript(scm, i, lscpClient);
943     sb.append(out.toString());
944     out.reset();
945    
946     sb.append("\r\n");
947     }
948    
949     return sb.toString();
950     }
951    
952     private static void
953     exportMidiDeviceToLscpScript(MidiInputDevice mid, int devId, Client lscpCLient) {
954     try {
955     String s = mid.getDriverName();
956     lscpCLient.createMidiInputDevice(s, mid.getAdditionalParameters());
957    
958     MidiPort[] mPorts = mid.getMidiPorts();
959     int l = mPorts.length;
960     if(l != 1) lscpCLient.setMidiInputPortCount(devId, l);
961    
962     for(int i = 0; i < l; i++) {
963     Parameter[] prms = mPorts[i].getAllParameters();
964     for(Parameter p : prms) {
965     if(!p.isFixed() && p.getStringValue().length() > 0)
966     lscpCLient.setMidiInputPortParameter(devId, i, p);
967     }
968     }
969     } catch(Exception e) {
970     CC.getLogger().log(Level.FINE, HF.getErrorMessage(e), e);
971     }
972     }
973    
974     private static void
975     exportAudioDeviceToLscpScript(AudioOutputDevice aod, int devId, Client lscpCLient) {
976     try {
977     String s = aod.getDriverName();
978     lscpCLient.createAudioOutputDevice(s, aod.getAllParameters());
979    
980     AudioOutputChannel[] chns = aod.getAudioChannels();
981    
982     for(int i = 0; i < chns.length; i++) {
983     Parameter[] prms = chns[i].getAllParameters();
984     for(Parameter p : prms) {
985     if(p.isFixed() || p.getStringValue().length() == 0);
986     else lscpCLient.setAudioOutputChannelParameter(devId, i, p);
987     }
988     }
989     } catch(Exception e) {
990     CC.getLogger().log(Level.FINE, HF.getErrorMessage(e), e);
991     }
992     }
993    
994     private static void
995     exportChannelToLscpScript(SamplerChannel chn, int chnId, Client lscpCLient) {
996     try {
997     lscpCLient.addSamplerChannel();
998    
999 iliev 1467 SamplerModel sm = CC.getSamplerModel();
1000     int id = chn.getMidiInputDevice();
1001     if(id != -1) {
1002     for(int i = 0; i < sm.getMidiDeviceCount(); i++) {
1003     if(sm.getMidiDevice(i).getDeviceId() == id) {
1004     lscpCLient.setChannelMidiInputDevice(chnId, i);
1005     break;
1006     }
1007     }
1008 iliev 1540 lscpCLient.setChannelMidiInputPort(chnId, chn.getMidiInputPort());
1009     lscpCLient.setChannelMidiInputChannel(chnId, chn.getMidiInputChannel());
1010 iliev 1467 }
1011 iliev 1143
1012 iliev 1670 if(chn.getEngine() != null) {
1013     lscpCLient.loadSamplerEngine(chn.getEngine().getName(), chnId);
1014     lscpCLient.setChannelVolume(chnId, chn.getVolume());
1015 iliev 1708 int mapId = chn.getMidiInstrumentMapId();
1016     lscpCLient.setChannelMidiInstrumentMap(chnId, mapId);
1017 iliev 1670 }
1018    
1019 iliev 1467 id = chn.getAudioOutputDevice();
1020     if(id != -1) {
1021     for(int i = 0; i < sm.getAudioDeviceCount(); i++) {
1022     if(sm.getAudioDevice(i).getDeviceId() == id) {
1023     lscpCLient.setChannelAudioOutputDevice(chnId, i);
1024     break;
1025     }
1026     }
1027    
1028 iliev 1143 Integer[] routing = chn.getAudioOutputRouting();
1029    
1030     for(int j = 0; j < routing.length; j++) {
1031     int k = routing[j];
1032     if(k == j) continue;
1033    
1034     lscpCLient.setChannelAudioOutputChannel(chnId, j, k);
1035     }
1036     }
1037    
1038     String s = chn.getInstrumentFile();
1039 iliev 1467 int i = chn.getInstrumentIndex();
1040 iliev 1143 if(s != null) lscpCLient.loadInstrument(s, i, chnId, true);
1041    
1042     if(chn.isMuted()) lscpCLient.setChannelMute(chnId, true);
1043     if(chn.isSoloChannel()) lscpCLient.setChannelSolo(chnId, true);
1044     } catch(Exception e) {
1045     CC.getLogger().log(Level.FINE, HF.getErrorMessage(e), e);
1046     }
1047     }
1048    
1049     private static void
1050     exportFxSendsToLscpScript(SamplerChannelModel scm, int chnId, Client lscpClient) {
1051     try {
1052     FxSend[] fxSends = scm.getFxSends();
1053    
1054     for(int i = 0; i < fxSends.length; i++) {
1055     FxSend f = fxSends[i];
1056     lscpClient.createFxSend(chnId, f.getMidiController(), f.getName());
1057    
1058     Integer[] r = f.getAudioOutputRouting();
1059     for(int j = 0; j < r.length; j++) {
1060     lscpClient.setFxSendAudioOutputChannel(chnId, i, j, r[j]);
1061     }
1062     }
1063     } catch(Exception e) {
1064     CC.getLogger().log(Level.FINE, HF.getErrorMessage(e), e);
1065     }
1066     }
1067    
1068 iliev 1688 public static void
1069     scheduleInTaskQueue(final Runnable r) {
1070     Task dummy = new Global.DummyTask();
1071     dummy.addTaskListener(new TaskListener() {
1072     public void
1073     taskPerformed(TaskEvent e) {
1074     javax.swing.SwingUtilities.invokeLater(r);
1075     }
1076     });
1077    
1078     CC.getTaskQueue().add(dummy);
1079     }
1080 iliev 1143
1081 iliev 1688 public static boolean
1082     verifyConnection() {
1083     if(getCurrentServer() == null) {
1084     HF.showErrorMessage(i18n.getError("CC.notConnected"));
1085     return false;
1086     }
1087    
1088     return true;
1089     }
1090    
1091    
1092 iliev 911 private final static EventHandler eventHandler = new EventHandler();
1093    
1094     private static EventHandler
1095     getHandler() { return eventHandler; }
1096    
1097 iliev 787 private static class EventHandler implements ChannelCountListener, ChannelInfoListener,
1098 iliev 1143 FxSendCountListener, FxSendInfoListener, StreamCountListener, VoiceCountListener,
1099 iliev 1545 TotalStreamCountListener, TotalVoiceCountListener, TaskQueueListener,
1100     OrchestraListener, ListListener<OrchestraModel>, MidiInstrumentCountListener,
1101 iliev 1143 MidiInstrumentInfoListener, GlobalInfoListener {
1102 iliev 787
1103     /** Invoked when the number of channels has changed. */
1104     public void
1105     channelCountChanged( ChannelCountEvent e) {
1106 iliev 1734 addTask(new UpdateChannels());
1107 iliev 787 }
1108    
1109     /** Invoked when changes to the sampler channel has occured. */
1110     public void
1111     channelInfoChanged(ChannelInfoEvent e) {
1112     /*
1113     * Because of the rapid notification flow when instrument is loaded
1114     * we need to do some optimization to decrease the traffic.
1115     */
1116     boolean b = true;
1117     Task[] tS = getTaskQueue().getPendingTasks();
1118    
1119     for(int i = tS.length - 1; i >= 0; i--) {
1120     Task t = tS[i];
1121    
1122 iliev 1143 if(t instanceof Channel.UpdateInfo) {
1123     Channel.UpdateInfo cui = (Channel.UpdateInfo)t;
1124     if(cui.getChannelId() == e.getSamplerChannel()) return;
1125 iliev 787 } else {
1126     b = false;
1127     break;
1128     }
1129     }
1130    
1131     if(b) {
1132     Task t = getTaskQueue().getRunningTask();
1133 iliev 1143 if(t instanceof Channel.UpdateInfo) {
1134     Channel.UpdateInfo cui = (Channel.UpdateInfo)t;
1135     if(cui.getChannelId() == e.getSamplerChannel()) return;
1136 iliev 787 }
1137     }
1138    
1139    
1140 iliev 1143 getTaskQueue().add(new Channel.UpdateInfo(e.getSamplerChannel()));
1141 iliev 787 }
1142    
1143     /**
1144 iliev 1143 * Invoked when the number of effect sends
1145     * on a particular sampler channel has changed.
1146     */
1147     public void
1148     fxSendCountChanged(FxSendCountEvent e) {
1149     getTaskQueue().add(new Channel.UpdateFxSends(e.getChannel()));
1150     }
1151    
1152     /**
1153     * Invoked when the settings of an effect sends are changed.
1154     */
1155     public void
1156     fxSendInfoChanged(FxSendInfoEvent e) {
1157     Task t = new Channel.UpdateFxSendInfo(e.getChannel(), e.getFxSend());
1158     getTaskQueue().add(t);
1159     }
1160    
1161     /**
1162 iliev 787 * Invoked when the number of active disk
1163     * streams in a specific sampler channel has changed.
1164     */
1165     public void
1166     streamCountChanged(StreamCountEvent e) {
1167     SamplerChannelModel scm =
1168 iliev 1204 getSamplerModel().getChannelById(e.getSamplerChannel());
1169 iliev 787
1170     if(scm == null) {
1171     CC.getLogger().log (
1172     Level.WARNING,
1173     "CC.unknownChannel!",
1174     e.getSamplerChannel()
1175     );
1176    
1177     return;
1178     }
1179    
1180     scm.setStreamCount(e.getStreamCount());
1181     }
1182    
1183     /**
1184     * Invoked when the number of active voices
1185     * in a specific sampler channel has changed.
1186     */
1187     public void
1188     voiceCountChanged(VoiceCountEvent e) {
1189     SamplerChannelModel scm =
1190 iliev 1204 getSamplerModel().getChannelById(e.getSamplerChannel());
1191 iliev 787
1192     if(scm == null) {
1193     CC.getLogger().log (
1194     Level.WARNING,
1195     "CC.unknownChannel!",
1196     e.getSamplerChannel()
1197     );
1198    
1199     return;
1200     }
1201    
1202     scm.setVoiceCount(e.getVoiceCount());
1203     }
1204    
1205 iliev 1545 /** Invoked when the total number of active streams has changed. */
1206     public void
1207     totalStreamCountChanged(TotalStreamCountEvent e) {
1208     getSamplerModel().updateActiveStreamsInfo(e.getTotalStreamCount());
1209     }
1210    
1211 iliev 787 /** Invoked when the total number of active voices has changed. */
1212     public void
1213     totalVoiceCountChanged(TotalVoiceCountEvent e) {
1214     getTaskQueue().add(new UpdateTotalVoiceCount());
1215     }
1216 iliev 911
1217 iliev 1143 /** Invoked when the number of MIDI instruments in a MIDI instrument map is changed. */
1218     public void
1219     instrumentCountChanged(MidiInstrumentCountEvent e) {
1220 iliev 1719 scheduleTask(new Midi.UpdateInstruments(e.getMapId()));
1221 iliev 1143 }
1222    
1223     /** Invoked when a MIDI instrument in a MIDI instrument map is changed. */
1224     public void
1225     instrumentInfoChanged(MidiInstrumentInfoEvent e) {
1226     Task t = new Midi.UpdateInstrumentInfo (
1227     e.getMapId(), e.getMidiBank(), e.getMidiProgram()
1228     );
1229     getTaskQueue().add(t);
1230    
1231     }
1232    
1233     /** Invoked when the global volume of the sampler is changed. */
1234     public void
1235     volumeChanged(GlobalInfoEvent e) {
1236     getSamplerModel().setVolume(e.getVolume());
1237     }
1238    
1239 iliev 911 /**
1240     * Invoked to indicate that the state of a task queue is changed.
1241     * This method is invoked only from the event-dispatching thread.
1242     */
1243     public void
1244     stateChanged(TaskQueueEvent e) {
1245     switch(e.getEventID()) {
1246     case TASK_FETCHED:
1247     getProgressIndicator().setString (
1248     ((Task)e.getSource()).getDescription()
1249     );
1250     break;
1251     case TASK_DONE:
1252     EnhancedTask t = (EnhancedTask)e.getSource();
1253 iliev 1204 if(t.doneWithErrors() && !t.isStopped()) {
1254 iliev 1285 showError(t);
1255 iliev 1204 }
1256 iliev 911 break;
1257     case NOT_IDLE:
1258     timer.start();
1259     break;
1260     case IDLE:
1261     timer.stop();
1262     getProgressIndicator().stop();
1263     break;
1264     }
1265     }
1266    
1267 iliev 1285 private void
1268     showError(final Task t) {
1269     javax.swing.SwingUtilities.invokeLater(new Runnable() {
1270     public void
1271     run() {
1272     if(t.getErrorDetails() == null) {
1273     HF.showErrorMessage(t.getErrorMessage());
1274     } else {
1275     getMainFrame().showDetailedErrorMessage (
1276     getMainFrame(),
1277     t.getErrorMessage(),
1278     t.getErrorDetails()
1279     );
1280     }
1281     }
1282     });
1283     }
1284    
1285 iliev 911 /** Invoked when the name of orchestra is changed. */
1286     public void
1287     nameChanged(OrchestraEvent e) { saveOrchestras(); }
1288    
1289     /** Invoked when the description of orchestra is changed. */
1290     public void
1291     descriptionChanged(OrchestraEvent e) { saveOrchestras(); }
1292    
1293     /** Invoked when an instrument is added to the orchestra. */
1294     public void
1295     instrumentAdded(OrchestraEvent e) { saveOrchestras(); }
1296    
1297     /** Invoked when an instrument is removed from the orchestra. */
1298     public void
1299     instrumentRemoved(OrchestraEvent e) { saveOrchestras(); }
1300    
1301     /** Invoked when the settings of an instrument are changed. */
1302     public void
1303     instrumentChanged(OrchestraEvent e) { saveOrchestras(); }
1304    
1305     /** Invoked when an orchestra is added to the orchestra list. */
1306     public void
1307 iliev 1143 entryAdded(ListEvent<OrchestraModel> e) {
1308     e.getEntry().addOrchestraListener(getHandler());
1309 iliev 911 saveOrchestras();
1310     }
1311    
1312     /** Invoked when an orchestra is removed from the orchestra list. */
1313     public void
1314 iliev 1143 entryRemoved(ListEvent<OrchestraModel> e) {
1315     e.getEntry().removeOrchestraListener(getHandler());
1316 iliev 911 saveOrchestras();
1317     }
1318 iliev 787 }
1319 iliev 1143
1320     private static final AudioDeviceCountListener audioDeviceCountListener =
1321     new AudioDeviceCountListener();
1322    
1323     private static class AudioDeviceCountListener implements ItemCountListener {
1324     /** Invoked when the number of audio output devices has changed. */
1325     public void
1326     itemCountChanged(ItemCountEvent e) {
1327     getTaskQueue().add(new Audio.UpdateDevices());
1328     }
1329     }
1330    
1331     private static final AudioDeviceInfoListener audioDeviceInfoListener =
1332     new AudioDeviceInfoListener();
1333    
1334     private static class AudioDeviceInfoListener implements ItemInfoListener {
1335     /** Invoked when the audio output device's settings are changed. */
1336     public void
1337     itemInfoChanged(ItemInfoEvent e) {
1338     getTaskQueue().add(new Audio.UpdateDeviceInfo(e.getItemID()));
1339     }
1340     }
1341    
1342     private static final MidiDeviceCountListener midiDeviceCountListener =
1343     new MidiDeviceCountListener();
1344    
1345     private static class MidiDeviceCountListener implements ItemCountListener {
1346     /** Invoked when the number of MIDI input devices has changed. */
1347     public void
1348     itemCountChanged(ItemCountEvent e) {
1349     getTaskQueue().add(new Midi.UpdateDevices());
1350     }
1351     }
1352    
1353     private static final MidiDeviceInfoListener midiDeviceInfoListener =
1354     new MidiDeviceInfoListener();
1355    
1356     private static class MidiDeviceInfoListener implements ItemInfoListener {
1357     /** Invoked when the MIDI input device's settings are changed. */
1358     public void
1359     itemInfoChanged(ItemInfoEvent e) {
1360     getTaskQueue().add(new Midi.UpdateDeviceInfo(e.getItemID()));
1361     }
1362     }
1363    
1364     private static final MidiInstrMapCountListener midiInstrMapCountListener =
1365     new MidiInstrMapCountListener();
1366    
1367     private static class MidiInstrMapCountListener implements ItemCountListener {
1368     /** Invoked when the number of MIDI instrument maps is changed. */
1369     public void
1370     itemCountChanged(ItemCountEvent e) {
1371     getTaskQueue().add(new Midi.UpdateInstrumentMaps());
1372     }
1373     }
1374    
1375     private static final MidiInstrMapInfoListener midiInstrMapInfoListener =
1376     new MidiInstrMapInfoListener();
1377    
1378     private static class MidiInstrMapInfoListener implements ItemInfoListener {
1379     /** Invoked when the MIDI instrument map's settings are changed. */
1380     public void
1381     itemInfoChanged(ItemInfoEvent e) {
1382     getTaskQueue().add(new Midi.UpdateInstrumentMapInfo(e.getItemID()));
1383     }
1384     }
1385 iliev 787 }

  ViewVC Help
Powered by ViewVC