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

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

  ViewVC Help
Powered by ViewVC