/[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 1786 - (hide annotations) (download)
Wed Oct 8 22:38:15 2008 UTC (15 years, 7 months ago) by iliev
File size: 45669 byte(s)
* Implemented option to launch the backend if it is not yet started
  (choose Edit/Preferences, then click the `Backend' tab)
* LSCP scripts can now be run by passing them to jsampler
  as command-line arguments
* The scripts in the `scripts' directory now pass the command-line
  arguments to the respective jsampler distribution
* ant: the default target is now build-fantasia
* bugfix: backend address was always set to 127.0.0.1 when adding
  backend to the backend list

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

  ViewVC Help
Powered by ViewVC