/[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 1421 by iliev, Sun Oct 14 18:08:45 2007 UTC revision 2242 by iliev, Wed Aug 17 09:06:46 2011 UTC
# Line 1  Line 1 
1  /*  /*
2   *   jlscp - a java LinuxSampler control protocol API   *   jlscp - a java LinuxSampler control protocol API
3   *   *
4   *   Copyright (C) 2005-2007 Grigor Iliev <grigor@grigoriliev.com>   *   Copyright (C) 2005-2011 Grigor Iliev <grigor@grigoriliev.com>
5   *   *
6   *   This file is part of jlscp.   *   This file is part of jlscp.
7   *   *
# Line 28  import java.io.OutputStream; Line 28  import java.io.OutputStream;
28  import java.net.InetSocketAddress;  import java.net.InetSocketAddress;
29  import java.net.Socket;  import java.net.Socket;
30  import java.net.SocketTimeoutException;  import java.net.SocketTimeoutException;
 import java.net.UnknownHostException;  
31    
32    import java.util.ArrayList;
33    import java.util.TreeMap;
34  import java.util.Vector;  import java.util.Vector;
35  import java.util.logging.Level;  import java.util.logging.Level;
36  import java.util.logging.Logger;  import java.util.logging.Logger;
# Line 41  import static org.linuxsampler.lscp.Pars Line 42  import static org.linuxsampler.lscp.Pars
42    
43  /**  /**
44   * This class is the abstraction representing a client endpoint for communication with LinuxSampler   * This class is the abstraction representing a client endpoint for communication with LinuxSampler
45   * instance. Since it implements all commands specified in the LSCP protocol v1.1, for more   * instance. Since it implements all commands specified in the LSCP protocol v1.5, for more
46   * information look at the   * information look at the
47   * <a href=http://www.linuxsampler.org/api/lscp-1.1.html>LSCP</a> specification.   * <a href=http://www.linuxsampler.org/api/lscp-1.5.html>LSCP</a> specification.
48   *   *
49   * <p> The following code establishes connection to LinuxSampler instance and gets the   * <p> The following code establishes connection to LinuxSampler instance and gets the
50   * LinuxSampler version:   * LinuxSampler version:
# Line 78  public class Client { Line 79  public class Client {
79          private EventThread eventThread;          private EventThread eventThread;
80                    
81          private boolean printOnlyMode = false;          private boolean printOnlyMode = false;
82    
83            public enum ResultSetType {
84                    EMPTY, SINGLE_LINE, MULTI_LINE
85            }
86            
87            private static class ResultSetEntry {
88                    public ResultSetType type;
89                    
90                    public
91                    ResultSetEntry(ResultSetType type) {
92                            this.type = type;
93                    }
94            }
95    
96            private Vector<ResultSetEntry> resultSetQueue = new Vector<ResultSetEntry>();
97            
98            /* Used for caching the engines' info */
99            private final TreeMap<String, SamplerEngine> engineMap = new TreeMap<String, SamplerEngine>();
100                    
101          class EventThread extends Thread {          class EventThread extends Thread {
102                  private Vector<String> queue = new Vector<String>();                  private Vector<String> queue = new Vector<String>();
# Line 85  public class Client { Line 104  public class Client {
104                                    
105                  EventThread() { super("LSCP-Event-Thread"); }                  EventThread() { super("LSCP-Event-Thread"); }
106                                    
107                    @Override
108                  public void                  public void
109                  run() {                  run() {
110                          while(!mustTerminate()) {                          while(!mustTerminate()) {
# Line 164  public class Client { Line 184  public class Client {
184                  if(printOnlyMode) setPrintOnlyMode(true);                  if(printOnlyMode) setPrintOnlyMode(true);
185          }          }
186                    
187            private boolean extendedCharacterEscaping = true;
188            
189            /**
190             * Sets whether strings sent to LinuxSampler should be more aggressively escaped.
191             */
192            public synchronized void
193            setExtendedCharacterEscaping(boolean b) { extendedCharacterEscaping = b; }
194            
195            /**
196             * Determines whether strings sent to LinuxSampler should be more aggressively escaped.
197             */
198            public synchronized boolean
199            getExtendedCharacterEscaping() { return extendedCharacterEscaping; }
200            
201            /**
202             * @see java.net.Socket#setSoTimeout
203             */
204            public synchronized void
205            setSoTimeout(int timeout) {
206                    soTimeout = timeout;
207                    
208                    try { if(sock != null) sock.setSoTimeout(timeout); }
209                    catch(Exception x) { getLogger().log(Level.INFO, "Unable to set timeout", x); }
210            }
211            
212            private String
213            toEscapedText(String s) {
214                    s = toEscapedString(s);
215                    return conv(s);
216            }
217            
218            private String
219            toEscapedFsEntry(String s) {
220                    s = toEscapedFileName(s);
221                    return conv(s);
222            }
223            
224            /**
225             * Applies an extended character escaping to the specified string if needed.
226             */
227            private String
228            conv(String s) {
229                    return getExtendedCharacterEscaping() ? toExtendedEscapeSequence(s) : s;
230            }
231            
232          /**          /**
233           * Determines whether the client is in print-only mode.           * Determines whether the client is in print-only mode.
234           * Print-only mode means that the client will just print all           * Print-only mode means that the client will just print all
# Line 262  public class Client { Line 327  public class Client {
327                  if(sock != null) disconnect();                  if(sock != null) disconnect();
328                  if(getPrintOnlyMode()) return;                  if(getPrintOnlyMode()) return;
329                                    
330                    engineMap.clear();
331                    
332                  // Initializing LSCP event thread                  // Initializing LSCP event thread
333                  if(eventThread.isAlive()) {                  if(eventThread.isAlive()) {
334                          getLogger().warning("LSCP event thread already running!");                          getLogger().warning("LSCP event thread already running!");
# Line 344  public class Client { Line 411  public class Client {
411                  if(!llFSI.isEmpty()) subscribe("FX_SEND_INFO");                  if(!llFSI.isEmpty()) subscribe("FX_SEND_INFO");
412                  if(!llSC.isEmpty()) subscribe("STREAM_COUNT");                  if(!llSC.isEmpty()) subscribe("STREAM_COUNT");
413                  if(!llVC.isEmpty()) subscribe("VOICE_COUNT");                  if(!llVC.isEmpty()) subscribe("VOICE_COUNT");
414                    if(!llTSC.isEmpty()) subscribe("TOTAL_STREAM_COUNT");
415                  if(!llTVC.isEmpty()) subscribe("TOTAL_VOICE_COUNT");                  if(!llTVC.isEmpty()) subscribe("TOTAL_VOICE_COUNT");
416                  if(!llMIMC.isEmpty()) subscribe("MIDI_INSTRUMENT_MAP_COUNT");                  if(!llMIMC.isEmpty()) subscribe("MIDI_INSTRUMENT_MAP_COUNT");
417                  if(!llMIMI.isEmpty()) subscribe("MIDI_INSTRUMENT_MAP_INFO");                  if(!llMIMI.isEmpty()) subscribe("MIDI_INSTRUMENT_MAP_INFO");
418                  if(!llMIC.isEmpty()) subscribe("MIDI_INSTRUMENT_COUNT");                  if(!llMIC.isEmpty()) subscribe("MIDI_INSTRUMENT_COUNT");
419                  if(!llMII.isEmpty()) subscribe("MIDI_INSTRUMENT_INFO");                  if(!llMII.isEmpty()) subscribe("MIDI_INSTRUMENT_INFO");
420                    if(!llDMD.isEmpty()) subscribe("DEVICE_MIDI");
421                    if(!llCMD.isEmpty()) subscribe("CHANNEL_MIDI");
422                  if(!llID.isEmpty()) {                  if(!llID.isEmpty()) {
423                          subscribe("DB_INSTRUMENT_DIRECTORY_COUNT");                          subscribe("DB_INSTRUMENT_DIRECTORY_COUNT");
424                          subscribe("DB_INSTRUMENT_DIRECTORY_INFO");                          subscribe("DB_INSTRUMENT_DIRECTORY_INFO");
425                          subscribe("DB_INSTRUMENT_COUNT");                          subscribe("DB_INSTRUMENT_COUNT");
426                          subscribe("DB_INSTRUMENT_INFO");                          subscribe("DB_INSTRUMENT_INFO");
427                            subscribe("DB_INSTRUMENTS_JOB_INFO");
428                  }                  }
429                  if(!llGI.isEmpty()) subscribe("GLOBAL_INFO");                  if(!llGI.isEmpty()) subscribe("GLOBAL_INFO");
430                    if(!llEIC.isEmpty()) subscribe("EFFECT_INSTANCE_COUNT");
431                    if(!llEII.isEmpty()) subscribe("EFFECT_INSTANCE_INFO");
432                    if(!llSECC.isEmpty()) subscribe("SEND_EFFECT_CHAIN_COUNT");
433                    if(!llSECI.isEmpty()) subscribe("SEND_EFFECT_CHAIN_INFO");
434          }          }
435                    
436          /**          /**
# Line 372  public class Client { Line 447  public class Client {
447                          eventThread.terminate();                          eventThread.terminate();
448                          eventThread = new EventThread();                          eventThread = new EventThread();
449                  }                  }
450                    
451                    engineMap.clear();
452          }          }
453                    
454          /**          /**
# Line 419  public class Client { Line 496  public class Client {
496                          else getLogger().severe("Unknown notification format: " + s);                          else getLogger().severe("Unknown notification format: " + s);
497                  }                  }
498          }          }
499    
500            private synchronized void
501            processResultSetQueue() {
502                    for(int i = 0; i < resultSetQueue.size(); i++) {
503                            try {
504                                    switch(resultSetQueue.get(i).type) {
505                                            case EMPTY:
506                                                    getEmptyResultSet();
507                                                    break;
508                                            case SINGLE_LINE:
509                                                    getSingleLineResultSet();
510                                                    break;
511                                            case MULTI_LINE:
512                                                    getMultiLineResultSet();
513                                                    break;
514                                            default:
515                                                    getLogger().severe("Unknown result set type");
516                                    }
517                            } catch(Exception x) {
518                                    getLogger().log(Level.FINE, "Error while processing result set queue", x);
519                            }
520                    }
521    
522                    resultSetQueue.removeAllElements();
523            }
524                    
525          /**          /**
526           * Gets empty result set.           * Gets empty result set.
527           * @return <code>ResultSet</code> instance.           * @return <code>ResultSet</code> instance.
528           */           */
529          private ResultSet          private ResultSet
530          getEmptyResultSet() throws IOException, LscpException, LSException {          getEmptyResultSet() throws IOException, LscpException, LSException {
531                    processResultSetQueue();
532                  return parseEmptyResultSet(getLine());                  return parseEmptyResultSet(getLine());
533          }          }
534                    
535          private ResultSet          private ResultSet
536          getSingleLineResultSet() throws IOException, LscpException, LSException {          getSingleLineResultSet() throws IOException, LscpException, LSException {
537                    processResultSetQueue();
538                  ResultSet rs = new ResultSet();                  ResultSet rs = new ResultSet();
539                  String ln = getLine();                  String ln = getLine();
540                                    
# Line 449  public class Client { Line 553  public class Client {
553                    
554          private ResultSet          private ResultSet
555          getMultiLineResultSet() throws IOException, LscpException, LSException {          getMultiLineResultSet() throws IOException, LscpException, LSException {
556                    processResultSetQueue();
557                  ResultSet rs = new ResultSet();                  ResultSet rs = new ResultSet();
558                  String ln = getLine();                  String ln = getLine();
559                                    
# Line 485  public class Client { Line 590  public class Client {
590          private final Vector<ItemInfoListener> llMIDI = new Vector<ItemInfoListener>();          private final Vector<ItemInfoListener> llMIDI = new Vector<ItemInfoListener>();
591          private final Vector<StreamCountListener> llSC = new Vector<StreamCountListener>();          private final Vector<StreamCountListener> llSC = new Vector<StreamCountListener>();
592          private final Vector<VoiceCountListener> llVC = new Vector<VoiceCountListener>();          private final Vector<VoiceCountListener> llVC = new Vector<VoiceCountListener>();
593            private final Vector<TotalStreamCountListener> llTSC = new Vector<TotalStreamCountListener>();
594          private final Vector<TotalVoiceCountListener> llTVC = new Vector<TotalVoiceCountListener>();          private final Vector<TotalVoiceCountListener> llTVC = new Vector<TotalVoiceCountListener>();
595                    
596          /** MIDI instrument map count listeners */          /** MIDI instrument map count listeners */
# Line 497  public class Client { Line 603  public class Client {
603          /** MIDI instrument info listeners */          /** MIDI instrument info listeners */
604          private final Vector<MidiInstrumentInfoListener> llMII =          private final Vector<MidiInstrumentInfoListener> llMII =
605                  new Vector<MidiInstrumentInfoListener>();                  new Vector<MidiInstrumentInfoListener>();
606            private final Vector<DeviceMidiDataListener> llDMD = new Vector<DeviceMidiDataListener>();
607            private final Vector<ChannelMidiDataListener> llCMD = new Vector<ChannelMidiDataListener>();
608          private final Vector<InstrumentsDbListener> llID = new Vector<InstrumentsDbListener>();          private final Vector<InstrumentsDbListener> llID = new Vector<InstrumentsDbListener>();
609          private final Vector<GlobalInfoListener> llGI = new Vector<GlobalInfoListener>();          private final Vector<GlobalInfoListener> llGI = new Vector<GlobalInfoListener>();
610            private final ArrayList<EffectInstanceCountListener> llEIC = new ArrayList<EffectInstanceCountListener>();
611            private final Vector<EffectInstanceInfoListener> llEII = new Vector<EffectInstanceInfoListener>();
612            private final Vector<SendEffectChainCountListener> llSECC = new Vector<SendEffectChainCountListener>();
613            private final Vector<SendEffectChainInfoListener> llSECI = new Vector<SendEffectChainInfoListener>();
614                    
615                    
616          /**          /**
# Line 522  public class Client { Line 634  public class Client {
634                          !llMIDI.isEmpty() ||                          !llMIDI.isEmpty() ||
635                          !llSC.isEmpty()   ||                          !llSC.isEmpty()   ||
636                          !llVC.isEmpty()   ||                          !llVC.isEmpty()   ||
637                            !llTSC.isEmpty()  ||
638                          !llTVC.isEmpty()  ||                          !llTVC.isEmpty()  ||
639                          !llMIMC.isEmpty() ||                          !llMIMC.isEmpty() ||
640                          !llMIMI.isEmpty() ||                          !llMIMI.isEmpty() ||
641                          !llMIC.isEmpty()  ||                          !llMIC.isEmpty()  ||
642                          !llMII.isEmpty()  ||                          !llMII.isEmpty()  ||
643                            !llDMD.isEmpty()  ||
644                            !llCMD.isEmpty()  ||
645                          !llID.isEmpty()   ||                          !llID.isEmpty()   ||
646                          !llGI.isEmpty();                          !llGI.isEmpty()   ||
647                            !llEIC.isEmpty()  ||
648                            !llEII.isEmpty()  ||
649                            !llSECC.isEmpty() ||
650                            !llSECI.isEmpty();
651            }
652            
653            private synchronized void
654            fireDeviceMidiDataEvent(String s) {
655                    try {
656                            String[] list = parseList(s, ' ');
657                            if(list.length != 5) {
658                                    getLogger().warning("Unknown DEVICE_MIDI format");
659                                    return;
660                            }
661                            
662                            int dev = parseInt(list[0]);
663                            int port = parseInt(list[1]);
664                            
665                            MidiDataEvent.Type type = parseMidiDataType(list[2]);
666                            if(type == null) return;
667                            
668                            int note = parseInt(list[3]);
669                            int velocity = parseInt(list[4]);
670                            
671                            DeviceMidiDataEvent e = new DeviceMidiDataEvent(this, type, note, velocity);
672                            e.setDeviceId(dev);
673                            e.setPortId(port);
674                            for(DeviceMidiDataListener l : llDMD) l.midiDataArrived(e);
675                    } catch(LscpException x) {
676                            getLogger().log (
677                                    Level.WARNING, LscpI18n.getLogMsg("CommandFailed!"), x
678                            );
679                    }
680            }
681            
682            private synchronized void
683            fireChannelMidiDataEvent(String s) {
684                    try {
685                            String[] list = parseList(s, ' ');
686                            if(list.length != 4) {
687                                    getLogger().warning("Unknown CHANNEL_MIDI format");
688                                    return;
689                            }
690                            
691                            int channel = parseInt(list[0]);
692                            
693                            MidiDataEvent.Type type = parseMidiDataType(list[1]);
694                            if(type == null) return;
695                            
696                            int note = parseInt(list[2]);
697                            int velocity = parseInt(list[3]);
698                            
699                            ChannelMidiDataEvent e = new ChannelMidiDataEvent(this, type, note, velocity);
700                            e.setChannelId(channel);
701                            for(ChannelMidiDataListener l : llCMD) l.midiDataArrived(e);
702                    } catch(LscpException x) {
703                            getLogger().log (
704                                    Level.WARNING, LscpI18n.getLogMsg("CommandFailed!"), x
705                            );
706                    }
707            }
708            
709            private MidiDataEvent.Type
710            parseMidiDataType(String s) {
711                    if("NOTE_ON".equals(s)) return MidiDataEvent.Type.NOTE_ON;
712                    if("NOTE_OFF".equals(s)) return MidiDataEvent.Type.NOTE_OFF;
713                    if("CC".equals(s)) return MidiDataEvent.Type.CC;
714                    
715                    getLogger().warning("Unknown MIDI data type: " + s);
716                    return null;
717          }          }
718                    
719          private synchronized void          private synchronized void
720          fireEvent(String s) {          fireEvent(String s) {
721                   if(s.startsWith("DB_INSTRUMENT_DIRECTORY_COUNT:")) {                  // Sort by priority
722                    
723                     if(s.startsWith("CHANNEL_MIDI:")) {
724                            s = s.substring("CHANNEL_MIDI:".length());
725                            fireChannelMidiDataEvent(s);
726                    } else if(s.startsWith("DEVICE_MIDI:")) {
727                            s = s.substring("DEVICE_MIDI:".length());
728                            fireDeviceMidiDataEvent(s);
729                    } else if(s.startsWith("DB_INSTRUMENT_DIRECTORY_COUNT:")) {
730                          s = s.substring("DB_INSTRUMENT_DIRECTORY_COUNT:".length());                          s = s.substring("DB_INSTRUMENT_DIRECTORY_COUNT:".length());
731                          InstrumentsDbEvent e = new InstrumentsDbEvent(this, s);                          InstrumentsDbEvent e = new InstrumentsDbEvent(this, s);
732                          for(InstrumentsDbListener l : llID) l.directoryCountChanged(e);                          for(InstrumentsDbListener l : llID) l.directoryCountChanged(e);
# Line 662  public class Client { Line 855  public class Client {
855                          } catch(NumberFormatException x) {                          } catch(NumberFormatException x) {
856                                  getLogger().log(Level.WARNING, "Unknown CHANNEL_INFO format", x);                                  getLogger().log(Level.WARNING, "Unknown CHANNEL_INFO format", x);
857                          }                          }
858                    } else if(s.startsWith("TOTAL_STREAM_COUNT:")) {
859                            try {
860                                    s = s.substring("TOTAL_STREAM_COUNT:".length());
861                                    int i = Integer.parseInt(s);
862                                    TotalStreamCountEvent e = new TotalStreamCountEvent(this, i);
863                                    for(TotalStreamCountListener l : llTSC) l.totalStreamCountChanged(e);
864                            } catch(NumberFormatException x) {
865                                    getLogger().log (
866                                            Level.WARNING, "Unknown TOTAL_STREAM_COUNT format", x
867                                    );
868                            }
869                  } else if(s.startsWith("TOTAL_VOICE_COUNT:")) {                  } else if(s.startsWith("TOTAL_VOICE_COUNT:")) {
870                          try {                          try {
871                                  s = s.substring("TOTAL_VOICE_COUNT:".length());                                  s = s.substring("TOTAL_VOICE_COUNT:".length());
# Line 809  public class Client { Line 1013  public class Client {
1013                          } catch(Exception x) {                          } catch(Exception x) {
1014                                  getLogger().log(Level.WARNING, "Unknown FX_SEND_INFO format", x);                                  getLogger().log(Level.WARNING, "Unknown FX_SEND_INFO format", x);
1015                          }                          }
1016                    } else if(s.startsWith("EFFECT_INSTANCE_COUNT:")) {
1017                            try {
1018                                    s = s.substring("EFFECT_INSTANCE_COUNT:".length());
1019                                    int i = Integer.parseInt(s);
1020                                    
1021                                    EffectInstanceCountEvent e = new EffectInstanceCountEvent(this, i);
1022                                    for(EffectInstanceCountListener l : llEIC) {
1023                                            l.effectInstanceCountChanged(e);
1024                                    }
1025                            } catch(Exception x) {
1026                                    getLogger().log(Level.WARNING, "Unknown EFFECT_INSTANCE_COUNT format", x);
1027                            }
1028                    } else if(s.startsWith("EFFECT_INSTANCE_INFO:")) {
1029                            try {
1030                                    s = s.substring("EFFECT_INSTANCE_INFO:".length());
1031                                    int i = Integer.parseInt(s);
1032                                    
1033                                    EffectInstanceInfoEvent e = new EffectInstanceInfoEvent(this, i);
1034                                    for(EffectInstanceInfoListener l : llEII) {
1035                                            l.effectInstanceInfoChanged(e);
1036                                    }
1037                            } catch(Exception x) {
1038                                    getLogger().log(Level.WARNING, "Unknown EFFECT_INSTANCE_INFO format", x);
1039                            }
1040                    } else if(s.startsWith("SEND_EFFECT_CHAIN_COUNT:")) {
1041                            try {
1042                                    s = s.substring("SEND_EFFECT_CHAIN_COUNT:".length());
1043                                    Integer[] i = parseIntList(s, ' ');
1044                                    if(i.length != 2) {
1045                                            getLogger().warning("Unknown SEND_EFFECT_CHAIN_COUNT format");
1046                                            return;
1047                                    }
1048                                    
1049                                    SendEffectChainCountEvent e =
1050                                            new SendEffectChainCountEvent(this, i[0], i[1]);
1051                                    
1052                                    for(SendEffectChainCountListener l : llSECC) {
1053                                            l.sendEffectChainCountChanged(e);
1054                                    }
1055                            } catch(Exception x) {
1056                                    getLogger().log(Level.WARNING, "Unknown SEND_EFFECT_CHAIN_COUNT format", x);
1057                            }
1058                    } else if(s.startsWith("SEND_EFFECT_CHAIN_INFO:")) {
1059                            try {
1060                                    s = s.substring("SEND_EFFECT_CHAIN_INFO:".length());
1061                                    Integer[] i = parseIntList(s, ' ');
1062                                    if(i.length != 3) {
1063                                            getLogger().warning("Unknown SEND_EFFECT_CHAIN_INFO format");
1064                                            return;
1065                                    }
1066                                    
1067                                    SendEffectChainInfoEvent e =
1068                                            new SendEffectChainInfoEvent(this, i[0], i[1], i[2]);
1069                                    
1070                                    for(SendEffectChainInfoListener l : llSECI) {
1071                                            l.sendEffectChainInfoChanged(e);
1072                                    }
1073                            } catch(Exception x) {
1074                                    getLogger().log(Level.WARNING, "Unknown SEND_EFFECT_CHAIN_INFO format", x);
1075                            }
1076                  } else if(s.startsWith("GLOBAL_INFO:")) {                  } else if(s.startsWith("GLOBAL_INFO:")) {
1077                          handleGlobalInfoEvent(s.substring("GLOBAL_INFO:".length()));                          handleGlobalInfoEvent(s.substring("GLOBAL_INFO:".length()));
1078                  } else if(s.startsWith("MISCELLANEOUS:")) {                  } else if(s.startsWith("MISCELLANEOUS:")) {
# Line 825  public class Client { Line 1089  public class Client {
1089                                  float f = Float.parseFloat(s.substring("VOLUME ".length()));                                  float f = Float.parseFloat(s.substring("VOLUME ".length()));
1090                                  GlobalInfoEvent e = new GlobalInfoEvent(this, f);                                  GlobalInfoEvent e = new GlobalInfoEvent(this, f);
1091                                  for(GlobalInfoListener l : llGI) l.volumeChanged(e);                                  for(GlobalInfoListener l : llGI) l.volumeChanged(e);
1092                            } else if(s.startsWith("VOICES ")) {
1093                                    int i = Integer.parseInt(s.substring("VOICES ".length()));
1094                                    GlobalInfoEvent e = new GlobalInfoEvent(this, i, -1);
1095                                    for(GlobalInfoListener l : llGI) l.voiceLimitChanged(e);
1096                            } else if(s.startsWith("STREAMS ")) {
1097                                    int i = Integer.parseInt(s.substring("STREAMS ".length()));
1098                                    GlobalInfoEvent e = new GlobalInfoEvent(this, -1, i);
1099                                    for(GlobalInfoListener l : llGI) l.streamLimitChanged(e);
1100                            } else {
1101                                    getLogger().info("Unknown GLOBAL_INFO format: " + s);
1102                          }                          }
1103                  } catch(NumberFormatException x) {                  } catch(NumberFormatException x) {
1104                          getLogger().log(Level.WARNING, "Unknown GLOBAL_INFO format", x);                          getLogger().log(Level.WARNING, "Unknown GLOBAL_INFO format", x);
# Line 1134  public class Client { Line 1408  public class Client {
1408          /**          /**
1409           * Registers the specified listener for receiving event messages.           * Registers the specified listener for receiving event messages.
1410           * Listeners can be registered regardless of the connection state.           * Listeners can be registered regardless of the connection state.
1411             * @param l The <code>TotalStreamCountListener</code> to register.
1412             */
1413            public synchronized void
1414            addTotalStreamCountListener(TotalStreamCountListener l) {
1415                    if(llTSC.isEmpty()) subscribe("TOTAL_STREAM_COUNT");
1416                    llTSC.add(l);
1417            }
1418            
1419            /**
1420             * Removes the specified listener.
1421             * Listeners can be removed regardless of the connection state.
1422             * @param l The <code>TotalStreamCountListener</code> to remove.
1423             */
1424            public synchronized void
1425            removeTotalStreamCountListener(TotalStreamCountListener l) {
1426                    boolean b = llTSC.remove(l);
1427                    if(b && llTSC.isEmpty()) unsubscribe("TOTAL_STREAM_COUNT");
1428            }
1429            
1430            /**
1431             * Registers the specified listener for receiving event messages.
1432             * Listeners can be registered regardless of the connection state.
1433           * @param l The <code>TotalVoiceCountListener</code> to register.           * @param l The <code>TotalVoiceCountListener</code> to register.
1434           */           */
1435          public synchronized void          public synchronized void
# Line 1244  public class Client { Line 1540  public class Client {
1540          /**          /**
1541           * Registers the specified listener for receiving event messages.           * Registers the specified listener for receiving event messages.
1542           * Listeners can be registered regardless of the connection state.           * Listeners can be registered regardless of the connection state.
1543             * @param l The <code>DeviceMidiDataListener</code> to register.
1544             */
1545            public synchronized void
1546            addDeviceMidiDataListener(DeviceMidiDataListener l) {
1547                    if(llDMD.isEmpty()) subscribe("DEVICE_MIDI");
1548                    llDMD.add(l);
1549            }
1550            
1551            /**
1552             * Removes the specified listener.
1553             * Listeners can be removed regardless of the connection state.
1554             * @param l The <code>DeviceMidiDataListener</code> to remove.
1555             */
1556            public synchronized void
1557            removeDeviceMidiDataListener(DeviceMidiDataListener l) {
1558                    boolean b = llDMD.remove(l);
1559                    if(b && llDMD.isEmpty()) unsubscribe("DEVICE_MIDI");
1560            }
1561            
1562            /**
1563             * Registers the specified listener for receiving event messages.
1564             * Listeners can be registered regardless of the connection state.
1565             * @param l The <code>ChannelMidiDataListener</code> to register.
1566             */
1567            public synchronized void
1568            addChannelMidiDataListener(ChannelMidiDataListener l) {
1569                    if(llCMD.isEmpty()) subscribe("CHANNEL_MIDI");
1570                    llCMD.add(l);
1571            }
1572            
1573            /**
1574             * Removes the specified listener.
1575             * Listeners can be removed regardless of the connection state.
1576             * @param l The <code>ChannelMidiDataListener</code> to remove.
1577             */
1578            public synchronized void
1579            removeChannelMidiDataListener(ChannelMidiDataListener l) {
1580                    boolean b = llCMD.remove(l);
1581                    if(b && llCMD.isEmpty()) unsubscribe("CHANNEL_MIDI");
1582            }
1583            
1584            /**
1585             * Registers the specified listener for receiving event messages.
1586             * Listeners can be registered regardless of the connection state.
1587           * @param l The <code>InstrumentsDbListener</code> to register.           * @param l The <code>InstrumentsDbListener</code> to register.
1588           */           */
1589          public synchronized void          public synchronized void
# Line 1298  public class Client { Line 1638  public class Client {
1638          }          }
1639                    
1640          /**          /**
1641             * Registers the specified listener for receiving event messages.
1642             * Listeners can be registered regardless of the connection state.
1643             * @param l The <code>EffectInstanceCountListener</code> to register.
1644             */
1645            public synchronized void
1646            addEffectInstanceCountListener(EffectInstanceCountListener l) {
1647                    if(llEIC.isEmpty()) subscribe("EFFECT_INSTANCE_COUNT");
1648                    llEIC.add(l);
1649            }
1650            
1651            /**
1652             * Removes the specified listener.
1653             * Listeners can be removed regardless of the connection state.
1654             * @param l The <code>EffectInstanceCountListener</code> to remove.
1655             */
1656            public synchronized void
1657            removeEffectInstanceCountListener(EffectInstanceCountListener l) {
1658                    boolean b = llEIC.remove(l);
1659                    if(b && llEIC.isEmpty()) unsubscribe("EFFECT_INSTANCE_COUNT");
1660            }
1661            
1662            /**
1663             * Registers the specified listener for receiving event messages.
1664             * Listeners can be registered regardless of the connection state.
1665             * @param l The <code>EffectInstanceInfoListener</code> to register.
1666             */
1667            public synchronized void
1668            addEffectInstanceInfoListener(EffectInstanceInfoListener l) {
1669                    if(llEII.isEmpty()) subscribe("EFFECT_INSTANCE_INFO");
1670                    llEII.add(l);
1671            }
1672            
1673            /**
1674             * Removes the specified listener.
1675             * Listeners can be removed regardless of the connection state.
1676             * @param l The <code>EffectInstanceInfoListener</code> to remove.
1677             */
1678            public synchronized void
1679            removeEffectInstanceInfoListener(EffectInstanceInfoListener l) {
1680                    boolean b = llEII.remove(l);
1681                    if(b && llEII.isEmpty()) unsubscribe("EFFECT_INSTANCE_INFO");
1682            }
1683            
1684            /**
1685             * Registers the specified listener for receiving event messages.
1686             * Listeners can be registered regardless of the connection state.
1687             * @param l The <code>SendEffectChainCountListener</code> to register.
1688             */
1689            public synchronized void
1690            addSendEffectChainCountListener(SendEffectChainCountListener l) {
1691                    if(llSECC.isEmpty()) subscribe("SEND_EFFECT_CHAIN_COUNT");
1692                    llSECC.add(l);
1693            }
1694            
1695            /**
1696             * Removes the specified listener.
1697             * Listeners can be removed regardless of the connection state.
1698             * @param l The <code>SendEffectChainCountListener</code> to remove.
1699             */
1700            public synchronized void
1701            removeSendEffectChainCountListener(SendEffectChainCountListener l) {
1702                    boolean b = llSECC.remove(l);
1703                    if(b && llSECC.isEmpty()) unsubscribe("SEND_EFFECT_CHAIN_COUNT");
1704            }
1705            
1706            /**
1707             * Registers the specified listener for receiving event messages.
1708             * Listeners can be registered regardless of the connection state.
1709             * @param l The <code>SendEffectChainInfoListener</code> to register.
1710             */
1711            public synchronized void
1712            addSendEffectChainInfoListener(SendEffectChainInfoListener l) {
1713                    if(llSECI.isEmpty()) subscribe("SEND_EFFECT_CHAIN_INFO");
1714                    llSECI.add(l);
1715            }
1716            
1717            /**
1718             * Removes the specified listener.
1719             * Listeners can be removed regardless of the connection state.
1720             * @param l The <code>SendEffectChainInfoListener</code> to remove.
1721             */
1722            public synchronized void
1723            removeSendEffectChainInfoListener(SendEffectChainInfoListener l) {
1724                    boolean b = llSECI.remove(l);
1725                    if(b && llSECI.isEmpty()) unsubscribe("SEND_EFFECT_CHAIN_INFO");
1726            }
1727            
1728            /**
1729           * Gets the number of all audio output drivers currently           * Gets the number of all audio output drivers currently
1730           * available for the LinuxSampler instance.           * available for the LinuxSampler instance.
1731           * @return The number of all audio output drivers currently           * @return The number of all audio output drivers currently
1732           * available for the LinuxSampler instance.           * available for the LinuxSampler instance or -1 if in "print only" mode.
1733           * @throws IOException If some I/O error occurs.           * @throws IOException If some I/O error occurs.
1734           * @throws LscpException If LSCP protocol corruption occurs.           * @throws LscpException If LSCP protocol corruption occurs.
1735           * @throws LSException If some other error occurs.           * @throws LSException If some other error occurs.
1736           */           */
1737          public synchronized int          public synchronized int
1738          getAudioOutputDriverCount() throws IOException, LscpException, LSException {          getAudioOutputDriverCount() throws IOException, LscpException, LSException {
1739                  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);  
1740          }          }
1741                    
1742          /**          /**
# Line 1373  public class Client { Line 1795  public class Client {
1795          public synchronized AudioOutputDriver          public synchronized AudioOutputDriver
1796          getAudioOutputDriverInfo(String driverName, Parameter... depList)          getAudioOutputDriverInfo(String driverName, Parameter... depList)
1797                                          throws IOException, LscpException, LSException {                                          throws IOException, LscpException, LSException {
1798                    
1799                  verifyConnection();                  AudioOutputDriver aod = new AudioOutputDriver();
1800                  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());  
1801                  aod.setName(driverName);                  aod.setName(driverName);
1802                                    
1803                  for(String s : aod.getParameterNames())                  for(String s : aod.getParameterNames())
# Line 1418  public class Client { Line 1836  public class Client {
1836                  args.append(' ').append(param);                  args.append(' ').append(param);
1837                                    
1838                  for(Parameter p : deplist) {                  for(Parameter p : deplist) {
1839                          if(p.getValue() == null) continue;                          if(p == null || p.getName() == null || p.getValue() == null) continue;
1840                          args.append(' ').append(p.getName()).append('=').append(p.getStringValue());                          args.append(' ').append(p.getName()).append('=').append(p.getStringValue());
1841                  }                  }
1842                                    
# Line 1478  public class Client { Line 1896  public class Client {
1896          createAudioOutputDevice(String aoDriver, Parameter... paramList)          createAudioOutputDevice(String aoDriver, Parameter... paramList)
1897                                          throws IOException, LSException, LscpException {                                          throws IOException, LSException, LscpException {
1898                                    
                 verifyConnection();  
1899                  StringBuffer args = new StringBuffer(aoDriver);                  StringBuffer args = new StringBuffer(aoDriver);
1900                                    
1901                  for(Parameter p : paramList) {                  for(Parameter p : paramList) {
1902                          if(p.getValue() == null) continue;                          if(p == null || p.getName() == null || p.getValue() == null) continue;
1903                          args.append(' ').append(p.getName()).append('=').append(p.getStringValue());                          args.append(' ').append(p.getName()).append('=').append(p.getStringValue());
1904                  }                  }
1905                    
1906                  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();  
1907          }          }
1908                    
1909          /**          /**
# Line 1504  public class Client { Line 1916  public class Client {
1916           */           */
1917          public synchronized void          public synchronized void
1918          destroyAudioOutputDevice(int deviceId) throws IOException, LSException, LscpException {          destroyAudioOutputDevice(int deviceId) throws IOException, LSException, LscpException {
1919                  verifyConnection();                  retrieveIndex("DESTROY AUDIO_OUTPUT_DEVICE " + deviceId);
                 out.writeLine("DESTROY AUDIO_OUTPUT_DEVICE " + deviceId);  
                 if(getPrintOnlyMode()) return;  
                   
                 ResultSet rs = getEmptyResultSet();  
1920          }          }
1921                    
1922          /**          /**
# Line 1530  public class Client { Line 1938  public class Client {
1938                    
1939          /**          /**
1940           * Gets the current number of all created audio output devices.           * Gets the current number of all created audio output devices.
1941           * @return The current number of all created audio output devices.           * @return The current number of all created audio output devices
1942             *  or -1 if in "print only" mode.
1943           * @throws IOException If some I/O error occurs.           * @throws IOException If some I/O error occurs.
1944           * @throws LscpException If LSCP protocol corruption occurs.           * @throws LscpException If LSCP protocol corruption occurs.
1945           * @throws LSException If some other error occurs.           * @throws LSException If some other error occurs.
1946           */           */
1947          public synchronized int          public synchronized int
1948          getAudioOutputDeviceCount() throws IOException, LscpException, LSException {          getAudioOutputDeviceCount() throws IOException, LscpException, LSException {
1949                  verifyConnection();                  return retrieveInt("GET AUDIO_OUTPUT_DEVICES");
                 out.writeLine("GET AUDIO_OUTPUT_DEVICES");  
                 if(getPrintOnlyMode()) return -1;  
                   
                 String s = getSingleLineResultSet().getResult();  
                 return parseInt(s);  
1950          }          }
1951                                    
1952          /**          /**
# Line 1576  public class Client { Line 1980  public class Client {
1980           */           */
1981          public synchronized Integer[]          public synchronized Integer[]
1982          getAudioOutputDeviceIDs() throws IOException, LscpException, LSException {          getAudioOutputDeviceIDs() throws IOException, LscpException, LSException {
1983                  verifyConnection();                  return getIntegerList("LIST AUDIO_OUTPUT_DEVICES");
                 out.writeLine("LIST AUDIO_OUTPUT_DEVICES");  
                 if(getPrintOnlyMode()) return null;  
                   
                 return parseIntList(getSingleLineResultSet().getResult());  
1984          }          }
1985                    
1986          /**          /**
# Line 1683  public class Client { Line 2083  public class Client {
2083           */           */
2084          public synchronized void          public synchronized void
2085          setAudioOutputDeviceParameter(int deviceId, Parameter prm)          setAudioOutputDeviceParameter(int deviceId, Parameter prm)
2086                                                  throws IOException, LscpException, LSException {                                          throws IOException, LscpException, LSException
2087                            {
                 verifyConnection();  
2088                  String kv = prm.getName() + '=' + prm.getStringValue();                  String kv = prm.getName() + '=' + prm.getStringValue();
2089                  out.writeLine("SET AUDIO_OUTPUT_DEVICE_PARAMETER " + deviceId + ' ' + kv);                  retrieveIndex("SET AUDIO_OUTPUT_DEVICE_PARAMETER " + deviceId + ' ' + kv);
                 if(getPrintOnlyMode()) return;  
                   
                 ResultSet rs = getEmptyResultSet();  
2090          }          }
2091                    
2092          /**          /**
# Line 1874  public class Client { Line 2270  public class Client {
2270           */           */
2271          public synchronized void          public synchronized void
2272          setAudioOutputChannelParameter(int devId, int chn,  Parameter prm)          setAudioOutputChannelParameter(int devId, int chn,  Parameter prm)
2273                                                  throws IOException, LscpException, LSException {                                                  throws IOException, LscpException, LSException
2274                            {
                 verifyConnection();  
2275                  String args = devId + " " + chn + " " + prm.getName() + '=' + prm.getStringValue();                  String args = devId + " " + chn + " " + prm.getName() + '=' + prm.getStringValue();
2276                  out.writeLine("SET AUDIO_OUTPUT_CHANNEL_PARAMETER " + args);                  retrieveIndex("SET AUDIO_OUTPUT_CHANNEL_PARAMETER " + args);
                 if(getPrintOnlyMode()) return;  
                   
                 ResultSet rs = getEmptyResultSet();  
2277          }          }
2278                    
2279          /**          /**
2280           * Gets the current number of all MIDI input drivers.           * Gets the current number of all MIDI input drivers.
2281           * @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.
2282           * @throws IOException If some I/O error occurs.           * @throws IOException If some I/O error occurs.
2283           * @throws LscpException If LSCP protocol corruption occurs.           * @throws LscpException If LSCP protocol corruption occurs.
2284           * @throws LSException If some other error occurs.           * @throws LSException If some other error occurs.
2285           */           */
2286          public synchronized int          public synchronized int
2287          getMidiInputDriverCount() throws IOException, LscpException, LSException {          getMidiInputDriverCount() throws IOException, LscpException, LSException {
2288                  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);  
2289          }          }
2290                    
2291          /**          /**
# Line 1958  public class Client { Line 2345  public class Client {
2345          public synchronized MidiInputDriver          public synchronized MidiInputDriver
2346          getMidiInputDriverInfo(String driverName, Parameter... depList)          getMidiInputDriverInfo(String driverName, Parameter... depList)
2347                                          throws IOException, LscpException, LSException {                                          throws IOException, LscpException, LSException {
2348                    
2349                  verifyConnection();                  MidiInputDriver mid = new MidiInputDriver();
2350                  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());  
2351                  mid.setName(driverName);                  mid.setName(driverName);
2352                                    
2353                  for(String s : mid.getParameterNames())                  for(String s : mid.getParameterNames())
# Line 2004  public class Client { Line 2386  public class Client {
2386                  args.append(' ').append(param);                  args.append(' ').append(param);
2387                                    
2388                  for(Parameter p : deplist) {                  for(Parameter p : deplist) {
2389                          if(p.getValue() == null) continue;                          if(p == null || p.getName() == null || p.getValue() == null) continue;
2390                          args.append(' ').append(p.getName()).append('=').append(p.getStringValue());                          args.append(' ').append(p.getName()).append('=').append(p.getStringValue());
2391                  }                  }
2392                                    
# Line 2063  public class Client { Line 2445  public class Client {
2445           */           */
2446          public synchronized int          public synchronized int
2447          createMidiInputDevice(String miDriver, Parameter... paramList)          createMidiInputDevice(String miDriver, Parameter... paramList)
2448                                          throws IOException, LSException, LscpException {                                          throws IOException, LSException, LscpException
2449                            {
                 verifyConnection();  
2450                  StringBuffer args = new StringBuffer(miDriver);                  StringBuffer args = new StringBuffer(miDriver);
2451                                    
2452                  for(Parameter p : paramList) {                  for(Parameter p : paramList) {
2453                          if(p.getValue() == null) continue;                          if(p == null || p.getName() == null || p.getValue() == null) continue;
2454                          args.append(' ').append(p.getName()).append('=').append(p.getStringValue());                          args.append(' ').append(p.getName()).append('=').append(p.getStringValue());
2455                  }                  }
2456                    
2457                  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();  
2458          }          }
2459                    
2460          /**          /**
# Line 2092  public class Client { Line 2468  public class Client {
2468           */           */
2469          public synchronized void          public synchronized void
2470          destroyMidiInputDevice(int deviceId) throws IOException, LSException, LscpException {          destroyMidiInputDevice(int deviceId) throws IOException, LSException, LscpException {
2471                  verifyConnection();                  retrieveIndex("DESTROY MIDI_INPUT_DEVICE " + deviceId);
                 out.writeLine("DESTROY MIDI_INPUT_DEVICE " + deviceId);  
                 if(getPrintOnlyMode()) return;  
                   
                 ResultSet rs = getEmptyResultSet();  
2472          }          }
2473                    
2474          /**          /**
# Line 2118  public class Client { Line 2490  public class Client {
2490                    
2491          /**          /**
2492           * Gets the current number of all created MIDI input devices.           * Gets the current number of all created MIDI input devices.
2493           * @return The current number of all created MIDI input devices.           * @return The current number of all created MIDI input
2494             * devices or -1 if in "print only" mode.
2495           * @throws IOException If some I/O error occurs.           * @throws IOException If some I/O error occurs.
2496           * @throws LscpException If LSCP protocol corruption occurs.           * @throws LscpException If LSCP protocol corruption occurs.
2497           * @throws LSException If some other error occurs.           * @throws LSException If some other error occurs.
2498           */           */
2499          public synchronized int          public synchronized int
2500          getMidiInputDeviceCount() throws IOException, LscpException, LSException {          getMidiInputDeviceCount() throws IOException, LscpException, LSException {
2501                  verifyConnection();                  return retrieveInt("GET MIDI_INPUT_DEVICES");
                 out.writeLine("GET MIDI_INPUT_DEVICES");  
                 if(getPrintOnlyMode()) return -1;  
                   
                 String s = getSingleLineResultSet().getResult();  
                 return parseInt(s);  
2502          }          }
2503                    
2504          /**          /**
# Line 2170  public class Client { Line 2538  public class Client {
2538           */           */
2539          public synchronized Integer[]          public synchronized Integer[]
2540          getMidiInputDeviceIDs() throws IOException, LscpException, LSException {          getMidiInputDeviceIDs() throws IOException, LscpException, LSException {
2541                  verifyConnection();                  return getIntegerList("LIST MIDI_INPUT_DEVICES");
                 out.writeLine("LIST MIDI_INPUT_DEVICES");  
                 if(getPrintOnlyMode()) return null;  
                   
                 return parseIntList(getSingleLineResultSet().getResult());  
2542          }          }
2543                    
2544          /**          /**
# Line 2216  public class Client { Line 2580  public class Client {
2580                                  mid.setActive(Boolean.parseBoolean(s));                                  mid.setActive(Boolean.parseBoolean(s));
2581                          } else if(s.startsWith("PORTS: ")) {                          } else if(s.startsWith("PORTS: ")) {
2582                                  s = s.substring("PORTS: ".length());                                  s = s.substring("PORTS: ".length());
2583                                  int ports = Parser.parseInt(s);                                  
2584                                  MidiPort[] midiPorts = new MidiPort[ports > 0 ? ports : 0];                                  Parameter<Integer> ports = (Parameter<Integer>)
2585                                            getMidiInputDriverParameterInfo(drv, "PORTS");
2586                                    
2587                                    ports.parseValue(s);
2588                                    mid.setPortsParameter(ports);
2589                                    
2590                                    int j = ports.getValue();
2591                                    MidiPort[] midiPorts = new MidiPort[j > 0 ? j : 0];
2592                                                                    
2593                                  for(int i = 0; i < midiPorts.length; i++)                                  for(int i = 0; i < midiPorts.length; i++)
2594                                          midiPorts[i] = getMidiInputPortInfo(deviceId, i);                                          midiPorts[i] = getMidiInputPortInfo(deviceId, i);
# Line 2264  public class Client { Line 2635  public class Client {
2635           */           */
2636          public synchronized void          public synchronized void
2637          setMidiInputDeviceParameter(int deviceId, Parameter prm)          setMidiInputDeviceParameter(int deviceId, Parameter prm)
2638                                                  throws IOException, LscpException, LSException {                                                  throws IOException, LscpException, LSException
2639                            {
                 verifyConnection();  
2640                  String kv = prm.getName() + '=' + prm.getStringValue();                  String kv = prm.getName() + '=' + prm.getStringValue();
2641                  out.writeLine("SET MIDI_INPUT_DEVICE_PARAMETER " + deviceId + ' ' + kv);                  retrieveIndex("SET MIDI_INPUT_DEVICE_PARAMETER " + deviceId + ' ' + kv);
                 if(getPrintOnlyMode()) return;  
                   
                 ResultSet rs = getEmptyResultSet();  
2642          }          }
2643                    
2644                    
2645          /**          /**
2646           * Changes the port number of the speicified MIDI input device.           * Changes the port number of the specified MIDI input device.
2647           * @param deviceId The numerical ID of the MIDI input device.           * @param deviceId The numerical ID of the MIDI input device.
2648           * @param ports The new number of MIDI input ports.           * @param ports The new number of MIDI input ports.
2649           *           *
# Line 2437  public class Client { Line 2804  public class Client {
2804           */           */
2805          public synchronized void          public synchronized void
2806          setMidiInputPortParameter(int deviceId, int port,  Parameter prm)          setMidiInputPortParameter(int deviceId, int port,  Parameter prm)
2807                                                  throws IOException, LscpException, LSException {                                                  throws IOException, LscpException, LSException
2808                            {
                 verifyConnection();  
2809                  String args = deviceId + " " + port + " " +                  String args = deviceId + " " + port + " " +
2810                          prm.getName() + '=' + prm.getStringValue();                          prm.getName() + '=' + prm.getStringValue();
2811                  out.writeLine("SET MIDI_INPUT_PORT_PARAMETER " + args);                  retrieveIndex("SET MIDI_INPUT_PORT_PARAMETER " + args);
                 if(getPrintOnlyMode()) return;  
                   
                 ResultSet rs = getEmptyResultSet();  
2812          }          }
2813                    
2814          /**          /**
# Line 2459  public class Client { Line 2822  public class Client {
2822           */           */
2823          public synchronized int          public synchronized int
2824          addMidiInstrumentMap(String name) throws IOException, LSException, LscpException {          addMidiInstrumentMap(String name) throws IOException, LSException, LscpException {
2825                  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();  
2826          }          }
2827                    
2828          /**          /**
# Line 2479  public class Client { Line 2836  public class Client {
2836           */           */
2837          public synchronized void          public synchronized void
2838          removeMidiInstrumentMap(int mapId) throws IOException, LscpException, LSException {          removeMidiInstrumentMap(int mapId) throws IOException, LscpException, LSException {
2839                  verifyConnection();                  retrieveIndex("REMOVE MIDI_INSTRUMENT_MAP " + mapId);
                 out.writeLine("REMOVE MIDI_INSTRUMENT_MAP " + mapId);  
                 if(getPrintOnlyMode()) return;  
                   
                 ResultSet rs = getEmptyResultSet();  
2840          }          }
2841                    
2842          /**          /**
# Line 2494  public class Client { Line 2847  public class Client {
2847           */           */
2848          public synchronized void          public synchronized void
2849          removeAllMidiInstrumentMaps() throws IOException, LscpException, LSException {          removeAllMidiInstrumentMaps() throws IOException, LscpException, LSException {
2850                  verifyConnection();                  retrieveIndex("REMOVE MIDI_INSTRUMENT_MAP ALL");
                 out.writeLine("REMOVE MIDI_INSTRUMENT_MAP ALL");  
                 if(getPrintOnlyMode()) return;  
                   
                 ResultSet rs = getEmptyResultSet();  
2851          }          }
2852                    
2853          /**          /**
2854           * Gets the current number of all MIDI instrument maps.           * Gets the current number of all MIDI instrument maps.
2855           * @return The current number of all MIDI instrument maps.           * @return The current number of all MIDI instrument maps
2856             *  or -1 if in "print only" mode.
2857           * @throws IOException If some I/O error occurs.           * @throws IOException If some I/O error occurs.
2858           * @throws LscpException If LSCP protocol corruption occurs.           * @throws LscpException If LSCP protocol corruption occurs.
2859           * @throws LSException If some other error occurs.           * @throws LSException If some other error occurs.
2860           */           */
2861          public synchronized int          public synchronized int
2862          getMidiInstrumentMapCount() throws IOException, LscpException, LSException {          getMidiInstrumentMapCount() throws IOException, LscpException, LSException {
2863                  verifyConnection();                  return retrieveInt("GET MIDI_INSTRUMENT_MAPS");
                 out.writeLine("GET MIDI_INSTRUMENT_MAPS");  
                 if(getPrintOnlyMode()) return -1;  
                   
                 String s = getSingleLineResultSet().getResult();  
                 return parseInt(s);  
2864          }          }
2865                    
2866          /**          /**
# Line 2530  public class Client { Line 2875  public class Client {
2875           */           */
2876          public synchronized Integer[]          public synchronized Integer[]
2877          getMidiInstrumentMapIDs() throws IOException, LscpException, LSException {          getMidiInstrumentMapIDs() throws IOException, LscpException, LSException {
2878                  verifyConnection();                  return getIntegerList("LIST MIDI_INSTRUMENT_MAPS");
                 out.writeLine("LIST MIDI_INSTRUMENT_MAPS");  
                 if(getPrintOnlyMode()) return null;  
                   
                 return parseIntList(getSingleLineResultSet().getResult());  
2879          }          }
2880                    
2881          /**          /**
# Line 2608  public class Client { Line 2949  public class Client {
2949           */           */
2950          public synchronized void          public synchronized void
2951          setMidiInstrumentMapName(int mapId, String name)          setMidiInstrumentMapName(int mapId, String name)
2952                                  throws IOException, LscpException, LSException {                                  throws IOException, LscpException, LSException
2953                            {
2954                  verifyConnection();                  name = toEscapedText(name);
2955                  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();  
2956          }          }
2957                    
2958                    
# Line 2661  public class Client { Line 2998  public class Client {
2998                  cmd.append(entry.getMidiBank()).append(' ');                  cmd.append(entry.getMidiBank()).append(' ');
2999                  cmd.append(entry.getMidiProgram()).append(' ');                  cmd.append(entry.getMidiProgram()).append(' ');
3000                  cmd.append(info.getEngine()).append(" '");                  cmd.append(info.getEngine()).append(" '");
3001                  cmd.append(info.getFilePath()).append("' ");                  cmd.append(conv(info.getFilePath())).append("' ");
3002                  cmd.append(info.getInstrumentIndex()).append(' ');                  cmd.append(info.getInstrumentIndex()).append(' ');
3003                  cmd.append(info.getVolume());                  cmd.append(info.getVolume());
3004                  if(!info.getLoadMode().name().equals("DEFAULT")) {                  if(!info.getLoadMode().name().equals("DEFAULT")) {
# Line 2669  public class Client { Line 3006  public class Client {
3006                  }                  }
3007                                    
3008                  if(info.getName() != null) {                  if(info.getName() != null) {
3009                          String s = toEscapedString(info.getName());                          String s = toEscapedText(info.getName());
3010                          cmd.append(" '").append(s).append("'");                          cmd.append(" '").append(s).append("'");
3011                  }                  }
3012                                    
# Line 2691  public class Client { Line 3028  public class Client {
3028           */           */
3029          public synchronized void          public synchronized void
3030          unmapMidiInstrument(int mapId, MidiInstrumentEntry entry)          unmapMidiInstrument(int mapId, MidiInstrumentEntry entry)
3031                                          throws IOException, LSException, LscpException {                                          throws IOException, LSException, LscpException
3032                            {
                 verifyConnection();  
3033                  StringBuffer cmd = new StringBuffer("UNMAP MIDI_INSTRUMENT ");                  StringBuffer cmd = new StringBuffer("UNMAP MIDI_INSTRUMENT ");
3034                  cmd.append(mapId).append(' ');                  cmd.append(mapId).append(' ');
3035                  cmd.append(entry.getMidiBank()).append(' ');                  cmd.append(entry.getMidiBank()).append(' ');
3036                  cmd.append(entry.getMidiProgram());                  cmd.append(entry.getMidiProgram());
3037                    
3038                  out.writeLine(cmd.toString());                  retrieveIndex(cmd.toString());
                 if(getPrintOnlyMode()) return;  
                   
                 ResultSet rs = getEmptyResultSet();  
3039          }          }
3040                    
3041          /**          /**
3042           * Gets the current number of all MIDI instrument in all maps.           * Gets the current number of all MIDI instrument in all maps.
3043           * @return The current number of all MIDI instrument in all maps.           * @return The current number of all MIDI instrument in all maps
3044             * or -1 if in "print only" mode.
3045           * @throws IOException If some I/O error occurs.           * @throws IOException If some I/O error occurs.
3046           * @throws LscpException If LSCP protocol corruption occurs.           * @throws LscpException If LSCP protocol corruption occurs.
3047           * @throws LSException If some other error occurs.           * @throws LSException If some other error occurs.
3048           */           */
3049          public synchronized int          public synchronized int
3050          getMidiInstrumentCount() throws IOException, LscpException, LSException {          getMidiInstrumentCount() throws IOException, LscpException, LSException {
3051                  verifyConnection();                  return retrieveInt("GET MIDI_INSTRUMENTS ALL");
                 out.writeLine("GET MIDI_INSTRUMENTS ALL");  
                 if(getPrintOnlyMode()) return -1;  
                   
                 String s = getSingleLineResultSet().getResult();  
                 return parseInt(s);  
3052          }          }
3053                    
3054          /**          /**
3055           * Gets the current number of MIDI instrument in the specified map.           * Gets the current number of MIDI instrument in the specified map.
3056           * @param mapId The ID of the map.           * @param mapId The ID of the map.
3057           * @return The current number of MIDI instrument in the specified map.           * @return The current number of MIDI instrument in the
3058             * specified map or -1 if in "print only" mode.
3059           * @throws IOException If some I/O error occurs.           * @throws IOException If some I/O error occurs.
3060           * @throws LscpException If LSCP protocol corruption occurs.           * @throws LscpException If LSCP protocol corruption occurs.
3061           * @throws LSException If some other error occurs.           * @throws LSException If some other error occurs.
3062           */           */
3063          public synchronized int          public synchronized int
3064          getMidiInstrumentCount(int mapId) throws IOException, LscpException, LSException {          getMidiInstrumentCount(int mapId) throws IOException, LscpException, LSException {
3065                  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);  
3066          }          }
3067                    
3068          /**          /**
# Line 2760  public class Client { Line 3085  public class Client {
3085          }          }
3086                    
3087          /**          /**
3088           * Gets all MIDI instrument contained int the specified MIDI instrument map.           * Gets all MIDI instrument entries contained int the specified MIDI instrument map.
3089             * @param mapId The ID of the map, which instruments should be obtained.
3090             * @return An int array providing all MIDI instrument entries
3091             * in the specified MIDI instrument map.
3092             * @throws IOException If some I/O error occurs.
3093             * @throws LscpException If LSCP protocol corruption occurs.
3094             * @throws LSException If some other error occurs.
3095             */
3096            public synchronized int[][]
3097            getMidiInstrumentEntries(int mapId) throws IOException, LscpException, LSException {
3098                    verifyConnection();
3099                    out.writeLine("LIST MIDI_INSTRUMENTS " + String.valueOf(mapId));
3100                    if(getPrintOnlyMode()) return null;
3101                    
3102                    String[] entries = parseArray(getSingleLineResultSet().getResult());
3103                    int[][] e = new int[entries.length][3];
3104                    
3105                    for(int i = 0; i < entries.length; i++) {
3106                            Integer[] vals = parseIntList(entries[i]);
3107                            if(vals.length != 3) {
3108                                    throw new LscpException(LscpI18n.getLogMsg("CommandFailed!"));
3109                            }
3110                            
3111                            e[i][0] = vals[0];
3112                            e[i][1] = vals[1];
3113                            e[i][2] = vals[2];
3114                    }
3115                    
3116                    return e;
3117            }
3118            
3119            /**
3120             * Gets all MIDI instruments contained int the specified MIDI instrument map.
3121           * @param mapId The ID of the map, which instruments should be obtained.           * @param mapId The ID of the map, which instruments should be obtained.
3122           * @return A <code>MidiInstrumentInfo</code> array providing           * @return A <code>MidiInstrumentInfo</code> array providing
3123           * all MIDI instruments from all MIDI instrument maps.           * all MIDI instruments in the specified MIDI instrument map.
3124           * @throws IOException If some I/O error occurs.           * @throws IOException If some I/O error occurs.
3125           * @throws LscpException If LSCP protocol corruption occurs.           * @throws LscpException If LSCP protocol corruption occurs.
3126           * @throws LSException If some other error occurs.           * @throws LSException If some other error occurs.
# Line 2811  public class Client { Line 3168  public class Client {
3168                                          throws IOException, LscpException, LSException {                                          throws IOException, LscpException, LSException {
3169                    
3170                  verifyConnection();                  verifyConnection();
3171                    requestMidiInstrumentInfo(mapId, bank, program);
3172                    return getMidiInstrumentInfoResponse(mapId, bank, program);
3173            }
3174            
3175            private void
3176            requestMidiInstrumentInfo(int mapId, int bank, int program) throws IOException {
3177                  StringBuffer cmd = new StringBuffer("GET MIDI_INSTRUMENT INFO ");                  StringBuffer cmd = new StringBuffer("GET MIDI_INSTRUMENT INFO ");
3178                  cmd.append(mapId).append(' ');                  cmd.append(mapId).append(' ');
3179                  cmd.append(bank).append(' ');                  cmd.append(bank).append(' ');
3180                  cmd.append(program);                  cmd.append(program);
3181                                    
3182                  out.writeLine(cmd.toString());                  out.writeLine(cmd.toString());
3183                  if(getPrintOnlyMode()) return null;          }
3184            
3185            private MidiInstrumentInfo
3186            getMidiInstrumentInfoResponse(int mapId, int bank, int program)
3187                                            throws IOException, LscpException, LSException {
3188                                    
3189                    if(getPrintOnlyMode()) return null;
3190                  ResultSet rs = getMultiLineResultSet();                  ResultSet rs = getMultiLineResultSet();
3191                  MidiInstrumentEntry entry = new MidiInstrumentEntry(bank, program);                  MidiInstrumentEntry entry = new MidiInstrumentEntry(bank, program);
3192                  return new MidiInstrumentInfo(mapId, entry, rs.getMultiLineResult());                  return new MidiInstrumentInfo(mapId, entry, rs.getMultiLineResult());
# Line 2865  public class Client { Line 3233  public class Client {
3233           */           */
3234          public synchronized void          public synchronized void
3235          loadInstrument(String filename, int instrIdx, int samplerChn, boolean nonModal)          loadInstrument(String filename, int instrIdx, int samplerChn, boolean nonModal)
3236                                                  throws IOException, LscpException, LSException {                                                  throws IOException, LscpException, LSException
3237                            {
3238                  String cmd = nonModal ? "LOAD INSTRUMENT NON_MODAL " : "LOAD INSTRUMENT ";                  String cmd = nonModal ? "LOAD INSTRUMENT NON_MODAL " : "LOAD INSTRUMENT ";
3239                  String args = '\'' + filename + "' " + instrIdx + ' ' + samplerChn;                  String args = '\'' + conv(filename) + "' " + instrIdx + ' ' + samplerChn;
3240                    
3241                  out.writeLine(cmd + args);                  retrieveIndex(cmd + args);
                 if(getPrintOnlyMode()) return;  
                   
                 ResultSet rs = getEmptyResultSet();  
3242          }          }
3243                    
3244          /**          /**
# Line 2890  public class Client { Line 3255  public class Client {
3255           */           */
3256          public synchronized void          public synchronized void
3257          loadSamplerEngine(String engineName, int samplerChn)          loadSamplerEngine(String engineName, int samplerChn)
3258                                          throws IOException, LscpException, LSException {                                          throws IOException, LscpException, LSException
3259                            { retrieveIndex("LOAD ENGINE " + engineName + ' ' + samplerChn); }
                 verifyConnection();  
                 out.writeLine("LOAD ENGINE " + engineName + ' ' + samplerChn);  
                 if(getPrintOnlyMode()) return;  
                   
                 ResultSet rs = getEmptyResultSet();  
         }  
3260                    
3261          /**          /**
3262           * Gets the current number of all created sampler channels.           * Gets the current number of all created sampler channels.
3263           * @return The current number of all created sampler channels.           * @return The current number of all created sampler
3264             * channels or -1 if in "print only" mode.
3265           * @throws IOException If some I/O error occurs.           * @throws IOException If some I/O error occurs.
3266           * @throws LscpException If LSCP protocol corruption occurs.           * @throws LscpException If LSCP protocol corruption occurs.
3267           * @throws LSException If some other error occurs.           * @throws LSException If some other error occurs.
3268           */           */
3269          public synchronized int          public synchronized int
3270          getSamplerChannelCount() throws IOException, LscpException, LSException {          getSamplerChannelCount() throws IOException, LscpException, LSException {
3271                  verifyConnection();                  return retrieveInt("GET CHANNELS");
                 out.writeLine("GET CHANNELS");  
                 if(getPrintOnlyMode()) return -1;  
                   
                 String s = getSingleLineResultSet().getResult();  
                 return parseInt(s);  
3272          }          }
3273                    
3274          /**          /**
# Line 2937  public class Client { Line 3292  public class Client {
3292                                    
3293                  return channels;                  return channels;
3294          }          }
3295    
3296            /**
3297             * Gets a list of the specified sampler channels.
3298             * @return A <code>SamplerChannel</code> array providing all created sampler channels.
3299             * @throws IOException If some I/O error occurs.
3300             * @throws LscpException If LSCP protocol corruption occurs.
3301             * @throws LSException If some other error occurs.
3302             * @see #addSamplerChannel
3303             * @see #removeSamplerChannel
3304             */
3305            public synchronized SamplerChannel[]
3306            getSamplerChannels(final Integer[] ids) throws IOException, LscpException, LSException {
3307                    verifyConnection();
3308    
3309                    int count = 0;
3310                    for(int i = 0; i < ids.length; i++) {
3311                            if(ids[i] >= 0) {
3312                                    int tmp = ids[i]; // to avoid overlapping
3313                                    ids[i] = -1;
3314                                    ids[count++] = tmp;
3315                            }
3316                    }
3317                    if(getPrintOnlyMode()) return null;
3318    
3319                    final SamplerChannel[] channels = new SamplerChannel[count];
3320    
3321                    new CmdListIterator(count) {
3322                            @Override
3323                            protected void
3324                            writeOutput(int index) throws IOException {
3325                                    channels[index] = new SamplerChannel();
3326                                    out.writeLine("GET CHANNEL INFO " + ids[index]);
3327                                    channels[index].setChannelId(ids[index]);
3328                            }
3329    
3330                            @Override
3331                            protected void
3332                            readInput(int index) throws IOException, LscpException, LSException {
3333                                    if(getPrintOnlyMode()) return;
3334                                    ResultSet rs = getMultiLineResultSet();
3335    
3336                                    for(String s : rs.getMultiLineResult()) {
3337                                            if(!channels[index].parse(s)) {
3338                                                    String msg = LscpI18n.getLogMsg("unknownLine", s);
3339                                                    Client.getLogger().info(msg);
3340                                            }
3341                                    }
3342                            }
3343                    }.run();
3344    
3345    
3346    
3347                    for(SamplerChannel sc : channels) {
3348                            if(sc.getEngine() != null) {
3349                                    sc.setEngine(getEngineInfo(sc.getEngine().getName()));
3350                            }
3351                    }
3352    
3353                    return channels;
3354            }
3355    
3356            private static abstract class CmdListIterator {
3357                    private final int cmdCount;
3358                    private final int cmdsPerStep;
3359    
3360                    CmdListIterator(int cmdCount) {
3361                            this(cmdCount, 100);
3362                    }
3363    
3364                    CmdListIterator(int cmdCount, int cmdsPerStep) {
3365                            this.cmdCount = cmdCount;
3366                            this.cmdsPerStep = cmdsPerStep;
3367                    }
3368    
3369                    public void
3370                    run() throws IOException, LscpException, LSException {
3371                            int currentStep = 0;
3372                            int stepCount = cmdCount / cmdsPerStep;
3373    
3374                            for(currentStep = 0; currentStep < stepCount; currentStep++) {
3375                                    for(int j = 0; j < cmdsPerStep; j++) {
3376                                            int idx = (currentStep * cmdsPerStep) + j;
3377                                            writeOutput(idx);
3378                                    }
3379    
3380                                    for(int j = 0; j < cmdsPerStep; j++) {
3381                                            int idx = (currentStep * cmdsPerStep) + j;
3382                                            readInput(idx);
3383                                    }
3384                            }
3385    
3386                            int cmdsLeft = cmdCount % cmdsPerStep;
3387                            if(cmdsLeft > 0) {
3388                                    for(int j = 0; j < cmdsLeft; j++) {
3389                                            int idx = stepCount * cmdsPerStep + j;
3390                                            writeOutput(idx);
3391                                    }
3392    
3393                                    for(int j = 0; j < cmdsLeft; j++) {
3394                                            int idx = stepCount * cmdsPerStep + j;
3395                                            readInput(idx);
3396                                    }
3397                            }
3398                    }
3399    
3400                    protected abstract void writeOutput(int index) throws IOException;
3401    
3402                    protected abstract void readInput(int index) throws IOException, LscpException, LSException;
3403            }
3404                    
3405          /**          /**
3406           * Gets a list with numerical IDs of all created sampler channels.           * Gets a list with numerical IDs of all created sampler channels.
# Line 2950  public class Client { Line 3414  public class Client {
3414           */           */
3415          public synchronized Integer[]          public synchronized Integer[]
3416          getSamplerChannelIDs() throws IOException, LscpException, LSException {          getSamplerChannelIDs() throws IOException, LscpException, LSException {
3417                  verifyConnection();                  return getIntegerList("LIST CHANNELS");
                 out.writeLine("LIST CHANNELS");  
                 if(getPrintOnlyMode()) return null;  
                   
                 return parseIntList(getSingleLineResultSet().getResult());  
3418          }          }
3419                    
3420          /**          /**
# Line 2969  public class Client { Line 3429  public class Client {
3429           */           */
3430          public synchronized int          public synchronized int
3431          addSamplerChannel() throws IOException, LSException, LscpException {          addSamplerChannel() throws IOException, LSException, LscpException {
3432                  verifyConnection();                  return retrieveIndex("ADD CHANNEL");
                 out.writeLine("ADD CHANNEL");  
                 if(getPrintOnlyMode()) return -1;  
                   
                 ResultSet rs = getEmptyResultSet();  
                   
                 return rs.getIndex();  
3433          }          }
3434                    
3435          /**          /**
# Line 2991  public class Client { Line 3445  public class Client {
3445           */           */
3446          public synchronized void          public synchronized void
3447          removeSamplerChannel(int samplerChn) throws IOException, LscpException, LSException {          removeSamplerChannel(int samplerChn) throws IOException, LscpException, LSException {
3448                  verifyConnection();                  retrieveIndex("REMOVE CHANNEL " + samplerChn);
                 out.writeLine("REMOVE CHANNEL " + samplerChn);  
                 if(getPrintOnlyMode()) return;  
                   
                 ResultSet rs = getEmptyResultSet();  
3449          }          }
3450                    
3451          /**          /**
3452           * Gets the number of all available engines.           * Gets the number of all available engines.
3453           * @return The number of all available engines.           * @return The number of all available engines or -1 if in "print only" mode.
3454           * @throws IOException If some I/O error occurs.           * @throws IOException If some I/O error occurs.
3455           * @throws LscpException If LSCP protocol corruption occurs.           * @throws LscpException If LSCP protocol corruption occurs.
3456           * @throws LSException If some other error occurs.           * @throws LSException If some other error occurs.
3457           */           */
3458          public synchronized int          public synchronized int
3459          getEngineCount() throws IOException, LscpException, LSException {          getEngineCount() throws IOException, LscpException, LSException {
3460                  verifyConnection();                  return retrieveInt("GET AVAILABLE_ENGINES");
                 out.writeLine("GET AVAILABLE_ENGINES");  
                 if(getPrintOnlyMode()) return -1;  
                   
                 String s = getSingleLineResultSet().getResult();  
                 return parseInt(s);  
3461          }          }
3462                    
3463          /**          /**
# Line 3066  public class Client { Line 3511  public class Client {
3511           */           */
3512          private synchronized SamplerEngine          private synchronized SamplerEngine
3513          getEngineInfo(String engineName) throws IOException, LscpException, LSException {          getEngineInfo(String engineName) throws IOException, LscpException, LSException {
3514                  verifyConnection();                  SamplerEngine se = engineMap.get(engineName);
3515                  out.writeLine("GET ENGINE INFO " + engineName);                  if(se != null) return se;
                 if(getPrintOnlyMode()) return null;  
3516                                    
3517                  ResultSet rs = getMultiLineResultSet();                  se = new SamplerEngine();
3518                  SamplerEngine se = new SamplerEngine(rs.getMultiLineResult());                  if(!retrieveInfo("GET ENGINE INFO " + engineName, se)) return null;
3519                  se.setName(engineName);                  se.setName(engineName);
3520                    engineMap.put(engineName, se);
3521    
3522                  return se;                  return se;
3523          }          }
3524                    
# Line 3090  public class Client { Line 3536  public class Client {
3536           */           */
3537          public synchronized SamplerChannel          public synchronized SamplerChannel
3538          getSamplerChannelInfo(int samplerChn) throws IOException, LscpException, LSException {          getSamplerChannelInfo(int samplerChn) throws IOException, LscpException, LSException {
3539                  verifyConnection();                  SamplerChannel sc = new SamplerChannel();
3540                  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());  
3541                  sc.setChannelId(samplerChn);                  sc.setChannelId(samplerChn);
3542                  if(sc.getEngine() != null) sc.setEngine(getEngineInfo(sc.getEngine().getName()));                  if(sc.getEngine() != null) sc.setEngine(getEngineInfo(sc.getEngine().getName()));
3543                                    
# Line 3106  public class Client { Line 3548  public class Client {
3548           * Gets the current number of active voices on the specified sampler channel.           * Gets the current number of active voices on the specified sampler channel.
3549           *           *
3550           * @param samplerChn The sampler channel number.           * @param samplerChn The sampler channel number.
3551           * @return The current number of active voices on the specified sampler channel.           * @return The current number of active voices on the
3552             * specified sampler channel or -1 if in "print only" mode.
3553           * @throws IOException If some I/O error occurs.           * @throws IOException If some I/O error occurs.
3554           * @throws LscpException If LSCP protocol corruption occurs.           * @throws LscpException If LSCP protocol corruption occurs.
3555           * @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 3114  public class Client { Line 3557  public class Client {
3557           */           */
3558          public synchronized int          public synchronized int
3559          getChannelVoiceCount(int samplerChn) throws IOException, LscpException, LSException {          getChannelVoiceCount(int samplerChn) throws IOException, LscpException, LSException {
3560                  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());  
3561          }          }
3562                    
3563          /**          /**
# Line 3260  public class Client { Line 3697  public class Client {
3697           */           */
3698          public synchronized void          public synchronized void
3699          setChannelAudioOutputDevice(int samplerChn, int devId)          setChannelAudioOutputDevice(int samplerChn, int devId)
3700                                  throws IOException, LscpException, LSException {                                  throws IOException, LscpException, LSException
3701                            { retrieveIndex("SET CHANNEL AUDIO_OUTPUT_DEVICE " + samplerChn + ' ' + devId); }
                 verifyConnection();  
                 out.writeLine("SET CHANNEL AUDIO_OUTPUT_DEVICE " + samplerChn + ' ' + devId);  
                 if(getPrintOnlyMode()) return;  
                   
                 ResultSet rs = getEmptyResultSet();  
         }  
3702                    
3703          /**          /**
3704           * Sets the audio output channel on the specified sampler channel.           * Sets the audio output channel on the specified sampler channel.
# Line 3290  public class Client { Line 3721  public class Client {
3721           */           */
3722          public synchronized void          public synchronized void
3723          setChannelAudioOutputChannel(int samplerChn, int audioOut, int audioIn)          setChannelAudioOutputChannel(int samplerChn, int audioOut, int audioIn)
3724                                  throws IOException, LscpException, LSException {                                  throws IOException, LscpException, LSException
3725                            {
                 verifyConnection();  
3726                  String args = " " + samplerChn + ' ' + audioOut + ' ' + audioIn;                  String args = " " + samplerChn + ' ' + audioOut + ' ' + audioIn;
3727                  out.writeLine("SET CHANNEL AUDIO_OUTPUT_CHANNEL" + args);                  retrieveIndex("SET CHANNEL AUDIO_OUTPUT_CHANNEL" + args);
                 if(getPrintOnlyMode()) return;  
                   
                 ResultSet rs = getEmptyResultSet();  
3728          }          }
3729                    
3730          /**          /**
# Line 3319  public class Client { Line 3746  public class Client {
3746           */           */
3747          public synchronized void          public synchronized void
3748          setChannelMidiInputDevice(int samplerChn, int devId)          setChannelMidiInputDevice(int samplerChn, int devId)
3749                                  throws IOException, LscpException, LSException {                                  throws IOException, LscpException, LSException
3750                            { retrieveIndex("SET CHANNEL MIDI_INPUT_DEVICE " + samplerChn + ' ' + devId); }
                 verifyConnection();  
                 out.writeLine("SET CHANNEL MIDI_INPUT_DEVICE " + samplerChn + ' ' + devId);  
                 if(getPrintOnlyMode()) return;  
                   
                 ResultSet rs = getEmptyResultSet();  
         }  
3751                    
3752          /**          /**
3753           * Sets the MIDI input port on the specified sampler channel.           * Sets the MIDI input port on the specified sampler channel.
# Line 3342  public class Client { Line 3763  public class Client {
3763           */           */
3764          public synchronized void          public synchronized void
3765          setChannelMidiInputPort(int samplerChn, int port)          setChannelMidiInputPort(int samplerChn, int port)
3766                                  throws IOException, LscpException, LSException {                                  throws IOException, LscpException, LSException
3767                            { retrieveIndex("SET CHANNEL MIDI_INPUT_PORT " + samplerChn + ' ' + port); }
                 verifyConnection();  
                 out.writeLine("SET CHANNEL MIDI_INPUT_PORT " + samplerChn + ' ' + port);  
                 if(getPrintOnlyMode()) return;  
                   
                 ResultSet rs = getEmptyResultSet();  
         }  
3768                    
3769          /**          /**
3770           * 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 3365  public class Client { Line 3780  public class Client {
3780           */           */
3781          public synchronized void          public synchronized void
3782          setChannelMidiInputChannel(int samplerChn, int midiChn)          setChannelMidiInputChannel(int samplerChn, int midiChn)
3783                                  throws IOException, LscpException, LSException {                                  throws IOException, LscpException, LSException
3784                            {
                 verifyConnection();  
3785                  String args = String.valueOf(samplerChn) + ' ';                  String args = String.valueOf(samplerChn) + ' ';
3786                  args += (midiChn == -1 ? "ALL" : String.valueOf(midiChn));                  args += (midiChn == -1 ? "ALL" : String.valueOf(midiChn));
3787                  out.writeLine("SET CHANNEL MIDI_INPUT_CHANNEL " + args);                  retrieveIndex("SET CHANNEL MIDI_INPUT_CHANNEL " + args);
                 if(getPrintOnlyMode()) return;  
                   
                 ResultSet rs = getEmptyResultSet();  
3788          }          }
3789                    
3790          /**          /**
# Line 3397  public class Client { Line 3808  public class Client {
3808           */           */
3809          public synchronized void          public synchronized void
3810          setChannelMidiInstrumentMap(int samplerChn, int mapId)          setChannelMidiInstrumentMap(int samplerChn, int mapId)
3811                                  throws IOException, LscpException, LSException {                                  throws IOException, LscpException, LSException
3812                            {
                 verifyConnection();  
3813                  String s;                  String s;
3814                  if(mapId == -1) {                  if(mapId == -1) {
3815                          s = " NONE";                          s = " NONE";
# Line 3408  public class Client { Line 3818  public class Client {
3818                  } else {                  } else {
3819                          s = " " + String.valueOf(mapId);                          s = " " + String.valueOf(mapId);
3820                  }                  }
3821                  out.writeLine("SET CHANNEL MIDI_INSTRUMENT_MAP " + samplerChn + s);  
3822                  if(getPrintOnlyMode()) return;                  retrieveIndex("SET CHANNEL MIDI_INSTRUMENT_MAP " + samplerChn + s);
                   
                 ResultSet rs = getEmptyResultSet();  
3823          }          }
3824                    
3825          /**          /**
# Line 3428  public class Client { Line 3836  public class Client {
3836           */           */
3837          public synchronized void          public synchronized void
3838          setChannelVolume(int samplerChn, float volume)          setChannelVolume(int samplerChn, float volume)
3839                                  throws IOException, LscpException, LSException {                                  throws IOException, LscpException, LSException
3840                    { retrieveIndex("SET CHANNEL VOLUME " + samplerChn + ' ' + volume); }
                 verifyConnection();  
                 out.writeLine("SET CHANNEL VOLUME " + samplerChn + ' ' + volume);  
                 if(getPrintOnlyMode()) return;  
                   
                 ResultSet rs = getEmptyResultSet();  
         }  
3841                    
3842          /**          /**
3843           * Mute/unmute the specified sampler channel.           * Mute/unmute the specified sampler channel.
# Line 3452  public class Client { Line 3854  public class Client {
3854           */           */
3855          public synchronized void          public synchronized void
3856          setChannelMute(int samplerChn, boolean mute)          setChannelMute(int samplerChn, boolean mute)
3857                                  throws IOException, LscpException, LSException {                                  throws IOException, LscpException, LSException
3858                    { retrieveIndex("SET CHANNEL MUTE " + samplerChn + ' ' + (mute ? 1 : 0)); }
                 verifyConnection();  
                 out.writeLine("SET CHANNEL MUTE " + samplerChn + ' ' + (mute ? 1 : 0));  
                 if(getPrintOnlyMode()) return;  
                   
                 ResultSet rs = getEmptyResultSet();  
         }  
3859                    
3860          /**          /**
3861           * Solo/unsolo the specified sampler channel.           * Solo/unsolo the specified sampler channel.
# Line 3476  public class Client { Line 3872  public class Client {
3872           */           */
3873          public synchronized void          public synchronized void
3874          setChannelSolo(int samplerChn, boolean solo)          setChannelSolo(int samplerChn, boolean solo)
3875                                  throws IOException, LscpException, LSException {                                  throws IOException, LscpException, LSException
3876                    { retrieveIndex("SET CHANNEL SOLO " + samplerChn + ' ' + (solo ? 1 : 0)); }
                 verifyConnection();  
                 out.writeLine("SET CHANNEL SOLO " + samplerChn + ' ' + (solo ? 1 : 0));  
                 if(getPrintOnlyMode()) return;  
                   
                 ResultSet rs = getEmptyResultSet();  
         }  
3877                    
3878          /**          /**
3879           * Creates an additional effect send on the specified sampler channel.           * Creates an additional effect send on the specified sampler channel.
# Line 3516  public class Client { Line 3906  public class Client {
3906           */           */
3907          public synchronized int          public synchronized int
3908          createFxSend(int channel, int midiCtrl, String name)          createFxSend(int channel, int midiCtrl, String name)
3909                          throws IOException, LSException, LscpException {                          throws IOException, LSException, LscpException
3910                            {
                 verifyConnection();  
3911                  String s = String.valueOf(channel) + " " + String.valueOf(midiCtrl);                  String s = String.valueOf(channel) + " " + String.valueOf(midiCtrl);
3912                  if(name != null) s += " '" + toEscapedString(name) + "'";                  if(name != null) s += " '" + toEscapedText(name) + "'";
3913                  out.writeLine("CREATE FX_SEND " + s);  
3914                  if(getPrintOnlyMode()) return -1;                  return retrieveIndex("CREATE FX_SEND " + s);
                   
                 ResultSet rs = getEmptyResultSet();  
                   
                 return rs.getIndex();  
3915          }          }
3916                    
3917          /**          /**
# Line 3540  public class Client { Line 3925  public class Client {
3925           */           */
3926          public synchronized void          public synchronized void
3927          destroyFxSend(int channel, int fxSend)          destroyFxSend(int channel, int fxSend)
3928                          throws IOException, LSException, LscpException {                          throws IOException, LSException, LscpException
3929                            {
                 verifyConnection();  
3930                  String s = String.valueOf(channel) + " " + String.valueOf(fxSend);                  String s = String.valueOf(channel) + " " + String.valueOf(fxSend);
3931                  out.writeLine("DESTROY FX_SEND " + s);                  retrieveIndex("DESTROY FX_SEND " + s);
                 if(getPrintOnlyMode()) return;  
                   
                 ResultSet rs = getEmptyResultSet();  
3932          }          }
3933                    
3934          /**          /**
# Line 3559  public class Client { Line 3940  public class Client {
3940           * @throws LSException If some other error occurs.           * @throws LSException If some other error occurs.
3941           */           */
3942          public synchronized int          public synchronized int
3943          getFxSoundCount(int channel) throws IOException, LscpException, LSException {          getFxSendCount(int channel) throws IOException, LscpException, LSException {
3944                  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);  
3945          }          }
3946                    
3947          /**          /**
# Line 3605  public class Client { Line 3981  public class Client {
3981           */           */
3982          public synchronized Integer[]          public synchronized Integer[]
3983          getFxSendIDs(int channel) throws IOException, LscpException, LSException {          getFxSendIDs(int channel) throws IOException, LscpException, LSException {
3984                  verifyConnection();                  return getIntegerList("LIST FX_SENDS " + channel);
                 out.writeLine("LIST FX_SENDS " + channel);  
                 if(getPrintOnlyMode()) return null;  
                   
                 return parseIntList(getSingleLineResultSet().getResult());  
3985          }          }
3986                    
3987          /**          /**
# Line 3624  public class Client { Line 3996  public class Client {
3996           */           */
3997          public synchronized FxSend          public synchronized FxSend
3998          getFxSendInfo(int channel, int fxSend) throws IOException, LscpException, LSException {          getFxSendInfo(int channel, int fxSend) throws IOException, LscpException, LSException {
3999                  verifyConnection();                  FxSend fxs = new FxSend();
4000                  String s = String.valueOf(channel) + " " + String.valueOf(fxSend);                  String s = String.valueOf(channel) + " " + String.valueOf(fxSend);
4001                  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());  
4002                  fxs.setFxSendId(fxSend);                  fxs.setFxSendId(fxSend);
4003                                    
4004                  return fxs;                  return fxs;
# Line 3648  public class Client { Line 4016  public class Client {
4016           */           */
4017          public synchronized void          public synchronized void
4018          setFxSendName(int channel, int fxSend, String name)          setFxSendName(int channel, int fxSend, String name)
4019                                  throws IOException, LscpException, LSException {                                  throws IOException, LscpException, LSException
4020                            {
4021                  verifyConnection();                  String args = " " + channel + " " + fxSend + " '" + toEscapedText(name) + "'";
4022                  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();  
4023          }          }
4024                    
4025          /**          /**
# Line 3678  public class Client { Line 4042  public class Client {
4042           */           */
4043          public synchronized void          public synchronized void
4044          setFxSendAudioOutputChannel(int channel, int fxSend, int audioSrc, int audioDst)          setFxSendAudioOutputChannel(int channel, int fxSend, int audioSrc, int audioDst)
4045                                  throws IOException, LscpException, LSException {                                  throws IOException, LscpException, LSException
4046                            {
                 verifyConnection();  
4047                  String args = " " + channel + " " + fxSend + " " + audioSrc + " " + audioDst;                  String args = " " + channel + " " + fxSend + " " + audioSrc + " " + audioDst;
4048                  out.writeLine("SET FX_SEND AUDIO_OUTPUT_CHANNEL" + args);                  retrieveIndex("SET FX_SEND AUDIO_OUTPUT_CHANNEL" + args);
4049                  if(getPrintOnlyMode()) return;          }
4050                    
4051                  ResultSet rs = getEmptyResultSet();          /**
4052             * Assign a destination effect to an effect send.
4053             * @param channel The sampler channel number.
4054             * @param fxSend The numerical ID of the effect send entity.
4055             * @param fxChainId The numerical ID of the destination effect chain.
4056             * @param chainPos The exact effect chain position in the effect
4057             * chain which hosts the actual destination effect.
4058             * @throws IOException If some I/O error occurs.
4059             * @throws LscpException If LSCP protocol corruption occurs.
4060             * @throws LSException If
4061             * <ul>
4062             * <li><code>channel</code> is not a valid channel number;
4063             * <li><code>fxSend</code> is not a valid effect send ID;
4064             * <li><code>fxChainId</code> is not a valid effect chain ID;
4065             * <li><code>chainPos</code> is out of bounds;
4066             * <li>There is no engine assigned yet to the specified sampler channel;
4067             * <li>There is no audio output device connected to the specified sampler channel.
4068             * </ul>
4069             */
4070            public synchronized void
4071            setFxSendEffect(int channel, int fxSend, int fxChainId, int chainPos)
4072                                    throws IOException, LscpException, LSException
4073            {
4074                    String args = " " + channel + " " + fxSend + " " + fxChainId + " " + chainPos;
4075                    retrieveIndex("SET FX_SEND EFFECT" + args);
4076            }
4077    
4078            /**
4079             * Removes destination effect from an effect send.
4080             * @param channel The sampler channel number.
4081             * @param fxSend The numerical ID of the effect send entity.
4082             * @throws IOException If some I/O error occurs.
4083             * @throws LscpException If LSCP protocol corruption occurs.
4084             * @throws LSException If other error occurs.
4085             */
4086            public synchronized void
4087            removeFxSendEffect(int channel, int fxSend) throws IOException, LscpException, LSException {
4088                    String args = " " + channel + " " + fxSend;
4089                    retrieveIndex("REMOVE FX_SEND EFFECT" + args);
4090          }          }
4091                    
4092          /**          /**
# Line 3706  public class Client { Line 4107  public class Client {
4107           */           */
4108          public synchronized void          public synchronized void
4109          setFxSendMidiController(int channel, int fxSend, int midiCtrl)          setFxSendMidiController(int channel, int fxSend, int midiCtrl)
4110                                  throws IOException, LscpException, LSException {                                  throws IOException, LscpException, LSException
4111                            {
                 verifyConnection();  
4112                  String args = " " + channel + " " + fxSend + " " + midiCtrl;                  String args = " " + channel + " " + fxSend + " " + midiCtrl;
4113                  out.writeLine("SET FX_SEND MIDI_CONTROLLER" + args);                  retrieveIndex("SET FX_SEND MIDI_CONTROLLER" + args);
                 if(getPrintOnlyMode()) return;  
                   
                 ResultSet rs = getEmptyResultSet();  
4114          }          }
4115                    
4116          /**          /**
# Line 3729  public class Client { Line 4126  public class Client {
4126           */           */
4127          public synchronized void          public synchronized void
4128          setFxSendLevel(int channel, int fxSend, float volume)          setFxSendLevel(int channel, int fxSend, float volume)
4129                                  throws IOException, LscpException, LSException {                                  throws IOException, LscpException, LSException
4130                            {
                 verifyConnection();  
4131                  String args = " " + channel + " " + fxSend + " " + String.valueOf(volume);                  String args = " " + channel + " " + fxSend + " " + String.valueOf(volume);
4132                  out.writeLine("SET FX_SEND LEVEL" + args);                  retrieveIndex("SET FX_SEND LEVEL" + args);
4133                  if(getPrintOnlyMode()) return;          }
4134                    
4135                  ResultSet rs = getEmptyResultSet();  
4136            /**
4137             * Gets the current amount of internal effects available to the sampler.
4138             * @return The current amount of internal effects available to the sampler.
4139             * @throws IOException If some I/O error occurs.
4140             * @throws LscpException If LSCP protocol corruption occurs.
4141             * @throws LSException If some other error occurs.
4142             */
4143            public synchronized int
4144            getEffectCount() throws IOException, LscpException, LSException
4145            { return retrieveInt("GET AVAILABLE_EFFECTS"); }
4146    
4147            /**
4148             * Gets the list of internal effects available to the sampler.
4149             * Note that the set of available internal effects can change at runtime.
4150             * @return An <code>Effect</code> array providing the current list of internal effects.
4151             * @throws IOException If some I/O error occurs.
4152             * @throws LscpException If LSCP protocol corruption occurs.
4153             */
4154            public synchronized Effect[]
4155            getEffects() throws IOException, LscpException, LSException {
4156                    Integer[] idS = getEffectIDs();
4157                    if(getPrintOnlyMode()) return null;
4158    
4159                    Effect[] effects = new Effect[idS.length];
4160    
4161                    for(int i = 0; i < effects.length; i++)
4162                            effects[i] = getEffectInfo(idS[i]);
4163    
4164                    return effects;
4165            }
4166    
4167            /**
4168             * Retrieves the list of available internal effects.
4169             * Note that the set of available internal effects can change at runtime.
4170             * @return An <code>Integer</code> array providing
4171             * the numerical IDs of all available internal effects.
4172             * @throws IOException If some I/O error occurs.
4173             * @throws LscpException If LSCP protocol corruption occurs.
4174             */
4175            public synchronized Integer[]
4176            getEffectIDs() throws IOException, LscpException, LSException
4177            { return getIntegerList("LIST AVAILABLE_EFFECTS"); }
4178    
4179            /**
4180             * Gets general informations about the specified effect.
4181             * @param effect The numerical ID of the effect entity.
4182             * @return <code>Effect</code> instance containing
4183             * general informations about the specified effect.
4184             * @throws IOException If an I/O error occurs.
4185             * @throws LscpException If LSCP protocol corruption occurs.
4186             * @throws LSException If the effect ID is invalid.
4187             */
4188            public synchronized Effect
4189            getEffectInfo(int effect) throws IOException, LscpException, LSException {
4190                    Effect e = new Effect();
4191                    if(!retrieveInfo("GET EFFECT INFO " + effect, e)) return null;
4192                    e.setEffectId(effect);
4193    
4194                    return e;
4195            }
4196    
4197            /**
4198             * Creates an instance of the desired effect.
4199             * @param id The unique ID of the effect.
4200             * @return The unique ID of the newly created effect instance.
4201             * @throws IOException If some I/O error occurs.
4202             * @throws LSException If the creation of the effect instance failed.
4203             * @throws LscpException If LSCP protocol corruption occurs.
4204             * @see #getEffectIDs
4205             * @see #getEffectInfo
4206             * @see #destroyEffectInstance
4207             */
4208            public synchronized int
4209            createEffectInstanceById(int id) throws IOException, LSException, LscpException
4210            { return retrieveIndex("CREATE EFFECT_INSTANCE " + String.valueOf(id)); }
4211    
4212            /**
4213             * Creates an instance of the desired effect.
4214             * @return The unique ID of the newly created effect instance.
4215             * @throws IOException If some I/O error occurs.
4216             * @throws LSException If the creation of the effect instance failed.
4217             * @throws LscpException If LSCP protocol corruption occurs.
4218             * @see #getEffectInfo
4219             * @see #destroyEffectInstance
4220             */
4221            public synchronized int
4222            createEffectInstance(Effect effect) throws IOException, LSException, LscpException
4223            { return createEffectInstanceById(effect.getEffectId()); }
4224    
4225            /**
4226             * Creates an instance of the desired effect.
4227             * @return The unique ID of the newly created effect instance.
4228             * @throws IOException If some I/O error occurs.
4229             * @throws LSException If the creation of the effect instance failed.
4230             * @throws LscpException If LSCP protocol corruption occurs.
4231             * @see #getEffectInfo
4232             * @see #destroyEffectInstance
4233             */
4234            public synchronized int
4235            createEffectInstance(String system, String module, String name)
4236                            throws IOException, LSException, LscpException
4237            {
4238                    String s = system + " '" + toEscapedText(module) + "' '" + toEscapedText(name) + "'";
4239                    return retrieveIndex("CREATE EFFECT_INSTANCE " + s);
4240            }
4241    
4242            /**
4243             * Destroys the specified unused effect instance.
4244             * @param instanceId The numerical ID of the effect instance.
4245             * @throws LscpException If LSCP protocol corruption occurs.
4246             * @throws LSException If some other error occurs.
4247             * @see #createEffectInstance
4248             */
4249            public synchronized void
4250            destroyEffectInstance(int instanceId) throws IOException, LSException, LscpException
4251            { retrieveIndex("DESTROY EFFECT_INSTANCE " + String.valueOf(instanceId)); }
4252            /**
4253             * Gets the current amount of effect instances available to the sampler.
4254             * @return The current amount of effect instances available to the sampler.
4255             * @throws IOException If some I/O error occurs.
4256             * @throws LscpException If LSCP protocol corruption occurs.
4257             * @throws LSException If some other error occurs.
4258             */
4259            public synchronized int
4260            getEffectInstanceCount() throws IOException, LscpException, LSException
4261            { return retrieveInt("GET EFFECT_INSTANCES"); }
4262    
4263            /**
4264             * Gets the current list of effect instances.
4265             * @return An <code>EffectInstanceInfo</code> array
4266             * providing the current list of effect instances.
4267             * @throws IOException If some I/O error occurs.
4268             * @throws LscpException If LSCP protocol corruption occurs.
4269             */
4270            public synchronized EffectInstanceInfo[]
4271            getEffectInstances() throws IOException, LscpException, LSException {
4272                    Integer[] idS = getEffectInscanceIDs();
4273                    if(getPrintOnlyMode()) return null;
4274    
4275                    EffectInstanceInfo[] eis = new EffectInstanceInfo[idS.length];
4276    
4277                    for(int i = 0; i < eis.length; i++)
4278                            eis[i] = getEffectInstanceInfo(idS[i]);
4279    
4280                    return eis;
4281            }
4282    
4283            /**
4284             * Retrieves the current list of effect instances.
4285             * @return An <code>Integer</code> array providing
4286             * the numerical IDs of all available effect instances.
4287             * @throws IOException If some I/O error occurs.
4288             * @throws LscpException If LSCP protocol corruption occurs.
4289             */
4290            public synchronized Integer[]
4291            getEffectInscanceIDs() throws IOException, LscpException, LSException
4292            { return getIntegerList("LIST EFFECT_INSTANCES"); }
4293    
4294            /**
4295             * Gets the current informations about the specified effect instance.
4296             * @param id The numerical ID of the effect instance.
4297             * @return <code>EffectInstanceInfo</code> object containing
4298             * the current informations about the specified effect instance.
4299             * @throws IOException If an I/O error occurs.
4300             * @throws LscpException If LSCP protocol corruption occurs.
4301             * @throws LSException If the effect instance ID is invalid.
4302             */
4303            public synchronized EffectInstanceInfo
4304            getEffectInstanceInfo(int id) throws IOException, LscpException, LSException {
4305                    EffectInstanceInfo ei = new EffectInstanceInfo();
4306                    if(!retrieveInfo("GET EFFECT_INSTANCE INFO " + id, ei)) return null;
4307                    ei.setInstanceId(id);
4308    
4309                    for(int i = 0; i < ei.getParameterCount(); i++) {
4310                            ei.addParameter(getEffectInstanceParameterInfo(id, i));
4311                    }
4312    
4313                    return ei;
4314            }
4315    
4316            /**
4317             * Gets information about the specified effect parameter.
4318             * @param id The numerical ID of the effect instance.
4319             * @param parameter The parameter index.
4320             * @return <code>EffectParameter</code> object containing
4321             * information about the specified effect parameter.
4322             * Note that only the following fields are used - description,
4323             * value, rangeMin, rangeMax, possibilities and default.
4324             * @throws IOException If an I/O error occurs.
4325             * @throws LscpException If LSCP protocol corruption occurs.
4326             * @throws LSException If the effect instance ID or the parameter index is invalid.
4327             */
4328            public synchronized EffectParameter
4329            getEffectInstanceParameterInfo(int instanceId, int parameter)
4330                                    throws IOException, LscpException, LSException
4331            {
4332                    EffectParameter prm = new EffectParameter(instanceId, parameter);
4333                    String s = String.valueOf(instanceId) + " " + String.valueOf(parameter);
4334                    if(!retrieveInfo("GET EFFECT_INSTANCE_INPUT_CONTROL INFO " + s, prm)) return null;
4335    
4336                    return prm;
4337            }
4338    
4339            /**
4340             * Alters the current value of an effect parameter.
4341             * @param instanceId The numerical ID of the effect instance.
4342             * @param prmIndex The index of the parameter to alter.
4343             * @param value The new value for this parameter.
4344             * @throws IOException If some I/O error occurs.
4345             * @throws LscpException If LSCP protocol corruption occurs.
4346             * @throws LSException If
4347             * <ul>
4348             * <li>There is no effect instance with numerical ID <code>instanceId</code>;
4349             * <li>There parameter index is invalid;
4350             * <li>The new value is out of range;
4351             * </ul>
4352             *
4353             * @see #getEffectInstanceInfo
4354             * @see #getEffectInstanceParameterInfo
4355             */
4356            public synchronized void
4357            setEffectInstanceParameter(int instanceId, int prmIndex, float value)
4358                                            throws IOException, LscpException, LSException
4359            {
4360                    String s = " " + instanceId + " " + prmIndex + " " + value;
4361                    retrieveIndex("SET EFFECT_INSTANCE_INPUT_CONTROL VALUE" + s);
4362            }
4363            /**
4364             * Gets the current amount of send effect chains on the specified audio output device.
4365             * @param audioDeviceId numerical ID of the audio output device.
4366             * @return The current amount of send effect chains or -1 if in "print only" mode.
4367             * @throws IOException If some I/O error occurs.
4368             * @throws LscpException If LSCP protocol corruption occurs.
4369             * @throws LSException If some other error occurs.
4370             */
4371            public synchronized int
4372            getSendEffectChainCount(int audioDeviceId) throws IOException, LscpException, LSException
4373            { return retrieveInt("GET SEND_EFFECT_CHAINS " + audioDeviceId); }
4374    
4375            /**
4376             * Gets the current list of send effect chains on the specified audio output device.
4377             * @param audioDeviceId The numerical ID of the audio output device.
4378             * @return An <code>EffectInstanceInfo</code> array
4379             * providing the current list of effect instances.
4380             * @throws IOException If some I/O error occurs.
4381             * @throws LscpException If LSCP protocol corruption occurs.
4382             */
4383            public synchronized EffectChainInfo[]
4384            getSendEffectChains(int audioDeviceId) throws IOException, LscpException, LSException {
4385                    Integer[] idS = getSendEffectChainIDs(audioDeviceId);
4386                    if(getPrintOnlyMode()) return null;
4387    
4388                    EffectChainInfo[] ecs = new EffectChainInfo[idS.length];
4389    
4390                    for(int i = 0; i < ecs.length; i++) {
4391                            ecs[i] = getSendEffectChainInfo(audioDeviceId, idS[i]);
4392                            ecs[i].setChainId(idS[i]);
4393                    }
4394    
4395                    return ecs;
4396            }
4397    
4398            /**
4399             * Retrieves the current list of send effect
4400             * chains on the specified audio output device.
4401             * @param audioDeviceId The numerical ID of the audio output device.
4402             * @return An <code>Integer</code> array providing the numerical
4403             * IDs of all send effect chains on the specified audio output device.
4404             * @throws IOException If some I/O error occurs.
4405             * @throws LscpException If LSCP protocol corruption occurs.
4406             */
4407            public synchronized Integer[]
4408            getSendEffectChainIDs(int audioDeviceId) throws IOException, LscpException, LSException
4409            { return getIntegerList("LIST SEND_EFFECT_CHAINS " + audioDeviceId); }
4410    
4411            /**
4412             * Adds a send effect chain to the specified audio output device.
4413             * @param audioDeviceId The numerical ID of the audio output device.
4414             * @return The numerical ID of the new send effect chain.
4415             * @throws IOException If some I/O error occurs.
4416             * @throws LSException If the creation of the effect chain failed.
4417             * @throws LscpException If LSCP protocol corruption occurs.
4418             * @see #removeSendEffectChain
4419             * @see #getSendEffectChainInfo
4420             */
4421            public synchronized int
4422            addSendEffectChain(int audioDeviceId) throws IOException, LSException, LscpException
4423            { return retrieveIndex("ADD SEND_EFFECT_CHAIN " + audioDeviceId); }
4424    
4425            /**
4426             * Removes a send effect chain from an audio output device.
4427             * @param audioDeviceId The numerical ID of the audio output device.
4428             * @param chainId The numerical ID of the send effect chain to remove.
4429             * @throws LscpException If LSCP protocol corruption occurs.
4430             * @throws LSException If some other error occurs.
4431             * @see #addSendEffectChain
4432             */
4433            public synchronized void
4434            removeSendEffectChain(int audioDeviceId, int chainId) throws IOException, LSException, LscpException
4435            { retrieveIndex("REMOVE SEND_EFFECT_CHAIN " + audioDeviceId + " " + chainId); }
4436    
4437            /**
4438             * Gets the current information of a send effect chain.
4439             * @param audioDeviceId The numerical ID of the audio output device.
4440             * @param chainId The numerical ID of the send effect chain.
4441             * @return <code>EffectChainInfo</code> object containing
4442             * the current informations about the specified effect chain.
4443             * @throws IOException If an I/O error occurs.
4444             * @throws LscpException If LSCP protocol corruption occurs.
4445             * @throws LSException If the audio device ID or the effect chain ID is invalid.
4446             */
4447            public synchronized EffectChainInfo
4448            getSendEffectChainInfo(int audioDeviceId, int chainId)
4449                                    throws IOException, LscpException, LSException
4450            {
4451                    verifyConnection();
4452                    String str = " " + audioDeviceId + " " + chainId;
4453                    out.writeLine("GET SEND_EFFECT_CHAIN INFO" + str);
4454                    if(getPrintOnlyMode()) return null;
4455    
4456                    ResultSet rs = getMultiLineResultSet();
4457                    EffectChainInfo chain = null;
4458    
4459                    for(String s : rs.getMultiLineResult()) {
4460                            if(s.startsWith("EFFECT_SEQUENCE: ")) {
4461                                    s = s.substring("EFFECT_SEQUENCE: ".length());
4462                                    Integer[] eis = parseIntList(s);
4463                                    EffectInstanceInfo[] instances = new EffectInstanceInfo[eis.length];
4464                                    for(int i = 0; i < eis.length; i++) {
4465                                            instances[i] = getEffectInstanceInfo(eis[i]);
4466                                    }
4467                                    chain = new EffectChainInfo(instances);
4468                                    chain.setChainId(chainId);
4469                            }
4470                    }
4471    
4472                    return chain;
4473            }
4474    
4475            /**
4476             * Adds an unused effect instance to the end of a send effect chain.
4477             * @param audioDeviceId The numerical ID of the audio output device.
4478             * @param chainId The numerical ID of the send effect chain.
4479             * @param fxInstanceId The numerical ID of the effect instance to add.
4480             * @throws IOException If some I/O error occurs.
4481             * @throws LSException If invalid index is specified.
4482             * @throws LscpException If LSCP protocol corruption occurs.
4483             * @see #addSendEffectChain
4484             * @see #createEffectInstance
4485             */
4486            public synchronized void
4487            appendEffectInstance(int audioDeviceId, int chainId, int fxInstanceId)
4488                            throws IOException, LSException, LscpException
4489            {
4490                    String s = " " + audioDeviceId + " " + chainId + " " + fxInstanceId;
4491                    retrieveIndex("APPEND SEND_EFFECT_CHAIN EFFECT" + s);
4492            }
4493    
4494            /**
4495             * Adds an unused effect instance at a certain position of a send effect chain.
4496             * @param audioDeviceId The numerical ID of the audio output device.
4497             * @param chainId The numerical ID of the send effect chain.
4498             * @param pos The exact position in the effect chain where
4499             * the supplied effect shall be inserted to.
4500             * @param fxInstanceId The numerical ID of the effect instance to insert.
4501             * @throws IOException If some I/O error occurs.
4502             * @throws LSException If invalid index is specified.
4503             * @throws LscpException If LSCP protocol corruption occurs.
4504             * @see #addSendEffectChain
4505             * @see #createEffectInstance
4506             */
4507            public synchronized void
4508            insertEffectInstance(int audioDeviceId, int chainId, int pos, int fxInstanceId)
4509                            throws IOException, LSException, LscpException
4510            {
4511                    String s = " " + audioDeviceId + " " + chainId + " " + pos + " " + fxInstanceId;
4512                    retrieveIndex("INSERT SEND_EFFECT_CHAIN EFFECT" + s);
4513            }
4514    
4515            /**
4516             * Removes an effect instance from a certain position of a send effect chain.
4517             * @param audioDeviceId The numerical ID of the audio output device.
4518             * @param chainId The numerical ID of the send effect chain.
4519             * @param pos The exact position of the effect
4520             * instance to be removed from the effect chain.
4521             * @throws IOException If some I/O error occurs.
4522             * @throws LscpException If LSCP protocol corruption occurs.
4523             * @throws LSException If invalid index is specified.
4524             * @see #appendEffectInstance
4525             * @see #insertEffectInstance
4526             */
4527            public synchronized void
4528            removeEffectInstanceFromChain(int audioDeviceId, int chainId, int pos)
4529                            throws IOException, LSException, LscpException
4530            {
4531                    String s = " " + audioDeviceId + " " + chainId + " " + pos;
4532                    retrieveIndex("REMOVE SEND_EFFECT_CHAIN EFFECT" + s);
4533          }          }
4534                    
4535          /**          /**
# Line 3750  public class Client { Line 4543  public class Client {
4543           * @see #getSamplerChannels           * @see #getSamplerChannels
4544           */           */
4545          public synchronized void          public synchronized void
4546          editChannelInstrument(int samplerChn) throws IOException, LscpException, LSException {          editChannelInstrument(int samplerChn) throws IOException, LscpException, LSException
4547                  verifyConnection();          { retrieveIndex("EDIT CHANNEL INSTRUMENT " + samplerChn); }
4548                  out.writeLine("EDIT CHANNEL INSTRUMENT " + samplerChn);          
4549                  if(getPrintOnlyMode()) return;          /**
4550                             * Sends a MIDI event to this sampler channel.
4551                  ResultSet rs = getEmptyResultSet();           * @param samplerChn The sampler channel number.
4552             * @param type The type of MIDI message to send.
4553             * @throws IOException If some I/O error occurs.
4554             * @throws LscpException If LSCP protocol corruption occurs.
4555             * @throws LSException If <code>samplerChn</code> is not a valid channel number or if
4556             * there is no instrument loaded on the specified sampler channel.
4557             * @see #getSamplerChannels
4558             */
4559            public synchronized void
4560            sendChannelMidiData(int samplerChn, MidiDataEvent.Type type, int arg1, int arg2)
4561                                                    throws IOException, LscpException, LSException
4562            {
4563                    StringBuffer sb = new StringBuffer();
4564                    sb.append("SEND CHANNEL MIDI_DATA ");
4565                    sb.append(type).append(" ").append(samplerChn).append(" ");
4566                    sb.append(arg1).append(" ").append(arg2);
4567    
4568                    retrieveIndex(sb.toString());
4569          }          }
4570                    
4571            /**
4572             * Resets the specified sampler channel.
4573             *
4574             * @param samplerChn The sampler channel number.
4575             *
4576             * @throws IOException If some I/O error occurs.
4577             * @throws LscpException If LSCP protocol corruption occurs.
4578             * @throws LSException If <code>samplerChn</code> is not a valid channel number or if
4579             * there is no engine assigned yet to the specified sampler channel.
4580             * @see #getSamplerChannels
4581             */
4582            public synchronized void
4583            resetChannel(int samplerChn) throws IOException, LscpException, LSException
4584            { retrieveIndex("RESET CHANNEL " + samplerChn); }
4585            
4586                    
4587                    
4588          /**          /**
# Line 3768  public class Client { Line 4593  public class Client {
4593           * @throws LscpException If LSCP protocol corruption occurs.           * @throws LscpException If LSCP protocol corruption occurs.
4594           */           */
4595          public synchronized void          public synchronized void
4596          addDbDirectory(String dir) throws IOException, LSException, LscpException {          addDbDirectory(String dir) throws IOException, LSException, LscpException
4597                  verifyConnection();          { retrieveIndex("ADD DB_INSTRUMENT_DIRECTORY '" + conv(dir) + "'"); }
                 out.writeLine("ADD DB_INSTRUMENT_DIRECTORY '" + dir + "'");  
                 if(getPrintOnlyMode()) return;  
                   
                 ResultSet rs = getEmptyResultSet();  
         }  
4598                    
4599          /**          /**
4600           * Removes the specified directory from the instruments database.           * Removes the specified directory from the instruments database.
# Line 3785  public class Client { Line 4605  public class Client {
4605           * empty or if the removal of the directory failed.           * empty or if the removal of the directory failed.
4606           */           */
4607          public synchronized void          public synchronized void
4608          removeDbDirectory(String dir) throws IOException, LscpException, LSException {          removeDbDirectory(String dir) throws IOException, LscpException, LSException
4609                  removeDbDirectory(dir, false);          { removeDbDirectory(dir, false); }
         }  
4610                    
4611          /**          /**
4612           * Removes the specified directory from the instruments database.           * Removes the specified directory from the instruments database.
# Line 3800  public class Client { Line 4619  public class Client {
4619           */           */
4620          public synchronized void          public synchronized void
4621          removeDbDirectory(String dir, boolean force)          removeDbDirectory(String dir, boolean force)
4622                                  throws IOException, LscpException, LSException {                                  throws IOException, LscpException, LSException
4623                            {
                 verifyConnection();  
4624                  String s = "REMOVE DB_INSTRUMENT_DIRECTORY ";                  String s = "REMOVE DB_INSTRUMENT_DIRECTORY ";
4625                  if(force) s += "FORCE ";                  if(force) s += "FORCE ";
4626                  out.writeLine(s + "'" + dir + "'");                  retrieveIndex(s + "'" + conv(dir) + "'");
                 if(getPrintOnlyMode()) return;  
                   
                 ResultSet rs = getEmptyResultSet();  
4627          }          }
4628                    
4629          /**          /**
# Line 3828  public class Client { Line 4643  public class Client {
4643                  String cmd = "REMOVE DB_INSTRUMENT_DIRECTORY ";                  String cmd = "REMOVE DB_INSTRUMENT_DIRECTORY ";
4644                  if(force) cmd += "FORCE ";                  if(force) cmd += "FORCE ";
4645                                    
4646                  for(String s : dirs) out.writeLine(cmd + "'" + s + "'");                  for(String s : dirs) out.writeLine(cmd + "'" + conv(s) + "'");
4647                                    
4648                  if(getPrintOnlyMode()) return;                  if(getPrintOnlyMode()) return;
4649                                    
# Line 3866  public class Client { Line 4681  public class Client {
4681                  String s;                  String s;
4682                  if(recursive) s = "GET DB_INSTRUMENT_DIRECTORIES RECURSIVE '";                  if(recursive) s = "GET DB_INSTRUMENT_DIRECTORIES RECURSIVE '";
4683                  else s = "GET DB_INSTRUMENT_DIRECTORIES '";                  else s = "GET DB_INSTRUMENT_DIRECTORIES '";
4684                  out.writeLine(s + dir + "'");                  out.writeLine(s + conv(dir) + "'");
4685                  if(getPrintOnlyMode()) return -1;                  if(getPrintOnlyMode()) return -1;
4686                                    
4687                  s = getSingleLineResultSet().getResult();                  s = getSingleLineResultSet().getResult();
# Line 3885  public class Client { Line 4700  public class Client {
4700          public synchronized String[]          public synchronized String[]
4701          getDbDirectoryNames(String dir) throws IOException, LscpException, LSException {          getDbDirectoryNames(String dir) throws IOException, LscpException, LSException {
4702                  verifyConnection();                  verifyConnection();
4703                  out.writeLine("LIST DB_INSTRUMENT_DIRECTORIES '" + dir + "'");                  out.writeLine("LIST DB_INSTRUMENT_DIRECTORIES '" + conv(dir) + "'");
4704                  if(getPrintOnlyMode()) return null;                  if(getPrintOnlyMode()) return null;
4705                                    
4706                  String[] names = parseEscapedStringList(getSingleLineResultSet().getResult());                  String[] names = parseEscapedStringList(getSingleLineResultSet().getResult());
# Line 3906  public class Client { Line 4721  public class Client {
4721           */           */
4722          public synchronized DbDirectoryInfo          public synchronized DbDirectoryInfo
4723          getDbDirectoryInfo(String dir) throws IOException, LscpException, LSException {          getDbDirectoryInfo(String dir) throws IOException, LscpException, LSException {
4724                  verifyConnection();                  DbDirectoryInfo info = new DbDirectoryInfo();
4725                  out.writeLine("GET DB_INSTRUMENT_DIRECTORY INFO '" + dir + "'");                  if(!retrieveInfo("GET DB_INSTRUMENT_DIRECTORY INFO '" + conv(dir) + "'", info)) return null;
4726                  if(getPrintOnlyMode()) return null;  
                   
                 ResultSet rs = getMultiLineResultSet();  
                 DbDirectoryInfo info = new DbDirectoryInfo(rs.getMultiLineResult());  
4727                  if(dir.equals("/")) {                  if(dir.equals("/")) {
4728                          info.setName("/");                          info.setName("/");
4729                  } else {                  } else {
# Line 3940  public class Client { Line 4752  public class Client {
4752                  if(!hasEndingFileSeparator(dir)) dir += "/";                  if(!hasEndingFileSeparator(dir)) dir += "/";
4753                  DbDirectoryInfo[] infoS = new DbDirectoryInfo[dirS.length];                  DbDirectoryInfo[] infoS = new DbDirectoryInfo[dirS.length];
4754                  for(int i = 0; i < dirS.length; i++) {                  for(int i = 0; i < dirS.length; i++) {
4755                          infoS[i] = getDbDirectoryInfo(dir + toEscapedFileName(dirS[i]));                          infoS[i] = getDbDirectoryInfo(conv(dir) + toEscapedFsEntry(dirS[i]));
4756                  }                  }
4757                  return infoS;                  return infoS;
4758          }          }
# Line 3956  public class Client { Line 4768  public class Client {
4768           *           *
4769          public synchronized DbDirectoryInfo[]          public synchronized DbDirectoryInfo[]
4770          getDbDirectories(String dir) throws IOException, LscpException, LSException {          getDbDirectories(String dir) throws IOException, LscpException, LSException {
4771                  String[] dirS = getDbDirectoryNames(dir);                  String[] dirS = getDbDirectoryNames(conv(dir));
4772                  if(dirS.length == 0) return new DbDirectoryInfo[0];                  if(dirS.length == 0) return new DbDirectoryInfo[0];
4773                                    
4774                  if(dir.charAt(dir.length() - 1) != '/') dir += "/";                  if(dir.charAt(dir.length() - 1) != '/') dir += "/"; // FIXME:
4775                                    
4776                  for(int i = 0; i < dirS.length; i++) {                  for(int i = 0; i < dirS.length; i++) {
4777                          out.writeLine("GET DB_INSTRUMENT_DIRECTORY INFO '" + dir + dirS[i] + "'");                          out.writeLine("GET DB_INSTRUMENT_DIRECTORY INFO '" + conv(dir + dirS[i]) + "'");
4778                  }                  }
4779                                    
4780                  if(getPrintOnlyMode()) return null;                  if(getPrintOnlyMode()) return null;
# Line 4005  public class Client { Line 4817  public class Client {
4817           */           */
4818          public synchronized void          public synchronized void
4819          renameDbDirectory(String dir, String name) throws IOException, LSException, LscpException {          renameDbDirectory(String dir, String name) throws IOException, LSException, LscpException {
4820                  verifyConnection();                  name = toEscapedText(name);
4821                  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();  
4822          }          }
4823                    
4824          /**          /**
# Line 4022  public class Client { Line 4830  public class Client {
4830           * @throws LscpException If LSCP protocol corruption occurs.           * @throws LscpException If LSCP protocol corruption occurs.
4831           */           */
4832          public synchronized void          public synchronized void
4833          moveDbDirectory(String dir, String dst) throws IOException, LSException, LscpException {          moveDbDirectory(String dir, String dst) throws IOException, LSException, LscpException
4834                  verifyConnection();          { retrieveIndex("MOVE DB_INSTRUMENT_DIRECTORY '" + conv(dir) + "' '" + conv(dst) + "'"); }
                 out.writeLine("MOVE DB_INSTRUMENT_DIRECTORY '" + dir + "' '" + dst + "'");  
                 if(getPrintOnlyMode()) return;  
                   
                 ResultSet rs = getEmptyResultSet();  
         }  
4835                    
4836          /**          /**
4837           * Moves the specified directories into the specified location.           * Moves the specified directories into the specified location.
# Line 4042  public class Client { Line 4845  public class Client {
4845          moveDbDirectories(String dirs[], String dst) throws IOException, LSException, LscpException {          moveDbDirectories(String dirs[], String dst) throws IOException, LSException, LscpException {
4846                  verifyConnection();                  verifyConnection();
4847                  for(String s : dirs) {                  for(String s : dirs) {
4848                          out.writeLine("MOVE DB_INSTRUMENT_DIRECTORY '" + s + "' '" + dst + "'");                          out.writeLine("MOVE DB_INSTRUMENT_DIRECTORY '" + conv(s) + "' '" + conv(dst) + "'");
4849                  }                  }
4850                  if(getPrintOnlyMode()) return;                  if(getPrintOnlyMode()) return;
4851                                    
# Line 4058  public class Client { Line 4861  public class Client {
4861           * @throws LscpException If LSCP protocol corruption occurs.           * @throws LscpException If LSCP protocol corruption occurs.
4862           */           */
4863          public synchronized void          public synchronized void
4864          copyDbDirectory(String dir, String dst) throws IOException, LSException, LscpException {          copyDbDirectory(String dir, String dst) throws IOException, LSException, LscpException
4865                  verifyConnection();          { retrieveIndex("COPY DB_INSTRUMENT_DIRECTORY '" + conv(dir) + "' '" + conv(dst) + "'"); }
                 out.writeLine("COPY DB_INSTRUMENT_DIRECTORY '" + dir + "' '" + dst + "'");  
                 if(getPrintOnlyMode()) return;  
                   
                 ResultSet rs = getEmptyResultSet();  
         }  
4866                    
4867          /**          /**
4868           * Copies the specified directories into the specified location.           * Copies the specified directories into the specified location.
# Line 4078  public class Client { Line 4876  public class Client {
4876          copyDbDirectories(String[] dirs, String dst) throws IOException, LSException, LscpException {          copyDbDirectories(String[] dirs, String dst) throws IOException, LSException, LscpException {
4877                  verifyConnection();                  verifyConnection();
4878                  for(String s : dirs) {                  for(String s : dirs) {
4879                          out.writeLine("COPY DB_INSTRUMENT_DIRECTORY '" + s + "' '" + dst + "'");                          out.writeLine("COPY DB_INSTRUMENT_DIRECTORY '" + conv(s) + "' '" + conv(dst) + "'");
4880                  }                  }
4881                  if(getPrintOnlyMode()) return;                  if(getPrintOnlyMode()) return;
4882                                    
# Line 4095  public class Client { Line 4893  public class Client {
4893           */           */
4894          public synchronized void          public synchronized void
4895          setDbDirectoryDescription(String dir, String desc)          setDbDirectoryDescription(String dir, String desc)
4896                                  throws IOException, LSException, LscpException {                                  throws IOException, LSException, LscpException
4897                            {
                 verifyConnection();  
4898                  String s = "SET DB_INSTRUMENT_DIRECTORY DESCRIPTION '";                  String s = "SET DB_INSTRUMENT_DIRECTORY DESCRIPTION '";
4899                  out.writeLine(s + dir + "' '" + toEscapedString(desc) + "'");                  retrieveIndex(s + conv(dir) + "' '" + toEscapedText(desc) + "'");
                 if(getPrintOnlyMode()) return;  
                   
                 ResultSet rs = getEmptyResultSet();  
4900          }          }
4901                    
4902          public static enum ScanMode {          public static enum ScanMode {
# Line 4143  public class Client { Line 4937  public class Client {
4937           */           */
4938          public synchronized int          public synchronized int
4939          addDbInstrument(String dbDir, String filePath, int instrIndex, boolean background)          addDbInstrument(String dbDir, String filePath, int instrIndex, boolean background)
4940                                          throws IOException, LSException, LscpException {                                          throws IOException, LSException, LscpException
4941                            {
                 verifyConnection();  
4942                  String s = "ADD DB_INSTRUMENTS";                  String s = "ADD DB_INSTRUMENTS";
4943                  if(background) s += " NON_MODAL";                  if(background) s += " NON_MODAL";
4944                  s += " '" + dbDir + "' '" + filePath + "' ";                  s += " '" + conv(dbDir) + "' '" + conv(filePath) + "' ";
4945                  out.writeLine(s + String.valueOf(instrIndex));                  return retrieveIndex(s + String.valueOf(instrIndex));
                 if(getPrintOnlyMode()) return -1;  
                   
                 ResultSet rs = getEmptyResultSet();  
                 return rs.getIndex();  
4946          }          }
4947                    
4948          /**          /**
# Line 4190  public class Client { Line 4979  public class Client {
4979           */           */
4980          public synchronized int          public synchronized int
4981          addDbInstruments(String dbDir, String filePath, boolean background)          addDbInstruments(String dbDir, String filePath, boolean background)
4982                                          throws IOException, LSException, LscpException {                                          throws IOException, LSException, LscpException
4983                            {
                 verifyConnection();  
4984                  String s = "ADD DB_INSTRUMENTS";                  String s = "ADD DB_INSTRUMENTS";
4985                  if(background) s += " NON_MODAL";                  if(background) s += " NON_MODAL";
4986                  out.writeLine(s + " '" + dbDir + "' '" + filePath + "'");                  return retrieveIndex(s + " '" + conv(dbDir) + "' '" + conv(filePath) + "'");
                 if(getPrintOnlyMode()) return -1;  
                   
                 ResultSet rs = getEmptyResultSet();  
                 return rs.getIndex();  
4987          }          }
4988                    
4989          /**          /**
# Line 4262  public class Client { Line 5046  public class Client {
5046          addDbInstruments(ScanMode mode, String dbDir, String fsDir, boolean background)          addDbInstruments(ScanMode mode, String dbDir, String fsDir, boolean background)
5047                                          throws IOException, LSException, LscpException {                                          throws IOException, LSException, LscpException {
5048                                    
5049                  verifyConnection();                  return addDbInstruments(mode, dbDir, fsDir, background, false);
5050            }
5051            
5052            /**
5053             * Adds the instruments in the specified file system directory
5054             * to the specified instruments database directory.
5055             * @param mode Determines the scanning mode. If RECURSIVE is
5056             * specified, all supported instruments in the specified file system
5057             * direcotry will be added to the specified instruments database
5058             * directory, including the instruments in subdirectories
5059             * of the supplied directory. If NON_RECURSIVE is specified,
5060             * the instruments in the subdirectories will not be processed.
5061             * If FLAT is specified, all supported instruments in the specified
5062             * file system direcotry will be added, including the instruments in
5063             * subdirectories of the supplied directory, but the respective
5064             * subdirectory structure will not be recreated in the instruments
5065             * database and all instruments will be added directly in the
5066             * specified database directory.
5067             * @param dbDir The absolute path name of the database directory
5068             * in which the supported instruments will be added.
5069             * @param fsDir The absolute path name of the file system directory.
5070             * @param background If <code>true</code>, the scan will be done
5071             * in background and this method may return before the job is finished.
5072             * @param insDir If <code>true</code> a drieectory is created for each
5073             * instrument file.
5074             * @return If <code>background</code> is <code>true</code>, the ID
5075             * of the scan job.
5076             * @throws IOException If some I/O error occurs.
5077             * @throws LSException If the operation failed.
5078             * @throws LscpException If LSCP protocol corruption occurs.
5079             * @see #addInstrumentsDbListener
5080             */
5081            public synchronized int
5082            addDbInstruments(ScanMode mode, String dbDir, String fsDir, boolean background, boolean insDir)
5083                                            throws IOException, LSException, LscpException
5084            {
5085                  StringBuffer sb = new StringBuffer("ADD DB_INSTRUMENTS");                  StringBuffer sb = new StringBuffer("ADD DB_INSTRUMENTS");
5086                  if(background) sb.append(" NON_MODAL");                  if(background) sb.append(" NON_MODAL");
5087                                    
# Line 4277  public class Client { Line 5096  public class Client {
5096                                  sb.append(" FLAT");                                  sb.append(" FLAT");
5097                                  break;                                  break;
5098                  }                  }
5099                    if(insDir)
5100                            sb.append(" FILE_AS_DIR");
5101                                    
5102                  sb.append(" '").append(dbDir).append("' '");                  sb.append(" '").append(conv(dbDir)).append("' '");
5103                  sb.append(fsDir).append("'");                  sb.append(conv(fsDir)).append("'");
5104                  out.writeLine(sb.toString());                  return retrieveIndex(sb.toString());
                 if(getPrintOnlyMode()) return -1;  
                   
                 ResultSet rs = getEmptyResultSet();  
                 return rs.getIndex();  
5105          }          }
5106            
5107          /**          /**
5108           * Removes the specified instrument from the instruments database.           * Removes the specified instrument from the instruments database.
5109           * @param instr The absolute path name of the instrument to remove.           * @param instr The absolute path name of the instrument to remove.
# Line 4295  public class Client { Line 5112  public class Client {
5112           * @throws LSException If the removing of the instrument failed.           * @throws LSException If the removing of the instrument failed.
5113           */           */
5114          public synchronized void          public synchronized void
5115          removeDbInstrument(String instr) throws IOException, LscpException, LSException {          removeDbInstrument(String instr) throws IOException, LscpException, LSException
5116                            { retrieveIndex("REMOVE DB_INSTRUMENT '" + conv(instr) + "'"); }
                 verifyConnection();  
                 out.writeLine("REMOVE DB_INSTRUMENT '" + instr + "'");  
                 if(getPrintOnlyMode()) return;  
                   
                 ResultSet rs = getEmptyResultSet();  
         }  
5117                    
5118          /**          /**
5119           * Removes the specified instruments from the instruments database.           * Removes the specified instruments from the instruments database.
# Line 4315  public class Client { Line 5126  public class Client {
5126          removeDbInstruments(String[] instrs) throws IOException, LscpException, LSException {          removeDbInstruments(String[] instrs) throws IOException, LscpException, LSException {
5127                  verifyConnection();                  verifyConnection();
5128                  for(String s : instrs) {                  for(String s : instrs) {
5129                          out.writeLine("REMOVE DB_INSTRUMENT '" + s + "'");                          out.writeLine("REMOVE DB_INSTRUMENT '" + conv(s) + "'");
5130                  }                  }
5131                  if(getPrintOnlyMode()) return;                  if(getPrintOnlyMode()) return;
5132                                    
# Line 4353  public class Client { Line 5164  public class Client {
5164                  String s;                  String s;
5165                  if(recursive) s = "GET DB_INSTRUMENTS RECURSIVE '";                  if(recursive) s = "GET DB_INSTRUMENTS RECURSIVE '";
5166                  else s = "GET DB_INSTRUMENTS '";                  else s = "GET DB_INSTRUMENTS '";
5167                  out.writeLine(s + dir + "'");                  out.writeLine(s + conv(dir) + "'");
5168                  if(getPrintOnlyMode()) return -1;                  if(getPrintOnlyMode()) return -1;
5169                                    
5170                  s = getSingleLineResultSet().getResult();                  s = getSingleLineResultSet().getResult();
# Line 4372  public class Client { Line 5183  public class Client {
5183          public synchronized String[]          public synchronized String[]
5184          getDbInstrumentNames(String dir) throws IOException, LscpException, LSException {          getDbInstrumentNames(String dir) throws IOException, LscpException, LSException {
5185                  verifyConnection();                  verifyConnection();
5186                  out.writeLine("LIST DB_INSTRUMENTS '" + dir + "'");                  out.writeLine("LIST DB_INSTRUMENTS '" + conv(dir) + "'");
5187                  if(getPrintOnlyMode()) return null;                  if(getPrintOnlyMode()) return null;
5188                                    
5189                  String[] names = parseEscapedStringList(getSingleLineResultSet().getResult());                  String[] names = parseEscapedStringList(getSingleLineResultSet().getResult());
# Line 4393  public class Client { Line 5204  public class Client {
5204           */           */
5205          public synchronized DbInstrumentInfo          public synchronized DbInstrumentInfo
5206          getDbInstrumentInfo(String instr) throws IOException, LscpException, LSException {          getDbInstrumentInfo(String instr) throws IOException, LscpException, LSException {
5207                  verifyConnection();                  DbInstrumentInfo info = new DbInstrumentInfo();
5208                  out.writeLine("GET DB_INSTRUMENT INFO '" + instr + "'");                  if(!retrieveInfo("GET DB_INSTRUMENT INFO '" + conv(instr) + "'", info)) return null;
5209                  if(getPrintOnlyMode()) return null;  
                   
                 ResultSet rs = getMultiLineResultSet();  
                 DbInstrumentInfo info = new DbInstrumentInfo(rs.getMultiLineResult());  
5210                  String s = getParentDirectory(instr);                  String s = getParentDirectory(instr);
5211                  if(s != null) info.setDirectoryPath(s);                  if(s != null) info.setDirectoryPath(s);
5212                  s = getFileName(instr);                  s = getFileName(instr);
# Line 4423  public class Client { Line 5231  public class Client {
5231                                    
5232                  DbInstrumentInfo[] infoS = new DbInstrumentInfo[instrS.length];                  DbInstrumentInfo[] infoS = new DbInstrumentInfo[instrS.length];
5233                  for(int i = 0; i < instrS.length; i++) {                  for(int i = 0; i < instrS.length; i++) {
5234                          infoS[i] = getDbInstrumentInfo(dir + toEscapedFileName(instrS[i]));                          infoS[i] = getDbInstrumentInfo(conv(dir) + toEscapedFsEntry(instrS[i]));
5235                  }                  }
5236                  return infoS;                  return infoS;
5237          }          }
# Line 4442  public class Client { Line 5250  public class Client {
5250                  String[] instrS = getDbInstrumentNames(dir);                  String[] instrS = getDbInstrumentNames(dir);
5251                  if(instrS.length == 0) return new DbInstrumentInfo[0];                  if(instrS.length == 0) return new DbInstrumentInfo[0];
5252                                    
5253                  if(dir.charAt(dir.length() - 1) != '/') dir += "/";                  if(dir.charAt(dir.length() - 1) != '/') dir += "/"; FIXME:
5254                                    
5255                  for(int i = 0; i < instrS.length; i++) {                  for(int i = 0; i < instrS.length; i++) {
5256                          out.writeLine("GET DB_INSTRUMENT INFO '" + dir + instrS[i] + "'");                          out.writeLine("GET DB_INSTRUMENT INFO '" + conv(dir) + instrS[i] + "'");
5257                  }                  }
5258                                    
5259                  if(getPrintOnlyMode()) return null;                  if(getPrintOnlyMode()) return null;
# Line 4488  public class Client { Line 5296  public class Client {
5296           */           */
5297          public synchronized void          public synchronized void
5298          renameDbInstrument(String instr, String name)          renameDbInstrument(String instr, String name)
5299                                  throws IOException, LSException, LscpException {                                  throws IOException, LSException, LscpException
5300                            {
5301                  verifyConnection();                  name = toEscapedText(name);
5302                  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();  
5303          }          }
5304                    
5305          /**          /**
# Line 4507  public class Client { Line 5311  public class Client {
5311           * @throws LscpException If LSCP protocol corruption occurs.           * @throws LscpException If LSCP protocol corruption occurs.
5312           */           */
5313          public synchronized void          public synchronized void
5314          moveDbInstrument(String instr, String dst) throws IOException, LSException, LscpException {          moveDbInstrument(String instr, String dst) throws IOException, LSException, LscpException
5315                  verifyConnection();          { retrieveIndex("MOVE DB_INSTRUMENT '" + conv(instr) + "' '" + conv(dst) + "'"); }
                 out.writeLine("MOVE DB_INSTRUMENT '" + instr + "' '" + dst + "'");  
                 if(getPrintOnlyMode()) return;  
                   
                 ResultSet rs = getEmptyResultSet();  
         }  
5316                    
5317          /**          /**
5318           * Moves the specified instruments into the specified location.           * Moves the specified instruments into the specified location.
# Line 4527  public class Client { Line 5326  public class Client {
5326          moveDbInstruments(String[] instrs, String dst) throws IOException, LSException, LscpException {          moveDbInstruments(String[] instrs, String dst) throws IOException, LSException, LscpException {
5327                  verifyConnection();                  verifyConnection();
5328                  for(String s : instrs) {                  for(String s : instrs) {
5329                          out.writeLine("MOVE DB_INSTRUMENT '" + s + "' '" + dst + "'");                          out.writeLine("MOVE DB_INSTRUMENT '" + conv(s) + "' '" + conv(dst) + "'");
5330                  }                  }
5331                  if(getPrintOnlyMode()) return;                  if(getPrintOnlyMode()) return;
5332                                    
# Line 4543  public class Client { Line 5342  public class Client {
5342           * @throws LscpException If LSCP protocol corruption occurs.           * @throws LscpException If LSCP protocol corruption occurs.
5343           */           */
5344          public synchronized void          public synchronized void
5345          copyDbInstrument(String instr, String dst) throws IOException, LSException, LscpException {          copyDbInstrument(String instr, String dst) throws IOException, LSException, LscpException
5346                  verifyConnection();          { retrieveIndex("COPY DB_INSTRUMENT '" + conv(instr) + "' '" + conv(dst) + "'"); }
                 out.writeLine("COPY DB_INSTRUMENT '" + instr + "' '" + dst + "'");  
                 if(getPrintOnlyMode()) return;  
                   
                 ResultSet rs = getEmptyResultSet();  
         }  
5347                    
5348          /**          /**
5349           * Copies the specified instruments into the specified location.           * Copies the specified instruments into the specified location.
# Line 4563  public class Client { Line 5357  public class Client {
5357          copyDbInstruments(String[] instrs, String dst) throws IOException, LSException, LscpException {          copyDbInstruments(String[] instrs, String dst) throws IOException, LSException, LscpException {
5358                  verifyConnection();                  verifyConnection();
5359                  for(String s : instrs) {                  for(String s : instrs) {
5360                          out.writeLine("COPY DB_INSTRUMENT '" + s + "' '" + dst + "'");                          out.writeLine("COPY DB_INSTRUMENT '" + conv(s) + "' '" + conv(dst) + "'");
5361                  }                  }
5362                  if(getPrintOnlyMode()) return;                  if(getPrintOnlyMode()) return;
5363                                    
# Line 4580  public class Client { Line 5374  public class Client {
5374           */           */
5375          public synchronized void          public synchronized void
5376          setDbInstrumentDescription(String instr, String desc)          setDbInstrumentDescription(String instr, String desc)
5377                                  throws IOException, LSException, LscpException {                                  throws IOException, LSException, LscpException
5378                            {
5379                  verifyConnection();                  desc = toEscapedText(desc);
5380                  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();  
5381          }          }
5382                    
5383          /**          /**
5384             * Substitutes all occurrences of the instrument file
5385             * <code>oldPath</code> in the database, with <code>newPath</code>.
5386             * @param oldPath The absolute path name of the instrument file to substitute.
5387             * @param newPath The new absolute path name.
5388             * @throws IOException If some I/O error occurs.
5389             * @throws LSException If the operation failed.
5390             * @throws LscpException If LSCP protocol corruption occurs.
5391             */
5392            public synchronized void
5393            setDbInstrumentFilePath(String oldPath, String newPath)
5394                                    throws IOException, LSException, LscpException
5395            { retrieveIndex("SET DB_INSTRUMENT FILE_PATH '" + conv(oldPath) + "' '" + conv(newPath) + "'"); }
5396            
5397            /**
5398           * Finds all directories in the specified directory           * Finds all directories in the specified directory
5399           * that corresponds to the specified search criterias.           * that corresponds to the specified search criterias.
5400           * @param dir The absolute path name of the directory to search.           * @param dir The absolute path name of the directory to search.
# Line 4628  public class Client { Line 5432  public class Client {
5432                  StringBuffer sb = new StringBuffer();                  StringBuffer sb = new StringBuffer();
5433                  sb.append("FIND DB_INSTRUMENT_DIRECTORIES");                  sb.append("FIND DB_INSTRUMENT_DIRECTORIES");
5434                  if(nonRecursive) sb.append(" NON_RECURSIVE");                  if(nonRecursive) sb.append(" NON_RECURSIVE");
5435                  sb.append(" '").append(dir).append("'");                  sb.append(" '").append(conv(dir)).append("'");
5436                                    
5437                  if(query.name != null && query.name.length() > 0) {                  if(query.name != null && query.name.length() > 0) {
5438                          sb.append(" NAME='").append(toEscapedString(query.name)).append("'");                          sb.append(" NAME='").append(toEscapedText(query.name)).append("'");
5439                  }                  }
5440                                    
5441                  String s = query.getCreatedAfter();                  String s = query.getCreatedAfter();
# Line 4656  public class Client { Line 5460  public class Client {
5460                                    
5461                  if(query.description != null && query.description.length() > 0) {                  if(query.description != null && query.description.length() > 0) {
5462                          sb.append(" DESCRIPTION='");                          sb.append(" DESCRIPTION='");
5463                          sb.append(toEscapedString(query.description)).append("'");                          sb.append(toEscapedText(query.description)).append("'");
5464                  }                  }
5465                                    
5466                  out.writeLine(sb.toString());                  out.writeLine(sb.toString());
# Line 4709  public class Client { Line 5513  public class Client {
5513                  StringBuffer sb = new StringBuffer();                  StringBuffer sb = new StringBuffer();
5514                  sb.append("FIND DB_INSTRUMENTS");                  sb.append("FIND DB_INSTRUMENTS");
5515                  if(nonRecursive) sb.append(" NON_RECURSIVE");                  if(nonRecursive) sb.append(" NON_RECURSIVE");
5516                  sb.append(" '").append(dir).append("'");                  sb.append(" '").append(conv(dir)).append("'");
5517                                    
5518                  if(query.name != null && query.name.length() > 0) {                  if(query.name != null && query.name.length() > 0) {
5519                          sb.append(" NAME='").append(toEscapedString(query.name)).append("'");                          sb.append(" NAME='").append(toEscapedText(query.name)).append("'");
5520                  }                  }
5521                                    
5522                  if(query.formatFamilies.size() > 0) {                  if(query.formatFamilies.size() > 0) {
# Line 4753  public class Client { Line 5557  public class Client {
5557                                    
5558                  if(query.description != null && query.description.length() > 0) {                  if(query.description != null && query.description.length() > 0) {
5559                          sb.append(" DESCRIPTION='");                          sb.append(" DESCRIPTION='");
5560                          sb.append(toEscapedString(query.description)).append("'");                          sb.append(toEscapedText(query.description)).append("'");
5561                  }                  }
5562                                    
5563                  if(query.instrumentType != DbSearchQuery.InstrumentType.BOTH) {                  if(query.instrumentType != DbSearchQuery.InstrumentType.BOTH) {
# Line 4766  public class Client { Line 5570  public class Client {
5570                  }                  }
5571                                    
5572                  if(query.product != null && query.product.length() > 0) {                  if(query.product != null && query.product.length() > 0) {
5573                          sb.append(" PRODUCT='").append(toEscapedString(query.product)).append("'");                          sb.append(" PRODUCT='").append(toEscapedText(query.product)).append("'");
5574                  }                  }
5575                                    
5576                  if(query.artists != null && query.artists.length() > 0) {                  if(query.artists != null && query.artists.length() > 0) {
5577                          sb.append(" ARTISTS='").append(toEscapedString(query.artists)).append("'");                          sb.append(" ARTISTS='").append(toEscapedText(query.artists)).append("'");
5578                  }                  }
5579                                    
5580                  if(query.keywords != null && query.keywords.length() > 0) {                  if(query.keywords != null && query.keywords.length() > 0) {
5581                          sb.append(" KEYWORDS='");                          sb.append(" KEYWORDS='");
5582                          sb.append(toEscapedString(query.keywords)).append("'");                          sb.append(toEscapedText(query.keywords)).append("'");
5583                  }                  }
5584                                    
5585                  out.writeLine(sb.toString());                  out.writeLine(sb.toString());
# Line 4791  public class Client { Line 5595  public class Client {
5595          }          }
5596                    
5597          /**          /**
5598             * Returns a list of all instrument files in the database
5599             * that that don't exist in the filesystem.
5600             * @throws IOException If some I/O error occurs.
5601             * @throws LscpException If LSCP protocol corruption occurs.
5602             * @throws LSException If other error occurs.
5603             */
5604            public synchronized String[]
5605            findLostDbInstrumentFiles() throws IOException, LscpException, LSException {
5606                    
5607                    verifyConnection();
5608                    out.writeLine("FIND LOST DB_INSTRUMENT_FILES");
5609                    if(getPrintOnlyMode()) return null;
5610                    
5611                    return parseEscapedStringList(getSingleLineResultSet().getResult());
5612            }
5613            
5614            /**
5615           * Gets status information about the specified job.           * Gets status information about the specified job.
5616           * @param jobId The ID of the job.           * @param jobId The ID of the job.
5617           * @return A <code>ScanJobInfo</code> instance providing information           * @return A <code>ScanJobInfo</code> instance providing information
# Line 4801  public class Client { Line 5622  public class Client {
5622           */           */
5623          public synchronized ScanJobInfo          public synchronized ScanJobInfo
5624          getDbInstrumentsJobInfo(int jobId) throws IOException, LscpException, LSException {          getDbInstrumentsJobInfo(int jobId) throws IOException, LscpException, LSException {
5625                  verifyConnection();                  ScanJobInfo info = new ScanJobInfo();
5626                  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());  
5627                                    
5628                  return info;                  return info;
5629          }          }
# Line 4819  public class Client { Line 5636  public class Client {
5636           * @throws LSException If the formatting of the instruments database failed.           * @throws LSException If the formatting of the instruments database failed.
5637           */           */
5638          public synchronized void          public synchronized void
5639          formatInstrumentsDb() throws IOException, LscpException, LSException {          formatInstrumentsDb() throws IOException, LscpException, LSException
5640                  verifyConnection();          { retrieveIndex("FORMAT INSTRUMENTS_DB"); }
                 out.writeLine("FORMAT INSTRUMENTS_DB");  
                 if(getPrintOnlyMode()) return;  
                   
                 ResultSet rs = getEmptyResultSet();  
         }  
5641                    
5642          /**          /**
5643           * Resets the specified sampler channel.           * Resets the whole sampler.
5644           *           *
          * @param samplerChn The sampler channel number.  
          *  
5645           * @throws IOException If some I/O error occurs.           * @throws IOException If some I/O error occurs.
5646           * @throws LscpException If LSCP protocol corruption 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  
5647           */           */
5648          public synchronized void          public synchronized void
5649          resetChannel(int samplerChn) throws IOException, LscpException, LSException {          resetSampler() throws IOException, LscpException {
5650                  verifyConnection();                  verifyConnection();
5651                  out.writeLine("RESET CHANNEL " + samplerChn);                  out.writeLine("RESET");
5652                  if(getPrintOnlyMode()) return;                  if(getPrintOnlyMode()) return;
5653                                    
5654                  ResultSet rs = getEmptyResultSet();                  try { ResultSet rs = getEmptyResultSet(); }
5655                    catch(LSException x) { getLogger().warning(x.getMessage()); }
5656          }          }
5657                    
5658          /**          /**
5659           * Resets the whole sampler.           * Gets the current number of all active streams.
5660           *           * @return The current number of all active streams 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.
5664           */           */
5665          public synchronized void          public synchronized int
5666          resetSampler() throws IOException, LscpException {          getTotalStreamCount() throws IOException, LscpException, LSException {
5667                  verifyConnection();                  return retrieveInt("GET TOTAL_STREAM_COUNT");
                 out.writeLine("RESET");  
                 if(getPrintOnlyMode()) return;  
                   
                 try { ResultSet rs = getEmptyResultSet(); }  
                 catch(LSException x) { getLogger().warning(x.getMessage()); }  
5668          }          }
5669                    
5670          /**          /**
5671           * Gets the current number of all active voices.           * Gets the current number of all active voices.
5672           * @return The current number of all active voices.           * @return The current number of all 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          getTotalVoiceCount() throws IOException, LscpException, LSException {          getTotalVoiceCount() throws IOException, LscpException, LSException {
5679                  verifyConnection();                  return retrieveInt("GET TOTAL_VOICE_COUNT");
                 out.writeLine("GET TOTAL_VOICE_COUNT");  
                 if(getPrintOnlyMode()) return -1;  
                   
                 String s = getSingleLineResultSet().getResult();  
                 return parseInt(s);  
5680          }          }
5681                    
5682          /**          /**
5683           * Gets the maximum number of active voices.           * Gets the maximum number of active voices.
5684           * @return The maximum number of active voices.           * @return The maximum number of active voices or -1 if in "print only" mode.
5685           * @throws IOException If some I/O error occurs.           * @throws IOException If some I/O error occurs.
5686           * @throws LscpException If LSCP protocol corruption occurs.           * @throws LscpException If LSCP protocol corruption occurs.
5687           * @throws LSException If some other error occurs.           * @throws LSException If some other error occurs.
5688           */           */
5689          public synchronized int          public synchronized int
5690          getTotalVoiceCountMax() throws IOException, LscpException, LSException {          getTotalVoiceCountMax() throws IOException, LscpException, LSException {
5691                  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);  
5692          }          }
5693                    
5694          /**          /**
# Line 4909  public class Client { Line 5703  public class Client {
5703           */           */
5704          public synchronized ServerInfo          public synchronized ServerInfo
5705          getServerInfo() throws IOException, LscpException, LSException {          getServerInfo() throws IOException, LscpException, LSException {
5706                  verifyConnection();                  ServerInfo info = new ServerInfo();
5707                  out.writeLine("GET SERVER INFO");                  if(!retrieveInfo("GET SERVER INFO", info)) return null;
                 if(getPrintOnlyMode()) return null;  
5708                                    
5709                  ResultSet rs = getMultiLineResultSet();                  return info;
                 return new ServerInfo(rs.getMultiLineResult());  
5710          }          }
5711                    
5712          /**          /**
5713           * Gets the golobal volume of the sampler.           * Gets the global volume of the sampler.
5714           * @return The golobal volume of the sampler.           * @return The global volume of the sampler.
5715           * @throws IOException If some I/O error occurs.           * @throws IOException If some I/O error occurs.
5716           * @throws LscpException If LSCP protocol corruption occurs.           * @throws LscpException If LSCP protocol corruption occurs.
5717           * @throws LSException If some other error occurs.           * @throws LSException If some other error occurs.
# Line 4943  public class Client { Line 5735  public class Client {
5735           * @see #getVolume           * @see #getVolume
5736           */           */
5737          public synchronized void          public synchronized void
5738          setVolume(float volume) throws IOException, LscpException, LSException {          setVolume(float volume) throws IOException, LscpException, LSException
5739            { retrieveIndex("SET VOLUME " + volume); }
5740                    
5741                  verifyConnection();          /**
5742                  out.writeLine("SET VOLUME " + volume);           * Gets the global sampler-wide limit of maximum voices.
5743                  if(getPrintOnlyMode()) return;           * @return The global sampler-wide limit of maximum voices or -1 if in "print only" mode.
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             */
5748            public synchronized int
5749            getGlobalVoiceLimit() throws IOException, LscpException, LSException {
5750                    return retrieveInt("GET VOICES");
5751            }
5752            
5753            /**
5754             * Sets the global sampler-wide limit of maximum voices.
5755             * @param maxVoices The new global limit of maximum voices.
5756             * @throws IOException If some I/O error occurs.
5757             * @throws LscpException If LSCP protocol corruption occurs.
5758             * @throws LSException If some other error occurs.
5759             * @see #getVolume
5760             */
5761            public synchronized void
5762            setGlobalVoiceLimit(int maxVoices) throws IOException, LscpException, LSException
5763            { retrieveIndex("SET VOICES " + maxVoices); }
5764            
5765            /**
5766             * Gets the global sampler-wide limit of maximum disk streams.
5767             * @return The global sampler-wide limit of maximum disk streams
5768             *  or -1 if in "print only" mode.
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             */
5773            public synchronized int
5774            getGlobalStreamLimit() throws IOException, LscpException, LSException {
5775                    return retrieveInt("GET STREAMS");
5776            }
5777            
5778            /**
5779             * Sets the global sampler-wide limit for maximum disk streams.
5780             * @param maxVoices The new global limit of maximum disk streams.
5781             * @throws IOException If some I/O error occurs.
5782             * @throws LscpException If LSCP protocol corruption occurs.
5783             * @throws LSException If some other error occurs.
5784             * @see #getVolume
5785             */
5786            public synchronized void
5787            setGlobalStreamLimit(int maxStreams) throws IOException, LscpException, LSException
5788            { retrieveIndex("SET STREAMS " + maxStreams); }
5789            
5790            /**
5791             * Gets the number of instruments in the specified instrument file.
5792             * @param filename The absolute path name of the instrument file.
5793             * @return The number of instruments in the specified instrument file
5794             *  or -1 if in "print only" mode.
5795             * @throws IOException If some I/O error occurs.
5796             * @throws LscpException If LSCP protocol corruption occurs.
5797             * @throws LSException If the file is not found, or other error occur.
5798             */
5799            public synchronized int
5800            getFileInstrumentCount(String filename) throws IOException, LscpException, LSException {
5801                    return retrieveInt("GET FILE INSTRUMENTS '" + conv(filename) +"'");
5802            }
5803            
5804            /**
5805             * Gets information about the instrument with index
5806             * <code>instrIdx</code> in the specified instrument file.
5807             * @param filename The absolute path name of the instrument file.
5808             * @param instrIdx The index of the instrument in the specified instrument file.
5809             * @throws IOException If some I/O error occurs.
5810             * @throws LscpException If LSCP protocol corruption occurs.
5811             * @throws LSException If failed to retrieve information.
5812             */
5813            public synchronized Instrument
5814            getFileInstrumentInfo(String filename, int instrIdx)
5815                                    throws IOException, LscpException, LSException {
5816    
5817                    FileInstrument instr = new FileInstrument();
5818                    String cmd = "GET FILE INSTRUMENT INFO '" + conv(filename) + "' " + String.valueOf(instrIdx);
5819                    if(!retrieveInfo(cmd, instr)) return null;
5820                                    
5821                  ResultSet rs = getEmptyResultSet();                  return instr;
5822            }
5823            
5824            /**
5825             * Gets the list of instruments in the specified instrument file.
5826             * @param filename The absolute path name of the instrument file.
5827             * @return An <code>Instrument</code> array providing
5828             * information about all instruments in the specified instrument file.
5829             * @throws IOException If some I/O error occurs.
5830             * @throws LscpException If LSCP protocol corruption occurs.
5831             * @throws LSException If the specified file name is invalid.
5832             */
5833            public synchronized Instrument[]
5834            getFileInstruments(String filename) throws IOException, LscpException, LSException {
5835                    int l = getFileInstrumentCount(filename);
5836                    if(l < 0) return null;
5837                    Instrument[] instrS = new FileInstrument[l];
5838                    
5839                    for(int i = 0; i < instrS.length; i++) {
5840                            instrS[i] = getFileInstrumentInfo(filename, i);
5841                    }
5842                    return instrS;
5843            }
5844            
5845            private static class FileInstrument extends AbstractInstrument {
5846                    FileInstrument() { }
5847                    
5848                    public String
5849                    getEngine() {
5850                            // TODO: engine lookup?
5851                            return getFormatFamily();
5852                    }
5853                    
5854                    @Override
5855                    public boolean
5856                    parse(String s) throws LscpException {
5857                            if(s.startsWith("PRODUCT: ") || s.startsWith("ARTISTS: ")) return true;
5858                            return super.parse(s);
5859                    }
5860          }          }
5861                    
5862          private void          private void
# Line 4973  public class Client { Line 5880  public class Client {
5880                          throw new LSException(0, s, details);                          throw new LSException(0, s, details);
5881                  }                  }
5882          }          }
5883    
5884            /**
5885             * Retrieves a list of integers.
5886             * @throws IOException If some I/O error occurs.
5887             * @throws LscpException If LSCP protocol corruption occurs.
5888             */
5889            private Integer[]
5890            getIntegerList(String lscpCmd) throws IOException, LscpException, LSException {
5891                    verifyConnection();
5892                    out.writeLine(lscpCmd);
5893                    if(getPrintOnlyMode()) return null;
5894    
5895                    return parseIntList(getSingleLineResultSet().getResult());
5896            }
5897    
5898            private boolean
5899            retrieveInfo(String lscpCmd, Parseable p) throws IOException, LscpException, LSException {
5900                    verifyConnection();
5901                    out.writeLine(lscpCmd);
5902                    if(getPrintOnlyMode()) return false;
5903    
5904                    ResultSet rs = getMultiLineResultSet();
5905    
5906                    for(String s : rs.getMultiLineResult()) {
5907                            if(!p.parse(s)) Client.getLogger().info(LscpI18n.getLogMsg("unknownLine", s));
5908                    }
5909    
5910                    return true;
5911            }
5912    
5913            private int
5914            retrieveInt(String lscpCmd) throws IOException, LscpException, LSException {
5915                    verifyConnection();
5916                    out.writeLine(lscpCmd);
5917                    if(getPrintOnlyMode()) return -1;
5918    
5919                    String s = getSingleLineResultSet().getResult();
5920                    return parseInt(s);
5921            }
5922    
5923            private int
5924            retrieveIndex(String lscpCmd) throws IOException, LSException, LscpException {
5925                    verifyConnection();
5926                    out.writeLine(lscpCmd);
5927                    if(getPrintOnlyMode()) return -1;
5928    
5929                    return getEmptyResultSet().getIndex();
5930            }
5931                    
5932          /**          /**
5933           * Returns the logger for this library.           * Returns the logger for this library.

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

  ViewVC Help
Powered by ViewVC