/[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 1718 by iliev, Wed Mar 19 10:05:33 2008 UTC revision 2190 by iliev, Fri Jun 24 20:18:03 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.Vector;  import java.util.Vector;
34  import java.util.logging.Level;  import java.util.logging.Level;
35  import java.util.logging.Logger;  import java.util.logging.Logger;
# Line 41  import static org.linuxsampler.lscp.Pars Line 41  import static org.linuxsampler.lscp.Pars
41    
42  /**  /**
43   * This class is the abstraction representing a client endpoint for communication with LinuxSampler   * This class is the abstraction representing a client endpoint for communication with LinuxSampler
44   * instance. Since it implements all commands specified in the LSCP protocol v1.1, for more   * instance. Since it implements all commands specified in the LSCP protocol v1.5, for more
45   * information look at the   * information look at the
46   * <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.
47   *   *
48   * <p> The following code establishes connection to LinuxSampler instance and gets the   * <p> The following code establishes connection to LinuxSampler instance and gets the
49   * LinuxSampler version:   * LinuxSampler version:
# Line 78  public class Client { Line 78  public class Client {
78          private EventThread eventThread;          private EventThread eventThread;
79                    
80          private boolean printOnlyMode = false;          private boolean printOnlyMode = false;
81    
82            public enum ResultSetType {
83                    EMPTY, SINGLE_LINE, MULTI_LINE
84            }
85            
86            private static class ResultSetEntry {
87                    public ResultSetType type;
88                    
89                    public
90                    ResultSetEntry(ResultSetType type) {
91                            this.type = type;
92                    }
93            }
94    
95            private Vector<ResultSetEntry> resultSetQueue = new Vector<ResultSetEntry>();
96                    
97          class EventThread extends Thread {          class EventThread extends Thread {
98                  private Vector<String> queue = new Vector<String>();                  private Vector<String> queue = new Vector<String>();
# Line 85  public class Client { Line 100  public class Client {
100                                    
101                  EventThread() { super("LSCP-Event-Thread"); }                  EventThread() { super("LSCP-Event-Thread"); }
102                                    
103                    @Override
104                  public void                  public void
105                  run() {                  run() {
106                          while(!mustTerminate()) {                          while(!mustTerminate()) {
# Line 164  public class Client { Line 180  public class Client {
180                  if(printOnlyMode) setPrintOnlyMode(true);                  if(printOnlyMode) setPrintOnlyMode(true);
181          }          }
182                    
183            private boolean extendedCharacterEscaping = true;
184            
185            /**
186             * Sets whether strings sent to LinuxSampler should be more aggressively escaped.
187             */
188            public synchronized void
189            setExtendedCharacterEscaping(boolean b) { extendedCharacterEscaping = b; }
190            
191            /**
192             * Determines whether strings sent to LinuxSampler should be more aggressively escaped.
193             */
194            public synchronized boolean
195            getExtendedCharacterEscaping() { return extendedCharacterEscaping; }
196            
197            /**
198             * @see java.net.Socket#setSoTimeout
199             */
200            public synchronized void
201            setSoTimeout(int timeout) {
202                    soTimeout = timeout;
203                    
204                    try { if(sock != null) sock.setSoTimeout(timeout); }
205                    catch(Exception x) { getLogger().log(Level.INFO, "Unable to set timeout", x); }
206            }
207            
208            private String
209            toEscapedText(String s) {
210                    s = toEscapedString(s);
211                    return conv(s);
212            }
213            
214            private String
215            toEscapedFsEntry(String s) {
216                    s = toEscapedFileName(s);
217                    return conv(s);
218            }
219            
220            /**
221             * Applies an extended character escaping to the specified string if needed.
222             */
223            private String
224            conv(String s) {
225                    return getExtendedCharacterEscaping() ? toExtendedEscapeSequence(s) : s;
226            }
227            
228          /**          /**
229           * Determines whether the client is in print-only mode.           * Determines whether the client is in print-only mode.
230           * Print-only mode means that the client will just print all           * Print-only mode means that the client will just print all
# Line 350  public class Client { Line 411  public class Client {
411                  if(!llMIMI.isEmpty()) subscribe("MIDI_INSTRUMENT_MAP_INFO");                  if(!llMIMI.isEmpty()) subscribe("MIDI_INSTRUMENT_MAP_INFO");
412                  if(!llMIC.isEmpty()) subscribe("MIDI_INSTRUMENT_COUNT");                  if(!llMIC.isEmpty()) subscribe("MIDI_INSTRUMENT_COUNT");
413                  if(!llMII.isEmpty()) subscribe("MIDI_INSTRUMENT_INFO");                  if(!llMII.isEmpty()) subscribe("MIDI_INSTRUMENT_INFO");
414                    if(!llDMD.isEmpty()) subscribe("DEVICE_MIDI");
415                    if(!llCMD.isEmpty()) subscribe("CHANNEL_MIDI");
416                  if(!llID.isEmpty()) {                  if(!llID.isEmpty()) {
417                          subscribe("DB_INSTRUMENT_DIRECTORY_COUNT");                          subscribe("DB_INSTRUMENT_DIRECTORY_COUNT");
418                          subscribe("DB_INSTRUMENT_DIRECTORY_INFO");                          subscribe("DB_INSTRUMENT_DIRECTORY_INFO");
# Line 358  public class Client { Line 421  public class Client {
421                          subscribe("DB_INSTRUMENTS_JOB_INFO");                          subscribe("DB_INSTRUMENTS_JOB_INFO");
422                  }                  }
423                  if(!llGI.isEmpty()) subscribe("GLOBAL_INFO");                  if(!llGI.isEmpty()) subscribe("GLOBAL_INFO");
424                    if(!llEIC.isEmpty()) subscribe("EFFECT_INSTANCE_COUNT");
425                    if(!llEII.isEmpty()) subscribe("EFFECT_INSTANCE_INFO");
426                    if(!llSECC.isEmpty()) subscribe("SEND_EFFECT_CHAIN_COUNT");
427                    if(!llSECI.isEmpty()) subscribe("SEND_EFFECT_CHAIN_INFO");
428          }          }
429                    
430          /**          /**
# Line 421  public class Client { Line 488  public class Client {
488                          else getLogger().severe("Unknown notification format: " + s);                          else getLogger().severe("Unknown notification format: " + s);
489                  }                  }
490          }          }
491    
492            private synchronized void
493            processResultSetQueue() {
494                    for(int i = 0; i < resultSetQueue.size(); i++) {
495                            try {
496                                    switch(resultSetQueue.get(i).type) {
497                                            case EMPTY:
498                                                    getEmptyResultSet();
499                                                    break;
500                                            case SINGLE_LINE:
501                                                    getSingleLineResultSet();
502                                                    break;
503                                            case MULTI_LINE:
504                                                    getMultiLineResultSet();
505                                                    break;
506                                            default:
507                                                    getLogger().severe("Unknown result set type");
508                                    }
509                            } catch(Exception x) {
510                                    getLogger().log(Level.FINE, "Error while processing result set queue", x);
511                            }
512                    }
513    
514                    resultSetQueue.removeAllElements();
515            }
516                    
517          /**          /**
518           * Gets empty result set.           * Gets empty result set.
519           * @return <code>ResultSet</code> instance.           * @return <code>ResultSet</code> instance.
520           */           */
521          private ResultSet          private ResultSet
522          getEmptyResultSet() throws IOException, LscpException, LSException {          getEmptyResultSet() throws IOException, LscpException, LSException {
523                    processResultSetQueue();
524                  return parseEmptyResultSet(getLine());                  return parseEmptyResultSet(getLine());
525          }          }
526                    
527          private ResultSet          private ResultSet
528          getSingleLineResultSet() throws IOException, LscpException, LSException {          getSingleLineResultSet() throws IOException, LscpException, LSException {
529                    processResultSetQueue();
530                  ResultSet rs = new ResultSet();                  ResultSet rs = new ResultSet();
531                  String ln = getLine();                  String ln = getLine();
532                                    
# Line 451  public class Client { Line 545  public class Client {
545                    
546          private ResultSet          private ResultSet
547          getMultiLineResultSet() throws IOException, LscpException, LSException {          getMultiLineResultSet() throws IOException, LscpException, LSException {
548                    processResultSetQueue();
549                  ResultSet rs = new ResultSet();                  ResultSet rs = new ResultSet();
550                  String ln = getLine();                  String ln = getLine();
551                                    
# Line 500  public class Client { Line 595  public class Client {
595          /** MIDI instrument info listeners */          /** MIDI instrument info listeners */
596          private final Vector<MidiInstrumentInfoListener> llMII =          private final Vector<MidiInstrumentInfoListener> llMII =
597                  new Vector<MidiInstrumentInfoListener>();                  new Vector<MidiInstrumentInfoListener>();
598            private final Vector<DeviceMidiDataListener> llDMD = new Vector<DeviceMidiDataListener>();
599            private final Vector<ChannelMidiDataListener> llCMD = new Vector<ChannelMidiDataListener>();
600          private final Vector<InstrumentsDbListener> llID = new Vector<InstrumentsDbListener>();          private final Vector<InstrumentsDbListener> llID = new Vector<InstrumentsDbListener>();
601          private final Vector<GlobalInfoListener> llGI = new Vector<GlobalInfoListener>();          private final Vector<GlobalInfoListener> llGI = new Vector<GlobalInfoListener>();
602            private final ArrayList<EffectInstanceCountListener> llEIC = new ArrayList<EffectInstanceCountListener>();
603            private final Vector<EffectInstanceInfoListener> llEII = new Vector<EffectInstanceInfoListener>();
604            private final Vector<SendEffectChainCountListener> llSECC = new Vector<SendEffectChainCountListener>();
605            private final Vector<SendEffectChainInfoListener> llSECI = new Vector<SendEffectChainInfoListener>();
606                    
607                    
608          /**          /**
# Line 531  public class Client { Line 632  public class Client {
632                          !llMIMI.isEmpty() ||                          !llMIMI.isEmpty() ||
633                          !llMIC.isEmpty()  ||                          !llMIC.isEmpty()  ||
634                          !llMII.isEmpty()  ||                          !llMII.isEmpty()  ||
635                            !llDMD.isEmpty()  ||
636                            !llCMD.isEmpty()  ||
637                          !llID.isEmpty()   ||                          !llID.isEmpty()   ||
638                          !llGI.isEmpty();                          !llGI.isEmpty()   ||
639                            !llEIC.isEmpty()  ||
640                            !llEII.isEmpty()  ||
641                            !llSECC.isEmpty() ||
642                            !llSECI.isEmpty();
643            }
644            
645            private synchronized void
646            fireDeviceMidiDataEvent(String s) {
647                    try {
648                            String[] list = parseList(s, ' ');
649                            if(list.length != 5) {
650                                    getLogger().warning("Unknown DEVICE_MIDI format");
651                                    return;
652                            }
653                            
654                            int dev = parseInt(list[0]);
655                            int port = parseInt(list[1]);
656                            
657                            MidiDataEvent.Type type = parseMidiDataType(list[2]);
658                            if(type == null) return;
659                            
660                            int note = parseInt(list[3]);
661                            int velocity = parseInt(list[4]);
662                            
663                            DeviceMidiDataEvent e = new DeviceMidiDataEvent(this, type, note, velocity);
664                            e.setDeviceId(dev);
665                            e.setPortId(port);
666                            for(DeviceMidiDataListener l : llDMD) l.midiDataArrived(e);
667                    } catch(LscpException x) {
668                            getLogger().log (
669                                    Level.WARNING, LscpI18n.getLogMsg("CommandFailed!"), x
670                            );
671                    }
672            }
673            
674            private synchronized void
675            fireChannelMidiDataEvent(String s) {
676                    try {
677                            String[] list = parseList(s, ' ');
678                            if(list.length != 4) {
679                                    getLogger().warning("Unknown CHANNEL_MIDI format");
680                                    return;
681                            }
682                            
683                            int channel = parseInt(list[0]);
684                            
685                            MidiDataEvent.Type type = parseMidiDataType(list[1]);
686                            if(type == null) return;
687                            
688                            int note = parseInt(list[2]);
689                            int velocity = parseInt(list[3]);
690                            
691                            ChannelMidiDataEvent e = new ChannelMidiDataEvent(this, type, note, velocity);
692                            e.setChannelId(channel);
693                            for(ChannelMidiDataListener l : llCMD) l.midiDataArrived(e);
694                    } catch(LscpException x) {
695                            getLogger().log (
696                                    Level.WARNING, LscpI18n.getLogMsg("CommandFailed!"), x
697                            );
698                    }
699            }
700            
701            private MidiDataEvent.Type
702            parseMidiDataType(String s) {
703                    if("NOTE_ON".equals(s)) return MidiDataEvent.Type.NOTE_ON;
704                    if("NOTE_OFF".equals(s)) return MidiDataEvent.Type.NOTE_OFF;
705                    if("CC".equals(s)) return MidiDataEvent.Type.CC;
706                    
707                    getLogger().warning("Unknown MIDI data type: " + s);
708                    return null;
709          }          }
710                    
711          private synchronized void          private synchronized void
712          fireEvent(String s) {          fireEvent(String s) {
713                   if(s.startsWith("DB_INSTRUMENT_DIRECTORY_COUNT:")) {                  // Sort by priority
714                    
715                     if(s.startsWith("CHANNEL_MIDI:")) {
716                            s = s.substring("CHANNEL_MIDI:".length());
717                            fireChannelMidiDataEvent(s);
718                    } else if(s.startsWith("DEVICE_MIDI:")) {
719                            s = s.substring("DEVICE_MIDI:".length());
720                            fireDeviceMidiDataEvent(s);
721                    } else if(s.startsWith("DB_INSTRUMENT_DIRECTORY_COUNT:")) {
722                          s = s.substring("DB_INSTRUMENT_DIRECTORY_COUNT:".length());                          s = s.substring("DB_INSTRUMENT_DIRECTORY_COUNT:".length());
723                          InstrumentsDbEvent e = new InstrumentsDbEvent(this, s);                          InstrumentsDbEvent e = new InstrumentsDbEvent(this, s);
724                          for(InstrumentsDbListener l : llID) l.directoryCountChanged(e);                          for(InstrumentsDbListener l : llID) l.directoryCountChanged(e);
# Line 824  public class Client { Line 1005  public class Client {
1005                          } catch(Exception x) {                          } catch(Exception x) {
1006                                  getLogger().log(Level.WARNING, "Unknown FX_SEND_INFO format", x);                                  getLogger().log(Level.WARNING, "Unknown FX_SEND_INFO format", x);
1007                          }                          }
1008                    } else if(s.startsWith("EFFECT_INSTANCE_COUNT:")) {
1009                            try {
1010                                    s = s.substring("EFFECT_INSTANCE_COUNT:".length());
1011                                    int i = Integer.parseInt(s);
1012                                    
1013                                    EffectInstanceCountEvent e = new EffectInstanceCountEvent(this, i);
1014                                    for(EffectInstanceCountListener l : llEIC) {
1015                                            l.effectInstanceCountChanged(e);
1016                                    }
1017                            } catch(Exception x) {
1018                                    getLogger().log(Level.WARNING, "Unknown EFFECT_INSTANCE_COUNT format", x);
1019                            }
1020                    } else if(s.startsWith("EFFECT_INSTANCE_INFO:")) {
1021                            try {
1022                                    s = s.substring("EFFECT_INSTANCE_INFO:".length());
1023                                    int i = Integer.parseInt(s);
1024                                    
1025                                    EffectInstanceInfoEvent e = new EffectInstanceInfoEvent(this, i);
1026                                    for(EffectInstanceInfoListener l : llEII) {
1027                                            l.effectInstanceInfoChanged(e);
1028                                    }
1029                            } catch(Exception x) {
1030                                    getLogger().log(Level.WARNING, "Unknown EFFECT_INSTANCE_INFO format", x);
1031                            }
1032                    } else if(s.startsWith("SEND_EFFECT_CHAIN_COUNT:")) {
1033                            try {
1034                                    s = s.substring("SEND_EFFECT_CHAIN_COUNT:".length());
1035                                    Integer[] i = parseIntList(s, ' ');
1036                                    if(i.length != 2) {
1037                                            getLogger().warning("Unknown SEND_EFFECT_CHAIN_COUNT format");
1038                                            return;
1039                                    }
1040                                    
1041                                    SendEffectChainCountEvent e =
1042                                            new SendEffectChainCountEvent(this, i[0], i[1]);
1043                                    
1044                                    for(SendEffectChainCountListener l : llSECC) {
1045                                            l.sendEffectChainCountChanged(e);
1046                                    }
1047                            } catch(Exception x) {
1048                                    getLogger().log(Level.WARNING, "Unknown SEND_EFFECT_CHAIN_COUNT format", x);
1049                            }
1050                    } else if(s.startsWith("SEND_EFFECT_CHAIN_INFO:")) {
1051                            try {
1052                                    s = s.substring("SEND_EFFECT_CHAIN_INFO:".length());
1053                                    Integer[] i = parseIntList(s, ' ');
1054                                    if(i.length != 3) {
1055                                            getLogger().warning("Unknown SEND_EFFECT_CHAIN_INFO format");
1056                                            return;
1057                                    }
1058                                    
1059                                    SendEffectChainInfoEvent e =
1060                                            new SendEffectChainInfoEvent(this, i[0], i[1], i[2]);
1061                                    
1062                                    for(SendEffectChainInfoListener l : llSECI) {
1063                                            l.sendEffectChainInfoChanged(e);
1064                                    }
1065                            } catch(Exception x) {
1066                                    getLogger().log(Level.WARNING, "Unknown SEND_EFFECT_CHAIN_INFO format", x);
1067                            }
1068                  } else if(s.startsWith("GLOBAL_INFO:")) {                  } else if(s.startsWith("GLOBAL_INFO:")) {
1069                          handleGlobalInfoEvent(s.substring("GLOBAL_INFO:".length()));                          handleGlobalInfoEvent(s.substring("GLOBAL_INFO:".length()));
1070                  } else if(s.startsWith("MISCELLANEOUS:")) {                  } else if(s.startsWith("MISCELLANEOUS:")) {
# Line 840  public class Client { Line 1081  public class Client {
1081                                  float f = Float.parseFloat(s.substring("VOLUME ".length()));                                  float f = Float.parseFloat(s.substring("VOLUME ".length()));
1082                                  GlobalInfoEvent e = new GlobalInfoEvent(this, f);                                  GlobalInfoEvent e = new GlobalInfoEvent(this, f);
1083                                  for(GlobalInfoListener l : llGI) l.volumeChanged(e);                                  for(GlobalInfoListener l : llGI) l.volumeChanged(e);
1084                            } else if(s.startsWith("VOICES ")) {
1085                                    int i = Integer.parseInt(s.substring("VOICES ".length()));
1086                                    GlobalInfoEvent e = new GlobalInfoEvent(this, i, -1);
1087                                    for(GlobalInfoListener l : llGI) l.voiceLimitChanged(e);
1088                            } else if(s.startsWith("STREAMS ")) {
1089                                    int i = Integer.parseInt(s.substring("STREAMS ".length()));
1090                                    GlobalInfoEvent e = new GlobalInfoEvent(this, -1, i);
1091                                    for(GlobalInfoListener l : llGI) l.streamLimitChanged(e);
1092                            } else {
1093                                    getLogger().info("Unknown GLOBAL_INFO format: " + s);
1094                          }                          }
1095                  } catch(NumberFormatException x) {                  } catch(NumberFormatException x) {
1096                          getLogger().log(Level.WARNING, "Unknown GLOBAL_INFO format", x);                          getLogger().log(Level.WARNING, "Unknown GLOBAL_INFO format", x);
# Line 1281  public class Client { Line 1532  public class Client {
1532          /**          /**
1533           * Registers the specified listener for receiving event messages.           * Registers the specified listener for receiving event messages.
1534           * Listeners can be registered regardless of the connection state.           * Listeners can be registered regardless of the connection state.
1535             * @param l The <code>DeviceMidiDataListener</code> to register.
1536             */
1537            public synchronized void
1538            addDeviceMidiDataListener(DeviceMidiDataListener l) {
1539                    if(llDMD.isEmpty()) subscribe("DEVICE_MIDI");
1540                    llDMD.add(l);
1541            }
1542            
1543            /**
1544             * Removes the specified listener.
1545             * Listeners can be removed regardless of the connection state.
1546             * @param l The <code>DeviceMidiDataListener</code> to remove.
1547             */
1548            public synchronized void
1549            removeDeviceMidiDataListener(DeviceMidiDataListener l) {
1550                    boolean b = llDMD.remove(l);
1551                    if(b && llDMD.isEmpty()) unsubscribe("DEVICE_MIDI");
1552            }
1553            
1554            /**
1555             * Registers the specified listener for receiving event messages.
1556             * Listeners can be registered regardless of the connection state.
1557             * @param l The <code>ChannelMidiDataListener</code> to register.
1558             */
1559            public synchronized void
1560            addChannelMidiDataListener(ChannelMidiDataListener l) {
1561                    if(llCMD.isEmpty()) subscribe("CHANNEL_MIDI");
1562                    llCMD.add(l);
1563            }
1564            
1565            /**
1566             * Removes the specified listener.
1567             * Listeners can be removed regardless of the connection state.
1568             * @param l The <code>ChannelMidiDataListener</code> to remove.
1569             */
1570            public synchronized void
1571            removeChannelMidiDataListener(ChannelMidiDataListener l) {
1572                    boolean b = llCMD.remove(l);
1573                    if(b && llCMD.isEmpty()) unsubscribe("CHANNEL_MIDI");
1574            }
1575            
1576            /**
1577             * Registers the specified listener for receiving event messages.
1578             * Listeners can be registered regardless of the connection state.
1579           * @param l The <code>InstrumentsDbListener</code> to register.           * @param l The <code>InstrumentsDbListener</code> to register.
1580           */           */
1581          public synchronized void          public synchronized void
# Line 1335  public class Client { Line 1630  public class Client {
1630          }          }
1631                    
1632          /**          /**
1633             * Registers the specified listener for receiving event messages.
1634             * Listeners can be registered regardless of the connection state.
1635             * @param l The <code>EffectInstanceCountListener</code> to register.
1636             */
1637            public synchronized void
1638            addEffectInstanceCountListener(EffectInstanceCountListener l) {
1639                    if(llEIC.isEmpty()) subscribe("EFFECT_INSTANCE_COUNT");
1640                    llEIC.add(l);
1641            }
1642            
1643            /**
1644             * Removes the specified listener.
1645             * Listeners can be removed regardless of the connection state.
1646             * @param l The <code>EffectInstanceCountListener</code> to remove.
1647             */
1648            public synchronized void
1649            removeEffectInstanceCountListener(EffectInstanceCountListener l) {
1650                    boolean b = llEIC.remove(l);
1651                    if(b && llEIC.isEmpty()) unsubscribe("EFFECT_INSTANCE_COUNT");
1652            }
1653            
1654            /**
1655             * Registers the specified listener for receiving event messages.
1656             * Listeners can be registered regardless of the connection state.
1657             * @param l The <code>EffectInstanceInfoListener</code> to register.
1658             */
1659            public synchronized void
1660            addEffectInstanceInfoListener(EffectInstanceInfoListener l) {
1661                    if(llEII.isEmpty()) subscribe("EFFECT_INSTANCE_INFO");
1662                    llEII.add(l);
1663            }
1664            
1665            /**
1666             * Removes the specified listener.
1667             * Listeners can be removed regardless of the connection state.
1668             * @param l The <code>EffectInstanceInfoListener</code> to remove.
1669             */
1670            public synchronized void
1671            removeEffectInstanceInfoListener(EffectInstanceInfoListener l) {
1672                    boolean b = llEII.remove(l);
1673                    if(b && llEII.isEmpty()) unsubscribe("EFFECT_INSTANCE_INFO");
1674            }
1675            
1676            /**
1677             * Registers the specified listener for receiving event messages.
1678             * Listeners can be registered regardless of the connection state.
1679             * @param l The <code>SendEffectChainCountListener</code> to register.
1680             */
1681            public synchronized void
1682            addSendEffectChainCountListener(SendEffectChainCountListener l) {
1683                    if(llSECC.isEmpty()) subscribe("SEND_EFFECT_CHAIN_COUNT");
1684                    llSECC.add(l);
1685            }
1686            
1687            /**
1688             * Removes the specified listener.
1689             * Listeners can be removed regardless of the connection state.
1690             * @param l The <code>SendEffectChainCountListener</code> to remove.
1691             */
1692            public synchronized void
1693            removeSendEffectChainCountListener(SendEffectChainCountListener l) {
1694                    boolean b = llSECC.remove(l);
1695                    if(b && llSECC.isEmpty()) unsubscribe("SEND_EFFECT_CHAIN_COUNT");
1696            }
1697            
1698            /**
1699             * Registers the specified listener for receiving event messages.
1700             * Listeners can be registered regardless of the connection state.
1701             * @param l The <code>SendEffectChainInfoListener</code> to register.
1702             */
1703            public synchronized void
1704            addSendEffectChainInfoListener(SendEffectChainInfoListener l) {
1705                    if(llSECI.isEmpty()) subscribe("SEND_EFFECT_CHAIN_INFO");
1706                    llSECI.add(l);
1707            }
1708            
1709            /**
1710             * Removes the specified listener.
1711             * Listeners can be removed regardless of the connection state.
1712             * @param l The <code>SendEffectChainInfoListener</code> to remove.
1713             */
1714            public synchronized void
1715            removeSendEffectChainInfoListener(SendEffectChainInfoListener l) {
1716                    boolean b = llSECI.remove(l);
1717                    if(b && llSECI.isEmpty()) unsubscribe("SEND_EFFECT_CHAIN_INFO");
1718            }
1719            
1720            /**
1721           * Gets the number of all audio output drivers currently           * Gets the number of all audio output drivers currently
1722           * available for the LinuxSampler instance.           * available for the LinuxSampler instance.
1723           * @return The number of all audio output drivers currently           * @return The number of all audio output drivers currently
1724           * available for the LinuxSampler instance.           * available for the LinuxSampler instance or -1 if in "print only" mode.
1725           * @throws IOException If some I/O error occurs.           * @throws IOException If some I/O error occurs.
1726           * @throws LscpException If LSCP protocol corruption occurs.           * @throws LscpException If LSCP protocol corruption occurs.
1727           * @throws LSException If some other error occurs.           * @throws LSException If some other error occurs.
1728           */           */
1729          public synchronized int          public synchronized int
1730          getAudioOutputDriverCount() throws IOException, LscpException, LSException {          getAudioOutputDriverCount() throws IOException, LscpException, LSException {
1731                  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);  
1732          }          }
1733                    
1734          /**          /**
# Line 1410  public class Client { Line 1787  public class Client {
1787          public synchronized AudioOutputDriver          public synchronized AudioOutputDriver
1788          getAudioOutputDriverInfo(String driverName, Parameter... depList)          getAudioOutputDriverInfo(String driverName, Parameter... depList)
1789                                          throws IOException, LscpException, LSException {                                          throws IOException, LscpException, LSException {
1790                    
1791                  verifyConnection();                  AudioOutputDriver aod = new AudioOutputDriver();
1792                  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());  
1793                  aod.setName(driverName);                  aod.setName(driverName);
1794                                    
1795                  for(String s : aod.getParameterNames())                  for(String s : aod.getParameterNames())
# Line 1515  public class Client { Line 1888  public class Client {
1888          createAudioOutputDevice(String aoDriver, Parameter... paramList)          createAudioOutputDevice(String aoDriver, Parameter... paramList)
1889                                          throws IOException, LSException, LscpException {                                          throws IOException, LSException, LscpException {
1890                                    
                 verifyConnection();  
1891                  StringBuffer args = new StringBuffer(aoDriver);                  StringBuffer args = new StringBuffer(aoDriver);
1892                                    
1893                  for(Parameter p : paramList) {                  for(Parameter p : paramList) {
1894                          if(p == null || p.getName() == null || p.getValue() == null) continue;                          if(p == null || p.getName() == null || p.getValue() == null) continue;
1895                          args.append(' ').append(p.getName()).append('=').append(p.getStringValue());                          args.append(' ').append(p.getName()).append('=').append(p.getStringValue());
1896                  }                  }
1897                    
1898                  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();  
1899          }          }
1900                    
1901          /**          /**
# Line 1541  public class Client { Line 1908  public class Client {
1908           */           */
1909          public synchronized void          public synchronized void
1910          destroyAudioOutputDevice(int deviceId) throws IOException, LSException, LscpException {          destroyAudioOutputDevice(int deviceId) throws IOException, LSException, LscpException {
1911                  verifyConnection();                  retrieveIndex("DESTROY AUDIO_OUTPUT_DEVICE " + deviceId);
                 out.writeLine("DESTROY AUDIO_OUTPUT_DEVICE " + deviceId);  
                 if(getPrintOnlyMode()) return;  
                   
                 ResultSet rs = getEmptyResultSet();  
1912          }          }
1913                    
1914          /**          /**
# Line 1567  public class Client { Line 1930  public class Client {
1930                    
1931          /**          /**
1932           * Gets the current number of all created audio output devices.           * Gets the current number of all created audio output devices.
1933           * @return The current number of all created audio output devices.           * @return The current number of all created audio output devices
1934             *  or -1 if in "print only" mode.
1935           * @throws IOException If some I/O error occurs.           * @throws IOException If some I/O error occurs.
1936           * @throws LscpException If LSCP protocol corruption occurs.           * @throws LscpException If LSCP protocol corruption occurs.
1937           * @throws LSException If some other error occurs.           * @throws LSException If some other error occurs.
1938           */           */
1939          public synchronized int          public synchronized int
1940          getAudioOutputDeviceCount() throws IOException, LscpException, LSException {          getAudioOutputDeviceCount() throws IOException, LscpException, LSException {
1941                  verifyConnection();                  return retrieveInt("GET AUDIO_OUTPUT_DEVICES");
                 out.writeLine("GET AUDIO_OUTPUT_DEVICES");  
                 if(getPrintOnlyMode()) return -1;  
                   
                 String s = getSingleLineResultSet().getResult();  
                 return parseInt(s);  
1942          }          }
1943                                    
1944          /**          /**
# Line 1613  public class Client { Line 1972  public class Client {
1972           */           */
1973          public synchronized Integer[]          public synchronized Integer[]
1974          getAudioOutputDeviceIDs() throws IOException, LscpException, LSException {          getAudioOutputDeviceIDs() throws IOException, LscpException, LSException {
1975                  verifyConnection();                  return getIntegerList("LIST AUDIO_OUTPUT_DEVICES");
                 out.writeLine("LIST AUDIO_OUTPUT_DEVICES");  
                 if(getPrintOnlyMode()) return null;  
                   
                 return parseIntList(getSingleLineResultSet().getResult());  
1976          }          }
1977                    
1978          /**          /**
# Line 1720  public class Client { Line 2075  public class Client {
2075           */           */
2076          public synchronized void          public synchronized void
2077          setAudioOutputDeviceParameter(int deviceId, Parameter prm)          setAudioOutputDeviceParameter(int deviceId, Parameter prm)
2078                                                  throws IOException, LscpException, LSException {                                          throws IOException, LscpException, LSException
2079                            {
                 verifyConnection();  
2080                  String kv = prm.getName() + '=' + prm.getStringValue();                  String kv = prm.getName() + '=' + prm.getStringValue();
2081                  out.writeLine("SET AUDIO_OUTPUT_DEVICE_PARAMETER " + deviceId + ' ' + kv);                  retrieveIndex("SET AUDIO_OUTPUT_DEVICE_PARAMETER " + deviceId + ' ' + kv);
                 if(getPrintOnlyMode()) return;  
                   
                 ResultSet rs = getEmptyResultSet();  
2082          }          }
2083                    
2084          /**          /**
# Line 1911  public class Client { Line 2262  public class Client {
2262           */           */
2263          public synchronized void          public synchronized void
2264          setAudioOutputChannelParameter(int devId, int chn,  Parameter prm)          setAudioOutputChannelParameter(int devId, int chn,  Parameter prm)
2265                                                  throws IOException, LscpException, LSException {                                                  throws IOException, LscpException, LSException
2266                            {
                 verifyConnection();  
2267                  String args = devId + " " + chn + " " + prm.getName() + '=' + prm.getStringValue();                  String args = devId + " " + chn + " " + prm.getName() + '=' + prm.getStringValue();
2268                  out.writeLine("SET AUDIO_OUTPUT_CHANNEL_PARAMETER " + args);                  retrieveIndex("SET AUDIO_OUTPUT_CHANNEL_PARAMETER " + args);
                 if(getPrintOnlyMode()) return;  
                   
                 ResultSet rs = getEmptyResultSet();  
2269          }          }
2270                    
2271          /**          /**
2272           * Gets the current number of all MIDI input drivers.           * Gets the current number of all MIDI input drivers.
2273           * @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.
2274           * @throws IOException If some I/O error occurs.           * @throws IOException If some I/O error occurs.
2275           * @throws LscpException If LSCP protocol corruption occurs.           * @throws LscpException If LSCP protocol corruption occurs.
2276           * @throws LSException If some other error occurs.           * @throws LSException If some other error occurs.
2277           */           */
2278          public synchronized int          public synchronized int
2279          getMidiInputDriverCount() throws IOException, LscpException, LSException {          getMidiInputDriverCount() throws IOException, LscpException, LSException {
2280                  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);  
2281          }          }
2282                    
2283          /**          /**
# Line 1995  public class Client { Line 2337  public class Client {
2337          public synchronized MidiInputDriver          public synchronized MidiInputDriver
2338          getMidiInputDriverInfo(String driverName, Parameter... depList)          getMidiInputDriverInfo(String driverName, Parameter... depList)
2339                                          throws IOException, LscpException, LSException {                                          throws IOException, LscpException, LSException {
2340                    
2341                  verifyConnection();                  MidiInputDriver mid = new MidiInputDriver();
2342                  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());  
2343                  mid.setName(driverName);                  mid.setName(driverName);
2344                                    
2345                  for(String s : mid.getParameterNames())                  for(String s : mid.getParameterNames())
# Line 2100  public class Client { Line 2437  public class Client {
2437           */           */
2438          public synchronized int          public synchronized int
2439          createMidiInputDevice(String miDriver, Parameter... paramList)          createMidiInputDevice(String miDriver, Parameter... paramList)
2440                                          throws IOException, LSException, LscpException {                                          throws IOException, LSException, LscpException
2441                            {
                 verifyConnection();  
2442                  StringBuffer args = new StringBuffer(miDriver);                  StringBuffer args = new StringBuffer(miDriver);
2443                                    
2444                  for(Parameter p : paramList) {                  for(Parameter p : paramList) {
2445                          if(p == null || p.getName() == null || p.getValue() == null) continue;                          if(p == null || p.getName() == null || p.getValue() == null) continue;
2446                          args.append(' ').append(p.getName()).append('=').append(p.getStringValue());                          args.append(' ').append(p.getName()).append('=').append(p.getStringValue());
2447                  }                  }
2448                    
2449                  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();  
2450          }          }
2451                    
2452          /**          /**
# Line 2129  public class Client { Line 2460  public class Client {
2460           */           */
2461          public synchronized void          public synchronized void
2462          destroyMidiInputDevice(int deviceId) throws IOException, LSException, LscpException {          destroyMidiInputDevice(int deviceId) throws IOException, LSException, LscpException {
2463                  verifyConnection();                  retrieveIndex("DESTROY MIDI_INPUT_DEVICE " + deviceId);
                 out.writeLine("DESTROY MIDI_INPUT_DEVICE " + deviceId);  
                 if(getPrintOnlyMode()) return;  
                   
                 ResultSet rs = getEmptyResultSet();  
2464          }          }
2465                    
2466          /**          /**
# Line 2155  public class Client { Line 2482  public class Client {
2482                    
2483          /**          /**
2484           * Gets the current number of all created MIDI input devices.           * Gets the current number of all created MIDI input devices.
2485           * @return The current number of all created MIDI input devices.           * @return The current number of all created MIDI input
2486             * devices or -1 if in "print only" mode.
2487           * @throws IOException If some I/O error occurs.           * @throws IOException If some I/O error occurs.
2488           * @throws LscpException If LSCP protocol corruption occurs.           * @throws LscpException If LSCP protocol corruption occurs.
2489           * @throws LSException If some other error occurs.           * @throws LSException If some other error occurs.
2490           */           */
2491          public synchronized int          public synchronized int
2492          getMidiInputDeviceCount() throws IOException, LscpException, LSException {          getMidiInputDeviceCount() throws IOException, LscpException, LSException {
2493                  verifyConnection();                  return retrieveInt("GET MIDI_INPUT_DEVICES");
                 out.writeLine("GET MIDI_INPUT_DEVICES");  
                 if(getPrintOnlyMode()) return -1;  
                   
                 String s = getSingleLineResultSet().getResult();  
                 return parseInt(s);  
2494          }          }
2495                    
2496          /**          /**
# Line 2207  public class Client { Line 2530  public class Client {
2530           */           */
2531          public synchronized Integer[]          public synchronized Integer[]
2532          getMidiInputDeviceIDs() throws IOException, LscpException, LSException {          getMidiInputDeviceIDs() throws IOException, LscpException, LSException {
2533                  verifyConnection();                  return getIntegerList("LIST MIDI_INPUT_DEVICES");
                 out.writeLine("LIST MIDI_INPUT_DEVICES");  
                 if(getPrintOnlyMode()) return null;  
                   
                 return parseIntList(getSingleLineResultSet().getResult());  
2534          }          }
2535                    
2536          /**          /**
# Line 2308  public class Client { Line 2627  public class Client {
2627           */           */
2628          public synchronized void          public synchronized void
2629          setMidiInputDeviceParameter(int deviceId, Parameter prm)          setMidiInputDeviceParameter(int deviceId, Parameter prm)
2630                                                  throws IOException, LscpException, LSException {                                                  throws IOException, LscpException, LSException
2631                            {
                 verifyConnection();  
2632                  String kv = prm.getName() + '=' + prm.getStringValue();                  String kv = prm.getName() + '=' + prm.getStringValue();
2633                  out.writeLine("SET MIDI_INPUT_DEVICE_PARAMETER " + deviceId + ' ' + kv);                  retrieveIndex("SET MIDI_INPUT_DEVICE_PARAMETER " + deviceId + ' ' + kv);
                 if(getPrintOnlyMode()) return;  
                   
                 ResultSet rs = getEmptyResultSet();  
2634          }          }
2635                    
2636                    
2637          /**          /**
2638           * Changes the port number of the speicified MIDI input device.           * Changes the port number of the specified MIDI input device.
2639           * @param deviceId The numerical ID of the MIDI input device.           * @param deviceId The numerical ID of the MIDI input device.
2640           * @param ports The new number of MIDI input ports.           * @param ports The new number of MIDI input ports.
2641           *           *
# Line 2481  public class Client { Line 2796  public class Client {
2796           */           */
2797          public synchronized void          public synchronized void
2798          setMidiInputPortParameter(int deviceId, int port,  Parameter prm)          setMidiInputPortParameter(int deviceId, int port,  Parameter prm)
2799                                                  throws IOException, LscpException, LSException {                                                  throws IOException, LscpException, LSException
2800                            {
                 verifyConnection();  
2801                  String args = deviceId + " " + port + " " +                  String args = deviceId + " " + port + " " +
2802                          prm.getName() + '=' + prm.getStringValue();                          prm.getName() + '=' + prm.getStringValue();
2803                  out.writeLine("SET MIDI_INPUT_PORT_PARAMETER " + args);                  retrieveIndex("SET MIDI_INPUT_PORT_PARAMETER " + args);
                 if(getPrintOnlyMode()) return;  
                   
                 ResultSet rs = getEmptyResultSet();  
2804          }          }
2805                    
2806          /**          /**
# Line 2503  public class Client { Line 2814  public class Client {
2814           */           */
2815          public synchronized int          public synchronized int
2816          addMidiInstrumentMap(String name) throws IOException, LSException, LscpException {          addMidiInstrumentMap(String name) throws IOException, LSException, LscpException {
2817                  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();  
2818          }          }
2819                    
2820          /**          /**
# Line 2523  public class Client { Line 2828  public class Client {
2828           */           */
2829          public synchronized void          public synchronized void
2830          removeMidiInstrumentMap(int mapId) throws IOException, LscpException, LSException {          removeMidiInstrumentMap(int mapId) throws IOException, LscpException, LSException {
2831                  verifyConnection();                  retrieveIndex("REMOVE MIDI_INSTRUMENT_MAP " + mapId);
                 out.writeLine("REMOVE MIDI_INSTRUMENT_MAP " + mapId);  
                 if(getPrintOnlyMode()) return;  
                   
                 ResultSet rs = getEmptyResultSet();  
2832          }          }
2833                    
2834          /**          /**
# Line 2538  public class Client { Line 2839  public class Client {
2839           */           */
2840          public synchronized void          public synchronized void
2841          removeAllMidiInstrumentMaps() throws IOException, LscpException, LSException {          removeAllMidiInstrumentMaps() throws IOException, LscpException, LSException {
2842                  verifyConnection();                  retrieveIndex("REMOVE MIDI_INSTRUMENT_MAP ALL");
                 out.writeLine("REMOVE MIDI_INSTRUMENT_MAP ALL");  
                 if(getPrintOnlyMode()) return;  
                   
                 ResultSet rs = getEmptyResultSet();  
2843          }          }
2844                    
2845          /**          /**
2846           * Gets the current number of all MIDI instrument maps.           * Gets the current number of all MIDI instrument maps.
2847           * @return The current number of all MIDI instrument maps.           * @return The current number of all MIDI instrument maps
2848             *  or -1 if in "print only" mode.
2849           * @throws IOException If some I/O error occurs.           * @throws IOException If some I/O error occurs.
2850           * @throws LscpException If LSCP protocol corruption occurs.           * @throws LscpException If LSCP protocol corruption occurs.
2851           * @throws LSException If some other error occurs.           * @throws LSException If some other error occurs.
2852           */           */
2853          public synchronized int          public synchronized int
2854          getMidiInstrumentMapCount() throws IOException, LscpException, LSException {          getMidiInstrumentMapCount() throws IOException, LscpException, LSException {
2855                  verifyConnection();                  return retrieveInt("GET MIDI_INSTRUMENT_MAPS");
                 out.writeLine("GET MIDI_INSTRUMENT_MAPS");  
                 if(getPrintOnlyMode()) return -1;  
                   
                 String s = getSingleLineResultSet().getResult();  
                 return parseInt(s);  
2856          }          }
2857                    
2858          /**          /**
# Line 2574  public class Client { Line 2867  public class Client {
2867           */           */
2868          public synchronized Integer[]          public synchronized Integer[]
2869          getMidiInstrumentMapIDs() throws IOException, LscpException, LSException {          getMidiInstrumentMapIDs() throws IOException, LscpException, LSException {
2870                  verifyConnection();                  return getIntegerList("LIST MIDI_INSTRUMENT_MAPS");
                 out.writeLine("LIST MIDI_INSTRUMENT_MAPS");  
                 if(getPrintOnlyMode()) return null;  
                   
                 return parseIntList(getSingleLineResultSet().getResult());  
2871          }          }
2872                    
2873          /**          /**
# Line 2652  public class Client { Line 2941  public class Client {
2941           */           */
2942          public synchronized void          public synchronized void
2943          setMidiInstrumentMapName(int mapId, String name)          setMidiInstrumentMapName(int mapId, String name)
2944                                  throws IOException, LscpException, LSException {                                  throws IOException, LscpException, LSException
2945                            {
2946                  verifyConnection();                  name = toEscapedText(name);
2947                  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();  
2948          }          }
2949                    
2950                    
# Line 2705  public class Client { Line 2990  public class Client {
2990                  cmd.append(entry.getMidiBank()).append(' ');                  cmd.append(entry.getMidiBank()).append(' ');
2991                  cmd.append(entry.getMidiProgram()).append(' ');                  cmd.append(entry.getMidiProgram()).append(' ');
2992                  cmd.append(info.getEngine()).append(" '");                  cmd.append(info.getEngine()).append(" '");
2993                  cmd.append(info.getFilePath()).append("' ");                  cmd.append(conv(info.getFilePath())).append("' ");
2994                  cmd.append(info.getInstrumentIndex()).append(' ');                  cmd.append(info.getInstrumentIndex()).append(' ');
2995                  cmd.append(info.getVolume());                  cmd.append(info.getVolume());
2996                  if(!info.getLoadMode().name().equals("DEFAULT")) {                  if(!info.getLoadMode().name().equals("DEFAULT")) {
# Line 2713  public class Client { Line 2998  public class Client {
2998                  }                  }
2999                                    
3000                  if(info.getName() != null) {                  if(info.getName() != null) {
3001                          String s = toEscapedString(info.getName());                          String s = toEscapedText(info.getName());
3002                          cmd.append(" '").append(s).append("'");                          cmd.append(" '").append(s).append("'");
3003                  }                  }
3004                                    
# Line 2735  public class Client { Line 3020  public class Client {
3020           */           */
3021          public synchronized void          public synchronized void
3022          unmapMidiInstrument(int mapId, MidiInstrumentEntry entry)          unmapMidiInstrument(int mapId, MidiInstrumentEntry entry)
3023                                          throws IOException, LSException, LscpException {                                          throws IOException, LSException, LscpException
3024                            {
                 verifyConnection();  
3025                  StringBuffer cmd = new StringBuffer("UNMAP MIDI_INSTRUMENT ");                  StringBuffer cmd = new StringBuffer("UNMAP MIDI_INSTRUMENT ");
3026                  cmd.append(mapId).append(' ');                  cmd.append(mapId).append(' ');
3027                  cmd.append(entry.getMidiBank()).append(' ');                  cmd.append(entry.getMidiBank()).append(' ');
3028                  cmd.append(entry.getMidiProgram());                  cmd.append(entry.getMidiProgram());
3029                    
3030                  out.writeLine(cmd.toString());                  retrieveIndex(cmd.toString());
                 if(getPrintOnlyMode()) return;  
                   
                 ResultSet rs = getEmptyResultSet();  
3031          }          }
3032                    
3033          /**          /**
3034           * Gets the current number of all MIDI instrument in all maps.           * Gets the current number of all MIDI instrument in all maps.
3035           * @return The current number of all MIDI instrument in all maps.           * @return The current number of all MIDI instrument in all maps
3036             * or -1 if in "print only" mode.
3037           * @throws IOException If some I/O error occurs.           * @throws IOException If some I/O error occurs.
3038           * @throws LscpException If LSCP protocol corruption occurs.           * @throws LscpException If LSCP protocol corruption occurs.
3039           * @throws LSException If some other error occurs.           * @throws LSException If some other error occurs.
3040           */           */
3041          public synchronized int          public synchronized int
3042          getMidiInstrumentCount() throws IOException, LscpException, LSException {          getMidiInstrumentCount() throws IOException, LscpException, LSException {
3043                  verifyConnection();                  return retrieveInt("GET MIDI_INSTRUMENTS ALL");
                 out.writeLine("GET MIDI_INSTRUMENTS ALL");  
                 if(getPrintOnlyMode()) return -1;  
                   
                 String s = getSingleLineResultSet().getResult();  
                 return parseInt(s);  
3044          }          }
3045                    
3046          /**          /**
3047           * Gets the current number of MIDI instrument in the specified map.           * Gets the current number of MIDI instrument in the specified map.
3048           * @param mapId The ID of the map.           * @param mapId The ID of the map.
3049           * @return The current number of MIDI instrument in the specified map.           * @return The current number of MIDI instrument in the
3050             * specified map 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(int mapId) throws IOException, LscpException, LSException {          getMidiInstrumentCount(int mapId) throws IOException, LscpException, LSException {
3057                  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);  
3058          }          }
3059                    
3060          /**          /**
# Line 2952  public class Client { Line 3225  public class Client {
3225           */           */
3226          public synchronized void          public synchronized void
3227          loadInstrument(String filename, int instrIdx, int samplerChn, boolean nonModal)          loadInstrument(String filename, int instrIdx, int samplerChn, boolean nonModal)
3228                                                  throws IOException, LscpException, LSException {                                                  throws IOException, LscpException, LSException
3229                            {
3230                  String cmd = nonModal ? "LOAD INSTRUMENT NON_MODAL " : "LOAD INSTRUMENT ";                  String cmd = nonModal ? "LOAD INSTRUMENT NON_MODAL " : "LOAD INSTRUMENT ";
3231                  String args = '\'' + filename + "' " + instrIdx + ' ' + samplerChn;                  String args = '\'' + conv(filename) + "' " + instrIdx + ' ' + samplerChn;
3232                    
3233                  out.writeLine(cmd + args);                  retrieveIndex(cmd + args);
                 if(getPrintOnlyMode()) return;  
                   
                 ResultSet rs = getEmptyResultSet();  
3234          }          }
3235                    
3236          /**          /**
# Line 2977  public class Client { Line 3247  public class Client {
3247           */           */
3248          public synchronized void          public synchronized void
3249          loadSamplerEngine(String engineName, int samplerChn)          loadSamplerEngine(String engineName, int samplerChn)
3250                                          throws IOException, LscpException, LSException {                                          throws IOException, LscpException, LSException
3251                            { retrieveIndex("LOAD ENGINE " + engineName + ' ' + samplerChn); }
                 verifyConnection();  
                 out.writeLine("LOAD ENGINE " + engineName + ' ' + samplerChn);  
                 if(getPrintOnlyMode()) return;  
                   
                 ResultSet rs = getEmptyResultSet();  
         }  
3252                    
3253          /**          /**
3254           * Gets the current number of all created sampler channels.           * Gets the current number of all created sampler channels.
3255           * @return The current number of all created sampler channels.           * @return The current number of all created sampler
3256             * channels or -1 if in "print only" mode.
3257           * @throws IOException If some I/O error occurs.           * @throws IOException If some I/O error occurs.
3258           * @throws LscpException If LSCP protocol corruption occurs.           * @throws LscpException If LSCP protocol corruption occurs.
3259           * @throws LSException If some other error occurs.           * @throws LSException If some other error occurs.
3260           */           */
3261          public synchronized int          public synchronized int
3262          getSamplerChannelCount() throws IOException, LscpException, LSException {          getSamplerChannelCount() throws IOException, LscpException, LSException {
3263                  verifyConnection();                  return retrieveInt("GET CHANNELS");
                 out.writeLine("GET CHANNELS");  
                 if(getPrintOnlyMode()) return -1;  
                   
                 String s = getSingleLineResultSet().getResult();  
                 return parseInt(s);  
3264          }          }
3265                    
3266          /**          /**
# Line 3024  public class Client { Line 3284  public class Client {
3284                                    
3285                  return channels;                  return channels;
3286          }          }
3287    
3288            /**
3289             * Gets a list of the specified sampler channels.
3290             * @return A <code>SamplerChannel</code> array providing all created sampler channels.
3291             * @throws IOException If some I/O error occurs.
3292             * @throws LscpException If LSCP protocol corruption occurs.
3293             * @throws LSException If some other error occurs.
3294             * @see #addSamplerChannel
3295             * @see #removeSamplerChannel
3296             */
3297            public synchronized SamplerChannel[]
3298            getSamplerChannels(final Integer[] ids) throws IOException, LscpException, LSException {
3299                    verifyConnection();
3300    
3301                    int count = 0;
3302                    for(int i = 0; i < ids.length; i++) {
3303                            if(ids[i] >= 0) {
3304                                    int tmp = ids[i]; // to avoid overlapping
3305                                    ids[i] = -1;
3306                                    ids[count++] = tmp;
3307                            }
3308                    }
3309                    if(getPrintOnlyMode()) return null;
3310    
3311                    final SamplerChannel[] channels = new SamplerChannel[count];
3312    
3313                    new CmdListIterator(count) {
3314                            @Override
3315                            protected void
3316                            writeOutput(int index) throws IOException {
3317                                    channels[index] = new SamplerChannel();
3318                                    out.writeLine("GET CHANNEL INFO " + ids[index]);
3319                                    channels[index].setChannelId(ids[index]);
3320                            }
3321    
3322                            @Override
3323                            protected void
3324                            readInput(int index) throws IOException, LscpException, LSException {
3325                                    if(getPrintOnlyMode()) return;
3326                                    ResultSet rs = getMultiLineResultSet();
3327    
3328                                    for(String s : rs.getMultiLineResult()) {
3329                                            if(!channels[index].parse(s)) {
3330                                                    String msg = LscpI18n.getLogMsg("unknownLine", s);
3331                                                    Client.getLogger().info(msg);
3332                                            }
3333                                    }
3334                            }
3335                    }.run();
3336    
3337    
3338    
3339                    for(SamplerChannel sc : channels) {
3340                            if(sc.getEngine() != null) {
3341                                    sc.setEngine(getEngineInfo(sc.getEngine().getName()));
3342                            }
3343                    }
3344    
3345                    return channels;
3346            }
3347    
3348            private static abstract class CmdListIterator {
3349                    private final int cmdCount;
3350                    private final int cmdsPerStep;
3351    
3352                    CmdListIterator(int cmdCount) {
3353                            this(cmdCount, 100);
3354                    }
3355    
3356                    CmdListIterator(int cmdCount, int cmdsPerStep) {
3357                            this.cmdCount = cmdCount;
3358                            this.cmdsPerStep = cmdsPerStep;
3359                    }
3360    
3361                    public void
3362                    run() throws IOException, LscpException, LSException {
3363                            int currentStep = 0;
3364                            int stepCount = cmdCount / cmdsPerStep;
3365    
3366                            for(currentStep = 0; currentStep < stepCount; currentStep++) {
3367                                    for(int j = 0; j < cmdsPerStep; j++) {
3368                                            int idx = (currentStep * cmdsPerStep) + j;
3369                                            writeOutput(idx);
3370                                    }
3371    
3372                                    for(int j = 0; j < cmdsPerStep; j++) {
3373                                            int idx = (currentStep * cmdsPerStep) + j;
3374                                            readInput(idx);
3375                                    }
3376                            }
3377    
3378                            int cmdsLeft = cmdCount % cmdsPerStep;
3379                            if(cmdsLeft > 0) {
3380                                    for(int j = 0; j < cmdsLeft; j++) {
3381                                            int idx = stepCount * cmdsPerStep + j;
3382                                            writeOutput(idx);
3383                                    }
3384    
3385                                    for(int j = 0; j < cmdsLeft; j++) {
3386                                            int idx = stepCount * cmdsPerStep + j;
3387                                            readInput(idx);
3388                                    }
3389                            }
3390                    }
3391    
3392                    protected abstract void writeOutput(int index) throws IOException;
3393    
3394                    protected abstract void readInput(int index) throws IOException, LscpException, LSException;
3395            }
3396                    
3397          /**          /**
3398           * Gets a list with numerical IDs of all created sampler channels.           * Gets a list with numerical IDs of all created sampler channels.
# Line 3037  public class Client { Line 3406  public class Client {
3406           */           */
3407          public synchronized Integer[]          public synchronized Integer[]
3408          getSamplerChannelIDs() throws IOException, LscpException, LSException {          getSamplerChannelIDs() throws IOException, LscpException, LSException {
3409                  verifyConnection();                  return getIntegerList("LIST CHANNELS");
                 out.writeLine("LIST CHANNELS");  
                 if(getPrintOnlyMode()) return null;  
                   
                 return parseIntList(getSingleLineResultSet().getResult());  
3410          }          }
3411                    
3412          /**          /**
# Line 3056  public class Client { Line 3421  public class Client {
3421           */           */
3422          public synchronized int          public synchronized int
3423          addSamplerChannel() throws IOException, LSException, LscpException {          addSamplerChannel() throws IOException, LSException, LscpException {
3424                  verifyConnection();                  return retrieveIndex("ADD CHANNEL");
                 out.writeLine("ADD CHANNEL");  
                 if(getPrintOnlyMode()) return -1;  
                   
                 ResultSet rs = getEmptyResultSet();  
                   
                 return rs.getIndex();  
3425          }          }
3426                    
3427          /**          /**
# Line 3078  public class Client { Line 3437  public class Client {
3437           */           */
3438          public synchronized void          public synchronized void
3439          removeSamplerChannel(int samplerChn) throws IOException, LscpException, LSException {          removeSamplerChannel(int samplerChn) throws IOException, LscpException, LSException {
3440                  verifyConnection();                  retrieveIndex("REMOVE CHANNEL " + samplerChn);
                 out.writeLine("REMOVE CHANNEL " + samplerChn);  
                 if(getPrintOnlyMode()) return;  
                   
                 ResultSet rs = getEmptyResultSet();  
3441          }          }
3442                    
3443          /**          /**
3444           * Gets the number of all available engines.           * Gets the number of all available engines.
3445           * @return The number of all available engines.           * @return The number of all available engines or -1 if in "print only" mode.
3446           * @throws IOException If some I/O error occurs.           * @throws IOException If some I/O error occurs.
3447           * @throws LscpException If LSCP protocol corruption occurs.           * @throws LscpException If LSCP protocol corruption occurs.
3448           * @throws LSException If some other error occurs.           * @throws LSException If some other error occurs.
3449           */           */
3450          public synchronized int          public synchronized int
3451          getEngineCount() throws IOException, LscpException, LSException {          getEngineCount() throws IOException, LscpException, LSException {
3452                  verifyConnection();                  return retrieveInt("GET AVAILABLE_ENGINES");
                 out.writeLine("GET AVAILABLE_ENGINES");  
                 if(getPrintOnlyMode()) return -1;  
                   
                 String s = getSingleLineResultSet().getResult();  
                 return parseInt(s);  
3453          }          }
3454                    
3455          /**          /**
# Line 3153  public class Client { Line 3503  public class Client {
3503           */           */
3504          private synchronized SamplerEngine          private synchronized SamplerEngine
3505          getEngineInfo(String engineName) throws IOException, LscpException, LSException {          getEngineInfo(String engineName) throws IOException, LscpException, LSException {
3506                  verifyConnection();                  SamplerEngine se = new SamplerEngine();
3507                  out.writeLine("GET ENGINE INFO " + engineName);                  if(!retrieveInfo("GET ENGINE INFO " + engineName, se)) return null;
                 if(getPrintOnlyMode()) return null;  
                   
                 ResultSet rs = getMultiLineResultSet();  
                 SamplerEngine se = new SamplerEngine(rs.getMultiLineResult());  
3508                  se.setName(engineName);                  se.setName(engineName);
3509    
3510                  return se;                  return se;
3511          }          }
3512                    
# Line 3177  public class Client { Line 3524  public class Client {
3524           */           */
3525          public synchronized SamplerChannel          public synchronized SamplerChannel
3526          getSamplerChannelInfo(int samplerChn) throws IOException, LscpException, LSException {          getSamplerChannelInfo(int samplerChn) throws IOException, LscpException, LSException {
3527                  verifyConnection();                  SamplerChannel sc = new SamplerChannel();
3528                  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());  
3529                  sc.setChannelId(samplerChn);                  sc.setChannelId(samplerChn);
3530                  if(sc.getEngine() != null) sc.setEngine(getEngineInfo(sc.getEngine().getName()));                  if(sc.getEngine() != null) sc.setEngine(getEngineInfo(sc.getEngine().getName()));
3531                                    
# Line 3193  public class Client { Line 3536  public class Client {
3536           * Gets the current number of active voices on the specified sampler channel.           * Gets the current number of active voices on the specified sampler channel.
3537           *           *
3538           * @param samplerChn The sampler channel number.           * @param samplerChn The sampler channel number.
3539           * @return The current number of active voices on the specified sampler channel.           * @return The current number of active voices on the
3540             * specified sampler channel or -1 if in "print only" mode.
3541           * @throws IOException If some I/O error occurs.           * @throws IOException If some I/O error occurs.
3542           * @throws LscpException If LSCP protocol corruption occurs.           * @throws LscpException If LSCP protocol corruption occurs.
3543           * @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 3201  public class Client { Line 3545  public class Client {
3545           */           */
3546          public synchronized int          public synchronized int
3547          getChannelVoiceCount(int samplerChn) throws IOException, LscpException, LSException {          getChannelVoiceCount(int samplerChn) throws IOException, LscpException, LSException {
3548                  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());  
3549          }          }
3550                    
3551          /**          /**
# Line 3347  public class Client { Line 3685  public class Client {
3685           */           */
3686          public synchronized void          public synchronized void
3687          setChannelAudioOutputDevice(int samplerChn, int devId)          setChannelAudioOutputDevice(int samplerChn, int devId)
3688                                  throws IOException, LscpException, LSException {                                  throws IOException, LscpException, LSException
3689                            { retrieveIndex("SET CHANNEL AUDIO_OUTPUT_DEVICE " + samplerChn + ' ' + devId); }
                 verifyConnection();  
                 out.writeLine("SET CHANNEL AUDIO_OUTPUT_DEVICE " + samplerChn + ' ' + devId);  
                 if(getPrintOnlyMode()) return;  
                   
                 ResultSet rs = getEmptyResultSet();  
         }  
3690                    
3691          /**          /**
3692           * Sets the audio output channel on the specified sampler channel.           * Sets the audio output channel on the specified sampler channel.
# Line 3377  public class Client { Line 3709  public class Client {
3709           */           */
3710          public synchronized void          public synchronized void
3711          setChannelAudioOutputChannel(int samplerChn, int audioOut, int audioIn)          setChannelAudioOutputChannel(int samplerChn, int audioOut, int audioIn)
3712                                  throws IOException, LscpException, LSException {                                  throws IOException, LscpException, LSException
3713                            {
                 verifyConnection();  
3714                  String args = " " + samplerChn + ' ' + audioOut + ' ' + audioIn;                  String args = " " + samplerChn + ' ' + audioOut + ' ' + audioIn;
3715                  out.writeLine("SET CHANNEL AUDIO_OUTPUT_CHANNEL" + args);                  retrieveIndex("SET CHANNEL AUDIO_OUTPUT_CHANNEL" + args);
                 if(getPrintOnlyMode()) return;  
                   
                 ResultSet rs = getEmptyResultSet();  
3716          }          }
3717                    
3718          /**          /**
# Line 3406  public class Client { Line 3734  public class Client {
3734           */           */
3735          public synchronized void          public synchronized void
3736          setChannelMidiInputDevice(int samplerChn, int devId)          setChannelMidiInputDevice(int samplerChn, int devId)
3737                                  throws IOException, LscpException, LSException {                                  throws IOException, LscpException, LSException
3738                            { retrieveIndex("SET CHANNEL MIDI_INPUT_DEVICE " + samplerChn + ' ' + devId); }
                 verifyConnection();  
                 out.writeLine("SET CHANNEL MIDI_INPUT_DEVICE " + samplerChn + ' ' + devId);  
                 if(getPrintOnlyMode()) return;  
                   
                 ResultSet rs = getEmptyResultSet();  
         }  
3739                    
3740          /**          /**
3741           * Sets the MIDI input port on the specified sampler channel.           * Sets the MIDI input port on the specified sampler channel.
# Line 3429  public class Client { Line 3751  public class Client {
3751           */           */
3752          public synchronized void          public synchronized void
3753          setChannelMidiInputPort(int samplerChn, int port)          setChannelMidiInputPort(int samplerChn, int port)
3754                                  throws IOException, LscpException, LSException {                                  throws IOException, LscpException, LSException
3755                            { retrieveIndex("SET CHANNEL MIDI_INPUT_PORT " + samplerChn + ' ' + port); }
                 verifyConnection();  
                 out.writeLine("SET CHANNEL MIDI_INPUT_PORT " + samplerChn + ' ' + port);  
                 if(getPrintOnlyMode()) return;  
                   
                 ResultSet rs = getEmptyResultSet();  
         }  
3756                    
3757          /**          /**
3758           * 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 3452  public class Client { Line 3768  public class Client {
3768           */           */
3769          public synchronized void          public synchronized void
3770          setChannelMidiInputChannel(int samplerChn, int midiChn)          setChannelMidiInputChannel(int samplerChn, int midiChn)
3771                                  throws IOException, LscpException, LSException {                                  throws IOException, LscpException, LSException
3772                            {
                 verifyConnection();  
3773                  String args = String.valueOf(samplerChn) + ' ';                  String args = String.valueOf(samplerChn) + ' ';
3774                  args += (midiChn == -1 ? "ALL" : String.valueOf(midiChn));                  args += (midiChn == -1 ? "ALL" : String.valueOf(midiChn));
3775                  out.writeLine("SET CHANNEL MIDI_INPUT_CHANNEL " + args);                  retrieveIndex("SET CHANNEL MIDI_INPUT_CHANNEL " + args);
                 if(getPrintOnlyMode()) return;  
                   
                 ResultSet rs = getEmptyResultSet();  
3776          }          }
3777                    
3778          /**          /**
# Line 3484  public class Client { Line 3796  public class Client {
3796           */           */
3797          public synchronized void          public synchronized void
3798          setChannelMidiInstrumentMap(int samplerChn, int mapId)          setChannelMidiInstrumentMap(int samplerChn, int mapId)
3799                                  throws IOException, LscpException, LSException {                                  throws IOException, LscpException, LSException
3800                            {
                 verifyConnection();  
3801                  String s;                  String s;
3802                  if(mapId == -1) {                  if(mapId == -1) {
3803                          s = " NONE";                          s = " NONE";
# Line 3495  public class Client { Line 3806  public class Client {
3806                  } else {                  } else {
3807                          s = " " + String.valueOf(mapId);                          s = " " + String.valueOf(mapId);
3808                  }                  }
3809                  out.writeLine("SET CHANNEL MIDI_INSTRUMENT_MAP " + samplerChn + s);  
3810                  if(getPrintOnlyMode()) return;                  retrieveIndex("SET CHANNEL MIDI_INSTRUMENT_MAP " + samplerChn + s);
                   
                 ResultSet rs = getEmptyResultSet();  
3811          }          }
3812                    
3813          /**          /**
# Line 3515  public class Client { Line 3824  public class Client {
3824           */           */
3825          public synchronized void          public synchronized void
3826          setChannelVolume(int samplerChn, float volume)          setChannelVolume(int samplerChn, float volume)
3827                                  throws IOException, LscpException, LSException {                                  throws IOException, LscpException, LSException
3828                    { retrieveIndex("SET CHANNEL VOLUME " + samplerChn + ' ' + volume); }
                 verifyConnection();  
                 out.writeLine("SET CHANNEL VOLUME " + samplerChn + ' ' + volume);  
                 if(getPrintOnlyMode()) return;  
                   
                 ResultSet rs = getEmptyResultSet();  
         }  
3829                    
3830          /**          /**
3831           * Mute/unmute the specified sampler channel.           * Mute/unmute the specified sampler channel.
# Line 3539  public class Client { Line 3842  public class Client {
3842           */           */
3843          public synchronized void          public synchronized void
3844          setChannelMute(int samplerChn, boolean mute)          setChannelMute(int samplerChn, boolean mute)
3845                                  throws IOException, LscpException, LSException {                                  throws IOException, LscpException, LSException
3846                    { retrieveIndex("SET CHANNEL MUTE " + samplerChn + ' ' + (mute ? 1 : 0)); }
                 verifyConnection();  
                 out.writeLine("SET CHANNEL MUTE " + samplerChn + ' ' + (mute ? 1 : 0));  
                 if(getPrintOnlyMode()) return;  
                   
                 ResultSet rs = getEmptyResultSet();  
         }  
3847                    
3848          /**          /**
3849           * Solo/unsolo the specified sampler channel.           * Solo/unsolo the specified sampler channel.
# Line 3563  public class Client { Line 3860  public class Client {
3860           */           */
3861          public synchronized void          public synchronized void
3862          setChannelSolo(int samplerChn, boolean solo)          setChannelSolo(int samplerChn, boolean solo)
3863                                  throws IOException, LscpException, LSException {                                  throws IOException, LscpException, LSException
3864                    { retrieveIndex("SET CHANNEL SOLO " + samplerChn + ' ' + (solo ? 1 : 0)); }
                 verifyConnection();  
                 out.writeLine("SET CHANNEL SOLO " + samplerChn + ' ' + (solo ? 1 : 0));  
                 if(getPrintOnlyMode()) return;  
                   
                 ResultSet rs = getEmptyResultSet();  
         }  
3865                    
3866          /**          /**
3867           * Creates an additional effect send on the specified sampler channel.           * Creates an additional effect send on the specified sampler channel.
# Line 3603  public class Client { Line 3894  public class Client {
3894           */           */
3895          public synchronized int          public synchronized int
3896          createFxSend(int channel, int midiCtrl, String name)          createFxSend(int channel, int midiCtrl, String name)
3897                          throws IOException, LSException, LscpException {                          throws IOException, LSException, LscpException
3898                            {
                 verifyConnection();  
3899                  String s = String.valueOf(channel) + " " + String.valueOf(midiCtrl);                  String s = String.valueOf(channel) + " " + String.valueOf(midiCtrl);
3900                  if(name != null) s += " '" + toEscapedString(name) + "'";                  if(name != null) s += " '" + toEscapedText(name) + "'";
3901                  out.writeLine("CREATE FX_SEND " + s);  
3902                  if(getPrintOnlyMode()) return -1;                  return retrieveIndex("CREATE FX_SEND " + s);
                   
                 ResultSet rs = getEmptyResultSet();  
                   
                 return rs.getIndex();  
3903          }          }
3904                    
3905          /**          /**
# Line 3627  public class Client { Line 3913  public class Client {
3913           */           */
3914          public synchronized void          public synchronized void
3915          destroyFxSend(int channel, int fxSend)          destroyFxSend(int channel, int fxSend)
3916                          throws IOException, LSException, LscpException {                          throws IOException, LSException, LscpException
3917                            {
                 verifyConnection();  
3918                  String s = String.valueOf(channel) + " " + String.valueOf(fxSend);                  String s = String.valueOf(channel) + " " + String.valueOf(fxSend);
3919                  out.writeLine("DESTROY FX_SEND " + s);                  retrieveIndex("DESTROY FX_SEND " + s);
                 if(getPrintOnlyMode()) return;  
                   
                 ResultSet rs = getEmptyResultSet();  
3920          }          }
3921                    
3922          /**          /**
# Line 3646  public class Client { Line 3928  public class Client {
3928           * @throws LSException If some other error occurs.           * @throws LSException If some other error occurs.
3929           */           */
3930          public synchronized int          public synchronized int
3931          getFxSoundCount(int channel) throws IOException, LscpException, LSException {          getFxSendCount(int channel) throws IOException, LscpException, LSException {
3932                  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);  
3933          }          }
3934                    
3935          /**          /**
# Line 3692  public class Client { Line 3969  public class Client {
3969           */           */
3970          public synchronized Integer[]          public synchronized Integer[]
3971          getFxSendIDs(int channel) throws IOException, LscpException, LSException {          getFxSendIDs(int channel) throws IOException, LscpException, LSException {
3972                  verifyConnection();                  return getIntegerList("LIST FX_SENDS " + channel);
                 out.writeLine("LIST FX_SENDS " + channel);  
                 if(getPrintOnlyMode()) return null;  
                   
                 return parseIntList(getSingleLineResultSet().getResult());  
3973          }          }
3974                    
3975          /**          /**
# Line 3711  public class Client { Line 3984  public class Client {
3984           */           */
3985          public synchronized FxSend          public synchronized FxSend
3986          getFxSendInfo(int channel, int fxSend) throws IOException, LscpException, LSException {          getFxSendInfo(int channel, int fxSend) throws IOException, LscpException, LSException {
3987                  verifyConnection();                  FxSend fxs = new FxSend();
3988                  String s = String.valueOf(channel) + " " + String.valueOf(fxSend);                  String s = String.valueOf(channel) + " " + String.valueOf(fxSend);
3989                  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());  
3990                  fxs.setFxSendId(fxSend);                  fxs.setFxSendId(fxSend);
3991                                    
3992                  return fxs;                  return fxs;
# Line 3735  public class Client { Line 4004  public class Client {
4004           */           */
4005          public synchronized void          public synchronized void
4006          setFxSendName(int channel, int fxSend, String name)          setFxSendName(int channel, int fxSend, String name)
4007                                  throws IOException, LscpException, LSException {                                  throws IOException, LscpException, LSException
4008                            {
4009                  verifyConnection();                  String args = " " + channel + " " + fxSend + " '" + toEscapedText(name) + "'";
4010                  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();  
4011          }          }
4012                    
4013          /**          /**
# Line 3765  public class Client { Line 4030  public class Client {
4030           */           */
4031          public synchronized void          public synchronized void
4032          setFxSendAudioOutputChannel(int channel, int fxSend, int audioSrc, int audioDst)          setFxSendAudioOutputChannel(int channel, int fxSend, int audioSrc, int audioDst)
4033                                  throws IOException, LscpException, LSException {                                  throws IOException, LscpException, LSException
4034                            {
                 verifyConnection();  
4035                  String args = " " + channel + " " + fxSend + " " + audioSrc + " " + audioDst;                  String args = " " + channel + " " + fxSend + " " + audioSrc + " " + audioDst;
4036                  out.writeLine("SET FX_SEND AUDIO_OUTPUT_CHANNEL" + args);                  retrieveIndex("SET FX_SEND AUDIO_OUTPUT_CHANNEL" + args);
4037                  if(getPrintOnlyMode()) return;          }
4038                    
4039                  ResultSet rs = getEmptyResultSet();          /**
4040             * Assign a destination effect to an effect send.
4041             * @param channel The sampler channel number.
4042             * @param fxSend The numerical ID of the effect send entity.
4043             * @param fxChainId The numerical ID of the destination effect chain.
4044             * @param chainPos The exact effect chain position in the effect
4045             * chain which hosts the actual destination effect.
4046             * @throws IOException If some I/O error occurs.
4047             * @throws LscpException If LSCP protocol corruption occurs.
4048             * @throws LSException If
4049             * <ul>
4050             * <li><code>channel</code> is not a valid channel number;
4051             * <li><code>fxSend</code> is not a valid effect send ID;
4052             * <li><code>fxChainId</code> is not a valid effect chain ID;
4053             * <li><code>chainPos</code> is out of bounds;
4054             * <li>There is no engine assigned yet to the specified sampler channel;
4055             * <li>There is no audio output device connected to the specified sampler channel.
4056             * </ul>
4057             */
4058            public synchronized void
4059            setFxSendEffect(int channel, int fxSend, int fxChainId, int chainPos)
4060                                    throws IOException, LscpException, LSException
4061            {
4062                    String args = " " + channel + " " + fxSend + " " + fxChainId + " " + chainPos;
4063                    retrieveIndex("SET FX_SEND EFFECT" + args);
4064            }
4065    
4066            /**
4067             * Removes destination effect from an effect send.
4068             * @param channel The sampler channel number.
4069             * @param fxSend The numerical ID of the effect send entity.
4070             * @throws IOException If some I/O error occurs.
4071             * @throws LscpException If LSCP protocol corruption occurs.
4072             * @throws LSException If other error occurs.
4073             */
4074            public synchronized void
4075            removeFxSendEffect(int channel, int fxSend) throws IOException, LscpException, LSException {
4076                    String args = " " + channel + " " + fxSend;
4077                    retrieveIndex("REMOVE FX_SEND EFFECT" + args);
4078          }          }
4079                    
4080          /**          /**
# Line 3793  public class Client { Line 4095  public class Client {
4095           */           */
4096          public synchronized void          public synchronized void
4097          setFxSendMidiController(int channel, int fxSend, int midiCtrl)          setFxSendMidiController(int channel, int fxSend, int midiCtrl)
4098                                  throws IOException, LscpException, LSException {                                  throws IOException, LscpException, LSException
4099                            {
                 verifyConnection();  
4100                  String args = " " + channel + " " + fxSend + " " + midiCtrl;                  String args = " " + channel + " " + fxSend + " " + midiCtrl;
4101                  out.writeLine("SET FX_SEND MIDI_CONTROLLER" + args);                  retrieveIndex("SET FX_SEND MIDI_CONTROLLER" + args);
                 if(getPrintOnlyMode()) return;  
                   
                 ResultSet rs = getEmptyResultSet();  
4102          }          }
4103                    
4104          /**          /**
# Line 3816  public class Client { Line 4114  public class Client {
4114           */           */
4115          public synchronized void          public synchronized void
4116          setFxSendLevel(int channel, int fxSend, float volume)          setFxSendLevel(int channel, int fxSend, float volume)
4117                                  throws IOException, LscpException, LSException {                                  throws IOException, LscpException, LSException
4118                            {
                 verifyConnection();  
4119                  String args = " " + channel + " " + fxSend + " " + String.valueOf(volume);                  String args = " " + channel + " " + fxSend + " " + String.valueOf(volume);
4120                  out.writeLine("SET FX_SEND LEVEL" + args);                  retrieveIndex("SET FX_SEND LEVEL" + args);
4121                  if(getPrintOnlyMode()) return;          }
4122                    
4123                  ResultSet rs = getEmptyResultSet();  
4124            /**
4125             * Gets the current amount of internal effects available to the sampler.
4126             * @return The current amount of internal effects available to the sampler.
4127             * @throws IOException If some I/O error occurs.
4128             * @throws LscpException If LSCP protocol corruption occurs.
4129             * @throws LSException If some other error occurs.
4130             */
4131            public synchronized int
4132            getEffectCount() throws IOException, LscpException, LSException
4133            { return retrieveInt("GET AVAILABLE_EFFECTS"); }
4134    
4135            /**
4136             * Gets the list of internal effects available to the sampler.
4137             * Note that the set of available internal effects can change at runtime.
4138             * @return An <code>Effect</code> array providing the current list of internal effects.
4139             * @throws IOException If some I/O error occurs.
4140             * @throws LscpException If LSCP protocol corruption occurs.
4141             */
4142            public synchronized Effect[]
4143            getEffects() throws IOException, LscpException, LSException {
4144                    Integer[] idS = getEffectIDs();
4145                    if(getPrintOnlyMode()) return null;
4146    
4147                    Effect[] effects = new Effect[idS.length];
4148    
4149                    for(int i = 0; i < effects.length; i++)
4150                            effects[i] = getEffectInfo(idS[i]);
4151    
4152                    return effects;
4153            }
4154    
4155            /**
4156             * Retrieves the list of available internal effects.
4157             * Note that the set of available internal effects can change at runtime.
4158             * @return An <code>Integer</code> array providing
4159             * the numerical IDs of all available internal effects.
4160             * @throws IOException If some I/O error occurs.
4161             * @throws LscpException If LSCP protocol corruption occurs.
4162             */
4163            public synchronized Integer[]
4164            getEffectIDs() throws IOException, LscpException, LSException
4165            { return getIntegerList("LIST AVAILABLE_EFFECTS"); }
4166    
4167            /**
4168             * Gets general informations about the specified effect.
4169             * @param effect The numerical ID of the effect entity.
4170             * @return <code>Effect</code> instance containing
4171             * general informations about the specified effect.
4172             * @throws IOException If an I/O error occurs.
4173             * @throws LscpException If LSCP protocol corruption occurs.
4174             * @throws LSException If the effect ID is invalid.
4175             */
4176            public synchronized Effect
4177            getEffectInfo(int effect) throws IOException, LscpException, LSException {
4178                    Effect e = new Effect();
4179                    if(!retrieveInfo("GET EFFECT INFO " + effect, e)) return null;
4180                    e.setEffectId(effect);
4181    
4182                    return e;
4183            }
4184    
4185            /**
4186             * Creates an instance of the desired effect.
4187             * @param id The unique ID of the effect.
4188             * @return The unique ID of the newly created effect instance.
4189             * @throws IOException If some I/O error occurs.
4190             * @throws LSException If the creation of the effect instance failed.
4191             * @throws LscpException If LSCP protocol corruption occurs.
4192             * @see #getEffectIDs
4193             * @see #getEffectInfo
4194             * @see #destroyEffectInstance
4195             */
4196            public synchronized int
4197            createEffectInstanceById(int id) throws IOException, LSException, LscpException
4198            { return retrieveIndex("CREATE EFFECT_INSTANCE " + String.valueOf(id)); }
4199    
4200            /**
4201             * Creates an instance of the desired effect.
4202             * @return The unique ID of the newly created effect instance.
4203             * @throws IOException If some I/O error occurs.
4204             * @throws LSException If the creation of the effect instance failed.
4205             * @throws LscpException If LSCP protocol corruption occurs.
4206             * @see #getEffectInfo
4207             * @see #destroyEffectInstance
4208             */
4209            public synchronized int
4210            createEffectInstance(Effect effect) throws IOException, LSException, LscpException
4211            { return createEffectInstanceById(effect.getEffectId()); }
4212    
4213            /**
4214             * Creates an instance of the desired effect.
4215             * @return The unique ID of the newly created effect instance.
4216             * @throws IOException If some I/O error occurs.
4217             * @throws LSException If the creation of the effect instance failed.
4218             * @throws LscpException If LSCP protocol corruption occurs.
4219             * @see #getEffectInfo
4220             * @see #destroyEffectInstance
4221             */
4222            public synchronized int
4223            createEffectInstance(String system, String module, String name)
4224                            throws IOException, LSException, LscpException
4225            {
4226                    String s = system + " '" + toEscapedText(module) + "' '" + toEscapedText(name) + "'";
4227                    return retrieveIndex("CREATE EFFECT_INSTANCE " + s);
4228            }
4229    
4230            /**
4231             * Destroys the specified unused effect instance.
4232             * @param instanceId The numerical ID of the effect instance.
4233             * @throws LscpException If LSCP protocol corruption occurs.
4234             * @throws LSException If some other error occurs.
4235             * @see #createEffectInstance
4236             */
4237            public synchronized void
4238            destroyEffectInstance(int instanceId) throws IOException, LSException, LscpException
4239            { retrieveIndex("DESTROY EFFECT_INSTANCE " + String.valueOf(instanceId)); }
4240            /**
4241             * Gets the current amount of effect instances available to the sampler.
4242             * @return The current amount of effect instances available to the sampler.
4243             * @throws IOException If some I/O error occurs.
4244             * @throws LscpException If LSCP protocol corruption occurs.
4245             * @throws LSException If some other error occurs.
4246             */
4247            public synchronized int
4248            getEffectInstanceCount() throws IOException, LscpException, LSException
4249            { return retrieveInt("GET EFFECT_INSTANCES"); }
4250    
4251            /**
4252             * Gets the current list of effect instances.
4253             * @return An <code>EffectInstance</code> array
4254             * providing the current list of effect instances.
4255             * @throws IOException If some I/O error occurs.
4256             * @throws LscpException If LSCP protocol corruption occurs.
4257             */
4258            public synchronized EffectInstance[]
4259            getEffectInstances() throws IOException, LscpException, LSException {
4260                    Integer[] idS = getEffectInscanceIDs();
4261                    if(getPrintOnlyMode()) return null;
4262    
4263                    EffectInstance[] eis = new EffectInstance[idS.length];
4264    
4265                    for(int i = 0; i < eis.length; i++)
4266                            eis[i] = getEffectInstanceInfo(idS[i]);
4267    
4268                    return eis;
4269            }
4270    
4271            /**
4272             * Retrieves the current list of effect instances.
4273             * @return An <code>Integer</code> array providing
4274             * the numerical IDs of all available effect instances.
4275             * @throws IOException If some I/O error occurs.
4276             * @throws LscpException If LSCP protocol corruption occurs.
4277             */
4278            public synchronized Integer[]
4279            getEffectInscanceIDs() throws IOException, LscpException, LSException
4280            { return getIntegerList("LIST EFFECT_INSTANCES"); }
4281    
4282            /**
4283             * Gets the current informations about the specified effect instance.
4284             * @param id The numerical ID of the effect instance.
4285             * @return <code>EffectInstance</code> object containing
4286             * the current informations about the specified effect instance.
4287             * @throws IOException If an I/O error occurs.
4288             * @throws LscpException If LSCP protocol corruption occurs.
4289             * @throws LSException If the effect instance ID is invalid.
4290             */
4291            public synchronized EffectInstance
4292            getEffectInstanceInfo(int id) throws IOException, LscpException, LSException {
4293                    EffectInstance ei = new EffectInstance();
4294                    if(!retrieveInfo("GET EFFECT_INSTANCE INFO " + id, ei)) return null;
4295                    ei.setInstanceId(id);
4296    
4297                    for(int i = 0; i < ei.getParameterCount(); i++) {
4298                            ei.addParameter(getEffectInstanceParameterInfo(id, i));
4299                    }
4300    
4301                    return ei;
4302            }
4303    
4304            /**
4305             * Gets information about the specified effect parameter.
4306             * @param id The numerical ID of the effect instance.
4307             * @param parameter The parameter index.
4308             * @return <code>EffectParameter</code> object containing
4309             * information about the specified effect parameter.
4310             * Note that only the following fields are used - description,
4311             * value, rangeMin, rangeMax, possibilities and default.
4312             * @throws IOException If an I/O error occurs.
4313             * @throws LscpException If LSCP protocol corruption occurs.
4314             * @throws LSException If the effect instance ID or the parameter index is invalid.
4315             */
4316            public synchronized EffectParameter
4317            getEffectInstanceParameterInfo(int instanceId, int parameter)
4318                                    throws IOException, LscpException, LSException
4319            {
4320                    EffectParameter prm = new EffectParameter();
4321                    String s = String.valueOf(instanceId) + " " + String.valueOf(parameter);
4322                    if(!retrieveInfo("GET EFFECT_INSTANCE_INPUT_CONTROL INFO " + s, prm)) return null;
4323    
4324                    return prm;
4325            }
4326    
4327            /**
4328             * Alters the current value of an effect parameter.
4329             * @param instanceId The numerical ID of the effect instance.
4330             * @param prmIndex The index of the parameter to alter.
4331             * @param value The new value for this parameter.
4332             * @throws IOException If some I/O error occurs.
4333             * @throws LscpException If LSCP protocol corruption occurs.
4334             * @throws LSException If
4335             * <ul>
4336             * <li>There is no effect instance with numerical ID <code>instanceId</code>;
4337             * <li>There parameter index is invalid;
4338             * <li>The new value is out of range;
4339             * </ul>
4340             *
4341             * @see #getEffectInstanceInfo
4342             * @see #getEffectInstanceParameterInfo
4343             */
4344            public synchronized void
4345            setEffectInstanceParameter(int instanceId, int prmIndex, float value)
4346                                            throws IOException, LscpException, LSException
4347            {
4348                    String s = " " + instanceId + " " + prmIndex + " " + value;
4349                    retrieveIndex("SET EFFECT_INSTANCE_INPUT_CONTROL VALUE" + s);
4350            }
4351            /**
4352             * Gets the current amount of send effect chains on the specified audio output device.
4353             * @param audioDeviceId numerical ID of the audio output device.
4354             * @return The current amount of send effect chains or -1 if in "print only" mode.
4355             * @throws IOException If some I/O error occurs.
4356             * @throws LscpException If LSCP protocol corruption occurs.
4357             * @throws LSException If some other error occurs.
4358             */
4359            public synchronized int
4360            getSendEffectChainCount(int audioDeviceId) throws IOException, LscpException, LSException
4361            { return retrieveInt("GET SEND_EFFECT_CHAINS " + audioDeviceId); }
4362    
4363            /**
4364             * Gets the current list of send effect chains on the specified audio output device.
4365             * @param audioDeviceId The numerical ID of the audio output device.
4366             * @return An <code>EffectInstance</code> array
4367             * providing the current list of effect instances.
4368             * @throws IOException If some I/O error occurs.
4369             * @throws LscpException If LSCP protocol corruption occurs.
4370             */
4371            public synchronized EffectChain[]
4372            getSendEffectChains(int audioDeviceId) throws IOException, LscpException, LSException {
4373                    Integer[] idS = getSendEffectChainIDs(audioDeviceId);
4374                    if(getPrintOnlyMode()) return null;
4375    
4376                    EffectChain[] ecs = new EffectChain[idS.length];
4377    
4378                    for(int i = 0; i < ecs.length; i++) {
4379                            ecs[i] = getSendEffectChainInfo(audioDeviceId, idS[i]);
4380                            ecs[i].setChainId(idS[i]);
4381                    }
4382    
4383                    return ecs;
4384            }
4385    
4386            /**
4387             * Retrieves the current list of send effect
4388             * chains on the specified audio output device.
4389             * @param audioDeviceId The numerical ID of the audio output device.
4390             * @return An <code>Integer</code> array providing the numerical
4391             * IDs of all send effect chains on the specified audio output device.
4392             * @throws IOException If some I/O error occurs.
4393             * @throws LscpException If LSCP protocol corruption occurs.
4394             */
4395            public synchronized Integer[]
4396            getSendEffectChainIDs(int audioDeviceId) throws IOException, LscpException, LSException
4397            { return getIntegerList("LIST SEND_EFFECT_CHAINS " + audioDeviceId); }
4398    
4399            /**
4400             * Adds a send effect chain to the specified audio output device.
4401             * @param audioDeviceId The numerical ID of the audio output device.
4402             * @return The numerical ID of the new send effect chain.
4403             * @throws IOException If some I/O error occurs.
4404             * @throws LSException If the creation of the effect chain failed.
4405             * @throws LscpException If LSCP protocol corruption occurs.
4406             * @see #removeSendEffectChain
4407             * @see #getSendEffectChainInfo
4408             */
4409            public synchronized int
4410            addSendEffectChain(int audioDeviceId) throws IOException, LSException, LscpException
4411            { return retrieveIndex("ADD SEND_EFFECT_CHAIN " + audioDeviceId); }
4412    
4413            /**
4414             * Removes a send effect chain from an audio output device.
4415             * @param audioDeviceId The numerical ID of the audio output device.
4416             * @param chainId The numerical ID of the send effect chain to remove.
4417             * @throws LscpException If LSCP protocol corruption occurs.
4418             * @throws LSException If some other error occurs.
4419             * @see #addSendEffectChain
4420             */
4421            public synchronized void
4422            removeSendEffectChain(int audioDeviceId, int chainId) throws IOException, LSException, LscpException
4423            { retrieveIndex("REMOVE SEND_EFFECT_CHAIN " + audioDeviceId + " " + chainId); }
4424    
4425            /**
4426             * Gets the current information of a send effect chain.
4427             * @param audioDeviceId The numerical ID of the audio output device.
4428             * @param chainId The numerical ID of the send effect chain.
4429             * @return <code>EffectChain</code> object containing
4430             * the current informations about the specified effect chain.
4431             * @throws IOException If an I/O error occurs.
4432             * @throws LscpException If LSCP protocol corruption occurs.
4433             * @throws LSException If the audio device ID or the effect chain ID is invalid.
4434             */
4435            public synchronized EffectChain
4436            getSendEffectChainInfo(int audioDeviceId, int chainId)
4437                                    throws IOException, LscpException, LSException
4438            {
4439                    verifyConnection();
4440                    String str = " " + audioDeviceId + " " + chainId;
4441                    out.writeLine("GET SEND_EFFECT_CHAIN INFO" + str);
4442                    if(getPrintOnlyMode()) return null;
4443    
4444                    ResultSet rs = getMultiLineResultSet();
4445                    EffectChain chain = null;
4446    
4447                    for(String s : rs.getMultiLineResult()) {
4448                            if(s.startsWith("EFFECT_SEQUENCE: ")) {
4449                                    s = s.substring("EFFECT_SEQUENCE: ".length());
4450                                    Integer[] eis = parseIntList(s);
4451                                    EffectInstance[] instances = new EffectInstance[eis.length];
4452                                    for(int i = 0; i < eis.length; i++) {
4453                                            instances[i] = getEffectInstanceInfo(eis[i]);
4454                                    }
4455                                    chain = new EffectChain(instances);
4456                                    chain.setChainId(chainId);
4457                            }
4458                    }
4459    
4460                    return chain;
4461            }
4462    
4463            /**
4464             * Adds an unused effect instance to the end of a send effect chain.
4465             * @param audioDeviceId The numerical ID of the audio output device.
4466             * @param chainId The numerical ID of the send effect chain.
4467             * @param fxInstanceId The numerical ID of the effect instance to add.
4468             * @throws IOException If some I/O error occurs.
4469             * @throws LSException If invalid index is specified.
4470             * @throws LscpException If LSCP protocol corruption occurs.
4471             * @see #addSendEffectChain
4472             * @see #createEffectInstance
4473             */
4474            public synchronized void
4475            appendEffectInstance(int audioDeviceId, int chainId, int fxInstanceId)
4476                            throws IOException, LSException, LscpException
4477            {
4478                    String s = " " + audioDeviceId + " " + chainId + " " + fxInstanceId;
4479                    retrieveIndex("APPEND SEND_EFFECT_CHAIN EFFECT" + s);
4480            }
4481    
4482            /**
4483             * Adds an unused effect instance at a certain position of a send effect chain.
4484             * @param audioDeviceId The numerical ID of the audio output device.
4485             * @param chainId The numerical ID of the send effect chain.
4486             * @param pos The exact position in the effect chain where
4487             * the supplied effect shall be inserted to.
4488             * @param fxInstanceId The numerical ID of the effect instance to insert.
4489             * @throws IOException If some I/O error occurs.
4490             * @throws LSException If invalid index is specified.
4491             * @throws LscpException If LSCP protocol corruption occurs.
4492             * @see #addSendEffectChain
4493             * @see #createEffectInstance
4494             */
4495            public synchronized void
4496            insertEffectInstance(int audioDeviceId, int chainId, int pos, int fxInstanceId)
4497                            throws IOException, LSException, LscpException
4498            {
4499                    String s = " " + audioDeviceId + " " + chainId + " " + pos + " " + fxInstanceId;
4500                    retrieveIndex("INSERT SEND_EFFECT_CHAIN EFFECT" + s);
4501            }
4502    
4503            /**
4504             * Removes an effect instance from a certain position of a send effect chain.
4505             * @param audioDeviceId The numerical ID of the audio output device.
4506             * @param chainId The numerical ID of the send effect chain.
4507             * @param pos The exact position of the effect
4508             * instance to be removed from the effect chain.
4509             * @throws IOException If some I/O error occurs.
4510             * @throws LscpException If LSCP protocol corruption occurs.
4511             * @throws LSException If invalid index is specified.
4512             * @see #appendEffectInstance
4513             * @see #insertEffectInstance
4514             */
4515            public synchronized void
4516            removeEffectInstanceFromChain(int audioDeviceId, int chainId, int pos)
4517                            throws IOException, LSException, LscpException
4518            {
4519                    String s = " " + audioDeviceId + " " + chainId + " " + pos;
4520                    retrieveIndex("REMOVE SEND_EFFECT_CHAIN EFFECT" + s);
4521          }          }
4522                    
4523          /**          /**
# Line 3837  public class Client { Line 4531  public class Client {
4531           * @see #getSamplerChannels           * @see #getSamplerChannels
4532           */           */
4533          public synchronized void          public synchronized void
4534          editChannelInstrument(int samplerChn) throws IOException, LscpException, LSException {          editChannelInstrument(int samplerChn) throws IOException, LscpException, LSException
4535                  verifyConnection();          { retrieveIndex("EDIT CHANNEL INSTRUMENT " + samplerChn); }
4536                  out.writeLine("EDIT CHANNEL INSTRUMENT " + samplerChn);          
4537                  if(getPrintOnlyMode()) return;          /**
4538                             * Sends a MIDI event to this sampler channel.
4539                  ResultSet rs = getEmptyResultSet();           * @param samplerChn The sampler channel number.
4540             * @param type The type of MIDI message to send.
4541             * @throws IOException If some I/O error occurs.
4542             * @throws LscpException If LSCP protocol corruption occurs.
4543             * @throws LSException If <code>samplerChn</code> is not a valid channel number or if
4544             * there is no instrument loaded on the specified sampler channel.
4545             * @see #getSamplerChannels
4546             */
4547            public synchronized void
4548            sendChannelMidiData(int samplerChn, MidiDataEvent.Type type, int arg1, int arg2)
4549                                                    throws IOException, LscpException, LSException
4550            {
4551                    StringBuffer sb = new StringBuffer();
4552                    sb.append("SEND CHANNEL MIDI_DATA ");
4553                    sb.append(type).append(" ").append(samplerChn).append(" ");
4554                    sb.append(arg1).append(" ").append(arg2);
4555    
4556                    retrieveIndex(sb.toString());
4557          }          }
4558                    
4559            /**
4560             * Resets the specified sampler channel.
4561             *
4562             * @param samplerChn The sampler channel number.
4563             *
4564             * @throws IOException If some I/O error occurs.
4565             * @throws LscpException If LSCP protocol corruption occurs.
4566             * @throws LSException If <code>samplerChn</code> is not a valid channel number or if
4567             * there is no engine assigned yet to the specified sampler channel.
4568             * @see #getSamplerChannels
4569             */
4570            public synchronized void
4571            resetChannel(int samplerChn) throws IOException, LscpException, LSException
4572            { retrieveIndex("RESET CHANNEL " + samplerChn); }
4573            
4574                    
4575                    
4576          /**          /**
# Line 3855  public class Client { Line 4581  public class Client {
4581           * @throws LscpException If LSCP protocol corruption occurs.           * @throws LscpException If LSCP protocol corruption occurs.
4582           */           */
4583          public synchronized void          public synchronized void
4584          addDbDirectory(String dir) throws IOException, LSException, LscpException {          addDbDirectory(String dir) throws IOException, LSException, LscpException
4585                  verifyConnection();          { retrieveIndex("ADD DB_INSTRUMENT_DIRECTORY '" + conv(dir) + "'"); }
                 out.writeLine("ADD DB_INSTRUMENT_DIRECTORY '" + dir + "'");  
                 if(getPrintOnlyMode()) return;  
                   
                 ResultSet rs = getEmptyResultSet();  
         }  
4586                    
4587          /**          /**
4588           * Removes the specified directory from the instruments database.           * Removes the specified directory from the instruments database.
# Line 3872  public class Client { Line 4593  public class Client {
4593           * empty or if the removal of the directory failed.           * empty or if the removal of the directory failed.
4594           */           */
4595          public synchronized void          public synchronized void
4596          removeDbDirectory(String dir) throws IOException, LscpException, LSException {          removeDbDirectory(String dir) throws IOException, LscpException, LSException
4597                  removeDbDirectory(dir, false);          { removeDbDirectory(dir, false); }
         }  
4598                    
4599          /**          /**
4600           * Removes the specified directory from the instruments database.           * Removes the specified directory from the instruments database.
# Line 3887  public class Client { Line 4607  public class Client {
4607           */           */
4608          public synchronized void          public synchronized void
4609          removeDbDirectory(String dir, boolean force)          removeDbDirectory(String dir, boolean force)
4610                                  throws IOException, LscpException, LSException {                                  throws IOException, LscpException, LSException
4611                            {
                 verifyConnection();  
4612                  String s = "REMOVE DB_INSTRUMENT_DIRECTORY ";                  String s = "REMOVE DB_INSTRUMENT_DIRECTORY ";
4613                  if(force) s += "FORCE ";                  if(force) s += "FORCE ";
4614                  out.writeLine(s + "'" + dir + "'");                  retrieveIndex(s + "'" + conv(dir) + "'");
                 if(getPrintOnlyMode()) return;  
                   
                 ResultSet rs = getEmptyResultSet();  
4615          }          }
4616                    
4617          /**          /**
# Line 3915  public class Client { Line 4631  public class Client {
4631                  String cmd = "REMOVE DB_INSTRUMENT_DIRECTORY ";                  String cmd = "REMOVE DB_INSTRUMENT_DIRECTORY ";
4632                  if(force) cmd += "FORCE ";                  if(force) cmd += "FORCE ";
4633                                    
4634                  for(String s : dirs) out.writeLine(cmd + "'" + s + "'");                  for(String s : dirs) out.writeLine(cmd + "'" + conv(s) + "'");
4635                                    
4636                  if(getPrintOnlyMode()) return;                  if(getPrintOnlyMode()) return;
4637                                    
# Line 3953  public class Client { Line 4669  public class Client {
4669                  String s;                  String s;
4670                  if(recursive) s = "GET DB_INSTRUMENT_DIRECTORIES RECURSIVE '";                  if(recursive) s = "GET DB_INSTRUMENT_DIRECTORIES RECURSIVE '";
4671                  else s = "GET DB_INSTRUMENT_DIRECTORIES '";                  else s = "GET DB_INSTRUMENT_DIRECTORIES '";
4672                  out.writeLine(s + dir + "'");                  out.writeLine(s + conv(dir) + "'");
4673                  if(getPrintOnlyMode()) return -1;                  if(getPrintOnlyMode()) return -1;
4674                                    
4675                  s = getSingleLineResultSet().getResult();                  s = getSingleLineResultSet().getResult();
# Line 3972  public class Client { Line 4688  public class Client {
4688          public synchronized String[]          public synchronized String[]
4689          getDbDirectoryNames(String dir) throws IOException, LscpException, LSException {          getDbDirectoryNames(String dir) throws IOException, LscpException, LSException {
4690                  verifyConnection();                  verifyConnection();
4691                  out.writeLine("LIST DB_INSTRUMENT_DIRECTORIES '" + dir + "'");                  out.writeLine("LIST DB_INSTRUMENT_DIRECTORIES '" + conv(dir) + "'");
4692                  if(getPrintOnlyMode()) return null;                  if(getPrintOnlyMode()) return null;
4693                                    
4694                  String[] names = parseEscapedStringList(getSingleLineResultSet().getResult());                  String[] names = parseEscapedStringList(getSingleLineResultSet().getResult());
# Line 3993  public class Client { Line 4709  public class Client {
4709           */           */
4710          public synchronized DbDirectoryInfo          public synchronized DbDirectoryInfo
4711          getDbDirectoryInfo(String dir) throws IOException, LscpException, LSException {          getDbDirectoryInfo(String dir) throws IOException, LscpException, LSException {
4712                  verifyConnection();                  DbDirectoryInfo info = new DbDirectoryInfo();
4713                  out.writeLine("GET DB_INSTRUMENT_DIRECTORY INFO '" + dir + "'");                  if(!retrieveInfo("GET DB_INSTRUMENT_DIRECTORY INFO '" + conv(dir) + "'", info)) return null;
4714                  if(getPrintOnlyMode()) return null;  
                   
                 ResultSet rs = getMultiLineResultSet();  
                 DbDirectoryInfo info = new DbDirectoryInfo(rs.getMultiLineResult());  
4715                  if(dir.equals("/")) {                  if(dir.equals("/")) {
4716                          info.setName("/");                          info.setName("/");
4717                  } else {                  } else {
# Line 4027  public class Client { Line 4740  public class Client {
4740                  if(!hasEndingFileSeparator(dir)) dir += "/";                  if(!hasEndingFileSeparator(dir)) dir += "/";
4741                  DbDirectoryInfo[] infoS = new DbDirectoryInfo[dirS.length];                  DbDirectoryInfo[] infoS = new DbDirectoryInfo[dirS.length];
4742                  for(int i = 0; i < dirS.length; i++) {                  for(int i = 0; i < dirS.length; i++) {
4743                          infoS[i] = getDbDirectoryInfo(dir + toEscapedFileName(dirS[i]));                          infoS[i] = getDbDirectoryInfo(conv(dir) + toEscapedFsEntry(dirS[i]));
4744                  }                  }
4745                  return infoS;                  return infoS;
4746          }          }
# Line 4043  public class Client { Line 4756  public class Client {
4756           *           *
4757          public synchronized DbDirectoryInfo[]          public synchronized DbDirectoryInfo[]
4758          getDbDirectories(String dir) throws IOException, LscpException, LSException {          getDbDirectories(String dir) throws IOException, LscpException, LSException {
4759                  String[] dirS = getDbDirectoryNames(dir);                  String[] dirS = getDbDirectoryNames(conv(dir));
4760                  if(dirS.length == 0) return new DbDirectoryInfo[0];                  if(dirS.length == 0) return new DbDirectoryInfo[0];
4761                                    
4762                  if(dir.charAt(dir.length() - 1) != '/') dir += "/";                  if(dir.charAt(dir.length() - 1) != '/') dir += "/"; // FIXME:
4763                                    
4764                  for(int i = 0; i < dirS.length; i++) {                  for(int i = 0; i < dirS.length; i++) {
4765                          out.writeLine("GET DB_INSTRUMENT_DIRECTORY INFO '" + dir + dirS[i] + "'");                          out.writeLine("GET DB_INSTRUMENT_DIRECTORY INFO '" + conv(dir + dirS[i]) + "'");
4766                  }                  }
4767                                    
4768                  if(getPrintOnlyMode()) return null;                  if(getPrintOnlyMode()) return null;
# Line 4092  public class Client { Line 4805  public class Client {
4805           */           */
4806          public synchronized void          public synchronized void
4807          renameDbDirectory(String dir, String name) throws IOException, LSException, LscpException {          renameDbDirectory(String dir, String name) throws IOException, LSException, LscpException {
4808                  verifyConnection();                  name = toEscapedText(name);
4809                  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();  
4810          }          }
4811                    
4812          /**          /**
# Line 4109  public class Client { Line 4818  public class Client {
4818           * @throws LscpException If LSCP protocol corruption occurs.           * @throws LscpException If LSCP protocol corruption occurs.
4819           */           */
4820          public synchronized void          public synchronized void
4821          moveDbDirectory(String dir, String dst) throws IOException, LSException, LscpException {          moveDbDirectory(String dir, String dst) throws IOException, LSException, LscpException
4822                  verifyConnection();          { retrieveIndex("MOVE DB_INSTRUMENT_DIRECTORY '" + conv(dir) + "' '" + conv(dst) + "'"); }
                 out.writeLine("MOVE DB_INSTRUMENT_DIRECTORY '" + dir + "' '" + dst + "'");  
                 if(getPrintOnlyMode()) return;  
                   
                 ResultSet rs = getEmptyResultSet();  
         }  
4823                    
4824          /**          /**
4825           * Moves the specified directories into the specified location.           * Moves the specified directories into the specified location.
# Line 4129  public class Client { Line 4833  public class Client {
4833          moveDbDirectories(String dirs[], String dst) throws IOException, LSException, LscpException {          moveDbDirectories(String dirs[], String dst) throws IOException, LSException, LscpException {
4834                  verifyConnection();                  verifyConnection();
4835                  for(String s : dirs) {                  for(String s : dirs) {
4836                          out.writeLine("MOVE DB_INSTRUMENT_DIRECTORY '" + s + "' '" + dst + "'");                          out.writeLine("MOVE DB_INSTRUMENT_DIRECTORY '" + conv(s) + "' '" + conv(dst) + "'");
4837                  }                  }
4838                  if(getPrintOnlyMode()) return;                  if(getPrintOnlyMode()) return;
4839                                    
# Line 4145  public class Client { Line 4849  public class Client {
4849           * @throws LscpException If LSCP protocol corruption occurs.           * @throws LscpException If LSCP protocol corruption occurs.
4850           */           */
4851          public synchronized void          public synchronized void
4852          copyDbDirectory(String dir, String dst) throws IOException, LSException, LscpException {          copyDbDirectory(String dir, String dst) throws IOException, LSException, LscpException
4853                  verifyConnection();          { retrieveIndex("COPY DB_INSTRUMENT_DIRECTORY '" + conv(dir) + "' '" + conv(dst) + "'"); }
                 out.writeLine("COPY DB_INSTRUMENT_DIRECTORY '" + dir + "' '" + dst + "'");  
                 if(getPrintOnlyMode()) return;  
                   
                 ResultSet rs = getEmptyResultSet();  
         }  
4854                    
4855          /**          /**
4856           * Copies the specified directories into the specified location.           * Copies the specified directories into the specified location.
# Line 4165  public class Client { Line 4864  public class Client {
4864          copyDbDirectories(String[] dirs, String dst) throws IOException, LSException, LscpException {          copyDbDirectories(String[] dirs, String dst) throws IOException, LSException, LscpException {
4865                  verifyConnection();                  verifyConnection();
4866                  for(String s : dirs) {                  for(String s : dirs) {
4867                          out.writeLine("COPY DB_INSTRUMENT_DIRECTORY '" + s + "' '" + dst + "'");                          out.writeLine("COPY DB_INSTRUMENT_DIRECTORY '" + conv(s) + "' '" + conv(dst) + "'");
4868                  }                  }
4869                  if(getPrintOnlyMode()) return;                  if(getPrintOnlyMode()) return;
4870                                    
# Line 4182  public class Client { Line 4881  public class Client {
4881           */           */
4882          public synchronized void          public synchronized void
4883          setDbDirectoryDescription(String dir, String desc)          setDbDirectoryDescription(String dir, String desc)
4884                                  throws IOException, LSException, LscpException {                                  throws IOException, LSException, LscpException
4885                            {
                 verifyConnection();  
4886                  String s = "SET DB_INSTRUMENT_DIRECTORY DESCRIPTION '";                  String s = "SET DB_INSTRUMENT_DIRECTORY DESCRIPTION '";
4887                  out.writeLine(s + dir + "' '" + toEscapedString(desc) + "'");                  retrieveIndex(s + conv(dir) + "' '" + toEscapedText(desc) + "'");
                 if(getPrintOnlyMode()) return;  
                   
                 ResultSet rs = getEmptyResultSet();  
4888          }          }
4889                    
4890          public static enum ScanMode {          public static enum ScanMode {
# Line 4230  public class Client { Line 4925  public class Client {
4925           */           */
4926          public synchronized int          public synchronized int
4927          addDbInstrument(String dbDir, String filePath, int instrIndex, boolean background)          addDbInstrument(String dbDir, String filePath, int instrIndex, boolean background)
4928                                          throws IOException, LSException, LscpException {                                          throws IOException, LSException, LscpException
4929                            {
                 verifyConnection();  
4930                  String s = "ADD DB_INSTRUMENTS";                  String s = "ADD DB_INSTRUMENTS";
4931                  if(background) s += " NON_MODAL";                  if(background) s += " NON_MODAL";
4932                  s += " '" + dbDir + "' '" + filePath + "' ";                  s += " '" + conv(dbDir) + "' '" + conv(filePath) + "' ";
4933                  out.writeLine(s + String.valueOf(instrIndex));                  return retrieveIndex(s + String.valueOf(instrIndex));
                 if(getPrintOnlyMode()) return -1;  
                   
                 ResultSet rs = getEmptyResultSet();  
                 return rs.getIndex();  
4934          }          }
4935                    
4936          /**          /**
# Line 4277  public class Client { Line 4967  public class Client {
4967           */           */
4968          public synchronized int          public synchronized int
4969          addDbInstruments(String dbDir, String filePath, boolean background)          addDbInstruments(String dbDir, String filePath, boolean background)
4970                                          throws IOException, LSException, LscpException {                                          throws IOException, LSException, LscpException
4971                            {
                 verifyConnection();  
4972                  String s = "ADD DB_INSTRUMENTS";                  String s = "ADD DB_INSTRUMENTS";
4973                  if(background) s += " NON_MODAL";                  if(background) s += " NON_MODAL";
4974                  out.writeLine(s + " '" + dbDir + "' '" + filePath + "'");                  return retrieveIndex(s + " '" + conv(dbDir) + "' '" + conv(filePath) + "'");
                 if(getPrintOnlyMode()) return -1;  
                   
                 ResultSet rs = getEmptyResultSet();  
                 return rs.getIndex();  
4975          }          }
4976                    
4977          /**          /**
# Line 4349  public class Client { Line 5034  public class Client {
5034          addDbInstruments(ScanMode mode, String dbDir, String fsDir, boolean background)          addDbInstruments(ScanMode mode, String dbDir, String fsDir, boolean background)
5035                                          throws IOException, LSException, LscpException {                                          throws IOException, LSException, LscpException {
5036                                    
5037                  verifyConnection();                  return addDbInstruments(mode, dbDir, fsDir, background, false);
5038            }
5039            
5040            /**
5041             * Adds the instruments in the specified file system directory
5042             * to the specified instruments database directory.
5043             * @param mode Determines the scanning mode. If RECURSIVE is
5044             * specified, all supported instruments in the specified file system
5045             * direcotry will be added to the specified instruments database
5046             * directory, including the instruments in subdirectories
5047             * of the supplied directory. If NON_RECURSIVE is specified,
5048             * the instruments in the subdirectories will not be processed.
5049             * If FLAT is specified, all supported instruments in the specified
5050             * file system direcotry will be added, including the instruments in
5051             * subdirectories of the supplied directory, but the respective
5052             * subdirectory structure will not be recreated in the instruments
5053             * database and all instruments will be added directly in the
5054             * specified database directory.
5055             * @param dbDir The absolute path name of the database directory
5056             * in which the supported instruments will be added.
5057             * @param fsDir The absolute path name of the file system directory.
5058             * @param background If <code>true</code>, the scan will be done
5059             * in background and this method may return before the job is finished.
5060             * @param insDir If <code>true</code> a drieectory is created for each
5061             * instrument file.
5062             * @return If <code>background</code> is <code>true</code>, the ID
5063             * of the scan job.
5064             * @throws IOException If some I/O error occurs.
5065             * @throws LSException If the operation failed.
5066             * @throws LscpException If LSCP protocol corruption occurs.
5067             * @see #addInstrumentsDbListener
5068             */
5069            public synchronized int
5070            addDbInstruments(ScanMode mode, String dbDir, String fsDir, boolean background, boolean insDir)
5071                                            throws IOException, LSException, LscpException
5072            {
5073                  StringBuffer sb = new StringBuffer("ADD DB_INSTRUMENTS");                  StringBuffer sb = new StringBuffer("ADD DB_INSTRUMENTS");
5074                  if(background) sb.append(" NON_MODAL");                  if(background) sb.append(" NON_MODAL");
5075                                    
# Line 4364  public class Client { Line 5084  public class Client {
5084                                  sb.append(" FLAT");                                  sb.append(" FLAT");
5085                                  break;                                  break;
5086                  }                  }
5087                    if(insDir)
5088                            sb.append(" FILE_AS_DIR");
5089                                    
5090                  sb.append(" '").append(dbDir).append("' '");                  sb.append(" '").append(conv(dbDir)).append("' '");
5091                  sb.append(fsDir).append("'");                  sb.append(conv(fsDir)).append("'");
5092                  out.writeLine(sb.toString());                  return retrieveIndex(sb.toString());
                 if(getPrintOnlyMode()) return -1;  
                   
                 ResultSet rs = getEmptyResultSet();  
                 return rs.getIndex();  
5093          }          }
5094            
5095          /**          /**
5096           * Removes the specified instrument from the instruments database.           * Removes the specified instrument from the instruments database.
5097           * @param instr The absolute path name of the instrument to remove.           * @param instr The absolute path name of the instrument to remove.
# Line 4382  public class Client { Line 5100  public class Client {
5100           * @throws LSException If the removing of the instrument failed.           * @throws LSException If the removing of the instrument failed.
5101           */           */
5102          public synchronized void          public synchronized void
5103          removeDbInstrument(String instr) throws IOException, LscpException, LSException {          removeDbInstrument(String instr) throws IOException, LscpException, LSException
5104                            { retrieveIndex("REMOVE DB_INSTRUMENT '" + conv(instr) + "'"); }
                 verifyConnection();  
                 out.writeLine("REMOVE DB_INSTRUMENT '" + instr + "'");  
                 if(getPrintOnlyMode()) return;  
                   
                 ResultSet rs = getEmptyResultSet();  
         }  
5105                    
5106          /**          /**
5107           * Removes the specified instruments from the instruments database.           * Removes the specified instruments from the instruments database.
# Line 4402  public class Client { Line 5114  public class Client {
5114          removeDbInstruments(String[] instrs) throws IOException, LscpException, LSException {          removeDbInstruments(String[] instrs) throws IOException, LscpException, LSException {
5115                  verifyConnection();                  verifyConnection();
5116                  for(String s : instrs) {                  for(String s : instrs) {
5117                          out.writeLine("REMOVE DB_INSTRUMENT '" + s + "'");                          out.writeLine("REMOVE DB_INSTRUMENT '" + conv(s) + "'");
5118                  }                  }
5119                  if(getPrintOnlyMode()) return;                  if(getPrintOnlyMode()) return;
5120                                    
# Line 4440  public class Client { Line 5152  public class Client {
5152                  String s;                  String s;
5153                  if(recursive) s = "GET DB_INSTRUMENTS RECURSIVE '";                  if(recursive) s = "GET DB_INSTRUMENTS RECURSIVE '";
5154                  else s = "GET DB_INSTRUMENTS '";                  else s = "GET DB_INSTRUMENTS '";
5155                  out.writeLine(s + dir + "'");                  out.writeLine(s + conv(dir) + "'");
5156                  if(getPrintOnlyMode()) return -1;                  if(getPrintOnlyMode()) return -1;
5157                                    
5158                  s = getSingleLineResultSet().getResult();                  s = getSingleLineResultSet().getResult();
# Line 4459  public class Client { Line 5171  public class Client {
5171          public synchronized String[]          public synchronized String[]
5172          getDbInstrumentNames(String dir) throws IOException, LscpException, LSException {          getDbInstrumentNames(String dir) throws IOException, LscpException, LSException {
5173                  verifyConnection();                  verifyConnection();
5174                  out.writeLine("LIST DB_INSTRUMENTS '" + dir + "'");                  out.writeLine("LIST DB_INSTRUMENTS '" + conv(dir) + "'");
5175                  if(getPrintOnlyMode()) return null;                  if(getPrintOnlyMode()) return null;
5176                                    
5177                  String[] names = parseEscapedStringList(getSingleLineResultSet().getResult());                  String[] names = parseEscapedStringList(getSingleLineResultSet().getResult());
# Line 4480  public class Client { Line 5192  public class Client {
5192           */           */
5193          public synchronized DbInstrumentInfo          public synchronized DbInstrumentInfo
5194          getDbInstrumentInfo(String instr) throws IOException, LscpException, LSException {          getDbInstrumentInfo(String instr) throws IOException, LscpException, LSException {
5195                  verifyConnection();                  DbInstrumentInfo info = new DbInstrumentInfo();
5196                  out.writeLine("GET DB_INSTRUMENT INFO '" + instr + "'");                  if(!retrieveInfo("GET DB_INSTRUMENT INFO '" + conv(instr) + "'", info)) return null;
5197                  if(getPrintOnlyMode()) return null;  
                   
                 ResultSet rs = getMultiLineResultSet();  
                 DbInstrumentInfo info = new DbInstrumentInfo(rs.getMultiLineResult());  
5198                  String s = getParentDirectory(instr);                  String s = getParentDirectory(instr);
5199                  if(s != null) info.setDirectoryPath(s);                  if(s != null) info.setDirectoryPath(s);
5200                  s = getFileName(instr);                  s = getFileName(instr);
# Line 4510  public class Client { Line 5219  public class Client {
5219                                    
5220                  DbInstrumentInfo[] infoS = new DbInstrumentInfo[instrS.length];                  DbInstrumentInfo[] infoS = new DbInstrumentInfo[instrS.length];
5221                  for(int i = 0; i < instrS.length; i++) {                  for(int i = 0; i < instrS.length; i++) {
5222                          infoS[i] = getDbInstrumentInfo(dir + toEscapedFileName(instrS[i]));                          infoS[i] = getDbInstrumentInfo(conv(dir) + toEscapedFsEntry(instrS[i]));
5223                  }                  }
5224                  return infoS;                  return infoS;
5225          }          }
# Line 4529  public class Client { Line 5238  public class Client {
5238                  String[] instrS = getDbInstrumentNames(dir);                  String[] instrS = getDbInstrumentNames(dir);
5239                  if(instrS.length == 0) return new DbInstrumentInfo[0];                  if(instrS.length == 0) return new DbInstrumentInfo[0];
5240                                    
5241                  if(dir.charAt(dir.length() - 1) != '/') dir += "/";                  if(dir.charAt(dir.length() - 1) != '/') dir += "/"; FIXME:
5242                                    
5243                  for(int i = 0; i < instrS.length; i++) {                  for(int i = 0; i < instrS.length; i++) {
5244                          out.writeLine("GET DB_INSTRUMENT INFO '" + dir + instrS[i] + "'");                          out.writeLine("GET DB_INSTRUMENT INFO '" + conv(dir) + instrS[i] + "'");
5245                  }                  }
5246                                    
5247                  if(getPrintOnlyMode()) return null;                  if(getPrintOnlyMode()) return null;
# Line 4575  public class Client { Line 5284  public class Client {
5284           */           */
5285          public synchronized void          public synchronized void
5286          renameDbInstrument(String instr, String name)          renameDbInstrument(String instr, String name)
5287                                  throws IOException, LSException, LscpException {                                  throws IOException, LSException, LscpException
5288                            {
5289                  verifyConnection();                  name = toEscapedText(name);
5290                  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();  
5291          }          }
5292                    
5293          /**          /**
# Line 4594  public class Client { Line 5299  public class Client {
5299           * @throws LscpException If LSCP protocol corruption occurs.           * @throws LscpException If LSCP protocol corruption occurs.
5300           */           */
5301          public synchronized void          public synchronized void
5302          moveDbInstrument(String instr, String dst) throws IOException, LSException, LscpException {          moveDbInstrument(String instr, String dst) throws IOException, LSException, LscpException
5303                  verifyConnection();          { retrieveIndex("MOVE DB_INSTRUMENT '" + conv(instr) + "' '" + conv(dst) + "'"); }
                 out.writeLine("MOVE DB_INSTRUMENT '" + instr + "' '" + dst + "'");  
                 if(getPrintOnlyMode()) return;  
                   
                 ResultSet rs = getEmptyResultSet();  
         }  
5304                    
5305          /**          /**
5306           * Moves the specified instruments into the specified location.           * Moves the specified instruments into the specified location.
# Line 4614  public class Client { Line 5314  public class Client {
5314          moveDbInstruments(String[] instrs, String dst) throws IOException, LSException, LscpException {          moveDbInstruments(String[] instrs, String dst) throws IOException, LSException, LscpException {
5315                  verifyConnection();                  verifyConnection();
5316                  for(String s : instrs) {                  for(String s : instrs) {
5317                          out.writeLine("MOVE DB_INSTRUMENT '" + s + "' '" + dst + "'");                          out.writeLine("MOVE DB_INSTRUMENT '" + conv(s) + "' '" + conv(dst) + "'");
5318                  }                  }
5319                  if(getPrintOnlyMode()) return;                  if(getPrintOnlyMode()) return;
5320                                    
# Line 4630  public class Client { Line 5330  public class Client {
5330           * @throws LscpException If LSCP protocol corruption occurs.           * @throws LscpException If LSCP protocol corruption occurs.
5331           */           */
5332          public synchronized void          public synchronized void
5333          copyDbInstrument(String instr, String dst) throws IOException, LSException, LscpException {          copyDbInstrument(String instr, String dst) throws IOException, LSException, LscpException
5334                  verifyConnection();          { retrieveIndex("COPY DB_INSTRUMENT '" + conv(instr) + "' '" + conv(dst) + "'"); }
                 out.writeLine("COPY DB_INSTRUMENT '" + instr + "' '" + dst + "'");  
                 if(getPrintOnlyMode()) return;  
                   
                 ResultSet rs = getEmptyResultSet();  
         }  
5335                    
5336          /**          /**
5337           * Copies the specified instruments into the specified location.           * Copies the specified instruments into the specified location.
# Line 4650  public class Client { Line 5345  public class Client {
5345          copyDbInstruments(String[] instrs, String dst) throws IOException, LSException, LscpException {          copyDbInstruments(String[] instrs, String dst) throws IOException, LSException, LscpException {
5346                  verifyConnection();                  verifyConnection();
5347                  for(String s : instrs) {                  for(String s : instrs) {
5348                          out.writeLine("COPY DB_INSTRUMENT '" + s + "' '" + dst + "'");                          out.writeLine("COPY DB_INSTRUMENT '" + conv(s) + "' '" + conv(dst) + "'");
5349                  }                  }
5350                  if(getPrintOnlyMode()) return;                  if(getPrintOnlyMode()) return;
5351                                    
# Line 4667  public class Client { Line 5362  public class Client {
5362           */           */
5363          public synchronized void          public synchronized void
5364          setDbInstrumentDescription(String instr, String desc)          setDbInstrumentDescription(String instr, String desc)
5365                                  throws IOException, LSException, LscpException {                                  throws IOException, LSException, LscpException
5366                            {
5367                  verifyConnection();                  desc = toEscapedText(desc);
5368                  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();  
5369          }          }
5370                    
5371          /**          /**
5372             * Substitutes all occurrences of the instrument file
5373             * <code>oldPath</code> in the database, with <code>newPath</code>.
5374             * @param oldPath The absolute path name of the instrument file to substitute.
5375             * @param newPath The new absolute path name.
5376             * @throws IOException If some I/O error occurs.
5377             * @throws LSException If the operation failed.
5378             * @throws LscpException If LSCP protocol corruption occurs.
5379             */
5380            public synchronized void
5381            setDbInstrumentFilePath(String oldPath, String newPath)
5382                                    throws IOException, LSException, LscpException
5383            { retrieveIndex("SET DB_INSTRUMENT FILE_PATH '" + conv(oldPath) + "' '" + conv(newPath) + "'"); }
5384            
5385            /**
5386           * Finds all directories in the specified directory           * Finds all directories in the specified directory
5387           * that corresponds to the specified search criterias.           * that corresponds to the specified search criterias.
5388           * @param dir The absolute path name of the directory to search.           * @param dir The absolute path name of the directory to search.
# Line 4715  public class Client { Line 5420  public class Client {
5420                  StringBuffer sb = new StringBuffer();                  StringBuffer sb = new StringBuffer();
5421                  sb.append("FIND DB_INSTRUMENT_DIRECTORIES");                  sb.append("FIND DB_INSTRUMENT_DIRECTORIES");
5422                  if(nonRecursive) sb.append(" NON_RECURSIVE");                  if(nonRecursive) sb.append(" NON_RECURSIVE");
5423                  sb.append(" '").append(dir).append("'");                  sb.append(" '").append(conv(dir)).append("'");
5424                                    
5425                  if(query.name != null && query.name.length() > 0) {                  if(query.name != null && query.name.length() > 0) {
5426                          sb.append(" NAME='").append(toEscapedString(query.name)).append("'");                          sb.append(" NAME='").append(toEscapedText(query.name)).append("'");
5427                  }                  }
5428                                    
5429                  String s = query.getCreatedAfter();                  String s = query.getCreatedAfter();
# Line 4743  public class Client { Line 5448  public class Client {
5448                                    
5449                  if(query.description != null && query.description.length() > 0) {                  if(query.description != null && query.description.length() > 0) {
5450                          sb.append(" DESCRIPTION='");                          sb.append(" DESCRIPTION='");
5451                          sb.append(toEscapedString(query.description)).append("'");                          sb.append(toEscapedText(query.description)).append("'");
5452                  }                  }
5453                                    
5454                  out.writeLine(sb.toString());                  out.writeLine(sb.toString());
# Line 4796  public class Client { Line 5501  public class Client {
5501                  StringBuffer sb = new StringBuffer();                  StringBuffer sb = new StringBuffer();
5502                  sb.append("FIND DB_INSTRUMENTS");                  sb.append("FIND DB_INSTRUMENTS");
5503                  if(nonRecursive) sb.append(" NON_RECURSIVE");                  if(nonRecursive) sb.append(" NON_RECURSIVE");
5504                  sb.append(" '").append(dir).append("'");                  sb.append(" '").append(conv(dir)).append("'");
5505                                    
5506                  if(query.name != null && query.name.length() > 0) {                  if(query.name != null && query.name.length() > 0) {
5507                          sb.append(" NAME='").append(toEscapedString(query.name)).append("'");                          sb.append(" NAME='").append(toEscapedText(query.name)).append("'");
5508                  }                  }
5509                                    
5510                  if(query.formatFamilies.size() > 0) {                  if(query.formatFamilies.size() > 0) {
# Line 4840  public class Client { Line 5545  public class Client {
5545                                    
5546                  if(query.description != null && query.description.length() > 0) {                  if(query.description != null && query.description.length() > 0) {
5547                          sb.append(" DESCRIPTION='");                          sb.append(" DESCRIPTION='");
5548                          sb.append(toEscapedString(query.description)).append("'");                          sb.append(toEscapedText(query.description)).append("'");
5549                  }                  }
5550                                    
5551                  if(query.instrumentType != DbSearchQuery.InstrumentType.BOTH) {                  if(query.instrumentType != DbSearchQuery.InstrumentType.BOTH) {
# Line 4853  public class Client { Line 5558  public class Client {
5558                  }                  }
5559                                    
5560                  if(query.product != null && query.product.length() > 0) {                  if(query.product != null && query.product.length() > 0) {
5561                          sb.append(" PRODUCT='").append(toEscapedString(query.product)).append("'");                          sb.append(" PRODUCT='").append(toEscapedText(query.product)).append("'");
5562                  }                  }
5563                                    
5564                  if(query.artists != null && query.artists.length() > 0) {                  if(query.artists != null && query.artists.length() > 0) {
5565                          sb.append(" ARTISTS='").append(toEscapedString(query.artists)).append("'");                          sb.append(" ARTISTS='").append(toEscapedText(query.artists)).append("'");
5566                  }                  }
5567                                    
5568                  if(query.keywords != null && query.keywords.length() > 0) {                  if(query.keywords != null && query.keywords.length() > 0) {
5569                          sb.append(" KEYWORDS='");                          sb.append(" KEYWORDS='");
5570                          sb.append(toEscapedString(query.keywords)).append("'");                          sb.append(toEscapedText(query.keywords)).append("'");
5571                  }                  }
5572                                    
5573                  out.writeLine(sb.toString());                  out.writeLine(sb.toString());
# Line 4878  public class Client { Line 5583  public class Client {
5583          }          }
5584                    
5585          /**          /**
5586             * Returns a list of all instrument files in the database
5587             * that that don't exist in the filesystem.
5588             * @throws IOException If some I/O error occurs.
5589             * @throws LscpException If LSCP protocol corruption occurs.
5590             * @throws LSException If other error occurs.
5591             */
5592            public synchronized String[]
5593            findLostDbInstrumentFiles() throws IOException, LscpException, LSException {
5594                    
5595                    verifyConnection();
5596                    out.writeLine("FIND LOST DB_INSTRUMENT_FILES");
5597                    if(getPrintOnlyMode()) return null;
5598                    
5599                    return parseEscapedStringList(getSingleLineResultSet().getResult());
5600            }
5601            
5602            /**
5603           * Gets status information about the specified job.           * Gets status information about the specified job.
5604           * @param jobId The ID of the job.           * @param jobId The ID of the job.
5605           * @return A <code>ScanJobInfo</code> instance providing information           * @return A <code>ScanJobInfo</code> instance providing information
# Line 4888  public class Client { Line 5610  public class Client {
5610           */           */
5611          public synchronized ScanJobInfo          public synchronized ScanJobInfo
5612          getDbInstrumentsJobInfo(int jobId) throws IOException, LscpException, LSException {          getDbInstrumentsJobInfo(int jobId) throws IOException, LscpException, LSException {
5613                  verifyConnection();                  ScanJobInfo info = new ScanJobInfo();
5614                  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());  
5615                                    
5616                  return info;                  return info;
5617          }          }
# Line 4906  public class Client { Line 5624  public class Client {
5624           * @throws LSException If the formatting of the instruments database failed.           * @throws LSException If the formatting of the instruments database failed.
5625           */           */
5626          public synchronized void          public synchronized void
5627          formatInstrumentsDb() throws IOException, LscpException, LSException {          formatInstrumentsDb() throws IOException, LscpException, LSException
5628                  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();  
         }  
5629                    
5630          /**          /**
5631           * Resets the whole sampler.           * Resets the whole sampler.
# Line 4952  public class Client { Line 5645  public class Client {
5645                    
5646          /**          /**
5647           * Gets the current number of all active streams.           * Gets the current number of all active streams.
5648           * @return The current number of all active streams.           * @return The current number of all active streams or -1 if in "print only" mode.
5649           * @throws IOException If some I/O error occurs.           * @throws IOException If some I/O error occurs.
5650           * @throws LscpException If LSCP protocol corruption occurs.           * @throws LscpException If LSCP protocol corruption occurs.
5651           * @throws LSException If some other error occurs.           * @throws LSException If some other error occurs.
5652           */           */
5653          public synchronized int          public synchronized int
5654          getTotalStreamCount() throws IOException, LscpException, LSException {          getTotalStreamCount() throws IOException, LscpException, LSException {
5655                  verifyConnection();                  return retrieveInt("GET TOTAL_STREAM_COUNT");
                 out.writeLine("GET TOTAL_STREAM_COUNT");  
                 if(getPrintOnlyMode()) return -1;  
                   
                 String s = getSingleLineResultSet().getResult();  
                 return parseInt(s);  
5656          }          }
5657                    
5658          /**          /**
5659           * Gets the current number of all active voices.           * Gets the current number of all active voices.
5660           * @return The current number of all active voices.           * @return The current number of all active voices or -1 if in "print only" mode.
5661           * @throws IOException If some I/O error occurs.           * @throws IOException If some I/O error occurs.
5662           * @throws LscpException If LSCP protocol corruption occurs.           * @throws LscpException If LSCP protocol corruption occurs.
5663           * @throws LSException If some other error occurs.           * @throws LSException If some other error occurs.
5664           */           */
5665          public synchronized int          public synchronized int
5666          getTotalVoiceCount() throws IOException, LscpException, LSException {          getTotalVoiceCount() throws IOException, LscpException, LSException {
5667                  verifyConnection();                  return retrieveInt("GET TOTAL_VOICE_COUNT");
                 out.writeLine("GET TOTAL_VOICE_COUNT");  
                 if(getPrintOnlyMode()) return -1;  
                   
                 String s = getSingleLineResultSet().getResult();  
                 return parseInt(s);  
5668          }          }
5669                    
5670          /**          /**
5671           * Gets the maximum number of active voices.           * Gets the maximum number of active voices.
5672           * @return The maximum number of active voices.           * @return The maximum number of active voices or -1 if in "print only" mode.
5673           * @throws IOException If some I/O error occurs.           * @throws IOException If some I/O error occurs.
5674           * @throws LscpException If LSCP protocol corruption occurs.           * @throws LscpException If LSCP protocol corruption occurs.
5675           * @throws LSException If some other error occurs.           * @throws LSException If some other error occurs.
5676           */           */
5677          public synchronized int          public synchronized int
5678          getTotalVoiceCountMax() throws IOException, LscpException, LSException {          getTotalVoiceCountMax() throws IOException, LscpException, LSException {
5679                  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);  
5680          }          }
5681                    
5682          /**          /**
# Line 5013  public class Client { Line 5691  public class Client {
5691           */           */
5692          public synchronized ServerInfo          public synchronized ServerInfo
5693          getServerInfo() throws IOException, LscpException, LSException {          getServerInfo() throws IOException, LscpException, LSException {
5694                  verifyConnection();                  ServerInfo info = new ServerInfo();
5695                  out.writeLine("GET SERVER INFO");                  if(!retrieveInfo("GET SERVER INFO", info)) return null;
                 if(getPrintOnlyMode()) return null;  
5696                                    
5697                  ResultSet rs = getMultiLineResultSet();                  return info;
                 return new ServerInfo(rs.getMultiLineResult());  
5698          }          }
5699                    
5700          /**          /**
5701           * Gets the golobal volume of the sampler.           * Gets the global volume of the sampler.
5702           * @return The golobal volume of the sampler.           * @return The global volume of the sampler.
5703           * @throws IOException If some I/O error occurs.           * @throws IOException If some I/O error occurs.
5704           * @throws LscpException If LSCP protocol corruption occurs.           * @throws LscpException If LSCP protocol corruption occurs.
5705           * @throws LSException If some other error occurs.           * @throws LSException If some other error occurs.
# Line 5047  public class Client { Line 5723  public class Client {
5723           * @see #getVolume           * @see #getVolume
5724           */           */
5725          public synchronized void          public synchronized void
5726          setVolume(float volume) throws IOException, LscpException, LSException {          setVolume(float volume) throws IOException, LscpException, LSException
5727            { retrieveIndex("SET VOLUME " + volume); }
5728                    
5729                  verifyConnection();          /**
5730                  out.writeLine("SET VOLUME " + volume);           * Gets the global sampler-wide limit of maximum voices.
5731                  if(getPrintOnlyMode()) return;           * @return The global sampler-wide limit of maximum voices or -1 if in "print only" mode.
5732                             * @throws IOException If some I/O error occurs.
5733                  ResultSet rs = getEmptyResultSet();           * @throws LscpException If LSCP protocol corruption occurs.
5734             * @throws LSException If some other error occurs.
5735             */
5736            public synchronized int
5737            getGlobalVoiceLimit() throws IOException, LscpException, LSException {
5738                    return retrieveInt("GET VOICES");
5739          }          }
5740                    
5741          /**          /**
5742             * Sets the global sampler-wide limit of maximum voices.
5743             * @param maxVoices The new global limit of maximum voices.
5744             * @throws IOException If some I/O error occurs.
5745             * @throws LscpException If LSCP protocol corruption occurs.
5746             * @throws LSException If some other error occurs.
5747             * @see #getVolume
5748             */
5749            public synchronized void
5750            setGlobalVoiceLimit(int maxVoices) throws IOException, LscpException, LSException
5751            { retrieveIndex("SET VOICES " + maxVoices); }
5752            
5753            /**
5754             * Gets the global sampler-wide limit of maximum disk streams.
5755             * @return The global sampler-wide limit of maximum disk streams
5756             *  or -1 if in "print only" mode.
5757             * @throws IOException If some I/O error occurs.
5758             * @throws LscpException If LSCP protocol corruption occurs.
5759             * @throws LSException If some other error occurs.
5760             */
5761            public synchronized int
5762            getGlobalStreamLimit() throws IOException, LscpException, LSException {
5763                    return retrieveInt("GET STREAMS");
5764            }
5765            
5766            /**
5767             * Sets the global sampler-wide limit for maximum disk streams.
5768             * @param maxVoices The new global limit of maximum disk streams.
5769             * @throws IOException If some I/O error occurs.
5770             * @throws LscpException If LSCP protocol corruption occurs.
5771             * @throws LSException If some other error occurs.
5772             * @see #getVolume
5773             */
5774            public synchronized void
5775            setGlobalStreamLimit(int maxStreams) throws IOException, LscpException, LSException
5776            { retrieveIndex("SET STREAMS " + maxStreams); }
5777            
5778            /**
5779           * Gets the number of instruments in the specified instrument file.           * Gets the number of instruments in the specified instrument file.
5780           * @param filename The absolute path name of the instrument file.           * @param filename The absolute path name of the instrument file.
5781           * @return The number of instruments in the specified instrument file.           * @return The number of instruments in the specified instrument file
5782             *  or -1 if in "print only" mode.
5783           * @throws IOException If some I/O error occurs.           * @throws IOException If some I/O error occurs.
5784           * @throws LscpException If LSCP protocol corruption occurs.           * @throws LscpException If LSCP protocol corruption occurs.
5785           * @throws LSException If the file is not found, or other error occur.           * @throws LSException If the file is not found, or other error occur.
5786           */           */
5787          public synchronized int          public synchronized int
5788          getFileInstrumentCount(String filename) throws IOException, LscpException, LSException {          getFileInstrumentCount(String filename) throws IOException, LscpException, LSException {
5789                  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);  
5790          }          }
5791                    
5792          /**          /**
# Line 5086  public class Client { Line 5801  public class Client {
5801          public synchronized Instrument          public synchronized Instrument
5802          getFileInstrumentInfo(String filename, int instrIdx)          getFileInstrumentInfo(String filename, int instrIdx)
5803                                  throws IOException, LscpException, LSException {                                  throws IOException, LscpException, LSException {
5804                    
5805                  verifyConnection();                  FileInstrument instr = new FileInstrument();
5806                  out.writeLine("GET FILE INSTRUMENT INFO '" + filename + "' " + String.valueOf(instrIdx));                  String cmd = "GET FILE INSTRUMENT INFO '" + conv(filename) + "' " + String.valueOf(instrIdx);
5807                  if(getPrintOnlyMode()) return null;                  if(!retrieveInfo(cmd, instr)) return null;
                   
                 ResultSet rs = getMultiLineResultSet();  
                 Instrument instr = new FileInstrument(rs.getMultiLineResult()) { };  
5808                                    
5809                  return instr;                  return instr;
5810          }          }
# Line 5119  public class Client { Line 5831  public class Client {
5831          }          }
5832                    
5833          private static class FileInstrument extends AbstractInstrument {          private static class FileInstrument extends AbstractInstrument {
5834                  FileInstrument(String[] resultSet) throws LscpException {                  FileInstrument() { }
                         super(resultSet);  
                 }  
5835                                    
5836                  public String                  public String
5837                  getEngine() {                  getEngine() {
# Line 5129  public class Client { Line 5839  public class Client {
5839                          return getFormatFamily();                          return getFormatFamily();
5840                  }                  }
5841                                    
5842                    @Override
5843                  public boolean                  public boolean
5844                  parse(String s) throws LscpException {                  parse(String s) throws LscpException {
5845                          if(s.startsWith("PRODUCT: ") || s.startsWith("ARTISTS: ")) return true;                          if(s.startsWith("PRODUCT: ") || s.startsWith("ARTISTS: ")) return true;
# Line 5157  public class Client { Line 5868  public class Client {
5868                          throw new LSException(0, s, details);                          throw new LSException(0, s, details);
5869                  }                  }
5870          }          }
5871    
5872            /**
5873             * Retrieves a list of integers.
5874             * @throws IOException If some I/O error occurs.
5875             * @throws LscpException If LSCP protocol corruption occurs.
5876             */
5877            private Integer[]
5878            getIntegerList(String lscpCmd) throws IOException, LscpException, LSException {
5879                    verifyConnection();
5880                    out.writeLine(lscpCmd);
5881                    if(getPrintOnlyMode()) return null;
5882    
5883                    return parseIntList(getSingleLineResultSet().getResult());
5884            }
5885    
5886            private boolean
5887            retrieveInfo(String lscpCmd, Parseable p) throws IOException, LscpException, LSException {
5888                    verifyConnection();
5889                    out.writeLine(lscpCmd);
5890                    if(getPrintOnlyMode()) return false;
5891    
5892                    ResultSet rs = getMultiLineResultSet();
5893    
5894                    for(String s : rs.getMultiLineResult()) {
5895                            if(!p.parse(s)) Client.getLogger().info(LscpI18n.getLogMsg("unknownLine", s));
5896                    }
5897    
5898                    return true;
5899            }
5900    
5901            private int
5902            retrieveInt(String lscpCmd) throws IOException, LscpException, LSException {
5903                    verifyConnection();
5904                    out.writeLine(lscpCmd);
5905                    if(getPrintOnlyMode()) return -1;
5906    
5907                    String s = getSingleLineResultSet().getResult();
5908                    return parseInt(s);
5909            }
5910    
5911            private int
5912            retrieveIndex(String lscpCmd) throws IOException, LSException, LscpException {
5913                    verifyConnection();
5914                    out.writeLine(lscpCmd);
5915                    if(getPrintOnlyMode()) return -1;
5916    
5917                    return getEmptyResultSet().getIndex();
5918            }
5919                    
5920          /**          /**
5921           * Returns the logger for this library.           * Returns the logger for this library.

Legend:
Removed from v.1718  
changed lines
  Added in v.2190

  ViewVC Help
Powered by ViewVC