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

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

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 596 by iliev, Wed Jun 1 07:11:31 2005 UTC revision 1605 by iliev, Mon Dec 31 15:42:55 2007 UTC
# Line 1  Line 1 
1  /*  /*
2   *   jlscp - a java LinuxSampler control protocol API   *   jlscp - a java LinuxSampler control protocol API
3   *   *
4   *   Copyright (C) 2005 Grigor Kirilov Iliev   *   Copyright (C) 2005-2007 Grigor Iliev <grigor@grigoriliev.com>
5   *   *
6   *   This file is part of jlscp.   *   This file is part of jlscp.
7   *   *
# Line 23  Line 23 
23  package org.linuxsampler.lscp;  package org.linuxsampler.lscp;
24    
25  import java.io.IOException;  import java.io.IOException;
26    import java.io.OutputStream;
27    
28  import java.net.InetSocketAddress;  import java.net.InetSocketAddress;
29  import java.net.Socket;  import java.net.Socket;
# Line 33  import java.util.Vector; Line 34  import java.util.Vector;
34  import java.util.logging.Level;  import java.util.logging.Level;
35  import java.util.logging.Logger;  import java.util.logging.Logger;
36    
 import static org.linuxsampler.lscp.Parser.*;  
37  import org.linuxsampler.lscp.event.*;  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   * 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 version 1.0, for more   * instance. Since it implements all commands specified in the LSCP protocol v1.1, for more
45   * information look at   * information look at the
46   * <a href=http://www.linuxsampler.org/api/draft-linuxsampler-protocol.html>LSCP</a>   * <a href=http://www.linuxsampler.org/api/lscp-1.1.html>LSCP</a> specification.
  * specification.  
47   *   *
48   * <p> The following code establishes connection to LinuxSampler instance and gets the   * <p> The following code establishes connection to LinuxSampler instance and gets the
49   * LinuxSampler version:   * LinuxSampler version:
# Line 66  import org.linuxsampler.lscp.event.*; Line 67  import org.linuxsampler.lscp.event.*;
67   * @author  Grigor Iliev   * @author  Grigor Iliev
68   */   */
69  public class Client {  public class Client {
         /** Specifies the current version of jlscp */  
         private final static String VERSION = "0.1a";  
           
70          private String address;          private String address;
71          private int port;          private int port;
72          private Socket sock = null;          private Socket sock = null;
73          private int soTimeout = 10000;          private int soTimeout = 20000;
74                    
75          private LscpInputStream in = null;          private LscpInputStream in = null;
76          private LscpOutputStream out = null;          private LscpOutputStream out = null;
77                    
78          private EventThread eventThread;          private EventThread eventThread;
79                    
80            private boolean printOnlyMode = false;
81            
82          class EventThread extends Thread {          class EventThread extends Thread {
83                    private Vector<String> queue = new Vector<String>();
84                  private boolean terminate = false;                  private boolean terminate = false;
85                                    
86                  EventThread() { super("LSCP-Event-Thread"); }                  EventThread() { super("LSCP-Event-Thread"); }
# Line 87  public class Client { Line 88  public class Client {
88                  public void                  public void
89                  run() {                  run() {
90                          while(!mustTerminate()) {                          while(!mustTerminate()) {
91                                  try { processNotifications(); }                                  try {
92                                  catch(Exception x) {                                          processQueue();
93                                            processNotifications();
94                                    } catch(Exception x) {
95                                          getLogger().log(Level.FINE, x.getMessage(), x);                                          getLogger().log(Level.FINE, x.getMessage(), x);
96                                  }                                  }
97                                  try { synchronized(this) { wait(100); } }                                  try { synchronized(this) { wait(100); } }
# Line 106  public class Client { Line 109  public class Client {
109                          terminate = true;                          terminate = true;
110                          this.notifyAll();                          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          /**          /**
# Line 137  public class Client { Line 156  public class Client {
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.           * Specifies the jlscp version.
217           * @return The jlscp version.           * @return The jlscp version.
218           */           */
219          public static String          public static String
220          getClientVersion() { return VERSION; }          getClientVersion() {
221                    return Package.getPackage("org.linuxsampler.lscp").getImplementationVersion();
222            }
223                    
224          /**          /**
225           * Gets the Linux Sampler address.           * Gets the Linux Sampler address.
# Line 182  public class Client { Line 260  public class Client {
260          public synchronized void          public synchronized void
261          connect() throws LscpException {          connect() throws LscpException {
262                  if(sock != null) disconnect();                  if(sock != null) disconnect();
263                    if(getPrintOnlyMode()) return;
264                                    
265                  // Initializing LSCP event thread                  // Initializing LSCP event thread
266                  if(eventThread.isAlive()) {                  if(eventThread.isAlive()) {
# Line 209  public class Client { Line 288  public class Client {
288                          sock.bind(null);                          sock.bind(null);
289                          sock.connect(sockAddr, soTimeout);                          sock.connect(sockAddr, soTimeout);
290                          sock.setSoTimeout(soTimeout);                          sock.setSoTimeout(soTimeout);
291                            sock.setTcpNoDelay(true);
292                                                    
293                          in = new LscpInputStream(sock.getInputStream());                          in = new LscpInputStream(sock.getInputStream());
294                          out = new LscpOutputStream(sock.getOutputStream());                          out = new LscpOutputStream(sock.getOutputStream());
# Line 220  public class Client { Line 300  public class Client {
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();                  if(hasSubscriptions()) eventThread.start();
334                                    
335                  if(!llM.isEmpty()) subscribe("MISCELLANEOUS");                  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");                  if(!llBF.isEmpty()) subscribe("BUFFER_FILL");
341                  if(!llCC.isEmpty()) subscribe("CHANNEL_COUNT");                  if(!llCC.isEmpty()) subscribe("CHANNEL_COUNT");
342                  if(!llCI.isEmpty()) subscribe("CHANNEL_INFO");                  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");                  if(!llSC.isEmpty()) subscribe("STREAM_COUNT");
346                  if(!llVC.isEmpty()) subscribe("VOICE_COUNT");                  if(!llVC.isEmpty()) subscribe("VOICE_COUNT");
347                    if(!llTSC.isEmpty()) subscribe("TOTAL_STREAM_COUNT");
348                    if(!llTVC.isEmpty()) subscribe("TOTAL_VOICE_COUNT");
349                    if(!llMIMC.isEmpty()) subscribe("MIDI_INSTRUMENT_MAP_COUNT");
350                    if(!llMIMI.isEmpty()) subscribe("MIDI_INSTRUMENT_MAP_INFO");
351                    if(!llMIC.isEmpty()) subscribe("MIDI_INSTRUMENT_COUNT");
352                    if(!llMII.isEmpty()) subscribe("MIDI_INSTRUMENT_INFO");
353                    if(!llID.isEmpty()) {
354                            subscribe("DB_INSTRUMENT_DIRECTORY_COUNT");
355                            subscribe("DB_INSTRUMENT_DIRECTORY_INFO");
356                            subscribe("DB_INSTRUMENT_COUNT");
357                            subscribe("DB_INSTRUMENT_INFO");
358                    }
359                    if(!llGI.isEmpty()) subscribe("GLOBAL_INFO");
360          }          }
361                    
362          /**          /**
# Line 235  public class Client { Line 364  public class Client {
364           */           */
365          public synchronized void          public synchronized void
366          disconnect() {          disconnect() {
367                    if(getPrintOnlyMode()) return;
368                  try { if(sock != null) sock.close(); }                  try { if(sock != null) sock.close(); }
369                  catch(Exception x) { getLogger().log(Level.FINE, x.getMessage(), x); }                  catch(Exception x) { getLogger().log(Level.FINE, x.getMessage(), x); }
370                  sock = null;                  sock = null;
# Line 262  public class Client { Line 392  public class Client {
392           */           */
393          private void          private void
394          verifyConnection() throws IOException {          verifyConnection() throws IOException {
395                    if(getPrintOnlyMode()) return;
396                    
397                  if(!isConnected())                  if(!isConnected())
398                          throw new IOException(LscpI18n.getLogMsg("Client.notConnected!"));                          throw new IOException(LscpI18n.getLogMsg("Client.notConnected!"));
399          }          }
# Line 271  public class Client { Line 403  public class Client {
403                  String s;                  String s;
404                  for(;;) {                  for(;;) {
405                          s = in.readLine();                          s = in.readLine();
406                          if(s.startsWith("NOTIFY:")) fireEvent(s.substring("NOTIFY:".length()));                          if(s.startsWith("NOTIFY:")) {
407                                    eventThread.scheduleNotification(s.substring("NOTIFY:".length()));
408                            }
409                          else break;                          else break;
410                  }                  }
411                  return s;                  return s;
412          }          }
413                    
414          /** Processes the notifications send by LinuxSampler */          /** Processes the notifications sent by LinuxSampler */
415          private synchronized void          private synchronized void
416          processNotifications() throws IOException, LscpException {          processNotifications() throws IOException, LscpException {
417                  while(in.available() > 0) {                  while(in.available() > 0) {
# Line 336  public class Client { Line 470  public class Client {
470                  return rs;                  return rs;
471          }          }
472                    
473            /** Audio output device count listeners */
474            private final Vector<ItemCountListener> llAODC = new Vector<ItemCountListener>();
475            /** Audio output device info listeners */
476            private final Vector<ItemInfoListener> llAODI = new Vector<ItemInfoListener>();
477          private final Vector<BufferFillListener> llBF = new Vector<BufferFillListener>();          private final Vector<BufferFillListener> llBF = new Vector<BufferFillListener>();
478          private final Vector<ChannelCountListener> llCC = new Vector<ChannelCountListener>();          private final Vector<ChannelCountListener> llCC = new Vector<ChannelCountListener>();
479          private final Vector<ChannelInfoListener> llCI = new Vector<ChannelInfoListener>();          private final Vector<ChannelInfoListener> llCI = new Vector<ChannelInfoListener>();
480            private final Vector<FxSendCountListener> llFSC = new Vector<FxSendCountListener>();
481            private final Vector<FxSendInfoListener> llFSI = new Vector<FxSendInfoListener>();
482          private final Vector<MiscellaneousListener> llM = new Vector<MiscellaneousListener>();          private final Vector<MiscellaneousListener> llM = new Vector<MiscellaneousListener>();
483            /** MIDI input device count listeners */
484            private final Vector<ItemCountListener> llMIDC = new Vector<ItemCountListener>();
485            /** MIDI input device info listeners */
486            private final Vector<ItemInfoListener> llMIDI = new Vector<ItemInfoListener>();
487          private final Vector<StreamCountListener> llSC = new Vector<StreamCountListener>();          private final Vector<StreamCountListener> llSC = new Vector<StreamCountListener>();
488          private final Vector<VoiceCountListener> llVC = new Vector<VoiceCountListener>();          private final Vector<VoiceCountListener> llVC = new Vector<VoiceCountListener>();
489            private final Vector<TotalStreamCountListener> llTSC = new Vector<TotalStreamCountListener>();
490            private final Vector<TotalVoiceCountListener> llTVC = new Vector<TotalVoiceCountListener>();
491            
492            /** MIDI instrument map count listeners */
493            private final Vector<ItemCountListener> llMIMC = new Vector<ItemCountListener>();
494            /** MIDI instrument map info listeners */
495            private final Vector<ItemInfoListener> llMIMI = new Vector<ItemInfoListener>();
496            /** MIDI instrument count listeners */
497            private final Vector<MidiInstrumentCountListener> llMIC =
498                    new Vector<MidiInstrumentCountListener>();
499            /** MIDI instrument info listeners */
500            private final Vector<MidiInstrumentInfoListener> llMII =
501                    new Vector<MidiInstrumentInfoListener>();
502            private final Vector<InstrumentsDbListener> llID = new Vector<InstrumentsDbListener>();
503            private final Vector<GlobalInfoListener> llGI = new Vector<GlobalInfoListener>();
504            
505                    
506          /**          /**
507           * Determines whether there is at least one subscription for notification events.           * Determines whether there is at least one subscription for notification events.
508           * Do not forget to check for additional listeners if the LSCP specification           * Do not forget to check for additional listeners if the LSCP specification
509           * extends in the future.           * is extended in the future.
510           * @return <code>true</code> if there is at least one subscription for notification events,           * @return <code>true</code> if there is at least one subscription for notification events,
511           * <code>false</code> otherwise.           * <code>false</code> otherwise.
512           */           */
513          private boolean          private boolean
514          hasSubscriptions() {          hasSubscriptions() {
515                  return  !llBF.isEmpty() ||                  return  !llAODC.isEmpty() ||
516                          !llCC.isEmpty() ||                          !llAODI.isEmpty() ||
517                          !llCI.isEmpty() ||                          !llBF.isEmpty()   ||
518                          !llM.isEmpty()  ||                          !llCC.isEmpty()   ||
519                          !llSC.isEmpty() ||                          !llCI.isEmpty()   ||
520                          !llVC.isEmpty();                          !llFSC.isEmpty()  ||
521                            !llFSI.isEmpty()  ||
522                            !llM.isEmpty()    ||
523                            !llMIDC.isEmpty() ||
524                            !llMIDI.isEmpty() ||
525                            !llSC.isEmpty()   ||
526                            !llVC.isEmpty()   ||
527                            !llTSC.isEmpty()  ||
528                            !llTVC.isEmpty()  ||
529                            !llMIMC.isEmpty() ||
530                            !llMIMI.isEmpty() ||
531                            !llMIC.isEmpty()  ||
532                            !llMII.isEmpty()  ||
533                            !llID.isEmpty()   ||
534                            !llGI.isEmpty();
535          }          }
536                    
537          private void          private synchronized void
538          fireEvent(String s) {          fireEvent(String s) {
539                  if(s.startsWith("CHANNEL_COUNT:")) {                   if(s.startsWith("DB_INSTRUMENT_DIRECTORY_COUNT:")) {
540                            s = s.substring("DB_INSTRUMENT_DIRECTORY_COUNT:".length());
541                            InstrumentsDbEvent e = new InstrumentsDbEvent(this, s);
542                            for(InstrumentsDbListener l : llID) l.directoryCountChanged(e);
543                    } else if(s.startsWith("DB_INSTRUMENT_DIRECTORY_INFO:")) {
544                            InstrumentsDbEvent e;
545                            s = s.substring("DB_INSTRUMENT_DIRECTORY_INFO:".length());
546                            if(s.startsWith("NAME ")) {
547                                    String[] list;
548                                    try {
549                                            s = s.substring("NAME ".length());
550                                            list = parseEscapedStringList(s, ' ');
551                                            if(list.length != 2) throw new LscpException();
552                                            list[1] = toNonEscapedString(list[1]);
553                                            e = new InstrumentsDbEvent(this, list[0], list[1]);
554                                            for(InstrumentsDbListener l : llID) {
555                                                    l.directoryNameChanged(e);
556                                            }
557                                    } catch(LscpException x) {
558                                            getLogger().log (
559                                                    Level.WARNING,
560                                                    LscpI18n.getLogMsg("CommandFailed!"),
561                                                    x
562                                            );
563                                    }
564                            } else {
565                                    e = new InstrumentsDbEvent(this, s);
566                                    for(InstrumentsDbListener l : llID) l.directoryInfoChanged(e);
567                            }
568                    } else if(s.startsWith("DB_INSTRUMENT_COUNT:")) {
569                            s = s.substring("DB_INSTRUMENT_COUNT:".length());
570                            InstrumentsDbEvent e = new InstrumentsDbEvent(this, s);
571                            for(InstrumentsDbListener l : llID) l.instrumentCountChanged(e);
572                    } else if(s.startsWith("DB_INSTRUMENT_INFO:")) {
573                            InstrumentsDbEvent e;
574                            s = s.substring("DB_INSTRUMENT_INFO:".length());
575                            if(s.startsWith("NAME ")) {
576                                    String[] list;
577                                    try {
578                                            s = s.substring("NAME ".length());
579                                            list = parseEscapedStringList(s, ' ');
580                                            if(list.length != 2) throw new LscpException();
581                                            list[1] = toNonEscapedString(list[1]);
582                                            e = new InstrumentsDbEvent(this, list[0], list[1]);
583                                            for(InstrumentsDbListener l : llID) {
584                                                    l.instrumentNameChanged(e);
585                                            }
586                                    } catch(LscpException x) {
587                                            getLogger().log (
588                                                    Level.WARNING,
589                                                    LscpI18n.getLogMsg("CommandFailed!"),
590                                                    x
591                                            );
592                                    }
593                            } else {
594                                    e = new InstrumentsDbEvent(this, s);
595                                    for(InstrumentsDbListener l : llID) l.instrumentInfoChanged(e);
596                            }
597                    } else if(s.startsWith("DB_INSTRUMENTS_JOB_INFO:")) {
598                            s = s.substring("DB_INSTRUMENTS_JOB_INFO:".length());
599                            try {
600                                    int i = Integer.parseInt(s);
601                                    InstrumentsDbEvent e = new InstrumentsDbEvent(this, i);
602                                    for(InstrumentsDbListener l : llID) l.jobStatusChanged(e);
603                            } catch(NumberFormatException x) {
604                                    s = "Unknown DB_INSTRUMENTS_JOB_INFO format";
605                                    getLogger().log(Level.WARNING, s, x);
606                            }
607                            
608                    } else if(s.startsWith("CHANNEL_COUNT:")) {
609                          try {                          try {
610                                  int i = Integer.parseInt(s.substring("CHANNEL_COUNT:".length()));                                  int i = Integer.parseInt(s.substring("CHANNEL_COUNT:".length()));
611                                  ChannelCountEvent e = new ChannelCountEvent(this, i);                                  ChannelCountEvent e = new ChannelCountEvent(this, i);
# Line 375  public class Client { Line 618  public class Client {
618                  } else if(s.startsWith("VOICE_COUNT:")) {                  } else if(s.startsWith("VOICE_COUNT:")) {
619                          try {                          try {
620                                  s = s.substring("VOICE_COUNT:".length());                                  s = s.substring("VOICE_COUNT:".length());
621                                  int i = s.indexOf(' ');                                  Integer[] i = parseIntList(s, ' ');
622                                  if(i == -1) {                                  if(i.length != 2) {
623                                          getLogger().warning("Unknown VOICE_COUNT format");                                          getLogger().warning("Unknown VOICE_COUNT format");
624                                          return;                                          return;
625                                  }                                  }
626                                  int j = Integer.parseInt(s.substring(0, i));                                  VoiceCountEvent e = new VoiceCountEvent(this, i[0], i[1]);
                                 i = Integer.parseInt(s.substring(i + 1));  
                                 VoiceCountEvent e = new VoiceCountEvent(this, j, i);  
627                                  for(VoiceCountListener l : llVC) l.voiceCountChanged(e);                                  for(VoiceCountListener l : llVC) l.voiceCountChanged(e);
628                          } catch(NumberFormatException x) {                          } catch(Exception x) {
629                                  getLogger().log(Level.WARNING, "Unknown VOICE_COUNT format", x);                                  getLogger().log(Level.WARNING, "Unknown VOICE_COUNT format", x);
630                          }                          }
631                  } else if(s.startsWith("STREAM_COUNT:")) {                  } else if(s.startsWith("STREAM_COUNT:")) {
632                          try {                          try {
633                                  s = s.substring("STREAM_COUNT:".length());                                  s = s.substring("STREAM_COUNT:".length());
634                                  int i = s.indexOf(' ');                                  Integer[] i = parseIntList(s, ' ');
635                                  if(i == -1) {                                  if(i.length != 2) {
636                                          getLogger().warning("Unknown STREAM_COUNT format");                                          getLogger().warning("Unknown STREAM_COUNT format");
637                                          return;                                          return;
638                                  }                                  }
639                                  int j = Integer.parseInt(s.substring(0, i));                                  StreamCountEvent e = new StreamCountEvent(this, i[0], i[1]);
                                 i = Integer.parseInt(s.substring(i + 1));  
                                 StreamCountEvent e = new StreamCountEvent(this, j, i);  
640                                  for(StreamCountListener l : llSC) l.streamCountChanged(e);                                  for(StreamCountListener l : llSC) l.streamCountChanged(e);
641                          } catch(NumberFormatException x) {                          } catch(Exception x) {
642                                  getLogger().log(Level.WARNING, "Unknown STREAM_COUNT format", x);                                  getLogger().log(Level.WARNING, "Unknown STREAM_COUNT format", x);
643                          }                          }
644                  } else if(s.startsWith("BUFFER_FILL:")) {                  } else if(s.startsWith("BUFFER_FILL:")) {
# Line 407  public class Client { Line 646  public class Client {
646                                  s = s.substring("BUFFER_FILL:".length());                                  s = s.substring("BUFFER_FILL:".length());
647                                  int i = s.indexOf(' ');                                  int i = s.indexOf(' ');
648                                  if(i == -1) {                                  if(i == -1) {
649                                          getLogger().warning("Unknown STREAM_COUNT format");                                          getLogger().warning("Unknown BUFFER_FILL format");
650                                          return;                                          return;
651                                  }                                  }
652                                  int j = Integer.parseInt(s.substring(0, i));                                  int j = Integer.parseInt(s.substring(0, i));
# Line 416  public class Client { Line 655  public class Client {
655                                  BufferFillEvent e = new BufferFillEvent(this, j, v);                                  BufferFillEvent e = new BufferFillEvent(this, j, v);
656                                  for(BufferFillListener l : llBF) l.bufferFillChanged(e);                                  for(BufferFillListener l : llBF) l.bufferFillChanged(e);
657                          } catch(Exception x) {                          } catch(Exception x) {
658                                  getLogger().log(Level.WARNING, "Unknown STREAM_COUNT format", x);                                  getLogger().log(Level.WARNING, "Unknown BUFFER_FILL format", x);
659                          }                          }
660                  } else if(s.startsWith("CHANNEL_INFO:")) {                  } else if(s.startsWith("CHANNEL_INFO:")) {
661                          try {                          try {
# Line 424  public class Client { Line 663  public class Client {
663                                  ChannelInfoEvent e = new ChannelInfoEvent(this, i);                                  ChannelInfoEvent e = new ChannelInfoEvent(this, i);
664                                  for(ChannelInfoListener l : llCI) l.channelInfoChanged(e);                                  for(ChannelInfoListener l : llCI) l.channelInfoChanged(e);
665                          } catch(NumberFormatException x) {                          } catch(NumberFormatException x) {
666                                  getLogger().log(Level.WARNING, "Unknown STREAM_COUNT format", x);                                  getLogger().log(Level.WARNING, "Unknown CHANNEL_INFO format", x);
667                            }
668                    } else if(s.startsWith("TOTAL_STREAM_COUNT:")) {
669                            try {
670                                    s = s.substring("TOTAL_STREAM_COUNT:".length());
671                                    int i = Integer.parseInt(s);
672                                    TotalStreamCountEvent e = new TotalStreamCountEvent(this, i);
673                                    for(TotalStreamCountListener l : llTSC) l.totalStreamCountChanged(e);
674                            } catch(NumberFormatException x) {
675                                    getLogger().log (
676                                            Level.WARNING, "Unknown TOTAL_STREAM_COUNT format", x
677                                    );
678                            }
679                    } else if(s.startsWith("TOTAL_VOICE_COUNT:")) {
680                            try {
681                                    s = s.substring("TOTAL_VOICE_COUNT:".length());
682                                    int i = Integer.parseInt(s);
683                                    TotalVoiceCountEvent e = new TotalVoiceCountEvent(this, i);
684                                    for(TotalVoiceCountListener l : llTVC) l.totalVoiceCountChanged(e);
685                            } catch(NumberFormatException x) {
686                                    getLogger().log (
687                                            Level.WARNING, "Unknown TOTAL_VOICE_COUNT format", x
688                                    );
689                            }
690                    } else if(s.startsWith("AUDIO_OUTPUT_DEVICE_COUNT:")) {
691                            try {
692                                    s = s.substring("AUDIO_OUTPUT_DEVICE_COUNT:".length());
693                                    int i = Integer.parseInt(s);
694                                    ItemCountEvent e = new ItemCountEvent(this, i);
695                                    for(ItemCountListener l : llAODC) l.itemCountChanged(e);
696                            } catch(NumberFormatException x) {
697                                    getLogger().log (
698                                            Level.WARNING, "Unknown AUDIO_OUTPUT_DEVICE_COUNT format", x
699                                    );
700                          }                          }
701                    } else if(s.startsWith("AUDIO_OUTPUT_DEVICE_INFO:")) {
702                            try {
703                                    s = s.substring("AUDIO_OUTPUT_DEVICE_INFO:".length());
704                                    int i = Integer.parseInt(s);
705                                    ItemInfoEvent e = new ItemInfoEvent(this, i);
706                                    for(ItemInfoListener l : llAODI) l.itemInfoChanged(e);
707                            } catch(NumberFormatException x) {
708                                    getLogger().log (
709                                            Level.WARNING, "Unknown AUDIO_OUTPUT_DEVICE_INFO format", x
710                                    );
711                            }
712                    } else if(s.startsWith("MIDI_INPUT_DEVICE_COUNT:")) {
713                            try {
714                                    s = s.substring("MIDI_INPUT_DEVICE_COUNT:".length());
715                                    int i = Integer.parseInt(s);
716                                    ItemCountEvent e = new ItemCountEvent(this, i);
717                                    for(ItemCountListener l : llMIDC) l.itemCountChanged(e);
718                            } catch(NumberFormatException x) {
719                                    getLogger().log (
720                                            Level.WARNING, "Unknown MIDI_INPUT_DEVICE_COUNT format", x
721                                    );
722                            }
723                    } else if(s.startsWith("MIDI_INPUT_DEVICE_INFO:")) {
724                            try {
725                                    s = s.substring("MIDI_INPUT_DEVICE_INFO:".length());
726                                    int i = Integer.parseInt(s);
727                                    ItemInfoEvent e = new ItemInfoEvent(this, i);
728                                    for(ItemInfoListener l : llMIDI) l.itemInfoChanged(e);
729                            } catch(NumberFormatException x) {
730                                    getLogger().log (
731                                            Level.WARNING, "Unknown MIDI_INPUT_DEVICE_INFO format", x
732                                    );
733                            }
734                    } else if(s.startsWith("MIDI_INSTRUMENT_MAP_COUNT:")) {
735                            try {
736                                    s = s.substring("MIDI_INSTRUMENT_MAP_COUNT:".length());
737                                    int i = Integer.parseInt(s);
738                                    ItemCountEvent e = new ItemCountEvent(this, i);
739                                    for(ItemCountListener l : llMIMC) l.itemCountChanged(e);
740                            } catch(NumberFormatException x) {
741                                    getLogger().log (
742                                            Level.WARNING, "Unknown MIDI_INSTRUMENT_MAP_COUNT format", x
743                                    );
744                            }
745                    } else if(s.startsWith("MIDI_INSTRUMENT_MAP_INFO:")) {
746                            try {
747                                    s = s.substring("MIDI_INSTRUMENT_MAP_INFO:".length());
748                                    int i = Integer.parseInt(s);
749                                    ItemInfoEvent e = new ItemInfoEvent(this, i);
750                                    for(ItemInfoListener l : llMIMI) l.itemInfoChanged(e);
751                            } catch(NumberFormatException x) {
752                                    getLogger().log (
753                                            Level.WARNING, "Unknown MIDI_INSTRUMENT_MAP_INFO format", x
754                                    );
755                            }
756                    } else if(s.startsWith("MIDI_INSTRUMENT_COUNT:")) {
757                            try {
758                                    s = s.substring("MIDI_INSTRUMENT_COUNT:".length());
759                                    Integer[] i = parseIntList(s, ' ');
760                                    if(i.length != 2) {
761                                            getLogger().warning("Unknown MIDI_INSTRUMENT_COUNT format");
762                                            return;
763                                    }
764                                    
765                                    MidiInstrumentCountEvent e =
766                                            new MidiInstrumentCountEvent(this, i[0], i[1]);
767                                    
768                                    for(MidiInstrumentCountListener l : llMIC) {
769                                            l.instrumentCountChanged(e);
770                                    }
771                            } catch(Exception x) {
772                                    getLogger().log (
773                                            Level.WARNING, "Unknown MIDI_INSTRUMENT_COUNT format", x
774                                    );
775                            }
776                    } else if(s.startsWith("MIDI_INSTRUMENT_INFO:")) {
777                            try {
778                                    s = s.substring("MIDI_INSTRUMENT_INFO:".length());
779                                    Integer[] i = parseIntList(s, ' ');
780                                    if(i.length != 3) {
781                                            getLogger().warning("Unknown MIDI_INSTRUMENT_INFO format");
782                                            return;
783                                    }
784                                    
785                                    MidiInstrumentInfoEvent e =
786                                            new MidiInstrumentInfoEvent(this, i[0], i[1], i[2]);
787                                    for(MidiInstrumentInfoListener l : llMII) {
788                                            l.instrumentInfoChanged(e);
789                                    }
790                            } catch(Exception x) {
791                                    getLogger().log (
792                                            Level.WARNING, "Unknown MIDI_INSTRUMENT_INFO format", x
793                                    );
794                            }
795                    } else if(s.startsWith("FX_SEND_COUNT:")) {
796                            try {
797                                    s = s.substring("FX_SEND_COUNT:".length());
798                                    Integer[] i = parseIntList(s, ' ');
799                                    if(i.length != 2) {
800                                            getLogger().warning("Unknown FX_SEND_COUNT format");
801                                            return;
802                                    }
803                                    
804                                    FxSendCountEvent e = new FxSendCountEvent(this, i[0], i[1]);
805                                    
806                                    for(FxSendCountListener l : llFSC) l.fxSendCountChanged(e);
807                            } catch(Exception x) {
808                                    getLogger().log(Level.WARNING, "Unknown FX_SEND_COUNT format", x);
809                            }
810                    } else if(s.startsWith("FX_SEND_INFO:")) {
811                            try {
812                                    s = s.substring("FX_SEND_INFO:".length());
813                                    Integer[] i = parseIntList(s, ' ');
814                                    if(i.length != 2) {
815                                            getLogger().warning("Unknown FX_SEND_INFO format");
816                                            return;
817                                    }
818                                    
819                                    FxSendInfoEvent e = new FxSendInfoEvent(this, i[0], i[1]);
820                                    for(FxSendInfoListener l : llFSI) {
821                                            l.fxSendInfoChanged(e);
822                                    }
823                            } catch(Exception x) {
824                                    getLogger().log(Level.WARNING, "Unknown FX_SEND_INFO format", x);
825                            }
826                    } else if(s.startsWith("GLOBAL_INFO:")) {
827                            handleGlobalInfoEvent(s.substring("GLOBAL_INFO:".length()));
828                  } else if(s.startsWith("MISCELLANEOUS:")) {                  } else if(s.startsWith("MISCELLANEOUS:")) {
829                          s = s.substring("MISCELLANEOUS:".length());                          s = s.substring("MISCELLANEOUS:".length());
830                          MiscellaneousEvent e = new MiscellaneousEvent(this, s);                          MiscellaneousEvent e = new MiscellaneousEvent(this, s);
# Line 434  public class Client { Line 833  public class Client {
833          }          }
834                    
835          private void          private void
836            handleGlobalInfoEvent(String s) {
837                    try {
838                            if(s.startsWith("VOLUME ")) {
839                                    float f = Float.parseFloat(s.substring("VOLUME ".length()));
840                                    GlobalInfoEvent e = new GlobalInfoEvent(this, f);
841                                    for(GlobalInfoListener l : llGI) l.volumeChanged(e);
842                            }
843                    } catch(NumberFormatException x) {
844                            getLogger().log(Level.WARNING, "Unknown GLOBAL_INFO format", x);
845                    }
846            }
847            
848            private void
849          subscribe(String event) {          subscribe(String event) {
850                  if(!isConnected()) return;                  if(!getPrintOnlyMode()) {
851                            if(!isConnected()) return;
852                                    
853                  if(!eventThread.isAlive()) eventThread.start();                          if(!eventThread.isAlive()) eventThread.start();
854                    }
855                                    
856                  try {                  try {
857                          out.writeLine("SUBSCRIBE " + event);                          out.writeLine("SUBSCRIBE " + event);
858                          ResultSet rs = getEmptyResultSet();                          if(!getPrintOnlyMode()) getEmptyResultSet();
859                  } catch(Exception x) {                  } catch(Exception x) {
860                          getLogger().log (                          getLogger().log (
861                                  Level.WARNING,                                  Level.WARNING,
# Line 453  public class Client { Line 867  public class Client {
867                    
868          private void          private void
869          unsubscribe(String event) {          unsubscribe(String event) {
870                  if(!isConnected()) return;                  if(!getPrintOnlyMode() && !isConnected()) return;
871                                    
872                  try {                  try {
873                          out.writeLine("UNSUBSCRIBE " + event);                          out.writeLine("UNSUBSCRIBE " + event);
874                          ResultSet rs = getEmptyResultSet();                          if(!getPrintOnlyMode()) getEmptyResultSet();
875                  } catch(Exception x) {                  } catch(Exception x) {
876                          getLogger().log (                          getLogger().log (
877                                  Level.WARNING,                                  Level.WARNING,
# Line 469  public class Client { Line 883  public class Client {
883                    
884          /**          /**
885           * Registers the specified listener for receiving event messages.           * Registers the specified listener for receiving event messages.
886             * Listeners can be registered regardless of the connection state.
887             * @param l The <code>ItemCountListener</code> to register.
888             */
889            public synchronized void
890            addAudioDeviceCountListener(ItemCountListener l) {
891                    if(llAODC.isEmpty()) subscribe("AUDIO_OUTPUT_DEVICE_COUNT");
892                    llAODC.add(l);
893            }
894            
895            /**
896             * Removes the specified listener.
897             * Listeners can be removed regardless of the connection state.
898             * @param l The <code>ItemCountListener</code> to remove.
899             */
900            public synchronized void
901            removeAudioDeviceCountListener(ItemCountListener l) {
902                    boolean b = llAODC.remove(l);
903                    if(b && llAODC.isEmpty()) unsubscribe("AUDIO_OUTPUT_DEVICE_COUNT");
904            }
905            
906            /**
907             * Registers the specified listener for receiving event messages.
908             * Listeners can be registered regardless of the connection state.
909             * @param l The <code>ItemInfoListener</code> to register.
910             */
911            public synchronized void
912            addAudioDeviceInfoListener(ItemInfoListener l) {
913                    if(llAODI.isEmpty()) subscribe("AUDIO_OUTPUT_DEVICE_INFO");
914                    llAODI.add(l);
915            }
916            
917            /**
918             * Removes the specified listener.
919             * Listeners can be removed regardless of the connection state.
920             * @param l The <code>ItemInfoListener</code> to remove.
921             */
922            public synchronized void
923            removeAudioDeviceInfoListener(ItemInfoListener l) {
924                    boolean b = llAODI.remove(l);
925                    if(b && llAODI.isEmpty()) unsubscribe("AUDIO_OUTPUT_DEVICE_INFO");
926            }
927            
928            /**
929             * Registers the specified listener for receiving event messages.
930           * Listeners can be removed regardless of the connection state.           * Listeners can be removed regardless of the connection state.
931           * @param l The <code>BufferFillListener</code> to register.           * @param l The <code>BufferFillListener</code> to register.
932           */           */
# Line 536  public class Client { Line 994  public class Client {
994          /**          /**
995           * Registers the specified listener for receiving event messages.           * Registers the specified listener for receiving event messages.
996           * Listeners can be registered regardless of the connection state.           * Listeners can be registered regardless of the connection state.
997             * @param l The <code>FxSendCountListener</code> to register.
998             */
999            public synchronized void
1000            addFxSendCountListener(FxSendCountListener l) {
1001                    if(llFSC.isEmpty()) subscribe("FX_SEND_COUNT");
1002                    llFSC.add(l);
1003            }
1004            
1005            /**
1006             * Removes the specified listener.
1007             * Listeners can be removed regardless of the connection state.
1008             * @param l The <code>FxSendCountListener</code> to remove.
1009             */
1010            public synchronized void
1011            removeFxSendCountListener(FxSendCountListener l) {
1012                    boolean b = llFSC.remove(l);
1013                    if(b && llFSC.isEmpty()) unsubscribe("FX_SEND_COUNT");
1014            }
1015            
1016            /**
1017             * Registers the specified listener for receiving event messages.
1018             * Listeners can be registered regardless of the connection state.
1019             * @param l The <code>FxSendInfoListener</code> to register.
1020             */
1021            public synchronized void
1022            addFxSendInfoListener(FxSendInfoListener l) {
1023                    if(llFSI.isEmpty()) subscribe("FX_SEND_INFO");
1024                    llFSI.add(l);
1025            }
1026            
1027            /**
1028             * Removes the specified listener.
1029             * Listeners can be removed regardless of the connection state.
1030             * @param l The <code>FxSendInfoListener</code> to remove.
1031             */
1032            public synchronized void
1033            removeFxSendInfoListener(FxSendInfoListener l) {
1034                    boolean b = llFSI.remove(l);
1035                    if(b && llFSI.isEmpty()) unsubscribe("FX_SEND_INFO");
1036            }
1037            
1038            /**
1039             * Registers the specified listener for receiving event messages.
1040             * Listeners can be registered regardless of the connection state.
1041             * @param l The <code>ItemCountListener</code> to register.
1042             */
1043            public synchronized void
1044            addMidiDeviceCountListener(ItemCountListener l) {
1045                    if(llMIDC.isEmpty()) subscribe("MIDI_INPUT_DEVICE_COUNT");
1046                    llMIDC.add(l);
1047            }
1048            
1049            /**
1050             * Removes the specified listener.
1051             * Listeners can be removed regardless of the connection state.
1052             * @param l The <code>ItemCountListener</code> to remove.
1053             */
1054            public synchronized void
1055            removeMidiDeviceCountListener(ItemCountListener l) {
1056                    boolean b = llMIDC.remove(l);
1057                    if(b && llMIDC.isEmpty()) unsubscribe("MIDI_INPUT_DEVICE_COUNT");
1058            }
1059            
1060            /**
1061             * Registers the specified listener for receiving event messages.
1062             * Listeners can be registered regardless of the connection state.
1063             * @param l The <code>ItemInfoListener</code> to register.
1064             */
1065            public synchronized void
1066            addMidiDeviceInfoListener(ItemInfoListener l) {
1067                    if(llMIDI.isEmpty()) subscribe("MIDI_INPUT_DEVICE_INFO");
1068                    llMIDI.add(l);
1069            }
1070            
1071            /**
1072             * Removes the specified listener.
1073             * Listeners can be removed regardless of the connection state.
1074             * @param l The <code>ItemInfoListener</code> to remove.
1075             */
1076            public synchronized void
1077            removeMidiDeviceInfoListener(ItemInfoListener l) {
1078                    boolean b = llMIDI.remove(l);
1079                    if(b && llMIDI.isEmpty()) unsubscribe("MIDI_INPUT_DEVICE_INFO");
1080            }
1081            
1082            /**
1083             * Registers the specified listener for receiving event messages.
1084             * Listeners can be registered regardless of the connection state.
1085           * @param l The <code>MiscellaneousListener</code> to register.           * @param l The <code>MiscellaneousListener</code> to register.
1086           */           */
1087          public synchronized void          public synchronized void
# Line 600  public class Client { Line 1146  public class Client {
1146          }          }
1147                    
1148          /**          /**
1149             * Registers the specified listener for receiving event messages.
1150             * Listeners can be registered regardless of the connection state.
1151             * @param l The <code>TotalStreamCountListener</code> to register.
1152             */
1153            public synchronized void
1154            addTotalStreamCountListener(TotalStreamCountListener l) {
1155                    if(llTSC.isEmpty()) subscribe("TOTAL_STREAM_COUNT");
1156                    llTSC.add(l);
1157            }
1158            
1159            /**
1160             * Removes the specified listener.
1161             * Listeners can be removed regardless of the connection state.
1162             * @param l The <code>TotalStreamCountListener</code> to remove.
1163             */
1164            public synchronized void
1165            removeTotalStreamCountListener(TotalStreamCountListener l) {
1166                    boolean b = llTSC.remove(l);
1167                    if(b && llTSC.isEmpty()) unsubscribe("TOTAL_STREAM_COUNT");
1168            }
1169            
1170            /**
1171             * Registers the specified listener for receiving event messages.
1172             * Listeners can be registered regardless of the connection state.
1173             * @param l The <code>TotalVoiceCountListener</code> to register.
1174             */
1175            public synchronized void
1176            addTotalVoiceCountListener(TotalVoiceCountListener l) {
1177                    if(llTVC.isEmpty()) subscribe("TOTAL_VOICE_COUNT");
1178                    llTVC.add(l);
1179            }
1180            
1181            /**
1182             * Removes the specified listener.
1183             * Listeners can be removed regardless of the connection state.
1184             * @param l The <code>TotalVoiceCountListener</code> to remove.
1185             */
1186            public synchronized void
1187            removeTotalVoiceCountListener(TotalVoiceCountListener l) {
1188                    boolean b = llTVC.remove(l);
1189                    if(b && llTVC.isEmpty()) unsubscribe("TOTAL_VOICE_COUNT");
1190            }
1191            
1192            /**
1193             * Registers the specified listener for receiving event messages.
1194             * Listeners can be registered regardless of the connection state.
1195             * @param l The <code>ItemCountListener</code> to register.
1196             */
1197            public synchronized void
1198            addMidiInstrumentMapCountListener(ItemCountListener l) {
1199                    if(llMIMC.isEmpty()) subscribe("MIDI_INSTRUMENT_MAP_COUNT");
1200                    llMIMC.add(l);
1201            }
1202            
1203            /**
1204             * Removes the specified listener.
1205             * Listeners can be removed regardless of the connection state.
1206             * @param l The <code>ItemCountListener</code> to remove.
1207             */
1208            public synchronized void
1209            removeMidiInstrumentMapCountListener(ItemCountListener l) {
1210                    boolean b = llMIMC.remove(l);
1211                    if(b && llMIMC.isEmpty()) unsubscribe("MIDI_INSTRUMENT_MAP_COUNT");
1212            }
1213            
1214            /**
1215             * Registers the specified listener for receiving event messages.
1216             * Listeners can be registered regardless of the connection state.
1217             * @param l The <code>ItemInfoListener</code> to register.
1218             */
1219            public synchronized void
1220            addMidiInstrumentMapInfoListener(ItemInfoListener l) {
1221                    if(llMIMI.isEmpty()) subscribe("MIDI_INSTRUMENT_MAP_INFO");
1222                    llMIMI.add(l);
1223            }
1224            
1225            /**
1226             * Removes the specified listener.
1227             * Listeners can be removed regardless of the connection state.
1228             * @param l The <code>ItemInfoListener</code> to remove.
1229             */
1230            public synchronized void
1231            removeMidiInstrumentMapInfoListener(ItemInfoListener l) {
1232                    boolean b = llMIMI.remove(l);
1233                    if(b && llMIMI.isEmpty()) unsubscribe("MIDI_INSTRUMENT_MAP_INFO");
1234            }
1235            
1236            /**
1237             * Registers the specified listener for receiving event messages.
1238             * Listeners can be registered regardless of the connection state.
1239             * @param l The <code>MidiInstrumentCountListener</code> to register.
1240             */
1241            public synchronized void
1242            addMidiInstrumentCountListener(MidiInstrumentCountListener l) {
1243                    if(llMIC.isEmpty()) subscribe("MIDI_INSTRUMENT_COUNT");
1244                    llMIC.add(l);
1245            }
1246            
1247            /**
1248             * Removes the specified listener.
1249             * Listeners can be removed regardless of the connection state.
1250             * @param l The <code>MidiInstrumentCountListener</code> to remove.
1251             */
1252            public synchronized void
1253            removeMidiInstrumentCountListener(MidiInstrumentCountListener l) {
1254                    boolean b = llMIC.remove(l);
1255                    if(b && llMIC.isEmpty()) unsubscribe("MIDI_INSTRUMENT_COUNT");
1256            }
1257            
1258            /**
1259             * Registers the specified listener for receiving event messages.
1260             * Listeners can be registered regardless of the connection state.
1261             * @param l The <code>MidiInstrumentInfoListener</code> to register.
1262             */
1263            public synchronized void
1264            addMidiInstrumentInfoListener(MidiInstrumentInfoListener l) {
1265                    if(llMII.isEmpty()) subscribe("MIDI_INSTRUMENT_INFO");
1266                    llMII.add(l);
1267            }
1268            
1269            /**
1270             * Removes the specified listener.
1271             * Listeners can be removed regardless of the connection state.
1272             * @param l The <code>MidiInstrumentInfoListener</code> to remove.
1273             */
1274            public synchronized void
1275            removeMidiInstrumentInfoListener(MidiInstrumentInfoListener l) {
1276                    boolean b = llMII.remove(l);
1277                    if(b && llMII.isEmpty()) unsubscribe("MIDI_INSTRUMENT_INFO");
1278            }
1279            
1280            /**
1281             * Registers the specified listener for receiving event messages.
1282             * Listeners can be registered regardless of the connection state.
1283             * @param l The <code>InstrumentsDbListener</code> to register.
1284             */
1285            public synchronized void
1286            addInstrumentsDbListener(InstrumentsDbListener l) {
1287                    if(llID.isEmpty()) {
1288                            subscribe("DB_INSTRUMENT_DIRECTORY_COUNT");
1289                            subscribe("DB_INSTRUMENT_DIRECTORY_INFO");
1290                            subscribe("DB_INSTRUMENT_COUNT");
1291                            subscribe("DB_INSTRUMENT_INFO");
1292                            subscribe("DB_INSTRUMENTS_JOB_INFO");
1293                    }
1294                    llID.add(l);
1295            }
1296            
1297            /**
1298             * Removes the specified listener.
1299             * Listeners can be removed regardless of the connection state.
1300             * @param l The <code>InstrumentsDbListener</code> to remove.
1301             */
1302            public synchronized void
1303            removeInstrumentsDbListener(InstrumentsDbListener l) {
1304                    boolean b = llID.remove(l);
1305                    if(b && llID.isEmpty()) {
1306                            unsubscribe("DB_INSTRUMENT_DIRECTORY_COUNT");
1307                            unsubscribe("DB_INSTRUMENT_DIRECTORY_INFO");
1308                            unsubscribe("DB_INSTRUMENT_COUNT");
1309                            unsubscribe("DB_INSTRUMENT_INFO");
1310                            unsubscribe("DB_INSTRUMENTS_JOB_INFO");
1311                    }
1312            }
1313            
1314            /**
1315             * Registers the specified listener for receiving event messages.
1316             * Listeners can be registered regardless of the connection state.
1317             * @param l The <code>GlobalInfoListener</code> to register.
1318             */
1319            public synchronized void
1320            addGlobalInfoListener(GlobalInfoListener l) {
1321                    if(llGI.isEmpty()) subscribe("GLOBAL_INFO");
1322                    llGI.add(l);
1323            }
1324            
1325            /**
1326             * Removes the specified listener.
1327             * Listeners can be removed regardless of the connection state.
1328             * @param l The <code>GlobalInfoListener</code> to remove.
1329             */
1330            public synchronized void
1331            removeGlobalInfoListener(GlobalInfoListener l) {
1332                    boolean b = llGI.remove(l);
1333                    if(b && llGI.isEmpty()) unsubscribe("GLOBAL_INFO");
1334            }
1335            
1336            /**
1337           * Gets the number of all audio output drivers currently           * Gets the number of all audio output drivers currently
1338           * available for the LinuxSampler instance.           * available for the LinuxSampler instance.
1339           * @return The number of all audio output drivers currently           * @return The number of all audio output drivers currently
# Line 612  public class Client { Line 1346  public class Client {
1346          getAudioOutputDriverCount() throws IOException, LscpException, LSException {          getAudioOutputDriverCount() throws IOException, LscpException, LSException {
1347                  verifyConnection();                  verifyConnection();
1348                  out.writeLine("GET AVAILABLE_AUDIO_OUTPUT_DRIVERS");                  out.writeLine("GET AVAILABLE_AUDIO_OUTPUT_DRIVERS");
1349                    
1350                    if(getPrintOnlyMode()) return -1;
1351                    
1352                  String s = getSingleLineResultSet().getResult();                  String s = getSingleLineResultSet().getResult();
1353                  return parseInt(s);                  return parseInt(s);
1354          }          }
1355            
1356          /**          /**
1357           * Gets all audio output drivers currently available for the LinuxSampler instance.           * Gets all audio output drivers currently available for the LinuxSampler instance.
1358           *           *
1359           * @return <code>String</code> array with all audio output drivers currently available for           * @return <code>AudioOutputDriver</code> array containing all audio output drivers
1360           * the LinuxSampler instance.           * currently available for the LinuxSampler instance.
1361           *           *
1362           * @throws IOException If an I/O error occurs.           * @throws IOException If an I/O error occurs.
1363           * @throws LscpException If LSCP protocol corruption occurs.           * @throws LscpException If LSCP protocol corruption occurs.
1364           * @throws LSException If some other error occurs.           * @throws LSException If some other error occurs.
1365           */           */
1366          public synchronized String[]          public synchronized AudioOutputDriver[]
1367          getAudioOutputDrivers() throws IOException, LscpException, LSException {          getAudioOutputDrivers() throws IOException, LscpException, LSException {
1368                    String[] drivers = getAudioOutputDriverNames();
1369                    if(getPrintOnlyMode()) return null;
1370                    
1371                    AudioOutputDriver[] aod = new AudioOutputDriver[drivers.length];
1372                    
1373                    for(int i = 0; i < aod.length; i++) aod[i] = getAudioOutputDriverInfo(drivers[i]);
1374                    
1375                    return aod;
1376            }
1377            
1378            /**
1379             * Gets all audio output drivers currently available for the LinuxSampler instance.
1380             *
1381             * @return <code>String</code> array containing all audio output drivers currently
1382             * available for the LinuxSampler instance.
1383             *
1384             * @throws IOException If an I/O error occurs.
1385             * @throws LscpException If LSCP protocol corruption occurs.
1386             * @throws LSException If some other error occurs.
1387             */
1388            private synchronized String[]
1389            getAudioOutputDriverNames() throws IOException, LscpException, LSException {
1390                  verifyConnection();                  verifyConnection();
1391                  out.writeLine("LIST AVAILABLE_AUDIO_OUTPUT_DRIVERS");                  out.writeLine("LIST AVAILABLE_AUDIO_OUTPUT_DRIVERS");
1392                    if(getPrintOnlyMode()) return null;
1393                  return parseList(getSingleLineResultSet().getResult());                  return parseList(getSingleLineResultSet().getResult());
1394          }          }
1395                    
1396          /**          /**
1397           * Gets detailed information about a specific audio output driver.           * Gets detailed information about a specific audio output driver.
1398           * @param driverName The name of the audio output driver.           * @param driverName The name of the audio output driver.
1399           *           * @param depList An optional list of dependences parameters.
1400           * @return An <code>AudioOutputDriver</code> object containing           * @return An <code>AudioOutputDriver</code> object containing
1401           * information about the specified audio output driver.           * information about the specified audio output driver.
1402           *           *
# Line 643  public class Client { Line 1404  public class Client {
1404           * @throws LscpException If LSCP protocol corruption occurs.           * @throws LscpException If LSCP protocol corruption occurs.
1405           * @throws LSException If there is no driver with name <code>driverName</code>.           * @throws LSException If there is no driver with name <code>driverName</code>.
1406           *           *
1407           * @see #getAudioOutputDrivers           * @see #getAudioOutputDriverNames
1408           */           */
1409          public synchronized AudioOutputDriver          public synchronized AudioOutputDriver
1410          getAudioOutputDriverInfo(String driverName) throws IOException, LscpException, LSException {          getAudioOutputDriverInfo(String driverName, Parameter... depList)
1411                                            throws IOException, LscpException, LSException {
1412                    
1413                  verifyConnection();                  verifyConnection();
1414                  out.writeLine("GET AUDIO_OUTPUT_DRIVER INFO " + driverName);                  out.writeLine("GET AUDIO_OUTPUT_DRIVER INFO " + driverName);
1415                    if(getPrintOnlyMode()) return null;
1416                    
1417                  ResultSet rs = getMultiLineResultSet();                  ResultSet rs = getMultiLineResultSet();
1418                  AudioOutputDriver aod = new AudioOutputDriver(rs.getMultiLineResult());                  AudioOutputDriver aod = new AudioOutputDriver(rs.getMultiLineResult());
1419                  aod.setName(driverName);                  aod.setName(driverName);
1420                                    
1421                  for(String s : aod.getParameterNames())                  for(String s : aod.getParameterNames())
1422                          aod.addParameter(getAudioOutputDriverParameterInfo(driverName, s));                          aod.addParameter(getAudioOutputDriverParameterInfo(driverName, s, depList));
1423                                    
1424                  return aod;                  return aod;
1425          }          }
# Line 688  public class Client { Line 1453  public class Client {
1453                  StringBuffer args = new StringBuffer(driver);                  StringBuffer args = new StringBuffer(driver);
1454                  args.append(' ').append(param);                  args.append(' ').append(param);
1455                                    
1456                  for(Parameter p : deplist)                  for(Parameter p : deplist) {
1457                            if(p == null || p.getName() == null || p.getValue() == null) continue;
1458                          args.append(' ').append(p.getName()).append('=').append(p.getStringValue());                          args.append(' ').append(p.getName()).append('=').append(p.getStringValue());
1459                    }
1460                                    
1461                  out.writeLine("GET AUDIO_OUTPUT_DRIVER_PARAMETER INFO " + args.toString());                  out.writeLine("GET AUDIO_OUTPUT_DRIVER_PARAMETER INFO " + args.toString());
1462                    if(getPrintOnlyMode()) return null;
1463                                    
1464                  ResultSet rs = getMultiLineResultSet();                  ResultSet rs = getMultiLineResultSet();
1465                                    
# Line 705  public class Client { Line 1473  public class Client {
1473                          if(!multi) prm = new BoolParameter(lnS);                          if(!multi) prm = new BoolParameter(lnS);
1474                          else prm = new BoolListParameter(lnS);                          else prm = new BoolListParameter(lnS);
1475                          prm.setName(param);                          prm.setName(param);
1476                            prm.setValue(prm.getDefault());
1477                          return prm;                          return prm;
1478                  case INT:                  case INT:
1479                          if(!multi) prm = new IntParameter(lnS);                          if(!multi) prm = new IntParameter(lnS);
1480                          else prm = new IntListParameter(lnS);                          else prm = new IntListParameter(lnS);
1481                          prm.setName(param);                          prm.setName(param);
1482                            prm.setValue(prm.getDefault());
1483                          return prm;                          return prm;
1484                  case FLOAT:                  case FLOAT:
1485                          if(!multi) prm = new FloatParameter(lnS);                          if(!multi) prm = new FloatParameter(lnS);
1486                          else prm = new FloatListParameter(lnS);                          else prm = new FloatListParameter(lnS);
1487                          prm.setName(param);                          prm.setName(param);
1488                            prm.setValue(prm.getDefault());
1489                          return prm;                          return prm;
1490                  case STRING:                  case STRING:
1491                          if(!multi) prm = new StringParameter(lnS);                          if(!multi) prm = new StringParameter(lnS);
1492                          else prm = new StringListParameter(lnS);                          else prm = new StringListParameter(lnS);
1493                          prm.setName(param);                          prm.setName(param);
1494                            prm.setValue(prm.getDefault());
1495                          return prm;                          return prm;
1496                  default: throw new LscpException(LscpI18n.getLogMsg("Client.unknownPrmType!"));                  default: throw new LscpException(LscpI18n.getLogMsg("Client.unknownPrmType!"));
1497                  }                  }
# Line 745  public class Client { Line 1517  public class Client {
1517                  verifyConnection();                  verifyConnection();
1518                  StringBuffer args = new StringBuffer(aoDriver);                  StringBuffer args = new StringBuffer(aoDriver);
1519                                    
1520                  for(Parameter p : paramList)                  for(Parameter p : paramList) {
1521                            if(p == null || p.getName() == null || p.getValue() == null) continue;
1522                          args.append(' ').append(p.getName()).append('=').append(p.getStringValue());                          args.append(' ').append(p.getName()).append('=').append(p.getStringValue());
1523                    }
1524                                    
1525                  out.writeLine("CREATE AUDIO_OUTPUT_DEVICE " + args.toString());                  out.writeLine("CREATE AUDIO_OUTPUT_DEVICE " + args.toString());
1526                    if(getPrintOnlyMode()) return -1;
1527                    
1528                  ResultSet rs = getEmptyResultSet();                  ResultSet rs = getEmptyResultSet();
1529                                    
1530                  return rs.getIndex();                  return rs.getIndex();
# Line 756  public class Client { Line 1532  public class Client {
1532                    
1533          /**          /**
1534           * Destroys already created audio output device.           * Destroys already created audio output device.
1535           * @param deviceID The ID of the audio output device to be destroyed.           * @param deviceId The ID of the audio output device to be destroyed.
1536           * @throws IOException If some I/O error occurs.           * @throws IOException If some I/O error occurs.
1537           * @throws LSException If the destroying of the audio output device failed.           * @throws LSException If the destroying of the audio output device failed.
1538           * @throws LscpException If LSCP protocol corruption occurs.           * @throws LscpException If LSCP protocol corruption occurs.
1539           * @see #getAudioOutputDevices           * @see #getAudioOutputDevices
1540           */           */
1541          public synchronized void          public synchronized void
1542          destroyAudioOutputDevice(int deviceID) throws IOException, LSException, LscpException {          destroyAudioOutputDevice(int deviceId) throws IOException, LSException, LscpException {
1543                  verifyConnection();                  verifyConnection();
1544                  out.writeLine("DESTROY AUDIO_OUTPUT_DEVICE " + deviceID);                  out.writeLine("DESTROY AUDIO_OUTPUT_DEVICE " + deviceId);
1545                    if(getPrintOnlyMode()) return;
1546                    
1547                  ResultSet rs = getEmptyResultSet();                  ResultSet rs = getEmptyResultSet();
1548          }          }
1549                    
1550            /**
1551             * Enables/disables the specified audio output device.
1552             * @param deviceId The ID of the audio output device to be enabled/disabled.
1553             * @param enable If <code>true</code> the audio output device is enabled,
1554             * else the device is disabled.
1555             * @throws IOException If some I/O error occurs.
1556             * @throws LSException If there is no audio output
1557             * device with numerical ID <code>deviceId</code>.
1558             * @throws LscpException If LSCP protocol corruption occurs.
1559             */
1560            public void
1561            enableAudioOutputDevice(int deviceId, boolean enable)
1562                                    throws IOException, LSException, LscpException {
1563                    
1564                    setAudioOutputDeviceParameter(deviceId, new BoolParameter("ACTIVE", enable));
1565            }
1566            
1567          /**          /**
1568           * Gets the current number of all created audio output devices.           * Gets the current number of all created audio output devices.
1569           * @return The current number of all created audio output devices.           * @return The current number of all created audio output devices.
# Line 780  public class Client { Line 1575  public class Client {
1575          getAudioOutputDeviceCount() throws IOException, LscpException, LSException {          getAudioOutputDeviceCount() throws IOException, LscpException, LSException {
1576                  verifyConnection();                  verifyConnection();
1577                  out.writeLine("GET AUDIO_OUTPUT_DEVICES");                  out.writeLine("GET AUDIO_OUTPUT_DEVICES");
1578                    if(getPrintOnlyMode()) return -1;
1579                    
1580                  String s = getSingleLineResultSet().getResult();                  String s = getSingleLineResultSet().getResult();
1581                  return parseInt(s);                  return parseInt(s);
1582          }          }
1583                                    
1584          /**          /**
1585             * Gets a list of all created audio output devices.
1586             * @return An <code>AudioOutputDevice</code> array
1587             * providing all created audio output devices.
1588             * @throws IOException If some I/O error occurs.
1589             * @throws LscpException If LSCP protocol corruption occurs.
1590             * @throws LSException If some other error occurs.
1591             */
1592            public synchronized AudioOutputDevice[]
1593            getAudioOutputDevices() throws IOException, LscpException, LSException {
1594                    Integer[] idS = getAudioOutputDeviceIDs();
1595                    if(getPrintOnlyMode()) return null;
1596                    
1597                    AudioOutputDevice[] devices = new AudioOutputDevice[idS.length];
1598                    
1599                    for(int i = 0; i < devices.length; i++)
1600                            devices[i] = getAudioOutputDeviceInfo(idS[i]);
1601                    
1602                    return devices;
1603            }
1604            
1605            /**
1606           * Gets a list of numerical IDs of all created audio output devices.           * Gets a list of numerical IDs of all created audio output devices.
1607           * @return An <code>Integer</code> array with numerical IDs of           * @return An <code>Integer</code> array providing the numerical IDs of
1608           * all created audio output devices.           * all created audio output devices.
1609           * @throws IOException If some I/O error occurs.           * @throws IOException If some I/O error occurs.
1610           * @throws LscpException If LSCP protocol corruption occurs.           * @throws LscpException If LSCP protocol corruption occurs.
1611           * @throws LSException If some other error occurs.           * @throws LSException If some other error occurs.
1612           */           */
1613          public synchronized Integer[]          public synchronized Integer[]
1614          getAudioOutputDevices() throws IOException, LscpException, LSException {          getAudioOutputDeviceIDs() throws IOException, LscpException, LSException {
1615                  verifyConnection();                  verifyConnection();
1616                  out.writeLine("LIST AUDIO_OUTPUT_DEVICES");                  out.writeLine("LIST AUDIO_OUTPUT_DEVICES");
1617                    if(getPrintOnlyMode()) return null;
1618                    
1619                  return parseIntList(getSingleLineResultSet().getResult());                  return parseIntList(getSingleLineResultSet().getResult());
1620          }          }
1621                    
1622          /**          /**
1623           * Gets the current settings of a specific, already created audio output device.           * Gets the current settings of a specific, already created audio output device.
1624           *           *
1625           * @param deviceID Specifies the numerical ID of the audio output device.           * @param deviceId Specifies the numerical ID of the audio output device.
1626           *           *
1627           * @return An <code>AudioOutputDevice</code> instance containing information           * @return An <code>AudioOutputDevice</code> instance containing information
1628           * about the specified device.           * about the specified device.
# Line 810  public class Client { Line 1630  public class Client {
1630           * @throws IOException If some I/O error occurs.           * @throws IOException If some I/O error occurs.
1631           * @throws LscpException If LSCP protocol corruption occurs.           * @throws LscpException If LSCP protocol corruption occurs.
1632           * @throws LSException If there is no audio output device           * @throws LSException If there is no audio output device
1633           * with device id <code>deviceID</code>.           * with device id <code>deviceId</code>.
1634           *           *
1635           * @see #getAudioOutputDevices           * @see #getAudioOutputDevices
1636           */           */
1637          public synchronized AudioOutputDevice          public synchronized AudioOutputDevice
1638          getAudioOutputDeviceInfo(int deviceID) throws IOException, LscpException, LSException {          getAudioOutputDeviceInfo(int deviceId) throws IOException, LscpException, LSException {
1639                  verifyConnection();                  verifyConnection();
1640                  out.writeLine("GET AUDIO_OUTPUT_DEVICE INFO " + deviceID);                  out.writeLine("GET AUDIO_OUTPUT_DEVICE INFO " + deviceId);
1641                    if(getPrintOnlyMode()) return null;
1642                                    
1643                  ResultSet rs = getMultiLineResultSet();                  ResultSet rs = getMultiLineResultSet();
1644                                    
1645                  String[] lnS = rs.getMultiLineResult();                  String[] lnS = rs.getMultiLineResult();
1646                                    
1647                  AudioOutputDevice aod = new AudioOutputDevice();                  AudioOutputDevice aod = new AudioOutputDevice();
1648                    aod.setDeviceId(deviceId);
1649                  Parameter<Integer> channels;                  Parameter<Integer> channels;
1650                  Parameter<Integer> samplerate;                  Parameter<Integer> samplerate;
1651                                    
# Line 838  public class Client { Line 1660  public class Client {
1660                                  s = s.substring("CHANNELS: ".length(), s.length());                                  s = s.substring("CHANNELS: ".length(), s.length());
1661                                  channels.parseValue(s);                                  channels.parseValue(s);
1662                                  aod.setChannelsParameter(channels);                                  aod.setChannelsParameter(channels);
1663                                    int count = channels.getValue() > 0 ? channels.getValue() : 0;
1664                                    AudioOutputChannel[] aoc = new AudioOutputChannel[count];
1665                                    for(int i = 0; i < count; i++) {
1666                                            aoc[i] = getAudioOutputChannelInfo(deviceId, i);
1667                                    }
1668                                    aod.setAudioChannels(aoc);
1669                          } else if(s.startsWith("SAMPLERATE: ")) {                          } else if(s.startsWith("SAMPLERATE: ")) {
1670                                  samplerate = (Parameter<Integer>)                                  samplerate = (Parameter<Integer>)
1671                                          getAudioOutputDriverParameterInfo(drv, "SAMPLERATE");                                          getAudioOutputDriverParameterInfo(drv, "SAMPLERATE");
# Line 872  public class Client { Line 1700  public class Client {
1700          /**          /**
1701           * Alters a specific setting of a created audio output device.           * Alters a specific setting of a created audio output device.
1702           *           *
1703           * @param deviceID The numerical ID of the audio output device.           * @param deviceId The numerical ID of the audio output device.
1704           * @param prm A <code>Parameter</code> instance containing the name of the parameter           * @param prm A <code>Parameter</code> instance containing the name of the parameter
1705           * and the new value for this parameter.           * and the new value for this parameter.
1706           *           *
# Line 880  public class Client { Line 1708  public class Client {
1708           * @throws LscpException If LSCP protocol corruption occurs.           * @throws LscpException If LSCP protocol corruption occurs.
1709           * @throws LSException If           * @throws LSException If
1710           * <ul>           * <ul>
1711           * <li>There is no audio output device with numerical ID <code>deviceID</code>;           * <li>There is no audio output device with numerical ID <code>deviceId</code>;
1712           * <li>There is no device parameter with the specified name;           * <li>There is no device parameter with the specified name;
1713           * <li>The device parameter is readonly;           * <li>The device parameter is readonly;
1714           * <li>The device parameter is from different type.           * <li>The device parameter is from different type.
# Line 890  public class Client { Line 1718  public class Client {
1718           * @see #getAudioOutputDeviceInfo           * @see #getAudioOutputDeviceInfo
1719           */           */
1720          public synchronized void          public synchronized void
1721          setAudioOutputDeviceParameter(int deviceID, Parameter prm)          setAudioOutputDeviceParameter(int deviceId, Parameter prm)
1722                                                  throws IOException, LscpException, LSException {                                                  throws IOException, LscpException, LSException {
1723                                    
1724                  verifyConnection();                  verifyConnection();
1725                  String kv = prm.getName() + '=' + prm.getStringValue();                  String kv = prm.getName() + '=' + prm.getStringValue();
1726                  out.writeLine("SET AUDIO_OUTPUT_DEVICE_PARAMETER " + deviceID + ' ' + kv);                  out.writeLine("SET AUDIO_OUTPUT_DEVICE_PARAMETER " + deviceId + ' ' + kv);
1727                    if(getPrintOnlyMode()) return;
1728                                    
1729                  ResultSet rs = getEmptyResultSet();                  ResultSet rs = getEmptyResultSet();
1730          }          }
1731                    
1732          /**          /**
1733             * Changes the channel number of the speicifed audio output device.
1734             * @param deviceId The numerical ID of the audio output device.
1735             * @param channels The new number of audio output channels.
1736             *
1737             * @throws IOException If an I/O error occurs.
1738             * @throws LscpException If LSCP protocol corruption occurs.
1739             * @throws LSException If there is no device with ID <code>deviceId</code> or
1740             * if <code>channels</code> number is out of range.
1741             *
1742             * @see #getAudioOutputChannelInfo
1743             */
1744            public synchronized void
1745            setAudioOutputChannelCount(int deviceId, int channels)
1746                                            throws IOException, LscpException, LSException {
1747                    
1748                    setAudioOutputDeviceParameter(deviceId, new IntParameter("CHANNELS", channels));
1749            }
1750            
1751            /**
1752           * Gets information about an audio channel.           * Gets information about an audio channel.
1753           *           *
1754           * @param deviceID The numerical ID of the audio output device.           * @param deviceId The numerical ID of the audio output device.
1755           * @param audioChn The audio channel number.           * @param audioChn The audio channel number.
1756           *           *
1757           * @return An <code>AudioOutputChannel</code> instance containing the           * @return An <code>AudioOutputChannel</code> instance containing the
# Line 913  public class Client { Line 1761  public class Client {
1761           * @throws LscpException If LSCP protocol corruption occurs.           * @throws LscpException If LSCP protocol corruption occurs.
1762           * @throws LSException If           * @throws LSException If
1763           * <ul>           * <ul>
1764           * <li>There is no audio output device with numerical ID <code>deviceID</code>;           * <li>There is no audio output device with numerical ID <code>deviceId</code>;
1765           * <li><code>audioChn</code> is not a valid channel number;           * <li><code>audioChn</code> is not a valid channel number;
1766           * </ul>           * </ul>
1767           *           *
# Line 921  public class Client { Line 1769  public class Client {
1769           * @see #getAudioOutputDeviceInfo           * @see #getAudioOutputDeviceInfo
1770           */           */
1771          public synchronized AudioOutputChannel          public synchronized AudioOutputChannel
1772          getAudioOutputChannelInfo(int deviceID, int audioChn)          getAudioOutputChannelInfo(int deviceId, int audioChn)
1773                                                  throws IOException, LscpException, LSException {                                                  throws IOException, LscpException, LSException {
1774                                    
1775                  verifyConnection();                  verifyConnection();
1776                  out.writeLine("GET AUDIO_OUTPUT_CHANNEL INFO " + deviceID + ' ' + audioChn);                  out.writeLine("GET AUDIO_OUTPUT_CHANNEL INFO " + deviceId + ' ' + audioChn);
1777                    if(getPrintOnlyMode()) return null;
1778                                    
1779                  ResultSet rs = getMultiLineResultSet();                  ResultSet rs = getMultiLineResultSet();
1780                                    
# Line 934  public class Client { Line 1783  public class Client {
1783                  String[] lnS = rs.getMultiLineResult();                  String[] lnS = rs.getMultiLineResult();
1784                  for(String s : lnS) {                  for(String s : lnS) {
1785                          if(s.startsWith("NAME: ")) {                          if(s.startsWith("NAME: ")) {
1786                                  aoc.setName(s.substring("NAME: ".length()));                                  s = s.substring("NAME: ".length());
1787                                    Parameter<String> prm = getAudioOutputChannelParameterInfo (
1788                                            deviceId, audioChn, "NAME"
1789                                    );
1790                                    prm.setValue(removeQuotation(s));
1791                                    aoc.setNameParameter(prm);
1792                          } else if(s.startsWith("IS_MIX_CHANNEL: ")) {                          } else if(s.startsWith("IS_MIX_CHANNEL: ")) {
1793                                  s = s.substring("IS_MIX_CHANNEL: ".length());                                  s = s.substring("IS_MIX_CHANNEL: ".length());
1794                                                                    Parameter<Boolean> prm = getAudioOutputChannelParameterInfo (
1795                                  aoc.setMixChannel(Boolean.parseBoolean(s));                                          deviceId, audioChn, "IS_MIX_CHANNEL"
1796                                    );
1797                                    prm.setValue(Boolean.parseBoolean(s));
1798                                    aoc.setMixChannelParameter(prm);
1799                          } else if(s.startsWith("MIX_CHANNEL_DESTINATION: ")) {                          } else if(s.startsWith("MIX_CHANNEL_DESTINATION: ")) {
1800                                  s = s.substring("MIX_CHANNEL_DESTINATION: ".length());                                  s = s.substring("MIX_CHANNEL_DESTINATION: ".length());
1801                                  aoc.setMixChannelDest(parseInt(s));                                  Parameter<Integer> prm = getAudioOutputChannelParameterInfo (
1802                                            deviceId, audioChn, "MIX_CHANNEL_DESTINATION"
1803                                    );
1804                                    prm.setValue(parseInt(s));
1805                                    aoc.setMixChannelDestParameter(prm);
1806                          } else {                          } else {
1807                                  int i = s.indexOf(": ");                                  int i = s.indexOf(": ");
1808                                  if(i == -1) throw new LscpException (                                  if(i == -1) throw new LscpException (
# Line 949  public class Client { Line 1810  public class Client {
1810                                  );                                  );
1811                                                                    
1812                                  Parameter prm = getAudioOutputChannelParameterInfo (                                  Parameter prm = getAudioOutputChannelParameterInfo (
1813                                          deviceID, audioChn, s.substring(0, i)                                          deviceId, audioChn, s.substring(0, i)
1814                                  );                                  );
1815                                                                    
1816                                  s = s.substring(i + 2);                                  s = s.substring(i + 2);
# Line 965  public class Client { Line 1826  public class Client {
1826          /**          /**
1827           * Gets detailed information about a specific audio output channel parameter.           * Gets detailed information about a specific audio output channel parameter.
1828           *           *
1829           * @param devID The numerical ID of the audio output device.           * @param devId The numerical ID of the audio output device.
1830           * @param chan The audio channel number.           * @param chan The audio channel number.
1831           * @param param a specific channel parameter name for which information should be obtained.           * @param param a specific channel parameter name for which information should be obtained.
1832           *           *
# Line 976  public class Client { Line 1837  public class Client {
1837           * @throws LscpException If LSCP protocol corruption occurs.           * @throws LscpException If LSCP protocol corruption occurs.
1838           * @throws LSException If           * @throws LSException If
1839           * <ul>           * <ul>
1840           * <li><code>devID</code> is not a valid device ID;           * <li><code>devId</code> is not a valid device ID;
1841           * <li><code>chan</code> is not a valid channel number;           * <li><code>chan</code> is not a valid channel number;
1842           * <li>There is no channel parameter with the specified name.           * <li>There is no channel parameter with the specified name.
1843           * </ul>           * </ul>
# Line 985  public class Client { Line 1846  public class Client {
1846           * @see #getAudioOutputChannelInfo           * @see #getAudioOutputChannelInfo
1847           */           */
1848          public synchronized Parameter          public synchronized Parameter
1849          getAudioOutputChannelParameterInfo(int devID, int chan, String param)          getAudioOutputChannelParameterInfo(int devId, int chan, String param)
1850                                                  throws IOException, LscpException, LSException {                                                  throws IOException, LscpException, LSException {
1851                                    
1852                  verifyConnection();                  verifyConnection();
1853                  String args = devID + ' ' + chan + ' ' + param;                  String args = devId + " " + chan + " " + param;
1854                  out.writeLine("GET AUDIO_OUTPUT_CHANNEL_PARAMETER INFO " + args);                  out.writeLine("GET AUDIO_OUTPUT_CHANNEL_PARAMETER INFO " + args);
1855                    if(getPrintOnlyMode()) return null;
1856                                    
1857                  ResultSet rs = getMultiLineResultSet();                  ResultSet rs = getMultiLineResultSet();
1858                                    
# Line 1027  public class Client { Line 1889  public class Client {
1889          /**          /**
1890           * Alters a specific setting of an audio output channel.           * Alters a specific setting of an audio output channel.
1891           *           *
1892           * @param devID The numerical ID of the audio device.           * @param devId The numerical ID of the audio device.
1893           * @param chn The audio channel number.           * @param chn The audio channel number.
1894           * @param prm A <code>Parameter</code> instance containing the name of the parameter           * @param prm A <code>Parameter</code> instance containing the name of the parameter
1895           * and the new value for this parameter.           * and the new value for this parameter.
# Line 1036  public class Client { Line 1898  public class Client {
1898           * @throws LscpException If LSCP protocol corruption occurs.           * @throws LscpException If LSCP protocol corruption occurs.
1899           * @throws LSException If           * @throws LSException If
1900           * <ul>           * <ul>
1901           * <li>There is no audio output device with numerical ID <code>devID</code>;           * <li>There is no audio output device with numerical ID <code>devId</code>;
1902           * <li><code>chn</code> is not a valid channel number;           * <li><code>chn</code> is not a valid channel number;
1903           * <li>There is no channel parameter with the specified name;           * <li>There is no channel parameter with the specified name;
1904           * <li>The channel parameter is readonly;           * <li>The channel parameter is readonly;
# Line 1047  public class Client { Line 1909  public class Client {
1909           * @see #getAudioOutputChannelInfo           * @see #getAudioOutputChannelInfo
1910           */           */
1911          public synchronized void          public synchronized void
1912          setAudioOutputChannelParameter(int devID, int chn,  Parameter prm)          setAudioOutputChannelParameter(int devId, int chn,  Parameter prm)
1913                                                  throws IOException, LscpException, LSException {                                                  throws IOException, LscpException, LSException {
1914                                    
1915                  verifyConnection();                  verifyConnection();
1916                  String args = devID + ' ' + chn + ' ' + prm.getName() + '=' + prm.getStringValue();                  String args = devId + " " + chn + " " + prm.getName() + '=' + prm.getStringValue();
1917                  out.writeLine("SET AUDIO_OUTPUT_CHANNEL_PARAMETER " + args);                  out.writeLine("SET AUDIO_OUTPUT_CHANNEL_PARAMETER " + args);
1918                    if(getPrintOnlyMode()) return;
1919                                    
1920                  ResultSet rs = getEmptyResultSet();                  ResultSet rs = getEmptyResultSet();
1921          }          }
# Line 1068  public class Client { Line 1931  public class Client {
1931          getMidiInputDriverCount() throws IOException, LscpException, LSException {          getMidiInputDriverCount() throws IOException, LscpException, LSException {
1932                  verifyConnection();                  verifyConnection();
1933                  out.writeLine("GET AVAILABLE_MIDI_INPUT_DRIVERS");                  out.writeLine("GET AVAILABLE_MIDI_INPUT_DRIVERS");
1934                    if(getPrintOnlyMode()) return -1;
1935                    
1936                  String s = getSingleLineResultSet().getResult();                  String s = getSingleLineResultSet().getResult();
1937                  return parseInt(s);                  return parseInt(s);
1938          }          }
# Line 1075  public class Client { Line 1940  public class Client {
1940          /**          /**
1941           * Gets all MIDI input drivers currently available for the LinuxSampler instance.           * Gets all MIDI input drivers currently available for the LinuxSampler instance.
1942           *           *
1943           * @return <code>String</code> array with all MIDI input drivers currently available for           * @return <code>MidiInputDriver</code> array containing all MIDI input drivers currently
1944           * the LinuxSampler instance or <code>null</code> if there are no MIDI input drivers           * available for the LinuxSampler instance.
          * currently available.  
1945           *           *
1946           * @throws IOException If an I/O error occurs.           * @throws IOException If an I/O error occurs.
1947           * @throws LscpException If LSCP protocol corruption occurs.           * @throws LscpException If LSCP protocol corruption occurs.
1948           * @throws LSException If some other error occurs.           * @throws LSException If some other error occurs.
1949           */           */
1950          public synchronized String[]          public synchronized MidiInputDriver[]
1951          getMidiInputDrivers() throws IOException, LscpException, LSException {          getMidiInputDrivers() throws IOException, LscpException, LSException {
1952                    String[] drivers = getMidiInputDriverNames();
1953                    if(getPrintOnlyMode()) return null;
1954                    
1955                    MidiInputDriver[] mid = new MidiInputDriver[drivers.length];
1956                    
1957                    for(int i = 0; i < mid.length; i++) mid[i] = getMidiInputDriverInfo(drivers[i]);
1958                    
1959                    return mid;
1960            }
1961            
1962            /**
1963             * Gets all MIDI input drivers currently available for the LinuxSampler instance.
1964             *
1965             * @return <code>String</code> array containing all MIDI input drivers currently available
1966             * for the LinuxSampler instance.
1967             *
1968             * @throws IOException If an I/O error occurs.
1969             * @throws LscpException If LSCP protocol corruption occurs.
1970             * @throws LSException If some other error occurs.
1971             */
1972            private synchronized String[]
1973            getMidiInputDriverNames() throws IOException, LscpException, LSException {
1974                  verifyConnection();                  verifyConnection();
1975                  out.writeLine("LIST AVAILABLE_MIDI_INPUT_DRIVERS");                  out.writeLine("LIST AVAILABLE_MIDI_INPUT_DRIVERS");
1976                    if(getPrintOnlyMode()) return null;
1977                    
1978                  return parseList(getSingleLineResultSet().getResult());                  return parseList(getSingleLineResultSet().getResult());
1979          }          }
1980                    
1981          /**          /**
1982           * Gets detailed information about a specific MIDI input driver.           * Gets detailed information about a specific MIDI input driver.
1983           * @param driverName The name of the MIDI input driver.           * @param driverName The name of the MIDI input driver.
1984           *           * @param depList An optional list of dependences parameters.
1985           * @return An <code>MidiInputDriver</code> object containing           * @return A <code>MidiInputDriver</code> object containing
1986           * information about the specified MIDI input driver.           * information about the specified MIDI input driver.
1987           *           *
1988           * @throws IOException If an I/O error occurs.           * @throws IOException If an I/O error occurs.
1989           * @throws LscpException If LSCP protocol corruption occurs.           * @throws LscpException If LSCP protocol corruption occurs.
1990           * @throws LSException If there is no driver with name <code>driverName</code>.           * @throws LSException If there is no driver with name <code>driverName</code>.
1991           *           *
1992           * @see #getMidiInputDrivers           * @see #getMidiInputDriverNames
1993           */           */
1994          public synchronized MidiInputDriver          public synchronized MidiInputDriver
1995          getMidiInputDriverInfo(String driverName) throws IOException, LscpException, LSException {          getMidiInputDriverInfo(String driverName, Parameter... depList)
1996                                            throws IOException, LscpException, LSException {
1997                    
1998                  verifyConnection();                  verifyConnection();
1999                  out.writeLine("GET MIDI_INPUT_DRIVER INFO " + driverName);                  out.writeLine("GET MIDI_INPUT_DRIVER INFO " + driverName);
2000                    if(getPrintOnlyMode()) return null;
2001                    
2002                  ResultSet rs = getMultiLineResultSet();                  ResultSet rs = getMultiLineResultSet();
2003                                    
2004                  MidiInputDriver mid = new MidiInputDriver(rs.getMultiLineResult());                  MidiInputDriver mid = new MidiInputDriver(rs.getMultiLineResult());
2005                  mid.setName(driverName);                  mid.setName(driverName);
2006                                    
2007                  for(String s : mid.getParameterNames())                  for(String s : mid.getParameterNames())
2008                          mid.addParameter(getMidiInputDriverParameterInfo(driverName, s));                          mid.addParameter(getMidiInputDriverParameterInfo(driverName, s, depList));
2009                                    
2010                  return mid;                  return mid;
2011          }          }
# Line 1127  public class Client { Line 2019  public class Client {
2019           * <code>param</code> depends on. <code>Parameter</code> instances can be           * <code>param</code> depends on. <code>Parameter</code> instances can be
2020           * easily created using {@link ParameterFactory} factory.           * easily created using {@link ParameterFactory} factory.
2021           *           *
2022           * @return An <code>Parameter</code> object containing           * @return A <code>Parameter</code> object containing
2023           * information about the specified MIDI input driver parameter.           * information about the specified MIDI input driver parameter.
2024           *           *
2025           * @throws IOException If an I/O error occurs.           * @throws IOException If an I/O error occurs.
# Line 1147  public class Client { Line 2039  public class Client {
2039                  StringBuffer args = new StringBuffer(driver);                  StringBuffer args = new StringBuffer(driver);
2040                  args.append(' ').append(param);                  args.append(' ').append(param);
2041                                    
2042                  for(Parameter p : deplist)                  for(Parameter p : deplist) {
2043                            if(p == null || p.getName() == null || p.getValue() == null) continue;
2044                          args.append(' ').append(p.getName()).append('=').append(p.getStringValue());                          args.append(' ').append(p.getName()).append('=').append(p.getStringValue());
2045                    }
2046                                    
2047                  out.writeLine("GET MIDI_INPUT_DRIVER_PARAMETER INFO " + args.toString());                  out.writeLine("GET MIDI_INPUT_DRIVER_PARAMETER INFO " + args.toString());
2048                    if(getPrintOnlyMode()) return null;
2049                                    
2050                  ResultSet rs = getMultiLineResultSet();                  ResultSet rs = getMultiLineResultSet();
2051                                    
# Line 1164  public class Client { Line 2059  public class Client {
2059                          if(!multi) prm = new BoolParameter(lnS);                          if(!multi) prm = new BoolParameter(lnS);
2060                          else prm = new BoolListParameter(lnS);                          else prm = new BoolListParameter(lnS);
2061                          prm.setName(param);                          prm.setName(param);
2062                            prm.setValue(prm.getDefault());
2063                          return prm;                          return prm;
2064                  case INT:                  case INT:
2065                          if(!multi) prm = new IntParameter(lnS);                          if(!multi) prm = new IntParameter(lnS);
2066                          else prm = new IntListParameter(lnS);                          else prm = new IntListParameter(lnS);
2067                          prm.setName(param);                          prm.setName(param);
2068                            prm.setValue(prm.getDefault());
2069                          return prm;                          return prm;
2070                  case FLOAT:                  case FLOAT:
2071                          if(!multi) prm = new FloatParameter(lnS);                          if(!multi) prm = new FloatParameter(lnS);
2072                          else prm = new FloatListParameter(lnS);                          else prm = new FloatListParameter(lnS);
2073                          prm.setName(param);                          prm.setName(param);
2074                            prm.setValue(prm.getDefault());
2075                          return prm;                          return prm;
2076                  case STRING:                  case STRING:
2077                          if(!multi) prm = new StringParameter(lnS);                          if(!multi) prm = new StringParameter(lnS);
2078                          else prm = new StringListParameter(lnS);                          else prm = new StringListParameter(lnS);
2079                          prm.setName(param);                          prm.setName(param);
2080                            prm.setValue(prm.getDefault());
2081                          return prm;                          return prm;
2082                  default: throw new LscpException(LscpI18n.getLogMsg("Client.unknownPrmType!"));                  default: throw new LscpException(LscpI18n.getLogMsg("Client.unknownPrmType!"));
2083                  }                  }
# Line 1205  public class Client { Line 2104  public class Client {
2104                  verifyConnection();                  verifyConnection();
2105                  StringBuffer args = new StringBuffer(miDriver);                  StringBuffer args = new StringBuffer(miDriver);
2106                                    
2107                  for(Parameter p : paramList)                  for(Parameter p : paramList) {
2108                            if(p == null || p.getName() == null || p.getValue() == null) continue;
2109                          args.append(' ').append(p.getName()).append('=').append(p.getStringValue());                          args.append(' ').append(p.getName()).append('=').append(p.getStringValue());
2110                    }
2111                                    
2112                  out.writeLine("CREATE MIDI_INPUT_DEVICE " + args.toString());                  out.writeLine("CREATE MIDI_INPUT_DEVICE " + args.toString());
2113                    if(getPrintOnlyMode()) return -1;
2114                    
2115                  ResultSet rs = getEmptyResultSet();                  ResultSet rs = getEmptyResultSet();
2116                                    
2117                  return rs.getIndex();                  return rs.getIndex();
# Line 1216  public class Client { Line 2119  public class Client {
2119                    
2120          /**          /**
2121           * Destroys already created MIDI input device.           * Destroys already created MIDI input device.
2122           * @param deviceID The numerical ID of the MIDI input device to be destroyed.           * @param deviceId The numerical ID of the MIDI input device to be destroyed.
2123           * @throws IOException If some I/O error occurs.           * @throws IOException If some I/O error occurs.
2124           * @throws LSException If the destroying of the MIDI input device failed.           * @throws LSException If the destroying of the MIDI input device failed.
2125           * @throws LscpException If LSCP protocol corruption occurs.           * @throws LscpException If LSCP protocol corruption occurs.
# Line 1224  public class Client { Line 2127  public class Client {
2127           * @see #getMidiInputDevices           * @see #getMidiInputDevices
2128           */           */
2129          public synchronized void          public synchronized void
2130          destroyMidiInputDevice(int deviceID) throws IOException, LSException, LscpException {          destroyMidiInputDevice(int deviceId) throws IOException, LSException, LscpException {
2131                  verifyConnection();                  verifyConnection();
2132                  out.writeLine("DESTROY MIDI_INPUT_DEVICE " + deviceID);                  out.writeLine("DESTROY MIDI_INPUT_DEVICE " + deviceId);
2133                    if(getPrintOnlyMode()) return;
2134                    
2135                  ResultSet rs = getEmptyResultSet();                  ResultSet rs = getEmptyResultSet();
2136          }          }
2137                    
2138            /**
2139             * Enables/disables the specified MIDI input device.
2140             * @param deviceId The ID of the MIDI input device to be enabled/disabled.
2141             * @param enable If <code>true</code> the MIDI input device is enabled,
2142             * else the device is disabled.
2143             * @throws IOException If some I/O error occurs.
2144             * @throws LSException If there is no MIDI input
2145             * device with numerical ID <code>deviceId</code>.
2146             * @throws LscpException If LSCP protocol corruption occurs.
2147             */
2148            public void
2149            enableMidiInputDevice(int deviceId, boolean enable)
2150                                    throws IOException, LSException, LscpException {
2151                    
2152                    setMidiInputDeviceParameter(deviceId, new BoolParameter("ACTIVE", enable));
2153            }
2154            
2155          /**          /**
2156           * Gets the current number of all created MIDI input devices.           * Gets the current number of all created MIDI input devices.
2157           * @return The current number of all created MIDI input devices.           * @return The current number of all created MIDI input devices.
# Line 1241  public class Client { Line 2163  public class Client {
2163          getMidiInputDeviceCount() throws IOException, LscpException, LSException {          getMidiInputDeviceCount() throws IOException, LscpException, LSException {
2164                  verifyConnection();                  verifyConnection();
2165                  out.writeLine("GET MIDI_INPUT_DEVICES");                  out.writeLine("GET MIDI_INPUT_DEVICES");
2166                    if(getPrintOnlyMode()) return -1;
2167                    
2168                  String s = getSingleLineResultSet().getResult();                  String s = getSingleLineResultSet().getResult();
2169                  return parseInt(s);                  return parseInt(s);
2170          }          }
2171                    
2172          /**          /**
2173             * Gets a list of all created MIDI input devices.
2174             * @return A <code>MidiInputDevice</code> array
2175             * providing all created MIDI input devices.
2176             * @throws IOException If some I/O error occurs.
2177             * @throws LscpException If LSCP protocol corruption occurs.
2178             * @throws LSException If some other error occurs.
2179             *
2180             * @see #createMidiInputDevice
2181             * @see #destroyMidiInputDevice
2182             */
2183            public synchronized MidiInputDevice[]
2184            getMidiInputDevices() throws IOException, LscpException, LSException {
2185                    Integer[] idS = getMidiInputDeviceIDs();
2186                    if(getPrintOnlyMode()) return null;
2187                    
2188                    MidiInputDevice[] devices = new MidiInputDevice[idS.length];
2189                    
2190                    for(int i = 0; i < devices.length; i++)
2191                            devices[i] = getMidiInputDeviceInfo(idS[i]);
2192                    
2193                    return devices;
2194            }
2195            
2196            /**
2197           * Gets a list of numerical IDs of all created MIDI input devices.           * Gets a list of numerical IDs of all created MIDI input devices.
2198           * @return An <code>Integer</code> array with numerical IDs of           * @return An <code>Integer</code> array providing the numerical IDs of
2199           * all created MIDI input devices.           * all created MIDI input devices.
2200           * @throws IOException If some I/O error occurs.           * @throws IOException If some I/O error occurs.
2201           * @throws LscpException If LSCP protocol corruption occurs.           * @throws LscpException If LSCP protocol corruption occurs.
# Line 1257  public class Client { Line 2205  public class Client {
2205           * @see #destroyMidiInputDevice           * @see #destroyMidiInputDevice
2206           */           */
2207          public synchronized Integer[]          public synchronized Integer[]
2208          getMidiInputDevices() throws IOException, LscpException, LSException {          getMidiInputDeviceIDs() throws IOException, LscpException, LSException {
2209                  verifyConnection();                  verifyConnection();
2210                  out.writeLine("LIST MIDI_INPUT_DEVICES");                  out.writeLine("LIST MIDI_INPUT_DEVICES");
2211                    if(getPrintOnlyMode()) return null;
2212                    
2213                  return parseIntList(getSingleLineResultSet().getResult());                  return parseIntList(getSingleLineResultSet().getResult());
2214          }          }
2215                    
2216          /**          /**
2217           * Gets the current settings of a specific, already created MIDI input device.           * Gets the current settings of a specific, already created MIDI input device.
2218           *           *
2219           * @param deviceID Specifies the numerical ID of the MIDI input device.           * @param deviceId Specifies the numerical ID of the MIDI input device.
2220           *           *
2221           * @return An <code>MidiInputDevice</code> instance containing information           * @return A <code>MidiInputDevice</code> instance containing information
2222           * about the specified device.           * about the specified device.
2223           *           *
2224           * @throws IOException If some I/O error occurs.           * @throws IOException If some I/O error occurs.
2225           * @throws LscpException If LSCP protocol corruption occurs.           * @throws LscpException If LSCP protocol corruption occurs.
2226           * @throws LSException If there is no MIDI input device           * @throws LSException If there is no MIDI input device
2227           * with device id <code>deviceID</code>.           * with device id <code>deviceId</code>.
2228           *           *
2229           * @see #getMidiInputDevices           * @see #getMidiInputDevices
2230           */           */
2231          public synchronized MidiInputDevice          public synchronized MidiInputDevice
2232          getMidiInputDeviceInfo(int deviceID) throws IOException, LscpException, LSException {          getMidiInputDeviceInfo(int deviceId) throws IOException, LscpException, LSException {
2233                  verifyConnection();                  verifyConnection();
2234                  out.writeLine("GET MIDI_INPUT_DEVICE INFO " + deviceID);                  out.writeLine("GET MIDI_INPUT_DEVICE INFO " + deviceId);
2235                    if(getPrintOnlyMode()) return null;
2236                                    
2237                  ResultSet rs = getMultiLineResultSet();                  ResultSet rs = getMultiLineResultSet();
2238                                    
2239                  String[] lnS = rs.getMultiLineResult();                  String[] lnS = rs.getMultiLineResult();
2240                                    
2241                  MidiInputDevice mid = new MidiInputDevice();                  MidiInputDevice mid = new MidiInputDevice();
2242                    mid.setDeviceId(deviceId);
2243                                    
2244                  String drv = getCategoryInfo(lnS, "DRIVER");                  String drv = getCategoryInfo(lnS, "DRIVER");
2245                  mid.setDriverName(drv);                  mid.setDriverName(drv);
# Line 1298  public class Client { Line 2250  public class Client {
2250                          } else if(s.startsWith("ACTIVE: ")) {                          } else if(s.startsWith("ACTIVE: ")) {
2251                                  s = s.substring("ACTIVE: ".length());                                  s = s.substring("ACTIVE: ".length());
2252                                  mid.setActive(Boolean.parseBoolean(s));                                  mid.setActive(Boolean.parseBoolean(s));
2253                            } else if(s.startsWith("PORTS: ")) {
2254                                    s = s.substring("PORTS: ".length());
2255                                    
2256                                    Parameter<Integer> ports = (Parameter<Integer>)
2257                                            getMidiInputDriverParameterInfo(drv, "PORTS");
2258                                    
2259                                    ports.parseValue(s);
2260                                    mid.setPortsParameter(ports);
2261                                    
2262                                    int j = ports.getValue();
2263                                    MidiPort[] midiPorts = new MidiPort[j > 0 ? j : 0];
2264                                    
2265                                    for(int i = 0; i < midiPorts.length; i++)
2266                                            midiPorts[i] = getMidiInputPortInfo(deviceId, i);
2267                                    
2268                                    mid.setMidiPorts(midiPorts);
2269                          } else {                          } else {
2270                                  int i = s.indexOf(": ");                                  int i = s.indexOf(": ");
2271                                  if(i == -1) throw new LscpException (                                  if(i == -1) throw new LscpException (
# Line 1320  public class Client { Line 2288  public class Client {
2288          /**          /**
2289           * Alters a specific setting of a created MIDI input device.           * Alters a specific setting of a created MIDI input device.
2290           *           *
2291           * @param deviceID The numerical ID of the MIDI input device.           * @param deviceId The numerical ID of the MIDI input device.
2292           * @param prm A <code>Parameter</code> instance containing the name of the parameter           * @param prm A <code>Parameter</code> instance containing the name of the parameter
2293           * and the new value for this parameter.           * and the new value for this parameter.
2294           *           *
# Line 1328  public class Client { Line 2296  public class Client {
2296           * @throws LscpException If LSCP protocol corruption occurs.           * @throws LscpException If LSCP protocol corruption occurs.
2297           * @throws LSException If           * @throws LSException If
2298           * <ul>           * <ul>
2299           * <li>There is no MIDI input device with numerical ID <code>deviceID</code>;           * <li>There is no MIDI input device with numerical ID <code>deviceId</code>;
2300           * <li>There is no device parameter with the specified name;           * <li>There is no device parameter with the specified name;
2301           * <li>The device parameter is readonly;           * <li>The device parameter is readonly;
2302           * <li>The device parameter is from different type.           * <li>The device parameter is from different type.
# Line 1338  public class Client { Line 2306  public class Client {
2306           * @see #getMidiInputDeviceInfo           * @see #getMidiInputDeviceInfo
2307           */           */
2308          public synchronized void          public synchronized void
2309          setMidiInputDeviceParameter(int deviceID, Parameter prm)          setMidiInputDeviceParameter(int deviceId, Parameter prm)
2310                                                  throws IOException, LscpException, LSException {                                                  throws IOException, LscpException, LSException {
2311                                    
2312                  verifyConnection();                  verifyConnection();
2313                  String kv = prm.getName() + '=' + prm.getStringValue();                  String kv = prm.getName() + '=' + prm.getStringValue();
2314                  out.writeLine("SET MIDI_INPUT_DEVICE_PARAMETER " + deviceID + ' ' + kv);                  out.writeLine("SET MIDI_INPUT_DEVICE_PARAMETER " + deviceId + ' ' + kv);
2315                    if(getPrintOnlyMode()) return;
2316                                    
2317                  ResultSet rs = getEmptyResultSet();                  ResultSet rs = getEmptyResultSet();
2318          }          }
2319                    
2320            
2321            /**
2322             * Changes the port number of the speicified MIDI input device.
2323             * @param deviceId The numerical ID of the MIDI input device.
2324             * @param ports The new number of MIDI input ports.
2325             *
2326             * @throws IOException If an I/O error occurs.
2327             * @throws LscpException If LSCP protocol corruption occurs.
2328             * @throws LSException If there is no device with ID <code>deviceId</code> or
2329             * if <code>ports</code> number is out of range.
2330             *
2331             * @see #getMidiInputPortInfo
2332             */
2333            public synchronized void
2334            setMidiInputPortCount(int deviceId, int ports)
2335                                            throws IOException, LscpException, LSException {
2336                    
2337                    setMidiInputDeviceParameter(deviceId, new IntParameter("PORTS", ports));
2338            }
2339            
2340          /**          /**
2341           * Gets detailed information about a specific MIDI input port.           * Gets detailed information about a specific MIDI input port.
2342           * @param deviceID The numerical ID of the MIDI input device.           * @param deviceId The numerical ID of the MIDI input device.
2343           * @param midiPort The MIDI input port number.           * @param midiPort The MIDI input port number.
2344           *           *
2345           * @return A <code>MidiPort</code> instance containing           * @return A <code>MidiPort</code> instance containing
# Line 1358  public class Client { Line 2347  public class Client {
2347           *           *
2348           * @throws IOException If an I/O error occurs.           * @throws IOException If an I/O error occurs.
2349           * @throws LscpException If LSCP protocol corruption occurs.           * @throws LscpException If LSCP protocol corruption occurs.
2350           * @throws LSException If there is no device with ID <code>deviceID</code> or           * @throws LSException If there is no device with ID <code>deviceId</code> or
2351           * if <code>midiPort</code> is not a valid MIDI port number.           * if <code>midiPort</code> is not a valid MIDI port number.
2352           *           *
2353           * @see #getMidiInputDevices           * @see #getMidiInputDevices
2354           */           */
2355          public synchronized MidiPort          public synchronized MidiPort
2356          getMidiInputPortInfo(int deviceID, int midiPort)          getMidiInputPortInfo(int deviceId, int midiPort)
2357                                          throws IOException, LscpException, LSException {                                          throws IOException, LscpException, LSException {
2358                                    
2359                  verifyConnection();                  verifyConnection();
2360                  out.writeLine("GET MIDI_INPUT_PORT INFO " + deviceID + " " + midiPort);                  out.writeLine("GET MIDI_INPUT_PORT INFO " + deviceId + " " + midiPort);
2361                    if(getPrintOnlyMode()) return null;
2362                    
2363                  ResultSet rs = getMultiLineResultSet();                  ResultSet rs = getMultiLineResultSet();
2364                                    
2365                  MidiPort mp = new MidiPort();                  MidiPort mp = new MidiPort();
# Line 1376  public class Client { Line 2367  public class Client {
2367                                    
2368                  for(String s : lnS) {                  for(String s : lnS) {
2369                          if(s.startsWith("NAME: ")) {                          if(s.startsWith("NAME: ")) {
2370                                  mp.setName(s.substring("NAME: ".length()));                                  s = s.substring("NAME: ".length());
2371                                    Parameter prm = getMidiInputPortParameterInfo (
2372                                            deviceId, midiPort, "NAME"
2373                                    );
2374                                    prm.setValue(removeQuotation(s));
2375                                    mp.setNameParameter(prm);
2376                          } else {                          } else {
2377                                  int i = s.indexOf(": ");                                  int i = s.indexOf(": ");
2378                                  if(i == -1) throw new LscpException (                                  if(i == -1) throw new LscpException (
# Line 1384  public class Client { Line 2380  public class Client {
2380                                  );                                  );
2381                                                                    
2382                                  Parameter prm = getMidiInputPortParameterInfo (                                  Parameter prm = getMidiInputPortParameterInfo (
2383                                          deviceID, midiPort, s.substring(0, i)                                          deviceId, midiPort, s.substring(0, i)
2384                                  );                                  );
2385                                                                    
2386                                  s = s.substring(i + 2);                                  s = s.substring(i + 2);
# Line 1400  public class Client { Line 2396  public class Client {
2396          /**          /**
2397           * Gets detailed information about a specific MIDI input port parameter.           * Gets detailed information about a specific MIDI input port parameter.
2398           *           *
2399           * @param deviceID The numerical ID of the MIDI input device.           * @param deviceId The numerical ID of the MIDI input device.
2400           * @param port The MIDI port number.           * @param port The MIDI port number.
2401           * @param param A specific parameter name for which information should be obtained.           * @param param A specific parameter name for which information should be obtained.
2402           *           *
# Line 1411  public class Client { Line 2407  public class Client {
2407           * @throws LscpException If LSCP protocol corruption occurs.           * @throws LscpException If LSCP protocol corruption occurs.
2408           * @throws LSException If           * @throws LSException If
2409           * <ul>           * <ul>
2410           * <li>There is no MIDI input device with numerical ID <code>deviceID</code>;           * <li>There is no MIDI input device with numerical ID <code>deviceId</code>;
2411           * <li> <code>port</code> is not a valid MIDI port number;           * <li> <code>port</code> is not a valid MIDI port number;
2412           * <li><code>param</code> is not a valid parameter for the specified MIDI port.           * <li><code>param</code> is not a valid parameter for the specified MIDI port.
2413           * </ul>           * </ul>
# Line 1420  public class Client { Line 2416  public class Client {
2416           * @see #getMidiInputPortInfo           * @see #getMidiInputPortInfo
2417           */           */
2418          public synchronized Parameter          public synchronized Parameter
2419          getMidiInputPortParameterInfo(int deviceID, int port, String param)          getMidiInputPortParameterInfo(int deviceId, int port, String param)
2420                                                  throws IOException, LscpException, LSException {                                                  throws IOException, LscpException, LSException {
2421                                    
2422                  verifyConnection();                  verifyConnection();
2423                  String args = deviceID + " " + port + " " + param;                  String args = deviceId + " " + port + " " + param;
2424                  out.writeLine("GET MIDI_INPUT_PORT_PARAMETER INFO " + args);                  out.writeLine("GET MIDI_INPUT_PORT_PARAMETER INFO " + args);
2425                    if(getPrintOnlyMode()) return null;
2426                                    
2427                  ResultSet rs = getMultiLineResultSet();                  ResultSet rs = getMultiLineResultSet();
2428                                    
# Line 1462  public class Client { Line 2459  public class Client {
2459          /**          /**
2460           * Alters a specific setting of a MIDI input port.           * Alters a specific setting of a MIDI input port.
2461           *           *
2462           * @param deviceID The numerical ID of the MIDI device.           * @param deviceId The numerical ID of the MIDI device.
2463           * @param port The MIDI port number.           * @param port The MIDI port number.
2464           * @param prm A <code>Parameter</code> instance containing the name of the parameter           * @param prm A <code>Parameter</code> instance containing the name of the parameter
2465           * and the new value for this parameter.           * and the new value for this parameter.
# Line 1471  public class Client { Line 2468  public class Client {
2468           * @throws LscpException If LSCP protocol corruption occurs.           * @throws LscpException If LSCP protocol corruption occurs.
2469           * @throws LSException If           * @throws LSException If
2470           * <ul>           * <ul>
2471           * <li>There is no MIDI device with numerical ID <code>deviceID</code>;           * <li>There is no MIDI device with numerical ID <code>deviceId</code>;
2472           * <li><code>port</code> is not a valid MIDI port number;           * <li><code>port</code> is not a valid MIDI port number;
2473           * <li><code>prm</code> is not a valid parameter;           * <li><code>prm</code> is not a valid parameter;
2474           * <li>The parameter is readonly;           * <li>The parameter is readonly;
# Line 1482  public class Client { Line 2479  public class Client {
2479           * @see #getMidiInputPortInfo           * @see #getMidiInputPortInfo
2480           */           */
2481          public synchronized void          public synchronized void
2482          setMidiInputPortParameter(int deviceID, int port,  Parameter prm)          setMidiInputPortParameter(int deviceId, int port,  Parameter prm)
2483                                                  throws IOException, LscpException, LSException {                                                  throws IOException, LscpException, LSException {
2484                                    
2485                  verifyConnection();                  verifyConnection();
2486                  String args = deviceID + ' ' + port + ' ' +                  String args = deviceId + " " + port + " " +
2487                          prm.getName() + '=' + prm.getStringValue();                          prm.getName() + '=' + prm.getStringValue();
2488                  out.writeLine("SET MIDI_INPUT_PORT_PARAMETER " + args);                  out.writeLine("SET MIDI_INPUT_PORT_PARAMETER " + args);
2489                    if(getPrintOnlyMode()) return;
2490                    
2491                    ResultSet rs = getEmptyResultSet();
2492            }
2493            
2494            /**
2495             * Adds a new MIDI instrument map.
2496             * @param name The name of this MIDI instrument map.
2497             * @return The number of the newly MIDI instrument map.
2498             * @throws IOException If some I/O error occurs.
2499             * @throws LSException If the creation of the new MIDI instrument map failed.
2500             * @throws LscpException If LSCP protocol corruption occurs.
2501             * @see #removeMidiInstrumentMap
2502             */
2503            public synchronized int
2504            addMidiInstrumentMap(String name) throws IOException, LSException, LscpException {
2505                    verifyConnection();
2506                    out.writeLine("ADD MIDI_INSTRUMENT_MAP '" + toEscapedString(name) + "'");
2507                    if(getPrintOnlyMode()) return -1;
2508                    
2509                    ResultSet rs = getEmptyResultSet();
2510                    
2511                    return rs.getIndex();
2512            }
2513            
2514            /**
2515             * Removes the specified MIDI instrument map.
2516             * @param mapId The numerical ID of the MIDI instrument map to be removed.
2517             * @throws IOException If some I/O error occurs.
2518             * @throws LscpException If LSCP protocol corruption occurs.
2519             * @throws LSException If the removing of the MIDI instrument map failed.
2520             * @see #addMidiInstrumentMap
2521             * @see #getMidiInstrumentMapIDs
2522             */
2523            public synchronized void
2524            removeMidiInstrumentMap(int mapId) throws IOException, LscpException, LSException {
2525                    verifyConnection();
2526                    out.writeLine("REMOVE MIDI_INSTRUMENT_MAP " + mapId);
2527                    if(getPrintOnlyMode()) return;
2528                    
2529                    ResultSet rs = getEmptyResultSet();
2530            }
2531            
2532            /**
2533             * Removes the all MIDI instrument maps.
2534             * @throws IOException If some I/O error occurs.
2535             * @throws LscpException If LSCP protocol corruption occurs.
2536             * @throws LSException If the removing of the MIDI instrument maps failed.
2537             */
2538            public synchronized void
2539            removeAllMidiInstrumentMaps() throws IOException, LscpException, LSException {
2540                    verifyConnection();
2541                    out.writeLine("REMOVE MIDI_INSTRUMENT_MAP ALL");
2542                    if(getPrintOnlyMode()) return;
2543                    
2544                    ResultSet rs = getEmptyResultSet();
2545            }
2546            
2547            /**
2548             * Gets the current number of all MIDI instrument maps.
2549             * @return The current number of all MIDI instrument maps.
2550             * @throws IOException If some I/O error occurs.
2551             * @throws LscpException If LSCP protocol corruption occurs.
2552             * @throws LSException If some other error occurs.
2553             */
2554            public synchronized int
2555            getMidiInstrumentMapCount() throws IOException, LscpException, LSException {
2556                    verifyConnection();
2557                    out.writeLine("GET MIDI_INSTRUMENT_MAPS");
2558                    if(getPrintOnlyMode()) return -1;
2559                    
2560                    String s = getSingleLineResultSet().getResult();
2561                    return parseInt(s);
2562            }
2563            
2564            /**
2565             * Gets a list of numerical IDs of all created MIDI instrument maps.
2566             * @return An <code>Integer</code> array providing the numerical IDs of
2567             * all created MIDI instrument maps.
2568             * @throws IOException If some I/O error occurs.
2569             * @throws LscpException If LSCP protocol corruption occurs.
2570             * @throws LSException If some other error occurs.
2571             * @see #addMidiInstrumentMap
2572             * @see #removeMidiInstrumentMap
2573             */
2574            public synchronized Integer[]
2575            getMidiInstrumentMapIDs() throws IOException, LscpException, LSException {
2576                    verifyConnection();
2577                    out.writeLine("LIST MIDI_INSTRUMENT_MAPS");
2578                    if(getPrintOnlyMode()) return null;
2579                    
2580                    return parseIntList(getSingleLineResultSet().getResult());
2581            }
2582            
2583            /**
2584             * Gets the current settings of a specific, already created MIDI instrument map.
2585             * @param mapId Specifies the numerical ID of the MIDI instrument map.
2586             * @return A <code>MidiInstrumentMapInfo</code> instance containing information
2587             * about the specified device.
2588             * @throws IOException If some I/O error occurs.
2589             * @throws LscpException If LSCP protocol corruption occurs.
2590             * @throws LSException If there is no MIDI instrument map
2591             * with map id <code>mapId</code>.
2592             * @see #getMidiInstrumentMaps
2593             */
2594            public synchronized MidiInstrumentMapInfo
2595            getMidiInstrumentMapInfo(int mapId) throws IOException, LscpException, LSException {
2596                    verifyConnection();
2597                    out.writeLine("GET MIDI_INSTRUMENT_MAP INFO " + mapId);
2598                    if(getPrintOnlyMode()) return null;
2599                    
2600                    ResultSet rs = getMultiLineResultSet();
2601                    
2602                    String[] lnS = rs.getMultiLineResult();
2603                    
2604                    String name = "";
2605                    boolean b = false;
2606                    
2607                    for(String s : lnS) {
2608                            if(s.startsWith("NAME: ")) {
2609                                    name = toNonEscapedString(s.substring("NAME: ".length()));
2610                            } else if(s.startsWith("DEFAULT: ")) {
2611                                    b = Boolean.parseBoolean(s.substring("DEFAULT: ".length()));
2612                            } else {
2613                                     getLogger().info(LscpI18n.getLogMsg("unknownLine", s));
2614                            }
2615                    }
2616                    
2617                    return new MidiInstrumentMapInfo(mapId, name, b);
2618            }
2619            
2620            /**
2621             * Gets an information of all created MIDI instrument maps.
2622             * @return A <code>MidiInstrumentMap</code> array
2623             * providing information for all created MIDI instrument maps.
2624             * @throws IOException If some I/O error occurs.
2625             * @throws LscpException If LSCP protocol corruption occurs.
2626             * @throws LSException If some other error occurs.
2627             * @see #addMidiInstrumentMap
2628             * @see #removeMidiInstrumentMap
2629             */
2630            public synchronized MidiInstrumentMapInfo[]
2631            getMidiInstrumentMaps() throws IOException, LscpException, LSException {
2632                    Integer[] idS = getMidiInstrumentMapIDs();
2633                    if(getPrintOnlyMode()) return null;
2634                    
2635                    MidiInstrumentMapInfo[] maps = new MidiInstrumentMapInfo[idS.length];
2636                    
2637                    for(int i = 0; i < maps.length; i++)
2638                            maps[i] = getMidiInstrumentMapInfo(idS[i]);
2639                    
2640                    return maps;
2641            }
2642            
2643            /**
2644             * Sets the name of the specified MIDI instrument map.
2645             * @param mapId The numerical ID of the MIDI instrument map.
2646             * @param name The new name for the specified MIDI instrument map.
2647             * @throws IOException If some I/O error occurs.
2648             * @throws LscpException If LSCP protocol corruption occurs.
2649             * @throws LSException If <code>mapId</code> is not a valid MIDI
2650             * instrument map number or <code>name</code> is not a valid name;
2651             */
2652            public synchronized void
2653            setMidiInstrumentMapName(int mapId, String name)
2654                                    throws IOException, LscpException, LSException {
2655                    
2656                    verifyConnection();
2657                    name = toEscapedString(name);
2658                    out.writeLine("SET MIDI_INSTRUMENT_MAP NAME " +  + mapId + " '" + name + "'");
2659                    if(getPrintOnlyMode()) return;
2660                    
2661                    ResultSet rs = getEmptyResultSet();
2662            }
2663            
2664            
2665            
2666            /**
2667             * Creates or replaces a MIDI instrument map entry.
2668             * @param mapId The ID of the map, where this instrument should be mapped.
2669             * @param entry Specifies the position of the MIDI instrument in the MIDI instrument map.
2670             * @param info Provides the needed information of the
2671             * MIDI instrument, which will be mapped to the specified MIDI instrument map.
2672             * @throws IOException If some I/O error occurs.
2673             * @throws LSException If the mapping failed.
2674             * @throws LscpException If LSCP protocol corruption occurs.
2675             * @see #unmapMidiInstrument
2676             */
2677            public synchronized void
2678            mapMidiInstrument(int mapId, MidiInstrumentEntry entry, MidiInstrumentInfo info)
2679                                            throws IOException, LSException, LscpException {
2680                    mapMidiInstrument(mapId, entry, info, false);
2681            }
2682            
2683            /**
2684             * Creates or replaces a MIDI instrument map entry.
2685             * @param mapId The ID of the map, where this instrument should be mapped.
2686             * @param entry Specifies the position of the MIDI instrument in the MIDI instrument map.
2687             * @param info Provides the needed information of the
2688             * MIDI instrument, which will be mapped to the specified MIDI instrument map.
2689             * @param nonModal If <code>true</code> the function returns immediately
2690             * and the mapping is established in the background.
2691             * @throws IOException If some I/O error occurs.
2692             * @throws LSException If the mapping failed.
2693             * @throws LscpException If LSCP protocol corruption occurs.
2694             * @see #unmapMidiInstrument
2695             */
2696            public synchronized void
2697            mapMidiInstrument(int mapId, MidiInstrumentEntry entry, MidiInstrumentInfo info, boolean nonModal)
2698                                            throws IOException, LSException, LscpException {
2699                    
2700                    verifyConnection();
2701                    StringBuffer cmd = new StringBuffer("MAP MIDI_INSTRUMENT ");
2702                    if(nonModal) cmd.append("NON_MODAL ");
2703                    cmd.append(mapId).append(' ');
2704                    cmd.append(entry.getMidiBank()).append(' ');
2705                    cmd.append(entry.getMidiProgram()).append(' ');
2706                    cmd.append(info.getEngine()).append(" '");
2707                    cmd.append(info.getFilePath()).append("' ");
2708                    cmd.append(info.getInstrumentIndex()).append(' ');
2709                    cmd.append(info.getVolume());
2710                    if(!info.getLoadMode().name().equals("DEFAULT")) {
2711                            cmd.append(' ').append(info.getLoadMode().name());
2712                    }
2713                    
2714                    if(info.getName() != null) {
2715                            String s = toEscapedString(info.getName());
2716                            cmd.append(" '").append(s).append("'");
2717                    }
2718                    
2719                    out.writeLine(cmd.toString());
2720                    if(getPrintOnlyMode()) return;
2721                    
2722                    ResultSet rs = getEmptyResultSet();
2723            }
2724            
2725            /**
2726             * Removes an entry MIDI instrument map.
2727             * @param mapId The ID of the map, from which
2728             * the specified MIDI instrument should be removed.
2729             * @param entry The entry to remove from the specified MIDI instrument map.
2730             * @throws IOException If some I/O error occurs.
2731             * @throws LSException If the unmapping failed.
2732             * @throws LscpException If LSCP protocol corruption occurs.
2733             * @see #mapMidiInstrument
2734             */
2735            public synchronized void
2736            unmapMidiInstrument(int mapId, MidiInstrumentEntry entry)
2737                                            throws IOException, LSException, LscpException {
2738                    
2739                    verifyConnection();
2740                    StringBuffer cmd = new StringBuffer("UNMAP MIDI_INSTRUMENT ");
2741                    cmd.append(mapId).append(' ');
2742                    cmd.append(entry.getMidiBank()).append(' ');
2743                    cmd.append(entry.getMidiProgram());
2744                    
2745                    out.writeLine(cmd.toString());
2746                    if(getPrintOnlyMode()) return;
2747                                    
2748                  ResultSet rs = getEmptyResultSet();                  ResultSet rs = getEmptyResultSet();
2749          }          }
2750                    
2751          /**          /**
2752             * Gets the current number of all MIDI instrument in all maps.
2753             * @return The current number of all MIDI instrument in all 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 int
2759            getMidiInstrumentCount() throws IOException, LscpException, LSException {
2760                    verifyConnection();
2761                    out.writeLine("GET MIDI_INSTRUMENTS ALL");
2762                    if(getPrintOnlyMode()) return -1;
2763                    
2764                    String s = getSingleLineResultSet().getResult();
2765                    return parseInt(s);
2766            }
2767            
2768            /**
2769             * Gets the current number of MIDI instrument in the specified map.
2770             * @param mapId The ID of the map.
2771             * @return The current number of MIDI instrument in the specified map.
2772             * @throws IOException If some I/O error occurs.
2773             * @throws LscpException If LSCP protocol corruption occurs.
2774             * @throws LSException If some other error occurs.
2775             */
2776            public synchronized int
2777            getMidiInstrumentCount(int mapId) throws IOException, LscpException, LSException {
2778                    verifyConnection();
2779                    out.writeLine("GET MIDI_INSTRUMENTS " + String.valueOf(mapId));
2780                    if(getPrintOnlyMode()) return -1;
2781                    
2782                    String s = getSingleLineResultSet().getResult();
2783                    return parseInt(s);
2784            }
2785            
2786            /**
2787             * Gets all MIDI instrument from all maps.
2788             * @return A <code>MidiInstrumentInfo</code> array providing
2789             * all MIDI instruments from all MIDI instrument maps.
2790             * @throws IOException If some I/O error occurs.
2791             * @throws LscpException If LSCP protocol corruption occurs.
2792             * @throws LSException If some other error occurs.
2793             */
2794            public synchronized MidiInstrumentInfo[]
2795            getMidiInstruments() throws IOException, LscpException, LSException {
2796                    verifyConnection();
2797                    out.writeLine("LIST MIDI_INSTRUMENTS ALL");
2798                    if(getPrintOnlyMode()) return null;
2799                    
2800                    String[] entries = parseArray(getSingleLineResultSet().getResult());
2801                    
2802                    return getMidiInstruments(entries);
2803            }
2804            
2805            /**
2806             * Gets all MIDI instrument contained int the specified MIDI instrument map.
2807             * @param mapId The ID of the map, which instruments should be obtained.
2808             * @return A <code>MidiInstrumentInfo</code> array providing
2809             * all MIDI instruments from all MIDI instrument maps.
2810             * @throws IOException If some I/O error occurs.
2811             * @throws LscpException If LSCP protocol corruption occurs.
2812             * @throws LSException If some other error occurs.
2813             */
2814            public synchronized MidiInstrumentInfo[]
2815            getMidiInstruments(int mapId) throws IOException, LscpException, LSException {
2816                    verifyConnection();
2817                    out.writeLine("LIST MIDI_INSTRUMENTS " + String.valueOf(mapId));
2818                    if(getPrintOnlyMode()) return null;
2819                    
2820                    String[] entries = parseArray(getSingleLineResultSet().getResult());
2821                    
2822                    return getMidiInstruments(entries);
2823            }
2824            
2825            private MidiInstrumentInfo[]
2826            getMidiInstruments(String[] entries) throws IOException, LscpException, LSException {
2827                    Vector<MidiInstrumentInfo> v = new Vector<MidiInstrumentInfo>();
2828                    
2829                    for(String s : entries) {
2830                            Integer[] vals = parseIntList(s);
2831                            if(vals.length != 3) {
2832                                    throw new LscpException(LscpI18n.getLogMsg("CommandFailed!"));
2833                            }
2834                            
2835                            v.add(getMidiInstrumentInfo(vals[0], vals[1], vals[2]));
2836                    }
2837                    
2838                    return v.toArray(new MidiInstrumentInfo[v.size()]);
2839            }
2840            
2841            /**
2842             * Gets the current settings of the specified MIDI instrument.
2843             * @param mapId The ID of the map.
2844             * @param bank The index of the MIDI bank.
2845             * @param program The MIDI program number of the instrument.
2846             * @return <code>MidiInstrumentInfo</code> instance containing
2847             * the current settings of the specified MIDI instrument.
2848             * @throws IOException If an I/O error occurs.
2849             * @throws LscpException If LSCP protocol corruption occurs.
2850             * @throws LSException If the specified MIDI instrument is missing.
2851             */
2852            public synchronized MidiInstrumentInfo
2853            getMidiInstrumentInfo(int mapId, int bank, int program)
2854                                            throws IOException, LscpException, LSException {
2855            
2856                    verifyConnection();
2857                    StringBuffer cmd = new StringBuffer("GET MIDI_INSTRUMENT INFO ");
2858                    cmd.append(mapId).append(' ');
2859                    cmd.append(bank).append(' ');
2860                    cmd.append(program);
2861                    
2862                    out.writeLine(cmd.toString());
2863                    if(getPrintOnlyMode()) return null;
2864                    
2865                    ResultSet rs = getMultiLineResultSet();
2866                    MidiInstrumentEntry entry = new MidiInstrumentEntry(bank, program);
2867                    return new MidiInstrumentInfo(mapId, entry, rs.getMultiLineResult());
2868            }
2869            
2870            /**
2871           * Loads and assigns an instrument to a sampler channel. Notice that this function will           * Loads and assigns an instrument to a sampler channel. Notice that this function will
2872           * return after the instrument is fully loaded and the channel is ready to be used.           * return after the instrument is fully loaded and the channel is ready to be used.
          *    
2873           * @param filename The name of the instrument file           * @param filename The name of the instrument file
2874           * on the LinuxSampler instance's host system.           * on the LinuxSampler instance's host system.
2875           * @param instrIdx The index of the instrument in the instrument file.           * @param instrIdx The index of the instrument in the instrument file.
2876           * @param samplerChn The number of the sampler channel the instrument should be assigned to.           * @param samplerChn The number of the sampler channel the instrument should be assigned to.
          *  
2877           * @throws IOException If some I/O error occurs.           * @throws IOException If some I/O error occurs.
2878           * @throws LscpException If LSCP protocol corruption occurs.           * @throws LscpException If LSCP protocol corruption occurs.
2879           * @throws LSException If the loading of the instrument failed.           * @throws LSException If the loading of the instrument failed.
          *  
2880           * @see #loadInstrument(String, int, int, boolean)           * @see #loadInstrument(String, int, int, boolean)
2881           * @see #getSamplerChannels           * @see #getSamplerChannels
2882           */           */
# Line 1543  public class Client { Line 2914  public class Client {
2914                  String args = '\'' + filename + "' " + instrIdx + ' ' + samplerChn;                  String args = '\'' + filename + "' " + instrIdx + ' ' + samplerChn;
2915                                    
2916                  out.writeLine(cmd + args);                  out.writeLine(cmd + args);
2917                    if(getPrintOnlyMode()) return;
2918                                    
2919                  ResultSet rs = getEmptyResultSet();                  ResultSet rs = getEmptyResultSet();
2920          }          }
# Line 1565  public class Client { Line 2937  public class Client {
2937                                    
2938                  verifyConnection();                  verifyConnection();
2939                  out.writeLine("LOAD ENGINE " + engineName + ' ' + samplerChn);                  out.writeLine("LOAD ENGINE " + engineName + ' ' + samplerChn);
2940                    if(getPrintOnlyMode()) return;
2941                                    
2942                  ResultSet rs = getEmptyResultSet();                  ResultSet rs = getEmptyResultSet();
2943          }          }
# Line 1580  public class Client { Line 2953  public class Client {
2953          getSamplerChannelCount() throws IOException, LscpException, LSException {          getSamplerChannelCount() throws IOException, LscpException, LSException {
2954                  verifyConnection();                  verifyConnection();
2955                  out.writeLine("GET CHANNELS");                  out.writeLine("GET CHANNELS");
2956                    if(getPrintOnlyMode()) return -1;
2957                    
2958                  String s = getSingleLineResultSet().getResult();                  String s = getSingleLineResultSet().getResult();
2959                  return parseInt(s);                  return parseInt(s);
2960          }          }
2961                    
2962          /**          /**
2963             * Gets a list of all created sampler channels.
2964             * @return A <code>SamplerChannel</code> array providing all created sampler channels.
2965             * @throws IOException If some I/O error occurs.
2966             * @throws LscpException If LSCP protocol corruption occurs.
2967             * @throws LSException If some other error occurs.
2968             * @see #addSamplerChannel
2969             * @see #removeSamplerChannel
2970             */
2971            public synchronized SamplerChannel[]
2972            getSamplerChannels() throws IOException, LscpException, LSException {
2973                    Integer[] idS = getSamplerChannelIDs();
2974                    if(getPrintOnlyMode()) return null;
2975                    
2976                    SamplerChannel[] channels = new SamplerChannel[idS.length];
2977                    
2978                    for(int i = 0; i < channels.length; i++)
2979                            channels[i] = getSamplerChannelInfo(idS[i]);
2980                    
2981                    return channels;
2982            }
2983            
2984            /**
2985           * Gets a list with numerical IDs of all created sampler channels.           * Gets a list with numerical IDs of all created sampler channels.
2986           * @return An <code>Integer</code> array with numerical IDs of all created sampler channels.           * @return An <code>Integer</code> array providing
2987             * the numerical IDs of all created sampler channels.
2988           * @throws IOException If some I/O error occurs.           * @throws IOException If some I/O error occurs.
2989           * @throws LscpException If LSCP protocol corruption occurs.           * @throws LscpException If LSCP protocol corruption occurs.
2990           * @throws LSException If some other error occurs.           * @throws LSException If some other error occurs.
# Line 1594  public class Client { Line 2992  public class Client {
2992           * @see #removeSamplerChannel           * @see #removeSamplerChannel
2993           */           */
2994          public synchronized Integer[]          public synchronized Integer[]
2995          getSamplerChannels() throws IOException, LscpException, LSException {          getSamplerChannelIDs() throws IOException, LscpException, LSException {
2996                  verifyConnection();                  verifyConnection();
2997                  out.writeLine("LIST CHANNELS");                  out.writeLine("LIST CHANNELS");
2998                    if(getPrintOnlyMode()) return null;
2999                    
3000                  return parseIntList(getSingleLineResultSet().getResult());                  return parseIntList(getSingleLineResultSet().getResult());
3001          }          }
3002                    
# Line 1614  public class Client { Line 3014  public class Client {
3014          addSamplerChannel() throws IOException, LSException, LscpException {          addSamplerChannel() throws IOException, LSException, LscpException {
3015                  verifyConnection();                  verifyConnection();
3016                  out.writeLine("ADD CHANNEL");                  out.writeLine("ADD CHANNEL");
3017                    if(getPrintOnlyMode()) return -1;
3018                    
3019                  ResultSet rs = getEmptyResultSet();                  ResultSet rs = getEmptyResultSet();
3020                                    
3021                  return rs.getIndex();                  return rs.getIndex();
# Line 1634  public class Client { Line 3036  public class Client {
3036          removeSamplerChannel(int samplerChn) throws IOException, LscpException, LSException {          removeSamplerChannel(int samplerChn) throws IOException, LscpException, LSException {
3037                  verifyConnection();                  verifyConnection();
3038                  out.writeLine("REMOVE CHANNEL " + samplerChn);                  out.writeLine("REMOVE CHANNEL " + samplerChn);
3039                    if(getPrintOnlyMode()) return;
3040                                    
3041                  ResultSet rs = getEmptyResultSet();                  ResultSet rs = getEmptyResultSet();
3042          }          }
# Line 1649  public class Client { Line 3052  public class Client {
3052          getEngineCount() throws IOException, LscpException, LSException {          getEngineCount() throws IOException, LscpException, LSException {
3053                  verifyConnection();                  verifyConnection();
3054                  out.writeLine("GET AVAILABLE_ENGINES");                  out.writeLine("GET AVAILABLE_ENGINES");
3055                    if(getPrintOnlyMode()) return -1;
3056                    
3057                  String s = getSingleLineResultSet().getResult();                  String s = getSingleLineResultSet().getResult();
3058                  return parseInt(s);                  return parseInt(s);
3059          }          }
3060                    
3061          /**          /**
3062             * Gets a list of all available engines.
3063             *
3064             * @return <code>SamplerEngine</code> array containing all available engines.
3065             * @throws IOException If some I/O error occurs.
3066             * @throws LscpException If LSCP protocol corruption occurs.
3067             * @throws LSException If some other error occurs.
3068             */
3069            public synchronized SamplerEngine[]
3070            getEngines() throws IOException, LscpException, LSException {
3071                    String[] engines = getEngineNames();
3072                    if(getPrintOnlyMode()) return null;
3073                    
3074                    SamplerEngine[] se = new SamplerEngine[engines.length];
3075                    
3076                    for(int i = 0; i < engines.length; i++) se[i] = getEngineInfo(engines[i]);
3077                    
3078                    return se;
3079            }
3080            
3081            /**
3082           * Gets a list of all available engines' names.           * Gets a list of all available engines' names.
3083           *           *
3084           * @return <code>String</code> array with all available engines' names.           * @return <code>String</code> array with all available engines' names.
# Line 1661  public class Client { Line 3086  public class Client {
3086           * @throws LscpException If LSCP protocol corruption occurs.           * @throws LscpException If LSCP protocol corruption occurs.
3087           * @throws LSException If some other error occurs.           * @throws LSException If some other error occurs.
3088           */           */
3089          public synchronized String[]          private synchronized String[]
3090          getEngines() throws IOException, LscpException, LSException {          getEngineNames() throws IOException, LscpException, LSException {
3091                  verifyConnection();                  verifyConnection();
3092                  out.writeLine("LIST AVAILABLE_ENGINES");                  out.writeLine("LIST AVAILABLE_ENGINES");
3093                    if(getPrintOnlyMode()) return null;
3094                    
3095                  return parseStringList(getSingleLineResultSet().getResult());                  return parseStringList(getSingleLineResultSet().getResult());
3096          }          }
3097                    
# Line 1678  public class Client { Line 3105  public class Client {
3105           * @throws IOException If an I/O error occurs.           * @throws IOException If an I/O error occurs.
3106           * @throws LscpException If LSCP protocol corruption occurs.           * @throws LscpException If LSCP protocol corruption occurs.
3107           * @throws LSException If there is no sampler engine with name <code>engineName</code>.           * @throws LSException If there is no sampler engine with name <code>engineName</code>.
3108           * @see #getEngines           * @see #getEngineNames
3109           */           */
3110          public synchronized SamplerEngine          private synchronized SamplerEngine
3111          getEngineInfo(String engineName) throws IOException, LscpException, LSException {          getEngineInfo(String engineName) throws IOException, LscpException, LSException {
3112                  verifyConnection();                  verifyConnection();
3113                  out.writeLine("GET ENGINE INFO " + engineName);                  out.writeLine("GET ENGINE INFO " + engineName);
3114                    if(getPrintOnlyMode()) return null;
3115                    
3116                  ResultSet rs = getMultiLineResultSet();                  ResultSet rs = getMultiLineResultSet();
3117                  SamplerEngine se = new SamplerEngine(rs.getMultiLineResult());                  SamplerEngine se = new SamplerEngine(rs.getMultiLineResult());
3118                  se.setName(engineName);                  se.setName(engineName);
# Line 1706  public class Client { Line 3135  public class Client {
3135          getSamplerChannelInfo(int samplerChn) throws IOException, LscpException, LSException {          getSamplerChannelInfo(int samplerChn) throws IOException, LscpException, LSException {
3136                  verifyConnection();                  verifyConnection();
3137                  out.writeLine("GET CHANNEL INFO " + samplerChn);                  out.writeLine("GET CHANNEL INFO " + samplerChn);
3138                    if(getPrintOnlyMode()) return null;
3139                    
3140                  ResultSet rs = getMultiLineResultSet();                  ResultSet rs = getMultiLineResultSet();
3141                  SamplerChannel sc = new SamplerChannel(rs.getMultiLineResult());                  SamplerChannel sc = new SamplerChannel(rs.getMultiLineResult());
3142                  sc.setChannelID(samplerChn);                  sc.setChannelId(samplerChn);
3143                    if(sc.getEngine() != null) sc.setEngine(getEngineInfo(sc.getEngine().getName()));
3144                                    
3145                  return sc;                  return sc;
3146          }          }
# Line 1727  public class Client { Line 3159  public class Client {
3159          getChannelVoiceCount(int samplerChn) throws IOException, LscpException, LSException {          getChannelVoiceCount(int samplerChn) throws IOException, LscpException, LSException {
3160                  verifyConnection();                  verifyConnection();
3161                  out.writeLine("GET CHANNEL VOICE_COUNT " + samplerChn);                  out.writeLine("GET CHANNEL VOICE_COUNT " + samplerChn);
3162                    if(getPrintOnlyMode()) return -1;
3163                    
3164                  ResultSet rs = getSingleLineResultSet();                  ResultSet rs = getSingleLineResultSet();
3165                                    
3166                  return parseInt(rs.getResult());                  return parseInt(rs.getResult());
# Line 1747  public class Client { Line 3181  public class Client {
3181          getChannelStreamCount(int samplerChn) throws IOException, LscpException, LSException {          getChannelStreamCount(int samplerChn) throws IOException, LscpException, LSException {
3182                  verifyConnection();                  verifyConnection();
3183                  out.writeLine("GET CHANNEL STREAM_COUNT " + samplerChn);                  out.writeLine("GET CHANNEL STREAM_COUNT " + samplerChn);
3184                    if(getPrintOnlyMode()) return -1;
3185            
3186                  ResultSet rs = getSingleLineResultSet();                  ResultSet rs = getSingleLineResultSet();
3187                                    
3188                  if(rs.getResult().equals("NA")) return -1;                  if(rs.getResult().equals("NA")) return -1;
# Line 1771  public class Client { Line 3207  public class Client {
3207          getChannelBufferFillBytes(int samplerChn) throws IOException, LscpException, LSException {          getChannelBufferFillBytes(int samplerChn) throws IOException, LscpException, LSException {
3208                  verifyConnection();                  verifyConnection();
3209                  out.writeLine("GET CHANNEL BUFFER_FILL BYTES " + samplerChn);                  out.writeLine("GET CHANNEL BUFFER_FILL BYTES " + samplerChn);
3210                    if(getPrintOnlyMode()) return null;
3211                    
3212                  ResultSet rs = getSingleLineResultSet();                  ResultSet rs = getSingleLineResultSet();
3213                                    
3214                  if(rs.getResult().equals("NA")) return null;                  if(rs.getResult().equals("NA")) return null;
# Line 1786  public class Client { Line 3224  public class Client {
3224                          if(i == -1) throw new LscpException(LscpI18n.getLogMsg("CommandFailed!"));                          if(i == -1) throw new LscpException(LscpI18n.getLogMsg("CommandFailed!"));
3225                                                    
3226                          BufferFill bf = new BufferFill();                          BufferFill bf = new BufferFill();
3227                          bf.setStreamID(parseInt(s.substring(1, i)));                          bf.setStreamId(parseInt(s.substring(1, i)));
3228                          bf.setValue(parseInt(s.substring(i + 1)));                          bf.setValue(parseInt(s.substring(i + 1)));
3229                          v.add(bf);                          v.add(bf);
3230                  }                  }
# Line 1813  public class Client { Line 3251  public class Client {
3251                                    
3252                  verifyConnection();                  verifyConnection();
3253                  out.writeLine("GET CHANNEL BUFFER_FILL PERCENTAGE " + samplerChn);                  out.writeLine("GET CHANNEL BUFFER_FILL PERCENTAGE " + samplerChn);
3254                    if(getPrintOnlyMode()) return null;
3255                    
3256                  ResultSet rs = getSingleLineResultSet();                  ResultSet rs = getSingleLineResultSet();
3257                                    
3258                  return getChannelBufferFillPercentage(rs.getResult());                  return getChannelBufferFillPercentage(rs.getResult());
# Line 1836  public class Client { Line 3276  public class Client {
3276                                  throw new LscpException(LscpI18n.getLogMsg("CommandFailed!"));                                  throw new LscpException(LscpI18n.getLogMsg("CommandFailed!"));
3277                                                    
3278                          BufferFill bf = new BufferFill();                          BufferFill bf = new BufferFill();
3279                          bf.setStreamID(parseInt(s.substring(1, i)));                          bf.setStreamId(parseInt(s.substring(1, i)));
3280                          bf.setValue(parseInt(s.substring(i + 1, s.length() - 1)));                          bf.setValue(parseInt(s.substring(i + 1, s.length() - 1)));
3281                          v.add(bf);                          v.add(bf);
3282                  }                  }
# Line 1848  public class Client { Line 3288  public class Client {
3288           * Sets the audio output device on the specified sampler channel.           * Sets the audio output device on the specified sampler channel.
3289           *           *
3290           * @param samplerChn The sampler channel number.           * @param samplerChn The sampler channel number.
3291           * @param devID The numerical ID of the audio output device.           * @param devId The numerical ID of the audio output device.
3292           *           *
3293           * @throws IOException If some I/O error occurs.           * @throws IOException If some I/O error occurs.
3294           * @throws LscpException If LSCP protocol corruption occurs.           * @throws LscpException If LSCP protocol corruption occurs.
3295           * @throws LSException If           * @throws LSException If
3296           * <ul>           * <ul>
3297           * <li><code>samplerChn</code> is not a valid channel number;           * <li><code>samplerChn</code> is not a valid channel number;
3298           * <li><code>devID</code> is not a valid audio output device ID;           * <li><code>devId</code> is not a valid audio output device ID;
3299           * </ul>           * </ul>
3300           *           *
3301           * @see #getSamplerChannels           * @see #getSamplerChannels
3302           * @see #getAudioOutputDevices           * @see #getAudioOutputDevices
3303           */           */
3304          public synchronized void          public synchronized void
3305          setChannelAudioOutputDevice(int samplerChn, int devID)          setChannelAudioOutputDevice(int samplerChn, int devId)
3306                                  throws IOException, LscpException, LSException {                                  throws IOException, LscpException, LSException {
3307                                    
3308                  verifyConnection();                  verifyConnection();
3309                  out.writeLine("SET CHANNEL AUDIO_OUTPUT_DEVICE " + samplerChn + ' ' + devID);                  out.writeLine("SET CHANNEL AUDIO_OUTPUT_DEVICE " + samplerChn + ' ' + devId);
3310                    if(getPrintOnlyMode()) return;
3311                                    
3312                  ResultSet rs = getEmptyResultSet();                  ResultSet rs = getEmptyResultSet();
3313          }          }
# Line 1897  public class Client { Line 3338  public class Client {
3338                  verifyConnection();                  verifyConnection();
3339                  String args = " " + samplerChn + ' ' + audioOut + ' ' + audioIn;                  String args = " " + samplerChn + ' ' + audioOut + ' ' + audioIn;
3340                  out.writeLine("SET CHANNEL AUDIO_OUTPUT_CHANNEL" + args);                  out.writeLine("SET CHANNEL AUDIO_OUTPUT_CHANNEL" + args);
3341                    if(getPrintOnlyMode()) return;
3342                                    
3343                  ResultSet rs = getEmptyResultSet();                  ResultSet rs = getEmptyResultSet();
3344          }          }
# Line 1905  public class Client { Line 3347  public class Client {
3347           * Sets the MIDI input device on the specified sampler channel.           * Sets the MIDI input device on the specified sampler channel.
3348           *           *
3349           * @param samplerChn The sampler channel number.           * @param samplerChn The sampler channel number.
3350           * @param devID The numerical ID of the MIDI input device.           * @param devId The numerical ID of the MIDI input device.
3351           *           *
3352           * @throws IOException If some I/O error occurs.           * @throws IOException If some I/O error occurs.
3353           * @throws LscpException If LSCP protocol corruption occurs.           * @throws LscpException If LSCP protocol corruption occurs.
3354           * @throws LSException If           * @throws LSException If
3355           * <ul>           * <ul>
3356           * <li><code>samplerChn</code> is not a valid channel number;           * <li><code>samplerChn</code> is not a valid channel number;
3357           * <li><code>devID</code> is not a valid MIDI input device ID;           * <li><code>devId</code> is not a valid MIDI input device ID;
3358           * </ul>           * </ul>
3359           *           *
3360           * @see #getSamplerChannels           * @see #getSamplerChannels
3361           * @see #getMidiInputDevices           * @see #getMidiInputDevices
3362           */           */
3363          public synchronized void          public synchronized void
3364          setChannelMidiInputDevice(int samplerChn, int devID)          setChannelMidiInputDevice(int samplerChn, int devId)
3365                                  throws IOException, LscpException, LSException {                                  throws IOException, LscpException, LSException {
3366                                    
3367                  verifyConnection();                  verifyConnection();
3368                  out.writeLine("SET CHANNEL MIDI_INPUT_DEVICE " + samplerChn + ' ' + devID);                  out.writeLine("SET CHANNEL MIDI_INPUT_DEVICE " + samplerChn + ' ' + devId);
3369                    if(getPrintOnlyMode()) return;
3370                                    
3371                  ResultSet rs = getEmptyResultSet();                  ResultSet rs = getEmptyResultSet();
3372          }          }
# Line 1946  public class Client { Line 3389  public class Client {
3389                                    
3390                  verifyConnection();                  verifyConnection();
3391                  out.writeLine("SET CHANNEL MIDI_INPUT_PORT " + samplerChn + ' ' + port);                  out.writeLine("SET CHANNEL MIDI_INPUT_PORT " + samplerChn + ' ' + port);
3392                    if(getPrintOnlyMode()) return;
3393                                    
3394                  ResultSet rs = getEmptyResultSet();                  ResultSet rs = getEmptyResultSet();
3395          }          }
# Line 1970  public class Client { Line 3414  public class Client {
3414                  String args = String.valueOf(samplerChn) + ' ';                  String args = String.valueOf(samplerChn) + ' ';
3415                  args += (midiChn == -1 ? "ALL" : String.valueOf(midiChn));                  args += (midiChn == -1 ? "ALL" : String.valueOf(midiChn));
3416                  out.writeLine("SET CHANNEL MIDI_INPUT_CHANNEL " + args);                  out.writeLine("SET CHANNEL MIDI_INPUT_CHANNEL " + args);
3417                    if(getPrintOnlyMode()) return;
3418                    
3419                    ResultSet rs = getEmptyResultSet();
3420            }
3421            
3422            /**
3423             * Sets the MIDI instrument map to be used on the specified sampler channel.
3424             *
3425             * @param samplerChn The sampler channel number.
3426             * @param mapId Specifies the numerical ID of the MIDI instrument
3427             * map to assign. To remove the current map binding use <code>-1</code>.
3428             * To set the current map to be the default map use <code>-2</code>.
3429             *
3430             * @throws IOException If some I/O error occurs.
3431             * @throws LscpException If LSCP protocol corruption occurs.
3432             * @throws LSException If
3433             * <ul>
3434             * <li><code>samplerChn</code> is not a valid channel number;
3435             * <li><code>mapId</code> is not a valid MIDI instrument map ID;
3436             * </ul>
3437             *
3438             * @see #getSamplerChannels
3439             * @see #getMidiInstrumentMaps
3440             */
3441            public synchronized void
3442            setChannelMidiInstrumentMap(int samplerChn, int mapId)
3443                                    throws IOException, LscpException, LSException {
3444                    
3445                    verifyConnection();
3446                    String s;
3447                    if(mapId == -1) {
3448                            s = " NONE";
3449                    } else if(mapId == -2) {
3450                            s = " DEFAULT";
3451                    } else {
3452                            s = " " + String.valueOf(mapId);
3453                    }
3454                    out.writeLine("SET CHANNEL MIDI_INSTRUMENT_MAP " + samplerChn + s);
3455                    if(getPrintOnlyMode()) return;
3456                                    
3457                  ResultSet rs = getEmptyResultSet();                  ResultSet rs = getEmptyResultSet();
3458          }          }
# Line 1992  public class Client { Line 3475  public class Client {
3475                    
3476                  verifyConnection();                  verifyConnection();
3477                  out.writeLine("SET CHANNEL VOLUME " + samplerChn + ' ' + volume);                  out.writeLine("SET CHANNEL VOLUME " + samplerChn + ' ' + volume);
3478                    if(getPrintOnlyMode()) return;
3479                    
3480                    ResultSet rs = getEmptyResultSet();
3481            }
3482            
3483            /**
3484             * Mute/unmute the specified sampler channel.
3485             *
3486             * @param samplerChn The sampler channel number.
3487             * @param mute If <code>true</code> the specified channel is muted, else the channel
3488             * is unmuted.
3489             *
3490             * @throws IOException If some I/O error occurs.
3491             * @throws LscpException If LSCP protocol corruption occurs.
3492             * @throws LSException If <code>samplerChn</code> is not a valid channel number or if
3493             * there is no engine assigned yet to the specified sampler channel.
3494             * @see #getSamplerChannels
3495             */
3496            public synchronized void
3497            setChannelMute(int samplerChn, boolean mute)
3498                                    throws IOException, LscpException, LSException {
3499            
3500                    verifyConnection();
3501                    out.writeLine("SET CHANNEL MUTE " + samplerChn + ' ' + (mute ? 1 : 0));
3502                    if(getPrintOnlyMode()) return;
3503                    
3504                    ResultSet rs = getEmptyResultSet();
3505            }
3506            
3507            /**
3508             * Solo/unsolo the specified sampler channel.
3509             *
3510             * @param samplerChn The sampler channel number.
3511             * @param solo <code>true</code> to solo the specified channel, <code>false</code>
3512             * otherwise.
3513             *
3514             * @throws IOException If some I/O error occurs.
3515             * @throws LscpException If LSCP protocol corruption occurs.
3516             * @throws LSException If <code>samplerChn</code> is not a valid channel number or if
3517             * there is no engine assigned yet to the specified sampler channel.
3518             * @see #getSamplerChannels
3519             */
3520            public synchronized void
3521            setChannelSolo(int samplerChn, boolean solo)
3522                                    throws IOException, LscpException, LSException {
3523            
3524                    verifyConnection();
3525                    out.writeLine("SET CHANNEL SOLO " + samplerChn + ' ' + (solo ? 1 : 0));
3526                    if(getPrintOnlyMode()) return;
3527                    
3528                    ResultSet rs = getEmptyResultSet();
3529            }
3530            
3531            /**
3532             * Creates an additional effect send on the specified sampler channel.
3533             * @param channel The sampler channel, on which a new effect send should be added.
3534             * @param midiCtrl Defines the MIDI controller, which
3535             * will be able alter the effect send level.
3536             * @return The unique ID of the newly created effect send entity.
3537             * @throws IOException If some I/O error occurs.
3538             * @throws LSException If the creation of the effect send failed.
3539             * @throws LscpException If LSCP protocol corruption occurs.
3540             * @see #destroyFxSend
3541             */
3542            public synchronized int
3543            createFxSend(int channel, int midiCtrl)
3544                            throws IOException, LSException, LscpException {
3545                    
3546                    return createFxSend(channel, midiCtrl, null);
3547            }
3548            
3549            /**
3550             * Creates an additional effect send on the specified sampler channel.
3551             * @param channel The sampler channel, on which the effect send should be created on.
3552             * @param midiCtrl Defines the MIDI controller, which can alter the effect send level.
3553             * @param name The name of the effect send entity. The name does not have to be unique.
3554             * @return The unique ID of the newly created effect send entity.
3555             * @throws IOException If some I/O error occurs.
3556             * @throws LSException If the creation of the effect send failed.
3557             * @throws LscpException If LSCP protocol corruption occurs.
3558             * @see #destroyFxSend
3559             */
3560            public synchronized int
3561            createFxSend(int channel, int midiCtrl, String name)
3562                            throws IOException, LSException, LscpException {
3563                    
3564                    verifyConnection();
3565                    String s = String.valueOf(channel) + " " + String.valueOf(midiCtrl);
3566                    if(name != null) s += " '" + toEscapedString(name) + "'";
3567                    out.writeLine("CREATE FX_SEND " + s);
3568                    if(getPrintOnlyMode()) return -1;
3569                    
3570                    ResultSet rs = getEmptyResultSet();
3571                    
3572                    return rs.getIndex();
3573            }
3574            
3575            /**
3576             * Destroys the specified effect send on the specified sampler channel.
3577             * @param channel The sampler channel, from which
3578             * the specified effect send should be removed.
3579             * @param fxSend The ID of the effect send that should be removed.
3580             * @throws LSException If some other error occurs.
3581             * @throws LscpException If LSCP protocol corruption occurs.
3582             * @see #createFxSend
3583             */
3584            public synchronized void
3585            destroyFxSend(int channel, int fxSend)
3586                            throws IOException, LSException, LscpException {
3587                    
3588                    verifyConnection();
3589                    String s = String.valueOf(channel) + " " + String.valueOf(fxSend);
3590                    out.writeLine("DESTROY FX_SEND " + s);
3591                    if(getPrintOnlyMode()) return;
3592                    
3593                    ResultSet rs = getEmptyResultSet();
3594            }
3595            
3596            /**
3597             * Gets the current number of effect sends on the specified sampler channel.
3598             * @param channel The ID of the sampler channel.
3599             * @return The current number of effect sends on the specified sampler channels.
3600             * @throws IOException If some I/O error occurs.
3601             * @throws LscpException If LSCP protocol corruption occurs.
3602             * @throws LSException If some other error occurs.
3603             */
3604            public synchronized int
3605            getFxSoundCount(int channel) throws IOException, LscpException, LSException {
3606                    verifyConnection();
3607                    out.writeLine("GET FX_SENDS " + String.valueOf(channel));
3608                    if(getPrintOnlyMode()) return -1;
3609                    
3610                    String s = getSingleLineResultSet().getResult();
3611                    return parseInt(s);
3612            }
3613            
3614            /**
3615             * Gets a list of all created effect sends on the specified sampler channel.
3616             * @param channel The sampler channel number.
3617             * @return A <code>FxSend</code> array providing all created
3618             * effect sends on the specified sampler channel.
3619             * @throws IOException If some I/O error occurs.
3620             * @throws LscpException If LSCP protocol corruption occurs.
3621             * @throws LSException If <code>channel</code> is not a valid sampler channel ID.
3622             * @see #createFxSend
3623             * @see #destroyFxSend
3624             */
3625            public synchronized FxSend[]
3626            getFxSends(int channel) throws IOException, LscpException, LSException {
3627                    Integer[] idS = getFxSendIDs(channel);
3628                    if(getPrintOnlyMode()) return null;
3629                    
3630                    FxSend[] fxSends = new FxSend[idS.length];
3631                    
3632                    for(int i = 0; i < fxSends.length; i++)
3633                            fxSends[i] = getFxSendInfo(channel, idS[i]);
3634                    
3635                    return fxSends;
3636            }
3637            
3638            /**
3639             * Gets a list of effect sends on the specified sampler channel.
3640             * @param channel The sampler channel number.
3641             * @return An <code>Integer</code> array providing
3642             * the numerical IDs of all effect sends on the specified sampler channel.
3643             * @throws IOException If some I/O error occurs.
3644             * @throws LscpException If LSCP protocol corruption occurs.
3645             * @throws LSException If <code>channel</code> is not a valid sampler channel ID.
3646             * @see #createFxSend
3647             * @see #destroyFxSend
3648             */
3649            public synchronized Integer[]
3650            getFxSendIDs(int channel) throws IOException, LscpException, LSException {
3651                    verifyConnection();
3652                    out.writeLine("LIST FX_SENDS " + channel);
3653                    if(getPrintOnlyMode()) return null;
3654                    
3655                    return parseIntList(getSingleLineResultSet().getResult());
3656            }
3657            
3658            /**
3659             * Gets the current settings of the specified effect send entity.
3660             * @param channel The sampler channel number.
3661             * @param fxSend The numerical ID of the effect send entity.
3662             * @return <code>FxSend</code> instance containing
3663             * the current settings of the specified effect send entity.
3664             * @throws IOException If an I/O error occurs.
3665             * @throws LscpException If LSCP protocol corruption occurs.
3666             * @throws LSException If the sampler channel and/or the effect send number are invalid.
3667             */
3668            public synchronized FxSend
3669            getFxSendInfo(int channel, int fxSend) throws IOException, LscpException, LSException {
3670                    verifyConnection();
3671                    String s = String.valueOf(channel) + " " + String.valueOf(fxSend);
3672                    out.writeLine("GET FX_SEND INFO " + s);
3673                    if(getPrintOnlyMode()) return null;
3674                    
3675                    ResultSet rs = getMultiLineResultSet();
3676                    FxSend fxs = new FxSend(rs.getMultiLineResult());
3677                    fxs.setFxSendId(fxSend);
3678                    
3679                    return fxs;
3680            }
3681            
3682            /**
3683             * Sets the name of the specified effect send.
3684             * @param channel The sampler channel number.
3685             * @param fxSend The numerical ID of the effect send entity.
3686             * @param name The new name for the specified effect send.
3687             * @throws IOException If some I/O error occurs.
3688             * @throws LscpException If LSCP protocol corruption occurs.
3689             * @throws LSException If <code>channel</code> is not a valid channel
3690             * number or <code>fxSend</code> is not a valid effect send ID;
3691             */
3692            public synchronized void
3693            setFxSendName(int channel, int fxSend, String name)
3694                                    throws IOException, LscpException, LSException {
3695                    
3696                    verifyConnection();
3697                    String args = " " + channel + " " + fxSend + " '" + toEscapedString(name) + "'";
3698                    out.writeLine("SET FX_SEND NAME" + args);
3699                    if(getPrintOnlyMode()) return;
3700                    
3701                    ResultSet rs = getEmptyResultSet();
3702            }
3703            
3704            /**
3705             * Sets the destination of an effect send's audio channel in the specified sampler channel.
3706             * @param channel The sampler channel number.
3707             * @param fxSend The numerical ID of the effect send entity to be rerouted.
3708             * @param audioSrc The numerical ID of the effect send's audio output channel,
3709             * which should be rerouted.
3710             * @param audioDst The audio channel of the selected audio output device
3711             * where <code>audioSrc</code> should be routed to.
3712             * @throws IOException If some I/O error occurs.
3713             * @throws LscpException If LSCP protocol corruption occurs.
3714             * @throws LSException If
3715             * <ul>
3716             * <li><code>channel</code> is not a valid channel number;
3717             * <li><code>fxSend</code> is not a valid effect send ID;
3718             * <li>There is no engine assigned yet to the specified sampler channel;
3719             * <li>There is no audio output device connected to the specified sampler channel.
3720             * </ul>
3721             */
3722            public synchronized void
3723            setFxSendAudioOutputChannel(int channel, int fxSend, int audioSrc, int audioDst)
3724                                    throws IOException, LscpException, LSException {
3725                    
3726                    verifyConnection();
3727                    String args = " " + channel + " " + fxSend + " " + audioSrc + " " + audioDst;
3728                    out.writeLine("SET FX_SEND AUDIO_OUTPUT_CHANNEL" + args);
3729                    if(getPrintOnlyMode()) return;
3730                    
3731                    ResultSet rs = getEmptyResultSet();
3732            }
3733            
3734            /**
3735             * Sets the MIDI controller, which will be able to modify
3736             * the send level of the specified effect send in the specified sampler channel.
3737             * @param channel The sampler channel number.
3738             * @param fxSend The numerical ID of the effect send entity.
3739             * @param midiCtrl The MIDI controller which shall be
3740             * able to modify the effect send's send level.
3741             * @throws IOException If some I/O error occurs.
3742             * @throws LscpException If LSCP protocol corruption occurs.
3743             * @throws LSException If
3744             * <ul>
3745             * <li><code>channel</code> is not a valid channel number;
3746             * <li><code>fxSend</code> is not a valid effect send ID;
3747             * <li><code>midiCtrl</code> is not a valid controller;
3748             * </ul>
3749             */
3750            public synchronized void
3751            setFxSendMidiController(int channel, int fxSend, int midiCtrl)
3752                                    throws IOException, LscpException, LSException {
3753                    
3754                    verifyConnection();
3755                    String args = " " + channel + " " + fxSend + " " + midiCtrl;
3756                    out.writeLine("SET FX_SEND MIDI_CONTROLLER" + args);
3757                    if(getPrintOnlyMode()) return;
3758                    
3759                    ResultSet rs = getEmptyResultSet();
3760            }
3761            
3762            /**
3763             * Sets the current send level of the specified
3764             * effect send entity in the specified sampler channel.
3765             * @param channel The sampler channel number.
3766             * @param fxSend The numerical ID of the effect send entity.
3767             * @param volume The new volume value (a value smaller than 1.0 means
3768             * attenuation, whereas a value greater than 1.0 means amplification).
3769             * @throws IOException If some I/O error occurs.
3770             * @throws LscpException If LSCP protocol corruption occurs.
3771             * @throws LSException If some other error occurs.
3772             */
3773            public synchronized void
3774            setFxSendLevel(int channel, int fxSend, float volume)
3775                                    throws IOException, LscpException, LSException {
3776                    
3777                    verifyConnection();
3778                    String args = " " + channel + " " + fxSend + " " + String.valueOf(volume);
3779                    out.writeLine("SET FX_SEND LEVEL" + args);
3780                    if(getPrintOnlyMode()) return;
3781                    
3782                    ResultSet rs = getEmptyResultSet();
3783            }
3784            
3785            /**
3786             * Starts an instrument editor for editing the loaded instrument
3787             * on the specified sampler channel.
3788             * @param samplerChn The sampler channel number.
3789             * @throws IOException If some I/O error occurs.
3790             * @throws LscpException If LSCP protocol corruption occurs.
3791             * @throws LSException If <code>samplerChn</code> is not a valid channel number or if
3792             * there is no instrument loaded on the specified sampler channel.
3793             * @see #getSamplerChannels
3794             */
3795            public synchronized void
3796            editChannelInstrument(int samplerChn) throws IOException, LscpException, LSException {
3797                    verifyConnection();
3798                    out.writeLine("EDIT CHANNEL INSTRUMENT " + samplerChn);
3799                    if(getPrintOnlyMode()) return;
3800                    
3801                    ResultSet rs = getEmptyResultSet();
3802            }
3803            
3804            
3805            
3806            /**
3807             * Adds the specified directory to the instruments database.
3808             * @param dir The absolute (escaped) path name of the directory to add.
3809             * @throws IOException If some I/O error occurs.
3810             * @throws LSException If the creation of the directory failed.
3811             * @throws LscpException If LSCP protocol corruption occurs.
3812             */
3813            public synchronized void
3814            addDbDirectory(String dir) throws IOException, LSException, LscpException {
3815                    verifyConnection();
3816                    out.writeLine("ADD DB_INSTRUMENT_DIRECTORY '" + dir + "'");
3817                    if(getPrintOnlyMode()) return;
3818                    
3819                    ResultSet rs = getEmptyResultSet();
3820            }
3821            
3822            /**
3823             * Removes the specified directory from the instruments database.
3824             * @param dir The absolute (escaped) path name of the directory to remove.
3825             * @throws IOException If some I/O error occurs.
3826             * @throws LscpException If LSCP protocol corruption occurs.
3827             * @throws LSException If the specified directory is not
3828             * empty or if the removal of the directory failed.
3829             */
3830            public synchronized void
3831            removeDbDirectory(String dir) throws IOException, LscpException, LSException {
3832                    removeDbDirectory(dir, false);
3833            }
3834            
3835            /**
3836             * Removes the specified directory from the instruments database.
3837             * @param dir The absolute path name of the directory to remove.
3838             * @param force If <code>true</code> forces the removal of non-empty
3839             * directory and all its content.
3840             * @throws IOException If some I/O error occurs.
3841             * @throws LscpException If LSCP protocol corruption occurs.
3842             * @throws LSException If the removing of the directory failed.
3843             */
3844            public synchronized void
3845            removeDbDirectory(String dir, boolean force)
3846                                    throws IOException, LscpException, LSException {
3847                    
3848                    verifyConnection();
3849                    String s = "REMOVE DB_INSTRUMENT_DIRECTORY ";
3850                    if(force) s += "FORCE ";
3851                    out.writeLine(s + "'" + dir + "'");
3852                    if(getPrintOnlyMode()) return;
3853                    
3854                    ResultSet rs = getEmptyResultSet();
3855            }
3856            
3857            /**
3858             * Removes the specified directories from the instruments database.
3859             * @param dirs The absolute (escaped) path names of the directories to remove.
3860             * @param force If <code>true</code> forces the removal of non-empty
3861             * directories.
3862             * @throws IOException If some I/O error occurs.
3863             * @throws LscpException If LSCP protocol corruption occurs.
3864             * @throws LSException If the removing of the directores failed.
3865             */
3866            public synchronized void
3867            removeDbDirectories(String[] dirs, boolean force)
3868                                    throws IOException, LscpException, LSException {
3869                    
3870                    verifyConnection();
3871                    String cmd = "REMOVE DB_INSTRUMENT_DIRECTORY ";
3872                    if(force) cmd += "FORCE ";
3873                    
3874                    for(String s : dirs) out.writeLine(cmd + "'" + s + "'");
3875                    
3876                    if(getPrintOnlyMode()) return;
3877                    
3878                    getEmptyResultSets(dirs.length, "Client.dirDeletionFailed!");
3879            }
3880            
3881            /**
3882             * Gets the number of directories in the specified directory.
3883             * @return The current number of directories in the specified directory.
3884             * @param dir The absolute path name of the directory.
3885             * @throws IOException If some I/O error occurs.
3886             * @throws LscpException If LSCP protocol corruption occurs.
3887             * @throws LSException If some other error occurs.
3888             */
3889            public synchronized int
3890            getDbDirectoryCount(String dir) throws IOException, LscpException, LSException {
3891                    return getDbDirectoryCount(dir, false);
3892            }
3893            
3894            /**
3895             * Gets the number of directories in the specified directory.
3896             * @return The current number of directories in the specified directory.
3897             * @param dir The absolute path name of the directory.
3898             * @param recursive If <code>true</code>, the number of all directories
3899             * in the specified subtree will be returned.
3900             * @throws IOException If some I/O error occurs.
3901             * @throws LscpException If LSCP protocol corruption occurs.
3902             * @throws LSException If some other error occurs.
3903             */
3904            public synchronized int
3905            getDbDirectoryCount(String dir, boolean recursive)
3906                                    throws IOException, LscpException, LSException {
3907                    
3908                    verifyConnection();
3909                    String s;
3910                    if(recursive) s = "GET DB_INSTRUMENT_DIRECTORIES RECURSIVE '";
3911                    else s = "GET DB_INSTRUMENT_DIRECTORIES '";
3912                    out.writeLine(s + dir + "'");
3913                    if(getPrintOnlyMode()) return -1;
3914                    
3915                    s = getSingleLineResultSet().getResult();
3916                    return parseInt(s);
3917            }
3918            
3919            /**
3920             * Gets the list of directories in the specified directory.
3921             * @param dir The absolute path name of the directory.
3922             * @return A <code>String</code> array providing the names of
3923             * all directories in the specified directory.
3924             * @throws IOException If some I/O error occurs.
3925             * @throws LscpException If LSCP protocol corruption occurs.
3926             * @throws LSException If the specified path name is invalid.
3927             */
3928            public synchronized String[]
3929            getDbDirectoryNames(String dir) throws IOException, LscpException, LSException {
3930                    verifyConnection();
3931                    out.writeLine("LIST DB_INSTRUMENT_DIRECTORIES '" + dir + "'");
3932                    if(getPrintOnlyMode()) return null;
3933                    
3934                    String[] names = parseEscapedStringList(getSingleLineResultSet().getResult());
3935                    for(int i = 0; i < names.length; i++) {
3936                            names[i] = toNonEscapedString(names[i]);
3937                    }
3938                    return names;
3939            }
3940            
3941            /**
3942             * Gets information about the specified directory.
3943             * @param dir The absolute path name of the directory.
3944             * @return A <code>DbDirectoryInfo</code> instance providing information
3945             * about the specified directory.
3946             * @throws IOException If some I/O error occurs.
3947             * @throws LscpException If LSCP protocol corruption occurs.
3948             * @throws LSException If the specified directory is not found.
3949             */
3950            public synchronized DbDirectoryInfo
3951            getDbDirectoryInfo(String dir) throws IOException, LscpException, LSException {
3952                    verifyConnection();
3953                    out.writeLine("GET DB_INSTRUMENT_DIRECTORY INFO '" + dir + "'");
3954                    if(getPrintOnlyMode()) return null;
3955                    
3956                    ResultSet rs = getMultiLineResultSet();
3957                    DbDirectoryInfo info = new DbDirectoryInfo(rs.getMultiLineResult());
3958                    if(dir.equals("/")) {
3959                            info.setName("/");
3960                    } else {
3961                            dir = removeEndingFileSeparator(dir);
3962                    }
3963                    String s = getFileName(dir);
3964                    if(s != null) info.setName(toNonEscapedFileName(s));
3965                    s = getParentDirectory(dir);
3966                    if(s != null) info.setParentDirectoryPath(s);
3967                    
3968                    return info;
3969            }
3970            
3971            /**
3972             * Gets the list of directories in the specified directory.
3973             * @param dir The absolute path name of the directory.
3974             * @return A <code>DbDirectoryInfo</code> array providing
3975             * information about all directories in the specified directory.
3976             * @throws IOException If some I/O error occurs.
3977             * @throws LscpException If LSCP protocol corruption occurs.
3978             * @throws LSException If the specified path name is invalid.
3979             */
3980            public synchronized DbDirectoryInfo[]
3981            getDbDirectories(String dir) throws IOException, LscpException, LSException {
3982                    String[] dirS = getDbDirectoryNames(dir);
3983                    if(!hasEndingFileSeparator(dir)) dir += "/";
3984                    DbDirectoryInfo[] infoS = new DbDirectoryInfo[dirS.length];
3985                    for(int i = 0; i < dirS.length; i++) {
3986                            infoS[i] = getDbDirectoryInfo(dir + toEscapedFileName(dirS[i]));
3987                    }
3988                    return infoS;
3989            }
3990            
3991            /**
3992             * Gets the list of directories in the specified directory.
3993             * @param dir The absolute path name of the directory.
3994             * @return A <code>DbDirectoryInfo</code> array providing
3995             * information about all directories in the specified directory.
3996             * @throws IOException If some I/O error occurs.
3997             * @throws LscpException If LSCP protocol corruption occurs.
3998             * @throws LSException If the specified path name is invalid.
3999             *
4000            public synchronized DbDirectoryInfo[]
4001            getDbDirectories(String dir) throws IOException, LscpException, LSException {
4002                    String[] dirS = getDbDirectoryNames(dir);
4003                    if(dirS.length == 0) return new DbDirectoryInfo[0];
4004                    
4005                    if(dir.charAt(dir.length() - 1) != '/') dir += "/";
4006                    
4007                    for(int i = 0; i < dirS.length; i++) {
4008                            out.writeLine("GET DB_INSTRUMENT_DIRECTORY INFO '" + dir + dirS[i] + "'");
4009                    }
4010                    
4011                    if(getPrintOnlyMode()) return null;
4012                    
4013                    if(dir.length() > 1) dir = dir.substring(0, dir.length() - 1);
4014                    StringBuffer sb = new StringBuffer();
4015                    DbDirectoryInfo[] infoS = new DbDirectoryInfo[dirS.length];
4016                    for(int i = 0; i < dirS.length; i++) {
4017                            try {
4018                                    ResultSet rs = getMultiLineResultSet();
4019                                    infoS[i] = new DbDirectoryInfo(rs.getMultiLineResult());
4020                                    infoS[i].setName(dirS[i]);
4021                                    infoS[i].setParentDirectoryPath(dir);
4022                            } catch (SocketTimeoutException e) {
4023                                    getLogger().log(Level.FINE, e.getMessage(), e);
4024                                    sb.append(e.getMessage()).append("\n");
4025                                    break;
4026                            } catch (Exception e) {
4027                                    getLogger().log(Level.FINE, e.getMessage(), e);
4028                                    sb.append(e.getMessage()).append("\n");
4029                            }
4030                    }
4031                    
4032                    String details = sb.toString();
4033                    if(details.length() > 0) {
4034                            String err = LscpI18n.getLogMsg("Client.getInstrsInfoFailed!");
4035                            throw new LSException(0, err, details);
4036                    }
4037                    
4038                    return infoS;
4039            }*/
4040            
4041            /**
4042             * Renames the specified directory.
4043             * @param dir The absolute path name of the directory to rename.
4044             * @param name The new name for the directory.
4045             * @throws IOException If some I/O error occurs.
4046             * @throws LSException If the renaming of the directory failed.
4047             * @throws LscpException If LSCP protocol corruption occurs.
4048             */
4049            public synchronized void
4050            renameDbDirectory(String dir, String name) throws IOException, LSException, LscpException {
4051                    verifyConnection();
4052                    name = toEscapedString(name);
4053                    out.writeLine("SET DB_INSTRUMENT_DIRECTORY NAME '" + dir + "' '" + name + "'");
4054                    if(getPrintOnlyMode()) return;
4055                    
4056                    ResultSet rs = getEmptyResultSet();
4057            }
4058            
4059            /**
4060             * Moves the specified directory into the specified location.
4061             * @param dir The absolute path name of the directory to move.
4062             * @param dst The location where the directory will be moved 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            moveDbDirectory(String dir, String dst) throws IOException, LSException, LscpException {
4069                    verifyConnection();
4070                    out.writeLine("MOVE DB_INSTRUMENT_DIRECTORY '" + dir + "' '" + dst + "'");
4071                    if(getPrintOnlyMode()) return;
4072                    
4073                    ResultSet rs = getEmptyResultSet();
4074            }
4075            
4076            /**
4077             * Moves the specified directories into the specified location.
4078             * @param dirs The absolute path names of the directories to move.
4079             * @param dst The location where the directories will be moved 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            moveDbDirectories(String dirs[], String dst) throws IOException, LSException, LscpException {
4086                    verifyConnection();
4087                    for(String s : dirs) {
4088                            out.writeLine("MOVE DB_INSTRUMENT_DIRECTORY '" + s + "' '" + dst + "'");
4089                    }
4090                    if(getPrintOnlyMode()) return;
4091                    
4092                    getEmptyResultSets(dirs.length, "Client.dirMovingFailed!");
4093            }
4094            
4095            /**
4096             * Copies the specified directory into the specified location.
4097             * @param dir The absolute path name of the directory to copy.
4098             * @param dst The location where the directory will be copied to.
4099             * @throws IOException If some I/O error occurs.
4100             * @throws LSException If the operation failed.
4101             * @throws LscpException If LSCP protocol corruption occurs.
4102             */
4103            public synchronized void
4104            copyDbDirectory(String dir, String dst) throws IOException, LSException, LscpException {
4105                    verifyConnection();
4106                    out.writeLine("COPY DB_INSTRUMENT_DIRECTORY '" + dir + "' '" + dst + "'");
4107                    if(getPrintOnlyMode()) return;
4108                    
4109                    ResultSet rs = getEmptyResultSet();
4110            }
4111            
4112            /**
4113             * Copies the specified directories into the specified location.
4114             * @param dirs The absolute path names of the directories to copy.
4115             * @param dst The location where the directories will be copied to.
4116             * @throws IOException If some I/O error occurs.
4117             * @throws LSException If the operation failed.
4118             * @throws LscpException If LSCP protocol corruption occurs.
4119             */
4120            public synchronized void
4121            copyDbDirectories(String[] dirs, String dst) throws IOException, LSException, LscpException {
4122                    verifyConnection();
4123                    for(String s : dirs) {
4124                            out.writeLine("COPY DB_INSTRUMENT_DIRECTORY '" + s + "' '" + dst + "'");
4125                    }
4126                    if(getPrintOnlyMode()) return;
4127                    
4128                    getEmptyResultSets(dirs.length, "Client.dirCopyingFailed!");
4129            }
4130            
4131            /**
4132             * Changes the description of the specified directory.
4133             * @param dir The absolute path name of the directory.
4134             * @param desc The new description for the directory.
4135             * @throws IOException If some I/O error occurs.
4136             * @throws LSException If failed to change the description.
4137             * @throws LscpException If LSCP protocol corruption occurs.
4138             */
4139            public synchronized void
4140            setDbDirectoryDescription(String dir, String desc)
4141                                    throws IOException, LSException, LscpException {
4142                    
4143                    verifyConnection();
4144                    String s = "SET DB_INSTRUMENT_DIRECTORY DESCRIPTION '";
4145                    out.writeLine(s + dir + "' '" + toEscapedString(desc) + "'");
4146                    if(getPrintOnlyMode()) return;
4147                    
4148                    ResultSet rs = getEmptyResultSet();
4149            }
4150            
4151            public static enum ScanMode {
4152                    RECURSIVE, NON_RECURSIVE, FLAT
4153            }
4154            
4155            /**
4156             * Adds the specified instrument to the specified instruments database directory.
4157             * @param dbDir The absolute path name of the database directory in which the
4158             * specified instrument will be added.
4159             * @param filePath The absolute path name of the instrument file.
4160             * @param instrIndex The index of the instrument (in the given instrument file) to add.
4161             * @throws IOException If some I/O error occurs.
4162             * @throws LSException If the operation failed.
4163             * @throws LscpException If LSCP protocol corruption occurs.
4164             */
4165            public synchronized void
4166            addDbInstrument(String dbDir, String filePath, int instrIndex)
4167                                            throws IOException, LSException, LscpException {
4168                    
4169                    addDbInstrument(dbDir, filePath, instrIndex, false);
4170            }
4171            
4172            /**
4173             * Adds the specified instrument to the specified instruments database directory.
4174             * @param dbDir The absolute path name of the database directory in which the
4175             * specified instrument will be added.
4176             * @param filePath The absolute path name of the instrument file.
4177             * @param instrIndex The index of the instrument (in the given instrument file) to add.
4178             * @param background If <code>true</code>, the scan will be done
4179             * in background and this method may return before the job is finished.
4180             * @return If <code>background</code> is <code>true</code>, the ID
4181             * of the scan job.
4182             * @throws IOException If some I/O error occurs.
4183             * @throws LSException If the operation failed.
4184             * @throws LscpException If LSCP protocol corruption occurs.
4185             * @see #addInstrumentsDbListener
4186             */
4187            public synchronized int
4188            addDbInstrument(String dbDir, String filePath, int instrIndex, boolean background)
4189                                            throws IOException, LSException, LscpException {
4190                    
4191                    verifyConnection();
4192                    String s = "ADD DB_INSTRUMENTS";
4193                    if(background) s += " NON_MODAL";
4194                    s += " '" + dbDir + "' '" + filePath + "' ";
4195                    out.writeLine(s + String.valueOf(instrIndex));
4196                    if(getPrintOnlyMode()) return -1;
4197                    
4198                    ResultSet rs = getEmptyResultSet();
4199                    return rs.getIndex();
4200            }
4201            
4202            /**
4203             * Adds the instruments in the specified file to the specified
4204             * instruments database directory.
4205             * @param dbDir The absolute path name of the database directory
4206             * in which the the supported instruments will be added.
4207             * @param filePath The absolute path name of the file to scan for instruments.
4208             * @throws IOException If some I/O error occurs.
4209             * @throws LSException If the operation failed.
4210             * @throws LscpException If LSCP protocol corruption occurs.
4211             */
4212            public synchronized void
4213            addDbInstruments(String dbDir, String filePath)
4214                                            throws IOException, LSException, LscpException {
4215                    
4216                    addDbInstruments(dbDir, filePath, false);
4217            }
4218            
4219            /**
4220             * Adds the instruments in the specified file to the specified
4221             * instruments database directory.
4222             * @param dbDir The absolute path name of the database directory
4223             * in which the the supported instruments will be added.
4224             * @param filePath The absolute path name of the file to scan for instruments.
4225             * @param background If <code>true</code>, the scan will be done
4226             * in background and this method may return before the job is finished.
4227             * @return If <code>background</code> is <code>true</code>, the ID
4228             * of the scan job.
4229             * @throws IOException If some I/O error occurs.
4230             * @throws LSException If the operation failed.
4231             * @throws LscpException If LSCP protocol corruption occurs.
4232             * @see #addInstrumentsDbListener
4233             */
4234            public synchronized int
4235            addDbInstruments(String dbDir, String filePath, boolean background)
4236                                            throws IOException, LSException, LscpException {
4237                    
4238                    verifyConnection();
4239                    String s = "ADD DB_INSTRUMENTS";
4240                    if(background) s += " NON_MODAL";
4241                    out.writeLine(s + " '" + dbDir + "' '" + filePath + "'");
4242                    if(getPrintOnlyMode()) return -1;
4243                    
4244                    ResultSet rs = getEmptyResultSet();
4245                    return rs.getIndex();
4246            }
4247            
4248            /**
4249             * Adds the instruments in the specified file system directory
4250             * to the specified instruments database directory.
4251             * @param mode Determines the scanning mode. If RECURSIVE is
4252             * specified, all supported instruments in the specified file system
4253             * direcotry will be added to the specified instruments database
4254             * directory, including the instruments in subdirectories
4255             * of the supplied directory. If NON_RECURSIVE is specified,
4256             * the instruments in the subdirectories will not be processed.
4257             * If FLAT is specified, all supported instruments in the specified
4258             * file system direcotry will be added, including the instruments in
4259             * subdirectories of the supplied directory, but the respective
4260             * subdirectory structure will not be recreated in the instruments
4261             * database and all instruments will be added directly in the
4262             * specified database directory.
4263             * @param dbDir The absolute path name of the database directory
4264             * in which the supported instruments will be added.
4265             * @param fsDir The absolute path name of the file system directory.
4266             * @throws IOException If some I/O error occurs.
4267             * @throws LSException If the operation failed.
4268             * @throws LscpException If LSCP protocol corruption occurs.
4269             */
4270            public synchronized void
4271            addDbInstruments(ScanMode mode, String dbDir, String fsDir)
4272                                            throws IOException, LSException, LscpException {
4273                    
4274                    addDbInstruments(mode, dbDir, fsDir, false);
4275            }
4276            
4277            /**
4278             * Adds the instruments in the specified file system directory
4279             * to the specified instruments database directory.
4280             * @param mode Determines the scanning mode. If RECURSIVE is
4281             * specified, all supported instruments in the specified file system
4282             * direcotry will be added to the specified instruments database
4283             * directory, including the instruments in subdirectories
4284             * of the supplied directory. If NON_RECURSIVE is specified,
4285             * the instruments in the subdirectories will not be processed.
4286             * If FLAT is specified, all supported instruments in the specified
4287             * file system direcotry will be added, including the instruments in
4288             * subdirectories of the supplied directory, but the respective
4289             * subdirectory structure will not be recreated in the instruments
4290             * database and all instruments will be added directly in the
4291             * specified database directory.
4292             * @param dbDir The absolute path name of the database directory
4293             * in which the supported instruments will be added.
4294             * @param fsDir The absolute path name of the file system directory.
4295             * @param background If <code>true</code>, the scan will be done
4296             * in background and this method may return before the job is finished.
4297             * @return If <code>background</code> is <code>true</code>, the ID
4298             * of the scan job.
4299             * @throws IOException If some I/O error occurs.
4300             * @throws LSException If the operation failed.
4301             * @throws LscpException If LSCP protocol corruption occurs.
4302             * @see #addInstrumentsDbListener
4303             */
4304            public synchronized int
4305            addDbInstruments(ScanMode mode, String dbDir, String fsDir, boolean background)
4306                                            throws IOException, LSException, LscpException {
4307                    
4308                    verifyConnection();
4309                    StringBuffer sb = new StringBuffer("ADD DB_INSTRUMENTS");
4310                    if(background) sb.append(" NON_MODAL");
4311                    
4312                    switch(mode) {
4313                            case RECURSIVE:
4314                                    sb.append(" RECURSIVE");
4315                                    break;
4316                            case NON_RECURSIVE:
4317                                    sb.append(" NON_RECURSIVE");
4318                                    break;
4319                            case FLAT:
4320                                    sb.append(" FLAT");
4321                                    break;
4322                    }
4323                    
4324                    sb.append(" '").append(dbDir).append("' '");
4325                    sb.append(fsDir).append("'");
4326                    out.writeLine(sb.toString());
4327                    if(getPrintOnlyMode()) return -1;
4328                    
4329                    ResultSet rs = getEmptyResultSet();
4330                    return rs.getIndex();
4331            }
4332            
4333            /**
4334             * Removes the specified instrument from the instruments database.
4335             * @param instr The absolute path name of the instrument to remove.
4336             * @throws IOException If some I/O error occurs.
4337             * @throws LscpException If LSCP protocol corruption occurs.
4338             * @throws LSException If the removing of the instrument failed.
4339             */
4340            public synchronized void
4341            removeDbInstrument(String instr) throws IOException, LscpException, LSException {
4342                    
4343                    verifyConnection();
4344                    out.writeLine("REMOVE DB_INSTRUMENT '" + instr + "'");
4345                    if(getPrintOnlyMode()) return;
4346                    
4347                    ResultSet rs = getEmptyResultSet();
4348            }
4349            
4350            /**
4351             * Removes the specified instruments from the instruments database.
4352             * @param instrs The absolute path names of the instruments to remove.
4353             * @throws IOException If some I/O error occurs.
4354             * @throws LscpException If LSCP protocol corruption occurs.
4355             * @throws LSException If the removing of the instruments failed.
4356             */
4357            public synchronized void
4358            removeDbInstruments(String[] instrs) throws IOException, LscpException, LSException {
4359                    verifyConnection();
4360                    for(String s : instrs) {
4361                            out.writeLine("REMOVE DB_INSTRUMENT '" + s + "'");
4362                    }
4363                    if(getPrintOnlyMode()) return;
4364                    
4365                    getEmptyResultSets(instrs.length, "Client.instrDeletionFailed!");
4366            }
4367            
4368            /**
4369             * Gets the number of instruments in the specified directory.
4370             * @return The current number of instruments in the specified directory.
4371             * @param dir The absolute path name of the directory.
4372             * @throws IOException If some I/O error occurs.
4373             * @throws LscpException If LSCP protocol corruption occurs.
4374             * @throws LSException If some other error occurs.
4375             */
4376            public synchronized int
4377            getDbInstrumentCount(String dir) throws IOException, LscpException, LSException {
4378                    return getDbInstrumentCount(dir, false);
4379            }
4380            
4381            /**
4382             * Gets the number of instruments in the specified directory.
4383             * @return The current number of instruments in the specified directory.
4384             * @param dir The absolute path name of the directory.
4385             * @param recursive If <code>true</code>, the number of all instruments
4386             * in the specified subtree will be returned.
4387             * @throws IOException If some I/O error occurs.
4388             * @throws LscpException If LSCP protocol corruption occurs.
4389             * @throws LSException If some other error occurs.
4390             */
4391            public synchronized int
4392            getDbInstrumentCount(String dir, boolean recursive)
4393                                    throws IOException, LscpException, LSException {
4394                    
4395                    verifyConnection();
4396                    String s;
4397                    if(recursive) s = "GET DB_INSTRUMENTS RECURSIVE '";
4398                    else s = "GET DB_INSTRUMENTS '";
4399                    out.writeLine(s + dir + "'");
4400                    if(getPrintOnlyMode()) return -1;
4401                    
4402                    s = getSingleLineResultSet().getResult();
4403                    return parseInt(s);
4404            }
4405            
4406            /**
4407             * Gets the list of instruments in the specified directory.
4408             * @param dir The absolute path name of the directory.
4409             * @return A <code>String</code> array providing the names of
4410             * all instruments in the specified directory.
4411             * @throws IOException If some I/O error occurs.
4412             * @throws LscpException If LSCP protocol corruption occurs.
4413             * @throws LSException If the specified path name is invalid.
4414             */
4415            public synchronized String[]
4416            getDbInstrumentNames(String dir) throws IOException, LscpException, LSException {
4417                    verifyConnection();
4418                    out.writeLine("LIST DB_INSTRUMENTS '" + dir + "'");
4419                    if(getPrintOnlyMode()) return null;
4420                    
4421                    String[] names = parseEscapedStringList(getSingleLineResultSet().getResult());
4422                    for(int i = 0; i < names.length; i++) {
4423                            names[i] = toNonEscapedString(names[i]);
4424                    }
4425                    return names;
4426            }
4427            
4428            /**
4429             * Gets information about the specified instrument.
4430             * @param instr The absolute path name of the instrument.
4431             * @return A <code>DbInstrumentInfo</code> instance providing information
4432             * about the specified instrument.
4433             * @throws IOException If some I/O error occurs.
4434             * @throws LscpException If LSCP protocol corruption occurs.
4435             * @throws LSException If the specified instrument is not found.
4436             */
4437            public synchronized DbInstrumentInfo
4438            getDbInstrumentInfo(String instr) throws IOException, LscpException, LSException {
4439                    verifyConnection();
4440                    out.writeLine("GET DB_INSTRUMENT INFO '" + instr + "'");
4441                    if(getPrintOnlyMode()) return null;
4442                    
4443                    ResultSet rs = getMultiLineResultSet();
4444                    DbInstrumentInfo info = new DbInstrumentInfo(rs.getMultiLineResult());
4445                    String s = getParentDirectory(instr);
4446                    if(s != null) info.setDirectoryPath(s);
4447                    s = getFileName(instr);
4448                    if(s != null) info.setName(toNonEscapedFileName(s));
4449                    
4450                    return info;
4451            }
4452            
4453            /**
4454             * Gets the list of instruments in the specified directory.
4455             * @param dir The absolute path name of the directory.
4456             * @return A <code>DbInstrumentInfo</code> array providing
4457             * information about all instruments in the specified directory.
4458             * @throws IOException If some I/O error occurs.
4459             * @throws LscpException If LSCP protocol corruption occurs.
4460             * @throws LSException If the specified path name is invalid.
4461             */
4462            public synchronized DbInstrumentInfo[]
4463            getDbInstruments(String dir) throws IOException, LscpException, LSException {
4464                    String[] instrS = getDbInstrumentNames(dir);
4465                    if(!hasEndingFileSeparator(dir)) dir += "/";
4466                    
4467                    DbInstrumentInfo[] infoS = new DbInstrumentInfo[instrS.length];
4468                    for(int i = 0; i < instrS.length; i++) {
4469                            infoS[i] = getDbInstrumentInfo(dir + toEscapedFileName(instrS[i]));
4470                    }
4471                    return infoS;
4472            }
4473            
4474            /**
4475             * Gets the list of instruments in the specified directory.
4476             * @param dir The absolute path name of the directory.
4477             * @return A <code>DbInstrumentInfo</code> array providing
4478             * information about all instruments in the specified directory.
4479             * @throws IOException If some I/O error occurs.
4480             * @throws LscpException If LSCP protocol corruption occurs.
4481             * @throws LSException If the specified path name is invalid.
4482             *
4483            public synchronized DbInstrumentInfo[]
4484            getDbInstruments(String dir) throws IOException, LscpException, LSException {
4485                    String[] instrS = getDbInstrumentNames(dir);
4486                    if(instrS.length == 0) return new DbInstrumentInfo[0];
4487                    
4488                    if(dir.charAt(dir.length() - 1) != '/') dir += "/";
4489                    
4490                    for(int i = 0; i < instrS.length; i++) {
4491                            out.writeLine("GET DB_INSTRUMENT INFO '" + dir + instrS[i] + "'");
4492                    }
4493                    
4494                    if(getPrintOnlyMode()) return null;
4495                    
4496                    if(dir.length() > 1) dir = dir.substring(0, dir.length() - 1);
4497                    StringBuffer sb = new StringBuffer();
4498                    DbInstrumentInfo[] infoS = new DbInstrumentInfo[instrS.length];
4499                    for(int i = 0; i < instrS.length; i++) {
4500                            try {
4501                                    ResultSet rs = getMultiLineResultSet();
4502                                    infoS[i] = new DbInstrumentInfo(rs.getMultiLineResult());
4503                                    infoS[i].setName(instrS[i]);
4504                                    infoS[i].setDirectoryPath(dir);
4505                            } catch (SocketTimeoutException e) {
4506                                    getLogger().log(Level.FINE, e.getMessage(), e);
4507                                    sb.append(e.getMessage()).append("\n");
4508                                    break;
4509                            } catch (Exception e) {
4510                                    getLogger().log(Level.FINE, e.getMessage(), e);
4511                                    sb.append(e.getMessage()).append("\n");
4512                            }
4513                    }
4514                    
4515                    String details = sb.toString();
4516                    if(details.length() > 0) {
4517                            String err = LscpI18n.getLogMsg("Client.getInstrsInfoFailed!");
4518                            throw new LSException(0, err, details);
4519                    }
4520                    
4521                    return infoS;
4522            }*/
4523            
4524            /**
4525             * Renames the specified instrument.
4526             * @param instr The absolute path name of the instrument to rename.
4527             * @param name The new name for the instrument.
4528             * @throws IOException If some I/O error occurs.
4529             * @throws LSException If the renaming of the instrument failed.
4530             * @throws LscpException If LSCP protocol corruption occurs.
4531             */
4532            public synchronized void
4533            renameDbInstrument(String instr, String name)
4534                                    throws IOException, LSException, LscpException {
4535                    
4536                    verifyConnection();
4537                    name = toEscapedString(name);
4538                    out.writeLine("SET DB_INSTRUMENT NAME '" + instr + "' '" + name + "'");
4539                    if(getPrintOnlyMode()) return;
4540                    
4541                    ResultSet rs = getEmptyResultSet();
4542            }
4543            
4544            /**
4545             * Moves the specified instrument into the specified location.
4546             * @param instr The absolute path name of the instrument to move.
4547             * @param dst The directory where the specified instrument will be moved 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            moveDbInstrument(String instr, String dst) throws IOException, LSException, LscpException {
4554                    verifyConnection();
4555                    out.writeLine("MOVE DB_INSTRUMENT '" + instr + "' '" + dst + "'");
4556                    if(getPrintOnlyMode()) return;
4557                    
4558                    ResultSet rs = getEmptyResultSet();
4559            }
4560            
4561            /**
4562             * Moves the specified instruments into the specified location.
4563             * @param instrs The absolute path names of the instruments to move.
4564             * @param dst The directory where the specified instruments will be moved 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            moveDbInstruments(String[] instrs, String dst) throws IOException, LSException, LscpException {
4571                    verifyConnection();
4572                    for(String s : instrs) {
4573                            out.writeLine("MOVE DB_INSTRUMENT '" + s + "' '" + dst + "'");
4574                    }
4575                    if(getPrintOnlyMode()) return;
4576                    
4577                    getEmptyResultSets(instrs.length, "Client.instrMovingFailed!");
4578            }
4579            
4580            /**
4581             * Copies the specified instrument into the specified location.
4582             * @param instr The absolute path name of the instrument to copy.
4583             * @param dst The directory where the specified instrument will be copied to.
4584             * @throws IOException If some I/O error occurs.
4585             * @throws LSException If the operation failed.
4586             * @throws LscpException If LSCP protocol corruption occurs.
4587             */
4588            public synchronized void
4589            copyDbInstrument(String instr, String dst) throws IOException, LSException, LscpException {
4590                    verifyConnection();
4591                    out.writeLine("COPY DB_INSTRUMENT '" + instr + "' '" + dst + "'");
4592                    if(getPrintOnlyMode()) return;
4593                    
4594                    ResultSet rs = getEmptyResultSet();
4595            }
4596            
4597            /**
4598             * Copies the specified instruments into the specified location.
4599             * @param instrs The absolute path name of the instruments to copy.
4600             * @param dst The directory where the specified instruments will be copied to.
4601             * @throws IOException If some I/O error occurs.
4602             * @throws LSException If the operation failed.
4603             * @throws LscpException If LSCP protocol corruption occurs.
4604             */
4605            public synchronized void
4606            copyDbInstruments(String[] instrs, String dst) throws IOException, LSException, LscpException {
4607                    verifyConnection();
4608                    for(String s : instrs) {
4609                            out.writeLine("COPY DB_INSTRUMENT '" + s + "' '" + dst + "'");
4610                    }
4611                    if(getPrintOnlyMode()) return;
4612                    
4613                    getEmptyResultSets(instrs.length, "Client.instrCopyingFailed!");
4614            }
4615            
4616            /**
4617             * Changes the description of the specified instrument.
4618             * @param instr The absolute path name of the instrument.
4619             * @param desc The new description for the instrument.
4620             * @throws IOException If some I/O error occurs.
4621             * @throws LSException If failed to change the description.
4622             * @throws LscpException If LSCP protocol corruption occurs.
4623             */
4624            public synchronized void
4625            setDbInstrumentDescription(String instr, String desc)
4626                                    throws IOException, LSException, LscpException {
4627                    
4628                    verifyConnection();
4629                    desc = toEscapedString(desc);
4630                    out.writeLine("SET DB_INSTRUMENT DESCRIPTION '" + instr + "' '" + desc + "'");
4631                    if(getPrintOnlyMode()) return;
4632                    
4633                    ResultSet rs = getEmptyResultSet();
4634            }
4635            
4636            /**
4637             * Finds all directories in the specified directory
4638             * that corresponds to the specified search criterias.
4639             * @param dir The absolute path name of the directory to search.
4640             * @param query Provides the search criterias.
4641             * @return A <code>DbDirectoryInfo</code> array providing
4642             * information about all directories that are found in the specified directory.
4643             * @throws IOException If some I/O error occurs.
4644             * @throws LscpException If LSCP protocol corruption occurs.
4645             * @throws LSException If the specified path name is invalid.
4646             */
4647            public synchronized DbDirectoryInfo[]
4648            findDbDirectories(String dir, DbSearchQuery query)
4649                                    throws IOException, LscpException, LSException {
4650                    
4651                    return findDbDirectories(dir, query, false);
4652            }
4653            
4654            /**
4655             * Finds all directories in the specified directory
4656             * that corresponds to the specified search criterias.
4657             * @param dir The absolute path name of the directory to search.
4658             * @param query Provides the search criterias.
4659             * @param nonRecursive If <code>true</code>, the search will be non-recursive.
4660             * @return A <code>DbDirectoryInfo</code> array providing
4661             * information about all directories that are found in the specified directory.
4662             * @throws IOException If some I/O error occurs.
4663             * @throws LscpException If LSCP protocol corruption occurs.
4664             * @throws LSException If the specified path name is invalid.
4665             */
4666            public synchronized DbDirectoryInfo[]
4667            findDbDirectories(String dir, DbSearchQuery query, boolean nonRecursive)
4668                                    throws IOException, LscpException, LSException {
4669                    
4670                    verifyConnection();
4671                    StringBuffer sb = new StringBuffer();
4672                    sb.append("FIND DB_INSTRUMENT_DIRECTORIES");
4673                    if(nonRecursive) sb.append(" NON_RECURSIVE");
4674                    sb.append(" '").append(dir).append("'");
4675                    
4676                    if(query.name != null && query.name.length() > 0) {
4677                            sb.append(" NAME='").append(toEscapedString(query.name)).append("'");
4678                    }
4679                    
4680                    String s = query.getCreatedAfter();
4681                    String s2 = query.getCreatedBefore();
4682                    if(s != null || s2 != null) {
4683                            sb.append(" CREATED='");
4684                            if(s != null) sb.append(s);
4685                            sb.append("..");
4686                            if(s2 != null) sb.append(s2);
4687                            sb.append("'");
4688                    }
4689                    
4690                    s = query.getModifiedAfter();
4691                    s2 = query.getModifiedBefore();
4692                    if(s != null || s2 != null) {
4693                            sb.append(" MODIFIED='");
4694                            if(s != null) sb.append(s);
4695                            sb.append("..");
4696                            if(s2 != null) sb.append(s2);
4697                            sb.append("'");
4698                    }
4699                    
4700                    if(query.description != null && query.description.length() > 0) {
4701                            sb.append(" DESCRIPTION='");
4702                            sb.append(toEscapedString(query.description)).append("'");
4703                    }
4704                    
4705                    out.writeLine(sb.toString());
4706                    if(getPrintOnlyMode()) return null;
4707                    
4708                    String[] dirS = parseEscapedStringList(getSingleLineResultSet().getResult());
4709                    
4710                    DbDirectoryInfo[] infoS = new DbDirectoryInfo[dirS.length];
4711                    for(int i = 0; i < dirS.length; i++) {
4712                            infoS[i] = getDbDirectoryInfo(dirS[i]);
4713                    }
4714                    return infoS;
4715            }
4716            
4717            /**
4718             * Finds all instruments in the specified directory
4719             * that corresponds to the specified search criterias.
4720             * @param dir The absolute path name of the directory to search.
4721             * @param query Provides the search criterias.
4722             * @return A <code>DbInstrumentInfo</code> array providing
4723             * information about all instruments that are found in the specified directory.
4724             * @throws IOException If some I/O error occurs.
4725             * @throws LscpException If LSCP protocol corruption occurs.
4726             * @throws LSException If the specified path name is invalid.
4727             */
4728            public synchronized DbInstrumentInfo[]
4729            findDbInstruments(String dir, DbSearchQuery query)
4730                                    throws IOException, LscpException, LSException {
4731                    
4732                    return findDbInstruments(dir, query, false);
4733            }
4734            
4735            /**
4736             * Finds all instruments in the specified directory
4737             * that corresponds to the specified search criterias.
4738             * @param dir The absolute path name of the directory to search.
4739             * @param query Provides the search criterias.
4740             * @param nonRecursive If <code>true</code>, the search will be non-recursive.
4741             * @return A <code>DbInstrumentInfo</code> array providing
4742             * information about all instruments that are found in the specified directory.
4743             * @throws IOException If some I/O error occurs.
4744             * @throws LscpException If LSCP protocol corruption occurs.
4745             * @throws LSException If the specified path name is invalid.
4746             */
4747            public synchronized DbInstrumentInfo[]
4748            findDbInstruments(String dir, DbSearchQuery query, boolean nonRecursive)
4749                                    throws IOException, LscpException, LSException {
4750                    
4751                    verifyConnection();
4752                    StringBuffer sb = new StringBuffer();
4753                    sb.append("FIND DB_INSTRUMENTS");
4754                    if(nonRecursive) sb.append(" NON_RECURSIVE");
4755                    sb.append(" '").append(dir).append("'");
4756                    
4757                    if(query.name != null && query.name.length() > 0) {
4758                            sb.append(" NAME='").append(toEscapedString(query.name)).append("'");
4759                    }
4760                    
4761                    if(query.formatFamilies.size() > 0) {
4762                            sb.append(" FORMAT_FAMILIES='").append(query.formatFamilies.get(0));
4763                            for(int i = 1; i < query.formatFamilies.size(); i++) {
4764                                    sb.append(',').append(query.formatFamilies.get(i));
4765                            }
4766                            sb.append("'");
4767                    }
4768                    
4769                    if(query.minSize != -1 || query.maxSize != -1) {
4770                            sb.append(" SIZE='");
4771                            if(query.minSize != -1) sb.append(query.minSize);
4772                            sb.append("..");
4773                            if(query.maxSize != -1) sb.append(query.maxSize);
4774                            sb.append("'");
4775                    }
4776                    
4777                    String s = query.getCreatedAfter();
4778                    String s2 = query.getCreatedBefore();
4779                    if(s != null || s2 != null) {
4780                            sb.append(" CREATED='");
4781                            if(s != null) sb.append(s);
4782                            sb.append("..");
4783                            if(s2 != null) sb.append(s2);
4784                            sb.append("'");
4785                    }
4786                    
4787                    s = query.getModifiedAfter();
4788                    s2 = query.getModifiedBefore();
4789                    if(s != null || s2 != null) {
4790                            sb.append(" MODIFIED='");
4791                            if(s != null) sb.append(s);
4792                            sb.append("..");
4793                            if(s2 != null) sb.append(s2);
4794                            sb.append("'");
4795                    }
4796                    
4797                    if(query.description != null && query.description.length() > 0) {
4798                            sb.append(" DESCRIPTION='");
4799                            sb.append(toEscapedString(query.description)).append("'");
4800                    }
4801                    
4802                    if(query.instrumentType != DbSearchQuery.InstrumentType.BOTH) {
4803                            sb.append(" IS_DRUM=");
4804                            if(query.instrumentType == DbSearchQuery.InstrumentType.DRUM) {
4805                                    sb.append("'true'");
4806                            } else {
4807                                    sb.append("'false'");
4808                            }
4809                    }
4810                    
4811                    if(query.product != null && query.product.length() > 0) {
4812                            sb.append(" PRODUCT='").append(toEscapedString(query.product)).append("'");
4813                    }
4814                    
4815                    if(query.artists != null && query.artists.length() > 0) {
4816                            sb.append(" ARTISTS='").append(toEscapedString(query.artists)).append("'");
4817                    }
4818                    
4819                    if(query.keywords != null && query.keywords.length() > 0) {
4820                            sb.append(" KEYWORDS='");
4821                            sb.append(toEscapedString(query.keywords)).append("'");
4822                    }
4823                    
4824                    out.writeLine(sb.toString());
4825                    if(getPrintOnlyMode()) return null;
4826                    
4827                    String[] instrS = parseEscapedStringList(getSingleLineResultSet().getResult());
4828                    
4829                    DbInstrumentInfo[] infoS = new DbInstrumentInfo[instrS.length];
4830                    for(int i = 0; i < instrS.length; i++) {
4831                            infoS[i] = getDbInstrumentInfo(instrS[i]);
4832                    }
4833                    return infoS;
4834            }
4835            
4836            /**
4837             * Gets status information about the specified job.
4838             * @param jobId The ID of the job.
4839             * @return A <code>ScanJobInfo</code> instance providing information
4840             * about the specified job.
4841             * @throws IOException If some I/O error occurs.
4842             * @throws LscpException If LSCP protocol corruption occurs.
4843             * @throws LSException If the specified job is not found.
4844             */
4845            public synchronized ScanJobInfo
4846            getDbInstrumentsJobInfo(int jobId) throws IOException, LscpException, LSException {
4847                    verifyConnection();
4848                    out.writeLine("GET DB_INSTRUMENTS_JOB INFO " + String.valueOf(jobId));
4849                    if(getPrintOnlyMode()) return null;
4850                    
4851                    ResultSet rs = getMultiLineResultSet();
4852                    ScanJobInfo info = new ScanJobInfo(rs.getMultiLineResult());
4853                    
4854                    return info;
4855            }
4856            
4857            /**
4858             * Removes all instruments and directories and re-creates
4859             * the instruments database structure.
4860             * @throws IOException If some I/O error occurs.
4861             * @throws LscpException If LSCP protocol corruption occurs.
4862             * @throws LSException If the formatting of the instruments database failed.
4863             */
4864            public synchronized void
4865            formatInstrumentsDb() throws IOException, LscpException, LSException {
4866                    verifyConnection();
4867                    out.writeLine("FORMAT INSTRUMENTS_DB");
4868                    if(getPrintOnlyMode()) return;
4869                                    
4870                  ResultSet rs = getEmptyResultSet();                  ResultSet rs = getEmptyResultSet();
4871          }          }
# Line 2011  public class Client { Line 4885  public class Client {
4885          resetChannel(int samplerChn) throws IOException, LscpException, LSException {          resetChannel(int samplerChn) throws IOException, LscpException, LSException {
4886                  verifyConnection();                  verifyConnection();
4887                  out.writeLine("RESET CHANNEL " + samplerChn);                  out.writeLine("RESET CHANNEL " + samplerChn);
4888                    if(getPrintOnlyMode()) return;
4889                                    
4890                  ResultSet rs = getEmptyResultSet();                  ResultSet rs = getEmptyResultSet();
4891          }          }
# Line 2025  public class Client { Line 4900  public class Client {
4900          resetSampler() throws IOException, LscpException {          resetSampler() throws IOException, LscpException {
4901                  verifyConnection();                  verifyConnection();
4902                  out.writeLine("RESET");                  out.writeLine("RESET");
4903                    if(getPrintOnlyMode()) return;
4904                    
4905                  try { ResultSet rs = getEmptyResultSet(); }                  try { ResultSet rs = getEmptyResultSet(); }
4906                  catch(LSException x) { getLogger().warning(x.getMessage()); }                  catch(LSException x) { getLogger().warning(x.getMessage()); }
4907          }          }
4908                    
4909          /**          /**
4910             * Gets the current number of all active streams.
4911             * @return The current number of all active streams.
4912             * @throws IOException If some I/O error occurs.
4913             * @throws LscpException If LSCP protocol corruption occurs.
4914             * @throws LSException If some other error occurs.
4915             */
4916            public synchronized int
4917            getTotalStreamCount() throws IOException, LscpException, LSException {
4918                    verifyConnection();
4919                    out.writeLine("GET TOTAL_STREAM_COUNT");
4920                    if(getPrintOnlyMode()) return -1;
4921                    
4922                    String s = getSingleLineResultSet().getResult();
4923                    return parseInt(s);
4924            }
4925            
4926            /**
4927             * Gets the current number of all active voices.
4928             * @return The current number of all active voices.
4929             * @throws IOException If some I/O error occurs.
4930             * @throws LscpException If LSCP protocol corruption occurs.
4931             * @throws LSException If some other error occurs.
4932             */
4933            public synchronized int
4934            getTotalVoiceCount() throws IOException, LscpException, LSException {
4935                    verifyConnection();
4936                    out.writeLine("GET TOTAL_VOICE_COUNT");
4937                    if(getPrintOnlyMode()) return -1;
4938                    
4939                    String s = getSingleLineResultSet().getResult();
4940                    return parseInt(s);
4941            }
4942            
4943            /**
4944             * Gets the maximum number of active voices.
4945             * @return The maximum number of active voices.
4946             * @throws IOException If some I/O error occurs.
4947             * @throws LscpException If LSCP protocol corruption occurs.
4948             * @throws LSException If some other error occurs.
4949             */
4950            public synchronized int
4951            getTotalVoiceCountMax() throws IOException, LscpException, LSException {
4952                    verifyConnection();
4953                    out.writeLine("GET TOTAL_VOICE_COUNT_MAX");
4954                    if(getPrintOnlyMode()) return -1;
4955                    
4956                    String s = getSingleLineResultSet().getResult();
4957                    return parseInt(s);
4958            }
4959            
4960            /**
4961           * Gets information about the LinuxSampler instance.           * Gets information about the LinuxSampler instance.
4962           *           *
4963           * @return <code>ServerInfo</code> instance containing           * @return <code>ServerInfo</code> instance containing
# Line 2043  public class Client { Line 4971  public class Client {
4971          getServerInfo() throws IOException, LscpException, LSException {          getServerInfo() throws IOException, LscpException, LSException {
4972                  verifyConnection();                  verifyConnection();
4973                  out.writeLine("GET SERVER INFO");                  out.writeLine("GET SERVER INFO");
4974                    if(getPrintOnlyMode()) return null;
4975                    
4976                  ResultSet rs = getMultiLineResultSet();                  ResultSet rs = getMultiLineResultSet();
4977                  return new ServerInfo(rs.getMultiLineResult());                  return new ServerInfo(rs.getMultiLineResult());
4978          }          }
4979                    
4980          /**          /**
4981             * Gets the golobal volume of the sampler.
4982             * @return The golobal volume of the sampler.
4983             * @throws IOException If some I/O error occurs.
4984             * @throws LscpException If LSCP protocol corruption occurs.
4985             * @throws LSException If some other error occurs.
4986             */
4987            public synchronized float
4988            getVolume() throws IOException, LscpException, LSException {
4989                    verifyConnection();
4990                    out.writeLine("GET VOLUME");
4991                    if(getPrintOnlyMode()) return -1;
4992                    
4993                    String s = getSingleLineResultSet().getResult();
4994                    return parseFloat(s);
4995            }
4996            
4997            /**
4998             * Sets the global volume of the sampler.
4999             * @param volume The new volume value.
5000             * @throws IOException If some I/O error occurs.
5001             * @throws LscpException If LSCP protocol corruption occurs.
5002             * @throws LSException If some other error occurs.
5003             * @see #getVolume
5004             */
5005            public synchronized void
5006            setVolume(float volume) throws IOException, LscpException, LSException {
5007            
5008                    verifyConnection();
5009                    out.writeLine("SET VOLUME " + volume);
5010                    if(getPrintOnlyMode()) return;
5011                    
5012                    ResultSet rs = getEmptyResultSet();
5013            }
5014            
5015            /**
5016             * Gets the number of instruments in the specified instrument file.
5017             * @param filename The absolute path name of the instrument file.
5018             * @return The number of instruments in the specified instrument file.
5019             * @throws IOException If some I/O error occurs.
5020             * @throws LscpException If LSCP protocol corruption occurs.
5021             * @throws LSException If the file is not found, or other error occur.
5022             */
5023            public synchronized int
5024            getFileInstrumentCount(String filename) throws IOException, LscpException, LSException {
5025                    verifyConnection();
5026                    out.writeLine("GET FILE INSTRUMENTS '" + filename +"'");
5027                    if(getPrintOnlyMode()) return -1;
5028                    
5029                    String s = getSingleLineResultSet().getResult();
5030                    return parseInt(s);
5031            }
5032            
5033            /**
5034             * Gets information about the instrument with index
5035             * <code>instrIdx</code> in the specified instrument file.
5036             * @param filename The absolute path name of the instrument file.
5037             * @param instrIdx The index of the instrument in the specified instrument file.
5038             * @throws IOException If some I/O error occurs.
5039             * @throws LscpException If LSCP protocol corruption occurs.
5040             * @throws LSException If failed to retrieve information.
5041             */
5042            public synchronized Instrument
5043            getFileInstrumentInfo(String filename, int instrIdx)
5044                                    throws IOException, LscpException, LSException {
5045                    
5046                    verifyConnection();
5047                    out.writeLine("GET FILE INSTRUMENT INFO '" + filename + "' " + String.valueOf(instrIdx));
5048                    if(getPrintOnlyMode()) return null;
5049                    
5050                    ResultSet rs = getMultiLineResultSet();
5051                    Instrument instr = new FileInstrument(rs.getMultiLineResult()) { };
5052                    
5053                    return instr;
5054            }
5055            
5056            /**
5057             * Gets the list of instruments in the specified instrument file.
5058             * @param filename The absolute path name of the instrument file.
5059             * @return An <code>Instrument</code> array providing
5060             * information about all instruments in the specified instrument file.
5061             * @throws IOException If some I/O error occurs.
5062             * @throws LscpException If LSCP protocol corruption occurs.
5063             * @throws LSException If the specified file name is invalid.
5064             */
5065            public synchronized Instrument[]
5066            getFileInstruments(String filename) throws IOException, LscpException, LSException {
5067                    int l = getFileInstrumentCount(filename);
5068                    if(l < 0) return null;
5069                    Instrument[] instrS = new FileInstrument[l];
5070                    
5071                    for(int i = 0; i < instrS.length; i++) {
5072                            instrS[i] = getFileInstrumentInfo(filename, i);
5073                    }
5074                    return instrS;
5075            }
5076            
5077            private static class FileInstrument extends AbstractInstrument {
5078                    FileInstrument(String[] resultSet) throws LscpException {
5079                            super(resultSet);
5080                    }
5081                    
5082                    public String
5083                    getEngine() {
5084                            // TODO: engine lookup?
5085                            return getFormatFamily();
5086                    }
5087                    
5088                    public boolean
5089                    parse(String s) throws LscpException {
5090                            if(s.startsWith("PRODUCT: ") || s.startsWith("ARTISTS: ")) return true;
5091                            return super.parse(s);
5092                    }
5093            }
5094            
5095            private void
5096            getEmptyResultSets(int count, String err) throws LSException {
5097                    StringBuffer sb = new StringBuffer();
5098                    for(int i = 0; i < count; i++) {
5099                            try { getEmptyResultSet(); }
5100                            catch (SocketTimeoutException e) {
5101                                    getLogger().log(Level.FINE, e.getMessage(), e);
5102                                    sb.append(e.getMessage()).append("\n");
5103                                    break;
5104                            } catch (Exception e) {
5105                                    getLogger().log(Level.FINE, e.getMessage(), e);
5106                                    sb.append(e.getMessage()).append("\n");
5107                            }
5108                    }
5109                    
5110                    String details = sb.toString();
5111                    if(details.length() > 0) {
5112                            String s = LscpI18n.getLogMsg(err);
5113                            throw new LSException(0, s, details);
5114                    }
5115            }
5116            
5117            /**
5118           * Returns the logger for this library.           * Returns the logger for this library.
5119           * @return The logger for this library.           * @return The logger for this library.
5120           */           */

Legend:
Removed from v.596  
changed lines
  Added in v.1605

  ViewVC Help
Powered by ViewVC