/[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 1545 - (show annotations) (download)
Tue Dec 4 18:28:29 2007 UTC (16 years, 4 months ago) by iliev
File size: 34262 byte(s)
* Added support for monitoring the total number of active disk streams

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

  ViewVC Help
Powered by ViewVC