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

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

  ViewVC Help
Powered by ViewVC