/[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 1327 - (show annotations) (download)
Fri Sep 7 12:09:59 2007 UTC (16 years, 7 months ago) by iliev
File size: 34201 byte(s)
* Implemented more proper retrieval of the MIDI/audio driver settings
* Implemented new table cell editor for editing string list
  parameters with possibilities
* Some javadoc documentation fixes

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

  ViewVC Help
Powered by ViewVC