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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1204 - (show annotations) (download)
Thu May 24 21:43:45 2007 UTC (16 years, 11 months ago) by iliev
File size: 33574 byte(s)
upgrading to version 0.5a

1 /*
2 * JSampler - a java front-end for LinuxSampler
3 *
4 * Copyright (C) 2005-2007 Grigor Iliev <grigor@grigoriliev.com>
5 *
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 import java.io.ByteArrayInputStream;
29 import java.io.ByteArrayOutputStream;
30 import java.io.File;
31 import java.io.FileInputStream;
32 import java.io.FileOutputStream;
33 import java.io.InputStream;
34
35 import java.util.Vector;
36
37 import java.util.logging.Handler;
38 import java.util.logging.Level;
39 import java.util.logging.Logger;
40 import java.util.logging.SimpleFormatter;
41 import java.util.logging.StreamHandler;
42
43 import javax.swing.Timer;
44
45 import net.sf.juife.Task;
46 import net.sf.juife.TaskQueue;
47
48 import net.sf.juife.event.TaskEvent;
49 import net.sf.juife.event.TaskListener;
50 import net.sf.juife.event.TaskQueueEvent;
51 import net.sf.juife.event.TaskQueueListener;
52
53 import org.jsampler.event.ListEvent;
54 import org.jsampler.event.ListListener;
55 import org.jsampler.event.OrchestraEvent;
56 import org.jsampler.event.OrchestraListener;
57
58 import org.jsampler.task.*;
59
60 import org.jsampler.view.JSMainFrame;
61 import org.jsampler.view.JSProgress;
62 import org.jsampler.view.InstrumentsDbTreeModel;
63
64 import org.linuxsampler.lscp.AudioOutputChannel;
65 import org.linuxsampler.lscp.AudioOutputDevice;
66 import org.linuxsampler.lscp.Client;
67 import org.linuxsampler.lscp.FxSend;
68 import org.linuxsampler.lscp.MidiInputDevice;
69 import org.linuxsampler.lscp.MidiPort;
70 import org.linuxsampler.lscp.Parameter;
71 import org.linuxsampler.lscp.SamplerChannel;
72
73 import org.linuxsampler.lscp.event.*;
74
75 import org.w3c.dom.Document;
76 import org.w3c.dom.Node;
77
78 import static org.jsampler.JSI18n.i18n;
79
80
81 /**
82 * This class serves as a 'Control Center' of the application.
83 * It also provides some fundamental routines and access to most used objects.
84 * @author Grigor Iliev
85 */
86 public class CC {
87 private static Handler handler;
88 private static FileOutputStream fos;
89
90 private static JSMainFrame mainFrame = null;
91 private static JSProgress progress = null;
92
93 private final static Client lsClient = new Client();
94
95 private static String jSamplerHome = null;
96
97 private final static TaskQueue taskQueue = new TaskQueue();
98 private final static Timer timer = new Timer(2000, null);
99
100 /** Forbits the instantiation of this class. */
101 private
102 CC() { }
103
104 /**
105 * Returns the logger to be used for logging events.
106 * @return The logger to be used for logging events.
107 */
108 public static Logger
109 getLogger() {
110 return Logger.getLogger (
111 "org.jsampler",
112 "org.jsampler.langprops.LogsBundle"
113 );
114 }
115
116 /**
117 * Returns the task queue to be used for scheduling tasks
118 * for execution out of the event-dispatching thread.
119 * @return The task queue to be used for scheduling tasks
120 * for execution out of the event-dispatching thread.
121 */
122 public static TaskQueue
123 getTaskQueue() { return taskQueue; }
124
125 /**
126 * Adds the specified task to the task queue. All task in the
127 * queue equal to the specified task are removed from the queue.
128 */
129 public static void
130 scheduleTask(Task t) {
131 while(getTaskQueue().removeTask(t)) { }
132
133 if(getTaskQueue().getPendingTaskCount() == 0) {
134 if(t.equals(getTaskQueue().getRunningTask())) return;
135 }
136
137 getTaskQueue().add(t);
138 }
139
140 /**
141 * Returns the main window of this application.
142 * @return The main window of this application.
143 */
144 public static JSMainFrame
145 getMainFrame() { return mainFrame; }
146
147 /**
148 * Sets the main window of this application.
149 * @param mainFrame The main window of this application.
150 */
151 public static void
152 setMainFrame(JSMainFrame mainFrame) { CC.mainFrame = mainFrame; }
153
154 /**
155 * Gets the progress indicator of this application.
156 * @return The progress indicator of this application.
157 */
158 public static JSProgress
159 getProgressIndicator() { return progress; }
160
161 /**
162 * Sets the progress indicator to be used by this application.
163 * @param progress The progress indicator to be used by this application.
164 */
165 public static void
166 setProgressIndicator(JSProgress progress) { CC.progress = progress; }
167
168 /**
169 * Gets the absolute path to the JSampler's home location.
170 * @return The absolute path to the JSampler's home location
171 * or <code>null</code> if the JSampler's home location is not specified yet.
172 */
173 public static String
174 getJSamplerHome() { return jSamplerHome; }
175
176 /**
177 * Sets the location of the JSampler's home.
178 * @param path The new absolute path to the JSampler's home location.
179 */
180 public static void
181 setJSamplerHome(String path) {
182 jSamplerHome = path;
183 Prefs.setJSamplerHome(jSamplerHome);
184 }
185
186 /**
187 * This method does the initial preparation of the application.
188 */
189 protected static void
190 initJSampler() {
191 fos = null;
192 setJSamplerHome(Prefs.getJSamplerHome());
193 String s = getJSamplerHome();
194 try {
195 if(s != null) {
196 s += File.separator + "jsampler.log";
197 File f = new File(s);
198 if(f.isFile()) HF.createBackup("jsampler.log", "jsampler.log.0");
199 fos = new FileOutputStream(s);
200 }
201 } catch(Exception x) { x.printStackTrace(); }
202
203 if(fos == null) handler = new StreamHandler(System.out, new SimpleFormatter());
204 else handler = new StreamHandler(fos, new SimpleFormatter());
205
206 handler.setLevel(Level.FINE);
207 getLogger().addHandler(handler);
208 getLogger().setLevel(Level.FINE);
209 Logger.getLogger("org.linuxsampler.lscp").setLevel(Level.FINE);
210 Logger.getLogger("org.linuxsampler.lscp").addHandler(handler);
211
212 // Flushing logs on every second
213 new java.util.Timer().schedule(new java.util.TimerTask() {
214 public void
215 run() { if(handler != null) handler.flush(); }
216 }, 1000, 1000);
217
218 CC.getLogger().fine("CC.jsStarted");
219
220 HF.setUIDefaultFont(Prefs.getInterfaceFont());
221
222 getClient().setServerAddress(Prefs.getLSAddress());
223 getClient().setServerPort(Prefs.getLSPort());
224
225 timer.setRepeats(false);
226
227 timer.addActionListener(new ActionListener() {
228 public void
229 actionPerformed(ActionEvent e) { CC.getProgressIndicator().start(); }
230 });
231
232 taskQueue.addTaskQueueListener(getHandler());
233
234 taskQueue.start();
235
236 getClient().removeChannelCountListener(getHandler());
237 getClient().addChannelCountListener(getHandler());
238
239 getClient().removeChannelInfoListener(getHandler());
240 getClient().addChannelInfoListener(getHandler());
241
242 getClient().removeFxSendCountListener(getHandler());
243 getClient().addFxSendCountListener(getHandler());
244
245 getClient().removeFxSendInfoListener(getHandler());
246 getClient().addFxSendInfoListener(getHandler());
247
248 getClient().removeStreamCountListener(getHandler());
249 getClient().addStreamCountListener(getHandler());
250
251 getClient().removeVoiceCountListener(getHandler());
252 getClient().addVoiceCountListener(getHandler());
253
254 getClient().removeTotalVoiceCountListener(getHandler());
255 getClient().addTotalVoiceCountListener(getHandler());
256
257 getClient().removeAudioDeviceCountListener(audioDeviceCountListener);
258 getClient().addAudioDeviceCountListener(audioDeviceCountListener);
259
260 getClient().removeAudioDeviceInfoListener(audioDeviceInfoListener);
261 getClient().addAudioDeviceInfoListener(audioDeviceInfoListener);
262
263 getClient().removeMidiDeviceCountListener(midiDeviceCountListener);
264 getClient().addMidiDeviceCountListener(midiDeviceCountListener);
265
266 getClient().removeMidiDeviceInfoListener(midiDeviceInfoListener);
267 getClient().addMidiDeviceInfoListener(midiDeviceInfoListener);
268
269 getClient().removeMidiInstrumentMapCountListener(midiInstrMapCountListener);
270 getClient().addMidiInstrumentMapCountListener(midiInstrMapCountListener);
271
272 getClient().removeMidiInstrumentMapInfoListener(midiInstrMapInfoListener);
273 getClient().addMidiInstrumentMapInfoListener(midiInstrMapInfoListener);
274
275 getClient().removeMidiInstrumentCountListener(getHandler());
276 getClient().addMidiInstrumentCountListener(getHandler());
277
278 getClient().removeMidiInstrumentInfoListener(getHandler());
279 getClient().addMidiInstrumentInfoListener(getHandler());
280
281 getClient().removeGlobalInfoListener(getHandler());
282 getClient().addGlobalInfoListener(getHandler());
283 }
284
285 /**
286 * Checks whether the JSampler home directory is specified and exist.
287 * If the JSampler home directory is not specifed, or is specified
288 * but doesn't exist, a procedure of specifying a JSampler home
289 * directory is initiated.
290 * @see org.jsampler.view.JSMainFrame#installJSamplerHome
291 */
292 public static void
293 checkJSamplerHome() {
294 if(getJSamplerHome() != null) {
295 File f = new File(getJSamplerHome());
296 if(f.isDirectory()) return;
297 }
298
299 CC.getMainFrame().installJSamplerHome();
300 }
301
302 /**
303 * Changes the JSampler's home directory and moves all files from
304 * the old JSampler's home directory to the new one. If all files are
305 * moved succesfully, the old directory is deleted.
306 * @param path The location of the new JSampler's home directory. If
307 * the last directory in the path doesn't exist, it is created.
308 */
309 public static void
310 changeJSamplerHome(String path) {
311 File fNew = new File(path);
312 if(fNew.isFile()) {
313 HF.showErrorMessage(i18n.getError("CC.JSamplerHomeIsNotDir!"));
314 return;
315 }
316
317 if(!fNew.isDirectory()) {
318 if(!fNew.mkdir()) {
319 String s = fNew.getAbsolutePath();
320 HF.showErrorMessage(i18n.getError("CC.mkdirFailed", s));
321 return;
322 }
323 }
324
325 if(getJSamplerHome() == null) {
326 setJSamplerHome(fNew.getAbsolutePath());
327 return;
328 }
329
330 File fOld = new File(getJSamplerHome());
331 if(!fOld.isDirectory()) {
332 setJSamplerHome(fNew.getAbsolutePath());
333 return;
334 }
335
336 File[] files = fOld.listFiles();
337 boolean b = true;
338 if(files != null) {
339 String s = fNew.getAbsolutePath() + File.separator;
340 for(File f : files) if(!f.renameTo(new File(s + f.getName()))) b = false;
341 }
342
343 if(b) fOld.delete();
344 setJSamplerHome(fNew.getAbsolutePath());
345 }
346
347 private final static OrchestraListModel orchestras = new DefaultOrchestraListModel();
348
349 /**
350 * Returns a list containing all available orchestras.
351 * @return A list containing all available orchestras.
352 */
353 public static OrchestraListModel
354 getOrchestras() { return orchestras; }
355
356 private static InstrumentsDbTreeModel instrumentsDbTreeModel = null;
357 /**
358 * Gets the tree model of the instruments database.
359 * If the currently used view doesn't have instruments
360 * database support the tree model is initialized on first use.
361 * @return The tree model of the instruments database or
362 * <code>null</code> if the backend doesn't have instruments database support.
363 * @see org.jsampler.view.JSMainFrame#getInstrumentsDbSupport
364 */
365 public static InstrumentsDbTreeModel
366 getInstrumentsDbTreeModel() {
367 if(!CC.getSamplerModel().getServerInfo().hasInstrumentsDbSupport()) return null;
368
369 if(instrumentsDbTreeModel == null) {
370 instrumentsDbTreeModel = new InstrumentsDbTreeModel();
371 }
372
373 return instrumentsDbTreeModel;
374 }
375
376 /**
377 * Loads the orchestras described in <code>&lt;jsampler_home&gt;/orchestras.xml</code>.
378 * If file with name <code>orchestras.xml.bkp</code> exist in the JSampler's home
379 * directory, this means that the last save has failed. In that case a recovery file
380 * <code>orchestras.xml.rec</code> is created and a recovery procedure
381 * will be initiated.
382 */
383 public static void
384 loadOrchestras() {
385 if(getJSamplerHome() == null) return;
386
387 //TODO: This should be removed in the next release (including loadOrchestras0())
388 File f2 = new File(getJSamplerHome() + File.separator + "orchestras.xml");
389 if(!f2.isFile()) {
390 loadOrchestras0();
391 saveOrchestras();
392 return;
393 }
394 ///////
395
396 try {
397 String s = getJSamplerHome();
398 if(s == null) return;
399
400 File f = new File(s + File.separator + "orchestras.xml.bkp");
401 if(f.isFile()) HF.createBackup("orchestras.xml.bkp", "orchestras.xml.rec");
402
403 FileInputStream fis;
404 fis = new FileInputStream(s + File.separator + "orchestras.xml");
405
406 loadOrchestras(fis);
407 fis.close();
408 } catch(Exception x) {
409 getLogger().log(Level.INFO, HF.getErrorMessage(x), x);
410 }
411 }
412
413
414 private static void
415 loadOrchestras(InputStream in) {
416 Document doc = DOMUtils.readObject(in);
417
418 try { getOrchestras().readObject(doc.getDocumentElement()); }
419 catch(Exception x) {
420 HF.showErrorMessage(x, "Loading orchestras: ");
421 return;
422 }
423
424 for(int i = 0; i < getOrchestras().getOrchestraCount(); i++) {
425 getOrchestras().getOrchestra(i).addOrchestraListener(getHandler());
426 }
427 getOrchestras().addOrchestraListListener(getHandler());
428 }
429
430 private static void
431 loadOrchestras0() {
432 String s = Prefs.getOrchestras();
433 if(s == null) return;
434
435 ByteArrayInputStream bais = new ByteArrayInputStream(s.getBytes());
436 Document doc = DOMUtils.readObject(bais);
437
438 try { getOrchestras().readObject(doc.getDocumentElement()); }
439 catch(Exception x) { HF.showErrorMessage(x, "Loading orchestras: "); }
440 }
441
442 private static void
443 saveOrchestras() {
444 try {
445 String s = getJSamplerHome();
446 if(s == null) return;
447
448 HF.createBackup("orchestras.xml", "orchestras.xml.bkp");
449
450 FileOutputStream fos;
451 fos = new FileOutputStream(s + File.separator + "orchestras.xml", false);
452
453 Document doc = DOMUtils.createEmptyDocument();
454
455 Node node = doc.createElement("temp");
456 doc.appendChild(node);
457
458 getOrchestras().writeObject(doc, doc.getDocumentElement());
459
460 doc.replaceChild(node.getFirstChild(), node);
461
462 DOMUtils.writeObject(doc, fos);
463
464 fos.close();
465
466 HF.deleteFile("orchestras.xml.bkp");
467 } catch(Exception x) {
468 HF.showErrorMessage(x, "Saving orchestras: ");
469 return;
470 }
471 }
472
473 /**
474 * The exit point of the application which ensures clean exit with default exit status 0.
475 * @see #cleanExit(int i)
476 */
477 public static void
478 cleanExit() { cleanExit(0); }
479
480 /**
481 * The exit point of the application which ensures clean exit.
482 * @param i The exit status.
483 */
484 public static void
485 cleanExit(int i) {
486 CC.getLogger().fine("CC.jsEnded");
487 System.exit(i);
488 }
489
490 /**
491 * Gets the <code>Client</code> object that is used to communicate with the backend.
492 * @return The <code>Client</code> object that is used to communicate with the backend.
493 */
494 public static Client
495 getClient() { return lsClient; }
496
497 private static final Vector<ActionListener> listeners = new Vector<ActionListener>();
498
499 /**
500 * Registers the specified listener to be notified when reconnecting to LinuxSampler.
501 * @param l The <code>ActionListener</code> to register.
502 */
503 public static void
504 addReconnectListener(ActionListener l) { listeners.add(l); }
505
506 /**
507 * Removes the specified listener.
508 * @param l The <code>ActionListener</code> to remove.
509 */
510 public static void
511 removeReconnectListener(ActionListener l) { listeners.remove(l); }
512
513 private static void
514 fireReconnectEvent() {
515 ActionEvent e = new ActionEvent(CC.class, ActionEvent.ACTION_PERFORMED, null);
516 for(ActionListener l : listeners) l.actionPerformed(e);
517 }
518
519 private static final SamplerModel samplerModel = new DefaultSamplerModel();
520
521 /**
522 * Gets the sampler model.
523 * @return The sampler model.
524 */
525 public static SamplerModel
526 getSamplerModel() { return samplerModel; }
527
528 /**
529 * Reconnects to LinuxSampler.
530 */
531 public static void
532 reconnect() {
533 initSamplerModel();
534 fireReconnectEvent();
535 }
536
537 /**
538 * This method updates the information about the backend state.
539 */
540 public static void
541 initSamplerModel() {
542 final DefaultSamplerModel model = (DefaultSamplerModel)getSamplerModel();
543
544 final Global.GetServerInfo gsi = new Global.GetServerInfo();
545 gsi.addTaskListener(new TaskListener() {
546 public void
547 taskPerformed(TaskEvent e) {
548 if(gsi.doneWithErrors()) return;
549
550 model.setServerInfo(gsi.getResult());
551
552 if(CC.getMainFrame().getInstrumentsDbSupport()) {
553 getInstrumentsDbTreeModel();
554 }
555 }
556 });
557
558 final Audio.GetDrivers gaod = new Audio.GetDrivers();
559 gaod.addTaskListener(new TaskListener() {
560 public void
561 taskPerformed(TaskEvent e) {
562 if(!gaod.doneWithErrors())
563 model.setAudioOutputDrivers(gaod.getResult());
564 }
565 });
566
567 final GetEngines ge = new GetEngines();
568 ge.addTaskListener(new TaskListener() {
569 public void
570 taskPerformed(TaskEvent e) {
571 if(!ge.doneWithErrors()) model.setEngines(ge.getResult());
572 }
573 });
574
575 final Midi.GetDrivers gmid = new Midi.GetDrivers();
576 gmid.addTaskListener(new TaskListener() {
577 public void
578 taskPerformed(TaskEvent e) {
579 if(!gmid.doneWithErrors())
580 model.setMidiInputDrivers(gmid.getResult());
581 }
582 });
583
584 final Global.GetVolume gv = new Global.GetVolume();
585 gv.addTaskListener(new TaskListener() {
586 public void
587 taskPerformed(TaskEvent e) {
588 if(!gv.doneWithErrors())
589 model.setVolume(gv.getResult());
590 }
591 });
592
593 final Midi.GetInstrumentMaps mgim = new Midi.GetInstrumentMaps();
594 mgim.addTaskListener(new TaskListener() {
595 public void
596 taskPerformed(TaskEvent e) {
597 if(mgim.doneWithErrors()) return;
598 model.removeAllMidiInstrumentMaps();
599
600 for(MidiInstrumentMap map : mgim.getResult()) {
601 model.addMidiInstrumentMap(map);
602 }
603 }
604 });
605
606 final UpdateChannels uc = new UpdateChannels();
607 uc.addTaskListener(new TaskListener() {
608 public void
609 taskPerformed(TaskEvent e) {
610 for(SamplerChannelModel c : model.getChannels()) {
611 if(c.getChannelInfo().getEngine() == null) continue;
612
613 Channel.GetFxSends gfs = new Channel.GetFxSends();
614 gfs.setChannel(c.getChannelId());
615 gfs.addTaskListener(new GetFxSendsListener());
616 getTaskQueue().add(gfs);
617 }
618 }
619 });
620
621
622 final Connect cnt = new Connect();
623 cnt.addTaskListener(new TaskListener() {
624 public void
625 taskPerformed(TaskEvent e) {
626 if(cnt.doneWithErrors()) return;
627
628 getTaskQueue().add(gsi);
629 getTaskQueue().add(gaod);
630 getTaskQueue().add(gmid);
631 getTaskQueue().add(ge);
632 getTaskQueue().add(gv);
633 getTaskQueue().add(mgim);
634 getTaskQueue().add(new Midi.UpdateDevices());
635 getTaskQueue().add(new Audio.UpdateDevices());
636 getTaskQueue().add(uc);
637 }
638 });
639 getTaskQueue().add(cnt);
640 }
641
642 private static class GetFxSendsListener implements TaskListener {
643 public void
644 taskPerformed(TaskEvent e) {
645 Channel.GetFxSends gfs = (Channel.GetFxSends)e.getSource();
646 if(gfs.doneWithErrors()) return;
647 SamplerChannelModel m = getSamplerModel().getChannelById(gfs.getChannel());
648 m.removeAllFxSends();
649
650 for(FxSend fxs : gfs.getResult()) m.addFxSend(fxs);
651 }
652 }
653
654 public static String
655 exportInstrMapsToLscpScript() {
656 StringBuffer sb = new StringBuffer("# Exported by: ");
657 sb.append("JSampler - a java front-end for LinuxSampler\r\n# Version: ");
658 sb.append(JSampler.VERSION).append("\r\n");
659 sb.append("# Date: ").append(new java.util.Date().toString()).append("\r\n\r\n");
660
661 Client lscpClient = new Client(true);
662 ByteArrayOutputStream out = new ByteArrayOutputStream();
663 lscpClient.setPrintOnlyModeOutputStream(out);
664
665 exportInstrMapsToLscpScript(lscpClient);
666 sb.append(out.toString());
667 out.reset();
668
669 return sb.toString();
670 }
671
672 private static void
673 exportInstrMapsToLscpScript(Client lscpClient) {
674 try {
675 lscpClient.removeAllMidiInstrumentMaps();
676 MidiInstrumentMap[] maps = CC.getSamplerModel().getMidiInstrumentMaps();
677 for(int i = 0; i < maps.length; i++) {
678 lscpClient.addMidiInstrumentMap(maps[i].getName());
679 exportInstrumentsToLscpScript(i, maps[i], lscpClient);
680 }
681 } catch(Exception e) {
682 CC.getLogger().log(Level.FINE, HF.getErrorMessage(e), e);
683 HF.showErrorMessage(e);
684 }
685 }
686
687 private static void
688 exportInstrumentsToLscpScript(int mapId, MidiInstrumentMap map, Client lscpClient)
689 throws Exception {
690
691 for(MidiInstrument i : map.getAllMidiInstruments()) {
692 lscpClient.mapMidiInstrument(mapId, i.getInfo().getEntry(), i.getInfo());
693 }
694 }
695
696 public static String
697 exportSessionToLscpScript() {
698 StringBuffer sb = new StringBuffer("# Exported by: ");
699 sb.append("JSampler - a java front-end for LinuxSampler\r\n# Version: ");
700 sb.append(JSampler.VERSION).append("\r\n");
701 sb.append("# Date: ").append(new java.util.Date().toString()).append("\r\n\r\n");
702
703 Client lscpClient = new Client(true);
704 ByteArrayOutputStream out = new ByteArrayOutputStream();
705 lscpClient.setPrintOnlyModeOutputStream(out);
706
707 try {
708 lscpClient.resetSampler();
709 sb.append(out.toString());
710 out.reset();
711 sb.append("\r\n");
712 lscpClient.setVolume(CC.getSamplerModel().getVolume());
713 sb.append(out.toString());
714 out.reset();
715 sb.append("\r\n");
716 } catch(Exception e) { CC.getLogger().log(Level.FINE, HF.getErrorMessage(e), e); }
717
718 MidiDeviceModel[] mDevs = getSamplerModel().getMidiDevices();
719 for(int i = 0; i < mDevs.length; i++) {
720 exportMidiDeviceToLscpScript(mDevs[i].getDeviceInfo(), i, lscpClient);
721 sb.append(out.toString());
722 out.reset();
723 sb.append("\r\n");
724 }
725
726 AudioDeviceModel[] aDevs = getSamplerModel().getAudioDevices();
727 for(int i = 0; i < aDevs.length; i++) {
728 exportAudioDeviceToLscpScript(aDevs[i].getDeviceInfo(), i, lscpClient);
729 sb.append(out.toString());
730 out.reset();
731 sb.append("\r\n");
732 }
733
734 SamplerChannelModel[] channels = getSamplerModel().getChannels();
735
736 for(int i = 0; i < channels.length; i++) {
737 SamplerChannelModel scm = getSamplerModel().getChannelById(i);
738 exportChannelToLscpScript(scm.getChannelInfo(), i, lscpClient);
739 sb.append(out.toString());
740 out.reset();
741
742 sb.append("\r\n");
743
744 exportFxSendsToLscpScript(scm, i, lscpClient);
745 sb.append(out.toString());
746 out.reset();
747
748 sb.append("\r\n");
749 }
750
751 exportInstrMapsToLscpScript(lscpClient);
752 sb.append(out.toString());
753 out.reset();
754
755 return sb.toString();
756 }
757
758 private static void
759 exportMidiDeviceToLscpScript(MidiInputDevice mid, int devId, Client lscpCLient) {
760 try {
761 String s = mid.getDriverName();
762 lscpCLient.createMidiInputDevice(s, mid.getAdditionalParameters());
763
764 MidiPort[] mPorts = mid.getMidiPorts();
765 int l = mPorts.length;
766 if(l != 1) lscpCLient.setMidiInputPortCount(devId, l);
767
768 for(int i = 0; i < l; i++) {
769 Parameter[] prms = mPorts[i].getAllParameters();
770 for(Parameter p : prms) {
771 if(!p.isFixed() && p.getStringValue().length() > 0)
772 lscpCLient.setMidiInputPortParameter(devId, i, p);
773 }
774 }
775 } catch(Exception e) {
776 CC.getLogger().log(Level.FINE, HF.getErrorMessage(e), e);
777 }
778 }
779
780 private static void
781 exportAudioDeviceToLscpScript(AudioOutputDevice aod, int devId, Client lscpCLient) {
782 try {
783 String s = aod.getDriverName();
784 lscpCLient.createAudioOutputDevice(s, aod.getAllParameters());
785
786 AudioOutputChannel[] chns = aod.getAudioChannels();
787
788 for(int i = 0; i < chns.length; i++) {
789 Parameter[] prms = chns[i].getAllParameters();
790 for(Parameter p : prms) {
791 if(p.isFixed() || p.getStringValue().length() == 0);
792 else lscpCLient.setAudioOutputChannelParameter(devId, i, p);
793 }
794 }
795 } catch(Exception e) {
796 CC.getLogger().log(Level.FINE, HF.getErrorMessage(e), e);
797 }
798 }
799
800 private static void
801 exportChannelToLscpScript(SamplerChannel chn, int chnId, Client lscpCLient) {
802 try {
803 lscpCLient.addSamplerChannel();
804
805 int i = chn.getMidiInputDevice();
806 if(i != -1) lscpCLient.setChannelMidiInputDevice(chnId, i);
807 lscpCLient.setChannelMidiInputPort(chnId, chn.getMidiInputPort());
808 lscpCLient.setChannelMidiInputChannel(chnId, chn.getMidiInputChannel());
809
810 i = chn.getAudioOutputDevice();
811 if(i != -1) {
812 lscpCLient.setChannelAudioOutputDevice(chnId, i);
813 Integer[] routing = chn.getAudioOutputRouting();
814
815 for(int j = 0; j < routing.length; j++) {
816 int k = routing[j];
817 if(k == j) continue;
818
819 lscpCLient.setChannelAudioOutputChannel(chnId, j, k);
820 }
821 }
822
823 if(chn.getEngine() != null) {
824 lscpCLient.loadSamplerEngine(chn.getEngine().getName(), chnId);
825 lscpCLient.setChannelVolume(chnId, chn.getVolume());
826 }
827
828 String s = chn.getInstrumentFile();
829 i = chn.getInstrumentIndex();
830 if(s != null) lscpCLient.loadInstrument(s, i, chnId, true);
831
832 if(chn.isMuted()) lscpCLient.setChannelMute(chnId, true);
833 if(chn.isSoloChannel()) lscpCLient.setChannelSolo(chnId, true);
834 } catch(Exception e) {
835 CC.getLogger().log(Level.FINE, HF.getErrorMessage(e), e);
836 }
837 }
838
839 private static void
840 exportFxSendsToLscpScript(SamplerChannelModel scm, int chnId, Client lscpClient) {
841 try {
842 FxSend[] fxSends = scm.getFxSends();
843
844 for(int i = 0; i < fxSends.length; i++) {
845 FxSend f = fxSends[i];
846 lscpClient.createFxSend(chnId, f.getMidiController(), f.getName());
847
848 Integer[] r = f.getAudioOutputRouting();
849 for(int j = 0; j < r.length; j++) {
850 lscpClient.setFxSendAudioOutputChannel(chnId, i, j, r[j]);
851 }
852 }
853 } catch(Exception e) {
854 CC.getLogger().log(Level.FINE, HF.getErrorMessage(e), e);
855 }
856 }
857
858
859 private final static EventHandler eventHandler = new EventHandler();
860
861 private static EventHandler
862 getHandler() { return eventHandler; }
863
864 private static class EventHandler implements ChannelCountListener, ChannelInfoListener,
865 FxSendCountListener, FxSendInfoListener, StreamCountListener, VoiceCountListener,
866 TotalVoiceCountListener, TaskQueueListener, OrchestraListener,
867 ListListener<OrchestraModel>, MidiInstrumentCountListener,
868 MidiInstrumentInfoListener, GlobalInfoListener {
869
870 /** Invoked when the number of channels has changed. */
871 public void
872 channelCountChanged( ChannelCountEvent e) {
873 getTaskQueue().add(new UpdateChannels());
874 }
875
876 /** Invoked when changes to the sampler channel has occured. */
877 public void
878 channelInfoChanged(ChannelInfoEvent e) {
879 /*
880 * Because of the rapid notification flow when instrument is loaded
881 * we need to do some optimization to decrease the traffic.
882 */
883 boolean b = true;
884 Task[] tS = getTaskQueue().getPendingTasks();
885
886 for(int i = tS.length - 1; i >= 0; i--) {
887 Task t = tS[i];
888
889 if(t instanceof Channel.UpdateInfo) {
890 Channel.UpdateInfo cui = (Channel.UpdateInfo)t;
891 if(cui.getChannelId() == e.getSamplerChannel()) return;
892 } else {
893 b = false;
894 break;
895 }
896 }
897
898 if(b) {
899 Task t = getTaskQueue().getRunningTask();
900 if(t instanceof Channel.UpdateInfo) {
901 Channel.UpdateInfo cui = (Channel.UpdateInfo)t;
902 if(cui.getChannelId() == e.getSamplerChannel()) return;
903 }
904 }
905
906
907 getTaskQueue().add(new Channel.UpdateInfo(e.getSamplerChannel()));
908 }
909
910 /**
911 * Invoked when the number of effect sends
912 * on a particular sampler channel has changed.
913 */
914 public void
915 fxSendCountChanged(FxSendCountEvent e) {
916 getTaskQueue().add(new Channel.UpdateFxSends(e.getChannel()));
917 }
918
919 /**
920 * Invoked when the settings of an effect sends are changed.
921 */
922 public void
923 fxSendInfoChanged(FxSendInfoEvent e) {
924 Task t = new Channel.UpdateFxSendInfo(e.getChannel(), e.getFxSend());
925 getTaskQueue().add(t);
926 }
927
928 /**
929 * Invoked when the number of active disk
930 * streams in a specific sampler channel has changed.
931 */
932 public void
933 streamCountChanged(StreamCountEvent e) {
934 SamplerChannelModel scm =
935 getSamplerModel().getChannelById(e.getSamplerChannel());
936
937 if(scm == null) {
938 CC.getLogger().log (
939 Level.WARNING,
940 "CC.unknownChannel!",
941 e.getSamplerChannel()
942 );
943
944 return;
945 }
946
947 scm.setStreamCount(e.getStreamCount());
948 }
949
950 /**
951 * Invoked when the number of active voices
952 * in a specific sampler channel has changed.
953 */
954 public void
955 voiceCountChanged(VoiceCountEvent e) {
956 SamplerChannelModel scm =
957 getSamplerModel().getChannelById(e.getSamplerChannel());
958
959 if(scm == null) {
960 CC.getLogger().log (
961 Level.WARNING,
962 "CC.unknownChannel!",
963 e.getSamplerChannel()
964 );
965
966 return;
967 }
968
969 scm.setVoiceCount(e.getVoiceCount());
970 }
971
972 /** Invoked when the total number of active voices has changed. */
973 public void
974 totalVoiceCountChanged(TotalVoiceCountEvent e) {
975 getTaskQueue().add(new UpdateTotalVoiceCount());
976 }
977
978 /** Invoked when the number of MIDI instruments in a MIDI instrument map is changed. */
979 public void
980 instrumentCountChanged(MidiInstrumentCountEvent e) {
981 getTaskQueue().add(new Midi.UpdateInstruments(e.getMapId()));
982 }
983
984 /** Invoked when a MIDI instrument in a MIDI instrument map is changed. */
985 public void
986 instrumentInfoChanged(MidiInstrumentInfoEvent e) {
987 Task t = new Midi.UpdateInstrumentInfo (
988 e.getMapId(), e.getMidiBank(), e.getMidiProgram()
989 );
990 getTaskQueue().add(t);
991
992 }
993
994 /** Invoked when the global volume of the sampler is changed. */
995 public void
996 volumeChanged(GlobalInfoEvent e) {
997 getSamplerModel().setVolume(e.getVolume());
998 }
999
1000 /**
1001 * Invoked to indicate that the state of a task queue is changed.
1002 * This method is invoked only from the event-dispatching thread.
1003 */
1004 public void
1005 stateChanged(TaskQueueEvent e) {
1006 switch(e.getEventID()) {
1007 case TASK_FETCHED:
1008 getProgressIndicator().setString (
1009 ((Task)e.getSource()).getDescription()
1010 );
1011 break;
1012 case TASK_DONE:
1013 EnhancedTask t = (EnhancedTask)e.getSource();
1014 if(t.doneWithErrors() && !t.isStopped()) {
1015 if(t.getErrorDetails() == null) {
1016 HF.showErrorMessage(t.getErrorMessage());
1017 } else {
1018 getMainFrame().showDetailedErrorMessage (
1019 getMainFrame(),
1020 t.getErrorMessage(),
1021 t.getErrorDetails()
1022 );
1023 }
1024 }
1025 break;
1026 case NOT_IDLE:
1027 timer.start();
1028 break;
1029 case IDLE:
1030 timer.stop();
1031 getProgressIndicator().stop();
1032 break;
1033 }
1034 }
1035
1036 /** Invoked when the name of orchestra is changed. */
1037 public void
1038 nameChanged(OrchestraEvent e) { saveOrchestras(); }
1039
1040 /** Invoked when the description of orchestra is changed. */
1041 public void
1042 descriptionChanged(OrchestraEvent e) { saveOrchestras(); }
1043
1044 /** Invoked when an instrument is added to the orchestra. */
1045 public void
1046 instrumentAdded(OrchestraEvent e) { saveOrchestras(); }
1047
1048 /** Invoked when an instrument is removed from the orchestra. */
1049 public void
1050 instrumentRemoved(OrchestraEvent e) { saveOrchestras(); }
1051
1052 /** Invoked when the settings of an instrument are changed. */
1053 public void
1054 instrumentChanged(OrchestraEvent e) { saveOrchestras(); }
1055
1056 /** Invoked when an orchestra is added to the orchestra list. */
1057 public void
1058 entryAdded(ListEvent<OrchestraModel> e) {
1059 e.getEntry().addOrchestraListener(getHandler());
1060 saveOrchestras();
1061 }
1062
1063 /** Invoked when an orchestra is removed from the orchestra list. */
1064 public void
1065 entryRemoved(ListEvent<OrchestraModel> e) {
1066 e.getEntry().removeOrchestraListener(getHandler());
1067 saveOrchestras();
1068 }
1069 }
1070
1071 private static final AudioDeviceCountListener audioDeviceCountListener =
1072 new AudioDeviceCountListener();
1073
1074 private static class AudioDeviceCountListener implements ItemCountListener {
1075 /** Invoked when the number of audio output devices has changed. */
1076 public void
1077 itemCountChanged(ItemCountEvent e) {
1078 getTaskQueue().add(new Audio.UpdateDevices());
1079 }
1080 }
1081
1082 private static final AudioDeviceInfoListener audioDeviceInfoListener =
1083 new AudioDeviceInfoListener();
1084
1085 private static class AudioDeviceInfoListener implements ItemInfoListener {
1086 /** Invoked when the audio output device's settings are changed. */
1087 public void
1088 itemInfoChanged(ItemInfoEvent e) {
1089 getTaskQueue().add(new Audio.UpdateDeviceInfo(e.getItemID()));
1090 }
1091 }
1092
1093 private static final MidiDeviceCountListener midiDeviceCountListener =
1094 new MidiDeviceCountListener();
1095
1096 private static class MidiDeviceCountListener implements ItemCountListener {
1097 /** Invoked when the number of MIDI input devices has changed. */
1098 public void
1099 itemCountChanged(ItemCountEvent e) {
1100 getTaskQueue().add(new Midi.UpdateDevices());
1101 }
1102 }
1103
1104 private static final MidiDeviceInfoListener midiDeviceInfoListener =
1105 new MidiDeviceInfoListener();
1106
1107 private static class MidiDeviceInfoListener implements ItemInfoListener {
1108 /** Invoked when the MIDI input device's settings are changed. */
1109 public void
1110 itemInfoChanged(ItemInfoEvent e) {
1111 getTaskQueue().add(new Midi.UpdateDeviceInfo(e.getItemID()));
1112 }
1113 }
1114
1115 private static final MidiInstrMapCountListener midiInstrMapCountListener =
1116 new MidiInstrMapCountListener();
1117
1118 private static class MidiInstrMapCountListener implements ItemCountListener {
1119 /** Invoked when the number of MIDI instrument maps is changed. */
1120 public void
1121 itemCountChanged(ItemCountEvent e) {
1122 getTaskQueue().add(new Midi.UpdateInstrumentMaps());
1123 }
1124 }
1125
1126 private static final MidiInstrMapInfoListener midiInstrMapInfoListener =
1127 new MidiInstrMapInfoListener();
1128
1129 private static class MidiInstrMapInfoListener implements ItemInfoListener {
1130 /** Invoked when the MIDI instrument map's settings are changed. */
1131 public void
1132 itemInfoChanged(ItemInfoEvent e) {
1133 getTaskQueue().add(new Midi.UpdateInstrumentMapInfo(e.getItemID()));
1134 }
1135 }
1136 }

  ViewVC Help
Powered by ViewVC