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

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

  ViewVC Help
Powered by ViewVC