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

Legend:
Removed from v.671  
changed lines
  Added in v.1340

  ViewVC Help
Powered by ViewVC