/[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 1883 - (hide annotations) (download)
Sun Apr 5 09:15:35 2009 UTC (15 years ago) by iliev
File size: 46829 byte(s)
* fixed the channel order when exporting sampler configuration
* don't mute channels muted by solo channel when exporting
   sampler configuration
* don't ask whether to replace a file on Mac OS when using
  native file choosers

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

  ViewVC Help
Powered by ViewVC