/[svn]/jlscp/trunk/src/org/linuxsampler/lscp/Client.java
ViewVC logotype

Contents of /jlscp/trunk/src/org/linuxsampler/lscp/Client.java

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1340 - (show annotations) (download)
Mon Sep 10 21:26:10 2007 UTC (16 years, 7 months ago) by iliev
File size: 170636 byte(s)
* Client: added new method - editInstrument

1 /*
2 * jlscp - a java LinuxSampler control protocol API
3 *
4 * Copyright (C) 2005-2007 Grigor Iliev <grigor@grigoriliev.com>
5 *
6 * This file is part of jlscp.
7 *
8 * jlscp 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 * jlscp 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 jlscp; 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.linuxsampler.lscp;
24
25 import java.io.IOException;
26 import java.io.OutputStream;
27
28 import java.net.InetSocketAddress;
29 import java.net.Socket;
30 import java.net.SocketTimeoutException;
31 import java.net.UnknownHostException;
32
33 import java.util.Vector;
34 import java.util.logging.Level;
35 import java.util.logging.Logger;
36
37 import static org.linuxsampler.lscp.Parser.*;
38 import org.linuxsampler.lscp.event.*;
39
40
41 /**
42 * This class is the abstraction representing a client endpoint for communication with LinuxSampler
43 * instance. Since it implements all commands specified in the LSCP protocol v1.1, for more
44 * information look at the
45 * <a href=http://www.linuxsampler.org/api/lscp-1.1.html>LSCP</a> specification.
46 *
47 * <p> The following code establishes connection to LinuxSampler instance and gets the
48 * LinuxSampler version:
49 * <pre>
50 * try {
51 * Client client = new Client();
52 * client.connect();
53 *
54 * String version = client.getServerInfo().getVersion();
55 * System.out.println(version);
56 *
57 * client.disconnect();
58 * } catch(Exception x) { x.printStackTrace(); }
59 * </pre>
60 * </p>
61 *
62 * <p>For more examples look at the <code>examples</code> directory
63 * located in the <b>jlscp</b> distribution.</p>
64 *
65 * All methods are thread safe.
66 * @author Grigor Iliev
67 */
68 public class Client {
69 private String address;
70 private int port;
71 private Socket sock = null;
72 private int soTimeout = 20000;
73
74 private LscpInputStream in = null;
75 private LscpOutputStream out = null;
76
77 private EventThread eventThread;
78
79 private boolean printOnlyMode = false;
80
81 class EventThread extends Thread {
82 private Vector<String> queue = new Vector<String>();
83 private boolean terminate = false;
84
85 EventThread() { super("LSCP-Event-Thread"); }
86
87 public void
88 run() {
89 while(!mustTerminate()) {
90 try {
91 processQueue();
92 processNotifications();
93 } catch(Exception x) {
94 getLogger().log(Level.FINE, x.getMessage(), x);
95 }
96 try { synchronized(this) { wait(100); } }
97 catch(Exception x) {
98 getLogger().log(Level.FINE, x.getMessage(), x);
99 }
100 }
101 }
102
103 private synchronized boolean
104 mustTerminate() { return terminate; }
105
106 public synchronized void
107 terminate() {
108 terminate = true;
109 this.notifyAll();
110 }
111
112 public synchronized void
113 scheduleNotification(String s) { queue.add(s); }
114
115 private void
116 processQueue() {
117 String[] notifications = popAllNotifications();
118 for(String n : notifications) fireEvent(n);
119 }
120
121 private synchronized String[]
122 popAllNotifications() {
123 String[] notifications = queue.toArray(new String[queue.size()]);
124 queue.removeAllElements();
125 return notifications;
126 }
127 }
128
129 /**
130 * Creates a new instance of Client with default server address and port.
131 * The default server address and port are 127.0.0.1:8888.
132 */
133 public
134 Client() { this("127.0.0.1"); }
135
136 /**
137 * Creates a new instance of Client with the specified address and default port.
138 * The default port is 8888.
139 * @param address The address of linux sampler server.
140 */
141 public
142 Client(String address) { this(address, 8888); }
143
144 /**
145 * Creates a new instance of Client with the specified address and port.
146 * @param address The address of the Linux Sampler.
147 * @param port The Linux Sampler port number.
148 */
149 public
150 Client(String address, int port) {
151 setServerAddress(address);
152 setServerPort(port);
153
154 eventThread = new EventThread();
155 }
156
157 /**
158 * Creates a new instance of Client.
159 * @param printOnlyMode Determines whether the client will be in print-only mode.
160 */
161 public
162 Client(boolean printOnlyMode) {
163 if(printOnlyMode) setPrintOnlyMode(true);
164 }
165
166 /**
167 * Determines whether the client is in print-only mode.
168 * Print-only mode means that the client will just print all
169 * LSCP commands to the specified output stream or to the standard output stream
170 * (<code>java.lang.System.out</code>) if no output stream is specified,
171 * without taking any further actions. Thus, in print-only mode all returned
172 * values by <code>Client</code>'s methods are meaningless and should be discarded.
173 * @return <code>true</code> if the client is in
174 * print-only mode, <code>false</code> otherwise.
175 * @see #setPrintOnlyModeOutputStream
176 */
177 public synchronized boolean
178 getPrintOnlyMode() { return printOnlyMode; }
179
180 /**
181 * Sets the print-only mode. Note that in print-only mode all returned
182 * values by <code>Client</code>'s methods are meaningless and should be discarded.
183 * The default output stream in print-only mode is <code>java.lang.System.out</code>.
184 * @param b If <code>true</code> all LSCP commands will be sent
185 * to the specified output stream or to the standard output stream
186 * (<code>java.lang.System.out</code>) if no output stream is specified,
187 * and no further actions will be taken.
188 * @throws IllegalStateException If the client is connected.
189 * @see #setPrintOnlyModeOutputStream
190 */
191 public synchronized void
192 setPrintOnlyMode(boolean b) {
193 if(printOnlyMode == b) return;
194 if(isConnected()) throw new IllegalStateException();
195
196 printOnlyMode = b;
197 if(b) out = new LscpOutputStream(System.out);
198 }
199
200 /**
201 * Sets the output stream to be used in print-only mode.
202 * @param out The output stream to be used in print-only mode.
203 * @throws IllegalStateException If the client is not in print-only mode.
204 * @throws IllegalArgumentException if <code>out</code> is <code>null</code>.
205 * @see #setPrintOnlyMode
206 */
207 public synchronized void
208 setPrintOnlyModeOutputStream(OutputStream out) {
209 if(!getPrintOnlyMode()) throw new IllegalStateException("Not in print-only mode");
210 if(out == null) throw new IllegalArgumentException("out must be non-null");
211 this.out = new LscpOutputStream(out);
212 }
213
214 /**
215 * Specifies the jlscp version.
216 * @return The jlscp version.
217 */
218 public static String
219 getClientVersion() {
220 return Package.getPackage("org.linuxsampler.lscp").getImplementationVersion();
221 }
222
223 /**
224 * Gets the Linux Sampler address.
225 * @return The Linux Sampler address.
226 */
227 public synchronized String
228 getServerAddress() { return address; }
229
230 /**
231 * Sets the Linux Sampler address.
232 * @param address The Linux Sampler address.
233 * If <code>address</code> is <code>null</code> sets to default address - 127.0.0.1.
234 */
235 public synchronized void
236 setServerAddress(String address) {
237 this.address = (address == null ? "127.0.0.1" : address);
238 }
239
240 /**
241 * Gets the Linux Sampler port number.
242 * @return The Linux Sampler port number.
243 */
244 public synchronized int
245 getServerPort() { return port; }
246
247 /**
248 * Sets the Linux Sampler port number.
249 * @param port The Linux Sampler port number.
250 */
251 public synchronized void
252 setServerPort(int port) { this.port = port; }
253
254 /**
255 * Connects to the LinuxSampler. If there is already established connection then
256 * the currently available connection is closed berfore connecting.
257 * @throws LscpException If timeout occurs or any other I/O exception.
258 */
259 public synchronized void
260 connect() throws LscpException {
261 if(sock != null) disconnect();
262 if(getPrintOnlyMode()) return;
263
264 // Initializing LSCP event thread
265 if(eventThread.isAlive()) {
266 getLogger().warning("LSCP event thread already running!");
267 eventThread.terminate();
268 }
269
270 if(eventThread.getState() != Thread.State.NEW) eventThread = new EventThread();
271 ///////
272
273 InetSocketAddress sockAddr = null;
274
275 try { sockAddr = new InetSocketAddress(address, port); }
276 catch(IllegalArgumentException x) {
277 String s = String.valueOf(port);
278 throw new LscpException(LscpI18n.getLogMsg("Client.invalidPort!", s), x);
279 }
280
281 if(sockAddr.isUnresolved()) throw new LscpException (
282 LscpI18n.getLogMsg("Client.unknownHost!", address)
283 );
284
285 try {
286 sock = new Socket();
287 sock.bind(null);
288 sock.connect(sockAddr, soTimeout);
289 sock.setSoTimeout(soTimeout);
290 sock.setTcpNoDelay(true);
291
292 in = new LscpInputStream(sock.getInputStream());
293 out = new LscpOutputStream(sock.getOutputStream());
294 } catch(SocketTimeoutException x) {
295 throw new LscpException(LscpI18n.getLogMsg("Client.conTimeout!"), x);
296 } catch(Exception x) {
297 throw new LscpException (
298 LscpI18n.getLogMsg("Client.connectionFailed!"), x
299 );
300 }
301
302 String s = Package.getPackage("org.linuxsampler.lscp").getSpecificationVersion();
303 String s2, sv, sv2;
304
305 try {
306 s2 = s.substring(0, s.indexOf('.'));
307 sv = getServerInfo().getProtocolVersion();
308 sv2 = sv.substring(0, sv.indexOf('.'));
309 } catch(Exception x) {
310 disconnect();
311
312 throw new LscpException (
313 LscpI18n.getLogMsg("Client.connectionFailed!"), x
314 );
315 }
316
317 if(!sv2.equals(s2)) {
318 disconnect();
319
320 throw new LscpException (
321 LscpI18n.getLogMsg("Client.incompatibleLscpVersion!", sv)
322 );
323 }
324
325 s2 = s.substring(s.indexOf('.'));
326 sv2 = sv.substring(sv.indexOf('.'));
327
328 if(sv2.compareToIgnoreCase(s2) < 0) getLogger().info (
329 LscpI18n.getLogMsg("Client.incompatibleLscpMinVersion!", sv)
330 );
331
332 if(hasSubscriptions()) eventThread.start();
333
334 if(!llM.isEmpty()) subscribe("MISCELLANEOUS");
335 if(!llAODC.isEmpty()) subscribe("AUDIO_OUTPUT_DEVICE_COUNT");
336 if(!llAODI.isEmpty()) subscribe("AUDIO_OUTPUT_DEVICE_INFO");
337 if(!llMIDC.isEmpty()) subscribe("MIDI_INPUT_DEVICE_COUNT");
338 if(!llMIDI.isEmpty()) subscribe("MIDI_INPUT_DEVICE_INFO");
339 if(!llBF.isEmpty()) subscribe("BUFFER_FILL");
340 if(!llCC.isEmpty()) subscribe("CHANNEL_COUNT");
341 if(!llCI.isEmpty()) subscribe("CHANNEL_INFO");
342 if(!llFSC.isEmpty()) subscribe("FX_SEND_COUNT");
343 if(!llFSI.isEmpty()) subscribe("FX_SEND_INFO");
344 if(!llSC.isEmpty()) subscribe("STREAM_COUNT");
345 if(!llVC.isEmpty()) subscribe("VOICE_COUNT");
346 if(!llTVC.isEmpty()) subscribe("TOTAL_VOICE_COUNT");
347 if(!llMIMC.isEmpty()) subscribe("MIDI_INSTRUMENT_MAP_COUNT");
348 if(!llMIMI.isEmpty()) subscribe("MIDI_INSTRUMENT_MAP_INFO");
349 if(!llMIC.isEmpty()) subscribe("MIDI_INSTRUMENT_COUNT");
350 if(!llMII.isEmpty()) subscribe("MIDI_INSTRUMENT_INFO");
351 if(!llID.isEmpty()) {
352 subscribe("DB_INSTRUMENT_DIRECTORY_COUNT");
353 subscribe("DB_INSTRUMENT_DIRECTORY_INFO");
354 subscribe("DB_INSTRUMENT_COUNT");
355 subscribe("DB_INSTRUMENT_INFO");
356 }
357 if(!llGI.isEmpty()) subscribe("GLOBAL_INFO");
358 }
359
360 /**
361 * Closes the connection to LinuxSampler.
362 */
363 public synchronized void
364 disconnect() {
365 if(getPrintOnlyMode()) return;
366 try { if(sock != null) sock.close(); }
367 catch(Exception x) { getLogger().log(Level.FINE, x.getMessage(), x); }
368 sock = null;
369
370 if(eventThread.getState() != Thread.State.NEW) {
371 eventThread.terminate();
372 eventThread = new EventThread();
373 }
374 }
375
376 /**
377 * Determines whether the client is connected.
378 * @return <code>true</code> if there is established connection,
379 * <code>false</code> otherwise.
380 */
381 public synchronized boolean
382 isConnected() {
383 if(sock == null) return false;
384 else return sock.isConnected();
385 }
386
387 /**
388 * Verifies that there is established connection.
389 * @throws IOException If the connection is not established.
390 */
391 private void
392 verifyConnection() throws IOException {
393 if(getPrintOnlyMode()) return;
394
395 if(!isConnected())
396 throw new IOException(LscpI18n.getLogMsg("Client.notConnected!"));
397 }
398
399 private String
400 getLine() throws IOException, LscpException {
401 String s;
402 for(;;) {
403 s = in.readLine();
404 if(s.startsWith("NOTIFY:")) {
405 eventThread.scheduleNotification(s.substring("NOTIFY:".length()));
406 }
407 else break;
408 }
409 return s;
410 }
411
412 /** Processes the notifications sent by LinuxSampler */
413 private synchronized void
414 processNotifications() throws IOException, LscpException {
415 while(in.available() > 0) {
416 String s = in.readLine();
417 if(s.startsWith("NOTIFY:")) fireEvent(s.substring("NOTIFY:".length()));
418 else getLogger().severe("Unknown notification format: " + s);
419 }
420 }
421
422 /**
423 * Gets empty result set.
424 * @return <code>ResultSet</code> instance.
425 */
426 private ResultSet
427 getEmptyResultSet() throws IOException, LscpException, LSException {
428 return parseEmptyResultSet(getLine());
429 }
430
431 private ResultSet
432 getSingleLineResultSet() throws IOException, LscpException, LSException {
433 ResultSet rs = new ResultSet();
434 String ln = getLine();
435
436 if(ln.startsWith("WRN")) {
437 parseWarning(ln, rs);
438 getLogger().warning(rs.getMessage());
439 return rs;
440 } else if(ln.startsWith("ERR")) {
441 parseError(ln, rs);
442 throw new LSException(rs.getCode(), rs.getMessage());
443 } else {
444 rs.setResult(ln);
445 return rs;
446 }
447 }
448
449 private ResultSet
450 getMultiLineResultSet() throws IOException, LscpException, LSException {
451 ResultSet rs = new ResultSet();
452 String ln = getLine();
453
454 if(ln.startsWith("WRN")) {
455 parseWarning(ln, rs);
456 getLogger().warning(rs.getMessage());
457 return rs;
458 } else if(ln.startsWith("ERR")) {
459 parseError(ln, rs);
460 throw new LSException(rs.getCode(), rs.getMessage());
461 }
462
463 while(!ln.equals(".")) {
464 rs.addLine(ln);
465 ln = getLine();
466 }
467
468 return rs;
469 }
470
471 /** Audio output device count listeners */
472 private final Vector<ItemCountListener> llAODC = new Vector<ItemCountListener>();
473 /** Audio output device info listeners */
474 private final Vector<ItemInfoListener> llAODI = new Vector<ItemInfoListener>();
475 private final Vector<BufferFillListener> llBF = new Vector<BufferFillListener>();
476 private final Vector<ChannelCountListener> llCC = new Vector<ChannelCountListener>();
477 private final Vector<ChannelInfoListener> llCI = new Vector<ChannelInfoListener>();
478 private final Vector<FxSendCountListener> llFSC = new Vector<FxSendCountListener>();
479 private final Vector<FxSendInfoListener> llFSI = new Vector<FxSendInfoListener>();
480 private final Vector<MiscellaneousListener> llM = new Vector<MiscellaneousListener>();
481 /** MIDI input device count listeners */
482 private final Vector<ItemCountListener> llMIDC = new Vector<ItemCountListener>();
483 /** MIDI input device info listeners */
484 private final Vector<ItemInfoListener> llMIDI = new Vector<ItemInfoListener>();
485 private final Vector<StreamCountListener> llSC = new Vector<StreamCountListener>();
486 private final Vector<VoiceCountListener> llVC = new Vector<VoiceCountListener>();
487 private final Vector<TotalVoiceCountListener> llTVC = new Vector<TotalVoiceCountListener>();
488
489 /** MIDI instrument map count listeners */
490 private final Vector<ItemCountListener> llMIMC = new Vector<ItemCountListener>();
491 /** MIDI instrument map info listeners */
492 private final Vector<ItemInfoListener> llMIMI = new Vector<ItemInfoListener>();
493 /** MIDI instrument count listeners */
494 private final Vector<MidiInstrumentCountListener> llMIC =
495 new Vector<MidiInstrumentCountListener>();
496 /** MIDI instrument info listeners */
497 private final Vector<MidiInstrumentInfoListener> llMII =
498 new Vector<MidiInstrumentInfoListener>();
499 private final Vector<InstrumentsDbListener> llID = new Vector<InstrumentsDbListener>();
500 private final Vector<GlobalInfoListener> llGI = new Vector<GlobalInfoListener>();
501
502
503 /**
504 * Determines whether there is at least one subscription for notification events.
505 * Do not forget to check for additional listeners if the LSCP specification
506 * is extended in the future.
507 * @return <code>true</code> if there is at least one subscription for notification events,
508 * <code>false</code> otherwise.
509 */
510 private boolean
511 hasSubscriptions() {
512 return !llAODC.isEmpty() ||
513 !llAODI.isEmpty() ||
514 !llBF.isEmpty() ||
515 !llCC.isEmpty() ||
516 !llCI.isEmpty() ||
517 !llFSC.isEmpty() ||
518 !llFSI.isEmpty() ||
519 !llM.isEmpty() ||
520 !llMIDC.isEmpty() ||
521 !llMIDI.isEmpty() ||
522 !llSC.isEmpty() ||
523 !llVC.isEmpty() ||
524 !llTVC.isEmpty() ||
525 !llMIMC.isEmpty() ||
526 !llMIMI.isEmpty() ||
527 !llMIC.isEmpty() ||
528 !llMII.isEmpty() ||
529 !llID.isEmpty() ||
530 !llGI.isEmpty();
531 }
532
533 private synchronized void
534 fireEvent(String s) {
535 if(s.startsWith("DB_INSTRUMENT_DIRECTORY_COUNT:")) {
536 s = s.substring("DB_INSTRUMENT_DIRECTORY_COUNT:".length());
537 InstrumentsDbEvent e = new InstrumentsDbEvent(this, s);
538 for(InstrumentsDbListener l : llID) l.directoryCountChanged(e);
539 } else if(s.startsWith("DB_INSTRUMENT_DIRECTORY_INFO:")) {
540 InstrumentsDbEvent e;
541 s = s.substring("DB_INSTRUMENT_DIRECTORY_INFO:".length());
542 if(s.startsWith("NAME ")) {
543 String[] list;
544 try {
545 list = parseQuotedStringList(s.substring("NAME ".length()), ' ');
546 if(list.length != 2) throw new LscpException();
547 e = new InstrumentsDbEvent(this, list[0], list[1]);
548 for(InstrumentsDbListener l : llID) {
549 l.directoryNameChanged(e);
550 }
551 } catch(LscpException x) {
552 getLogger().log (
553 Level.WARNING,
554 LscpI18n.getLogMsg("CommandFailed!"),
555 x
556 );
557 }
558 } else {
559 e = new InstrumentsDbEvent(this, s);
560 for(InstrumentsDbListener l : llID) l.directoryInfoChanged(e);
561 }
562 } else if(s.startsWith("DB_INSTRUMENT_COUNT:")) {
563 s = s.substring("DB_INSTRUMENT_COUNT:".length());
564 InstrumentsDbEvent e = new InstrumentsDbEvent(this, s);
565 for(InstrumentsDbListener l : llID) l.instrumentCountChanged(e);
566 } else if(s.startsWith("DB_INSTRUMENT_INFO:")) {
567 InstrumentsDbEvent e;
568 s = s.substring("DB_INSTRUMENT_INFO:".length());
569 if(s.startsWith("NAME ")) {
570 String[] list;
571 try {
572 list = parseQuotedStringList(s.substring("NAME ".length()), ' ');
573 if(list.length != 2) throw new LscpException();
574 e = new InstrumentsDbEvent(this, list[0], list[1]);
575 for(InstrumentsDbListener l : llID) {
576 l.instrumentNameChanged(e);
577 }
578 } catch(LscpException x) {
579 getLogger().log (
580 Level.WARNING,
581 LscpI18n.getLogMsg("CommandFailed!"),
582 x
583 );
584 }
585 } else {
586 e = new InstrumentsDbEvent(this, s);
587 for(InstrumentsDbListener l : llID) l.instrumentInfoChanged(e);
588 }
589 } else if(s.startsWith("DB_INSTRUMENTS_JOB_INFO:")) {
590 s = s.substring("DB_INSTRUMENTS_JOB_INFO:".length());
591 try {
592 int i = Integer.parseInt(s);
593 InstrumentsDbEvent e = new InstrumentsDbEvent(this, i);
594 for(InstrumentsDbListener l : llID) l.jobStatusChanged(e);
595 } catch(NumberFormatException x) {
596 s = "Unknown DB_INSTRUMENTS_JOB_INFO format";
597 getLogger().log(Level.WARNING, s, x);
598 }
599
600 } else if(s.startsWith("CHANNEL_COUNT:")) {
601 try {
602 int i = Integer.parseInt(s.substring("CHANNEL_COUNT:".length()));
603 ChannelCountEvent e = new ChannelCountEvent(this, i);
604 for(ChannelCountListener l : llCC) l.channelCountChanged(e);
605 } catch(NumberFormatException x) {
606 getLogger().log (
607 Level.WARNING, LscpI18n.getLogMsg("CommandFailed!"), x
608 );
609 }
610 } else if(s.startsWith("VOICE_COUNT:")) {
611 try {
612 s = s.substring("VOICE_COUNT:".length());
613 Integer[] i = parseIntList(s, ' ');
614 if(i.length != 2) {
615 getLogger().warning("Unknown VOICE_COUNT format");
616 return;
617 }
618 VoiceCountEvent e = new VoiceCountEvent(this, i[0], i[1]);
619 for(VoiceCountListener l : llVC) l.voiceCountChanged(e);
620 } catch(Exception x) {
621 getLogger().log(Level.WARNING, "Unknown VOICE_COUNT format", x);
622 }
623 } else if(s.startsWith("STREAM_COUNT:")) {
624 try {
625 s = s.substring("STREAM_COUNT:".length());
626 Integer[] i = parseIntList(s, ' ');
627 if(i.length != 2) {
628 getLogger().warning("Unknown STREAM_COUNT format");
629 return;
630 }
631 StreamCountEvent e = new StreamCountEvent(this, i[0], i[1]);
632 for(StreamCountListener l : llSC) l.streamCountChanged(e);
633 } catch(Exception x) {
634 getLogger().log(Level.WARNING, "Unknown STREAM_COUNT format", x);
635 }
636 } else if(s.startsWith("BUFFER_FILL:")) {
637 try {
638 s = s.substring("BUFFER_FILL:".length());
639 int i = s.indexOf(' ');
640 if(i == -1) {
641 getLogger().warning("Unknown BUFFER_FILL format");
642 return;
643 }
644 int j = Integer.parseInt(s.substring(0, i));
645 Vector<BufferFill> v =
646 getChannelBufferFillPercentage(s.substring(i + 1));
647 BufferFillEvent e = new BufferFillEvent(this, j, v);
648 for(BufferFillListener l : llBF) l.bufferFillChanged(e);
649 } catch(Exception x) {
650 getLogger().log(Level.WARNING, "Unknown BUFFER_FILL format", x);
651 }
652 } else if(s.startsWith("CHANNEL_INFO:")) {
653 try {
654 int i = Integer.parseInt(s.substring("CHANNEL_INFO:".length()));
655 ChannelInfoEvent e = new ChannelInfoEvent(this, i);
656 for(ChannelInfoListener l : llCI) l.channelInfoChanged(e);
657 } catch(NumberFormatException x) {
658 getLogger().log(Level.WARNING, "Unknown CHANNEL_INFO format", x);
659 }
660 } else if(s.startsWith("TOTAL_VOICE_COUNT:")) {
661 try {
662 s = s.substring("TOTAL_VOICE_COUNT:".length());
663 int i = Integer.parseInt(s);
664 TotalVoiceCountEvent e = new TotalVoiceCountEvent(this, i);
665 for(TotalVoiceCountListener l : llTVC) l.totalVoiceCountChanged(e);
666 } catch(NumberFormatException x) {
667 getLogger().log (
668 Level.WARNING, "Unknown TOTAL_VOICE_COUNT format", x
669 );
670 }
671 } else if(s.startsWith("AUDIO_OUTPUT_DEVICE_COUNT:")) {
672 try {
673 s = s.substring("AUDIO_OUTPUT_DEVICE_COUNT:".length());
674 int i = Integer.parseInt(s);
675 ItemCountEvent e = new ItemCountEvent(this, i);
676 for(ItemCountListener l : llAODC) l.itemCountChanged(e);
677 } catch(NumberFormatException x) {
678 getLogger().log (
679 Level.WARNING, "Unknown AUDIO_OUTPUT_DEVICE_COUNT format", x
680 );
681 }
682 } else if(s.startsWith("AUDIO_OUTPUT_DEVICE_INFO:")) {
683 try {
684 s = s.substring("AUDIO_OUTPUT_DEVICE_INFO:".length());
685 int i = Integer.parseInt(s);
686 ItemInfoEvent e = new ItemInfoEvent(this, i);
687 for(ItemInfoListener l : llAODI) l.itemInfoChanged(e);
688 } catch(NumberFormatException x) {
689 getLogger().log (
690 Level.WARNING, "Unknown AUDIO_OUTPUT_DEVICE_INFO format", x
691 );
692 }
693 } else if(s.startsWith("MIDI_INPUT_DEVICE_COUNT:")) {
694 try {
695 s = s.substring("MIDI_INPUT_DEVICE_COUNT:".length());
696 int i = Integer.parseInt(s);
697 ItemCountEvent e = new ItemCountEvent(this, i);
698 for(ItemCountListener l : llMIDC) l.itemCountChanged(e);
699 } catch(NumberFormatException x) {
700 getLogger().log (
701 Level.WARNING, "Unknown MIDI_INPUT_DEVICE_COUNT format", x
702 );
703 }
704 } else if(s.startsWith("MIDI_INPUT_DEVICE_INFO:")) {
705 try {
706 s = s.substring("MIDI_INPUT_DEVICE_INFO:".length());
707 int i = Integer.parseInt(s);
708 ItemInfoEvent e = new ItemInfoEvent(this, i);
709 for(ItemInfoListener l : llMIDI) l.itemInfoChanged(e);
710 } catch(NumberFormatException x) {
711 getLogger().log (
712 Level.WARNING, "Unknown MIDI_INPUT_DEVICE_INFO format", x
713 );
714 }
715 } else if(s.startsWith("MIDI_INSTRUMENT_MAP_COUNT:")) {
716 try {
717 s = s.substring("MIDI_INSTRUMENT_MAP_COUNT:".length());
718 int i = Integer.parseInt(s);
719 ItemCountEvent e = new ItemCountEvent(this, i);
720 for(ItemCountListener l : llMIMC) l.itemCountChanged(e);
721 } catch(NumberFormatException x) {
722 getLogger().log (
723 Level.WARNING, "Unknown MIDI_INSTRUMENT_MAP_COUNT format", x
724 );
725 }
726 } else if(s.startsWith("MIDI_INSTRUMENT_MAP_INFO:")) {
727 try {
728 s = s.substring("MIDI_INSTRUMENT_MAP_INFO:".length());
729 int i = Integer.parseInt(s);
730 ItemInfoEvent e = new ItemInfoEvent(this, i);
731 for(ItemInfoListener l : llMIMI) l.itemInfoChanged(e);
732 } catch(NumberFormatException x) {
733 getLogger().log (
734 Level.WARNING, "Unknown MIDI_INSTRUMENT_MAP_INFO format", x
735 );
736 }
737 } else if(s.startsWith("MIDI_INSTRUMENT_COUNT:")) {
738 try {
739 s = s.substring("MIDI_INSTRUMENT_COUNT:".length());
740 Integer[] i = parseIntList(s, ' ');
741 if(i.length != 2) {
742 getLogger().warning("Unknown MIDI_INSTRUMENT_COUNT format");
743 return;
744 }
745
746 MidiInstrumentCountEvent e =
747 new MidiInstrumentCountEvent(this, i[0], i[1]);
748
749 for(MidiInstrumentCountListener l : llMIC) {
750 l.instrumentCountChanged(e);
751 }
752 } catch(Exception x) {
753 getLogger().log (
754 Level.WARNING, "Unknown MIDI_INSTRUMENT_COUNT format", x
755 );
756 }
757 } else if(s.startsWith("MIDI_INSTRUMENT_INFO:")) {
758 try {
759 s = s.substring("MIDI_INSTRUMENT_INFO:".length());
760 Integer[] i = parseIntList(s, ' ');
761 if(i.length != 3) {
762 getLogger().warning("Unknown MIDI_INSTRUMENT_INFO format");
763 return;
764 }
765
766 MidiInstrumentInfoEvent e =
767 new MidiInstrumentInfoEvent(this, i[0], i[1], i[2]);
768 for(MidiInstrumentInfoListener l : llMII) {
769 l.instrumentInfoChanged(e);
770 }
771 } catch(Exception x) {
772 getLogger().log (
773 Level.WARNING, "Unknown MIDI_INSTRUMENT_INFO format", x
774 );
775 }
776 } else if(s.startsWith("FX_SEND_COUNT:")) {
777 try {
778 s = s.substring("FX_SEND_COUNT:".length());
779 Integer[] i = parseIntList(s, ' ');
780 if(i.length != 2) {
781 getLogger().warning("Unknown FX_SEND_COUNT format");
782 return;
783 }
784
785 FxSendCountEvent e = new FxSendCountEvent(this, i[0], i[1]);
786
787 for(FxSendCountListener l : llFSC) l.fxSendCountChanged(e);
788 } catch(Exception x) {
789 getLogger().log(Level.WARNING, "Unknown FX_SEND_COUNT format", x);
790 }
791 } else if(s.startsWith("FX_SEND_INFO:")) {
792 try {
793 s = s.substring("FX_SEND_INFO:".length());
794 Integer[] i = parseIntList(s, ' ');
795 if(i.length != 2) {
796 getLogger().warning("Unknown FX_SEND_INFO format");
797 return;
798 }
799
800 FxSendInfoEvent e = new FxSendInfoEvent(this, i[0], i[1]);
801 for(FxSendInfoListener l : llFSI) {
802 l.fxSendInfoChanged(e);
803 }
804 } catch(Exception x) {
805 getLogger().log(Level.WARNING, "Unknown FX_SEND_INFO format", x);
806 }
807 } else if(s.startsWith("GLOBAL_INFO:")) {
808 handleGlobalInfoEvent(s.substring("GLOBAL_INFO:".length()));
809 } else if(s.startsWith("MISCELLANEOUS:")) {
810 s = s.substring("MISCELLANEOUS:".length());
811 MiscellaneousEvent e = new MiscellaneousEvent(this, s);
812 for(MiscellaneousListener l : llM) l.miscEventOccured(e);
813 }
814 }
815
816 private void
817 handleGlobalInfoEvent(String s) {
818 try {
819 if(s.startsWith("VOLUME ")) {
820 float f = Float.parseFloat(s.substring("VOLUME ".length()));
821 GlobalInfoEvent e = new GlobalInfoEvent(this, f);
822 for(GlobalInfoListener l : llGI) l.volumeChanged(e);
823 }
824 } catch(NumberFormatException x) {
825 getLogger().log(Level.WARNING, "Unknown GLOBAL_INFO format", x);
826 }
827 }
828
829 private void
830 subscribe(String event) {
831 if(!getPrintOnlyMode()) {
832 if(!isConnected()) return;
833
834 if(!eventThread.isAlive()) eventThread.start();
835 }
836
837 try {
838 out.writeLine("SUBSCRIBE " + event);
839 if(!getPrintOnlyMode()) getEmptyResultSet();
840 } catch(Exception x) {
841 getLogger().log (
842 Level.WARNING,
843 LscpI18n.getLogMsg("Client.subscriptionFailed!", event),
844 x
845 );
846 }
847 }
848
849 private void
850 unsubscribe(String event) {
851 if(!getPrintOnlyMode() && !isConnected()) return;
852
853 try {
854 out.writeLine("UNSUBSCRIBE " + event);
855 if(!getPrintOnlyMode()) getEmptyResultSet();
856 } catch(Exception x) {
857 getLogger().log (
858 Level.WARNING,
859 LscpI18n.getLogMsg("Client.unsubscriptionFailed!", event),
860 x
861 );
862 }
863 }
864
865 /**
866 * Registers the specified listener for receiving event messages.
867 * Listeners can be registered regardless of the connection state.
868 * @param l The <code>ItemCountListener</code> to register.
869 */
870 public synchronized void
871 addAudioDeviceCountListener(ItemCountListener l) {
872 if(llAODC.isEmpty()) subscribe("AUDIO_OUTPUT_DEVICE_COUNT");
873 llAODC.add(l);
874 }
875
876 /**
877 * Removes the specified listener.
878 * Listeners can be removed regardless of the connection state.
879 * @param l The <code>ItemCountListener</code> to remove.
880 */
881 public synchronized void
882 removeAudioDeviceCountListener(ItemCountListener l) {
883 boolean b = llAODC.remove(l);
884 if(b && llAODC.isEmpty()) unsubscribe("AUDIO_OUTPUT_DEVICE_COUNT");
885 }
886
887 /**
888 * Registers the specified listener for receiving event messages.
889 * Listeners can be registered regardless of the connection state.
890 * @param l The <code>ItemInfoListener</code> to register.
891 */
892 public synchronized void
893 addAudioDeviceInfoListener(ItemInfoListener l) {
894 if(llAODI.isEmpty()) subscribe("AUDIO_OUTPUT_DEVICE_INFO");
895 llAODI.add(l);
896 }
897
898 /**
899 * Removes the specified listener.
900 * Listeners can be removed regardless of the connection state.
901 * @param l The <code>ItemInfoListener</code> to remove.
902 */
903 public synchronized void
904 removeAudioDeviceInfoListener(ItemInfoListener l) {
905 boolean b = llAODI.remove(l);
906 if(b && llAODI.isEmpty()) unsubscribe("AUDIO_OUTPUT_DEVICE_INFO");
907 }
908
909 /**
910 * Registers the specified listener for receiving event messages.
911 * Listeners can be removed regardless of the connection state.
912 * @param l The <code>BufferFillListener</code> to register.
913 */
914 public synchronized void
915 addBufferFillListener(BufferFillListener l) {
916 if(llBF.isEmpty()) subscribe("BUFFER_FILL");
917 llBF.add(l);
918 }
919
920 /**
921 * Removes the specified listener.
922 * Listeners can be removed regardless of the connection state.
923 * @param l The <code>BufferFillListener</code> to remove.
924 */
925 public synchronized void
926 removeBufferFillListener(BufferFillListener l) {
927 boolean b = llBF.remove(l);
928 if(b && llBF.isEmpty()) unsubscribe("BUFFER_FILL");
929 }
930
931 /**
932 * Registers the specified listener for receiving event messages.
933 * Listeners can be registered regardless of the connection state.
934 * @param l The <code>ChannelCountListener</code> to register.
935 */
936 public synchronized void
937 addChannelCountListener(ChannelCountListener l) {
938 if(llCC.isEmpty()) subscribe("CHANNEL_COUNT");
939 llCC.add(l);
940 }
941
942 /**
943 * Removes the specified listener.
944 * Listeners can be removed regardless of the connection state.
945 * @param l The <code>ChannelCountListener</code> to remove.
946 */
947 public synchronized void
948 removeChannelCountListener(ChannelCountListener l) {
949 boolean b = llCC.remove(l);
950 if(b && llCC.isEmpty()) unsubscribe("CHANNEL_COUNT");
951 }
952
953 /**
954 * Registers the specified listener for receiving event messages.
955 * Listeners can be registered regardless of the connection state.
956 * @param l The <code>ChannelInfoListener</code> to register.
957 */
958 public synchronized void
959 addChannelInfoListener(ChannelInfoListener l) {
960 if(llCI.isEmpty()) subscribe("CHANNEL_INFO");
961 llCI.add(l);
962 }
963
964 /**
965 * Removes the specified listener.
966 * Listeners can be removed regardless of the connection state.
967 * @param l The <code>ChannelInfoListener</code> to remove.
968 */
969 public synchronized void
970 removeChannelInfoListener(ChannelInfoListener l) {
971 boolean b = llCI.remove(l);
972 if(b && llCI.isEmpty()) unsubscribe("CHANNEL_INFO");
973 }
974
975 /**
976 * Registers the specified listener for receiving event messages.
977 * Listeners can be registered regardless of the connection state.
978 * @param l The <code>FxSendCountListener</code> to register.
979 */
980 public synchronized void
981 addFxSendCountListener(FxSendCountListener l) {
982 if(llFSC.isEmpty()) subscribe("FX_SEND_COUNT");
983 llFSC.add(l);
984 }
985
986 /**
987 * Removes the specified listener.
988 * Listeners can be removed regardless of the connection state.
989 * @param l The <code>FxSendCountListener</code> to remove.
990 */
991 public synchronized void
992 removeFxSendCountListener(FxSendCountListener l) {
993 boolean b = llFSC.remove(l);
994 if(b && llFSC.isEmpty()) unsubscribe("FX_SEND_COUNT");
995 }
996
997 /**
998 * Registers the specified listener for receiving event messages.
999 * Listeners can be registered regardless of the connection state.
1000 * @param l The <code>FxSendInfoListener</code> to register.
1001 */
1002 public synchronized void
1003 addFxSendInfoListener(FxSendInfoListener l) {
1004 if(llFSI.isEmpty()) subscribe("FX_SEND_INFO");
1005 llFSI.add(l);
1006 }
1007
1008 /**
1009 * Removes the specified listener.
1010 * Listeners can be removed regardless of the connection state.
1011 * @param l The <code>FxSendInfoListener</code> to remove.
1012 */
1013 public synchronized void
1014 removeFxSendInfoListener(FxSendInfoListener l) {
1015 boolean b = llFSI.remove(l);
1016 if(b && llFSI.isEmpty()) unsubscribe("FX_SEND_INFO");
1017 }
1018
1019 /**
1020 * Registers the specified listener for receiving event messages.
1021 * Listeners can be registered regardless of the connection state.
1022 * @param l The <code>ItemCountListener</code> to register.
1023 */
1024 public synchronized void
1025 addMidiDeviceCountListener(ItemCountListener l) {
1026 if(llMIDC.isEmpty()) subscribe("MIDI_INPUT_DEVICE_COUNT");
1027 llMIDC.add(l);
1028 }
1029
1030 /**
1031 * Removes the specified listener.
1032 * Listeners can be removed regardless of the connection state.
1033 * @param l The <code>ItemCountListener</code> to remove.
1034 */
1035 public synchronized void
1036 removeMidiDeviceCountListener(ItemCountListener l) {
1037 boolean b = llMIDC.remove(l);
1038 if(b && llMIDC.isEmpty()) unsubscribe("MIDI_INPUT_DEVICE_COUNT");
1039 }
1040
1041 /**
1042 * Registers the specified listener for receiving event messages.
1043 * Listeners can be registered regardless of the connection state.
1044 * @param l The <code>ItemInfoListener</code> to register.
1045 */
1046 public synchronized void
1047 addMidiDeviceInfoListener(ItemInfoListener l) {
1048 if(llMIDI.isEmpty()) subscribe("MIDI_INPUT_DEVICE_INFO");
1049 llMIDI.add(l);
1050 }
1051
1052 /**
1053 * Removes the specified listener.
1054 * Listeners can be removed regardless of the connection state.
1055 * @param l The <code>ItemInfoListener</code> to remove.
1056 */
1057 public synchronized void
1058 removeMidiDeviceInfoListener(ItemInfoListener l) {
1059 boolean b = llMIDI.remove(l);
1060 if(b && llMIDI.isEmpty()) unsubscribe("MIDI_INPUT_DEVICE_INFO");
1061 }
1062
1063 /**
1064 * Registers the specified listener for receiving event messages.
1065 * Listeners can be registered regardless of the connection state.
1066 * @param l The <code>MiscellaneousListener</code> to register.
1067 */
1068 public synchronized void
1069 addMiscellaneousListener(MiscellaneousListener l) {
1070 if(llM.isEmpty()) subscribe("MISCELLANEOUS");
1071 llM.add(l);
1072 }
1073
1074 /**
1075 * Removes the specified listener.
1076 * Listeners can be removed regardless of the connection state.
1077 * @param l The <code>MiscellaneousListener</code> to remove.
1078 */
1079 public synchronized void
1080 removeMiscellaneousListener(MiscellaneousListener l) {
1081 boolean b = llM.remove(l);
1082 if(b && llM.isEmpty()) unsubscribe("MISCELLANEOUS");
1083 }
1084
1085 /**
1086 * Registers the specified listener for receiving event messages.
1087 * Listeners can be registered regardless of the connection state.
1088 * @param l The <code>StreamCountListener</code> to register.
1089 */
1090 public synchronized void
1091 addStreamCountListener(StreamCountListener l) {
1092 if(llSC.isEmpty()) subscribe("STREAM_COUNT");
1093 llSC.add(l);
1094 }
1095
1096 /**
1097 * Removes the specified listener.
1098 * Listeners can be removed regardless of the connection state.
1099 * @param l The <code>StreamCountListener</code> to remove.
1100 */
1101 public synchronized void
1102 removeStreamCountListener(StreamCountListener l) {
1103 boolean b = llSC.remove(l);
1104 if(b && llSC.isEmpty()) unsubscribe("STREAM_COUNT");
1105 }
1106
1107 /**
1108 * Registers the specified listener for receiving event messages.
1109 * Listeners can be registered regardless of the connection state.
1110 * @param l The <code>VoiceCountListener</code> to register.
1111 */
1112 public synchronized void
1113 addVoiceCountListener(VoiceCountListener l) {
1114 if(llVC.isEmpty()) subscribe("VOICE_COUNT");
1115 llVC.add(l);
1116 }
1117
1118 /**
1119 * Removes the specified listener.
1120 * Listeners can be removed regardless of the connection state.
1121 * @param l The <code>VoiceCountListener</code> to remove.
1122 */
1123 public synchronized void
1124 removeVoiceCountListener(VoiceCountListener l) {
1125 boolean b = llVC.remove(l);
1126 if(b && llVC.isEmpty()) unsubscribe("VOICE_COUNT");
1127 }
1128
1129 /**
1130 * Registers the specified listener for receiving event messages.
1131 * Listeners can be registered regardless of the connection state.
1132 * @param l The <code>TotalVoiceCountListener</code> to register.
1133 */
1134 public synchronized void
1135 addTotalVoiceCountListener(TotalVoiceCountListener l) {
1136 if(llTVC.isEmpty()) subscribe("TOTAL_VOICE_COUNT");
1137 llTVC.add(l);
1138 }
1139
1140 /**
1141 * Removes the specified listener.
1142 * Listeners can be removed regardless of the connection state.
1143 * @param l The <code>TotalVoiceCountListener</code> to remove.
1144 */
1145 public synchronized void
1146 removeTotalVoiceCountListener(TotalVoiceCountListener l) {
1147 boolean b = llTVC.remove(l);
1148 if(b && llTVC.isEmpty()) unsubscribe("TOTAL_VOICE_COUNT");
1149 }
1150
1151 /**
1152 * Registers the specified listener for receiving event messages.
1153 * Listeners can be registered regardless of the connection state.
1154 * @param l The <code>ItemCountListener</code> to register.
1155 */
1156 public synchronized void
1157 addMidiInstrumentMapCountListener(ItemCountListener l) {
1158 if(llMIMC.isEmpty()) subscribe("MIDI_INSTRUMENT_MAP_COUNT");
1159 llMIMC.add(l);
1160 }
1161
1162 /**
1163 * Removes the specified listener.
1164 * Listeners can be removed regardless of the connection state.
1165 * @param l The <code>ItemCountListener</code> to remove.
1166 */
1167 public synchronized void
1168 removeMidiInstrumentMapCountListener(ItemCountListener l) {
1169 boolean b = llMIMC.remove(l);
1170 if(b && llMIMC.isEmpty()) unsubscribe("MIDI_INSTRUMENT_MAP_COUNT");
1171 }
1172
1173 /**
1174 * Registers the specified listener for receiving event messages.
1175 * Listeners can be registered regardless of the connection state.
1176 * @param l The <code>ItemInfoListener</code> to register.
1177 */
1178 public synchronized void
1179 addMidiInstrumentMapInfoListener(ItemInfoListener l) {
1180 if(llMIMI.isEmpty()) subscribe("MIDI_INSTRUMENT_MAP_INFO");
1181 llMIMI.add(l);
1182 }
1183
1184 /**
1185 * Removes the specified listener.
1186 * Listeners can be removed regardless of the connection state.
1187 * @param l The <code>ItemInfoListener</code> to remove.
1188 */
1189 public synchronized void
1190 removeMidiInstrumentMapInfoListener(ItemInfoListener l) {
1191 boolean b = llMIMI.remove(l);
1192 if(b && llMIMI.isEmpty()) unsubscribe("MIDI_INSTRUMENT_MAP_INFO");
1193 }
1194
1195 /**
1196 * Registers the specified listener for receiving event messages.
1197 * Listeners can be registered regardless of the connection state.
1198 * @param l The <code>MidiInstrumentCountListener</code> to register.
1199 */
1200 public synchronized void
1201 addMidiInstrumentCountListener(MidiInstrumentCountListener l) {
1202 if(llMIC.isEmpty()) subscribe("MIDI_INSTRUMENT_COUNT");
1203 llMIC.add(l);
1204 }
1205
1206 /**
1207 * Removes the specified listener.
1208 * Listeners can be removed regardless of the connection state.
1209 * @param l The <code>MidiInstrumentCountListener</code> to remove.
1210 */
1211 public synchronized void
1212 removeMidiInstrumentCountListener(MidiInstrumentCountListener l) {
1213 boolean b = llMIC.remove(l);
1214 if(b && llMIC.isEmpty()) unsubscribe("MIDI_INSTRUMENT_COUNT");
1215 }
1216
1217 /**
1218 * Registers the specified listener for receiving event messages.
1219 * Listeners can be registered regardless of the connection state.
1220 * @param l The <code>MidiInstrumentInfoListener</code> to register.
1221 */
1222 public synchronized void
1223 addMidiInstrumentInfoListener(MidiInstrumentInfoListener l) {
1224 if(llMII.isEmpty()) subscribe("MIDI_INSTRUMENT_INFO");
1225 llMII.add(l);
1226 }
1227
1228 /**
1229 * Removes the specified listener.
1230 * Listeners can be removed regardless of the connection state.
1231 * @param l The <code>MidiInstrumentInfoListener</code> to remove.
1232 */
1233 public synchronized void
1234 removeMidiInstrumentInfoListener(MidiInstrumentInfoListener l) {
1235 boolean b = llMII.remove(l);
1236 if(b && llMII.isEmpty()) unsubscribe("MIDI_INSTRUMENT_INFO");
1237 }
1238
1239 /**
1240 * Registers the specified listener for receiving event messages.
1241 * Listeners can be registered regardless of the connection state.
1242 * @param l The <code>InstrumentsDbListener</code> to register.
1243 */
1244 public synchronized void
1245 addInstrumentsDbListener(InstrumentsDbListener l) {
1246 if(llID.isEmpty()) {
1247 subscribe("DB_INSTRUMENT_DIRECTORY_COUNT");
1248 subscribe("DB_INSTRUMENT_DIRECTORY_INFO");
1249 subscribe("DB_INSTRUMENT_COUNT");
1250 subscribe("DB_INSTRUMENT_INFO");
1251 subscribe("DB_INSTRUMENTS_JOB_INFO");
1252 }
1253 llID.add(l);
1254 }
1255
1256 /**
1257 * Removes the specified listener.
1258 * Listeners can be removed regardless of the connection state.
1259 * @param l The <code>InstrumentsDbListener</code> to remove.
1260 */
1261 public synchronized void
1262 removeInstrumentsDbListener(InstrumentsDbListener l) {
1263 boolean b = llID.remove(l);
1264 if(b && llID.isEmpty()) {
1265 unsubscribe("DB_INSTRUMENT_DIRECTORY_COUNT");
1266 unsubscribe("DB_INSTRUMENT_DIRECTORY_INFO");
1267 unsubscribe("DB_INSTRUMENT_COUNT");
1268 unsubscribe("DB_INSTRUMENT_INFO");
1269 unsubscribe("DB_INSTRUMENTS_JOB_INFO");
1270 }
1271 }
1272
1273 /**
1274 * Registers the specified listener for receiving event messages.
1275 * Listeners can be registered regardless of the connection state.
1276 * @param l The <code>GlobalInfoListener</code> to register.
1277 */
1278 public synchronized void
1279 addGlobalInfoListener(GlobalInfoListener l) {
1280 if(llGI.isEmpty()) subscribe("GLOBAL_INFO");
1281 llGI.add(l);
1282 }
1283
1284 /**
1285 * Removes the specified listener.
1286 * Listeners can be removed regardless of the connection state.
1287 * @param l The <code>GlobalInfoListener</code> to remove.
1288 */
1289 public synchronized void
1290 removeGlobalInfoListener(GlobalInfoListener l) {
1291 boolean b = llGI.remove(l);
1292 if(b && llGI.isEmpty()) unsubscribe("GLOBAL_INFO");
1293 }
1294
1295 /**
1296 * Gets the number of all audio output drivers currently
1297 * available for the LinuxSampler instance.
1298 * @return The number of all audio output drivers currently
1299 * available for the LinuxSampler instance.
1300 * @throws IOException If some I/O error occurs.
1301 * @throws LscpException If LSCP protocol corruption occurs.
1302 * @throws LSException If some other error occurs.
1303 */
1304 public synchronized int
1305 getAudioOutputDriverCount() throws IOException, LscpException, LSException {
1306 verifyConnection();
1307 out.writeLine("GET AVAILABLE_AUDIO_OUTPUT_DRIVERS");
1308
1309 if(getPrintOnlyMode()) return -1;
1310
1311 String s = getSingleLineResultSet().getResult();
1312 return parseInt(s);
1313 }
1314
1315 /**
1316 * Gets all audio output drivers currently available for the LinuxSampler instance.
1317 *
1318 * @return <code>AudioOutputDriver</code> array containing all audio output drivers
1319 * currently available for the LinuxSampler instance.
1320 *
1321 * @throws IOException If an I/O error occurs.
1322 * @throws LscpException If LSCP protocol corruption occurs.
1323 * @throws LSException If some other error occurs.
1324 */
1325 public synchronized AudioOutputDriver[]
1326 getAudioOutputDrivers() throws IOException, LscpException, LSException {
1327 String[] drivers = getAudioOutputDriverNames();
1328 if(getPrintOnlyMode()) return null;
1329
1330 AudioOutputDriver[] aod = new AudioOutputDriver[drivers.length];
1331
1332 for(int i = 0; i < aod.length; i++) aod[i] = getAudioOutputDriverInfo(drivers[i]);
1333
1334 return aod;
1335 }
1336
1337 /**
1338 * Gets all audio output drivers currently available for the LinuxSampler instance.
1339 *
1340 * @return <code>String</code> array containing all audio output drivers currently
1341 * available for the LinuxSampler instance.
1342 *
1343 * @throws IOException If an I/O error occurs.
1344 * @throws LscpException If LSCP protocol corruption occurs.
1345 * @throws LSException If some other error occurs.
1346 */
1347 private synchronized String[]
1348 getAudioOutputDriverNames() throws IOException, LscpException, LSException {
1349 verifyConnection();
1350 out.writeLine("LIST AVAILABLE_AUDIO_OUTPUT_DRIVERS");
1351 if(getPrintOnlyMode()) return null;
1352 return parseList(getSingleLineResultSet().getResult());
1353 }
1354
1355 /**
1356 * Gets detailed information about a specific audio output driver.
1357 * @param driverName The name of the audio output driver.
1358 * @param depList An optional list of dependences parameters.
1359 * @return An <code>AudioOutputDriver</code> object containing
1360 * information about the specified audio output driver.
1361 *
1362 * @throws IOException If an I/O error occurs.
1363 * @throws LscpException If LSCP protocol corruption occurs.
1364 * @throws LSException If there is no driver with name <code>driverName</code>.
1365 *
1366 * @see #getAudioOutputDriverNames
1367 */
1368 public synchronized AudioOutputDriver
1369 getAudioOutputDriverInfo(String driverName, Parameter... depList)
1370 throws IOException, LscpException, LSException {
1371
1372 verifyConnection();
1373 out.writeLine("GET AUDIO_OUTPUT_DRIVER INFO " + driverName);
1374 if(getPrintOnlyMode()) return null;
1375
1376 ResultSet rs = getMultiLineResultSet();
1377 AudioOutputDriver aod = new AudioOutputDriver(rs.getMultiLineResult());
1378 aod.setName(driverName);
1379
1380 for(String s : aod.getParameterNames())
1381 aod.addParameter(getAudioOutputDriverParameterInfo(driverName, s, depList));
1382
1383 return aod;
1384 }
1385
1386 /**
1387 * Gets detailed information about a specific audio output driver parameter.
1388 *
1389 * @param driver The name of the audio output driver.
1390 * @param param A specific parameter name for which information should be obtained.
1391 * @param deplist An optional list of parameters on which the sought parameter
1392 * <code>param</code> depends on. <code>Parameter</code> instances can be
1393 * easily created using {@link ParameterFactory} factory.
1394 *
1395 * @return <code>Parameter</code> object containing
1396 * information about the specified audio output driver parameter.
1397 *
1398 * @throws IOException If an I/O error occurs.
1399 * @throws LscpException If LSCP protocol corruption occurs.
1400 * @throws LSException If <code>driver</code> is not a valid driver name
1401 * or <code>param</code> is not a valid parameter for the specified driver.
1402 *
1403 * @see #getAudioOutputDrivers
1404 * @see #getAudioOutputDriverInfo
1405 * @see ParameterFactory
1406 */
1407 public synchronized Parameter
1408 getAudioOutputDriverParameterInfo(String driver, String param, Parameter... deplist)
1409 throws IOException, LscpException, LSException {
1410
1411 verifyConnection();
1412 StringBuffer args = new StringBuffer(driver);
1413 args.append(' ').append(param);
1414
1415 for(Parameter p : deplist) {
1416 if(p.getValue() == null) continue;
1417 args.append(' ').append(p.getName()).append('=').append(p.getStringValue());
1418 }
1419
1420 out.writeLine("GET AUDIO_OUTPUT_DRIVER_PARAMETER INFO " + args.toString());
1421 if(getPrintOnlyMode()) return null;
1422
1423 ResultSet rs = getMultiLineResultSet();
1424
1425 String[] lnS = rs.getMultiLineResult();
1426 ParameterType type = parseType(lnS);
1427 boolean multi = parseMultiplicity(lnS);
1428 Parameter prm;
1429
1430 switch(type) {
1431 case BOOL:
1432 if(!multi) prm = new BoolParameter(lnS);
1433 else prm = new BoolListParameter(lnS);
1434 prm.setName(param);
1435 prm.setValue(prm.getDefault());
1436 return prm;
1437 case INT:
1438 if(!multi) prm = new IntParameter(lnS);
1439 else prm = new IntListParameter(lnS);
1440 prm.setName(param);
1441 prm.setValue(prm.getDefault());
1442 return prm;
1443 case FLOAT:
1444 if(!multi) prm = new FloatParameter(lnS);
1445 else prm = new FloatListParameter(lnS);
1446 prm.setName(param);
1447 prm.setValue(prm.getDefault());
1448 return prm;
1449 case STRING:
1450 if(!multi) prm = new StringParameter(lnS);
1451 else prm = new StringListParameter(lnS);
1452 prm.setName(param);
1453 prm.setValue(prm.getDefault());
1454 return prm;
1455 default: throw new LscpException(LscpI18n.getLogMsg("Client.unknownPrmType!"));
1456 }
1457 }
1458
1459 /**
1460 * Creates a new audio output device for the desired audio output system.
1461 * @param aoDriver The desired audio output system.
1462 * @param paramList An optional list of driver specific parameters. <code>Parameter</code>
1463 * instances can be easily created using {@link ParameterFactory} factory.
1464 * @return The numerical ID of the newly created device.
1465 * @throws IOException If some I/O error occurs.
1466 * @throws LSException If the creation of the new audio output device failed.
1467 * @throws LscpException If LSCP protocol corruption occurs.
1468 * @see #getAudioOutputDrivers
1469 * @see #getAudioOutputDriverInfo
1470 * @see ParameterFactory
1471 */
1472 public synchronized int
1473 createAudioOutputDevice(String aoDriver, Parameter... paramList)
1474 throws IOException, LSException, LscpException {
1475
1476 verifyConnection();
1477 StringBuffer args = new StringBuffer(aoDriver);
1478
1479 for(Parameter p : paramList) {
1480 if(p.getValue() == null) continue;
1481 args.append(' ').append(p.getName()).append('=').append(p.getStringValue());
1482 }
1483
1484 out.writeLine("CREATE AUDIO_OUTPUT_DEVICE " + args.toString());
1485 if(getPrintOnlyMode()) return -1;
1486
1487 ResultSet rs = getEmptyResultSet();
1488
1489 return rs.getIndex();
1490 }
1491
1492 /**
1493 * Destroys already created audio output device.
1494 * @param deviceId The ID of the audio output device to be destroyed.
1495 * @throws IOException If some I/O error occurs.
1496 * @throws LSException If the destroying of the audio output device failed.
1497 * @throws LscpException If LSCP protocol corruption occurs.
1498 * @see #getAudioOutputDevices
1499 */
1500 public synchronized void
1501 destroyAudioOutputDevice(int deviceId) throws IOException, LSException, LscpException {
1502 verifyConnection();
1503 out.writeLine("DESTROY AUDIO_OUTPUT_DEVICE " + deviceId);
1504 if(getPrintOnlyMode()) return;
1505
1506 ResultSet rs = getEmptyResultSet();
1507 }
1508
1509 /**
1510 * Enables/disables the specified audio output device.
1511 * @param deviceId The ID of the audio output device to be enabled/disabled.
1512 * @param enable If <code>true</code> the audio output device is enabled,
1513 * else the device is disabled.
1514 * @throws IOException If some I/O error occurs.
1515 * @throws LSException If there is no audio output
1516 * device with numerical ID <code>deviceId</code>.
1517 * @throws LscpException If LSCP protocol corruption occurs.
1518 */
1519 public void
1520 enableAudioOutputDevice(int deviceId, boolean enable)
1521 throws IOException, LSException, LscpException {
1522
1523 setAudioOutputDeviceParameter(deviceId, new BoolParameter("ACTIVE", enable));
1524 }
1525
1526 /**
1527 * Gets the current number of all created audio output devices.
1528 * @return The current number of all created audio output devices.
1529 * @throws IOException If some I/O error occurs.
1530 * @throws LscpException If LSCP protocol corruption occurs.
1531 * @throws LSException If some other error occurs.
1532 */
1533 public synchronized int
1534 getAudioOutputDeviceCount() throws IOException, LscpException, LSException {
1535 verifyConnection();
1536 out.writeLine("GET AUDIO_OUTPUT_DEVICES");
1537 if(getPrintOnlyMode()) return -1;
1538
1539 String s = getSingleLineResultSet().getResult();
1540 return parseInt(s);
1541 }
1542
1543 /**
1544 * Gets a list of all created audio output devices.
1545 * @return An <code>AudioOutputDevice</code> array
1546 * providing all created audio output devices.
1547 * @throws IOException If some I/O error occurs.
1548 * @throws LscpException If LSCP protocol corruption occurs.
1549 * @throws LSException If some other error occurs.
1550 */
1551 public synchronized AudioOutputDevice[]
1552 getAudioOutputDevices() throws IOException, LscpException, LSException {
1553 Integer[] idS = getAudioOutputDeviceIDs();
1554 if(getPrintOnlyMode()) return null;
1555
1556 AudioOutputDevice[] devices = new AudioOutputDevice[idS.length];
1557
1558 for(int i = 0; i < devices.length; i++)
1559 devices[i] = getAudioOutputDeviceInfo(idS[i]);
1560
1561 return devices;
1562 }
1563
1564 /**
1565 * Gets a list of numerical IDs of all created audio output devices.
1566 * @return An <code>Integer</code> array providing the numerical IDs of
1567 * all created audio output devices.
1568 * @throws IOException If some I/O error occurs.
1569 * @throws LscpException If LSCP protocol corruption occurs.
1570 * @throws LSException If some other error occurs.
1571 */
1572 public synchronized Integer[]
1573 getAudioOutputDeviceIDs() throws IOException, LscpException, LSException {
1574 verifyConnection();
1575 out.writeLine("LIST AUDIO_OUTPUT_DEVICES");
1576 if(getPrintOnlyMode()) return null;
1577
1578 return parseIntList(getSingleLineResultSet().getResult());
1579 }
1580
1581 /**
1582 * Gets the current settings of a specific, already created audio output device.
1583 *
1584 * @param deviceId Specifies the numerical ID of the audio output device.
1585 *
1586 * @return An <code>AudioOutputDevice</code> instance containing information
1587 * about the specified device.
1588 *
1589 * @throws IOException If some I/O error occurs.
1590 * @throws LscpException If LSCP protocol corruption occurs.
1591 * @throws LSException If there is no audio output device
1592 * with device id <code>deviceId</code>.
1593 *
1594 * @see #getAudioOutputDevices
1595 */
1596 public synchronized AudioOutputDevice
1597 getAudioOutputDeviceInfo(int deviceId) throws IOException, LscpException, LSException {
1598 verifyConnection();
1599 out.writeLine("GET AUDIO_OUTPUT_DEVICE INFO " + deviceId);
1600 if(getPrintOnlyMode()) return null;
1601
1602 ResultSet rs = getMultiLineResultSet();
1603
1604 String[] lnS = rs.getMultiLineResult();
1605
1606 AudioOutputDevice aod = new AudioOutputDevice();
1607 aod.setDeviceId(deviceId);
1608 Parameter<Integer> channels;
1609 Parameter<Integer> samplerate;
1610
1611 String drv = getCategoryInfo(lnS, "DRIVER");
1612 aod.setDriverName(drv);
1613
1614 for(String s : lnS) {
1615 if(s.startsWith("CHANNELS: ")) {
1616 channels = (Parameter<Integer>)
1617 getAudioOutputDriverParameterInfo(drv, "CHANNELS");
1618
1619 s = s.substring("CHANNELS: ".length(), s.length());
1620 channels.parseValue(s);
1621 aod.setChannelsParameter(channels);
1622 int count = channels.getValue() > 0 ? channels.getValue() : 0;
1623 AudioOutputChannel[] aoc = new AudioOutputChannel[count];
1624 for(int i = 0; i < count; i++) {
1625 aoc[i] = getAudioOutputChannelInfo(deviceId, i);
1626 }
1627 aod.setAudioChannels(aoc);
1628 } else if(s.startsWith("SAMPLERATE: ")) {
1629 samplerate = (Parameter<Integer>)
1630 getAudioOutputDriverParameterInfo(drv, "SAMPLERATE");
1631
1632 s = s.substring("SAMPLERATE: ".length(), s.length());
1633 samplerate.parseValue(s);
1634 aod.setSampleRateParameter(samplerate);
1635 } else if(s.startsWith("ACTIVE: ")) {
1636 s = s.substring("ACTIVE: ".length(), s.length());
1637 aod.setActive(Boolean.parseBoolean(s));
1638 } else if(s.startsWith("DRIVER: ")) {
1639
1640 } else {
1641 int i = s.indexOf(": ");
1642 if(i == -1) throw new LscpException (
1643 LscpI18n.getLogMsg("CommandFailed!")
1644 );
1645
1646 Parameter prm =
1647 getAudioOutputDriverParameterInfo(drv, s.substring(0, i));
1648
1649 s = s.substring(i + 2);
1650 prm.parseValue(s);
1651
1652 aod.addParameter(prm);
1653 }
1654 }
1655
1656 return aod;
1657 }
1658
1659 /**
1660 * Alters a specific setting of a created audio output device.
1661 *
1662 * @param deviceId The numerical ID of the audio output device.
1663 * @param prm A <code>Parameter</code> instance containing the name of the parameter
1664 * and the new value for this parameter.
1665 *
1666 * @throws IOException If some I/O error occurs.
1667 * @throws LscpException If LSCP protocol corruption occurs.
1668 * @throws LSException If
1669 * <ul>
1670 * <li>There is no audio output device with numerical ID <code>deviceId</code>;
1671 * <li>There is no device parameter with the specified name;
1672 * <li>The device parameter is readonly;
1673 * <li>The device parameter is from different type.
1674 * </ul>
1675 *
1676 * @see #getAudioOutputDevices
1677 * @see #getAudioOutputDeviceInfo
1678 */
1679 public synchronized void
1680 setAudioOutputDeviceParameter(int deviceId, Parameter prm)
1681 throws IOException, LscpException, LSException {
1682
1683 verifyConnection();
1684 String kv = prm.getName() + '=' + prm.getStringValue();
1685 out.writeLine("SET AUDIO_OUTPUT_DEVICE_PARAMETER " + deviceId + ' ' + kv);
1686 if(getPrintOnlyMode()) return;
1687
1688 ResultSet rs = getEmptyResultSet();
1689 }
1690
1691 /**
1692 * Changes the channel number of the speicifed audio output device.
1693 * @param deviceId The numerical ID of the audio output device.
1694 * @param channels The new number of audio output channels.
1695 *
1696 * @throws IOException If an I/O error occurs.
1697 * @throws LscpException If LSCP protocol corruption occurs.
1698 * @throws LSException If there is no device with ID <code>deviceId</code> or
1699 * if <code>channels</code> number is out of range.
1700 *
1701 * @see #getAudioOutputChannelInfo
1702 */
1703 public synchronized void
1704 setAudioOutputChannelCount(int deviceId, int channels)
1705 throws IOException, LscpException, LSException {
1706
1707 setAudioOutputDeviceParameter(deviceId, new IntParameter("CHANNELS", channels));
1708 }
1709
1710 /**
1711 * Gets information about an audio channel.
1712 *
1713 * @param deviceId The numerical ID of the audio output device.
1714 * @param audioChn The audio channel number.
1715 *
1716 * @return An <code>AudioOutputChannel</code> instance containing the
1717 * information about the specified audio output channel.
1718 *
1719 * @throws IOException If some I/O error occurs.
1720 * @throws LscpException If LSCP protocol corruption occurs.
1721 * @throws LSException If
1722 * <ul>
1723 * <li>There is no audio output device with numerical ID <code>deviceId</code>;
1724 * <li><code>audioChn</code> is not a valid channel number;
1725 * </ul>
1726 *
1727 * @see #getAudioOutputDevices
1728 * @see #getAudioOutputDeviceInfo
1729 */
1730 public synchronized AudioOutputChannel
1731 getAudioOutputChannelInfo(int deviceId, int audioChn)
1732 throws IOException, LscpException, LSException {
1733
1734 verifyConnection();
1735 out.writeLine("GET AUDIO_OUTPUT_CHANNEL INFO " + deviceId + ' ' + audioChn);
1736 if(getPrintOnlyMode()) return null;
1737
1738 ResultSet rs = getMultiLineResultSet();
1739
1740 AudioOutputChannel aoc = new AudioOutputChannel();
1741
1742 String[] lnS = rs.getMultiLineResult();
1743 for(String s : lnS) {
1744 if(s.startsWith("NAME: ")) {
1745 s = s.substring("NAME: ".length());
1746 Parameter<String> prm = getAudioOutputChannelParameterInfo (
1747 deviceId, audioChn, "NAME"
1748 );
1749 prm.setValue(removeQuotation(s));
1750 aoc.setNameParameter(prm);
1751 } else if(s.startsWith("IS_MIX_CHANNEL: ")) {
1752 s = s.substring("IS_MIX_CHANNEL: ".length());
1753 Parameter<Boolean> prm = getAudioOutputChannelParameterInfo (
1754 deviceId, audioChn, "IS_MIX_CHANNEL"
1755 );
1756 prm.setValue(Boolean.parseBoolean(s));
1757 aoc.setMixChannelParameter(prm);
1758 } else if(s.startsWith("MIX_CHANNEL_DESTINATION: ")) {
1759 s = s.substring("MIX_CHANNEL_DESTINATION: ".length());
1760 Parameter<Integer> prm = getAudioOutputChannelParameterInfo (
1761 deviceId, audioChn, "MIX_CHANNEL_DESTINATION"
1762 );
1763 prm.setValue(parseInt(s));
1764 aoc.setMixChannelDestParameter(prm);
1765 } else {
1766 int i = s.indexOf(": ");
1767 if(i == -1) throw new LscpException (
1768 LscpI18n.getLogMsg("CommandFailed!")
1769 );
1770
1771 Parameter prm = getAudioOutputChannelParameterInfo (
1772 deviceId, audioChn, s.substring(0, i)
1773 );
1774
1775 s = s.substring(i + 2);
1776 prm.parseValue(s);
1777
1778 aoc.addParameter(prm);
1779 }
1780 }
1781
1782 return aoc;
1783 }
1784
1785 /**
1786 * Gets detailed information about a specific audio output channel parameter.
1787 *
1788 * @param devId The numerical ID of the audio output device.
1789 * @param chan The audio channel number.
1790 * @param param a specific channel parameter name for which information should be obtained.
1791 *
1792 * @return An <code>Parameter</code> instance containing
1793 * information about the specified audio output channel parameter.
1794 *
1795 * @throws IOException If an I/O error occurs.
1796 * @throws LscpException If LSCP protocol corruption occurs.
1797 * @throws LSException If
1798 * <ul>
1799 * <li><code>devId</code> is not a valid device ID;
1800 * <li><code>chan</code> is not a valid channel number;
1801 * <li>There is no channel parameter with the specified name.
1802 * </ul>
1803 *
1804 * @see #getAudioOutputDevices
1805 * @see #getAudioOutputChannelInfo
1806 */
1807 public synchronized Parameter
1808 getAudioOutputChannelParameterInfo(int devId, int chan, String param)
1809 throws IOException, LscpException, LSException {
1810
1811 verifyConnection();
1812 String args = devId + " " + chan + " " + param;
1813 out.writeLine("GET AUDIO_OUTPUT_CHANNEL_PARAMETER INFO " + args);
1814 if(getPrintOnlyMode()) return null;
1815
1816 ResultSet rs = getMultiLineResultSet();
1817
1818 String[] lnS = rs.getMultiLineResult();
1819 ParameterType type = parseType(lnS);
1820 boolean multi = parseMultiplicity(lnS);
1821 Parameter prm;
1822
1823 switch(type) {
1824 case BOOL:
1825 if(!multi) prm = new BoolParameter(lnS);
1826 else prm = new BoolListParameter(lnS);
1827 prm.setName(param);
1828 return prm;
1829 case INT:
1830 if(!multi) prm = new IntParameter(lnS);
1831 else prm = new IntListParameter(lnS);
1832 prm.setName(param);
1833 return prm;
1834 case FLOAT:
1835 if(!multi) prm = new FloatParameter(lnS);
1836 else prm = new FloatListParameter(lnS);
1837 prm.setName(param);
1838 return prm;
1839 case STRING:
1840 if(!multi) prm = new StringParameter(lnS);
1841 else prm = new StringListParameter(lnS);
1842 prm.setName(param);
1843 return prm;
1844 default: throw new LscpException(LscpI18n.getLogMsg("Client.unknownPrmType!"));
1845 }
1846 }
1847
1848 /**
1849 * Alters a specific setting of an audio output channel.
1850 *
1851 * @param devId The numerical ID of the audio device.
1852 * @param chn The audio channel number.
1853 * @param prm A <code>Parameter</code> instance containing the name of the parameter
1854 * and the new value for this parameter.
1855 *
1856 * @throws IOException If some I/O error occurs.
1857 * @throws LscpException If LSCP protocol corruption occurs.
1858 * @throws LSException If
1859 * <ul>
1860 * <li>There is no audio output device with numerical ID <code>devId</code>;
1861 * <li><code>chn</code> is not a valid channel number;
1862 * <li>There is no channel parameter with the specified name;
1863 * <li>The channel parameter is readonly;
1864 * <li>The channel parameter is from different type.
1865 * </ul>
1866 *
1867 * @see #getAudioOutputDevices
1868 * @see #getAudioOutputChannelInfo
1869 */
1870 public synchronized void
1871 setAudioOutputChannelParameter(int devId, int chn, Parameter prm)
1872 throws IOException, LscpException, LSException {
1873
1874 verifyConnection();
1875 String args = devId + " " + chn + " " + prm.getName() + '=' + prm.getStringValue();
1876 out.writeLine("SET AUDIO_OUTPUT_CHANNEL_PARAMETER " + args);
1877 if(getPrintOnlyMode()) return;
1878
1879 ResultSet rs = getEmptyResultSet();
1880 }
1881
1882 /**
1883 * Gets the current number of all MIDI input drivers.
1884 * @return The current number of all MIDI input drivers.
1885 * @throws IOException If some I/O error occurs.
1886 * @throws LscpException If LSCP protocol corruption occurs.
1887 * @throws LSException If some other error occurs.
1888 */
1889 public synchronized int
1890 getMidiInputDriverCount() throws IOException, LscpException, LSException {
1891 verifyConnection();
1892 out.writeLine("GET AVAILABLE_MIDI_INPUT_DRIVERS");
1893 if(getPrintOnlyMode()) return -1;
1894
1895 String s = getSingleLineResultSet().getResult();
1896 return parseInt(s);
1897 }
1898
1899 /**
1900 * Gets all MIDI input drivers currently available for the LinuxSampler instance.
1901 *
1902 * @return <code>MidiInputDriver</code> array containing all MIDI input drivers currently
1903 * available for the LinuxSampler instance.
1904 *
1905 * @throws IOException If an I/O error occurs.
1906 * @throws LscpException If LSCP protocol corruption occurs.
1907 * @throws LSException If some other error occurs.
1908 */
1909 public synchronized MidiInputDriver[]
1910 getMidiInputDrivers() throws IOException, LscpException, LSException {
1911 String[] drivers = getMidiInputDriverNames();
1912 if(getPrintOnlyMode()) return null;
1913
1914 MidiInputDriver[] mid = new MidiInputDriver[drivers.length];
1915
1916 for(int i = 0; i < mid.length; i++) mid[i] = getMidiInputDriverInfo(drivers[i]);
1917
1918 return mid;
1919 }
1920
1921 /**
1922 * Gets all MIDI input drivers currently available for the LinuxSampler instance.
1923 *
1924 * @return <code>String</code> array containing all MIDI input drivers currently available
1925 * for the LinuxSampler instance.
1926 *
1927 * @throws IOException If an I/O error occurs.
1928 * @throws LscpException If LSCP protocol corruption occurs.
1929 * @throws LSException If some other error occurs.
1930 */
1931 private synchronized String[]
1932 getMidiInputDriverNames() throws IOException, LscpException, LSException {
1933 verifyConnection();
1934 out.writeLine("LIST AVAILABLE_MIDI_INPUT_DRIVERS");
1935 if(getPrintOnlyMode()) return null;
1936
1937 return parseList(getSingleLineResultSet().getResult());
1938 }
1939
1940 /**
1941 * Gets detailed information about a specific MIDI input driver.
1942 * @param driverName The name of the MIDI input driver.
1943 * @param depList An optional list of dependences parameters.
1944 * @return A <code>MidiInputDriver</code> object containing
1945 * information about the specified MIDI input driver.
1946 *
1947 * @throws IOException If an I/O error occurs.
1948 * @throws LscpException If LSCP protocol corruption occurs.
1949 * @throws LSException If there is no driver with name <code>driverName</code>.
1950 *
1951 * @see #getMidiInputDriverNames
1952 */
1953 public synchronized MidiInputDriver
1954 getMidiInputDriverInfo(String driverName, Parameter... depList)
1955 throws IOException, LscpException, LSException {
1956
1957 verifyConnection();
1958 out.writeLine("GET MIDI_INPUT_DRIVER INFO " + driverName);
1959 if(getPrintOnlyMode()) return null;
1960
1961 ResultSet rs = getMultiLineResultSet();
1962
1963 MidiInputDriver mid = new MidiInputDriver(rs.getMultiLineResult());
1964 mid.setName(driverName);
1965
1966 for(String s : mid.getParameterNames())
1967 mid.addParameter(getMidiInputDriverParameterInfo(driverName, s, depList));
1968
1969 return mid;
1970 }
1971
1972 /**
1973 * Gets detailed information about a specific MIDI input driver parameter.
1974 *
1975 * @param driver The name of the MIDI input driver.
1976 * @param param a specific parameter name for which information should be obtained.
1977 * @param deplist An optional list of parameters on which the sought parameter
1978 * <code>param</code> depends on. <code>Parameter</code> instances can be
1979 * easily created using {@link ParameterFactory} factory.
1980 *
1981 * @return A <code>Parameter</code> object containing
1982 * information about the specified MIDI input driver parameter.
1983 *
1984 * @throws IOException If an I/O error occurs.
1985 * @throws LscpException If LSCP protocol corruption occurs.
1986 * @throws LSException If <code>driver</code> is not a valid driver name
1987 * or <code>param</code> is not a valid parameter for the specified driver.
1988 *
1989 * @see #getMidiInputDrivers
1990 * @see #getMidiInputDriverInfo
1991 * @see ParameterFactory
1992 */
1993 public synchronized Parameter
1994 getMidiInputDriverParameterInfo(String driver, String param, Parameter... deplist)
1995 throws IOException, LscpException, LSException {
1996
1997 verifyConnection();
1998 StringBuffer args = new StringBuffer(driver);
1999 args.append(' ').append(param);
2000
2001 for(Parameter p : deplist) {
2002 if(p.getValue() == null) continue;
2003 args.append(' ').append(p.getName()).append('=').append(p.getStringValue());
2004 }
2005
2006 out.writeLine("GET MIDI_INPUT_DRIVER_PARAMETER INFO " + args.toString());
2007 if(getPrintOnlyMode()) return null;
2008
2009 ResultSet rs = getMultiLineResultSet();
2010
2011 String[] lnS = rs.getMultiLineResult();
2012 ParameterType type = parseType(lnS);
2013 boolean multi = parseMultiplicity(lnS);
2014 Parameter prm;
2015
2016 switch(type) {
2017 case BOOL:
2018 if(!multi) prm = new BoolParameter(lnS);
2019 else prm = new BoolListParameter(lnS);
2020 prm.setName(param);
2021 prm.setValue(prm.getDefault());
2022 return prm;
2023 case INT:
2024 if(!multi) prm = new IntParameter(lnS);
2025 else prm = new IntListParameter(lnS);
2026 prm.setName(param);
2027 prm.setValue(prm.getDefault());
2028 return prm;
2029 case FLOAT:
2030 if(!multi) prm = new FloatParameter(lnS);
2031 else prm = new FloatListParameter(lnS);
2032 prm.setName(param);
2033 prm.setValue(prm.getDefault());
2034 return prm;
2035 case STRING:
2036 if(!multi) prm = new StringParameter(lnS);
2037 else prm = new StringListParameter(lnS);
2038 prm.setName(param);
2039 prm.setValue(prm.getDefault());
2040 return prm;
2041 default: throw new LscpException(LscpI18n.getLogMsg("Client.unknownPrmType!"));
2042 }
2043 }
2044
2045 /**
2046 * Creates a new MIDI input device.
2047 * @param miDriver The desired MIDI input system.
2048 * @param paramList An optional list of driver specific parameters. <code>Parameter</code>
2049 * instances can be easily created using {@link ParameterFactory} factory.
2050 * @return The numerical ID of the newly created device.
2051 * @throws IOException If some I/O error occurs.
2052 * @throws LSException If the creation of the new MIDI input device failed.
2053 * @throws LscpException If LSCP protocol corruption occurs.
2054 *
2055 * @see #getMidiInputDrivers
2056 * @see #getMidiInputDriverInfo
2057 * @see ParameterFactory
2058 */
2059 public synchronized int
2060 createMidiInputDevice(String miDriver, Parameter... paramList)
2061 throws IOException, LSException, LscpException {
2062
2063 verifyConnection();
2064 StringBuffer args = new StringBuffer(miDriver);
2065
2066 for(Parameter p : paramList) {
2067 if(p.getValue() == null) continue;
2068 args.append(' ').append(p.getName()).append('=').append(p.getStringValue());
2069 }
2070
2071 out.writeLine("CREATE MIDI_INPUT_DEVICE " + args.toString());
2072 if(getPrintOnlyMode()) return -1;
2073
2074 ResultSet rs = getEmptyResultSet();
2075
2076 return rs.getIndex();
2077 }
2078
2079 /**
2080 * Destroys already created MIDI input device.
2081 * @param deviceId The numerical ID of the MIDI input device to be destroyed.
2082 * @throws IOException If some I/O error occurs.
2083 * @throws LSException If the destroying of the MIDI input device failed.
2084 * @throws LscpException If LSCP protocol corruption occurs.
2085 * @see #createMidiInputDevice
2086 * @see #getMidiInputDevices
2087 */
2088 public synchronized void
2089 destroyMidiInputDevice(int deviceId) throws IOException, LSException, LscpException {
2090 verifyConnection();
2091 out.writeLine("DESTROY MIDI_INPUT_DEVICE " + deviceId);
2092 if(getPrintOnlyMode()) return;
2093
2094 ResultSet rs = getEmptyResultSet();
2095 }
2096
2097 /**
2098 * Enables/disables the specified MIDI input device.
2099 * @param deviceId The ID of the MIDI input device to be enabled/disabled.
2100 * @param enable If <code>true</code> the MIDI input device is enabled,
2101 * else the device is disabled.
2102 * @throws IOException If some I/O error occurs.
2103 * @throws LSException If there is no MIDI input
2104 * device with numerical ID <code>deviceId</code>.
2105 * @throws LscpException If LSCP protocol corruption occurs.
2106 */
2107 public void
2108 enableMidiInputDevice(int deviceId, boolean enable)
2109 throws IOException, LSException, LscpException {
2110
2111 setMidiInputDeviceParameter(deviceId, new BoolParameter("ACTIVE", enable));
2112 }
2113
2114 /**
2115 * Gets the current number of all created MIDI input devices.
2116 * @return The current number of all created MIDI input devices.
2117 * @throws IOException If some I/O error occurs.
2118 * @throws LscpException If LSCP protocol corruption occurs.
2119 * @throws LSException If some other error occurs.
2120 */
2121 public synchronized int
2122 getMidiInputDeviceCount() throws IOException, LscpException, LSException {
2123 verifyConnection();
2124 out.writeLine("GET MIDI_INPUT_DEVICES");
2125 if(getPrintOnlyMode()) return -1;
2126
2127 String s = getSingleLineResultSet().getResult();
2128 return parseInt(s);
2129 }
2130
2131 /**
2132 * Gets a list of all created MIDI input devices.
2133 * @return A <code>MidiInputDevice</code> array
2134 * providing all created MIDI input devices.
2135 * @throws IOException If some I/O error occurs.
2136 * @throws LscpException If LSCP protocol corruption occurs.
2137 * @throws LSException If some other error occurs.
2138 *
2139 * @see #createMidiInputDevice
2140 * @see #destroyMidiInputDevice
2141 */
2142 public synchronized MidiInputDevice[]
2143 getMidiInputDevices() throws IOException, LscpException, LSException {
2144 Integer[] idS = getMidiInputDeviceIDs();
2145 if(getPrintOnlyMode()) return null;
2146
2147 MidiInputDevice[] devices = new MidiInputDevice[idS.length];
2148
2149 for(int i = 0; i < devices.length; i++)
2150 devices[i] = getMidiInputDeviceInfo(idS[i]);
2151
2152 return devices;
2153 }
2154
2155 /**
2156 * Gets a list of numerical IDs of all created MIDI input devices.
2157 * @return An <code>Integer</code> array providing the numerical IDs of
2158 * all created MIDI input devices.
2159 * @throws IOException If some I/O error occurs.
2160 * @throws LscpException If LSCP protocol corruption occurs.
2161 * @throws LSException If some other error occurs.
2162 *
2163 * @see #createMidiInputDevice
2164 * @see #destroyMidiInputDevice
2165 */
2166 public synchronized Integer[]
2167 getMidiInputDeviceIDs() throws IOException, LscpException, LSException {
2168 verifyConnection();
2169 out.writeLine("LIST MIDI_INPUT_DEVICES");
2170 if(getPrintOnlyMode()) return null;
2171
2172 return parseIntList(getSingleLineResultSet().getResult());
2173 }
2174
2175 /**
2176 * Gets the current settings of a specific, already created MIDI input device.
2177 *
2178 * @param deviceId Specifies the numerical ID of the MIDI input device.
2179 *
2180 * @return A <code>MidiInputDevice</code> instance containing information
2181 * about the specified device.
2182 *
2183 * @throws IOException If some I/O error occurs.
2184 * @throws LscpException If LSCP protocol corruption occurs.
2185 * @throws LSException If there is no MIDI input device
2186 * with device id <code>deviceId</code>.
2187 *
2188 * @see #getMidiInputDevices
2189 */
2190 public synchronized MidiInputDevice
2191 getMidiInputDeviceInfo(int deviceId) throws IOException, LscpException, LSException {
2192 verifyConnection();
2193 out.writeLine("GET MIDI_INPUT_DEVICE INFO " + deviceId);
2194 if(getPrintOnlyMode()) return null;
2195
2196 ResultSet rs = getMultiLineResultSet();
2197
2198 String[] lnS = rs.getMultiLineResult();
2199
2200 MidiInputDevice mid = new MidiInputDevice();
2201 mid.setDeviceId(deviceId);
2202
2203 String drv = getCategoryInfo(lnS, "DRIVER");
2204 mid.setDriverName(drv);
2205
2206 for(String s : lnS) {
2207 if(s.startsWith("DRIVER: ")) {
2208
2209 } else if(s.startsWith("ACTIVE: ")) {
2210 s = s.substring("ACTIVE: ".length());
2211 mid.setActive(Boolean.parseBoolean(s));
2212 } else if(s.startsWith("PORTS: ")) {
2213 s = s.substring("PORTS: ".length());
2214 int ports = Parser.parseInt(s);
2215 MidiPort[] midiPorts = new MidiPort[ports > 0 ? ports : 0];
2216
2217 for(int i = 0; i < midiPorts.length; i++)
2218 midiPorts[i] = getMidiInputPortInfo(deviceId, i);
2219
2220 mid.setMidiPorts(midiPorts);
2221 } else {
2222 int i = s.indexOf(": ");
2223 if(i == -1) throw new LscpException (
2224 LscpI18n.getLogMsg("CommandFailed!")
2225 );
2226
2227 Parameter prm =
2228 getMidiInputDriverParameterInfo(drv, s.substring(0, i));
2229
2230 s = s.substring(i + 2);
2231 prm.parseValue(s);
2232
2233 mid.addParameter(prm);
2234 }
2235 }
2236
2237 return mid;
2238 }
2239
2240 /**
2241 * Alters a specific setting of a created MIDI input device.
2242 *
2243 * @param deviceId The numerical ID of the MIDI input device.
2244 * @param prm A <code>Parameter</code> instance containing the name of the parameter
2245 * and the new value for this parameter.
2246 *
2247 * @throws IOException If some I/O error occurs.
2248 * @throws LscpException If LSCP protocol corruption occurs.
2249 * @throws LSException If
2250 * <ul>
2251 * <li>There is no MIDI input device with numerical ID <code>deviceId</code>;
2252 * <li>There is no device parameter with the specified name;
2253 * <li>The device parameter is readonly;
2254 * <li>The device parameter is from different type.
2255 * </ul>
2256 *
2257 * @see #getMidiInputDevices
2258 * @see #getMidiInputDeviceInfo
2259 */
2260 public synchronized void
2261 setMidiInputDeviceParameter(int deviceId, Parameter prm)
2262 throws IOException, LscpException, LSException {
2263
2264 verifyConnection();
2265 String kv = prm.getName() + '=' + prm.getStringValue();
2266 out.writeLine("SET MIDI_INPUT_DEVICE_PARAMETER " + deviceId + ' ' + kv);
2267 if(getPrintOnlyMode()) return;
2268
2269 ResultSet rs = getEmptyResultSet();
2270 }
2271
2272
2273 /**
2274 * Changes the port number of the speicified MIDI input device.
2275 * @param deviceId The numerical ID of the MIDI input device.
2276 * @param ports The new number of MIDI input ports.
2277 *
2278 * @throws IOException If an I/O error occurs.
2279 * @throws LscpException If LSCP protocol corruption occurs.
2280 * @throws LSException If there is no device with ID <code>deviceId</code> or
2281 * if <code>ports</code> number is out of range.
2282 *
2283 * @see #getMidiInputPortInfo
2284 */
2285 public synchronized void
2286 setMidiInputPortCount(int deviceId, int ports)
2287 throws IOException, LscpException, LSException {
2288
2289 setMidiInputDeviceParameter(deviceId, new IntParameter("PORTS", ports));
2290 }
2291
2292 /**
2293 * Gets detailed information about a specific MIDI input port.
2294 * @param deviceId The numerical ID of the MIDI input device.
2295 * @param midiPort The MIDI input port number.
2296 *
2297 * @return A <code>MidiPort</code> instance containing
2298 * information about the specified MIDI input port.
2299 *
2300 * @throws IOException If an I/O error occurs.
2301 * @throws LscpException If LSCP protocol corruption occurs.
2302 * @throws LSException If there is no device with ID <code>deviceId</code> or
2303 * if <code>midiPort</code> is not a valid MIDI port number.
2304 *
2305 * @see #getMidiInputDevices
2306 */
2307 public synchronized MidiPort
2308 getMidiInputPortInfo(int deviceId, int midiPort)
2309 throws IOException, LscpException, LSException {
2310
2311 verifyConnection();
2312 out.writeLine("GET MIDI_INPUT_PORT INFO " + deviceId + " " + midiPort);
2313 if(getPrintOnlyMode()) return null;
2314
2315 ResultSet rs = getMultiLineResultSet();
2316
2317 MidiPort mp = new MidiPort();
2318 String[] lnS = rs.getMultiLineResult();
2319
2320 for(String s : lnS) {
2321 if(s.startsWith("NAME: ")) {
2322 s = s.substring("NAME: ".length());
2323 Parameter prm = getMidiInputPortParameterInfo (
2324 deviceId, midiPort, "NAME"
2325 );
2326 prm.setValue(removeQuotation(s));
2327 mp.setNameParameter(prm);
2328 } else {
2329 int i = s.indexOf(": ");
2330 if(i == -1) throw new LscpException (
2331 LscpI18n.getLogMsg("CommandFailed!")
2332 );
2333
2334 Parameter prm = getMidiInputPortParameterInfo (
2335 deviceId, midiPort, s.substring(0, i)
2336 );
2337
2338 s = s.substring(i + 2);
2339 prm.parseValue(s);
2340
2341 mp.addParameter(prm);
2342 }
2343 }
2344
2345 return mp;
2346 }
2347
2348 /**
2349 * Gets detailed information about a specific MIDI input port parameter.
2350 *
2351 * @param deviceId The numerical ID of the MIDI input device.
2352 * @param port The MIDI port number.
2353 * @param param A specific parameter name for which information should be obtained.
2354 *
2355 * @return A <code>Parameter</code> instance containing
2356 * information about the specified MIDI input port parameter.
2357 *
2358 * @throws IOException If an I/O error occurs.
2359 * @throws LscpException If LSCP protocol corruption occurs.
2360 * @throws LSException If
2361 * <ul>
2362 * <li>There is no MIDI input device with numerical ID <code>deviceId</code>;
2363 * <li> <code>port</code> is not a valid MIDI port number;
2364 * <li><code>param</code> is not a valid parameter for the specified MIDI port.
2365 * </ul>
2366 *
2367 * @see #getMidiInputDevices
2368 * @see #getMidiInputPortInfo
2369 */
2370 public synchronized Parameter
2371 getMidiInputPortParameterInfo(int deviceId, int port, String param)
2372 throws IOException, LscpException, LSException {
2373
2374 verifyConnection();
2375 String args = deviceId + " " + port + " " + param;
2376 out.writeLine("GET MIDI_INPUT_PORT_PARAMETER INFO " + args);
2377 if(getPrintOnlyMode()) return null;
2378
2379 ResultSet rs = getMultiLineResultSet();
2380
2381 String[] lnS = rs.getMultiLineResult();
2382 ParameterType type = parseType(lnS);
2383 boolean multi = parseMultiplicity(lnS);
2384 Parameter prm;
2385
2386 switch(type) {
2387 case BOOL:
2388 if(!multi) prm = new BoolParameter(lnS);
2389 else prm = new BoolListParameter(lnS);
2390 prm.setName(param);
2391 return prm;
2392 case INT:
2393 if(!multi) prm = new IntParameter(lnS);
2394 else prm = new IntListParameter(lnS);
2395 prm.setName(param);
2396 return prm;
2397 case FLOAT:
2398 if(!multi) prm = new FloatParameter(lnS);
2399 else prm = new FloatListParameter(lnS);
2400 prm.setName(param);
2401 return prm;
2402 case STRING:
2403 if(!multi) prm = new StringParameter(lnS);
2404 else prm = new StringListParameter(lnS);
2405 prm.setName(param);
2406 return prm;
2407 default: throw new LscpException(LscpI18n.getLogMsg("Client.unknownPrmType!"));
2408 }
2409 }
2410
2411 /**
2412 * Alters a specific setting of a MIDI input port.
2413 *
2414 * @param deviceId The numerical ID of the MIDI device.
2415 * @param port The MIDI port number.
2416 * @param prm A <code>Parameter</code> instance containing the name of the parameter
2417 * and the new value for this parameter.
2418 *
2419 * @throws IOException If some I/O error occurs.
2420 * @throws LscpException If LSCP protocol corruption occurs.
2421 * @throws LSException If
2422 * <ul>
2423 * <li>There is no MIDI device with numerical ID <code>deviceId</code>;
2424 * <li><code>port</code> is not a valid MIDI port number;
2425 * <li><code>prm</code> is not a valid parameter;
2426 * <li>The parameter is readonly;
2427 * <li>The parameter is from different type.
2428 * </ul>
2429 *
2430 * @see #getMidiInputDevices
2431 * @see #getMidiInputPortInfo
2432 */
2433 public synchronized void
2434 setMidiInputPortParameter(int deviceId, int port, Parameter prm)
2435 throws IOException, LscpException, LSException {
2436
2437 verifyConnection();
2438 String args = deviceId + " " + port + " " +
2439 prm.getName() + '=' + prm.getStringValue();
2440 out.writeLine("SET MIDI_INPUT_PORT_PARAMETER " + args);
2441 if(getPrintOnlyMode()) return;
2442
2443 ResultSet rs = getEmptyResultSet();
2444 }
2445
2446 /**
2447 * Adds a new MIDI instrument map.
2448 * @param name The name of this MIDI instrument map.
2449 * @return The number of the newly MIDI instrument map.
2450 * @throws IOException If some I/O error occurs.
2451 * @throws LSException If the creation of the new MIDI instrument map failed.
2452 * @throws LscpException If LSCP protocol corruption occurs.
2453 * @see #removeMidiInstrumentMap
2454 */
2455 public synchronized int
2456 addMidiInstrumentMap(String name) throws IOException, LSException, LscpException {
2457 verifyConnection();
2458 out.writeLine("ADD MIDI_INSTRUMENT_MAP '" + name + "'");
2459 if(getPrintOnlyMode()) return -1;
2460
2461 ResultSet rs = getEmptyResultSet();
2462
2463 return rs.getIndex();
2464 }
2465
2466 /**
2467 * Removes the specified MIDI instrument map.
2468 * @param mapId The numerical ID of the MIDI instrument map to be removed.
2469 * @throws IOException If some I/O error occurs.
2470 * @throws LscpException If LSCP protocol corruption occurs.
2471 * @throws LSException If the removing of the MIDI instrument map failed.
2472 * @see #addMidiInstrumentMap
2473 * @see #getMidiInstrumentMapIDs
2474 */
2475 public synchronized void
2476 removeMidiInstrumentMap(int mapId) throws IOException, LscpException, LSException {
2477 verifyConnection();
2478 out.writeLine("REMOVE MIDI_INSTRUMENT_MAP " + mapId);
2479 if(getPrintOnlyMode()) return;
2480
2481 ResultSet rs = getEmptyResultSet();
2482 }
2483
2484 /**
2485 * Removes the all MIDI instrument maps.
2486 * @throws IOException If some I/O error occurs.
2487 * @throws LscpException If LSCP protocol corruption occurs.
2488 * @throws LSException If the removing of the MIDI instrument maps failed.
2489 */
2490 public synchronized void
2491 removeAllMidiInstrumentMaps() throws IOException, LscpException, LSException {
2492 verifyConnection();
2493 out.writeLine("REMOVE MIDI_INSTRUMENT_MAP ALL");
2494 if(getPrintOnlyMode()) return;
2495
2496 ResultSet rs = getEmptyResultSet();
2497 }
2498
2499 /**
2500 * Gets the current number of all MIDI instrument maps.
2501 * @return The current number of all MIDI instrument maps.
2502 * @throws IOException If some I/O error occurs.
2503 * @throws LscpException If LSCP protocol corruption occurs.
2504 * @throws LSException If some other error occurs.
2505 */
2506 public synchronized int
2507 getMidiInstrumentMapCount() throws IOException, LscpException, LSException {
2508 verifyConnection();
2509 out.writeLine("GET MIDI_INSTRUMENT_MAPS");
2510 if(getPrintOnlyMode()) return -1;
2511
2512 String s = getSingleLineResultSet().getResult();
2513 return parseInt(s);
2514 }
2515
2516 /**
2517 * Gets a list of numerical IDs of all created MIDI instrument maps.
2518 * @return An <code>Integer</code> array providing the numerical IDs of
2519 * all created MIDI instrument maps.
2520 * @throws IOException If some I/O error occurs.
2521 * @throws LscpException If LSCP protocol corruption occurs.
2522 * @throws LSException If some other error occurs.
2523 * @see #addMidiInstrumentMap
2524 * @see #removeMidiInstrumentMap
2525 */
2526 public synchronized Integer[]
2527 getMidiInstrumentMapIDs() throws IOException, LscpException, LSException {
2528 verifyConnection();
2529 out.writeLine("LIST MIDI_INSTRUMENT_MAPS");
2530 if(getPrintOnlyMode()) return null;
2531
2532 return parseIntList(getSingleLineResultSet().getResult());
2533 }
2534
2535 /**
2536 * Gets the current settings of a specific, already created MIDI instrument map.
2537 * @param mapId Specifies the numerical ID of the MIDI instrument map.
2538 * @return A <code>MidiInstrumentMapInfo</code> instance containing information
2539 * about the specified device.
2540 * @throws IOException If some I/O error occurs.
2541 * @throws LscpException If LSCP protocol corruption occurs.
2542 * @throws LSException If there is no MIDI instrument map
2543 * with map id <code>mapId</code>.
2544 * @see #getMidiInstrumentMaps
2545 */
2546 public synchronized MidiInstrumentMapInfo
2547 getMidiInstrumentMapInfo(int mapId) throws IOException, LscpException, LSException {
2548 verifyConnection();
2549 out.writeLine("GET MIDI_INSTRUMENT_MAP INFO " + mapId);
2550 if(getPrintOnlyMode()) return null;
2551
2552 ResultSet rs = getMultiLineResultSet();
2553
2554 String[] lnS = rs.getMultiLineResult();
2555
2556 String name = "";
2557 boolean b = false;
2558
2559 for(String s : lnS) {
2560 if(s.startsWith("NAME: ")) {
2561 name = s.substring("NAME: ".length());
2562 } else if(s.startsWith("DEFAULT: ")) {
2563 b = Boolean.parseBoolean(s.substring("DEFAULT: ".length()));
2564 } else {
2565 getLogger().info(LscpI18n.getLogMsg("unknownLine", s));
2566 }
2567 }
2568
2569 return new MidiInstrumentMapInfo(mapId, name, b);
2570 }
2571
2572 /**
2573 * Gets an information of all created MIDI instrument maps.
2574 * @return A <code>MidiInstrumentMap</code> array
2575 * providing information for all created MIDI instrument maps.
2576 * @throws IOException If some I/O error occurs.
2577 * @throws LscpException If LSCP protocol corruption occurs.
2578 * @throws LSException If some other error occurs.
2579 * @see #addMidiInstrumentMap
2580 * @see #removeMidiInstrumentMap
2581 */
2582 public synchronized MidiInstrumentMapInfo[]
2583 getMidiInstrumentMaps() throws IOException, LscpException, LSException {
2584 Integer[] idS = getMidiInstrumentMapIDs();
2585 if(getPrintOnlyMode()) return null;
2586
2587 MidiInstrumentMapInfo[] maps = new MidiInstrumentMapInfo[idS.length];
2588
2589 for(int i = 0; i < maps.length; i++)
2590 maps[i] = getMidiInstrumentMapInfo(idS[i]);
2591
2592 return maps;
2593 }
2594
2595 /**
2596 * Sets the name of the specified MIDI instrument map.
2597 * @param mapId The numerical ID of the MIDI instrument map.
2598 * @param name The new name for the specified MIDI instrument map.
2599 * @throws IOException If some I/O error occurs.
2600 * @throws LscpException If LSCP protocol corruption occurs.
2601 * @throws LSException If <code>mapId</code> is not a valid MIDI
2602 * instrument map number or <code>name</code> is not a valid name;
2603 */
2604 public synchronized void
2605 setMidiInstrumentMapName(int mapId, String name)
2606 throws IOException, LscpException, LSException {
2607
2608 verifyConnection();
2609 out.writeLine("SET MIDI_INSTRUMENT_MAP NAME " + + mapId + " '" + name + "'");
2610 if(getPrintOnlyMode()) return;
2611
2612 ResultSet rs = getEmptyResultSet();
2613 }
2614
2615
2616
2617 /**
2618 * Creates or replaces a MIDI instrument map entry.
2619 * @param mapId The ID of the map, where this instrument should be mapped.
2620 * @param entry Specifies the position of the MIDI instrument in the MIDI instrument map.
2621 * @param info Provides the needed information of the
2622 * MIDI instrument, which will be mapped to the specified MIDI instrument map.
2623 * @throws IOException If some I/O error occurs.
2624 * @throws LSException If the mapping failed.
2625 * @throws LscpException If LSCP protocol corruption occurs.
2626 * @see #unmapMidiInstrument
2627 */
2628 public synchronized void
2629 mapMidiInstrument(int mapId, MidiInstrumentEntry entry, MidiInstrumentInfo info)
2630 throws IOException, LSException, LscpException {
2631 mapMidiInstrument(mapId, entry, info, false);
2632 }
2633
2634 /**
2635 * Creates or replaces a MIDI instrument map entry.
2636 * @param mapId The ID of the map, where this instrument should be mapped.
2637 * @param entry Specifies the position of the MIDI instrument in the MIDI instrument map.
2638 * @param info Provides the needed information of the
2639 * MIDI instrument, which will be mapped to the specified MIDI instrument map.
2640 * @param nonModal If <code>true</code> the function returns immediately
2641 * and the mapping is established in the background.
2642 * @throws IOException If some I/O error occurs.
2643 * @throws LSException If the mapping failed.
2644 * @throws LscpException If LSCP protocol corruption occurs.
2645 * @see #unmapMidiInstrument
2646 */
2647 public synchronized void
2648 mapMidiInstrument(int mapId, MidiInstrumentEntry entry, MidiInstrumentInfo info, boolean nonModal)
2649 throws IOException, LSException, LscpException {
2650
2651 verifyConnection();
2652 StringBuffer cmd = new StringBuffer("MAP MIDI_INSTRUMENT ");
2653 if(nonModal) cmd.append("NON_MODAL ");
2654 cmd.append(mapId).append(' ');
2655 cmd.append(entry.getMidiBank()).append(' ');
2656 cmd.append(entry.getMidiProgram()).append(' ');
2657 cmd.append(info.getEngine()).append(" '");
2658 cmd.append(info.getFilePath()).append("' ");
2659 cmd.append(info.getInstrumentIndex()).append(' ');
2660 cmd.append(info.getVolume());
2661 if(!info.getLoadMode().name().equals("DEFAULT")) {
2662 cmd.append(' ').append(info.getLoadMode().name());
2663 }
2664 if(info.getName() != null) cmd.append(" '").append(info.getName()).append("'");
2665
2666 out.writeLine(cmd.toString());
2667 if(getPrintOnlyMode()) return;
2668
2669 ResultSet rs = getEmptyResultSet();
2670 }
2671
2672 /**
2673 * Removes an entry MIDI instrument map.
2674 * @param mapId The ID of the map, from which
2675 * the specified MIDI instrument should be removed.
2676 * @param entry The entry to remove from the specified MIDI instrument map.
2677 * @throws IOException If some I/O error occurs.
2678 * @throws LSException If the unmapping failed.
2679 * @throws LscpException If LSCP protocol corruption occurs.
2680 * @see #mapMidiInstrument
2681 */
2682 public synchronized void
2683 unmapMidiInstrument(int mapId, MidiInstrumentEntry entry)
2684 throws IOException, LSException, LscpException {
2685
2686 verifyConnection();
2687 StringBuffer cmd = new StringBuffer("UNMAP MIDI_INSTRUMENT ");
2688 cmd.append(mapId).append(' ');
2689 cmd.append(entry.getMidiBank()).append(' ');
2690 cmd.append(entry.getMidiProgram());
2691
2692 out.writeLine(cmd.toString());
2693 if(getPrintOnlyMode()) return;
2694
2695 ResultSet rs = getEmptyResultSet();
2696 }
2697
2698 /**
2699 * Gets the current number of all MIDI instrument in all maps.
2700 * @return The current number of all MIDI instrument in all maps.
2701 * @throws IOException If some I/O error occurs.
2702 * @throws LscpException If LSCP protocol corruption occurs.
2703 * @throws LSException If some other error occurs.
2704 */
2705 public synchronized int
2706 getMidiInstrumentCount() throws IOException, LscpException, LSException {
2707 verifyConnection();
2708 out.writeLine("GET MIDI_INSTRUMENTS ALL");
2709 if(getPrintOnlyMode()) return -1;
2710
2711 String s = getSingleLineResultSet().getResult();
2712 return parseInt(s);
2713 }
2714
2715 /**
2716 * Gets the current number of MIDI instrument in the specified map.
2717 * @param mapId The ID of the map.
2718 * @return The current number of MIDI instrument in the specified map.
2719 * @throws IOException If some I/O error occurs.
2720 * @throws LscpException If LSCP protocol corruption occurs.
2721 * @throws LSException If some other error occurs.
2722 */
2723 public synchronized int
2724 getMidiInstrumentCount(int mapId) throws IOException, LscpException, LSException {
2725 verifyConnection();
2726 out.writeLine("GET MIDI_INSTRUMENTS " + String.valueOf(mapId));
2727 if(getPrintOnlyMode()) return -1;
2728
2729 String s = getSingleLineResultSet().getResult();
2730 return parseInt(s);
2731 }
2732
2733 /**
2734 * Gets all MIDI instrument from all maps.
2735 * @return A <code>MidiInstrumentInfo</code> array providing
2736 * all MIDI instruments from all MIDI instrument maps.
2737 * @throws IOException If some I/O error occurs.
2738 * @throws LscpException If LSCP protocol corruption occurs.
2739 * @throws LSException If some other error occurs.
2740 */
2741 public synchronized MidiInstrumentInfo[]
2742 getMidiInstruments() throws IOException, LscpException, LSException {
2743 verifyConnection();
2744 out.writeLine("LIST MIDI_INSTRUMENTS ALL");
2745 if(getPrintOnlyMode()) return null;
2746
2747 String[] entries = parseArray(getSingleLineResultSet().getResult());
2748
2749 return getMidiInstruments(entries);
2750 }
2751
2752 /**
2753 * Gets all MIDI instrument contained int the specified MIDI instrument map.
2754 * @param mapId The ID of the map, which instruments should be obtained.
2755 * @return A <code>MidiInstrumentInfo</code> array providing
2756 * all MIDI instruments from all MIDI instrument maps.
2757 * @throws IOException If some I/O error occurs.
2758 * @throws LscpException If LSCP protocol corruption occurs.
2759 * @throws LSException If some other error occurs.
2760 */
2761 public synchronized MidiInstrumentInfo[]
2762 getMidiInstruments(int mapId) throws IOException, LscpException, LSException {
2763 verifyConnection();
2764 out.writeLine("LIST MIDI_INSTRUMENTS " + String.valueOf(mapId));
2765 if(getPrintOnlyMode()) return null;
2766
2767 String[] entries = parseArray(getSingleLineResultSet().getResult());
2768
2769 return getMidiInstruments(entries);
2770 }
2771
2772 private MidiInstrumentInfo[]
2773 getMidiInstruments(String[] entries) throws IOException, LscpException, LSException {
2774 Vector<MidiInstrumentInfo> v = new Vector<MidiInstrumentInfo>();
2775
2776 for(String s : entries) {
2777 Integer[] vals = parseIntList(s);
2778 if(vals.length != 3) {
2779 throw new LscpException(LscpI18n.getLogMsg("CommandFailed!"));
2780 }
2781
2782 v.add(getMidiInstrumentInfo(vals[0], vals[1], vals[2]));
2783 }
2784
2785 return v.toArray(new MidiInstrumentInfo[v.size()]);
2786 }
2787
2788 /**
2789 * Gets the current settings of the specified MIDI instrument.
2790 * @param mapId The ID of the map.
2791 * @param bank The index of the MIDI bank.
2792 * @param program The MIDI program number of the instrument.
2793 * @return <code>MidiInstrumentInfo</code> instance containing
2794 * the current settings of the specified MIDI instrument.
2795 * @throws IOException If an I/O error occurs.
2796 * @throws LscpException If LSCP protocol corruption occurs.
2797 * @throws LSException If the specified MIDI instrument is missing.
2798 */
2799 public synchronized MidiInstrumentInfo
2800 getMidiInstrumentInfo(int mapId, int bank, int program)
2801 throws IOException, LscpException, LSException {
2802
2803 verifyConnection();
2804 StringBuffer cmd = new StringBuffer("GET MIDI_INSTRUMENT INFO ");
2805 cmd.append(mapId).append(' ');
2806 cmd.append(bank).append(' ');
2807 cmd.append(program);
2808
2809 out.writeLine(cmd.toString());
2810 if(getPrintOnlyMode()) return null;
2811
2812 ResultSet rs = getMultiLineResultSet();
2813 MidiInstrumentEntry entry = new MidiInstrumentEntry(bank, program);
2814 return new MidiInstrumentInfo(mapId, entry, rs.getMultiLineResult());
2815 }
2816
2817 /**
2818 * Loads and assigns an instrument to a sampler channel. Notice that this function will
2819 * return after the instrument is fully loaded and the channel is ready to be used.
2820 * @param filename The name of the instrument file
2821 * on the LinuxSampler instance's host system.
2822 * @param instrIdx The index of the instrument in the instrument file.
2823 * @param samplerChn The number of the sampler channel the instrument should be assigned to.
2824 * @throws IOException If some I/O error occurs.
2825 * @throws LscpException If LSCP protocol corruption occurs.
2826 * @throws LSException If the loading of the instrument failed.
2827 * @see #loadInstrument(String, int, int, boolean)
2828 * @see #getSamplerChannels
2829 */
2830 public synchronized void
2831 loadInstrument(String filename, int instrIdx, int samplerChn)
2832 throws IOException, LscpException, LSException {
2833
2834 verifyConnection();
2835 loadInstrument(filename, instrIdx, samplerChn, false);
2836 }
2837
2838 /**
2839 * Loads and assigns an instrument to a sampler channel.
2840 *
2841 * @param filename The name of the instrument file
2842 * on the LinuxSampler instance's host system.
2843 * @param instrIdx The index of the instrument in the instrument file.
2844 * @param samplerChn The number of the sampler channel the instrument should be assigned to.
2845 * @param nonModal If <code>false</code> the function will return after the instrument
2846 * has been fully loaded and the channel is ready to be used. If <code>true</code>
2847 * the function returns immediately.
2848 *
2849 * @throws IOException If some I/O error occurs.
2850 * @throws LscpException If LSCP protocol corruption occurs.
2851 * @throws LSException If the loading of the instrument failed.
2852 *
2853 * @see #loadInstrument(String, int, int)
2854 * @see #getSamplerChannels
2855 */
2856 public synchronized void
2857 loadInstrument(String filename, int instrIdx, int samplerChn, boolean nonModal)
2858 throws IOException, LscpException, LSException {
2859
2860 filename = getEscapedString(filename);
2861 String cmd = nonModal ? "LOAD INSTRUMENT NON_MODAL " : "LOAD INSTRUMENT ";
2862 String args = '\'' + filename + "' " + instrIdx + ' ' + samplerChn;
2863
2864 out.writeLine(cmd + args);
2865 if(getPrintOnlyMode()) return;
2866
2867 ResultSet rs = getEmptyResultSet();
2868 }
2869
2870 /**
2871 * Loads a sampler engine to a specific sampler channel.
2872 * @param engineName The name of the engine.
2873 * @param samplerChn The number of the sampler channel
2874 * the deployed engine should be assigned to.
2875 *
2876 * @throws IOException If some I/O error occurs.
2877 * @throws LscpException If LSCP protocol corruption occurs.
2878 * @throws LSException If the loading of the sampler engine failed.
2879 * @see #getEngines
2880 * @see #getSamplerChannels
2881 */
2882 public synchronized void
2883 loadSamplerEngine(String engineName, int samplerChn)
2884 throws IOException, LscpException, LSException {
2885
2886 verifyConnection();
2887 out.writeLine("LOAD ENGINE " + engineName + ' ' + samplerChn);
2888 if(getPrintOnlyMode()) return;
2889
2890 ResultSet rs = getEmptyResultSet();
2891 }
2892
2893 /**
2894 * Gets the current number of all created sampler channels.
2895 * @return The current number of all created sampler channels.
2896 * @throws IOException If some I/O error occurs.
2897 * @throws LscpException If LSCP protocol corruption occurs.
2898 * @throws LSException If some other error occurs.
2899 */
2900 public synchronized int
2901 getSamplerChannelCount() throws IOException, LscpException, LSException {
2902 verifyConnection();
2903 out.writeLine("GET CHANNELS");
2904 if(getPrintOnlyMode()) return -1;
2905
2906 String s = getSingleLineResultSet().getResult();
2907 return parseInt(s);
2908 }
2909
2910 /**
2911 * Gets a list of all created sampler channels.
2912 * @return A <code>SamplerChannel</code> array providing all created sampler channels.
2913 * @throws IOException If some I/O error occurs.
2914 * @throws LscpException If LSCP protocol corruption occurs.
2915 * @throws LSException If some other error occurs.
2916 * @see #addSamplerChannel
2917 * @see #removeSamplerChannel
2918 */
2919 public synchronized SamplerChannel[]
2920 getSamplerChannels() throws IOException, LscpException, LSException {
2921 Integer[] idS = getSamplerChannelIDs();
2922 if(getPrintOnlyMode()) return null;
2923
2924 SamplerChannel[] channels = new SamplerChannel[idS.length];
2925
2926 for(int i = 0; i < channels.length; i++)
2927 channels[i] = getSamplerChannelInfo(idS[i]);
2928
2929 return channels;
2930 }
2931
2932 /**
2933 * Gets a list with numerical IDs of all created sampler channels.
2934 * @return An <code>Integer</code> array providing
2935 * the numerical IDs of all created sampler channels.
2936 * @throws IOException If some I/O error occurs.
2937 * @throws LscpException If LSCP protocol corruption occurs.
2938 * @throws LSException If some other error occurs.
2939 * @see #addSamplerChannel
2940 * @see #removeSamplerChannel
2941 */
2942 public synchronized Integer[]
2943 getSamplerChannelIDs() throws IOException, LscpException, LSException {
2944 verifyConnection();
2945 out.writeLine("LIST CHANNELS");
2946 if(getPrintOnlyMode()) return null;
2947
2948 return parseIntList(getSingleLineResultSet().getResult());
2949 }
2950
2951 /**
2952 * Adds a new sampler channel. This method will increment the sampler channel count by one
2953 * and the new sampler channel will be appended to the end of the sampler channel list.
2954 *
2955 * @return The number of the newly created sampler channel.
2956 * @throws IOException If some I/O error occurs.
2957 * @throws LSException If the creation of the new sampler channel failed.
2958 * @throws LscpException If LSCP protocol corruption occurs.
2959 * @see #removeSamplerChannel
2960 */
2961 public synchronized int
2962 addSamplerChannel() throws IOException, LSException, LscpException {
2963 verifyConnection();
2964 out.writeLine("ADD CHANNEL");
2965 if(getPrintOnlyMode()) return -1;
2966
2967 ResultSet rs = getEmptyResultSet();
2968
2969 return rs.getIndex();
2970 }
2971
2972 /**
2973 * Removes the specified sampler channel.
2974 *
2975 * @param samplerChn The numerical ID of the sampler channel to be removed.
2976 *
2977 * @throws IOException If some I/O error occurs.
2978 * @throws LscpException If LSCP protocol corruption occurs.
2979 * @throws LSException If the removing of the sampler channel failed.
2980 * @see #addSamplerChannel
2981 * @see #getSamplerChannels
2982 */
2983 public synchronized void
2984 removeSamplerChannel(int samplerChn) throws IOException, LscpException, LSException {
2985 verifyConnection();
2986 out.writeLine("REMOVE CHANNEL " + samplerChn);
2987 if(getPrintOnlyMode()) return;
2988
2989 ResultSet rs = getEmptyResultSet();
2990 }
2991
2992 /**
2993 * Gets the number of all available engines.
2994 * @return The number of all available engines.
2995 * @throws IOException If some I/O error occurs.
2996 * @throws LscpException If LSCP protocol corruption occurs.
2997 * @throws LSException If some other error occurs.
2998 */
2999 public synchronized int
3000 getEngineCount() throws IOException, LscpException, LSException {
3001 verifyConnection();
3002 out.writeLine("GET AVAILABLE_ENGINES");
3003 if(getPrintOnlyMode()) return -1;
3004
3005 String s = getSingleLineResultSet().getResult();
3006 return parseInt(s);
3007 }
3008
3009 /**
3010 * Gets a list of all available engines.
3011 *
3012 * @return <code>SamplerEngine</code> array containing all available engines.
3013 * @throws IOException If some I/O error occurs.
3014 * @throws LscpException If LSCP protocol corruption occurs.
3015 * @throws LSException If some other error occurs.
3016 */
3017 public synchronized SamplerEngine[]
3018 getEngines() throws IOException, LscpException, LSException {
3019 String[] engines = getEngineNames();
3020 if(getPrintOnlyMode()) return null;
3021
3022 SamplerEngine[] se = new SamplerEngine[engines.length];
3023
3024 for(int i = 0; i < engines.length; i++) se[i] = getEngineInfo(engines[i]);
3025
3026 return se;
3027 }
3028
3029 /**
3030 * Gets a list of all available engines' names.
3031 *
3032 * @return <code>String</code> array with all available engines' names.
3033 * @throws IOException If some I/O error occurs.
3034 * @throws LscpException If LSCP protocol corruption occurs.
3035 * @throws LSException If some other error occurs.
3036 */
3037 private synchronized String[]
3038 getEngineNames() throws IOException, LscpException, LSException {
3039 verifyConnection();
3040 out.writeLine("LIST AVAILABLE_ENGINES");
3041 if(getPrintOnlyMode()) return null;
3042
3043 return parseQuotedStringList(getSingleLineResultSet().getResult());
3044 }
3045
3046 /**
3047 * Gets information about a specific sampler engine.
3048 * @param engineName The name of the sampler engine.
3049 *
3050 * @return <code>SamplerEngine</code> instance containing
3051 * information about the specified sampler engine.
3052 *
3053 * @throws IOException If an I/O error occurs.
3054 * @throws LscpException If LSCP protocol corruption occurs.
3055 * @throws LSException If there is no sampler engine with name <code>engineName</code>.
3056 * @see #getEngineNames
3057 */
3058 private synchronized SamplerEngine
3059 getEngineInfo(String engineName) throws IOException, LscpException, LSException {
3060 verifyConnection();
3061 out.writeLine("GET ENGINE INFO " + engineName);
3062 if(getPrintOnlyMode()) return null;
3063
3064 ResultSet rs = getMultiLineResultSet();
3065 SamplerEngine se = new SamplerEngine(rs.getMultiLineResult());
3066 se.setName(engineName);
3067 return se;
3068 }
3069
3070 /**
3071 * Gets the current settings of the specified sampler channel.
3072 * @param samplerChn The sampler channel number.
3073 *
3074 * @return <code>SamplerChannel</code> instance containing
3075 * the current settings of the specified sampler channel.
3076 *
3077 * @throws IOException If an I/O error occurs.
3078 * @throws LscpException If LSCP protocol corruption occurs.
3079 * @throws LSException If there is no sampler channel with <code>samplerChn</code> number.
3080 * @see #getSamplerChannels
3081 */
3082 public synchronized SamplerChannel
3083 getSamplerChannelInfo(int samplerChn) throws IOException, LscpException, LSException {
3084 verifyConnection();
3085 out.writeLine("GET CHANNEL INFO " + samplerChn);
3086 if(getPrintOnlyMode()) return null;
3087
3088 ResultSet rs = getMultiLineResultSet();
3089 SamplerChannel sc = new SamplerChannel(rs.getMultiLineResult());
3090 sc.setChannelId(samplerChn);
3091 if(sc.getEngine() != null) sc.setEngine(getEngineInfo(sc.getEngine().getName()));
3092
3093 return sc;
3094 }
3095
3096 /**
3097 * Gets the current number of active voices on the specified sampler channel.
3098 *
3099 * @param samplerChn The sampler channel number.
3100 * @return The current number of active voices on the specified sampler channel.
3101 * @throws IOException If some I/O error occurs.
3102 * @throws LscpException If LSCP protocol corruption occurs.
3103 * @throws LSException If there is no sampler channel with number <code>samplerChn</code>.
3104 * @see #getSamplerChannels
3105 */
3106 public synchronized int
3107 getChannelVoiceCount(int samplerChn) throws IOException, LscpException, LSException {
3108 verifyConnection();
3109 out.writeLine("GET CHANNEL VOICE_COUNT " + samplerChn);
3110 if(getPrintOnlyMode()) return -1;
3111
3112 ResultSet rs = getSingleLineResultSet();
3113
3114 return parseInt(rs.getResult());
3115 }
3116
3117 /**
3118 * Gets the current number of active disk streams on the specified sampler channel.
3119 *
3120 * @param samplerChn The sampler channel number.
3121 * @return The current number of active disk streams on the specified sampler channel
3122 * or -1 if the engine doesn't support disk streaming.
3123 * @throws IOException If some I/O error occurs.
3124 * @throws LscpException If LSCP protocol corruption occurs.
3125 * @throws LSException If there is no sampler channel with number <code>samplerChn</code>.
3126 * @see #getSamplerChannels
3127 */
3128 public synchronized int
3129 getChannelStreamCount(int samplerChn) throws IOException, LscpException, LSException {
3130 verifyConnection();
3131 out.writeLine("GET CHANNEL STREAM_COUNT " + samplerChn);
3132 if(getPrintOnlyMode()) return -1;
3133
3134 ResultSet rs = getSingleLineResultSet();
3135
3136 if(rs.getResult().equals("NA")) return -1;
3137
3138 return parseInt(rs.getResult());
3139 }
3140
3141 /**
3142 * Gets the current fill state of all disk streams on the specified sampler channel
3143 * in bytes.
3144 *
3145 * @param samplerChn The sampler channel number.
3146 * @return The current fill state of all disk streams on the specified sampler channel
3147 * or <code>null</code> if the engine which is deployed doesn't support disk streaming.
3148 * @throws IOException If some I/O error occurs.
3149 * @throws LscpException If LSCP protocol corruption occurs.
3150 * @throws LSException If there is no sampler channel with number <code>samplerChn</code>.
3151 * @see #getChannelBufferFillPercentage
3152 * @see #getSamplerChannels
3153 */
3154 public synchronized Vector<BufferFill>
3155 getChannelBufferFillBytes(int samplerChn) throws IOException, LscpException, LSException {
3156 verifyConnection();
3157 out.writeLine("GET CHANNEL BUFFER_FILL BYTES " + samplerChn);
3158 if(getPrintOnlyMode()) return null;
3159
3160 ResultSet rs = getSingleLineResultSet();
3161
3162 if(rs.getResult().equals("NA")) return null;
3163
3164 Vector<BufferFill> v = new Vector<BufferFill>();
3165 String[] args = parseList(rs.getResult());
3166
3167 for(String s : args) {
3168 if(s.charAt(0) != '[')
3169 throw new LscpException(LscpI18n.getLogMsg("CommandFailed!"));
3170
3171 int i = s.indexOf(']');
3172 if(i == -1) throw new LscpException(LscpI18n.getLogMsg("CommandFailed!"));
3173
3174 BufferFill bf = new BufferFill();
3175 bf.setStreamId(parseInt(s.substring(1, i)));
3176 bf.setValue(parseInt(s.substring(i + 1)));
3177 v.add(bf);
3178 }
3179
3180 return v;
3181 }
3182
3183 /**
3184 * Gets the current fill state of all disk streams on the specified sampler channel
3185 * in percent.
3186 *
3187 * @param samplerChn The sampler channel number.
3188 * @return The current fill state of all disk streams on the specified sampler channel
3189 * or <code>null</code> if the engine which is deployed doesn't support disk streaming.
3190 * @throws IOException If some I/O error occurs.
3191 * @throws LscpException If LSCP protocol corruption occurs.
3192 * @throws LSException If there is no sampler channel with number <code>samplerChn</code>.
3193 * @see #getChannelBufferFillBytes
3194 * @see #getSamplerChannels
3195 */
3196 public synchronized Vector<BufferFill>
3197 getChannelBufferFillPercentage(int samplerChn)
3198 throws IOException, LscpException, LSException {
3199
3200 verifyConnection();
3201 out.writeLine("GET CHANNEL BUFFER_FILL PERCENTAGE " + samplerChn);
3202 if(getPrintOnlyMode()) return null;
3203
3204 ResultSet rs = getSingleLineResultSet();
3205
3206 return getChannelBufferFillPercentage(rs.getResult());
3207 }
3208
3209 private Vector<BufferFill>
3210 getChannelBufferFillPercentage(String ln) throws LscpException {
3211 if(ln.equals("NA")) return null;
3212
3213 Vector<BufferFill> v = new Vector<BufferFill>();
3214 String[] args = parseList(ln);
3215
3216 for(String s : args) {
3217 if(s.charAt(0) != '[')
3218 throw new LscpException(LscpI18n.getLogMsg("CommandFailed!"));
3219
3220 int i = s.indexOf(']');
3221 if(i == -1) throw new LscpException(LscpI18n.getLogMsg("CommandFailed!"));
3222
3223 if(s.charAt(s.length() - 1) != '%')
3224 throw new LscpException(LscpI18n.getLogMsg("CommandFailed!"));
3225
3226 BufferFill bf = new BufferFill();
3227 bf.setStreamId(parseInt(s.substring(1, i)));
3228 bf.setValue(parseInt(s.substring(i + 1, s.length() - 1)));
3229 v.add(bf);
3230 }
3231
3232 return v;
3233 }
3234
3235 /**
3236 * Sets the audio output device on the specified sampler channel.
3237 *
3238 * @param samplerChn The sampler channel number.
3239 * @param devId The numerical ID of the audio output device.
3240 *
3241 * @throws IOException If some I/O error occurs.
3242 * @throws LscpException If LSCP protocol corruption occurs.
3243 * @throws LSException If
3244 * <ul>
3245 * <li><code>samplerChn</code> is not a valid channel number;
3246 * <li><code>devId</code> is not a valid audio output device ID;
3247 * </ul>
3248 *
3249 * @see #getSamplerChannels
3250 * @see #getAudioOutputDevices
3251 */
3252 public synchronized void
3253 setChannelAudioOutputDevice(int samplerChn, int devId)
3254 throws IOException, LscpException, LSException {
3255
3256 verifyConnection();
3257 out.writeLine("SET CHANNEL AUDIO_OUTPUT_DEVICE " + samplerChn + ' ' + devId);
3258 if(getPrintOnlyMode()) return;
3259
3260 ResultSet rs = getEmptyResultSet();
3261 }
3262
3263 /**
3264 * Sets the audio output channel on the specified sampler channel.
3265 *
3266 * @param samplerChn The sampler channel number.
3267 * @param audioOut The sampler channel's audio output channel which should be rerouted.
3268 * @param audioIn The audio channel of the selected audio output device
3269 * where <code>audioOut</code> should be routed to.
3270 *
3271 * @throws IOException If some I/O error occurs.
3272 * @throws LscpException If LSCP protocol corruption occurs.
3273 * @throws LSException If
3274 * <ul>
3275 * <li><code>samplerChn</code> is not a valid channel number;
3276 * <li>There is no engine assigned yet to the specified sampler channel.
3277 * <li> There is no audio output device connected to the specified sampler channel.
3278 * </ul>
3279 *
3280 * @see #getSamplerChannels
3281 */
3282 public synchronized void
3283 setChannelAudioOutputChannel(int samplerChn, int audioOut, int audioIn)
3284 throws IOException, LscpException, LSException {
3285
3286 verifyConnection();
3287 String args = " " + samplerChn + ' ' + audioOut + ' ' + audioIn;
3288 out.writeLine("SET CHANNEL AUDIO_OUTPUT_CHANNEL" + args);
3289 if(getPrintOnlyMode()) return;
3290
3291 ResultSet rs = getEmptyResultSet();
3292 }
3293
3294 /**
3295 * Sets the MIDI input device on the specified sampler channel.
3296 *
3297 * @param samplerChn The sampler channel number.
3298 * @param devId The numerical ID of the MIDI input device.
3299 *
3300 * @throws IOException If some I/O error occurs.
3301 * @throws LscpException If LSCP protocol corruption occurs.
3302 * @throws LSException If
3303 * <ul>
3304 * <li><code>samplerChn</code> is not a valid channel number;
3305 * <li><code>devId</code> is not a valid MIDI input device ID;
3306 * </ul>
3307 *
3308 * @see #getSamplerChannels
3309 * @see #getMidiInputDevices
3310 */
3311 public synchronized void
3312 setChannelMidiInputDevice(int samplerChn, int devId)
3313 throws IOException, LscpException, LSException {
3314
3315 verifyConnection();
3316 out.writeLine("SET CHANNEL MIDI_INPUT_DEVICE " + samplerChn + ' ' + devId);
3317 if(getPrintOnlyMode()) return;
3318
3319 ResultSet rs = getEmptyResultSet();
3320 }
3321
3322 /**
3323 * Sets the MIDI input port on the specified sampler channel.
3324 *
3325 * @param samplerChn The sampler channel number.
3326 * @param port The MIDI input port number of
3327 * the MIDI input device connected to the specified sampler channel.
3328 *
3329 * @throws IOException If some I/O error occurs.
3330 * @throws LscpException If LSCP protocol corruption occurs.
3331 * @throws LSException If <code>samplerChn</code> is not a valid channel number.
3332 * @see #getSamplerChannels
3333 */
3334 public synchronized void
3335 setChannelMidiInputPort(int samplerChn, int port)
3336 throws IOException, LscpException, LSException {
3337
3338 verifyConnection();
3339 out.writeLine("SET CHANNEL MIDI_INPUT_PORT " + samplerChn + ' ' + port);
3340 if(getPrintOnlyMode()) return;
3341
3342 ResultSet rs = getEmptyResultSet();
3343 }
3344
3345 /**
3346 * Sets the MIDI input channel the specified sampler channel should listen to.
3347 *
3348 * @param samplerChn The sampler channel number.
3349 * @param midiChn The number of the new MIDI input channel where
3350 * <code>samplerChn</code> should listen to or -1 to listen on all 16 MIDI channels.
3351 *
3352 * @throws IOException If some I/O error occurs.
3353 * @throws LscpException If LSCP protocol corruption occurs.
3354 * @throws LSException If <code>samplerChn</code> is not a valid channel number.
3355 * @see #getSamplerChannels
3356 */
3357 public synchronized void
3358 setChannelMidiInputChannel(int samplerChn, int midiChn)
3359 throws IOException, LscpException, LSException {
3360
3361 verifyConnection();
3362 String args = String.valueOf(samplerChn) + ' ';
3363 args += (midiChn == -1 ? "ALL" : String.valueOf(midiChn));
3364 out.writeLine("SET CHANNEL MIDI_INPUT_CHANNEL " + args);
3365 if(getPrintOnlyMode()) return;
3366
3367 ResultSet rs = getEmptyResultSet();
3368 }
3369
3370 /**
3371 * Sets the MIDI instrument map to be used on the specified sampler channel.
3372 *
3373 * @param samplerChn The sampler channel number.
3374 * @param mapId Specifies the numerical ID of the MIDI instrument
3375 * map to assign. To remove the current map binding use <code>-1</code>.
3376 * To set the current map to be the default map use <code>-2</code>.
3377 *
3378 * @throws IOException If some I/O error occurs.
3379 * @throws LscpException If LSCP protocol corruption occurs.
3380 * @throws LSException If
3381 * <ul>
3382 * <li><code>samplerChn</code> is not a valid channel number;
3383 * <li><code>mapId</code> is not a valid MIDI instrument map ID;
3384 * </ul>
3385 *
3386 * @see #getSamplerChannels
3387 * @see #getMidiInstrumentMaps
3388 */
3389 public synchronized void
3390 setChannelMidiInstrumentMap(int samplerChn, int mapId)
3391 throws IOException, LscpException, LSException {
3392
3393 verifyConnection();
3394 String s;
3395 if(mapId == -1) {
3396 s = " NONE";
3397 } else if(mapId == -2) {
3398 s = " DEFAULT";
3399 } else {
3400 s = " " + String.valueOf(mapId);
3401 }
3402 out.writeLine("SET CHANNEL MIDI_INSTRUMENT_MAP " + samplerChn + s);
3403 if(getPrintOnlyMode()) return;
3404
3405 ResultSet rs = getEmptyResultSet();
3406 }
3407
3408 /**
3409 * Sets the volume of the specified sampler channel.
3410 *
3411 * @param samplerChn The sampler channel number.
3412 * @param volume The new volume value.
3413 *
3414 * @throws IOException If some I/O error occurs.
3415 * @throws LscpException If LSCP protocol corruption occurs.
3416 * @throws LSException If <code>samplerChn</code> is not a valid channel number or if
3417 * there is no engine assigned yet to the specified sampler channel.
3418 * @see #getSamplerChannels
3419 */
3420 public synchronized void
3421 setChannelVolume(int samplerChn, float volume)
3422 throws IOException, LscpException, LSException {
3423
3424 verifyConnection();
3425 out.writeLine("SET CHANNEL VOLUME " + samplerChn + ' ' + volume);
3426 if(getPrintOnlyMode()) return;
3427
3428 ResultSet rs = getEmptyResultSet();
3429 }
3430
3431 /**
3432 * Mute/unmute the specified sampler channel.
3433 *
3434 * @param samplerChn The sampler channel number.
3435 * @param mute If <code>true</code> the specified channel is muted, else the channel
3436 * is unmuted.
3437 *
3438 * @throws IOException If some I/O error occurs.
3439 * @throws LscpException If LSCP protocol corruption occurs.
3440 * @throws LSException If <code>samplerChn</code> is not a valid channel number or if
3441 * there is no engine assigned yet to the specified sampler channel.
3442 * @see #getSamplerChannels
3443 */
3444 public synchronized void
3445 setChannelMute(int samplerChn, boolean mute)
3446 throws IOException, LscpException, LSException {
3447
3448 verifyConnection();
3449 out.writeLine("SET CHANNEL MUTE " + samplerChn + ' ' + (mute ? 1 : 0));
3450 if(getPrintOnlyMode()) return;
3451
3452 ResultSet rs = getEmptyResultSet();
3453 }
3454
3455 /**
3456 * Solo/unsolo the specified sampler channel.
3457 *
3458 * @param samplerChn The sampler channel number.
3459 * @param solo <code>true</code> to solo the specified channel, <code>false</code>
3460 * otherwise.
3461 *
3462 * @throws IOException If some I/O error occurs.
3463 * @throws LscpException If LSCP protocol corruption occurs.
3464 * @throws LSException If <code>samplerChn</code> is not a valid channel number or if
3465 * there is no engine assigned yet to the specified sampler channel.
3466 * @see #getSamplerChannels
3467 */
3468 public synchronized void
3469 setChannelSolo(int samplerChn, boolean solo)
3470 throws IOException, LscpException, LSException {
3471
3472 verifyConnection();
3473 out.writeLine("SET CHANNEL SOLO " + samplerChn + ' ' + (solo ? 1 : 0));
3474 if(getPrintOnlyMode()) return;
3475
3476 ResultSet rs = getEmptyResultSet();
3477 }
3478
3479 /**
3480 * Creates an additional effect send on the specified sampler channel.
3481 * @param channel The sampler channel, on which a new effect send should be added.
3482 * @param midiCtrl Defines the MIDI controller, which
3483 * will be able alter the effect send level.
3484 * @return The unique ID of the newly created effect send entity.
3485 * @throws IOException If some I/O error occurs.
3486 * @throws LSException If the creation of the effect send failed.
3487 * @throws LscpException If LSCP protocol corruption occurs.
3488 * @see #destroyFxSend
3489 */
3490 public synchronized int
3491 createFxSend(int channel, int midiCtrl)
3492 throws IOException, LSException, LscpException {
3493
3494 return createFxSend(channel, midiCtrl, null);
3495 }
3496
3497 /**
3498 * Creates an additional effect send on the specified sampler channel.
3499 * @param channel The sampler channel, on which the effect send should be created on.
3500 * @param midiCtrl Defines the MIDI controller, which can alter the effect send level.
3501 * @param name The name of the effect send entity. The name does not have to be unique.
3502 * @return The unique ID of the newly created effect send entity.
3503 * @throws IOException If some I/O error occurs.
3504 * @throws LSException If the creation of the effect send failed.
3505 * @throws LscpException If LSCP protocol corruption occurs.
3506 * @see #destroyFxSend
3507 */
3508 public synchronized int
3509 createFxSend(int channel, int midiCtrl, String name)
3510 throws IOException, LSException, LscpException {
3511
3512 verifyConnection();
3513 String s = String.valueOf(channel) + " " + String.valueOf(midiCtrl);
3514 if(name != null) s += " '" + name + "'";
3515 out.writeLine("CREATE FX_SEND " + s);
3516 if(getPrintOnlyMode()) return -1;
3517
3518 ResultSet rs = getEmptyResultSet();
3519
3520 return rs.getIndex();
3521 }
3522
3523 /**
3524 * Destroys the specified effect send on the specified sampler channel.
3525 * @param channel The sampler channel, from which
3526 * the specified effect send should be removed.
3527 * @param fxSend The ID of the effect send that should be removed.
3528 * @throws LSException If some other error occurs.
3529 * @throws LscpException If LSCP protocol corruption occurs.
3530 * @see #createFxSend
3531 */
3532 public synchronized void
3533 destroyFxSend(int channel, int fxSend)
3534 throws IOException, LSException, LscpException {
3535
3536 verifyConnection();
3537 String s = String.valueOf(channel) + " " + String.valueOf(fxSend);
3538 out.writeLine("DESTROY FX_SEND " + s);
3539 if(getPrintOnlyMode()) return;
3540
3541 ResultSet rs = getEmptyResultSet();
3542 }
3543
3544 /**
3545 * Gets the current number of effect sends on the specified sampler channel.
3546 * @param channel The ID of the sampler channel.
3547 * @return The current number of effect sends on the specified sampler channels.
3548 * @throws IOException If some I/O error occurs.
3549 * @throws LscpException If LSCP protocol corruption occurs.
3550 * @throws LSException If some other error occurs.
3551 */
3552 public synchronized int
3553 getFxSoundCount(int channel) throws IOException, LscpException, LSException {
3554 verifyConnection();
3555 out.writeLine("GET FX_SENDS " + String.valueOf(channel));
3556 if(getPrintOnlyMode()) return -1;
3557
3558 String s = getSingleLineResultSet().getResult();
3559 return parseInt(s);
3560 }
3561
3562 /**
3563 * Gets a list of all created effect sends on the specified sampler channel.
3564 * @param channel The sampler channel number.
3565 * @return A <code>FxSend</code> array providing all created
3566 * effect sends on the specified sampler channel.
3567 * @throws IOException If some I/O error occurs.
3568 * @throws LscpException If LSCP protocol corruption occurs.
3569 * @throws LSException If <code>channel</code> is not a valid sampler channel ID.
3570 * @see #createFxSend
3571 * @see #destroyFxSend
3572 */
3573 public synchronized FxSend[]
3574 getFxSends(int channel) throws IOException, LscpException, LSException {
3575 Integer[] idS = getFxSendIDs(channel);
3576 if(getPrintOnlyMode()) return null;
3577
3578 FxSend[] fxSends = new FxSend[idS.length];
3579
3580 for(int i = 0; i < fxSends.length; i++)
3581 fxSends[i] = getFxSendInfo(channel, idS[i]);
3582
3583 return fxSends;
3584 }
3585
3586 /**
3587 * Gets a list of effect sends on the specified sampler channel.
3588 * @param channel The sampler channel number.
3589 * @return An <code>Integer</code> array providing
3590 * the numerical IDs of all effect sends on the specified sampler channel.
3591 * @throws IOException If some I/O error occurs.
3592 * @throws LscpException If LSCP protocol corruption occurs.
3593 * @throws LSException If <code>channel</code> is not a valid sampler channel ID.
3594 * @see #createFxSend
3595 * @see #destroyFxSend
3596 */
3597 public synchronized Integer[]
3598 getFxSendIDs(int channel) throws IOException, LscpException, LSException {
3599 verifyConnection();
3600 out.writeLine("LIST FX_SENDS " + channel);
3601 if(getPrintOnlyMode()) return null;
3602
3603 return parseIntList(getSingleLineResultSet().getResult());
3604 }
3605
3606 /**
3607 * Gets the current settings of the specified effect send entity.
3608 * @param channel The sampler channel number.
3609 * @param fxSend The numerical ID of the effect send entity.
3610 * @return <code>FxSend</code> instance containing
3611 * the current settings of the specified effect send entity.
3612 * @throws IOException If an I/O error occurs.
3613 * @throws LscpException If LSCP protocol corruption occurs.
3614 * @throws LSException If the sampler channel and/or the effect send number are invalid.
3615 */
3616 public synchronized FxSend
3617 getFxSendInfo(int channel, int fxSend) throws IOException, LscpException, LSException {
3618 verifyConnection();
3619 String s = String.valueOf(channel) + " " + String.valueOf(fxSend);
3620 out.writeLine("GET FX_SEND INFO " + s);
3621 if(getPrintOnlyMode()) return null;
3622
3623 ResultSet rs = getMultiLineResultSet();
3624 FxSend fxs = new FxSend(rs.getMultiLineResult());
3625 fxs.setFxSendId(fxSend);
3626
3627 return fxs;
3628 }
3629
3630 /**
3631 * Sets the name of the specified effect send.
3632 * @param channel The sampler channel number.
3633 * @param fxSend The numerical ID of the effect send entity.
3634 * @param name The new name for the specified effect send.
3635 * @throws IOException If some I/O error occurs.
3636 * @throws LscpException If LSCP protocol corruption occurs.
3637 * @throws LSException If <code>channel</code> is not a valid channel
3638 * number or <code>fxSend</code> is not a valid effect send ID;
3639 */
3640 public synchronized void
3641 setFxSendName(int channel, int fxSend, String name)
3642 throws IOException, LscpException, LSException {
3643
3644 verifyConnection();
3645 String args = " " + channel + " " + fxSend + " '" + name + "'";
3646 out.writeLine("SET FX_SEND NAME" + args);
3647 if(getPrintOnlyMode()) return;
3648
3649 ResultSet rs = getEmptyResultSet();
3650 }
3651
3652 /**
3653 * Sets the destination of an effect send's audio channel in the specified sampler channel.
3654 * @param channel The sampler channel number.
3655 * @param fxSend The numerical ID of the effect send entity to be rerouted.
3656 * @param audioSrc The numerical ID of the effect send's audio output channel,
3657 * which should be rerouted.
3658 * @param audioDst The audio channel of the selected audio output device
3659 * where <code>audioSrc</code> should be routed to.
3660 * @throws IOException If some I/O error occurs.
3661 * @throws LscpException If LSCP protocol corruption occurs.
3662 * @throws LSException If
3663 * <ul>
3664 * <li><code>channel</code> is not a valid channel number;
3665 * <li><code>fxSend</code> is not a valid effect send ID;
3666 * <li>There is no engine assigned yet to the specified sampler channel;
3667 * <li>There is no audio output device connected to the specified sampler channel.
3668 * </ul>
3669 */
3670 public synchronized void
3671 setFxSendAudioOutputChannel(int channel, int fxSend, int audioSrc, int audioDst)
3672 throws IOException, LscpException, LSException {
3673
3674 verifyConnection();
3675 String args = " " + channel + " " + fxSend + " " + audioSrc + " " + audioDst;
3676 out.writeLine("SET FX_SEND AUDIO_OUTPUT_CHANNEL" + args);
3677 if(getPrintOnlyMode()) return;
3678
3679 ResultSet rs = getEmptyResultSet();
3680 }
3681
3682 /**
3683 * Sets the MIDI controller, which will be able to modify
3684 * the send level of the specified effect send in the specified sampler channel.
3685 * @param channel The sampler channel number.
3686 * @param fxSend The numerical ID of the effect send entity.
3687 * @param midiCtrl The MIDI controller which shall be
3688 * able to modify the effect send's send level.
3689 * @throws IOException If some I/O error occurs.
3690 * @throws LscpException If LSCP protocol corruption occurs.
3691 * @throws LSException If
3692 * <ul>
3693 * <li><code>channel</code> is not a valid channel number;
3694 * <li><code>fxSend</code> is not a valid effect send ID;
3695 * <li><code>midiCtrl</code> is not a valid controller;
3696 * </ul>
3697 */
3698 public synchronized void
3699 setFxSendMidiController(int channel, int fxSend, int midiCtrl)
3700 throws IOException, LscpException, LSException {
3701
3702 verifyConnection();
3703 String args = " " + channel + " " + fxSend + " " + midiCtrl;
3704 out.writeLine("SET FX_SEND MIDI_CONTROLLER" + args);
3705 if(getPrintOnlyMode()) return;
3706
3707 ResultSet rs = getEmptyResultSet();
3708 }
3709
3710 /**
3711 * Sets the current send level of the specified
3712 * effect send entity in the specified sampler channel.
3713 * @param channel The sampler channel number.
3714 * @param fxSend The numerical ID of the effect send entity.
3715 * @param volume The new volume value (a value smaller than 1.0 means
3716 * attenuation, whereas a value greater than 1.0 means amplification).
3717 * @throws IOException If some I/O error occurs.
3718 * @throws LscpException If LSCP protocol corruption occurs.
3719 * @throws LSException If some other error occurs.
3720 */
3721 public synchronized void
3722 setFxSendLevel(int channel, int fxSend, float volume)
3723 throws IOException, LscpException, LSException {
3724
3725 verifyConnection();
3726 String args = " " + channel + " " + fxSend + " " + String.valueOf(volume);
3727 out.writeLine("SET FX_SEND LEVEL" + args);
3728 if(getPrintOnlyMode()) return;
3729
3730 ResultSet rs = getEmptyResultSet();
3731 }
3732
3733 /**
3734 * Starts an instrument editor for editing the loaded instrument
3735 * on the specified sampler channel.
3736 * @param samplerChn The sampler channel number.
3737 * @throws IOException If some I/O error occurs.
3738 * @throws LscpException If LSCP protocol corruption occurs.
3739 * @throws LSException If <code>samplerChn</code> is not a valid channel number or if
3740 * there is no instrument loaded on the specified sampler channel.
3741 * @see #getSamplerChannels
3742 */
3743 public synchronized void
3744 editInstrument(int samplerChn) throws IOException, LscpException, LSException {
3745 verifyConnection();
3746 out.writeLine("EDIT INSTRUMENT " + samplerChn);
3747 if(getPrintOnlyMode()) return;
3748
3749 ResultSet rs = getEmptyResultSet();
3750 }
3751
3752
3753
3754 /**
3755 * Adds the specified directory to the instruments database.
3756 * @param dir The absolute path name of the directory to add.
3757 * @throws IOException If some I/O error occurs.
3758 * @throws LSException If the creation of the directory failed.
3759 * @throws LscpException If LSCP protocol corruption occurs.
3760 */
3761 public synchronized void
3762 addDbDirectory(String dir) throws IOException, LSException, LscpException {
3763 verifyConnection();
3764 out.writeLine("ADD DB_INSTRUMENT_DIRECTORY '" + dir + "'");
3765 if(getPrintOnlyMode()) return;
3766
3767 ResultSet rs = getEmptyResultSet();
3768 }
3769
3770 /**
3771 * Removes the specified directory from the instruments database.
3772 * @param dir The absolute path name of the directory to remove.
3773 * @throws IOException If some I/O error occurs.
3774 * @throws LscpException If LSCP protocol corruption occurs.
3775 * @throws LSException If the specified directory is not
3776 * empty or if the removal of the directory failed.
3777 */
3778 public synchronized void
3779 removeDbDirectory(String dir) throws IOException, LscpException, LSException {
3780 removeDbDirectory(dir, false);
3781 }
3782
3783 /**
3784 * Removes the specified directory from the instruments database.
3785 * @param dir The absolute path name of the directory to remove.
3786 * @param force If <code>true</code> forces the removal of non-empty
3787 * directory and all its content.
3788 * @throws IOException If some I/O error occurs.
3789 * @throws LscpException If LSCP protocol corruption occurs.
3790 * @throws LSException If the removing of the directory failed.
3791 */
3792 public synchronized void
3793 removeDbDirectory(String dir, boolean force)
3794 throws IOException, LscpException, LSException {
3795
3796 verifyConnection();
3797 String s = "REMOVE DB_INSTRUMENT_DIRECTORY ";
3798 if(force) s += "FORCE ";
3799 out.writeLine(s + "'" + dir + "'");
3800 if(getPrintOnlyMode()) return;
3801
3802 ResultSet rs = getEmptyResultSet();
3803 }
3804
3805 /**
3806 * Removes the specified directories from the instruments database.
3807 * @param dirs The absolute path names of the directories to remove.
3808 * @param force If <code>true</code> forces the removal of non-empty
3809 * directories.
3810 * @throws IOException If some I/O error occurs.
3811 * @throws LscpException If LSCP protocol corruption occurs.
3812 * @throws LSException If the removing of the directores failed.
3813 */
3814 public synchronized void
3815 removeDbDirectories(String[] dirs, boolean force)
3816 throws IOException, LscpException, LSException {
3817
3818 verifyConnection();
3819 String cmd = "REMOVE DB_INSTRUMENT_DIRECTORY ";
3820 if(force) cmd += "FORCE ";
3821
3822 for(String s : dirs) out.writeLine(cmd + "'" + s + "'");
3823
3824 if(getPrintOnlyMode()) return;
3825
3826 getEmptyResultSets(dirs.length, "Client.dirDeletionFailed!");
3827 }
3828
3829 /**
3830 * Gets the number of directories in the specified directory.
3831 * @return The current number of directories in the specified directory.
3832 * @param dir The absolute path name of the directory.
3833 * @throws IOException If some I/O error occurs.
3834 * @throws LscpException If LSCP protocol corruption occurs.
3835 * @throws LSException If some other error occurs.
3836 */
3837 public synchronized int
3838 getDbDirectoryCount(String dir) throws IOException, LscpException, LSException {
3839 return getDbDirectoryCount(dir, false);
3840 }
3841
3842 /**
3843 * Gets the number of directories in the specified directory.
3844 * @return The current number of directories in the specified directory.
3845 * @param dir The absolute path name of the directory.
3846 * @param recursive If <code>true</code>, the number of all directories
3847 * in the specified subtree will be returned.
3848 * @throws IOException If some I/O error occurs.
3849 * @throws LscpException If LSCP protocol corruption occurs.
3850 * @throws LSException If some other error occurs.
3851 */
3852 public synchronized int
3853 getDbDirectoryCount(String dir, boolean recursive)
3854 throws IOException, LscpException, LSException {
3855
3856 verifyConnection();
3857 String s;
3858 if(recursive) s = "GET DB_INSTRUMENT_DIRECTORIES RECURSIVE '";
3859 else s = "GET DB_INSTRUMENT_DIRECTORIES '";
3860 out.writeLine(s + dir + "'");
3861 if(getPrintOnlyMode()) return -1;
3862
3863 s = getSingleLineResultSet().getResult();
3864 return parseInt(s);
3865 }
3866
3867 /**
3868 * Gets the list of directories in the specified directory.
3869 * @param dir The absolute path name of the directory.
3870 * @return A <code>String</code> array providing the names of
3871 * all directories in the specified directory.
3872 * @throws IOException If some I/O error occurs.
3873 * @throws LscpException If LSCP protocol corruption occurs.
3874 * @throws LSException If the specified path name is invalid.
3875 */
3876 public synchronized String[]
3877 getDbDirectoryNames(String dir) throws IOException, LscpException, LSException {
3878 verifyConnection();
3879 out.writeLine("LIST DB_INSTRUMENT_DIRECTORIES '" + dir + "'");
3880 if(getPrintOnlyMode()) return null;
3881
3882 return parseQuotedStringList(getSingleLineResultSet().getResult());
3883 }
3884
3885 /**
3886 * Gets information about the specified directory.
3887 * @param dir The absolute path name of the directory.
3888 * @return A <code>DbDirectoryInfo</code> instance providing information
3889 * about the specified directory.
3890 * @throws IOException If some I/O error occurs.
3891 * @throws LscpException If LSCP protocol corruption occurs.
3892 * @throws LSException If the specified directory is not found.
3893 */
3894 public synchronized DbDirectoryInfo
3895 getDbDirectoryInfo(String dir) throws IOException, LscpException, LSException {
3896 verifyConnection();
3897 out.writeLine("GET DB_INSTRUMENT_DIRECTORY INFO '" + dir + "'");
3898 if(getPrintOnlyMode()) return null;
3899
3900 ResultSet rs = getMultiLineResultSet();
3901 DbDirectoryInfo info = new DbDirectoryInfo(rs.getMultiLineResult());
3902 if(dir.equals("/")) {
3903 info.setName("/");
3904 } else if(dir.length() > 1 && dir.charAt(dir.length() - 1) == '/') {
3905 dir = dir.substring(0, dir.length() - 1);
3906 }
3907 int i = dir.lastIndexOf('/');
3908 if(i != -1 && i < dir.length() - 1) {
3909 info.setName(dir.substring(i + 1));
3910 if(i == 0) info.setParentDirectoryPath("/");
3911 else info.setParentDirectoryPath(dir.substring(0, i));
3912 }
3913
3914 return info;
3915 }
3916
3917 /**
3918 * Gets the list of directories in the specified directory.
3919 * @param dir The absolute path name of the directory.
3920 * @return A <code>DbDirectoryInfo</code> array providing
3921 * information about all directories in the specified directory.
3922 * @throws IOException If some I/O error occurs.
3923 * @throws LscpException If LSCP protocol corruption occurs.
3924 * @throws LSException If the specified path name is invalid.
3925 */
3926 public synchronized DbDirectoryInfo[]
3927 getDbDirectories(String dir) throws IOException, LscpException, LSException {
3928 String[] dirS = getDbDirectoryNames(dir);
3929 if(dir.charAt(dir.length() - 1) != '/') dir += "/";
3930 DbDirectoryInfo[] infoS = new DbDirectoryInfo[dirS.length];
3931 for(int i = 0; i < dirS.length; i++) infoS[i] = getDbDirectoryInfo(dir + dirS[i]);
3932 return infoS;
3933 }
3934
3935 /**
3936 * Gets the list of directories in the specified directory.
3937 * @param dir The absolute path name of the directory.
3938 * @return A <code>DbDirectoryInfo</code> array providing
3939 * information about all directories in the specified directory.
3940 * @throws IOException If some I/O error occurs.
3941 * @throws LscpException If LSCP protocol corruption occurs.
3942 * @throws LSException If the specified path name is invalid.
3943 *
3944 public synchronized DbDirectoryInfo[]
3945 getDbDirectories(String dir) throws IOException, LscpException, LSException {
3946 String[] dirS = getDbDirectoryNames(dir);
3947 if(dirS.length == 0) return new DbDirectoryInfo[0];
3948
3949 if(dir.charAt(dir.length() - 1) != '/') dir += "/";
3950
3951 for(int i = 0; i < dirS.length; i++) {
3952 out.writeLine("GET DB_INSTRUMENT_DIRECTORY INFO '" + dir + dirS[i] + "'");
3953 }
3954
3955 if(getPrintOnlyMode()) return null;
3956
3957 if(dir.length() > 1) dir = dir.substring(0, dir.length() - 1);
3958 StringBuffer sb = new StringBuffer();
3959 DbDirectoryInfo[] infoS = new DbDirectoryInfo[dirS.length];
3960 for(int i = 0; i < dirS.length; i++) {
3961 try {
3962 ResultSet rs = getMultiLineResultSet();
3963 infoS[i] = new DbDirectoryInfo(rs.getMultiLineResult());
3964 infoS[i].setName(dirS[i]);
3965 infoS[i].setParentDirectoryPath(dir);
3966 } catch (SocketTimeoutException e) {
3967 getLogger().log(Level.FINE, e.getMessage(), e);
3968 sb.append(e.getMessage()).append("\n");
3969 break;
3970 } catch (Exception e) {
3971 getLogger().log(Level.FINE, e.getMessage(), e);
3972 sb.append(e.getMessage()).append("\n");
3973 }
3974 }
3975
3976 String details = sb.toString();
3977 if(details.length() > 0) {
3978 String err = LscpI18n.getLogMsg("Client.getInstrsInfoFailed!");
3979 throw new LSException(0, err, details);
3980 }
3981
3982 return infoS;
3983 }*/
3984
3985 /**
3986 * Renames the specified directory.
3987 * @param dir The absolute path name of the directory to rename.
3988 * @param name The new name for the directory.
3989 * @throws IOException If some I/O error occurs.
3990 * @throws LSException If the renaming of the directory failed.
3991 * @throws LscpException If LSCP protocol corruption occurs.
3992 */
3993 public synchronized void
3994 renameDbDirectory(String dir, String name) throws IOException, LSException, LscpException {
3995 verifyConnection();
3996 out.writeLine("SET DB_INSTRUMENT_DIRECTORY NAME '" + dir + "' '" + name + "'");
3997 if(getPrintOnlyMode()) return;
3998
3999 ResultSet rs = getEmptyResultSet();
4000 }
4001
4002 /**
4003 * Moves the specified directory into the specified location.
4004 * @param dir The absolute path name of the directory to move.
4005 * @param dst The location where the directory will be moved to.
4006 * @throws IOException If some I/O error occurs.
4007 * @throws LSException If the operation failed.
4008 * @throws LscpException If LSCP protocol corruption occurs.
4009 */
4010 public synchronized void
4011 moveDbDirectory(String dir, String dst) throws IOException, LSException, LscpException {
4012 verifyConnection();
4013 out.writeLine("MOVE DB_INSTRUMENT_DIRECTORY '" + dir + "' '" + dst + "'");
4014 if(getPrintOnlyMode()) return;
4015
4016 ResultSet rs = getEmptyResultSet();
4017 }
4018
4019 /**
4020 * Moves the specified directories into the specified location.
4021 * @param dirs The absolute path names of the directories to move.
4022 * @param dst The location where the directories will be moved to.
4023 * @throws IOException If some I/O error occurs.
4024 * @throws LSException If the operation failed.
4025 * @throws LscpException If LSCP protocol corruption occurs.
4026 */
4027 public synchronized void
4028 moveDbDirectories(String dirs[], String dst) throws IOException, LSException, LscpException {
4029 verifyConnection();
4030 for(String s : dirs) {
4031 out.writeLine("MOVE DB_INSTRUMENT_DIRECTORY '" + s + "' '" + dst + "'");
4032 }
4033 if(getPrintOnlyMode()) return;
4034
4035 getEmptyResultSets(dirs.length, "Client.dirMovingFailed!");
4036 }
4037
4038 /**
4039 * Copies the specified directory into the specified location.
4040 * @param dir The absolute path name of the directory to copy.
4041 * @param dst The location where the directory will be copied to.
4042 * @throws IOException If some I/O error occurs.
4043 * @throws LSException If the operation failed.
4044 * @throws LscpException If LSCP protocol corruption occurs.
4045 */
4046 public synchronized void
4047 copyDbDirectory(String dir, String dst) throws IOException, LSException, LscpException {
4048 verifyConnection();
4049 out.writeLine("COPY DB_INSTRUMENT_DIRECTORY '" + dir + "' '" + dst + "'");
4050 if(getPrintOnlyMode()) return;
4051
4052 ResultSet rs = getEmptyResultSet();
4053 }
4054
4055 /**
4056 * Copies the specified directories into the specified location.
4057 * @param dirs The absolute path names of the directories to copy.
4058 * @param dst The location where the directories will be copied to.
4059 * @throws IOException If some I/O error occurs.
4060 * @throws LSException If the operation failed.
4061 * @throws LscpException If LSCP protocol corruption occurs.
4062 */
4063 public synchronized void
4064 copyDbDirectories(String[] dirs, String dst) throws IOException, LSException, LscpException {
4065 verifyConnection();
4066 for(String s : dirs) {
4067 out.writeLine("COPY DB_INSTRUMENT_DIRECTORY '" + s + "' '" + dst + "'");
4068 }
4069 if(getPrintOnlyMode()) return;
4070
4071 getEmptyResultSets(dirs.length, "Client.dirCopyingFailed!");
4072 }
4073
4074 /**
4075 * Changes the description of the specified directory.
4076 * @param dir The absolute path name of the directory.
4077 * @param desc The new description for the directory.
4078 * @throws IOException If some I/O error occurs.
4079 * @throws LSException If failed to change the description.
4080 * @throws LscpException If LSCP protocol corruption occurs.
4081 */
4082 public synchronized void
4083 setDbDirectoryDescription(String dir, String desc)
4084 throws IOException, LSException, LscpException {
4085
4086 verifyConnection();
4087 String s = "SET DB_INSTRUMENT_DIRECTORY DESCRIPTION '";
4088 out.writeLine(s + dir + "' '" + desc + "'");
4089 if(getPrintOnlyMode()) return;
4090
4091 ResultSet rs = getEmptyResultSet();
4092 }
4093
4094 public static enum ScanMode {
4095 RECURSIVE, NON_RECURSIVE, FLAT
4096 }
4097
4098 /**
4099 * Adds the specified instrument to the specified instruments database directory.
4100 * @param dbDir The absolute path name of the database directory in which the
4101 * specified instrument will be added.
4102 * @param filePath The absolute path name of the instrument file.
4103 * @param instrIndex The index of the instrument (in the given instrument file) to add.
4104 * @throws IOException If some I/O error occurs.
4105 * @throws LSException If the operation failed.
4106 * @throws LscpException If LSCP protocol corruption occurs.
4107 */
4108 public synchronized void
4109 addDbInstrument(String dbDir, String filePath, int instrIndex)
4110 throws IOException, LSException, LscpException {
4111
4112 addDbInstrument(dbDir, filePath, instrIndex, false);
4113 }
4114
4115 /**
4116 * Adds the specified instrument to the specified instruments database directory.
4117 * @param dbDir The absolute path name of the database directory in which the
4118 * specified instrument will be added.
4119 * @param filePath The absolute path name of the instrument file.
4120 * @param instrIndex The index of the instrument (in the given instrument file) to add.
4121 * @param background If <code>true</code>, the scan will be done
4122 * in background and this method may return before the job is finished.
4123 * @return If <code>background</code> is <code>true</code>, the ID
4124 * of the scan job.
4125 * @throws IOException If some I/O error occurs.
4126 * @throws LSException If the operation failed.
4127 * @throws LscpException If LSCP protocol corruption occurs.
4128 * @see #addInstrumentsDbListener
4129 */
4130 public synchronized int
4131 addDbInstrument(String dbDir, String filePath, int instrIndex, boolean background)
4132 throws IOException, LSException, LscpException {
4133
4134 verifyConnection();
4135 String s = "ADD DB_INSTRUMENTS";
4136 if(background) s += " NON_MODAL";
4137 s += " '" + dbDir + "' '" + filePath + "' ";
4138 out.writeLine(s + String.valueOf(instrIndex));
4139 if(getPrintOnlyMode()) return -1;
4140
4141 ResultSet rs = getEmptyResultSet();
4142 return rs.getIndex();
4143 }
4144
4145 /**
4146 * Adds the instruments in the specified file to the specified
4147 * instruments database directory.
4148 * @param dbDir The absolute path name of the database directory
4149 * in which the the supported instruments will be added.
4150 * @param filePath The absolute path name of the file to scan for instruments.
4151 * @throws IOException If some I/O error occurs.
4152 * @throws LSException If the operation failed.
4153 * @throws LscpException If LSCP protocol corruption occurs.
4154 */
4155 public synchronized void
4156 addDbInstruments(String dbDir, String filePath)
4157 throws IOException, LSException, LscpException {
4158
4159 addDbInstruments(dbDir, filePath, false);
4160 }
4161
4162 /**
4163 * Adds the instruments in the specified file to the specified
4164 * instruments database directory.
4165 * @param dbDir The absolute path name of the database directory
4166 * in which the the supported instruments will be added.
4167 * @param filePath The absolute path name of the file to scan for instruments.
4168 * @param background If <code>true</code>, the scan will be done
4169 * in background and this method may return before the job is finished.
4170 * @return If <code>background</code> is <code>true</code>, the ID
4171 * of the scan job.
4172 * @throws IOException If some I/O error occurs.
4173 * @throws LSException If the operation failed.
4174 * @throws LscpException If LSCP protocol corruption occurs.
4175 * @see #addInstrumentsDbListener
4176 */
4177 public synchronized int
4178 addDbInstruments(String dbDir, String filePath, boolean background)
4179 throws IOException, LSException, LscpException {
4180
4181 verifyConnection();
4182 String s = "ADD DB_INSTRUMENTS";
4183 if(background) s += " NON_MODAL";
4184 out.writeLine(s + " '" + dbDir + "' '" + filePath + "'");
4185 if(getPrintOnlyMode()) return -1;
4186
4187 ResultSet rs = getEmptyResultSet();
4188 return rs.getIndex();
4189 }
4190
4191 /**
4192 * Adds the instruments in the specified file system directory
4193 * to the specified instruments database directory.
4194 * @param mode Determines the scanning mode. If RECURSIVE is
4195 * specified, all supported instruments in the specified file system
4196 * direcotry will be added to the specified instruments database
4197 * directory, including the instruments in subdirectories
4198 * of the supplied directory. If NON_RECURSIVE is specified,
4199 * the instruments in the subdirectories will not be processed.
4200 * If FLAT is specified, all supported instruments in the specified
4201 * file system direcotry will be added, including the instruments in
4202 * subdirectories of the supplied directory, but the respective
4203 * subdirectory structure will not be recreated in the instruments
4204 * database and all instruments will be added directly in the
4205 * specified database directory.
4206 * @param dbDir The absolute path name of the database directory
4207 * in which the supported instruments will be added.
4208 * @param fsDir The absolute path name of the file system directory.
4209 * @throws IOException If some I/O error occurs.
4210 * @throws LSException If the operation failed.
4211 * @throws LscpException If LSCP protocol corruption occurs.
4212 */
4213 public synchronized void
4214 addDbInstruments(ScanMode mode, String dbDir, String fsDir)
4215 throws IOException, LSException, LscpException {
4216
4217 addDbInstruments(mode, dbDir, fsDir, false);
4218 }
4219
4220 /**
4221 * Adds the instruments in the specified file system directory
4222 * to the specified instruments database directory.
4223 * @param mode Determines the scanning mode. If RECURSIVE is
4224 * specified, all supported instruments in the specified file system
4225 * direcotry will be added to the specified instruments database
4226 * directory, including the instruments in subdirectories
4227 * of the supplied directory. If NON_RECURSIVE is specified,
4228 * the instruments in the subdirectories will not be processed.
4229 * If FLAT is specified, all supported instruments in the specified
4230 * file system direcotry will be added, including the instruments in
4231 * subdirectories of the supplied directory, but the respective
4232 * subdirectory structure will not be recreated in the instruments
4233 * database and all instruments will be added directly in the
4234 * specified database directory.
4235 * @param dbDir The absolute path name of the database directory
4236 * in which the supported instruments will be added.
4237 * @param fsDir The absolute path name of the file system directory.
4238 * @param background If <code>true</code>, the scan will be done
4239 * in background and this method may return before the job is finished.
4240 * @return If <code>background</code> is <code>true</code>, the ID
4241 * of the scan job.
4242 * @throws IOException If some I/O error occurs.
4243 * @throws LSException If the operation failed.
4244 * @throws LscpException If LSCP protocol corruption occurs.
4245 * @see #addInstrumentsDbListener
4246 */
4247 public synchronized int
4248 addDbInstruments(ScanMode mode, String dbDir, String fsDir, boolean background)
4249 throws IOException, LSException, LscpException {
4250
4251 verifyConnection();
4252 StringBuffer sb = new StringBuffer("ADD DB_INSTRUMENTS");
4253 if(background) sb.append(" NON_MODAL");
4254
4255 switch(mode) {
4256 case RECURSIVE:
4257 sb.append(" RECURSIVE");
4258 break;
4259 case NON_RECURSIVE:
4260 sb.append(" NON_RECURSIVE");
4261 break;
4262 case FLAT:
4263 sb.append(" FLAT");
4264 break;
4265 }
4266
4267 sb.append(" '").append(dbDir).append("' '").append(fsDir).append("'");
4268 out.writeLine(sb.toString());
4269 if(getPrintOnlyMode()) return -1;
4270
4271 ResultSet rs = getEmptyResultSet();
4272 return rs.getIndex();
4273 }
4274
4275 /**
4276 * Removes the specified instrument from the instruments database.
4277 * @param instr The absolute path name of the instrument to remove.
4278 * @throws IOException If some I/O error occurs.
4279 * @throws LscpException If LSCP protocol corruption occurs.
4280 * @throws LSException If the removing of the instrument failed.
4281 */
4282 public synchronized void
4283 removeDbInstrument(String instr) throws IOException, LscpException, LSException {
4284
4285 verifyConnection();
4286 out.writeLine("REMOVE DB_INSTRUMENT '" + instr + "'");
4287 if(getPrintOnlyMode()) return;
4288
4289 ResultSet rs = getEmptyResultSet();
4290 }
4291
4292 /**
4293 * Removes the specified instruments from the instruments database.
4294 * @param instrs The absolute path names of the instruments to remove.
4295 * @throws IOException If some I/O error occurs.
4296 * @throws LscpException If LSCP protocol corruption occurs.
4297 * @throws LSException If the removing of the instruments failed.
4298 */
4299 public synchronized void
4300 removeDbInstruments(String[] instrs) throws IOException, LscpException, LSException {
4301 verifyConnection();
4302 for(String s : instrs) {
4303 out.writeLine("REMOVE DB_INSTRUMENT '" + s + "'");
4304 }
4305 if(getPrintOnlyMode()) return;
4306
4307 getEmptyResultSets(instrs.length, "Client.instrDeletionFailed!");
4308 }
4309
4310 /**
4311 * Gets the number of instruments in the specified directory.
4312 * @return The current number of instruments in the specified directory.
4313 * @param dir The absolute path name of the directory.
4314 * @throws IOException If some I/O error occurs.
4315 * @throws LscpException If LSCP protocol corruption occurs.
4316 * @throws LSException If some other error occurs.
4317 */
4318 public synchronized int
4319 getDbInstrumentCount(String dir) throws IOException, LscpException, LSException {
4320 return getDbInstrumentCount(dir, false);
4321 }
4322
4323 /**
4324 * Gets the number of instruments in the specified directory.
4325 * @return The current number of instruments in the specified directory.
4326 * @param dir The absolute path name of the directory.
4327 * @param recursive If <code>true</code>, the number of all instruments
4328 * in the specified subtree will be returned.
4329 * @throws IOException If some I/O error occurs.
4330 * @throws LscpException If LSCP protocol corruption occurs.
4331 * @throws LSException If some other error occurs.
4332 */
4333 public synchronized int
4334 getDbInstrumentCount(String dir, boolean recursive)
4335 throws IOException, LscpException, LSException {
4336
4337 verifyConnection();
4338 String s;
4339 if(recursive) s = "GET DB_INSTRUMENTS RECURSIVE '";
4340 else s = "GET DB_INSTRUMENTS '";
4341 out.writeLine(s + dir + "'");
4342 if(getPrintOnlyMode()) return -1;
4343
4344 s = getSingleLineResultSet().getResult();
4345 return parseInt(s);
4346 }
4347
4348 /**
4349 * Gets the list of instruments in the specified directory.
4350 * @param dir The absolute path name of the directory.
4351 * @return A <code>String</code> array providing the names of
4352 * all instruments in the specified directory.
4353 * @throws IOException If some I/O error occurs.
4354 * @throws LscpException If LSCP protocol corruption occurs.
4355 * @throws LSException If the specified path name is invalid.
4356 */
4357 public synchronized String[]
4358 getDbInstrumentNames(String dir) throws IOException, LscpException, LSException {
4359 verifyConnection();
4360 out.writeLine("LIST DB_INSTRUMENTS '" + dir + "'");
4361 if(getPrintOnlyMode()) return null;
4362
4363 return parseQuotedStringList(getSingleLineResultSet().getResult());
4364 }
4365
4366 /**
4367 * Gets information about the specified instrument.
4368 * @param instr The absolute path name of the instrument.
4369 * @return A <code>DbInstrumentInfo</code> instance providing information
4370 * about the specified instrument.
4371 * @throws IOException If some I/O error occurs.
4372 * @throws LscpException If LSCP protocol corruption occurs.
4373 * @throws LSException If the specified instrument is not found.
4374 */
4375 public synchronized DbInstrumentInfo
4376 getDbInstrumentInfo(String instr) throws IOException, LscpException, LSException {
4377 verifyConnection();
4378 out.writeLine("GET DB_INSTRUMENT INFO '" + instr + "'");
4379 if(getPrintOnlyMode()) return null;
4380
4381 ResultSet rs = getMultiLineResultSet();
4382 DbInstrumentInfo info = new DbInstrumentInfo(rs.getMultiLineResult());
4383 int i = instr.lastIndexOf('/');
4384 if(i != -1 && i < instr.length() - 1) {
4385 info.setName(instr.substring(i + 1));
4386 if(i == 0) info.setDirectoryPath("/");
4387 else info.setDirectoryPath(instr.substring(0, i));
4388 }
4389
4390 return info;
4391 }
4392
4393 /**
4394 * Gets the list of instruments in the specified directory.
4395 * @param dir The absolute path name of the directory.
4396 * @return A <code>DbInstrumentInfo</code> array providing
4397 * information about all instruments in the specified directory.
4398 * @throws IOException If some I/O error occurs.
4399 * @throws LscpException If LSCP protocol corruption occurs.
4400 * @throws LSException If the specified path name is invalid.
4401 */
4402 public synchronized DbInstrumentInfo[]
4403 getDbInstruments(String dir) throws IOException, LscpException, LSException {
4404 String[] instrS = getDbInstrumentNames(dir);
4405 if(dir.charAt(dir.length() - 1) != '/') dir += "/";
4406
4407 DbInstrumentInfo[] infoS = new DbInstrumentInfo[instrS.length];
4408 for(int i = 0; i < instrS.length; i++) {
4409 infoS[i] = getDbInstrumentInfo(dir + instrS[i]);
4410 }
4411 return infoS;
4412 }
4413
4414 /**
4415 * Gets the list of instruments in the specified directory.
4416 * @param dir The absolute path name of the directory.
4417 * @return A <code>DbInstrumentInfo</code> array providing
4418 * information about all instruments in the specified directory.
4419 * @throws IOException If some I/O error occurs.
4420 * @throws LscpException If LSCP protocol corruption occurs.
4421 * @throws LSException If the specified path name is invalid.
4422 *
4423 public synchronized DbInstrumentInfo[]
4424 getDbInstruments(String dir) throws IOException, LscpException, LSException {
4425 String[] instrS = getDbInstrumentNames(dir);
4426 if(instrS.length == 0) return new DbInstrumentInfo[0];
4427
4428 if(dir.charAt(dir.length() - 1) != '/') dir += "/";
4429
4430 for(int i = 0; i < instrS.length; i++) {
4431 out.writeLine("GET DB_INSTRUMENT INFO '" + dir + instrS[i] + "'");
4432 }
4433
4434 if(getPrintOnlyMode()) return null;
4435
4436 if(dir.length() > 1) dir = dir.substring(0, dir.length() - 1);
4437 StringBuffer sb = new StringBuffer();
4438 DbInstrumentInfo[] infoS = new DbInstrumentInfo[instrS.length];
4439 for(int i = 0; i < instrS.length; i++) {
4440 try {
4441 ResultSet rs = getMultiLineResultSet();
4442 infoS[i] = new DbInstrumentInfo(rs.getMultiLineResult());
4443 infoS[i].setName(instrS[i]);
4444 infoS[i].setDirectoryPath(dir);
4445 } catch (SocketTimeoutException e) {
4446 getLogger().log(Level.FINE, e.getMessage(), e);
4447 sb.append(e.getMessage()).append("\n");
4448 break;
4449 } catch (Exception e) {
4450 getLogger().log(Level.FINE, e.getMessage(), e);
4451 sb.append(e.getMessage()).append("\n");
4452 }
4453 }
4454
4455 String details = sb.toString();
4456 if(details.length() > 0) {
4457 String err = LscpI18n.getLogMsg("Client.getInstrsInfoFailed!");
4458 throw new LSException(0, err, details);
4459 }
4460
4461 return infoS;
4462 }*/
4463
4464 /**
4465 * Renames the specified instrument.
4466 * @param instr The absolute path name of the instrument to rename.
4467 * @param name The new name for the instrument.
4468 * @throws IOException If some I/O error occurs.
4469 * @throws LSException If the renaming of the instrument failed.
4470 * @throws LscpException If LSCP protocol corruption occurs.
4471 */
4472 public synchronized void
4473 renameDbInstrument(String instr, String name)
4474 throws IOException, LSException, LscpException {
4475
4476 verifyConnection();
4477 out.writeLine("SET DB_INSTRUMENT NAME '" + instr + "' '" + name + "'");
4478 if(getPrintOnlyMode()) return;
4479
4480 ResultSet rs = getEmptyResultSet();
4481 }
4482
4483 /**
4484 * Moves the specified instrument into the specified location.
4485 * @param instr The absolute path name of the instrument to move.
4486 * @param dst The directory where the specified instrument will be moved to.
4487 * @throws IOException If some I/O error occurs.
4488 * @throws LSException If the operation failed.
4489 * @throws LscpException If LSCP protocol corruption occurs.
4490 */
4491 public synchronized void
4492 moveDbInstrument(String instr, String dst) throws IOException, LSException, LscpException {
4493 verifyConnection();
4494 out.writeLine("MOVE DB_INSTRUMENT '" + instr + "' '" + dst + "'");
4495 if(getPrintOnlyMode()) return;
4496
4497 ResultSet rs = getEmptyResultSet();
4498 }
4499
4500 /**
4501 * Moves the specified instruments into the specified location.
4502 * @param instrs The absolute path names of the instruments to move.
4503 * @param dst The directory where the specified instruments will be moved to.
4504 * @throws IOException If some I/O error occurs.
4505 * @throws LSException If the operation failed.
4506 * @throws LscpException If LSCP protocol corruption occurs.
4507 */
4508 public synchronized void
4509 moveDbInstruments(String[] instrs, String dst) throws IOException, LSException, LscpException {
4510 verifyConnection();
4511 for(String s : instrs) {
4512 out.writeLine("MOVE DB_INSTRUMENT '" + s + "' '" + dst + "'");
4513 }
4514 if(getPrintOnlyMode()) return;
4515
4516 getEmptyResultSets(instrs.length, "Client.instrMovingFailed!");
4517 }
4518
4519 /**
4520 * Copies the specified instrument into the specified location.
4521 * @param instr The absolute path name of the instrument to copy.
4522 * @param dst The directory where the specified instrument will be copied to.
4523 * @throws IOException If some I/O error occurs.
4524 * @throws LSException If the operation failed.
4525 * @throws LscpException If LSCP protocol corruption occurs.
4526 */
4527 public synchronized void
4528 copyDbInstrument(String instr, String dst) throws IOException, LSException, LscpException {
4529 verifyConnection();
4530 out.writeLine("COPY DB_INSTRUMENT '" + instr + "' '" + dst + "'");
4531 if(getPrintOnlyMode()) return;
4532
4533 ResultSet rs = getEmptyResultSet();
4534 }
4535
4536 /**
4537 * Copies the specified instruments into the specified location.
4538 * @param instrs The absolute path name of the instruments to copy.
4539 * @param dst The directory where the specified instruments will be copied to.
4540 * @throws IOException If some I/O error occurs.
4541 * @throws LSException If the operation failed.
4542 * @throws LscpException If LSCP protocol corruption occurs.
4543 */
4544 public synchronized void
4545 copyDbInstruments(String[] instrs, String dst) throws IOException, LSException, LscpException {
4546 verifyConnection();
4547 for(String s : instrs) {
4548 out.writeLine("COPY DB_INSTRUMENT '" + s + "' '" + dst + "'");
4549 }
4550 if(getPrintOnlyMode()) return;
4551
4552 getEmptyResultSets(instrs.length, "Client.instrCopyingFailed!");
4553 }
4554
4555 /**
4556 * Changes the description of the specified instrument.
4557 * @param instr The absolute path name of the instrument.
4558 * @param desc The new description for the instrument.
4559 * @throws IOException If some I/O error occurs.
4560 * @throws LSException If failed to change the description.
4561 * @throws LscpException If LSCP protocol corruption occurs.
4562 */
4563 public synchronized void
4564 setDbInstrumentDescription(String instr, String desc)
4565 throws IOException, LSException, LscpException {
4566
4567 verifyConnection();
4568 out.writeLine("SET DB_INSTRUMENT DESCRIPTION '" + instr + "' '" + desc + "'");
4569 if(getPrintOnlyMode()) return;
4570
4571 ResultSet rs = getEmptyResultSet();
4572 }
4573
4574 /**
4575 * Finds all directories in the specified directory
4576 * that corresponds to the specified search criterias.
4577 * @param dir The absolute path name of the directory to search.
4578 * @param query Provides the search criterias.
4579 * @return A <code>DbDirectoryInfo</code> array providing
4580 * information about all directories that are found in the specified directory.
4581 * @throws IOException If some I/O error occurs.
4582 * @throws LscpException If LSCP protocol corruption occurs.
4583 * @throws LSException If the specified path name is invalid.
4584 */
4585 public synchronized DbDirectoryInfo[]
4586 findDbDirectories(String dir, DbSearchQuery query)
4587 throws IOException, LscpException, LSException {
4588
4589 return findDbDirectories(dir, query, false);
4590 }
4591
4592 /**
4593 * Finds all directories in the specified directory
4594 * that corresponds to the specified search criterias.
4595 * @param dir The absolute path name of the directory to search.
4596 * @param query Provides the search criterias.
4597 * @param nonRecursive If <code>true</code>, the search will be non-recursive.
4598 * @return A <code>DbDirectoryInfo</code> array providing
4599 * information about all directories that are found in the specified directory.
4600 * @throws IOException If some I/O error occurs.
4601 * @throws LscpException If LSCP protocol corruption occurs.
4602 * @throws LSException If the specified path name is invalid.
4603 */
4604 public synchronized DbDirectoryInfo[]
4605 findDbDirectories(String dir, DbSearchQuery query, boolean nonRecursive)
4606 throws IOException, LscpException, LSException {
4607
4608 verifyConnection();
4609 StringBuffer sb = new StringBuffer();
4610 sb.append("FIND DB_INSTRUMENT_DIRECTORIES");
4611 if(nonRecursive) sb.append(" NON_RECURSIVE");
4612 sb.append(" '").append(dir).append("'");
4613
4614 if(query.name != null && query.name.length() > 0) {
4615 sb.append(" NAME='").append(query.name).append("'");
4616 }
4617
4618 String s = query.getCreatedAfter();
4619 String s2 = query.getCreatedBefore();
4620 if(s != null || s2 != null) {
4621 sb.append(" CREATED='");
4622 if(s != null) sb.append(s);
4623 sb.append("..");
4624 if(s2 != null) sb.append(s2);
4625 sb.append("'");
4626 }
4627
4628 s = query.getModifiedAfter();
4629 s2 = query.getModifiedBefore();
4630 if(s != null || s2 != null) {
4631 sb.append(" MODIFIED='");
4632 if(s != null) sb.append(s);
4633 sb.append("..");
4634 if(s2 != null) sb.append(s2);
4635 sb.append("'");
4636 }
4637
4638 if(query.description != null && query.description.length() > 0) {
4639 sb.append(" DESCRIPTION='").append(query.description).append("'");
4640 }
4641
4642 out.writeLine(sb.toString());
4643 if(getPrintOnlyMode()) return null;
4644
4645 String[] dirS = parseQuotedStringList(getSingleLineResultSet().getResult());
4646
4647 DbDirectoryInfo[] infoS = new DbDirectoryInfo[dirS.length];
4648 for(int i = 0; i < dirS.length; i++) {
4649 infoS[i] = getDbDirectoryInfo(dirS[i]);
4650 }
4651 return infoS;
4652 }
4653
4654 /**
4655 * Finds all instruments in the specified directory
4656 * that corresponds to the specified search criterias.
4657 * @param dir The absolute path name of the directory to search.
4658 * @param query Provides the search criterias.
4659 * @return A <code>DbInstrumentInfo</code> array providing
4660 * information about all instruments that are found in the specified directory.
4661 * @throws IOException If some I/O error occurs.
4662 * @throws LscpException If LSCP protocol corruption occurs.
4663 * @throws LSException If the specified path name is invalid.
4664 */
4665 public synchronized DbInstrumentInfo[]
4666 findDbInstruments(String dir, DbSearchQuery query)
4667 throws IOException, LscpException, LSException {
4668
4669 return findDbInstruments(dir, query, false);
4670 }
4671
4672 /**
4673 * Finds all instruments in the specified directory
4674 * that corresponds to the specified search criterias.
4675 * @param dir The absolute path name of the directory to search.
4676 * @param query Provides the search criterias.
4677 * @param nonRecursive If <code>true</code>, the search will be non-recursive.
4678 * @return A <code>DbInstrumentInfo</code> array providing
4679 * information about all instruments that are found in the specified directory.
4680 * @throws IOException If some I/O error occurs.
4681 * @throws LscpException If LSCP protocol corruption occurs.
4682 * @throws LSException If the specified path name is invalid.
4683 */
4684 public synchronized DbInstrumentInfo[]
4685 findDbInstruments(String dir, DbSearchQuery query, boolean nonRecursive)
4686 throws IOException, LscpException, LSException {
4687
4688 verifyConnection();
4689 StringBuffer sb = new StringBuffer();
4690 sb.append("FIND DB_INSTRUMENTS");
4691 if(nonRecursive) sb.append(" NON_RECURSIVE");
4692 sb.append(" '").append(dir).append("'");
4693
4694 if(query.name != null && query.name.length() > 0) {
4695 sb.append(" NAME='").append(query.name).append("'");
4696 }
4697
4698 if(query.formatFamilies.size() > 0) {
4699 sb.append(" FORMAT_FAMILIES='").append(query.formatFamilies.get(0));
4700 for(int i = 1; i < query.formatFamilies.size(); i++) {
4701 sb.append(',').append(query.formatFamilies.get(i));
4702 }
4703 sb.append("'");
4704 }
4705
4706 if(query.minSize != -1 || query.maxSize != -1) {
4707 sb.append(" SIZE='");
4708 if(query.minSize != -1) sb.append(query.minSize);
4709 sb.append("..");
4710 if(query.maxSize != -1) sb.append(query.maxSize);
4711 sb.append("'");
4712 }
4713
4714 String s = query.getCreatedAfter();
4715 String s2 = query.getCreatedBefore();
4716 if(s != null || s2 != null) {
4717 sb.append(" CREATED='");
4718 if(s != null) sb.append(s);
4719 sb.append("..");
4720 if(s2 != null) sb.append(s2);
4721 sb.append("'");
4722 }
4723
4724 s = query.getModifiedAfter();
4725 s2 = query.getModifiedBefore();
4726 if(s != null || s2 != null) {
4727 sb.append(" MODIFIED='");
4728 if(s != null) sb.append(s);
4729 sb.append("..");
4730 if(s2 != null) sb.append(s2);
4731 sb.append("'");
4732 }
4733
4734 if(query.description != null && query.description.length() > 0) {
4735 sb.append(" DESCRIPTION='").append(query.description).append("'");
4736 }
4737
4738 if(query.instrumentType != DbSearchQuery.InstrumentType.BOTH) {
4739 sb.append(" IS_DRUM=");
4740 if(query.instrumentType == DbSearchQuery.InstrumentType.DRUM) {
4741 sb.append("'true'");
4742 } else {
4743 sb.append("'false'");
4744 }
4745 }
4746
4747 if(query.product != null && query.product.length() > 0) {
4748 sb.append(" PRODUCT='").append(query.product).append("'");
4749 }
4750
4751 if(query.artists != null && query.artists.length() > 0) {
4752 sb.append(" ARTISTS='").append(query.artists).append("'");
4753 }
4754
4755 if(query.keywords != null && query.keywords.length() > 0) {
4756 sb.append(" KEYWORDS='").append(query.keywords).append("'");
4757 }
4758
4759 out.writeLine(sb.toString());
4760 if(getPrintOnlyMode()) return null;
4761
4762 String[] instrS = parseQuotedStringList(getSingleLineResultSet().getResult());
4763
4764 DbInstrumentInfo[] infoS = new DbInstrumentInfo[instrS.length];
4765 for(int i = 0; i < instrS.length; i++) {
4766 infoS[i] = getDbInstrumentInfo(instrS[i]);
4767 }
4768 return infoS;
4769 }
4770
4771 /**
4772 * Gets status information about the specified job.
4773 * @param jobId The ID of the job.
4774 * @return A <code>ScanJobInfo</code> instance providing information
4775 * about the specified job.
4776 * @throws IOException If some I/O error occurs.
4777 * @throws LscpException If LSCP protocol corruption occurs.
4778 * @throws LSException If the specified job is not found.
4779 */
4780 public synchronized ScanJobInfo
4781 getDbInstrumentsJobInfo(int jobId) throws IOException, LscpException, LSException {
4782 verifyConnection();
4783 out.writeLine("GET DB_INSTRUMENTS_JOB INFO " + String.valueOf(jobId));
4784 if(getPrintOnlyMode()) return null;
4785
4786 ResultSet rs = getMultiLineResultSet();
4787 ScanJobInfo info = new ScanJobInfo(rs.getMultiLineResult());
4788
4789 return info;
4790 }
4791
4792 /**
4793 * Resets the specified sampler channel.
4794 *
4795 * @param samplerChn The sampler channel number.
4796 *
4797 * @throws IOException If some I/O error occurs.
4798 * @throws LscpException If LSCP protocol corruption occurs.
4799 * @throws LSException If <code>samplerChn</code> is not a valid channel number or if
4800 * there is no engine assigned yet to the specified sampler channel.
4801 * @see #getSamplerChannels
4802 */
4803 public synchronized void
4804 resetChannel(int samplerChn) throws IOException, LscpException, LSException {
4805 verifyConnection();
4806 out.writeLine("RESET CHANNEL " + samplerChn);
4807 if(getPrintOnlyMode()) return;
4808
4809 ResultSet rs = getEmptyResultSet();
4810 }
4811
4812 /**
4813 * Resets the whole sampler.
4814 *
4815 * @throws IOException If some I/O error occurs.
4816 * @throws LscpException If LSCP protocol corruption occurs.
4817 */
4818 public synchronized void
4819 resetSampler() throws IOException, LscpException {
4820 verifyConnection();
4821 out.writeLine("RESET");
4822 if(getPrintOnlyMode()) return;
4823
4824 try { ResultSet rs = getEmptyResultSet(); }
4825 catch(LSException x) { getLogger().warning(x.getMessage()); }
4826 }
4827
4828 /**
4829 * Gets the current number of all active voices.
4830 * @return The current number of all active voices.
4831 * @throws IOException If some I/O error occurs.
4832 * @throws LscpException If LSCP protocol corruption occurs.
4833 * @throws LSException If some other error occurs.
4834 */
4835 public synchronized int
4836 getTotalVoiceCount() throws IOException, LscpException, LSException {
4837 verifyConnection();
4838 out.writeLine("GET TOTAL_VOICE_COUNT");
4839 if(getPrintOnlyMode()) return -1;
4840
4841 String s = getSingleLineResultSet().getResult();
4842 return parseInt(s);
4843 }
4844
4845 /**
4846 * Gets the maximum number of active voices.
4847 * @return The maximum number of active voices.
4848 * @throws IOException If some I/O error occurs.
4849 * @throws LscpException If LSCP protocol corruption occurs.
4850 * @throws LSException If some other error occurs.
4851 */
4852 public synchronized int
4853 getTotalVoiceCountMax() throws IOException, LscpException, LSException {
4854 verifyConnection();
4855 out.writeLine("GET TOTAL_VOICE_COUNT_MAX");
4856 if(getPrintOnlyMode()) return -1;
4857
4858 String s = getSingleLineResultSet().getResult();
4859 return parseInt(s);
4860 }
4861
4862 /**
4863 * Gets information about the LinuxSampler instance.
4864 *
4865 * @return <code>ServerInfo</code> instance containing
4866 * information about the LinuxSampler instance.
4867 *
4868 * @throws IOException If an I/O error occurs.
4869 * @throws LscpException If LSCP protocol corruption occurs.
4870 * @throws LSException If some other error occurs.
4871 */
4872 public synchronized ServerInfo
4873 getServerInfo() throws IOException, LscpException, LSException {
4874 verifyConnection();
4875 out.writeLine("GET SERVER INFO");
4876 if(getPrintOnlyMode()) return null;
4877
4878 ResultSet rs = getMultiLineResultSet();
4879 return new ServerInfo(rs.getMultiLineResult());
4880 }
4881
4882 /**
4883 * Gets the golobal volume of the sampler.
4884 * @return The golobal volume of the sampler.
4885 * @throws IOException If some I/O error occurs.
4886 * @throws LscpException If LSCP protocol corruption occurs.
4887 * @throws LSException If some other error occurs.
4888 */
4889 public synchronized float
4890 getVolume() throws IOException, LscpException, LSException {
4891 verifyConnection();
4892 out.writeLine("GET VOLUME");
4893 if(getPrintOnlyMode()) return -1;
4894
4895 String s = getSingleLineResultSet().getResult();
4896 return parseFloat(s);
4897 }
4898
4899 /**
4900 * Sets the global volume of the sampler.
4901 * @param volume The new volume value.
4902 * @throws IOException If some I/O error occurs.
4903 * @throws LscpException If LSCP protocol corruption occurs.
4904 * @throws LSException If some other error occurs.
4905 * @see #getVolume
4906 */
4907 public synchronized void
4908 setVolume(float volume) throws IOException, LscpException, LSException {
4909
4910 verifyConnection();
4911 out.writeLine("SET VOLUME " + volume);
4912 if(getPrintOnlyMode()) return;
4913
4914 ResultSet rs = getEmptyResultSet();
4915 }
4916
4917 private void
4918 getEmptyResultSets(int count, String err) throws LSException {
4919 StringBuffer sb = new StringBuffer();
4920 for(int i = 0; i < count; i++) {
4921 try { getEmptyResultSet(); }
4922 catch (SocketTimeoutException e) {
4923 getLogger().log(Level.FINE, e.getMessage(), e);
4924 sb.append(e.getMessage()).append("\n");
4925 break;
4926 } catch (Exception e) {
4927 getLogger().log(Level.FINE, e.getMessage(), e);
4928 sb.append(e.getMessage()).append("\n");
4929 }
4930 }
4931
4932 String details = sb.toString();
4933 if(details.length() > 0) {
4934 String s = LscpI18n.getLogMsg(err);
4935 throw new LSException(0, s, details);
4936 }
4937 }
4938
4939 /**
4940 * Returns the logger for this library.
4941 * @return The logger for this library.
4942 */
4943 protected static Logger
4944 getLogger() { return Logger.getLogger("org.linuxsampler.lscp"); }
4945 }

  ViewVC Help
Powered by ViewVC