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

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

  ViewVC Help
Powered by ViewVC