/[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 1351 by iliev, Sun Sep 16 23:15:57 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(!llTVC.isEmpty()) subscribe("TOTAL_VOICE_COUNT");
348                    if(!llMIMC.isEmpty()) subscribe("MIDI_INSTRUMENT_MAP_COUNT");
349                    if(!llMIMI.isEmpty()) subscribe("MIDI_INSTRUMENT_MAP_INFO");
350                    if(!llMIC.isEmpty()) subscribe("MIDI_INSTRUMENT_COUNT");
351                    if(!llMII.isEmpty()) subscribe("MIDI_INSTRUMENT_INFO");
352                    if(!llID.isEmpty()) {
353                            subscribe("DB_INSTRUMENT_DIRECTORY_COUNT");
354                            subscribe("DB_INSTRUMENT_DIRECTORY_INFO");
355                            subscribe("DB_INSTRUMENT_COUNT");
356                            subscribe("DB_INSTRUMENT_INFO");
357                    }
358                    if(!llGI.isEmpty()) subscribe("GLOBAL_INFO");
359          }          }
360                    
361          /**          /**
# Line 235  public class Client { Line 363  public class Client {
363           */           */
364          public synchronized void          public synchronized void
365          disconnect() {          disconnect() {
366                    if(getPrintOnlyMode()) return;
367                  try { if(sock != null) sock.close(); }                  try { if(sock != null) sock.close(); }
368                  catch(Exception x) { getLogger().log(Level.FINE, x.getMessage(), x); }                  catch(Exception x) { getLogger().log(Level.FINE, x.getMessage(), x); }
369                  sock = null;                  sock = null;
# Line 262  public class Client { Line 391  public class Client {
391           */           */
392          private void          private void
393          verifyConnection() throws IOException {          verifyConnection() throws IOException {
394                    if(getPrintOnlyMode()) return;
395                    
396                  if(!isConnected())                  if(!isConnected())
397                          throw new IOException(LscpI18n.getLogMsg("Client.notConnected!"));                          throw new IOException(LscpI18n.getLogMsg("Client.notConnected!"));
398          }          }
# Line 271  public class Client { Line 402  public class Client {
402                  String s;                  String s;
403                  for(;;) {                  for(;;) {
404                          s = in.readLine();                          s = in.readLine();
405                          if(s.startsWith("NOTIFY:")) fireEvent(s.substring("NOTIFY:".length()));                          if(s.startsWith("NOTIFY:")) {
406                                    eventThread.scheduleNotification(s.substring("NOTIFY:".length()));
407                            }
408                          else break;                          else break;
409                  }                  }
410                  return s;                  return s;
411          }          }
412                    
413          /** Processes the notifications send by LinuxSampler */          /** Processes the notifications sent by LinuxSampler */
414          private synchronized void          private synchronized void
415          processNotifications() throws IOException, LscpException {          processNotifications() throws IOException, LscpException {
416                  while(in.available() > 0) {                  while(in.available() > 0) {
# Line 336  public class Client { Line 469  public class Client {
469                  return rs;                  return rs;
470          }          }
471                    
472            /** Audio output device count listeners */
473            private final Vector<ItemCountListener> llAODC = new Vector<ItemCountListener>();
474            /** Audio output device info listeners */
475            private final Vector<ItemInfoListener> llAODI = new Vector<ItemInfoListener>();
476          private final Vector<BufferFillListener> llBF = new Vector<BufferFillListener>();          private final Vector<BufferFillListener> llBF = new Vector<BufferFillListener>();
477          private final Vector<ChannelCountListener> llCC = new Vector<ChannelCountListener>();          private final Vector<ChannelCountListener> llCC = new Vector<ChannelCountListener>();
478          private final Vector<ChannelInfoListener> llCI = new Vector<ChannelInfoListener>();          private final Vector<ChannelInfoListener> llCI = new Vector<ChannelInfoListener>();
479            private final Vector<FxSendCountListener> llFSC = new Vector<FxSendCountListener>();
480            private final Vector<FxSendInfoListener> llFSI = new Vector<FxSendInfoListener>();
481          private final Vector<MiscellaneousListener> llM = new Vector<MiscellaneousListener>();          private final Vector<MiscellaneousListener> llM = new Vector<MiscellaneousListener>();
482            /** MIDI input device count listeners */
483            private final Vector<ItemCountListener> llMIDC = new Vector<ItemCountListener>();
484            /** MIDI input device info listeners */
485            private final Vector<ItemInfoListener> llMIDI = new Vector<ItemInfoListener>();
486          private final Vector<StreamCountListener> llSC = new Vector<StreamCountListener>();          private final Vector<StreamCountListener> llSC = new Vector<StreamCountListener>();
487          private final Vector<VoiceCountListener> llVC = new Vector<VoiceCountListener>();          private final Vector<VoiceCountListener> llVC = new Vector<VoiceCountListener>();
488            private final Vector<TotalVoiceCountListener> llTVC = new Vector<TotalVoiceCountListener>();
489            
490            /** MIDI instrument map count listeners */
491            private final Vector<ItemCountListener> llMIMC = new Vector<ItemCountListener>();
492            /** MIDI instrument map info listeners */
493            private final Vector<ItemInfoListener> llMIMI = new Vector<ItemInfoListener>();
494            /** MIDI instrument count listeners */
495            private final Vector<MidiInstrumentCountListener> llMIC =
496                    new Vector<MidiInstrumentCountListener>();
497            /** MIDI instrument info listeners */
498            private final Vector<MidiInstrumentInfoListener> llMII =
499                    new Vector<MidiInstrumentInfoListener>();
500            private final Vector<InstrumentsDbListener> llID = new Vector<InstrumentsDbListener>();
501            private final Vector<GlobalInfoListener> llGI = new Vector<GlobalInfoListener>();
502            
503                    
504          /**          /**
505           * Determines whether there is at least one subscription for notification events.           * Determines whether there is at least one subscription for notification events.
506           * Do not forget to check for additional listeners if the LSCP specification           * Do not forget to check for additional listeners if the LSCP specification
507           * extends in the future.           * is extended in the future.
508           * @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,
509           * <code>false</code> otherwise.           * <code>false</code> otherwise.
510           */           */
511          private boolean          private boolean
512          hasSubscriptions() {          hasSubscriptions() {
513                  return  !llBF.isEmpty() ||                  return  !llAODC.isEmpty() ||
514                          !llCC.isEmpty() ||                          !llAODI.isEmpty() ||
515                          !llCI.isEmpty() ||                          !llBF.isEmpty()   ||
516                          !llM.isEmpty()  ||                          !llCC.isEmpty()   ||
517                          !llSC.isEmpty() ||                          !llCI.isEmpty()   ||
518                          !llVC.isEmpty();                          !llFSC.isEmpty()  ||
519                            !llFSI.isEmpty()  ||
520                            !llM.isEmpty()    ||
521                            !llMIDC.isEmpty() ||
522                            !llMIDI.isEmpty() ||
523                            !llSC.isEmpty()   ||
524                            !llVC.isEmpty()   ||
525                            !llTVC.isEmpty()  ||
526                            !llMIMC.isEmpty() ||
527                            !llMIMI.isEmpty() ||
528                            !llMIC.isEmpty()  ||
529                            !llMII.isEmpty()  ||
530                            !llID.isEmpty()   ||
531                            !llGI.isEmpty();
532          }          }
533                    
534          private void          private synchronized void
535          fireEvent(String s) {          fireEvent(String s) {
536                  if(s.startsWith("CHANNEL_COUNT:")) {                   if(s.startsWith("DB_INSTRUMENT_DIRECTORY_COUNT:")) {
537                            s = s.substring("DB_INSTRUMENT_DIRECTORY_COUNT:".length());
538                            InstrumentsDbEvent e = new InstrumentsDbEvent(this, s);
539                            for(InstrumentsDbListener l : llID) l.directoryCountChanged(e);
540                    } else if(s.startsWith("DB_INSTRUMENT_DIRECTORY_INFO:")) {
541                            InstrumentsDbEvent e;
542                            s = s.substring("DB_INSTRUMENT_DIRECTORY_INFO:".length());
543                            if(s.startsWith("NAME ")) {
544                                    String[] list;
545                                    try {
546                                            s = s.substring("NAME ".length());
547                                            list = parseEscapedStringList(s, ' ');
548                                            if(list.length != 2) throw new LscpException();
549                                            list[1] = toNonEscapedString(list[1]);
550                                            e = new InstrumentsDbEvent(this, list[0], list[1]);
551                                            for(InstrumentsDbListener l : llID) {
552                                                    l.directoryNameChanged(e);
553                                            }
554                                    } catch(LscpException x) {
555                                            getLogger().log (
556                                                    Level.WARNING,
557                                                    LscpI18n.getLogMsg("CommandFailed!"),
558                                                    x
559                                            );
560                                    }
561                            } else {
562                                    e = new InstrumentsDbEvent(this, s);
563                                    for(InstrumentsDbListener l : llID) l.directoryInfoChanged(e);
564                            }
565                    } else if(s.startsWith("DB_INSTRUMENT_COUNT:")) {
566                            s = s.substring("DB_INSTRUMENT_COUNT:".length());
567                            InstrumentsDbEvent e = new InstrumentsDbEvent(this, s);
568                            for(InstrumentsDbListener l : llID) l.instrumentCountChanged(e);
569                    } else if(s.startsWith("DB_INSTRUMENT_INFO:")) {
570                            InstrumentsDbEvent e;
571                            s = s.substring("DB_INSTRUMENT_INFO:".length());
572                            if(s.startsWith("NAME ")) {
573                                    String[] list;
574                                    try {
575                                            s = s.substring("NAME ".length());
576                                            list = parseEscapedStringList(s, ' ');
577                                            if(list.length != 2) throw new LscpException();
578                                            list[1] = toNonEscapedString(list[1]);
579                                            e = new InstrumentsDbEvent(this, list[0], list[1]);
580                                            for(InstrumentsDbListener l : llID) {
581                                                    l.instrumentNameChanged(e);
582                                            }
583                                    } catch(LscpException x) {
584                                            getLogger().log (
585                                                    Level.WARNING,
586                                                    LscpI18n.getLogMsg("CommandFailed!"),
587                                                    x
588                                            );
589                                    }
590                            } else {
591                                    e = new InstrumentsDbEvent(this, s);
592                                    for(InstrumentsDbListener l : llID) l.instrumentInfoChanged(e);
593                            }
594                    } else if(s.startsWith("DB_INSTRUMENTS_JOB_INFO:")) {
595                            s = s.substring("DB_INSTRUMENTS_JOB_INFO:".length());
596                            try {
597                                    int i = Integer.parseInt(s);
598                                    InstrumentsDbEvent e = new InstrumentsDbEvent(this, i);
599                                    for(InstrumentsDbListener l : llID) l.jobStatusChanged(e);
600                            } catch(NumberFormatException x) {
601                                    s = "Unknown DB_INSTRUMENTS_JOB_INFO format";
602                                    getLogger().log(Level.WARNING, s, x);
603                            }
604                            
605                    } else if(s.startsWith("CHANNEL_COUNT:")) {
606                          try {                          try {
607                                  int i = Integer.parseInt(s.substring("CHANNEL_COUNT:".length()));                                  int i = Integer.parseInt(s.substring("CHANNEL_COUNT:".length()));
608                                  ChannelCountEvent e = new ChannelCountEvent(this, i);                                  ChannelCountEvent e = new ChannelCountEvent(this, i);
# Line 375  public class Client { Line 615  public class Client {
615                  } else if(s.startsWith("VOICE_COUNT:")) {                  } else if(s.startsWith("VOICE_COUNT:")) {
616                          try {                          try {
617                                  s = s.substring("VOICE_COUNT:".length());                                  s = s.substring("VOICE_COUNT:".length());
618                                  int i = s.indexOf(' ');                                  Integer[] i = parseIntList(s, ' ');
619                                  if(i == -1) {                                  if(i.length != 2) {
620                                          getLogger().warning("Unknown VOICE_COUNT format");                                          getLogger().warning("Unknown VOICE_COUNT format");
621                                          return;                                          return;
622                                  }                                  }
623                                  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);  
624                                  for(VoiceCountListener l : llVC) l.voiceCountChanged(e);                                  for(VoiceCountListener l : llVC) l.voiceCountChanged(e);
625                          } catch(NumberFormatException x) {                          } catch(Exception x) {
626                                  getLogger().log(Level.WARNING, "Unknown VOICE_COUNT format", x);                                  getLogger().log(Level.WARNING, "Unknown VOICE_COUNT format", x);
627                          }                          }
628                  } else if(s.startsWith("STREAM_COUNT:")) {                  } else if(s.startsWith("STREAM_COUNT:")) {
629                          try {                          try {
630                                  s = s.substring("STREAM_COUNT:".length());                                  s = s.substring("STREAM_COUNT:".length());
631                                  int i = s.indexOf(' ');                                  Integer[] i = parseIntList(s, ' ');
632                                  if(i == -1) {                                  if(i.length != 2) {
633                                          getLogger().warning("Unknown STREAM_COUNT format");                                          getLogger().warning("Unknown STREAM_COUNT format");
634                                          return;                                          return;
635                                  }                                  }
636                                  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);  
637                                  for(StreamCountListener l : llSC) l.streamCountChanged(e);                                  for(StreamCountListener l : llSC) l.streamCountChanged(e);
638                          } catch(NumberFormatException x) {                          } catch(Exception x) {
639                                  getLogger().log(Level.WARNING, "Unknown STREAM_COUNT format", x);                                  getLogger().log(Level.WARNING, "Unknown STREAM_COUNT format", x);
640                          }                          }
641                  } else if(s.startsWith("BUFFER_FILL:")) {                  } else if(s.startsWith("BUFFER_FILL:")) {
# Line 407  public class Client { Line 643  public class Client {
643                                  s = s.substring("BUFFER_FILL:".length());                                  s = s.substring("BUFFER_FILL:".length());
644                                  int i = s.indexOf(' ');                                  int i = s.indexOf(' ');
645                                  if(i == -1) {                                  if(i == -1) {
646                                          getLogger().warning("Unknown STREAM_COUNT format");                                          getLogger().warning("Unknown BUFFER_FILL format");
647                                          return;                                          return;
648                                  }                                  }
649                                  int j = Integer.parseInt(s.substring(0, i));                                  int j = Integer.parseInt(s.substring(0, i));
# Line 416  public class Client { Line 652  public class Client {
652                                  BufferFillEvent e = new BufferFillEvent(this, j, v);                                  BufferFillEvent e = new BufferFillEvent(this, j, v);
653                                  for(BufferFillListener l : llBF) l.bufferFillChanged(e);                                  for(BufferFillListener l : llBF) l.bufferFillChanged(e);
654                          } catch(Exception x) {                          } catch(Exception x) {
655                                  getLogger().log(Level.WARNING, "Unknown STREAM_COUNT format", x);                                  getLogger().log(Level.WARNING, "Unknown BUFFER_FILL format", x);
656                          }                          }
657                  } else if(s.startsWith("CHANNEL_INFO:")) {                  } else if(s.startsWith("CHANNEL_INFO:")) {
658                          try {                          try {
# Line 424  public class Client { Line 660  public class Client {
660                                  ChannelInfoEvent e = new ChannelInfoEvent(this, i);                                  ChannelInfoEvent e = new ChannelInfoEvent(this, i);
661                                  for(ChannelInfoListener l : llCI) l.channelInfoChanged(e);                                  for(ChannelInfoListener l : llCI) l.channelInfoChanged(e);
662                          } catch(NumberFormatException x) {                          } catch(NumberFormatException x) {
663                                  getLogger().log(Level.WARNING, "Unknown STREAM_COUNT format", x);                                  getLogger().log(Level.WARNING, "Unknown CHANNEL_INFO format", x);
664                            }
665                    } else if(s.startsWith("TOTAL_VOICE_COUNT:")) {
666                            try {
667                                    s = s.substring("TOTAL_VOICE_COUNT:".length());
668                                    int i = Integer.parseInt(s);
669                                    TotalVoiceCountEvent e = new TotalVoiceCountEvent(this, i);
670                                    for(TotalVoiceCountListener l : llTVC) l.totalVoiceCountChanged(e);
671                            } catch(NumberFormatException x) {
672                                    getLogger().log (
673                                            Level.WARNING, "Unknown TOTAL_VOICE_COUNT format", x
674                                    );
675                            }
676                    } else if(s.startsWith("AUDIO_OUTPUT_DEVICE_COUNT:")) {
677                            try {
678                                    s = s.substring("AUDIO_OUTPUT_DEVICE_COUNT:".length());
679                                    int i = Integer.parseInt(s);
680                                    ItemCountEvent e = new ItemCountEvent(this, i);
681                                    for(ItemCountListener l : llAODC) l.itemCountChanged(e);
682                            } catch(NumberFormatException x) {
683                                    getLogger().log (
684                                            Level.WARNING, "Unknown AUDIO_OUTPUT_DEVICE_COUNT format", x
685                                    );
686                          }                          }
687                    } else if(s.startsWith("AUDIO_OUTPUT_DEVICE_INFO:")) {
688                            try {
689                                    s = s.substring("AUDIO_OUTPUT_DEVICE_INFO:".length());
690                                    int i = Integer.parseInt(s);
691                                    ItemInfoEvent e = new ItemInfoEvent(this, i);
692                                    for(ItemInfoListener l : llAODI) l.itemInfoChanged(e);
693                            } catch(NumberFormatException x) {
694                                    getLogger().log (
695                                            Level.WARNING, "Unknown AUDIO_OUTPUT_DEVICE_INFO format", x
696                                    );
697                            }
698                    } else if(s.startsWith("MIDI_INPUT_DEVICE_COUNT:")) {
699                            try {
700                                    s = s.substring("MIDI_INPUT_DEVICE_COUNT:".length());
701                                    int i = Integer.parseInt(s);
702                                    ItemCountEvent e = new ItemCountEvent(this, i);
703                                    for(ItemCountListener l : llMIDC) l.itemCountChanged(e);
704                            } catch(NumberFormatException x) {
705                                    getLogger().log (
706                                            Level.WARNING, "Unknown MIDI_INPUT_DEVICE_COUNT format", x
707                                    );
708                            }
709                    } else if(s.startsWith("MIDI_INPUT_DEVICE_INFO:")) {
710                            try {
711                                    s = s.substring("MIDI_INPUT_DEVICE_INFO:".length());
712                                    int i = Integer.parseInt(s);
713                                    ItemInfoEvent e = new ItemInfoEvent(this, i);
714                                    for(ItemInfoListener l : llMIDI) l.itemInfoChanged(e);
715                            } catch(NumberFormatException x) {
716                                    getLogger().log (
717                                            Level.WARNING, "Unknown MIDI_INPUT_DEVICE_INFO format", x
718                                    );
719                            }
720                    } else if(s.startsWith("MIDI_INSTRUMENT_MAP_COUNT:")) {
721                            try {
722                                    s = s.substring("MIDI_INSTRUMENT_MAP_COUNT:".length());
723                                    int i = Integer.parseInt(s);
724                                    ItemCountEvent e = new ItemCountEvent(this, i);
725                                    for(ItemCountListener l : llMIMC) l.itemCountChanged(e);
726                            } catch(NumberFormatException x) {
727                                    getLogger().log (
728                                            Level.WARNING, "Unknown MIDI_INSTRUMENT_MAP_COUNT format", x
729                                    );
730                            }
731                    } else if(s.startsWith("MIDI_INSTRUMENT_MAP_INFO:")) {
732                            try {
733                                    s = s.substring("MIDI_INSTRUMENT_MAP_INFO:".length());
734                                    int i = Integer.parseInt(s);
735                                    ItemInfoEvent e = new ItemInfoEvent(this, i);
736                                    for(ItemInfoListener l : llMIMI) l.itemInfoChanged(e);
737                            } catch(NumberFormatException x) {
738                                    getLogger().log (
739                                            Level.WARNING, "Unknown MIDI_INSTRUMENT_MAP_INFO format", x
740                                    );
741                            }
742                    } else if(s.startsWith("MIDI_INSTRUMENT_COUNT:")) {
743                            try {
744                                    s = s.substring("MIDI_INSTRUMENT_COUNT:".length());
745                                    Integer[] i = parseIntList(s, ' ');
746                                    if(i.length != 2) {
747                                            getLogger().warning("Unknown MIDI_INSTRUMENT_COUNT format");
748                                            return;
749                                    }
750                                    
751                                    MidiInstrumentCountEvent e =
752                                            new MidiInstrumentCountEvent(this, i[0], i[1]);
753                                    
754                                    for(MidiInstrumentCountListener l : llMIC) {
755                                            l.instrumentCountChanged(e);
756                                    }
757                            } catch(Exception x) {
758                                    getLogger().log (
759                                            Level.WARNING, "Unknown MIDI_INSTRUMENT_COUNT format", x
760                                    );
761                            }
762                    } else if(s.startsWith("MIDI_INSTRUMENT_INFO:")) {
763                            try {
764                                    s = s.substring("MIDI_INSTRUMENT_INFO:".length());
765                                    Integer[] i = parseIntList(s, ' ');
766                                    if(i.length != 3) {
767                                            getLogger().warning("Unknown MIDI_INSTRUMENT_INFO format");
768                                            return;
769                                    }
770                                    
771                                    MidiInstrumentInfoEvent e =
772                                            new MidiInstrumentInfoEvent(this, i[0], i[1], i[2]);
773                                    for(MidiInstrumentInfoListener l : llMII) {
774                                            l.instrumentInfoChanged(e);
775                                    }
776                            } catch(Exception x) {
777                                    getLogger().log (
778                                            Level.WARNING, "Unknown MIDI_INSTRUMENT_INFO format", x
779                                    );
780                            }
781                    } else if(s.startsWith("FX_SEND_COUNT:")) {
782                            try {
783                                    s = s.substring("FX_SEND_COUNT:".length());
784                                    Integer[] i = parseIntList(s, ' ');
785                                    if(i.length != 2) {
786                                            getLogger().warning("Unknown FX_SEND_COUNT format");
787                                            return;
788                                    }
789                                    
790                                    FxSendCountEvent e = new FxSendCountEvent(this, i[0], i[1]);
791                                    
792                                    for(FxSendCountListener l : llFSC) l.fxSendCountChanged(e);
793                            } catch(Exception x) {
794                                    getLogger().log(Level.WARNING, "Unknown FX_SEND_COUNT format", x);
795                            }
796                    } else if(s.startsWith("FX_SEND_INFO:")) {
797                            try {
798                                    s = s.substring("FX_SEND_INFO:".length());
799                                    Integer[] i = parseIntList(s, ' ');
800                                    if(i.length != 2) {
801                                            getLogger().warning("Unknown FX_SEND_INFO format");
802                                            return;
803                                    }
804                                    
805                                    FxSendInfoEvent e = new FxSendInfoEvent(this, i[0], i[1]);
806                                    for(FxSendInfoListener l : llFSI) {
807                                            l.fxSendInfoChanged(e);
808                                    }
809                            } catch(Exception x) {
810                                    getLogger().log(Level.WARNING, "Unknown FX_SEND_INFO format", x);
811                            }
812                    } else if(s.startsWith("GLOBAL_INFO:")) {
813                            handleGlobalInfoEvent(s.substring("GLOBAL_INFO:".length()));
814                  } else if(s.startsWith("MISCELLANEOUS:")) {                  } else if(s.startsWith("MISCELLANEOUS:")) {
815                          s = s.substring("MISCELLANEOUS:".length());                          s = s.substring("MISCELLANEOUS:".length());
816                          MiscellaneousEvent e = new MiscellaneousEvent(this, s);                          MiscellaneousEvent e = new MiscellaneousEvent(this, s);
# Line 434  public class Client { Line 819  public class Client {
819          }          }
820                    
821          private void          private void
822            handleGlobalInfoEvent(String s) {
823                    try {
824                            if(s.startsWith("VOLUME ")) {
825                                    float f = Float.parseFloat(s.substring("VOLUME ".length()));
826                                    GlobalInfoEvent e = new GlobalInfoEvent(this, f);
827                                    for(GlobalInfoListener l : llGI) l.volumeChanged(e);
828                            }
829                    } catch(NumberFormatException x) {
830                            getLogger().log(Level.WARNING, "Unknown GLOBAL_INFO format", x);
831                    }
832            }
833            
834            private void
835          subscribe(String event) {          subscribe(String event) {
836                  if(!isConnected()) return;                  if(!getPrintOnlyMode()) {
837                            if(!isConnected()) return;
838                                    
839                  if(!eventThread.isAlive()) eventThread.start();                          if(!eventThread.isAlive()) eventThread.start();
840                    }
841                                    
842                  try {                  try {
843                          out.writeLine("SUBSCRIBE " + event);                          out.writeLine("SUBSCRIBE " + event);
844                          ResultSet rs = getEmptyResultSet();                          if(!getPrintOnlyMode()) getEmptyResultSet();
845                  } catch(Exception x) {                  } catch(Exception x) {
846                          getLogger().log (                          getLogger().log (
847                                  Level.WARNING,                                  Level.WARNING,
# Line 453  public class Client { Line 853  public class Client {
853                    
854          private void          private void
855          unsubscribe(String event) {          unsubscribe(String event) {
856                  if(!isConnected()) return;                  if(!getPrintOnlyMode() && !isConnected()) return;
857                                    
858                  try {                  try {
859                          out.writeLine("UNSUBSCRIBE " + event);                          out.writeLine("UNSUBSCRIBE " + event);
860                          ResultSet rs = getEmptyResultSet();                          if(!getPrintOnlyMode()) getEmptyResultSet();
861                  } catch(Exception x) {                  } catch(Exception x) {
862                          getLogger().log (                          getLogger().log (
863                                  Level.WARNING,                                  Level.WARNING,
# Line 469  public class Client { Line 869  public class Client {
869                    
870          /**          /**
871           * Registers the specified listener for receiving event messages.           * Registers the specified listener for receiving event messages.
872             * Listeners can be registered regardless of the connection state.
873             * @param l The <code>ItemCountListener</code> to register.
874             */
875            public synchronized void
876            addAudioDeviceCountListener(ItemCountListener l) {
877                    if(llAODC.isEmpty()) subscribe("AUDIO_OUTPUT_DEVICE_COUNT");
878                    llAODC.add(l);
879            }
880            
881            /**
882             * Removes the specified listener.
883             * Listeners can be removed regardless of the connection state.
884             * @param l The <code>ItemCountListener</code> to remove.
885             */
886            public synchronized void
887            removeAudioDeviceCountListener(ItemCountListener l) {
888                    boolean b = llAODC.remove(l);
889                    if(b && llAODC.isEmpty()) unsubscribe("AUDIO_OUTPUT_DEVICE_COUNT");
890            }
891            
892            /**
893             * Registers the specified listener for receiving event messages.
894             * Listeners can be registered regardless of the connection state.
895             * @param l The <code>ItemInfoListener</code> to register.
896             */
897            public synchronized void
898            addAudioDeviceInfoListener(ItemInfoListener l) {
899                    if(llAODI.isEmpty()) subscribe("AUDIO_OUTPUT_DEVICE_INFO");
900                    llAODI.add(l);
901            }
902            
903            /**
904             * Removes the specified listener.
905             * Listeners can be removed regardless of the connection state.
906             * @param l The <code>ItemInfoListener</code> to remove.
907             */
908            public synchronized void
909            removeAudioDeviceInfoListener(ItemInfoListener l) {
910                    boolean b = llAODI.remove(l);
911                    if(b && llAODI.isEmpty()) unsubscribe("AUDIO_OUTPUT_DEVICE_INFO");
912            }
913            
914            /**
915             * Registers the specified listener for receiving event messages.
916           * Listeners can be removed regardless of the connection state.           * Listeners can be removed regardless of the connection state.
917           * @param l The <code>BufferFillListener</code> to register.           * @param l The <code>BufferFillListener</code> to register.
918           */           */
# Line 536  public class Client { Line 980  public class Client {
980          /**          /**
981           * Registers the specified listener for receiving event messages.           * Registers the specified listener for receiving event messages.
982           * Listeners can be registered regardless of the connection state.           * Listeners can be registered regardless of the connection state.
983             * @param l The <code>FxSendCountListener</code> to register.
984             */
985            public synchronized void
986            addFxSendCountListener(FxSendCountListener l) {
987                    if(llFSC.isEmpty()) subscribe("FX_SEND_COUNT");
988                    llFSC.add(l);
989            }
990            
991            /**
992             * Removes the specified listener.
993             * Listeners can be removed regardless of the connection state.
994             * @param l The <code>FxSendCountListener</code> to remove.
995             */
996            public synchronized void
997            removeFxSendCountListener(FxSendCountListener l) {
998                    boolean b = llFSC.remove(l);
999                    if(b && llFSC.isEmpty()) unsubscribe("FX_SEND_COUNT");
1000            }
1001            
1002            /**
1003             * Registers the specified listener for receiving event messages.
1004             * Listeners can be registered regardless of the connection state.
1005             * @param l The <code>FxSendInfoListener</code> to register.
1006             */
1007            public synchronized void
1008            addFxSendInfoListener(FxSendInfoListener l) {
1009                    if(llFSI.isEmpty()) subscribe("FX_SEND_INFO");
1010                    llFSI.add(l);
1011            }
1012            
1013            /**
1014             * Removes the specified listener.
1015             * Listeners can be removed regardless of the connection state.
1016             * @param l The <code>FxSendInfoListener</code> to remove.
1017             */
1018            public synchronized void
1019            removeFxSendInfoListener(FxSendInfoListener l) {
1020                    boolean b = llFSI.remove(l);
1021                    if(b && llFSI.isEmpty()) unsubscribe("FX_SEND_INFO");
1022            }
1023            
1024            /**
1025             * Registers the specified listener for receiving event messages.
1026             * Listeners can be registered regardless of the connection state.
1027             * @param l The <code>ItemCountListener</code> to register.
1028             */
1029            public synchronized void
1030            addMidiDeviceCountListener(ItemCountListener l) {
1031                    if(llMIDC.isEmpty()) subscribe("MIDI_INPUT_DEVICE_COUNT");
1032                    llMIDC.add(l);
1033            }
1034            
1035            /**
1036             * Removes the specified listener.
1037             * Listeners can be removed regardless of the connection state.
1038             * @param l The <code>ItemCountListener</code> to remove.
1039             */
1040            public synchronized void
1041            removeMidiDeviceCountListener(ItemCountListener l) {
1042                    boolean b = llMIDC.remove(l);
1043                    if(b && llMIDC.isEmpty()) unsubscribe("MIDI_INPUT_DEVICE_COUNT");
1044            }
1045            
1046            /**
1047             * Registers the specified listener for receiving event messages.
1048             * Listeners can be registered regardless of the connection state.
1049             * @param l The <code>ItemInfoListener</code> to register.
1050             */
1051            public synchronized void
1052            addMidiDeviceInfoListener(ItemInfoListener l) {
1053                    if(llMIDI.isEmpty()) subscribe("MIDI_INPUT_DEVICE_INFO");
1054                    llMIDI.add(l);
1055            }
1056            
1057            /**
1058             * Removes the specified listener.
1059             * Listeners can be removed regardless of the connection state.
1060             * @param l The <code>ItemInfoListener</code> to remove.
1061             */
1062            public synchronized void
1063            removeMidiDeviceInfoListener(ItemInfoListener l) {
1064                    boolean b = llMIDI.remove(l);
1065                    if(b && llMIDI.isEmpty()) unsubscribe("MIDI_INPUT_DEVICE_INFO");
1066            }
1067            
1068            /**
1069             * Registers the specified listener for receiving event messages.
1070             * Listeners can be registered regardless of the connection state.
1071           * @param l The <code>MiscellaneousListener</code> to register.           * @param l The <code>MiscellaneousListener</code> to register.
1072           */           */
1073          public synchronized void          public synchronized void
# Line 600  public class Client { Line 1132  public class Client {
1132          }          }
1133                    
1134          /**          /**
1135             * Registers the specified listener for receiving event messages.
1136             * Listeners can be registered regardless of the connection state.
1137             * @param l The <code>TotalVoiceCountListener</code> to register.
1138             */
1139            public synchronized void
1140            addTotalVoiceCountListener(TotalVoiceCountListener l) {
1141                    if(llTVC.isEmpty()) subscribe("TOTAL_VOICE_COUNT");
1142                    llTVC.add(l);
1143            }
1144            
1145            /**
1146             * Removes the specified listener.
1147             * Listeners can be removed regardless of the connection state.
1148             * @param l The <code>TotalVoiceCountListener</code> to remove.
1149             */
1150            public synchronized void
1151            removeTotalVoiceCountListener(TotalVoiceCountListener l) {
1152                    boolean b = llTVC.remove(l);
1153                    if(b && llTVC.isEmpty()) unsubscribe("TOTAL_VOICE_COUNT");
1154            }
1155            
1156            /**
1157             * Registers the specified listener for receiving event messages.
1158             * Listeners can be registered regardless of the connection state.
1159             * @param l The <code>ItemCountListener</code> to register.
1160             */
1161            public synchronized void
1162            addMidiInstrumentMapCountListener(ItemCountListener l) {
1163                    if(llMIMC.isEmpty()) subscribe("MIDI_INSTRUMENT_MAP_COUNT");
1164                    llMIMC.add(l);
1165            }
1166            
1167            /**
1168             * Removes the specified listener.
1169             * Listeners can be removed regardless of the connection state.
1170             * @param l The <code>ItemCountListener</code> to remove.
1171             */
1172            public synchronized void
1173            removeMidiInstrumentMapCountListener(ItemCountListener l) {
1174                    boolean b = llMIMC.remove(l);
1175                    if(b && llMIMC.isEmpty()) unsubscribe("MIDI_INSTRUMENT_MAP_COUNT");
1176            }
1177            
1178            /**
1179             * Registers the specified listener for receiving event messages.
1180             * Listeners can be registered regardless of the connection state.
1181             * @param l The <code>ItemInfoListener</code> to register.
1182             */
1183            public synchronized void
1184            addMidiInstrumentMapInfoListener(ItemInfoListener l) {
1185                    if(llMIMI.isEmpty()) subscribe("MIDI_INSTRUMENT_MAP_INFO");
1186                    llMIMI.add(l);
1187            }
1188            
1189            /**
1190             * Removes the specified listener.
1191             * Listeners can be removed regardless of the connection state.
1192             * @param l The <code>ItemInfoListener</code> to remove.
1193             */
1194            public synchronized void
1195            removeMidiInstrumentMapInfoListener(ItemInfoListener l) {
1196                    boolean b = llMIMI.remove(l);
1197                    if(b && llMIMI.isEmpty()) unsubscribe("MIDI_INSTRUMENT_MAP_INFO");
1198            }
1199            
1200            /**
1201             * Registers the specified listener for receiving event messages.
1202             * Listeners can be registered regardless of the connection state.
1203             * @param l The <code>MidiInstrumentCountListener</code> to register.
1204             */
1205            public synchronized void
1206            addMidiInstrumentCountListener(MidiInstrumentCountListener l) {
1207                    if(llMIC.isEmpty()) subscribe("MIDI_INSTRUMENT_COUNT");
1208                    llMIC.add(l);
1209            }
1210            
1211            /**
1212             * Removes the specified listener.
1213             * Listeners can be removed regardless of the connection state.
1214             * @param l The <code>MidiInstrumentCountListener</code> to remove.
1215             */
1216            public synchronized void
1217            removeMidiInstrumentCountListener(MidiInstrumentCountListener l) {
1218                    boolean b = llMIC.remove(l);
1219                    if(b && llMIC.isEmpty()) unsubscribe("MIDI_INSTRUMENT_COUNT");
1220            }
1221            
1222            /**
1223             * Registers the specified listener for receiving event messages.
1224             * Listeners can be registered regardless of the connection state.
1225             * @param l The <code>MidiInstrumentInfoListener</code> to register.
1226             */
1227            public synchronized void
1228            addMidiInstrumentInfoListener(MidiInstrumentInfoListener l) {
1229                    if(llMII.isEmpty()) subscribe("MIDI_INSTRUMENT_INFO");
1230                    llMII.add(l);
1231            }
1232            
1233            /**
1234             * Removes the specified listener.
1235             * Listeners can be removed regardless of the connection state.
1236             * @param l The <code>MidiInstrumentInfoListener</code> to remove.
1237             */
1238            public synchronized void
1239            removeMidiInstrumentInfoListener(MidiInstrumentInfoListener l) {
1240                    boolean b = llMII.remove(l);
1241                    if(b && llMII.isEmpty()) unsubscribe("MIDI_INSTRUMENT_INFO");
1242            }
1243            
1244            /**
1245             * Registers the specified listener for receiving event messages.
1246             * Listeners can be registered regardless of the connection state.
1247             * @param l The <code>InstrumentsDbListener</code> to register.
1248             */
1249            public synchronized void
1250            addInstrumentsDbListener(InstrumentsDbListener l) {
1251                    if(llID.isEmpty()) {
1252                            subscribe("DB_INSTRUMENT_DIRECTORY_COUNT");
1253                            subscribe("DB_INSTRUMENT_DIRECTORY_INFO");
1254                            subscribe("DB_INSTRUMENT_COUNT");
1255                            subscribe("DB_INSTRUMENT_INFO");
1256                            subscribe("DB_INSTRUMENTS_JOB_INFO");
1257                    }
1258                    llID.add(l);
1259            }
1260            
1261            /**
1262             * Removes the specified listener.
1263             * Listeners can be removed regardless of the connection state.
1264             * @param l The <code>InstrumentsDbListener</code> to remove.
1265             */
1266            public synchronized void
1267            removeInstrumentsDbListener(InstrumentsDbListener l) {
1268                    boolean b = llID.remove(l);
1269                    if(b && llID.isEmpty()) {
1270                            unsubscribe("DB_INSTRUMENT_DIRECTORY_COUNT");
1271                            unsubscribe("DB_INSTRUMENT_DIRECTORY_INFO");
1272                            unsubscribe("DB_INSTRUMENT_COUNT");
1273                            unsubscribe("DB_INSTRUMENT_INFO");
1274                            unsubscribe("DB_INSTRUMENTS_JOB_INFO");
1275                    }
1276            }
1277            
1278            /**
1279             * Registers the specified listener for receiving event messages.
1280             * Listeners can be registered regardless of the connection state.
1281             * @param l The <code>GlobalInfoListener</code> to register.
1282             */
1283            public synchronized void
1284            addGlobalInfoListener(GlobalInfoListener l) {
1285                    if(llGI.isEmpty()) subscribe("GLOBAL_INFO");
1286                    llGI.add(l);
1287            }
1288            
1289            /**
1290             * Removes the specified listener.
1291             * Listeners can be removed regardless of the connection state.
1292             * @param l The <code>GlobalInfoListener</code> to remove.
1293             */
1294            public synchronized void
1295            removeGlobalInfoListener(GlobalInfoListener l) {
1296                    boolean b = llGI.remove(l);
1297                    if(b && llGI.isEmpty()) unsubscribe("GLOBAL_INFO");
1298            }
1299            
1300            /**
1301           * Gets the number of all audio output drivers currently           * Gets the number of all audio output drivers currently
1302           * available for the LinuxSampler instance.           * available for the LinuxSampler instance.
1303           * @return The number of all audio output drivers currently           * @return The number of all audio output drivers currently
# Line 612  public class Client { Line 1310  public class Client {
1310          getAudioOutputDriverCount() throws IOException, LscpException, LSException {          getAudioOutputDriverCount() throws IOException, LscpException, LSException {
1311                  verifyConnection();                  verifyConnection();
1312                  out.writeLine("GET AVAILABLE_AUDIO_OUTPUT_DRIVERS");                  out.writeLine("GET AVAILABLE_AUDIO_OUTPUT_DRIVERS");
1313                    
1314                    if(getPrintOnlyMode()) return -1;
1315                    
1316                  String s = getSingleLineResultSet().getResult();                  String s = getSingleLineResultSet().getResult();
1317                  return parseInt(s);                  return parseInt(s);
1318          }          }
1319            
1320          /**          /**
1321           * Gets all audio output drivers currently available for the LinuxSampler instance.           * Gets all audio output drivers currently available for the LinuxSampler instance.
1322           *           *
1323           * @return <code>String</code> array with all audio output drivers currently available for           * @return <code>AudioOutputDriver</code> array containing all audio output drivers
1324           * the LinuxSampler instance.           * currently available for the LinuxSampler instance.
1325           *           *
1326           * @throws IOException If an I/O error occurs.           * @throws IOException If an I/O error occurs.
1327           * @throws LscpException If LSCP protocol corruption occurs.           * @throws LscpException If LSCP protocol corruption occurs.
1328           * @throws LSException If some other error occurs.           * @throws LSException If some other error occurs.
1329           */           */
1330          public synchronized String[]          public synchronized AudioOutputDriver[]
1331          getAudioOutputDrivers() throws IOException, LscpException, LSException {          getAudioOutputDrivers() throws IOException, LscpException, LSException {
1332                    String[] drivers = getAudioOutputDriverNames();
1333                    if(getPrintOnlyMode()) return null;
1334                    
1335                    AudioOutputDriver[] aod = new AudioOutputDriver[drivers.length];
1336                    
1337                    for(int i = 0; i < aod.length; i++) aod[i] = getAudioOutputDriverInfo(drivers[i]);
1338                    
1339                    return aod;
1340            }
1341            
1342            /**
1343             * Gets all audio output drivers currently available for the LinuxSampler instance.
1344             *
1345             * @return <code>String</code> array containing all audio output drivers currently
1346             * available for the LinuxSampler instance.
1347             *
1348             * @throws IOException If an I/O error occurs.
1349             * @throws LscpException If LSCP protocol corruption occurs.
1350             * @throws LSException If some other error occurs.
1351             */
1352            private synchronized String[]
1353            getAudioOutputDriverNames() throws IOException, LscpException, LSException {
1354                  verifyConnection();                  verifyConnection();
1355                  out.writeLine("LIST AVAILABLE_AUDIO_OUTPUT_DRIVERS");                  out.writeLine("LIST AVAILABLE_AUDIO_OUTPUT_DRIVERS");
1356                    if(getPrintOnlyMode()) return null;
1357                  return parseList(getSingleLineResultSet().getResult());                  return parseList(getSingleLineResultSet().getResult());
1358          }          }
1359                    
1360          /**          /**
1361           * Gets detailed information about a specific audio output driver.           * Gets detailed information about a specific audio output driver.
1362           * @param driverName The name of the audio output driver.           * @param driverName The name of the audio output driver.
1363           *           * @param depList An optional list of dependences parameters.
1364           * @return An <code>AudioOutputDriver</code> object containing           * @return An <code>AudioOutputDriver</code> object containing
1365           * information about the specified audio output driver.           * information about the specified audio output driver.
1366           *           *
# Line 643  public class Client { Line 1368  public class Client {
1368           * @throws LscpException If LSCP protocol corruption occurs.           * @throws LscpException If LSCP protocol corruption occurs.
1369           * @throws LSException If there is no driver with name <code>driverName</code>.           * @throws LSException If there is no driver with name <code>driverName</code>.
1370           *           *
1371           * @see #getAudioOutputDrivers           * @see #getAudioOutputDriverNames
1372           */           */
1373          public synchronized AudioOutputDriver          public synchronized AudioOutputDriver
1374          getAudioOutputDriverInfo(String driverName) throws IOException, LscpException, LSException {          getAudioOutputDriverInfo(String driverName, Parameter... depList)
1375                                            throws IOException, LscpException, LSException {
1376                    
1377                  verifyConnection();                  verifyConnection();
1378                  out.writeLine("GET AUDIO_OUTPUT_DRIVER INFO " + driverName);                  out.writeLine("GET AUDIO_OUTPUT_DRIVER INFO " + driverName);
1379                    if(getPrintOnlyMode()) return null;
1380                    
1381                  ResultSet rs = getMultiLineResultSet();                  ResultSet rs = getMultiLineResultSet();
1382                  AudioOutputDriver aod = new AudioOutputDriver(rs.getMultiLineResult());                  AudioOutputDriver aod = new AudioOutputDriver(rs.getMultiLineResult());
1383                  aod.setName(driverName);                  aod.setName(driverName);
1384                                    
1385                  for(String s : aod.getParameterNames())                  for(String s : aod.getParameterNames())
1386                          aod.addParameter(getAudioOutputDriverParameterInfo(driverName, s));                          aod.addParameter(getAudioOutputDriverParameterInfo(driverName, s, depList));
1387                                    
1388                  return aod;                  return aod;
1389          }          }
# Line 688  public class Client { Line 1417  public class Client {
1417                  StringBuffer args = new StringBuffer(driver);                  StringBuffer args = new StringBuffer(driver);
1418                  args.append(' ').append(param);                  args.append(' ').append(param);
1419                                    
1420                  for(Parameter p : deplist)                  for(Parameter p : deplist) {
1421                            if(p.getValue() == null) continue;
1422                          args.append(' ').append(p.getName()).append('=').append(p.getStringValue());                          args.append(' ').append(p.getName()).append('=').append(p.getStringValue());
1423                    }
1424                                    
1425                  out.writeLine("GET AUDIO_OUTPUT_DRIVER_PARAMETER INFO " + args.toString());                  out.writeLine("GET AUDIO_OUTPUT_DRIVER_PARAMETER INFO " + args.toString());
1426                    if(getPrintOnlyMode()) return null;
1427                                    
1428                  ResultSet rs = getMultiLineResultSet();                  ResultSet rs = getMultiLineResultSet();
1429                                    
# Line 705  public class Client { Line 1437  public class Client {
1437                          if(!multi) prm = new BoolParameter(lnS);                          if(!multi) prm = new BoolParameter(lnS);
1438                          else prm = new BoolListParameter(lnS);                          else prm = new BoolListParameter(lnS);
1439                          prm.setName(param);                          prm.setName(param);
1440                            prm.setValue(prm.getDefault());
1441                          return prm;                          return prm;
1442                  case INT:                  case INT:
1443                          if(!multi) prm = new IntParameter(lnS);                          if(!multi) prm = new IntParameter(lnS);
1444                          else prm = new IntListParameter(lnS);                          else prm = new IntListParameter(lnS);
1445                          prm.setName(param);                          prm.setName(param);
1446                            prm.setValue(prm.getDefault());
1447                          return prm;                          return prm;
1448                  case FLOAT:                  case FLOAT:
1449                          if(!multi) prm = new FloatParameter(lnS);                          if(!multi) prm = new FloatParameter(lnS);
1450                          else prm = new FloatListParameter(lnS);                          else prm = new FloatListParameter(lnS);
1451                          prm.setName(param);                          prm.setName(param);
1452                            prm.setValue(prm.getDefault());
1453                          return prm;                          return prm;
1454                  case STRING:                  case STRING:
1455                          if(!multi) prm = new StringParameter(lnS);                          if(!multi) prm = new StringParameter(lnS);
1456                          else prm = new StringListParameter(lnS);                          else prm = new StringListParameter(lnS);
1457                          prm.setName(param);                          prm.setName(param);
1458                            prm.setValue(prm.getDefault());
1459                          return prm;                          return prm;
1460                  default: throw new LscpException(LscpI18n.getLogMsg("Client.unknownPrmType!"));                  default: throw new LscpException(LscpI18n.getLogMsg("Client.unknownPrmType!"));
1461                  }                  }
# Line 745  public class Client { Line 1481  public class Client {
1481                  verifyConnection();                  verifyConnection();
1482                  StringBuffer args = new StringBuffer(aoDriver);                  StringBuffer args = new StringBuffer(aoDriver);
1483                                    
1484                  for(Parameter p : paramList)                  for(Parameter p : paramList) {
1485                            if(p.getValue() == null) continue;
1486                          args.append(' ').append(p.getName()).append('=').append(p.getStringValue());                          args.append(' ').append(p.getName()).append('=').append(p.getStringValue());
1487                    }
1488                                    
1489                  out.writeLine("CREATE AUDIO_OUTPUT_DEVICE " + args.toString());                  out.writeLine("CREATE AUDIO_OUTPUT_DEVICE " + args.toString());
1490                    if(getPrintOnlyMode()) return -1;
1491                    
1492                  ResultSet rs = getEmptyResultSet();                  ResultSet rs = getEmptyResultSet();
1493                                    
1494                  return rs.getIndex();                  return rs.getIndex();
# Line 756  public class Client { Line 1496  public class Client {
1496                    
1497          /**          /**
1498           * Destroys already created audio output device.           * Destroys already created audio output device.
1499           * @param deviceID The ID of the audio output device to be destroyed.           * @param deviceId The ID of the audio output device to be destroyed.
1500           * @throws IOException If some I/O error occurs.           * @throws IOException If some I/O error occurs.
1501           * @throws LSException If the destroying of the audio output device failed.           * @throws LSException If the destroying of the audio output device failed.
1502           * @throws LscpException If LSCP protocol corruption occurs.           * @throws LscpException If LSCP protocol corruption occurs.
1503           * @see #getAudioOutputDevices           * @see #getAudioOutputDevices
1504           */           */
1505          public synchronized void          public synchronized void
1506          destroyAudioOutputDevice(int deviceID) throws IOException, LSException, LscpException {          destroyAudioOutputDevice(int deviceId) throws IOException, LSException, LscpException {
1507                  verifyConnection();                  verifyConnection();
1508                  out.writeLine("DESTROY AUDIO_OUTPUT_DEVICE " + deviceID);                  out.writeLine("DESTROY AUDIO_OUTPUT_DEVICE " + deviceId);
1509                    if(getPrintOnlyMode()) return;
1510                    
1511                  ResultSet rs = getEmptyResultSet();                  ResultSet rs = getEmptyResultSet();
1512          }          }
1513                    
1514            /**
1515             * Enables/disables the specified audio output device.
1516             * @param deviceId The ID of the audio output device to be enabled/disabled.
1517             * @param enable If <code>true</code> the audio output device is enabled,
1518             * else the device is disabled.
1519             * @throws IOException If some I/O error occurs.
1520             * @throws LSException If there is no audio output
1521             * device with numerical ID <code>deviceId</code>.
1522             * @throws LscpException If LSCP protocol corruption occurs.
1523             */
1524            public void
1525            enableAudioOutputDevice(int deviceId, boolean enable)
1526                                    throws IOException, LSException, LscpException {
1527                    
1528                    setAudioOutputDeviceParameter(deviceId, new BoolParameter("ACTIVE", enable));
1529            }
1530            
1531          /**          /**
1532           * Gets the current number of all created audio output devices.           * Gets the current number of all created audio output devices.
1533           * @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 1539  public class Client {
1539          getAudioOutputDeviceCount() throws IOException, LscpException, LSException {          getAudioOutputDeviceCount() throws IOException, LscpException, LSException {
1540                  verifyConnection();                  verifyConnection();
1541                  out.writeLine("GET AUDIO_OUTPUT_DEVICES");                  out.writeLine("GET AUDIO_OUTPUT_DEVICES");
1542                    if(getPrintOnlyMode()) return -1;
1543                    
1544                  String s = getSingleLineResultSet().getResult();                  String s = getSingleLineResultSet().getResult();
1545                  return parseInt(s);                  return parseInt(s);
1546          }          }
1547                                    
1548          /**          /**
1549             * Gets a list of all created audio output devices.
1550             * @return An <code>AudioOutputDevice</code> array
1551             * providing all created audio output devices.
1552             * @throws IOException If some I/O error occurs.
1553             * @throws LscpException If LSCP protocol corruption occurs.
1554             * @throws LSException If some other error occurs.
1555             */
1556            public synchronized AudioOutputDevice[]
1557            getAudioOutputDevices() throws IOException, LscpException, LSException {
1558                    Integer[] idS = getAudioOutputDeviceIDs();
1559                    if(getPrintOnlyMode()) return null;
1560                    
1561                    AudioOutputDevice[] devices = new AudioOutputDevice[idS.length];
1562                    
1563                    for(int i = 0; i < devices.length; i++)
1564                            devices[i] = getAudioOutputDeviceInfo(idS[i]);
1565                    
1566                    return devices;
1567            }
1568            
1569            /**
1570           * Gets a list of numerical IDs of all created audio output devices.           * Gets a list of numerical IDs of all created audio output devices.
1571           * @return An <code>Integer</code> array with numerical IDs of           * @return An <code>Integer</code> array providing the numerical IDs of
1572           * all created audio output devices.           * all created audio output devices.
1573           * @throws IOException If some I/O error occurs.           * @throws IOException If some I/O error occurs.
1574           * @throws LscpException If LSCP protocol corruption occurs.           * @throws LscpException If LSCP protocol corruption occurs.
1575           * @throws LSException If some other error occurs.           * @throws LSException If some other error occurs.
1576           */           */
1577          public synchronized Integer[]          public synchronized Integer[]
1578          getAudioOutputDevices() throws IOException, LscpException, LSException {          getAudioOutputDeviceIDs() throws IOException, LscpException, LSException {
1579                  verifyConnection();                  verifyConnection();
1580                  out.writeLine("LIST AUDIO_OUTPUT_DEVICES");                  out.writeLine("LIST AUDIO_OUTPUT_DEVICES");
1581                    if(getPrintOnlyMode()) return null;
1582                    
1583                  return parseIntList(getSingleLineResultSet().getResult());                  return parseIntList(getSingleLineResultSet().getResult());
1584          }          }
1585                    
1586          /**          /**
1587           * Gets the current settings of a specific, already created audio output device.           * Gets the current settings of a specific, already created audio output device.
1588           *           *
1589           * @param deviceID Specifies the numerical ID of the audio output device.           * @param deviceId Specifies the numerical ID of the audio output device.
1590           *           *
1591           * @return An <code>AudioOutputDevice</code> instance containing information           * @return An <code>AudioOutputDevice</code> instance containing information
1592           * about the specified device.           * about the specified device.
# Line 810  public class Client { Line 1594  public class Client {
1594           * @throws IOException If some I/O error occurs.           * @throws IOException If some I/O error occurs.
1595           * @throws LscpException If LSCP protocol corruption occurs.           * @throws LscpException If LSCP protocol corruption occurs.
1596           * @throws LSException If there is no audio output device           * @throws LSException If there is no audio output device
1597           * with device id <code>deviceID</code>.           * with device id <code>deviceId</code>.
1598           *           *
1599           * @see #getAudioOutputDevices           * @see #getAudioOutputDevices
1600           */           */
1601          public synchronized AudioOutputDevice          public synchronized AudioOutputDevice
1602          getAudioOutputDeviceInfo(int deviceID) throws IOException, LscpException, LSException {          getAudioOutputDeviceInfo(int deviceId) throws IOException, LscpException, LSException {
1603                  verifyConnection();                  verifyConnection();
1604                  out.writeLine("GET AUDIO_OUTPUT_DEVICE INFO " + deviceID);                  out.writeLine("GET AUDIO_OUTPUT_DEVICE INFO " + deviceId);
1605                    if(getPrintOnlyMode()) return null;
1606                                    
1607                  ResultSet rs = getMultiLineResultSet();                  ResultSet rs = getMultiLineResultSet();
1608                                    
1609                  String[] lnS = rs.getMultiLineResult();                  String[] lnS = rs.getMultiLineResult();
1610                                    
1611                  AudioOutputDevice aod = new AudioOutputDevice();                  AudioOutputDevice aod = new AudioOutputDevice();
1612                    aod.setDeviceId(deviceId);
1613                  Parameter<Integer> channels;                  Parameter<Integer> channels;
1614                  Parameter<Integer> samplerate;                  Parameter<Integer> samplerate;
1615                                    
# Line 838  public class Client { Line 1624  public class Client {
1624                                  s = s.substring("CHANNELS: ".length(), s.length());                                  s = s.substring("CHANNELS: ".length(), s.length());
1625                                  channels.parseValue(s);                                  channels.parseValue(s);
1626                                  aod.setChannelsParameter(channels);                                  aod.setChannelsParameter(channels);
1627                                    int count = channels.getValue() > 0 ? channels.getValue() : 0;
1628                                    AudioOutputChannel[] aoc = new AudioOutputChannel[count];
1629                                    for(int i = 0; i < count; i++) {
1630                                            aoc[i] = getAudioOutputChannelInfo(deviceId, i);
1631                                    }
1632                                    aod.setAudioChannels(aoc);
1633                          } else if(s.startsWith("SAMPLERATE: ")) {                          } else if(s.startsWith("SAMPLERATE: ")) {
1634                                  samplerate = (Parameter<Integer>)                                  samplerate = (Parameter<Integer>)
1635                                          getAudioOutputDriverParameterInfo(drv, "SAMPLERATE");                                          getAudioOutputDriverParameterInfo(drv, "SAMPLERATE");
# Line 872  public class Client { Line 1664  public class Client {
1664          /**          /**
1665           * Alters a specific setting of a created audio output device.           * Alters a specific setting of a created audio output device.
1666           *           *
1667           * @param deviceID The numerical ID of the audio output device.           * @param deviceId The numerical ID of the audio output device.
1668           * @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
1669           * and the new value for this parameter.           * and the new value for this parameter.
1670           *           *
# Line 880  public class Client { Line 1672  public class Client {
1672           * @throws LscpException If LSCP protocol corruption occurs.           * @throws LscpException If LSCP protocol corruption occurs.
1673           * @throws LSException If           * @throws LSException If
1674           * <ul>           * <ul>
1675           * <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>;
1676           * <li>There is no device parameter with the specified name;           * <li>There is no device parameter with the specified name;
1677           * <li>The device parameter is readonly;           * <li>The device parameter is readonly;
1678           * <li>The device parameter is from different type.           * <li>The device parameter is from different type.
# Line 890  public class Client { Line 1682  public class Client {
1682           * @see #getAudioOutputDeviceInfo           * @see #getAudioOutputDeviceInfo
1683           */           */
1684          public synchronized void          public synchronized void
1685          setAudioOutputDeviceParameter(int deviceID, Parameter prm)          setAudioOutputDeviceParameter(int deviceId, Parameter prm)
1686                                                  throws IOException, LscpException, LSException {                                                  throws IOException, LscpException, LSException {
1687                                    
1688                  verifyConnection();                  verifyConnection();
1689                  String kv = prm.getName() + '=' + prm.getStringValue();                  String kv = prm.getName() + '=' + prm.getStringValue();
1690                  out.writeLine("SET AUDIO_OUTPUT_DEVICE_PARAMETER " + deviceID + ' ' + kv);                  out.writeLine("SET AUDIO_OUTPUT_DEVICE_PARAMETER " + deviceId + ' ' + kv);
1691                    if(getPrintOnlyMode()) return;
1692                                    
1693                  ResultSet rs = getEmptyResultSet();                  ResultSet rs = getEmptyResultSet();
1694          }          }
1695                    
1696          /**          /**
1697             * Changes the channel number of the speicifed audio output device.
1698             * @param deviceId The numerical ID of the audio output device.
1699             * @param channels The new number of audio output channels.
1700             *
1701             * @throws IOException If an I/O error occurs.
1702             * @throws LscpException If LSCP protocol corruption occurs.
1703             * @throws LSException If there is no device with ID <code>deviceId</code> or
1704             * if <code>channels</code> number is out of range.
1705             *
1706             * @see #getAudioOutputChannelInfo
1707             */
1708            public synchronized void
1709            setAudioOutputChannelCount(int deviceId, int channels)
1710                                            throws IOException, LscpException, LSException {
1711                    
1712                    setAudioOutputDeviceParameter(deviceId, new IntParameter("CHANNELS", channels));
1713            }
1714            
1715            /**
1716           * Gets information about an audio channel.           * Gets information about an audio channel.
1717           *           *
1718           * @param deviceID The numerical ID of the audio output device.           * @param deviceId The numerical ID of the audio output device.
1719           * @param audioChn The audio channel number.           * @param audioChn The audio channel number.
1720           *           *
1721           * @return An <code>AudioOutputChannel</code> instance containing the           * @return An <code>AudioOutputChannel</code> instance containing the
# Line 913  public class Client { Line 1725  public class Client {
1725           * @throws LscpException If LSCP protocol corruption occurs.           * @throws LscpException If LSCP protocol corruption occurs.
1726           * @throws LSException If           * @throws LSException If
1727           * <ul>           * <ul>
1728           * <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>;
1729           * <li><code>audioChn</code> is not a valid channel number;           * <li><code>audioChn</code> is not a valid channel number;
1730           * </ul>           * </ul>
1731           *           *
# Line 921  public class Client { Line 1733  public class Client {
1733           * @see #getAudioOutputDeviceInfo           * @see #getAudioOutputDeviceInfo
1734           */           */
1735          public synchronized AudioOutputChannel          public synchronized AudioOutputChannel
1736          getAudioOutputChannelInfo(int deviceID, int audioChn)          getAudioOutputChannelInfo(int deviceId, int audioChn)
1737                                                  throws IOException, LscpException, LSException {                                                  throws IOException, LscpException, LSException {
1738                                    
1739                  verifyConnection();                  verifyConnection();
1740                  out.writeLine("GET AUDIO_OUTPUT_CHANNEL INFO " + deviceID + ' ' + audioChn);                  out.writeLine("GET AUDIO_OUTPUT_CHANNEL INFO " + deviceId + ' ' + audioChn);
1741                    if(getPrintOnlyMode()) return null;
1742                                    
1743                  ResultSet rs = getMultiLineResultSet();                  ResultSet rs = getMultiLineResultSet();
1744                                    
# Line 934  public class Client { Line 1747  public class Client {
1747                  String[] lnS = rs.getMultiLineResult();                  String[] lnS = rs.getMultiLineResult();
1748                  for(String s : lnS) {                  for(String s : lnS) {
1749                          if(s.startsWith("NAME: ")) {                          if(s.startsWith("NAME: ")) {
1750                                  aoc.setName(s.substring("NAME: ".length()));                                  s = s.substring("NAME: ".length());
1751                                    Parameter<String> prm = getAudioOutputChannelParameterInfo (
1752                                            deviceId, audioChn, "NAME"
1753                                    );
1754                                    prm.setValue(removeQuotation(s));
1755                                    aoc.setNameParameter(prm);
1756                          } else if(s.startsWith("IS_MIX_CHANNEL: ")) {                          } else if(s.startsWith("IS_MIX_CHANNEL: ")) {
1757                                  s = s.substring("IS_MIX_CHANNEL: ".length());                                  s = s.substring("IS_MIX_CHANNEL: ".length());
1758                                                                    Parameter<Boolean> prm = getAudioOutputChannelParameterInfo (
1759                                  aoc.setMixChannel(Boolean.parseBoolean(s));                                          deviceId, audioChn, "IS_MIX_CHANNEL"
1760                                    );
1761                                    prm.setValue(Boolean.parseBoolean(s));
1762                                    aoc.setMixChannelParameter(prm);
1763                          } else if(s.startsWith("MIX_CHANNEL_DESTINATION: ")) {                          } else if(s.startsWith("MIX_CHANNEL_DESTINATION: ")) {
1764                                  s = s.substring("MIX_CHANNEL_DESTINATION: ".length());                                  s = s.substring("MIX_CHANNEL_DESTINATION: ".length());
1765                                  aoc.setMixChannelDest(parseInt(s));                                  Parameter<Integer> prm = getAudioOutputChannelParameterInfo (
1766                                            deviceId, audioChn, "MIX_CHANNEL_DESTINATION"
1767                                    );
1768                                    prm.setValue(parseInt(s));
1769                                    aoc.setMixChannelDestParameter(prm);
1770                          } else {                          } else {
1771                                  int i = s.indexOf(": ");                                  int i = s.indexOf(": ");
1772                                  if(i == -1) throw new LscpException (                                  if(i == -1) throw new LscpException (
# Line 949  public class Client { Line 1774  public class Client {
1774                                  );                                  );
1775                                                                    
1776                                  Parameter prm = getAudioOutputChannelParameterInfo (                                  Parameter prm = getAudioOutputChannelParameterInfo (
1777                                          deviceID, audioChn, s.substring(0, i)                                          deviceId, audioChn, s.substring(0, i)
1778                                  );                                  );
1779                                                                    
1780                                  s = s.substring(i + 2);                                  s = s.substring(i + 2);
# Line 965  public class Client { Line 1790  public class Client {
1790          /**          /**
1791           * Gets detailed information about a specific audio output channel parameter.           * Gets detailed information about a specific audio output channel parameter.
1792           *           *
1793           * @param devID The numerical ID of the audio output device.           * @param devId The numerical ID of the audio output device.
1794           * @param chan The audio channel number.           * @param chan The audio channel number.
1795           * @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.
1796           *           *
# Line 976  public class Client { Line 1801  public class Client {
1801           * @throws LscpException If LSCP protocol corruption occurs.           * @throws LscpException If LSCP protocol corruption occurs.
1802           * @throws LSException If           * @throws LSException If
1803           * <ul>           * <ul>
1804           * <li><code>devID</code> is not a valid device ID;           * <li><code>devId</code> is not a valid device ID;
1805           * <li><code>chan</code> is not a valid channel number;           * <li><code>chan</code> is not a valid channel number;
1806           * <li>There is no channel parameter with the specified name.           * <li>There is no channel parameter with the specified name.
1807           * </ul>           * </ul>
# Line 985  public class Client { Line 1810  public class Client {
1810           * @see #getAudioOutputChannelInfo           * @see #getAudioOutputChannelInfo
1811           */           */
1812          public synchronized Parameter          public synchronized Parameter
1813          getAudioOutputChannelParameterInfo(int devID, int chan, String param)          getAudioOutputChannelParameterInfo(int devId, int chan, String param)
1814                                                  throws IOException, LscpException, LSException {                                                  throws IOException, LscpException, LSException {
1815                                    
1816                  verifyConnection();                  verifyConnection();
1817                  String args = devID + ' ' + chan + ' ' + param;                  String args = devId + " " + chan + " " + param;
1818                  out.writeLine("GET AUDIO_OUTPUT_CHANNEL_PARAMETER INFO " + args);                  out.writeLine("GET AUDIO_OUTPUT_CHANNEL_PARAMETER INFO " + args);
1819                    if(getPrintOnlyMode()) return null;
1820                                    
1821                  ResultSet rs = getMultiLineResultSet();                  ResultSet rs = getMultiLineResultSet();
1822                                    
# Line 1027  public class Client { Line 1853  public class Client {
1853          /**          /**
1854           * Alters a specific setting of an audio output channel.           * Alters a specific setting of an audio output channel.
1855           *           *
1856           * @param devID The numerical ID of the audio device.           * @param devId The numerical ID of the audio device.
1857           * @param chn The audio channel number.           * @param chn The audio channel number.
1858           * @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
1859           * and the new value for this parameter.           * and the new value for this parameter.
# Line 1036  public class Client { Line 1862  public class Client {
1862           * @throws LscpException If LSCP protocol corruption occurs.           * @throws LscpException If LSCP protocol corruption occurs.
1863           * @throws LSException If           * @throws LSException If
1864           * <ul>           * <ul>
1865           * <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>;
1866           * <li><code>chn</code> is not a valid channel number;           * <li><code>chn</code> is not a valid channel number;
1867           * <li>There is no channel parameter with the specified name;           * <li>There is no channel parameter with the specified name;
1868           * <li>The channel parameter is readonly;           * <li>The channel parameter is readonly;
# Line 1047  public class Client { Line 1873  public class Client {
1873           * @see #getAudioOutputChannelInfo           * @see #getAudioOutputChannelInfo
1874           */           */
1875          public synchronized void          public synchronized void
1876          setAudioOutputChannelParameter(int devID, int chn,  Parameter prm)          setAudioOutputChannelParameter(int devId, int chn,  Parameter prm)
1877                                                  throws IOException, LscpException, LSException {                                                  throws IOException, LscpException, LSException {
1878                                    
1879                  verifyConnection();                  verifyConnection();
1880                  String args = devID + ' ' + chn + ' ' + prm.getName() + '=' + prm.getStringValue();                  String args = devId + " " + chn + " " + prm.getName() + '=' + prm.getStringValue();
1881                  out.writeLine("SET AUDIO_OUTPUT_CHANNEL_PARAMETER " + args);                  out.writeLine("SET AUDIO_OUTPUT_CHANNEL_PARAMETER " + args);
1882                    if(getPrintOnlyMode()) return;
1883                                    
1884                  ResultSet rs = getEmptyResultSet();                  ResultSet rs = getEmptyResultSet();
1885          }          }
# Line 1068  public class Client { Line 1895  public class Client {
1895          getMidiInputDriverCount() throws IOException, LscpException, LSException {          getMidiInputDriverCount() throws IOException, LscpException, LSException {
1896                  verifyConnection();                  verifyConnection();
1897                  out.writeLine("GET AVAILABLE_MIDI_INPUT_DRIVERS");                  out.writeLine("GET AVAILABLE_MIDI_INPUT_DRIVERS");
1898                    if(getPrintOnlyMode()) return -1;
1899                    
1900                  String s = getSingleLineResultSet().getResult();                  String s = getSingleLineResultSet().getResult();
1901                  return parseInt(s);                  return parseInt(s);
1902          }          }
# Line 1075  public class Client { Line 1904  public class Client {
1904          /**          /**
1905           * Gets all MIDI input drivers currently available for the LinuxSampler instance.           * Gets all MIDI input drivers currently available for the LinuxSampler instance.
1906           *           *
1907           * @return <code>String</code> array with all MIDI input drivers currently available for           * @return <code>MidiInputDriver</code> array containing all MIDI input drivers currently
1908           * the LinuxSampler instance or <code>null</code> if there are no MIDI input drivers           * available for the LinuxSampler instance.
          * currently available.  
1909           *           *
1910           * @throws IOException If an I/O error occurs.           * @throws IOException If an I/O error occurs.
1911           * @throws LscpException If LSCP protocol corruption occurs.           * @throws LscpException If LSCP protocol corruption occurs.
1912           * @throws LSException If some other error occurs.           * @throws LSException If some other error occurs.
1913           */           */
1914          public synchronized String[]          public synchronized MidiInputDriver[]
1915          getMidiInputDrivers() throws IOException, LscpException, LSException {          getMidiInputDrivers() throws IOException, LscpException, LSException {
1916                    String[] drivers = getMidiInputDriverNames();
1917                    if(getPrintOnlyMode()) return null;
1918                    
1919                    MidiInputDriver[] mid = new MidiInputDriver[drivers.length];
1920                    
1921                    for(int i = 0; i < mid.length; i++) mid[i] = getMidiInputDriverInfo(drivers[i]);
1922                    
1923                    return mid;
1924            }
1925            
1926            /**
1927             * Gets all MIDI input drivers currently available for the LinuxSampler instance.
1928             *
1929             * @return <code>String</code> array containing all MIDI input drivers currently available
1930             * for the LinuxSampler instance.
1931             *
1932             * @throws IOException If an I/O error occurs.
1933             * @throws LscpException If LSCP protocol corruption occurs.
1934             * @throws LSException If some other error occurs.
1935             */
1936            private synchronized String[]
1937            getMidiInputDriverNames() throws IOException, LscpException, LSException {
1938                  verifyConnection();                  verifyConnection();
1939                  out.writeLine("LIST AVAILABLE_MIDI_INPUT_DRIVERS");                  out.writeLine("LIST AVAILABLE_MIDI_INPUT_DRIVERS");
1940                    if(getPrintOnlyMode()) return null;
1941                    
1942                  return parseList(getSingleLineResultSet().getResult());                  return parseList(getSingleLineResultSet().getResult());
1943          }          }
1944                    
1945          /**          /**
1946           * Gets detailed information about a specific MIDI input driver.           * Gets detailed information about a specific MIDI input driver.
1947           * @param driverName The name of the MIDI input driver.           * @param driverName The name of the MIDI input driver.
1948           *           * @param depList An optional list of dependences parameters.
1949           * @return An <code>MidiInputDriver</code> object containing           * @return A <code>MidiInputDriver</code> object containing
1950           * information about the specified MIDI input driver.           * information about the specified MIDI input driver.
1951           *           *
1952           * @throws IOException If an I/O error occurs.           * @throws IOException If an I/O error occurs.
1953           * @throws LscpException If LSCP protocol corruption occurs.           * @throws LscpException If LSCP protocol corruption occurs.
1954           * @throws LSException If there is no driver with name <code>driverName</code>.           * @throws LSException If there is no driver with name <code>driverName</code>.
1955           *           *
1956           * @see #getMidiInputDrivers           * @see #getMidiInputDriverNames
1957           */           */
1958          public synchronized MidiInputDriver          public synchronized MidiInputDriver
1959          getMidiInputDriverInfo(String driverName) throws IOException, LscpException, LSException {          getMidiInputDriverInfo(String driverName, Parameter... depList)
1960                                            throws IOException, LscpException, LSException {
1961                    
1962                  verifyConnection();                  verifyConnection();
1963                  out.writeLine("GET MIDI_INPUT_DRIVER INFO " + driverName);                  out.writeLine("GET MIDI_INPUT_DRIVER INFO " + driverName);
1964                    if(getPrintOnlyMode()) return null;
1965                    
1966                  ResultSet rs = getMultiLineResultSet();                  ResultSet rs = getMultiLineResultSet();
1967                                    
1968                  MidiInputDriver mid = new MidiInputDriver(rs.getMultiLineResult());                  MidiInputDriver mid = new MidiInputDriver(rs.getMultiLineResult());
1969                  mid.setName(driverName);                  mid.setName(driverName);
1970                                    
1971                  for(String s : mid.getParameterNames())                  for(String s : mid.getParameterNames())
1972                          mid.addParameter(getMidiInputDriverParameterInfo(driverName, s));                          mid.addParameter(getMidiInputDriverParameterInfo(driverName, s, depList));
1973                                    
1974                  return mid;                  return mid;
1975          }          }
# Line 1127  public class Client { Line 1983  public class Client {
1983           * <code>param</code> depends on. <code>Parameter</code> instances can be           * <code>param</code> depends on. <code>Parameter</code> instances can be
1984           * easily created using {@link ParameterFactory} factory.           * easily created using {@link ParameterFactory} factory.
1985           *           *
1986           * @return An <code>Parameter</code> object containing           * @return A <code>Parameter</code> object containing
1987           * information about the specified MIDI input driver parameter.           * information about the specified MIDI input driver parameter.
1988           *           *
1989           * @throws IOException If an I/O error occurs.           * @throws IOException If an I/O error occurs.
# Line 1147  public class Client { Line 2003  public class Client {
2003                  StringBuffer args = new StringBuffer(driver);                  StringBuffer args = new StringBuffer(driver);
2004                  args.append(' ').append(param);                  args.append(' ').append(param);
2005                                    
2006                  for(Parameter p : deplist)                  for(Parameter p : deplist) {
2007                            if(p.getValue() == null) continue;
2008                          args.append(' ').append(p.getName()).append('=').append(p.getStringValue());                          args.append(' ').append(p.getName()).append('=').append(p.getStringValue());
2009                    }
2010                                    
2011                  out.writeLine("GET MIDI_INPUT_DRIVER_PARAMETER INFO " + args.toString());                  out.writeLine("GET MIDI_INPUT_DRIVER_PARAMETER INFO " + args.toString());
2012                    if(getPrintOnlyMode()) return null;
2013                                    
2014                  ResultSet rs = getMultiLineResultSet();                  ResultSet rs = getMultiLineResultSet();
2015                                    
# Line 1164  public class Client { Line 2023  public class Client {
2023                          if(!multi) prm = new BoolParameter(lnS);                          if(!multi) prm = new BoolParameter(lnS);
2024                          else prm = new BoolListParameter(lnS);                          else prm = new BoolListParameter(lnS);
2025                          prm.setName(param);                          prm.setName(param);
2026                            prm.setValue(prm.getDefault());
2027                          return prm;                          return prm;
2028                  case INT:                  case INT:
2029                          if(!multi) prm = new IntParameter(lnS);                          if(!multi) prm = new IntParameter(lnS);
2030                          else prm = new IntListParameter(lnS);                          else prm = new IntListParameter(lnS);
2031                          prm.setName(param);                          prm.setName(param);
2032                            prm.setValue(prm.getDefault());
2033                          return prm;                          return prm;
2034                  case FLOAT:                  case FLOAT:
2035                          if(!multi) prm = new FloatParameter(lnS);                          if(!multi) prm = new FloatParameter(lnS);
2036                          else prm = new FloatListParameter(lnS);                          else prm = new FloatListParameter(lnS);
2037                          prm.setName(param);                          prm.setName(param);
2038                            prm.setValue(prm.getDefault());
2039                          return prm;                          return prm;
2040                  case STRING:                  case STRING:
2041                          if(!multi) prm = new StringParameter(lnS);                          if(!multi) prm = new StringParameter(lnS);
2042                          else prm = new StringListParameter(lnS);                          else prm = new StringListParameter(lnS);
2043                          prm.setName(param);                          prm.setName(param);
2044                            prm.setValue(prm.getDefault());
2045                          return prm;                          return prm;
2046                  default: throw new LscpException(LscpI18n.getLogMsg("Client.unknownPrmType!"));                  default: throw new LscpException(LscpI18n.getLogMsg("Client.unknownPrmType!"));
2047                  }                  }
# Line 1205  public class Client { Line 2068  public class Client {
2068                  verifyConnection();                  verifyConnection();
2069                  StringBuffer args = new StringBuffer(miDriver);                  StringBuffer args = new StringBuffer(miDriver);
2070                                    
2071                  for(Parameter p : paramList)                  for(Parameter p : paramList) {
2072                            if(p.getValue() == null) continue;
2073                          args.append(' ').append(p.getName()).append('=').append(p.getStringValue());                          args.append(' ').append(p.getName()).append('=').append(p.getStringValue());
2074                    }
2075                                    
2076                  out.writeLine("CREATE MIDI_INPUT_DEVICE " + args.toString());                  out.writeLine("CREATE MIDI_INPUT_DEVICE " + args.toString());
2077                    if(getPrintOnlyMode()) return -1;
2078                    
2079                  ResultSet rs = getEmptyResultSet();                  ResultSet rs = getEmptyResultSet();
2080                                    
2081                  return rs.getIndex();                  return rs.getIndex();
# Line 1216  public class Client { Line 2083  public class Client {
2083                    
2084          /**          /**
2085           * Destroys already created MIDI input device.           * Destroys already created MIDI input device.
2086           * @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.
2087           * @throws IOException If some I/O error occurs.           * @throws IOException If some I/O error occurs.
2088           * @throws LSException If the destroying of the MIDI input device failed.           * @throws LSException If the destroying of the MIDI input device failed.
2089           * @throws LscpException If LSCP protocol corruption occurs.           * @throws LscpException If LSCP protocol corruption occurs.
# Line 1224  public class Client { Line 2091  public class Client {
2091           * @see #getMidiInputDevices           * @see #getMidiInputDevices
2092           */           */
2093          public synchronized void          public synchronized void
2094          destroyMidiInputDevice(int deviceID) throws IOException, LSException, LscpException {          destroyMidiInputDevice(int deviceId) throws IOException, LSException, LscpException {
2095                  verifyConnection();                  verifyConnection();
2096                  out.writeLine("DESTROY MIDI_INPUT_DEVICE " + deviceID);                  out.writeLine("DESTROY MIDI_INPUT_DEVICE " + deviceId);
2097                    if(getPrintOnlyMode()) return;
2098                    
2099                  ResultSet rs = getEmptyResultSet();                  ResultSet rs = getEmptyResultSet();
2100          }          }
2101                    
2102            /**
2103             * Enables/disables the specified MIDI input device.
2104             * @param deviceId The ID of the MIDI input device to be enabled/disabled.
2105             * @param enable If <code>true</code> the MIDI input device is enabled,
2106             * else the device is disabled.
2107             * @throws IOException If some I/O error occurs.
2108             * @throws LSException If there is no MIDI input
2109             * device with numerical ID <code>deviceId</code>.
2110             * @throws LscpException If LSCP protocol corruption occurs.
2111             */
2112            public void
2113            enableMidiInputDevice(int deviceId, boolean enable)
2114                                    throws IOException, LSException, LscpException {
2115                    
2116                    setMidiInputDeviceParameter(deviceId, new BoolParameter("ACTIVE", enable));
2117            }
2118            
2119          /**          /**
2120           * Gets the current number of all created MIDI input devices.           * Gets the current number of all created MIDI input devices.
2121           * @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 2127  public class Client {
2127          getMidiInputDeviceCount() throws IOException, LscpException, LSException {          getMidiInputDeviceCount() throws IOException, LscpException, LSException {
2128                  verifyConnection();                  verifyConnection();
2129                  out.writeLine("GET MIDI_INPUT_DEVICES");                  out.writeLine("GET MIDI_INPUT_DEVICES");
2130                    if(getPrintOnlyMode()) return -1;
2131                    
2132                  String s = getSingleLineResultSet().getResult();                  String s = getSingleLineResultSet().getResult();
2133                  return parseInt(s);                  return parseInt(s);
2134          }          }
2135                    
2136          /**          /**
2137             * Gets a list of all created MIDI input devices.
2138             * @return A <code>MidiInputDevice</code> array
2139             * providing all created MIDI input devices.
2140             * @throws IOException If some I/O error occurs.
2141             * @throws LscpException If LSCP protocol corruption occurs.
2142             * @throws LSException If some other error occurs.
2143             *
2144             * @see #createMidiInputDevice
2145             * @see #destroyMidiInputDevice
2146             */
2147            public synchronized MidiInputDevice[]
2148            getMidiInputDevices() throws IOException, LscpException, LSException {
2149                    Integer[] idS = getMidiInputDeviceIDs();
2150                    if(getPrintOnlyMode()) return null;
2151                    
2152                    MidiInputDevice[] devices = new MidiInputDevice[idS.length];
2153                    
2154                    for(int i = 0; i < devices.length; i++)
2155                            devices[i] = getMidiInputDeviceInfo(idS[i]);
2156                    
2157                    return devices;
2158            }
2159            
2160            /**
2161           * Gets a list of numerical IDs of all created MIDI input devices.           * Gets a list of numerical IDs of all created MIDI input devices.
2162           * @return An <code>Integer</code> array with numerical IDs of           * @return An <code>Integer</code> array providing the numerical IDs of
2163           * all created MIDI input devices.           * all created MIDI input devices.
2164           * @throws IOException If some I/O error occurs.           * @throws IOException If some I/O error occurs.
2165           * @throws LscpException If LSCP protocol corruption occurs.           * @throws LscpException If LSCP protocol corruption occurs.
# Line 1257  public class Client { Line 2169  public class Client {
2169           * @see #destroyMidiInputDevice           * @see #destroyMidiInputDevice
2170           */           */
2171          public synchronized Integer[]          public synchronized Integer[]
2172          getMidiInputDevices() throws IOException, LscpException, LSException {          getMidiInputDeviceIDs() throws IOException, LscpException, LSException {
2173                  verifyConnection();                  verifyConnection();
2174                  out.writeLine("LIST MIDI_INPUT_DEVICES");                  out.writeLine("LIST MIDI_INPUT_DEVICES");
2175                    if(getPrintOnlyMode()) return null;
2176                    
2177                  return parseIntList(getSingleLineResultSet().getResult());                  return parseIntList(getSingleLineResultSet().getResult());
2178          }          }
2179                    
2180          /**          /**
2181           * Gets the current settings of a specific, already created MIDI input device.           * Gets the current settings of a specific, already created MIDI input device.
2182           *           *
2183           * @param deviceID Specifies the numerical ID of the MIDI input device.           * @param deviceId Specifies the numerical ID of the MIDI input device.
2184           *           *
2185           * @return An <code>MidiInputDevice</code> instance containing information           * @return A <code>MidiInputDevice</code> instance containing information
2186           * about the specified device.           * about the specified device.
2187           *           *
2188           * @throws IOException If some I/O error occurs.           * @throws IOException If some I/O error occurs.
2189           * @throws LscpException If LSCP protocol corruption occurs.           * @throws LscpException If LSCP protocol corruption occurs.
2190           * @throws LSException If there is no MIDI input device           * @throws LSException If there is no MIDI input device
2191           * with device id <code>deviceID</code>.           * with device id <code>deviceId</code>.
2192           *           *
2193           * @see #getMidiInputDevices           * @see #getMidiInputDevices
2194           */           */
2195          public synchronized MidiInputDevice          public synchronized MidiInputDevice
2196          getMidiInputDeviceInfo(int deviceID) throws IOException, LscpException, LSException {          getMidiInputDeviceInfo(int deviceId) throws IOException, LscpException, LSException {
2197                  verifyConnection();                  verifyConnection();
2198                  out.writeLine("GET MIDI_INPUT_DEVICE INFO " + deviceID);                  out.writeLine("GET MIDI_INPUT_DEVICE INFO " + deviceId);
2199                    if(getPrintOnlyMode()) return null;
2200                                    
2201                  ResultSet rs = getMultiLineResultSet();                  ResultSet rs = getMultiLineResultSet();
2202                                    
2203                  String[] lnS = rs.getMultiLineResult();                  String[] lnS = rs.getMultiLineResult();
2204                                    
2205                  MidiInputDevice mid = new MidiInputDevice();                  MidiInputDevice mid = new MidiInputDevice();
2206                    mid.setDeviceId(deviceId);
2207                                    
2208                  String drv = getCategoryInfo(lnS, "DRIVER");                  String drv = getCategoryInfo(lnS, "DRIVER");
2209                  mid.setDriverName(drv);                  mid.setDriverName(drv);
# Line 1298  public class Client { Line 2214  public class Client {
2214                          } else if(s.startsWith("ACTIVE: ")) {                          } else if(s.startsWith("ACTIVE: ")) {
2215                                  s = s.substring("ACTIVE: ".length());                                  s = s.substring("ACTIVE: ".length());
2216                                  mid.setActive(Boolean.parseBoolean(s));                                  mid.setActive(Boolean.parseBoolean(s));
2217                            } else if(s.startsWith("PORTS: ")) {
2218                                    s = s.substring("PORTS: ".length());
2219                                    int ports = Parser.parseInt(s);
2220                                    MidiPort[] midiPorts = new MidiPort[ports > 0 ? ports : 0];
2221                                    
2222                                    for(int i = 0; i < midiPorts.length; i++)
2223                                            midiPorts[i] = getMidiInputPortInfo(deviceId, i);
2224                                    
2225                                    mid.setMidiPorts(midiPorts);
2226                          } else {                          } else {
2227                                  int i = s.indexOf(": ");                                  int i = s.indexOf(": ");
2228                                  if(i == -1) throw new LscpException (                                  if(i == -1) throw new LscpException (
# Line 1320  public class Client { Line 2245  public class Client {
2245          /**          /**
2246           * Alters a specific setting of a created MIDI input device.           * Alters a specific setting of a created MIDI input device.
2247           *           *
2248           * @param deviceID The numerical ID of the MIDI input device.           * @param deviceId The numerical ID of the MIDI input device.
2249           * @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
2250           * and the new value for this parameter.           * and the new value for this parameter.
2251           *           *
# Line 1328  public class Client { Line 2253  public class Client {
2253           * @throws LscpException If LSCP protocol corruption occurs.           * @throws LscpException If LSCP protocol corruption occurs.
2254           * @throws LSException If           * @throws LSException If
2255           * <ul>           * <ul>
2256           * <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>;
2257           * <li>There is no device parameter with the specified name;           * <li>There is no device parameter with the specified name;
2258           * <li>The device parameter is readonly;           * <li>The device parameter is readonly;
2259           * <li>The device parameter is from different type.           * <li>The device parameter is from different type.
# Line 1338  public class Client { Line 2263  public class Client {
2263           * @see #getMidiInputDeviceInfo           * @see #getMidiInputDeviceInfo
2264           */           */
2265          public synchronized void          public synchronized void
2266          setMidiInputDeviceParameter(int deviceID, Parameter prm)          setMidiInputDeviceParameter(int deviceId, Parameter prm)
2267                                                  throws IOException, LscpException, LSException {                                                  throws IOException, LscpException, LSException {
2268                                    
2269                  verifyConnection();                  verifyConnection();
2270                  String kv = prm.getName() + '=' + prm.getStringValue();                  String kv = prm.getName() + '=' + prm.getStringValue();
2271                  out.writeLine("SET MIDI_INPUT_DEVICE_PARAMETER " + deviceID + ' ' + kv);                  out.writeLine("SET MIDI_INPUT_DEVICE_PARAMETER " + deviceId + ' ' + kv);
2272                    if(getPrintOnlyMode()) return;
2273                                    
2274                  ResultSet rs = getEmptyResultSet();                  ResultSet rs = getEmptyResultSet();
2275          }          }
2276                    
2277            
2278            /**
2279             * Changes the port number of the speicified MIDI input device.
2280             * @param deviceId The numerical ID of the MIDI input device.
2281             * @param ports The new number of MIDI input ports.
2282             *
2283             * @throws IOException If an I/O error occurs.
2284             * @throws LscpException If LSCP protocol corruption occurs.
2285             * @throws LSException If there is no device with ID <code>deviceId</code> or
2286             * if <code>ports</code> number is out of range.
2287             *
2288             * @see #getMidiInputPortInfo
2289             */
2290            public synchronized void
2291            setMidiInputPortCount(int deviceId, int ports)
2292                                            throws IOException, LscpException, LSException {
2293                    
2294                    setMidiInputDeviceParameter(deviceId, new IntParameter("PORTS", ports));
2295            }
2296            
2297          /**          /**
2298           * Gets detailed information about a specific MIDI input port.           * Gets detailed information about a specific MIDI input port.
2299           * @param deviceID The numerical ID of the MIDI input device.           * @param deviceId The numerical ID of the MIDI input device.
2300           * @param midiPort The MIDI input port number.           * @param midiPort The MIDI input port number.
2301           *           *
2302           * @return A <code>MidiPort</code> instance containing           * @return A <code>MidiPort</code> instance containing
# Line 1358  public class Client { Line 2304  public class Client {
2304           *           *
2305           * @throws IOException If an I/O error occurs.           * @throws IOException If an I/O error occurs.
2306           * @throws LscpException If LSCP protocol corruption occurs.           * @throws LscpException If LSCP protocol corruption occurs.
2307           * @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
2308           * if <code>midiPort</code> is not a valid MIDI port number.           * if <code>midiPort</code> is not a valid MIDI port number.
2309           *           *
2310           * @see #getMidiInputDevices           * @see #getMidiInputDevices
2311           */           */
2312          public synchronized MidiPort          public synchronized MidiPort
2313          getMidiInputPortInfo(int deviceID, int midiPort)          getMidiInputPortInfo(int deviceId, int midiPort)
2314                                          throws IOException, LscpException, LSException {                                          throws IOException, LscpException, LSException {
2315                                    
2316                  verifyConnection();                  verifyConnection();
2317                  out.writeLine("GET MIDI_INPUT_PORT INFO " + deviceID + " " + midiPort);                  out.writeLine("GET MIDI_INPUT_PORT INFO " + deviceId + " " + midiPort);
2318                    if(getPrintOnlyMode()) return null;
2319                    
2320                  ResultSet rs = getMultiLineResultSet();                  ResultSet rs = getMultiLineResultSet();
2321                                    
2322                  MidiPort mp = new MidiPort();                  MidiPort mp = new MidiPort();
# Line 1376  public class Client { Line 2324  public class Client {
2324                                    
2325                  for(String s : lnS) {                  for(String s : lnS) {
2326                          if(s.startsWith("NAME: ")) {                          if(s.startsWith("NAME: ")) {
2327                                  mp.setName(s.substring("NAME: ".length()));                                  s = s.substring("NAME: ".length());
2328                                    Parameter prm = getMidiInputPortParameterInfo (
2329                                            deviceId, midiPort, "NAME"
2330                                    );
2331                                    prm.setValue(removeQuotation(s));
2332                                    mp.setNameParameter(prm);
2333                          } else {                          } else {
2334                                  int i = s.indexOf(": ");                                  int i = s.indexOf(": ");
2335                                  if(i == -1) throw new LscpException (                                  if(i == -1) throw new LscpException (
# Line 1384  public class Client { Line 2337  public class Client {
2337                                  );                                  );
2338                                                                    
2339                                  Parameter prm = getMidiInputPortParameterInfo (                                  Parameter prm = getMidiInputPortParameterInfo (
2340                                          deviceID, midiPort, s.substring(0, i)                                          deviceId, midiPort, s.substring(0, i)
2341                                  );                                  );
2342                                                                    
2343                                  s = s.substring(i + 2);                                  s = s.substring(i + 2);
# Line 1400  public class Client { Line 2353  public class Client {
2353          /**          /**
2354           * Gets detailed information about a specific MIDI input port parameter.           * Gets detailed information about a specific MIDI input port parameter.
2355           *           *
2356           * @param deviceID The numerical ID of the MIDI input device.           * @param deviceId The numerical ID of the MIDI input device.
2357           * @param port The MIDI port number.           * @param port The MIDI port number.
2358           * @param param A specific parameter name for which information should be obtained.           * @param param A specific parameter name for which information should be obtained.
2359           *           *
# Line 1411  public class Client { Line 2364  public class Client {
2364           * @throws LscpException If LSCP protocol corruption occurs.           * @throws LscpException If LSCP protocol corruption occurs.
2365           * @throws LSException If           * @throws LSException If
2366           * <ul>           * <ul>
2367           * <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>;
2368           * <li> <code>port</code> is not a valid MIDI port number;           * <li> <code>port</code> is not a valid MIDI port number;
2369           * <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.
2370           * </ul>           * </ul>
# Line 1420  public class Client { Line 2373  public class Client {
2373           * @see #getMidiInputPortInfo           * @see #getMidiInputPortInfo
2374           */           */
2375          public synchronized Parameter          public synchronized Parameter
2376          getMidiInputPortParameterInfo(int deviceID, int port, String param)          getMidiInputPortParameterInfo(int deviceId, int port, String param)
2377                                                  throws IOException, LscpException, LSException {                                                  throws IOException, LscpException, LSException {
2378                                    
2379                  verifyConnection();                  verifyConnection();
2380                  String args = deviceID + " " + port + " " + param;                  String args = deviceId + " " + port + " " + param;
2381                  out.writeLine("GET MIDI_INPUT_PORT_PARAMETER INFO " + args);                  out.writeLine("GET MIDI_INPUT_PORT_PARAMETER INFO " + args);
2382                    if(getPrintOnlyMode()) return null;
2383                                    
2384                  ResultSet rs = getMultiLineResultSet();                  ResultSet rs = getMultiLineResultSet();
2385                                    
# Line 1462  public class Client { Line 2416  public class Client {
2416          /**          /**
2417           * Alters a specific setting of a MIDI input port.           * Alters a specific setting of a MIDI input port.
2418           *           *
2419           * @param deviceID The numerical ID of the MIDI device.           * @param deviceId The numerical ID of the MIDI device.
2420           * @param port The MIDI port number.           * @param port The MIDI port number.
2421           * @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
2422           * and the new value for this parameter.           * and the new value for this parameter.
# Line 1471  public class Client { Line 2425  public class Client {
2425           * @throws LscpException If LSCP protocol corruption occurs.           * @throws LscpException If LSCP protocol corruption occurs.
2426           * @throws LSException If           * @throws LSException If
2427           * <ul>           * <ul>
2428           * <li>There is no MIDI device with numerical ID <code>deviceID</code>;           * <li>There is no MIDI device with numerical ID <code>deviceId</code>;
2429           * <li><code>port</code> is not a valid MIDI port number;           * <li><code>port</code> is not a valid MIDI port number;
2430           * <li><code>prm</code> is not a valid parameter;           * <li><code>prm</code> is not a valid parameter;
2431           * <li>The parameter is readonly;           * <li>The parameter is readonly;
# Line 1482  public class Client { Line 2436  public class Client {
2436           * @see #getMidiInputPortInfo           * @see #getMidiInputPortInfo
2437           */           */
2438          public synchronized void          public synchronized void
2439          setMidiInputPortParameter(int deviceID, int port,  Parameter prm)          setMidiInputPortParameter(int deviceId, int port,  Parameter prm)
2440                                                  throws IOException, LscpException, LSException {                                                  throws IOException, LscpException, LSException {
2441                                    
2442                  verifyConnection();                  verifyConnection();
2443                  String args = deviceID + ' ' + port + ' ' +                  String args = deviceId + " " + port + " " +
2444                          prm.getName() + '=' + prm.getStringValue();                          prm.getName() + '=' + prm.getStringValue();
2445                  out.writeLine("SET MIDI_INPUT_PORT_PARAMETER " + args);                  out.writeLine("SET MIDI_INPUT_PORT_PARAMETER " + args);
2446                    if(getPrintOnlyMode()) return;
2447                    
2448                    ResultSet rs = getEmptyResultSet();
2449            }
2450            
2451            /**
2452             * Adds a new MIDI instrument map.
2453             * @param name The name of this MIDI instrument map.
2454             * @return The number of the newly MIDI instrument map.
2455             * @throws IOException If some I/O error occurs.
2456             * @throws LSException If the creation of the new MIDI instrument map failed.
2457             * @throws LscpException If LSCP protocol corruption occurs.
2458             * @see #removeMidiInstrumentMap
2459             */
2460            public synchronized int
2461            addMidiInstrumentMap(String name) throws IOException, LSException, LscpException {
2462                    verifyConnection();
2463                    out.writeLine("ADD MIDI_INSTRUMENT_MAP '" + name + "'");
2464                    if(getPrintOnlyMode()) return -1;
2465                    
2466                    ResultSet rs = getEmptyResultSet();
2467                    
2468                    return rs.getIndex();
2469            }
2470            
2471            /**
2472             * Removes the specified MIDI instrument map.
2473             * @param mapId The numerical ID of the MIDI instrument map to be removed.
2474             * @throws IOException If some I/O error occurs.
2475             * @throws LscpException If LSCP protocol corruption occurs.
2476             * @throws LSException If the removing of the MIDI instrument map failed.
2477             * @see #addMidiInstrumentMap
2478             * @see #getMidiInstrumentMapIDs
2479             */
2480            public synchronized void
2481            removeMidiInstrumentMap(int mapId) throws IOException, LscpException, LSException {
2482                    verifyConnection();
2483                    out.writeLine("REMOVE MIDI_INSTRUMENT_MAP " + mapId);
2484                    if(getPrintOnlyMode()) return;
2485                    
2486                    ResultSet rs = getEmptyResultSet();
2487            }
2488            
2489            /**
2490             * Removes the all MIDI instrument maps.
2491             * @throws IOException If some I/O error occurs.
2492             * @throws LscpException If LSCP protocol corruption occurs.
2493             * @throws LSException If the removing of the MIDI instrument maps failed.
2494             */
2495            public synchronized void
2496            removeAllMidiInstrumentMaps() throws IOException, LscpException, LSException {
2497                    verifyConnection();
2498                    out.writeLine("REMOVE MIDI_INSTRUMENT_MAP ALL");
2499                    if(getPrintOnlyMode()) return;
2500                                    
2501                  ResultSet rs = getEmptyResultSet();                  ResultSet rs = getEmptyResultSet();
2502          }          }
2503                    
2504          /**          /**
2505             * Gets the current number of all MIDI instrument maps.
2506             * @return The current number of all MIDI instrument maps.
2507             * @throws IOException If some I/O error occurs.
2508             * @throws LscpException If LSCP protocol corruption occurs.
2509             * @throws LSException If some other error occurs.
2510             */
2511            public synchronized int
2512            getMidiInstrumentMapCount() throws IOException, LscpException, LSException {
2513                    verifyConnection();
2514                    out.writeLine("GET MIDI_INSTRUMENT_MAPS");
2515                    if(getPrintOnlyMode()) return -1;
2516                    
2517                    String s = getSingleLineResultSet().getResult();
2518                    return parseInt(s);
2519            }
2520            
2521            /**
2522             * Gets a list of numerical IDs of all created MIDI instrument maps.
2523             * @return An <code>Integer</code> array providing the numerical IDs of
2524             * all created MIDI instrument maps.
2525             * @throws IOException If some I/O error occurs.
2526             * @throws LscpException If LSCP protocol corruption occurs.
2527             * @throws LSException If some other error occurs.
2528             * @see #addMidiInstrumentMap
2529             * @see #removeMidiInstrumentMap
2530             */
2531            public synchronized Integer[]
2532            getMidiInstrumentMapIDs() throws IOException, LscpException, LSException {
2533                    verifyConnection();
2534                    out.writeLine("LIST MIDI_INSTRUMENT_MAPS");
2535                    if(getPrintOnlyMode()) return null;
2536                    
2537                    return parseIntList(getSingleLineResultSet().getResult());
2538            }
2539            
2540            /**
2541             * Gets the current settings of a specific, already created MIDI instrument map.
2542             * @param mapId Specifies the numerical ID of the MIDI instrument map.
2543             * @return A <code>MidiInstrumentMapInfo</code> instance containing information
2544             * about the specified device.
2545             * @throws IOException If some I/O error occurs.
2546             * @throws LscpException If LSCP protocol corruption occurs.
2547             * @throws LSException If there is no MIDI instrument map
2548             * with map id <code>mapId</code>.
2549             * @see #getMidiInstrumentMaps
2550             */
2551            public synchronized MidiInstrumentMapInfo
2552            getMidiInstrumentMapInfo(int mapId) throws IOException, LscpException, LSException {
2553                    verifyConnection();
2554                    out.writeLine("GET MIDI_INSTRUMENT_MAP INFO " + mapId);
2555                    if(getPrintOnlyMode()) return null;
2556                    
2557                    ResultSet rs = getMultiLineResultSet();
2558                    
2559                    String[] lnS = rs.getMultiLineResult();
2560                    
2561                    String name = "";
2562                    boolean b = false;
2563                    
2564                    for(String s : lnS) {
2565                            if(s.startsWith("NAME: ")) {
2566                                    name = s.substring("NAME: ".length());
2567                            } else if(s.startsWith("DEFAULT: ")) {
2568                                    b = Boolean.parseBoolean(s.substring("DEFAULT: ".length()));
2569                            } else {
2570                                     getLogger().info(LscpI18n.getLogMsg("unknownLine", s));
2571                            }
2572                    }
2573                    
2574                    return new MidiInstrumentMapInfo(mapId, name, b);
2575            }
2576            
2577            /**
2578             * Gets an information of all created MIDI instrument maps.
2579             * @return A <code>MidiInstrumentMap</code> array
2580             * providing information for all created MIDI instrument maps.
2581             * @throws IOException If some I/O error occurs.
2582             * @throws LscpException If LSCP protocol corruption occurs.
2583             * @throws LSException If some other error occurs.
2584             * @see #addMidiInstrumentMap
2585             * @see #removeMidiInstrumentMap
2586             */
2587            public synchronized MidiInstrumentMapInfo[]
2588            getMidiInstrumentMaps() throws IOException, LscpException, LSException {
2589                    Integer[] idS = getMidiInstrumentMapIDs();
2590                    if(getPrintOnlyMode()) return null;
2591                    
2592                    MidiInstrumentMapInfo[] maps = new MidiInstrumentMapInfo[idS.length];
2593                    
2594                    for(int i = 0; i < maps.length; i++)
2595                            maps[i] = getMidiInstrumentMapInfo(idS[i]);
2596                    
2597                    return maps;
2598            }
2599            
2600            /**
2601             * Sets the name of the specified MIDI instrument map.
2602             * @param mapId The numerical ID of the MIDI instrument map.
2603             * @param name The new name for the specified MIDI instrument map.
2604             * @throws IOException If some I/O error occurs.
2605             * @throws LscpException If LSCP protocol corruption occurs.
2606             * @throws LSException If <code>mapId</code> is not a valid MIDI
2607             * instrument map number or <code>name</code> is not a valid name;
2608             */
2609            public synchronized void
2610            setMidiInstrumentMapName(int mapId, String name)
2611                                    throws IOException, LscpException, LSException {
2612                    
2613                    verifyConnection();
2614                    out.writeLine("SET MIDI_INSTRUMENT_MAP NAME " +  + mapId + " '" + name + "'");
2615                    if(getPrintOnlyMode()) return;
2616                    
2617                    ResultSet rs = getEmptyResultSet();
2618            }
2619            
2620            
2621            
2622            /**
2623             * Creates or replaces a MIDI instrument map entry.
2624             * @param mapId The ID of the map, where this instrument should be mapped.
2625             * @param entry Specifies the position of the MIDI instrument in the MIDI instrument map.
2626             * @param info Provides the needed information of the
2627             * MIDI instrument, which will be mapped to the specified MIDI instrument map.
2628             * @throws IOException If some I/O error occurs.
2629             * @throws LSException If the mapping failed.
2630             * @throws LscpException If LSCP protocol corruption occurs.
2631             * @see #unmapMidiInstrument
2632             */
2633            public synchronized void
2634            mapMidiInstrument(int mapId, MidiInstrumentEntry entry, MidiInstrumentInfo info)
2635                                            throws IOException, LSException, LscpException {
2636                    mapMidiInstrument(mapId, entry, info, false);
2637            }
2638            
2639            /**
2640             * Creates or replaces a MIDI instrument map entry.
2641             * @param mapId The ID of the map, where this instrument should be mapped.
2642             * @param entry Specifies the position of the MIDI instrument in the MIDI instrument map.
2643             * @param info Provides the needed information of the
2644             * MIDI instrument, which will be mapped to the specified MIDI instrument map.
2645             * @param nonModal If <code>true</code> the function returns immediately
2646             * and the mapping is established in the background.
2647             * @throws IOException If some I/O error occurs.
2648             * @throws LSException If the mapping failed.
2649             * @throws LscpException If LSCP protocol corruption occurs.
2650             * @see #unmapMidiInstrument
2651             */
2652            public synchronized void
2653            mapMidiInstrument(int mapId, MidiInstrumentEntry entry, MidiInstrumentInfo info, boolean nonModal)
2654                                            throws IOException, LSException, LscpException {
2655                    
2656                    verifyConnection();
2657                    StringBuffer cmd = new StringBuffer("MAP MIDI_INSTRUMENT ");
2658                    if(nonModal) cmd.append("NON_MODAL ");
2659                    cmd.append(mapId).append(' ');
2660                    cmd.append(entry.getMidiBank()).append(' ');
2661                    cmd.append(entry.getMidiProgram()).append(' ');
2662                    cmd.append(info.getEngine()).append(" '");
2663                    cmd.append(info.getFilePath()).append("' ");
2664                    cmd.append(info.getInstrumentIndex()).append(' ');
2665                    cmd.append(info.getVolume());
2666                    if(!info.getLoadMode().name().equals("DEFAULT")) {
2667                            cmd.append(' ').append(info.getLoadMode().name());
2668                    }
2669                    if(info.getName() != null) cmd.append(" '").append(info.getName()).append("'");
2670                    
2671                    out.writeLine(cmd.toString());
2672                    if(getPrintOnlyMode()) return;
2673                    
2674                    ResultSet rs = getEmptyResultSet();
2675            }
2676            
2677            /**
2678             * Removes an entry MIDI instrument map.
2679             * @param mapId The ID of the map, from which
2680             * the specified MIDI instrument should be removed.
2681             * @param entry The entry to remove from the specified MIDI instrument map.
2682             * @throws IOException If some I/O error occurs.
2683             * @throws LSException If the unmapping failed.
2684             * @throws LscpException If LSCP protocol corruption occurs.
2685             * @see #mapMidiInstrument
2686             */
2687            public synchronized void
2688            unmapMidiInstrument(int mapId, MidiInstrumentEntry entry)
2689                                            throws IOException, LSException, LscpException {
2690                    
2691                    verifyConnection();
2692                    StringBuffer cmd = new StringBuffer("UNMAP MIDI_INSTRUMENT ");
2693                    cmd.append(mapId).append(' ');
2694                    cmd.append(entry.getMidiBank()).append(' ');
2695                    cmd.append(entry.getMidiProgram());
2696                    
2697                    out.writeLine(cmd.toString());
2698                    if(getPrintOnlyMode()) return;
2699                    
2700                    ResultSet rs = getEmptyResultSet();
2701            }
2702            
2703            /**
2704             * Gets the current number of all MIDI instrument in all maps.
2705             * @return The current number of all MIDI instrument in all maps.
2706             * @throws IOException If some I/O error occurs.
2707             * @throws LscpException If LSCP protocol corruption occurs.
2708             * @throws LSException If some other error occurs.
2709             */
2710            public synchronized int
2711            getMidiInstrumentCount() throws IOException, LscpException, LSException {
2712                    verifyConnection();
2713                    out.writeLine("GET MIDI_INSTRUMENTS ALL");
2714                    if(getPrintOnlyMode()) return -1;
2715                    
2716                    String s = getSingleLineResultSet().getResult();
2717                    return parseInt(s);
2718            }
2719            
2720            /**
2721             * Gets the current number of MIDI instrument in the specified map.
2722             * @param mapId The ID of the map.
2723             * @return The current number of MIDI instrument in the specified map.
2724             * @throws IOException If some I/O error occurs.
2725             * @throws LscpException If LSCP protocol corruption occurs.
2726             * @throws LSException If some other error occurs.
2727             */
2728            public synchronized int
2729            getMidiInstrumentCount(int mapId) throws IOException, LscpException, LSException {
2730                    verifyConnection();
2731                    out.writeLine("GET MIDI_INSTRUMENTS " + String.valueOf(mapId));
2732                    if(getPrintOnlyMode()) return -1;
2733                    
2734                    String s = getSingleLineResultSet().getResult();
2735                    return parseInt(s);
2736            }
2737            
2738            /**
2739             * Gets all MIDI instrument from all maps.
2740             * @return A <code>MidiInstrumentInfo</code> array providing
2741             * all MIDI instruments from all MIDI instrument maps.
2742             * @throws IOException If some I/O error occurs.
2743             * @throws LscpException If LSCP protocol corruption occurs.
2744             * @throws LSException If some other error occurs.
2745             */
2746            public synchronized MidiInstrumentInfo[]
2747            getMidiInstruments() throws IOException, LscpException, LSException {
2748                    verifyConnection();
2749                    out.writeLine("LIST MIDI_INSTRUMENTS ALL");
2750                    if(getPrintOnlyMode()) return null;
2751                    
2752                    String[] entries = parseArray(getSingleLineResultSet().getResult());
2753                    
2754                    return getMidiInstruments(entries);
2755            }
2756            
2757            /**
2758             * Gets all MIDI instrument contained int the specified MIDI instrument map.
2759             * @param mapId The ID of the map, which instruments should be obtained.
2760             * @return A <code>MidiInstrumentInfo</code> array providing
2761             * all MIDI instruments from all MIDI instrument maps.
2762             * @throws IOException If some I/O error occurs.
2763             * @throws LscpException If LSCP protocol corruption occurs.
2764             * @throws LSException If some other error occurs.
2765             */
2766            public synchronized MidiInstrumentInfo[]
2767            getMidiInstruments(int mapId) throws IOException, LscpException, LSException {
2768                    verifyConnection();
2769                    out.writeLine("LIST MIDI_INSTRUMENTS " + String.valueOf(mapId));
2770                    if(getPrintOnlyMode()) return null;
2771                    
2772                    String[] entries = parseArray(getSingleLineResultSet().getResult());
2773                    
2774                    return getMidiInstruments(entries);
2775            }
2776            
2777            private MidiInstrumentInfo[]
2778            getMidiInstruments(String[] entries) throws IOException, LscpException, LSException {
2779                    Vector<MidiInstrumentInfo> v = new Vector<MidiInstrumentInfo>();
2780                    
2781                    for(String s : entries) {
2782                            Integer[] vals = parseIntList(s);
2783                            if(vals.length != 3) {
2784                                    throw new LscpException(LscpI18n.getLogMsg("CommandFailed!"));
2785                            }
2786                            
2787                            v.add(getMidiInstrumentInfo(vals[0], vals[1], vals[2]));
2788                    }
2789                    
2790                    return v.toArray(new MidiInstrumentInfo[v.size()]);
2791            }
2792            
2793            /**
2794             * Gets the current settings of the specified MIDI instrument.
2795             * @param mapId The ID of the map.
2796             * @param bank The index of the MIDI bank.
2797             * @param program The MIDI program number of the instrument.
2798             * @return <code>MidiInstrumentInfo</code> instance containing
2799             * the current settings of the specified MIDI instrument.
2800             * @throws IOException If an I/O error occurs.
2801             * @throws LscpException If LSCP protocol corruption occurs.
2802             * @throws LSException If the specified MIDI instrument is missing.
2803             */
2804            public synchronized MidiInstrumentInfo
2805            getMidiInstrumentInfo(int mapId, int bank, int program)
2806                                            throws IOException, LscpException, LSException {
2807            
2808                    verifyConnection();
2809                    StringBuffer cmd = new StringBuffer("GET MIDI_INSTRUMENT INFO ");
2810                    cmd.append(mapId).append(' ');
2811                    cmd.append(bank).append(' ');
2812                    cmd.append(program);
2813                    
2814                    out.writeLine(cmd.toString());
2815                    if(getPrintOnlyMode()) return null;
2816                    
2817                    ResultSet rs = getMultiLineResultSet();
2818                    MidiInstrumentEntry entry = new MidiInstrumentEntry(bank, program);
2819                    return new MidiInstrumentInfo(mapId, entry, rs.getMultiLineResult());
2820            }
2821            
2822            /**
2823           * 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
2824           * 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.
          *    
2825           * @param filename The name of the instrument file           * @param filename The name of the instrument file
2826           * on the LinuxSampler instance's host system.           * on the LinuxSampler instance's host system.
2827           * @param instrIdx The index of the instrument in the instrument file.           * @param instrIdx The index of the instrument in the instrument file.
2828           * @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.
          *  
2829           * @throws IOException If some I/O error occurs.           * @throws IOException If some I/O error occurs.
2830           * @throws LscpException If LSCP protocol corruption occurs.           * @throws LscpException If LSCP protocol corruption occurs.
2831           * @throws LSException If the loading of the instrument failed.           * @throws LSException If the loading of the instrument failed.
          *  
2832           * @see #loadInstrument(String, int, int, boolean)           * @see #loadInstrument(String, int, int, boolean)
2833           * @see #getSamplerChannels           * @see #getSamplerChannels
2834           */           */
# Line 1543  public class Client { Line 2866  public class Client {
2866                  String args = '\'' + filename + "' " + instrIdx + ' ' + samplerChn;                  String args = '\'' + filename + "' " + instrIdx + ' ' + samplerChn;
2867                                    
2868                  out.writeLine(cmd + args);                  out.writeLine(cmd + args);
2869                    if(getPrintOnlyMode()) return;
2870                                    
2871                  ResultSet rs = getEmptyResultSet();                  ResultSet rs = getEmptyResultSet();
2872          }          }
# Line 1565  public class Client { Line 2889  public class Client {
2889                                    
2890                  verifyConnection();                  verifyConnection();
2891                  out.writeLine("LOAD ENGINE " + engineName + ' ' + samplerChn);                  out.writeLine("LOAD ENGINE " + engineName + ' ' + samplerChn);
2892                    if(getPrintOnlyMode()) return;
2893                                    
2894                  ResultSet rs = getEmptyResultSet();                  ResultSet rs = getEmptyResultSet();
2895          }          }
# Line 1580  public class Client { Line 2905  public class Client {
2905          getSamplerChannelCount() throws IOException, LscpException, LSException {          getSamplerChannelCount() throws IOException, LscpException, LSException {
2906                  verifyConnection();                  verifyConnection();
2907                  out.writeLine("GET CHANNELS");                  out.writeLine("GET CHANNELS");
2908                    if(getPrintOnlyMode()) return -1;
2909                    
2910                  String s = getSingleLineResultSet().getResult();                  String s = getSingleLineResultSet().getResult();
2911                  return parseInt(s);                  return parseInt(s);
2912          }          }
2913                    
2914          /**          /**
2915             * Gets a list of all created sampler channels.
2916             * @return A <code>SamplerChannel</code> array providing all created sampler channels.
2917             * @throws IOException If some I/O error occurs.
2918             * @throws LscpException If LSCP protocol corruption occurs.
2919             * @throws LSException If some other error occurs.
2920             * @see #addSamplerChannel
2921             * @see #removeSamplerChannel
2922             */
2923            public synchronized SamplerChannel[]
2924            getSamplerChannels() throws IOException, LscpException, LSException {
2925                    Integer[] idS = getSamplerChannelIDs();
2926                    if(getPrintOnlyMode()) return null;
2927                    
2928                    SamplerChannel[] channels = new SamplerChannel[idS.length];
2929                    
2930                    for(int i = 0; i < channels.length; i++)
2931                            channels[i] = getSamplerChannelInfo(idS[i]);
2932                    
2933                    return channels;
2934            }
2935            
2936            /**
2937           * Gets a list with numerical IDs of all created sampler channels.           * Gets a list with numerical IDs of all created sampler channels.
2938           * @return An <code>Integer</code> array with numerical IDs of all created sampler channels.           * @return An <code>Integer</code> array providing
2939             * the numerical IDs of all created sampler channels.
2940           * @throws IOException If some I/O error occurs.           * @throws IOException If some I/O error occurs.
2941           * @throws LscpException If LSCP protocol corruption occurs.           * @throws LscpException If LSCP protocol corruption occurs.
2942           * @throws LSException If some other error occurs.           * @throws LSException If some other error occurs.
# Line 1594  public class Client { Line 2944  public class Client {
2944           * @see #removeSamplerChannel           * @see #removeSamplerChannel
2945           */           */
2946          public synchronized Integer[]          public synchronized Integer[]
2947          getSamplerChannels() throws IOException, LscpException, LSException {          getSamplerChannelIDs() throws IOException, LscpException, LSException {
2948                  verifyConnection();                  verifyConnection();
2949                  out.writeLine("LIST CHANNELS");                  out.writeLine("LIST CHANNELS");
2950                    if(getPrintOnlyMode()) return null;
2951                    
2952                  return parseIntList(getSingleLineResultSet().getResult());                  return parseIntList(getSingleLineResultSet().getResult());
2953          }          }
2954                    
# Line 1614  public class Client { Line 2966  public class Client {
2966          addSamplerChannel() throws IOException, LSException, LscpException {          addSamplerChannel() throws IOException, LSException, LscpException {
2967                  verifyConnection();                  verifyConnection();
2968                  out.writeLine("ADD CHANNEL");                  out.writeLine("ADD CHANNEL");
2969                    if(getPrintOnlyMode()) return -1;
2970                    
2971                  ResultSet rs = getEmptyResultSet();                  ResultSet rs = getEmptyResultSet();
2972                                    
2973                  return rs.getIndex();                  return rs.getIndex();
# Line 1634  public class Client { Line 2988  public class Client {
2988          removeSamplerChannel(int samplerChn) throws IOException, LscpException, LSException {          removeSamplerChannel(int samplerChn) throws IOException, LscpException, LSException {
2989                  verifyConnection();                  verifyConnection();
2990                  out.writeLine("REMOVE CHANNEL " + samplerChn);                  out.writeLine("REMOVE CHANNEL " + samplerChn);
2991                    if(getPrintOnlyMode()) return;
2992                                    
2993                  ResultSet rs = getEmptyResultSet();                  ResultSet rs = getEmptyResultSet();
2994          }          }
# Line 1649  public class Client { Line 3004  public class Client {
3004          getEngineCount() throws IOException, LscpException, LSException {          getEngineCount() throws IOException, LscpException, LSException {
3005                  verifyConnection();                  verifyConnection();
3006                  out.writeLine("GET AVAILABLE_ENGINES");                  out.writeLine("GET AVAILABLE_ENGINES");
3007                    if(getPrintOnlyMode()) return -1;
3008                    
3009                  String s = getSingleLineResultSet().getResult();                  String s = getSingleLineResultSet().getResult();
3010                  return parseInt(s);                  return parseInt(s);
3011          }          }
3012                    
3013          /**          /**
3014             * Gets a list of all available engines.
3015             *
3016             * @return <code>SamplerEngine</code> array containing all available engines.
3017             * @throws IOException If some I/O error occurs.
3018             * @throws LscpException If LSCP protocol corruption occurs.
3019             * @throws LSException If some other error occurs.
3020             */
3021            public synchronized SamplerEngine[]
3022            getEngines() throws IOException, LscpException, LSException {
3023                    String[] engines = getEngineNames();
3024                    if(getPrintOnlyMode()) return null;
3025                    
3026                    SamplerEngine[] se = new SamplerEngine[engines.length];
3027                    
3028                    for(int i = 0; i < engines.length; i++) se[i] = getEngineInfo(engines[i]);
3029                    
3030                    return se;
3031            }
3032            
3033            /**
3034           * Gets a list of all available engines' names.           * Gets a list of all available engines' names.
3035           *           *
3036           * @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 3038  public class Client {
3038           * @throws LscpException If LSCP protocol corruption occurs.           * @throws LscpException If LSCP protocol corruption occurs.
3039           * @throws LSException If some other error occurs.           * @throws LSException If some other error occurs.
3040           */           */
3041          public synchronized String[]          private synchronized String[]
3042          getEngines() throws IOException, LscpException, LSException {          getEngineNames() throws IOException, LscpException, LSException {
3043                  verifyConnection();                  verifyConnection();
3044                  out.writeLine("LIST AVAILABLE_ENGINES");                  out.writeLine("LIST AVAILABLE_ENGINES");
3045                  return parseStringList(getSingleLineResultSet().getResult());                  if(getPrintOnlyMode()) return null;
3046                    
3047                    return parseQuotedStringList(getSingleLineResultSet().getResult());
3048          }          }
3049                    
3050          /**          /**
# Line 1678  public class Client { Line 3057  public class Client {
3057           * @throws IOException If an I/O error occurs.           * @throws IOException If an I/O error occurs.
3058           * @throws LscpException If LSCP protocol corruption occurs.           * @throws LscpException If LSCP protocol corruption occurs.
3059           * @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>.
3060           * @see #getEngines           * @see #getEngineNames
3061           */           */
3062          public synchronized SamplerEngine          private synchronized SamplerEngine
3063          getEngineInfo(String engineName) throws IOException, LscpException, LSException {          getEngineInfo(String engineName) throws IOException, LscpException, LSException {
3064                  verifyConnection();                  verifyConnection();
3065                  out.writeLine("GET ENGINE INFO " + engineName);                  out.writeLine("GET ENGINE INFO " + engineName);
3066                    if(getPrintOnlyMode()) return null;
3067                    
3068                  ResultSet rs = getMultiLineResultSet();                  ResultSet rs = getMultiLineResultSet();
3069                  SamplerEngine se = new SamplerEngine(rs.getMultiLineResult());                  SamplerEngine se = new SamplerEngine(rs.getMultiLineResult());
3070                  se.setName(engineName);                  se.setName(engineName);
# Line 1706  public class Client { Line 3087  public class Client {
3087          getSamplerChannelInfo(int samplerChn) throws IOException, LscpException, LSException {          getSamplerChannelInfo(int samplerChn) throws IOException, LscpException, LSException {
3088                  verifyConnection();                  verifyConnection();
3089                  out.writeLine("GET CHANNEL INFO " + samplerChn);                  out.writeLine("GET CHANNEL INFO " + samplerChn);
3090                    if(getPrintOnlyMode()) return null;
3091                    
3092                  ResultSet rs = getMultiLineResultSet();                  ResultSet rs = getMultiLineResultSet();
3093                  SamplerChannel sc = new SamplerChannel(rs.getMultiLineResult());                  SamplerChannel sc = new SamplerChannel(rs.getMultiLineResult());
3094                  sc.setChannelID(samplerChn);                  sc.setChannelId(samplerChn);
3095                    if(sc.getEngine() != null) sc.setEngine(getEngineInfo(sc.getEngine().getName()));
3096                                    
3097                  return sc;                  return sc;
3098          }          }
# Line 1727  public class Client { Line 3111  public class Client {
3111          getChannelVoiceCount(int samplerChn) throws IOException, LscpException, LSException {          getChannelVoiceCount(int samplerChn) throws IOException, LscpException, LSException {
3112                  verifyConnection();                  verifyConnection();
3113                  out.writeLine("GET CHANNEL VOICE_COUNT " + samplerChn);                  out.writeLine("GET CHANNEL VOICE_COUNT " + samplerChn);
3114                    if(getPrintOnlyMode()) return -1;
3115                    
3116                  ResultSet rs = getSingleLineResultSet();                  ResultSet rs = getSingleLineResultSet();
3117                                    
3118                  return parseInt(rs.getResult());                  return parseInt(rs.getResult());
# Line 1747  public class Client { Line 3133  public class Client {
3133          getChannelStreamCount(int samplerChn) throws IOException, LscpException, LSException {          getChannelStreamCount(int samplerChn) throws IOException, LscpException, LSException {
3134                  verifyConnection();                  verifyConnection();
3135                  out.writeLine("GET CHANNEL STREAM_COUNT " + samplerChn);                  out.writeLine("GET CHANNEL STREAM_COUNT " + samplerChn);
3136                    if(getPrintOnlyMode()) return -1;
3137            
3138                  ResultSet rs = getSingleLineResultSet();                  ResultSet rs = getSingleLineResultSet();
3139                                    
3140                  if(rs.getResult().equals("NA")) return -1;                  if(rs.getResult().equals("NA")) return -1;
# Line 1771  public class Client { Line 3159  public class Client {
3159          getChannelBufferFillBytes(int samplerChn) throws IOException, LscpException, LSException {          getChannelBufferFillBytes(int samplerChn) throws IOException, LscpException, LSException {
3160                  verifyConnection();                  verifyConnection();
3161                  out.writeLine("GET CHANNEL BUFFER_FILL BYTES " + samplerChn);                  out.writeLine("GET CHANNEL BUFFER_FILL BYTES " + samplerChn);
3162                    if(getPrintOnlyMode()) return null;
3163                    
3164                  ResultSet rs = getSingleLineResultSet();                  ResultSet rs = getSingleLineResultSet();
3165                                    
3166                  if(rs.getResult().equals("NA")) return null;                  if(rs.getResult().equals("NA")) return null;
# Line 1786  public class Client { Line 3176  public class Client {
3176                          if(i == -1) throw new LscpException(LscpI18n.getLogMsg("CommandFailed!"));                          if(i == -1) throw new LscpException(LscpI18n.getLogMsg("CommandFailed!"));
3177                                                    
3178                          BufferFill bf = new BufferFill();                          BufferFill bf = new BufferFill();
3179                          bf.setStreamID(parseInt(s.substring(1, i)));                          bf.setStreamId(parseInt(s.substring(1, i)));
3180                          bf.setValue(parseInt(s.substring(i + 1)));                          bf.setValue(parseInt(s.substring(i + 1)));
3181                          v.add(bf);                          v.add(bf);
3182                  }                  }
# Line 1813  public class Client { Line 3203  public class Client {
3203                                    
3204                  verifyConnection();                  verifyConnection();
3205                  out.writeLine("GET CHANNEL BUFFER_FILL PERCENTAGE " + samplerChn);                  out.writeLine("GET CHANNEL BUFFER_FILL PERCENTAGE " + samplerChn);
3206                    if(getPrintOnlyMode()) return null;
3207                    
3208                  ResultSet rs = getSingleLineResultSet();                  ResultSet rs = getSingleLineResultSet();
3209                                    
3210                  return getChannelBufferFillPercentage(rs.getResult());                  return getChannelBufferFillPercentage(rs.getResult());
# Line 1836  public class Client { Line 3228  public class Client {
3228                                  throw new LscpException(LscpI18n.getLogMsg("CommandFailed!"));                                  throw new LscpException(LscpI18n.getLogMsg("CommandFailed!"));
3229                                                    
3230                          BufferFill bf = new BufferFill();                          BufferFill bf = new BufferFill();
3231                          bf.setStreamID(parseInt(s.substring(1, i)));                          bf.setStreamId(parseInt(s.substring(1, i)));
3232                          bf.setValue(parseInt(s.substring(i + 1, s.length() - 1)));                          bf.setValue(parseInt(s.substring(i + 1, s.length() - 1)));
3233                          v.add(bf);                          v.add(bf);
3234                  }                  }
# Line 1848  public class Client { Line 3240  public class Client {
3240           * Sets the audio output device on the specified sampler channel.           * Sets the audio output device on the specified sampler channel.
3241           *           *
3242           * @param samplerChn The sampler channel number.           * @param samplerChn The sampler channel number.
3243           * @param devID The numerical ID of the audio output device.           * @param devId The numerical ID of the audio output device.
3244           *           *
3245           * @throws IOException If some I/O error occurs.           * @throws IOException If some I/O error occurs.
3246           * @throws LscpException If LSCP protocol corruption occurs.           * @throws LscpException If LSCP protocol corruption occurs.
3247           * @throws LSException If           * @throws LSException If
3248           * <ul>           * <ul>
3249           * <li><code>samplerChn</code> is not a valid channel number;           * <li><code>samplerChn</code> is not a valid channel number;
3250           * <li><code>devID</code> is not a valid audio output device ID;           * <li><code>devId</code> is not a valid audio output device ID;
3251           * </ul>           * </ul>
3252           *           *
3253           * @see #getSamplerChannels           * @see #getSamplerChannels
3254           * @see #getAudioOutputDevices           * @see #getAudioOutputDevices
3255           */           */
3256          public synchronized void          public synchronized void
3257          setChannelAudioOutputDevice(int samplerChn, int devID)          setChannelAudioOutputDevice(int samplerChn, int devId)
3258                                  throws IOException, LscpException, LSException {                                  throws IOException, LscpException, LSException {
3259                                    
3260                  verifyConnection();                  verifyConnection();
3261                  out.writeLine("SET CHANNEL AUDIO_OUTPUT_DEVICE " + samplerChn + ' ' + devID);                  out.writeLine("SET CHANNEL AUDIO_OUTPUT_DEVICE " + samplerChn + ' ' + devId);
3262                    if(getPrintOnlyMode()) return;
3263                                    
3264                  ResultSet rs = getEmptyResultSet();                  ResultSet rs = getEmptyResultSet();
3265          }          }
# Line 1897  public class Client { Line 3290  public class Client {
3290                  verifyConnection();                  verifyConnection();
3291                  String args = " " + samplerChn + ' ' + audioOut + ' ' + audioIn;                  String args = " " + samplerChn + ' ' + audioOut + ' ' + audioIn;
3292                  out.writeLine("SET CHANNEL AUDIO_OUTPUT_CHANNEL" + args);                  out.writeLine("SET CHANNEL AUDIO_OUTPUT_CHANNEL" + args);
3293                    if(getPrintOnlyMode()) return;
3294                                    
3295                  ResultSet rs = getEmptyResultSet();                  ResultSet rs = getEmptyResultSet();
3296          }          }
# Line 1905  public class Client { Line 3299  public class Client {
3299           * Sets the MIDI input device on the specified sampler channel.           * Sets the MIDI input device on the specified sampler channel.
3300           *           *
3301           * @param samplerChn The sampler channel number.           * @param samplerChn The sampler channel number.
3302           * @param devID The numerical ID of the MIDI input device.           * @param devId The numerical ID of the MIDI input device.
3303           *           *
3304           * @throws IOException If some I/O error occurs.           * @throws IOException If some I/O error occurs.
3305           * @throws LscpException If LSCP protocol corruption occurs.           * @throws LscpException If LSCP protocol corruption occurs.
3306           * @throws LSException If           * @throws LSException If
3307           * <ul>           * <ul>
3308           * <li><code>samplerChn</code> is not a valid channel number;           * <li><code>samplerChn</code> is not a valid channel number;
3309           * <li><code>devID</code> is not a valid MIDI input device ID;           * <li><code>devId</code> is not a valid MIDI input device ID;
3310           * </ul>           * </ul>
3311           *           *
3312           * @see #getSamplerChannels           * @see #getSamplerChannels
3313           * @see #getMidiInputDevices           * @see #getMidiInputDevices
3314           */           */
3315          public synchronized void          public synchronized void
3316          setChannelMidiInputDevice(int samplerChn, int devID)          setChannelMidiInputDevice(int samplerChn, int devId)
3317                                  throws IOException, LscpException, LSException {                                  throws IOException, LscpException, LSException {
3318                                    
3319                  verifyConnection();                  verifyConnection();
3320                  out.writeLine("SET CHANNEL MIDI_INPUT_DEVICE " + samplerChn + ' ' + devID);                  out.writeLine("SET CHANNEL MIDI_INPUT_DEVICE " + samplerChn + ' ' + devId);
3321                    if(getPrintOnlyMode()) return;
3322                                    
3323                  ResultSet rs = getEmptyResultSet();                  ResultSet rs = getEmptyResultSet();
3324          }          }
# Line 1946  public class Client { Line 3341  public class Client {
3341                                    
3342                  verifyConnection();                  verifyConnection();
3343                  out.writeLine("SET CHANNEL MIDI_INPUT_PORT " + samplerChn + ' ' + port);                  out.writeLine("SET CHANNEL MIDI_INPUT_PORT " + samplerChn + ' ' + port);
3344                    if(getPrintOnlyMode()) return;
3345                                    
3346                  ResultSet rs = getEmptyResultSet();                  ResultSet rs = getEmptyResultSet();
3347          }          }
# Line 1970  public class Client { Line 3366  public class Client {
3366                  String args = String.valueOf(samplerChn) + ' ';                  String args = String.valueOf(samplerChn) + ' ';
3367                  args += (midiChn == -1 ? "ALL" : String.valueOf(midiChn));                  args += (midiChn == -1 ? "ALL" : String.valueOf(midiChn));
3368                  out.writeLine("SET CHANNEL MIDI_INPUT_CHANNEL " + args);                  out.writeLine("SET CHANNEL MIDI_INPUT_CHANNEL " + args);
3369                    if(getPrintOnlyMode()) return;
3370                    
3371                    ResultSet rs = getEmptyResultSet();
3372            }
3373            
3374            /**
3375             * Sets the MIDI instrument map to be used on the specified sampler channel.
3376             *
3377             * @param samplerChn The sampler channel number.
3378             * @param mapId Specifies the numerical ID of the MIDI instrument
3379             * map to assign. To remove the current map binding use <code>-1</code>.
3380             * To set the current map to be the default map use <code>-2</code>.
3381             *
3382             * @throws IOException If some I/O error occurs.
3383             * @throws LscpException If LSCP protocol corruption occurs.
3384             * @throws LSException If
3385             * <ul>
3386             * <li><code>samplerChn</code> is not a valid channel number;
3387             * <li><code>mapId</code> is not a valid MIDI instrument map ID;
3388             * </ul>
3389             *
3390             * @see #getSamplerChannels
3391             * @see #getMidiInstrumentMaps
3392             */
3393            public synchronized void
3394            setChannelMidiInstrumentMap(int samplerChn, int mapId)
3395                                    throws IOException, LscpException, LSException {
3396                    
3397                    verifyConnection();
3398                    String s;
3399                    if(mapId == -1) {
3400                            s = " NONE";
3401                    } else if(mapId == -2) {
3402                            s = " DEFAULT";
3403                    } else {
3404                            s = " " + String.valueOf(mapId);
3405                    }
3406                    out.writeLine("SET CHANNEL MIDI_INSTRUMENT_MAP " + samplerChn + s);
3407                    if(getPrintOnlyMode()) return;
3408                                    
3409                  ResultSet rs = getEmptyResultSet();                  ResultSet rs = getEmptyResultSet();
3410          }          }
# Line 1992  public class Client { Line 3427  public class Client {
3427                    
3428                  verifyConnection();                  verifyConnection();
3429                  out.writeLine("SET CHANNEL VOLUME " + samplerChn + ' ' + volume);                  out.writeLine("SET CHANNEL VOLUME " + samplerChn + ' ' + volume);
3430                    if(getPrintOnlyMode()) return;
3431                    
3432                    ResultSet rs = getEmptyResultSet();
3433            }
3434            
3435            /**
3436             * Mute/unmute the specified sampler channel.
3437             *
3438             * @param samplerChn The sampler channel number.
3439             * @param mute If <code>true</code> the specified channel is muted, else the channel
3440             * is unmuted.
3441             *
3442             * @throws IOException If some I/O error occurs.
3443             * @throws LscpException If LSCP protocol corruption occurs.
3444             * @throws LSException If <code>samplerChn</code> is not a valid channel number or if
3445             * there is no engine assigned yet to the specified sampler channel.
3446             * @see #getSamplerChannels
3447             */
3448            public synchronized void
3449            setChannelMute(int samplerChn, boolean mute)
3450                                    throws IOException, LscpException, LSException {
3451            
3452                    verifyConnection();
3453                    out.writeLine("SET CHANNEL MUTE " + samplerChn + ' ' + (mute ? 1 : 0));
3454                    if(getPrintOnlyMode()) return;
3455                    
3456                    ResultSet rs = getEmptyResultSet();
3457            }
3458            
3459            /**
3460             * Solo/unsolo the specified sampler channel.
3461             *
3462             * @param samplerChn The sampler channel number.
3463             * @param solo <code>true</code> to solo the specified channel, <code>false</code>
3464             * otherwise.
3465             *
3466             * @throws IOException If some I/O error occurs.
3467             * @throws LscpException If LSCP protocol corruption occurs.
3468             * @throws LSException If <code>samplerChn</code> is not a valid channel number or if
3469             * there is no engine assigned yet to the specified sampler channel.
3470             * @see #getSamplerChannels
3471             */
3472            public synchronized void
3473            setChannelSolo(int samplerChn, boolean solo)
3474                                    throws IOException, LscpException, LSException {
3475            
3476                    verifyConnection();
3477                    out.writeLine("SET CHANNEL SOLO " + samplerChn + ' ' + (solo ? 1 : 0));
3478                    if(getPrintOnlyMode()) return;
3479                    
3480                    ResultSet rs = getEmptyResultSet();
3481            }
3482            
3483            /**
3484             * Creates an additional effect send on the specified sampler channel.
3485             * @param channel The sampler channel, on which a new effect send should be added.
3486             * @param midiCtrl Defines the MIDI controller, which
3487             * will be able alter the effect send level.
3488             * @return The unique ID of the newly created effect send entity.
3489             * @throws IOException If some I/O error occurs.
3490             * @throws LSException If the creation of the effect send failed.
3491             * @throws LscpException If LSCP protocol corruption occurs.
3492             * @see #destroyFxSend
3493             */
3494            public synchronized int
3495            createFxSend(int channel, int midiCtrl)
3496                            throws IOException, LSException, LscpException {
3497                    
3498                    return createFxSend(channel, midiCtrl, null);
3499            }
3500            
3501            /**
3502             * Creates an additional effect send on the specified sampler channel.
3503             * @param channel The sampler channel, on which the effect send should be created on.
3504             * @param midiCtrl Defines the MIDI controller, which can alter the effect send level.
3505             * @param name The name of the effect send entity. The name does not have to be unique.
3506             * @return The unique ID of the newly created effect send entity.
3507             * @throws IOException If some I/O error occurs.
3508             * @throws LSException If the creation of the effect send failed.
3509             * @throws LscpException If LSCP protocol corruption occurs.
3510             * @see #destroyFxSend
3511             */
3512            public synchronized int
3513            createFxSend(int channel, int midiCtrl, String name)
3514                            throws IOException, LSException, LscpException {
3515                    
3516                    verifyConnection();
3517                    String s = String.valueOf(channel) + " " + String.valueOf(midiCtrl);
3518                    if(name != null) s += " '" + name + "'";
3519                    out.writeLine("CREATE FX_SEND " + s);
3520                    if(getPrintOnlyMode()) return -1;
3521                    
3522                    ResultSet rs = getEmptyResultSet();
3523                    
3524                    return rs.getIndex();
3525            }
3526            
3527            /**
3528             * Destroys the specified effect send on the specified sampler channel.
3529             * @param channel The sampler channel, from which
3530             * the specified effect send should be removed.
3531             * @param fxSend The ID of the effect send that should be removed.
3532             * @throws LSException If some other error occurs.
3533             * @throws LscpException If LSCP protocol corruption occurs.
3534             * @see #createFxSend
3535             */
3536            public synchronized void
3537            destroyFxSend(int channel, int fxSend)
3538                            throws IOException, LSException, LscpException {
3539                    
3540                    verifyConnection();
3541                    String s = String.valueOf(channel) + " " + String.valueOf(fxSend);
3542                    out.writeLine("DESTROY FX_SEND " + s);
3543                    if(getPrintOnlyMode()) return;
3544                    
3545                    ResultSet rs = getEmptyResultSet();
3546            }
3547            
3548            /**
3549             * Gets the current number of effect sends on the specified sampler channel.
3550             * @param channel The ID of the sampler channel.
3551             * @return The current number of effect sends on the specified sampler channels.
3552             * @throws IOException If some I/O error occurs.
3553             * @throws LscpException If LSCP protocol corruption occurs.
3554             * @throws LSException If some other error occurs.
3555             */
3556            public synchronized int
3557            getFxSoundCount(int channel) throws IOException, LscpException, LSException {
3558                    verifyConnection();
3559                    out.writeLine("GET FX_SENDS " + String.valueOf(channel));
3560                    if(getPrintOnlyMode()) return -1;
3561                    
3562                    String s = getSingleLineResultSet().getResult();
3563                    return parseInt(s);
3564            }
3565            
3566            /**
3567             * Gets a list of all created effect sends on the specified sampler channel.
3568             * @param channel The sampler channel number.
3569             * @return A <code>FxSend</code> array providing all created
3570             * effect sends on the specified sampler channel.
3571             * @throws IOException If some I/O error occurs.
3572             * @throws LscpException If LSCP protocol corruption occurs.
3573             * @throws LSException If <code>channel</code> is not a valid sampler channel ID.
3574             * @see #createFxSend
3575             * @see #destroyFxSend
3576             */
3577            public synchronized FxSend[]
3578            getFxSends(int channel) throws IOException, LscpException, LSException {
3579                    Integer[] idS = getFxSendIDs(channel);
3580                    if(getPrintOnlyMode()) return null;
3581                    
3582                    FxSend[] fxSends = new FxSend[idS.length];
3583                    
3584                    for(int i = 0; i < fxSends.length; i++)
3585                            fxSends[i] = getFxSendInfo(channel, idS[i]);
3586                    
3587                    return fxSends;
3588            }
3589            
3590            /**
3591             * Gets a list of effect sends on the specified sampler channel.
3592             * @param channel The sampler channel number.
3593             * @return An <code>Integer</code> array providing
3594             * the numerical IDs of all effect sends on the specified sampler channel.
3595             * @throws IOException If some I/O error occurs.
3596             * @throws LscpException If LSCP protocol corruption occurs.
3597             * @throws LSException If <code>channel</code> is not a valid sampler channel ID.
3598             * @see #createFxSend
3599             * @see #destroyFxSend
3600             */
3601            public synchronized Integer[]
3602            getFxSendIDs(int channel) throws IOException, LscpException, LSException {
3603                    verifyConnection();
3604                    out.writeLine("LIST FX_SENDS " + channel);
3605                    if(getPrintOnlyMode()) return null;
3606                    
3607                    return parseIntList(getSingleLineResultSet().getResult());
3608            }
3609            
3610            /**
3611             * Gets the current settings of the specified effect send entity.
3612             * @param channel The sampler channel number.
3613             * @param fxSend The numerical ID of the effect send entity.
3614             * @return <code>FxSend</code> instance containing
3615             * the current settings of the specified effect send entity.
3616             * @throws IOException If an I/O error occurs.
3617             * @throws LscpException If LSCP protocol corruption occurs.
3618             * @throws LSException If the sampler channel and/or the effect send number are invalid.
3619             */
3620            public synchronized FxSend
3621            getFxSendInfo(int channel, int fxSend) throws IOException, LscpException, LSException {
3622                    verifyConnection();
3623                    String s = String.valueOf(channel) + " " + String.valueOf(fxSend);
3624                    out.writeLine("GET FX_SEND INFO " + s);
3625                    if(getPrintOnlyMode()) return null;
3626                    
3627                    ResultSet rs = getMultiLineResultSet();
3628                    FxSend fxs = new FxSend(rs.getMultiLineResult());
3629                    fxs.setFxSendId(fxSend);
3630                    
3631                    return fxs;
3632            }
3633            
3634            /**
3635             * Sets the name of the specified effect send.
3636             * @param channel The sampler channel number.
3637             * @param fxSend The numerical ID of the effect send entity.
3638             * @param name The new name for the specified effect send.
3639             * @throws IOException If some I/O error occurs.
3640             * @throws LscpException If LSCP protocol corruption occurs.
3641             * @throws LSException If <code>channel</code> is not a valid channel
3642             * number or <code>fxSend</code> is not a valid effect send ID;
3643             */
3644            public synchronized void
3645            setFxSendName(int channel, int fxSend, String name)
3646                                    throws IOException, LscpException, LSException {
3647                    
3648                    verifyConnection();
3649                    String args = " " + channel + " " + fxSend + " '" + name + "'";
3650                    out.writeLine("SET FX_SEND NAME" + args);
3651                    if(getPrintOnlyMode()) return;
3652                    
3653                    ResultSet rs = getEmptyResultSet();
3654            }
3655            
3656            /**
3657             * Sets the destination of an effect send's audio channel in the specified sampler channel.
3658             * @param channel The sampler channel number.
3659             * @param fxSend The numerical ID of the effect send entity to be rerouted.
3660             * @param audioSrc The numerical ID of the effect send's audio output channel,
3661             * which should be rerouted.
3662             * @param audioDst The audio channel of the selected audio output device
3663             * where <code>audioSrc</code> should be routed to.
3664             * @throws IOException If some I/O error occurs.
3665             * @throws LscpException If LSCP protocol corruption occurs.
3666             * @throws LSException If
3667             * <ul>
3668             * <li><code>channel</code> is not a valid channel number;
3669             * <li><code>fxSend</code> is not a valid effect send ID;
3670             * <li>There is no engine assigned yet to the specified sampler channel;
3671             * <li>There is no audio output device connected to the specified sampler channel.
3672             * </ul>
3673             */
3674            public synchronized void
3675            setFxSendAudioOutputChannel(int channel, int fxSend, int audioSrc, int audioDst)
3676                                    throws IOException, LscpException, LSException {
3677                    
3678                    verifyConnection();
3679                    String args = " " + channel + " " + fxSend + " " + audioSrc + " " + audioDst;
3680                    out.writeLine("SET FX_SEND AUDIO_OUTPUT_CHANNEL" + args);
3681                    if(getPrintOnlyMode()) return;
3682                    
3683                    ResultSet rs = getEmptyResultSet();
3684            }
3685            
3686            /**
3687             * Sets the MIDI controller, which will be able to modify
3688             * the send level of the specified effect send in the specified sampler channel.
3689             * @param channel The sampler channel number.
3690             * @param fxSend The numerical ID of the effect send entity.
3691             * @param midiCtrl The MIDI controller which shall be
3692             * able to modify the effect send's send level.
3693             * @throws IOException If some I/O error occurs.
3694             * @throws LscpException If LSCP protocol corruption occurs.
3695             * @throws LSException If
3696             * <ul>
3697             * <li><code>channel</code> is not a valid channel number;
3698             * <li><code>fxSend</code> is not a valid effect send ID;
3699             * <li><code>midiCtrl</code> is not a valid controller;
3700             * </ul>
3701             */
3702            public synchronized void
3703            setFxSendMidiController(int channel, int fxSend, int midiCtrl)
3704                                    throws IOException, LscpException, LSException {
3705                    
3706                    verifyConnection();
3707                    String args = " " + channel + " " + fxSend + " " + midiCtrl;
3708                    out.writeLine("SET FX_SEND MIDI_CONTROLLER" + args);
3709                    if(getPrintOnlyMode()) return;
3710                    
3711                    ResultSet rs = getEmptyResultSet();
3712            }
3713            
3714            /**
3715             * Sets the current send level of the specified
3716             * effect send entity in the specified sampler channel.
3717             * @param channel The sampler channel number.
3718             * @param fxSend The numerical ID of the effect send entity.
3719             * @param volume The new volume value (a value smaller than 1.0 means
3720             * attenuation, whereas a value greater than 1.0 means amplification).
3721             * @throws IOException If some I/O error occurs.
3722             * @throws LscpException If LSCP protocol corruption occurs.
3723             * @throws LSException If some other error occurs.
3724             */
3725            public synchronized void
3726            setFxSendLevel(int channel, int fxSend, float volume)
3727                                    throws IOException, LscpException, LSException {
3728                    
3729                    verifyConnection();
3730                    String args = " " + channel + " " + fxSend + " " + String.valueOf(volume);
3731                    out.writeLine("SET FX_SEND LEVEL" + args);
3732                    if(getPrintOnlyMode()) return;
3733                    
3734                    ResultSet rs = getEmptyResultSet();
3735            }
3736            
3737            /**
3738             * Starts an instrument editor for editing the loaded instrument
3739             * on the specified sampler channel.
3740             * @param samplerChn The sampler channel number.
3741             * @throws IOException If some I/O error occurs.
3742             * @throws LscpException If LSCP protocol corruption occurs.
3743             * @throws LSException If <code>samplerChn</code> is not a valid channel number or if
3744             * there is no instrument loaded on the specified sampler channel.
3745             * @see #getSamplerChannels
3746             */
3747            public synchronized void
3748            editInstrument(int samplerChn) throws IOException, LscpException, LSException {
3749                    verifyConnection();
3750                    out.writeLine("EDIT INSTRUMENT " + samplerChn);
3751                    if(getPrintOnlyMode()) return;
3752                    
3753                    ResultSet rs = getEmptyResultSet();
3754            }
3755            
3756            
3757            
3758            /**
3759             * Adds the specified directory to the instruments database.
3760             * @param dir The absolute (escaped) path name of the directory to add.
3761             * @throws IOException If some I/O error occurs.
3762             * @throws LSException If the creation of the directory failed.
3763             * @throws LscpException If LSCP protocol corruption occurs.
3764             */
3765            public synchronized void
3766            addDbDirectory(String dir) throws IOException, LSException, LscpException {
3767                    verifyConnection();
3768                    out.writeLine("ADD DB_INSTRUMENT_DIRECTORY '" + dir + "'");
3769                    if(getPrintOnlyMode()) return;
3770                    
3771                    ResultSet rs = getEmptyResultSet();
3772            }
3773            
3774            /**
3775             * Removes the specified directory from the instruments database.
3776             * @param dir The absolute (escaped) path name of the directory to remove.
3777             * @throws IOException If some I/O error occurs.
3778             * @throws LscpException If LSCP protocol corruption occurs.
3779             * @throws LSException If the specified directory is not
3780             * empty or if the removal of the directory failed.
3781             */
3782            public synchronized void
3783            removeDbDirectory(String dir) throws IOException, LscpException, LSException {
3784                    removeDbDirectory(dir, false);
3785            }
3786            
3787            /**
3788             * Removes the specified directory from the instruments database.
3789             * @param dir The absolute path name of the directory to remove.
3790             * @param force If <code>true</code> forces the removal of non-empty
3791             * directory and all its content.
3792             * @throws IOException If some I/O error occurs.
3793             * @throws LscpException If LSCP protocol corruption occurs.
3794             * @throws LSException If the removing of the directory failed.
3795             */
3796            public synchronized void
3797            removeDbDirectory(String dir, boolean force)
3798                                    throws IOException, LscpException, LSException {
3799                    
3800                    verifyConnection();
3801                    String s = "REMOVE DB_INSTRUMENT_DIRECTORY ";
3802                    if(force) s += "FORCE ";
3803                    out.writeLine(s + "'" + dir + "'");
3804                    if(getPrintOnlyMode()) return;
3805                    
3806                    ResultSet rs = getEmptyResultSet();
3807            }
3808            
3809            /**
3810             * Removes the specified directories from the instruments database.
3811             * @param dirs The absolute (escaped) path names of the directories to remove.
3812             * @param force If <code>true</code> forces the removal of non-empty
3813             * directories.
3814             * @throws IOException If some I/O error occurs.
3815             * @throws LscpException If LSCP protocol corruption occurs.
3816             * @throws LSException If the removing of the directores failed.
3817             */
3818            public synchronized void
3819            removeDbDirectories(String[] dirs, boolean force)
3820                                    throws IOException, LscpException, LSException {
3821                    
3822                    verifyConnection();
3823                    String cmd = "REMOVE DB_INSTRUMENT_DIRECTORY ";
3824                    if(force) cmd += "FORCE ";
3825                    
3826                    for(String s : dirs) out.writeLine(cmd + "'" + s + "'");
3827                    
3828                    if(getPrintOnlyMode()) return;
3829                    
3830                    getEmptyResultSets(dirs.length, "Client.dirDeletionFailed!");
3831            }
3832            
3833            /**
3834             * Gets the number of directories in the specified directory.
3835             * @return The current number of directories in the specified directory.
3836             * @param dir The absolute path name of the directory.
3837             * @throws IOException If some I/O error occurs.
3838             * @throws LscpException If LSCP protocol corruption occurs.
3839             * @throws LSException If some other error occurs.
3840             */
3841            public synchronized int
3842            getDbDirectoryCount(String dir) throws IOException, LscpException, LSException {
3843                    return getDbDirectoryCount(dir, false);
3844            }
3845            
3846            /**
3847             * Gets the number of directories in the specified directory.
3848             * @return The current number of directories in the specified directory.
3849             * @param dir The absolute path name of the directory.
3850             * @param recursive If <code>true</code>, the number of all directories
3851             * in the specified subtree will be returned.
3852             * @throws IOException If some I/O error occurs.
3853             * @throws LscpException If LSCP protocol corruption occurs.
3854             * @throws LSException If some other error occurs.
3855             */
3856            public synchronized int
3857            getDbDirectoryCount(String dir, boolean recursive)
3858                                    throws IOException, LscpException, LSException {
3859                    
3860                    verifyConnection();
3861                    String s;
3862                    if(recursive) s = "GET DB_INSTRUMENT_DIRECTORIES RECURSIVE '";
3863                    else s = "GET DB_INSTRUMENT_DIRECTORIES '";
3864                    out.writeLine(s + dir + "'");
3865                    if(getPrintOnlyMode()) return -1;
3866                    
3867                    s = getSingleLineResultSet().getResult();
3868                    return parseInt(s);
3869            }
3870            
3871            /**
3872             * Gets the list of directories in the specified directory.
3873             * @param dir The absolute path name of the directory.
3874             * @return A <code>String</code> array providing the names of
3875             * all directories in the specified directory.
3876             * @throws IOException If some I/O error occurs.
3877             * @throws LscpException If LSCP protocol corruption occurs.
3878             * @throws LSException If the specified path name is invalid.
3879             */
3880            public synchronized String[]
3881            getDbDirectoryNames(String dir) throws IOException, LscpException, LSException {
3882                    verifyConnection();
3883                    out.writeLine("LIST DB_INSTRUMENT_DIRECTORIES '" + dir + "'");
3884                    if(getPrintOnlyMode()) return null;
3885                    
3886                    String[] names = parseEscapedStringList(getSingleLineResultSet().getResult());
3887                    for(int i = 0; i < names.length; i++) {
3888                            names[i] = toNonEscapedString(names[i]);
3889                    }
3890                    return names;
3891            }
3892            
3893            /**
3894             * Gets information about the specified directory.
3895             * @param dir The absolute path name of the directory.
3896             * @return A <code>DbDirectoryInfo</code> instance providing information
3897             * about the specified directory.
3898             * @throws IOException If some I/O error occurs.
3899             * @throws LscpException If LSCP protocol corruption occurs.
3900             * @throws LSException If the specified directory is not found.
3901             */
3902            public synchronized DbDirectoryInfo
3903            getDbDirectoryInfo(String dir) throws IOException, LscpException, LSException {
3904                    verifyConnection();
3905                    out.writeLine("GET DB_INSTRUMENT_DIRECTORY INFO '" + dir + "'");
3906                    if(getPrintOnlyMode()) return null;
3907                    
3908                    ResultSet rs = getMultiLineResultSet();
3909                    DbDirectoryInfo info = new DbDirectoryInfo(rs.getMultiLineResult());
3910                    if(dir.equals("/")) {
3911                            info.setName("/");
3912                    } else {
3913                            dir = removeEndingFileSeparator(dir);
3914                    }
3915                    String s = getFileName(dir);
3916                    if(s != null) info.setName(toNonEscapedFileName(s));
3917                    s = getParentDirectory(dir);
3918                    if(s != null) info.setParentDirectoryPath(s);
3919                    
3920                    return info;
3921            }
3922            
3923            /**
3924             * Gets the list of directories in the specified directory.
3925             * @param dir The absolute path name of the directory.
3926             * @return A <code>DbDirectoryInfo</code> array providing
3927             * information about all directories in the specified directory.
3928             * @throws IOException If some I/O error occurs.
3929             * @throws LscpException If LSCP protocol corruption occurs.
3930             * @throws LSException If the specified path name is invalid.
3931             */
3932            public synchronized DbDirectoryInfo[]
3933            getDbDirectories(String dir) throws IOException, LscpException, LSException {
3934                    String[] dirS = getDbDirectoryNames(dir);
3935                    if(!hasEndingFileSeparator(dir)) dir += "/";
3936                    DbDirectoryInfo[] infoS = new DbDirectoryInfo[dirS.length];
3937                    for(int i = 0; i < dirS.length; i++) {
3938                            infoS[i] = getDbDirectoryInfo(dir + toEscapedFileName(dirS[i]));
3939                    }
3940                    return infoS;
3941            }
3942            
3943            /**
3944             * Gets the list of directories in the specified directory.
3945             * @param dir The absolute path name of the directory.
3946             * @return A <code>DbDirectoryInfo</code> array providing
3947             * information about all directories in the specified directory.
3948             * @throws IOException If some I/O error occurs.
3949             * @throws LscpException If LSCP protocol corruption occurs.
3950             * @throws LSException If the specified path name is invalid.
3951             *
3952            public synchronized DbDirectoryInfo[]
3953            getDbDirectories(String dir) throws IOException, LscpException, LSException {
3954                    String[] dirS = getDbDirectoryNames(dir);
3955                    if(dirS.length == 0) return new DbDirectoryInfo[0];
3956                    
3957                    if(dir.charAt(dir.length() - 1) != '/') dir += "/";
3958                    
3959                    for(int i = 0; i < dirS.length; i++) {
3960                            out.writeLine("GET DB_INSTRUMENT_DIRECTORY INFO '" + dir + dirS[i] + "'");
3961                    }
3962                    
3963                    if(getPrintOnlyMode()) return null;
3964                    
3965                    if(dir.length() > 1) dir = dir.substring(0, dir.length() - 1);
3966                    StringBuffer sb = new StringBuffer();
3967                    DbDirectoryInfo[] infoS = new DbDirectoryInfo[dirS.length];
3968                    for(int i = 0; i < dirS.length; i++) {
3969                            try {
3970                                    ResultSet rs = getMultiLineResultSet();
3971                                    infoS[i] = new DbDirectoryInfo(rs.getMultiLineResult());
3972                                    infoS[i].setName(dirS[i]);
3973                                    infoS[i].setParentDirectoryPath(dir);
3974                            } catch (SocketTimeoutException e) {
3975                                    getLogger().log(Level.FINE, e.getMessage(), e);
3976                                    sb.append(e.getMessage()).append("\n");
3977                                    break;
3978                            } catch (Exception e) {
3979                                    getLogger().log(Level.FINE, e.getMessage(), e);
3980                                    sb.append(e.getMessage()).append("\n");
3981                            }
3982                    }
3983                    
3984                    String details = sb.toString();
3985                    if(details.length() > 0) {
3986                            String err = LscpI18n.getLogMsg("Client.getInstrsInfoFailed!");
3987                            throw new LSException(0, err, details);
3988                    }
3989                    
3990                    return infoS;
3991            }*/
3992            
3993            /**
3994             * Renames the specified directory.
3995             * @param dir The absolute path name of the directory to rename.
3996             * @param name The new name for the directory.
3997             * @throws IOException If some I/O error occurs.
3998             * @throws LSException If the renaming of the directory failed.
3999             * @throws LscpException If LSCP protocol corruption occurs.
4000             */
4001            public synchronized void
4002            renameDbDirectory(String dir, String name) throws IOException, LSException, LscpException {
4003                    verifyConnection();
4004                    name = toEscapedString(name);
4005                    out.writeLine("SET DB_INSTRUMENT_DIRECTORY NAME '" + dir + "' '" + name + "'");
4006                    if(getPrintOnlyMode()) return;
4007                    
4008                    ResultSet rs = getEmptyResultSet();
4009            }
4010            
4011            /**
4012             * Moves the specified directory into the specified location.
4013             * @param dir The absolute path name of the directory to move.
4014             * @param dst The location where the directory will be moved to.
4015             * @throws IOException If some I/O error occurs.
4016             * @throws LSException If the operation failed.
4017             * @throws LscpException If LSCP protocol corruption occurs.
4018             */
4019            public synchronized void
4020            moveDbDirectory(String dir, String dst) throws IOException, LSException, LscpException {
4021                    verifyConnection();
4022                    out.writeLine("MOVE DB_INSTRUMENT_DIRECTORY '" + dir + "' '" + dst + "'");
4023                    if(getPrintOnlyMode()) return;
4024                    
4025                    ResultSet rs = getEmptyResultSet();
4026            }
4027            
4028            /**
4029             * Moves the specified directories into the specified location.
4030             * @param dirs The absolute path names of the directories to move.
4031             * @param dst The location where the directories will be moved to.
4032             * @throws IOException If some I/O error occurs.
4033             * @throws LSException If the operation failed.
4034             * @throws LscpException If LSCP protocol corruption occurs.
4035             */
4036            public synchronized void
4037            moveDbDirectories(String dirs[], String dst) throws IOException, LSException, LscpException {
4038                    verifyConnection();
4039                    for(String s : dirs) {
4040                            out.writeLine("MOVE DB_INSTRUMENT_DIRECTORY '" + s + "' '" + dst + "'");
4041                    }
4042                    if(getPrintOnlyMode()) return;
4043                    
4044                    getEmptyResultSets(dirs.length, "Client.dirMovingFailed!");
4045            }
4046            
4047            /**
4048             * Copies the specified directory into the specified location.
4049             * @param dir The absolute path name of the directory to copy.
4050             * @param dst The location where the directory will be copied to.
4051             * @throws IOException If some I/O error occurs.
4052             * @throws LSException If the operation failed.
4053             * @throws LscpException If LSCP protocol corruption occurs.
4054             */
4055            public synchronized void
4056            copyDbDirectory(String dir, String dst) throws IOException, LSException, LscpException {
4057                    verifyConnection();
4058                    out.writeLine("COPY DB_INSTRUMENT_DIRECTORY '" + dir + "' '" + dst + "'");
4059                    if(getPrintOnlyMode()) return;
4060                    
4061                    ResultSet rs = getEmptyResultSet();
4062            }
4063            
4064            /**
4065             * Copies the specified directories into the specified location.
4066             * @param dirs The absolute path names of the directories to copy.
4067             * @param dst The location where the directories will be copied to.
4068             * @throws IOException If some I/O error occurs.
4069             * @throws LSException If the operation failed.
4070             * @throws LscpException If LSCP protocol corruption occurs.
4071             */
4072            public synchronized void
4073            copyDbDirectories(String[] dirs, String dst) throws IOException, LSException, LscpException {
4074                    verifyConnection();
4075                    for(String s : dirs) {
4076                            out.writeLine("COPY DB_INSTRUMENT_DIRECTORY '" + s + "' '" + dst + "'");
4077                    }
4078                    if(getPrintOnlyMode()) return;
4079                    
4080                    getEmptyResultSets(dirs.length, "Client.dirCopyingFailed!");
4081            }
4082            
4083            /**
4084             * Changes the description of the specified directory.
4085             * @param dir The absolute path name of the directory.
4086             * @param desc The new description for the directory.
4087             * @throws IOException If some I/O error occurs.
4088             * @throws LSException If failed to change the description.
4089             * @throws LscpException If LSCP protocol corruption occurs.
4090             */
4091            public synchronized void
4092            setDbDirectoryDescription(String dir, String desc)
4093                                    throws IOException, LSException, LscpException {
4094                    
4095                    verifyConnection();
4096                    String s = "SET DB_INSTRUMENT_DIRECTORY DESCRIPTION '";
4097                    out.writeLine(s + dir + "' '" + toEscapedString(desc) + "'");
4098                    if(getPrintOnlyMode()) return;
4099                    
4100                    ResultSet rs = getEmptyResultSet();
4101            }
4102            
4103            public static enum ScanMode {
4104                    RECURSIVE, NON_RECURSIVE, FLAT
4105            }
4106            
4107            /**
4108             * Adds the specified instrument to the specified instruments database directory.
4109             * @param dbDir The absolute path name of the database directory in which the
4110             * specified instrument will be added.
4111             * @param filePath The absolute path name of the instrument file.
4112             * @param instrIndex The index of the instrument (in the given instrument file) to add.
4113             * @throws IOException If some I/O error occurs.
4114             * @throws LSException If the operation failed.
4115             * @throws LscpException If LSCP protocol corruption occurs.
4116             */
4117            public synchronized void
4118            addDbInstrument(String dbDir, String filePath, int instrIndex)
4119                                            throws IOException, LSException, LscpException {
4120                    
4121                    addDbInstrument(dbDir, filePath, instrIndex, false);
4122            }
4123            
4124            /**
4125             * Adds the specified instrument to the specified instruments database directory.
4126             * @param dbDir The absolute path name of the database directory in which the
4127             * specified instrument will be added.
4128             * @param filePath The absolute path name of the instrument file.
4129             * @param instrIndex The index of the instrument (in the given instrument file) to add.
4130             * @param background If <code>true</code>, the scan will be done
4131             * in background and this method may return before the job is finished.
4132             * @return If <code>background</code> is <code>true</code>, the ID
4133             * of the scan job.
4134             * @throws IOException If some I/O error occurs.
4135             * @throws LSException If the operation failed.
4136             * @throws LscpException If LSCP protocol corruption occurs.
4137             * @see #addInstrumentsDbListener
4138             */
4139            public synchronized int
4140            addDbInstrument(String dbDir, String filePath, int instrIndex, boolean background)
4141                                            throws IOException, LSException, LscpException {
4142                    
4143                    verifyConnection();
4144                    String s = "ADD DB_INSTRUMENTS";
4145                    if(background) s += " NON_MODAL";
4146                    s += " '" + dbDir + "' '" + filePath + "' ";
4147                    out.writeLine(s + String.valueOf(instrIndex));
4148                    if(getPrintOnlyMode()) return -1;
4149                    
4150                    ResultSet rs = getEmptyResultSet();
4151                    return rs.getIndex();
4152            }
4153            
4154            /**
4155             * Adds the instruments in the specified file to the specified
4156             * instruments database directory.
4157             * @param dbDir The absolute path name of the database directory
4158             * in which the the supported instruments will be added.
4159             * @param filePath The absolute path name of the file to scan for instruments.
4160             * @throws IOException If some I/O error occurs.
4161             * @throws LSException If the operation failed.
4162             * @throws LscpException If LSCP protocol corruption occurs.
4163             */
4164            public synchronized void
4165            addDbInstruments(String dbDir, String filePath)
4166                                            throws IOException, LSException, LscpException {
4167                    
4168                    addDbInstruments(dbDir, filePath, false);
4169            }
4170            
4171            /**
4172             * Adds the instruments in the specified file to the specified
4173             * instruments database directory.
4174             * @param dbDir The absolute path name of the database directory
4175             * in which the the supported instruments will be added.
4176             * @param filePath The absolute path name of the file to scan for instruments.
4177             * @param background If <code>true</code>, the scan will be done
4178             * in background and this method may return before the job is finished.
4179             * @return If <code>background</code> is <code>true</code>, the ID
4180             * of the scan job.
4181             * @throws IOException If some I/O error occurs.
4182             * @throws LSException If the operation failed.
4183             * @throws LscpException If LSCP protocol corruption occurs.
4184             * @see #addInstrumentsDbListener
4185             */
4186            public synchronized int
4187            addDbInstruments(String dbDir, String filePath, boolean background)
4188                                            throws IOException, LSException, LscpException {
4189                    
4190                    verifyConnection();
4191                    String s = "ADD DB_INSTRUMENTS";
4192                    if(background) s += " NON_MODAL";
4193                    out.writeLine(s + " '" + dbDir + "' '" + filePath + "'");
4194                    if(getPrintOnlyMode()) return -1;
4195                    
4196                    ResultSet rs = getEmptyResultSet();
4197                    return rs.getIndex();
4198            }
4199            
4200            /**
4201             * Adds the instruments in the specified file system directory
4202             * to the specified instruments database directory.
4203             * @param mode Determines the scanning mode. If RECURSIVE is
4204             * specified, all supported instruments in the specified file system
4205             * direcotry will be added to the specified instruments database
4206             * directory, including the instruments in subdirectories
4207             * of the supplied directory. If NON_RECURSIVE is specified,
4208             * the instruments in the subdirectories will not be processed.
4209             * If FLAT is specified, all supported instruments in the specified
4210             * file system direcotry will be added, including the instruments in
4211             * subdirectories of the supplied directory, but the respective
4212             * subdirectory structure will not be recreated in the instruments
4213             * database and all instruments will be added directly in the
4214             * specified database directory.
4215             * @param dbDir The absolute path name of the database directory
4216             * in which the supported instruments will be added.
4217             * @param fsDir The absolute path name of the file system directory.
4218             * @throws IOException If some I/O error occurs.
4219             * @throws LSException If the operation failed.
4220             * @throws LscpException If LSCP protocol corruption occurs.
4221             */
4222            public synchronized void
4223            addDbInstruments(ScanMode mode, String dbDir, String fsDir)
4224                                            throws IOException, LSException, LscpException {
4225                    
4226                    addDbInstruments(mode, dbDir, fsDir, false);
4227            }
4228            
4229            /**
4230             * Adds the instruments in the specified file system directory
4231             * to the specified instruments database directory.
4232             * @param mode Determines the scanning mode. If RECURSIVE is
4233             * specified, all supported instruments in the specified file system
4234             * direcotry will be added to the specified instruments database
4235             * directory, including the instruments in subdirectories
4236             * of the supplied directory. If NON_RECURSIVE is specified,
4237             * the instruments in the subdirectories will not be processed.
4238             * If FLAT is specified, all supported instruments in the specified
4239             * file system direcotry will be added, including the instruments in
4240             * subdirectories of the supplied directory, but the respective
4241             * subdirectory structure will not be recreated in the instruments
4242             * database and all instruments will be added directly in the
4243             * specified database directory.
4244             * @param dbDir The absolute path name of the database directory
4245             * in which the supported instruments will be added.
4246             * @param fsDir The absolute path name of the file system directory.
4247             * @param background If <code>true</code>, the scan will be done
4248             * in background and this method may return before the job is finished.
4249             * @return If <code>background</code> is <code>true</code>, the ID
4250             * of the scan job.
4251             * @throws IOException If some I/O error occurs.
4252             * @throws LSException If the operation failed.
4253             * @throws LscpException If LSCP protocol corruption occurs.
4254             * @see #addInstrumentsDbListener
4255             */
4256            public synchronized int
4257            addDbInstruments(ScanMode mode, String dbDir, String fsDir, boolean background)
4258                                            throws IOException, LSException, LscpException {
4259                    
4260                    verifyConnection();
4261                    StringBuffer sb = new StringBuffer("ADD DB_INSTRUMENTS");
4262                    if(background) sb.append(" NON_MODAL");
4263                    
4264                    switch(mode) {
4265                            case RECURSIVE:
4266                                    sb.append(" RECURSIVE");
4267                                    break;
4268                            case NON_RECURSIVE:
4269                                    sb.append(" NON_RECURSIVE");
4270                                    break;
4271                            case FLAT:
4272                                    sb.append(" FLAT");
4273                                    break;
4274                    }
4275                    
4276                    sb.append(" '").append(dbDir).append("' '");
4277                    sb.append(fsDir).append("'");
4278                    out.writeLine(sb.toString());
4279                    if(getPrintOnlyMode()) return -1;
4280                    
4281                    ResultSet rs = getEmptyResultSet();
4282                    return rs.getIndex();
4283            }
4284            
4285            /**
4286             * Removes the specified instrument from the instruments database.
4287             * @param instr The absolute path name of the instrument to remove.
4288             * @throws IOException If some I/O error occurs.
4289             * @throws LscpException If LSCP protocol corruption occurs.
4290             * @throws LSException If the removing of the instrument failed.
4291             */
4292            public synchronized void
4293            removeDbInstrument(String instr) throws IOException, LscpException, LSException {
4294                    
4295                    verifyConnection();
4296                    out.writeLine("REMOVE DB_INSTRUMENT '" + instr + "'");
4297                    if(getPrintOnlyMode()) return;
4298                    
4299                    ResultSet rs = getEmptyResultSet();
4300            }
4301            
4302            /**
4303             * Removes the specified instruments from the instruments database.
4304             * @param instrs The absolute path names of the instruments to remove.
4305             * @throws IOException If some I/O error occurs.
4306             * @throws LscpException If LSCP protocol corruption occurs.
4307             * @throws LSException If the removing of the instruments failed.
4308             */
4309            public synchronized void
4310            removeDbInstruments(String[] instrs) throws IOException, LscpException, LSException {
4311                    verifyConnection();
4312                    for(String s : instrs) {
4313                            out.writeLine("REMOVE DB_INSTRUMENT '" + s + "'");
4314                    }
4315                    if(getPrintOnlyMode()) return;
4316                    
4317                    getEmptyResultSets(instrs.length, "Client.instrDeletionFailed!");
4318            }
4319            
4320            /**
4321             * Gets the number of instruments in the specified directory.
4322             * @return The current number of instruments in the specified directory.
4323             * @param dir The absolute path name of the directory.
4324             * @throws IOException If some I/O error occurs.
4325             * @throws LscpException If LSCP protocol corruption occurs.
4326             * @throws LSException If some other error occurs.
4327             */
4328            public synchronized int
4329            getDbInstrumentCount(String dir) throws IOException, LscpException, LSException {
4330                    return getDbInstrumentCount(dir, false);
4331            }
4332            
4333            /**
4334             * Gets the number of instruments in the specified directory.
4335             * @return The current number of instruments in the specified directory.
4336             * @param dir The absolute path name of the directory.
4337             * @param recursive If <code>true</code>, the number of all instruments
4338             * in the specified subtree will be returned.
4339             * @throws IOException If some I/O error occurs.
4340             * @throws LscpException If LSCP protocol corruption occurs.
4341             * @throws LSException If some other error occurs.
4342             */
4343            public synchronized int
4344            getDbInstrumentCount(String dir, boolean recursive)
4345                                    throws IOException, LscpException, LSException {
4346                    
4347                    verifyConnection();
4348                    String s;
4349                    if(recursive) s = "GET DB_INSTRUMENTS RECURSIVE '";
4350                    else s = "GET DB_INSTRUMENTS '";
4351                    out.writeLine(s + dir + "'");
4352                    if(getPrintOnlyMode()) return -1;
4353                    
4354                    s = getSingleLineResultSet().getResult();
4355                    return parseInt(s);
4356            }
4357            
4358            /**
4359             * Gets the list of instruments in the specified directory.
4360             * @param dir The absolute path name of the directory.
4361             * @return A <code>String</code> array providing the names of
4362             * all instruments in the specified directory.
4363             * @throws IOException If some I/O error occurs.
4364             * @throws LscpException If LSCP protocol corruption occurs.
4365             * @throws LSException If the specified path name is invalid.
4366             */
4367            public synchronized String[]
4368            getDbInstrumentNames(String dir) throws IOException, LscpException, LSException {
4369                    verifyConnection();
4370                    out.writeLine("LIST DB_INSTRUMENTS '" + dir + "'");
4371                    if(getPrintOnlyMode()) return null;
4372                    
4373                    String[] names = parseEscapedStringList(getSingleLineResultSet().getResult());
4374                    for(int i = 0; i < names.length; i++) {
4375                            names[i] = toNonEscapedString(names[i]);
4376                    }
4377                    return names;
4378            }
4379            
4380            /**
4381             * Gets information about the specified instrument.
4382             * @param instr The absolute path name of the instrument.
4383             * @return A <code>DbInstrumentInfo</code> instance providing information
4384             * about the specified instrument.
4385             * @throws IOException If some I/O error occurs.
4386             * @throws LscpException If LSCP protocol corruption occurs.
4387             * @throws LSException If the specified instrument is not found.
4388             */
4389            public synchronized DbInstrumentInfo
4390            getDbInstrumentInfo(String instr) throws IOException, LscpException, LSException {
4391                    verifyConnection();
4392                    out.writeLine("GET DB_INSTRUMENT INFO '" + instr + "'");
4393                    if(getPrintOnlyMode()) return null;
4394                    
4395                    ResultSet rs = getMultiLineResultSet();
4396                    DbInstrumentInfo info = new DbInstrumentInfo(rs.getMultiLineResult());
4397                    String s = getParentDirectory(instr);
4398                    if(s != null) info.setDirectoryPath(s);
4399                    s = getFileName(instr);
4400                    if(s != null) info.setName(toNonEscapedFileName(s));
4401                    
4402                    return info;
4403            }
4404            
4405            /**
4406             * Gets the list of instruments in the specified directory.
4407             * @param dir The absolute path name of the directory.
4408             * @return A <code>DbInstrumentInfo</code> array providing
4409             * information about all instruments in the specified directory.
4410             * @throws IOException If some I/O error occurs.
4411             * @throws LscpException If LSCP protocol corruption occurs.
4412             * @throws LSException If the specified path name is invalid.
4413             */
4414            public synchronized DbInstrumentInfo[]
4415            getDbInstruments(String dir) throws IOException, LscpException, LSException {
4416                    String[] instrS = getDbInstrumentNames(dir);
4417                    if(!hasEndingFileSeparator(dir)) dir += "/";
4418                    
4419                    DbInstrumentInfo[] infoS = new DbInstrumentInfo[instrS.length];
4420                    for(int i = 0; i < instrS.length; i++) {
4421                            infoS[i] = getDbInstrumentInfo(dir + toEscapedFileName(instrS[i]));
4422                    }
4423                    return infoS;
4424            }
4425            
4426            /**
4427             * Gets the list of instruments in the specified directory.
4428             * @param dir The absolute path name of the directory.
4429             * @return A <code>DbInstrumentInfo</code> array providing
4430             * information about all instruments in the specified directory.
4431             * @throws IOException If some I/O error occurs.
4432             * @throws LscpException If LSCP protocol corruption occurs.
4433             * @throws LSException If the specified path name is invalid.
4434             *
4435            public synchronized DbInstrumentInfo[]
4436            getDbInstruments(String dir) throws IOException, LscpException, LSException {
4437                    String[] instrS = getDbInstrumentNames(dir);
4438                    if(instrS.length == 0) return new DbInstrumentInfo[0];
4439                    
4440                    if(dir.charAt(dir.length() - 1) != '/') dir += "/";
4441                    
4442                    for(int i = 0; i < instrS.length; i++) {
4443                            out.writeLine("GET DB_INSTRUMENT INFO '" + dir + instrS[i] + "'");
4444                    }
4445                    
4446                    if(getPrintOnlyMode()) return null;
4447                    
4448                    if(dir.length() > 1) dir = dir.substring(0, dir.length() - 1);
4449                    StringBuffer sb = new StringBuffer();
4450                    DbInstrumentInfo[] infoS = new DbInstrumentInfo[instrS.length];
4451                    for(int i = 0; i < instrS.length; i++) {
4452                            try {
4453                                    ResultSet rs = getMultiLineResultSet();
4454                                    infoS[i] = new DbInstrumentInfo(rs.getMultiLineResult());
4455                                    infoS[i].setName(instrS[i]);
4456                                    infoS[i].setDirectoryPath(dir);
4457                            } catch (SocketTimeoutException e) {
4458                                    getLogger().log(Level.FINE, e.getMessage(), e);
4459                                    sb.append(e.getMessage()).append("\n");
4460                                    break;
4461                            } catch (Exception e) {
4462                                    getLogger().log(Level.FINE, e.getMessage(), e);
4463                                    sb.append(e.getMessage()).append("\n");
4464                            }
4465                    }
4466                    
4467                    String details = sb.toString();
4468                    if(details.length() > 0) {
4469                            String err = LscpI18n.getLogMsg("Client.getInstrsInfoFailed!");
4470                            throw new LSException(0, err, details);
4471                    }
4472                    
4473                    return infoS;
4474            }*/
4475            
4476            /**
4477             * Renames the specified instrument.
4478             * @param instr The absolute path name of the instrument to rename.
4479             * @param name The new name for the instrument.
4480             * @throws IOException If some I/O error occurs.
4481             * @throws LSException If the renaming of the instrument failed.
4482             * @throws LscpException If LSCP protocol corruption occurs.
4483             */
4484            public synchronized void
4485            renameDbInstrument(String instr, String name)
4486                                    throws IOException, LSException, LscpException {
4487                    
4488                    verifyConnection();
4489                    name = toEscapedString(name);
4490                    out.writeLine("SET DB_INSTRUMENT NAME '" + instr + "' '" + name + "'");
4491                    if(getPrintOnlyMode()) return;
4492                    
4493                    ResultSet rs = getEmptyResultSet();
4494            }
4495            
4496            /**
4497             * Moves the specified instrument into the specified location.
4498             * @param instr The absolute path name of the instrument to move.
4499             * @param dst The directory where the specified instrument will be moved to.
4500             * @throws IOException If some I/O error occurs.
4501             * @throws LSException If the operation failed.
4502             * @throws LscpException If LSCP protocol corruption occurs.
4503             */
4504            public synchronized void
4505            moveDbInstrument(String instr, String dst) throws IOException, LSException, LscpException {
4506                    verifyConnection();
4507                    out.writeLine("MOVE DB_INSTRUMENT '" + instr + "' '" + dst + "'");
4508                    if(getPrintOnlyMode()) return;
4509                                    
4510                  ResultSet rs = getEmptyResultSet();                  ResultSet rs = getEmptyResultSet();
4511          }          }
4512                    
4513          /**          /**
4514             * Moves the specified instruments into the specified location.
4515             * @param instrs The absolute path names of the instruments to move.
4516             * @param dst The directory where the specified instruments will be moved to.
4517             * @throws IOException If some I/O error occurs.
4518             * @throws LSException If the operation failed.
4519             * @throws LscpException If LSCP protocol corruption occurs.
4520             */
4521            public synchronized void
4522            moveDbInstruments(String[] instrs, String dst) throws IOException, LSException, LscpException {
4523                    verifyConnection();
4524                    for(String s : instrs) {
4525                            out.writeLine("MOVE DB_INSTRUMENT '" + s + "' '" + dst + "'");
4526                    }
4527                    if(getPrintOnlyMode()) return;
4528                    
4529                    getEmptyResultSets(instrs.length, "Client.instrMovingFailed!");
4530            }
4531            
4532            /**
4533             * Copies the specified instrument into the specified location.
4534             * @param instr The absolute path name of the instrument to copy.
4535             * @param dst The directory where the specified instrument will be copied to.
4536             * @throws IOException If some I/O error occurs.
4537             * @throws LSException If the operation failed.
4538             * @throws LscpException If LSCP protocol corruption occurs.
4539             */
4540            public synchronized void
4541            copyDbInstrument(String instr, String dst) throws IOException, LSException, LscpException {
4542                    verifyConnection();
4543                    out.writeLine("COPY DB_INSTRUMENT '" + instr + "' '" + dst + "'");
4544                    if(getPrintOnlyMode()) return;
4545                    
4546                    ResultSet rs = getEmptyResultSet();
4547            }
4548            
4549            /**
4550             * Copies the specified instruments into the specified location.
4551             * @param instrs The absolute path name of the instruments to copy.
4552             * @param dst The directory where the specified instruments will be copied to.
4553             * @throws IOException If some I/O error occurs.
4554             * @throws LSException If the operation failed.
4555             * @throws LscpException If LSCP protocol corruption occurs.
4556             */
4557            public synchronized void
4558            copyDbInstruments(String[] instrs, String dst) throws IOException, LSException, LscpException {
4559                    verifyConnection();
4560                    for(String s : instrs) {
4561                            out.writeLine("COPY DB_INSTRUMENT '" + s + "' '" + dst + "'");
4562                    }
4563                    if(getPrintOnlyMode()) return;
4564                    
4565                    getEmptyResultSets(instrs.length, "Client.instrCopyingFailed!");
4566            }
4567            
4568            /**
4569             * Changes the description of the specified instrument.
4570             * @param instr The absolute path name of the instrument.
4571             * @param desc The new description for the instrument.
4572             * @throws IOException If some I/O error occurs.
4573             * @throws LSException If failed to change the description.
4574             * @throws LscpException If LSCP protocol corruption occurs.
4575             */
4576            public synchronized void
4577            setDbInstrumentDescription(String instr, String desc)
4578                                    throws IOException, LSException, LscpException {
4579                    
4580                    verifyConnection();
4581                    desc = toEscapedString(desc);
4582                    out.writeLine("SET DB_INSTRUMENT DESCRIPTION '" + instr + "' '" + desc + "'");
4583                    if(getPrintOnlyMode()) return;
4584                    
4585                    ResultSet rs = getEmptyResultSet();
4586            }
4587            
4588            /**
4589             * Finds all directories in the specified directory
4590             * that corresponds to the specified search criterias.
4591             * @param dir The absolute path name of the directory to search.
4592             * @param query Provides the search criterias.
4593             * @return A <code>DbDirectoryInfo</code> array providing
4594             * information about all directories that are found in the specified directory.
4595             * @throws IOException If some I/O error occurs.
4596             * @throws LscpException If LSCP protocol corruption occurs.
4597             * @throws LSException If the specified path name is invalid.
4598             */
4599            public synchronized DbDirectoryInfo[]
4600            findDbDirectories(String dir, DbSearchQuery query)
4601                                    throws IOException, LscpException, LSException {
4602                    
4603                    return findDbDirectories(dir, query, false);
4604            }
4605            
4606            /**
4607             * Finds all directories in the specified directory
4608             * that corresponds to the specified search criterias.
4609             * @param dir The absolute path name of the directory to search.
4610             * @param query Provides the search criterias.
4611             * @param nonRecursive If <code>true</code>, the search will be non-recursive.
4612             * @return A <code>DbDirectoryInfo</code> array providing
4613             * information about all directories that are found in the specified directory.
4614             * @throws IOException If some I/O error occurs.
4615             * @throws LscpException If LSCP protocol corruption occurs.
4616             * @throws LSException If the specified path name is invalid.
4617             */
4618            public synchronized DbDirectoryInfo[]
4619            findDbDirectories(String dir, DbSearchQuery query, boolean nonRecursive)
4620                                    throws IOException, LscpException, LSException {
4621                    
4622                    verifyConnection();
4623                    StringBuffer sb = new StringBuffer();
4624                    sb.append("FIND DB_INSTRUMENT_DIRECTORIES");
4625                    if(nonRecursive) sb.append(" NON_RECURSIVE");
4626                    sb.append(" '").append(dir).append("'");
4627                    
4628                    if(query.name != null && query.name.length() > 0) {
4629                            sb.append(" NAME='").append(toEscapedString(query.name)).append("'");
4630                    }
4631                    
4632                    String s = query.getCreatedAfter();
4633                    String s2 = query.getCreatedBefore();
4634                    if(s != null || s2 != null) {
4635                            sb.append(" CREATED='");
4636                            if(s != null) sb.append(s);
4637                            sb.append("..");
4638                            if(s2 != null) sb.append(s2);
4639                            sb.append("'");
4640                    }
4641                    
4642                    s = query.getModifiedAfter();
4643                    s2 = query.getModifiedBefore();
4644                    if(s != null || s2 != null) {
4645                            sb.append(" MODIFIED='");
4646                            if(s != null) sb.append(s);
4647                            sb.append("..");
4648                            if(s2 != null) sb.append(s2);
4649                            sb.append("'");
4650                    }
4651                    
4652                    if(query.description != null && query.description.length() > 0) {
4653                            sb.append(" DESCRIPTION='");
4654                            sb.append(toEscapedString(query.description)).append("'");
4655                    }
4656                    
4657                    out.writeLine(sb.toString());
4658                    if(getPrintOnlyMode()) return null;
4659                    
4660                    String[] dirS = parseEscapedStringList(getSingleLineResultSet().getResult());
4661                    
4662                    DbDirectoryInfo[] infoS = new DbDirectoryInfo[dirS.length];
4663                    for(int i = 0; i < dirS.length; i++) {
4664                            infoS[i] = getDbDirectoryInfo(dirS[i]);
4665                    }
4666                    return infoS;
4667            }
4668            
4669            /**
4670             * Finds all instruments in the specified directory
4671             * that corresponds to the specified search criterias.
4672             * @param dir The absolute path name of the directory to search.
4673             * @param query Provides the search criterias.
4674             * @return A <code>DbInstrumentInfo</code> array providing
4675             * information about all instruments that are found in the specified directory.
4676             * @throws IOException If some I/O error occurs.
4677             * @throws LscpException If LSCP protocol corruption occurs.
4678             * @throws LSException If the specified path name is invalid.
4679             */
4680            public synchronized DbInstrumentInfo[]
4681            findDbInstruments(String dir, DbSearchQuery query)
4682                                    throws IOException, LscpException, LSException {
4683                    
4684                    return findDbInstruments(dir, query, false);
4685            }
4686            
4687            /**
4688             * Finds all instruments in the specified directory
4689             * that corresponds to the specified search criterias.
4690             * @param dir The absolute path name of the directory to search.
4691             * @param query Provides the search criterias.
4692             * @param nonRecursive If <code>true</code>, the search will be non-recursive.
4693             * @return A <code>DbInstrumentInfo</code> array providing
4694             * information about all instruments that are found in the specified directory.
4695             * @throws IOException If some I/O error occurs.
4696             * @throws LscpException If LSCP protocol corruption occurs.
4697             * @throws LSException If the specified path name is invalid.
4698             */
4699            public synchronized DbInstrumentInfo[]
4700            findDbInstruments(String dir, DbSearchQuery query, boolean nonRecursive)
4701                                    throws IOException, LscpException, LSException {
4702                    
4703                    verifyConnection();
4704                    StringBuffer sb = new StringBuffer();
4705                    sb.append("FIND DB_INSTRUMENTS");
4706                    if(nonRecursive) sb.append(" NON_RECURSIVE");
4707                    sb.append(" '").append(dir).append("'");
4708                    
4709                    if(query.name != null && query.name.length() > 0) {
4710                            sb.append(" NAME='").append(toEscapedString(query.name)).append("'");
4711                    }
4712                    
4713                    if(query.formatFamilies.size() > 0) {
4714                            sb.append(" FORMAT_FAMILIES='").append(query.formatFamilies.get(0));
4715                            for(int i = 1; i < query.formatFamilies.size(); i++) {
4716                                    sb.append(',').append(query.formatFamilies.get(i));
4717                            }
4718                            sb.append("'");
4719                    }
4720                    
4721                    if(query.minSize != -1 || query.maxSize != -1) {
4722                            sb.append(" SIZE='");
4723                            if(query.minSize != -1) sb.append(query.minSize);
4724                            sb.append("..");
4725                            if(query.maxSize != -1) sb.append(query.maxSize);
4726                            sb.append("'");
4727                    }
4728                    
4729                    String s = query.getCreatedAfter();
4730                    String s2 = query.getCreatedBefore();
4731                    if(s != null || s2 != null) {
4732                            sb.append(" CREATED='");
4733                            if(s != null) sb.append(s);
4734                            sb.append("..");
4735                            if(s2 != null) sb.append(s2);
4736                            sb.append("'");
4737                    }
4738                    
4739                    s = query.getModifiedAfter();
4740                    s2 = query.getModifiedBefore();
4741                    if(s != null || s2 != null) {
4742                            sb.append(" MODIFIED='");
4743                            if(s != null) sb.append(s);
4744                            sb.append("..");
4745                            if(s2 != null) sb.append(s2);
4746                            sb.append("'");
4747                    }
4748                    
4749                    if(query.description != null && query.description.length() > 0) {
4750                            sb.append(" DESCRIPTION='");
4751                            sb.append(toEscapedString(query.description)).append("'");
4752                    }
4753                    
4754                    if(query.instrumentType != DbSearchQuery.InstrumentType.BOTH) {
4755                            sb.append(" IS_DRUM=");
4756                            if(query.instrumentType == DbSearchQuery.InstrumentType.DRUM) {
4757                                    sb.append("'true'");
4758                            } else {
4759                                    sb.append("'false'");
4760                            }
4761                    }
4762                    
4763                    if(query.product != null && query.product.length() > 0) {
4764                            sb.append(" PRODUCT='").append(toEscapedString(query.product)).append("'");
4765                    }
4766                    
4767                    if(query.artists != null && query.artists.length() > 0) {
4768                            sb.append(" ARTISTS='").append(toEscapedString(query.artists)).append("'");
4769                    }
4770                    
4771                    if(query.keywords != null && query.keywords.length() > 0) {
4772                            sb.append(" KEYWORDS='");
4773                            sb.append(toEscapedString(query.keywords)).append("'");
4774                    }
4775                    
4776                    out.writeLine(sb.toString());
4777                    if(getPrintOnlyMode()) return null;
4778                    
4779                    String[] instrS = parseEscapedStringList(getSingleLineResultSet().getResult());
4780                    
4781                    DbInstrumentInfo[] infoS = new DbInstrumentInfo[instrS.length];
4782                    for(int i = 0; i < instrS.length; i++) {
4783                            infoS[i] = getDbInstrumentInfo(instrS[i]);
4784                    }
4785                    return infoS;
4786            }
4787            
4788            /**
4789             * Gets status information about the specified job.
4790             * @param jobId The ID of the job.
4791             * @return A <code>ScanJobInfo</code> instance providing information
4792             * about the specified job.
4793             * @throws IOException If some I/O error occurs.
4794             * @throws LscpException If LSCP protocol corruption occurs.
4795             * @throws LSException If the specified job is not found.
4796             */
4797            public synchronized ScanJobInfo
4798            getDbInstrumentsJobInfo(int jobId) throws IOException, LscpException, LSException {
4799                    verifyConnection();
4800                    out.writeLine("GET DB_INSTRUMENTS_JOB INFO " + String.valueOf(jobId));
4801                    if(getPrintOnlyMode()) return null;
4802                    
4803                    ResultSet rs = getMultiLineResultSet();
4804                    ScanJobInfo info = new ScanJobInfo(rs.getMultiLineResult());
4805                    
4806                    return info;
4807            }
4808            
4809            /**
4810           * Resets the specified sampler channel.           * Resets the specified sampler channel.
4811           *           *
4812           * @param samplerChn The sampler channel number.           * @param samplerChn The sampler channel number.
# Line 2011  public class Client { Line 4821  public class Client {
4821          resetChannel(int samplerChn) throws IOException, LscpException, LSException {          resetChannel(int samplerChn) throws IOException, LscpException, LSException {
4822                  verifyConnection();                  verifyConnection();
4823                  out.writeLine("RESET CHANNEL " + samplerChn);                  out.writeLine("RESET CHANNEL " + samplerChn);
4824                    if(getPrintOnlyMode()) return;
4825                                    
4826                  ResultSet rs = getEmptyResultSet();                  ResultSet rs = getEmptyResultSet();
4827          }          }
# Line 2025  public class Client { Line 4836  public class Client {
4836          resetSampler() throws IOException, LscpException {          resetSampler() throws IOException, LscpException {
4837                  verifyConnection();                  verifyConnection();
4838                  out.writeLine("RESET");                  out.writeLine("RESET");
4839                    if(getPrintOnlyMode()) return;
4840                    
4841                  try { ResultSet rs = getEmptyResultSet(); }                  try { ResultSet rs = getEmptyResultSet(); }
4842                  catch(LSException x) { getLogger().warning(x.getMessage()); }                  catch(LSException x) { getLogger().warning(x.getMessage()); }
4843          }          }
4844                    
4845          /**          /**
4846             * Gets the current number of all active voices.
4847             * @return The current number of all active voices.
4848             * @throws IOException If some I/O error occurs.
4849             * @throws LscpException If LSCP protocol corruption occurs.
4850             * @throws LSException If some other error occurs.
4851             */
4852            public synchronized int
4853            getTotalVoiceCount() throws IOException, LscpException, LSException {
4854                    verifyConnection();
4855                    out.writeLine("GET TOTAL_VOICE_COUNT");
4856                    if(getPrintOnlyMode()) return -1;
4857                    
4858                    String s = getSingleLineResultSet().getResult();
4859                    return parseInt(s);
4860            }
4861            
4862            /**
4863             * Gets the maximum number of active voices.
4864             * @return The maximum number of active voices.
4865             * @throws IOException If some I/O error occurs.
4866             * @throws LscpException If LSCP protocol corruption occurs.
4867             * @throws LSException If some other error occurs.
4868             */
4869            public synchronized int
4870            getTotalVoiceCountMax() throws IOException, LscpException, LSException {
4871                    verifyConnection();
4872                    out.writeLine("GET TOTAL_VOICE_COUNT_MAX");
4873                    if(getPrintOnlyMode()) return -1;
4874                    
4875                    String s = getSingleLineResultSet().getResult();
4876                    return parseInt(s);
4877            }
4878            
4879            /**
4880           * Gets information about the LinuxSampler instance.           * Gets information about the LinuxSampler instance.
4881           *           *
4882           * @return <code>ServerInfo</code> instance containing           * @return <code>ServerInfo</code> instance containing
# Line 2043  public class Client { Line 4890  public class Client {
4890          getServerInfo() throws IOException, LscpException, LSException {          getServerInfo() throws IOException, LscpException, LSException {
4891                  verifyConnection();                  verifyConnection();
4892                  out.writeLine("GET SERVER INFO");                  out.writeLine("GET SERVER INFO");
4893                    if(getPrintOnlyMode()) return null;
4894                    
4895                  ResultSet rs = getMultiLineResultSet();                  ResultSet rs = getMultiLineResultSet();
4896                  return new ServerInfo(rs.getMultiLineResult());                  return new ServerInfo(rs.getMultiLineResult());
4897          }          }
4898                    
4899          /**          /**
4900             * Gets the golobal volume of the sampler.
4901             * @return The golobal volume of the sampler.
4902             * @throws IOException If some I/O error occurs.
4903             * @throws LscpException If LSCP protocol corruption occurs.
4904             * @throws LSException If some other error occurs.
4905             */
4906            public synchronized float
4907            getVolume() throws IOException, LscpException, LSException {
4908                    verifyConnection();
4909                    out.writeLine("GET VOLUME");
4910                    if(getPrintOnlyMode()) return -1;
4911                    
4912                    String s = getSingleLineResultSet().getResult();
4913                    return parseFloat(s);
4914            }
4915            
4916            /**
4917             * Sets the global volume of the sampler.
4918             * @param volume The new volume value.
4919             * @throws IOException If some I/O error occurs.
4920             * @throws LscpException If LSCP protocol corruption occurs.
4921             * @throws LSException If some other error occurs.
4922             * @see #getVolume
4923             */
4924            public synchronized void
4925            setVolume(float volume) throws IOException, LscpException, LSException {
4926            
4927                    verifyConnection();
4928                    out.writeLine("SET VOLUME " + volume);
4929                    if(getPrintOnlyMode()) return;
4930                    
4931                    ResultSet rs = getEmptyResultSet();
4932            }
4933            
4934            private void
4935            getEmptyResultSets(int count, String err) throws LSException {
4936                    StringBuffer sb = new StringBuffer();
4937                    for(int i = 0; i < count; i++) {
4938                            try { getEmptyResultSet(); }
4939                            catch (SocketTimeoutException e) {
4940                                    getLogger().log(Level.FINE, e.getMessage(), e);
4941                                    sb.append(e.getMessage()).append("\n");
4942                                    break;
4943                            } catch (Exception e) {
4944                                    getLogger().log(Level.FINE, e.getMessage(), e);
4945                                    sb.append(e.getMessage()).append("\n");
4946                            }
4947                    }
4948                    
4949                    String details = sb.toString();
4950                    if(details.length() > 0) {
4951                            String s = LscpI18n.getLogMsg(err);
4952                            throw new LSException(0, s, details);
4953                    }
4954            }
4955            
4956            /**
4957           * Returns the logger for this library.           * Returns the logger for this library.
4958           * @return The logger for this library.           * @return The logger for this library.
4959           */           */

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

  ViewVC Help
Powered by ViewVC