/[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 1542 by iliev, Tue Dec 4 18:14:31 2007 UTC revision 2287 by iliev, Wed Nov 23 18:58:46 2011 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-2007 Grigor Iliev <grigor@grigoriliev.com>   *   Copyright (C) 2005-2011 Grigor Iliev <grigor@grigoriliev.com>
5   *   *
6   *   This file is part of jlscp.   *   This file is part of jlscp.
7   *   *
# Line 28  import java.io.OutputStream; Line 28  import java.io.OutputStream;
28  import java.net.InetSocketAddress;  import java.net.InetSocketAddress;
29  import java.net.Socket;  import java.net.Socket;
30  import java.net.SocketTimeoutException;  import java.net.SocketTimeoutException;
 import java.net.UnknownHostException;  
31    
32    import java.util.ArrayList;
33    import java.util.TreeMap;
34  import java.util.Vector;  import java.util.Vector;
35  import java.util.logging.Level;  import java.util.logging.Level;
36  import java.util.logging.Logger;  import java.util.logging.Logger;
# Line 41  import static org.linuxsampler.lscp.Pars Line 42  import static org.linuxsampler.lscp.Pars
42    
43  /**  /**
44   * 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
45   * instance. Since it implements all commands specified in the LSCP protocol v1.1, for more   * instance. Since it implements all commands specified in the LSCP protocol v1.5, for more
46   * information look at the   * information look at the
47   * <a href=http://www.linuxsampler.org/api/lscp-1.1.html>LSCP</a> specification.   * <a href=http://www.linuxsampler.org/api/lscp-1.5.html>LSCP</a> specification.
48   *   *
49   * <p> The following code establishes connection to LinuxSampler instance and gets the   * <p> The following code establishes connection to LinuxSampler instance and gets the
50   * LinuxSampler version:   * LinuxSampler version:
# Line 67  import static org.linuxsampler.lscp.Pars Line 68  import static org.linuxsampler.lscp.Pars
68   * @author  Grigor Iliev   * @author  Grigor Iliev
69   */   */
70  public class Client {  public class Client {
71            public static final String VERSION = "0.8";
72            public static final String PROTOCOL_VERSION = "1.4";
73          private String address;          private String address;
74          private int port;          private int port;
75          private Socket sock = null;          private Socket sock = null;
# Line 78  public class Client { Line 81  public class Client {
81          private EventThread eventThread;          private EventThread eventThread;
82                    
83          private boolean printOnlyMode = false;          private boolean printOnlyMode = false;
84    
85            public enum ResultSetType {
86                    EMPTY, SINGLE_LINE, MULTI_LINE
87            }
88            
89            private static class ResultSetEntry {
90                    public ResultSetType type;
91                    
92                    public
93                    ResultSetEntry(ResultSetType type) {
94                            this.type = type;
95                    }
96            }
97    
98            private Vector<ResultSetEntry> resultSetQueue = new Vector<ResultSetEntry>();
99            
100            /* Used for caching the engines' info */
101            private final TreeMap<String, SamplerEngine> engineMap = new TreeMap<String, SamplerEngine>();
102                    
103          class EventThread extends Thread {          class EventThread extends Thread {
104                  private Vector<String> queue = new Vector<String>();                  private Vector<String> queue = new Vector<String>();
# Line 85  public class Client { Line 106  public class Client {
106                                    
107                  EventThread() { super("LSCP-Event-Thread"); }                  EventThread() { super("LSCP-Event-Thread"); }
108                                    
109                    @Override
110                  public void                  public void
111                  run() {                  run() {
112                          while(!mustTerminate()) {                          while(!mustTerminate()) {
# Line 164  public class Client { Line 186  public class Client {
186                  if(printOnlyMode) setPrintOnlyMode(true);                  if(printOnlyMode) setPrintOnlyMode(true);
187          }          }
188                    
189            private boolean extendedCharacterEscaping = true;
190            
191            /**
192             * Sets whether strings sent to LinuxSampler should be more aggressively escaped.
193             */
194            public synchronized void
195            setExtendedCharacterEscaping(boolean b) { extendedCharacterEscaping = b; }
196            
197            /**
198             * Determines whether strings sent to LinuxSampler should be more aggressively escaped.
199             */
200            public synchronized boolean
201            getExtendedCharacterEscaping() { return extendedCharacterEscaping; }
202            
203            /**
204             * @see java.net.Socket#setSoTimeout
205             */
206            public synchronized void
207            setSoTimeout(int timeout) {
208                    soTimeout = timeout;
209                    
210                    try { if(sock != null) sock.setSoTimeout(timeout); }
211                    catch(Exception x) { getLogger().log(Level.INFO, "Unable to set timeout", x); }
212            }
213            
214            private String
215            toEscapedText(String s) {
216                    s = toEscapedString(s);
217                    return conv(s);
218            }
219            
220            private String
221            toEscapedFsEntry(String s) {
222                    s = toEscapedFileName(s);
223                    return conv(s);
224            }
225            
226            /**
227             * Applies an extended character escaping to the specified string if needed.
228             */
229            private String
230            conv(String s) {
231                    return getExtendedCharacterEscaping() ? toExtendedEscapeSequence(s) : s;
232            }
233            
234          /**          /**
235           * Determines whether the client is in print-only mode.           * Determines whether the client is in print-only mode.
236           * Print-only mode means that the client will just print all           * Print-only mode means that the client will just print all
# Line 217  public class Client { Line 284  public class Client {
284           * @return The jlscp version.           * @return The jlscp version.
285           */           */
286          public static String          public static String
287          getClientVersion() {          getClientVersion() { return VERSION; }
288                  return Package.getPackage("org.linuxsampler.lscp").getImplementationVersion();          
289          }          /**
290             * Gets the LSCP protocol version supported by this client.
291             */
292            public static String
293            getProtocolVersion() { return PROTOCOL_VERSION; }
294                    
295          /**          /**
296           * Gets the Linux Sampler address.           * Gets the Linux Sampler address.
# Line 262  public class Client { Line 333  public class Client {
333                  if(sock != null) disconnect();                  if(sock != null) disconnect();
334                  if(getPrintOnlyMode()) return;                  if(getPrintOnlyMode()) return;
335                                    
336                    engineMap.clear();
337                    
338                  // Initializing LSCP event thread                  // Initializing LSCP event thread
339                  if(eventThread.isAlive()) {                  if(eventThread.isAlive()) {
340                          getLogger().warning("LSCP event thread already running!");                          getLogger().warning("LSCP event thread already running!");
# Line 300  public class Client { Line 373  public class Client {
373                          );                          );
374                  }                  }
375                                    
376                  String s = Package.getPackage("org.linuxsampler.lscp").getSpecificationVersion();                  String s = getProtocolVersion();
377                  String s2, sv, sv2;                  String s2, sv, sv2;
378                                    
379                  try {                  try {
# Line 350  public class Client { Line 423  public class Client {
423                  if(!llMIMI.isEmpty()) subscribe("MIDI_INSTRUMENT_MAP_INFO");                  if(!llMIMI.isEmpty()) subscribe("MIDI_INSTRUMENT_MAP_INFO");
424                  if(!llMIC.isEmpty()) subscribe("MIDI_INSTRUMENT_COUNT");                  if(!llMIC.isEmpty()) subscribe("MIDI_INSTRUMENT_COUNT");
425                  if(!llMII.isEmpty()) subscribe("MIDI_INSTRUMENT_INFO");                  if(!llMII.isEmpty()) subscribe("MIDI_INSTRUMENT_INFO");
426                    if(!llDMD.isEmpty()) subscribe("DEVICE_MIDI");
427                    if(!llCMD.isEmpty()) subscribe("CHANNEL_MIDI");
428                  if(!llID.isEmpty()) {                  if(!llID.isEmpty()) {
429                          subscribe("DB_INSTRUMENT_DIRECTORY_COUNT");                          subscribe("DB_INSTRUMENT_DIRECTORY_COUNT");
430                          subscribe("DB_INSTRUMENT_DIRECTORY_INFO");                          subscribe("DB_INSTRUMENT_DIRECTORY_INFO");
431                          subscribe("DB_INSTRUMENT_COUNT");                          subscribe("DB_INSTRUMENT_COUNT");
432                          subscribe("DB_INSTRUMENT_INFO");                          subscribe("DB_INSTRUMENT_INFO");
433                            subscribe("DB_INSTRUMENTS_JOB_INFO");
434                  }                  }
435                  if(!llGI.isEmpty()) subscribe("GLOBAL_INFO");                  if(!llGI.isEmpty()) subscribe("GLOBAL_INFO");
436                    if(!llEIC.isEmpty()) subscribe("EFFECT_INSTANCE_COUNT");
437                    if(!llEII.isEmpty()) subscribe("EFFECT_INSTANCE_INFO");
438                    if(!llSECC.isEmpty()) subscribe("SEND_EFFECT_CHAIN_COUNT");
439                    if(!llSECI.isEmpty()) subscribe("SEND_EFFECT_CHAIN_INFO");
440          }          }
441                    
442          /**          /**
# Line 373  public class Client { Line 453  public class Client {
453                          eventThread.terminate();                          eventThread.terminate();
454                          eventThread = new EventThread();                          eventThread = new EventThread();
455                  }                  }
456                    
457                    engineMap.clear();
458          }          }
459                    
460          /**          /**
# Line 420  public class Client { Line 502  public class Client {
502                          else getLogger().severe("Unknown notification format: " + s);                          else getLogger().severe("Unknown notification format: " + s);
503                  }                  }
504          }          }
505    
506            private synchronized void
507            processResultSetQueue() {
508                    for(int i = 0; i < resultSetQueue.size(); i++) {
509                            try {
510                                    switch(resultSetQueue.get(i).type) {
511                                            case EMPTY:
512                                                    getEmptyResultSet();
513                                                    break;
514                                            case SINGLE_LINE:
515                                                    getSingleLineResultSet();
516                                                    break;
517                                            case MULTI_LINE:
518                                                    getMultiLineResultSet();
519                                                    break;
520                                            default:
521                                                    getLogger().severe("Unknown result set type");
522                                    }
523                            } catch(Exception x) {
524                                    getLogger().log(Level.FINE, "Error while processing result set queue", x);
525                            }
526                    }
527    
528                    resultSetQueue.removeAllElements();
529            }
530                    
531          /**          /**
532           * Gets empty result set.           * Gets empty result set.
533           * @return <code>ResultSet</code> instance.           * @return <code>ResultSet</code> instance.
534           */           */
535          private ResultSet          private ResultSet
536          getEmptyResultSet() throws IOException, LscpException, LSException {          getEmptyResultSet() throws IOException, LscpException, LSException {
537                    processResultSetQueue();
538                  return parseEmptyResultSet(getLine());                  return parseEmptyResultSet(getLine());
539          }          }
540                    
541          private ResultSet          private ResultSet
542          getSingleLineResultSet() throws IOException, LscpException, LSException {          getSingleLineResultSet() throws IOException, LscpException, LSException {
543                    processResultSetQueue();
544                  ResultSet rs = new ResultSet();                  ResultSet rs = new ResultSet();
545                  String ln = getLine();                  String ln = getLine();
546                                    
# Line 450  public class Client { Line 559  public class Client {
559                    
560          private ResultSet          private ResultSet
561          getMultiLineResultSet() throws IOException, LscpException, LSException {          getMultiLineResultSet() throws IOException, LscpException, LSException {
562                    processResultSetQueue();
563                  ResultSet rs = new ResultSet();                  ResultSet rs = new ResultSet();
564                  String ln = getLine();                  String ln = getLine();
565                                    
# Line 499  public class Client { Line 609  public class Client {
609          /** MIDI instrument info listeners */          /** MIDI instrument info listeners */
610          private final Vector<MidiInstrumentInfoListener> llMII =          private final Vector<MidiInstrumentInfoListener> llMII =
611                  new Vector<MidiInstrumentInfoListener>();                  new Vector<MidiInstrumentInfoListener>();
612            private final Vector<DeviceMidiDataListener> llDMD = new Vector<DeviceMidiDataListener>();
613            private final Vector<ChannelMidiDataListener> llCMD = new Vector<ChannelMidiDataListener>();
614          private final Vector<InstrumentsDbListener> llID = new Vector<InstrumentsDbListener>();          private final Vector<InstrumentsDbListener> llID = new Vector<InstrumentsDbListener>();
615          private final Vector<GlobalInfoListener> llGI = new Vector<GlobalInfoListener>();          private final Vector<GlobalInfoListener> llGI = new Vector<GlobalInfoListener>();
616            private final ArrayList<EffectInstanceCountListener> llEIC = new ArrayList<EffectInstanceCountListener>();
617            private final Vector<EffectInstanceInfoListener> llEII = new Vector<EffectInstanceInfoListener>();
618            private final Vector<SendEffectChainCountListener> llSECC = new Vector<SendEffectChainCountListener>();
619            private final Vector<SendEffectChainInfoListener> llSECI = new Vector<SendEffectChainInfoListener>();
620                    
621                    
622          /**          /**
# Line 530  public class Client { Line 646  public class Client {
646                          !llMIMI.isEmpty() ||                          !llMIMI.isEmpty() ||
647                          !llMIC.isEmpty()  ||                          !llMIC.isEmpty()  ||
648                          !llMII.isEmpty()  ||                          !llMII.isEmpty()  ||
649                            !llDMD.isEmpty()  ||
650                            !llCMD.isEmpty()  ||
651                          !llID.isEmpty()   ||                          !llID.isEmpty()   ||
652                          !llGI.isEmpty();                          !llGI.isEmpty()   ||
653                            !llEIC.isEmpty()  ||
654                            !llEII.isEmpty()  ||
655                            !llSECC.isEmpty() ||
656                            !llSECI.isEmpty();
657            }
658            
659            private synchronized void
660            fireDeviceMidiDataEvent(String s) {
661                    try {
662                            String[] list = parseList(s, ' ');
663                            if(list.length != 5) {
664                                    getLogger().warning("Unknown DEVICE_MIDI format");
665                                    return;
666                            }
667                            
668                            int dev = parseInt(list[0]);
669                            int port = parseInt(list[1]);
670                            
671                            MidiDataEvent.Type type = parseMidiDataType(list[2]);
672                            if(type == null) return;
673                            
674                            int note = parseInt(list[3]);
675                            int velocity = parseInt(list[4]);
676                            
677                            DeviceMidiDataEvent e = new DeviceMidiDataEvent(this, type, note, velocity);
678                            e.setDeviceId(dev);
679                            e.setPortId(port);
680                            for(DeviceMidiDataListener l : llDMD) l.midiDataArrived(e);
681                    } catch(LscpException x) {
682                            getLogger().log (
683                                    Level.WARNING, LscpI18n.getLogMsg("CommandFailed!"), x
684                            );
685                    }
686            }
687            
688            private synchronized void
689            fireChannelMidiDataEvent(String s) {
690                    try {
691                            String[] list = parseList(s, ' ');
692                            if(list.length != 4) {
693                                    getLogger().warning("Unknown CHANNEL_MIDI format");
694                                    return;
695                            }
696                            
697                            int channel = parseInt(list[0]);
698                            
699                            MidiDataEvent.Type type = parseMidiDataType(list[1]);
700                            if(type == null) return;
701                            
702                            int note = parseInt(list[2]);
703                            int velocity = parseInt(list[3]);
704                            
705                            ChannelMidiDataEvent e = new ChannelMidiDataEvent(this, type, note, velocity);
706                            e.setChannelId(channel);
707                            for(ChannelMidiDataListener l : llCMD) l.midiDataArrived(e);
708                    } catch(LscpException x) {
709                            getLogger().log (
710                                    Level.WARNING, LscpI18n.getLogMsg("CommandFailed!"), x
711                            );
712                    }
713            }
714            
715            private MidiDataEvent.Type
716            parseMidiDataType(String s) {
717                    if("NOTE_ON".equals(s)) return MidiDataEvent.Type.NOTE_ON;
718                    if("NOTE_OFF".equals(s)) return MidiDataEvent.Type.NOTE_OFF;
719                    if("CC".equals(s)) return MidiDataEvent.Type.CC;
720                    
721                    getLogger().warning("Unknown MIDI data type: " + s);
722                    return null;
723          }          }
724                    
725          private synchronized void          private synchronized void
726          fireEvent(String s) {          fireEvent(String s) {
727                   if(s.startsWith("DB_INSTRUMENT_DIRECTORY_COUNT:")) {                  // Sort by priority
728                    
729                     if(s.startsWith("CHANNEL_MIDI:")) {
730                            s = s.substring("CHANNEL_MIDI:".length());
731                            fireChannelMidiDataEvent(s);
732                    } else if(s.startsWith("DEVICE_MIDI:")) {
733                            s = s.substring("DEVICE_MIDI:".length());
734                            fireDeviceMidiDataEvent(s);
735                    } else if(s.startsWith("DB_INSTRUMENT_DIRECTORY_COUNT:")) {
736                          s = s.substring("DB_INSTRUMENT_DIRECTORY_COUNT:".length());                          s = s.substring("DB_INSTRUMENT_DIRECTORY_COUNT:".length());
737                          InstrumentsDbEvent e = new InstrumentsDbEvent(this, s);                          InstrumentsDbEvent e = new InstrumentsDbEvent(this, s);
738                          for(InstrumentsDbListener l : llID) l.directoryCountChanged(e);                          for(InstrumentsDbListener l : llID) l.directoryCountChanged(e);
# Line 823  public class Client { Line 1019  public class Client {
1019                          } catch(Exception x) {                          } catch(Exception x) {
1020                                  getLogger().log(Level.WARNING, "Unknown FX_SEND_INFO format", x);                                  getLogger().log(Level.WARNING, "Unknown FX_SEND_INFO format", x);
1021                          }                          }
1022                    } else if(s.startsWith("EFFECT_INSTANCE_COUNT:")) {
1023                            try {
1024                                    s = s.substring("EFFECT_INSTANCE_COUNT:".length());
1025                                    int i = Integer.parseInt(s);
1026                                    
1027                                    EffectInstanceCountEvent e = new EffectInstanceCountEvent(this, i);
1028                                    for(EffectInstanceCountListener l : llEIC) {
1029                                            l.effectInstanceCountChanged(e);
1030                                    }
1031                            } catch(Exception x) {
1032                                    getLogger().log(Level.WARNING, "Unknown EFFECT_INSTANCE_COUNT format", x);
1033                            }
1034                    } else if(s.startsWith("EFFECT_INSTANCE_INFO:")) {
1035                            try {
1036                                    s = s.substring("EFFECT_INSTANCE_INFO:".length());
1037                                    int i = Integer.parseInt(s);
1038                                    
1039                                    EffectInstanceInfoEvent e = new EffectInstanceInfoEvent(this, i);
1040                                    for(EffectInstanceInfoListener l : llEII) {
1041                                            l.effectInstanceInfoChanged(e);
1042                                    }
1043                            } catch(Exception x) {
1044                                    getLogger().log(Level.WARNING, "Unknown EFFECT_INSTANCE_INFO format", x);
1045                            }
1046                    } else if(s.startsWith("SEND_EFFECT_CHAIN_COUNT:")) {
1047                            try {
1048                                    s = s.substring("SEND_EFFECT_CHAIN_COUNT:".length());
1049                                    Integer[] i = parseIntList(s, ' ');
1050                                    if(i.length != 2) {
1051                                            getLogger().warning("Unknown SEND_EFFECT_CHAIN_COUNT format");
1052                                            return;
1053                                    }
1054                                    
1055                                    SendEffectChainCountEvent e =
1056                                            new SendEffectChainCountEvent(this, i[0], i[1]);
1057                                    
1058                                    for(SendEffectChainCountListener l : llSECC) {
1059                                            l.sendEffectChainCountChanged(e);
1060                                    }
1061                            } catch(Exception x) {
1062                                    getLogger().log(Level.WARNING, "Unknown SEND_EFFECT_CHAIN_COUNT format", x);
1063                            }
1064                    } else if(s.startsWith("SEND_EFFECT_CHAIN_INFO:")) {
1065                            try {
1066                                    s = s.substring("SEND_EFFECT_CHAIN_INFO:".length());
1067                                    Integer[] i = parseIntList(s, ' ');
1068                                    if(i.length != 3) {
1069                                            getLogger().warning("Unknown SEND_EFFECT_CHAIN_INFO format");
1070                                            return;
1071                                    }
1072                                    
1073                                    SendEffectChainInfoEvent e =
1074                                            new SendEffectChainInfoEvent(this, i[0], i[1], i[2]);
1075                                    
1076                                    for(SendEffectChainInfoListener l : llSECI) {
1077                                            l.sendEffectChainInfoChanged(e);
1078                                    }
1079                            } catch(Exception x) {
1080                                    getLogger().log(Level.WARNING, "Unknown SEND_EFFECT_CHAIN_INFO format", x);
1081                            }
1082                  } else if(s.startsWith("GLOBAL_INFO:")) {                  } else if(s.startsWith("GLOBAL_INFO:")) {
1083                          handleGlobalInfoEvent(s.substring("GLOBAL_INFO:".length()));                          handleGlobalInfoEvent(s.substring("GLOBAL_INFO:".length()));
1084                  } else if(s.startsWith("MISCELLANEOUS:")) {                  } else if(s.startsWith("MISCELLANEOUS:")) {
# Line 839  public class Client { Line 1095  public class Client {
1095                                  float f = Float.parseFloat(s.substring("VOLUME ".length()));                                  float f = Float.parseFloat(s.substring("VOLUME ".length()));
1096                                  GlobalInfoEvent e = new GlobalInfoEvent(this, f);                                  GlobalInfoEvent e = new GlobalInfoEvent(this, f);
1097                                  for(GlobalInfoListener l : llGI) l.volumeChanged(e);                                  for(GlobalInfoListener l : llGI) l.volumeChanged(e);
1098                            } else if(s.startsWith("VOICES ")) {
1099                                    int i = Integer.parseInt(s.substring("VOICES ".length()));
1100                                    GlobalInfoEvent e = new GlobalInfoEvent(this, i, -1);
1101                                    for(GlobalInfoListener l : llGI) l.voiceLimitChanged(e);
1102                            } else if(s.startsWith("STREAMS ")) {
1103                                    int i = Integer.parseInt(s.substring("STREAMS ".length()));
1104                                    GlobalInfoEvent e = new GlobalInfoEvent(this, -1, i);
1105                                    for(GlobalInfoListener l : llGI) l.streamLimitChanged(e);
1106                            } else {
1107                                    getLogger().info("Unknown GLOBAL_INFO format: " + s);
1108                          }                          }
1109                  } catch(NumberFormatException x) {                  } catch(NumberFormatException x) {
1110                          getLogger().log(Level.WARNING, "Unknown GLOBAL_INFO format", x);                          getLogger().log(Level.WARNING, "Unknown GLOBAL_INFO format", x);
# Line 1280  public class Client { Line 1546  public class Client {
1546          /**          /**
1547           * Registers the specified listener for receiving event messages.           * Registers the specified listener for receiving event messages.
1548           * Listeners can be registered regardless of the connection state.           * Listeners can be registered regardless of the connection state.
1549             * @param l The <code>DeviceMidiDataListener</code> to register.
1550             */
1551            public synchronized void
1552            addDeviceMidiDataListener(DeviceMidiDataListener l) {
1553                    if(llDMD.isEmpty()) subscribe("DEVICE_MIDI");
1554                    llDMD.add(l);
1555            }
1556            
1557            /**
1558             * Removes the specified listener.
1559             * Listeners can be removed regardless of the connection state.
1560             * @param l The <code>DeviceMidiDataListener</code> to remove.
1561             */
1562            public synchronized void
1563            removeDeviceMidiDataListener(DeviceMidiDataListener l) {
1564                    boolean b = llDMD.remove(l);
1565                    if(b && llDMD.isEmpty()) unsubscribe("DEVICE_MIDI");
1566            }
1567            
1568            /**
1569             * Registers the specified listener for receiving event messages.
1570             * Listeners can be registered regardless of the connection state.
1571             * @param l The <code>ChannelMidiDataListener</code> to register.
1572             */
1573            public synchronized void
1574            addChannelMidiDataListener(ChannelMidiDataListener l) {
1575                    if(llCMD.isEmpty()) subscribe("CHANNEL_MIDI");
1576                    llCMD.add(l);
1577            }
1578            
1579            /**
1580             * Removes the specified listener.
1581             * Listeners can be removed regardless of the connection state.
1582             * @param l The <code>ChannelMidiDataListener</code> to remove.
1583             */
1584            public synchronized void
1585            removeChannelMidiDataListener(ChannelMidiDataListener l) {
1586                    boolean b = llCMD.remove(l);
1587                    if(b && llCMD.isEmpty()) unsubscribe("CHANNEL_MIDI");
1588            }
1589            
1590            /**
1591             * Registers the specified listener for receiving event messages.
1592             * Listeners can be registered regardless of the connection state.
1593           * @param l The <code>InstrumentsDbListener</code> to register.           * @param l The <code>InstrumentsDbListener</code> to register.
1594           */           */
1595          public synchronized void          public synchronized void
# Line 1334  public class Client { Line 1644  public class Client {
1644          }          }
1645                    
1646          /**          /**
1647             * Registers the specified listener for receiving event messages.
1648             * Listeners can be registered regardless of the connection state.
1649             * @param l The <code>EffectInstanceCountListener</code> to register.
1650             */
1651            public synchronized void
1652            addEffectInstanceCountListener(EffectInstanceCountListener l) {
1653                    if(llEIC.isEmpty()) subscribe("EFFECT_INSTANCE_COUNT");
1654                    llEIC.add(l);
1655            }
1656            
1657            /**
1658             * Removes the specified listener.
1659             * Listeners can be removed regardless of the connection state.
1660             * @param l The <code>EffectInstanceCountListener</code> to remove.
1661             */
1662            public synchronized void
1663            removeEffectInstanceCountListener(EffectInstanceCountListener l) {
1664                    boolean b = llEIC.remove(l);
1665                    if(b && llEIC.isEmpty()) unsubscribe("EFFECT_INSTANCE_COUNT");
1666            }
1667            
1668            /**
1669             * Registers the specified listener for receiving event messages.
1670             * Listeners can be registered regardless of the connection state.
1671             * @param l The <code>EffectInstanceInfoListener</code> to register.
1672             */
1673            public synchronized void
1674            addEffectInstanceInfoListener(EffectInstanceInfoListener l) {
1675                    if(llEII.isEmpty()) subscribe("EFFECT_INSTANCE_INFO");
1676                    llEII.add(l);
1677            }
1678            
1679            /**
1680             * Removes the specified listener.
1681             * Listeners can be removed regardless of the connection state.
1682             * @param l The <code>EffectInstanceInfoListener</code> to remove.
1683             */
1684            public synchronized void
1685            removeEffectInstanceInfoListener(EffectInstanceInfoListener l) {
1686                    boolean b = llEII.remove(l);
1687                    if(b && llEII.isEmpty()) unsubscribe("EFFECT_INSTANCE_INFO");
1688            }
1689            
1690            /**
1691             * Registers the specified listener for receiving event messages.
1692             * Listeners can be registered regardless of the connection state.
1693             * @param l The <code>SendEffectChainCountListener</code> to register.
1694             */
1695            public synchronized void
1696            addSendEffectChainCountListener(SendEffectChainCountListener l) {
1697                    if(llSECC.isEmpty()) subscribe("SEND_EFFECT_CHAIN_COUNT");
1698                    llSECC.add(l);
1699            }
1700            
1701            /**
1702             * Removes the specified listener.
1703             * Listeners can be removed regardless of the connection state.
1704             * @param l The <code>SendEffectChainCountListener</code> to remove.
1705             */
1706            public synchronized void
1707            removeSendEffectChainCountListener(SendEffectChainCountListener l) {
1708                    boolean b = llSECC.remove(l);
1709                    if(b && llSECC.isEmpty()) unsubscribe("SEND_EFFECT_CHAIN_COUNT");
1710            }
1711            
1712            /**
1713             * Registers the specified listener for receiving event messages.
1714             * Listeners can be registered regardless of the connection state.
1715             * @param l The <code>SendEffectChainInfoListener</code> to register.
1716             */
1717            public synchronized void
1718            addSendEffectChainInfoListener(SendEffectChainInfoListener l) {
1719                    if(llSECI.isEmpty()) subscribe("SEND_EFFECT_CHAIN_INFO");
1720                    llSECI.add(l);
1721            }
1722            
1723            /**
1724             * Removes the specified listener.
1725             * Listeners can be removed regardless of the connection state.
1726             * @param l The <code>SendEffectChainInfoListener</code> to remove.
1727             */
1728            public synchronized void
1729            removeSendEffectChainInfoListener(SendEffectChainInfoListener l) {
1730                    boolean b = llSECI.remove(l);
1731                    if(b && llSECI.isEmpty()) unsubscribe("SEND_EFFECT_CHAIN_INFO");
1732            }
1733            
1734            /**
1735           * Gets the number of all audio output drivers currently           * Gets the number of all audio output drivers currently
1736           * available for the LinuxSampler instance.           * available for the LinuxSampler instance.
1737           * @return The number of all audio output drivers currently           * @return The number of all audio output drivers currently
1738           * available for the LinuxSampler instance.           * available for the LinuxSampler instance or -1 if in "print only" mode.
1739           * @throws IOException If some I/O error occurs.           * @throws IOException If some I/O error occurs.
1740           * @throws LscpException If LSCP protocol corruption occurs.           * @throws LscpException If LSCP protocol corruption occurs.
1741           * @throws LSException If some other error occurs.           * @throws LSException If some other error occurs.
1742           */           */
1743          public synchronized int          public synchronized int
1744          getAudioOutputDriverCount() throws IOException, LscpException, LSException {          getAudioOutputDriverCount() throws IOException, LscpException, LSException {
1745                  verifyConnection();                  return retrieveInt("GET AVAILABLE_AUDIO_OUTPUT_DRIVERS");
                 out.writeLine("GET AVAILABLE_AUDIO_OUTPUT_DRIVERS");  
                   
                 if(getPrintOnlyMode()) return -1;  
                   
                 String s = getSingleLineResultSet().getResult();  
                 return parseInt(s);  
1746          }          }
1747                    
1748          /**          /**
# Line 1409  public class Client { Line 1801  public class Client {
1801          public synchronized AudioOutputDriver          public synchronized AudioOutputDriver
1802          getAudioOutputDriverInfo(String driverName, Parameter... depList)          getAudioOutputDriverInfo(String driverName, Parameter... depList)
1803                                          throws IOException, LscpException, LSException {                                          throws IOException, LscpException, LSException {
1804                    
1805                  verifyConnection();                  AudioOutputDriver aod = new AudioOutputDriver();
1806                  out.writeLine("GET AUDIO_OUTPUT_DRIVER INFO " + driverName);                  if(!retrieveInfo("GET AUDIO_OUTPUT_DRIVER INFO " + driverName, aod)) return null;
                 if(getPrintOnlyMode()) return null;  
                   
                 ResultSet rs = getMultiLineResultSet();  
                 AudioOutputDriver aod = new AudioOutputDriver(rs.getMultiLineResult());  
1807                  aod.setName(driverName);                  aod.setName(driverName);
1808                                    
1809                  for(String s : aod.getParameterNames())                  for(String s : aod.getParameterNames())
# Line 1454  public class Client { Line 1842  public class Client {
1842                  args.append(' ').append(param);                  args.append(' ').append(param);
1843                                    
1844                  for(Parameter p : deplist) {                  for(Parameter p : deplist) {
1845                          if(p.getValue() == null) continue;                          if(p == null || p.getName() == null || p.getValue() == null) continue;
1846                          args.append(' ').append(p.getName()).append('=').append(p.getStringValue());                          args.append(' ').append(p.getName()).append('=').append(p.getStringValue());
1847                  }                  }
1848                                    
# Line 1514  public class Client { Line 1902  public class Client {
1902          createAudioOutputDevice(String aoDriver, Parameter... paramList)          createAudioOutputDevice(String aoDriver, Parameter... paramList)
1903                                          throws IOException, LSException, LscpException {                                          throws IOException, LSException, LscpException {
1904                                    
                 verifyConnection();  
1905                  StringBuffer args = new StringBuffer(aoDriver);                  StringBuffer args = new StringBuffer(aoDriver);
1906                                    
1907                  for(Parameter p : paramList) {                  for(Parameter p : paramList) {
1908                          if(p.getValue() == null) continue;                          if(p == null || p.getName() == null || p.getValue() == null) continue;
1909                          args.append(' ').append(p.getName()).append('=').append(p.getStringValue());                          args.append(' ').append(p.getName()).append('=').append(p.getStringValue());
1910                  }                  }
1911                    
1912                  out.writeLine("CREATE AUDIO_OUTPUT_DEVICE " + args.toString());                  return retrieveIndex("CREATE AUDIO_OUTPUT_DEVICE " + args.toString());
                 if(getPrintOnlyMode()) return -1;  
                   
                 ResultSet rs = getEmptyResultSet();  
                   
                 return rs.getIndex();  
1913          }          }
1914                    
1915          /**          /**
# Line 1540  public class Client { Line 1922  public class Client {
1922           */           */
1923          public synchronized void          public synchronized void
1924          destroyAudioOutputDevice(int deviceId) throws IOException, LSException, LscpException {          destroyAudioOutputDevice(int deviceId) throws IOException, LSException, LscpException {
1925                  verifyConnection();                  retrieveIndex("DESTROY AUDIO_OUTPUT_DEVICE " + deviceId);
                 out.writeLine("DESTROY AUDIO_OUTPUT_DEVICE " + deviceId);  
                 if(getPrintOnlyMode()) return;  
                   
                 ResultSet rs = getEmptyResultSet();  
1926          }          }
1927                    
1928          /**          /**
# Line 1566  public class Client { Line 1944  public class Client {
1944                    
1945          /**          /**
1946           * Gets the current number of all created audio output devices.           * Gets the current number of all created audio output devices.
1947           * @return The current number of all created audio output devices.           * @return The current number of all created audio output devices
1948             *  or -1 if in "print only" mode.
1949           * @throws IOException If some I/O error occurs.           * @throws IOException If some I/O error occurs.
1950           * @throws LscpException If LSCP protocol corruption occurs.           * @throws LscpException If LSCP protocol corruption occurs.
1951           * @throws LSException If some other error occurs.           * @throws LSException If some other error occurs.
1952           */           */
1953          public synchronized int          public synchronized int
1954          getAudioOutputDeviceCount() throws IOException, LscpException, LSException {          getAudioOutputDeviceCount() throws IOException, LscpException, LSException {
1955                  verifyConnection();                  return retrieveInt("GET AUDIO_OUTPUT_DEVICES");
                 out.writeLine("GET AUDIO_OUTPUT_DEVICES");  
                 if(getPrintOnlyMode()) return -1;  
                   
                 String s = getSingleLineResultSet().getResult();  
                 return parseInt(s);  
1956          }          }
1957                                    
1958          /**          /**
# Line 1612  public class Client { Line 1986  public class Client {
1986           */           */
1987          public synchronized Integer[]          public synchronized Integer[]
1988          getAudioOutputDeviceIDs() throws IOException, LscpException, LSException {          getAudioOutputDeviceIDs() throws IOException, LscpException, LSException {
1989                  verifyConnection();                  return getIntegerList("LIST AUDIO_OUTPUT_DEVICES");
                 out.writeLine("LIST AUDIO_OUTPUT_DEVICES");  
                 if(getPrintOnlyMode()) return null;  
                   
                 return parseIntList(getSingleLineResultSet().getResult());  
1990          }          }
1991                    
1992          /**          /**
# Line 1719  public class Client { Line 2089  public class Client {
2089           */           */
2090          public synchronized void          public synchronized void
2091          setAudioOutputDeviceParameter(int deviceId, Parameter prm)          setAudioOutputDeviceParameter(int deviceId, Parameter prm)
2092                                                  throws IOException, LscpException, LSException {                                          throws IOException, LscpException, LSException
2093                            {
                 verifyConnection();  
2094                  String kv = prm.getName() + '=' + prm.getStringValue();                  String kv = prm.getName() + '=' + prm.getStringValue();
2095                  out.writeLine("SET AUDIO_OUTPUT_DEVICE_PARAMETER " + deviceId + ' ' + kv);                  retrieveIndex("SET AUDIO_OUTPUT_DEVICE_PARAMETER " + deviceId + ' ' + kv);
                 if(getPrintOnlyMode()) return;  
                   
                 ResultSet rs = getEmptyResultSet();  
2096          }          }
2097                    
2098          /**          /**
# Line 1910  public class Client { Line 2276  public class Client {
2276           */           */
2277          public synchronized void          public synchronized void
2278          setAudioOutputChannelParameter(int devId, int chn,  Parameter prm)          setAudioOutputChannelParameter(int devId, int chn,  Parameter prm)
2279                                                  throws IOException, LscpException, LSException {                                                  throws IOException, LscpException, LSException
2280                            {
                 verifyConnection();  
2281                  String args = devId + " " + chn + " " + prm.getName() + '=' + prm.getStringValue();                  String args = devId + " " + chn + " " + prm.getName() + '=' + prm.getStringValue();
2282                  out.writeLine("SET AUDIO_OUTPUT_CHANNEL_PARAMETER " + args);                  retrieveIndex("SET AUDIO_OUTPUT_CHANNEL_PARAMETER " + args);
                 if(getPrintOnlyMode()) return;  
                   
                 ResultSet rs = getEmptyResultSet();  
2283          }          }
2284                    
2285          /**          /**
2286           * Gets the current number of all MIDI input drivers.           * Gets the current number of all MIDI input drivers.
2287           * @return The current number of all MIDI input drivers.           * @return The current number of all MIDI input drivers or -1 if in "print only" mode.
2288           * @throws IOException If some I/O error occurs.           * @throws IOException If some I/O error occurs.
2289           * @throws LscpException If LSCP protocol corruption occurs.           * @throws LscpException If LSCP protocol corruption occurs.
2290           * @throws LSException If some other error occurs.           * @throws LSException If some other error occurs.
2291           */           */
2292          public synchronized int          public synchronized int
2293          getMidiInputDriverCount() throws IOException, LscpException, LSException {          getMidiInputDriverCount() throws IOException, LscpException, LSException {
2294                  verifyConnection();                  return retrieveInt("GET AVAILABLE_MIDI_INPUT_DRIVERS");
                 out.writeLine("GET AVAILABLE_MIDI_INPUT_DRIVERS");  
                 if(getPrintOnlyMode()) return -1;  
                   
                 String s = getSingleLineResultSet().getResult();  
                 return parseInt(s);  
2295          }          }
2296                    
2297          /**          /**
# Line 1994  public class Client { Line 2351  public class Client {
2351          public synchronized MidiInputDriver          public synchronized MidiInputDriver
2352          getMidiInputDriverInfo(String driverName, Parameter... depList)          getMidiInputDriverInfo(String driverName, Parameter... depList)
2353                                          throws IOException, LscpException, LSException {                                          throws IOException, LscpException, LSException {
2354                    
2355                  verifyConnection();                  MidiInputDriver mid = new MidiInputDriver();
2356                  out.writeLine("GET MIDI_INPUT_DRIVER INFO " + driverName);                  if(!retrieveInfo("GET MIDI_INPUT_DRIVER INFO " + driverName, mid)) return null;
                 if(getPrintOnlyMode()) return null;  
                   
                 ResultSet rs = getMultiLineResultSet();  
                   
                 MidiInputDriver mid = new MidiInputDriver(rs.getMultiLineResult());  
2357                  mid.setName(driverName);                  mid.setName(driverName);
2358                                    
2359                  for(String s : mid.getParameterNames())                  for(String s : mid.getParameterNames())
# Line 2040  public class Client { Line 2392  public class Client {
2392                  args.append(' ').append(param);                  args.append(' ').append(param);
2393                                    
2394                  for(Parameter p : deplist) {                  for(Parameter p : deplist) {
2395                          if(p.getValue() == null) continue;                          if(p == null || p.getName() == null || p.getValue() == null) continue;
2396                          args.append(' ').append(p.getName()).append('=').append(p.getStringValue());                          args.append(' ').append(p.getName()).append('=').append(p.getStringValue());
2397                  }                  }
2398                                    
# Line 2099  public class Client { Line 2451  public class Client {
2451           */           */
2452          public synchronized int          public synchronized int
2453          createMidiInputDevice(String miDriver, Parameter... paramList)          createMidiInputDevice(String miDriver, Parameter... paramList)
2454                                          throws IOException, LSException, LscpException {                                          throws IOException, LSException, LscpException
2455                            {
                 verifyConnection();  
2456                  StringBuffer args = new StringBuffer(miDriver);                  StringBuffer args = new StringBuffer(miDriver);
2457                                    
2458                  for(Parameter p : paramList) {                  for(Parameter p : paramList) {
2459                          if(p.getValue() == null) continue;                          if(p == null || p.getName() == null || p.getValue() == null) continue;
2460                          args.append(' ').append(p.getName()).append('=').append(p.getStringValue());                          args.append(' ').append(p.getName()).append('=').append(p.getStringValue());
2461                  }                  }
2462                    
2463                  out.writeLine("CREATE MIDI_INPUT_DEVICE " + args.toString());                  return retrieveIndex("CREATE MIDI_INPUT_DEVICE " + args.toString());
                 if(getPrintOnlyMode()) return -1;  
                   
                 ResultSet rs = getEmptyResultSet();  
                   
                 return rs.getIndex();  
2464          }          }
2465                    
2466          /**          /**
# Line 2128  public class Client { Line 2474  public class Client {
2474           */           */
2475          public synchronized void          public synchronized void
2476          destroyMidiInputDevice(int deviceId) throws IOException, LSException, LscpException {          destroyMidiInputDevice(int deviceId) throws IOException, LSException, LscpException {
2477                  verifyConnection();                  retrieveIndex("DESTROY MIDI_INPUT_DEVICE " + deviceId);
                 out.writeLine("DESTROY MIDI_INPUT_DEVICE " + deviceId);  
                 if(getPrintOnlyMode()) return;  
                   
                 ResultSet rs = getEmptyResultSet();  
2478          }          }
2479                    
2480          /**          /**
# Line 2154  public class Client { Line 2496  public class Client {
2496                    
2497          /**          /**
2498           * Gets the current number of all created MIDI input devices.           * Gets the current number of all created MIDI input devices.
2499           * @return The current number of all created MIDI input devices.           * @return The current number of all created MIDI input
2500             * devices or -1 if in "print only" mode.
2501           * @throws IOException If some I/O error occurs.           * @throws IOException If some I/O error occurs.
2502           * @throws LscpException If LSCP protocol corruption occurs.           * @throws LscpException If LSCP protocol corruption occurs.
2503           * @throws LSException If some other error occurs.           * @throws LSException If some other error occurs.
2504           */           */
2505          public synchronized int          public synchronized int
2506          getMidiInputDeviceCount() throws IOException, LscpException, LSException {          getMidiInputDeviceCount() throws IOException, LscpException, LSException {
2507                  verifyConnection();                  return retrieveInt("GET MIDI_INPUT_DEVICES");
                 out.writeLine("GET MIDI_INPUT_DEVICES");  
                 if(getPrintOnlyMode()) return -1;  
                   
                 String s = getSingleLineResultSet().getResult();  
                 return parseInt(s);  
2508          }          }
2509                    
2510          /**          /**
# Line 2206  public class Client { Line 2544  public class Client {
2544           */           */
2545          public synchronized Integer[]          public synchronized Integer[]
2546          getMidiInputDeviceIDs() throws IOException, LscpException, LSException {          getMidiInputDeviceIDs() throws IOException, LscpException, LSException {
2547                  verifyConnection();                  return getIntegerList("LIST MIDI_INPUT_DEVICES");
                 out.writeLine("LIST MIDI_INPUT_DEVICES");  
                 if(getPrintOnlyMode()) return null;  
                   
                 return parseIntList(getSingleLineResultSet().getResult());  
2548          }          }
2549                    
2550          /**          /**
# Line 2307  public class Client { Line 2641  public class Client {
2641           */           */
2642          public synchronized void          public synchronized void
2643          setMidiInputDeviceParameter(int deviceId, Parameter prm)          setMidiInputDeviceParameter(int deviceId, Parameter prm)
2644                                                  throws IOException, LscpException, LSException {                                                  throws IOException, LscpException, LSException
2645                            {
                 verifyConnection();  
2646                  String kv = prm.getName() + '=' + prm.getStringValue();                  String kv = prm.getName() + '=' + prm.getStringValue();
2647                  out.writeLine("SET MIDI_INPUT_DEVICE_PARAMETER " + deviceId + ' ' + kv);                  retrieveIndex("SET MIDI_INPUT_DEVICE_PARAMETER " + deviceId + ' ' + kv);
                 if(getPrintOnlyMode()) return;  
                   
                 ResultSet rs = getEmptyResultSet();  
2648          }          }
2649                    
2650                    
2651          /**          /**
2652           * Changes the port number of the speicified MIDI input device.           * Changes the port number of the specified MIDI input device.
2653           * @param deviceId The numerical ID of the MIDI input device.           * @param deviceId The numerical ID of the MIDI input device.
2654           * @param ports The new number of MIDI input ports.           * @param ports The new number of MIDI input ports.
2655           *           *
# Line 2480  public class Client { Line 2810  public class Client {
2810           */           */
2811          public synchronized void          public synchronized void
2812          setMidiInputPortParameter(int deviceId, int port,  Parameter prm)          setMidiInputPortParameter(int deviceId, int port,  Parameter prm)
2813                                                  throws IOException, LscpException, LSException {                                                  throws IOException, LscpException, LSException
2814                            {
                 verifyConnection();  
2815                  String args = deviceId + " " + port + " " +                  String args = deviceId + " " + port + " " +
2816                          prm.getName() + '=' + prm.getStringValue();                          prm.getName() + '=' + prm.getStringValue();
2817                  out.writeLine("SET MIDI_INPUT_PORT_PARAMETER " + args);                  retrieveIndex("SET MIDI_INPUT_PORT_PARAMETER " + args);
                 if(getPrintOnlyMode()) return;  
                   
                 ResultSet rs = getEmptyResultSet();  
2818          }          }
2819                    
2820          /**          /**
# Line 2502  public class Client { Line 2828  public class Client {
2828           */           */
2829          public synchronized int          public synchronized int
2830          addMidiInstrumentMap(String name) throws IOException, LSException, LscpException {          addMidiInstrumentMap(String name) throws IOException, LSException, LscpException {
2831                  verifyConnection();                  return retrieveIndex("ADD MIDI_INSTRUMENT_MAP '" + toEscapedText(name) + "'");
                 out.writeLine("ADD MIDI_INSTRUMENT_MAP '" + toEscapedString(name) + "'");  
                 if(getPrintOnlyMode()) return -1;  
                   
                 ResultSet rs = getEmptyResultSet();  
                   
                 return rs.getIndex();  
2832          }          }
2833                    
2834          /**          /**
# Line 2522  public class Client { Line 2842  public class Client {
2842           */           */
2843          public synchronized void          public synchronized void
2844          removeMidiInstrumentMap(int mapId) throws IOException, LscpException, LSException {          removeMidiInstrumentMap(int mapId) throws IOException, LscpException, LSException {
2845                  verifyConnection();                  retrieveIndex("REMOVE MIDI_INSTRUMENT_MAP " + mapId);
                 out.writeLine("REMOVE MIDI_INSTRUMENT_MAP " + mapId);  
                 if(getPrintOnlyMode()) return;  
                   
                 ResultSet rs = getEmptyResultSet();  
2846          }          }
2847                    
2848          /**          /**
# Line 2537  public class Client { Line 2853  public class Client {
2853           */           */
2854          public synchronized void          public synchronized void
2855          removeAllMidiInstrumentMaps() throws IOException, LscpException, LSException {          removeAllMidiInstrumentMaps() throws IOException, LscpException, LSException {
2856                  verifyConnection();                  retrieveIndex("REMOVE MIDI_INSTRUMENT_MAP ALL");
                 out.writeLine("REMOVE MIDI_INSTRUMENT_MAP ALL");  
                 if(getPrintOnlyMode()) return;  
                   
                 ResultSet rs = getEmptyResultSet();  
2857          }          }
2858                    
2859          /**          /**
2860           * Gets the current number of all MIDI instrument maps.           * Gets the current number of all MIDI instrument maps.
2861           * @return The current number of all MIDI instrument maps.           * @return The current number of all MIDI instrument maps
2862             *  or -1 if in "print only" mode.
2863           * @throws IOException If some I/O error occurs.           * @throws IOException If some I/O error occurs.
2864           * @throws LscpException If LSCP protocol corruption occurs.           * @throws LscpException If LSCP protocol corruption occurs.
2865           * @throws LSException If some other error occurs.           * @throws LSException If some other error occurs.
2866           */           */
2867          public synchronized int          public synchronized int
2868          getMidiInstrumentMapCount() throws IOException, LscpException, LSException {          getMidiInstrumentMapCount() throws IOException, LscpException, LSException {
2869                  verifyConnection();                  return retrieveInt("GET MIDI_INSTRUMENT_MAPS");
                 out.writeLine("GET MIDI_INSTRUMENT_MAPS");  
                 if(getPrintOnlyMode()) return -1;  
                   
                 String s = getSingleLineResultSet().getResult();  
                 return parseInt(s);  
2870          }          }
2871                    
2872          /**          /**
# Line 2573  public class Client { Line 2881  public class Client {
2881           */           */
2882          public synchronized Integer[]          public synchronized Integer[]
2883          getMidiInstrumentMapIDs() throws IOException, LscpException, LSException {          getMidiInstrumentMapIDs() throws IOException, LscpException, LSException {
2884                  verifyConnection();                  return getIntegerList("LIST MIDI_INSTRUMENT_MAPS");
                 out.writeLine("LIST MIDI_INSTRUMENT_MAPS");  
                 if(getPrintOnlyMode()) return null;  
                   
                 return parseIntList(getSingleLineResultSet().getResult());  
2885          }          }
2886                    
2887          /**          /**
# Line 2651  public class Client { Line 2955  public class Client {
2955           */           */
2956          public synchronized void          public synchronized void
2957          setMidiInstrumentMapName(int mapId, String name)          setMidiInstrumentMapName(int mapId, String name)
2958                                  throws IOException, LscpException, LSException {                                  throws IOException, LscpException, LSException
2959                            {
2960                  verifyConnection();                  name = toEscapedText(name);
2961                  name = toEscapedString(name);                  retrieveIndex("SET MIDI_INSTRUMENT_MAP NAME " +  + mapId + " '" + name + "'");
                 out.writeLine("SET MIDI_INSTRUMENT_MAP NAME " +  + mapId + " '" + name + "'");  
                 if(getPrintOnlyMode()) return;  
                   
                 ResultSet rs = getEmptyResultSet();  
2962          }          }
2963                    
2964                    
# Line 2704  public class Client { Line 3004  public class Client {
3004                  cmd.append(entry.getMidiBank()).append(' ');                  cmd.append(entry.getMidiBank()).append(' ');
3005                  cmd.append(entry.getMidiProgram()).append(' ');                  cmd.append(entry.getMidiProgram()).append(' ');
3006                  cmd.append(info.getEngine()).append(" '");                  cmd.append(info.getEngine()).append(" '");
3007                  cmd.append(info.getFilePath()).append("' ");                  cmd.append(conv(info.getFilePath())).append("' ");
3008                  cmd.append(info.getInstrumentIndex()).append(' ');                  cmd.append(info.getInstrumentIndex()).append(' ');
3009                  cmd.append(info.getVolume());                  cmd.append(info.getVolume());
3010                  if(!info.getLoadMode().name().equals("DEFAULT")) {                  if(!info.getLoadMode().name().equals("DEFAULT")) {
# Line 2712  public class Client { Line 3012  public class Client {
3012                  }                  }
3013                                    
3014                  if(info.getName() != null) {                  if(info.getName() != null) {
3015                          String s = toEscapedString(info.getName());                          String s = toEscapedText(info.getName());
3016                          cmd.append(" '").append(s).append("'");                          cmd.append(" '").append(s).append("'");
3017                  }                  }
3018                                    
# Line 2734  public class Client { Line 3034  public class Client {
3034           */           */
3035          public synchronized void          public synchronized void
3036          unmapMidiInstrument(int mapId, MidiInstrumentEntry entry)          unmapMidiInstrument(int mapId, MidiInstrumentEntry entry)
3037                                          throws IOException, LSException, LscpException {                                          throws IOException, LSException, LscpException
3038                            {
                 verifyConnection();  
3039                  StringBuffer cmd = new StringBuffer("UNMAP MIDI_INSTRUMENT ");                  StringBuffer cmd = new StringBuffer("UNMAP MIDI_INSTRUMENT ");
3040                  cmd.append(mapId).append(' ');                  cmd.append(mapId).append(' ');
3041                  cmd.append(entry.getMidiBank()).append(' ');                  cmd.append(entry.getMidiBank()).append(' ');
3042                  cmd.append(entry.getMidiProgram());                  cmd.append(entry.getMidiProgram());
3043                    
3044                  out.writeLine(cmd.toString());                  retrieveIndex(cmd.toString());
                 if(getPrintOnlyMode()) return;  
                   
                 ResultSet rs = getEmptyResultSet();  
3045          }          }
3046                    
3047          /**          /**
3048           * Gets the current number of all MIDI instrument in all maps.           * Gets the current number of all MIDI instrument in all maps.
3049           * @return The current number of all MIDI instrument in all maps.           * @return The current number of all MIDI instrument in all maps
3050             * or -1 if in "print only" mode.
3051           * @throws IOException If some I/O error occurs.           * @throws IOException If some I/O error occurs.
3052           * @throws LscpException If LSCP protocol corruption occurs.           * @throws LscpException If LSCP protocol corruption occurs.
3053           * @throws LSException If some other error occurs.           * @throws LSException If some other error occurs.
3054           */           */
3055          public synchronized int          public synchronized int
3056          getMidiInstrumentCount() throws IOException, LscpException, LSException {          getMidiInstrumentCount() throws IOException, LscpException, LSException {
3057                  verifyConnection();                  return retrieveInt("GET MIDI_INSTRUMENTS ALL");
                 out.writeLine("GET MIDI_INSTRUMENTS ALL");  
                 if(getPrintOnlyMode()) return -1;  
                   
                 String s = getSingleLineResultSet().getResult();  
                 return parseInt(s);  
3058          }          }
3059                    
3060          /**          /**
3061           * Gets the current number of MIDI instrument in the specified map.           * Gets the current number of MIDI instrument in the specified map.
3062           * @param mapId The ID of the map.           * @param mapId The ID of the map.
3063           * @return The current number of MIDI instrument in the specified map.           * @return The current number of MIDI instrument in the
3064             * specified map or -1 if in "print only" mode.
3065           * @throws IOException If some I/O error occurs.           * @throws IOException If some I/O error occurs.
3066           * @throws LscpException If LSCP protocol corruption occurs.           * @throws LscpException If LSCP protocol corruption occurs.
3067           * @throws LSException If some other error occurs.           * @throws LSException If some other error occurs.
3068           */           */
3069          public synchronized int          public synchronized int
3070          getMidiInstrumentCount(int mapId) throws IOException, LscpException, LSException {          getMidiInstrumentCount(int mapId) throws IOException, LscpException, LSException {
3071                  verifyConnection();                  return retrieveInt("GET MIDI_INSTRUMENTS " + String.valueOf(mapId));
                 out.writeLine("GET MIDI_INSTRUMENTS " + String.valueOf(mapId));  
                 if(getPrintOnlyMode()) return -1;  
                   
                 String s = getSingleLineResultSet().getResult();  
                 return parseInt(s);  
3072          }          }
3073                    
3074          /**          /**
# Line 2803  public class Client { Line 3091  public class Client {
3091          }          }
3092                    
3093          /**          /**
3094           * Gets all MIDI instrument contained int the specified MIDI instrument map.           * Gets all MIDI instrument entries contained int the specified MIDI instrument map.
3095             * @param mapId The ID of the map, which instruments should be obtained.
3096             * @return An int array providing all MIDI instrument entries
3097             * in the specified MIDI instrument map.
3098             * @throws IOException If some I/O error occurs.
3099             * @throws LscpException If LSCP protocol corruption occurs.
3100             * @throws LSException If some other error occurs.
3101             */
3102            public synchronized int[][]
3103            getMidiInstrumentEntries(int mapId) throws IOException, LscpException, LSException {
3104                    verifyConnection();
3105                    out.writeLine("LIST MIDI_INSTRUMENTS " + String.valueOf(mapId));
3106                    if(getPrintOnlyMode()) return null;
3107                    
3108                    String[] entries = parseArray(getSingleLineResultSet().getResult());
3109                    int[][] e = new int[entries.length][3];
3110                    
3111                    for(int i = 0; i < entries.length; i++) {
3112                            Integer[] vals = parseIntList(entries[i]);
3113                            if(vals.length != 3) {
3114                                    throw new LscpException(LscpI18n.getLogMsg("CommandFailed!"));
3115                            }
3116                            
3117                            e[i][0] = vals[0];
3118                            e[i][1] = vals[1];
3119                            e[i][2] = vals[2];
3120                    }
3121                    
3122                    return e;
3123            }
3124            
3125            /**
3126             * Gets all MIDI instruments contained int the specified MIDI instrument map.
3127           * @param mapId The ID of the map, which instruments should be obtained.           * @param mapId The ID of the map, which instruments should be obtained.
3128           * @return A <code>MidiInstrumentInfo</code> array providing           * @return A <code>MidiInstrumentInfo</code> array providing
3129           * all MIDI instruments from all MIDI instrument maps.           * all MIDI instruments in the specified MIDI instrument map.
3130           * @throws IOException If some I/O error occurs.           * @throws IOException If some I/O error occurs.
3131           * @throws LscpException If LSCP protocol corruption occurs.           * @throws LscpException If LSCP protocol corruption occurs.
3132           * @throws LSException If some other error occurs.           * @throws LSException If some other error occurs.
# Line 2854  public class Client { Line 3174  public class Client {
3174                                          throws IOException, LscpException, LSException {                                          throws IOException, LscpException, LSException {
3175                    
3176                  verifyConnection();                  verifyConnection();
3177                    requestMidiInstrumentInfo(mapId, bank, program);
3178                    return getMidiInstrumentInfoResponse(mapId, bank, program);
3179            }
3180            
3181            private void
3182            requestMidiInstrumentInfo(int mapId, int bank, int program) throws IOException {
3183                  StringBuffer cmd = new StringBuffer("GET MIDI_INSTRUMENT INFO ");                  StringBuffer cmd = new StringBuffer("GET MIDI_INSTRUMENT INFO ");
3184                  cmd.append(mapId).append(' ');                  cmd.append(mapId).append(' ');
3185                  cmd.append(bank).append(' ');                  cmd.append(bank).append(' ');
3186                  cmd.append(program);                  cmd.append(program);
3187                                    
3188                  out.writeLine(cmd.toString());                  out.writeLine(cmd.toString());
3189                  if(getPrintOnlyMode()) return null;          }
3190            
3191            private MidiInstrumentInfo
3192            getMidiInstrumentInfoResponse(int mapId, int bank, int program)
3193                                            throws IOException, LscpException, LSException {
3194                                    
3195                    if(getPrintOnlyMode()) return null;
3196                  ResultSet rs = getMultiLineResultSet();                  ResultSet rs = getMultiLineResultSet();
3197                  MidiInstrumentEntry entry = new MidiInstrumentEntry(bank, program);                  MidiInstrumentEntry entry = new MidiInstrumentEntry(bank, program);
3198                  return new MidiInstrumentInfo(mapId, entry, rs.getMultiLineResult());                  return new MidiInstrumentInfo(mapId, entry, rs.getMultiLineResult());
# Line 2908  public class Client { Line 3239  public class Client {
3239           */           */
3240          public synchronized void          public synchronized void
3241          loadInstrument(String filename, int instrIdx, int samplerChn, boolean nonModal)          loadInstrument(String filename, int instrIdx, int samplerChn, boolean nonModal)
3242                                                  throws IOException, LscpException, LSException {                                                  throws IOException, LscpException, LSException
3243                            {
3244                  String cmd = nonModal ? "LOAD INSTRUMENT NON_MODAL " : "LOAD INSTRUMENT ";                  String cmd = nonModal ? "LOAD INSTRUMENT NON_MODAL " : "LOAD INSTRUMENT ";
3245                  String args = '\'' + filename + "' " + instrIdx + ' ' + samplerChn;                  String args = '\'' + conv(filename) + "' " + instrIdx + ' ' + samplerChn;
3246                    
3247                  out.writeLine(cmd + args);                  retrieveIndex(cmd + args);
                 if(getPrintOnlyMode()) return;  
                   
                 ResultSet rs = getEmptyResultSet();  
3248          }          }
3249                    
3250          /**          /**
# Line 2933  public class Client { Line 3261  public class Client {
3261           */           */
3262          public synchronized void          public synchronized void
3263          loadSamplerEngine(String engineName, int samplerChn)          loadSamplerEngine(String engineName, int samplerChn)
3264                                          throws IOException, LscpException, LSException {                                          throws IOException, LscpException, LSException
3265                            { retrieveIndex("LOAD ENGINE " + engineName + ' ' + samplerChn); }
                 verifyConnection();  
                 out.writeLine("LOAD ENGINE " + engineName + ' ' + samplerChn);  
                 if(getPrintOnlyMode()) return;  
                   
                 ResultSet rs = getEmptyResultSet();  
         }  
3266                    
3267          /**          /**
3268           * Gets the current number of all created sampler channels.           * Gets the current number of all created sampler channels.
3269           * @return The current number of all created sampler channels.           * @return The current number of all created sampler
3270             * channels or -1 if in "print only" mode.
3271           * @throws IOException If some I/O error occurs.           * @throws IOException If some I/O error occurs.
3272           * @throws LscpException If LSCP protocol corruption occurs.           * @throws LscpException If LSCP protocol corruption occurs.
3273           * @throws LSException If some other error occurs.           * @throws LSException If some other error occurs.
3274           */           */
3275          public synchronized int          public synchronized int
3276          getSamplerChannelCount() throws IOException, LscpException, LSException {          getSamplerChannelCount() throws IOException, LscpException, LSException {
3277                  verifyConnection();                  return retrieveInt("GET CHANNELS");
                 out.writeLine("GET CHANNELS");  
                 if(getPrintOnlyMode()) return -1;  
                   
                 String s = getSingleLineResultSet().getResult();  
                 return parseInt(s);  
3278          }          }
3279                    
3280          /**          /**
# Line 2980  public class Client { Line 3298  public class Client {
3298                                    
3299                  return channels;                  return channels;
3300          }          }
3301    
3302            /**
3303             * Gets a list of the specified sampler channels.
3304             * @return A <code>SamplerChannel</code> array providing all created sampler channels.
3305             * @throws IOException If some I/O error occurs.
3306             * @throws LscpException If LSCP protocol corruption occurs.
3307             * @throws LSException If some other error occurs.
3308             * @see #addSamplerChannel
3309             * @see #removeSamplerChannel
3310             */
3311            public synchronized SamplerChannel[]
3312            getSamplerChannels(final Integer[] ids) throws IOException, LscpException, LSException {
3313                    verifyConnection();
3314    
3315                    int count = 0;
3316                    for(int i = 0; i < ids.length; i++) {
3317                            if(ids[i] >= 0) {
3318                                    int tmp = ids[i]; // to avoid overlapping
3319                                    ids[i] = -1;
3320                                    ids[count++] = tmp;
3321                            }
3322                    }
3323                    if(getPrintOnlyMode()) return null;
3324    
3325                    final SamplerChannel[] channels = new SamplerChannel[count];
3326    
3327                    new CmdListIterator(count) {
3328                            @Override
3329                            protected void
3330                            writeOutput(int index) throws IOException {
3331                                    channels[index] = new SamplerChannel();
3332                                    out.writeLine("GET CHANNEL INFO " + ids[index]);
3333                                    channels[index].setChannelId(ids[index]);
3334                            }
3335    
3336                            @Override
3337                            protected void
3338                            readInput(int index) throws IOException, LscpException, LSException {
3339                                    if(getPrintOnlyMode()) return;
3340                                    ResultSet rs = getMultiLineResultSet();
3341    
3342                                    for(String s : rs.getMultiLineResult()) {
3343                                            if(!channels[index].parse(s)) {
3344                                                    String msg = LscpI18n.getLogMsg("unknownLine", s);
3345                                                    Client.getLogger().info(msg);
3346                                            }
3347                                    }
3348                            }
3349                    }.run();
3350    
3351    
3352    
3353                    for(SamplerChannel sc : channels) {
3354                            if(sc.getEngine() != null) {
3355                                    sc.setEngine(getEngineInfo(sc.getEngine().getName()));
3356                            }
3357                    }
3358    
3359                    return channels;
3360            }
3361    
3362            private static abstract class CmdListIterator {
3363                    private final int cmdCount;
3364                    private final int cmdsPerStep;
3365    
3366                    CmdListIterator(int cmdCount) {
3367                            this(cmdCount, 100);
3368                    }
3369    
3370                    CmdListIterator(int cmdCount, int cmdsPerStep) {
3371                            this.cmdCount = cmdCount;
3372                            this.cmdsPerStep = cmdsPerStep;
3373                    }
3374    
3375                    public void
3376                    run() throws IOException, LscpException, LSException {
3377                            int currentStep = 0;
3378                            int stepCount = cmdCount / cmdsPerStep;
3379    
3380                            for(currentStep = 0; currentStep < stepCount; currentStep++) {
3381                                    for(int j = 0; j < cmdsPerStep; j++) {
3382                                            int idx = (currentStep * cmdsPerStep) + j;
3383                                            writeOutput(idx);
3384                                    }
3385    
3386                                    for(int j = 0; j < cmdsPerStep; j++) {
3387                                            int idx = (currentStep * cmdsPerStep) + j;
3388                                            readInput(idx);
3389                                    }
3390                            }
3391    
3392                            int cmdsLeft = cmdCount % cmdsPerStep;
3393                            if(cmdsLeft > 0) {
3394                                    for(int j = 0; j < cmdsLeft; j++) {
3395                                            int idx = stepCount * cmdsPerStep + j;
3396                                            writeOutput(idx);
3397                                    }
3398    
3399                                    for(int j = 0; j < cmdsLeft; j++) {
3400                                            int idx = stepCount * cmdsPerStep + j;
3401                                            readInput(idx);
3402                                    }
3403                            }
3404                    }
3405    
3406                    protected abstract void writeOutput(int index) throws IOException;
3407    
3408                    protected abstract void readInput(int index) throws IOException, LscpException, LSException;
3409            }
3410                    
3411          /**          /**
3412           * Gets a list with numerical IDs of all created sampler channels.           * Gets a list with numerical IDs of all created sampler channels.
# Line 2993  public class Client { Line 3420  public class Client {
3420           */           */
3421          public synchronized Integer[]          public synchronized Integer[]
3422          getSamplerChannelIDs() throws IOException, LscpException, LSException {          getSamplerChannelIDs() throws IOException, LscpException, LSException {
3423                  verifyConnection();                  return getIntegerList("LIST CHANNELS");
                 out.writeLine("LIST CHANNELS");  
                 if(getPrintOnlyMode()) return null;  
                   
                 return parseIntList(getSingleLineResultSet().getResult());  
3424          }          }
3425                    
3426          /**          /**
# Line 3012  public class Client { Line 3435  public class Client {
3435           */           */
3436          public synchronized int          public synchronized int
3437          addSamplerChannel() throws IOException, LSException, LscpException {          addSamplerChannel() throws IOException, LSException, LscpException {
3438                  verifyConnection();                  return retrieveIndex("ADD CHANNEL");
                 out.writeLine("ADD CHANNEL");  
                 if(getPrintOnlyMode()) return -1;  
                   
                 ResultSet rs = getEmptyResultSet();  
                   
                 return rs.getIndex();  
3439          }          }
3440                    
3441          /**          /**
# Line 3034  public class Client { Line 3451  public class Client {
3451           */           */
3452          public synchronized void          public synchronized void
3453          removeSamplerChannel(int samplerChn) throws IOException, LscpException, LSException {          removeSamplerChannel(int samplerChn) throws IOException, LscpException, LSException {
3454                  verifyConnection();                  retrieveIndex("REMOVE CHANNEL " + samplerChn);
                 out.writeLine("REMOVE CHANNEL " + samplerChn);  
                 if(getPrintOnlyMode()) return;  
                   
                 ResultSet rs = getEmptyResultSet();  
3455          }          }
3456                    
3457          /**          /**
3458           * Gets the number of all available engines.           * Gets the number of all available engines.
3459           * @return The number of all available engines.           * @return The number of all available engines or -1 if in "print only" mode.
3460           * @throws IOException If some I/O error occurs.           * @throws IOException If some I/O error occurs.
3461           * @throws LscpException If LSCP protocol corruption occurs.           * @throws LscpException If LSCP protocol corruption occurs.
3462           * @throws LSException If some other error occurs.           * @throws LSException If some other error occurs.
3463           */           */
3464          public synchronized int          public synchronized int
3465          getEngineCount() throws IOException, LscpException, LSException {          getEngineCount() throws IOException, LscpException, LSException {
3466                  verifyConnection();                  return retrieveInt("GET AVAILABLE_ENGINES");
                 out.writeLine("GET AVAILABLE_ENGINES");  
                 if(getPrintOnlyMode()) return -1;  
                   
                 String s = getSingleLineResultSet().getResult();  
                 return parseInt(s);  
3467          }          }
3468                    
3469          /**          /**
# Line 3109  public class Client { Line 3517  public class Client {
3517           */           */
3518          private synchronized SamplerEngine          private synchronized SamplerEngine
3519          getEngineInfo(String engineName) throws IOException, LscpException, LSException {          getEngineInfo(String engineName) throws IOException, LscpException, LSException {
3520                  verifyConnection();                  SamplerEngine se = engineMap.get(engineName);
3521                  out.writeLine("GET ENGINE INFO " + engineName);                  if(se != null) return se;
                 if(getPrintOnlyMode()) return null;  
3522                                    
3523                  ResultSet rs = getMultiLineResultSet();                  se = new SamplerEngine();
3524                  SamplerEngine se = new SamplerEngine(rs.getMultiLineResult());                  if(!retrieveInfo("GET ENGINE INFO " + engineName, se)) return null;
3525                  se.setName(engineName);                  se.setName(engineName);
3526                    engineMap.put(engineName, se);
3527    
3528                  return se;                  return se;
3529          }          }
3530                    
# Line 3133  public class Client { Line 3542  public class Client {
3542           */           */
3543          public synchronized SamplerChannel          public synchronized SamplerChannel
3544          getSamplerChannelInfo(int samplerChn) throws IOException, LscpException, LSException {          getSamplerChannelInfo(int samplerChn) throws IOException, LscpException, LSException {
3545                  verifyConnection();                  SamplerChannel sc = new SamplerChannel();
3546                  out.writeLine("GET CHANNEL INFO " + samplerChn);                  if(!retrieveInfo("GET CHANNEL INFO " + samplerChn, sc)) return null;
                 if(getPrintOnlyMode()) return null;  
                   
                 ResultSet rs = getMultiLineResultSet();  
                 SamplerChannel sc = new SamplerChannel(rs.getMultiLineResult());  
3547                  sc.setChannelId(samplerChn);                  sc.setChannelId(samplerChn);
3548                  if(sc.getEngine() != null) sc.setEngine(getEngineInfo(sc.getEngine().getName()));                  if(sc.getEngine() != null) sc.setEngine(getEngineInfo(sc.getEngine().getName()));
3549                                    
# Line 3149  public class Client { Line 3554  public class Client {
3554           * Gets the current number of active voices on the specified sampler channel.           * Gets the current number of active voices on the specified sampler channel.
3555           *           *
3556           * @param samplerChn The sampler channel number.           * @param samplerChn The sampler channel number.
3557           * @return The current number of active voices on the specified sampler channel.           * @return The current number of active voices on the
3558             * specified sampler channel or -1 if in "print only" mode.
3559           * @throws IOException If some I/O error occurs.           * @throws IOException If some I/O error occurs.
3560           * @throws LscpException If LSCP protocol corruption occurs.           * @throws LscpException If LSCP protocol corruption occurs.
3561           * @throws LSException If there is no sampler channel with number <code>samplerChn</code>.           * @throws LSException If there is no sampler channel with number <code>samplerChn</code>.
# Line 3157  public class Client { Line 3563  public class Client {
3563           */           */
3564          public synchronized int          public synchronized int
3565          getChannelVoiceCount(int samplerChn) throws IOException, LscpException, LSException {          getChannelVoiceCount(int samplerChn) throws IOException, LscpException, LSException {
3566                  verifyConnection();                  return retrieveInt("GET CHANNEL VOICE_COUNT " + samplerChn);
                 out.writeLine("GET CHANNEL VOICE_COUNT " + samplerChn);  
                 if(getPrintOnlyMode()) return -1;  
                   
                 ResultSet rs = getSingleLineResultSet();  
                   
                 return parseInt(rs.getResult());  
3567          }          }
3568                    
3569          /**          /**
# Line 3303  public class Client { Line 3703  public class Client {
3703           */           */
3704          public synchronized void          public synchronized void
3705          setChannelAudioOutputDevice(int samplerChn, int devId)          setChannelAudioOutputDevice(int samplerChn, int devId)
3706                                  throws IOException, LscpException, LSException {                                  throws IOException, LscpException, LSException
3707                            { retrieveIndex("SET CHANNEL AUDIO_OUTPUT_DEVICE " + samplerChn + ' ' + devId); }
                 verifyConnection();  
                 out.writeLine("SET CHANNEL AUDIO_OUTPUT_DEVICE " + samplerChn + ' ' + devId);  
                 if(getPrintOnlyMode()) return;  
                   
                 ResultSet rs = getEmptyResultSet();  
         }  
3708                    
3709          /**          /**
3710           * Sets the audio output channel on the specified sampler channel.           * Sets the audio output channel on the specified sampler channel.
# Line 3333  public class Client { Line 3727  public class Client {
3727           */           */
3728          public synchronized void          public synchronized void
3729          setChannelAudioOutputChannel(int samplerChn, int audioOut, int audioIn)          setChannelAudioOutputChannel(int samplerChn, int audioOut, int audioIn)
3730                                  throws IOException, LscpException, LSException {                                  throws IOException, LscpException, LSException
3731                            {
                 verifyConnection();  
3732                  String args = " " + samplerChn + ' ' + audioOut + ' ' + audioIn;                  String args = " " + samplerChn + ' ' + audioOut + ' ' + audioIn;
3733                  out.writeLine("SET CHANNEL AUDIO_OUTPUT_CHANNEL" + args);                  retrieveIndex("SET CHANNEL AUDIO_OUTPUT_CHANNEL" + args);
                 if(getPrintOnlyMode()) return;  
                   
                 ResultSet rs = getEmptyResultSet();  
3734          }          }
3735                    
3736          /**          /**
# Line 3362  public class Client { Line 3752  public class Client {
3752           */           */
3753          public synchronized void          public synchronized void
3754          setChannelMidiInputDevice(int samplerChn, int devId)          setChannelMidiInputDevice(int samplerChn, int devId)
3755                                  throws IOException, LscpException, LSException {                                  throws IOException, LscpException, LSException
3756                            { retrieveIndex("SET CHANNEL MIDI_INPUT_DEVICE " + samplerChn + ' ' + devId); }
                 verifyConnection();  
                 out.writeLine("SET CHANNEL MIDI_INPUT_DEVICE " + samplerChn + ' ' + devId);  
                 if(getPrintOnlyMode()) return;  
                   
                 ResultSet rs = getEmptyResultSet();  
         }  
3757                    
3758          /**          /**
3759           * Sets the MIDI input port on the specified sampler channel.           * Sets the MIDI input port on the specified sampler channel.
# Line 3385  public class Client { Line 3769  public class Client {
3769           */           */
3770          public synchronized void          public synchronized void
3771          setChannelMidiInputPort(int samplerChn, int port)          setChannelMidiInputPort(int samplerChn, int port)
3772                                  throws IOException, LscpException, LSException {                                  throws IOException, LscpException, LSException
3773                            { retrieveIndex("SET CHANNEL MIDI_INPUT_PORT " + samplerChn + ' ' + port); }
                 verifyConnection();  
                 out.writeLine("SET CHANNEL MIDI_INPUT_PORT " + samplerChn + ' ' + port);  
                 if(getPrintOnlyMode()) return;  
                   
                 ResultSet rs = getEmptyResultSet();  
         }  
3774                    
3775          /**          /**
3776           * Sets the MIDI input channel the specified sampler channel should listen to.           * Sets the MIDI input channel the specified sampler channel should listen to.
# Line 3408  public class Client { Line 3786  public class Client {
3786           */           */
3787          public synchronized void          public synchronized void
3788          setChannelMidiInputChannel(int samplerChn, int midiChn)          setChannelMidiInputChannel(int samplerChn, int midiChn)
3789                                  throws IOException, LscpException, LSException {                                  throws IOException, LscpException, LSException
3790                            {
                 verifyConnection();  
3791                  String args = String.valueOf(samplerChn) + ' ';                  String args = String.valueOf(samplerChn) + ' ';
3792                  args += (midiChn == -1 ? "ALL" : String.valueOf(midiChn));                  args += (midiChn == -1 ? "ALL" : String.valueOf(midiChn));
3793                  out.writeLine("SET CHANNEL MIDI_INPUT_CHANNEL " + args);                  retrieveIndex("SET CHANNEL MIDI_INPUT_CHANNEL " + args);
                 if(getPrintOnlyMode()) return;  
                   
                 ResultSet rs = getEmptyResultSet();  
3794          }          }
3795                    
3796          /**          /**
# Line 3440  public class Client { Line 3814  public class Client {
3814           */           */
3815          public synchronized void          public synchronized void
3816          setChannelMidiInstrumentMap(int samplerChn, int mapId)          setChannelMidiInstrumentMap(int samplerChn, int mapId)
3817                                  throws IOException, LscpException, LSException {                                  throws IOException, LscpException, LSException
3818                            {
                 verifyConnection();  
3819                  String s;                  String s;
3820                  if(mapId == -1) {                  if(mapId == -1) {
3821                          s = " NONE";                          s = " NONE";
# Line 3451  public class Client { Line 3824  public class Client {
3824                  } else {                  } else {
3825                          s = " " + String.valueOf(mapId);                          s = " " + String.valueOf(mapId);
3826                  }                  }
3827                  out.writeLine("SET CHANNEL MIDI_INSTRUMENT_MAP " + samplerChn + s);  
3828                  if(getPrintOnlyMode()) return;                  retrieveIndex("SET CHANNEL MIDI_INSTRUMENT_MAP " + samplerChn + s);
                   
                 ResultSet rs = getEmptyResultSet();  
3829          }          }
3830                    
3831          /**          /**
# Line 3471  public class Client { Line 3842  public class Client {
3842           */           */
3843          public synchronized void          public synchronized void
3844          setChannelVolume(int samplerChn, float volume)          setChannelVolume(int samplerChn, float volume)
3845                                  throws IOException, LscpException, LSException {                                  throws IOException, LscpException, LSException
3846                    { retrieveIndex("SET CHANNEL VOLUME " + samplerChn + ' ' + volume); }
                 verifyConnection();  
                 out.writeLine("SET CHANNEL VOLUME " + samplerChn + ' ' + volume);  
                 if(getPrintOnlyMode()) return;  
                   
                 ResultSet rs = getEmptyResultSet();  
         }  
3847                    
3848          /**          /**
3849           * Mute/unmute the specified sampler channel.           * Mute/unmute the specified sampler channel.
# Line 3495  public class Client { Line 3860  public class Client {
3860           */           */
3861          public synchronized void          public synchronized void
3862          setChannelMute(int samplerChn, boolean mute)          setChannelMute(int samplerChn, boolean mute)
3863                                  throws IOException, LscpException, LSException {                                  throws IOException, LscpException, LSException
3864                    { retrieveIndex("SET CHANNEL MUTE " + samplerChn + ' ' + (mute ? 1 : 0)); }
                 verifyConnection();  
                 out.writeLine("SET CHANNEL MUTE " + samplerChn + ' ' + (mute ? 1 : 0));  
                 if(getPrintOnlyMode()) return;  
                   
                 ResultSet rs = getEmptyResultSet();  
         }  
3865                    
3866          /**          /**
3867           * Solo/unsolo the specified sampler channel.           * Solo/unsolo the specified sampler channel.
# Line 3519  public class Client { Line 3878  public class Client {
3878           */           */
3879          public synchronized void          public synchronized void
3880          setChannelSolo(int samplerChn, boolean solo)          setChannelSolo(int samplerChn, boolean solo)
3881                                  throws IOException, LscpException, LSException {                                  throws IOException, LscpException, LSException
3882                    { retrieveIndex("SET CHANNEL SOLO " + samplerChn + ' ' + (solo ? 1 : 0)); }
                 verifyConnection();  
                 out.writeLine("SET CHANNEL SOLO " + samplerChn + ' ' + (solo ? 1 : 0));  
                 if(getPrintOnlyMode()) return;  
                   
                 ResultSet rs = getEmptyResultSet();  
         }  
3883                    
3884          /**          /**
3885           * Creates an additional effect send on the specified sampler channel.           * Creates an additional effect send on the specified sampler channel.
# Line 3559  public class Client { Line 3912  public class Client {
3912           */           */
3913          public synchronized int          public synchronized int
3914          createFxSend(int channel, int midiCtrl, String name)          createFxSend(int channel, int midiCtrl, String name)
3915                          throws IOException, LSException, LscpException {                          throws IOException, LSException, LscpException
3916                            {
                 verifyConnection();  
3917                  String s = String.valueOf(channel) + " " + String.valueOf(midiCtrl);                  String s = String.valueOf(channel) + " " + String.valueOf(midiCtrl);
3918                  if(name != null) s += " '" + toEscapedString(name) + "'";                  if(name != null) s += " '" + toEscapedText(name) + "'";
3919                  out.writeLine("CREATE FX_SEND " + s);  
3920                  if(getPrintOnlyMode()) return -1;                  return retrieveIndex("CREATE FX_SEND " + s);
                   
                 ResultSet rs = getEmptyResultSet();  
                   
                 return rs.getIndex();  
3921          }          }
3922                    
3923          /**          /**
# Line 3583  public class Client { Line 3931  public class Client {
3931           */           */
3932          public synchronized void          public synchronized void
3933          destroyFxSend(int channel, int fxSend)          destroyFxSend(int channel, int fxSend)
3934                          throws IOException, LSException, LscpException {                          throws IOException, LSException, LscpException
3935                            {
                 verifyConnection();  
3936                  String s = String.valueOf(channel) + " " + String.valueOf(fxSend);                  String s = String.valueOf(channel) + " " + String.valueOf(fxSend);
3937                  out.writeLine("DESTROY FX_SEND " + s);                  retrieveIndex("DESTROY FX_SEND " + s);
                 if(getPrintOnlyMode()) return;  
                   
                 ResultSet rs = getEmptyResultSet();  
3938          }          }
3939                    
3940          /**          /**
# Line 3602  public class Client { Line 3946  public class Client {
3946           * @throws LSException If some other error occurs.           * @throws LSException If some other error occurs.
3947           */           */
3948          public synchronized int          public synchronized int
3949          getFxSoundCount(int channel) throws IOException, LscpException, LSException {          getFxSendCount(int channel) throws IOException, LscpException, LSException {
3950                  verifyConnection();                  return retrieveInt("GET FX_SENDS " + String.valueOf(channel));
                 out.writeLine("GET FX_SENDS " + String.valueOf(channel));  
                 if(getPrintOnlyMode()) return -1;  
                   
                 String s = getSingleLineResultSet().getResult();  
                 return parseInt(s);  
3951          }          }
3952                    
3953          /**          /**
# Line 3648  public class Client { Line 3987  public class Client {
3987           */           */
3988          public synchronized Integer[]          public synchronized Integer[]
3989          getFxSendIDs(int channel) throws IOException, LscpException, LSException {          getFxSendIDs(int channel) throws IOException, LscpException, LSException {
3990                  verifyConnection();                  return getIntegerList("LIST FX_SENDS " + channel);
                 out.writeLine("LIST FX_SENDS " + channel);  
                 if(getPrintOnlyMode()) return null;  
                   
                 return parseIntList(getSingleLineResultSet().getResult());  
3991          }          }
3992                    
3993          /**          /**
# Line 3667  public class Client { Line 4002  public class Client {
4002           */           */
4003          public synchronized FxSend          public synchronized FxSend
4004          getFxSendInfo(int channel, int fxSend) throws IOException, LscpException, LSException {          getFxSendInfo(int channel, int fxSend) throws IOException, LscpException, LSException {
4005                  verifyConnection();                  FxSend fxs = new FxSend();
4006                  String s = String.valueOf(channel) + " " + String.valueOf(fxSend);                  String s = String.valueOf(channel) + " " + String.valueOf(fxSend);
4007                  out.writeLine("GET FX_SEND INFO " + s);                  if(!retrieveInfo("GET FX_SEND INFO " + s, fxs)) return null;
                 if(getPrintOnlyMode()) return null;  
                   
                 ResultSet rs = getMultiLineResultSet();  
                 FxSend fxs = new FxSend(rs.getMultiLineResult());  
4008                  fxs.setFxSendId(fxSend);                  fxs.setFxSendId(fxSend);
4009                                    
4010                  return fxs;                  return fxs;
# Line 3691  public class Client { Line 4022  public class Client {
4022           */           */
4023          public synchronized void          public synchronized void
4024          setFxSendName(int channel, int fxSend, String name)          setFxSendName(int channel, int fxSend, String name)
4025                                  throws IOException, LscpException, LSException {                                  throws IOException, LscpException, LSException
4026                            {
4027                  verifyConnection();                  String args = " " + channel + " " + fxSend + " '" + toEscapedText(name) + "'";
4028                  String args = " " + channel + " " + fxSend + " '" + toEscapedString(name) + "'";                  retrieveIndex("SET FX_SEND NAME" + args);
                 out.writeLine("SET FX_SEND NAME" + args);  
                 if(getPrintOnlyMode()) return;  
                   
                 ResultSet rs = getEmptyResultSet();  
4029          }          }
4030                    
4031          /**          /**
# Line 3721  public class Client { Line 4048  public class Client {
4048           */           */
4049          public synchronized void          public synchronized void
4050          setFxSendAudioOutputChannel(int channel, int fxSend, int audioSrc, int audioDst)          setFxSendAudioOutputChannel(int channel, int fxSend, int audioSrc, int audioDst)
4051                                  throws IOException, LscpException, LSException {                                  throws IOException, LscpException, LSException
4052                            {
                 verifyConnection();  
4053                  String args = " " + channel + " " + fxSend + " " + audioSrc + " " + audioDst;                  String args = " " + channel + " " + fxSend + " " + audioSrc + " " + audioDst;
4054                  out.writeLine("SET FX_SEND AUDIO_OUTPUT_CHANNEL" + args);                  retrieveIndex("SET FX_SEND AUDIO_OUTPUT_CHANNEL" + args);
4055                  if(getPrintOnlyMode()) return;          }
4056                    
4057                  ResultSet rs = getEmptyResultSet();          /**
4058             * Assign a destination effect to an effect send.
4059             * @param channel The sampler channel number.
4060             * @param fxSend The numerical ID of the effect send entity.
4061             * @param fxChainId The numerical ID of the destination effect chain.
4062             * @param chainPos The exact effect chain position in the effect
4063             * chain which hosts the actual destination effect.
4064             * @throws IOException If some I/O error occurs.
4065             * @throws LscpException If LSCP protocol corruption occurs.
4066             * @throws LSException If
4067             * <ul>
4068             * <li><code>channel</code> is not a valid channel number;
4069             * <li><code>fxSend</code> is not a valid effect send ID;
4070             * <li><code>fxChainId</code> is not a valid effect chain ID;
4071             * <li><code>chainPos</code> is out of bounds;
4072             * <li>There is no engine assigned yet to the specified sampler channel;
4073             * <li>There is no audio output device connected to the specified sampler channel.
4074             * </ul>
4075             */
4076            public synchronized void
4077            setFxSendEffect(int channel, int fxSend, int fxChainId, int chainPos)
4078                                    throws IOException, LscpException, LSException
4079            {
4080                    String args = " " + channel + " " + fxSend + " " + fxChainId + " " + chainPos;
4081                    retrieveIndex("SET FX_SEND EFFECT" + args);
4082            }
4083    
4084            /**
4085             * Removes destination effect from an effect send.
4086             * @param channel The sampler channel number.
4087             * @param fxSend The numerical ID of the effect send entity.
4088             * @throws IOException If some I/O error occurs.
4089             * @throws LscpException If LSCP protocol corruption occurs.
4090             * @throws LSException If other error occurs.
4091             */
4092            public synchronized void
4093            removeFxSendEffect(int channel, int fxSend) throws IOException, LscpException, LSException {
4094                    String args = " " + channel + " " + fxSend;
4095                    retrieveIndex("REMOVE FX_SEND EFFECT" + args);
4096          }          }
4097                    
4098          /**          /**
# Line 3749  public class Client { Line 4113  public class Client {
4113           */           */
4114          public synchronized void          public synchronized void
4115          setFxSendMidiController(int channel, int fxSend, int midiCtrl)          setFxSendMidiController(int channel, int fxSend, int midiCtrl)
4116                                  throws IOException, LscpException, LSException {                                  throws IOException, LscpException, LSException
4117                            {
                 verifyConnection();  
4118                  String args = " " + channel + " " + fxSend + " " + midiCtrl;                  String args = " " + channel + " " + fxSend + " " + midiCtrl;
4119                  out.writeLine("SET FX_SEND MIDI_CONTROLLER" + args);                  retrieveIndex("SET FX_SEND MIDI_CONTROLLER" + args);
                 if(getPrintOnlyMode()) return;  
                   
                 ResultSet rs = getEmptyResultSet();  
4120          }          }
4121                    
4122          /**          /**
# Line 3772  public class Client { Line 4132  public class Client {
4132           */           */
4133          public synchronized void          public synchronized void
4134          setFxSendLevel(int channel, int fxSend, float volume)          setFxSendLevel(int channel, int fxSend, float volume)
4135                                  throws IOException, LscpException, LSException {                                  throws IOException, LscpException, LSException
4136                            {
                 verifyConnection();  
4137                  String args = " " + channel + " " + fxSend + " " + String.valueOf(volume);                  String args = " " + channel + " " + fxSend + " " + String.valueOf(volume);
4138                  out.writeLine("SET FX_SEND LEVEL" + args);                  retrieveIndex("SET FX_SEND LEVEL" + args);
4139                  if(getPrintOnlyMode()) return;          }
4140                    
4141                  ResultSet rs = getEmptyResultSet();  
4142            /**
4143             * Gets the current amount of internal effects available to the sampler.
4144             * @return The current amount of internal effects available to the sampler.
4145             * @throws IOException If some I/O error occurs.
4146             * @throws LscpException If LSCP protocol corruption occurs.
4147             * @throws LSException If some other error occurs.
4148             */
4149            public synchronized int
4150            getEffectCount() throws IOException, LscpException, LSException
4151            { return retrieveInt("GET AVAILABLE_EFFECTS"); }
4152    
4153            /**
4154             * Gets the list of internal effects available to the sampler.
4155             * Note that the set of available internal effects can change at runtime.
4156             * @return An <code>Effect</code> array providing the current list of internal effects.
4157             * @throws IOException If some I/O error occurs.
4158             * @throws LscpException If LSCP protocol corruption occurs.
4159             */
4160            public synchronized Effect[]
4161            getEffects() throws IOException, LscpException, LSException {
4162                    Integer[] idS = getEffectIDs();
4163                    if(getPrintOnlyMode()) return null;
4164    
4165                    Effect[] effects = new Effect[idS.length];
4166    
4167                    for(int i = 0; i < effects.length; i++)
4168                            effects[i] = getEffectInfo(idS[i]);
4169    
4170                    return effects;
4171            }
4172    
4173            /**
4174             * Retrieves the list of available internal effects.
4175             * Note that the set of available internal effects can change at runtime.
4176             * @return An <code>Integer</code> array providing
4177             * the numerical IDs of all available internal effects.
4178             * @throws IOException If some I/O error occurs.
4179             * @throws LscpException If LSCP protocol corruption occurs.
4180             */
4181            public synchronized Integer[]
4182            getEffectIDs() throws IOException, LscpException, LSException
4183            { return getIntegerList("LIST AVAILABLE_EFFECTS"); }
4184    
4185            /**
4186             * Gets general informations about the specified effect.
4187             * @param effect The numerical ID of the effect entity.
4188             * @return <code>Effect</code> instance containing
4189             * general informations about the specified effect.
4190             * @throws IOException If an I/O error occurs.
4191             * @throws LscpException If LSCP protocol corruption occurs.
4192             * @throws LSException If the effect ID is invalid.
4193             */
4194            public synchronized Effect
4195            getEffectInfo(int effect) throws IOException, LscpException, LSException {
4196                    Effect e = new Effect();
4197                    if(!retrieveInfo("GET EFFECT INFO " + effect, e)) return null;
4198                    e.setEffectId(effect);
4199    
4200                    return e;
4201            }
4202    
4203            /**
4204             * Creates an instance of the desired effect.
4205             * @param id The unique ID of the effect.
4206             * @return The unique ID of the newly created effect instance.
4207             * @throws IOException If some I/O error occurs.
4208             * @throws LSException If the creation of the effect instance failed.
4209             * @throws LscpException If LSCP protocol corruption occurs.
4210             * @see #getEffectIDs
4211             * @see #getEffectInfo
4212             * @see #destroyEffectInstance
4213             */
4214            public synchronized int
4215            createEffectInstanceById(int id) throws IOException, LSException, LscpException
4216            { return retrieveIndex("CREATE EFFECT_INSTANCE " + String.valueOf(id)); }
4217    
4218            /**
4219             * Creates an instance of the desired effect.
4220             * @return The unique ID of the newly created effect instance.
4221             * @throws IOException If some I/O error occurs.
4222             * @throws LSException If the creation of the effect instance failed.
4223             * @throws LscpException If LSCP protocol corruption occurs.
4224             * @see #getEffectInfo
4225             * @see #destroyEffectInstance
4226             */
4227            public synchronized int
4228            createEffectInstance(Effect effect) throws IOException, LSException, LscpException
4229            { return createEffectInstanceById(effect.getEffectId()); }
4230    
4231            /**
4232             * Creates an instance of the desired effect.
4233             * @return The unique ID of the newly created effect instance.
4234             * @throws IOException If some I/O error occurs.
4235             * @throws LSException If the creation of the effect instance failed.
4236             * @throws LscpException If LSCP protocol corruption occurs.
4237             * @see #getEffectInfo
4238             * @see #destroyEffectInstance
4239             */
4240            public synchronized int
4241            createEffectInstance(String system, String module, String name)
4242                            throws IOException, LSException, LscpException
4243            {
4244                    String s = system + " '" + toEscapedText(module) + "' '" + toEscapedText(name) + "'";
4245                    return retrieveIndex("CREATE EFFECT_INSTANCE " + s);
4246            }
4247    
4248            /**
4249             * Destroys the specified unused effect instance.
4250             * @param instanceId The numerical ID of the effect instance.
4251             * @throws LscpException If LSCP protocol corruption occurs.
4252             * @throws LSException If some other error occurs.
4253             * @see #createEffectInstance
4254             */
4255            public synchronized void
4256            destroyEffectInstance(int instanceId) throws IOException, LSException, LscpException
4257            { retrieveIndex("DESTROY EFFECT_INSTANCE " + String.valueOf(instanceId)); }
4258            /**
4259             * Gets the current amount of effect instances available to the sampler.
4260             * @return The current amount of effect instances available to the sampler.
4261             * @throws IOException If some I/O error occurs.
4262             * @throws LscpException If LSCP protocol corruption occurs.
4263             * @throws LSException If some other error occurs.
4264             */
4265            public synchronized int
4266            getEffectInstanceCount() throws IOException, LscpException, LSException
4267            { return retrieveInt("GET EFFECT_INSTANCES"); }
4268    
4269            /**
4270             * Gets the current list of effect instances.
4271             * @return An <code>EffectInstanceInfo</code> array
4272             * providing the current list of effect instances.
4273             * @throws IOException If some I/O error occurs.
4274             * @throws LscpException If LSCP protocol corruption occurs.
4275             */
4276            public synchronized EffectInstanceInfo[]
4277            getEffectInstances() throws IOException, LscpException, LSException {
4278                    Integer[] idS = getEffectInscanceIDs();
4279                    if(getPrintOnlyMode()) return null;
4280    
4281                    EffectInstanceInfo[] eis = new EffectInstanceInfo[idS.length];
4282    
4283                    for(int i = 0; i < eis.length; i++)
4284                            eis[i] = getEffectInstanceInfo(idS[i]);
4285    
4286                    return eis;
4287            }
4288    
4289            /**
4290             * Retrieves the current list of effect instances.
4291             * @return An <code>Integer</code> array providing
4292             * the numerical IDs of all available effect instances.
4293             * @throws IOException If some I/O error occurs.
4294             * @throws LscpException If LSCP protocol corruption occurs.
4295             */
4296            public synchronized Integer[]
4297            getEffectInscanceIDs() throws IOException, LscpException, LSException
4298            { return getIntegerList("LIST EFFECT_INSTANCES"); }
4299    
4300            /**
4301             * Gets the current informations about the specified effect instance.
4302             * @param id The numerical ID of the effect instance.
4303             * @return <code>EffectInstanceInfo</code> object containing
4304             * the current informations about the specified effect instance.
4305             * @throws IOException If an I/O error occurs.
4306             * @throws LscpException If LSCP protocol corruption occurs.
4307             * @throws LSException If the effect instance ID is invalid.
4308             */
4309            public synchronized EffectInstanceInfo
4310            getEffectInstanceInfo(int id) throws IOException, LscpException, LSException {
4311                    EffectInstanceInfo ei = new EffectInstanceInfo();
4312                    if(!retrieveInfo("GET EFFECT_INSTANCE INFO " + id, ei)) return null;
4313                    ei.setInstanceId(id);
4314    
4315                    for(int i = 0; i < ei.getParameterCount(); i++) {
4316                            ei.addParameter(getEffectInstanceParameterInfo(id, i));
4317                    }
4318    
4319                    return ei;
4320            }
4321    
4322            /**
4323             * Gets information about the specified effect parameter.
4324             * @param id The numerical ID of the effect instance.
4325             * @param parameter The parameter index.
4326             * @return <code>EffectParameter</code> object containing
4327             * information about the specified effect parameter.
4328             * Note that only the following fields are used - description,
4329             * value, rangeMin, rangeMax, possibilities and default.
4330             * @throws IOException If an I/O error occurs.
4331             * @throws LscpException If LSCP protocol corruption occurs.
4332             * @throws LSException If the effect instance ID or the parameter index is invalid.
4333             */
4334            public synchronized EffectParameter
4335            getEffectInstanceParameterInfo(int instanceId, int parameter)
4336                                    throws IOException, LscpException, LSException
4337            {
4338                    EffectParameter prm = new EffectParameter(instanceId, parameter);
4339                    String s = String.valueOf(instanceId) + " " + String.valueOf(parameter);
4340                    if(!retrieveInfo("GET EFFECT_INSTANCE_INPUT_CONTROL INFO " + s, prm)) return null;
4341    
4342                    return prm;
4343            }
4344    
4345            /**
4346             * Alters the current value of an effect parameter.
4347             * @param instanceId The numerical ID of the effect instance.
4348             * @param prmIndex The index of the parameter to alter.
4349             * @param value The new value for this parameter.
4350             * @throws IOException If some I/O error occurs.
4351             * @throws LscpException If LSCP protocol corruption occurs.
4352             * @throws LSException If
4353             * <ul>
4354             * <li>There is no effect instance with numerical ID <code>instanceId</code>;
4355             * <li>There parameter index is invalid;
4356             * <li>The new value is out of range;
4357             * </ul>
4358             *
4359             * @see #getEffectInstanceInfo
4360             * @see #getEffectInstanceParameterInfo
4361             */
4362            public synchronized void
4363            setEffectInstanceParameter(int instanceId, int prmIndex, float value)
4364                                            throws IOException, LscpException, LSException
4365            {
4366                    String s = " " + instanceId + " " + prmIndex + " " + value;
4367                    retrieveIndex("SET EFFECT_INSTANCE_INPUT_CONTROL VALUE" + s);
4368            }
4369            /**
4370             * Gets the current amount of send effect chains on the specified audio output device.
4371             * @param audioDeviceId numerical ID of the audio output device.
4372             * @return The current amount of send effect chains or -1 if in "print only" mode.
4373             * @throws IOException If some I/O error occurs.
4374             * @throws LscpException If LSCP protocol corruption occurs.
4375             * @throws LSException If some other error occurs.
4376             */
4377            public synchronized int
4378            getSendEffectChainCount(int audioDeviceId) throws IOException, LscpException, LSException
4379            { return retrieveInt("GET SEND_EFFECT_CHAINS " + audioDeviceId); }
4380    
4381            /**
4382             * Gets the current list of send effect chains on the specified audio output device.
4383             * @param audioDeviceId The numerical ID of the audio output device.
4384             * @return An <code>EffectInstanceInfo</code> array
4385             * providing the current list of effect instances.
4386             * @throws IOException If some I/O error occurs.
4387             * @throws LscpException If LSCP protocol corruption occurs.
4388             */
4389            public synchronized EffectChainInfo[]
4390            getSendEffectChains(int audioDeviceId) throws IOException, LscpException, LSException {
4391                    Integer[] idS = getSendEffectChainIDs(audioDeviceId);
4392                    if(getPrintOnlyMode()) return null;
4393    
4394                    EffectChainInfo[] ecs = new EffectChainInfo[idS.length];
4395    
4396                    for(int i = 0; i < ecs.length; i++) {
4397                            ecs[i] = getSendEffectChainInfo(audioDeviceId, idS[i]);
4398                            ecs[i].setChainId(idS[i]);
4399                    }
4400    
4401                    return ecs;
4402            }
4403    
4404            /**
4405             * Retrieves the current list of send effect
4406             * chains on the specified audio output device.
4407             * @param audioDeviceId The numerical ID of the audio output device.
4408             * @return An <code>Integer</code> array providing the numerical
4409             * IDs of all send effect chains on the specified audio output device.
4410             * @throws IOException If some I/O error occurs.
4411             * @throws LscpException If LSCP protocol corruption occurs.
4412             */
4413            public synchronized Integer[]
4414            getSendEffectChainIDs(int audioDeviceId) throws IOException, LscpException, LSException
4415            { return getIntegerList("LIST SEND_EFFECT_CHAINS " + audioDeviceId); }
4416    
4417            /**
4418             * Adds a send effect chain to the specified audio output device.
4419             * @param audioDeviceId The numerical ID of the audio output device.
4420             * @return The numerical ID of the new send effect chain.
4421             * @throws IOException If some I/O error occurs.
4422             * @throws LSException If the creation of the effect chain failed.
4423             * @throws LscpException If LSCP protocol corruption occurs.
4424             * @see #removeSendEffectChain
4425             * @see #getSendEffectChainInfo
4426             */
4427            public synchronized int
4428            addSendEffectChain(int audioDeviceId) throws IOException, LSException, LscpException
4429            { return retrieveIndex("ADD SEND_EFFECT_CHAIN " + audioDeviceId); }
4430    
4431            /**
4432             * Removes a send effect chain from an audio output device.
4433             * @param audioDeviceId The numerical ID of the audio output device.
4434             * @param chainId The numerical ID of the send effect chain to remove.
4435             * @throws LscpException If LSCP protocol corruption occurs.
4436             * @throws LSException If some other error occurs.
4437             * @see #addSendEffectChain
4438             */
4439            public synchronized void
4440            removeSendEffectChain(int audioDeviceId, int chainId) throws IOException, LSException, LscpException
4441            { retrieveIndex("REMOVE SEND_EFFECT_CHAIN " + audioDeviceId + " " + chainId); }
4442    
4443            /**
4444             * Gets the current information of a send effect chain.
4445             * @param audioDeviceId The numerical ID of the audio output device.
4446             * @param chainId The numerical ID of the send effect chain.
4447             * @return <code>EffectChainInfo</code> object containing
4448             * the current informations about the specified effect chain.
4449             * @throws IOException If an I/O error occurs.
4450             * @throws LscpException If LSCP protocol corruption occurs.
4451             * @throws LSException If the audio device ID or the effect chain ID is invalid.
4452             */
4453            public synchronized EffectChainInfo
4454            getSendEffectChainInfo(int audioDeviceId, int chainId)
4455                                    throws IOException, LscpException, LSException
4456            {
4457                    verifyConnection();
4458                    String str = " " + audioDeviceId + " " + chainId;
4459                    out.writeLine("GET SEND_EFFECT_CHAIN INFO" + str);
4460                    if(getPrintOnlyMode()) return null;
4461    
4462                    ResultSet rs = getMultiLineResultSet();
4463                    EffectChainInfo chain = null;
4464    
4465                    for(String s : rs.getMultiLineResult()) {
4466                            if(s.startsWith("EFFECT_SEQUENCE: ")) {
4467                                    s = s.substring("EFFECT_SEQUENCE: ".length());
4468                                    Integer[] eis = parseIntList(s);
4469                                    EffectInstanceInfo[] instances = new EffectInstanceInfo[eis.length];
4470                                    for(int i = 0; i < eis.length; i++) {
4471                                            instances[i] = getEffectInstanceInfo(eis[i]);
4472                                    }
4473                                    chain = new EffectChainInfo(instances);
4474                                    chain.setChainId(chainId);
4475                            }
4476                    }
4477    
4478                    return chain;
4479            }
4480    
4481            /**
4482             * Adds an unused effect instance to the end of a send effect chain.
4483             * @param audioDeviceId The numerical ID of the audio output device.
4484             * @param chainId The numerical ID of the send effect chain.
4485             * @param fxInstanceId The numerical ID of the effect instance to add.
4486             * @throws IOException If some I/O error occurs.
4487             * @throws LSException If invalid index is specified.
4488             * @throws LscpException If LSCP protocol corruption occurs.
4489             * @see #addSendEffectChain
4490             * @see #createEffectInstance
4491             */
4492            public synchronized void
4493            appendEffectInstance(int audioDeviceId, int chainId, int fxInstanceId)
4494                            throws IOException, LSException, LscpException
4495            {
4496                    String s = " " + audioDeviceId + " " + chainId + " " + fxInstanceId;
4497                    retrieveIndex("APPEND SEND_EFFECT_CHAIN EFFECT" + s);
4498            }
4499    
4500            /**
4501             * Adds an unused effect instance at a certain position of a send effect chain.
4502             * @param audioDeviceId The numerical ID of the audio output device.
4503             * @param chainId The numerical ID of the send effect chain.
4504             * @param pos The exact position in the effect chain where
4505             * the supplied effect shall be inserted to.
4506             * @param fxInstanceId The numerical ID of the effect instance to insert.
4507             * @throws IOException If some I/O error occurs.
4508             * @throws LSException If invalid index is specified.
4509             * @throws LscpException If LSCP protocol corruption occurs.
4510             * @see #addSendEffectChain
4511             * @see #createEffectInstance
4512             */
4513            public synchronized void
4514            insertEffectInstance(int audioDeviceId, int chainId, int pos, int fxInstanceId)
4515                            throws IOException, LSException, LscpException
4516            {
4517                    String s = " " + audioDeviceId + " " + chainId + " " + pos + " " + fxInstanceId;
4518                    retrieveIndex("INSERT SEND_EFFECT_CHAIN EFFECT" + s);
4519            }
4520    
4521            /**
4522             * Removes an effect instance from a certain position of a send effect chain.
4523             * @param audioDeviceId The numerical ID of the audio output device.
4524             * @param chainId The numerical ID of the send effect chain.
4525             * @param pos The exact position of the effect
4526             * instance to be removed from the effect chain.
4527             * @throws IOException If some I/O error occurs.
4528             * @throws LscpException If LSCP protocol corruption occurs.
4529             * @throws LSException If invalid index is specified.
4530             * @see #appendEffectInstance
4531             * @see #insertEffectInstance
4532             */
4533            public synchronized void
4534            removeEffectInstanceFromChain(int audioDeviceId, int chainId, int pos)
4535                            throws IOException, LSException, LscpException
4536            {
4537                    String s = " " + audioDeviceId + " " + chainId + " " + pos;
4538                    retrieveIndex("REMOVE SEND_EFFECT_CHAIN EFFECT" + s);
4539          }          }
4540                    
4541          /**          /**
# Line 3793  public class Client { Line 4549  public class Client {
4549           * @see #getSamplerChannels           * @see #getSamplerChannels
4550           */           */
4551          public synchronized void          public synchronized void
4552          editChannelInstrument(int samplerChn) throws IOException, LscpException, LSException {          editChannelInstrument(int samplerChn) throws IOException, LscpException, LSException
4553                  verifyConnection();          { retrieveIndex("EDIT CHANNEL INSTRUMENT " + samplerChn); }
4554                  out.writeLine("EDIT CHANNEL INSTRUMENT " + samplerChn);          
4555                  if(getPrintOnlyMode()) return;          /**
4556                             * Sends a MIDI event to this sampler channel.
4557                  ResultSet rs = getEmptyResultSet();           * @param samplerChn The sampler channel number.
4558             * @param type The type of MIDI message to send.
4559             * @throws IOException If some I/O error occurs.
4560             * @throws LscpException If LSCP protocol corruption occurs.
4561             * @throws LSException If <code>samplerChn</code> is not a valid channel number or if
4562             * there is no instrument loaded on the specified sampler channel.
4563             * @see #getSamplerChannels
4564             */
4565            public synchronized void
4566            sendChannelMidiData(int samplerChn, MidiDataEvent.Type type, int arg1, int arg2)
4567                                                    throws IOException, LscpException, LSException
4568            {
4569                    StringBuffer sb = new StringBuffer();
4570                    sb.append("SEND CHANNEL MIDI_DATA ");
4571                    sb.append(type).append(" ").append(samplerChn).append(" ");
4572                    sb.append(arg1).append(" ").append(arg2);
4573    
4574                    retrieveIndex(sb.toString());
4575          }          }
4576                    
4577            /**
4578             * Resets the specified sampler channel.
4579             *
4580             * @param samplerChn The sampler channel number.
4581             *
4582             * @throws IOException If some I/O error occurs.
4583             * @throws LscpException If LSCP protocol corruption occurs.
4584             * @throws LSException If <code>samplerChn</code> is not a valid channel number or if
4585             * there is no engine assigned yet to the specified sampler channel.
4586             * @see #getSamplerChannels
4587             */
4588            public synchronized void
4589            resetChannel(int samplerChn) throws IOException, LscpException, LSException
4590            { retrieveIndex("RESET CHANNEL " + samplerChn); }
4591            
4592                    
4593                    
4594          /**          /**
# Line 3811  public class Client { Line 4599  public class Client {
4599           * @throws LscpException If LSCP protocol corruption occurs.           * @throws LscpException If LSCP protocol corruption occurs.
4600           */           */
4601          public synchronized void          public synchronized void
4602          addDbDirectory(String dir) throws IOException, LSException, LscpException {          addDbDirectory(String dir) throws IOException, LSException, LscpException
4603                  verifyConnection();          { retrieveIndex("ADD DB_INSTRUMENT_DIRECTORY '" + conv(dir) + "'"); }
                 out.writeLine("ADD DB_INSTRUMENT_DIRECTORY '" + dir + "'");  
                 if(getPrintOnlyMode()) return;  
                   
                 ResultSet rs = getEmptyResultSet();  
         }  
4604                    
4605          /**          /**
4606           * Removes the specified directory from the instruments database.           * Removes the specified directory from the instruments database.
# Line 3828  public class Client { Line 4611  public class Client {
4611           * empty or if the removal of the directory failed.           * empty or if the removal of the directory failed.
4612           */           */
4613          public synchronized void          public synchronized void
4614          removeDbDirectory(String dir) throws IOException, LscpException, LSException {          removeDbDirectory(String dir) throws IOException, LscpException, LSException
4615                  removeDbDirectory(dir, false);          { removeDbDirectory(dir, false); }
         }  
4616                    
4617          /**          /**
4618           * Removes the specified directory from the instruments database.           * Removes the specified directory from the instruments database.
# Line 3843  public class Client { Line 4625  public class Client {
4625           */           */
4626          public synchronized void          public synchronized void
4627          removeDbDirectory(String dir, boolean force)          removeDbDirectory(String dir, boolean force)
4628                                  throws IOException, LscpException, LSException {                                  throws IOException, LscpException, LSException
4629                            {
                 verifyConnection();  
4630                  String s = "REMOVE DB_INSTRUMENT_DIRECTORY ";                  String s = "REMOVE DB_INSTRUMENT_DIRECTORY ";
4631                  if(force) s += "FORCE ";                  if(force) s += "FORCE ";
4632                  out.writeLine(s + "'" + dir + "'");                  retrieveIndex(s + "'" + conv(dir) + "'");
                 if(getPrintOnlyMode()) return;  
                   
                 ResultSet rs = getEmptyResultSet();  
4633          }          }
4634                    
4635          /**          /**
# Line 3871  public class Client { Line 4649  public class Client {
4649                  String cmd = "REMOVE DB_INSTRUMENT_DIRECTORY ";                  String cmd = "REMOVE DB_INSTRUMENT_DIRECTORY ";
4650                  if(force) cmd += "FORCE ";                  if(force) cmd += "FORCE ";
4651                                    
4652                  for(String s : dirs) out.writeLine(cmd + "'" + s + "'");                  for(String s : dirs) out.writeLine(cmd + "'" + conv(s) + "'");
4653                                    
4654                  if(getPrintOnlyMode()) return;                  if(getPrintOnlyMode()) return;
4655                                    
# Line 3909  public class Client { Line 4687  public class Client {
4687                  String s;                  String s;
4688                  if(recursive) s = "GET DB_INSTRUMENT_DIRECTORIES RECURSIVE '";                  if(recursive) s = "GET DB_INSTRUMENT_DIRECTORIES RECURSIVE '";
4689                  else s = "GET DB_INSTRUMENT_DIRECTORIES '";                  else s = "GET DB_INSTRUMENT_DIRECTORIES '";
4690                  out.writeLine(s + dir + "'");                  out.writeLine(s + conv(dir) + "'");
4691                  if(getPrintOnlyMode()) return -1;                  if(getPrintOnlyMode()) return -1;
4692                                    
4693                  s = getSingleLineResultSet().getResult();                  s = getSingleLineResultSet().getResult();
# Line 3928  public class Client { Line 4706  public class Client {
4706          public synchronized String[]          public synchronized String[]
4707          getDbDirectoryNames(String dir) throws IOException, LscpException, LSException {          getDbDirectoryNames(String dir) throws IOException, LscpException, LSException {
4708                  verifyConnection();                  verifyConnection();
4709                  out.writeLine("LIST DB_INSTRUMENT_DIRECTORIES '" + dir + "'");                  out.writeLine("LIST DB_INSTRUMENT_DIRECTORIES '" + conv(dir) + "'");
4710                  if(getPrintOnlyMode()) return null;                  if(getPrintOnlyMode()) return null;
4711                                    
4712                  String[] names = parseEscapedStringList(getSingleLineResultSet().getResult());                  String[] names = parseEscapedStringList(getSingleLineResultSet().getResult());
# Line 3949  public class Client { Line 4727  public class Client {
4727           */           */
4728          public synchronized DbDirectoryInfo          public synchronized DbDirectoryInfo
4729          getDbDirectoryInfo(String dir) throws IOException, LscpException, LSException {          getDbDirectoryInfo(String dir) throws IOException, LscpException, LSException {
4730                  verifyConnection();                  DbDirectoryInfo info = new DbDirectoryInfo();
4731                  out.writeLine("GET DB_INSTRUMENT_DIRECTORY INFO '" + dir + "'");                  if(!retrieveInfo("GET DB_INSTRUMENT_DIRECTORY INFO '" + conv(dir) + "'", info)) return null;
4732                  if(getPrintOnlyMode()) return null;  
                   
                 ResultSet rs = getMultiLineResultSet();  
                 DbDirectoryInfo info = new DbDirectoryInfo(rs.getMultiLineResult());  
4733                  if(dir.equals("/")) {                  if(dir.equals("/")) {
4734                          info.setName("/");                          info.setName("/");
4735                  } else {                  } else {
# Line 3983  public class Client { Line 4758  public class Client {
4758                  if(!hasEndingFileSeparator(dir)) dir += "/";                  if(!hasEndingFileSeparator(dir)) dir += "/";
4759                  DbDirectoryInfo[] infoS = new DbDirectoryInfo[dirS.length];                  DbDirectoryInfo[] infoS = new DbDirectoryInfo[dirS.length];
4760                  for(int i = 0; i < dirS.length; i++) {                  for(int i = 0; i < dirS.length; i++) {
4761                          infoS[i] = getDbDirectoryInfo(dir + toEscapedFileName(dirS[i]));                          infoS[i] = getDbDirectoryInfo(conv(dir) + toEscapedFsEntry(dirS[i]));
4762                  }                  }
4763                  return infoS;                  return infoS;
4764          }          }
# Line 3999  public class Client { Line 4774  public class Client {
4774           *           *
4775          public synchronized DbDirectoryInfo[]          public synchronized DbDirectoryInfo[]
4776          getDbDirectories(String dir) throws IOException, LscpException, LSException {          getDbDirectories(String dir) throws IOException, LscpException, LSException {
4777                  String[] dirS = getDbDirectoryNames(dir);                  String[] dirS = getDbDirectoryNames(conv(dir));
4778                  if(dirS.length == 0) return new DbDirectoryInfo[0];                  if(dirS.length == 0) return new DbDirectoryInfo[0];
4779                                    
4780                  if(dir.charAt(dir.length() - 1) != '/') dir += "/";                  if(dir.charAt(dir.length() - 1) != '/') dir += "/"; // FIXME:
4781                                    
4782                  for(int i = 0; i < dirS.length; i++) {                  for(int i = 0; i < dirS.length; i++) {
4783                          out.writeLine("GET DB_INSTRUMENT_DIRECTORY INFO '" + dir + dirS[i] + "'");                          out.writeLine("GET DB_INSTRUMENT_DIRECTORY INFO '" + conv(dir + dirS[i]) + "'");
4784                  }                  }
4785                                    
4786                  if(getPrintOnlyMode()) return null;                  if(getPrintOnlyMode()) return null;
# Line 4048  public class Client { Line 4823  public class Client {
4823           */           */
4824          public synchronized void          public synchronized void
4825          renameDbDirectory(String dir, String name) throws IOException, LSException, LscpException {          renameDbDirectory(String dir, String name) throws IOException, LSException, LscpException {
4826                  verifyConnection();                  name = toEscapedText(name);
4827                  name = toEscapedString(name);                  retrieveIndex("SET DB_INSTRUMENT_DIRECTORY NAME '" + conv(dir) + "' '" + conv(name) + "'");
                 out.writeLine("SET DB_INSTRUMENT_DIRECTORY NAME '" + dir + "' '" + name + "'");  
                 if(getPrintOnlyMode()) return;  
                   
                 ResultSet rs = getEmptyResultSet();  
4828          }          }
4829                    
4830          /**          /**
# Line 4065  public class Client { Line 4836  public class Client {
4836           * @throws LscpException If LSCP protocol corruption occurs.           * @throws LscpException If LSCP protocol corruption occurs.
4837           */           */
4838          public synchronized void          public synchronized void
4839          moveDbDirectory(String dir, String dst) throws IOException, LSException, LscpException {          moveDbDirectory(String dir, String dst) throws IOException, LSException, LscpException
4840                  verifyConnection();          { retrieveIndex("MOVE DB_INSTRUMENT_DIRECTORY '" + conv(dir) + "' '" + conv(dst) + "'"); }
                 out.writeLine("MOVE DB_INSTRUMENT_DIRECTORY '" + dir + "' '" + dst + "'");  
                 if(getPrintOnlyMode()) return;  
                   
                 ResultSet rs = getEmptyResultSet();  
         }  
4841                    
4842          /**          /**
4843           * Moves the specified directories into the specified location.           * Moves the specified directories into the specified location.
# Line 4085  public class Client { Line 4851  public class Client {
4851          moveDbDirectories(String dirs[], String dst) throws IOException, LSException, LscpException {          moveDbDirectories(String dirs[], String dst) throws IOException, LSException, LscpException {
4852                  verifyConnection();                  verifyConnection();
4853                  for(String s : dirs) {                  for(String s : dirs) {
4854                          out.writeLine("MOVE DB_INSTRUMENT_DIRECTORY '" + s + "' '" + dst + "'");                          out.writeLine("MOVE DB_INSTRUMENT_DIRECTORY '" + conv(s) + "' '" + conv(dst) + "'");
4855                  }                  }
4856                  if(getPrintOnlyMode()) return;                  if(getPrintOnlyMode()) return;
4857                                    
# Line 4101  public class Client { Line 4867  public class Client {
4867           * @throws LscpException If LSCP protocol corruption occurs.           * @throws LscpException If LSCP protocol corruption occurs.
4868           */           */
4869          public synchronized void          public synchronized void
4870          copyDbDirectory(String dir, String dst) throws IOException, LSException, LscpException {          copyDbDirectory(String dir, String dst) throws IOException, LSException, LscpException
4871                  verifyConnection();          { retrieveIndex("COPY DB_INSTRUMENT_DIRECTORY '" + conv(dir) + "' '" + conv(dst) + "'"); }
                 out.writeLine("COPY DB_INSTRUMENT_DIRECTORY '" + dir + "' '" + dst + "'");  
                 if(getPrintOnlyMode()) return;  
                   
                 ResultSet rs = getEmptyResultSet();  
         }  
4872                    
4873          /**          /**
4874           * Copies the specified directories into the specified location.           * Copies the specified directories into the specified location.
# Line 4121  public class Client { Line 4882  public class Client {
4882          copyDbDirectories(String[] dirs, String dst) throws IOException, LSException, LscpException {          copyDbDirectories(String[] dirs, String dst) throws IOException, LSException, LscpException {
4883                  verifyConnection();                  verifyConnection();
4884                  for(String s : dirs) {                  for(String s : dirs) {
4885                          out.writeLine("COPY DB_INSTRUMENT_DIRECTORY '" + s + "' '" + dst + "'");                          out.writeLine("COPY DB_INSTRUMENT_DIRECTORY '" + conv(s) + "' '" + conv(dst) + "'");
4886                  }                  }
4887                  if(getPrintOnlyMode()) return;                  if(getPrintOnlyMode()) return;
4888                                    
# Line 4138  public class Client { Line 4899  public class Client {
4899           */           */
4900          public synchronized void          public synchronized void
4901          setDbDirectoryDescription(String dir, String desc)          setDbDirectoryDescription(String dir, String desc)
4902                                  throws IOException, LSException, LscpException {                                  throws IOException, LSException, LscpException
4903                            {
                 verifyConnection();  
4904                  String s = "SET DB_INSTRUMENT_DIRECTORY DESCRIPTION '";                  String s = "SET DB_INSTRUMENT_DIRECTORY DESCRIPTION '";
4905                  out.writeLine(s + dir + "' '" + toEscapedString(desc) + "'");                  retrieveIndex(s + conv(dir) + "' '" + toEscapedText(desc) + "'");
                 if(getPrintOnlyMode()) return;  
                   
                 ResultSet rs = getEmptyResultSet();  
4906          }          }
4907                    
4908          public static enum ScanMode {          public static enum ScanMode {
# Line 4186  public class Client { Line 4943  public class Client {
4943           */           */
4944          public synchronized int          public synchronized int
4945          addDbInstrument(String dbDir, String filePath, int instrIndex, boolean background)          addDbInstrument(String dbDir, String filePath, int instrIndex, boolean background)
4946                                          throws IOException, LSException, LscpException {                                          throws IOException, LSException, LscpException
4947                            {
                 verifyConnection();  
4948                  String s = "ADD DB_INSTRUMENTS";                  String s = "ADD DB_INSTRUMENTS";
4949                  if(background) s += " NON_MODAL";                  if(background) s += " NON_MODAL";
4950                  s += " '" + dbDir + "' '" + filePath + "' ";                  s += " '" + conv(dbDir) + "' '" + conv(filePath) + "' ";
4951                  out.writeLine(s + String.valueOf(instrIndex));                  return retrieveIndex(s + String.valueOf(instrIndex));
                 if(getPrintOnlyMode()) return -1;  
                   
                 ResultSet rs = getEmptyResultSet();  
                 return rs.getIndex();  
4952          }          }
4953                    
4954          /**          /**
# Line 4233  public class Client { Line 4985  public class Client {
4985           */           */
4986          public synchronized int          public synchronized int
4987          addDbInstruments(String dbDir, String filePath, boolean background)          addDbInstruments(String dbDir, String filePath, boolean background)
4988                                          throws IOException, LSException, LscpException {                                          throws IOException, LSException, LscpException
4989                            {
                 verifyConnection();  
4990                  String s = "ADD DB_INSTRUMENTS";                  String s = "ADD DB_INSTRUMENTS";
4991                  if(background) s += " NON_MODAL";                  if(background) s += " NON_MODAL";
4992                  out.writeLine(s + " '" + dbDir + "' '" + filePath + "'");                  return retrieveIndex(s + " '" + conv(dbDir) + "' '" + conv(filePath) + "'");
                 if(getPrintOnlyMode()) return -1;  
                   
                 ResultSet rs = getEmptyResultSet();  
                 return rs.getIndex();  
4993          }          }
4994                    
4995          /**          /**
# Line 4305  public class Client { Line 5052  public class Client {
5052          addDbInstruments(ScanMode mode, String dbDir, String fsDir, boolean background)          addDbInstruments(ScanMode mode, String dbDir, String fsDir, boolean background)
5053                                          throws IOException, LSException, LscpException {                                          throws IOException, LSException, LscpException {
5054                                    
5055                  verifyConnection();                  return addDbInstruments(mode, dbDir, fsDir, background, false);
5056            }
5057            
5058            /**
5059             * Adds the instruments in the specified file system directory
5060             * to the specified instruments database directory.
5061             * @param mode Determines the scanning mode. If RECURSIVE is
5062             * specified, all supported instruments in the specified file system
5063             * direcotry will be added to the specified instruments database
5064             * directory, including the instruments in subdirectories
5065             * of the supplied directory. If NON_RECURSIVE is specified,
5066             * the instruments in the subdirectories will not be processed.
5067             * If FLAT is specified, all supported instruments in the specified
5068             * file system direcotry will be added, including the instruments in
5069             * subdirectories of the supplied directory, but the respective
5070             * subdirectory structure will not be recreated in the instruments
5071             * database and all instruments will be added directly in the
5072             * specified database directory.
5073             * @param dbDir The absolute path name of the database directory
5074             * in which the supported instruments will be added.
5075             * @param fsDir The absolute path name of the file system directory.
5076             * @param background If <code>true</code>, the scan will be done
5077             * in background and this method may return before the job is finished.
5078             * @param insDir If <code>true</code> a drieectory is created for each
5079             * instrument file.
5080             * @return If <code>background</code> is <code>true</code>, the ID
5081             * of the scan job.
5082             * @throws IOException If some I/O error occurs.
5083             * @throws LSException If the operation failed.
5084             * @throws LscpException If LSCP protocol corruption occurs.
5085             * @see #addInstrumentsDbListener
5086             */
5087            public synchronized int
5088            addDbInstruments(ScanMode mode, String dbDir, String fsDir, boolean background, boolean insDir)
5089                                            throws IOException, LSException, LscpException
5090            {
5091                  StringBuffer sb = new StringBuffer("ADD DB_INSTRUMENTS");                  StringBuffer sb = new StringBuffer("ADD DB_INSTRUMENTS");
5092                  if(background) sb.append(" NON_MODAL");                  if(background) sb.append(" NON_MODAL");
5093                                    
# Line 4320  public class Client { Line 5102  public class Client {
5102                                  sb.append(" FLAT");                                  sb.append(" FLAT");
5103                                  break;                                  break;
5104                  }                  }
5105                    if(insDir)
5106                            sb.append(" FILE_AS_DIR");
5107                                    
5108                  sb.append(" '").append(dbDir).append("' '");                  sb.append(" '").append(conv(dbDir)).append("' '");
5109                  sb.append(fsDir).append("'");                  sb.append(conv(fsDir)).append("'");
5110                  out.writeLine(sb.toString());                  return retrieveIndex(sb.toString());
                 if(getPrintOnlyMode()) return -1;  
                   
                 ResultSet rs = getEmptyResultSet();  
                 return rs.getIndex();  
5111          }          }
5112            
5113          /**          /**
5114           * Removes the specified instrument from the instruments database.           * Removes the specified instrument from the instruments database.
5115           * @param instr The absolute path name of the instrument to remove.           * @param instr The absolute path name of the instrument to remove.
# Line 4338  public class Client { Line 5118  public class Client {
5118           * @throws LSException If the removing of the instrument failed.           * @throws LSException If the removing of the instrument failed.
5119           */           */
5120          public synchronized void          public synchronized void
5121          removeDbInstrument(String instr) throws IOException, LscpException, LSException {          removeDbInstrument(String instr) throws IOException, LscpException, LSException
5122                            { retrieveIndex("REMOVE DB_INSTRUMENT '" + conv(instr) + "'"); }
                 verifyConnection();  
                 out.writeLine("REMOVE DB_INSTRUMENT '" + instr + "'");  
                 if(getPrintOnlyMode()) return;  
                   
                 ResultSet rs = getEmptyResultSet();  
         }  
5123                    
5124          /**          /**
5125           * Removes the specified instruments from the instruments database.           * Removes the specified instruments from the instruments database.
# Line 4358  public class Client { Line 5132  public class Client {
5132          removeDbInstruments(String[] instrs) throws IOException, LscpException, LSException {          removeDbInstruments(String[] instrs) throws IOException, LscpException, LSException {
5133                  verifyConnection();                  verifyConnection();
5134                  for(String s : instrs) {                  for(String s : instrs) {
5135                          out.writeLine("REMOVE DB_INSTRUMENT '" + s + "'");                          out.writeLine("REMOVE DB_INSTRUMENT '" + conv(s) + "'");
5136                  }                  }
5137                  if(getPrintOnlyMode()) return;                  if(getPrintOnlyMode()) return;
5138                                    
# Line 4396  public class Client { Line 5170  public class Client {
5170                  String s;                  String s;
5171                  if(recursive) s = "GET DB_INSTRUMENTS RECURSIVE '";                  if(recursive) s = "GET DB_INSTRUMENTS RECURSIVE '";
5172                  else s = "GET DB_INSTRUMENTS '";                  else s = "GET DB_INSTRUMENTS '";
5173                  out.writeLine(s + dir + "'");                  out.writeLine(s + conv(dir) + "'");
5174                  if(getPrintOnlyMode()) return -1;                  if(getPrintOnlyMode()) return -1;
5175                                    
5176                  s = getSingleLineResultSet().getResult();                  s = getSingleLineResultSet().getResult();
# Line 4415  public class Client { Line 5189  public class Client {
5189          public synchronized String[]          public synchronized String[]
5190          getDbInstrumentNames(String dir) throws IOException, LscpException, LSException {          getDbInstrumentNames(String dir) throws IOException, LscpException, LSException {
5191                  verifyConnection();                  verifyConnection();
5192                  out.writeLine("LIST DB_INSTRUMENTS '" + dir + "'");                  out.writeLine("LIST DB_INSTRUMENTS '" + conv(dir) + "'");
5193                  if(getPrintOnlyMode()) return null;                  if(getPrintOnlyMode()) return null;
5194                                    
5195                  String[] names = parseEscapedStringList(getSingleLineResultSet().getResult());                  String[] names = parseEscapedStringList(getSingleLineResultSet().getResult());
# Line 4436  public class Client { Line 5210  public class Client {
5210           */           */
5211          public synchronized DbInstrumentInfo          public synchronized DbInstrumentInfo
5212          getDbInstrumentInfo(String instr) throws IOException, LscpException, LSException {          getDbInstrumentInfo(String instr) throws IOException, LscpException, LSException {
5213                  verifyConnection();                  DbInstrumentInfo info = new DbInstrumentInfo();
5214                  out.writeLine("GET DB_INSTRUMENT INFO '" + instr + "'");                  if(!retrieveInfo("GET DB_INSTRUMENT INFO '" + conv(instr) + "'", info)) return null;
5215                  if(getPrintOnlyMode()) return null;  
                   
                 ResultSet rs = getMultiLineResultSet();  
                 DbInstrumentInfo info = new DbInstrumentInfo(rs.getMultiLineResult());  
5216                  String s = getParentDirectory(instr);                  String s = getParentDirectory(instr);
5217                  if(s != null) info.setDirectoryPath(s);                  if(s != null) info.setDirectoryPath(s);
5218                  s = getFileName(instr);                  s = getFileName(instr);
# Line 4466  public class Client { Line 5237  public class Client {
5237                                    
5238                  DbInstrumentInfo[] infoS = new DbInstrumentInfo[instrS.length];                  DbInstrumentInfo[] infoS = new DbInstrumentInfo[instrS.length];
5239                  for(int i = 0; i < instrS.length; i++) {                  for(int i = 0; i < instrS.length; i++) {
5240                          infoS[i] = getDbInstrumentInfo(dir + toEscapedFileName(instrS[i]));                          infoS[i] = getDbInstrumentInfo(conv(dir) + toEscapedFsEntry(instrS[i]));
5241                  }                  }
5242                  return infoS;                  return infoS;
5243          }          }
# Line 4485  public class Client { Line 5256  public class Client {
5256                  String[] instrS = getDbInstrumentNames(dir);                  String[] instrS = getDbInstrumentNames(dir);
5257                  if(instrS.length == 0) return new DbInstrumentInfo[0];                  if(instrS.length == 0) return new DbInstrumentInfo[0];
5258                                    
5259                  if(dir.charAt(dir.length() - 1) != '/') dir += "/";                  if(dir.charAt(dir.length() - 1) != '/') dir += "/"; FIXME:
5260                                    
5261                  for(int i = 0; i < instrS.length; i++) {                  for(int i = 0; i < instrS.length; i++) {
5262                          out.writeLine("GET DB_INSTRUMENT INFO '" + dir + instrS[i] + "'");                          out.writeLine("GET DB_INSTRUMENT INFO '" + conv(dir) + instrS[i] + "'");
5263                  }                  }
5264                                    
5265                  if(getPrintOnlyMode()) return null;                  if(getPrintOnlyMode()) return null;
# Line 4531  public class Client { Line 5302  public class Client {
5302           */           */
5303          public synchronized void          public synchronized void
5304          renameDbInstrument(String instr, String name)          renameDbInstrument(String instr, String name)
5305                                  throws IOException, LSException, LscpException {                                  throws IOException, LSException, LscpException
5306                            {
5307                  verifyConnection();                  name = toEscapedText(name);
5308                  name = toEscapedString(name);                  retrieveIndex("SET DB_INSTRUMENT NAME '" + conv(instr) + "' '" + conv(name) + "'");
                 out.writeLine("SET DB_INSTRUMENT NAME '" + instr + "' '" + name + "'");  
                 if(getPrintOnlyMode()) return;  
                   
                 ResultSet rs = getEmptyResultSet();  
5309          }          }
5310                    
5311          /**          /**
# Line 4550  public class Client { Line 5317  public class Client {
5317           * @throws LscpException If LSCP protocol corruption occurs.           * @throws LscpException If LSCP protocol corruption occurs.
5318           */           */
5319          public synchronized void          public synchronized void
5320          moveDbInstrument(String instr, String dst) throws IOException, LSException, LscpException {          moveDbInstrument(String instr, String dst) throws IOException, LSException, LscpException
5321                  verifyConnection();          { retrieveIndex("MOVE DB_INSTRUMENT '" + conv(instr) + "' '" + conv(dst) + "'"); }
                 out.writeLine("MOVE DB_INSTRUMENT '" + instr + "' '" + dst + "'");  
                 if(getPrintOnlyMode()) return;  
                   
                 ResultSet rs = getEmptyResultSet();  
         }  
5322                    
5323          /**          /**
5324           * Moves the specified instruments into the specified location.           * Moves the specified instruments into the specified location.
# Line 4570  public class Client { Line 5332  public class Client {
5332          moveDbInstruments(String[] instrs, String dst) throws IOException, LSException, LscpException {          moveDbInstruments(String[] instrs, String dst) throws IOException, LSException, LscpException {
5333                  verifyConnection();                  verifyConnection();
5334                  for(String s : instrs) {                  for(String s : instrs) {
5335                          out.writeLine("MOVE DB_INSTRUMENT '" + s + "' '" + dst + "'");                          out.writeLine("MOVE DB_INSTRUMENT '" + conv(s) + "' '" + conv(dst) + "'");
5336                  }                  }
5337                  if(getPrintOnlyMode()) return;                  if(getPrintOnlyMode()) return;
5338                                    
# Line 4586  public class Client { Line 5348  public class Client {
5348           * @throws LscpException If LSCP protocol corruption occurs.           * @throws LscpException If LSCP protocol corruption occurs.
5349           */           */
5350          public synchronized void          public synchronized void
5351          copyDbInstrument(String instr, String dst) throws IOException, LSException, LscpException {          copyDbInstrument(String instr, String dst) throws IOException, LSException, LscpException
5352                  verifyConnection();          { retrieveIndex("COPY DB_INSTRUMENT '" + conv(instr) + "' '" + conv(dst) + "'"); }
                 out.writeLine("COPY DB_INSTRUMENT '" + instr + "' '" + dst + "'");  
                 if(getPrintOnlyMode()) return;  
                   
                 ResultSet rs = getEmptyResultSet();  
         }  
5353                    
5354          /**          /**
5355           * Copies the specified instruments into the specified location.           * Copies the specified instruments into the specified location.
# Line 4606  public class Client { Line 5363  public class Client {
5363          copyDbInstruments(String[] instrs, String dst) throws IOException, LSException, LscpException {          copyDbInstruments(String[] instrs, String dst) throws IOException, LSException, LscpException {
5364                  verifyConnection();                  verifyConnection();
5365                  for(String s : instrs) {                  for(String s : instrs) {
5366                          out.writeLine("COPY DB_INSTRUMENT '" + s + "' '" + dst + "'");                          out.writeLine("COPY DB_INSTRUMENT '" + conv(s) + "' '" + conv(dst) + "'");
5367                  }                  }
5368                  if(getPrintOnlyMode()) return;                  if(getPrintOnlyMode()) return;
5369                                    
# Line 4623  public class Client { Line 5380  public class Client {
5380           */           */
5381          public synchronized void          public synchronized void
5382          setDbInstrumentDescription(String instr, String desc)          setDbInstrumentDescription(String instr, String desc)
5383                                  throws IOException, LSException, LscpException {                                  throws IOException, LSException, LscpException
5384                            {
5385                  verifyConnection();                  desc = toEscapedText(desc);
5386                  desc = toEscapedString(desc);                  retrieveIndex("SET DB_INSTRUMENT DESCRIPTION '" + conv(instr) + "' '" + desc + "'");
                 out.writeLine("SET DB_INSTRUMENT DESCRIPTION '" + instr + "' '" + desc + "'");  
                 if(getPrintOnlyMode()) return;  
                   
                 ResultSet rs = getEmptyResultSet();  
5387          }          }
5388                    
5389          /**          /**
5390             * Substitutes all occurrences of the instrument file
5391             * <code>oldPath</code> in the database, with <code>newPath</code>.
5392             * @param oldPath The absolute path name of the instrument file to substitute.
5393             * @param newPath The new absolute path name.
5394             * @throws IOException If some I/O error occurs.
5395             * @throws LSException If the operation failed.
5396             * @throws LscpException If LSCP protocol corruption occurs.
5397             */
5398            public synchronized void
5399            setDbInstrumentFilePath(String oldPath, String newPath)
5400                                    throws IOException, LSException, LscpException
5401            { retrieveIndex("SET DB_INSTRUMENT FILE_PATH '" + conv(oldPath) + "' '" + conv(newPath) + "'"); }
5402            
5403            /**
5404           * Finds all directories in the specified directory           * Finds all directories in the specified directory
5405           * that corresponds to the specified search criterias.           * that corresponds to the specified search criterias.
5406           * @param dir The absolute path name of the directory to search.           * @param dir The absolute path name of the directory to search.
# Line 4671  public class Client { Line 5438  public class Client {
5438                  StringBuffer sb = new StringBuffer();                  StringBuffer sb = new StringBuffer();
5439                  sb.append("FIND DB_INSTRUMENT_DIRECTORIES");                  sb.append("FIND DB_INSTRUMENT_DIRECTORIES");
5440                  if(nonRecursive) sb.append(" NON_RECURSIVE");                  if(nonRecursive) sb.append(" NON_RECURSIVE");
5441                  sb.append(" '").append(dir).append("'");                  sb.append(" '").append(conv(dir)).append("'");
5442                                    
5443                  if(query.name != null && query.name.length() > 0) {                  if(query.name != null && query.name.length() > 0) {
5444                          sb.append(" NAME='").append(toEscapedString(query.name)).append("'");                          sb.append(" NAME='").append(toEscapedText(query.name)).append("'");
5445                  }                  }
5446                                    
5447                  String s = query.getCreatedAfter();                  String s = query.getCreatedAfter();
# Line 4699  public class Client { Line 5466  public class Client {
5466                                    
5467                  if(query.description != null && query.description.length() > 0) {                  if(query.description != null && query.description.length() > 0) {
5468                          sb.append(" DESCRIPTION='");                          sb.append(" DESCRIPTION='");
5469                          sb.append(toEscapedString(query.description)).append("'");                          sb.append(toEscapedText(query.description)).append("'");
5470                  }                  }
5471                                    
5472                  out.writeLine(sb.toString());                  out.writeLine(sb.toString());
# Line 4752  public class Client { Line 5519  public class Client {
5519                  StringBuffer sb = new StringBuffer();                  StringBuffer sb = new StringBuffer();
5520                  sb.append("FIND DB_INSTRUMENTS");                  sb.append("FIND DB_INSTRUMENTS");
5521                  if(nonRecursive) sb.append(" NON_RECURSIVE");                  if(nonRecursive) sb.append(" NON_RECURSIVE");
5522                  sb.append(" '").append(dir).append("'");                  sb.append(" '").append(conv(dir)).append("'");
5523                                    
5524                  if(query.name != null && query.name.length() > 0) {                  if(query.name != null && query.name.length() > 0) {
5525                          sb.append(" NAME='").append(toEscapedString(query.name)).append("'");                          sb.append(" NAME='").append(toEscapedText(query.name)).append("'");
5526                  }                  }
5527                                    
5528                  if(query.formatFamilies.size() > 0) {                  if(query.formatFamilies.size() > 0) {
# Line 4796  public class Client { Line 5563  public class Client {
5563                                    
5564                  if(query.description != null && query.description.length() > 0) {                  if(query.description != null && query.description.length() > 0) {
5565                          sb.append(" DESCRIPTION='");                          sb.append(" DESCRIPTION='");
5566                          sb.append(toEscapedString(query.description)).append("'");                          sb.append(toEscapedText(query.description)).append("'");
5567                  }                  }
5568                                    
5569                  if(query.instrumentType != DbSearchQuery.InstrumentType.BOTH) {                  if(query.instrumentType != DbSearchQuery.InstrumentType.BOTH) {
# Line 4809  public class Client { Line 5576  public class Client {
5576                  }                  }
5577                                    
5578                  if(query.product != null && query.product.length() > 0) {                  if(query.product != null && query.product.length() > 0) {
5579                          sb.append(" PRODUCT='").append(toEscapedString(query.product)).append("'");                          sb.append(" PRODUCT='").append(toEscapedText(query.product)).append("'");
5580                  }                  }
5581                                    
5582                  if(query.artists != null && query.artists.length() > 0) {                  if(query.artists != null && query.artists.length() > 0) {
5583                          sb.append(" ARTISTS='").append(toEscapedString(query.artists)).append("'");                          sb.append(" ARTISTS='").append(toEscapedText(query.artists)).append("'");
5584                  }                  }
5585                                    
5586                  if(query.keywords != null && query.keywords.length() > 0) {                  if(query.keywords != null && query.keywords.length() > 0) {
5587                          sb.append(" KEYWORDS='");                          sb.append(" KEYWORDS='");
5588                          sb.append(toEscapedString(query.keywords)).append("'");                          sb.append(toEscapedText(query.keywords)).append("'");
5589                  }                  }
5590                                    
5591                  out.writeLine(sb.toString());                  out.writeLine(sb.toString());
# Line 4834  public class Client { Line 5601  public class Client {
5601          }          }
5602                    
5603          /**          /**
5604             * Returns a list of all instrument files in the database
5605             * that that don't exist in the filesystem.
5606             * @throws IOException If some I/O error occurs.
5607             * @throws LscpException If LSCP protocol corruption occurs.
5608             * @throws LSException If other error occurs.
5609             */
5610            public synchronized String[]
5611            findLostDbInstrumentFiles() throws IOException, LscpException, LSException {
5612                    
5613                    verifyConnection();
5614                    out.writeLine("FIND LOST DB_INSTRUMENT_FILES");
5615                    if(getPrintOnlyMode()) return null;
5616                    
5617                    return parseEscapedStringList(getSingleLineResultSet().getResult());
5618            }
5619            
5620            /**
5621           * Gets status information about the specified job.           * Gets status information about the specified job.
5622           * @param jobId The ID of the job.           * @param jobId The ID of the job.
5623           * @return A <code>ScanJobInfo</code> instance providing information           * @return A <code>ScanJobInfo</code> instance providing information
# Line 4844  public class Client { Line 5628  public class Client {
5628           */           */
5629          public synchronized ScanJobInfo          public synchronized ScanJobInfo
5630          getDbInstrumentsJobInfo(int jobId) throws IOException, LscpException, LSException {          getDbInstrumentsJobInfo(int jobId) throws IOException, LscpException, LSException {
5631                  verifyConnection();                  ScanJobInfo info = new ScanJobInfo();
5632                  out.writeLine("GET DB_INSTRUMENTS_JOB INFO " + String.valueOf(jobId));                  if(!retrieveInfo("GET DB_INSTRUMENTS_JOB INFO " + String.valueOf(jobId), info)) return null;
                 if(getPrintOnlyMode()) return null;  
                   
                 ResultSet rs = getMultiLineResultSet();  
                 ScanJobInfo info = new ScanJobInfo(rs.getMultiLineResult());  
5633                                    
5634                  return info;                  return info;
5635          }          }
# Line 4862  public class Client { Line 5642  public class Client {
5642           * @throws LSException If the formatting of the instruments database failed.           * @throws LSException If the formatting of the instruments database failed.
5643           */           */
5644          public synchronized void          public synchronized void
5645          formatInstrumentsDb() throws IOException, LscpException, LSException {          formatInstrumentsDb() throws IOException, LscpException, LSException
5646                  verifyConnection();          { retrieveIndex("FORMAT INSTRUMENTS_DB"); }
                 out.writeLine("FORMAT INSTRUMENTS_DB");  
                 if(getPrintOnlyMode()) return;  
                   
                 ResultSet rs = getEmptyResultSet();  
         }  
           
         /**  
          * Resets the specified sampler channel.  
          *  
          * @param samplerChn The sampler channel number.  
          *  
          * @throws IOException If some I/O error occurs.  
          * @throws LscpException If LSCP protocol corruption occurs.  
          * @throws LSException If <code>samplerChn</code> is not a valid channel number or if  
          * there is no engine assigned yet to the specified sampler channel.  
          * @see #getSamplerChannels  
          */  
         public synchronized void  
         resetChannel(int samplerChn) throws IOException, LscpException, LSException {  
                 verifyConnection();  
                 out.writeLine("RESET CHANNEL " + samplerChn);  
                 if(getPrintOnlyMode()) return;  
                   
                 ResultSet rs = getEmptyResultSet();  
         }  
5647                    
5648          /**          /**
5649           * Resets the whole sampler.           * Resets the whole sampler.
# Line 4908  public class Client { Line 5663  public class Client {
5663                    
5664          /**          /**
5665           * Gets the current number of all active streams.           * Gets the current number of all active streams.
5666           * @return The current number of all active streams.           * @return The current number of all active streams or -1 if in "print only" mode.
5667           * @throws IOException If some I/O error occurs.           * @throws IOException If some I/O error occurs.
5668           * @throws LscpException If LSCP protocol corruption occurs.           * @throws LscpException If LSCP protocol corruption occurs.
5669           * @throws LSException If some other error occurs.           * @throws LSException If some other error occurs.
5670           */           */
5671          public synchronized int          public synchronized int
5672          getTotalStreamCount() throws IOException, LscpException, LSException {          getTotalStreamCount() throws IOException, LscpException, LSException {
5673                  verifyConnection();                  return retrieveInt("GET TOTAL_STREAM_COUNT");
                 out.writeLine("GET TOTAL_STREAM_COUNT");  
                 if(getPrintOnlyMode()) return -1;  
                   
                 String s = getSingleLineResultSet().getResult();  
                 return parseInt(s);  
5674          }          }
5675                    
5676          /**          /**
5677           * Gets the current number of all active voices.           * Gets the current number of all active voices.
5678           * @return The current number of all active voices.           * @return The current number of all active voices or -1 if in "print only" mode.
5679           * @throws IOException If some I/O error occurs.           * @throws IOException If some I/O error occurs.
5680           * @throws LscpException If LSCP protocol corruption occurs.           * @throws LscpException If LSCP protocol corruption occurs.
5681           * @throws LSException If some other error occurs.           * @throws LSException If some other error occurs.
5682           */           */
5683          public synchronized int          public synchronized int
5684          getTotalVoiceCount() throws IOException, LscpException, LSException {          getTotalVoiceCount() throws IOException, LscpException, LSException {
5685                  verifyConnection();                  return retrieveInt("GET TOTAL_VOICE_COUNT");
                 out.writeLine("GET TOTAL_VOICE_COUNT");  
                 if(getPrintOnlyMode()) return -1;  
                   
                 String s = getSingleLineResultSet().getResult();  
                 return parseInt(s);  
5686          }          }
5687                    
5688          /**          /**
5689           * Gets the maximum number of active voices.           * Gets the maximum number of active voices.
5690           * @return The maximum number of active voices.           * @return The maximum number of active voices or -1 if in "print only" mode.
5691           * @throws IOException If some I/O error occurs.           * @throws IOException If some I/O error occurs.
5692           * @throws LscpException If LSCP protocol corruption occurs.           * @throws LscpException If LSCP protocol corruption occurs.
5693           * @throws LSException If some other error occurs.           * @throws LSException If some other error occurs.
5694           */           */
5695          public synchronized int          public synchronized int
5696          getTotalVoiceCountMax() throws IOException, LscpException, LSException {          getTotalVoiceCountMax() throws IOException, LscpException, LSException {
5697                  verifyConnection();                  return retrieveInt("GET TOTAL_VOICE_COUNT_MAX");
                 out.writeLine("GET TOTAL_VOICE_COUNT_MAX");  
                 if(getPrintOnlyMode()) return -1;  
                   
                 String s = getSingleLineResultSet().getResult();  
                 return parseInt(s);  
5698          }          }
5699                    
5700          /**          /**
# Line 4969  public class Client { Line 5709  public class Client {
5709           */           */
5710          public synchronized ServerInfo          public synchronized ServerInfo
5711          getServerInfo() throws IOException, LscpException, LSException {          getServerInfo() throws IOException, LscpException, LSException {
5712                  verifyConnection();                  ServerInfo info = new ServerInfo();
5713                  out.writeLine("GET SERVER INFO");                  if(!retrieveInfo("GET SERVER INFO", info)) return null;
                 if(getPrintOnlyMode()) return null;  
5714                                    
5715                  ResultSet rs = getMultiLineResultSet();                  return info;
                 return new ServerInfo(rs.getMultiLineResult());  
5716          }          }
5717                    
5718          /**          /**
5719           * Gets the golobal volume of the sampler.           * Gets the global volume of the sampler.
5720           * @return The golobal volume of the sampler.           * @return The global volume of the sampler.
5721           * @throws IOException If some I/O error occurs.           * @throws IOException If some I/O error occurs.
5722           * @throws LscpException If LSCP protocol corruption occurs.           * @throws LscpException If LSCP protocol corruption occurs.
5723           * @throws LSException If some other error occurs.           * @throws LSException If some other error occurs.
# Line 5003  public class Client { Line 5741  public class Client {
5741           * @see #getVolume           * @see #getVolume
5742           */           */
5743          public synchronized void          public synchronized void
5744          setVolume(float volume) throws IOException, LscpException, LSException {          setVolume(float volume) throws IOException, LscpException, LSException
5745            { retrieveIndex("SET VOLUME " + volume); }
5746                    
5747                  verifyConnection();          /**
5748                  out.writeLine("SET VOLUME " + volume);           * Gets the global sampler-wide limit of maximum voices.
5749                  if(getPrintOnlyMode()) return;           * @return The global sampler-wide limit of maximum voices or -1 if in "print only" mode.
5750                             * @throws IOException If some I/O error occurs.
5751                  ResultSet rs = getEmptyResultSet();           * @throws LscpException If LSCP protocol corruption occurs.
5752             * @throws LSException If some other error occurs.
5753             */
5754            public synchronized int
5755            getGlobalVoiceLimit() throws IOException, LscpException, LSException {
5756                    return retrieveInt("GET VOICES");
5757            }
5758            
5759            /**
5760             * Sets the global sampler-wide limit of maximum voices.
5761             * @param maxVoices The new global limit of maximum voices.
5762             * @throws IOException If some I/O error occurs.
5763             * @throws LscpException If LSCP protocol corruption occurs.
5764             * @throws LSException If some other error occurs.
5765             * @see #getVolume
5766             */
5767            public synchronized void
5768            setGlobalVoiceLimit(int maxVoices) throws IOException, LscpException, LSException
5769            { retrieveIndex("SET VOICES " + maxVoices); }
5770            
5771            /**
5772             * Gets the global sampler-wide limit of maximum disk streams.
5773             * @return The global sampler-wide limit of maximum disk streams
5774             *  or -1 if in "print only" mode.
5775             * @throws IOException If some I/O error occurs.
5776             * @throws LscpException If LSCP protocol corruption occurs.
5777             * @throws LSException If some other error occurs.
5778             */
5779            public synchronized int
5780            getGlobalStreamLimit() throws IOException, LscpException, LSException {
5781                    return retrieveInt("GET STREAMS");
5782          }          }
5783                    
5784          /**          /**
5785             * Sets the global sampler-wide limit for maximum disk streams.
5786             * @param maxVoices The new global limit of maximum disk streams.
5787             * @throws IOException If some I/O error occurs.
5788             * @throws LscpException If LSCP protocol corruption occurs.
5789             * @throws LSException If some other error occurs.
5790             * @see #getVolume
5791             */
5792            public synchronized void
5793            setGlobalStreamLimit(int maxStreams) throws IOException, LscpException, LSException
5794            { retrieveIndex("SET STREAMS " + maxStreams); }
5795            
5796            /**
5797           * Gets the number of instruments in the specified instrument file.           * Gets the number of instruments in the specified instrument file.
5798           * @param filename The absolute path name of the instrument file.           * @param filename The absolute path name of the instrument file.
5799           * @return The number of instruments in the specified instrument file.           * @return The number of instruments in the specified instrument file
5800             *  or -1 if in "print only" mode.
5801           * @throws IOException If some I/O error occurs.           * @throws IOException If some I/O error occurs.
5802           * @throws LscpException If LSCP protocol corruption occurs.           * @throws LscpException If LSCP protocol corruption occurs.
5803           * @throws LSException If the file is not found, or other error occur.           * @throws LSException If the file is not found, or other error occur.
5804           */           */
5805          public synchronized int          public synchronized int
5806          getFileInstrumentCount(String filename) throws IOException, LscpException, LSException {          getFileInstrumentCount(String filename) throws IOException, LscpException, LSException {
5807                  verifyConnection();                  return retrieveInt("GET FILE INSTRUMENTS '" + conv(filename) +"'");
                 out.writeLine("GET FILE INSTRUMENTS '" + filename +"'");  
                 if(getPrintOnlyMode()) return -1;  
                   
                 String s = getSingleLineResultSet().getResult();  
                 return parseInt(s);  
5808          }          }
5809                    
5810          /**          /**
# Line 5042  public class Client { Line 5819  public class Client {
5819          public synchronized Instrument          public synchronized Instrument
5820          getFileInstrumentInfo(String filename, int instrIdx)          getFileInstrumentInfo(String filename, int instrIdx)
5821                                  throws IOException, LscpException, LSException {                                  throws IOException, LscpException, LSException {
5822                    
5823                  verifyConnection();                  FileInstrument instr = new FileInstrument();
5824                  out.writeLine("GET FILE INSTRUMENT INFO '" + filename + "' " + String.valueOf(instrIdx));                  String cmd = "GET FILE INSTRUMENT INFO '" + conv(filename) + "' " + String.valueOf(instrIdx);
5825                  if(getPrintOnlyMode()) return null;                  if(!retrieveInfo(cmd, instr)) return null;
                   
                 ResultSet rs = getMultiLineResultSet();  
                 Instrument instr = new FileInstrument(rs.getMultiLineResult()) { };  
5826                                    
5827                  return instr;                  return instr;
5828          }          }
# Line 5075  public class Client { Line 5849  public class Client {
5849          }          }
5850                    
5851          private static class FileInstrument extends AbstractInstrument {          private static class FileInstrument extends AbstractInstrument {
5852                  FileInstrument(String[] resultSet) throws LscpException {                  FileInstrument() { }
                         super(resultSet);  
                 }  
5853                                    
5854                  public String                  public String
5855                  getEngine() {                  getEngine() {
# Line 5085  public class Client { Line 5857  public class Client {
5857                          return getFormatFamily();                          return getFormatFamily();
5858                  }                  }
5859                                    
5860                    @Override
5861                  public boolean                  public boolean
5862                  parse(String s) throws LscpException {                  parse(String s) throws LscpException {
5863                          if(s.startsWith("PRODUCT: ") || s.startsWith("ARTISTS: ")) return true;                          if(s.startsWith("PRODUCT: ") || s.startsWith("ARTISTS: ")) return true;
# Line 5113  public class Client { Line 5886  public class Client {
5886                          throw new LSException(0, s, details);                          throw new LSException(0, s, details);
5887                  }                  }
5888          }          }
5889    
5890            /**
5891             * Retrieves a list of integers.
5892             * @throws IOException If some I/O error occurs.
5893             * @throws LscpException If LSCP protocol corruption occurs.
5894             */
5895            private Integer[]
5896            getIntegerList(String lscpCmd) throws IOException, LscpException, LSException {
5897                    verifyConnection();
5898                    out.writeLine(lscpCmd);
5899                    if(getPrintOnlyMode()) return null;
5900    
5901                    return parseIntList(getSingleLineResultSet().getResult());
5902            }
5903    
5904            private boolean
5905            retrieveInfo(String lscpCmd, Parseable p) throws IOException, LscpException, LSException {
5906                    verifyConnection();
5907                    out.writeLine(lscpCmd);
5908                    if(getPrintOnlyMode()) return false;
5909    
5910                    ResultSet rs = getMultiLineResultSet();
5911    
5912                    for(String s : rs.getMultiLineResult()) {
5913                            if(!p.parse(s)) Client.getLogger().info(LscpI18n.getLogMsg("unknownLine", s));
5914                    }
5915    
5916                    return true;
5917            }
5918    
5919            private int
5920            retrieveInt(String lscpCmd) throws IOException, LscpException, LSException {
5921                    verifyConnection();
5922                    out.writeLine(lscpCmd);
5923                    if(getPrintOnlyMode()) return -1;
5924    
5925                    String s = getSingleLineResultSet().getResult();
5926                    return parseInt(s);
5927            }
5928    
5929            private int
5930            retrieveIndex(String lscpCmd) throws IOException, LSException, LscpException {
5931                    verifyConnection();
5932                    out.writeLine(lscpCmd);
5933                    if(getPrintOnlyMode()) return -1;
5934    
5935                    return getEmptyResultSet().getIndex();
5936            }
5937                    
5938          /**          /**
5939           * Returns the logger for this library.           * Returns the logger for this library.

Legend:
Removed from v.1542  
changed lines
  Added in v.2287

  ViewVC Help
Powered by ViewVC