/[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 784 by iliev, Mon Oct 10 14:55:44 2005 UTC revision 1728 by iliev, Tue Apr 29 16:04:42 2008 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-2008 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 v1.0, for more   * instance. Since it implements all commands specified in the LSCP protocol v1.2, for more
45   * information look at the   * information look at the
46   * <a href=http://www.linuxsampler.org/api/lscp-1.0.html>LSCP</a> specification.   * <a href=http://www.linuxsampler.org/api/lscp-1.2.html>LSCP</a> 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 68  public class Client { Line 70  public class Client {
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 83  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 102  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 133  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            private boolean extendedCharacterEscaping = true;
168            
169            /**
170             * Sets whether strings sent to LinuxSampler should be more aggressively escaped.
171             */
172            public synchronized void
173            setExtendedCharacterEscaping(boolean b) { extendedCharacterEscaping = b; }
174            
175            /**
176             * Determines whether strings sent to LinuxSampler should be more aggressively escaped.
177             */
178            public synchronized boolean
179            getExtendedCharacterEscaping() { return extendedCharacterEscaping; }
180            
181            private String
182            toEscapedText(String s) {
183                    s = toEscapedString(s);
184                    return conv(s);
185            }
186            
187            private String
188            toEscapedFsEntry(String s) {
189                    s = toEscapedFileName(s);
190                    return conv(s);
191            }
192            
193            /**
194             * Applies an extended character escaping to the specified string if needed.
195             */
196            private String
197            conv(String s) {
198                    return getExtendedCharacterEscaping() ? toExtendedEscapeSequence(s) : s;
199            }
200            
201            /**
202             * Determines whether the client is in print-only mode.
203             * Print-only mode means that the client will just print all
204             * LSCP commands to the specified output stream or to the standard output stream
205             * (<code>java.lang.System.out</code>) if no output stream is specified,
206             * without taking any further actions. Thus, in print-only mode all returned
207             * values by <code>Client</code>'s methods are meaningless and should be discarded.
208             * @return <code>true</code> if the client is in
209             * print-only mode, <code>false</code> otherwise.
210             * @see #setPrintOnlyModeOutputStream
211             */
212            public synchronized boolean
213            getPrintOnlyMode() { return printOnlyMode; }
214            
215            /**
216             * Sets the print-only mode. Note that in print-only mode all returned
217             * values by <code>Client</code>'s methods are meaningless and should be discarded.
218             * The default output stream in print-only mode is <code>java.lang.System.out</code>.
219             * @param b If <code>true</code> all LSCP commands will be sent
220             * to the specified output stream or to the standard output stream
221             * (<code>java.lang.System.out</code>) if no output stream is specified,
222             * and no further actions will be taken.
223             * @throws IllegalStateException If the client is connected.
224             * @see #setPrintOnlyModeOutputStream
225             */
226            public synchronized void
227            setPrintOnlyMode(boolean b) {
228                    if(printOnlyMode == b) return;
229                    if(isConnected()) throw new IllegalStateException();
230                    
231                    printOnlyMode = b;
232                    if(b) out = new LscpOutputStream(System.out);
233            }
234            
235            /**
236             * Sets the output stream to be used in print-only mode.
237             * @param out The output stream to be used in print-only mode.
238             * @throws IllegalStateException If the client is not in print-only mode.
239             * @throws IllegalArgumentException if <code>out</code> is <code>null</code>.
240             * @see #setPrintOnlyMode
241             */
242            public synchronized void
243            setPrintOnlyModeOutputStream(OutputStream out) {
244                    if(!getPrintOnlyMode()) throw new IllegalStateException("Not in print-only mode");
245                    if(out == null) throw new IllegalArgumentException("out must be non-null");
246                    this.out = new LscpOutputStream(out);
247            }
248            
249            /**
250           * Specifies the jlscp version.           * Specifies the jlscp version.
251           * @return The jlscp version.           * @return The jlscp version.
252           */           */
# Line 180  public class Client { Line 294  public class Client {
294          public synchronized void          public synchronized void
295          connect() throws LscpException {          connect() throws LscpException {
296                  if(sock != null) disconnect();                  if(sock != null) disconnect();
297                    if(getPrintOnlyMode()) return;
298                                    
299                  // Initializing LSCP event thread                  // Initializing LSCP event thread
300                  if(eventThread.isAlive()) {                  if(eventThread.isAlive()) {
# Line 252  public class Client { Line 367  public class Client {
367                  if(hasSubscriptions()) eventThread.start();                  if(hasSubscriptions()) eventThread.start();
368                                    
369                  if(!llM.isEmpty()) subscribe("MISCELLANEOUS");                  if(!llM.isEmpty()) subscribe("MISCELLANEOUS");
370                    if(!llAODC.isEmpty()) subscribe("AUDIO_OUTPUT_DEVICE_COUNT");
371                    if(!llAODI.isEmpty()) subscribe("AUDIO_OUTPUT_DEVICE_INFO");
372                    if(!llMIDC.isEmpty()) subscribe("MIDI_INPUT_DEVICE_COUNT");
373                    if(!llMIDI.isEmpty()) subscribe("MIDI_INPUT_DEVICE_INFO");
374                  if(!llBF.isEmpty()) subscribe("BUFFER_FILL");                  if(!llBF.isEmpty()) subscribe("BUFFER_FILL");
375                  if(!llCC.isEmpty()) subscribe("CHANNEL_COUNT");                  if(!llCC.isEmpty()) subscribe("CHANNEL_COUNT");
376                  if(!llCI.isEmpty()) subscribe("CHANNEL_INFO");                  if(!llCI.isEmpty()) subscribe("CHANNEL_INFO");
377                    if(!llFSC.isEmpty()) subscribe("FX_SEND_COUNT");
378                    if(!llFSI.isEmpty()) subscribe("FX_SEND_INFO");
379                  if(!llSC.isEmpty()) subscribe("STREAM_COUNT");                  if(!llSC.isEmpty()) subscribe("STREAM_COUNT");
380                  if(!llVC.isEmpty()) subscribe("VOICE_COUNT");                  if(!llVC.isEmpty()) subscribe("VOICE_COUNT");
381                    if(!llTSC.isEmpty()) subscribe("TOTAL_STREAM_COUNT");
382                  if(!llTVC.isEmpty()) subscribe("TOTAL_VOICE_COUNT");                  if(!llTVC.isEmpty()) subscribe("TOTAL_VOICE_COUNT");
383                    if(!llMIMC.isEmpty()) subscribe("MIDI_INSTRUMENT_MAP_COUNT");
384                    if(!llMIMI.isEmpty()) subscribe("MIDI_INSTRUMENT_MAP_INFO");
385                    if(!llMIC.isEmpty()) subscribe("MIDI_INSTRUMENT_COUNT");
386                    if(!llMII.isEmpty()) subscribe("MIDI_INSTRUMENT_INFO");
387                    if(!llID.isEmpty()) {
388                            subscribe("DB_INSTRUMENT_DIRECTORY_COUNT");
389                            subscribe("DB_INSTRUMENT_DIRECTORY_INFO");
390                            subscribe("DB_INSTRUMENT_COUNT");
391                            subscribe("DB_INSTRUMENT_INFO");
392                            subscribe("DB_INSTRUMENTS_JOB_INFO");
393                    }
394                    if(!llGI.isEmpty()) subscribe("GLOBAL_INFO");
395          }          }
396                    
397          /**          /**
# Line 265  public class Client { Line 399  public class Client {
399           */           */
400          public synchronized void          public synchronized void
401          disconnect() {          disconnect() {
402                    if(getPrintOnlyMode()) return;
403                  try { if(sock != null) sock.close(); }                  try { if(sock != null) sock.close(); }
404                  catch(Exception x) { getLogger().log(Level.FINE, x.getMessage(), x); }                  catch(Exception x) { getLogger().log(Level.FINE, x.getMessage(), x); }
405                  sock = null;                  sock = null;
# Line 292  public class Client { Line 427  public class Client {
427           */           */
428          private void          private void
429          verifyConnection() throws IOException {          verifyConnection() throws IOException {
430                    if(getPrintOnlyMode()) return;
431                    
432                  if(!isConnected())                  if(!isConnected())
433                          throw new IOException(LscpI18n.getLogMsg("Client.notConnected!"));                          throw new IOException(LscpI18n.getLogMsg("Client.notConnected!"));
434          }          }
# Line 301  public class Client { Line 438  public class Client {
438                  String s;                  String s;
439                  for(;;) {                  for(;;) {
440                          s = in.readLine();                          s = in.readLine();
441                          if(s.startsWith("NOTIFY:")) fireEvent(s.substring("NOTIFY:".length()));                          if(s.startsWith("NOTIFY:")) {
442                                    eventThread.scheduleNotification(s.substring("NOTIFY:".length()));
443                            }
444                          else break;                          else break;
445                  }                  }
446                  return s;                  return s;
447          }          }
448                    
449          /** Processes the notifications send by LinuxSampler */          /** Processes the notifications sent by LinuxSampler */
450          private synchronized void          private synchronized void
451          processNotifications() throws IOException, LscpException {          processNotifications() throws IOException, LscpException {
452                  while(in.available() > 0) {                  while(in.available() > 0) {
# Line 366  public class Client { Line 505  public class Client {
505                  return rs;                  return rs;
506          }          }
507                    
508            /** Audio output device count listeners */
509            private final Vector<ItemCountListener> llAODC = new Vector<ItemCountListener>();
510            /** Audio output device info listeners */
511            private final Vector<ItemInfoListener> llAODI = new Vector<ItemInfoListener>();
512          private final Vector<BufferFillListener> llBF = new Vector<BufferFillListener>();          private final Vector<BufferFillListener> llBF = new Vector<BufferFillListener>();
513          private final Vector<ChannelCountListener> llCC = new Vector<ChannelCountListener>();          private final Vector<ChannelCountListener> llCC = new Vector<ChannelCountListener>();
514          private final Vector<ChannelInfoListener> llCI = new Vector<ChannelInfoListener>();          private final Vector<ChannelInfoListener> llCI = new Vector<ChannelInfoListener>();
515            private final Vector<FxSendCountListener> llFSC = new Vector<FxSendCountListener>();
516            private final Vector<FxSendInfoListener> llFSI = new Vector<FxSendInfoListener>();
517          private final Vector<MiscellaneousListener> llM = new Vector<MiscellaneousListener>();          private final Vector<MiscellaneousListener> llM = new Vector<MiscellaneousListener>();
518            /** MIDI input device count listeners */
519            private final Vector<ItemCountListener> llMIDC = new Vector<ItemCountListener>();
520            /** MIDI input device info listeners */
521            private final Vector<ItemInfoListener> llMIDI = new Vector<ItemInfoListener>();
522          private final Vector<StreamCountListener> llSC = new Vector<StreamCountListener>();          private final Vector<StreamCountListener> llSC = new Vector<StreamCountListener>();
523          private final Vector<VoiceCountListener> llVC = new Vector<VoiceCountListener>();          private final Vector<VoiceCountListener> llVC = new Vector<VoiceCountListener>();
524            private final Vector<TotalStreamCountListener> llTSC = new Vector<TotalStreamCountListener>();
525          private final Vector<TotalVoiceCountListener> llTVC = new Vector<TotalVoiceCountListener>();          private final Vector<TotalVoiceCountListener> llTVC = new Vector<TotalVoiceCountListener>();
526                    
527            /** MIDI instrument map count listeners */
528            private final Vector<ItemCountListener> llMIMC = new Vector<ItemCountListener>();
529            /** MIDI instrument map info listeners */
530            private final Vector<ItemInfoListener> llMIMI = new Vector<ItemInfoListener>();
531            /** MIDI instrument count listeners */
532            private final Vector<MidiInstrumentCountListener> llMIC =
533                    new Vector<MidiInstrumentCountListener>();
534            /** MIDI instrument info listeners */
535            private final Vector<MidiInstrumentInfoListener> llMII =
536                    new Vector<MidiInstrumentInfoListener>();
537            private final Vector<InstrumentsDbListener> llID = new Vector<InstrumentsDbListener>();
538            private final Vector<GlobalInfoListener> llGI = new Vector<GlobalInfoListener>();
539            
540            
541          /**          /**
542           * Determines whether there is at least one subscription for notification events.           * Determines whether there is at least one subscription for notification events.
543           * Do not forget to check for additional listeners if the LSCP specification           * Do not forget to check for additional listeners if the LSCP specification
# Line 383  public class Client { Line 547  public class Client {
547           */           */
548          private boolean          private boolean
549          hasSubscriptions() {          hasSubscriptions() {
550                  return  !llBF.isEmpty() ||                  return  !llAODC.isEmpty() ||
551                          !llCC.isEmpty() ||                          !llAODI.isEmpty() ||
552                          !llCI.isEmpty() ||                          !llBF.isEmpty()   ||
553                          !llM.isEmpty()  ||                          !llCC.isEmpty()   ||
554                          !llSC.isEmpty() ||                          !llCI.isEmpty()   ||
555                          !llVC.isEmpty() ||                          !llFSC.isEmpty()  ||
556                          !llTVC.isEmpty();                          !llFSI.isEmpty()  ||
557                            !llM.isEmpty()    ||
558                            !llMIDC.isEmpty() ||
559                            !llMIDI.isEmpty() ||
560                            !llSC.isEmpty()   ||
561                            !llVC.isEmpty()   ||
562                            !llTSC.isEmpty()  ||
563                            !llTVC.isEmpty()  ||
564                            !llMIMC.isEmpty() ||
565                            !llMIMI.isEmpty() ||
566                            !llMIC.isEmpty()  ||
567                            !llMII.isEmpty()  ||
568                            !llID.isEmpty()   ||
569                            !llGI.isEmpty();
570          }          }
571                    
572          private void          private synchronized void
573          fireEvent(String s) {          fireEvent(String s) {
574                  if(s.startsWith("CHANNEL_COUNT:")) {                   if(s.startsWith("DB_INSTRUMENT_DIRECTORY_COUNT:")) {
575                            s = s.substring("DB_INSTRUMENT_DIRECTORY_COUNT:".length());
576                            InstrumentsDbEvent e = new InstrumentsDbEvent(this, s);
577                            for(InstrumentsDbListener l : llID) l.directoryCountChanged(e);
578                    } else if(s.startsWith("DB_INSTRUMENT_DIRECTORY_INFO:")) {
579                            InstrumentsDbEvent e;
580                            s = s.substring("DB_INSTRUMENT_DIRECTORY_INFO:".length());
581                            if(s.startsWith("NAME ")) {
582                                    String[] list;
583                                    try {
584                                            s = s.substring("NAME ".length());
585                                            list = parseEscapedStringList(s, ' ');
586                                            if(list.length != 2) throw new LscpException();
587                                            list[1] = toNonEscapedString(list[1]);
588                                            e = new InstrumentsDbEvent(this, list[0], list[1]);
589                                            for(InstrumentsDbListener l : llID) {
590                                                    l.directoryNameChanged(e);
591                                            }
592                                    } catch(LscpException x) {
593                                            getLogger().log (
594                                                    Level.WARNING,
595                                                    LscpI18n.getLogMsg("CommandFailed!"),
596                                                    x
597                                            );
598                                    }
599                            } else {
600                                    e = new InstrumentsDbEvent(this, s);
601                                    for(InstrumentsDbListener l : llID) l.directoryInfoChanged(e);
602                            }
603                    } else if(s.startsWith("DB_INSTRUMENT_COUNT:")) {
604                            s = s.substring("DB_INSTRUMENT_COUNT:".length());
605                            InstrumentsDbEvent e = new InstrumentsDbEvent(this, s);
606                            for(InstrumentsDbListener l : llID) l.instrumentCountChanged(e);
607                    } else if(s.startsWith("DB_INSTRUMENT_INFO:")) {
608                            InstrumentsDbEvent e;
609                            s = s.substring("DB_INSTRUMENT_INFO:".length());
610                            if(s.startsWith("NAME ")) {
611                                    String[] list;
612                                    try {
613                                            s = s.substring("NAME ".length());
614                                            list = parseEscapedStringList(s, ' ');
615                                            if(list.length != 2) throw new LscpException();
616                                            list[1] = toNonEscapedString(list[1]);
617                                            e = new InstrumentsDbEvent(this, list[0], list[1]);
618                                            for(InstrumentsDbListener l : llID) {
619                                                    l.instrumentNameChanged(e);
620                                            }
621                                    } catch(LscpException x) {
622                                            getLogger().log (
623                                                    Level.WARNING,
624                                                    LscpI18n.getLogMsg("CommandFailed!"),
625                                                    x
626                                            );
627                                    }
628                            } else {
629                                    e = new InstrumentsDbEvent(this, s);
630                                    for(InstrumentsDbListener l : llID) l.instrumentInfoChanged(e);
631                            }
632                    } else if(s.startsWith("DB_INSTRUMENTS_JOB_INFO:")) {
633                            s = s.substring("DB_INSTRUMENTS_JOB_INFO:".length());
634                            try {
635                                    int i = Integer.parseInt(s);
636                                    InstrumentsDbEvent e = new InstrumentsDbEvent(this, i);
637                                    for(InstrumentsDbListener l : llID) l.jobStatusChanged(e);
638                            } catch(NumberFormatException x) {
639                                    s = "Unknown DB_INSTRUMENTS_JOB_INFO format";
640                                    getLogger().log(Level.WARNING, s, x);
641                            }
642                            
643                    } else if(s.startsWith("CHANNEL_COUNT:")) {
644                          try {                          try {
645                                  int i = Integer.parseInt(s.substring("CHANNEL_COUNT:".length()));                                  int i = Integer.parseInt(s.substring("CHANNEL_COUNT:".length()));
646                                  ChannelCountEvent e = new ChannelCountEvent(this, i);                                  ChannelCountEvent e = new ChannelCountEvent(this, i);
# Line 407  public class Client { Line 653  public class Client {
653                  } else if(s.startsWith("VOICE_COUNT:")) {                  } else if(s.startsWith("VOICE_COUNT:")) {
654                          try {                          try {
655                                  s = s.substring("VOICE_COUNT:".length());                                  s = s.substring("VOICE_COUNT:".length());
656                                  int i = s.indexOf(' ');                                  Integer[] i = parseIntList(s, ' ');
657                                  if(i == -1) {                                  if(i.length != 2) {
658                                          getLogger().warning("Unknown VOICE_COUNT format");                                          getLogger().warning("Unknown VOICE_COUNT format");
659                                          return;                                          return;
660                                  }                                  }
661                                  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);  
662                                  for(VoiceCountListener l : llVC) l.voiceCountChanged(e);                                  for(VoiceCountListener l : llVC) l.voiceCountChanged(e);
663                          } catch(NumberFormatException x) {                          } catch(Exception x) {
664                                  getLogger().log(Level.WARNING, "Unknown VOICE_COUNT format", x);                                  getLogger().log(Level.WARNING, "Unknown VOICE_COUNT format", x);
665                          }                          }
666                  } else if(s.startsWith("STREAM_COUNT:")) {                  } else if(s.startsWith("STREAM_COUNT:")) {
667                          try {                          try {
668                                  s = s.substring("STREAM_COUNT:".length());                                  s = s.substring("STREAM_COUNT:".length());
669                                  int i = s.indexOf(' ');                                  Integer[] i = parseIntList(s, ' ');
670                                  if(i == -1) {                                  if(i.length != 2) {
671                                          getLogger().warning("Unknown STREAM_COUNT format");                                          getLogger().warning("Unknown STREAM_COUNT format");
672                                          return;                                          return;
673                                  }                                  }
674                                  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);  
675                                  for(StreamCountListener l : llSC) l.streamCountChanged(e);                                  for(StreamCountListener l : llSC) l.streamCountChanged(e);
676                          } catch(NumberFormatException x) {                          } catch(Exception x) {
677                                  getLogger().log(Level.WARNING, "Unknown STREAM_COUNT format", x);                                  getLogger().log(Level.WARNING, "Unknown STREAM_COUNT format", x);
678                          }                          }
679                  } else if(s.startsWith("BUFFER_FILL:")) {                  } else if(s.startsWith("BUFFER_FILL:")) {
# Line 439  public class Client { Line 681  public class Client {
681                                  s = s.substring("BUFFER_FILL:".length());                                  s = s.substring("BUFFER_FILL:".length());
682                                  int i = s.indexOf(' ');                                  int i = s.indexOf(' ');
683                                  if(i == -1) {                                  if(i == -1) {
684                                          getLogger().warning("Unknown STREAM_COUNT format");                                          getLogger().warning("Unknown BUFFER_FILL format");
685                                          return;                                          return;
686                                  }                                  }
687                                  int j = Integer.parseInt(s.substring(0, i));                                  int j = Integer.parseInt(s.substring(0, i));
# Line 448  public class Client { Line 690  public class Client {
690                                  BufferFillEvent e = new BufferFillEvent(this, j, v);                                  BufferFillEvent e = new BufferFillEvent(this, j, v);
691                                  for(BufferFillListener l : llBF) l.bufferFillChanged(e);                                  for(BufferFillListener l : llBF) l.bufferFillChanged(e);
692                          } catch(Exception x) {                          } catch(Exception x) {
693                                  getLogger().log(Level.WARNING, "Unknown STREAM_COUNT format", x);                                  getLogger().log(Level.WARNING, "Unknown BUFFER_FILL format", x);
694                          }                          }
695                  } else if(s.startsWith("CHANNEL_INFO:")) {                  } else if(s.startsWith("CHANNEL_INFO:")) {
696                          try {                          try {
# Line 456  public class Client { Line 698  public class Client {
698                                  ChannelInfoEvent e = new ChannelInfoEvent(this, i);                                  ChannelInfoEvent e = new ChannelInfoEvent(this, i);
699                                  for(ChannelInfoListener l : llCI) l.channelInfoChanged(e);                                  for(ChannelInfoListener l : llCI) l.channelInfoChanged(e);
700                          } catch(NumberFormatException x) {                          } catch(NumberFormatException x) {
701                                  getLogger().log(Level.WARNING, "Unknown STREAM_COUNT format", x);                                  getLogger().log(Level.WARNING, "Unknown CHANNEL_INFO format", x);
702                            }
703                    } else if(s.startsWith("TOTAL_STREAM_COUNT:")) {
704                            try {
705                                    s = s.substring("TOTAL_STREAM_COUNT:".length());
706                                    int i = Integer.parseInt(s);
707                                    TotalStreamCountEvent e = new TotalStreamCountEvent(this, i);
708                                    for(TotalStreamCountListener l : llTSC) l.totalStreamCountChanged(e);
709                            } catch(NumberFormatException x) {
710                                    getLogger().log (
711                                            Level.WARNING, "Unknown TOTAL_STREAM_COUNT format", x
712                                    );
713                          }                          }
714                  } else if(s.startsWith("TOTAL_VOICE_COUNT:")) {                  } else if(s.startsWith("TOTAL_VOICE_COUNT:")) {
715                          try {                          try {
# Line 469  public class Client { Line 722  public class Client {
722                                          Level.WARNING, "Unknown TOTAL_VOICE_COUNT format", x                                          Level.WARNING, "Unknown TOTAL_VOICE_COUNT format", x
723                                  );                                  );
724                          }                          }
725                    } else if(s.startsWith("AUDIO_OUTPUT_DEVICE_COUNT:")) {
726                            try {
727                                    s = s.substring("AUDIO_OUTPUT_DEVICE_COUNT:".length());
728                                    int i = Integer.parseInt(s);
729                                    ItemCountEvent e = new ItemCountEvent(this, i);
730                                    for(ItemCountListener l : llAODC) l.itemCountChanged(e);
731                            } catch(NumberFormatException x) {
732                                    getLogger().log (
733                                            Level.WARNING, "Unknown AUDIO_OUTPUT_DEVICE_COUNT format", x
734                                    );
735                            }
736                    } else if(s.startsWith("AUDIO_OUTPUT_DEVICE_INFO:")) {
737                            try {
738                                    s = s.substring("AUDIO_OUTPUT_DEVICE_INFO:".length());
739                                    int i = Integer.parseInt(s);
740                                    ItemInfoEvent e = new ItemInfoEvent(this, i);
741                                    for(ItemInfoListener l : llAODI) l.itemInfoChanged(e);
742                            } catch(NumberFormatException x) {
743                                    getLogger().log (
744                                            Level.WARNING, "Unknown AUDIO_OUTPUT_DEVICE_INFO format", x
745                                    );
746                            }
747                    } else if(s.startsWith("MIDI_INPUT_DEVICE_COUNT:")) {
748                            try {
749                                    s = s.substring("MIDI_INPUT_DEVICE_COUNT:".length());
750                                    int i = Integer.parseInt(s);
751                                    ItemCountEvent e = new ItemCountEvent(this, i);
752                                    for(ItemCountListener l : llMIDC) l.itemCountChanged(e);
753                            } catch(NumberFormatException x) {
754                                    getLogger().log (
755                                            Level.WARNING, "Unknown MIDI_INPUT_DEVICE_COUNT format", x
756                                    );
757                            }
758                    } else if(s.startsWith("MIDI_INPUT_DEVICE_INFO:")) {
759                            try {
760                                    s = s.substring("MIDI_INPUT_DEVICE_INFO:".length());
761                                    int i = Integer.parseInt(s);
762                                    ItemInfoEvent e = new ItemInfoEvent(this, i);
763                                    for(ItemInfoListener l : llMIDI) l.itemInfoChanged(e);
764                            } catch(NumberFormatException x) {
765                                    getLogger().log (
766                                            Level.WARNING, "Unknown MIDI_INPUT_DEVICE_INFO format", x
767                                    );
768                            }
769                    } else if(s.startsWith("MIDI_INSTRUMENT_MAP_COUNT:")) {
770                            try {
771                                    s = s.substring("MIDI_INSTRUMENT_MAP_COUNT:".length());
772                                    int i = Integer.parseInt(s);
773                                    ItemCountEvent e = new ItemCountEvent(this, i);
774                                    for(ItemCountListener l : llMIMC) l.itemCountChanged(e);
775                            } catch(NumberFormatException x) {
776                                    getLogger().log (
777                                            Level.WARNING, "Unknown MIDI_INSTRUMENT_MAP_COUNT format", x
778                                    );
779                            }
780                    } else if(s.startsWith("MIDI_INSTRUMENT_MAP_INFO:")) {
781                            try {
782                                    s = s.substring("MIDI_INSTRUMENT_MAP_INFO:".length());
783                                    int i = Integer.parseInt(s);
784                                    ItemInfoEvent e = new ItemInfoEvent(this, i);
785                                    for(ItemInfoListener l : llMIMI) l.itemInfoChanged(e);
786                            } catch(NumberFormatException x) {
787                                    getLogger().log (
788                                            Level.WARNING, "Unknown MIDI_INSTRUMENT_MAP_INFO format", x
789                                    );
790                            }
791                    } else if(s.startsWith("MIDI_INSTRUMENT_COUNT:")) {
792                            try {
793                                    s = s.substring("MIDI_INSTRUMENT_COUNT:".length());
794                                    Integer[] i = parseIntList(s, ' ');
795                                    if(i.length != 2) {
796                                            getLogger().warning("Unknown MIDI_INSTRUMENT_COUNT format");
797                                            return;
798                                    }
799                                    
800                                    MidiInstrumentCountEvent e =
801                                            new MidiInstrumentCountEvent(this, i[0], i[1]);
802                                    
803                                    for(MidiInstrumentCountListener l : llMIC) {
804                                            l.instrumentCountChanged(e);
805                                    }
806                            } catch(Exception x) {
807                                    getLogger().log (
808                                            Level.WARNING, "Unknown MIDI_INSTRUMENT_COUNT format", x
809                                    );
810                            }
811                    } else if(s.startsWith("MIDI_INSTRUMENT_INFO:")) {
812                            try {
813                                    s = s.substring("MIDI_INSTRUMENT_INFO:".length());
814                                    Integer[] i = parseIntList(s, ' ');
815                                    if(i.length != 3) {
816                                            getLogger().warning("Unknown MIDI_INSTRUMENT_INFO format");
817                                            return;
818                                    }
819                                    
820                                    MidiInstrumentInfoEvent e =
821                                            new MidiInstrumentInfoEvent(this, i[0], i[1], i[2]);
822                                    for(MidiInstrumentInfoListener l : llMII) {
823                                            l.instrumentInfoChanged(e);
824                                    }
825                            } catch(Exception x) {
826                                    getLogger().log (
827                                            Level.WARNING, "Unknown MIDI_INSTRUMENT_INFO format", x
828                                    );
829                            }
830                    } else if(s.startsWith("FX_SEND_COUNT:")) {
831                            try {
832                                    s = s.substring("FX_SEND_COUNT:".length());
833                                    Integer[] i = parseIntList(s, ' ');
834                                    if(i.length != 2) {
835                                            getLogger().warning("Unknown FX_SEND_COUNT format");
836                                            return;
837                                    }
838                                    
839                                    FxSendCountEvent e = new FxSendCountEvent(this, i[0], i[1]);
840                                    
841                                    for(FxSendCountListener l : llFSC) l.fxSendCountChanged(e);
842                            } catch(Exception x) {
843                                    getLogger().log(Level.WARNING, "Unknown FX_SEND_COUNT format", x);
844                            }
845                    } else if(s.startsWith("FX_SEND_INFO:")) {
846                            try {
847                                    s = s.substring("FX_SEND_INFO:".length());
848                                    Integer[] i = parseIntList(s, ' ');
849                                    if(i.length != 2) {
850                                            getLogger().warning("Unknown FX_SEND_INFO format");
851                                            return;
852                                    }
853                                    
854                                    FxSendInfoEvent e = new FxSendInfoEvent(this, i[0], i[1]);
855                                    for(FxSendInfoListener l : llFSI) {
856                                            l.fxSendInfoChanged(e);
857                                    }
858                            } catch(Exception x) {
859                                    getLogger().log(Level.WARNING, "Unknown FX_SEND_INFO format", x);
860                            }
861                    } else if(s.startsWith("GLOBAL_INFO:")) {
862                            handleGlobalInfoEvent(s.substring("GLOBAL_INFO:".length()));
863                  } else if(s.startsWith("MISCELLANEOUS:")) {                  } else if(s.startsWith("MISCELLANEOUS:")) {
864                          s = s.substring("MISCELLANEOUS:".length());                          s = s.substring("MISCELLANEOUS:".length());
865                          MiscellaneousEvent e = new MiscellaneousEvent(this, s);                          MiscellaneousEvent e = new MiscellaneousEvent(this, s);
# Line 477  public class Client { Line 868  public class Client {
868          }          }
869                    
870          private void          private void
871            handleGlobalInfoEvent(String s) {
872                    try {
873                            if(s.startsWith("VOLUME ")) {
874                                    float f = Float.parseFloat(s.substring("VOLUME ".length()));
875                                    GlobalInfoEvent e = new GlobalInfoEvent(this, f);
876                                    for(GlobalInfoListener l : llGI) l.volumeChanged(e);
877                            }
878                    } catch(NumberFormatException x) {
879                            getLogger().log(Level.WARNING, "Unknown GLOBAL_INFO format", x);
880                    }
881            }
882            
883            private void
884          subscribe(String event) {          subscribe(String event) {
885                  if(!isConnected()) return;                  if(!getPrintOnlyMode()) {
886                            if(!isConnected()) return;
887                                    
888                  if(!eventThread.isAlive()) eventThread.start();                          if(!eventThread.isAlive()) eventThread.start();
889                    }
890                                    
891                  try {                  try {
892                          out.writeLine("SUBSCRIBE " + event);                          out.writeLine("SUBSCRIBE " + event);
893                          ResultSet rs = getEmptyResultSet();                          if(!getPrintOnlyMode()) getEmptyResultSet();
894                  } catch(Exception x) {                  } catch(Exception x) {
895                          getLogger().log (                          getLogger().log (
896                                  Level.WARNING,                                  Level.WARNING,
# Line 496  public class Client { Line 902  public class Client {
902                    
903          private void          private void
904          unsubscribe(String event) {          unsubscribe(String event) {
905                  if(!isConnected()) return;                  if(!getPrintOnlyMode() && !isConnected()) return;
906                                    
907                  try {                  try {
908                          out.writeLine("UNSUBSCRIBE " + event);                          out.writeLine("UNSUBSCRIBE " + event);
909                          ResultSet rs = getEmptyResultSet();                          if(!getPrintOnlyMode()) getEmptyResultSet();
910                  } catch(Exception x) {                  } catch(Exception x) {
911                          getLogger().log (                          getLogger().log (
912                                  Level.WARNING,                                  Level.WARNING,
# Line 512  public class Client { Line 918  public class Client {
918                    
919          /**          /**
920           * Registers the specified listener for receiving event messages.           * Registers the specified listener for receiving event messages.
921             * Listeners can be registered regardless of the connection state.
922             * @param l The <code>ItemCountListener</code> to register.
923             */
924            public synchronized void
925            addAudioDeviceCountListener(ItemCountListener l) {
926                    if(llAODC.isEmpty()) subscribe("AUDIO_OUTPUT_DEVICE_COUNT");
927                    llAODC.add(l);
928            }
929            
930            /**
931             * Removes the specified listener.
932             * Listeners can be removed regardless of the connection state.
933             * @param l The <code>ItemCountListener</code> to remove.
934             */
935            public synchronized void
936            removeAudioDeviceCountListener(ItemCountListener l) {
937                    boolean b = llAODC.remove(l);
938                    if(b && llAODC.isEmpty()) unsubscribe("AUDIO_OUTPUT_DEVICE_COUNT");
939            }
940            
941            /**
942             * Registers the specified listener for receiving event messages.
943             * Listeners can be registered regardless of the connection state.
944             * @param l The <code>ItemInfoListener</code> to register.
945             */
946            public synchronized void
947            addAudioDeviceInfoListener(ItemInfoListener l) {
948                    if(llAODI.isEmpty()) subscribe("AUDIO_OUTPUT_DEVICE_INFO");
949                    llAODI.add(l);
950            }
951            
952            /**
953             * Removes the specified listener.
954             * Listeners can be removed regardless of the connection state.
955             * @param l The <code>ItemInfoListener</code> to remove.
956             */
957            public synchronized void
958            removeAudioDeviceInfoListener(ItemInfoListener l) {
959                    boolean b = llAODI.remove(l);
960                    if(b && llAODI.isEmpty()) unsubscribe("AUDIO_OUTPUT_DEVICE_INFO");
961            }
962            
963            /**
964             * Registers the specified listener for receiving event messages.
965           * Listeners can be removed regardless of the connection state.           * Listeners can be removed regardless of the connection state.
966           * @param l The <code>BufferFillListener</code> to register.           * @param l The <code>BufferFillListener</code> to register.
967           */           */
# Line 579  public class Client { Line 1029  public class Client {
1029          /**          /**
1030           * Registers the specified listener for receiving event messages.           * Registers the specified listener for receiving event messages.
1031           * Listeners can be registered regardless of the connection state.           * Listeners can be registered regardless of the connection state.
1032             * @param l The <code>FxSendCountListener</code> to register.
1033             */
1034            public synchronized void
1035            addFxSendCountListener(FxSendCountListener l) {
1036                    if(llFSC.isEmpty()) subscribe("FX_SEND_COUNT");
1037                    llFSC.add(l);
1038            }
1039            
1040            /**
1041             * Removes the specified listener.
1042             * Listeners can be removed regardless of the connection state.
1043             * @param l The <code>FxSendCountListener</code> to remove.
1044             */
1045            public synchronized void
1046            removeFxSendCountListener(FxSendCountListener l) {
1047                    boolean b = llFSC.remove(l);
1048                    if(b && llFSC.isEmpty()) unsubscribe("FX_SEND_COUNT");
1049            }
1050            
1051            /**
1052             * Registers the specified listener for receiving event messages.
1053             * Listeners can be registered regardless of the connection state.
1054             * @param l The <code>FxSendInfoListener</code> to register.
1055             */
1056            public synchronized void
1057            addFxSendInfoListener(FxSendInfoListener l) {
1058                    if(llFSI.isEmpty()) subscribe("FX_SEND_INFO");
1059                    llFSI.add(l);
1060            }
1061            
1062            /**
1063             * Removes the specified listener.
1064             * Listeners can be removed regardless of the connection state.
1065             * @param l The <code>FxSendInfoListener</code> to remove.
1066             */
1067            public synchronized void
1068            removeFxSendInfoListener(FxSendInfoListener l) {
1069                    boolean b = llFSI.remove(l);
1070                    if(b && llFSI.isEmpty()) unsubscribe("FX_SEND_INFO");
1071            }
1072            
1073            /**
1074             * Registers the specified listener for receiving event messages.
1075             * Listeners can be registered regardless of the connection state.
1076             * @param l The <code>ItemCountListener</code> to register.
1077             */
1078            public synchronized void
1079            addMidiDeviceCountListener(ItemCountListener l) {
1080                    if(llMIDC.isEmpty()) subscribe("MIDI_INPUT_DEVICE_COUNT");
1081                    llMIDC.add(l);
1082            }
1083            
1084            /**
1085             * Removes the specified listener.
1086             * Listeners can be removed regardless of the connection state.
1087             * @param l The <code>ItemCountListener</code> to remove.
1088             */
1089            public synchronized void
1090            removeMidiDeviceCountListener(ItemCountListener l) {
1091                    boolean b = llMIDC.remove(l);
1092                    if(b && llMIDC.isEmpty()) unsubscribe("MIDI_INPUT_DEVICE_COUNT");
1093            }
1094            
1095            /**
1096             * Registers the specified listener for receiving event messages.
1097             * Listeners can be registered regardless of the connection state.
1098             * @param l The <code>ItemInfoListener</code> to register.
1099             */
1100            public synchronized void
1101            addMidiDeviceInfoListener(ItemInfoListener l) {
1102                    if(llMIDI.isEmpty()) subscribe("MIDI_INPUT_DEVICE_INFO");
1103                    llMIDI.add(l);
1104            }
1105            
1106            /**
1107             * Removes the specified listener.
1108             * Listeners can be removed regardless of the connection state.
1109             * @param l The <code>ItemInfoListener</code> to remove.
1110             */
1111            public synchronized void
1112            removeMidiDeviceInfoListener(ItemInfoListener l) {
1113                    boolean b = llMIDI.remove(l);
1114                    if(b && llMIDI.isEmpty()) unsubscribe("MIDI_INPUT_DEVICE_INFO");
1115            }
1116            
1117            /**
1118             * Registers the specified listener for receiving event messages.
1119             * Listeners can be registered regardless of the connection state.
1120           * @param l The <code>MiscellaneousListener</code> to register.           * @param l The <code>MiscellaneousListener</code> to register.
1121           */           */
1122          public synchronized void          public synchronized void
# Line 645  public class Client { Line 1183  public class Client {
1183          /**          /**
1184           * Registers the specified listener for receiving event messages.           * Registers the specified listener for receiving event messages.
1185           * Listeners can be registered regardless of the connection state.           * Listeners can be registered regardless of the connection state.
1186             * @param l The <code>TotalStreamCountListener</code> to register.
1187             */
1188            public synchronized void
1189            addTotalStreamCountListener(TotalStreamCountListener l) {
1190                    if(llTSC.isEmpty()) subscribe("TOTAL_STREAM_COUNT");
1191                    llTSC.add(l);
1192            }
1193            
1194            /**
1195             * Removes the specified listener.
1196             * Listeners can be removed regardless of the connection state.
1197             * @param l The <code>TotalStreamCountListener</code> to remove.
1198             */
1199            public synchronized void
1200            removeTotalStreamCountListener(TotalStreamCountListener l) {
1201                    boolean b = llTSC.remove(l);
1202                    if(b && llTSC.isEmpty()) unsubscribe("TOTAL_STREAM_COUNT");
1203            }
1204            
1205            /**
1206             * Registers the specified listener for receiving event messages.
1207             * Listeners can be registered regardless of the connection state.
1208           * @param l The <code>TotalVoiceCountListener</code> to register.           * @param l The <code>TotalVoiceCountListener</code> to register.
1209           */           */
1210          public synchronized void          public synchronized void
# Line 665  public class Client { Line 1225  public class Client {
1225          }          }
1226                    
1227          /**          /**
1228             * Registers the specified listener for receiving event messages.
1229             * Listeners can be registered regardless of the connection state.
1230             * @param l The <code>ItemCountListener</code> to register.
1231             */
1232            public synchronized void
1233            addMidiInstrumentMapCountListener(ItemCountListener l) {
1234                    if(llMIMC.isEmpty()) subscribe("MIDI_INSTRUMENT_MAP_COUNT");
1235                    llMIMC.add(l);
1236            }
1237            
1238            /**
1239             * Removes the specified listener.
1240             * Listeners can be removed regardless of the connection state.
1241             * @param l The <code>ItemCountListener</code> to remove.
1242             */
1243            public synchronized void
1244            removeMidiInstrumentMapCountListener(ItemCountListener l) {
1245                    boolean b = llMIMC.remove(l);
1246                    if(b && llMIMC.isEmpty()) unsubscribe("MIDI_INSTRUMENT_MAP_COUNT");
1247            }
1248            
1249            /**
1250             * Registers the specified listener for receiving event messages.
1251             * Listeners can be registered regardless of the connection state.
1252             * @param l The <code>ItemInfoListener</code> to register.
1253             */
1254            public synchronized void
1255            addMidiInstrumentMapInfoListener(ItemInfoListener l) {
1256                    if(llMIMI.isEmpty()) subscribe("MIDI_INSTRUMENT_MAP_INFO");
1257                    llMIMI.add(l);
1258            }
1259            
1260            /**
1261             * Removes the specified listener.
1262             * Listeners can be removed regardless of the connection state.
1263             * @param l The <code>ItemInfoListener</code> to remove.
1264             */
1265            public synchronized void
1266            removeMidiInstrumentMapInfoListener(ItemInfoListener l) {
1267                    boolean b = llMIMI.remove(l);
1268                    if(b && llMIMI.isEmpty()) unsubscribe("MIDI_INSTRUMENT_MAP_INFO");
1269            }
1270            
1271            /**
1272             * Registers the specified listener for receiving event messages.
1273             * Listeners can be registered regardless of the connection state.
1274             * @param l The <code>MidiInstrumentCountListener</code> to register.
1275             */
1276            public synchronized void
1277            addMidiInstrumentCountListener(MidiInstrumentCountListener l) {
1278                    if(llMIC.isEmpty()) subscribe("MIDI_INSTRUMENT_COUNT");
1279                    llMIC.add(l);
1280            }
1281            
1282            /**
1283             * Removes the specified listener.
1284             * Listeners can be removed regardless of the connection state.
1285             * @param l The <code>MidiInstrumentCountListener</code> to remove.
1286             */
1287            public synchronized void
1288            removeMidiInstrumentCountListener(MidiInstrumentCountListener l) {
1289                    boolean b = llMIC.remove(l);
1290                    if(b && llMIC.isEmpty()) unsubscribe("MIDI_INSTRUMENT_COUNT");
1291            }
1292            
1293            /**
1294             * Registers the specified listener for receiving event messages.
1295             * Listeners can be registered regardless of the connection state.
1296             * @param l The <code>MidiInstrumentInfoListener</code> to register.
1297             */
1298            public synchronized void
1299            addMidiInstrumentInfoListener(MidiInstrumentInfoListener l) {
1300                    if(llMII.isEmpty()) subscribe("MIDI_INSTRUMENT_INFO");
1301                    llMII.add(l);
1302            }
1303            
1304            /**
1305             * Removes the specified listener.
1306             * Listeners can be removed regardless of the connection state.
1307             * @param l The <code>MidiInstrumentInfoListener</code> to remove.
1308             */
1309            public synchronized void
1310            removeMidiInstrumentInfoListener(MidiInstrumentInfoListener l) {
1311                    boolean b = llMII.remove(l);
1312                    if(b && llMII.isEmpty()) unsubscribe("MIDI_INSTRUMENT_INFO");
1313            }
1314            
1315            /**
1316             * Registers the specified listener for receiving event messages.
1317             * Listeners can be registered regardless of the connection state.
1318             * @param l The <code>InstrumentsDbListener</code> to register.
1319             */
1320            public synchronized void
1321            addInstrumentsDbListener(InstrumentsDbListener l) {
1322                    if(llID.isEmpty()) {
1323                            subscribe("DB_INSTRUMENT_DIRECTORY_COUNT");
1324                            subscribe("DB_INSTRUMENT_DIRECTORY_INFO");
1325                            subscribe("DB_INSTRUMENT_COUNT");
1326                            subscribe("DB_INSTRUMENT_INFO");
1327                            subscribe("DB_INSTRUMENTS_JOB_INFO");
1328                    }
1329                    llID.add(l);
1330            }
1331            
1332            /**
1333             * Removes the specified listener.
1334             * Listeners can be removed regardless of the connection state.
1335             * @param l The <code>InstrumentsDbListener</code> to remove.
1336             */
1337            public synchronized void
1338            removeInstrumentsDbListener(InstrumentsDbListener l) {
1339                    boolean b = llID.remove(l);
1340                    if(b && llID.isEmpty()) {
1341                            unsubscribe("DB_INSTRUMENT_DIRECTORY_COUNT");
1342                            unsubscribe("DB_INSTRUMENT_DIRECTORY_INFO");
1343                            unsubscribe("DB_INSTRUMENT_COUNT");
1344                            unsubscribe("DB_INSTRUMENT_INFO");
1345                            unsubscribe("DB_INSTRUMENTS_JOB_INFO");
1346                    }
1347            }
1348            
1349            /**
1350             * Registers the specified listener for receiving event messages.
1351             * Listeners can be registered regardless of the connection state.
1352             * @param l The <code>GlobalInfoListener</code> to register.
1353             */
1354            public synchronized void
1355            addGlobalInfoListener(GlobalInfoListener l) {
1356                    if(llGI.isEmpty()) subscribe("GLOBAL_INFO");
1357                    llGI.add(l);
1358            }
1359            
1360            /**
1361             * Removes the specified listener.
1362             * Listeners can be removed regardless of the connection state.
1363             * @param l The <code>GlobalInfoListener</code> to remove.
1364             */
1365            public synchronized void
1366            removeGlobalInfoListener(GlobalInfoListener l) {
1367                    boolean b = llGI.remove(l);
1368                    if(b && llGI.isEmpty()) unsubscribe("GLOBAL_INFO");
1369            }
1370            
1371            /**
1372           * Gets the number of all audio output drivers currently           * Gets the number of all audio output drivers currently
1373           * available for the LinuxSampler instance.           * available for the LinuxSampler instance.
1374           * @return The number of all audio output drivers currently           * @return The number of all audio output drivers currently
# Line 677  public class Client { Line 1381  public class Client {
1381          getAudioOutputDriverCount() throws IOException, LscpException, LSException {          getAudioOutputDriverCount() throws IOException, LscpException, LSException {
1382                  verifyConnection();                  verifyConnection();
1383                  out.writeLine("GET AVAILABLE_AUDIO_OUTPUT_DRIVERS");                  out.writeLine("GET AVAILABLE_AUDIO_OUTPUT_DRIVERS");
1384                    
1385                    if(getPrintOnlyMode()) return -1;
1386                    
1387                  String s = getSingleLineResultSet().getResult();                  String s = getSingleLineResultSet().getResult();
1388                  return parseInt(s);                  return parseInt(s);
1389          }          }
# Line 694  public class Client { Line 1401  public class Client {
1401          public synchronized AudioOutputDriver[]          public synchronized AudioOutputDriver[]
1402          getAudioOutputDrivers() throws IOException, LscpException, LSException {          getAudioOutputDrivers() throws IOException, LscpException, LSException {
1403                  String[] drivers = getAudioOutputDriverNames();                  String[] drivers = getAudioOutputDriverNames();
1404                    if(getPrintOnlyMode()) return null;
1405                    
1406                  AudioOutputDriver[] aod = new AudioOutputDriver[drivers.length];                  AudioOutputDriver[] aod = new AudioOutputDriver[drivers.length];
1407                                    
1408                  for(int i = 0; i < aod.length; i++) aod[i] = getAudioOutputDriverInfo(drivers[i]);                  for(int i = 0; i < aod.length; i++) aod[i] = getAudioOutputDriverInfo(drivers[i]);
# Line 715  public class Client { Line 1424  public class Client {
1424          getAudioOutputDriverNames() throws IOException, LscpException, LSException {          getAudioOutputDriverNames() throws IOException, LscpException, LSException {
1425                  verifyConnection();                  verifyConnection();
1426                  out.writeLine("LIST AVAILABLE_AUDIO_OUTPUT_DRIVERS");                  out.writeLine("LIST AVAILABLE_AUDIO_OUTPUT_DRIVERS");
1427                    if(getPrintOnlyMode()) return null;
1428                  return parseList(getSingleLineResultSet().getResult());                  return parseList(getSingleLineResultSet().getResult());
1429          }          }
1430                    
1431          /**          /**
1432           * Gets detailed information about a specific audio output driver.           * Gets detailed information about a specific audio output driver.
1433           * @param driverName The name of the audio output driver.           * @param driverName The name of the audio output driver.
1434           *           * @param depList An optional list of dependences parameters.
1435           * @return An <code>AudioOutputDriver</code> object containing           * @return An <code>AudioOutputDriver</code> object containing
1436           * information about the specified audio output driver.           * information about the specified audio output driver.
1437           *           *
# Line 731  public class Client { Line 1441  public class Client {
1441           *           *
1442           * @see #getAudioOutputDriverNames           * @see #getAudioOutputDriverNames
1443           */           */
1444          private synchronized AudioOutputDriver          public synchronized AudioOutputDriver
1445          getAudioOutputDriverInfo(String driverName) throws IOException, LscpException, LSException {          getAudioOutputDriverInfo(String driverName, Parameter... depList)
1446                                            throws IOException, LscpException, LSException {
1447                    
1448                  verifyConnection();                  verifyConnection();
1449                  out.writeLine("GET AUDIO_OUTPUT_DRIVER INFO " + driverName);                  out.writeLine("GET AUDIO_OUTPUT_DRIVER INFO " + driverName);
1450                    if(getPrintOnlyMode()) return null;
1451                    
1452                  ResultSet rs = getMultiLineResultSet();                  ResultSet rs = getMultiLineResultSet();
1453                  AudioOutputDriver aod = new AudioOutputDriver(rs.getMultiLineResult());                  AudioOutputDriver aod = new AudioOutputDriver(rs.getMultiLineResult());
1454                  aod.setName(driverName);                  aod.setName(driverName);
1455                                    
1456                  for(String s : aod.getParameterNames())                  for(String s : aod.getParameterNames())
1457                          aod.addParameter(getAudioOutputDriverParameterInfo(driverName, s));                          aod.addParameter(getAudioOutputDriverParameterInfo(driverName, s, depList));
1458                                    
1459                  return aod;                  return aod;
1460          }          }
# Line 774  public class Client { Line 1488  public class Client {
1488                  StringBuffer args = new StringBuffer(driver);                  StringBuffer args = new StringBuffer(driver);
1489                  args.append(' ').append(param);                  args.append(' ').append(param);
1490                                    
1491                  for(Parameter p : deplist)                  for(Parameter p : deplist) {
1492                            if(p == null || p.getName() == null || p.getValue() == null) continue;
1493                          args.append(' ').append(p.getName()).append('=').append(p.getStringValue());                          args.append(' ').append(p.getName()).append('=').append(p.getStringValue());
1494                    }
1495                                    
1496                  out.writeLine("GET AUDIO_OUTPUT_DRIVER_PARAMETER INFO " + args.toString());                  out.writeLine("GET AUDIO_OUTPUT_DRIVER_PARAMETER INFO " + args.toString());
1497                    if(getPrintOnlyMode()) return null;
1498                                    
1499                  ResultSet rs = getMultiLineResultSet();                  ResultSet rs = getMultiLineResultSet();
1500                                    
# Line 835  public class Client { Line 1552  public class Client {
1552                  verifyConnection();                  verifyConnection();
1553                  StringBuffer args = new StringBuffer(aoDriver);                  StringBuffer args = new StringBuffer(aoDriver);
1554                                    
1555                  for(Parameter p : paramList)                  for(Parameter p : paramList) {
1556                            if(p == null || p.getName() == null || p.getValue() == null) continue;
1557                          args.append(' ').append(p.getName()).append('=').append(p.getStringValue());                          args.append(' ').append(p.getName()).append('=').append(p.getStringValue());
1558                    }
1559                                    
1560                  out.writeLine("CREATE AUDIO_OUTPUT_DEVICE " + args.toString());                  out.writeLine("CREATE AUDIO_OUTPUT_DEVICE " + args.toString());
1561                    if(getPrintOnlyMode()) return -1;
1562                    
1563                  ResultSet rs = getEmptyResultSet();                  ResultSet rs = getEmptyResultSet();
1564                                    
1565                  return rs.getIndex();                  return rs.getIndex();
# Line 846  public class Client { Line 1567  public class Client {
1567                    
1568          /**          /**
1569           * Destroys already created audio output device.           * Destroys already created audio output device.
1570           * @param deviceID The ID of the audio output device to be destroyed.           * @param deviceId The ID of the audio output device to be destroyed.
1571           * @throws IOException If some I/O error occurs.           * @throws IOException If some I/O error occurs.
1572           * @throws LSException If the destroying of the audio output device failed.           * @throws LSException If the destroying of the audio output device failed.
1573           * @throws LscpException If LSCP protocol corruption occurs.           * @throws LscpException If LSCP protocol corruption occurs.
1574           * @see #getAudioOutputDevices           * @see #getAudioOutputDevices
1575           */           */
1576          public synchronized void          public synchronized void
1577          destroyAudioOutputDevice(int deviceID) throws IOException, LSException, LscpException {          destroyAudioOutputDevice(int deviceId) throws IOException, LSException, LscpException {
1578                  verifyConnection();                  verifyConnection();
1579                  out.writeLine("DESTROY AUDIO_OUTPUT_DEVICE " + deviceID);                  out.writeLine("DESTROY AUDIO_OUTPUT_DEVICE " + deviceId);
1580                    if(getPrintOnlyMode()) return;
1581                    
1582                  ResultSet rs = getEmptyResultSet();                  ResultSet rs = getEmptyResultSet();
1583          }          }
1584                    
1585          /**          /**
1586           * Enables/disables the specified audio output device.           * Enables/disables the specified audio output device.
1587           * @param deviceID The ID of the audio output device to be enabled/disabled.           * @param deviceId The ID of the audio output device to be enabled/disabled.
1588           * @param enable If <code>true</code> the audio output device is enabled,           * @param enable If <code>true</code> the audio output device is enabled,
1589           * else the device is disabled.           * else the device is disabled.
1590           * @throws IOException If some I/O error occurs.           * @throws IOException If some I/O error occurs.
1591           * @throws LSException If there is no audio output           * @throws LSException If there is no audio output
1592           * device with numerical ID <code>deviceID</code>.           * device with numerical ID <code>deviceId</code>.
1593           * @throws LscpException If LSCP protocol corruption occurs.           * @throws LscpException If LSCP protocol corruption occurs.
1594           */           */
1595          public void          public void
1596          enableAudioOutputDevice(int deviceID, boolean enable)          enableAudioOutputDevice(int deviceId, boolean enable)
1597                                  throws IOException, LSException, LscpException {                                  throws IOException, LSException, LscpException {
1598                                    
1599                  setAudioOutputDeviceParameter(deviceID, new BoolParameter("ACTIVE", enable));                  setAudioOutputDeviceParameter(deviceId, new BoolParameter("ACTIVE", enable));
1600          }          }
1601                    
1602          /**          /**
# Line 887  public class Client { Line 1610  public class Client {
1610          getAudioOutputDeviceCount() throws IOException, LscpException, LSException {          getAudioOutputDeviceCount() throws IOException, LscpException, LSException {
1611                  verifyConnection();                  verifyConnection();
1612                  out.writeLine("GET AUDIO_OUTPUT_DEVICES");                  out.writeLine("GET AUDIO_OUTPUT_DEVICES");
1613                    if(getPrintOnlyMode()) return -1;
1614                    
1615                  String s = getSingleLineResultSet().getResult();                  String s = getSingleLineResultSet().getResult();
1616                  return parseInt(s);                  return parseInt(s);
1617          }          }
# Line 902  public class Client { Line 1627  public class Client {
1627          public synchronized AudioOutputDevice[]          public synchronized AudioOutputDevice[]
1628          getAudioOutputDevices() throws IOException, LscpException, LSException {          getAudioOutputDevices() throws IOException, LscpException, LSException {
1629                  Integer[] idS = getAudioOutputDeviceIDs();                  Integer[] idS = getAudioOutputDeviceIDs();
1630                    if(getPrintOnlyMode()) return null;
1631                    
1632                  AudioOutputDevice[] devices = new AudioOutputDevice[idS.length];                  AudioOutputDevice[] devices = new AudioOutputDevice[idS.length];
1633                                    
1634                  for(int i = 0; i < devices.length; i++)                  for(int i = 0; i < devices.length; i++)
# Line 922  public class Client { Line 1649  public class Client {
1649          getAudioOutputDeviceIDs() throws IOException, LscpException, LSException {          getAudioOutputDeviceIDs() throws IOException, LscpException, LSException {
1650                  verifyConnection();                  verifyConnection();
1651                  out.writeLine("LIST AUDIO_OUTPUT_DEVICES");                  out.writeLine("LIST AUDIO_OUTPUT_DEVICES");
1652                    if(getPrintOnlyMode()) return null;
1653                    
1654                  return parseIntList(getSingleLineResultSet().getResult());                  return parseIntList(getSingleLineResultSet().getResult());
1655          }          }
1656                    
1657          /**          /**
1658           * Gets the current settings of a specific, already created audio output device.           * Gets the current settings of a specific, already created audio output device.
1659           *           *
1660           * @param deviceID Specifies the numerical ID of the audio output device.           * @param deviceId Specifies the numerical ID of the audio output device.
1661           *           *
1662           * @return An <code>AudioOutputDevice</code> instance containing information           * @return An <code>AudioOutputDevice</code> instance containing information
1663           * about the specified device.           * about the specified device.
# Line 936  public class Client { Line 1665  public class Client {
1665           * @throws IOException If some I/O error occurs.           * @throws IOException If some I/O error occurs.
1666           * @throws LscpException If LSCP protocol corruption occurs.           * @throws LscpException If LSCP protocol corruption occurs.
1667           * @throws LSException If there is no audio output device           * @throws LSException If there is no audio output device
1668           * with device id <code>deviceID</code>.           * with device id <code>deviceId</code>.
1669           *           *
1670           * @see #getAudioOutputDevices           * @see #getAudioOutputDevices
1671           */           */
1672          public synchronized AudioOutputDevice          public synchronized AudioOutputDevice
1673          getAudioOutputDeviceInfo(int deviceID) throws IOException, LscpException, LSException {          getAudioOutputDeviceInfo(int deviceId) throws IOException, LscpException, LSException {
1674                  verifyConnection();                  verifyConnection();
1675                  out.writeLine("GET AUDIO_OUTPUT_DEVICE INFO " + deviceID);                  out.writeLine("GET AUDIO_OUTPUT_DEVICE INFO " + deviceId);
1676                    if(getPrintOnlyMode()) return null;
1677                                    
1678                  ResultSet rs = getMultiLineResultSet();                  ResultSet rs = getMultiLineResultSet();
1679                                    
1680                  String[] lnS = rs.getMultiLineResult();                  String[] lnS = rs.getMultiLineResult();
1681                                    
1682                  AudioOutputDevice aod = new AudioOutputDevice();                  AudioOutputDevice aod = new AudioOutputDevice();
1683                  aod.setDeviceID(deviceID);                  aod.setDeviceId(deviceId);
1684                  Parameter<Integer> channels;                  Parameter<Integer> channels;
1685                  Parameter<Integer> samplerate;                  Parameter<Integer> samplerate;
1686                                    
# Line 968  public class Client { Line 1698  public class Client {
1698                                  int count = channels.getValue() > 0 ? channels.getValue() : 0;                                  int count = channels.getValue() > 0 ? channels.getValue() : 0;
1699                                  AudioOutputChannel[] aoc = new AudioOutputChannel[count];                                  AudioOutputChannel[] aoc = new AudioOutputChannel[count];
1700                                  for(int i = 0; i < count; i++) {                                  for(int i = 0; i < count; i++) {
1701                                          aoc[i] = this.getAudioOutputChannelInfo(deviceID, i);                                          aoc[i] = getAudioOutputChannelInfo(deviceId, i);
1702                                  }                                  }
1703                                  aod.setAudioChannels(aoc);                                  aod.setAudioChannels(aoc);
1704                          } else if(s.startsWith("SAMPLERATE: ")) {                          } else if(s.startsWith("SAMPLERATE: ")) {
# Line 1005  public class Client { Line 1735  public class Client {
1735          /**          /**
1736           * Alters a specific setting of a created audio output device.           * Alters a specific setting of a created audio output device.
1737           *           *
1738           * @param deviceID The numerical ID of the audio output device.           * @param deviceId The numerical ID of the audio output device.
1739           * @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
1740           * and the new value for this parameter.           * and the new value for this parameter.
1741           *           *
# Line 1013  public class Client { Line 1743  public class Client {
1743           * @throws LscpException If LSCP protocol corruption occurs.           * @throws LscpException If LSCP protocol corruption occurs.
1744           * @throws LSException If           * @throws LSException If
1745           * <ul>           * <ul>
1746           * <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>;
1747           * <li>There is no device parameter with the specified name;           * <li>There is no device parameter with the specified name;
1748           * <li>The device parameter is readonly;           * <li>The device parameter is readonly;
1749           * <li>The device parameter is from different type.           * <li>The device parameter is from different type.
# Line 1023  public class Client { Line 1753  public class Client {
1753           * @see #getAudioOutputDeviceInfo           * @see #getAudioOutputDeviceInfo
1754           */           */
1755          public synchronized void          public synchronized void
1756          setAudioOutputDeviceParameter(int deviceID, Parameter prm)          setAudioOutputDeviceParameter(int deviceId, Parameter prm)
1757                                                  throws IOException, LscpException, LSException {                                                  throws IOException, LscpException, LSException {
1758                                    
1759                  verifyConnection();                  verifyConnection();
1760                  String kv = prm.getName() + '=' + prm.getStringValue();                  String kv = prm.getName() + '=' + prm.getStringValue();
1761                  out.writeLine("SET AUDIO_OUTPUT_DEVICE_PARAMETER " + deviceID + ' ' + kv);                  out.writeLine("SET AUDIO_OUTPUT_DEVICE_PARAMETER " + deviceId + ' ' + kv);
1762                    if(getPrintOnlyMode()) return;
1763                                    
1764                  ResultSet rs = getEmptyResultSet();                  ResultSet rs = getEmptyResultSet();
1765          }          }
1766                    
1767          /**          /**
1768           * Changes the channels number of the speicifed audio output device.           * Changes the channel number of the speicifed audio output device.
1769           * @param deviceID The numerical ID of the audio output device.           * @param deviceId The numerical ID of the audio output device.
1770           * @param channels The new number of audio output channels.           * @param channels The new number of audio output channels.
1771           *           *
1772           * @throws IOException If an I/O error occurs.           * @throws IOException If an I/O error occurs.
1773           * @throws LscpException If LSCP protocol corruption occurs.           * @throws LscpException If LSCP protocol corruption occurs.
1774           * @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
1775           * if <code>channels</code> number is out of range.           * if <code>channels</code> number is out of range.
1776           *           *
1777           * @see #getAudioOutputChannelInfo           * @see #getAudioOutputChannelInfo
1778           */           */
1779          public synchronized void          public synchronized void
1780          setAudioOutputChannelCount(int deviceID, int channels)          setAudioOutputChannelCount(int deviceId, int channels)
1781                                          throws IOException, LscpException, LSException {                                          throws IOException, LscpException, LSException {
1782                                    
1783                  setAudioOutputDeviceParameter(deviceID, new IntParameter("CHANNELS", channels));                  setAudioOutputDeviceParameter(deviceId, new IntParameter("CHANNELS", channels));
1784          }          }
1785                    
1786          /**          /**
1787           * Gets information about an audio channel.           * Gets information about an audio channel.
1788           *           *
1789           * @param deviceID The numerical ID of the audio output device.           * @param deviceId The numerical ID of the audio output device.
1790           * @param audioChn The audio channel number.           * @param audioChn The audio channel number.
1791           *           *
1792           * @return An <code>AudioOutputChannel</code> instance containing the           * @return An <code>AudioOutputChannel</code> instance containing the
# Line 1065  public class Client { Line 1796  public class Client {
1796           * @throws LscpException If LSCP protocol corruption occurs.           * @throws LscpException If LSCP protocol corruption occurs.
1797           * @throws LSException If           * @throws LSException If
1798           * <ul>           * <ul>
1799           * <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>;
1800           * <li><code>audioChn</code> is not a valid channel number;           * <li><code>audioChn</code> is not a valid channel number;
1801           * </ul>           * </ul>
1802           *           *
# Line 1073  public class Client { Line 1804  public class Client {
1804           * @see #getAudioOutputDeviceInfo           * @see #getAudioOutputDeviceInfo
1805           */           */
1806          public synchronized AudioOutputChannel          public synchronized AudioOutputChannel
1807          getAudioOutputChannelInfo(int deviceID, int audioChn)          getAudioOutputChannelInfo(int deviceId, int audioChn)
1808                                                  throws IOException, LscpException, LSException {                                                  throws IOException, LscpException, LSException {
1809                                    
1810                  verifyConnection();                  verifyConnection();
1811                  out.writeLine("GET AUDIO_OUTPUT_CHANNEL INFO " + deviceID + ' ' + audioChn);                  out.writeLine("GET AUDIO_OUTPUT_CHANNEL INFO " + deviceId + ' ' + audioChn);
1812                    if(getPrintOnlyMode()) return null;
1813                                    
1814                  ResultSet rs = getMultiLineResultSet();                  ResultSet rs = getMultiLineResultSet();
1815                                    
# Line 1088  public class Client { Line 1820  public class Client {
1820                          if(s.startsWith("NAME: ")) {                          if(s.startsWith("NAME: ")) {
1821                                  s = s.substring("NAME: ".length());                                  s = s.substring("NAME: ".length());
1822                                  Parameter<String> prm = getAudioOutputChannelParameterInfo (                                  Parameter<String> prm = getAudioOutputChannelParameterInfo (
1823                                          deviceID, audioChn, "NAME"                                          deviceId, audioChn, "NAME"
1824                                  );                                  );
1825                                  prm.setValue(removeQuotation(s));                                  prm.setValue(removeQuotation(s));
1826                                  aoc.setNameParameter(prm);                                  aoc.setNameParameter(prm);
1827                          } else if(s.startsWith("IS_MIX_CHANNEL: ")) {                          } else if(s.startsWith("IS_MIX_CHANNEL: ")) {
1828                                  s = s.substring("IS_MIX_CHANNEL: ".length());                                  s = s.substring("IS_MIX_CHANNEL: ".length());
1829                                  Parameter<Boolean> prm = getAudioOutputChannelParameterInfo (                                  Parameter<Boolean> prm = getAudioOutputChannelParameterInfo (
1830                                          deviceID, audioChn, "IS_MIX_CHANNEL"                                          deviceId, audioChn, "IS_MIX_CHANNEL"
1831                                  );                                  );
1832                                  prm.setValue(Boolean.parseBoolean(s));                                  prm.setValue(Boolean.parseBoolean(s));
1833                                  aoc.setMixChannelParameter(prm);                                  aoc.setMixChannelParameter(prm);
1834                          } else if(s.startsWith("MIX_CHANNEL_DESTINATION: ")) {                          } else if(s.startsWith("MIX_CHANNEL_DESTINATION: ")) {
1835                                  s = s.substring("MIX_CHANNEL_DESTINATION: ".length());                                  s = s.substring("MIX_CHANNEL_DESTINATION: ".length());
1836                                  Parameter<Integer> prm = getAudioOutputChannelParameterInfo (                                  Parameter<Integer> prm = getAudioOutputChannelParameterInfo (
1837                                          deviceID, audioChn, "MIX_CHANNEL_DESTINATION"                                          deviceId, audioChn, "MIX_CHANNEL_DESTINATION"
1838                                  );                                  );
1839                                  prm.setValue(parseInt(s));                                  prm.setValue(parseInt(s));
1840                                  aoc.setMixChannelDestParameter(prm);                                  aoc.setMixChannelDestParameter(prm);
# Line 1113  public class Client { Line 1845  public class Client {
1845                                  );                                  );
1846                                                                    
1847                                  Parameter prm = getAudioOutputChannelParameterInfo (                                  Parameter prm = getAudioOutputChannelParameterInfo (
1848                                          deviceID, audioChn, s.substring(0, i)                                          deviceId, audioChn, s.substring(0, i)
1849                                  );                                  );
1850                                                                    
1851                                  s = s.substring(i + 2);                                  s = s.substring(i + 2);
# Line 1129  public class Client { Line 1861  public class Client {
1861          /**          /**
1862           * Gets detailed information about a specific audio output channel parameter.           * Gets detailed information about a specific audio output channel parameter.
1863           *           *
1864           * @param devID The numerical ID of the audio output device.           * @param devId The numerical ID of the audio output device.
1865           * @param chan The audio channel number.           * @param chan The audio channel number.
1866           * @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.
1867           *           *
# Line 1140  public class Client { Line 1872  public class Client {
1872           * @throws LscpException If LSCP protocol corruption occurs.           * @throws LscpException If LSCP protocol corruption occurs.
1873           * @throws LSException If           * @throws LSException If
1874           * <ul>           * <ul>
1875           * <li><code>devID</code> is not a valid device ID;           * <li><code>devId</code> is not a valid device ID;
1876           * <li><code>chan</code> is not a valid channel number;           * <li><code>chan</code> is not a valid channel number;
1877           * <li>There is no channel parameter with the specified name.           * <li>There is no channel parameter with the specified name.
1878           * </ul>           * </ul>
# Line 1149  public class Client { Line 1881  public class Client {
1881           * @see #getAudioOutputChannelInfo           * @see #getAudioOutputChannelInfo
1882           */           */
1883          public synchronized Parameter          public synchronized Parameter
1884          getAudioOutputChannelParameterInfo(int devID, int chan, String param)          getAudioOutputChannelParameterInfo(int devId, int chan, String param)
1885                                                  throws IOException, LscpException, LSException {                                                  throws IOException, LscpException, LSException {
1886                                    
1887                  verifyConnection();                  verifyConnection();
1888                  String args = devID + " " + chan + " " + param;                  String args = devId + " " + chan + " " + param;
1889                  out.writeLine("GET AUDIO_OUTPUT_CHANNEL_PARAMETER INFO " + args);                  out.writeLine("GET AUDIO_OUTPUT_CHANNEL_PARAMETER INFO " + args);
1890                    if(getPrintOnlyMode()) return null;
1891                                    
1892                  ResultSet rs = getMultiLineResultSet();                  ResultSet rs = getMultiLineResultSet();
1893                                    
# Line 1191  public class Client { Line 1924  public class Client {
1924          /**          /**
1925           * Alters a specific setting of an audio output channel.           * Alters a specific setting of an audio output channel.
1926           *           *
1927           * @param devID The numerical ID of the audio device.           * @param devId The numerical ID of the audio device.
1928           * @param chn The audio channel number.           * @param chn The audio channel number.
1929           * @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
1930           * and the new value for this parameter.           * and the new value for this parameter.
# Line 1200  public class Client { Line 1933  public class Client {
1933           * @throws LscpException If LSCP protocol corruption occurs.           * @throws LscpException If LSCP protocol corruption occurs.
1934           * @throws LSException If           * @throws LSException If
1935           * <ul>           * <ul>
1936           * <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>;
1937           * <li><code>chn</code> is not a valid channel number;           * <li><code>chn</code> is not a valid channel number;
1938           * <li>There is no channel parameter with the specified name;           * <li>There is no channel parameter with the specified name;
1939           * <li>The channel parameter is readonly;           * <li>The channel parameter is readonly;
# Line 1211  public class Client { Line 1944  public class Client {
1944           * @see #getAudioOutputChannelInfo           * @see #getAudioOutputChannelInfo
1945           */           */
1946          public synchronized void          public synchronized void
1947          setAudioOutputChannelParameter(int devID, int chn,  Parameter prm)          setAudioOutputChannelParameter(int devId, int chn,  Parameter prm)
1948                                                  throws IOException, LscpException, LSException {                                                  throws IOException, LscpException, LSException {
1949                                    
1950                  verifyConnection();                  verifyConnection();
1951                  String args = devID + " " + chn + " " + prm.getName() + '=' + prm.getStringValue();                  String args = devId + " " + chn + " " + prm.getName() + '=' + prm.getStringValue();
1952                  out.writeLine("SET AUDIO_OUTPUT_CHANNEL_PARAMETER " + args);                  out.writeLine("SET AUDIO_OUTPUT_CHANNEL_PARAMETER " + args);
1953                    if(getPrintOnlyMode()) return;
1954                                    
1955                  ResultSet rs = getEmptyResultSet();                  ResultSet rs = getEmptyResultSet();
1956          }          }
# Line 1232  public class Client { Line 1966  public class Client {
1966          getMidiInputDriverCount() throws IOException, LscpException, LSException {          getMidiInputDriverCount() throws IOException, LscpException, LSException {
1967                  verifyConnection();                  verifyConnection();
1968                  out.writeLine("GET AVAILABLE_MIDI_INPUT_DRIVERS");                  out.writeLine("GET AVAILABLE_MIDI_INPUT_DRIVERS");
1969                    if(getPrintOnlyMode()) return -1;
1970                    
1971                  String s = getSingleLineResultSet().getResult();                  String s = getSingleLineResultSet().getResult();
1972                  return parseInt(s);                  return parseInt(s);
1973          }          }
# Line 1249  public class Client { Line 1985  public class Client {
1985          public synchronized MidiInputDriver[]          public synchronized MidiInputDriver[]
1986          getMidiInputDrivers() throws IOException, LscpException, LSException {          getMidiInputDrivers() throws IOException, LscpException, LSException {
1987                  String[] drivers = getMidiInputDriverNames();                  String[] drivers = getMidiInputDriverNames();
1988                    if(getPrintOnlyMode()) return null;
1989                    
1990                  MidiInputDriver[] mid = new MidiInputDriver[drivers.length];                  MidiInputDriver[] mid = new MidiInputDriver[drivers.length];
1991                                    
1992                  for(int i = 0; i < mid.length; i++) mid[i] = getMidiInputDriverInfo(drivers[i]);                  for(int i = 0; i < mid.length; i++) mid[i] = getMidiInputDriverInfo(drivers[i]);
# Line 1270  public class Client { Line 2008  public class Client {
2008          getMidiInputDriverNames() throws IOException, LscpException, LSException {          getMidiInputDriverNames() throws IOException, LscpException, LSException {
2009                  verifyConnection();                  verifyConnection();
2010                  out.writeLine("LIST AVAILABLE_MIDI_INPUT_DRIVERS");                  out.writeLine("LIST AVAILABLE_MIDI_INPUT_DRIVERS");
2011                    if(getPrintOnlyMode()) return null;
2012                    
2013                  return parseList(getSingleLineResultSet().getResult());                  return parseList(getSingleLineResultSet().getResult());
2014          }          }
2015                    
2016          /**          /**
2017           * Gets detailed information about a specific MIDI input driver.           * Gets detailed information about a specific MIDI input driver.
2018           * @param driverName The name of the MIDI input driver.           * @param driverName The name of the MIDI input driver.
2019           *           * @param depList An optional list of dependences parameters.
2020           * @return A <code>MidiInputDriver</code> object containing           * @return A <code>MidiInputDriver</code> object containing
2021           * information about the specified MIDI input driver.           * information about the specified MIDI input driver.
2022           *           *
# Line 1286  public class Client { Line 2026  public class Client {
2026           *           *
2027           * @see #getMidiInputDriverNames           * @see #getMidiInputDriverNames
2028           */           */
2029          private synchronized MidiInputDriver          public synchronized MidiInputDriver
2030          getMidiInputDriverInfo(String driverName) throws IOException, LscpException, LSException {          getMidiInputDriverInfo(String driverName, Parameter... depList)
2031                                            throws IOException, LscpException, LSException {
2032                    
2033                  verifyConnection();                  verifyConnection();
2034                  out.writeLine("GET MIDI_INPUT_DRIVER INFO " + driverName);                  out.writeLine("GET MIDI_INPUT_DRIVER INFO " + driverName);
2035                    if(getPrintOnlyMode()) return null;
2036                    
2037                  ResultSet rs = getMultiLineResultSet();                  ResultSet rs = getMultiLineResultSet();
2038                                    
2039                  MidiInputDriver mid = new MidiInputDriver(rs.getMultiLineResult());                  MidiInputDriver mid = new MidiInputDriver(rs.getMultiLineResult());
2040                  mid.setName(driverName);                  mid.setName(driverName);
2041                                    
2042                  for(String s : mid.getParameterNames())                  for(String s : mid.getParameterNames())
2043                          mid.addParameter(getMidiInputDriverParameterInfo(driverName, s));                          mid.addParameter(getMidiInputDriverParameterInfo(driverName, s, depList));
2044                                    
2045                  return mid;                  return mid;
2046          }          }
# Line 1330  public class Client { Line 2074  public class Client {
2074                  StringBuffer args = new StringBuffer(driver);                  StringBuffer args = new StringBuffer(driver);
2075                  args.append(' ').append(param);                  args.append(' ').append(param);
2076                                    
2077                  for(Parameter p : deplist)                  for(Parameter p : deplist) {
2078                            if(p == null || p.getName() == null || p.getValue() == null) continue;
2079                          args.append(' ').append(p.getName()).append('=').append(p.getStringValue());                          args.append(' ').append(p.getName()).append('=').append(p.getStringValue());
2080                    }
2081                                    
2082                  out.writeLine("GET MIDI_INPUT_DRIVER_PARAMETER INFO " + args.toString());                  out.writeLine("GET MIDI_INPUT_DRIVER_PARAMETER INFO " + args.toString());
2083                    if(getPrintOnlyMode()) return null;
2084                                    
2085                  ResultSet rs = getMultiLineResultSet();                  ResultSet rs = getMultiLineResultSet();
2086                                    
# Line 1392  public class Client { Line 2139  public class Client {
2139                  verifyConnection();                  verifyConnection();
2140                  StringBuffer args = new StringBuffer(miDriver);                  StringBuffer args = new StringBuffer(miDriver);
2141                                    
2142                  for(Parameter p : paramList)                  for(Parameter p : paramList) {
2143                            if(p == null || p.getName() == null || p.getValue() == null) continue;
2144                          args.append(' ').append(p.getName()).append('=').append(p.getStringValue());                          args.append(' ').append(p.getName()).append('=').append(p.getStringValue());
2145                    }
2146                                    
2147                  out.writeLine("CREATE MIDI_INPUT_DEVICE " + args.toString());                  out.writeLine("CREATE MIDI_INPUT_DEVICE " + args.toString());
2148                    if(getPrintOnlyMode()) return -1;
2149                    
2150                  ResultSet rs = getEmptyResultSet();                  ResultSet rs = getEmptyResultSet();
2151                                    
2152                  return rs.getIndex();                  return rs.getIndex();
# Line 1403  public class Client { Line 2154  public class Client {
2154                    
2155          /**          /**
2156           * Destroys already created MIDI input device.           * Destroys already created MIDI input device.
2157           * @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.
2158           * @throws IOException If some I/O error occurs.           * @throws IOException If some I/O error occurs.
2159           * @throws LSException If the destroying of the MIDI input device failed.           * @throws LSException If the destroying of the MIDI input device failed.
2160           * @throws LscpException If LSCP protocol corruption occurs.           * @throws LscpException If LSCP protocol corruption occurs.
# Line 1411  public class Client { Line 2162  public class Client {
2162           * @see #getMidiInputDevices           * @see #getMidiInputDevices
2163           */           */
2164          public synchronized void          public synchronized void
2165          destroyMidiInputDevice(int deviceID) throws IOException, LSException, LscpException {          destroyMidiInputDevice(int deviceId) throws IOException, LSException, LscpException {
2166                  verifyConnection();                  verifyConnection();
2167                  out.writeLine("DESTROY MIDI_INPUT_DEVICE " + deviceID);                  out.writeLine("DESTROY MIDI_INPUT_DEVICE " + deviceId);
2168                    if(getPrintOnlyMode()) return;
2169                    
2170                  ResultSet rs = getEmptyResultSet();                  ResultSet rs = getEmptyResultSet();
2171          }          }
2172                    
2173          /**          /**
2174           * Enables/disables the specified MIDI input device.           * Enables/disables the specified MIDI input device.
2175           * @param deviceID The ID of the MIDI input device to be enabled/disabled.           * @param deviceId The ID of the MIDI input device to be enabled/disabled.
2176           * @param enable If <code>true</code> the MIDI input device is enabled,           * @param enable If <code>true</code> the MIDI input device is enabled,
2177           * else the device is disabled.           * else the device is disabled.
2178           * @throws IOException If some I/O error occurs.           * @throws IOException If some I/O error occurs.
2179           * @throws LSException If there is no MIDI input           * @throws LSException If there is no MIDI input
2180           * device with numerical ID <code>deviceID</code>.           * device with numerical ID <code>deviceId</code>.
2181           * @throws LscpException If LSCP protocol corruption occurs.           * @throws LscpException If LSCP protocol corruption occurs.
2182           */           */
2183          public void          public void
2184          enableMidiInputDevice(int deviceID, boolean enable)          enableMidiInputDevice(int deviceId, boolean enable)
2185                                  throws IOException, LSException, LscpException {                                  throws IOException, LSException, LscpException {
2186                                    
2187                  setMidiInputDeviceParameter(deviceID, new BoolParameter("ACTIVE", enable));                  setMidiInputDeviceParameter(deviceId, new BoolParameter("ACTIVE", enable));
2188          }          }
2189                    
2190          /**          /**
# Line 1445  public class Client { Line 2198  public class Client {
2198          getMidiInputDeviceCount() throws IOException, LscpException, LSException {          getMidiInputDeviceCount() throws IOException, LscpException, LSException {
2199                  verifyConnection();                  verifyConnection();
2200                  out.writeLine("GET MIDI_INPUT_DEVICES");                  out.writeLine("GET MIDI_INPUT_DEVICES");
2201                    if(getPrintOnlyMode()) return -1;
2202                    
2203                  String s = getSingleLineResultSet().getResult();                  String s = getSingleLineResultSet().getResult();
2204                  return parseInt(s);                  return parseInt(s);
2205          }          }
# Line 1463  public class Client { Line 2218  public class Client {
2218          public synchronized MidiInputDevice[]          public synchronized MidiInputDevice[]
2219          getMidiInputDevices() throws IOException, LscpException, LSException {          getMidiInputDevices() throws IOException, LscpException, LSException {
2220                  Integer[] idS = getMidiInputDeviceIDs();                  Integer[] idS = getMidiInputDeviceIDs();
2221                    if(getPrintOnlyMode()) return null;
2222                    
2223                  MidiInputDevice[] devices = new MidiInputDevice[idS.length];                  MidiInputDevice[] devices = new MidiInputDevice[idS.length];
2224                                    
2225                  for(int i = 0; i < devices.length; i++)                  for(int i = 0; i < devices.length; i++)
# Line 1486  public class Client { Line 2243  public class Client {
2243          getMidiInputDeviceIDs() throws IOException, LscpException, LSException {          getMidiInputDeviceIDs() throws IOException, LscpException, LSException {
2244                  verifyConnection();                  verifyConnection();
2245                  out.writeLine("LIST MIDI_INPUT_DEVICES");                  out.writeLine("LIST MIDI_INPUT_DEVICES");
2246                    if(getPrintOnlyMode()) return null;
2247                    
2248                  return parseIntList(getSingleLineResultSet().getResult());                  return parseIntList(getSingleLineResultSet().getResult());
2249          }          }
2250                    
2251          /**          /**
2252           * Gets the current settings of a specific, already created MIDI input device.           * Gets the current settings of a specific, already created MIDI input device.
2253           *           *
2254           * @param deviceID Specifies the numerical ID of the MIDI input device.           * @param deviceId Specifies the numerical ID of the MIDI input device.
2255           *           *
2256           * @return An <code>MidiInputDevice</code> instance containing information           * @return A <code>MidiInputDevice</code> instance containing information
2257           * about the specified device.           * about the specified device.
2258           *           *
2259           * @throws IOException If some I/O error occurs.           * @throws IOException If some I/O error occurs.
2260           * @throws LscpException If LSCP protocol corruption occurs.           * @throws LscpException If LSCP protocol corruption occurs.
2261           * @throws LSException If there is no MIDI input device           * @throws LSException If there is no MIDI input device
2262           * with device id <code>deviceID</code>.           * with device id <code>deviceId</code>.
2263           *           *
2264           * @see #getMidiInputDevices           * @see #getMidiInputDevices
2265           */           */
2266          public synchronized MidiInputDevice          public synchronized MidiInputDevice
2267          getMidiInputDeviceInfo(int deviceID) throws IOException, LscpException, LSException {          getMidiInputDeviceInfo(int deviceId) throws IOException, LscpException, LSException {
2268                  verifyConnection();                  verifyConnection();
2269                  out.writeLine("GET MIDI_INPUT_DEVICE INFO " + deviceID);                  out.writeLine("GET MIDI_INPUT_DEVICE INFO " + deviceId);
2270                    if(getPrintOnlyMode()) return null;
2271                                    
2272                  ResultSet rs = getMultiLineResultSet();                  ResultSet rs = getMultiLineResultSet();
2273                                    
2274                  String[] lnS = rs.getMultiLineResult();                  String[] lnS = rs.getMultiLineResult();
2275                                    
2276                  MidiInputDevice mid = new MidiInputDevice();                  MidiInputDevice mid = new MidiInputDevice();
2277                  mid.setDeviceID(deviceID);                  mid.setDeviceId(deviceId);
2278                                    
2279                  String drv = getCategoryInfo(lnS, "DRIVER");                  String drv = getCategoryInfo(lnS, "DRIVER");
2280                  mid.setDriverName(drv);                  mid.setDriverName(drv);
# Line 1527  public class Client { Line 2287  public class Client {
2287                                  mid.setActive(Boolean.parseBoolean(s));                                  mid.setActive(Boolean.parseBoolean(s));
2288                          } else if(s.startsWith("PORTS: ")) {                          } else if(s.startsWith("PORTS: ")) {
2289                                  s = s.substring("PORTS: ".length());                                  s = s.substring("PORTS: ".length());
2290                                  int ports = Parser.parseInt(s);                                  
2291                                  MidiPort[] midiPorts = new MidiPort[ports > 0 ? ports : 0];                                  Parameter<Integer> ports = (Parameter<Integer>)
2292                                            getMidiInputDriverParameterInfo(drv, "PORTS");
2293                                    
2294                                    ports.parseValue(s);
2295                                    mid.setPortsParameter(ports);
2296                                    
2297                                    int j = ports.getValue();
2298                                    MidiPort[] midiPorts = new MidiPort[j > 0 ? j : 0];
2299                                                                    
2300                                  for(int i = 0; i < midiPorts.length; i++)                                  for(int i = 0; i < midiPorts.length; i++)
2301                                          midiPorts[i] = getMidiInputPortInfo(deviceID, i);                                          midiPorts[i] = getMidiInputPortInfo(deviceId, i);
2302                                                                    
2303                                  mid.setMidiPorts(midiPorts);                                  mid.setMidiPorts(midiPorts);
2304                          } else {                          } else {
# Line 1556  public class Client { Line 2323  public class Client {
2323          /**          /**
2324           * Alters a specific setting of a created MIDI input device.           * Alters a specific setting of a created MIDI input device.
2325           *           *
2326           * @param deviceID The numerical ID of the MIDI input device.           * @param deviceId The numerical ID of the MIDI input device.
2327           * @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
2328           * and the new value for this parameter.           * and the new value for this parameter.
2329           *           *
# Line 1564  public class Client { Line 2331  public class Client {
2331           * @throws LscpException If LSCP protocol corruption occurs.           * @throws LscpException If LSCP protocol corruption occurs.
2332           * @throws LSException If           * @throws LSException If
2333           * <ul>           * <ul>
2334           * <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>;
2335           * <li>There is no device parameter with the specified name;           * <li>There is no device parameter with the specified name;
2336           * <li>The device parameter is readonly;           * <li>The device parameter is readonly;
2337           * <li>The device parameter is from different type.           * <li>The device parameter is from different type.
# Line 1574  public class Client { Line 2341  public class Client {
2341           * @see #getMidiInputDeviceInfo           * @see #getMidiInputDeviceInfo
2342           */           */
2343          public synchronized void          public synchronized void
2344          setMidiInputDeviceParameter(int deviceID, Parameter prm)          setMidiInputDeviceParameter(int deviceId, Parameter prm)
2345                                                  throws IOException, LscpException, LSException {                                                  throws IOException, LscpException, LSException {
2346                                    
2347                  verifyConnection();                  verifyConnection();
2348                  String kv = prm.getName() + '=' + prm.getStringValue();                  String kv = prm.getName() + '=' + prm.getStringValue();
2349                  out.writeLine("SET MIDI_INPUT_DEVICE_PARAMETER " + deviceID + ' ' + kv);                  out.writeLine("SET MIDI_INPUT_DEVICE_PARAMETER " + deviceId + ' ' + kv);
2350                    if(getPrintOnlyMode()) return;
2351                                    
2352                  ResultSet rs = getEmptyResultSet();                  ResultSet rs = getEmptyResultSet();
2353          }          }
2354                    
2355                    
2356          /**          /**
2357           * Changes the ports number of the speicifed MIDI input device.           * Changes the port number of the speicified MIDI input device.
2358           * @param deviceID The numerical ID of the MIDI input device.           * @param deviceId The numerical ID of the MIDI input device.
2359           * @param ports The new number of MIDI input ports.           * @param ports The new number of MIDI input ports.
2360           *           *
2361           * @throws IOException If an I/O error occurs.           * @throws IOException If an I/O error occurs.
2362           * @throws LscpException If LSCP protocol corruption occurs.           * @throws LscpException If LSCP protocol corruption occurs.
2363           * @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
2364           * if <code>ports</code> number is out of range.           * if <code>ports</code> number is out of range.
2365           *           *
2366           * @see #getMidiInputPortInfo           * @see #getMidiInputPortInfo
2367           */           */
2368          public synchronized void          public synchronized void
2369          setMidiInputPortCount(int deviceID, int ports)          setMidiInputPortCount(int deviceId, int ports)
2370                                          throws IOException, LscpException, LSException {                                          throws IOException, LscpException, LSException {
2371                                    
2372                  setMidiInputDeviceParameter(deviceID, new IntParameter("PORTS", ports));                  setMidiInputDeviceParameter(deviceId, new IntParameter("PORTS", ports));
2373          }          }
2374                    
2375          /**          /**
2376           * Gets detailed information about a specific MIDI input port.           * Gets detailed information about a specific MIDI input port.
2377           * @param deviceID The numerical ID of the MIDI input device.           * @param deviceId The numerical ID of the MIDI input device.
2378           * @param midiPort The MIDI input port number.           * @param midiPort The MIDI input port number.
2379           *           *
2380           * @return A <code>MidiPort</code> instance containing           * @return A <code>MidiPort</code> instance containing
# Line 1614  public class Client { Line 2382  public class Client {
2382           *           *
2383           * @throws IOException If an I/O error occurs.           * @throws IOException If an I/O error occurs.
2384           * @throws LscpException If LSCP protocol corruption occurs.           * @throws LscpException If LSCP protocol corruption occurs.
2385           * @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
2386           * if <code>midiPort</code> is not a valid MIDI port number.           * if <code>midiPort</code> is not a valid MIDI port number.
2387           *           *
2388           * @see #getMidiInputDevices           * @see #getMidiInputDevices
2389           */           */
2390          public synchronized MidiPort          public synchronized MidiPort
2391          getMidiInputPortInfo(int deviceID, int midiPort)          getMidiInputPortInfo(int deviceId, int midiPort)
2392                                          throws IOException, LscpException, LSException {                                          throws IOException, LscpException, LSException {
2393                                    
2394                  verifyConnection();                  verifyConnection();
2395                  out.writeLine("GET MIDI_INPUT_PORT INFO " + deviceID + " " + midiPort);                  out.writeLine("GET MIDI_INPUT_PORT INFO " + deviceId + " " + midiPort);
2396                    if(getPrintOnlyMode()) return null;
2397                    
2398                  ResultSet rs = getMultiLineResultSet();                  ResultSet rs = getMultiLineResultSet();
2399                                    
2400                  MidiPort mp = new MidiPort();                  MidiPort mp = new MidiPort();
# Line 1634  public class Client { Line 2404  public class Client {
2404                          if(s.startsWith("NAME: ")) {                          if(s.startsWith("NAME: ")) {
2405                                  s = s.substring("NAME: ".length());                                  s = s.substring("NAME: ".length());
2406                                  Parameter prm = getMidiInputPortParameterInfo (                                  Parameter prm = getMidiInputPortParameterInfo (
2407                                          deviceID, midiPort, "NAME"                                          deviceId, midiPort, "NAME"
2408                                  );                                  );
2409                                  prm.setValue(removeQuotation(s));                                  prm.setValue(removeQuotation(s));
2410                                  mp.setNameParameter(prm);                                  mp.setNameParameter(prm);
# Line 1645  public class Client { Line 2415  public class Client {
2415                                  );                                  );
2416                                                                    
2417                                  Parameter prm = getMidiInputPortParameterInfo (                                  Parameter prm = getMidiInputPortParameterInfo (
2418                                          deviceID, midiPort, s.substring(0, i)                                          deviceId, midiPort, s.substring(0, i)
2419                                  );                                  );
2420                                                                    
2421                                  s = s.substring(i + 2);                                  s = s.substring(i + 2);
# Line 1661  public class Client { Line 2431  public class Client {
2431          /**          /**
2432           * Gets detailed information about a specific MIDI input port parameter.           * Gets detailed information about a specific MIDI input port parameter.
2433           *           *
2434           * @param deviceID The numerical ID of the MIDI input device.           * @param deviceId The numerical ID of the MIDI input device.
2435           * @param port The MIDI port number.           * @param port The MIDI port number.
2436           * @param param A specific parameter name for which information should be obtained.           * @param param A specific parameter name for which information should be obtained.
2437           *           *
# Line 1672  public class Client { Line 2442  public class Client {
2442           * @throws LscpException If LSCP protocol corruption occurs.           * @throws LscpException If LSCP protocol corruption occurs.
2443           * @throws LSException If           * @throws LSException If
2444           * <ul>           * <ul>
2445           * <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>;
2446           * <li> <code>port</code> is not a valid MIDI port number;           * <li> <code>port</code> is not a valid MIDI port number;
2447           * <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.
2448           * </ul>           * </ul>
# Line 1681  public class Client { Line 2451  public class Client {
2451           * @see #getMidiInputPortInfo           * @see #getMidiInputPortInfo
2452           */           */
2453          public synchronized Parameter          public synchronized Parameter
2454          getMidiInputPortParameterInfo(int deviceID, int port, String param)          getMidiInputPortParameterInfo(int deviceId, int port, String param)
2455                                                  throws IOException, LscpException, LSException {                                                  throws IOException, LscpException, LSException {
2456                                    
2457                  verifyConnection();                  verifyConnection();
2458                  String args = deviceID + " " + port + " " + param;                  String args = deviceId + " " + port + " " + param;
2459                  out.writeLine("GET MIDI_INPUT_PORT_PARAMETER INFO " + args);                  out.writeLine("GET MIDI_INPUT_PORT_PARAMETER INFO " + args);
2460                    if(getPrintOnlyMode()) return null;
2461                                    
2462                  ResultSet rs = getMultiLineResultSet();                  ResultSet rs = getMultiLineResultSet();
2463                                    
# Line 1723  public class Client { Line 2494  public class Client {
2494          /**          /**
2495           * Alters a specific setting of a MIDI input port.           * Alters a specific setting of a MIDI input port.
2496           *           *
2497           * @param deviceID The numerical ID of the MIDI device.           * @param deviceId The numerical ID of the MIDI device.
2498           * @param port The MIDI port number.           * @param port The MIDI port number.
2499           * @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
2500           * and the new value for this parameter.           * and the new value for this parameter.
# Line 1732  public class Client { Line 2503  public class Client {
2503           * @throws LscpException If LSCP protocol corruption occurs.           * @throws LscpException If LSCP protocol corruption occurs.
2504           * @throws LSException If           * @throws LSException If
2505           * <ul>           * <ul>
2506           * <li>There is no MIDI device with numerical ID <code>deviceID</code>;           * <li>There is no MIDI device with numerical ID <code>deviceId</code>;
2507           * <li><code>port</code> is not a valid MIDI port number;           * <li><code>port</code> is not a valid MIDI port number;
2508           * <li><code>prm</code> is not a valid parameter;           * <li><code>prm</code> is not a valid parameter;
2509           * <li>The parameter is readonly;           * <li>The parameter is readonly;
# Line 1743  public class Client { Line 2514  public class Client {
2514           * @see #getMidiInputPortInfo           * @see #getMidiInputPortInfo
2515           */           */
2516          public synchronized void          public synchronized void
2517          setMidiInputPortParameter(int deviceID, int port,  Parameter prm)          setMidiInputPortParameter(int deviceId, int port,  Parameter prm)
2518                                                  throws IOException, LscpException, LSException {                                                  throws IOException, LscpException, LSException {
2519                                    
2520                  verifyConnection();                  verifyConnection();
2521                  String args = deviceID + " " + port + " " +                  String args = deviceId + " " + port + " " +
2522                          prm.getName() + '=' + prm.getStringValue();                          prm.getName() + '=' + prm.getStringValue();
2523                  out.writeLine("SET MIDI_INPUT_PORT_PARAMETER " + args);                  out.writeLine("SET MIDI_INPUT_PORT_PARAMETER " + args);
2524                    if(getPrintOnlyMode()) return;
2525                    
2526                    ResultSet rs = getEmptyResultSet();
2527            }
2528            
2529            /**
2530             * Adds a new MIDI instrument map.
2531             * @param name The name of this MIDI instrument map.
2532             * @return The number of the newly MIDI instrument map.
2533             * @throws IOException If some I/O error occurs.
2534             * @throws LSException If the creation of the new MIDI instrument map failed.
2535             * @throws LscpException If LSCP protocol corruption occurs.
2536             * @see #removeMidiInstrumentMap
2537             */
2538            public synchronized int
2539            addMidiInstrumentMap(String name) throws IOException, LSException, LscpException {
2540                    verifyConnection();
2541                    out.writeLine("ADD MIDI_INSTRUMENT_MAP '" + toEscapedText(name) + "'");
2542                    if(getPrintOnlyMode()) return -1;
2543                    
2544                    ResultSet rs = getEmptyResultSet();
2545                    
2546                    return rs.getIndex();
2547            }
2548            
2549            /**
2550             * Removes the specified MIDI instrument map.
2551             * @param mapId The numerical ID of the MIDI instrument map to be removed.
2552             * @throws IOException If some I/O error occurs.
2553             * @throws LscpException If LSCP protocol corruption occurs.
2554             * @throws LSException If the removing of the MIDI instrument map failed.
2555             * @see #addMidiInstrumentMap
2556             * @see #getMidiInstrumentMapIDs
2557             */
2558            public synchronized void
2559            removeMidiInstrumentMap(int mapId) throws IOException, LscpException, LSException {
2560                    verifyConnection();
2561                    out.writeLine("REMOVE MIDI_INSTRUMENT_MAP " + mapId);
2562                    if(getPrintOnlyMode()) return;
2563                    
2564                    ResultSet rs = getEmptyResultSet();
2565            }
2566            
2567            /**
2568             * Removes the all MIDI instrument maps.
2569             * @throws IOException If some I/O error occurs.
2570             * @throws LscpException If LSCP protocol corruption occurs.
2571             * @throws LSException If the removing of the MIDI instrument maps failed.
2572             */
2573            public synchronized void
2574            removeAllMidiInstrumentMaps() throws IOException, LscpException, LSException {
2575                    verifyConnection();
2576                    out.writeLine("REMOVE MIDI_INSTRUMENT_MAP ALL");
2577                    if(getPrintOnlyMode()) return;
2578                    
2579                    ResultSet rs = getEmptyResultSet();
2580            }
2581            
2582            /**
2583             * Gets the current number of all MIDI instrument maps.
2584             * @return The current number of all MIDI instrument maps.
2585             * @throws IOException If some I/O error occurs.
2586             * @throws LscpException If LSCP protocol corruption occurs.
2587             * @throws LSException If some other error occurs.
2588             */
2589            public synchronized int
2590            getMidiInstrumentMapCount() throws IOException, LscpException, LSException {
2591                    verifyConnection();
2592                    out.writeLine("GET MIDI_INSTRUMENT_MAPS");
2593                    if(getPrintOnlyMode()) return -1;
2594                    
2595                    String s = getSingleLineResultSet().getResult();
2596                    return parseInt(s);
2597            }
2598            
2599            /**
2600             * Gets a list of numerical IDs of all created MIDI instrument maps.
2601             * @return An <code>Integer</code> array providing the numerical IDs of
2602             * all created MIDI instrument maps.
2603             * @throws IOException If some I/O error occurs.
2604             * @throws LscpException If LSCP protocol corruption occurs.
2605             * @throws LSException If some other error occurs.
2606             * @see #addMidiInstrumentMap
2607             * @see #removeMidiInstrumentMap
2608             */
2609            public synchronized Integer[]
2610            getMidiInstrumentMapIDs() throws IOException, LscpException, LSException {
2611                    verifyConnection();
2612                    out.writeLine("LIST MIDI_INSTRUMENT_MAPS");
2613                    if(getPrintOnlyMode()) return null;
2614                    
2615                    return parseIntList(getSingleLineResultSet().getResult());
2616            }
2617            
2618            /**
2619             * Gets the current settings of a specific, already created MIDI instrument map.
2620             * @param mapId Specifies the numerical ID of the MIDI instrument map.
2621             * @return A <code>MidiInstrumentMapInfo</code> instance containing information
2622             * about the specified device.
2623             * @throws IOException If some I/O error occurs.
2624             * @throws LscpException If LSCP protocol corruption occurs.
2625             * @throws LSException If there is no MIDI instrument map
2626             * with map id <code>mapId</code>.
2627             * @see #getMidiInstrumentMaps
2628             */
2629            public synchronized MidiInstrumentMapInfo
2630            getMidiInstrumentMapInfo(int mapId) throws IOException, LscpException, LSException {
2631                    verifyConnection();
2632                    out.writeLine("GET MIDI_INSTRUMENT_MAP INFO " + mapId);
2633                    if(getPrintOnlyMode()) return null;
2634                    
2635                    ResultSet rs = getMultiLineResultSet();
2636                    
2637                    String[] lnS = rs.getMultiLineResult();
2638                    
2639                    String name = "";
2640                    boolean b = false;
2641                    
2642                    for(String s : lnS) {
2643                            if(s.startsWith("NAME: ")) {
2644                                    name = toNonEscapedString(s.substring("NAME: ".length()));
2645                            } else if(s.startsWith("DEFAULT: ")) {
2646                                    b = Boolean.parseBoolean(s.substring("DEFAULT: ".length()));
2647                            } else {
2648                                     getLogger().info(LscpI18n.getLogMsg("unknownLine", s));
2649                            }
2650                    }
2651                    
2652                    return new MidiInstrumentMapInfo(mapId, name, b);
2653            }
2654            
2655            /**
2656             * Gets an information of all created MIDI instrument maps.
2657             * @return A <code>MidiInstrumentMap</code> array
2658             * providing information for all created MIDI instrument maps.
2659             * @throws IOException If some I/O error occurs.
2660             * @throws LscpException If LSCP protocol corruption occurs.
2661             * @throws LSException If some other error occurs.
2662             * @see #addMidiInstrumentMap
2663             * @see #removeMidiInstrumentMap
2664             */
2665            public synchronized MidiInstrumentMapInfo[]
2666            getMidiInstrumentMaps() throws IOException, LscpException, LSException {
2667                    Integer[] idS = getMidiInstrumentMapIDs();
2668                    if(getPrintOnlyMode()) return null;
2669                    
2670                    MidiInstrumentMapInfo[] maps = new MidiInstrumentMapInfo[idS.length];
2671                    
2672                    for(int i = 0; i < maps.length; i++)
2673                            maps[i] = getMidiInstrumentMapInfo(idS[i]);
2674                    
2675                    return maps;
2676            }
2677            
2678            /**
2679             * Sets the name of the specified MIDI instrument map.
2680             * @param mapId The numerical ID of the MIDI instrument map.
2681             * @param name The new name for the specified MIDI instrument map.
2682             * @throws IOException If some I/O error occurs.
2683             * @throws LscpException If LSCP protocol corruption occurs.
2684             * @throws LSException If <code>mapId</code> is not a valid MIDI
2685             * instrument map number or <code>name</code> is not a valid name;
2686             */
2687            public synchronized void
2688            setMidiInstrumentMapName(int mapId, String name)
2689                                    throws IOException, LscpException, LSException {
2690                    
2691                    verifyConnection();
2692                    name = toEscapedText(name);
2693                    out.writeLine("SET MIDI_INSTRUMENT_MAP NAME " +  + mapId + " '" + name + "'");
2694                    if(getPrintOnlyMode()) return;
2695                    
2696                    ResultSet rs = getEmptyResultSet();
2697            }
2698            
2699            
2700            
2701            /**
2702             * Creates or replaces a MIDI instrument map entry.
2703             * @param mapId The ID of the map, where this instrument should be mapped.
2704             * @param entry Specifies the position of the MIDI instrument in the MIDI instrument map.
2705             * @param info Provides the needed information of the
2706             * MIDI instrument, which will be mapped to the specified MIDI instrument map.
2707             * @throws IOException If some I/O error occurs.
2708             * @throws LSException If the mapping failed.
2709             * @throws LscpException If LSCP protocol corruption occurs.
2710             * @see #unmapMidiInstrument
2711             */
2712            public synchronized void
2713            mapMidiInstrument(int mapId, MidiInstrumentEntry entry, MidiInstrumentInfo info)
2714                                            throws IOException, LSException, LscpException {
2715                    mapMidiInstrument(mapId, entry, info, false);
2716            }
2717            
2718            /**
2719             * Creates or replaces a MIDI instrument map entry.
2720             * @param mapId The ID of the map, where this instrument should be mapped.
2721             * @param entry Specifies the position of the MIDI instrument in the MIDI instrument map.
2722             * @param info Provides the needed information of the
2723             * MIDI instrument, which will be mapped to the specified MIDI instrument map.
2724             * @param nonModal If <code>true</code> the function returns immediately
2725             * and the mapping is established in the background.
2726             * @throws IOException If some I/O error occurs.
2727             * @throws LSException If the mapping failed.
2728             * @throws LscpException If LSCP protocol corruption occurs.
2729             * @see #unmapMidiInstrument
2730             */
2731            public synchronized void
2732            mapMidiInstrument(int mapId, MidiInstrumentEntry entry, MidiInstrumentInfo info, boolean nonModal)
2733                                            throws IOException, LSException, LscpException {
2734                    
2735                    verifyConnection();
2736                    StringBuffer cmd = new StringBuffer("MAP MIDI_INSTRUMENT ");
2737                    if(nonModal) cmd.append("NON_MODAL ");
2738                    cmd.append(mapId).append(' ');
2739                    cmd.append(entry.getMidiBank()).append(' ');
2740                    cmd.append(entry.getMidiProgram()).append(' ');
2741                    cmd.append(info.getEngine()).append(" '");
2742                    cmd.append(conv(info.getFilePath())).append("' ");
2743                    cmd.append(info.getInstrumentIndex()).append(' ');
2744                    cmd.append(info.getVolume());
2745                    if(!info.getLoadMode().name().equals("DEFAULT")) {
2746                            cmd.append(' ').append(info.getLoadMode().name());
2747                    }
2748                    
2749                    if(info.getName() != null) {
2750                            String s = toEscapedText(info.getName());
2751                            cmd.append(" '").append(s).append("'");
2752                    }
2753                    
2754                    out.writeLine(cmd.toString());
2755                    if(getPrintOnlyMode()) return;
2756                    
2757                    ResultSet rs = getEmptyResultSet();
2758            }
2759            
2760            /**
2761             * Removes an entry MIDI instrument map.
2762             * @param mapId The ID of the map, from which
2763             * the specified MIDI instrument should be removed.
2764             * @param entry The entry to remove from the specified MIDI instrument map.
2765             * @throws IOException If some I/O error occurs.
2766             * @throws LSException If the unmapping failed.
2767             * @throws LscpException If LSCP protocol corruption occurs.
2768             * @see #mapMidiInstrument
2769             */
2770            public synchronized void
2771            unmapMidiInstrument(int mapId, MidiInstrumentEntry entry)
2772                                            throws IOException, LSException, LscpException {
2773                    
2774                    verifyConnection();
2775                    StringBuffer cmd = new StringBuffer("UNMAP MIDI_INSTRUMENT ");
2776                    cmd.append(mapId).append(' ');
2777                    cmd.append(entry.getMidiBank()).append(' ');
2778                    cmd.append(entry.getMidiProgram());
2779                    
2780                    out.writeLine(cmd.toString());
2781                    if(getPrintOnlyMode()) return;
2782                                    
2783                  ResultSet rs = getEmptyResultSet();                  ResultSet rs = getEmptyResultSet();
2784          }          }
2785                    
2786          /**          /**
2787             * Gets the current number of all MIDI instrument in all maps.
2788             * @return The current number of all MIDI instrument in all maps.
2789             * @throws IOException If some I/O error occurs.
2790             * @throws LscpException If LSCP protocol corruption occurs.
2791             * @throws LSException If some other error occurs.
2792             */
2793            public synchronized int
2794            getMidiInstrumentCount() throws IOException, LscpException, LSException {
2795                    verifyConnection();
2796                    out.writeLine("GET MIDI_INSTRUMENTS ALL");
2797                    if(getPrintOnlyMode()) return -1;
2798                    
2799                    String s = getSingleLineResultSet().getResult();
2800                    return parseInt(s);
2801            }
2802            
2803            /**
2804             * Gets the current number of MIDI instrument in the specified map.
2805             * @param mapId The ID of the map.
2806             * @return The current number of MIDI instrument in the specified map.
2807             * @throws IOException If some I/O error occurs.
2808             * @throws LscpException If LSCP protocol corruption occurs.
2809             * @throws LSException If some other error occurs.
2810             */
2811            public synchronized int
2812            getMidiInstrumentCount(int mapId) throws IOException, LscpException, LSException {
2813                    verifyConnection();
2814                    out.writeLine("GET MIDI_INSTRUMENTS " + String.valueOf(mapId));
2815                    if(getPrintOnlyMode()) return -1;
2816                    
2817                    String s = getSingleLineResultSet().getResult();
2818                    return parseInt(s);
2819            }
2820            
2821            /**
2822             * Gets all MIDI instrument from all maps.
2823             * @return A <code>MidiInstrumentInfo</code> array providing
2824             * all MIDI instruments from all MIDI instrument maps.
2825             * @throws IOException If some I/O error occurs.
2826             * @throws LscpException If LSCP protocol corruption occurs.
2827             * @throws LSException If some other error occurs.
2828             */
2829            public synchronized MidiInstrumentInfo[]
2830            getMidiInstruments() throws IOException, LscpException, LSException {
2831                    verifyConnection();
2832                    out.writeLine("LIST MIDI_INSTRUMENTS ALL");
2833                    if(getPrintOnlyMode()) return null;
2834                    
2835                    String[] entries = parseArray(getSingleLineResultSet().getResult());
2836                    
2837                    return getMidiInstruments(entries);
2838            }
2839            
2840            /**
2841             * Gets all MIDI instrument entries contained int the specified MIDI instrument map.
2842             * @param mapId The ID of the map, which instruments should be obtained.
2843             * @return An int array providing all MIDI instrument entries
2844             * in the specified MIDI instrument map.
2845             * @throws IOException If some I/O error occurs.
2846             * @throws LscpException If LSCP protocol corruption occurs.
2847             * @throws LSException If some other error occurs.
2848             */
2849            public synchronized int[][]
2850            getMidiInstrumentEntries(int mapId) throws IOException, LscpException, LSException {
2851                    verifyConnection();
2852                    out.writeLine("LIST MIDI_INSTRUMENTS " + String.valueOf(mapId));
2853                    if(getPrintOnlyMode()) return null;
2854                    
2855                    String[] entries = parseArray(getSingleLineResultSet().getResult());
2856                    int[][] e = new int[entries.length][3];
2857                    
2858                    for(int i = 0; i < entries.length; i++) {
2859                            Integer[] vals = parseIntList(entries[i]);
2860                            if(vals.length != 3) {
2861                                    throw new LscpException(LscpI18n.getLogMsg("CommandFailed!"));
2862                            }
2863                            
2864                            e[i][0] = vals[0];
2865                            e[i][1] = vals[1];
2866                            e[i][2] = vals[2];
2867                    }
2868                    
2869                    return e;
2870            }
2871            
2872            /**
2873             * Gets all MIDI instruments contained int the specified MIDI instrument map.
2874             * @param mapId The ID of the map, which instruments should be obtained.
2875             * @return A <code>MidiInstrumentInfo</code> array providing
2876             * all MIDI instruments in the specified MIDI instrument map.
2877             * @throws IOException If some I/O error occurs.
2878             * @throws LscpException If LSCP protocol corruption occurs.
2879             * @throws LSException If some other error occurs.
2880             */
2881            public synchronized MidiInstrumentInfo[]
2882            getMidiInstruments(int mapId) throws IOException, LscpException, LSException {
2883                    verifyConnection();
2884                    out.writeLine("LIST MIDI_INSTRUMENTS " + String.valueOf(mapId));
2885                    if(getPrintOnlyMode()) return null;
2886                    
2887                    String[] entries = parseArray(getSingleLineResultSet().getResult());
2888                    
2889                    return getMidiInstruments(entries);
2890            }
2891            
2892            private MidiInstrumentInfo[]
2893            getMidiInstruments(String[] entries) throws IOException, LscpException, LSException {
2894                    Vector<MidiInstrumentInfo> v = new Vector<MidiInstrumentInfo>();
2895                    
2896                    for(String s : entries) {
2897                            Integer[] vals = parseIntList(s);
2898                            if(vals.length != 3) {
2899                                    throw new LscpException(LscpI18n.getLogMsg("CommandFailed!"));
2900                            }
2901                            
2902                            v.add(getMidiInstrumentInfo(vals[0], vals[1], vals[2]));
2903                    }
2904                    
2905                    return v.toArray(new MidiInstrumentInfo[v.size()]);
2906            }
2907            
2908            /**
2909             * Gets the current settings of the specified MIDI instrument.
2910             * @param mapId The ID of the map.
2911             * @param bank The index of the MIDI bank.
2912             * @param program The MIDI program number of the instrument.
2913             * @return <code>MidiInstrumentInfo</code> instance containing
2914             * the current settings of the specified MIDI instrument.
2915             * @throws IOException If an I/O error occurs.
2916             * @throws LscpException If LSCP protocol corruption occurs.
2917             * @throws LSException If the specified MIDI instrument is missing.
2918             */
2919            public synchronized MidiInstrumentInfo
2920            getMidiInstrumentInfo(int mapId, int bank, int program)
2921                                            throws IOException, LscpException, LSException {
2922            
2923                    verifyConnection();
2924                    requestMidiInstrumentInfo(mapId, bank, program);
2925                    return getMidiInstrumentInfoResponse(mapId, bank, program);
2926            }
2927            
2928            private void
2929            requestMidiInstrumentInfo(int mapId, int bank, int program) throws IOException {
2930                    StringBuffer cmd = new StringBuffer("GET MIDI_INSTRUMENT INFO ");
2931                    cmd.append(mapId).append(' ');
2932                    cmd.append(bank).append(' ');
2933                    cmd.append(program);
2934                    
2935                    out.writeLine(cmd.toString());
2936            }
2937            
2938            private MidiInstrumentInfo
2939            getMidiInstrumentInfoResponse(int mapId, int bank, int program)
2940                                            throws IOException, LscpException, LSException {
2941                    
2942                    if(getPrintOnlyMode()) return null;
2943                    ResultSet rs = getMultiLineResultSet();
2944                    MidiInstrumentEntry entry = new MidiInstrumentEntry(bank, program);
2945                    return new MidiInstrumentInfo(mapId, entry, rs.getMultiLineResult());
2946            }
2947            
2948            /**
2949           * 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
2950           * 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.
          *    
2951           * @param filename The name of the instrument file           * @param filename The name of the instrument file
2952           * on the LinuxSampler instance's host system.           * on the LinuxSampler instance's host system.
2953           * @param instrIdx The index of the instrument in the instrument file.           * @param instrIdx The index of the instrument in the instrument file.
2954           * @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.
          *  
2955           * @throws IOException If some I/O error occurs.           * @throws IOException If some I/O error occurs.
2956           * @throws LscpException If LSCP protocol corruption occurs.           * @throws LscpException If LSCP protocol corruption occurs.
2957           * @throws LSException If the loading of the instrument failed.           * @throws LSException If the loading of the instrument failed.
          *  
2958           * @see #loadInstrument(String, int, int, boolean)           * @see #loadInstrument(String, int, int, boolean)
2959           * @see #getSamplerChannels           * @see #getSamplerChannels
2960           */           */
# Line 1801  public class Client { Line 2989  public class Client {
2989                                                  throws IOException, LscpException, LSException {                                                  throws IOException, LscpException, LSException {
2990                                    
2991                  String cmd = nonModal ? "LOAD INSTRUMENT NON_MODAL " : "LOAD INSTRUMENT ";                  String cmd = nonModal ? "LOAD INSTRUMENT NON_MODAL " : "LOAD INSTRUMENT ";
2992                  String args = '\'' + filename + "' " + instrIdx + ' ' + samplerChn;                  String args = '\'' + conv(filename) + "' " + instrIdx + ' ' + samplerChn;
2993                                    
2994                  out.writeLine(cmd + args);                  out.writeLine(cmd + args);
2995                    if(getPrintOnlyMode()) return;
2996                                    
2997                  ResultSet rs = getEmptyResultSet();                  ResultSet rs = getEmptyResultSet();
2998          }          }
# Line 1826  public class Client { Line 3015  public class Client {
3015                                    
3016                  verifyConnection();                  verifyConnection();
3017                  out.writeLine("LOAD ENGINE " + engineName + ' ' + samplerChn);                  out.writeLine("LOAD ENGINE " + engineName + ' ' + samplerChn);
3018                    if(getPrintOnlyMode()) return;
3019                                    
3020                  ResultSet rs = getEmptyResultSet();                  ResultSet rs = getEmptyResultSet();
3021          }          }
# Line 1841  public class Client { Line 3031  public class Client {
3031          getSamplerChannelCount() throws IOException, LscpException, LSException {          getSamplerChannelCount() throws IOException, LscpException, LSException {
3032                  verifyConnection();                  verifyConnection();
3033                  out.writeLine("GET CHANNELS");                  out.writeLine("GET CHANNELS");
3034                    if(getPrintOnlyMode()) return -1;
3035                    
3036                  String s = getSingleLineResultSet().getResult();                  String s = getSingleLineResultSet().getResult();
3037                  return parseInt(s);                  return parseInt(s);
3038          }          }
# Line 1857  public class Client { Line 3049  public class Client {
3049          public synchronized SamplerChannel[]          public synchronized SamplerChannel[]
3050          getSamplerChannels() throws IOException, LscpException, LSException {          getSamplerChannels() throws IOException, LscpException, LSException {
3051                  Integer[] idS = getSamplerChannelIDs();                  Integer[] idS = getSamplerChannelIDs();
3052                    if(getPrintOnlyMode()) return null;
3053                    
3054                  SamplerChannel[] channels = new SamplerChannel[idS.length];                  SamplerChannel[] channels = new SamplerChannel[idS.length];
3055                                    
3056                  for(int i = 0; i < channels.length; i++)                  for(int i = 0; i < channels.length; i++)
# Line 1879  public class Client { Line 3073  public class Client {
3073          getSamplerChannelIDs() throws IOException, LscpException, LSException {          getSamplerChannelIDs() throws IOException, LscpException, LSException {
3074                  verifyConnection();                  verifyConnection();
3075                  out.writeLine("LIST CHANNELS");                  out.writeLine("LIST CHANNELS");
3076                    if(getPrintOnlyMode()) return null;
3077                    
3078                  return parseIntList(getSingleLineResultSet().getResult());                  return parseIntList(getSingleLineResultSet().getResult());
3079          }          }
3080                    
# Line 1896  public class Client { Line 3092  public class Client {
3092          addSamplerChannel() throws IOException, LSException, LscpException {          addSamplerChannel() throws IOException, LSException, LscpException {
3093                  verifyConnection();                  verifyConnection();
3094                  out.writeLine("ADD CHANNEL");                  out.writeLine("ADD CHANNEL");
3095                    if(getPrintOnlyMode()) return -1;
3096                    
3097                  ResultSet rs = getEmptyResultSet();                  ResultSet rs = getEmptyResultSet();
3098                                    
3099                  return rs.getIndex();                  return rs.getIndex();
# Line 1916  public class Client { Line 3114  public class Client {
3114          removeSamplerChannel(int samplerChn) throws IOException, LscpException, LSException {          removeSamplerChannel(int samplerChn) throws IOException, LscpException, LSException {
3115                  verifyConnection();                  verifyConnection();
3116                  out.writeLine("REMOVE CHANNEL " + samplerChn);                  out.writeLine("REMOVE CHANNEL " + samplerChn);
3117                    if(getPrintOnlyMode()) return;
3118                                    
3119                  ResultSet rs = getEmptyResultSet();                  ResultSet rs = getEmptyResultSet();
3120          }          }
# Line 1931  public class Client { Line 3130  public class Client {
3130          getEngineCount() throws IOException, LscpException, LSException {          getEngineCount() throws IOException, LscpException, LSException {
3131                  verifyConnection();                  verifyConnection();
3132                  out.writeLine("GET AVAILABLE_ENGINES");                  out.writeLine("GET AVAILABLE_ENGINES");
3133                    if(getPrintOnlyMode()) return -1;
3134                    
3135                  String s = getSingleLineResultSet().getResult();                  String s = getSingleLineResultSet().getResult();
3136                  return parseInt(s);                  return parseInt(s);
3137          }          }
# Line 1946  public class Client { Line 3147  public class Client {
3147          public synchronized SamplerEngine[]          public synchronized SamplerEngine[]
3148          getEngines() throws IOException, LscpException, LSException {          getEngines() throws IOException, LscpException, LSException {
3149                  String[] engines = getEngineNames();                  String[] engines = getEngineNames();
3150                    if(getPrintOnlyMode()) return null;
3151                    
3152                  SamplerEngine[] se = new SamplerEngine[engines.length];                  SamplerEngine[] se = new SamplerEngine[engines.length];
3153                                    
3154                  for(int i = 0; i < engines.length; i++) se[i] = getEngineInfo(engines[i]);                  for(int i = 0; i < engines.length; i++) se[i] = getEngineInfo(engines[i]);
# Line 1965  public class Client { Line 3168  public class Client {
3168          getEngineNames() throws IOException, LscpException, LSException {          getEngineNames() throws IOException, LscpException, LSException {
3169                  verifyConnection();                  verifyConnection();
3170                  out.writeLine("LIST AVAILABLE_ENGINES");                  out.writeLine("LIST AVAILABLE_ENGINES");
3171                    if(getPrintOnlyMode()) return null;
3172                    
3173                  return parseStringList(getSingleLineResultSet().getResult());                  return parseStringList(getSingleLineResultSet().getResult());
3174          }          }
3175                    
# Line 1984  public class Client { Line 3189  public class Client {
3189          getEngineInfo(String engineName) throws IOException, LscpException, LSException {          getEngineInfo(String engineName) throws IOException, LscpException, LSException {
3190                  verifyConnection();                  verifyConnection();
3191                  out.writeLine("GET ENGINE INFO " + engineName);                  out.writeLine("GET ENGINE INFO " + engineName);
3192                    if(getPrintOnlyMode()) return null;
3193                    
3194                  ResultSet rs = getMultiLineResultSet();                  ResultSet rs = getMultiLineResultSet();
3195                  SamplerEngine se = new SamplerEngine(rs.getMultiLineResult());                  SamplerEngine se = new SamplerEngine(rs.getMultiLineResult());
3196                  se.setName(engineName);                  se.setName(engineName);
# Line 2006  public class Client { Line 3213  public class Client {
3213          getSamplerChannelInfo(int samplerChn) throws IOException, LscpException, LSException {          getSamplerChannelInfo(int samplerChn) throws IOException, LscpException, LSException {
3214                  verifyConnection();                  verifyConnection();
3215                  out.writeLine("GET CHANNEL INFO " + samplerChn);                  out.writeLine("GET CHANNEL INFO " + samplerChn);
3216                    if(getPrintOnlyMode()) return null;
3217                    
3218                  ResultSet rs = getMultiLineResultSet();                  ResultSet rs = getMultiLineResultSet();
3219                  SamplerChannel sc = new SamplerChannel(rs.getMultiLineResult());                  SamplerChannel sc = new SamplerChannel(rs.getMultiLineResult());
3220                  sc.setChannelID(samplerChn);                  sc.setChannelId(samplerChn);
3221                  if(sc.getEngine() != null) sc.setEngine(getEngineInfo(sc.getEngine().getName()));                  if(sc.getEngine() != null) sc.setEngine(getEngineInfo(sc.getEngine().getName()));
3222                                    
3223                  return sc;                  return sc;
# Line 2028  public class Client { Line 3237  public class Client {
3237          getChannelVoiceCount(int samplerChn) throws IOException, LscpException, LSException {          getChannelVoiceCount(int samplerChn) throws IOException, LscpException, LSException {
3238                  verifyConnection();                  verifyConnection();
3239                  out.writeLine("GET CHANNEL VOICE_COUNT " + samplerChn);                  out.writeLine("GET CHANNEL VOICE_COUNT " + samplerChn);
3240                    if(getPrintOnlyMode()) return -1;
3241                    
3242                  ResultSet rs = getSingleLineResultSet();                  ResultSet rs = getSingleLineResultSet();
3243                                    
3244                  return parseInt(rs.getResult());                  return parseInt(rs.getResult());
# Line 2048  public class Client { Line 3259  public class Client {
3259          getChannelStreamCount(int samplerChn) throws IOException, LscpException, LSException {          getChannelStreamCount(int samplerChn) throws IOException, LscpException, LSException {
3260                  verifyConnection();                  verifyConnection();
3261                  out.writeLine("GET CHANNEL STREAM_COUNT " + samplerChn);                  out.writeLine("GET CHANNEL STREAM_COUNT " + samplerChn);
3262                    if(getPrintOnlyMode()) return -1;
3263            
3264                  ResultSet rs = getSingleLineResultSet();                  ResultSet rs = getSingleLineResultSet();
3265                                    
3266                  if(rs.getResult().equals("NA")) return -1;                  if(rs.getResult().equals("NA")) return -1;
# Line 2072  public class Client { Line 3285  public class Client {
3285          getChannelBufferFillBytes(int samplerChn) throws IOException, LscpException, LSException {          getChannelBufferFillBytes(int samplerChn) throws IOException, LscpException, LSException {
3286                  verifyConnection();                  verifyConnection();
3287                  out.writeLine("GET CHANNEL BUFFER_FILL BYTES " + samplerChn);                  out.writeLine("GET CHANNEL BUFFER_FILL BYTES " + samplerChn);
3288                    if(getPrintOnlyMode()) return null;
3289                    
3290                  ResultSet rs = getSingleLineResultSet();                  ResultSet rs = getSingleLineResultSet();
3291                                    
3292                  if(rs.getResult().equals("NA")) return null;                  if(rs.getResult().equals("NA")) return null;
# Line 2087  public class Client { Line 3302  public class Client {
3302                          if(i == -1) throw new LscpException(LscpI18n.getLogMsg("CommandFailed!"));                          if(i == -1) throw new LscpException(LscpI18n.getLogMsg("CommandFailed!"));
3303                                                    
3304                          BufferFill bf = new BufferFill();                          BufferFill bf = new BufferFill();
3305                          bf.setStreamID(parseInt(s.substring(1, i)));                          bf.setStreamId(parseInt(s.substring(1, i)));
3306                          bf.setValue(parseInt(s.substring(i + 1)));                          bf.setValue(parseInt(s.substring(i + 1)));
3307                          v.add(bf);                          v.add(bf);
3308                  }                  }
# Line 2114  public class Client { Line 3329  public class Client {
3329                                    
3330                  verifyConnection();                  verifyConnection();
3331                  out.writeLine("GET CHANNEL BUFFER_FILL PERCENTAGE " + samplerChn);                  out.writeLine("GET CHANNEL BUFFER_FILL PERCENTAGE " + samplerChn);
3332                    if(getPrintOnlyMode()) return null;
3333                    
3334                  ResultSet rs = getSingleLineResultSet();                  ResultSet rs = getSingleLineResultSet();
3335                                    
3336                  return getChannelBufferFillPercentage(rs.getResult());                  return getChannelBufferFillPercentage(rs.getResult());
# Line 2137  public class Client { Line 3354  public class Client {
3354                                  throw new LscpException(LscpI18n.getLogMsg("CommandFailed!"));                                  throw new LscpException(LscpI18n.getLogMsg("CommandFailed!"));
3355                                                    
3356                          BufferFill bf = new BufferFill();                          BufferFill bf = new BufferFill();
3357                          bf.setStreamID(parseInt(s.substring(1, i)));                          bf.setStreamId(parseInt(s.substring(1, i)));
3358                          bf.setValue(parseInt(s.substring(i + 1, s.length() - 1)));                          bf.setValue(parseInt(s.substring(i + 1, s.length() - 1)));
3359                          v.add(bf);                          v.add(bf);
3360                  }                  }
# Line 2149  public class Client { Line 3366  public class Client {
3366           * Sets the audio output device on the specified sampler channel.           * Sets the audio output device on the specified sampler channel.
3367           *           *
3368           * @param samplerChn The sampler channel number.           * @param samplerChn The sampler channel number.
3369           * @param devID The numerical ID of the audio output device.           * @param devId The numerical ID of the audio output device.
3370           *           *
3371           * @throws IOException If some I/O error occurs.           * @throws IOException If some I/O error occurs.
3372           * @throws LscpException If LSCP protocol corruption occurs.           * @throws LscpException If LSCP protocol corruption occurs.
3373           * @throws LSException If           * @throws LSException If
3374           * <ul>           * <ul>
3375           * <li><code>samplerChn</code> is not a valid channel number;           * <li><code>samplerChn</code> is not a valid channel number;
3376           * <li><code>devID</code> is not a valid audio output device ID;           * <li><code>devId</code> is not a valid audio output device ID;
3377           * </ul>           * </ul>
3378           *           *
3379           * @see #getSamplerChannels           * @see #getSamplerChannels
3380           * @see #getAudioOutputDevices           * @see #getAudioOutputDevices
3381           */           */
3382          public synchronized void          public synchronized void
3383          setChannelAudioOutputDevice(int samplerChn, int devID)          setChannelAudioOutputDevice(int samplerChn, int devId)
3384                                  throws IOException, LscpException, LSException {                                  throws IOException, LscpException, LSException {
3385                                    
3386                  verifyConnection();                  verifyConnection();
3387                  out.writeLine("SET CHANNEL AUDIO_OUTPUT_DEVICE " + samplerChn + ' ' + devID);                  out.writeLine("SET CHANNEL AUDIO_OUTPUT_DEVICE " + samplerChn + ' ' + devId);
3388                    if(getPrintOnlyMode()) return;
3389                                    
3390                  ResultSet rs = getEmptyResultSet();                  ResultSet rs = getEmptyResultSet();
3391          }          }
# Line 2198  public class Client { Line 3416  public class Client {
3416                  verifyConnection();                  verifyConnection();
3417                  String args = " " + samplerChn + ' ' + audioOut + ' ' + audioIn;                  String args = " " + samplerChn + ' ' + audioOut + ' ' + audioIn;
3418                  out.writeLine("SET CHANNEL AUDIO_OUTPUT_CHANNEL" + args);                  out.writeLine("SET CHANNEL AUDIO_OUTPUT_CHANNEL" + args);
3419                    if(getPrintOnlyMode()) return;
3420                                    
3421                  ResultSet rs = getEmptyResultSet();                  ResultSet rs = getEmptyResultSet();
3422          }          }
# Line 2206  public class Client { Line 3425  public class Client {
3425           * Sets the MIDI input device on the specified sampler channel.           * Sets the MIDI input device on the specified sampler channel.
3426           *           *
3427           * @param samplerChn The sampler channel number.           * @param samplerChn The sampler channel number.
3428           * @param devID The numerical ID of the MIDI input device.           * @param devId The numerical ID of the MIDI input device.
3429           *           *
3430           * @throws IOException If some I/O error occurs.           * @throws IOException If some I/O error occurs.
3431           * @throws LscpException If LSCP protocol corruption occurs.           * @throws LscpException If LSCP protocol corruption occurs.
3432           * @throws LSException If           * @throws LSException If
3433           * <ul>           * <ul>
3434           * <li><code>samplerChn</code> is not a valid channel number;           * <li><code>samplerChn</code> is not a valid channel number;
3435           * <li><code>devID</code> is not a valid MIDI input device ID;           * <li><code>devId</code> is not a valid MIDI input device ID;
3436           * </ul>           * </ul>
3437           *           *
3438           * @see #getSamplerChannels           * @see #getSamplerChannels
3439           * @see #getMidiInputDevices           * @see #getMidiInputDevices
3440           */           */
3441          public synchronized void          public synchronized void
3442          setChannelMidiInputDevice(int samplerChn, int devID)          setChannelMidiInputDevice(int samplerChn, int devId)
3443                                  throws IOException, LscpException, LSException {                                  throws IOException, LscpException, LSException {
3444                                    
3445                  verifyConnection();                  verifyConnection();
3446                  out.writeLine("SET CHANNEL MIDI_INPUT_DEVICE " + samplerChn + ' ' + devID);                  out.writeLine("SET CHANNEL MIDI_INPUT_DEVICE " + samplerChn + ' ' + devId);
3447                    if(getPrintOnlyMode()) return;
3448                                    
3449                  ResultSet rs = getEmptyResultSet();                  ResultSet rs = getEmptyResultSet();
3450          }          }
# Line 2247  public class Client { Line 3467  public class Client {
3467                                    
3468                  verifyConnection();                  verifyConnection();
3469                  out.writeLine("SET CHANNEL MIDI_INPUT_PORT " + samplerChn + ' ' + port);                  out.writeLine("SET CHANNEL MIDI_INPUT_PORT " + samplerChn + ' ' + port);
3470                    if(getPrintOnlyMode()) return;
3471                                    
3472                  ResultSet rs = getEmptyResultSet();                  ResultSet rs = getEmptyResultSet();
3473          }          }
# Line 2271  public class Client { Line 3492  public class Client {
3492                  String args = String.valueOf(samplerChn) + ' ';                  String args = String.valueOf(samplerChn) + ' ';
3493                  args += (midiChn == -1 ? "ALL" : String.valueOf(midiChn));                  args += (midiChn == -1 ? "ALL" : String.valueOf(midiChn));
3494                  out.writeLine("SET CHANNEL MIDI_INPUT_CHANNEL " + args);                  out.writeLine("SET CHANNEL MIDI_INPUT_CHANNEL " + args);
3495                    if(getPrintOnlyMode()) return;
3496                    
3497                    ResultSet rs = getEmptyResultSet();
3498            }
3499            
3500            /**
3501             * Sets the MIDI instrument map to be used on the specified sampler channel.
3502             *
3503             * @param samplerChn The sampler channel number.
3504             * @param mapId Specifies the numerical ID of the MIDI instrument
3505             * map to assign. To remove the current map binding use <code>-1</code>.
3506             * To set the current map to be the default map use <code>-2</code>.
3507             *
3508             * @throws IOException If some I/O error occurs.
3509             * @throws LscpException If LSCP protocol corruption occurs.
3510             * @throws LSException If
3511             * <ul>
3512             * <li><code>samplerChn</code> is not a valid channel number;
3513             * <li><code>mapId</code> is not a valid MIDI instrument map ID;
3514             * </ul>
3515             *
3516             * @see #getSamplerChannels
3517             * @see #getMidiInstrumentMaps
3518             */
3519            public synchronized void
3520            setChannelMidiInstrumentMap(int samplerChn, int mapId)
3521                                    throws IOException, LscpException, LSException {
3522                    
3523                    verifyConnection();
3524                    String s;
3525                    if(mapId == -1) {
3526                            s = " NONE";
3527                    } else if(mapId == -2) {
3528                            s = " DEFAULT";
3529                    } else {
3530                            s = " " + String.valueOf(mapId);
3531                    }
3532                    out.writeLine("SET CHANNEL MIDI_INSTRUMENT_MAP " + samplerChn + s);
3533                    if(getPrintOnlyMode()) return;
3534                                    
3535                  ResultSet rs = getEmptyResultSet();                  ResultSet rs = getEmptyResultSet();
3536          }          }
# Line 2293  public class Client { Line 3553  public class Client {
3553                    
3554                  verifyConnection();                  verifyConnection();
3555                  out.writeLine("SET CHANNEL VOLUME " + samplerChn + ' ' + volume);                  out.writeLine("SET CHANNEL VOLUME " + samplerChn + ' ' + volume);
3556                    if(getPrintOnlyMode()) return;
3557                                    
3558                  ResultSet rs = getEmptyResultSet();                  ResultSet rs = getEmptyResultSet();
3559          }          }
# Line 2316  public class Client { Line 3577  public class Client {
3577                    
3578                  verifyConnection();                  verifyConnection();
3579                  out.writeLine("SET CHANNEL MUTE " + samplerChn + ' ' + (mute ? 1 : 0));                  out.writeLine("SET CHANNEL MUTE " + samplerChn + ' ' + (mute ? 1 : 0));
3580                    if(getPrintOnlyMode()) return;
3581                                    
3582                  ResultSet rs = getEmptyResultSet();                  ResultSet rs = getEmptyResultSet();
3583          }          }
# Line 2339  public class Client { Line 3601  public class Client {
3601                    
3602                  verifyConnection();                  verifyConnection();
3603                  out.writeLine("SET CHANNEL SOLO " + samplerChn + ' ' + (solo ? 1 : 0));                  out.writeLine("SET CHANNEL SOLO " + samplerChn + ' ' + (solo ? 1 : 0));
3604                    if(getPrintOnlyMode()) return;
3605                    
3606                    ResultSet rs = getEmptyResultSet();
3607            }
3608            
3609            /**
3610             * Creates an additional effect send on the specified sampler channel.
3611             * @param channel The sampler channel, on which a new effect send should be added.
3612             * @param midiCtrl Defines the MIDI controller, which
3613             * will be able alter the effect send level.
3614             * @return The unique ID of the newly created effect send entity.
3615             * @throws IOException If some I/O error occurs.
3616             * @throws LSException If the creation of the effect send failed.
3617             * @throws LscpException If LSCP protocol corruption occurs.
3618             * @see #destroyFxSend
3619             */
3620            public synchronized int
3621            createFxSend(int channel, int midiCtrl)
3622                            throws IOException, LSException, LscpException {
3623                    
3624                    return createFxSend(channel, midiCtrl, null);
3625            }
3626            
3627            /**
3628             * Creates an additional effect send on the specified sampler channel.
3629             * @param channel The sampler channel, on which the effect send should be created on.
3630             * @param midiCtrl Defines the MIDI controller, which can alter the effect send level.
3631             * @param name The name of the effect send entity. The name does not have to be unique.
3632             * @return The unique ID of the newly created effect send entity.
3633             * @throws IOException If some I/O error occurs.
3634             * @throws LSException If the creation of the effect send failed.
3635             * @throws LscpException If LSCP protocol corruption occurs.
3636             * @see #destroyFxSend
3637             */
3638            public synchronized int
3639            createFxSend(int channel, int midiCtrl, String name)
3640                            throws IOException, LSException, LscpException {
3641                    
3642                    verifyConnection();
3643                    String s = String.valueOf(channel) + " " + String.valueOf(midiCtrl);
3644                    if(name != null) s += " '" + toEscapedText(name) + "'";
3645                    out.writeLine("CREATE FX_SEND " + s);
3646                    if(getPrintOnlyMode()) return -1;
3647                    
3648                    ResultSet rs = getEmptyResultSet();
3649                    
3650                    return rs.getIndex();
3651            }
3652            
3653            /**
3654             * Destroys the specified effect send on the specified sampler channel.
3655             * @param channel The sampler channel, from which
3656             * the specified effect send should be removed.
3657             * @param fxSend The ID of the effect send that should be removed.
3658             * @throws LSException If some other error occurs.
3659             * @throws LscpException If LSCP protocol corruption occurs.
3660             * @see #createFxSend
3661             */
3662            public synchronized void
3663            destroyFxSend(int channel, int fxSend)
3664                            throws IOException, LSException, LscpException {
3665                    
3666                    verifyConnection();
3667                    String s = String.valueOf(channel) + " " + String.valueOf(fxSend);
3668                    out.writeLine("DESTROY FX_SEND " + s);
3669                    if(getPrintOnlyMode()) return;
3670                    
3671                    ResultSet rs = getEmptyResultSet();
3672            }
3673            
3674            /**
3675             * Gets the current number of effect sends on the specified sampler channel.
3676             * @param channel The ID of the sampler channel.
3677             * @return The current number of effect sends on the specified sampler channels.
3678             * @throws IOException If some I/O error occurs.
3679             * @throws LscpException If LSCP protocol corruption occurs.
3680             * @throws LSException If some other error occurs.
3681             */
3682            public synchronized int
3683            getFxSoundCount(int channel) throws IOException, LscpException, LSException {
3684                    verifyConnection();
3685                    out.writeLine("GET FX_SENDS " + String.valueOf(channel));
3686                    if(getPrintOnlyMode()) return -1;
3687                    
3688                    String s = getSingleLineResultSet().getResult();
3689                    return parseInt(s);
3690            }
3691            
3692            /**
3693             * Gets a list of all created effect sends on the specified sampler channel.
3694             * @param channel The sampler channel number.
3695             * @return A <code>FxSend</code> array providing all created
3696             * effect sends on the specified sampler channel.
3697             * @throws IOException If some I/O error occurs.
3698             * @throws LscpException If LSCP protocol corruption occurs.
3699             * @throws LSException If <code>channel</code> is not a valid sampler channel ID.
3700             * @see #createFxSend
3701             * @see #destroyFxSend
3702             */
3703            public synchronized FxSend[]
3704            getFxSends(int channel) throws IOException, LscpException, LSException {
3705                    Integer[] idS = getFxSendIDs(channel);
3706                    if(getPrintOnlyMode()) return null;
3707                    
3708                    FxSend[] fxSends = new FxSend[idS.length];
3709                    
3710                    for(int i = 0; i < fxSends.length; i++)
3711                            fxSends[i] = getFxSendInfo(channel, idS[i]);
3712                    
3713                    return fxSends;
3714            }
3715            
3716            /**
3717             * Gets a list of effect sends on the specified sampler channel.
3718             * @param channel The sampler channel number.
3719             * @return An <code>Integer</code> array providing
3720             * the numerical IDs of all effect sends on the specified sampler channel.
3721             * @throws IOException If some I/O error occurs.
3722             * @throws LscpException If LSCP protocol corruption occurs.
3723             * @throws LSException If <code>channel</code> is not a valid sampler channel ID.
3724             * @see #createFxSend
3725             * @see #destroyFxSend
3726             */
3727            public synchronized Integer[]
3728            getFxSendIDs(int channel) throws IOException, LscpException, LSException {
3729                    verifyConnection();
3730                    out.writeLine("LIST FX_SENDS " + channel);
3731                    if(getPrintOnlyMode()) return null;
3732                    
3733                    return parseIntList(getSingleLineResultSet().getResult());
3734            }
3735            
3736            /**
3737             * Gets the current settings of the specified effect send entity.
3738             * @param channel The sampler channel number.
3739             * @param fxSend The numerical ID of the effect send entity.
3740             * @return <code>FxSend</code> instance containing
3741             * the current settings of the specified effect send entity.
3742             * @throws IOException If an I/O error occurs.
3743             * @throws LscpException If LSCP protocol corruption occurs.
3744             * @throws LSException If the sampler channel and/or the effect send number are invalid.
3745             */
3746            public synchronized FxSend
3747            getFxSendInfo(int channel, int fxSend) throws IOException, LscpException, LSException {
3748                    verifyConnection();
3749                    String s = String.valueOf(channel) + " " + String.valueOf(fxSend);
3750                    out.writeLine("GET FX_SEND INFO " + s);
3751                    if(getPrintOnlyMode()) return null;
3752                    
3753                    ResultSet rs = getMultiLineResultSet();
3754                    FxSend fxs = new FxSend(rs.getMultiLineResult());
3755                    fxs.setFxSendId(fxSend);
3756                    
3757                    return fxs;
3758            }
3759            
3760            /**
3761             * Sets the name of the specified effect send.
3762             * @param channel The sampler channel number.
3763             * @param fxSend The numerical ID of the effect send entity.
3764             * @param name The new name for the specified effect send.
3765             * @throws IOException If some I/O error occurs.
3766             * @throws LscpException If LSCP protocol corruption occurs.
3767             * @throws LSException If <code>channel</code> is not a valid channel
3768             * number or <code>fxSend</code> is not a valid effect send ID;
3769             */
3770            public synchronized void
3771            setFxSendName(int channel, int fxSend, String name)
3772                                    throws IOException, LscpException, LSException {
3773                    
3774                    verifyConnection();
3775                    String args = " " + channel + " " + fxSend + " '" + toEscapedText(name) + "'";
3776                    out.writeLine("SET FX_SEND NAME" + args);
3777                    if(getPrintOnlyMode()) return;
3778                    
3779                    ResultSet rs = getEmptyResultSet();
3780            }
3781            
3782            /**
3783             * Sets the destination of an effect send's audio channel in the specified sampler channel.
3784             * @param channel The sampler channel number.
3785             * @param fxSend The numerical ID of the effect send entity to be rerouted.
3786             * @param audioSrc The numerical ID of the effect send's audio output channel,
3787             * which should be rerouted.
3788             * @param audioDst The audio channel of the selected audio output device
3789             * where <code>audioSrc</code> should be routed to.
3790             * @throws IOException If some I/O error occurs.
3791             * @throws LscpException If LSCP protocol corruption occurs.
3792             * @throws LSException If
3793             * <ul>
3794             * <li><code>channel</code> is not a valid channel number;
3795             * <li><code>fxSend</code> is not a valid effect send ID;
3796             * <li>There is no engine assigned yet to the specified sampler channel;
3797             * <li>There is no audio output device connected to the specified sampler channel.
3798             * </ul>
3799             */
3800            public synchronized void
3801            setFxSendAudioOutputChannel(int channel, int fxSend, int audioSrc, int audioDst)
3802                                    throws IOException, LscpException, LSException {
3803                    
3804                    verifyConnection();
3805                    String args = " " + channel + " " + fxSend + " " + audioSrc + " " + audioDst;
3806                    out.writeLine("SET FX_SEND AUDIO_OUTPUT_CHANNEL" + args);
3807                    if(getPrintOnlyMode()) return;
3808                    
3809                    ResultSet rs = getEmptyResultSet();
3810            }
3811            
3812            /**
3813             * Sets the MIDI controller, which will be able to modify
3814             * the send level of the specified effect send in the specified sampler channel.
3815             * @param channel The sampler channel number.
3816             * @param fxSend The numerical ID of the effect send entity.
3817             * @param midiCtrl The MIDI controller which shall be
3818             * able to modify the effect send's send level.
3819             * @throws IOException If some I/O error occurs.
3820             * @throws LscpException If LSCP protocol corruption occurs.
3821             * @throws LSException If
3822             * <ul>
3823             * <li><code>channel</code> is not a valid channel number;
3824             * <li><code>fxSend</code> is not a valid effect send ID;
3825             * <li><code>midiCtrl</code> is not a valid controller;
3826             * </ul>
3827             */
3828            public synchronized void
3829            setFxSendMidiController(int channel, int fxSend, int midiCtrl)
3830                                    throws IOException, LscpException, LSException {
3831                    
3832                    verifyConnection();
3833                    String args = " " + channel + " " + fxSend + " " + midiCtrl;
3834                    out.writeLine("SET FX_SEND MIDI_CONTROLLER" + args);
3835                    if(getPrintOnlyMode()) return;
3836                    
3837                    ResultSet rs = getEmptyResultSet();
3838            }
3839            
3840            /**
3841             * Sets the current send level of the specified
3842             * effect send entity in the specified sampler channel.
3843             * @param channel The sampler channel number.
3844             * @param fxSend The numerical ID of the effect send entity.
3845             * @param volume The new volume value (a value smaller than 1.0 means
3846             * attenuation, whereas a value greater than 1.0 means amplification).
3847             * @throws IOException If some I/O error occurs.
3848             * @throws LscpException If LSCP protocol corruption occurs.
3849             * @throws LSException If some other error occurs.
3850             */
3851            public synchronized void
3852            setFxSendLevel(int channel, int fxSend, float volume)
3853                                    throws IOException, LscpException, LSException {
3854                    
3855                    verifyConnection();
3856                    String args = " " + channel + " " + fxSend + " " + String.valueOf(volume);
3857                    out.writeLine("SET FX_SEND LEVEL" + args);
3858                    if(getPrintOnlyMode()) return;
3859                    
3860                    ResultSet rs = getEmptyResultSet();
3861            }
3862            
3863            /**
3864             * Starts an instrument editor for editing the loaded instrument
3865             * on the specified sampler channel.
3866             * @param samplerChn The sampler channel number.
3867             * @throws IOException If some I/O error occurs.
3868             * @throws LscpException If LSCP protocol corruption occurs.
3869             * @throws LSException If <code>samplerChn</code> is not a valid channel number or if
3870             * there is no instrument loaded on the specified sampler channel.
3871             * @see #getSamplerChannels
3872             */
3873            public synchronized void
3874            editChannelInstrument(int samplerChn) throws IOException, LscpException, LSException {
3875                    verifyConnection();
3876                    out.writeLine("EDIT CHANNEL INSTRUMENT " + samplerChn);
3877                    if(getPrintOnlyMode()) return;
3878                    
3879                    ResultSet rs = getEmptyResultSet();
3880            }
3881            
3882            
3883            
3884            /**
3885             * Adds the specified directory to the instruments database.
3886             * @param dir The absolute (escaped) path name of the directory to add.
3887             * @throws IOException If some I/O error occurs.
3888             * @throws LSException If the creation of the directory failed.
3889             * @throws LscpException If LSCP protocol corruption occurs.
3890             */
3891            public synchronized void
3892            addDbDirectory(String dir) throws IOException, LSException, LscpException {
3893                    verifyConnection();
3894                    out.writeLine("ADD DB_INSTRUMENT_DIRECTORY '" + conv(dir) + "'");
3895                    if(getPrintOnlyMode()) return;
3896                    
3897                    ResultSet rs = getEmptyResultSet();
3898            }
3899            
3900            /**
3901             * Removes the specified directory from the instruments database.
3902             * @param dir The absolute (escaped) path name of the directory to remove.
3903             * @throws IOException If some I/O error occurs.
3904             * @throws LscpException If LSCP protocol corruption occurs.
3905             * @throws LSException If the specified directory is not
3906             * empty or if the removal of the directory failed.
3907             */
3908            public synchronized void
3909            removeDbDirectory(String dir) throws IOException, LscpException, LSException {
3910                    removeDbDirectory(dir, false);
3911            }
3912            
3913            /**
3914             * Removes the specified directory from the instruments database.
3915             * @param dir The absolute path name of the directory to remove.
3916             * @param force If <code>true</code> forces the removal of non-empty
3917             * directory and all its content.
3918             * @throws IOException If some I/O error occurs.
3919             * @throws LscpException If LSCP protocol corruption occurs.
3920             * @throws LSException If the removing of the directory failed.
3921             */
3922            public synchronized void
3923            removeDbDirectory(String dir, boolean force)
3924                                    throws IOException, LscpException, LSException {
3925                    
3926                    verifyConnection();
3927                    String s = "REMOVE DB_INSTRUMENT_DIRECTORY ";
3928                    if(force) s += "FORCE ";
3929                    out.writeLine(s + "'" + conv(dir) + "'");
3930                    if(getPrintOnlyMode()) return;
3931                    
3932                    ResultSet rs = getEmptyResultSet();
3933            }
3934            
3935            /**
3936             * Removes the specified directories from the instruments database.
3937             * @param dirs The absolute (escaped) path names of the directories to remove.
3938             * @param force If <code>true</code> forces the removal of non-empty
3939             * directories.
3940             * @throws IOException If some I/O error occurs.
3941             * @throws LscpException If LSCP protocol corruption occurs.
3942             * @throws LSException If the removing of the directores failed.
3943             */
3944            public synchronized void
3945            removeDbDirectories(String[] dirs, boolean force)
3946                                    throws IOException, LscpException, LSException {
3947                    
3948                    verifyConnection();
3949                    String cmd = "REMOVE DB_INSTRUMENT_DIRECTORY ";
3950                    if(force) cmd += "FORCE ";
3951                    
3952                    for(String s : dirs) out.writeLine(cmd + "'" + conv(s) + "'");
3953                    
3954                    if(getPrintOnlyMode()) return;
3955                    
3956                    getEmptyResultSets(dirs.length, "Client.dirDeletionFailed!");
3957            }
3958            
3959            /**
3960             * Gets the number of directories in the specified directory.
3961             * @return The current number of directories in the specified directory.
3962             * @param dir The absolute path name of the directory.
3963             * @throws IOException If some I/O error occurs.
3964             * @throws LscpException If LSCP protocol corruption occurs.
3965             * @throws LSException If some other error occurs.
3966             */
3967            public synchronized int
3968            getDbDirectoryCount(String dir) throws IOException, LscpException, LSException {
3969                    return getDbDirectoryCount(dir, false);
3970            }
3971            
3972            /**
3973             * Gets the number of directories in the specified directory.
3974             * @return The current number of directories in the specified directory.
3975             * @param dir The absolute path name of the directory.
3976             * @param recursive If <code>true</code>, the number of all directories
3977             * in the specified subtree will be returned.
3978             * @throws IOException If some I/O error occurs.
3979             * @throws LscpException If LSCP protocol corruption occurs.
3980             * @throws LSException If some other error occurs.
3981             */
3982            public synchronized int
3983            getDbDirectoryCount(String dir, boolean recursive)
3984                                    throws IOException, LscpException, LSException {
3985                    
3986                    verifyConnection();
3987                    String s;
3988                    if(recursive) s = "GET DB_INSTRUMENT_DIRECTORIES RECURSIVE '";
3989                    else s = "GET DB_INSTRUMENT_DIRECTORIES '";
3990                    out.writeLine(s + conv(dir) + "'");
3991                    if(getPrintOnlyMode()) return -1;
3992                    
3993                    s = getSingleLineResultSet().getResult();
3994                    return parseInt(s);
3995            }
3996            
3997            /**
3998             * Gets the list of directories in the specified directory.
3999             * @param dir The absolute path name of the directory.
4000             * @return A <code>String</code> array providing the names of
4001             * all directories in the specified directory.
4002             * @throws IOException If some I/O error occurs.
4003             * @throws LscpException If LSCP protocol corruption occurs.
4004             * @throws LSException If the specified path name is invalid.
4005             */
4006            public synchronized String[]
4007            getDbDirectoryNames(String dir) throws IOException, LscpException, LSException {
4008                    verifyConnection();
4009                    out.writeLine("LIST DB_INSTRUMENT_DIRECTORIES '" + conv(dir) + "'");
4010                    if(getPrintOnlyMode()) return null;
4011                    
4012                    String[] names = parseEscapedStringList(getSingleLineResultSet().getResult());
4013                    for(int i = 0; i < names.length; i++) {
4014                            names[i] = toNonEscapedString(names[i]);
4015                    }
4016                    return names;
4017            }
4018            
4019            /**
4020             * Gets information about the specified directory.
4021             * @param dir The absolute path name of the directory.
4022             * @return A <code>DbDirectoryInfo</code> instance providing information
4023             * about the specified directory.
4024             * @throws IOException If some I/O error occurs.
4025             * @throws LscpException If LSCP protocol corruption occurs.
4026             * @throws LSException If the specified directory is not found.
4027             */
4028            public synchronized DbDirectoryInfo
4029            getDbDirectoryInfo(String dir) throws IOException, LscpException, LSException {
4030                    verifyConnection();
4031                    out.writeLine("GET DB_INSTRUMENT_DIRECTORY INFO '" + conv(dir) + "'");
4032                    if(getPrintOnlyMode()) return null;
4033                    
4034                    ResultSet rs = getMultiLineResultSet();
4035                    DbDirectoryInfo info = new DbDirectoryInfo(rs.getMultiLineResult());
4036                    if(dir.equals("/")) {
4037                            info.setName("/");
4038                    } else {
4039                            dir = removeEndingFileSeparator(dir);
4040                    }
4041                    String s = getFileName(dir);
4042                    if(s != null) info.setName(toNonEscapedFileName(s));
4043                    s = getParentDirectory(dir);
4044                    if(s != null) info.setParentDirectoryPath(s);
4045                    
4046                    return info;
4047            }
4048            
4049            /**
4050             * Gets the list of directories in the specified directory.
4051             * @param dir The absolute path name of the directory.
4052             * @return A <code>DbDirectoryInfo</code> array providing
4053             * information about all directories in the specified directory.
4054             * @throws IOException If some I/O error occurs.
4055             * @throws LscpException If LSCP protocol corruption occurs.
4056             * @throws LSException If the specified path name is invalid.
4057             */
4058            public synchronized DbDirectoryInfo[]
4059            getDbDirectories(String dir) throws IOException, LscpException, LSException {
4060                    String[] dirS = getDbDirectoryNames(dir);
4061                    if(!hasEndingFileSeparator(dir)) dir += "/";
4062                    DbDirectoryInfo[] infoS = new DbDirectoryInfo[dirS.length];
4063                    for(int i = 0; i < dirS.length; i++) {
4064                            infoS[i] = getDbDirectoryInfo(conv(dir) + toEscapedFsEntry(dirS[i]));
4065                    }
4066                    return infoS;
4067            }
4068            
4069            /**
4070             * Gets the list of directories in the specified directory.
4071             * @param dir The absolute path name of the directory.
4072             * @return A <code>DbDirectoryInfo</code> array providing
4073             * information about all directories in the specified directory.
4074             * @throws IOException If some I/O error occurs.
4075             * @throws LscpException If LSCP protocol corruption occurs.
4076             * @throws LSException If the specified path name is invalid.
4077             *
4078            public synchronized DbDirectoryInfo[]
4079            getDbDirectories(String dir) throws IOException, LscpException, LSException {
4080                    String[] dirS = getDbDirectoryNames(conv(dir));
4081                    if(dirS.length == 0) return new DbDirectoryInfo[0];
4082                    
4083                    if(dir.charAt(dir.length() - 1) != '/') dir += "/"; // FIXME:
4084                    
4085                    for(int i = 0; i < dirS.length; i++) {
4086                            out.writeLine("GET DB_INSTRUMENT_DIRECTORY INFO '" + conv(dir + dirS[i]) + "'");
4087                    }
4088                    
4089                    if(getPrintOnlyMode()) return null;
4090                    
4091                    if(dir.length() > 1) dir = dir.substring(0, dir.length() - 1);
4092                    StringBuffer sb = new StringBuffer();
4093                    DbDirectoryInfo[] infoS = new DbDirectoryInfo[dirS.length];
4094                    for(int i = 0; i < dirS.length; i++) {
4095                            try {
4096                                    ResultSet rs = getMultiLineResultSet();
4097                                    infoS[i] = new DbDirectoryInfo(rs.getMultiLineResult());
4098                                    infoS[i].setName(dirS[i]);
4099                                    infoS[i].setParentDirectoryPath(dir);
4100                            } catch (SocketTimeoutException e) {
4101                                    getLogger().log(Level.FINE, e.getMessage(), e);
4102                                    sb.append(e.getMessage()).append("\n");
4103                                    break;
4104                            } catch (Exception e) {
4105                                    getLogger().log(Level.FINE, e.getMessage(), e);
4106                                    sb.append(e.getMessage()).append("\n");
4107                            }
4108                    }
4109                    
4110                    String details = sb.toString();
4111                    if(details.length() > 0) {
4112                            String err = LscpI18n.getLogMsg("Client.getInstrsInfoFailed!");
4113                            throw new LSException(0, err, details);
4114                    }
4115                    
4116                    return infoS;
4117            }*/
4118            
4119            /**
4120             * Renames the specified directory.
4121             * @param dir The absolute path name of the directory to rename.
4122             * @param name The new name for the directory.
4123             * @throws IOException If some I/O error occurs.
4124             * @throws LSException If the renaming of the directory failed.
4125             * @throws LscpException If LSCP protocol corruption occurs.
4126             */
4127            public synchronized void
4128            renameDbDirectory(String dir, String name) throws IOException, LSException, LscpException {
4129                    verifyConnection();
4130                    name = toEscapedText(name);
4131                    out.writeLine("SET DB_INSTRUMENT_DIRECTORY NAME '" + conv(dir) + "' '" + conv(name) + "'");
4132                    if(getPrintOnlyMode()) return;
4133                    
4134                    ResultSet rs = getEmptyResultSet();
4135            }
4136            
4137            /**
4138             * Moves the specified directory into the specified location.
4139             * @param dir The absolute path name of the directory to move.
4140             * @param dst The location where the directory will be moved to.
4141             * @throws IOException If some I/O error occurs.
4142             * @throws LSException If the operation failed.
4143             * @throws LscpException If LSCP protocol corruption occurs.
4144             */
4145            public synchronized void
4146            moveDbDirectory(String dir, String dst) throws IOException, LSException, LscpException {
4147                    verifyConnection();
4148                    out.writeLine("MOVE DB_INSTRUMENT_DIRECTORY '" + conv(dir) + "' '" + conv(dst) + "'");
4149                    if(getPrintOnlyMode()) return;
4150                    
4151                    ResultSet rs = getEmptyResultSet();
4152            }
4153            
4154            /**
4155             * Moves the specified directories into the specified location.
4156             * @param dirs The absolute path names of the directories to move.
4157             * @param dst The location where the directories will be moved to.
4158             * @throws IOException If some I/O error occurs.
4159             * @throws LSException If the operation failed.
4160             * @throws LscpException If LSCP protocol corruption occurs.
4161             */
4162            public synchronized void
4163            moveDbDirectories(String dirs[], String dst) throws IOException, LSException, LscpException {
4164                    verifyConnection();
4165                    for(String s : dirs) {
4166                            out.writeLine("MOVE DB_INSTRUMENT_DIRECTORY '" + conv(s) + "' '" + conv(dst) + "'");
4167                    }
4168                    if(getPrintOnlyMode()) return;
4169                    
4170                    getEmptyResultSets(dirs.length, "Client.dirMovingFailed!");
4171            }
4172            
4173            /**
4174             * Copies the specified directory into the specified location.
4175             * @param dir The absolute path name of the directory to copy.
4176             * @param dst The location where the directory will be copied to.
4177             * @throws IOException If some I/O error occurs.
4178             * @throws LSException If the operation failed.
4179             * @throws LscpException If LSCP protocol corruption occurs.
4180             */
4181            public synchronized void
4182            copyDbDirectory(String dir, String dst) throws IOException, LSException, LscpException {
4183                    verifyConnection();
4184                    out.writeLine("COPY DB_INSTRUMENT_DIRECTORY '" + conv(dir) + "' '" + conv(dst) + "'");
4185                    if(getPrintOnlyMode()) return;
4186                    
4187                    ResultSet rs = getEmptyResultSet();
4188            }
4189            
4190            /**
4191             * Copies the specified directories into the specified location.
4192             * @param dirs The absolute path names of the directories to copy.
4193             * @param dst The location where the directories will be copied to.
4194             * @throws IOException If some I/O error occurs.
4195             * @throws LSException If the operation failed.
4196             * @throws LscpException If LSCP protocol corruption occurs.
4197             */
4198            public synchronized void
4199            copyDbDirectories(String[] dirs, String dst) throws IOException, LSException, LscpException {
4200                    verifyConnection();
4201                    for(String s : dirs) {
4202                            out.writeLine("COPY DB_INSTRUMENT_DIRECTORY '" + conv(s) + "' '" + conv(dst) + "'");
4203                    }
4204                    if(getPrintOnlyMode()) return;
4205                    
4206                    getEmptyResultSets(dirs.length, "Client.dirCopyingFailed!");
4207            }
4208            
4209            /**
4210             * Changes the description of the specified directory.
4211             * @param dir The absolute path name of the directory.
4212             * @param desc The new description for the directory.
4213             * @throws IOException If some I/O error occurs.
4214             * @throws LSException If failed to change the description.
4215             * @throws LscpException If LSCP protocol corruption occurs.
4216             */
4217            public synchronized void
4218            setDbDirectoryDescription(String dir, String desc)
4219                                    throws IOException, LSException, LscpException {
4220                    
4221                    verifyConnection();
4222                    String s = "SET DB_INSTRUMENT_DIRECTORY DESCRIPTION '";
4223                    out.writeLine(s + conv(dir) + "' '" + toEscapedText(desc) + "'");
4224                    if(getPrintOnlyMode()) return;
4225                    
4226                    ResultSet rs = getEmptyResultSet();
4227            }
4228            
4229            public static enum ScanMode {
4230                    RECURSIVE, NON_RECURSIVE, FLAT
4231            }
4232            
4233            /**
4234             * Adds the specified instrument to the specified instruments database directory.
4235             * @param dbDir The absolute path name of the database directory in which the
4236             * specified instrument will be added.
4237             * @param filePath The absolute path name of the instrument file.
4238             * @param instrIndex The index of the instrument (in the given instrument file) to add.
4239             * @throws IOException If some I/O error occurs.
4240             * @throws LSException If the operation failed.
4241             * @throws LscpException If LSCP protocol corruption occurs.
4242             */
4243            public synchronized void
4244            addDbInstrument(String dbDir, String filePath, int instrIndex)
4245                                            throws IOException, LSException, LscpException {
4246                    
4247                    addDbInstrument(dbDir, filePath, instrIndex, false);
4248            }
4249            
4250            /**
4251             * Adds the specified instrument to the specified instruments database directory.
4252             * @param dbDir The absolute path name of the database directory in which the
4253             * specified instrument will be added.
4254             * @param filePath The absolute path name of the instrument file.
4255             * @param instrIndex The index of the instrument (in the given instrument file) to add.
4256             * @param background If <code>true</code>, the scan will be done
4257             * in background and this method may return before the job is finished.
4258             * @return If <code>background</code> is <code>true</code>, the ID
4259             * of the scan job.
4260             * @throws IOException If some I/O error occurs.
4261             * @throws LSException If the operation failed.
4262             * @throws LscpException If LSCP protocol corruption occurs.
4263             * @see #addInstrumentsDbListener
4264             */
4265            public synchronized int
4266            addDbInstrument(String dbDir, String filePath, int instrIndex, boolean background)
4267                                            throws IOException, LSException, LscpException {
4268                    
4269                    verifyConnection();
4270                    String s = "ADD DB_INSTRUMENTS";
4271                    if(background) s += " NON_MODAL";
4272                    s += " '" + conv(dbDir) + "' '" + conv(filePath) + "' ";
4273                    out.writeLine(s + String.valueOf(instrIndex));
4274                    if(getPrintOnlyMode()) return -1;
4275                    
4276                    ResultSet rs = getEmptyResultSet();
4277                    return rs.getIndex();
4278            }
4279            
4280            /**
4281             * Adds the instruments in the specified file to the specified
4282             * instruments database directory.
4283             * @param dbDir The absolute path name of the database directory
4284             * in which the the supported instruments will be added.
4285             * @param filePath The absolute path name of the file to scan for instruments.
4286             * @throws IOException If some I/O error occurs.
4287             * @throws LSException If the operation failed.
4288             * @throws LscpException If LSCP protocol corruption occurs.
4289             */
4290            public synchronized void
4291            addDbInstruments(String dbDir, String filePath)
4292                                            throws IOException, LSException, LscpException {
4293                    
4294                    addDbInstruments(dbDir, filePath, false);
4295            }
4296            
4297            /**
4298             * Adds the instruments in the specified file to the specified
4299             * instruments database directory.
4300             * @param dbDir The absolute path name of the database directory
4301             * in which the the supported instruments will be added.
4302             * @param filePath The absolute path name of the file to scan for instruments.
4303             * @param background If <code>true</code>, the scan will be done
4304             * in background and this method may return before the job is finished.
4305             * @return If <code>background</code> is <code>true</code>, the ID
4306             * of the scan job.
4307             * @throws IOException If some I/O error occurs.
4308             * @throws LSException If the operation failed.
4309             * @throws LscpException If LSCP protocol corruption occurs.
4310             * @see #addInstrumentsDbListener
4311             */
4312            public synchronized int
4313            addDbInstruments(String dbDir, String filePath, boolean background)
4314                                            throws IOException, LSException, LscpException {
4315                    
4316                    verifyConnection();
4317                    String s = "ADD DB_INSTRUMENTS";
4318                    if(background) s += " NON_MODAL";
4319                    out.writeLine(s + " '" + conv(dbDir) + "' '" + conv(filePath) + "'");
4320                    if(getPrintOnlyMode()) return -1;
4321                    
4322                    ResultSet rs = getEmptyResultSet();
4323                    return rs.getIndex();
4324            }
4325            
4326            /**
4327             * Adds the instruments in the specified file system directory
4328             * to the specified instruments database directory.
4329             * @param mode Determines the scanning mode. If RECURSIVE is
4330             * specified, all supported instruments in the specified file system
4331             * direcotry will be added to the specified instruments database
4332             * directory, including the instruments in subdirectories
4333             * of the supplied directory. If NON_RECURSIVE is specified,
4334             * the instruments in the subdirectories will not be processed.
4335             * If FLAT is specified, all supported instruments in the specified
4336             * file system direcotry will be added, including the instruments in
4337             * subdirectories of the supplied directory, but the respective
4338             * subdirectory structure will not be recreated in the instruments
4339             * database and all instruments will be added directly in the
4340             * specified database directory.
4341             * @param dbDir The absolute path name of the database directory
4342             * in which the supported instruments will be added.
4343             * @param fsDir The absolute path name of the file system directory.
4344             * @throws IOException If some I/O error occurs.
4345             * @throws LSException If the operation failed.
4346             * @throws LscpException If LSCP protocol corruption occurs.
4347             */
4348            public synchronized void
4349            addDbInstruments(ScanMode mode, String dbDir, String fsDir)
4350                                            throws IOException, LSException, LscpException {
4351                    
4352                    addDbInstruments(mode, dbDir, fsDir, false);
4353            }
4354            
4355            /**
4356             * Adds the instruments in the specified file system directory
4357             * to the specified instruments database directory.
4358             * @param mode Determines the scanning mode. If RECURSIVE is
4359             * specified, all supported instruments in the specified file system
4360             * direcotry will be added to the specified instruments database
4361             * directory, including the instruments in subdirectories
4362             * of the supplied directory. If NON_RECURSIVE is specified,
4363             * the instruments in the subdirectories will not be processed.
4364             * If FLAT is specified, all supported instruments in the specified
4365             * file system direcotry will be added, including the instruments in
4366             * subdirectories of the supplied directory, but the respective
4367             * subdirectory structure will not be recreated in the instruments
4368             * database and all instruments will be added directly in the
4369             * specified database directory.
4370             * @param dbDir The absolute path name of the database directory
4371             * in which the supported instruments will be added.
4372             * @param fsDir The absolute path name of the file system directory.
4373             * @param background If <code>true</code>, the scan will be done
4374             * in background and this method may return before the job is finished.
4375             * @return If <code>background</code> is <code>true</code>, the ID
4376             * of the scan job.
4377             * @throws IOException If some I/O error occurs.
4378             * @throws LSException If the operation failed.
4379             * @throws LscpException If LSCP protocol corruption occurs.
4380             * @see #addInstrumentsDbListener
4381             */
4382            public synchronized int
4383            addDbInstruments(ScanMode mode, String dbDir, String fsDir, boolean background)
4384                                            throws IOException, LSException, LscpException {
4385                    
4386                    verifyConnection();
4387                    StringBuffer sb = new StringBuffer("ADD DB_INSTRUMENTS");
4388                    if(background) sb.append(" NON_MODAL");
4389                    
4390                    switch(mode) {
4391                            case RECURSIVE:
4392                                    sb.append(" RECURSIVE");
4393                                    break;
4394                            case NON_RECURSIVE:
4395                                    sb.append(" NON_RECURSIVE");
4396                                    break;
4397                            case FLAT:
4398                                    sb.append(" FLAT");
4399                                    break;
4400                    }
4401                    
4402                    sb.append(" '").append(conv(dbDir)).append("' '");
4403                    sb.append(conv(fsDir)).append("'");
4404                    out.writeLine(sb.toString());
4405                    if(getPrintOnlyMode()) return -1;
4406                    
4407                    ResultSet rs = getEmptyResultSet();
4408                    return rs.getIndex();
4409            }
4410            
4411            /**
4412             * Removes the specified instrument from the instruments database.
4413             * @param instr The absolute path name of the instrument to remove.
4414             * @throws IOException If some I/O error occurs.
4415             * @throws LscpException If LSCP protocol corruption occurs.
4416             * @throws LSException If the removing of the instrument failed.
4417             */
4418            public synchronized void
4419            removeDbInstrument(String instr) throws IOException, LscpException, LSException {
4420                    
4421                    verifyConnection();
4422                    out.writeLine("REMOVE DB_INSTRUMENT '" + conv(instr) + "'");
4423                    if(getPrintOnlyMode()) return;
4424                    
4425                    ResultSet rs = getEmptyResultSet();
4426            }
4427            
4428            /**
4429             * Removes the specified instruments from the instruments database.
4430             * @param instrs The absolute path names of the instruments to remove.
4431             * @throws IOException If some I/O error occurs.
4432             * @throws LscpException If LSCP protocol corruption occurs.
4433             * @throws LSException If the removing of the instruments failed.
4434             */
4435            public synchronized void
4436            removeDbInstruments(String[] instrs) throws IOException, LscpException, LSException {
4437                    verifyConnection();
4438                    for(String s : instrs) {
4439                            out.writeLine("REMOVE DB_INSTRUMENT '" + conv(s) + "'");
4440                    }
4441                    if(getPrintOnlyMode()) return;
4442                    
4443                    getEmptyResultSets(instrs.length, "Client.instrDeletionFailed!");
4444            }
4445            
4446            /**
4447             * Gets the number of instruments in the specified directory.
4448             * @return The current number of instruments in the specified directory.
4449             * @param dir The absolute path name of the directory.
4450             * @throws IOException If some I/O error occurs.
4451             * @throws LscpException If LSCP protocol corruption occurs.
4452             * @throws LSException If some other error occurs.
4453             */
4454            public synchronized int
4455            getDbInstrumentCount(String dir) throws IOException, LscpException, LSException {
4456                    return getDbInstrumentCount(dir, false);
4457            }
4458            
4459            /**
4460             * Gets the number of instruments in the specified directory.
4461             * @return The current number of instruments in the specified directory.
4462             * @param dir The absolute path name of the directory.
4463             * @param recursive If <code>true</code>, the number of all instruments
4464             * in the specified subtree will be returned.
4465             * @throws IOException If some I/O error occurs.
4466             * @throws LscpException If LSCP protocol corruption occurs.
4467             * @throws LSException If some other error occurs.
4468             */
4469            public synchronized int
4470            getDbInstrumentCount(String dir, boolean recursive)
4471                                    throws IOException, LscpException, LSException {
4472                    
4473                    verifyConnection();
4474                    String s;
4475                    if(recursive) s = "GET DB_INSTRUMENTS RECURSIVE '";
4476                    else s = "GET DB_INSTRUMENTS '";
4477                    out.writeLine(s + conv(dir) + "'");
4478                    if(getPrintOnlyMode()) return -1;
4479                    
4480                    s = getSingleLineResultSet().getResult();
4481                    return parseInt(s);
4482            }
4483            
4484            /**
4485             * Gets the list of instruments in the specified directory.
4486             * @param dir The absolute path name of the directory.
4487             * @return A <code>String</code> array providing the names of
4488             * all instruments in the specified directory.
4489             * @throws IOException If some I/O error occurs.
4490             * @throws LscpException If LSCP protocol corruption occurs.
4491             * @throws LSException If the specified path name is invalid.
4492             */
4493            public synchronized String[]
4494            getDbInstrumentNames(String dir) throws IOException, LscpException, LSException {
4495                    verifyConnection();
4496                    out.writeLine("LIST DB_INSTRUMENTS '" + conv(dir) + "'");
4497                    if(getPrintOnlyMode()) return null;
4498                    
4499                    String[] names = parseEscapedStringList(getSingleLineResultSet().getResult());
4500                    for(int i = 0; i < names.length; i++) {
4501                            names[i] = toNonEscapedString(names[i]);
4502                    }
4503                    return names;
4504            }
4505            
4506            /**
4507             * Gets information about the specified instrument.
4508             * @param instr The absolute path name of the instrument.
4509             * @return A <code>DbInstrumentInfo</code> instance providing information
4510             * about the specified instrument.
4511             * @throws IOException If some I/O error occurs.
4512             * @throws LscpException If LSCP protocol corruption occurs.
4513             * @throws LSException If the specified instrument is not found.
4514             */
4515            public synchronized DbInstrumentInfo
4516            getDbInstrumentInfo(String instr) throws IOException, LscpException, LSException {
4517                    verifyConnection();
4518                    out.writeLine("GET DB_INSTRUMENT INFO '" + conv(instr) + "'");
4519                    if(getPrintOnlyMode()) return null;
4520                    
4521                    ResultSet rs = getMultiLineResultSet();
4522                    DbInstrumentInfo info = new DbInstrumentInfo(rs.getMultiLineResult());
4523                    String s = getParentDirectory(instr);
4524                    if(s != null) info.setDirectoryPath(s);
4525                    s = getFileName(instr);
4526                    if(s != null) info.setName(toNonEscapedFileName(s));
4527                    
4528                    return info;
4529            }
4530            
4531            /**
4532             * Gets the list of instruments in the specified directory.
4533             * @param dir The absolute path name of the directory.
4534             * @return A <code>DbInstrumentInfo</code> array providing
4535             * information about all instruments in the specified directory.
4536             * @throws IOException If some I/O error occurs.
4537             * @throws LscpException If LSCP protocol corruption occurs.
4538             * @throws LSException If the specified path name is invalid.
4539             */
4540            public synchronized DbInstrumentInfo[]
4541            getDbInstruments(String dir) throws IOException, LscpException, LSException {
4542                    String[] instrS = getDbInstrumentNames(dir);
4543                    if(!hasEndingFileSeparator(dir)) dir += "/";
4544                    
4545                    DbInstrumentInfo[] infoS = new DbInstrumentInfo[instrS.length];
4546                    for(int i = 0; i < instrS.length; i++) {
4547                            infoS[i] = getDbInstrumentInfo(conv(dir) + toEscapedFsEntry(instrS[i]));
4548                    }
4549                    return infoS;
4550            }
4551            
4552            /**
4553             * Gets the list of instruments in the specified directory.
4554             * @param dir The absolute path name of the directory.
4555             * @return A <code>DbInstrumentInfo</code> array providing
4556             * information about all instruments in the specified directory.
4557             * @throws IOException If some I/O error occurs.
4558             * @throws LscpException If LSCP protocol corruption occurs.
4559             * @throws LSException If the specified path name is invalid.
4560             *
4561            public synchronized DbInstrumentInfo[]
4562            getDbInstruments(String dir) throws IOException, LscpException, LSException {
4563                    String[] instrS = getDbInstrumentNames(dir);
4564                    if(instrS.length == 0) return new DbInstrumentInfo[0];
4565                    
4566                    if(dir.charAt(dir.length() - 1) != '/') dir += "/"; FIXME:
4567                    
4568                    for(int i = 0; i < instrS.length; i++) {
4569                            out.writeLine("GET DB_INSTRUMENT INFO '" + conv(dir) + instrS[i] + "'");
4570                    }
4571                    
4572                    if(getPrintOnlyMode()) return null;
4573                    
4574                    if(dir.length() > 1) dir = dir.substring(0, dir.length() - 1);
4575                    StringBuffer sb = new StringBuffer();
4576                    DbInstrumentInfo[] infoS = new DbInstrumentInfo[instrS.length];
4577                    for(int i = 0; i < instrS.length; i++) {
4578                            try {
4579                                    ResultSet rs = getMultiLineResultSet();
4580                                    infoS[i] = new DbInstrumentInfo(rs.getMultiLineResult());
4581                                    infoS[i].setName(instrS[i]);
4582                                    infoS[i].setDirectoryPath(dir);
4583                            } catch (SocketTimeoutException e) {
4584                                    getLogger().log(Level.FINE, e.getMessage(), e);
4585                                    sb.append(e.getMessage()).append("\n");
4586                                    break;
4587                            } catch (Exception e) {
4588                                    getLogger().log(Level.FINE, e.getMessage(), e);
4589                                    sb.append(e.getMessage()).append("\n");
4590                            }
4591                    }
4592                    
4593                    String details = sb.toString();
4594                    if(details.length() > 0) {
4595                            String err = LscpI18n.getLogMsg("Client.getInstrsInfoFailed!");
4596                            throw new LSException(0, err, details);
4597                    }
4598                    
4599                    return infoS;
4600            }*/
4601            
4602            /**
4603             * Renames the specified instrument.
4604             * @param instr The absolute path name of the instrument to rename.
4605             * @param name The new name for the instrument.
4606             * @throws IOException If some I/O error occurs.
4607             * @throws LSException If the renaming of the instrument failed.
4608             * @throws LscpException If LSCP protocol corruption occurs.
4609             */
4610            public synchronized void
4611            renameDbInstrument(String instr, String name)
4612                                    throws IOException, LSException, LscpException {
4613                    
4614                    verifyConnection();
4615                    name = toEscapedText(name);
4616                    out.writeLine("SET DB_INSTRUMENT NAME '" + conv(instr) + "' '" + conv(name) + "'");
4617                    if(getPrintOnlyMode()) return;
4618                    
4619                    ResultSet rs = getEmptyResultSet();
4620            }
4621            
4622            /**
4623             * Moves the specified instrument into the specified location.
4624             * @param instr The absolute path name of the instrument to move.
4625             * @param dst The directory where the specified instrument will be moved to.
4626             * @throws IOException If some I/O error occurs.
4627             * @throws LSException If the operation failed.
4628             * @throws LscpException If LSCP protocol corruption occurs.
4629             */
4630            public synchronized void
4631            moveDbInstrument(String instr, String dst) throws IOException, LSException, LscpException {
4632                    verifyConnection();
4633                    out.writeLine("MOVE DB_INSTRUMENT '" + conv(instr) + "' '" + conv(dst) + "'");
4634                    if(getPrintOnlyMode()) return;
4635                    
4636                    ResultSet rs = getEmptyResultSet();
4637            }
4638            
4639            /**
4640             * Moves the specified instruments into the specified location.
4641             * @param instrs The absolute path names of the instruments to move.
4642             * @param dst The directory where the specified instruments will be moved to.
4643             * @throws IOException If some I/O error occurs.
4644             * @throws LSException If the operation failed.
4645             * @throws LscpException If LSCP protocol corruption occurs.
4646             */
4647            public synchronized void
4648            moveDbInstruments(String[] instrs, String dst) throws IOException, LSException, LscpException {
4649                    verifyConnection();
4650                    for(String s : instrs) {
4651                            out.writeLine("MOVE DB_INSTRUMENT '" + conv(s) + "' '" + conv(dst) + "'");
4652                    }
4653                    if(getPrintOnlyMode()) return;
4654                    
4655                    getEmptyResultSets(instrs.length, "Client.instrMovingFailed!");
4656            }
4657            
4658            /**
4659             * Copies the specified instrument into the specified location.
4660             * @param instr The absolute path name of the instrument to copy.
4661             * @param dst The directory where the specified instrument will be copied to.
4662             * @throws IOException If some I/O error occurs.
4663             * @throws LSException If the operation failed.
4664             * @throws LscpException If LSCP protocol corruption occurs.
4665             */
4666            public synchronized void
4667            copyDbInstrument(String instr, String dst) throws IOException, LSException, LscpException {
4668                    verifyConnection();
4669                    out.writeLine("COPY DB_INSTRUMENT '" + conv(instr) + "' '" + conv(dst) + "'");
4670                    if(getPrintOnlyMode()) return;
4671                    
4672                    ResultSet rs = getEmptyResultSet();
4673            }
4674            
4675            /**
4676             * Copies the specified instruments into the specified location.
4677             * @param instrs The absolute path name of the instruments to copy.
4678             * @param dst The directory where the specified instruments will be copied to.
4679             * @throws IOException If some I/O error occurs.
4680             * @throws LSException If the operation failed.
4681             * @throws LscpException If LSCP protocol corruption occurs.
4682             */
4683            public synchronized void
4684            copyDbInstruments(String[] instrs, String dst) throws IOException, LSException, LscpException {
4685                    verifyConnection();
4686                    for(String s : instrs) {
4687                            out.writeLine("COPY DB_INSTRUMENT '" + conv(s) + "' '" + conv(dst) + "'");
4688                    }
4689                    if(getPrintOnlyMode()) return;
4690                    
4691                    getEmptyResultSets(instrs.length, "Client.instrCopyingFailed!");
4692            }
4693            
4694            /**
4695             * Changes the description of the specified instrument.
4696             * @param instr The absolute path name of the instrument.
4697             * @param desc The new description for the instrument.
4698             * @throws IOException If some I/O error occurs.
4699             * @throws LSException If failed to change the description.
4700             * @throws LscpException If LSCP protocol corruption occurs.
4701             */
4702            public synchronized void
4703            setDbInstrumentDescription(String instr, String desc)
4704                                    throws IOException, LSException, LscpException {
4705                    
4706                    verifyConnection();
4707                    desc = toEscapedText(desc);
4708                    out.writeLine("SET DB_INSTRUMENT DESCRIPTION '" + conv(instr) + "' '" + desc + "'");
4709                    if(getPrintOnlyMode()) return;
4710                    
4711                    ResultSet rs = getEmptyResultSet();
4712            }
4713            
4714            /**
4715             * Substitutes all occurrences of the instrument file
4716             * <code>oldPath</code> in the database, with <code>newPath</code>.
4717             * @param oldPath The absolute path name of the instrument file to substitute.
4718             * @param newPath The new absolute path name.
4719             * @throws IOException If some I/O error occurs.
4720             * @throws LSException If the operation failed.
4721             * @throws LscpException If LSCP protocol corruption occurs.
4722             */
4723            public synchronized void
4724            setDbInstrumentFilePath(String oldPath, String newPath)
4725                                    throws IOException, LSException, LscpException {
4726                    
4727                    verifyConnection();
4728                    out.writeLine("SET DB_INSTRUMENT FILE_PATH '" + conv(oldPath) + "' '" + conv(newPath) + "'");
4729                    if(getPrintOnlyMode()) return;
4730                    
4731                    ResultSet rs = getEmptyResultSet();
4732            }
4733            
4734            /**
4735             * Finds all directories in the specified directory
4736             * that corresponds to the specified search criterias.
4737             * @param dir The absolute path name of the directory to search.
4738             * @param query Provides the search criterias.
4739             * @return A <code>DbDirectoryInfo</code> array providing
4740             * information about all directories that are found in the specified directory.
4741             * @throws IOException If some I/O error occurs.
4742             * @throws LscpException If LSCP protocol corruption occurs.
4743             * @throws LSException If the specified path name is invalid.
4744             */
4745            public synchronized DbDirectoryInfo[]
4746            findDbDirectories(String dir, DbSearchQuery query)
4747                                    throws IOException, LscpException, LSException {
4748                    
4749                    return findDbDirectories(dir, query, false);
4750            }
4751            
4752            /**
4753             * Finds all directories in the specified directory
4754             * that corresponds to the specified search criterias.
4755             * @param dir The absolute path name of the directory to search.
4756             * @param query Provides the search criterias.
4757             * @param nonRecursive If <code>true</code>, the search will be non-recursive.
4758             * @return A <code>DbDirectoryInfo</code> array providing
4759             * information about all directories that are found in the specified directory.
4760             * @throws IOException If some I/O error occurs.
4761             * @throws LscpException If LSCP protocol corruption occurs.
4762             * @throws LSException If the specified path name is invalid.
4763             */
4764            public synchronized DbDirectoryInfo[]
4765            findDbDirectories(String dir, DbSearchQuery query, boolean nonRecursive)
4766                                    throws IOException, LscpException, LSException {
4767                    
4768                    verifyConnection();
4769                    StringBuffer sb = new StringBuffer();
4770                    sb.append("FIND DB_INSTRUMENT_DIRECTORIES");
4771                    if(nonRecursive) sb.append(" NON_RECURSIVE");
4772                    sb.append(" '").append(conv(dir)).append("'");
4773                    
4774                    if(query.name != null && query.name.length() > 0) {
4775                            sb.append(" NAME='").append(toEscapedText(query.name)).append("'");
4776                    }
4777                    
4778                    String s = query.getCreatedAfter();
4779                    String s2 = query.getCreatedBefore();
4780                    if(s != null || s2 != null) {
4781                            sb.append(" CREATED='");
4782                            if(s != null) sb.append(s);
4783                            sb.append("..");
4784                            if(s2 != null) sb.append(s2);
4785                            sb.append("'");
4786                    }
4787                    
4788                    s = query.getModifiedAfter();
4789                    s2 = query.getModifiedBefore();
4790                    if(s != null || s2 != null) {
4791                            sb.append(" MODIFIED='");
4792                            if(s != null) sb.append(s);
4793                            sb.append("..");
4794                            if(s2 != null) sb.append(s2);
4795                            sb.append("'");
4796                    }
4797                    
4798                    if(query.description != null && query.description.length() > 0) {
4799                            sb.append(" DESCRIPTION='");
4800                            sb.append(toEscapedText(query.description)).append("'");
4801                    }
4802                    
4803                    out.writeLine(sb.toString());
4804                    if(getPrintOnlyMode()) return null;
4805                    
4806                    String[] dirS = parseEscapedStringList(getSingleLineResultSet().getResult());
4807                    
4808                    DbDirectoryInfo[] infoS = new DbDirectoryInfo[dirS.length];
4809                    for(int i = 0; i < dirS.length; i++) {
4810                            infoS[i] = getDbDirectoryInfo(dirS[i]);
4811                    }
4812                    return infoS;
4813            }
4814            
4815            /**
4816             * Finds all instruments in the specified directory
4817             * that corresponds to the specified search criterias.
4818             * @param dir The absolute path name of the directory to search.
4819             * @param query Provides the search criterias.
4820             * @return A <code>DbInstrumentInfo</code> array providing
4821             * information about all instruments that are found in the specified directory.
4822             * @throws IOException If some I/O error occurs.
4823             * @throws LscpException If LSCP protocol corruption occurs.
4824             * @throws LSException If the specified path name is invalid.
4825             */
4826            public synchronized DbInstrumentInfo[]
4827            findDbInstruments(String dir, DbSearchQuery query)
4828                                    throws IOException, LscpException, LSException {
4829                    
4830                    return findDbInstruments(dir, query, false);
4831            }
4832            
4833            /**
4834             * Finds all instruments in the specified directory
4835             * that corresponds to the specified search criterias.
4836             * @param dir The absolute path name of the directory to search.
4837             * @param query Provides the search criterias.
4838             * @param nonRecursive If <code>true</code>, the search will be non-recursive.
4839             * @return A <code>DbInstrumentInfo</code> array providing
4840             * information about all instruments that are found in the specified directory.
4841             * @throws IOException If some I/O error occurs.
4842             * @throws LscpException If LSCP protocol corruption occurs.
4843             * @throws LSException If the specified path name is invalid.
4844             */
4845            public synchronized DbInstrumentInfo[]
4846            findDbInstruments(String dir, DbSearchQuery query, boolean nonRecursive)
4847                                    throws IOException, LscpException, LSException {
4848                    
4849                    verifyConnection();
4850                    StringBuffer sb = new StringBuffer();
4851                    sb.append("FIND DB_INSTRUMENTS");
4852                    if(nonRecursive) sb.append(" NON_RECURSIVE");
4853                    sb.append(" '").append(conv(dir)).append("'");
4854                    
4855                    if(query.name != null && query.name.length() > 0) {
4856                            sb.append(" NAME='").append(toEscapedText(query.name)).append("'");
4857                    }
4858                    
4859                    if(query.formatFamilies.size() > 0) {
4860                            sb.append(" FORMAT_FAMILIES='").append(query.formatFamilies.get(0));
4861                            for(int i = 1; i < query.formatFamilies.size(); i++) {
4862                                    sb.append(',').append(query.formatFamilies.get(i));
4863                            }
4864                            sb.append("'");
4865                    }
4866                    
4867                    if(query.minSize != -1 || query.maxSize != -1) {
4868                            sb.append(" SIZE='");
4869                            if(query.minSize != -1) sb.append(query.minSize);
4870                            sb.append("..");
4871                            if(query.maxSize != -1) sb.append(query.maxSize);
4872                            sb.append("'");
4873                    }
4874                    
4875                    String s = query.getCreatedAfter();
4876                    String s2 = query.getCreatedBefore();
4877                    if(s != null || s2 != null) {
4878                            sb.append(" CREATED='");
4879                            if(s != null) sb.append(s);
4880                            sb.append("..");
4881                            if(s2 != null) sb.append(s2);
4882                            sb.append("'");
4883                    }
4884                    
4885                    s = query.getModifiedAfter();
4886                    s2 = query.getModifiedBefore();
4887                    if(s != null || s2 != null) {
4888                            sb.append(" MODIFIED='");
4889                            if(s != null) sb.append(s);
4890                            sb.append("..");
4891                            if(s2 != null) sb.append(s2);
4892                            sb.append("'");
4893                    }
4894                    
4895                    if(query.description != null && query.description.length() > 0) {
4896                            sb.append(" DESCRIPTION='");
4897                            sb.append(toEscapedText(query.description)).append("'");
4898                    }
4899                    
4900                    if(query.instrumentType != DbSearchQuery.InstrumentType.BOTH) {
4901                            sb.append(" IS_DRUM=");
4902                            if(query.instrumentType == DbSearchQuery.InstrumentType.DRUM) {
4903                                    sb.append("'true'");
4904                            } else {
4905                                    sb.append("'false'");
4906                            }
4907                    }
4908                    
4909                    if(query.product != null && query.product.length() > 0) {
4910                            sb.append(" PRODUCT='").append(toEscapedText(query.product)).append("'");
4911                    }
4912                    
4913                    if(query.artists != null && query.artists.length() > 0) {
4914                            sb.append(" ARTISTS='").append(toEscapedText(query.artists)).append("'");
4915                    }
4916                    
4917                    if(query.keywords != null && query.keywords.length() > 0) {
4918                            sb.append(" KEYWORDS='");
4919                            sb.append(toEscapedText(query.keywords)).append("'");
4920                    }
4921                    
4922                    out.writeLine(sb.toString());
4923                    if(getPrintOnlyMode()) return null;
4924                    
4925                    String[] instrS = parseEscapedStringList(getSingleLineResultSet().getResult());
4926                    
4927                    DbInstrumentInfo[] infoS = new DbInstrumentInfo[instrS.length];
4928                    for(int i = 0; i < instrS.length; i++) {
4929                            infoS[i] = getDbInstrumentInfo(instrS[i]);
4930                    }
4931                    return infoS;
4932            }
4933            
4934            /**
4935             * Returns a list of all instrument files in the database
4936             * that that doesn't exist in the filesystem.
4937             * @throws IOException If some I/O error occurs.
4938             * @throws LscpException If LSCP protocol corruption occurs.
4939             * @throws LSException If other error occurs.
4940             */
4941            public synchronized String[]
4942            findLostDbInstrumentFiles() throws IOException, LscpException, LSException {
4943                    
4944                    verifyConnection();
4945                    out.writeLine("FIND LOST DB_INSTRUMENT_FILES");
4946                    if(getPrintOnlyMode()) return null;
4947                    
4948                    return parseEscapedStringList(getSingleLineResultSet().getResult());
4949            }
4950            
4951            /**
4952             * Gets status information about the specified job.
4953             * @param jobId The ID of the job.
4954             * @return A <code>ScanJobInfo</code> instance providing information
4955             * about the specified job.
4956             * @throws IOException If some I/O error occurs.
4957             * @throws LscpException If LSCP protocol corruption occurs.
4958             * @throws LSException If the specified job is not found.
4959             */
4960            public synchronized ScanJobInfo
4961            getDbInstrumentsJobInfo(int jobId) throws IOException, LscpException, LSException {
4962                    verifyConnection();
4963                    out.writeLine("GET DB_INSTRUMENTS_JOB INFO " + String.valueOf(jobId));
4964                    if(getPrintOnlyMode()) return null;
4965                    
4966                    ResultSet rs = getMultiLineResultSet();
4967                    ScanJobInfo info = new ScanJobInfo(rs.getMultiLineResult());
4968                    
4969                    return info;
4970            }
4971            
4972            /**
4973             * Removes all instruments and directories and re-creates
4974             * the instruments database structure.
4975             * @throws IOException If some I/O error occurs.
4976             * @throws LscpException If LSCP protocol corruption occurs.
4977             * @throws LSException If the formatting of the instruments database failed.
4978             */
4979            public synchronized void
4980            formatInstrumentsDb() throws IOException, LscpException, LSException {
4981                    verifyConnection();
4982                    out.writeLine("FORMAT INSTRUMENTS_DB");
4983                    if(getPrintOnlyMode()) return;
4984                                    
4985                  ResultSet rs = getEmptyResultSet();                  ResultSet rs = getEmptyResultSet();
4986          }          }
# Line 2358  public class Client { Line 5000  public class Client {
5000          resetChannel(int samplerChn) throws IOException, LscpException, LSException {          resetChannel(int samplerChn) throws IOException, LscpException, LSException {
5001                  verifyConnection();                  verifyConnection();
5002                  out.writeLine("RESET CHANNEL " + samplerChn);                  out.writeLine("RESET CHANNEL " + samplerChn);
5003                    if(getPrintOnlyMode()) return;
5004                                    
5005                  ResultSet rs = getEmptyResultSet();                  ResultSet rs = getEmptyResultSet();
5006          }          }
# Line 2372  public class Client { Line 5015  public class Client {
5015          resetSampler() throws IOException, LscpException {          resetSampler() throws IOException, LscpException {
5016                  verifyConnection();                  verifyConnection();
5017                  out.writeLine("RESET");                  out.writeLine("RESET");
5018                    if(getPrintOnlyMode()) return;
5019                    
5020                  try { ResultSet rs = getEmptyResultSet(); }                  try { ResultSet rs = getEmptyResultSet(); }
5021                  catch(LSException x) { getLogger().warning(x.getMessage()); }                  catch(LSException x) { getLogger().warning(x.getMessage()); }
5022          }          }
5023                    
5024          /**          /**
5025             * Gets the current number of all active streams.
5026             * @return The current number of all active streams.
5027             * @throws IOException If some I/O error occurs.
5028             * @throws LscpException If LSCP protocol corruption occurs.
5029             * @throws LSException If some other error occurs.
5030             */
5031            public synchronized int
5032            getTotalStreamCount() throws IOException, LscpException, LSException {
5033                    verifyConnection();
5034                    out.writeLine("GET TOTAL_STREAM_COUNT");
5035                    if(getPrintOnlyMode()) return -1;
5036                    
5037                    String s = getSingleLineResultSet().getResult();
5038                    return parseInt(s);
5039            }
5040            
5041            /**
5042           * Gets the current number of all active voices.           * Gets the current number of all active voices.
5043           * @return The current number of all active voices.           * @return The current number of all active voices.
5044           * @throws IOException If some I/O error occurs.           * @throws IOException If some I/O error occurs.
# Line 2387  public class Client { Line 5049  public class Client {
5049          getTotalVoiceCount() throws IOException, LscpException, LSException {          getTotalVoiceCount() throws IOException, LscpException, LSException {
5050                  verifyConnection();                  verifyConnection();
5051                  out.writeLine("GET TOTAL_VOICE_COUNT");                  out.writeLine("GET TOTAL_VOICE_COUNT");
5052                    if(getPrintOnlyMode()) return -1;
5053                    
5054                  String s = getSingleLineResultSet().getResult();                  String s = getSingleLineResultSet().getResult();
5055                  return parseInt(s);                  return parseInt(s);
5056          }          }
# Line 2402  public class Client { Line 5066  public class Client {
5066          getTotalVoiceCountMax() throws IOException, LscpException, LSException {          getTotalVoiceCountMax() throws IOException, LscpException, LSException {
5067                  verifyConnection();                  verifyConnection();
5068                  out.writeLine("GET TOTAL_VOICE_COUNT_MAX");                  out.writeLine("GET TOTAL_VOICE_COUNT_MAX");
5069                    if(getPrintOnlyMode()) return -1;
5070                    
5071                  String s = getSingleLineResultSet().getResult();                  String s = getSingleLineResultSet().getResult();
5072                  return parseInt(s);                  return parseInt(s);
5073          }          }
# Line 2420  public class Client { Line 5086  public class Client {
5086          getServerInfo() throws IOException, LscpException, LSException {          getServerInfo() throws IOException, LscpException, LSException {
5087                  verifyConnection();                  verifyConnection();
5088                  out.writeLine("GET SERVER INFO");                  out.writeLine("GET SERVER INFO");
5089                    if(getPrintOnlyMode()) return null;
5090                    
5091                  ResultSet rs = getMultiLineResultSet();                  ResultSet rs = getMultiLineResultSet();
5092                  return new ServerInfo(rs.getMultiLineResult());                  return new ServerInfo(rs.getMultiLineResult());
5093          }          }
5094                    
5095          /**          /**
5096             * Gets the golobal volume of the sampler.
5097             * @return The golobal volume of the sampler.
5098             * @throws IOException If some I/O error occurs.
5099             * @throws LscpException If LSCP protocol corruption occurs.
5100             * @throws LSException If some other error occurs.
5101             */
5102            public synchronized float
5103            getVolume() throws IOException, LscpException, LSException {
5104                    verifyConnection();
5105                    out.writeLine("GET VOLUME");
5106                    if(getPrintOnlyMode()) return -1;
5107                    
5108                    String s = getSingleLineResultSet().getResult();
5109                    return parseFloat(s);
5110            }
5111            
5112            /**
5113             * Sets the global volume of the sampler.
5114             * @param volume The new volume value.
5115             * @throws IOException If some I/O error occurs.
5116             * @throws LscpException If LSCP protocol corruption occurs.
5117             * @throws LSException If some other error occurs.
5118             * @see #getVolume
5119             */
5120            public synchronized void
5121            setVolume(float volume) throws IOException, LscpException, LSException {
5122            
5123                    verifyConnection();
5124                    out.writeLine("SET VOLUME " + volume);
5125                    if(getPrintOnlyMode()) return;
5126                    
5127                    ResultSet rs = getEmptyResultSet();
5128            }
5129            
5130            /**
5131             * Gets the number of instruments in the specified instrument file.
5132             * @param filename The absolute path name of the instrument file.
5133             * @return The number of instruments in the specified instrument file.
5134             * @throws IOException If some I/O error occurs.
5135             * @throws LscpException If LSCP protocol corruption occurs.
5136             * @throws LSException If the file is not found, or other error occur.
5137             */
5138            public synchronized int
5139            getFileInstrumentCount(String filename) throws IOException, LscpException, LSException {
5140                    verifyConnection();
5141                    out.writeLine("GET FILE INSTRUMENTS '" + conv(filename) +"'");
5142                    if(getPrintOnlyMode()) return -1;
5143                    
5144                    String s = getSingleLineResultSet().getResult();
5145                    return parseInt(s);
5146            }
5147            
5148            /**
5149             * Gets information about the instrument with index
5150             * <code>instrIdx</code> in the specified instrument file.
5151             * @param filename The absolute path name of the instrument file.
5152             * @param instrIdx The index of the instrument in the specified instrument file.
5153             * @throws IOException If some I/O error occurs.
5154             * @throws LscpException If LSCP protocol corruption occurs.
5155             * @throws LSException If failed to retrieve information.
5156             */
5157            public synchronized Instrument
5158            getFileInstrumentInfo(String filename, int instrIdx)
5159                                    throws IOException, LscpException, LSException {
5160                    
5161                    verifyConnection();
5162                    out.writeLine("GET FILE INSTRUMENT INFO '" + conv(filename) + "' " + String.valueOf(instrIdx));
5163                    if(getPrintOnlyMode()) return null;
5164                    
5165                    ResultSet rs = getMultiLineResultSet();
5166                    Instrument instr = new FileInstrument(rs.getMultiLineResult()) { };
5167                    
5168                    return instr;
5169            }
5170            
5171            /**
5172             * Gets the list of instruments in the specified instrument file.
5173             * @param filename The absolute path name of the instrument file.
5174             * @return An <code>Instrument</code> array providing
5175             * information about all instruments in the specified instrument file.
5176             * @throws IOException If some I/O error occurs.
5177             * @throws LscpException If LSCP protocol corruption occurs.
5178             * @throws LSException If the specified file name is invalid.
5179             */
5180            public synchronized Instrument[]
5181            getFileInstruments(String filename) throws IOException, LscpException, LSException {
5182                    int l = getFileInstrumentCount(filename);
5183                    if(l < 0) return null;
5184                    Instrument[] instrS = new FileInstrument[l];
5185                    
5186                    for(int i = 0; i < instrS.length; i++) {
5187                            instrS[i] = getFileInstrumentInfo(filename, i);
5188                    }
5189                    return instrS;
5190            }
5191            
5192            private static class FileInstrument extends AbstractInstrument {
5193                    FileInstrument(String[] resultSet) throws LscpException {
5194                            super(resultSet);
5195                    }
5196                    
5197                    public String
5198                    getEngine() {
5199                            // TODO: engine lookup?
5200                            return getFormatFamily();
5201                    }
5202                    
5203                    public boolean
5204                    parse(String s) throws LscpException {
5205                            if(s.startsWith("PRODUCT: ") || s.startsWith("ARTISTS: ")) return true;
5206                            return super.parse(s);
5207                    }
5208            }
5209            
5210            private void
5211            getEmptyResultSets(int count, String err) throws LSException {
5212                    StringBuffer sb = new StringBuffer();
5213                    for(int i = 0; i < count; i++) {
5214                            try { getEmptyResultSet(); }
5215                            catch (SocketTimeoutException e) {
5216                                    getLogger().log(Level.FINE, e.getMessage(), e);
5217                                    sb.append(e.getMessage()).append("\n");
5218                                    break;
5219                            } catch (Exception e) {
5220                                    getLogger().log(Level.FINE, e.getMessage(), e);
5221                                    sb.append(e.getMessage()).append("\n");
5222                            }
5223                    }
5224                    
5225                    String details = sb.toString();
5226                    if(details.length() > 0) {
5227                            String s = LscpI18n.getLogMsg(err);
5228                            throw new LSException(0, s, details);
5229                    }
5230            }
5231            
5232            /**
5233           * Returns the logger for this library.           * Returns the logger for this library.
5234           * @return The logger for this library.           * @return The logger for this library.
5235           */           */

Legend:
Removed from v.784  
changed lines
  Added in v.1728

  ViewVC Help
Powered by ViewVC