/[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 911 - (show annotations) (download)
Mon Aug 7 18:25:58 2006 UTC (17 years, 7 months ago) by iliev
File size: 14235 byte(s)
updating to JSampler 0.3a

1 /*
2 * JSampler - a java front-end for LinuxSampler
3 *
4 * Copyright (C) 2005 Grigor Kirilov Iliev
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.FileOutputStream;
31
32 import java.util.Vector;
33
34 import java.util.logging.Handler;
35 import java.util.logging.Level;
36 import java.util.logging.Logger;
37 import java.util.logging.SimpleFormatter;
38 import java.util.logging.StreamHandler;
39
40 import javax.swing.Timer;
41
42 import net.sf.juife.Task;
43 import net.sf.juife.TaskQueue;
44
45 import net.sf.juife.event.TaskEvent;
46 import net.sf.juife.event.TaskListener;
47 import net.sf.juife.event.TaskQueueEvent;
48 import net.sf.juife.event.TaskQueueListener;
49
50 import org.jsampler.event.OrchestraEvent;
51 import org.jsampler.event.OrchestraListEvent;
52 import org.jsampler.event.OrchestraListListener;
53 import org.jsampler.event.OrchestraListener;
54
55 import org.jsampler.task.*;
56
57 import org.jsampler.view.JSMainFrame;
58 import org.jsampler.view.JSProgress;
59
60 import org.linuxsampler.lscp.Client;
61 import org.linuxsampler.lscp.event.*;
62
63 import org.w3c.dom.Document;
64 import org.w3c.dom.Node;
65
66
67 /**
68 * This class serves as a 'Control Center' of the application.
69 * It also provides some fundamental routines and access to most used objects.
70 * @author Grigor Iliev
71 */
72 public class CC {
73 private static Handler handler;
74 private static FileOutputStream fos;
75
76 private static JSMainFrame mainFrame = null;
77 private static JSProgress progress = null;
78
79 private final static Client lsClient = new Client();
80
81 private final static TaskQueue taskQueue = new TaskQueue();
82 private final static Timer timer = new Timer(2000, null);
83
84
85 /**
86 * Returns the logger to be used for logging events.
87 * @return The logger to be used for logging events.
88 */
89 public static Logger
90 getLogger() {
91 return Logger.getLogger (
92 "org.jsampler",
93 "org.jsampler.langprops.LogsBundle"
94 );
95 }
96
97 /**
98 * Returns the task queue to be used for scheduling tasks
99 * for execution out of the event-dispatching thread.
100 * @return The task queue to be used for scheduling tasks
101 * for execution out of the event-dispatching thread.
102 */
103 public static TaskQueue
104 getTaskQueue() { return taskQueue; }
105
106 /**
107 * Returns the main window of this application.
108 * @return The main window of this application.
109 */
110 public static JSMainFrame
111 getMainFrame() { return mainFrame; }
112
113 /**
114 * Sets the main window of this application.
115 * @param mainFrame The main window of this application.
116 */
117 public static void
118 setMainFrame(JSMainFrame mainFrame) { CC.mainFrame = mainFrame; }
119
120 /**
121 * Gets the progress indicator of this application.
122 * @return The progress indicator of this application.
123 */
124 public static JSProgress
125 getProgressIndicator() { return progress; }
126
127 /**
128 * Sets the progress indicator to be used by this application.
129 * @param progress The progress indicator to be used by this application.
130 */
131 public static void
132 setProgressIndicator(JSProgress progress) { CC.progress = progress; }
133
134 /**
135 * This method does the initial preparation of the application.
136 */
137 protected static void
138 initJSampler() {
139 fos = null;
140
141 try { fos = new FileOutputStream("JSampler.log"); }
142 catch(Exception x) { x.printStackTrace(); }
143
144 if(fos == null) handler = new StreamHandler(System.out, new SimpleFormatter());
145 else handler = new StreamHandler(fos, new SimpleFormatter());
146
147 handler.setLevel(Level.FINE);
148 getLogger().addHandler(handler);
149 getLogger().setLevel(Level.FINE);
150 Logger.getLogger("org.linuxsampler.lscp").addHandler(handler);
151 Logger.getLogger("org.linuxsampler.lscp").setLevel(Level.FINE);
152
153 // Flushing logs on every second
154 new java.util.Timer().schedule(new java.util.TimerTask() {
155 public void
156 run() { if(handler != null) handler.flush(); }
157 }, 1000, 1000);
158
159 CC.getLogger().fine("CC.jsStarted");
160
161 HF.setUIDefaultFont(Prefs.getInterfaceFont());
162
163
164
165 getClient().setServerAddress(Prefs.getLSAddress());
166 getClient().setServerPort(Prefs.getLSPort());
167
168 timer.setRepeats(false);
169
170 timer.addActionListener(new ActionListener() {
171 public void
172 actionPerformed(ActionEvent e) { CC.getProgressIndicator().start(); }
173 });
174
175 taskQueue.addTaskQueueListener(getHandler());
176
177 taskQueue.start();
178
179 getClient().addChannelCountListener(getHandler());
180 getClient().addChannelInfoListener(getHandler());
181 getClient().addStreamCountListener(getHandler());
182 getClient().addVoiceCountListener(getHandler());
183 getClient().addTotalVoiceCountListener(getHandler());
184
185 loadOrchestras();
186
187 for(int i = 0; i < getOrchestras().getOrchestraCount(); i++) {
188 getOrchestras().getOrchestra(i).addOrchestraListener(getHandler());
189 }
190 getOrchestras().addOrchestraListListener(getHandler());
191 }
192
193 private final static OrchestraListModel orchestras = new DefaultOrchestraListModel();
194
195 /**
196 * Returns a list containing all available orchestras.
197 * @return A list containing all available orchestras.
198 */
199 public static OrchestraListModel
200 getOrchestras() { return orchestras; }
201
202 private static void
203 loadOrchestras() {
204 String s = Prefs.getOrchestras();
205 if(s == null) return;
206
207 ByteArrayInputStream bais = new ByteArrayInputStream(s.getBytes());
208 Document doc = DOMUtils.readObject(bais);
209
210 try { getOrchestras().readObject(doc.getDocumentElement()); }
211 catch(Exception x) { HF.showErrorMessage(x, "Loading orchestras: "); }
212 }
213
214 private static void
215 saveOrchestras() {
216 Document doc = DOMUtils.createEmptyDocument();
217
218 Node node = doc.createElement("temp");
219 doc.appendChild(node);
220
221 getOrchestras().writeObject(doc, doc.getDocumentElement());
222
223 doc.replaceChild(node.getFirstChild(), node);
224
225 ByteArrayOutputStream baos = new ByteArrayOutputStream();
226 DOMUtils.writeObject(doc, baos);
227 Prefs.setOrchestras(baos.toString());
228 }
229
230 /**
231 * The exit point of the application which ensures clean exit with default exit status 0.
232 * @see #cleanExit(int i)
233 */
234 public static void
235 cleanExit() { cleanExit(0); }
236
237 /**
238 * The exit point of the application which ensures clean exit.
239 * @param i The exit status.
240 */
241 public static void
242 cleanExit(int i) {
243 CC.getLogger().fine("CC.jsEnded");
244 System.exit(i);
245 }
246
247 /**
248 * Gets the <code>Client</code> object that is used to communicate with the backend.
249 * @return The <code>Client</code> object that is used to communicate with the backend.
250 */
251 public static Client
252 getClient() { return lsClient; }
253
254 private static final Vector<ActionListener> listeners = new Vector<ActionListener>();
255
256 /**
257 * Registers the specified listener to be notified when reconnecting to LinuxSampler.
258 * @param l The <code>ActionListener</code> to register.
259 */
260 public static void
261 addReconnectListener(ActionListener l) { listeners.add(l); }
262
263 /**
264 * Removes the specified listener.
265 * @param l The <code>ActionListener</code> to remove.
266 */
267 public static void
268 removeReconnectListener(ActionListener l) { listeners.remove(l); }
269
270 private static void
271 fireReconnectEvent() {
272 ActionEvent e = new ActionEvent(CC.class, ActionEvent.ACTION_PERFORMED, null);
273 for(ActionListener l : listeners) l.actionPerformed(e);
274 }
275
276 private static final SamplerModel samplerModel = new DefaultSamplerModel();
277
278 /**
279 * Gets the sampler model.
280 * @return The sampler model.
281 */
282 public static SamplerModel
283 getSamplerModel() { return samplerModel; }
284
285 /**
286 * Reconnects to LinuxSampler.
287 */
288 public static void
289 reconnect() {
290 initSamplerModel();
291 fireReconnectEvent();
292 }
293
294 /**
295 * This method updates the information about the backend state.
296 */
297 public static void
298 initSamplerModel() {
299 final DefaultSamplerModel model = (DefaultSamplerModel)getSamplerModel();
300
301 final GetServerInfo gsi = new GetServerInfo();
302 gsi.addTaskListener(new TaskListener() {
303 public void
304 taskPerformed(TaskEvent e) {
305 if(!gsi.doneWithErrors()) model.setServerInfo(gsi.getResult());
306 }
307 });
308
309 final GetAODrivers gaod = new GetAODrivers();
310 gaod.addTaskListener(new TaskListener() {
311 public void
312 taskPerformed(TaskEvent e) {
313 if(!gaod.doneWithErrors())
314 model.setAudioOutputDrivers(gaod.getResult());
315 }
316 });
317
318 final GetEngines ge = new GetEngines();
319 ge.addTaskListener(new TaskListener() {
320 public void
321 taskPerformed(TaskEvent e) {
322 if(!ge.doneWithErrors()) model.setEngines(ge.getResult());
323 }
324 });
325
326 final GetMIDrivers gmid = new GetMIDrivers();
327 gmid.addTaskListener(new TaskListener() {
328 public void
329 taskPerformed(TaskEvent e) {
330 if(!gmid.doneWithErrors())
331 model.setMidiInputDrivers(gmid.getResult());
332 }
333 });
334
335 final Connect cnt = new Connect();
336 cnt.addTaskListener(new TaskListener() {
337 public void
338 taskPerformed(TaskEvent e) {
339 if(cnt.doneWithErrors()) return;
340
341 getTaskQueue().add(gsi);
342 getTaskQueue().add(gaod);
343 getTaskQueue().add(gmid);
344 getTaskQueue().add(ge);
345 getTaskQueue().add(new UpdateMidiDevices());
346 getTaskQueue().add(new UpdateAudioDevices());
347 getTaskQueue().add(new UpdateChannels());
348 }
349 });
350 getTaskQueue().add(cnt);
351 }
352
353 private final static EventHandler eventHandler = new EventHandler();
354
355 private static EventHandler
356 getHandler() { return eventHandler; }
357
358 private static class EventHandler implements ChannelCountListener, ChannelInfoListener,
359 StreamCountListener, VoiceCountListener, TotalVoiceCountListener,
360 TaskQueueListener, OrchestraListener, OrchestraListListener {
361
362 /** Invoked when the number of channels has changed. */
363 public void
364 channelCountChanged( ChannelCountEvent e) {
365 getTaskQueue().add(new UpdateChannels());
366 }
367
368 /** Invoked when changes to the sampler channel has occured. */
369 public void
370 channelInfoChanged(ChannelInfoEvent e) {
371 /*
372 * Because of the rapid notification flow when instrument is loaded
373 * we need to do some optimization to decrease the traffic.
374 */
375 boolean b = true;
376 Task[] tS = getTaskQueue().getPendingTasks();
377
378 for(int i = tS.length - 1; i >= 0; i--) {
379 Task t = tS[i];
380
381 if(t instanceof UpdateChannelInfo) {
382 UpdateChannelInfo uci = (UpdateChannelInfo)t;
383 if(uci.getChannelID() == e.getSamplerChannel()) return;
384 } else {
385 b = false;
386 break;
387 }
388 }
389
390 if(b) {
391 Task t = getTaskQueue().getRunningTask();
392 if(t instanceof UpdateChannelInfo) {
393 UpdateChannelInfo uci = (UpdateChannelInfo)t;
394 if(uci.getChannelID() == e.getSamplerChannel()) return;
395 }
396 }
397
398
399 getTaskQueue().add(new UpdateChannelInfo(e.getSamplerChannel()));
400 }
401
402 /**
403 * Invoked when the number of active disk
404 * streams in a specific sampler channel has changed.
405 */
406 public void
407 streamCountChanged(StreamCountEvent e) {
408 SamplerChannelModel scm =
409 getSamplerModel().getChannelModel(e.getSamplerChannel());
410
411 if(scm == null) {
412 CC.getLogger().log (
413 Level.WARNING,
414 "CC.unknownChannel!",
415 e.getSamplerChannel()
416 );
417
418 return;
419 }
420
421 scm.setStreamCount(e.getStreamCount());
422 }
423
424 /**
425 * Invoked when the number of active voices
426 * in a specific sampler channel has changed.
427 */
428 public void
429 voiceCountChanged(VoiceCountEvent e) {
430 SamplerChannelModel scm =
431 getSamplerModel().getChannelModel(e.getSamplerChannel());
432
433 if(scm == null) {
434 CC.getLogger().log (
435 Level.WARNING,
436 "CC.unknownChannel!",
437 e.getSamplerChannel()
438 );
439
440 return;
441 }
442
443 scm.setVoiceCount(e.getVoiceCount());
444 }
445
446 /** Invoked when the total number of active voices has changed. */
447 public void
448 totalVoiceCountChanged(TotalVoiceCountEvent e) {
449 getTaskQueue().add(new UpdateTotalVoiceCount());
450 }
451
452 /**
453 * Invoked to indicate that the state of a task queue is changed.
454 * This method is invoked only from the event-dispatching thread.
455 */
456 public void
457 stateChanged(TaskQueueEvent e) {
458 switch(e.getEventID()) {
459 case TASK_FETCHED:
460 getProgressIndicator().setString (
461 ((Task)e.getSource()).getDescription()
462 );
463 break;
464 case TASK_DONE:
465 EnhancedTask t = (EnhancedTask)e.getSource();
466 if(t.doneWithErrors() && !t.isStopped())
467 HF.showErrorMessage(t.getErrorMessage());
468 break;
469 case NOT_IDLE:
470 timer.start();
471 break;
472 case IDLE:
473 timer.stop();
474 getProgressIndicator().stop();
475 break;
476 }
477 }
478
479 /** Invoked when the name of orchestra is changed. */
480 public void
481 nameChanged(OrchestraEvent e) { saveOrchestras(); }
482
483 /** Invoked when the description of orchestra is changed. */
484 public void
485 descriptionChanged(OrchestraEvent e) { saveOrchestras(); }
486
487 /** Invoked when an instrument is added to the orchestra. */
488 public void
489 instrumentAdded(OrchestraEvent e) { saveOrchestras(); }
490
491 /** Invoked when an instrument is removed from the orchestra. */
492 public void
493 instrumentRemoved(OrchestraEvent e) { saveOrchestras(); }
494
495 /** Invoked when the settings of an instrument are changed. */
496 public void
497 instrumentChanged(OrchestraEvent e) { saveOrchestras(); }
498
499 /** Invoked when an orchestra is added to the orchestra list. */
500 public void
501 orchestraAdded(OrchestraListEvent e) {
502 e.getOrchestraModel().addOrchestraListener(getHandler());
503 saveOrchestras();
504 }
505
506 /** Invoked when an orchestra is removed from the orchestra list. */
507 public void
508 orchestraRemoved(OrchestraListEvent e) {
509 e.getOrchestraModel().removeOrchestraListener(getHandler());
510 saveOrchestras();
511 }
512 }
513 }

  ViewVC Help
Powered by ViewVC