/[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 1494 - (show annotations) (download)
Mon Nov 19 22:00:04 2007 UTC (16 years, 5 months ago) by iliev
File size: 171956 byte(s)
* MidiInputDevice: added new methods - getPortsParameter, setPortsParameter

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

  ViewVC Help
Powered by ViewVC