/[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 2195 - (hide annotations) (download)
Tue Jun 28 22:44:39 2011 UTC (12 years, 10 months ago) by iliev
File size: 38759 byte(s)
* Sampler Browser (work in progress): initial implementation of main pane

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

  ViewVC Help
Powered by ViewVC