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

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

  ViewVC Help
Powered by ViewVC