/[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 1467 - (show annotations) (download)
Sat Nov 3 13:14:31 2007 UTC (16 years, 5 months ago) by iliev
File size: 33899 byte(s)
* bugfix: The parameter changes were
  discarded when creating new audio/MIDI device
* bugfix: The orchestras changes were not saved for the next session
  when orchestras.xml does not exist in the JSampler's home directory
* bugfix: In some cases the sampler configuration was not exported
  properly to LSCP script
* Some minor bugfixes and enhancements

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

  ViewVC Help
Powered by ViewVC