/[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 1351 by iliev, Sun Sep 16 23:15:57 2007 UTC revision 1817 by iliev, Wed Dec 24 16:55:54 2008 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-2008 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.Vector;  import java.util.Vector;
33  import java.util.logging.Level;  import java.util.logging.Level;
# Line 41  import static org.linuxsampler.lscp.Pars Line 40  import static org.linuxsampler.lscp.Pars
40    
41  /**  /**
42   * This class is the abstraction representing a client endpoint for communication with LinuxSampler   * This class is the abstraction representing a client endpoint for communication with LinuxSampler
43   * instance. Since it implements all commands specified in the LSCP protocol v1.1, for more   * instance. Since it implements all commands specified in the LSCP protocol v1.3, for more
44   * information look at the   * information look at the
45   * <a href=http://www.linuxsampler.org/api/lscp-1.1.html>LSCP</a> specification.   * <a href=http://www.linuxsampler.org/api/lscp-1.3.html>LSCP</a> specification.
46   *   *
47   * <p> The following code establishes connection to LinuxSampler instance and gets the   * <p> The following code establishes connection to LinuxSampler instance and gets the
48   * LinuxSampler version:   * LinuxSampler version:
# Line 85  public class Client { Line 84  public class Client {
84                                    
85                  EventThread() { super("LSCP-Event-Thread"); }                  EventThread() { super("LSCP-Event-Thread"); }
86                                    
87                    @Override
88                  public void                  public void
89                  run() {                  run() {
90                          while(!mustTerminate()) {                          while(!mustTerminate()) {
# Line 164  public class Client { Line 164  public class Client {
164                  if(printOnlyMode) setPrintOnlyMode(true);                  if(printOnlyMode) setPrintOnlyMode(true);
165          }          }
166                    
167            private boolean extendedCharacterEscaping = true;
168            
169            /**
170             * Sets whether strings sent to LinuxSampler should be more aggressively escaped.
171             */
172            public synchronized void
173            setExtendedCharacterEscaping(boolean b) { extendedCharacterEscaping = b; }
174            
175            /**
176             * Determines whether strings sent to LinuxSampler should be more aggressively escaped.
177             */
178            public synchronized boolean
179            getExtendedCharacterEscaping() { return extendedCharacterEscaping; }
180            
181            /**
182             * @see java.net.Socket#setSoTimeout
183             */
184            public synchronized void
185            setSoTimeout(int timeout) {
186                    soTimeout = timeout;
187                    
188                    try { if(sock != null) sock.setSoTimeout(timeout); }
189                    catch(Exception x) { getLogger().log(Level.INFO, "Unable to set timeout", x); }
190            }
191            
192            private String
193            toEscapedText(String s) {
194                    s = toEscapedString(s);
195                    return conv(s);
196            }
197            
198            private String
199            toEscapedFsEntry(String s) {
200                    s = toEscapedFileName(s);
201                    return conv(s);
202            }
203            
204            /**
205             * Applies an extended character escaping to the specified string if needed.
206             */
207            private String
208            conv(String s) {
209                    return getExtendedCharacterEscaping() ? toExtendedEscapeSequence(s) : s;
210            }
211            
212          /**          /**
213           * Determines whether the client is in print-only mode.           * Determines whether the client is in print-only mode.
214           * 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 389  public class Client {
389                  if(!llFSI.isEmpty()) subscribe("FX_SEND_INFO");                  if(!llFSI.isEmpty()) subscribe("FX_SEND_INFO");
390                  if(!llSC.isEmpty()) subscribe("STREAM_COUNT");                  if(!llSC.isEmpty()) subscribe("STREAM_COUNT");
391                  if(!llVC.isEmpty()) subscribe("VOICE_COUNT");                  if(!llVC.isEmpty()) subscribe("VOICE_COUNT");
392                    if(!llTSC.isEmpty()) subscribe("TOTAL_STREAM_COUNT");
393                  if(!llTVC.isEmpty()) subscribe("TOTAL_VOICE_COUNT");                  if(!llTVC.isEmpty()) subscribe("TOTAL_VOICE_COUNT");
394                  if(!llMIMC.isEmpty()) subscribe("MIDI_INSTRUMENT_MAP_COUNT");                  if(!llMIMC.isEmpty()) subscribe("MIDI_INSTRUMENT_MAP_COUNT");
395                  if(!llMIMI.isEmpty()) subscribe("MIDI_INSTRUMENT_MAP_INFO");                  if(!llMIMI.isEmpty()) subscribe("MIDI_INSTRUMENT_MAP_INFO");
396                  if(!llMIC.isEmpty()) subscribe("MIDI_INSTRUMENT_COUNT");                  if(!llMIC.isEmpty()) subscribe("MIDI_INSTRUMENT_COUNT");
397                  if(!llMII.isEmpty()) subscribe("MIDI_INSTRUMENT_INFO");                  if(!llMII.isEmpty()) subscribe("MIDI_INSTRUMENT_INFO");
398                    if(!llDMD.isEmpty()) subscribe("DEVICE_MIDI");
399                    if(!llCMD.isEmpty()) subscribe("CHANNEL_MIDI");
400                  if(!llID.isEmpty()) {                  if(!llID.isEmpty()) {
401                          subscribe("DB_INSTRUMENT_DIRECTORY_COUNT");                          subscribe("DB_INSTRUMENT_DIRECTORY_COUNT");
402                          subscribe("DB_INSTRUMENT_DIRECTORY_INFO");                          subscribe("DB_INSTRUMENT_DIRECTORY_INFO");
403                          subscribe("DB_INSTRUMENT_COUNT");                          subscribe("DB_INSTRUMENT_COUNT");
404                          subscribe("DB_INSTRUMENT_INFO");                          subscribe("DB_INSTRUMENT_INFO");
405                            subscribe("DB_INSTRUMENTS_JOB_INFO");
406                  }                  }
407                  if(!llGI.isEmpty()) subscribe("GLOBAL_INFO");                  if(!llGI.isEmpty()) subscribe("GLOBAL_INFO");
408          }          }
# Line 485  public class Client { Line 534  public class Client {
534          private final Vector<ItemInfoListener> llMIDI = new Vector<ItemInfoListener>();          private final Vector<ItemInfoListener> llMIDI = new Vector<ItemInfoListener>();
535          private final Vector<StreamCountListener> llSC = new Vector<StreamCountListener>();          private final Vector<StreamCountListener> llSC = new Vector<StreamCountListener>();
536          private final Vector<VoiceCountListener> llVC = new Vector<VoiceCountListener>();          private final Vector<VoiceCountListener> llVC = new Vector<VoiceCountListener>();
537            private final Vector<TotalStreamCountListener> llTSC = new Vector<TotalStreamCountListener>();
538          private final Vector<TotalVoiceCountListener> llTVC = new Vector<TotalVoiceCountListener>();          private final Vector<TotalVoiceCountListener> llTVC = new Vector<TotalVoiceCountListener>();
539                    
540          /** MIDI instrument map count listeners */          /** MIDI instrument map count listeners */
# Line 497  public class Client { Line 547  public class Client {
547          /** MIDI instrument info listeners */          /** MIDI instrument info listeners */
548          private final Vector<MidiInstrumentInfoListener> llMII =          private final Vector<MidiInstrumentInfoListener> llMII =
549                  new Vector<MidiInstrumentInfoListener>();                  new Vector<MidiInstrumentInfoListener>();
550            private final Vector<DeviceMidiDataListener> llDMD = new Vector<DeviceMidiDataListener>();
551            private final Vector<ChannelMidiDataListener> llCMD = new Vector<ChannelMidiDataListener>();
552          private final Vector<InstrumentsDbListener> llID = new Vector<InstrumentsDbListener>();          private final Vector<InstrumentsDbListener> llID = new Vector<InstrumentsDbListener>();
553          private final Vector<GlobalInfoListener> llGI = new Vector<GlobalInfoListener>();          private final Vector<GlobalInfoListener> llGI = new Vector<GlobalInfoListener>();
554                    
# Line 522  public class Client { Line 574  public class Client {
574                          !llMIDI.isEmpty() ||                          !llMIDI.isEmpty() ||
575                          !llSC.isEmpty()   ||                          !llSC.isEmpty()   ||
576                          !llVC.isEmpty()   ||                          !llVC.isEmpty()   ||
577                            !llTSC.isEmpty()  ||
578                          !llTVC.isEmpty()  ||                          !llTVC.isEmpty()  ||
579                          !llMIMC.isEmpty() ||                          !llMIMC.isEmpty() ||
580                          !llMIMI.isEmpty() ||                          !llMIMI.isEmpty() ||
581                          !llMIC.isEmpty()  ||                          !llMIC.isEmpty()  ||
582                          !llMII.isEmpty()  ||                          !llMII.isEmpty()  ||
583                            !llDMD.isEmpty()  ||
584                            !llCMD.isEmpty()  ||
585                          !llID.isEmpty()   ||                          !llID.isEmpty()   ||
586                          !llGI.isEmpty();                          !llGI.isEmpty();
587          }          }
588                    
589          private synchronized void          private synchronized void
590            fireDeviceMidiDataEvent(String s) {
591                    try {
592                            String[] list = parseList(s, ' ');
593                            if(list.length != 5) {
594                                    getLogger().warning("Unknown DEVICE_MIDI format");
595                                    return;
596                            }
597                            
598                            int dev = parseInt(list[0]);
599                            int port = parseInt(list[1]);
600                            
601                            MidiDataEvent.Type type = parseMidiDataType(list[2]);
602                            if(type == null) return;
603                            
604                            int note = parseInt(list[3]);
605                            int velocity = parseInt(list[4]);
606                            
607                            DeviceMidiDataEvent e = new DeviceMidiDataEvent(this, type, note, velocity);
608                            e.setDeviceId(dev);
609                            e.setPortId(port);
610                            for(DeviceMidiDataListener l : llDMD) l.midiDataArrived(e);
611                    } catch(LscpException x) {
612                            getLogger().log (
613                                    Level.WARNING, LscpI18n.getLogMsg("CommandFailed!"), x
614                            );
615                    }
616            }
617            
618            private synchronized void
619            fireChannelMidiDataEvent(String s) {
620                    try {
621                            String[] list = parseList(s, ' ');
622                            if(list.length != 4) {
623                                    getLogger().warning("Unknown CHANNEL_MIDI format");
624                                    return;
625                            }
626                            
627                            int channel = parseInt(list[0]);
628                            
629                            MidiDataEvent.Type type = parseMidiDataType(list[1]);
630                            if(type == null) return;
631                            
632                            int note = parseInt(list[2]);
633                            int velocity = parseInt(list[3]);
634                            
635                            ChannelMidiDataEvent e = new ChannelMidiDataEvent(this, type, note, velocity);
636                            e.setChannelId(channel);
637                            for(ChannelMidiDataListener l : llCMD) l.midiDataArrived(e);
638                    } catch(LscpException x) {
639                            getLogger().log (
640                                    Level.WARNING, LscpI18n.getLogMsg("CommandFailed!"), x
641                            );
642                    }
643            }
644            
645            private MidiDataEvent.Type
646            parseMidiDataType(String s) {
647                    if("NOTE_ON".equals(s)) return MidiDataEvent.Type.NOTE_ON;
648                    if("NOTE_OFF".equals(s)) return MidiDataEvent.Type.NOTE_OFF;
649                    
650                    getLogger().warning("Unknown MIDI data type: " + s);
651                    return null;
652            }
653            
654            private synchronized void
655          fireEvent(String s) {          fireEvent(String s) {
656                   if(s.startsWith("DB_INSTRUMENT_DIRECTORY_COUNT:")) {                  // Sort by priority
657                    
658                     if(s.startsWith("CHANNEL_MIDI:")) {
659                            s = s.substring("CHANNEL_MIDI:".length());
660                            fireChannelMidiDataEvent(s);
661                    } else if(s.startsWith("DEVICE_MIDI:")) {
662                            s = s.substring("DEVICE_MIDI:".length());
663                            fireDeviceMidiDataEvent(s);
664                    } else if(s.startsWith("DB_INSTRUMENT_DIRECTORY_COUNT:")) {
665                          s = s.substring("DB_INSTRUMENT_DIRECTORY_COUNT:".length());                          s = s.substring("DB_INSTRUMENT_DIRECTORY_COUNT:".length());
666                          InstrumentsDbEvent e = new InstrumentsDbEvent(this, s);                          InstrumentsDbEvent e = new InstrumentsDbEvent(this, s);
667                          for(InstrumentsDbListener l : llID) l.directoryCountChanged(e);                          for(InstrumentsDbListener l : llID) l.directoryCountChanged(e);
# Line 662  public class Client { Line 790  public class Client {
790                          } catch(NumberFormatException x) {                          } catch(NumberFormatException x) {
791                                  getLogger().log(Level.WARNING, "Unknown CHANNEL_INFO format", x);                                  getLogger().log(Level.WARNING, "Unknown CHANNEL_INFO format", x);
792                          }                          }
793                    } else if(s.startsWith("TOTAL_STREAM_COUNT:")) {
794                            try {
795                                    s = s.substring("TOTAL_STREAM_COUNT:".length());
796                                    int i = Integer.parseInt(s);
797                                    TotalStreamCountEvent e = new TotalStreamCountEvent(this, i);
798                                    for(TotalStreamCountListener l : llTSC) l.totalStreamCountChanged(e);
799                            } catch(NumberFormatException x) {
800                                    getLogger().log (
801                                            Level.WARNING, "Unknown TOTAL_STREAM_COUNT format", x
802                                    );
803                            }
804                  } else if(s.startsWith("TOTAL_VOICE_COUNT:")) {                  } else if(s.startsWith("TOTAL_VOICE_COUNT:")) {
805                          try {                          try {
806                                  s = s.substring("TOTAL_VOICE_COUNT:".length());                                  s = s.substring("TOTAL_VOICE_COUNT:".length());
# Line 825  public class Client { Line 964  public class Client {
964                                  float f = Float.parseFloat(s.substring("VOLUME ".length()));                                  float f = Float.parseFloat(s.substring("VOLUME ".length()));
965                                  GlobalInfoEvent e = new GlobalInfoEvent(this, f);                                  GlobalInfoEvent e = new GlobalInfoEvent(this, f);
966                                  for(GlobalInfoListener l : llGI) l.volumeChanged(e);                                  for(GlobalInfoListener l : llGI) l.volumeChanged(e);
967                            } else if(s.startsWith("VOICES ")) {
968                                    int i = Integer.parseInt(s.substring("VOICES ".length()));
969                                    GlobalInfoEvent e = new GlobalInfoEvent(this, i, -1);
970                                    for(GlobalInfoListener l : llGI) l.voiceLimitChanged(e);
971                            } else if(s.startsWith("STREAMS ")) {
972                                    int i = Integer.parseInt(s.substring("STREAMS ".length()));
973                                    GlobalInfoEvent e = new GlobalInfoEvent(this, -1, i);
974                                    for(GlobalInfoListener l : llGI) l.streamLimitChanged(e);
975                            } else {
976                                    getLogger().info("Unknown GLOBAL_INFO format: " + s);
977                          }                          }
978                  } catch(NumberFormatException x) {                  } catch(NumberFormatException x) {
979                          getLogger().log(Level.WARNING, "Unknown GLOBAL_INFO format", x);                          getLogger().log(Level.WARNING, "Unknown GLOBAL_INFO format", x);
# Line 1134  public class Client { Line 1283  public class Client {
1283          /**          /**
1284           * Registers the specified listener for receiving event messages.           * Registers the specified listener for receiving event messages.
1285           * Listeners can be registered regardless of the connection state.           * Listeners can be registered regardless of the connection state.
1286             * @param l The <code>TotalStreamCountListener</code> to register.
1287             */
1288            public synchronized void
1289            addTotalStreamCountListener(TotalStreamCountListener l) {
1290                    if(llTSC.isEmpty()) subscribe("TOTAL_STREAM_COUNT");
1291                    llTSC.add(l);
1292            }
1293            
1294            /**
1295             * Removes the specified listener.
1296             * Listeners can be removed regardless of the connection state.
1297             * @param l The <code>TotalStreamCountListener</code> to remove.
1298             */
1299            public synchronized void
1300            removeTotalStreamCountListener(TotalStreamCountListener l) {
1301                    boolean b = llTSC.remove(l);
1302                    if(b && llTSC.isEmpty()) unsubscribe("TOTAL_STREAM_COUNT");
1303            }
1304            
1305            /**
1306             * Registers the specified listener for receiving event messages.
1307             * Listeners can be registered regardless of the connection state.
1308           * @param l The <code>TotalVoiceCountListener</code> to register.           * @param l The <code>TotalVoiceCountListener</code> to register.
1309           */           */
1310          public synchronized void          public synchronized void
# Line 1244  public class Client { Line 1415  public class Client {
1415          /**          /**
1416           * Registers the specified listener for receiving event messages.           * Registers the specified listener for receiving event messages.
1417           * Listeners can be registered regardless of the connection state.           * Listeners can be registered regardless of the connection state.
1418             * @param l The <code>DeviceMidiDataListener</code> to register.
1419             */
1420            public synchronized void
1421            addDeviceMidiDataListener(DeviceMidiDataListener l) {
1422                    if(llDMD.isEmpty()) subscribe("DEVICE_MIDI");
1423                    llDMD.add(l);
1424            }
1425            
1426            /**
1427             * Removes the specified listener.
1428             * Listeners can be removed regardless of the connection state.
1429             * @param l The <code>DeviceMidiDataListener</code> to remove.
1430             */
1431            public synchronized void
1432            removeDeviceMidiDataListener(DeviceMidiDataListener l) {
1433                    boolean b = llDMD.remove(l);
1434                    if(b && llDMD.isEmpty()) unsubscribe("DEVICE_MIDI");
1435            }
1436            
1437            /**
1438             * Registers the specified listener for receiving event messages.
1439             * Listeners can be registered regardless of the connection state.
1440             * @param l The <code>ChannelMidiDataListener</code> to register.
1441             */
1442            public synchronized void
1443            addChannelMidiDataListener(ChannelMidiDataListener l) {
1444                    if(llCMD.isEmpty()) subscribe("CHANNEL_MIDI");
1445                    llCMD.add(l);
1446            }
1447            
1448            /**
1449             * Removes the specified listener.
1450             * Listeners can be removed regardless of the connection state.
1451             * @param l The <code>ChannelMidiDataListener</code> to remove.
1452             */
1453            public synchronized void
1454            removeChannelMidiDataListener(ChannelMidiDataListener l) {
1455                    boolean b = llCMD.remove(l);
1456                    if(b && llCMD.isEmpty()) unsubscribe("CHANNEL_MIDI");
1457            }
1458            
1459            /**
1460             * Registers the specified listener for receiving event messages.
1461             * Listeners can be registered regardless of the connection state.
1462           * @param l The <code>InstrumentsDbListener</code> to register.           * @param l The <code>InstrumentsDbListener</code> to register.
1463           */           */
1464          public synchronized void          public synchronized void
# Line 1418  public class Client { Line 1633  public class Client {
1633                  args.append(' ').append(param);                  args.append(' ').append(param);
1634                                    
1635                  for(Parameter p : deplist) {                  for(Parameter p : deplist) {
1636                          if(p.getValue() == null) continue;                          if(p == null || p.getName() == null || p.getValue() == null) continue;
1637                          args.append(' ').append(p.getName()).append('=').append(p.getStringValue());                          args.append(' ').append(p.getName()).append('=').append(p.getStringValue());
1638                  }                  }
1639                                    
# Line 1482  public class Client { Line 1697  public class Client {
1697                  StringBuffer args = new StringBuffer(aoDriver);                  StringBuffer args = new StringBuffer(aoDriver);
1698                                    
1699                  for(Parameter p : paramList) {                  for(Parameter p : paramList) {
1700                          if(p.getValue() == null) continue;                          if(p == null || p.getName() == null || p.getValue() == null) continue;
1701                          args.append(' ').append(p.getName()).append('=').append(p.getStringValue());                          args.append(' ').append(p.getName()).append('=').append(p.getStringValue());
1702                  }                  }
1703                                    
# Line 2004  public class Client { Line 2219  public class Client {
2219                  args.append(' ').append(param);                  args.append(' ').append(param);
2220                                    
2221                  for(Parameter p : deplist) {                  for(Parameter p : deplist) {
2222                          if(p.getValue() == null) continue;                          if(p == null || p.getName() == null || p.getValue() == null) continue;
2223                          args.append(' ').append(p.getName()).append('=').append(p.getStringValue());                          args.append(' ').append(p.getName()).append('=').append(p.getStringValue());
2224                  }                  }
2225                                    
# Line 2069  public class Client { Line 2284  public class Client {
2284                  StringBuffer args = new StringBuffer(miDriver);                  StringBuffer args = new StringBuffer(miDriver);
2285                                    
2286                  for(Parameter p : paramList) {                  for(Parameter p : paramList) {
2287                          if(p.getValue() == null) continue;                          if(p == null || p.getName() == null || p.getValue() == null) continue;
2288                          args.append(' ').append(p.getName()).append('=').append(p.getStringValue());                          args.append(' ').append(p.getName()).append('=').append(p.getStringValue());
2289                  }                  }
2290                                    
# Line 2216  public class Client { Line 2431  public class Client {
2431                                  mid.setActive(Boolean.parseBoolean(s));                                  mid.setActive(Boolean.parseBoolean(s));
2432                          } else if(s.startsWith("PORTS: ")) {                          } else if(s.startsWith("PORTS: ")) {
2433                                  s = s.substring("PORTS: ".length());                                  s = s.substring("PORTS: ".length());
2434                                  int ports = Parser.parseInt(s);                                  
2435                                  MidiPort[] midiPorts = new MidiPort[ports > 0 ? ports : 0];                                  Parameter<Integer> ports = (Parameter<Integer>)
2436                                            getMidiInputDriverParameterInfo(drv, "PORTS");
2437                                    
2438                                    ports.parseValue(s);
2439                                    mid.setPortsParameter(ports);
2440                                    
2441                                    int j = ports.getValue();
2442                                    MidiPort[] midiPorts = new MidiPort[j > 0 ? j : 0];
2443                                                                    
2444                                  for(int i = 0; i < midiPorts.length; i++)                                  for(int i = 0; i < midiPorts.length; i++)
2445                                          midiPorts[i] = getMidiInputPortInfo(deviceId, i);                                          midiPorts[i] = getMidiInputPortInfo(deviceId, i);
# Line 2460  public class Client { Line 2682  public class Client {
2682          public synchronized int          public synchronized int
2683          addMidiInstrumentMap(String name) throws IOException, LSException, LscpException {          addMidiInstrumentMap(String name) throws IOException, LSException, LscpException {
2684                  verifyConnection();                  verifyConnection();
2685                  out.writeLine("ADD MIDI_INSTRUMENT_MAP '" + name + "'");                  out.writeLine("ADD MIDI_INSTRUMENT_MAP '" + toEscapedText(name) + "'");
2686                  if(getPrintOnlyMode()) return -1;                  if(getPrintOnlyMode()) return -1;
2687                                    
2688                  ResultSet rs = getEmptyResultSet();                  ResultSet rs = getEmptyResultSet();
# Line 2563  public class Client { Line 2785  public class Client {
2785                                    
2786                  for(String s : lnS) {                  for(String s : lnS) {
2787                          if(s.startsWith("NAME: ")) {                          if(s.startsWith("NAME: ")) {
2788                                  name = s.substring("NAME: ".length());                                  name = toNonEscapedString(s.substring("NAME: ".length()));
2789                          } else if(s.startsWith("DEFAULT: ")) {                          } else if(s.startsWith("DEFAULT: ")) {
2790                                  b = Boolean.parseBoolean(s.substring("DEFAULT: ".length()));                                  b = Boolean.parseBoolean(s.substring("DEFAULT: ".length()));
2791                          } else {                          } else {
# Line 2611  public class Client { Line 2833  public class Client {
2833                                  throws IOException, LscpException, LSException {                                  throws IOException, LscpException, LSException {
2834                                    
2835                  verifyConnection();                  verifyConnection();
2836                    name = toEscapedText(name);
2837                  out.writeLine("SET MIDI_INSTRUMENT_MAP NAME " +  + mapId + " '" + name + "'");                  out.writeLine("SET MIDI_INSTRUMENT_MAP NAME " +  + mapId + " '" + name + "'");
2838                  if(getPrintOnlyMode()) return;                  if(getPrintOnlyMode()) return;
2839                                    
# Line 2660  public class Client { Line 2883  public class Client {
2883                  cmd.append(entry.getMidiBank()).append(' ');                  cmd.append(entry.getMidiBank()).append(' ');
2884                  cmd.append(entry.getMidiProgram()).append(' ');                  cmd.append(entry.getMidiProgram()).append(' ');
2885                  cmd.append(info.getEngine()).append(" '");                  cmd.append(info.getEngine()).append(" '");
2886                  cmd.append(info.getFilePath()).append("' ");                  cmd.append(conv(info.getFilePath())).append("' ");
2887                  cmd.append(info.getInstrumentIndex()).append(' ');                  cmd.append(info.getInstrumentIndex()).append(' ');
2888                  cmd.append(info.getVolume());                  cmd.append(info.getVolume());
2889                  if(!info.getLoadMode().name().equals("DEFAULT")) {                  if(!info.getLoadMode().name().equals("DEFAULT")) {
2890                          cmd.append(' ').append(info.getLoadMode().name());                          cmd.append(' ').append(info.getLoadMode().name());
2891                  }                  }
2892                  if(info.getName() != null) cmd.append(" '").append(info.getName()).append("'");                  
2893                    if(info.getName() != null) {
2894                            String s = toEscapedText(info.getName());
2895                            cmd.append(" '").append(s).append("'");
2896                    }
2897                                    
2898                  out.writeLine(cmd.toString());                  out.writeLine(cmd.toString());
2899                  if(getPrintOnlyMode()) return;                  if(getPrintOnlyMode()) return;
# Line 2755  public class Client { Line 2982  public class Client {
2982          }          }
2983                    
2984          /**          /**
2985           * Gets all MIDI instrument contained int the specified MIDI instrument map.           * Gets all MIDI instrument entries contained int the specified MIDI instrument map.
2986             * @param mapId The ID of the map, which instruments should be obtained.
2987             * @return An int array providing all MIDI instrument entries
2988             * in the specified MIDI instrument map.
2989             * @throws IOException If some I/O error occurs.
2990             * @throws LscpException If LSCP protocol corruption occurs.
2991             * @throws LSException If some other error occurs.
2992             */
2993            public synchronized int[][]
2994            getMidiInstrumentEntries(int mapId) throws IOException, LscpException, LSException {
2995                    verifyConnection();
2996                    out.writeLine("LIST MIDI_INSTRUMENTS " + String.valueOf(mapId));
2997                    if(getPrintOnlyMode()) return null;
2998                    
2999                    String[] entries = parseArray(getSingleLineResultSet().getResult());
3000                    int[][] e = new int[entries.length][3];
3001                    
3002                    for(int i = 0; i < entries.length; i++) {
3003                            Integer[] vals = parseIntList(entries[i]);
3004                            if(vals.length != 3) {
3005                                    throw new LscpException(LscpI18n.getLogMsg("CommandFailed!"));
3006                            }
3007                            
3008                            e[i][0] = vals[0];
3009                            e[i][1] = vals[1];
3010                            e[i][2] = vals[2];
3011                    }
3012                    
3013                    return e;
3014            }
3015            
3016            /**
3017             * Gets all MIDI instruments contained int the specified MIDI instrument map.
3018           * @param mapId The ID of the map, which instruments should be obtained.           * @param mapId The ID of the map, which instruments should be obtained.
3019           * @return A <code>MidiInstrumentInfo</code> array providing           * @return A <code>MidiInstrumentInfo</code> array providing
3020           * all MIDI instruments from all MIDI instrument maps.           * all MIDI instruments in the specified MIDI instrument map.
3021           * @throws IOException If some I/O error occurs.           * @throws IOException If some I/O error occurs.
3022           * @throws LscpException If LSCP protocol corruption occurs.           * @throws LscpException If LSCP protocol corruption occurs.
3023           * @throws LSException If some other error occurs.           * @throws LSException If some other error occurs.
# Line 2806  public class Client { Line 3065  public class Client {
3065                                          throws IOException, LscpException, LSException {                                          throws IOException, LscpException, LSException {
3066                    
3067                  verifyConnection();                  verifyConnection();
3068                    requestMidiInstrumentInfo(mapId, bank, program);
3069                    return getMidiInstrumentInfoResponse(mapId, bank, program);
3070            }
3071            
3072            private void
3073            requestMidiInstrumentInfo(int mapId, int bank, int program) throws IOException {
3074                  StringBuffer cmd = new StringBuffer("GET MIDI_INSTRUMENT INFO ");                  StringBuffer cmd = new StringBuffer("GET MIDI_INSTRUMENT INFO ");
3075                  cmd.append(mapId).append(' ');                  cmd.append(mapId).append(' ');
3076                  cmd.append(bank).append(' ');                  cmd.append(bank).append(' ');
3077                  cmd.append(program);                  cmd.append(program);
3078                                    
3079                  out.writeLine(cmd.toString());                  out.writeLine(cmd.toString());
3080                  if(getPrintOnlyMode()) return null;          }
3081            
3082            private MidiInstrumentInfo
3083            getMidiInstrumentInfoResponse(int mapId, int bank, int program)
3084                                            throws IOException, LscpException, LSException {
3085                                    
3086                    if(getPrintOnlyMode()) return null;
3087                  ResultSet rs = getMultiLineResultSet();                  ResultSet rs = getMultiLineResultSet();
3088                  MidiInstrumentEntry entry = new MidiInstrumentEntry(bank, program);                  MidiInstrumentEntry entry = new MidiInstrumentEntry(bank, program);
3089                  return new MidiInstrumentInfo(mapId, entry, rs.getMultiLineResult());                  return new MidiInstrumentInfo(mapId, entry, rs.getMultiLineResult());
# Line 2863  public class Client { Line 3133  public class Client {
3133                                                  throws IOException, LscpException, LSException {                                                  throws IOException, LscpException, LSException {
3134                                    
3135                  String cmd = nonModal ? "LOAD INSTRUMENT NON_MODAL " : "LOAD INSTRUMENT ";                  String cmd = nonModal ? "LOAD INSTRUMENT NON_MODAL " : "LOAD INSTRUMENT ";
3136                  String args = '\'' + filename + "' " + instrIdx + ' ' + samplerChn;                  String args = '\'' + conv(filename) + "' " + instrIdx + ' ' + samplerChn;
3137                                    
3138                  out.writeLine(cmd + args);                  out.writeLine(cmd + args);
3139                  if(getPrintOnlyMode()) return;                  if(getPrintOnlyMode()) return;
# Line 3044  public class Client { Line 3314  public class Client {
3314                  out.writeLine("LIST AVAILABLE_ENGINES");                  out.writeLine("LIST AVAILABLE_ENGINES");
3315                  if(getPrintOnlyMode()) return null;                  if(getPrintOnlyMode()) return null;
3316                                    
3317                  return parseQuotedStringList(getSingleLineResultSet().getResult());                  return parseStringList(getSingleLineResultSet().getResult());
3318          }          }
3319                    
3320          /**          /**
# Line 3515  public class Client { Line 3785  public class Client {
3785                                    
3786                  verifyConnection();                  verifyConnection();
3787                  String s = String.valueOf(channel) + " " + String.valueOf(midiCtrl);                  String s = String.valueOf(channel) + " " + String.valueOf(midiCtrl);
3788                  if(name != null) s += " '" + name + "'";                  if(name != null) s += " '" + toEscapedText(name) + "'";
3789                  out.writeLine("CREATE FX_SEND " + s);                  out.writeLine("CREATE FX_SEND " + s);
3790                  if(getPrintOnlyMode()) return -1;                  if(getPrintOnlyMode()) return -1;
3791                                    
# Line 3646  public class Client { Line 3916  public class Client {
3916                                  throws IOException, LscpException, LSException {                                  throws IOException, LscpException, LSException {
3917                                    
3918                  verifyConnection();                  verifyConnection();
3919                  String args = " " + channel + " " + fxSend + " '" + name + "'";                  String args = " " + channel + " " + fxSend + " '" + toEscapedText(name) + "'";
3920                  out.writeLine("SET FX_SEND NAME" + args);                  out.writeLine("SET FX_SEND NAME" + args);
3921                  if(getPrintOnlyMode()) return;                  if(getPrintOnlyMode()) return;
3922                                    
# Line 3745  public class Client { Line 4015  public class Client {
4015           * @see #getSamplerChannels           * @see #getSamplerChannels
4016           */           */
4017          public synchronized void          public synchronized void
4018          editInstrument(int samplerChn) throws IOException, LscpException, LSException {          editChannelInstrument(int samplerChn) throws IOException, LscpException, LSException {
4019                    verifyConnection();
4020                    out.writeLine("EDIT CHANNEL INSTRUMENT " + samplerChn);
4021                    if(getPrintOnlyMode()) return;
4022                    
4023                    ResultSet rs = getEmptyResultSet();
4024            }
4025            
4026            /**
4027             * Sends a MIDI event to this sampler channel.
4028             * @param samplerChn The sampler channel number.
4029             * @param type The type of MIDI message to send.
4030             * @throws IOException If some I/O error occurs.
4031             * @throws LscpException If LSCP protocol corruption occurs.
4032             * @throws LSException If <code>samplerChn</code> is not a valid channel number or if
4033             * there is no instrument loaded on the specified sampler channel.
4034             * @see #getSamplerChannels
4035             */
4036            public synchronized void
4037            sendChannelMidiData(int samplerChn, MidiDataEvent.Type type, int arg1, int arg2)
4038                                                    throws IOException, LscpException, LSException {
4039                    
4040                  verifyConnection();                  verifyConnection();
4041                  out.writeLine("EDIT INSTRUMENT " + samplerChn);                  StringBuffer sb = new StringBuffer();
4042                    sb.append("SEND CHANNEL MIDI_DATA ");
4043                    sb.append(type).append(" ").append(samplerChn).append(" ");
4044                    sb.append(arg1).append(" ").append(arg2);
4045                    
4046                    out.writeLine(sb.toString());
4047                    if(getPrintOnlyMode()) return;
4048                    
4049                    ResultSet rs = getEmptyResultSet();
4050            }
4051            
4052            /**
4053             * Resets the specified sampler channel.
4054             *
4055             * @param samplerChn The sampler channel number.
4056             *
4057             * @throws IOException If some I/O error occurs.
4058             * @throws LscpException If LSCP protocol corruption occurs.
4059             * @throws LSException If <code>samplerChn</code> is not a valid channel number or if
4060             * there is no engine assigned yet to the specified sampler channel.
4061             * @see #getSamplerChannels
4062             */
4063            public synchronized void
4064            resetChannel(int samplerChn) throws IOException, LscpException, LSException {
4065                    verifyConnection();
4066                    out.writeLine("RESET CHANNEL " + samplerChn);
4067                  if(getPrintOnlyMode()) return;                  if(getPrintOnlyMode()) return;
4068                                    
4069                  ResultSet rs = getEmptyResultSet();                  ResultSet rs = getEmptyResultSet();
# Line 3765  public class Client { Line 4081  public class Client {
4081          public synchronized void          public synchronized void
4082          addDbDirectory(String dir) throws IOException, LSException, LscpException {          addDbDirectory(String dir) throws IOException, LSException, LscpException {
4083                  verifyConnection();                  verifyConnection();
4084                  out.writeLine("ADD DB_INSTRUMENT_DIRECTORY '" + dir + "'");                  out.writeLine("ADD DB_INSTRUMENT_DIRECTORY '" + conv(dir) + "'");
4085                  if(getPrintOnlyMode()) return;                  if(getPrintOnlyMode()) return;
4086                                    
4087                  ResultSet rs = getEmptyResultSet();                  ResultSet rs = getEmptyResultSet();
# Line 3800  public class Client { Line 4116  public class Client {
4116                  verifyConnection();                  verifyConnection();
4117                  String s = "REMOVE DB_INSTRUMENT_DIRECTORY ";                  String s = "REMOVE DB_INSTRUMENT_DIRECTORY ";
4118                  if(force) s += "FORCE ";                  if(force) s += "FORCE ";
4119                  out.writeLine(s + "'" + dir + "'");                  out.writeLine(s + "'" + conv(dir) + "'");
4120                  if(getPrintOnlyMode()) return;                  if(getPrintOnlyMode()) return;
4121                                    
4122                  ResultSet rs = getEmptyResultSet();                  ResultSet rs = getEmptyResultSet();
# Line 3823  public class Client { Line 4139  public class Client {
4139                  String cmd = "REMOVE DB_INSTRUMENT_DIRECTORY ";                  String cmd = "REMOVE DB_INSTRUMENT_DIRECTORY ";
4140                  if(force) cmd += "FORCE ";                  if(force) cmd += "FORCE ";
4141                                    
4142                  for(String s : dirs) out.writeLine(cmd + "'" + s + "'");                  for(String s : dirs) out.writeLine(cmd + "'" + conv(s) + "'");
4143                                    
4144                  if(getPrintOnlyMode()) return;                  if(getPrintOnlyMode()) return;
4145                                    
# Line 3861  public class Client { Line 4177  public class Client {
4177                  String s;                  String s;
4178                  if(recursive) s = "GET DB_INSTRUMENT_DIRECTORIES RECURSIVE '";                  if(recursive) s = "GET DB_INSTRUMENT_DIRECTORIES RECURSIVE '";
4179                  else s = "GET DB_INSTRUMENT_DIRECTORIES '";                  else s = "GET DB_INSTRUMENT_DIRECTORIES '";
4180                  out.writeLine(s + dir + "'");                  out.writeLine(s + conv(dir) + "'");
4181                  if(getPrintOnlyMode()) return -1;                  if(getPrintOnlyMode()) return -1;
4182                                    
4183                  s = getSingleLineResultSet().getResult();                  s = getSingleLineResultSet().getResult();
# Line 3880  public class Client { Line 4196  public class Client {
4196          public synchronized String[]          public synchronized String[]
4197          getDbDirectoryNames(String dir) throws IOException, LscpException, LSException {          getDbDirectoryNames(String dir) throws IOException, LscpException, LSException {
4198                  verifyConnection();                  verifyConnection();
4199                  out.writeLine("LIST DB_INSTRUMENT_DIRECTORIES '" + dir + "'");                  out.writeLine("LIST DB_INSTRUMENT_DIRECTORIES '" + conv(dir) + "'");
4200                  if(getPrintOnlyMode()) return null;                  if(getPrintOnlyMode()) return null;
4201                                    
4202                  String[] names = parseEscapedStringList(getSingleLineResultSet().getResult());                  String[] names = parseEscapedStringList(getSingleLineResultSet().getResult());
# Line 3902  public class Client { Line 4218  public class Client {
4218          public synchronized DbDirectoryInfo          public synchronized DbDirectoryInfo
4219          getDbDirectoryInfo(String dir) throws IOException, LscpException, LSException {          getDbDirectoryInfo(String dir) throws IOException, LscpException, LSException {
4220                  verifyConnection();                  verifyConnection();
4221                  out.writeLine("GET DB_INSTRUMENT_DIRECTORY INFO '" + dir + "'");                  out.writeLine("GET DB_INSTRUMENT_DIRECTORY INFO '" + conv(dir) + "'");
4222                  if(getPrintOnlyMode()) return null;                  if(getPrintOnlyMode()) return null;
4223                                    
4224                  ResultSet rs = getMultiLineResultSet();                  ResultSet rs = getMultiLineResultSet();
# Line 3935  public class Client { Line 4251  public class Client {
4251                  if(!hasEndingFileSeparator(dir)) dir += "/";                  if(!hasEndingFileSeparator(dir)) dir += "/";
4252                  DbDirectoryInfo[] infoS = new DbDirectoryInfo[dirS.length];                  DbDirectoryInfo[] infoS = new DbDirectoryInfo[dirS.length];
4253                  for(int i = 0; i < dirS.length; i++) {                  for(int i = 0; i < dirS.length; i++) {
4254                          infoS[i] = getDbDirectoryInfo(dir + toEscapedFileName(dirS[i]));                          infoS[i] = getDbDirectoryInfo(conv(dir) + toEscapedFsEntry(dirS[i]));
4255                  }                  }
4256                  return infoS;                  return infoS;
4257          }          }
# Line 3951  public class Client { Line 4267  public class Client {
4267           *           *
4268          public synchronized DbDirectoryInfo[]          public synchronized DbDirectoryInfo[]
4269          getDbDirectories(String dir) throws IOException, LscpException, LSException {          getDbDirectories(String dir) throws IOException, LscpException, LSException {
4270                  String[] dirS = getDbDirectoryNames(dir);                  String[] dirS = getDbDirectoryNames(conv(dir));
4271                  if(dirS.length == 0) return new DbDirectoryInfo[0];                  if(dirS.length == 0) return new DbDirectoryInfo[0];
4272                                    
4273                  if(dir.charAt(dir.length() - 1) != '/') dir += "/";                  if(dir.charAt(dir.length() - 1) != '/') dir += "/"; // FIXME:
4274                                    
4275                  for(int i = 0; i < dirS.length; i++) {                  for(int i = 0; i < dirS.length; i++) {
4276                          out.writeLine("GET DB_INSTRUMENT_DIRECTORY INFO '" + dir + dirS[i] + "'");                          out.writeLine("GET DB_INSTRUMENT_DIRECTORY INFO '" + conv(dir + dirS[i]) + "'");
4277                  }                  }
4278                                    
4279                  if(getPrintOnlyMode()) return null;                  if(getPrintOnlyMode()) return null;
# Line 4001  public class Client { Line 4317  public class Client {
4317          public synchronized void          public synchronized void
4318          renameDbDirectory(String dir, String name) throws IOException, LSException, LscpException {          renameDbDirectory(String dir, String name) throws IOException, LSException, LscpException {
4319                  verifyConnection();                  verifyConnection();
4320                  name = toEscapedString(name);                  name = toEscapedText(name);
4321                  out.writeLine("SET DB_INSTRUMENT_DIRECTORY NAME '" + dir + "' '" + name + "'");                  out.writeLine("SET DB_INSTRUMENT_DIRECTORY NAME '" + conv(dir) + "' '" + conv(name) + "'");
4322                  if(getPrintOnlyMode()) return;                  if(getPrintOnlyMode()) return;
4323                                    
4324                  ResultSet rs = getEmptyResultSet();                  ResultSet rs = getEmptyResultSet();
# Line 4019  public class Client { Line 4335  public class Client {
4335          public synchronized void          public synchronized void
4336          moveDbDirectory(String dir, String dst) throws IOException, LSException, LscpException {          moveDbDirectory(String dir, String dst) throws IOException, LSException, LscpException {
4337                  verifyConnection();                  verifyConnection();
4338                  out.writeLine("MOVE DB_INSTRUMENT_DIRECTORY '" + dir + "' '" + dst + "'");                  out.writeLine("MOVE DB_INSTRUMENT_DIRECTORY '" + conv(dir) + "' '" + conv(dst) + "'");
4339                  if(getPrintOnlyMode()) return;                  if(getPrintOnlyMode()) return;
4340                                    
4341                  ResultSet rs = getEmptyResultSet();                  ResultSet rs = getEmptyResultSet();
# Line 4037  public class Client { Line 4353  public class Client {
4353          moveDbDirectories(String dirs[], String dst) throws IOException, LSException, LscpException {          moveDbDirectories(String dirs[], String dst) throws IOException, LSException, LscpException {
4354                  verifyConnection();                  verifyConnection();
4355                  for(String s : dirs) {                  for(String s : dirs) {
4356                          out.writeLine("MOVE DB_INSTRUMENT_DIRECTORY '" + s + "' '" + dst + "'");                          out.writeLine("MOVE DB_INSTRUMENT_DIRECTORY '" + conv(s) + "' '" + conv(dst) + "'");
4357                  }                  }
4358                  if(getPrintOnlyMode()) return;                  if(getPrintOnlyMode()) return;
4359                                    
# Line 4055  public class Client { Line 4371  public class Client {
4371          public synchronized void          public synchronized void
4372          copyDbDirectory(String dir, String dst) throws IOException, LSException, LscpException {          copyDbDirectory(String dir, String dst) throws IOException, LSException, LscpException {
4373                  verifyConnection();                  verifyConnection();
4374                  out.writeLine("COPY DB_INSTRUMENT_DIRECTORY '" + dir + "' '" + dst + "'");                  out.writeLine("COPY DB_INSTRUMENT_DIRECTORY '" + conv(dir) + "' '" + conv(dst) + "'");
4375                  if(getPrintOnlyMode()) return;                  if(getPrintOnlyMode()) return;
4376                                    
4377                  ResultSet rs = getEmptyResultSet();                  ResultSet rs = getEmptyResultSet();
# Line 4073  public class Client { Line 4389  public class Client {
4389          copyDbDirectories(String[] dirs, String dst) throws IOException, LSException, LscpException {          copyDbDirectories(String[] dirs, String dst) throws IOException, LSException, LscpException {
4390                  verifyConnection();                  verifyConnection();
4391                  for(String s : dirs) {                  for(String s : dirs) {
4392                          out.writeLine("COPY DB_INSTRUMENT_DIRECTORY '" + s + "' '" + dst + "'");                          out.writeLine("COPY DB_INSTRUMENT_DIRECTORY '" + conv(s) + "' '" + conv(dst) + "'");
4393                  }                  }
4394                  if(getPrintOnlyMode()) return;                  if(getPrintOnlyMode()) return;
4395                                    
# Line 4094  public class Client { Line 4410  public class Client {
4410                                    
4411                  verifyConnection();                  verifyConnection();
4412                  String s = "SET DB_INSTRUMENT_DIRECTORY DESCRIPTION '";                  String s = "SET DB_INSTRUMENT_DIRECTORY DESCRIPTION '";
4413                  out.writeLine(s + dir + "' '" + toEscapedString(desc) + "'");                  out.writeLine(s + conv(dir) + "' '" + toEscapedText(desc) + "'");
4414                  if(getPrintOnlyMode()) return;                  if(getPrintOnlyMode()) return;
4415                                    
4416                  ResultSet rs = getEmptyResultSet();                  ResultSet rs = getEmptyResultSet();
# Line 4143  public class Client { Line 4459  public class Client {
4459                  verifyConnection();                  verifyConnection();
4460                  String s = "ADD DB_INSTRUMENTS";                  String s = "ADD DB_INSTRUMENTS";
4461                  if(background) s += " NON_MODAL";                  if(background) s += " NON_MODAL";
4462                  s += " '" + dbDir + "' '" + filePath + "' ";                  s += " '" + conv(dbDir) + "' '" + conv(filePath) + "' ";
4463                  out.writeLine(s + String.valueOf(instrIndex));                  out.writeLine(s + String.valueOf(instrIndex));
4464                  if(getPrintOnlyMode()) return -1;                  if(getPrintOnlyMode()) return -1;
4465                                    
# Line 4190  public class Client { Line 4506  public class Client {
4506                  verifyConnection();                  verifyConnection();
4507                  String s = "ADD DB_INSTRUMENTS";                  String s = "ADD DB_INSTRUMENTS";
4508                  if(background) s += " NON_MODAL";                  if(background) s += " NON_MODAL";
4509                  out.writeLine(s + " '" + dbDir + "' '" + filePath + "'");                  out.writeLine(s + " '" + conv(dbDir) + "' '" + conv(filePath) + "'");
4510                  if(getPrintOnlyMode()) return -1;                  if(getPrintOnlyMode()) return -1;
4511                                    
4512                  ResultSet rs = getEmptyResultSet();                  ResultSet rs = getEmptyResultSet();
# Line 4257  public class Client { Line 4573  public class Client {
4573          addDbInstruments(ScanMode mode, String dbDir, String fsDir, boolean background)          addDbInstruments(ScanMode mode, String dbDir, String fsDir, boolean background)
4574                                          throws IOException, LSException, LscpException {                                          throws IOException, LSException, LscpException {
4575                                    
4576                    return addDbInstruments(mode, dbDir, fsDir, background, false);
4577            }
4578            
4579            /**
4580             * Adds the instruments in the specified file system directory
4581             * to the specified instruments database directory.
4582             * @param mode Determines the scanning mode. If RECURSIVE is
4583             * specified, all supported instruments in the specified file system
4584             * direcotry will be added to the specified instruments database
4585             * directory, including the instruments in subdirectories
4586             * of the supplied directory. If NON_RECURSIVE is specified,
4587             * the instruments in the subdirectories will not be processed.
4588             * If FLAT is specified, all supported instruments in the specified
4589             * file system direcotry will be added, including the instruments in
4590             * subdirectories of the supplied directory, but the respective
4591             * subdirectory structure will not be recreated in the instruments
4592             * database and all instruments will be added directly in the
4593             * specified database directory.
4594             * @param dbDir The absolute path name of the database directory
4595             * in which the supported instruments will be added.
4596             * @param fsDir The absolute path name of the file system directory.
4597             * @param background If <code>true</code>, the scan will be done
4598             * in background and this method may return before the job is finished.
4599             * @param insDir If <code>true</code> a drieectory is created for each
4600             * instrument file.
4601             * @return If <code>background</code> is <code>true</code>, the ID
4602             * of the scan job.
4603             * @throws IOException If some I/O error occurs.
4604             * @throws LSException If the operation failed.
4605             * @throws LscpException If LSCP protocol corruption occurs.
4606             * @see #addInstrumentsDbListener
4607             */
4608            public synchronized int
4609            addDbInstruments(ScanMode mode, String dbDir, String fsDir, boolean background, boolean insDir)
4610                                            throws IOException, LSException, LscpException {
4611                    
4612                  verifyConnection();                  verifyConnection();
4613                  StringBuffer sb = new StringBuffer("ADD DB_INSTRUMENTS");                  StringBuffer sb = new StringBuffer("ADD DB_INSTRUMENTS");
4614                  if(background) sb.append(" NON_MODAL");                  if(background) sb.append(" NON_MODAL");
# Line 4272  public class Client { Line 4624  public class Client {
4624                                  sb.append(" FLAT");                                  sb.append(" FLAT");
4625                                  break;                                  break;
4626                  }                  }
4627                    if(insDir)
4628                            sb.append(" FILE_AS_DIR");
4629                                    
4630                  sb.append(" '").append(dbDir).append("' '");                  sb.append(" '").append(conv(dbDir)).append("' '");
4631                  sb.append(fsDir).append("'");                  sb.append(conv(fsDir)).append("'");
4632                  out.writeLine(sb.toString());                  out.writeLine(sb.toString());
4633                  if(getPrintOnlyMode()) return -1;                  if(getPrintOnlyMode()) return -1;
4634                                    
4635                  ResultSet rs = getEmptyResultSet();                  ResultSet rs = getEmptyResultSet();
4636                  return rs.getIndex();                  return rs.getIndex();
4637          }          }
4638            
4639          /**          /**
4640           * Removes the specified instrument from the instruments database.           * Removes the specified instrument from the instruments database.
4641           * @param instr The absolute path name of the instrument to remove.           * @param instr The absolute path name of the instrument to remove.
# Line 4293  public class Client { Line 4647  public class Client {
4647          removeDbInstrument(String instr) throws IOException, LscpException, LSException {          removeDbInstrument(String instr) throws IOException, LscpException, LSException {
4648                                    
4649                  verifyConnection();                  verifyConnection();
4650                  out.writeLine("REMOVE DB_INSTRUMENT '" + instr + "'");                  out.writeLine("REMOVE DB_INSTRUMENT '" + conv(instr) + "'");
4651                  if(getPrintOnlyMode()) return;                  if(getPrintOnlyMode()) return;
4652                                    
4653                  ResultSet rs = getEmptyResultSet();                  ResultSet rs = getEmptyResultSet();
# Line 4310  public class Client { Line 4664  public class Client {
4664          removeDbInstruments(String[] instrs) throws IOException, LscpException, LSException {          removeDbInstruments(String[] instrs) throws IOException, LscpException, LSException {
4665                  verifyConnection();                  verifyConnection();
4666                  for(String s : instrs) {                  for(String s : instrs) {
4667                          out.writeLine("REMOVE DB_INSTRUMENT '" + s + "'");                          out.writeLine("REMOVE DB_INSTRUMENT '" + conv(s) + "'");
4668                  }                  }
4669                  if(getPrintOnlyMode()) return;                  if(getPrintOnlyMode()) return;
4670                                    
# Line 4348  public class Client { Line 4702  public class Client {
4702                  String s;                  String s;
4703                  if(recursive) s = "GET DB_INSTRUMENTS RECURSIVE '";                  if(recursive) s = "GET DB_INSTRUMENTS RECURSIVE '";
4704                  else s = "GET DB_INSTRUMENTS '";                  else s = "GET DB_INSTRUMENTS '";
4705                  out.writeLine(s + dir + "'");                  out.writeLine(s + conv(dir) + "'");
4706                  if(getPrintOnlyMode()) return -1;                  if(getPrintOnlyMode()) return -1;
4707                                    
4708                  s = getSingleLineResultSet().getResult();                  s = getSingleLineResultSet().getResult();
# Line 4367  public class Client { Line 4721  public class Client {
4721          public synchronized String[]          public synchronized String[]
4722          getDbInstrumentNames(String dir) throws IOException, LscpException, LSException {          getDbInstrumentNames(String dir) throws IOException, LscpException, LSException {
4723                  verifyConnection();                  verifyConnection();
4724                  out.writeLine("LIST DB_INSTRUMENTS '" + dir + "'");                  out.writeLine("LIST DB_INSTRUMENTS '" + conv(dir) + "'");
4725                  if(getPrintOnlyMode()) return null;                  if(getPrintOnlyMode()) return null;
4726                                    
4727                  String[] names = parseEscapedStringList(getSingleLineResultSet().getResult());                  String[] names = parseEscapedStringList(getSingleLineResultSet().getResult());
# Line 4389  public class Client { Line 4743  public class Client {
4743          public synchronized DbInstrumentInfo          public synchronized DbInstrumentInfo
4744          getDbInstrumentInfo(String instr) throws IOException, LscpException, LSException {          getDbInstrumentInfo(String instr) throws IOException, LscpException, LSException {
4745                  verifyConnection();                  verifyConnection();
4746                  out.writeLine("GET DB_INSTRUMENT INFO '" + instr + "'");                  out.writeLine("GET DB_INSTRUMENT INFO '" + conv(instr) + "'");
4747                  if(getPrintOnlyMode()) return null;                  if(getPrintOnlyMode()) return null;
4748                                    
4749                  ResultSet rs = getMultiLineResultSet();                  ResultSet rs = getMultiLineResultSet();
# Line 4418  public class Client { Line 4772  public class Client {
4772                                    
4773                  DbInstrumentInfo[] infoS = new DbInstrumentInfo[instrS.length];                  DbInstrumentInfo[] infoS = new DbInstrumentInfo[instrS.length];
4774                  for(int i = 0; i < instrS.length; i++) {                  for(int i = 0; i < instrS.length; i++) {
4775                          infoS[i] = getDbInstrumentInfo(dir + toEscapedFileName(instrS[i]));                          infoS[i] = getDbInstrumentInfo(conv(dir) + toEscapedFsEntry(instrS[i]));
4776                  }                  }
4777                  return infoS;                  return infoS;
4778          }          }
# Line 4437  public class Client { Line 4791  public class Client {
4791                  String[] instrS = getDbInstrumentNames(dir);                  String[] instrS = getDbInstrumentNames(dir);
4792                  if(instrS.length == 0) return new DbInstrumentInfo[0];                  if(instrS.length == 0) return new DbInstrumentInfo[0];
4793                                    
4794                  if(dir.charAt(dir.length() - 1) != '/') dir += "/";                  if(dir.charAt(dir.length() - 1) != '/') dir += "/"; FIXME:
4795                                    
4796                  for(int i = 0; i < instrS.length; i++) {                  for(int i = 0; i < instrS.length; i++) {
4797                          out.writeLine("GET DB_INSTRUMENT INFO '" + dir + instrS[i] + "'");                          out.writeLine("GET DB_INSTRUMENT INFO '" + conv(dir) + instrS[i] + "'");
4798                  }                  }
4799                                    
4800                  if(getPrintOnlyMode()) return null;                  if(getPrintOnlyMode()) return null;
# Line 4486  public class Client { Line 4840  public class Client {
4840                                  throws IOException, LSException, LscpException {                                  throws IOException, LSException, LscpException {
4841                                    
4842                  verifyConnection();                  verifyConnection();
4843                  name = toEscapedString(name);                  name = toEscapedText(name);
4844                  out.writeLine("SET DB_INSTRUMENT NAME '" + instr + "' '" + name + "'");                  out.writeLine("SET DB_INSTRUMENT NAME '" + conv(instr) + "' '" + conv(name) + "'");
4845                  if(getPrintOnlyMode()) return;                  if(getPrintOnlyMode()) return;
4846                                    
4847                  ResultSet rs = getEmptyResultSet();                  ResultSet rs = getEmptyResultSet();
# Line 4504  public class Client { Line 4858  public class Client {
4858          public synchronized void          public synchronized void
4859          moveDbInstrument(String instr, String dst) throws IOException, LSException, LscpException {          moveDbInstrument(String instr, String dst) throws IOException, LSException, LscpException {
4860                  verifyConnection();                  verifyConnection();
4861                  out.writeLine("MOVE DB_INSTRUMENT '" + instr + "' '" + dst + "'");                  out.writeLine("MOVE DB_INSTRUMENT '" + conv(instr) + "' '" + conv(dst) + "'");
4862                  if(getPrintOnlyMode()) return;                  if(getPrintOnlyMode()) return;
4863                                    
4864                  ResultSet rs = getEmptyResultSet();                  ResultSet rs = getEmptyResultSet();
# Line 4522  public class Client { Line 4876  public class Client {
4876          moveDbInstruments(String[] instrs, String dst) throws IOException, LSException, LscpException {          moveDbInstruments(String[] instrs, String dst) throws IOException, LSException, LscpException {
4877                  verifyConnection();                  verifyConnection();
4878                  for(String s : instrs) {                  for(String s : instrs) {
4879                          out.writeLine("MOVE DB_INSTRUMENT '" + s + "' '" + dst + "'");                          out.writeLine("MOVE DB_INSTRUMENT '" + conv(s) + "' '" + conv(dst) + "'");
4880                  }                  }
4881                  if(getPrintOnlyMode()) return;                  if(getPrintOnlyMode()) return;
4882                                    
# Line 4540  public class Client { Line 4894  public class Client {
4894          public synchronized void          public synchronized void
4895          copyDbInstrument(String instr, String dst) throws IOException, LSException, LscpException {          copyDbInstrument(String instr, String dst) throws IOException, LSException, LscpException {
4896                  verifyConnection();                  verifyConnection();
4897                  out.writeLine("COPY DB_INSTRUMENT '" + instr + "' '" + dst + "'");                  out.writeLine("COPY DB_INSTRUMENT '" + conv(instr) + "' '" + conv(dst) + "'");
4898                  if(getPrintOnlyMode()) return;                  if(getPrintOnlyMode()) return;
4899                                    
4900                  ResultSet rs = getEmptyResultSet();                  ResultSet rs = getEmptyResultSet();
# Line 4558  public class Client { Line 4912  public class Client {
4912          copyDbInstruments(String[] instrs, String dst) throws IOException, LSException, LscpException {          copyDbInstruments(String[] instrs, String dst) throws IOException, LSException, LscpException {
4913                  verifyConnection();                  verifyConnection();
4914                  for(String s : instrs) {                  for(String s : instrs) {
4915                          out.writeLine("COPY DB_INSTRUMENT '" + s + "' '" + dst + "'");                          out.writeLine("COPY DB_INSTRUMENT '" + conv(s) + "' '" + conv(dst) + "'");
4916                  }                  }
4917                  if(getPrintOnlyMode()) return;                  if(getPrintOnlyMode()) return;
4918                                    
# Line 4578  public class Client { Line 4932  public class Client {
4932                                  throws IOException, LSException, LscpException {                                  throws IOException, LSException, LscpException {
4933                                    
4934                  verifyConnection();                  verifyConnection();
4935                  desc = toEscapedString(desc);                  desc = toEscapedText(desc);
4936                  out.writeLine("SET DB_INSTRUMENT DESCRIPTION '" + instr + "' '" + desc + "'");                  out.writeLine("SET DB_INSTRUMENT DESCRIPTION '" + conv(instr) + "' '" + desc + "'");
4937                    if(getPrintOnlyMode()) return;
4938                    
4939                    ResultSet rs = getEmptyResultSet();
4940            }
4941            
4942            /**
4943             * Substitutes all occurrences of the instrument file
4944             * <code>oldPath</code> in the database, with <code>newPath</code>.
4945             * @param oldPath The absolute path name of the instrument file to substitute.
4946             * @param newPath The new absolute path name.
4947             * @throws IOException If some I/O error occurs.
4948             * @throws LSException If the operation failed.
4949             * @throws LscpException If LSCP protocol corruption occurs.
4950             */
4951            public synchronized void
4952            setDbInstrumentFilePath(String oldPath, String newPath)
4953                                    throws IOException, LSException, LscpException {
4954                    
4955                    verifyConnection();
4956                    out.writeLine("SET DB_INSTRUMENT FILE_PATH '" + conv(oldPath) + "' '" + conv(newPath) + "'");
4957                  if(getPrintOnlyMode()) return;                  if(getPrintOnlyMode()) return;
4958                                    
4959                  ResultSet rs = getEmptyResultSet();                  ResultSet rs = getEmptyResultSet();
# Line 4623  public class Client { Line 4997  public class Client {
4997                  StringBuffer sb = new StringBuffer();                  StringBuffer sb = new StringBuffer();
4998                  sb.append("FIND DB_INSTRUMENT_DIRECTORIES");                  sb.append("FIND DB_INSTRUMENT_DIRECTORIES");
4999                  if(nonRecursive) sb.append(" NON_RECURSIVE");                  if(nonRecursive) sb.append(" NON_RECURSIVE");
5000                  sb.append(" '").append(dir).append("'");                  sb.append(" '").append(conv(dir)).append("'");
5001                                    
5002                  if(query.name != null && query.name.length() > 0) {                  if(query.name != null && query.name.length() > 0) {
5003                          sb.append(" NAME='").append(toEscapedString(query.name)).append("'");                          sb.append(" NAME='").append(toEscapedText(query.name)).append("'");
5004                  }                  }
5005                                    
5006                  String s = query.getCreatedAfter();                  String s = query.getCreatedAfter();
# Line 4651  public class Client { Line 5025  public class Client {
5025                                    
5026                  if(query.description != null && query.description.length() > 0) {                  if(query.description != null && query.description.length() > 0) {
5027                          sb.append(" DESCRIPTION='");                          sb.append(" DESCRIPTION='");
5028                          sb.append(toEscapedString(query.description)).append("'");                          sb.append(toEscapedText(query.description)).append("'");
5029                  }                  }
5030                                    
5031                  out.writeLine(sb.toString());                  out.writeLine(sb.toString());
# Line 4704  public class Client { Line 5078  public class Client {
5078                  StringBuffer sb = new StringBuffer();                  StringBuffer sb = new StringBuffer();
5079                  sb.append("FIND DB_INSTRUMENTS");                  sb.append("FIND DB_INSTRUMENTS");
5080                  if(nonRecursive) sb.append(" NON_RECURSIVE");                  if(nonRecursive) sb.append(" NON_RECURSIVE");
5081                  sb.append(" '").append(dir).append("'");                  sb.append(" '").append(conv(dir)).append("'");
5082                                    
5083                  if(query.name != null && query.name.length() > 0) {                  if(query.name != null && query.name.length() > 0) {
5084                          sb.append(" NAME='").append(toEscapedString(query.name)).append("'");                          sb.append(" NAME='").append(toEscapedText(query.name)).append("'");
5085                  }                  }
5086                                    
5087                  if(query.formatFamilies.size() > 0) {                  if(query.formatFamilies.size() > 0) {
# Line 4748  public class Client { Line 5122  public class Client {
5122                                    
5123                  if(query.description != null && query.description.length() > 0) {                  if(query.description != null && query.description.length() > 0) {
5124                          sb.append(" DESCRIPTION='");                          sb.append(" DESCRIPTION='");
5125                          sb.append(toEscapedString(query.description)).append("'");                          sb.append(toEscapedText(query.description)).append("'");
5126                  }                  }
5127                                    
5128                  if(query.instrumentType != DbSearchQuery.InstrumentType.BOTH) {                  if(query.instrumentType != DbSearchQuery.InstrumentType.BOTH) {
# Line 4761  public class Client { Line 5135  public class Client {
5135                  }                  }
5136                                    
5137                  if(query.product != null && query.product.length() > 0) {                  if(query.product != null && query.product.length() > 0) {
5138                          sb.append(" PRODUCT='").append(toEscapedString(query.product)).append("'");                          sb.append(" PRODUCT='").append(toEscapedText(query.product)).append("'");
5139                  }                  }
5140                                    
5141                  if(query.artists != null && query.artists.length() > 0) {                  if(query.artists != null && query.artists.length() > 0) {
5142                          sb.append(" ARTISTS='").append(toEscapedString(query.artists)).append("'");                          sb.append(" ARTISTS='").append(toEscapedText(query.artists)).append("'");
5143                  }                  }
5144                                    
5145                  if(query.keywords != null && query.keywords.length() > 0) {                  if(query.keywords != null && query.keywords.length() > 0) {
5146                          sb.append(" KEYWORDS='");                          sb.append(" KEYWORDS='");
5147                          sb.append(toEscapedString(query.keywords)).append("'");                          sb.append(toEscapedText(query.keywords)).append("'");
5148                  }                  }
5149                                    
5150                  out.writeLine(sb.toString());                  out.writeLine(sb.toString());
# Line 4786  public class Client { Line 5160  public class Client {
5160          }          }
5161                    
5162          /**          /**
5163             * Returns a list of all instrument files in the database
5164             * that that don't exist in the filesystem.
5165             * @throws IOException If some I/O error occurs.
5166             * @throws LscpException If LSCP protocol corruption occurs.
5167             * @throws LSException If other error occurs.
5168             */
5169            public synchronized String[]
5170            findLostDbInstrumentFiles() throws IOException, LscpException, LSException {
5171                    
5172                    verifyConnection();
5173                    out.writeLine("FIND LOST DB_INSTRUMENT_FILES");
5174                    if(getPrintOnlyMode()) return null;
5175                    
5176                    return parseEscapedStringList(getSingleLineResultSet().getResult());
5177            }
5178            
5179            /**
5180           * Gets status information about the specified job.           * Gets status information about the specified job.
5181           * @param jobId The ID of the job.           * @param jobId The ID of the job.
5182           * @return A <code>ScanJobInfo</code> instance providing information           * @return A <code>ScanJobInfo</code> instance providing information
# Line 4807  public class Client { Line 5198  public class Client {
5198          }          }
5199                    
5200          /**          /**
5201           * Resets the specified sampler channel.           * Removes all instruments and directories and re-creates
5202           *           * the instruments database structure.
          * @param samplerChn The sampler channel number.  
          *  
5203           * @throws IOException If some I/O error occurs.           * @throws IOException If some I/O error occurs.
5204           * @throws LscpException If LSCP protocol corruption occurs.           * @throws LscpException If LSCP protocol corruption occurs.
5205           * @throws LSException If <code>samplerChn</code> is not a valid channel number or if           * @throws LSException If the formatting of the instruments database failed.
          * there is no engine assigned yet to the specified sampler channel.  
          * @see #getSamplerChannels  
5206           */           */
5207          public synchronized void          public synchronized void
5208          resetChannel(int samplerChn) throws IOException, LscpException, LSException {          formatInstrumentsDb() throws IOException, LscpException, LSException {
5209                  verifyConnection();                  verifyConnection();
5210                  out.writeLine("RESET CHANNEL " + samplerChn);                  out.writeLine("FORMAT INSTRUMENTS_DB");
5211                  if(getPrintOnlyMode()) return;                  if(getPrintOnlyMode()) return;
5212                                    
5213                  ResultSet rs = getEmptyResultSet();                  ResultSet rs = getEmptyResultSet();
# Line 4843  public class Client { Line 5230  public class Client {
5230          }          }
5231                    
5232          /**          /**
5233             * Gets the current number of all active streams.
5234             * @return The current number of all active streams.
5235             * @throws IOException If some I/O error occurs.
5236             * @throws LscpException If LSCP protocol corruption occurs.
5237             * @throws LSException If some other error occurs.
5238             */
5239            public synchronized int
5240            getTotalStreamCount() throws IOException, LscpException, LSException {
5241                    verifyConnection();
5242                    out.writeLine("GET TOTAL_STREAM_COUNT");
5243                    if(getPrintOnlyMode()) return -1;
5244                    
5245                    String s = getSingleLineResultSet().getResult();
5246                    return parseInt(s);
5247            }
5248            
5249            /**
5250           * Gets the current number of all active voices.           * Gets the current number of all active voices.
5251           * @return The current number of all active voices.           * @return The current number of all active voices.
5252           * @throws IOException If some I/O error occurs.           * @throws IOException If some I/O error occurs.
# Line 4897  public class Client { Line 5301  public class Client {
5301          }          }
5302                    
5303          /**          /**
5304           * Gets the golobal volume of the sampler.           * Gets the global volume of the sampler.
5305           * @return The golobal volume of the sampler.           * @return The global volume of the sampler.
5306           * @throws IOException If some I/O error occurs.           * @throws IOException If some I/O error occurs.
5307           * @throws LscpException If LSCP protocol corruption occurs.           * @throws LscpException If LSCP protocol corruption occurs.
5308           * @throws LSException If some other error occurs.           * @throws LSException If some other error occurs.
# Line 4931  public class Client { Line 5335  public class Client {
5335                  ResultSet rs = getEmptyResultSet();                  ResultSet rs = getEmptyResultSet();
5336          }          }
5337                    
5338            /**
5339             * Gets the global sampler-wide limit of maximum voices.
5340             * @return The global sampler-wide limit of maximum voices.
5341             * @throws IOException If some I/O error occurs.
5342             * @throws LscpException If LSCP protocol corruption occurs.
5343             * @throws LSException If some other error occurs.
5344             */
5345            public synchronized int
5346            getGlobalVoiceLimit() throws IOException, LscpException, LSException {
5347                    verifyConnection();
5348                    out.writeLine("GET VOICES");
5349                    if(getPrintOnlyMode()) return -1;
5350                    
5351                    String s = getSingleLineResultSet().getResult();
5352                    return parseInt(s);
5353            }
5354            
5355            /**
5356             * Sets the global sampler-wide limit of maximum voices.
5357             * @param maxVoices The new global limit of maximum voices.
5358             * @throws IOException If some I/O error occurs.
5359             * @throws LscpException If LSCP protocol corruption occurs.
5360             * @throws LSException If some other error occurs.
5361             * @see #getVolume
5362             */
5363            public synchronized void
5364            setGlobalVoiceLimit(int maxVoices) throws IOException, LscpException, LSException {
5365                    verifyConnection();
5366                    out.writeLine("SET VOICES " + maxVoices);
5367                    if(getPrintOnlyMode()) return;
5368                    
5369                    ResultSet rs = getEmptyResultSet();
5370            }
5371            
5372            /**
5373             * Gets the global sampler-wide limit of maximum disk streams.
5374             * @return The global sampler-wide limit of maximum disk streams.
5375             * @throws IOException If some I/O error occurs.
5376             * @throws LscpException If LSCP protocol corruption occurs.
5377             * @throws LSException If some other error occurs.
5378             */
5379            public synchronized int
5380            getGlobalStreamLimit() throws IOException, LscpException, LSException {
5381                    verifyConnection();
5382                    out.writeLine("GET STREAMS");
5383                    if(getPrintOnlyMode()) return -1;
5384                    
5385                    String s = getSingleLineResultSet().getResult();
5386                    return parseInt(s);
5387            }
5388            
5389            /**
5390             * Sets the global sampler-wide limit for maximum disk streams.
5391             * @param maxVoices The new global limit of maximum disk streams.
5392             * @throws IOException If some I/O error occurs.
5393             * @throws LscpException If LSCP protocol corruption occurs.
5394             * @throws LSException If some other error occurs.
5395             * @see #getVolume
5396             */
5397            public synchronized void
5398            setGlobalStreamLimit(int maxStreams) throws IOException, LscpException, LSException {
5399                    verifyConnection();
5400                    out.writeLine("SET STREAMS " + maxStreams);
5401                    if(getPrintOnlyMode()) return;
5402                    
5403                    ResultSet rs = getEmptyResultSet();
5404            }
5405            
5406            /**
5407             * Gets the number of instruments in the specified instrument file.
5408             * @param filename The absolute path name of the instrument file.
5409             * @return The number of instruments in the specified instrument file.
5410             * @throws IOException If some I/O error occurs.
5411             * @throws LscpException If LSCP protocol corruption occurs.
5412             * @throws LSException If the file is not found, or other error occur.
5413             */
5414            public synchronized int
5415            getFileInstrumentCount(String filename) throws IOException, LscpException, LSException {
5416                    verifyConnection();
5417                    out.writeLine("GET FILE INSTRUMENTS '" + conv(filename) +"'");
5418                    if(getPrintOnlyMode()) return -1;
5419                    
5420                    String s = getSingleLineResultSet().getResult();
5421                    return parseInt(s);
5422            }
5423            
5424            /**
5425             * Gets information about the instrument with index
5426             * <code>instrIdx</code> in the specified instrument file.
5427             * @param filename The absolute path name of the instrument file.
5428             * @param instrIdx The index of the instrument in the specified instrument file.
5429             * @throws IOException If some I/O error occurs.
5430             * @throws LscpException If LSCP protocol corruption occurs.
5431             * @throws LSException If failed to retrieve information.
5432             */
5433            public synchronized Instrument
5434            getFileInstrumentInfo(String filename, int instrIdx)
5435                                    throws IOException, LscpException, LSException {
5436                    
5437                    verifyConnection();
5438                    out.writeLine("GET FILE INSTRUMENT INFO '" + conv(filename) + "' " + String.valueOf(instrIdx));
5439                    if(getPrintOnlyMode()) return null;
5440                    
5441                    ResultSet rs = getMultiLineResultSet();
5442                    Instrument instr = new FileInstrument(rs.getMultiLineResult()) { };
5443                    
5444                    return instr;
5445            }
5446            
5447            /**
5448             * Gets the list of instruments in the specified instrument file.
5449             * @param filename The absolute path name of the instrument file.
5450             * @return An <code>Instrument</code> array providing
5451             * information about all instruments in the specified instrument file.
5452             * @throws IOException If some I/O error occurs.
5453             * @throws LscpException If LSCP protocol corruption occurs.
5454             * @throws LSException If the specified file name is invalid.
5455             */
5456            public synchronized Instrument[]
5457            getFileInstruments(String filename) throws IOException, LscpException, LSException {
5458                    int l = getFileInstrumentCount(filename);
5459                    if(l < 0) return null;
5460                    Instrument[] instrS = new FileInstrument[l];
5461                    
5462                    for(int i = 0; i < instrS.length; i++) {
5463                            instrS[i] = getFileInstrumentInfo(filename, i);
5464                    }
5465                    return instrS;
5466            }
5467            
5468            private static class FileInstrument extends AbstractInstrument {
5469                    FileInstrument(String[] resultSet) throws LscpException {
5470                            super(resultSet);
5471                    }
5472                    
5473                    @Override
5474                    public String
5475                    getEngine() {
5476                            // TODO: engine lookup?
5477                            return getFormatFamily();
5478                    }
5479                    
5480                    @Override
5481                    public boolean
5482                    parse(String s) throws LscpException {
5483                            if(s.startsWith("PRODUCT: ") || s.startsWith("ARTISTS: ")) return true;
5484                            return super.parse(s);
5485                    }
5486            }
5487            
5488          private void          private void
5489          getEmptyResultSets(int count, String err) throws LSException {          getEmptyResultSets(int count, String err) throws LSException {
5490                  StringBuffer sb = new StringBuffer();                  StringBuffer sb = new StringBuffer();

Legend:
Removed from v.1351  
changed lines
  Added in v.1817

  ViewVC Help
Powered by ViewVC