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

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

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 842 by iliev, Thu Mar 16 18:08:34 2006 UTC revision 1818 by iliev, Wed Dec 24 17:29:47 2008 UTC
# Line 1  Line 1 
1  /*  /*
2   *   JSampler - a java front-end for LinuxSampler   *   JSampler - a java front-end for LinuxSampler
3   *   *
4   *   Copyright (C) 2005 Grigor Kirilov Iliev   *   Copyright (C) 2005-2008 Grigor Iliev <grigor@grigoriliev.com>
5   *   *
6   *   This file is part of JSampler.   *   This file is part of JSampler.
7   *   *
# Line 25  package org.jsampler; Line 25  package org.jsampler;
25  import java.awt.event.ActionEvent;  import java.awt.event.ActionEvent;
26  import java.awt.event.ActionListener;  import java.awt.event.ActionListener;
27    
28    import java.io.ByteArrayOutputStream;
29    import java.io.File;
30    import java.io.FileInputStream;
31  import java.io.FileOutputStream;  import java.io.FileOutputStream;
32    import java.io.InputStream;
33    
34    import java.util.Vector;
35    
36  import java.util.logging.Handler;  import java.util.logging.Handler;
37  import java.util.logging.Level;  import java.util.logging.Level;
# Line 33  import java.util.logging.Logger; Line 39  import java.util.logging.Logger;
39  import java.util.logging.SimpleFormatter;  import java.util.logging.SimpleFormatter;
40  import java.util.logging.StreamHandler;  import java.util.logging.StreamHandler;
41    
42    import javax.swing.SwingUtilities;
43  import javax.swing.Timer;  import javax.swing.Timer;
44    
45    import javax.swing.event.ChangeEvent;
46    import javax.swing.event.ChangeListener;
47    
48    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    import org.jsampler.event.ListEvent;
57    import org.jsampler.event.ListListener;
58    import org.jsampler.event.OrchestraEvent;
59    import org.jsampler.event.OrchestraListener;
60    
61  import org.jsampler.task.*;  import org.jsampler.task.*;
62    
63  import org.jsampler.view.JSMainFrame;  import org.jsampler.view.JSMainFrame;
64  import org.jsampler.view.JSProgress;  import org.jsampler.view.JSProgress;
65    import org.jsampler.view.JSViewConfig;
66    import org.jsampler.view.InstrumentsDbTreeModel;
67    
68    import org.linuxsampler.lscp.AudioOutputChannel;
69    import org.linuxsampler.lscp.AudioOutputDevice;
70  import org.linuxsampler.lscp.Client;  import org.linuxsampler.lscp.Client;
71    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  import org.linuxsampler.lscp.event.*;  import org.linuxsampler.lscp.event.*;
78    
79  import net.sf.juife.Task;  import org.w3c.dom.Document;
80  import net.sf.juife.TaskQueue;  import org.w3c.dom.Node;
81    
82  import net.sf.juife.event.TaskEvent;  import static org.jsampler.JSI18n.i18n;
 import net.sf.juife.event.TaskListener;  
 import net.sf.juife.event.TaskQueueEvent;  
 import net.sf.juife.event.TaskQueueListener;  
83    
84    
85  /**  /**
86   *   * This class serves as a 'Control Center' of the application.
87     * It also provides some fundamental routines and access to most used objects.
88   * @author Grigor Iliev   * @author Grigor Iliev
89   */   */
90  public class CC {  public class CC {
91          private static Handler handler;          private static Handler handler;
92          public static FileOutputStream fos;          private static FileOutputStream fos;
93                    
94            private static JSViewConfig viewConfig = null;
95          private static JSMainFrame mainFrame = null;          private static JSMainFrame mainFrame = null;
96          private static JSProgress progress = null;          private static JSProgress progress = null;
97                    
98          private final static Client lsClient = new Client();          private final static Client lsClient = new Client();
99                    
100            private static String jSamplerHome = null;
101            
102          private final static TaskQueue taskQueue = new TaskQueue();          private final static TaskQueue taskQueue = new TaskQueue();
103          private final static Timer timer = new Timer(1000, null);          private final static Timer timer = new Timer(2000, null);
104                    
105          private final static EventHandler eventHandler = new EventHandler();          private static int connectionFailureCount = 0;
106                    
107            /** Forbits the instantiation of this class. */
108            private
109            CC() { }
110            
111            /**
112             * Returns the logger to be used for logging events.
113             * @return The logger to be used for logging events.
114             */
115          public static Logger          public static Logger
116          getLogger() {          getLogger() {
117                  return Logger.getLogger (                  return Logger.getLogger (
# Line 78  public class CC { Line 120  public class CC {
120                  );                  );
121          }          }
122                    
123          public static TaskQueue          /**
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            public static synchronized TaskQueue
130          getTaskQueue() { return taskQueue; }          getTaskQueue() { return taskQueue; }
131                    
132            /**
133             * 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 synchronized void
137            scheduleTask(Task t) {
138                    while(getTaskQueue().removeTask(t)) { }
139                    
140                    getTaskQueue().add(t);
141            }
142            
143            /**
144             * Adds the specified task to the task queue only if the last
145             * task in the queue is not equal to <code>t</code>.
146             */
147            public static synchronized 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             * Gets the configuration of the current view.
156             */
157            public static JSViewConfig
158            getViewConfig() { return viewConfig; }
159            
160            public static JSPrefs
161            preferences() { return getViewConfig().preferences(); }
162            
163            /**
164             * Sets the configuration of the current view.
165             */
166            public static void
167            setViewConfig(JSViewConfig viewConfig) { CC.viewConfig = viewConfig; }
168            
169            /**
170             * Returns the main window of this application.
171             * @return The main window of this application.
172             */
173          public static JSMainFrame          public static JSMainFrame
174          getMainFrame() { return mainFrame; }          getMainFrame() { return mainFrame; }
175                    
176            /**
177             * Sets the main window of this application.
178             * @param mainFrame The main window of this application.
179             */
180          public static void          public static void
181          setMainFrame(JSMainFrame mainFrame) { CC.mainFrame = mainFrame; }          setMainFrame(JSMainFrame mainFrame) { CC.mainFrame = mainFrame; }
182                    
183            /**
184             * Gets the progress indicator of this application.
185             * @return The progress indicator of this application.
186             */
187          public static JSProgress          public static JSProgress
188          getProgressIndicator() { return progress; }          getProgressIndicator() { return progress; }
189                    
190            /**
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          public static void          public static void
195          setProgressIndicator(JSProgress progress) { CC.progress = progress; }          setProgressIndicator(JSProgress progress) { CC.progress = progress; }
196                    
197            /**
198             * 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             * This method does the initial preparation of the application.
217             */
218          protected static void          protected static void
219          initJSampler() {          initJSampler() {
220                  fos = null;                  fos = null;
221                                    setJSamplerHome(Prefs.getJSamplerHome());
222                  try { fos = new FileOutputStream("JSampler.log"); }                  String s = getJSamplerHome();
223                  catch(Exception x) { x.printStackTrace(); }                  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                                    
232                  if(fos == null) handler = new StreamHandler(System.out, new SimpleFormatter());                  if(fos == null) handler = new StreamHandler(System.out, new SimpleFormatter());
233                  else handler = new StreamHandler(fos, new SimpleFormatter());                  else handler = new StreamHandler(fos, new SimpleFormatter());
# Line 106  public class CC { Line 235  public class CC {
235                  handler.setLevel(Level.FINE);                  handler.setLevel(Level.FINE);
236                  getLogger().addHandler(handler);                  getLogger().addHandler(handler);
237                  getLogger().setLevel(Level.FINE);                  getLogger().setLevel(Level.FINE);
                 Logger.getLogger("org.linuxsampler.lscp").addHandler(handler);  
238                  Logger.getLogger("org.linuxsampler.lscp").setLevel(Level.FINE);                  Logger.getLogger("org.linuxsampler.lscp").setLevel(Level.FINE);
239                    Logger.getLogger("org.linuxsampler.lscp").addHandler(handler);
240                                    
241                  // Flushing logs on every second                  // Flushing logs on every second
242                  new java.util.Timer().schedule(new java.util.TimerTask() {                  new java.util.Timer().schedule(new java.util.TimerTask() {
# Line 115  public class CC { Line 244  public class CC {
244                          run() { if(handler != null) handler.flush(); }                          run() { if(handler != null) handler.flush(); }
245                  }, 1000, 1000);                  }, 1000, 1000);
246                                    
247                  CC.getLogger().fine("CC.jsStarted");                  getLogger().fine("CC.jsStarted");
248                                    
249                  HF.setUIDefaultFont(Prefs.getInterfaceFont());                  HF.setUIDefaultFont(Prefs.getInterfaceFont());
250                                    
                   
                   
                 getClient().setServerAddress(Prefs.getLSAddress());  
                 getClient().setServerPort(Prefs.getLSPort());  
                   
251                  timer.setRepeats(false);                  timer.setRepeats(false);
252                                    
253                  timer.addActionListener(new ActionListener() {                  timer.addActionListener(new ActionListener() {
# Line 131  public class CC { Line 255  public class CC {
255                          actionPerformed(ActionEvent e) { CC.getProgressIndicator().start(); }                          actionPerformed(ActionEvent e) { CC.getProgressIndicator().start(); }
256                  });                  });
257                                    
258                  taskQueue.addTaskQueueListener(new TaskQueueListener() {                  getTaskQueue().addTaskQueueListener(getHandler());
259                    
260                    getTaskQueue().start();
261                    
262                    getClient().removeChannelCountListener(getHandler());
263                    getClient().addChannelCountListener(getHandler());
264                    
265                    getClient().removeChannelInfoListener(getHandler());
266                    getClient().addChannelInfoListener(getHandler());
267                    
268                    getClient().removeFxSendCountListener(getHandler());
269                    getClient().addFxSendCountListener(getHandler());
270                    
271                    getClient().removeFxSendInfoListener(getHandler());
272                    getClient().addFxSendInfoListener(getHandler());
273                    
274                    getClient().removeStreamCountListener(getHandler());
275                    getClient().addStreamCountListener(getHandler());
276                    
277                    getClient().removeVoiceCountListener(getHandler());
278                    getClient().addVoiceCountListener(getHandler());
279                    
280                    getClient().removeTotalStreamCountListener(getHandler());
281                    getClient().addTotalStreamCountListener(getHandler());
282                    
283                    getClient().removeTotalVoiceCountListener(getHandler());
284                    getClient().addTotalVoiceCountListener(getHandler());
285                    
286                    getClient().removeAudioDeviceCountListener(audioDeviceCountListener);
287                    getClient().addAudioDeviceCountListener(audioDeviceCountListener);
288                    
289                    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                    
313                    getClient().removeChannelMidiDataListener(getHandler());
314                    getClient().addChannelMidiDataListener(getHandler());
315                    
316                    CC.addConnectionEstablishedListener(new ActionListener() {
317                          public void                          public void
318                          stateChanged(TaskQueueEvent e) {                          actionPerformed(ActionEvent e) {
319                                  switch(e.getEventID()) {                                  connectionFailureCount = 0;
                                 case TASK_FETCHED:  
                                         CC.getProgressIndicator().setString (  
                                                 ((Task)e.getSource()).getDescription()  
                                         );  
                                         break;  
                                 case TASK_DONE:  
                                         EnhancedTask t = (EnhancedTask)e.getSource();  
                                         if(t.doneWithErrors() && !t.isStopped())  
                                                 HF.showErrorMessage(t.getErrorMessage());  
                                         break;  
                                 case NOT_IDLE:  
                                         timer.start();  
                                         break;  
                                 case IDLE:  
                                         timer.stop();  
                                         CC.getProgressIndicator().stop();  
                                         break;  
                                 }  
320                          }                          }
321                  });                  });
322            }
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                            if(f.exists() && f.isDirectory()) {
336                                    return;
337                            }
338                    }
339                    
340                    getMainFrame().installJSamplerHome();
341            }
342            
343            /**
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                    if(fNew.exists() && fNew.isFile()) {
354                            HF.showErrorMessage(i18n.getError("CC.JSamplerHomeIsNotDir!"));
355                            return;
356                    }
357                    
358                    if(!fNew.exists()) {
359                            if(!fNew.mkdir()) {
360                                    String s = fNew.getAbsolutePath();
361                                    HF.showErrorMessage(i18n.getError("CC.mkdirFailed", s));
362                                    return;
363                            }
364                    }
365                    
366                    if(getJSamplerHome() == null || path.equals(getJSamplerHome())) {
367                            setJSamplerHome(fNew.getAbsolutePath());
368                            return;
369                    }
370                    
371                    File fOld = new File(getJSamplerHome());
372                    if(!fOld.exists() || !fOld.isDirectory()) {
373                            setJSamplerHome(fNew.getAbsolutePath());
374                            return;
375                    }
376                                    
377                  taskQueue.start();                  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                  getClient().addChannelCountListener(eventHandler);                  if(b) fOld.delete();
385                  getClient().addChannelInfoListener(eventHandler);                  setJSamplerHome(fNew.getAbsolutePath());
386                  getClient().addStreamCountListener(eventHandler);          }
387                  getClient().addVoiceCountListener(eventHandler);          
388                  getClient().addTotalVoiceCountListener(eventHandler);          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            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                    @Override
407                    public void
408                    stateChanged(ChangeEvent e) {
409                            saveServerList();
410                    }
411            }
412            
413            private static final Vector<ChangeListener> idtmListeners = new Vector<ChangeListener>();
414            private static InstrumentsDbTreeModel instrumentsDbTreeModel = null;
415            
416            /**
417             * 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             * @see org.jsampler.view.JSViewConfig#getInstrumentsDbSupport
423             */
424            public static InstrumentsDbTreeModel
425            getInstrumentsDbTreeModel() {
426                    if(getSamplerModel().getServerInfo() == null) return null;
427                    if(!getSamplerModel().getServerInfo().hasInstrumentsDbSupport()) return null;
428                    
429                    if(instrumentsDbTreeModel == null) {
430                            instrumentsDbTreeModel = new InstrumentsDbTreeModel();
431                            for(ChangeListener l : idtmListeners) l.stateChanged(null);
432                    }
433                    
434                    return instrumentsDbTreeModel;
435            }
436            
437            public static void
438            addInstrumentsDbChangeListener(ChangeListener l) {
439                    idtmListeners.add(l);
440          }          }
441                    
442          public static void          public static void
443            removeInstrumentsDbChangeListener(ChangeListener l) {
444                    idtmListeners.remove(l);
445            }
446            
447            private static final LostFilesModel lostFilesModel = new LostFilesModel();
448            
449            public static LostFilesModel
450            getLostFilesModel() { return lostFilesModel; }
451            
452            /**
453             * 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                    
478                    getOrchestras().addOrchestraListListener(getHandler());
479            }
480            
481            
482            private static void
483            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            saveOrchestras() {
499                    try {
500                            String s = getJSamplerHome();
501                            if(s == null) return;
502                            
503                            HF.createBackup("orchestras.xml", "orchestras.xml.bkp");
504                            
505                            FileOutputStream fos2;
506                            fos2 = new FileOutputStream(s + File.separator + "orchestras.xml", false);
507                            
508                            Document doc = DOMUtils.createEmptyDocument();
509                    
510                            Node node = doc.createElement("temp");
511                            doc.appendChild(node);
512                            
513                            getOrchestras().writeObject(doc, doc.getDocumentElement());
514                            
515                            doc.replaceChild(node.getFirstChild(), node);
516                    
517                            DOMUtils.writeObject(doc, fos2);
518                            
519                            fos2.close();
520                            
521                            HF.deleteFile("orchestras.xml.bkp");
522                    } catch(Exception x) {
523                            HF.showErrorMessage(x, "Saving orchestras: ");
524                            return;
525                    }
526            }
527            
528            /**
529             * 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                            FileOutputStream fos2;
587                            fos2 = new FileOutputStream(s + File.separator + "servers.xml", false);
588                            
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                            DOMUtils.writeObject(doc, fos2);
599                            
600                            fos2.close();
601                            
602                            HF.deleteFile("servers.xml.bkp");
603                    } catch(Exception x) {
604                            HF.showErrorMessage(x, "Saving server list: ");
605                            return;
606                    }
607            }
608            
609            /**
610             * The exit point of the application which ensures clean exit with default exit status 0.
611             *  @see #cleanExit(int i)
612             */
613            public static void
614          cleanExit() { cleanExit(0); }          cleanExit() { cleanExit(0); }
615                    
616            /**
617             * The exit point of the application which ensures clean exit.
618             * @param i The exit status.
619             */
620          public static void          public static void
621          cleanExit(int i) {          cleanExit(int i) {
622                  CC.getLogger().fine("CC.jsEnded");                  getLogger().fine("CC.jsEnded");
623                    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                  System.exit(i);                  System.exit(i);
629          }          }
630                    
631            /**
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          public static Client          public static Client
636          getClient() { return lsClient; }          getClient() { return lsClient; }
637                    
638            private static final Vector<ActionListener> listeners = new Vector<ActionListener>();
639            
640            /**
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            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          private static final SamplerModel samplerModel = new DefaultSamplerModel();          private static final SamplerModel samplerModel = new DefaultSamplerModel();
684                    
# Line 187  public class CC { Line 689  public class CC {
689          public static SamplerModel          public static SamplerModel
690          getSamplerModel() { return samplerModel; }          getSamplerModel() { return samplerModel; }
691                    
692            /**
693             * Connects to LinuxSampler.
694             */
695            public static void
696            connect() { initSamplerModel(); }
697            
698            /**
699             * Reconnects to LinuxSampler.
700             */
701            public static void
702            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            setCurrentServer(Server server) {
718                    if(server == currentServer) return;
719                    connectionFailureCount = 0;
720                    currentServer = server;
721            }
722            
723            /**
724             * Sets the LSCP client's read timeout.
725             * @param timeout The new timeout value (in seconds).
726             */
727          public static void          public static void
728            setClientReadTimeout(int timeout) {
729                    getTaskQueue().add(new Global.SetClientReadTimeout(timeout));
730            }
731            
732            /**
733             * This method updates the information about the backend state.
734             */
735            private static void
736          initSamplerModel() {          initSamplerModel() {
737                    Server srv = getMainFrame().getServer();
738                    if(srv == null) return;
739                    initSamplerModel(srv);
740            }
741            
742            /**
743             * This method updates the information about the backend state.
744             */
745            private static void
746            initSamplerModel(Server srv) {
747                    setCurrentServer(srv);
748                    final SetServerAddress ssa = new SetServerAddress(srv.getAddress(), srv.getPort());
749                    
750                  final DefaultSamplerModel model = (DefaultSamplerModel)getSamplerModel();                  final DefaultSamplerModel model = (DefaultSamplerModel)getSamplerModel();
751                                    
752                  final GetServerInfo gsi = new GetServerInfo();                  final Global.GetServerInfo gsi = new Global.GetServerInfo();
753                  gsi.addTaskListener(new TaskListener() {                  gsi.addTaskListener(new TaskListener() {
754                          public void                          public void
755                          taskPerformed(TaskEvent e) {                          taskPerformed(TaskEvent e) {
756                                  if(!gsi.doneWithErrors()) model.setServerInfo(gsi.getResult());                                  if(gsi.doneWithErrors()) return;
757                                    
758                                    model.setServerInfo(gsi.getResult());
759                                    
760                                    if(CC.getViewConfig().getInstrumentsDbSupport()) {
761                                            getInstrumentsDbTreeModel();
762                                    }
763                          }                          }
764                  });                  });
765                                    
766                  final GetAODrivers gaod = new GetAODrivers();                  final Audio.GetDrivers gaod = new Audio.GetDrivers();
767                  gaod.addTaskListener(new TaskListener() {                  gaod.addTaskListener(new TaskListener() {
768                          public void                          public void
769                          taskPerformed(TaskEvent e) {                          taskPerformed(TaskEvent e) {
# Line 216  public class CC { Line 780  public class CC {
780                          }                          }
781                  });                  });
782                                    
783                  final GetMIDrivers gmid = new GetMIDrivers();                  final Midi.GetDrivers gmid = new Midi.GetDrivers();
784                  gmid.addTaskListener(new TaskListener() {                  gmid.addTaskListener(new TaskListener() {
785                          public void                          public void
786                          taskPerformed(TaskEvent e) {                          taskPerformed(TaskEvent e) {
# Line 225  public class CC { Line 789  public class CC {
789                          }                          }
790                  });                  });
791                                    
792                    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                                    for(SamplerChannelModel c : model.getChannels()) {
819                                            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                                    
827                                    // TODO: This should be done after the fx sends are set
828                                    //CC.getSamplerModel().setModified(false);
829                            }
830                    });
831                    
832                    
833                  final Connect cnt = new Connect();                  final Connect cnt = new Connect();
834                    boolean b = preferences().getBoolProperty(JSPrefs.LAUNCH_BACKEND_LOCALLY);
835                    if(b && srv.isLocal() && backendProcess == null) cnt.setSilent(true);
836                  cnt.addTaskListener(new TaskListener() {                  cnt.addTaskListener(new TaskListener() {
837                          public void                          public void
838                          taskPerformed(TaskEvent e) {                          taskPerformed(TaskEvent e) {
839                                  if(cnt.doneWithErrors()) return;                                  if(cnt.doneWithErrors()) {
840                                            onConnectFailure();
841                                            return;
842                                    }
843                                                                    
844                                  getTaskQueue().add(gsi);                                  getTaskQueue().add(gsi);
845                                  getTaskQueue().add(gaod);                                  getTaskQueue().add(gaod);
846                                  getTaskQueue().add(gmid);                                  getTaskQueue().add(gmid);
847                                  getTaskQueue().add(ge);                                  getTaskQueue().add(ge);
848                                  getTaskQueue().add(new UpdateMidiDevices());                                  getTaskQueue().add(gv);
849                                  getTaskQueue().add(new UpdateAudioDevices());                                  getTaskQueue().add(mgim);
850                                  getTaskQueue().add(new UpdateChannels());                                  getTaskQueue().add(new Midi.UpdateDevices());
851                                    getTaskQueue().add(new Audio.UpdateDevices());
852                                    addTask(uc);
853                                    
854                                    int vl = preferences().getIntProperty(JSPrefs.GLOBAL_VOICE_LIMIT);
855                                    int sl = preferences().getIntProperty(JSPrefs.GLOBAL_STREAM_LIMIT);
856                                    
857                                    getTaskQueue().add(new Global.SetPolyphony(vl, sl));
858                                    
859                                    fireConnectionEstablishedEvent();
860                            }
861                    });
862                    
863                    ssa.addTaskListener(new TaskListener() {
864                            public void
865                            taskPerformed(TaskEvent e) {
866                                    int t = preferences().getIntProperty(JSPrefs.SOCKET_READ_TIMEOUT);
867                                    CC.setClientReadTimeout(t * 1000);
868                                    CC.getTaskQueue().add(cnt);
869                          }                          }
870                  });                  });
871                  getTaskQueue().add(cnt);                  
872                    getSamplerModel().reset();
873                    if(instrumentsDbTreeModel != null) {
874                            instrumentsDbTreeModel.reset();
875                            instrumentsDbTreeModel = null;
876                    }
877                    
878                    getTaskQueue().removePendingTasks();
879                    getTaskQueue().add(ssa);
880                    
881                    fireReconnectEvent();
882            }
883            
884            private static void
885            onConnectFailure() {
886                    connectionFailureCount++;
887                    if(connectionFailureCount > 50) { // to prevent eventual infinite loop
888                            getLogger().warning("Reached maximum number of connection failures");
889                            return;
890                    }
891                    
892                    try {
893                            if(launchBackend()) {
894                                    int i = preferences().getIntProperty(JSPrefs.BACKEND_LAUNCH_DELAY);
895                                    if(i < 1) {
896                                            initSamplerModel(getCurrentServer());
897                                            return;
898                                    }
899                                    
900                                    LaunchBackend lb = new LaunchBackend(i, getBackendMonitor());
901                                    //CC.getTaskQueue().add(lb);
902                                    new Thread(lb).start();
903                                    return;
904                            }
905                    } catch(Exception x) {
906                            final String s = JSI18n.i18n.getError("CC.failedToLaunchBackend");
907                            CC.getLogger().log(Level.INFO, s, x);
908                            
909                            SwingUtilities.invokeLater(new Runnable() {
910                                    public void
911                                    run() { HF.showErrorMessage(s); }
912                            });
913                            return;
914                    }
915                    
916                    retryToConnect();
917            }
918            
919            private static void
920            retryToConnect() {
921                    javax.swing.SwingUtilities.invokeLater(new Runnable() {
922                            public void
923                            run() { changeBackend(); }
924                    });
925            }
926            
927            public static void
928            changeBackend() {
929                    Server s = getMainFrame().getServer(true);
930                    if(s != null) {
931                            connectionFailureCount = 0; // cleared because this change due to user interaction
932                            initSamplerModel(s);
933                    }
934            }
935            
936            private static final Vector<ActionListener> pListeners = new Vector<ActionListener>();
937            
938            /**
939             * Registers the specified listener to be notified when
940             * backend process is created/terminated.
941             * @param l The <code>ActionListener</code> to register.
942             */
943            public static void
944            addBackendProcessListener(ActionListener l) { pListeners.add(l); }
945            
946            /**
947             * Removes the specified listener.
948             * @param l The <code>ActionListener</code> to remove.
949             */
950            public static void
951            removeBackendProcessListener(ActionListener l) { pListeners.remove(l); }
952            
953            private static void
954            fireBackendProcessEvent() {
955                    ActionEvent e = new ActionEvent(CC.class, ActionEvent.ACTION_PERFORMED, null);
956                    for(ActionListener l : pListeners) l.actionPerformed(e);
957          }          }
958                    
959            private static Process backendProcess = null;
960            
961            public static Process
962            getBackendProcess() { return backendProcess; }
963            
964            private static final Object backendMonitor = new Object();
965            
966            public static Object
967            getBackendMonitor() { return backendMonitor; }
968            
969            private static boolean
970            launchBackend() throws Exception {
971                    if(backendProcess != null) {
972                            try {
973                                    int i = backendProcess.exitValue();
974                                    getLogger().info("Backend exited with exit value " + i);
975                                    backendProcess = null;
976                                    fireBackendProcessEvent();
977                            } catch(IllegalThreadStateException x) { return false; }
978                    }
979                    
980                    if(!preferences().getBoolProperty(JSPrefs.LAUNCH_BACKEND_LOCALLY)) return false;
981                    if(connectionFailureCount > 1) return false;
982                    
983                    Server  s = getCurrentServer();
984                    if(s != null && s.isLocal()) {
985                            String cmd = preferences().getStringProperty(JSPrefs.BACKEND_LAUNCH_COMMAND);
986                            backendProcess = Runtime.getRuntime().exec(cmd);
987                            fireBackendProcessEvent();
988                            return true;
989                    }
990                    
991                    return false;
992            }
993            
994            private static class GetFxSendsListener implements TaskListener {
995                    @Override
996                    public void
997                    taskPerformed(TaskEvent e) {
998                            Channel.GetFxSends gfs = (Channel.GetFxSends)e.getSource();
999                            if(gfs.doneWithErrors()) return;
1000                            SamplerChannelModel m = getSamplerModel().getChannelById(gfs.getChannel());
1001                            m.removeAllFxSends();
1002                            
1003                            for(FxSend fxs : gfs.getResult()) m.addFxSend(fxs);
1004                    }
1005            }
1006            
1007            public static String
1008            exportInstrMapsToLscpScript() {
1009                    StringBuffer sb = new StringBuffer("# Exported by: ");
1010                    sb.append("JSampler - a java front-end for LinuxSampler\r\n# Version: ");
1011                    sb.append(JSampler.VERSION).append("\r\n");
1012                    sb.append("# Date: ").append(new java.util.Date().toString()).append("\r\n\r\n");
1013                    
1014                    Client lscpClient = new Client(true);
1015                    ByteArrayOutputStream out = new ByteArrayOutputStream();
1016                    lscpClient.setPrintOnlyModeOutputStream(out);
1017                    
1018                    exportInstrMapsToLscpScript(lscpClient);
1019                    sb.append(out.toString());
1020                    out.reset();
1021                    
1022                    return sb.toString();
1023            }
1024            
1025            private static void
1026            exportInstrMapsToLscpScript(Client lscpClient) {
1027                    try {
1028                            lscpClient.removeAllMidiInstrumentMaps();
1029                            MidiInstrumentMap[] maps = getSamplerModel().getMidiInstrumentMaps();
1030                            for(int i = 0; i < maps.length; i++) {
1031                                    lscpClient.addMidiInstrumentMap(maps[i].getName());
1032                                    exportInstrumentsToLscpScript(i, maps[i], lscpClient);
1033                            }
1034                    } catch(Exception e) {
1035                            getLogger().log(Level.FINE, HF.getErrorMessage(e), e);
1036                            HF.showErrorMessage(e);
1037                    }
1038            }
1039            
1040            private static void
1041            exportInstrumentsToLscpScript(int mapId, MidiInstrumentMap map, Client lscpClient)
1042                                                                                    throws Exception {
1043            
1044                    boolean b = preferences().getBoolProperty(JSPrefs.LOAD_MIDI_INSTRUMENTS_IN_BACKGROUND);
1045                    
1046                    for(MidiInstrument i : map.getAllMidiInstruments()) {
1047                            lscpClient.mapMidiInstrument(mapId, i.getInfo().getEntry(), i.getInfo(), b);
1048                    }
1049            }
1050            
1051            public static String
1052            exportSessionToLscpScript() {
1053                    getSamplerModel().setModified(false);
1054                    
1055                    StringBuffer sb = new StringBuffer("# Exported by: ");
1056                    sb.append("JSampler - a java front-end for LinuxSampler\r\n# Version: ");
1057                    sb.append(JSampler.VERSION).append("\r\n");
1058                    sb.append("# Date: ").append(new java.util.Date().toString()).append("\r\n\r\n");
1059                    
1060                    Client lscpClient = new Client(true);
1061                    ByteArrayOutputStream out = new ByteArrayOutputStream();
1062                    lscpClient.setPrintOnlyModeOutputStream(out);
1063                    
1064                    try {
1065                            lscpClient.resetSampler();
1066                            sb.append(out.toString());
1067                            out.reset();
1068                            sb.append("\r\n");
1069                            lscpClient.setVolume(getSamplerModel().getVolume());
1070                            sb.append(out.toString());
1071                            out.reset();
1072                            sb.append("\r\n");
1073                    } catch(Exception e) { getLogger().log(Level.FINE, HF.getErrorMessage(e), e); }
1074                                    
1075                    MidiDeviceModel[] mDevs = getSamplerModel().getMidiDevices();
1076                    for(int i = 0; i < mDevs.length; i++) {
1077                            exportMidiDeviceToLscpScript(mDevs[i].getDeviceInfo(), i, lscpClient);
1078                            sb.append(out.toString());
1079                            out.reset();
1080                            sb.append("\r\n");
1081                    }
1082                    
1083                    AudioDeviceModel[] aDevs = getSamplerModel().getAudioDevices();
1084                    for(int i = 0; i < aDevs.length; i++) {
1085                            exportAudioDeviceToLscpScript(aDevs[i].getDeviceInfo(), i, lscpClient);
1086                            sb.append(out.toString());
1087                            out.reset();
1088                            sb.append("\r\n");
1089                    }
1090                    
1091                    boolean b = preferences().getBoolProperty(JSPrefs.EXPORT_MIDI_MAPS_TO_SESSION_SCRIPT);
1092                    if(b) {
1093                            exportInstrMapsToLscpScript(lscpClient);
1094                            sb.append(out.toString());
1095                            out.reset();
1096                            sb.append("\r\n");
1097                    }
1098                    
1099                    SamplerChannelModel[] channels = getSamplerModel().getChannels();
1100                    
1101                    for(int i = 0; i < channels.length; i++) {
1102                            SamplerChannelModel scm = channels[i];
1103                            exportChannelToLscpScript(scm.getChannelInfo(), i, lscpClient);
1104                            sb.append(out.toString());
1105                            out.reset();
1106                            
1107                            sb.append("\r\n");
1108                            
1109                            exportFxSendsToLscpScript(scm, i, lscpClient);
1110                            sb.append(out.toString());
1111                            out.reset();
1112                            
1113                            sb.append("\r\n");
1114                    }
1115                    
1116                    sb.append(getViewConfig().exportSessionViewConfig());
1117                    
1118                    return sb.toString();
1119            }
1120            
1121            private static void
1122            exportMidiDeviceToLscpScript(MidiInputDevice mid, int devId, Client lscpCLient) {
1123                    try {
1124                            String s = mid.getDriverName();
1125                            lscpCLient.createMidiInputDevice(s, mid.getAdditionalParameters());
1126                            
1127                            MidiPort[] mPorts = mid.getMidiPorts();
1128                            int l = mPorts.length;
1129                            if(l != 1) lscpCLient.setMidiInputPortCount(devId, l);
1130                            
1131                            for(int i = 0; i < l; i++) {
1132                                    Parameter[] prms = mPorts[i].getAllParameters();
1133                                    for(Parameter p : prms) {
1134                                            if(!p.isFixed() && p.getStringValue().length() > 0)
1135                                                    lscpCLient.setMidiInputPortParameter(devId, i, p);
1136                                    }
1137                            }
1138                    } catch(Exception e) {
1139                            getLogger().log(Level.FINE, HF.getErrorMessage(e), e);
1140                    }
1141            }
1142            
1143            private static void
1144            exportAudioDeviceToLscpScript(AudioOutputDevice aod, int devId, Client lscpCLient) {
1145                    try {
1146                            String s = aod.getDriverName();
1147                            lscpCLient.createAudioOutputDevice(s, aod.getAllParameters());
1148                            
1149                            AudioOutputChannel[] chns = aod.getAudioChannels();
1150                            
1151                            for(int i = 0; i < chns.length; i++) {
1152                                    Parameter[] prms = chns[i].getAllParameters();
1153                                    for(Parameter p : prms) {
1154                                            if(p.isFixed() || p.getStringValue().length() == 0);
1155                                            else lscpCLient.setAudioOutputChannelParameter(devId, i, p);
1156                                    }
1157                            }
1158                    } catch(Exception e) {
1159                            getLogger().log(Level.FINE, HF.getErrorMessage(e), e);
1160                    }
1161            }
1162            
1163            private static void
1164            exportChannelToLscpScript(SamplerChannel chn, int chnId, Client lscpCLient) {
1165                    try {
1166                            lscpCLient.addSamplerChannel();
1167                            
1168                            SamplerModel sm = getSamplerModel();
1169                            int id = chn.getMidiInputDevice();
1170                            if(id != -1) {
1171                                    for(int i = 0; i < sm.getMidiDeviceCount(); i++) {
1172                                            if(sm.getMidiDevice(i).getDeviceId() == id) {
1173                                                    lscpCLient.setChannelMidiInputDevice(chnId, i);
1174                                                    break;
1175                                            }
1176                                    }
1177                                    lscpCLient.setChannelMidiInputPort(chnId, chn.getMidiInputPort());
1178                                    lscpCLient.setChannelMidiInputChannel(chnId, chn.getMidiInputChannel());
1179                            }
1180                            
1181                            if(chn.getEngine() != null) {
1182                                    lscpCLient.loadSamplerEngine(chn.getEngine().getName(), chnId);
1183                                    lscpCLient.setChannelVolume(chnId, chn.getVolume());
1184                                    int mapId = chn.getMidiInstrumentMapId();
1185                                    lscpCLient.setChannelMidiInstrumentMap(chnId, mapId);
1186                            }
1187                            
1188                            id = chn.getAudioOutputDevice();
1189                            if(id != -1) {
1190                                    for(int i = 0; i < sm.getAudioDeviceCount(); i++) {
1191                                            if(sm.getAudioDevice(i).getDeviceId() == id) {
1192                                                    lscpCLient.setChannelAudioOutputDevice(chnId, i);
1193                                                    break;
1194                                            }
1195                                    }
1196                                    
1197                                    Integer[] routing = chn.getAudioOutputRouting();
1198                                    
1199                                    for(int j = 0; j < routing.length; j++) {
1200                                            int k = routing[j];
1201                                            if(k == j) continue;
1202                                            
1203                                            lscpCLient.setChannelAudioOutputChannel(chnId, j, k);
1204                                    }
1205                            }
1206                            
1207                            String s = chn.getInstrumentFile();
1208                            int i = chn.getInstrumentIndex();
1209                            if(s != null) lscpCLient.loadInstrument(s, i, chnId, true);
1210                            
1211                            if(chn.isMuted()) lscpCLient.setChannelMute(chnId, true);
1212                            if(chn.isSoloChannel()) lscpCLient.setChannelSolo(chnId, true);
1213                    } catch(Exception e) {
1214                            getLogger().log(Level.FINE, HF.getErrorMessage(e), e);
1215                    }
1216            }
1217            
1218            private static void
1219            exportFxSendsToLscpScript(SamplerChannelModel scm, int chnId, Client lscpClient) {
1220                    try {
1221                            FxSend[] fxSends = scm.getFxSends();
1222                            
1223                            for(int i = 0; i < fxSends.length; i++) {
1224                                    FxSend f = fxSends[i];
1225                                    lscpClient.createFxSend(chnId, f.getMidiController(), f.getName());
1226                                    
1227                                    Integer[] r = f.getAudioOutputRouting();
1228                                    for(int j = 0; j < r.length; j++) {
1229                                            lscpClient.setFxSendAudioOutputChannel(chnId, i, j, r[j]);
1230                                    }
1231                            }
1232                    } catch(Exception e) {
1233                            getLogger().log(Level.FINE, HF.getErrorMessage(e), e);
1234                    }
1235            }
1236            
1237            public static void
1238            scheduleInTaskQueue(final Runnable r) {
1239                    Task dummy = new Global.DummyTask();
1240                    dummy.addTaskListener(new TaskListener() {
1241                            public void
1242                            taskPerformed(TaskEvent e) {
1243                                    javax.swing.SwingUtilities.invokeLater(r);
1244                            }
1245                    });
1246                    
1247                    getTaskQueue().add(dummy);
1248            }
1249            
1250            public static boolean
1251            verifyConnection() {
1252                    if(getCurrentServer() == null) {
1253                            HF.showErrorMessage(i18n.getError("CC.notConnected"));
1254                            return false;
1255                    }
1256                    
1257                    return true;
1258            }
1259            
1260            
1261            private final static EventHandler eventHandler = new EventHandler();
1262            
1263            private static EventHandler
1264            getHandler() { return eventHandler; }
1265            
1266          private static class EventHandler implements ChannelCountListener, ChannelInfoListener,          private static class EventHandler implements ChannelCountListener, ChannelInfoListener,
1267                                  StreamCountListener, VoiceCountListener, TotalVoiceCountListener {                  FxSendCountListener, FxSendInfoListener, StreamCountListener, VoiceCountListener,
1268                    TotalStreamCountListener, TotalVoiceCountListener, TaskQueueListener,
1269                    OrchestraListener, ListListener<OrchestraModel>, MidiInstrumentCountListener,
1270                    MidiInstrumentInfoListener, GlobalInfoListener, ChannelMidiDataListener {
1271                                    
1272                  /** Invoked when the number of channels has changed. */                  /** Invoked when the number of channels has changed. */
1273                    @Override
1274                  public void                  public void
1275                  channelCountChanged( ChannelCountEvent e) {                  channelCountChanged( ChannelCountEvent e) {
1276                          getTaskQueue().add(new UpdateChannels());                          if(e.getChannelCount() == 0) {
1277                                    /*
1278                                     * This special case is handled because this might be due to
1279                                     * loading a lscp script containing sampler view configuration.
1280                                     */
1281                                    CC.getSamplerModel().removeAllChannels();
1282                                    return;
1283                            }
1284                            addTask(new UpdateChannels());
1285                  }                  }
1286                                    
1287                  /** Invoked when changes to the sampler channel has occured. */                  /** Invoked when changes to the sampler channel has occured. */
1288                    @Override
1289                  public void                  public void
1290                  channelInfoChanged(ChannelInfoEvent e) {                  channelInfoChanged(ChannelInfoEvent e) {
1291                          /*                          /*
# Line 265  public class CC { Line 1298  public class CC {
1298                          for(int i = tS.length - 1; i >= 0; i--) {                          for(int i = tS.length - 1; i >= 0; i--) {
1299                                  Task t = tS[i];                                  Task t = tS[i];
1300                                                                    
1301                                  if(t instanceof UpdateChannelInfo) {                                  if(t instanceof Channel.UpdateInfo) {
1302                                          UpdateChannelInfo uci = (UpdateChannelInfo)t;                                          Channel.UpdateInfo cui = (Channel.UpdateInfo)t;
1303                                          if(uci.getChannelID() == e.getSamplerChannel()) return;                                          if(cui.getChannelId() == e.getSamplerChannel()) return;
1304                                  } else {                                  } else {
1305                                          b = false;                                          b = false;
1306                                          break;                                          break;
# Line 276  public class CC { Line 1309  public class CC {
1309                                                    
1310                          if(b) {                          if(b) {
1311                                  Task t = getTaskQueue().getRunningTask();                                  Task t = getTaskQueue().getRunningTask();
1312                                  if(t instanceof UpdateChannelInfo) {                                  if(t instanceof Channel.UpdateInfo) {
1313                                          UpdateChannelInfo uci = (UpdateChannelInfo)t;                                          Channel.UpdateInfo cui = (Channel.UpdateInfo)t;
1314                                          if(uci.getChannelID() == e.getSamplerChannel()) return;                                          if(cui.getChannelId() == e.getSamplerChannel()) return;
1315                                  }                                  }
1316                          }                          }
1317                                                    
1318                                                    
1319                          getTaskQueue().add(new UpdateChannelInfo(e.getSamplerChannel()));                          getTaskQueue().add(new Channel.UpdateInfo(e.getSamplerChannel()));
1320                    }
1321                    
1322                    /**
1323                     * Invoked when the number of effect sends
1324                     * on a particular sampler channel has changed.
1325                     */
1326                    @Override
1327                    public void
1328                    fxSendCountChanged(FxSendCountEvent e) {
1329                            getTaskQueue().add(new Channel.UpdateFxSends(e.getChannel()));
1330                    }
1331                    
1332                    /**
1333                     * Invoked when the settings of an effect sends are changed.
1334                     */
1335                    @Override
1336                    public void
1337                    fxSendInfoChanged(FxSendInfoEvent e) {
1338                            Task t = new Channel.UpdateFxSendInfo(e.getChannel(), e.getFxSend());
1339                            getTaskQueue().add(t);
1340                  }                  }
1341                                    
1342                  /**                  /**
1343                   * Invoked when the number of active disk                   * Invoked when the number of active disk
1344                   * streams in a specific sampler channel has changed.                   * streams in a specific sampler channel has changed.
1345                   */                   */
1346                    @Override
1347                  public void                  public void
1348                  streamCountChanged(StreamCountEvent e) {                  streamCountChanged(StreamCountEvent e) {
1349                          SamplerChannelModel scm =                          SamplerChannelModel scm =
1350                                  getSamplerModel().getChannelModel(e.getSamplerChannel());                                  getSamplerModel().getChannelById(e.getSamplerChannel());
1351                                                    
1352                          if(scm == null) {                          if(scm == null) {
1353                                  CC.getLogger().log (                                  CC.getLogger().log (
# Line 312  public class CC { Line 1366  public class CC {
1366                   * Invoked when the number of active voices                   * Invoked when the number of active voices
1367                   * in a specific sampler channel has changed.                   * in a specific sampler channel has changed.
1368                   */                   */
1369                    @Override
1370                  public void                  public void
1371                  voiceCountChanged(VoiceCountEvent e) {                  voiceCountChanged(VoiceCountEvent e) {
1372                          SamplerChannelModel scm =                          SamplerChannelModel scm =
1373                                  getSamplerModel().getChannelModel(e.getSamplerChannel());                                  getSamplerModel().getChannelById(e.getSamplerChannel());
1374                                                    
1375                          if(scm == null) {                          if(scm == null) {
1376                                  CC.getLogger().log (                                  CC.getLogger().log (
# Line 330  public class CC { Line 1385  public class CC {
1385                          scm.setVoiceCount(e.getVoiceCount());                          scm.setVoiceCount(e.getVoiceCount());
1386                  }                  }
1387                                    
1388                    /** Invoked when the total number of active streams has changed. */
1389                    @Override
1390                    public void
1391                    totalStreamCountChanged(TotalStreamCountEvent e) {
1392                            getSamplerModel().updateActiveStreamsInfo(e.getTotalStreamCount());
1393                    }
1394                    
1395                  /** Invoked when the total number of active voices has changed. */                  /** Invoked when the total number of active voices has changed. */
1396                    @Override
1397                  public void                  public void
1398                  totalVoiceCountChanged(TotalVoiceCountEvent e) {                  totalVoiceCountChanged(TotalVoiceCountEvent e) {
1399                          getTaskQueue().add(new UpdateTotalVoiceCount());                          scheduleTask(new UpdateTotalVoiceCount());
1400                    }
1401                    
1402                    /** Invoked when the number of MIDI instruments in a MIDI instrument map is changed. */
1403                    @Override
1404                    public void
1405                    instrumentCountChanged(MidiInstrumentCountEvent e) {
1406                            scheduleTask(new Midi.UpdateInstruments(e.getMapId()));
1407                    }
1408                    
1409                    /** Invoked when a MIDI instrument in a MIDI instrument map is changed. */
1410                    @Override
1411                    public void
1412                    instrumentInfoChanged(MidiInstrumentInfoEvent e) {
1413                            Task t = new Midi.UpdateInstrumentInfo (
1414                                    e.getMapId(), e.getMidiBank(), e.getMidiProgram()
1415                            );
1416                            getTaskQueue().add(t);
1417                                    
1418                    }
1419                    
1420                    /** Invoked when the global volume of the sampler is changed. */
1421                    @Override
1422                    public void
1423                    volumeChanged(GlobalInfoEvent e) {
1424                            getSamplerModel().setVolume(e.getVolume());
1425                    }
1426                    
1427                    @Override
1428                    public void
1429                    voiceLimitChanged(GlobalInfoEvent e) { }
1430                    
1431                    @Override
1432                    public void
1433                    streamLimitChanged(GlobalInfoEvent e) { }
1434                    
1435                    /**
1436                     * Invoked to indicate that the state of a task queue is changed.
1437                     * This method is invoked only from the event-dispatching thread.
1438                     */
1439                    @Override
1440                    public void
1441                    stateChanged(TaskQueueEvent e) {
1442                            switch(e.getEventID()) {
1443                            case TASK_FETCHED:
1444                                    getProgressIndicator().setString (
1445                                            ((Task)e.getSource()).getDescription()
1446                                    );
1447                                    break;
1448                            case TASK_DONE:
1449                                    EnhancedTask t = (EnhancedTask)e.getSource();
1450                                    if(t.doneWithErrors() && !t.isStopped() && !t.isSilent()) {
1451                                            showError(t);
1452                                    }
1453                                    break;
1454                            case NOT_IDLE:
1455                                    timer.start();
1456                                    break;
1457                            case IDLE:
1458                                    timer.stop();
1459                                    getProgressIndicator().stop();
1460                                    break;
1461                            }
1462                    }
1463                    
1464                    private void
1465                    showError(final Task t) {
1466                            javax.swing.SwingUtilities.invokeLater(new Runnable() {
1467                                    public void
1468                                    run() {
1469                                            if(t.getErrorDetails() == null) {
1470                                                    HF.showErrorMessage(t.getErrorMessage());
1471                                            } else {
1472                                                    getMainFrame().showDetailedErrorMessage (
1473                                                            getMainFrame(),
1474                                                            t.getErrorMessage(),
1475                                                            t.getErrorDetails()
1476                                                    );
1477                                            }
1478                                    }
1479                            });
1480                    }
1481                    
1482                    /** Invoked when the name of orchestra is changed. */
1483                    @Override
1484                    public void
1485                    nameChanged(OrchestraEvent e) { saveOrchestras(); }
1486            
1487                    /** Invoked when the description of orchestra is changed. */
1488                    @Override
1489                    public void
1490                    descriptionChanged(OrchestraEvent e) { saveOrchestras(); }
1491            
1492                    /** Invoked when an instrument is added to the orchestra. */
1493                    @Override
1494                    public void
1495                    instrumentAdded(OrchestraEvent e) { saveOrchestras(); }
1496            
1497                    /** Invoked when an instrument is removed from the orchestra. */
1498                    @Override
1499                    public void
1500                    instrumentRemoved(OrchestraEvent e) { saveOrchestras(); }
1501            
1502                    /** Invoked when the settings of an instrument are changed. */
1503                    @Override
1504                    public void
1505                    instrumentChanged(OrchestraEvent e) { saveOrchestras(); }
1506                    
1507                    /** Invoked when an orchestra is added to the orchestra list. */
1508                    @Override
1509                    public void
1510                    entryAdded(ListEvent<OrchestraModel> e) {
1511                            e.getEntry().addOrchestraListener(getHandler());
1512                            saveOrchestras();
1513                    }
1514            
1515                    /** Invoked when an orchestra is removed from the orchestra list. */
1516                    @Override
1517                    public void
1518                    entryRemoved(ListEvent<OrchestraModel> e) {
1519                            e.getEntry().removeOrchestraListener(getHandler());
1520                            saveOrchestras();
1521                    }
1522                    
1523                    /**
1524                     * Invoked when MIDI data arrives.
1525                     */
1526                    @Override
1527                    public void
1528                    midiDataArrived(final ChannelMidiDataEvent e) {
1529                            try {
1530                                    javax.swing.SwingUtilities.invokeAndWait(new Runnable() {
1531                                            public void
1532                                            run() { fireChannelMidiDataEvent(e); }
1533                                    });
1534                            } catch(Exception x) {
1535                                    CC.getLogger().log(Level.INFO, "Failed!", x);
1536                            }
1537                    }
1538            }
1539            
1540            private static void
1541            fireChannelMidiDataEvent(ChannelMidiDataEvent e) {
1542                    SamplerChannelModel chn;
1543                    chn = CC.getSamplerModel().getChannelById(e.getChannelId());
1544                    if(chn == null) {
1545                            CC.getLogger().info("Unknown channel ID: " + e.getChannelId());
1546                    }
1547                    
1548                    ((DefaultSamplerChannelModel)chn).fireMidiDataEvent(e);
1549            }
1550            
1551            private static final AudioDeviceCountListener audioDeviceCountListener =
1552                    new AudioDeviceCountListener();
1553            
1554            private static class AudioDeviceCountListener implements ItemCountListener {
1555                    /** Invoked when the number of audio output devices has changed. */
1556                    @Override
1557                    public void
1558                    itemCountChanged(ItemCountEvent e) {
1559                            getTaskQueue().add(new Audio.UpdateDevices());
1560                    }
1561            }
1562            
1563            private static final AudioDeviceInfoListener audioDeviceInfoListener =
1564                    new AudioDeviceInfoListener();
1565            
1566            private static class AudioDeviceInfoListener implements ItemInfoListener {
1567                    /** Invoked when the audio output device's settings are changed. */
1568                    @Override
1569                    public void
1570                    itemInfoChanged(ItemInfoEvent e) {
1571                            getTaskQueue().add(new Audio.UpdateDeviceInfo(e.getItemID()));
1572                    }
1573            }
1574            
1575            private static final MidiDeviceCountListener midiDeviceCountListener =
1576                    new MidiDeviceCountListener();
1577            
1578            private static class MidiDeviceCountListener implements ItemCountListener {
1579                    /** Invoked when the number of MIDI input devices has changed. */
1580                    @Override
1581                    public void
1582                    itemCountChanged(ItemCountEvent e) {
1583                            getTaskQueue().add(new Midi.UpdateDevices());
1584                    }
1585            }
1586            
1587            private static final MidiDeviceInfoListener midiDeviceInfoListener =
1588                    new MidiDeviceInfoListener();
1589            
1590            private static class MidiDeviceInfoListener implements ItemInfoListener {
1591                    /** Invoked when the MIDI input device's settings are changed. */
1592                    @Override
1593                    public void
1594                    itemInfoChanged(ItemInfoEvent e) {
1595                            getTaskQueue().add(new Midi.UpdateDeviceInfo(e.getItemID()));
1596                    }
1597            }
1598            
1599            private static final MidiInstrMapCountListener midiInstrMapCountListener =
1600                    new MidiInstrMapCountListener();
1601            
1602            private static class MidiInstrMapCountListener implements ItemCountListener {
1603                    /** Invoked when the number of MIDI instrument maps is changed. */
1604                    @Override
1605                    public void
1606                    itemCountChanged(ItemCountEvent e) {
1607                            getTaskQueue().add(new Midi.UpdateInstrumentMaps());
1608                    }
1609            }
1610            
1611            private static final MidiInstrMapInfoListener midiInstrMapInfoListener =
1612                    new MidiInstrMapInfoListener();
1613            
1614            private static class MidiInstrMapInfoListener implements ItemInfoListener {
1615                    /** Invoked when the MIDI instrument map's settings are changed. */
1616                    @Override
1617                    public void
1618                    itemInfoChanged(ItemInfoEvent e) {
1619                            getTaskQueue().add(new Midi.UpdateInstrumentMapInfo(e.getItemID()));
1620                  }                  }
1621          }          }
1622  }  }

Legend:
Removed from v.842  
changed lines
  Added in v.1818

  ViewVC Help
Powered by ViewVC