/* * jlscp - a java LinuxSampler control protocol API * * Copyright (C) 2005-2007 Grigor Iliev * * This file is part of jlscp. * * jlscp is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 * as published by the Free Software Foundation. * * jlscp is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with jlscp; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, * MA 02111-1307 USA */ package org.linuxsampler.lscp; import java.io.IOException; import java.io.OutputStream; import java.net.InetSocketAddress; import java.net.Socket; import java.net.SocketTimeoutException; import java.net.UnknownHostException; import java.util.Vector; import java.util.logging.Level; import java.util.logging.Logger; import org.linuxsampler.lscp.event.*; import static org.linuxsampler.lscp.Parser.*; /** * This class is the abstraction representing a client endpoint for communication with LinuxSampler * instance. Since it implements all commands specified in the LSCP protocol v1.1, for more * information look at the * LSCP specification. * *

The following code establishes connection to LinuxSampler instance and gets the * LinuxSampler version: *

 *	try {
 *		Client client = new Client();
 *		client.connect();
 *		
 *		String version = client.getServerInfo().getVersion();
 *		System.out.println(version);
 *		
 *		client.disconnect();
 *	} catch(Exception x) { x.printStackTrace(); }
 * 
*

* *

For more examples look at the examples directory * located in the jlscp distribution.

* * All methods are thread safe. * @author Grigor Iliev */ public class Client { private String address; private int port; private Socket sock = null; private int soTimeout = 20000; private LscpInputStream in = null; private LscpOutputStream out = null; private EventThread eventThread; private boolean printOnlyMode = false; class EventThread extends Thread { private Vector queue = new Vector(); private boolean terminate = false; EventThread() { super("LSCP-Event-Thread"); } public void run() { while(!mustTerminate()) { try { processQueue(); processNotifications(); } catch(Exception x) { getLogger().log(Level.FINE, x.getMessage(), x); } try { synchronized(this) { wait(100); } } catch(Exception x) { getLogger().log(Level.FINE, x.getMessage(), x); } } } private synchronized boolean mustTerminate() { return terminate; } public synchronized void terminate() { terminate = true; this.notifyAll(); } public synchronized void scheduleNotification(String s) { queue.add(s); } private void processQueue() { String[] notifications = popAllNotifications(); for(String n : notifications) fireEvent(n); } private synchronized String[] popAllNotifications() { String[] notifications = queue.toArray(new String[queue.size()]); queue.removeAllElements(); return notifications; } } /** * Creates a new instance of Client with default server address and port. * The default server address and port are 127.0.0.1:8888. */ public Client() { this("127.0.0.1"); } /** * Creates a new instance of Client with the specified address and default port. * The default port is 8888. * @param address The address of linux sampler server. */ public Client(String address) { this(address, 8888); } /** * Creates a new instance of Client with the specified address and port. * @param address The address of the Linux Sampler. * @param port The Linux Sampler port number. */ public Client(String address, int port) { setServerAddress(address); setServerPort(port); eventThread = new EventThread(); } /** * Creates a new instance of Client. * @param printOnlyMode Determines whether the client will be in print-only mode. */ public Client(boolean printOnlyMode) { if(printOnlyMode) setPrintOnlyMode(true); } /** * Determines whether the client is in print-only mode. * Print-only mode means that the client will just print all * LSCP commands to the specified output stream or to the standard output stream * (java.lang.System.out) if no output stream is specified, * without taking any further actions. Thus, in print-only mode all returned * values by Client's methods are meaningless and should be discarded. * @return true if the client is in * print-only mode, false otherwise. * @see #setPrintOnlyModeOutputStream */ public synchronized boolean getPrintOnlyMode() { return printOnlyMode; } /** * Sets the print-only mode. Note that in print-only mode all returned * values by Client's methods are meaningless and should be discarded. * The default output stream in print-only mode is java.lang.System.out. * @param b If true all LSCP commands will be sent * to the specified output stream or to the standard output stream * (java.lang.System.out) if no output stream is specified, * and no further actions will be taken. * @throws IllegalStateException If the client is connected. * @see #setPrintOnlyModeOutputStream */ public synchronized void setPrintOnlyMode(boolean b) { if(printOnlyMode == b) return; if(isConnected()) throw new IllegalStateException(); printOnlyMode = b; if(b) out = new LscpOutputStream(System.out); } /** * Sets the output stream to be used in print-only mode. * @param out The output stream to be used in print-only mode. * @throws IllegalStateException If the client is not in print-only mode. * @throws IllegalArgumentException if out is null. * @see #setPrintOnlyMode */ public synchronized void setPrintOnlyModeOutputStream(OutputStream out) { if(!getPrintOnlyMode()) throw new IllegalStateException("Not in print-only mode"); if(out == null) throw new IllegalArgumentException("out must be non-null"); this.out = new LscpOutputStream(out); } /** * Specifies the jlscp version. * @return The jlscp version. */ public static String getClientVersion() { return Package.getPackage("org.linuxsampler.lscp").getImplementationVersion(); } /** * Gets the Linux Sampler address. * @return The Linux Sampler address. */ public synchronized String getServerAddress() { return address; } /** * Sets the Linux Sampler address. * @param address The Linux Sampler address. * If address is null sets to default address - 127.0.0.1. */ public synchronized void setServerAddress(String address) { this.address = (address == null ? "127.0.0.1" : address); } /** * Gets the Linux Sampler port number. * @return The Linux Sampler port number. */ public synchronized int getServerPort() { return port; } /** * Sets the Linux Sampler port number. * @param port The Linux Sampler port number. */ public synchronized void setServerPort(int port) { this.port = port; } /** * Connects to the LinuxSampler. If there is already established connection then * the currently available connection is closed berfore connecting. * @throws LscpException If timeout occurs or any other I/O exception. */ public synchronized void connect() throws LscpException { if(sock != null) disconnect(); if(getPrintOnlyMode()) return; // Initializing LSCP event thread if(eventThread.isAlive()) { getLogger().warning("LSCP event thread already running!"); eventThread.terminate(); } if(eventThread.getState() != Thread.State.NEW) eventThread = new EventThread(); /////// InetSocketAddress sockAddr = null; try { sockAddr = new InetSocketAddress(address, port); } catch(IllegalArgumentException x) { String s = String.valueOf(port); throw new LscpException(LscpI18n.getLogMsg("Client.invalidPort!", s), x); } if(sockAddr.isUnresolved()) throw new LscpException ( LscpI18n.getLogMsg("Client.unknownHost!", address) ); try { sock = new Socket(); sock.bind(null); sock.connect(sockAddr, soTimeout); sock.setSoTimeout(soTimeout); sock.setTcpNoDelay(true); in = new LscpInputStream(sock.getInputStream()); out = new LscpOutputStream(sock.getOutputStream()); } catch(SocketTimeoutException x) { throw new LscpException(LscpI18n.getLogMsg("Client.conTimeout!"), x); } catch(Exception x) { throw new LscpException ( LscpI18n.getLogMsg("Client.connectionFailed!"), x ); } String s = Package.getPackage("org.linuxsampler.lscp").getSpecificationVersion(); String s2, sv, sv2; try { s2 = s.substring(0, s.indexOf('.')); sv = getServerInfo().getProtocolVersion(); sv2 = sv.substring(0, sv.indexOf('.')); } catch(Exception x) { disconnect(); throw new LscpException ( LscpI18n.getLogMsg("Client.connectionFailed!"), x ); } if(!sv2.equals(s2)) { disconnect(); throw new LscpException ( LscpI18n.getLogMsg("Client.incompatibleLscpVersion!", sv) ); } s2 = s.substring(s.indexOf('.')); sv2 = sv.substring(sv.indexOf('.')); if(sv2.compareToIgnoreCase(s2) < 0) getLogger().info ( LscpI18n.getLogMsg("Client.incompatibleLscpMinVersion!", sv) ); if(hasSubscriptions()) eventThread.start(); if(!llM.isEmpty()) subscribe("MISCELLANEOUS"); if(!llAODC.isEmpty()) subscribe("AUDIO_OUTPUT_DEVICE_COUNT"); if(!llAODI.isEmpty()) subscribe("AUDIO_OUTPUT_DEVICE_INFO"); if(!llMIDC.isEmpty()) subscribe("MIDI_INPUT_DEVICE_COUNT"); if(!llMIDI.isEmpty()) subscribe("MIDI_INPUT_DEVICE_INFO"); if(!llBF.isEmpty()) subscribe("BUFFER_FILL"); if(!llCC.isEmpty()) subscribe("CHANNEL_COUNT"); if(!llCI.isEmpty()) subscribe("CHANNEL_INFO"); if(!llFSC.isEmpty()) subscribe("FX_SEND_COUNT"); if(!llFSI.isEmpty()) subscribe("FX_SEND_INFO"); if(!llSC.isEmpty()) subscribe("STREAM_COUNT"); if(!llVC.isEmpty()) subscribe("VOICE_COUNT"); if(!llTVC.isEmpty()) subscribe("TOTAL_VOICE_COUNT"); if(!llMIMC.isEmpty()) subscribe("MIDI_INSTRUMENT_MAP_COUNT"); if(!llMIMI.isEmpty()) subscribe("MIDI_INSTRUMENT_MAP_INFO"); if(!llMIC.isEmpty()) subscribe("MIDI_INSTRUMENT_COUNT"); if(!llMII.isEmpty()) subscribe("MIDI_INSTRUMENT_INFO"); if(!llID.isEmpty()) { subscribe("DB_INSTRUMENT_DIRECTORY_COUNT"); subscribe("DB_INSTRUMENT_DIRECTORY_INFO"); subscribe("DB_INSTRUMENT_COUNT"); subscribe("DB_INSTRUMENT_INFO"); } if(!llGI.isEmpty()) subscribe("GLOBAL_INFO"); } /** * Closes the connection to LinuxSampler. */ public synchronized void disconnect() { if(getPrintOnlyMode()) return; try { if(sock != null) sock.close(); } catch(Exception x) { getLogger().log(Level.FINE, x.getMessage(), x); } sock = null; if(eventThread.getState() != Thread.State.NEW) { eventThread.terminate(); eventThread = new EventThread(); } } /** * Determines whether the client is connected. * @return true if there is established connection, * false otherwise. */ public synchronized boolean isConnected() { if(sock == null) return false; else return sock.isConnected(); } /** * Verifies that there is established connection. * @throws IOException If the connection is not established. */ private void verifyConnection() throws IOException { if(getPrintOnlyMode()) return; if(!isConnected()) throw new IOException(LscpI18n.getLogMsg("Client.notConnected!")); } private String getLine() throws IOException, LscpException { String s; for(;;) { s = in.readLine(); if(s.startsWith("NOTIFY:")) { eventThread.scheduleNotification(s.substring("NOTIFY:".length())); } else break; } return s; } /** Processes the notifications sent by LinuxSampler */ private synchronized void processNotifications() throws IOException, LscpException { while(in.available() > 0) { String s = in.readLine(); if(s.startsWith("NOTIFY:")) fireEvent(s.substring("NOTIFY:".length())); else getLogger().severe("Unknown notification format: " + s); } } /** * Gets empty result set. * @return ResultSet instance. */ private ResultSet getEmptyResultSet() throws IOException, LscpException, LSException { return parseEmptyResultSet(getLine()); } private ResultSet getSingleLineResultSet() throws IOException, LscpException, LSException { ResultSet rs = new ResultSet(); String ln = getLine(); if(ln.startsWith("WRN")) { parseWarning(ln, rs); getLogger().warning(rs.getMessage()); return rs; } else if(ln.startsWith("ERR")) { parseError(ln, rs); throw new LSException(rs.getCode(), rs.getMessage()); } else { rs.setResult(ln); return rs; } } private ResultSet getMultiLineResultSet() throws IOException, LscpException, LSException { ResultSet rs = new ResultSet(); String ln = getLine(); if(ln.startsWith("WRN")) { parseWarning(ln, rs); getLogger().warning(rs.getMessage()); return rs; } else if(ln.startsWith("ERR")) { parseError(ln, rs); throw new LSException(rs.getCode(), rs.getMessage()); } while(!ln.equals(".")) { rs.addLine(ln); ln = getLine(); } return rs; } /** Audio output device count listeners */ private final Vector llAODC = new Vector(); /** Audio output device info listeners */ private final Vector llAODI = new Vector(); private final Vector llBF = new Vector(); private final Vector llCC = new Vector(); private final Vector llCI = new Vector(); private final Vector llFSC = new Vector(); private final Vector llFSI = new Vector(); private final Vector llM = new Vector(); /** MIDI input device count listeners */ private final Vector llMIDC = new Vector(); /** MIDI input device info listeners */ private final Vector llMIDI = new Vector(); private final Vector llSC = new Vector(); private final Vector llVC = new Vector(); private final Vector llTVC = new Vector(); /** MIDI instrument map count listeners */ private final Vector llMIMC = new Vector(); /** MIDI instrument map info listeners */ private final Vector llMIMI = new Vector(); /** MIDI instrument count listeners */ private final Vector llMIC = new Vector(); /** MIDI instrument info listeners */ private final Vector llMII = new Vector(); private final Vector llID = new Vector(); private final Vector llGI = new Vector(); /** * Determines whether there is at least one subscription for notification events. * Do not forget to check for additional listeners if the LSCP specification * is extended in the future. * @return true if there is at least one subscription for notification events, * false otherwise. */ private boolean hasSubscriptions() { return !llAODC.isEmpty() || !llAODI.isEmpty() || !llBF.isEmpty() || !llCC.isEmpty() || !llCI.isEmpty() || !llFSC.isEmpty() || !llFSI.isEmpty() || !llM.isEmpty() || !llMIDC.isEmpty() || !llMIDI.isEmpty() || !llSC.isEmpty() || !llVC.isEmpty() || !llTVC.isEmpty() || !llMIMC.isEmpty() || !llMIMI.isEmpty() || !llMIC.isEmpty() || !llMII.isEmpty() || !llID.isEmpty() || !llGI.isEmpty(); } private synchronized void fireEvent(String s) { if(s.startsWith("DB_INSTRUMENT_DIRECTORY_COUNT:")) { s = s.substring("DB_INSTRUMENT_DIRECTORY_COUNT:".length()); InstrumentsDbEvent e = new InstrumentsDbEvent(this, s); for(InstrumentsDbListener l : llID) l.directoryCountChanged(e); } else if(s.startsWith("DB_INSTRUMENT_DIRECTORY_INFO:")) { InstrumentsDbEvent e; s = s.substring("DB_INSTRUMENT_DIRECTORY_INFO:".length()); if(s.startsWith("NAME ")) { String[] list; try { s = s.substring("NAME ".length()); list = parseEscapedStringList(s, ' '); if(list.length != 2) throw new LscpException(); list[1] = toNonEscapedString(list[1]); e = new InstrumentsDbEvent(this, list[0], list[1]); for(InstrumentsDbListener l : llID) { l.directoryNameChanged(e); } } catch(LscpException x) { getLogger().log ( Level.WARNING, LscpI18n.getLogMsg("CommandFailed!"), x ); } } else { e = new InstrumentsDbEvent(this, s); for(InstrumentsDbListener l : llID) l.directoryInfoChanged(e); } } else if(s.startsWith("DB_INSTRUMENT_COUNT:")) { s = s.substring("DB_INSTRUMENT_COUNT:".length()); InstrumentsDbEvent e = new InstrumentsDbEvent(this, s); for(InstrumentsDbListener l : llID) l.instrumentCountChanged(e); } else if(s.startsWith("DB_INSTRUMENT_INFO:")) { InstrumentsDbEvent e; s = s.substring("DB_INSTRUMENT_INFO:".length()); if(s.startsWith("NAME ")) { String[] list; try { s = s.substring("NAME ".length()); list = parseEscapedStringList(s, ' '); if(list.length != 2) throw new LscpException(); list[1] = toNonEscapedString(list[1]); e = new InstrumentsDbEvent(this, list[0], list[1]); for(InstrumentsDbListener l : llID) { l.instrumentNameChanged(e); } } catch(LscpException x) { getLogger().log ( Level.WARNING, LscpI18n.getLogMsg("CommandFailed!"), x ); } } else { e = new InstrumentsDbEvent(this, s); for(InstrumentsDbListener l : llID) l.instrumentInfoChanged(e); } } else if(s.startsWith("DB_INSTRUMENTS_JOB_INFO:")) { s = s.substring("DB_INSTRUMENTS_JOB_INFO:".length()); try { int i = Integer.parseInt(s); InstrumentsDbEvent e = new InstrumentsDbEvent(this, i); for(InstrumentsDbListener l : llID) l.jobStatusChanged(e); } catch(NumberFormatException x) { s = "Unknown DB_INSTRUMENTS_JOB_INFO format"; getLogger().log(Level.WARNING, s, x); } } else if(s.startsWith("CHANNEL_COUNT:")) { try { int i = Integer.parseInt(s.substring("CHANNEL_COUNT:".length())); ChannelCountEvent e = new ChannelCountEvent(this, i); for(ChannelCountListener l : llCC) l.channelCountChanged(e); } catch(NumberFormatException x) { getLogger().log ( Level.WARNING, LscpI18n.getLogMsg("CommandFailed!"), x ); } } else if(s.startsWith("VOICE_COUNT:")) { try { s = s.substring("VOICE_COUNT:".length()); Integer[] i = parseIntList(s, ' '); if(i.length != 2) { getLogger().warning("Unknown VOICE_COUNT format"); return; } VoiceCountEvent e = new VoiceCountEvent(this, i[0], i[1]); for(VoiceCountListener l : llVC) l.voiceCountChanged(e); } catch(Exception x) { getLogger().log(Level.WARNING, "Unknown VOICE_COUNT format", x); } } else if(s.startsWith("STREAM_COUNT:")) { try { s = s.substring("STREAM_COUNT:".length()); Integer[] i = parseIntList(s, ' '); if(i.length != 2) { getLogger().warning("Unknown STREAM_COUNT format"); return; } StreamCountEvent e = new StreamCountEvent(this, i[0], i[1]); for(StreamCountListener l : llSC) l.streamCountChanged(e); } catch(Exception x) { getLogger().log(Level.WARNING, "Unknown STREAM_COUNT format", x); } } else if(s.startsWith("BUFFER_FILL:")) { try { s = s.substring("BUFFER_FILL:".length()); int i = s.indexOf(' '); if(i == -1) { getLogger().warning("Unknown BUFFER_FILL format"); return; } int j = Integer.parseInt(s.substring(0, i)); Vector v = getChannelBufferFillPercentage(s.substring(i + 1)); BufferFillEvent e = new BufferFillEvent(this, j, v); for(BufferFillListener l : llBF) l.bufferFillChanged(e); } catch(Exception x) { getLogger().log(Level.WARNING, "Unknown BUFFER_FILL format", x); } } else if(s.startsWith("CHANNEL_INFO:")) { try { int i = Integer.parseInt(s.substring("CHANNEL_INFO:".length())); ChannelInfoEvent e = new ChannelInfoEvent(this, i); for(ChannelInfoListener l : llCI) l.channelInfoChanged(e); } catch(NumberFormatException x) { getLogger().log(Level.WARNING, "Unknown CHANNEL_INFO format", x); } } else if(s.startsWith("TOTAL_VOICE_COUNT:")) { try { s = s.substring("TOTAL_VOICE_COUNT:".length()); int i = Integer.parseInt(s); TotalVoiceCountEvent e = new TotalVoiceCountEvent(this, i); for(TotalVoiceCountListener l : llTVC) l.totalVoiceCountChanged(e); } catch(NumberFormatException x) { getLogger().log ( Level.WARNING, "Unknown TOTAL_VOICE_COUNT format", x ); } } else if(s.startsWith("AUDIO_OUTPUT_DEVICE_COUNT:")) { try { s = s.substring("AUDIO_OUTPUT_DEVICE_COUNT:".length()); int i = Integer.parseInt(s); ItemCountEvent e = new ItemCountEvent(this, i); for(ItemCountListener l : llAODC) l.itemCountChanged(e); } catch(NumberFormatException x) { getLogger().log ( Level.WARNING, "Unknown AUDIO_OUTPUT_DEVICE_COUNT format", x ); } } else if(s.startsWith("AUDIO_OUTPUT_DEVICE_INFO:")) { try { s = s.substring("AUDIO_OUTPUT_DEVICE_INFO:".length()); int i = Integer.parseInt(s); ItemInfoEvent e = new ItemInfoEvent(this, i); for(ItemInfoListener l : llAODI) l.itemInfoChanged(e); } catch(NumberFormatException x) { getLogger().log ( Level.WARNING, "Unknown AUDIO_OUTPUT_DEVICE_INFO format", x ); } } else if(s.startsWith("MIDI_INPUT_DEVICE_COUNT:")) { try { s = s.substring("MIDI_INPUT_DEVICE_COUNT:".length()); int i = Integer.parseInt(s); ItemCountEvent e = new ItemCountEvent(this, i); for(ItemCountListener l : llMIDC) l.itemCountChanged(e); } catch(NumberFormatException x) { getLogger().log ( Level.WARNING, "Unknown MIDI_INPUT_DEVICE_COUNT format", x ); } } else if(s.startsWith("MIDI_INPUT_DEVICE_INFO:")) { try { s = s.substring("MIDI_INPUT_DEVICE_INFO:".length()); int i = Integer.parseInt(s); ItemInfoEvent e = new ItemInfoEvent(this, i); for(ItemInfoListener l : llMIDI) l.itemInfoChanged(e); } catch(NumberFormatException x) { getLogger().log ( Level.WARNING, "Unknown MIDI_INPUT_DEVICE_INFO format", x ); } } else if(s.startsWith("MIDI_INSTRUMENT_MAP_COUNT:")) { try { s = s.substring("MIDI_INSTRUMENT_MAP_COUNT:".length()); int i = Integer.parseInt(s); ItemCountEvent e = new ItemCountEvent(this, i); for(ItemCountListener l : llMIMC) l.itemCountChanged(e); } catch(NumberFormatException x) { getLogger().log ( Level.WARNING, "Unknown MIDI_INSTRUMENT_MAP_COUNT format", x ); } } else if(s.startsWith("MIDI_INSTRUMENT_MAP_INFO:")) { try { s = s.substring("MIDI_INSTRUMENT_MAP_INFO:".length()); int i = Integer.parseInt(s); ItemInfoEvent e = new ItemInfoEvent(this, i); for(ItemInfoListener l : llMIMI) l.itemInfoChanged(e); } catch(NumberFormatException x) { getLogger().log ( Level.WARNING, "Unknown MIDI_INSTRUMENT_MAP_INFO format", x ); } } else if(s.startsWith("MIDI_INSTRUMENT_COUNT:")) { try { s = s.substring("MIDI_INSTRUMENT_COUNT:".length()); Integer[] i = parseIntList(s, ' '); if(i.length != 2) { getLogger().warning("Unknown MIDI_INSTRUMENT_COUNT format"); return; } MidiInstrumentCountEvent e = new MidiInstrumentCountEvent(this, i[0], i[1]); for(MidiInstrumentCountListener l : llMIC) { l.instrumentCountChanged(e); } } catch(Exception x) { getLogger().log ( Level.WARNING, "Unknown MIDI_INSTRUMENT_COUNT format", x ); } } else if(s.startsWith("MIDI_INSTRUMENT_INFO:")) { try { s = s.substring("MIDI_INSTRUMENT_INFO:".length()); Integer[] i = parseIntList(s, ' '); if(i.length != 3) { getLogger().warning("Unknown MIDI_INSTRUMENT_INFO format"); return; } MidiInstrumentInfoEvent e = new MidiInstrumentInfoEvent(this, i[0], i[1], i[2]); for(MidiInstrumentInfoListener l : llMII) { l.instrumentInfoChanged(e); } } catch(Exception x) { getLogger().log ( Level.WARNING, "Unknown MIDI_INSTRUMENT_INFO format", x ); } } else if(s.startsWith("FX_SEND_COUNT:")) { try { s = s.substring("FX_SEND_COUNT:".length()); Integer[] i = parseIntList(s, ' '); if(i.length != 2) { getLogger().warning("Unknown FX_SEND_COUNT format"); return; } FxSendCountEvent e = new FxSendCountEvent(this, i[0], i[1]); for(FxSendCountListener l : llFSC) l.fxSendCountChanged(e); } catch(Exception x) { getLogger().log(Level.WARNING, "Unknown FX_SEND_COUNT format", x); } } else if(s.startsWith("FX_SEND_INFO:")) { try { s = s.substring("FX_SEND_INFO:".length()); Integer[] i = parseIntList(s, ' '); if(i.length != 2) { getLogger().warning("Unknown FX_SEND_INFO format"); return; } FxSendInfoEvent e = new FxSendInfoEvent(this, i[0], i[1]); for(FxSendInfoListener l : llFSI) { l.fxSendInfoChanged(e); } } catch(Exception x) { getLogger().log(Level.WARNING, "Unknown FX_SEND_INFO format", x); } } else if(s.startsWith("GLOBAL_INFO:")) { handleGlobalInfoEvent(s.substring("GLOBAL_INFO:".length())); } else if(s.startsWith("MISCELLANEOUS:")) { s = s.substring("MISCELLANEOUS:".length()); MiscellaneousEvent e = new MiscellaneousEvent(this, s); for(MiscellaneousListener l : llM) l.miscEventOccured(e); } } private void handleGlobalInfoEvent(String s) { try { if(s.startsWith("VOLUME ")) { float f = Float.parseFloat(s.substring("VOLUME ".length())); GlobalInfoEvent e = new GlobalInfoEvent(this, f); for(GlobalInfoListener l : llGI) l.volumeChanged(e); } } catch(NumberFormatException x) { getLogger().log(Level.WARNING, "Unknown GLOBAL_INFO format", x); } } private void subscribe(String event) { if(!getPrintOnlyMode()) { if(!isConnected()) return; if(!eventThread.isAlive()) eventThread.start(); } try { out.writeLine("SUBSCRIBE " + event); if(!getPrintOnlyMode()) getEmptyResultSet(); } catch(Exception x) { getLogger().log ( Level.WARNING, LscpI18n.getLogMsg("Client.subscriptionFailed!", event), x ); } } private void unsubscribe(String event) { if(!getPrintOnlyMode() && !isConnected()) return; try { out.writeLine("UNSUBSCRIBE " + event); if(!getPrintOnlyMode()) getEmptyResultSet(); } catch(Exception x) { getLogger().log ( Level.WARNING, LscpI18n.getLogMsg("Client.unsubscriptionFailed!", event), x ); } } /** * Registers the specified listener for receiving event messages. * Listeners can be registered regardless of the connection state. * @param l The ItemCountListener to register. */ public synchronized void addAudioDeviceCountListener(ItemCountListener l) { if(llAODC.isEmpty()) subscribe("AUDIO_OUTPUT_DEVICE_COUNT"); llAODC.add(l); } /** * Removes the specified listener. * Listeners can be removed regardless of the connection state. * @param l The ItemCountListener to remove. */ public synchronized void removeAudioDeviceCountListener(ItemCountListener l) { boolean b = llAODC.remove(l); if(b && llAODC.isEmpty()) unsubscribe("AUDIO_OUTPUT_DEVICE_COUNT"); } /** * Registers the specified listener for receiving event messages. * Listeners can be registered regardless of the connection state. * @param l The ItemInfoListener to register. */ public synchronized void addAudioDeviceInfoListener(ItemInfoListener l) { if(llAODI.isEmpty()) subscribe("AUDIO_OUTPUT_DEVICE_INFO"); llAODI.add(l); } /** * Removes the specified listener. * Listeners can be removed regardless of the connection state. * @param l The ItemInfoListener to remove. */ public synchronized void removeAudioDeviceInfoListener(ItemInfoListener l) { boolean b = llAODI.remove(l); if(b && llAODI.isEmpty()) unsubscribe("AUDIO_OUTPUT_DEVICE_INFO"); } /** * Registers the specified listener for receiving event messages. * Listeners can be removed regardless of the connection state. * @param l The BufferFillListener to register. */ public synchronized void addBufferFillListener(BufferFillListener l) { if(llBF.isEmpty()) subscribe("BUFFER_FILL"); llBF.add(l); } /** * Removes the specified listener. * Listeners can be removed regardless of the connection state. * @param l The BufferFillListener to remove. */ public synchronized void removeBufferFillListener(BufferFillListener l) { boolean b = llBF.remove(l); if(b && llBF.isEmpty()) unsubscribe("BUFFER_FILL"); } /** * Registers the specified listener for receiving event messages. * Listeners can be registered regardless of the connection state. * @param l The ChannelCountListener to register. */ public synchronized void addChannelCountListener(ChannelCountListener l) { if(llCC.isEmpty()) subscribe("CHANNEL_COUNT"); llCC.add(l); } /** * Removes the specified listener. * Listeners can be removed regardless of the connection state. * @param l The ChannelCountListener to remove. */ public synchronized void removeChannelCountListener(ChannelCountListener l) { boolean b = llCC.remove(l); if(b && llCC.isEmpty()) unsubscribe("CHANNEL_COUNT"); } /** * Registers the specified listener for receiving event messages. * Listeners can be registered regardless of the connection state. * @param l The ChannelInfoListener to register. */ public synchronized void addChannelInfoListener(ChannelInfoListener l) { if(llCI.isEmpty()) subscribe("CHANNEL_INFO"); llCI.add(l); } /** * Removes the specified listener. * Listeners can be removed regardless of the connection state. * @param l The ChannelInfoListener to remove. */ public synchronized void removeChannelInfoListener(ChannelInfoListener l) { boolean b = llCI.remove(l); if(b && llCI.isEmpty()) unsubscribe("CHANNEL_INFO"); } /** * Registers the specified listener for receiving event messages. * Listeners can be registered regardless of the connection state. * @param l The FxSendCountListener to register. */ public synchronized void addFxSendCountListener(FxSendCountListener l) { if(llFSC.isEmpty()) subscribe("FX_SEND_COUNT"); llFSC.add(l); } /** * Removes the specified listener. * Listeners can be removed regardless of the connection state. * @param l The FxSendCountListener to remove. */ public synchronized void removeFxSendCountListener(FxSendCountListener l) { boolean b = llFSC.remove(l); if(b && llFSC.isEmpty()) unsubscribe("FX_SEND_COUNT"); } /** * Registers the specified listener for receiving event messages. * Listeners can be registered regardless of the connection state. * @param l The FxSendInfoListener to register. */ public synchronized void addFxSendInfoListener(FxSendInfoListener l) { if(llFSI.isEmpty()) subscribe("FX_SEND_INFO"); llFSI.add(l); } /** * Removes the specified listener. * Listeners can be removed regardless of the connection state. * @param l The FxSendInfoListener to remove. */ public synchronized void removeFxSendInfoListener(FxSendInfoListener l) { boolean b = llFSI.remove(l); if(b && llFSI.isEmpty()) unsubscribe("FX_SEND_INFO"); } /** * Registers the specified listener for receiving event messages. * Listeners can be registered regardless of the connection state. * @param l The ItemCountListener to register. */ public synchronized void addMidiDeviceCountListener(ItemCountListener l) { if(llMIDC.isEmpty()) subscribe("MIDI_INPUT_DEVICE_COUNT"); llMIDC.add(l); } /** * Removes the specified listener. * Listeners can be removed regardless of the connection state. * @param l The ItemCountListener to remove. */ public synchronized void removeMidiDeviceCountListener(ItemCountListener l) { boolean b = llMIDC.remove(l); if(b && llMIDC.isEmpty()) unsubscribe("MIDI_INPUT_DEVICE_COUNT"); } /** * Registers the specified listener for receiving event messages. * Listeners can be registered regardless of the connection state. * @param l The ItemInfoListener to register. */ public synchronized void addMidiDeviceInfoListener(ItemInfoListener l) { if(llMIDI.isEmpty()) subscribe("MIDI_INPUT_DEVICE_INFO"); llMIDI.add(l); } /** * Removes the specified listener. * Listeners can be removed regardless of the connection state. * @param l The ItemInfoListener to remove. */ public synchronized void removeMidiDeviceInfoListener(ItemInfoListener l) { boolean b = llMIDI.remove(l); if(b && llMIDI.isEmpty()) unsubscribe("MIDI_INPUT_DEVICE_INFO"); } /** * Registers the specified listener for receiving event messages. * Listeners can be registered regardless of the connection state. * @param l The MiscellaneousListener to register. */ public synchronized void addMiscellaneousListener(MiscellaneousListener l) { if(llM.isEmpty()) subscribe("MISCELLANEOUS"); llM.add(l); } /** * Removes the specified listener. * Listeners can be removed regardless of the connection state. * @param l The MiscellaneousListener to remove. */ public synchronized void removeMiscellaneousListener(MiscellaneousListener l) { boolean b = llM.remove(l); if(b && llM.isEmpty()) unsubscribe("MISCELLANEOUS"); } /** * Registers the specified listener for receiving event messages. * Listeners can be registered regardless of the connection state. * @param l The StreamCountListener to register. */ public synchronized void addStreamCountListener(StreamCountListener l) { if(llSC.isEmpty()) subscribe("STREAM_COUNT"); llSC.add(l); } /** * Removes the specified listener. * Listeners can be removed regardless of the connection state. * @param l The StreamCountListener to remove. */ public synchronized void removeStreamCountListener(StreamCountListener l) { boolean b = llSC.remove(l); if(b && llSC.isEmpty()) unsubscribe("STREAM_COUNT"); } /** * Registers the specified listener for receiving event messages. * Listeners can be registered regardless of the connection state. * @param l The VoiceCountListener to register. */ public synchronized void addVoiceCountListener(VoiceCountListener l) { if(llVC.isEmpty()) subscribe("VOICE_COUNT"); llVC.add(l); } /** * Removes the specified listener. * Listeners can be removed regardless of the connection state. * @param l The VoiceCountListener to remove. */ public synchronized void removeVoiceCountListener(VoiceCountListener l) { boolean b = llVC.remove(l); if(b && llVC.isEmpty()) unsubscribe("VOICE_COUNT"); } /** * Registers the specified listener for receiving event messages. * Listeners can be registered regardless of the connection state. * @param l The TotalVoiceCountListener to register. */ public synchronized void addTotalVoiceCountListener(TotalVoiceCountListener l) { if(llTVC.isEmpty()) subscribe("TOTAL_VOICE_COUNT"); llTVC.add(l); } /** * Removes the specified listener. * Listeners can be removed regardless of the connection state. * @param l The TotalVoiceCountListener to remove. */ public synchronized void removeTotalVoiceCountListener(TotalVoiceCountListener l) { boolean b = llTVC.remove(l); if(b && llTVC.isEmpty()) unsubscribe("TOTAL_VOICE_COUNT"); } /** * Registers the specified listener for receiving event messages. * Listeners can be registered regardless of the connection state. * @param l The ItemCountListener to register. */ public synchronized void addMidiInstrumentMapCountListener(ItemCountListener l) { if(llMIMC.isEmpty()) subscribe("MIDI_INSTRUMENT_MAP_COUNT"); llMIMC.add(l); } /** * Removes the specified listener. * Listeners can be removed regardless of the connection state. * @param l The ItemCountListener to remove. */ public synchronized void removeMidiInstrumentMapCountListener(ItemCountListener l) { boolean b = llMIMC.remove(l); if(b && llMIMC.isEmpty()) unsubscribe("MIDI_INSTRUMENT_MAP_COUNT"); } /** * Registers the specified listener for receiving event messages. * Listeners can be registered regardless of the connection state. * @param l The ItemInfoListener to register. */ public synchronized void addMidiInstrumentMapInfoListener(ItemInfoListener l) { if(llMIMI.isEmpty()) subscribe("MIDI_INSTRUMENT_MAP_INFO"); llMIMI.add(l); } /** * Removes the specified listener. * Listeners can be removed regardless of the connection state. * @param l The ItemInfoListener to remove. */ public synchronized void removeMidiInstrumentMapInfoListener(ItemInfoListener l) { boolean b = llMIMI.remove(l); if(b && llMIMI.isEmpty()) unsubscribe("MIDI_INSTRUMENT_MAP_INFO"); } /** * Registers the specified listener for receiving event messages. * Listeners can be registered regardless of the connection state. * @param l The MidiInstrumentCountListener to register. */ public synchronized void addMidiInstrumentCountListener(MidiInstrumentCountListener l) { if(llMIC.isEmpty()) subscribe("MIDI_INSTRUMENT_COUNT"); llMIC.add(l); } /** * Removes the specified listener. * Listeners can be removed regardless of the connection state. * @param l The MidiInstrumentCountListener to remove. */ public synchronized void removeMidiInstrumentCountListener(MidiInstrumentCountListener l) { boolean b = llMIC.remove(l); if(b && llMIC.isEmpty()) unsubscribe("MIDI_INSTRUMENT_COUNT"); } /** * Registers the specified listener for receiving event messages. * Listeners can be registered regardless of the connection state. * @param l The MidiInstrumentInfoListener to register. */ public synchronized void addMidiInstrumentInfoListener(MidiInstrumentInfoListener l) { if(llMII.isEmpty()) subscribe("MIDI_INSTRUMENT_INFO"); llMII.add(l); } /** * Removes the specified listener. * Listeners can be removed regardless of the connection state. * @param l The MidiInstrumentInfoListener to remove. */ public synchronized void removeMidiInstrumentInfoListener(MidiInstrumentInfoListener l) { boolean b = llMII.remove(l); if(b && llMII.isEmpty()) unsubscribe("MIDI_INSTRUMENT_INFO"); } /** * Registers the specified listener for receiving event messages. * Listeners can be registered regardless of the connection state. * @param l The InstrumentsDbListener to register. */ public synchronized void addInstrumentsDbListener(InstrumentsDbListener l) { if(llID.isEmpty()) { subscribe("DB_INSTRUMENT_DIRECTORY_COUNT"); subscribe("DB_INSTRUMENT_DIRECTORY_INFO"); subscribe("DB_INSTRUMENT_COUNT"); subscribe("DB_INSTRUMENT_INFO"); subscribe("DB_INSTRUMENTS_JOB_INFO"); } llID.add(l); } /** * Removes the specified listener. * Listeners can be removed regardless of the connection state. * @param l The InstrumentsDbListener to remove. */ public synchronized void removeInstrumentsDbListener(InstrumentsDbListener l) { boolean b = llID.remove(l); if(b && llID.isEmpty()) { unsubscribe("DB_INSTRUMENT_DIRECTORY_COUNT"); unsubscribe("DB_INSTRUMENT_DIRECTORY_INFO"); unsubscribe("DB_INSTRUMENT_COUNT"); unsubscribe("DB_INSTRUMENT_INFO"); unsubscribe("DB_INSTRUMENTS_JOB_INFO"); } } /** * Registers the specified listener for receiving event messages. * Listeners can be registered regardless of the connection state. * @param l The GlobalInfoListener to register. */ public synchronized void addGlobalInfoListener(GlobalInfoListener l) { if(llGI.isEmpty()) subscribe("GLOBAL_INFO"); llGI.add(l); } /** * Removes the specified listener. * Listeners can be removed regardless of the connection state. * @param l The GlobalInfoListener to remove. */ public synchronized void removeGlobalInfoListener(GlobalInfoListener l) { boolean b = llGI.remove(l); if(b && llGI.isEmpty()) unsubscribe("GLOBAL_INFO"); } /** * Gets the number of all audio output drivers currently * available for the LinuxSampler instance. * @return The number of all audio output drivers currently * available for the LinuxSampler instance. * @throws IOException If some I/O error occurs. * @throws LscpException If LSCP protocol corruption occurs. * @throws LSException If some other error occurs. */ public synchronized int getAudioOutputDriverCount() throws IOException, LscpException, LSException { verifyConnection(); out.writeLine("GET AVAILABLE_AUDIO_OUTPUT_DRIVERS"); if(getPrintOnlyMode()) return -1; String s = getSingleLineResultSet().getResult(); return parseInt(s); } /** * Gets all audio output drivers currently available for the LinuxSampler instance. * * @return AudioOutputDriver array containing all audio output drivers * currently available for the LinuxSampler instance. * * @throws IOException If an I/O error occurs. * @throws LscpException If LSCP protocol corruption occurs. * @throws LSException If some other error occurs. */ public synchronized AudioOutputDriver[] getAudioOutputDrivers() throws IOException, LscpException, LSException { String[] drivers = getAudioOutputDriverNames(); if(getPrintOnlyMode()) return null; AudioOutputDriver[] aod = new AudioOutputDriver[drivers.length]; for(int i = 0; i < aod.length; i++) aod[i] = getAudioOutputDriverInfo(drivers[i]); return aod; } /** * Gets all audio output drivers currently available for the LinuxSampler instance. * * @return String array containing all audio output drivers currently * available for the LinuxSampler instance. * * @throws IOException If an I/O error occurs. * @throws LscpException If LSCP protocol corruption occurs. * @throws LSException If some other error occurs. */ private synchronized String[] getAudioOutputDriverNames() throws IOException, LscpException, LSException { verifyConnection(); out.writeLine("LIST AVAILABLE_AUDIO_OUTPUT_DRIVERS"); if(getPrintOnlyMode()) return null; return parseList(getSingleLineResultSet().getResult()); } /** * Gets detailed information about a specific audio output driver. * @param driverName The name of the audio output driver. * @param depList An optional list of dependences parameters. * @return An AudioOutputDriver object containing * information about the specified audio output driver. * * @throws IOException If an I/O error occurs. * @throws LscpException If LSCP protocol corruption occurs. * @throws LSException If there is no driver with name driverName. * * @see #getAudioOutputDriverNames */ public synchronized AudioOutputDriver getAudioOutputDriverInfo(String driverName, Parameter... depList) throws IOException, LscpException, LSException { verifyConnection(); out.writeLine("GET AUDIO_OUTPUT_DRIVER INFO " + driverName); if(getPrintOnlyMode()) return null; ResultSet rs = getMultiLineResultSet(); AudioOutputDriver aod = new AudioOutputDriver(rs.getMultiLineResult()); aod.setName(driverName); for(String s : aod.getParameterNames()) aod.addParameter(getAudioOutputDriverParameterInfo(driverName, s, depList)); return aod; } /** * Gets detailed information about a specific audio output driver parameter. * * @param driver The name of the audio output driver. * @param param A specific parameter name for which information should be obtained. * @param deplist An optional list of parameters on which the sought parameter * param depends on. Parameter instances can be * easily created using {@link ParameterFactory} factory. * * @return Parameter object containing * information about the specified audio output driver parameter. * * @throws IOException If an I/O error occurs. * @throws LscpException If LSCP protocol corruption occurs. * @throws LSException If driver is not a valid driver name * or param is not a valid parameter for the specified driver. * * @see #getAudioOutputDrivers * @see #getAudioOutputDriverInfo * @see ParameterFactory */ public synchronized Parameter getAudioOutputDriverParameterInfo(String driver, String param, Parameter... deplist) throws IOException, LscpException, LSException { verifyConnection(); StringBuffer args = new StringBuffer(driver); args.append(' ').append(param); for(Parameter p : deplist) { if(p.getValue() == null) continue; args.append(' ').append(p.getName()).append('=').append(p.getStringValue()); } out.writeLine("GET AUDIO_OUTPUT_DRIVER_PARAMETER INFO " + args.toString()); if(getPrintOnlyMode()) return null; ResultSet rs = getMultiLineResultSet(); String[] lnS = rs.getMultiLineResult(); ParameterType type = parseType(lnS); boolean multi = parseMultiplicity(lnS); Parameter prm; switch(type) { case BOOL: if(!multi) prm = new BoolParameter(lnS); else prm = new BoolListParameter(lnS); prm.setName(param); prm.setValue(prm.getDefault()); return prm; case INT: if(!multi) prm = new IntParameter(lnS); else prm = new IntListParameter(lnS); prm.setName(param); prm.setValue(prm.getDefault()); return prm; case FLOAT: if(!multi) prm = new FloatParameter(lnS); else prm = new FloatListParameter(lnS); prm.setName(param); prm.setValue(prm.getDefault()); return prm; case STRING: if(!multi) prm = new StringParameter(lnS); else prm = new StringListParameter(lnS); prm.setName(param); prm.setValue(prm.getDefault()); return prm; default: throw new LscpException(LscpI18n.getLogMsg("Client.unknownPrmType!")); } } /** * Creates a new audio output device for the desired audio output system. * @param aoDriver The desired audio output system. * @param paramList An optional list of driver specific parameters. Parameter * instances can be easily created using {@link ParameterFactory} factory. * @return The numerical ID of the newly created device. * @throws IOException If some I/O error occurs. * @throws LSException If the creation of the new audio output device failed. * @throws LscpException If LSCP protocol corruption occurs. * @see #getAudioOutputDrivers * @see #getAudioOutputDriverInfo * @see ParameterFactory */ public synchronized int createAudioOutputDevice(String aoDriver, Parameter... paramList) throws IOException, LSException, LscpException { verifyConnection(); StringBuffer args = new StringBuffer(aoDriver); for(Parameter p : paramList) { if(p.getValue() == null) continue; args.append(' ').append(p.getName()).append('=').append(p.getStringValue()); } out.writeLine("CREATE AUDIO_OUTPUT_DEVICE " + args.toString()); if(getPrintOnlyMode()) return -1; ResultSet rs = getEmptyResultSet(); return rs.getIndex(); } /** * Destroys already created audio output device. * @param deviceId The ID of the audio output device to be destroyed. * @throws IOException If some I/O error occurs. * @throws LSException If the destroying of the audio output device failed. * @throws LscpException If LSCP protocol corruption occurs. * @see #getAudioOutputDevices */ public synchronized void destroyAudioOutputDevice(int deviceId) throws IOException, LSException, LscpException { verifyConnection(); out.writeLine("DESTROY AUDIO_OUTPUT_DEVICE " + deviceId); if(getPrintOnlyMode()) return; ResultSet rs = getEmptyResultSet(); } /** * Enables/disables the specified audio output device. * @param deviceId The ID of the audio output device to be enabled/disabled. * @param enable If true the audio output device is enabled, * else the device is disabled. * @throws IOException If some I/O error occurs. * @throws LSException If there is no audio output * device with numerical ID deviceId. * @throws LscpException If LSCP protocol corruption occurs. */ public void enableAudioOutputDevice(int deviceId, boolean enable) throws IOException, LSException, LscpException { setAudioOutputDeviceParameter(deviceId, new BoolParameter("ACTIVE", enable)); } /** * Gets the current number of all created audio output devices. * @return The current number of all created audio output devices. * @throws IOException If some I/O error occurs. * @throws LscpException If LSCP protocol corruption occurs. * @throws LSException If some other error occurs. */ public synchronized int getAudioOutputDeviceCount() throws IOException, LscpException, LSException { verifyConnection(); out.writeLine("GET AUDIO_OUTPUT_DEVICES"); if(getPrintOnlyMode()) return -1; String s = getSingleLineResultSet().getResult(); return parseInt(s); } /** * Gets a list of all created audio output devices. * @return An AudioOutputDevice array * providing all created audio output devices. * @throws IOException If some I/O error occurs. * @throws LscpException If LSCP protocol corruption occurs. * @throws LSException If some other error occurs. */ public synchronized AudioOutputDevice[] getAudioOutputDevices() throws IOException, LscpException, LSException { Integer[] idS = getAudioOutputDeviceIDs(); if(getPrintOnlyMode()) return null; AudioOutputDevice[] devices = new AudioOutputDevice[idS.length]; for(int i = 0; i < devices.length; i++) devices[i] = getAudioOutputDeviceInfo(idS[i]); return devices; } /** * Gets a list of numerical IDs of all created audio output devices. * @return An Integer array providing the numerical IDs of * all created audio output devices. * @throws IOException If some I/O error occurs. * @throws LscpException If LSCP protocol corruption occurs. * @throws LSException If some other error occurs. */ public synchronized Integer[] getAudioOutputDeviceIDs() throws IOException, LscpException, LSException { verifyConnection(); out.writeLine("LIST AUDIO_OUTPUT_DEVICES"); if(getPrintOnlyMode()) return null; return parseIntList(getSingleLineResultSet().getResult()); } /** * Gets the current settings of a specific, already created audio output device. * * @param deviceId Specifies the numerical ID of the audio output device. * * @return An AudioOutputDevice instance containing information * about the specified device. * * @throws IOException If some I/O error occurs. * @throws LscpException If LSCP protocol corruption occurs. * @throws LSException If there is no audio output device * with device id deviceId. * * @see #getAudioOutputDevices */ public synchronized AudioOutputDevice getAudioOutputDeviceInfo(int deviceId) throws IOException, LscpException, LSException { verifyConnection(); out.writeLine("GET AUDIO_OUTPUT_DEVICE INFO " + deviceId); if(getPrintOnlyMode()) return null; ResultSet rs = getMultiLineResultSet(); String[] lnS = rs.getMultiLineResult(); AudioOutputDevice aod = new AudioOutputDevice(); aod.setDeviceId(deviceId); Parameter channels; Parameter samplerate; String drv = getCategoryInfo(lnS, "DRIVER"); aod.setDriverName(drv); for(String s : lnS) { if(s.startsWith("CHANNELS: ")) { channels = (Parameter) getAudioOutputDriverParameterInfo(drv, "CHANNELS"); s = s.substring("CHANNELS: ".length(), s.length()); channels.parseValue(s); aod.setChannelsParameter(channels); int count = channels.getValue() > 0 ? channels.getValue() : 0; AudioOutputChannel[] aoc = new AudioOutputChannel[count]; for(int i = 0; i < count; i++) { aoc[i] = getAudioOutputChannelInfo(deviceId, i); } aod.setAudioChannels(aoc); } else if(s.startsWith("SAMPLERATE: ")) { samplerate = (Parameter) getAudioOutputDriverParameterInfo(drv, "SAMPLERATE"); s = s.substring("SAMPLERATE: ".length(), s.length()); samplerate.parseValue(s); aod.setSampleRateParameter(samplerate); } else if(s.startsWith("ACTIVE: ")) { s = s.substring("ACTIVE: ".length(), s.length()); aod.setActive(Boolean.parseBoolean(s)); } else if(s.startsWith("DRIVER: ")) { } else { int i = s.indexOf(": "); if(i == -1) throw new LscpException ( LscpI18n.getLogMsg("CommandFailed!") ); Parameter prm = getAudioOutputDriverParameterInfo(drv, s.substring(0, i)); s = s.substring(i + 2); prm.parseValue(s); aod.addParameter(prm); } } return aod; } /** * Alters a specific setting of a created audio output device. * * @param deviceId The numerical ID of the audio output device. * @param prm A Parameter instance containing the name of the parameter * and the new value for this parameter. * * @throws IOException If some I/O error occurs. * @throws LscpException If LSCP protocol corruption occurs. * @throws LSException If *
    *
  • There is no audio output device with numerical ID deviceId; *
  • There is no device parameter with the specified name; *
  • The device parameter is readonly; *
  • The device parameter is from different type. *
* * @see #getAudioOutputDevices * @see #getAudioOutputDeviceInfo */ public synchronized void setAudioOutputDeviceParameter(int deviceId, Parameter prm) throws IOException, LscpException, LSException { verifyConnection(); String kv = prm.getName() + '=' + prm.getStringValue(); out.writeLine("SET AUDIO_OUTPUT_DEVICE_PARAMETER " + deviceId + ' ' + kv); if(getPrintOnlyMode()) return; ResultSet rs = getEmptyResultSet(); } /** * Changes the channel number of the speicifed audio output device. * @param deviceId The numerical ID of the audio output device. * @param channels The new number of audio output channels. * * @throws IOException If an I/O error occurs. * @throws LscpException If LSCP protocol corruption occurs. * @throws LSException If there is no device with ID deviceId or * if channels number is out of range. * * @see #getAudioOutputChannelInfo */ public synchronized void setAudioOutputChannelCount(int deviceId, int channels) throws IOException, LscpException, LSException { setAudioOutputDeviceParameter(deviceId, new IntParameter("CHANNELS", channels)); } /** * Gets information about an audio channel. * * @param deviceId The numerical ID of the audio output device. * @param audioChn The audio channel number. * * @return An AudioOutputChannel instance containing the * information about the specified audio output channel. * * @throws IOException If some I/O error occurs. * @throws LscpException If LSCP protocol corruption occurs. * @throws LSException If *
    *
  • There is no audio output device with numerical ID deviceId; *
  • audioChn is not a valid channel number; *
* * @see #getAudioOutputDevices * @see #getAudioOutputDeviceInfo */ public synchronized AudioOutputChannel getAudioOutputChannelInfo(int deviceId, int audioChn) throws IOException, LscpException, LSException { verifyConnection(); out.writeLine("GET AUDIO_OUTPUT_CHANNEL INFO " + deviceId + ' ' + audioChn); if(getPrintOnlyMode()) return null; ResultSet rs = getMultiLineResultSet(); AudioOutputChannel aoc = new AudioOutputChannel(); String[] lnS = rs.getMultiLineResult(); for(String s : lnS) { if(s.startsWith("NAME: ")) { s = s.substring("NAME: ".length()); Parameter prm = getAudioOutputChannelParameterInfo ( deviceId, audioChn, "NAME" ); prm.setValue(removeQuotation(s)); aoc.setNameParameter(prm); } else if(s.startsWith("IS_MIX_CHANNEL: ")) { s = s.substring("IS_MIX_CHANNEL: ".length()); Parameter prm = getAudioOutputChannelParameterInfo ( deviceId, audioChn, "IS_MIX_CHANNEL" ); prm.setValue(Boolean.parseBoolean(s)); aoc.setMixChannelParameter(prm); } else if(s.startsWith("MIX_CHANNEL_DESTINATION: ")) { s = s.substring("MIX_CHANNEL_DESTINATION: ".length()); Parameter prm = getAudioOutputChannelParameterInfo ( deviceId, audioChn, "MIX_CHANNEL_DESTINATION" ); prm.setValue(parseInt(s)); aoc.setMixChannelDestParameter(prm); } else { int i = s.indexOf(": "); if(i == -1) throw new LscpException ( LscpI18n.getLogMsg("CommandFailed!") ); Parameter prm = getAudioOutputChannelParameterInfo ( deviceId, audioChn, s.substring(0, i) ); s = s.substring(i + 2); prm.parseValue(s); aoc.addParameter(prm); } } return aoc; } /** * Gets detailed information about a specific audio output channel parameter. * * @param devId The numerical ID of the audio output device. * @param chan The audio channel number. * @param param a specific channel parameter name for which information should be obtained. * * @return An Parameter instance containing * information about the specified audio output channel parameter. * * @throws IOException If an I/O error occurs. * @throws LscpException If LSCP protocol corruption occurs. * @throws LSException If *
    *
  • devId is not a valid device ID; *
  • chan is not a valid channel number; *
  • There is no channel parameter with the specified name. *
* * @see #getAudioOutputDevices * @see #getAudioOutputChannelInfo */ public synchronized Parameter getAudioOutputChannelParameterInfo(int devId, int chan, String param) throws IOException, LscpException, LSException { verifyConnection(); String args = devId + " " + chan + " " + param; out.writeLine("GET AUDIO_OUTPUT_CHANNEL_PARAMETER INFO " + args); if(getPrintOnlyMode()) return null; ResultSet rs = getMultiLineResultSet(); String[] lnS = rs.getMultiLineResult(); ParameterType type = parseType(lnS); boolean multi = parseMultiplicity(lnS); Parameter prm; switch(type) { case BOOL: if(!multi) prm = new BoolParameter(lnS); else prm = new BoolListParameter(lnS); prm.setName(param); return prm; case INT: if(!multi) prm = new IntParameter(lnS); else prm = new IntListParameter(lnS); prm.setName(param); return prm; case FLOAT: if(!multi) prm = new FloatParameter(lnS); else prm = new FloatListParameter(lnS); prm.setName(param); return prm; case STRING: if(!multi) prm = new StringParameter(lnS); else prm = new StringListParameter(lnS); prm.setName(param); return prm; default: throw new LscpException(LscpI18n.getLogMsg("Client.unknownPrmType!")); } } /** * Alters a specific setting of an audio output channel. * * @param devId The numerical ID of the audio device. * @param chn The audio channel number. * @param prm A Parameter instance containing the name of the parameter * and the new value for this parameter. * * @throws IOException If some I/O error occurs. * @throws LscpException If LSCP protocol corruption occurs. * @throws LSException If *
    *
  • There is no audio output device with numerical ID devId; *
  • chn is not a valid channel number; *
  • There is no channel parameter with the specified name; *
  • The channel parameter is readonly; *
  • The channel parameter is from different type. *
* * @see #getAudioOutputDevices * @see #getAudioOutputChannelInfo */ public synchronized void setAudioOutputChannelParameter(int devId, int chn, Parameter prm) throws IOException, LscpException, LSException { verifyConnection(); String args = devId + " " + chn + " " + prm.getName() + '=' + prm.getStringValue(); out.writeLine("SET AUDIO_OUTPUT_CHANNEL_PARAMETER " + args); if(getPrintOnlyMode()) return; ResultSet rs = getEmptyResultSet(); } /** * Gets the current number of all MIDI input drivers. * @return The current number of all MIDI input drivers. * @throws IOException If some I/O error occurs. * @throws LscpException If LSCP protocol corruption occurs. * @throws LSException If some other error occurs. */ public synchronized int getMidiInputDriverCount() throws IOException, LscpException, LSException { verifyConnection(); out.writeLine("GET AVAILABLE_MIDI_INPUT_DRIVERS"); if(getPrintOnlyMode()) return -1; String s = getSingleLineResultSet().getResult(); return parseInt(s); } /** * Gets all MIDI input drivers currently available for the LinuxSampler instance. * * @return MidiInputDriver array containing all MIDI input drivers currently * available for the LinuxSampler instance. * * @throws IOException If an I/O error occurs. * @throws LscpException If LSCP protocol corruption occurs. * @throws LSException If some other error occurs. */ public synchronized MidiInputDriver[] getMidiInputDrivers() throws IOException, LscpException, LSException { String[] drivers = getMidiInputDriverNames(); if(getPrintOnlyMode()) return null; MidiInputDriver[] mid = new MidiInputDriver[drivers.length]; for(int i = 0; i < mid.length; i++) mid[i] = getMidiInputDriverInfo(drivers[i]); return mid; } /** * Gets all MIDI input drivers currently available for the LinuxSampler instance. * * @return String array containing all MIDI input drivers currently available * for the LinuxSampler instance. * * @throws IOException If an I/O error occurs. * @throws LscpException If LSCP protocol corruption occurs. * @throws LSException If some other error occurs. */ private synchronized String[] getMidiInputDriverNames() throws IOException, LscpException, LSException { verifyConnection(); out.writeLine("LIST AVAILABLE_MIDI_INPUT_DRIVERS"); if(getPrintOnlyMode()) return null; return parseList(getSingleLineResultSet().getResult()); } /** * Gets detailed information about a specific MIDI input driver. * @param driverName The name of the MIDI input driver. * @param depList An optional list of dependences parameters. * @return A MidiInputDriver object containing * information about the specified MIDI input driver. * * @throws IOException If an I/O error occurs. * @throws LscpException If LSCP protocol corruption occurs. * @throws LSException If there is no driver with name driverName. * * @see #getMidiInputDriverNames */ public synchronized MidiInputDriver getMidiInputDriverInfo(String driverName, Parameter... depList) throws IOException, LscpException, LSException { verifyConnection(); out.writeLine("GET MIDI_INPUT_DRIVER INFO " + driverName); if(getPrintOnlyMode()) return null; ResultSet rs = getMultiLineResultSet(); MidiInputDriver mid = new MidiInputDriver(rs.getMultiLineResult()); mid.setName(driverName); for(String s : mid.getParameterNames()) mid.addParameter(getMidiInputDriverParameterInfo(driverName, s, depList)); return mid; } /** * Gets detailed information about a specific MIDI input driver parameter. * * @param driver The name of the MIDI input driver. * @param param a specific parameter name for which information should be obtained. * @param deplist An optional list of parameters on which the sought parameter * param depends on. Parameter instances can be * easily created using {@link ParameterFactory} factory. * * @return A Parameter object containing * information about the specified MIDI input driver parameter. * * @throws IOException If an I/O error occurs. * @throws LscpException If LSCP protocol corruption occurs. * @throws LSException If driver is not a valid driver name * or param is not a valid parameter for the specified driver. * * @see #getMidiInputDrivers * @see #getMidiInputDriverInfo * @see ParameterFactory */ public synchronized Parameter getMidiInputDriverParameterInfo(String driver, String param, Parameter... deplist) throws IOException, LscpException, LSException { verifyConnection(); StringBuffer args = new StringBuffer(driver); args.append(' ').append(param); for(Parameter p : deplist) { if(p.getValue() == null) continue; args.append(' ').append(p.getName()).append('=').append(p.getStringValue()); } out.writeLine("GET MIDI_INPUT_DRIVER_PARAMETER INFO " + args.toString()); if(getPrintOnlyMode()) return null; ResultSet rs = getMultiLineResultSet(); String[] lnS = rs.getMultiLineResult(); ParameterType type = parseType(lnS); boolean multi = parseMultiplicity(lnS); Parameter prm; switch(type) { case BOOL: if(!multi) prm = new BoolParameter(lnS); else prm = new BoolListParameter(lnS); prm.setName(param); prm.setValue(prm.getDefault()); return prm; case INT: if(!multi) prm = new IntParameter(lnS); else prm = new IntListParameter(lnS); prm.setName(param); prm.setValue(prm.getDefault()); return prm; case FLOAT: if(!multi) prm = new FloatParameter(lnS); else prm = new FloatListParameter(lnS); prm.setName(param); prm.setValue(prm.getDefault()); return prm; case STRING: if(!multi) prm = new StringParameter(lnS); else prm = new StringListParameter(lnS); prm.setName(param); prm.setValue(prm.getDefault()); return prm; default: throw new LscpException(LscpI18n.getLogMsg("Client.unknownPrmType!")); } } /** * Creates a new MIDI input device. * @param miDriver The desired MIDI input system. * @param paramList An optional list of driver specific parameters. Parameter * instances can be easily created using {@link ParameterFactory} factory. * @return The numerical ID of the newly created device. * @throws IOException If some I/O error occurs. * @throws LSException If the creation of the new MIDI input device failed. * @throws LscpException If LSCP protocol corruption occurs. * * @see #getMidiInputDrivers * @see #getMidiInputDriverInfo * @see ParameterFactory */ public synchronized int createMidiInputDevice(String miDriver, Parameter... paramList) throws IOException, LSException, LscpException { verifyConnection(); StringBuffer args = new StringBuffer(miDriver); for(Parameter p : paramList) { if(p.getValue() == null) continue; args.append(' ').append(p.getName()).append('=').append(p.getStringValue()); } out.writeLine("CREATE MIDI_INPUT_DEVICE " + args.toString()); if(getPrintOnlyMode()) return -1; ResultSet rs = getEmptyResultSet(); return rs.getIndex(); } /** * Destroys already created MIDI input device. * @param deviceId The numerical ID of the MIDI input device to be destroyed. * @throws IOException If some I/O error occurs. * @throws LSException If the destroying of the MIDI input device failed. * @throws LscpException If LSCP protocol corruption occurs. * @see #createMidiInputDevice * @see #getMidiInputDevices */ public synchronized void destroyMidiInputDevice(int deviceId) throws IOException, LSException, LscpException { verifyConnection(); out.writeLine("DESTROY MIDI_INPUT_DEVICE " + deviceId); if(getPrintOnlyMode()) return; ResultSet rs = getEmptyResultSet(); } /** * Enables/disables the specified MIDI input device. * @param deviceId The ID of the MIDI input device to be enabled/disabled. * @param enable If true the MIDI input device is enabled, * else the device is disabled. * @throws IOException If some I/O error occurs. * @throws LSException If there is no MIDI input * device with numerical ID deviceId. * @throws LscpException If LSCP protocol corruption occurs. */ public void enableMidiInputDevice(int deviceId, boolean enable) throws IOException, LSException, LscpException { setMidiInputDeviceParameter(deviceId, new BoolParameter("ACTIVE", enable)); } /** * Gets the current number of all created MIDI input devices. * @return The current number of all created MIDI input devices. * @throws IOException If some I/O error occurs. * @throws LscpException If LSCP protocol corruption occurs. * @throws LSException If some other error occurs. */ public synchronized int getMidiInputDeviceCount() throws IOException, LscpException, LSException { verifyConnection(); out.writeLine("GET MIDI_INPUT_DEVICES"); if(getPrintOnlyMode()) return -1; String s = getSingleLineResultSet().getResult(); return parseInt(s); } /** * Gets a list of all created MIDI input devices. * @return A MidiInputDevice array * providing all created MIDI input devices. * @throws IOException If some I/O error occurs. * @throws LscpException If LSCP protocol corruption occurs. * @throws LSException If some other error occurs. * * @see #createMidiInputDevice * @see #destroyMidiInputDevice */ public synchronized MidiInputDevice[] getMidiInputDevices() throws IOException, LscpException, LSException { Integer[] idS = getMidiInputDeviceIDs(); if(getPrintOnlyMode()) return null; MidiInputDevice[] devices = new MidiInputDevice[idS.length]; for(int i = 0; i < devices.length; i++) devices[i] = getMidiInputDeviceInfo(idS[i]); return devices; } /** * Gets a list of numerical IDs of all created MIDI input devices. * @return An Integer array providing the numerical IDs of * all created MIDI input devices. * @throws IOException If some I/O error occurs. * @throws LscpException If LSCP protocol corruption occurs. * @throws LSException If some other error occurs. * * @see #createMidiInputDevice * @see #destroyMidiInputDevice */ public synchronized Integer[] getMidiInputDeviceIDs() throws IOException, LscpException, LSException { verifyConnection(); out.writeLine("LIST MIDI_INPUT_DEVICES"); if(getPrintOnlyMode()) return null; return parseIntList(getSingleLineResultSet().getResult()); } /** * Gets the current settings of a specific, already created MIDI input device. * * @param deviceId Specifies the numerical ID of the MIDI input device. * * @return A MidiInputDevice instance containing information * about the specified device. * * @throws IOException If some I/O error occurs. * @throws LscpException If LSCP protocol corruption occurs. * @throws LSException If there is no MIDI input device * with device id deviceId. * * @see #getMidiInputDevices */ public synchronized MidiInputDevice getMidiInputDeviceInfo(int deviceId) throws IOException, LscpException, LSException { verifyConnection(); out.writeLine("GET MIDI_INPUT_DEVICE INFO " + deviceId); if(getPrintOnlyMode()) return null; ResultSet rs = getMultiLineResultSet(); String[] lnS = rs.getMultiLineResult(); MidiInputDevice mid = new MidiInputDevice(); mid.setDeviceId(deviceId); String drv = getCategoryInfo(lnS, "DRIVER"); mid.setDriverName(drv); for(String s : lnS) { if(s.startsWith("DRIVER: ")) { } else if(s.startsWith("ACTIVE: ")) { s = s.substring("ACTIVE: ".length()); mid.setActive(Boolean.parseBoolean(s)); } else if(s.startsWith("PORTS: ")) { s = s.substring("PORTS: ".length()); Parameter ports = (Parameter) getMidiInputDriverParameterInfo(drv, "PORTS"); ports.parseValue(s); mid.setPortsParameter(ports); int j = ports.getValue(); MidiPort[] midiPorts = new MidiPort[j > 0 ? j : 0]; for(int i = 0; i < midiPorts.length; i++) midiPorts[i] = getMidiInputPortInfo(deviceId, i); mid.setMidiPorts(midiPorts); } else { int i = s.indexOf(": "); if(i == -1) throw new LscpException ( LscpI18n.getLogMsg("CommandFailed!") ); Parameter prm = getMidiInputDriverParameterInfo(drv, s.substring(0, i)); s = s.substring(i + 2); prm.parseValue(s); mid.addParameter(prm); } } return mid; } /** * Alters a specific setting of a created MIDI input device. * * @param deviceId The numerical ID of the MIDI input device. * @param prm A Parameter instance containing the name of the parameter * and the new value for this parameter. * * @throws IOException If some I/O error occurs. * @throws LscpException If LSCP protocol corruption occurs. * @throws LSException If *
    *
  • There is no MIDI input device with numerical ID deviceId; *
  • There is no device parameter with the specified name; *
  • The device parameter is readonly; *
  • The device parameter is from different type. *
* * @see #getMidiInputDevices * @see #getMidiInputDeviceInfo */ public synchronized void setMidiInputDeviceParameter(int deviceId, Parameter prm) throws IOException, LscpException, LSException { verifyConnection(); String kv = prm.getName() + '=' + prm.getStringValue(); out.writeLine("SET MIDI_INPUT_DEVICE_PARAMETER " + deviceId + ' ' + kv); if(getPrintOnlyMode()) return; ResultSet rs = getEmptyResultSet(); } /** * Changes the port number of the speicified MIDI input device. * @param deviceId The numerical ID of the MIDI input device. * @param ports The new number of MIDI input ports. * * @throws IOException If an I/O error occurs. * @throws LscpException If LSCP protocol corruption occurs. * @throws LSException If there is no device with ID deviceId or * if ports number is out of range. * * @see #getMidiInputPortInfo */ public synchronized void setMidiInputPortCount(int deviceId, int ports) throws IOException, LscpException, LSException { setMidiInputDeviceParameter(deviceId, new IntParameter("PORTS", ports)); } /** * Gets detailed information about a specific MIDI input port. * @param deviceId The numerical ID of the MIDI input device. * @param midiPort The MIDI input port number. * * @return A MidiPort instance containing * information about the specified MIDI input port. * * @throws IOException If an I/O error occurs. * @throws LscpException If LSCP protocol corruption occurs. * @throws LSException If there is no device with ID deviceId or * if midiPort is not a valid MIDI port number. * * @see #getMidiInputDevices */ public synchronized MidiPort getMidiInputPortInfo(int deviceId, int midiPort) throws IOException, LscpException, LSException { verifyConnection(); out.writeLine("GET MIDI_INPUT_PORT INFO " + deviceId + " " + midiPort); if(getPrintOnlyMode()) return null; ResultSet rs = getMultiLineResultSet(); MidiPort mp = new MidiPort(); String[] lnS = rs.getMultiLineResult(); for(String s : lnS) { if(s.startsWith("NAME: ")) { s = s.substring("NAME: ".length()); Parameter prm = getMidiInputPortParameterInfo ( deviceId, midiPort, "NAME" ); prm.setValue(removeQuotation(s)); mp.setNameParameter(prm); } else { int i = s.indexOf(": "); if(i == -1) throw new LscpException ( LscpI18n.getLogMsg("CommandFailed!") ); Parameter prm = getMidiInputPortParameterInfo ( deviceId, midiPort, s.substring(0, i) ); s = s.substring(i + 2); prm.parseValue(s); mp.addParameter(prm); } } return mp; } /** * Gets detailed information about a specific MIDI input port parameter. * * @param deviceId The numerical ID of the MIDI input device. * @param port The MIDI port number. * @param param A specific parameter name for which information should be obtained. * * @return A Parameter instance containing * information about the specified MIDI input port parameter. * * @throws IOException If an I/O error occurs. * @throws LscpException If LSCP protocol corruption occurs. * @throws LSException If *
    *
  • There is no MIDI input device with numerical ID deviceId; *
  • port is not a valid MIDI port number; *
  • param is not a valid parameter for the specified MIDI port. *
* * @see #getMidiInputDevices * @see #getMidiInputPortInfo */ public synchronized Parameter getMidiInputPortParameterInfo(int deviceId, int port, String param) throws IOException, LscpException, LSException { verifyConnection(); String args = deviceId + " " + port + " " + param; out.writeLine("GET MIDI_INPUT_PORT_PARAMETER INFO " + args); if(getPrintOnlyMode()) return null; ResultSet rs = getMultiLineResultSet(); String[] lnS = rs.getMultiLineResult(); ParameterType type = parseType(lnS); boolean multi = parseMultiplicity(lnS); Parameter prm; switch(type) { case BOOL: if(!multi) prm = new BoolParameter(lnS); else prm = new BoolListParameter(lnS); prm.setName(param); return prm; case INT: if(!multi) prm = new IntParameter(lnS); else prm = new IntListParameter(lnS); prm.setName(param); return prm; case FLOAT: if(!multi) prm = new FloatParameter(lnS); else prm = new FloatListParameter(lnS); prm.setName(param); return prm; case STRING: if(!multi) prm = new StringParameter(lnS); else prm = new StringListParameter(lnS); prm.setName(param); return prm; default: throw new LscpException(LscpI18n.getLogMsg("Client.unknownPrmType!")); } } /** * Alters a specific setting of a MIDI input port. * * @param deviceId The numerical ID of the MIDI device. * @param port The MIDI port number. * @param prm A Parameter instance containing the name of the parameter * and the new value for this parameter. * * @throws IOException If some I/O error occurs. * @throws LscpException If LSCP protocol corruption occurs. * @throws LSException If *
    *
  • There is no MIDI device with numerical ID deviceId; *
  • port is not a valid MIDI port number; *
  • prm is not a valid parameter; *
  • The parameter is readonly; *
  • The parameter is from different type. *
* * @see #getMidiInputDevices * @see #getMidiInputPortInfo */ public synchronized void setMidiInputPortParameter(int deviceId, int port, Parameter prm) throws IOException, LscpException, LSException { verifyConnection(); String args = deviceId + " " + port + " " + prm.getName() + '=' + prm.getStringValue(); out.writeLine("SET MIDI_INPUT_PORT_PARAMETER " + args); if(getPrintOnlyMode()) return; ResultSet rs = getEmptyResultSet(); } /** * Adds a new MIDI instrument map. * @param name The name of this MIDI instrument map. * @return The number of the newly MIDI instrument map. * @throws IOException If some I/O error occurs. * @throws LSException If the creation of the new MIDI instrument map failed. * @throws LscpException If LSCP protocol corruption occurs. * @see #removeMidiInstrumentMap */ public synchronized int addMidiInstrumentMap(String name) throws IOException, LSException, LscpException { verifyConnection(); out.writeLine("ADD MIDI_INSTRUMENT_MAP '" + toEscapedString(name) + "'"); if(getPrintOnlyMode()) return -1; ResultSet rs = getEmptyResultSet(); return rs.getIndex(); } /** * Removes the specified MIDI instrument map. * @param mapId The numerical ID of the MIDI instrument map to be removed. * @throws IOException If some I/O error occurs. * @throws LscpException If LSCP protocol corruption occurs. * @throws LSException If the removing of the MIDI instrument map failed. * @see #addMidiInstrumentMap * @see #getMidiInstrumentMapIDs */ public synchronized void removeMidiInstrumentMap(int mapId) throws IOException, LscpException, LSException { verifyConnection(); out.writeLine("REMOVE MIDI_INSTRUMENT_MAP " + mapId); if(getPrintOnlyMode()) return; ResultSet rs = getEmptyResultSet(); } /** * Removes the all MIDI instrument maps. * @throws IOException If some I/O error occurs. * @throws LscpException If LSCP protocol corruption occurs. * @throws LSException If the removing of the MIDI instrument maps failed. */ public synchronized void removeAllMidiInstrumentMaps() throws IOException, LscpException, LSException { verifyConnection(); out.writeLine("REMOVE MIDI_INSTRUMENT_MAP ALL"); if(getPrintOnlyMode()) return; ResultSet rs = getEmptyResultSet(); } /** * Gets the current number of all MIDI instrument maps. * @return The current number of all MIDI instrument maps. * @throws IOException If some I/O error occurs. * @throws LscpException If LSCP protocol corruption occurs. * @throws LSException If some other error occurs. */ public synchronized int getMidiInstrumentMapCount() throws IOException, LscpException, LSException { verifyConnection(); out.writeLine("GET MIDI_INSTRUMENT_MAPS"); if(getPrintOnlyMode()) return -1; String s = getSingleLineResultSet().getResult(); return parseInt(s); } /** * Gets a list of numerical IDs of all created MIDI instrument maps. * @return An Integer array providing the numerical IDs of * all created MIDI instrument maps. * @throws IOException If some I/O error occurs. * @throws LscpException If LSCP protocol corruption occurs. * @throws LSException If some other error occurs. * @see #addMidiInstrumentMap * @see #removeMidiInstrumentMap */ public synchronized Integer[] getMidiInstrumentMapIDs() throws IOException, LscpException, LSException { verifyConnection(); out.writeLine("LIST MIDI_INSTRUMENT_MAPS"); if(getPrintOnlyMode()) return null; return parseIntList(getSingleLineResultSet().getResult()); } /** * Gets the current settings of a specific, already created MIDI instrument map. * @param mapId Specifies the numerical ID of the MIDI instrument map. * @return A MidiInstrumentMapInfo instance containing information * about the specified device. * @throws IOException If some I/O error occurs. * @throws LscpException If LSCP protocol corruption occurs. * @throws LSException If there is no MIDI instrument map * with map id mapId. * @see #getMidiInstrumentMaps */ public synchronized MidiInstrumentMapInfo getMidiInstrumentMapInfo(int mapId) throws IOException, LscpException, LSException { verifyConnection(); out.writeLine("GET MIDI_INSTRUMENT_MAP INFO " + mapId); if(getPrintOnlyMode()) return null; ResultSet rs = getMultiLineResultSet(); String[] lnS = rs.getMultiLineResult(); String name = ""; boolean b = false; for(String s : lnS) { if(s.startsWith("NAME: ")) { name = toNonEscapedString(s.substring("NAME: ".length())); } else if(s.startsWith("DEFAULT: ")) { b = Boolean.parseBoolean(s.substring("DEFAULT: ".length())); } else { getLogger().info(LscpI18n.getLogMsg("unknownLine", s)); } } return new MidiInstrumentMapInfo(mapId, name, b); } /** * Gets an information of all created MIDI instrument maps. * @return A MidiInstrumentMap array * providing information for all created MIDI instrument maps. * @throws IOException If some I/O error occurs. * @throws LscpException If LSCP protocol corruption occurs. * @throws LSException If some other error occurs. * @see #addMidiInstrumentMap * @see #removeMidiInstrumentMap */ public synchronized MidiInstrumentMapInfo[] getMidiInstrumentMaps() throws IOException, LscpException, LSException { Integer[] idS = getMidiInstrumentMapIDs(); if(getPrintOnlyMode()) return null; MidiInstrumentMapInfo[] maps = new MidiInstrumentMapInfo[idS.length]; for(int i = 0; i < maps.length; i++) maps[i] = getMidiInstrumentMapInfo(idS[i]); return maps; } /** * Sets the name of the specified MIDI instrument map. * @param mapId The numerical ID of the MIDI instrument map. * @param name The new name for the specified MIDI instrument map. * @throws IOException If some I/O error occurs. * @throws LscpException If LSCP protocol corruption occurs. * @throws LSException If mapId is not a valid MIDI * instrument map number or name is not a valid name; */ public synchronized void setMidiInstrumentMapName(int mapId, String name) throws IOException, LscpException, LSException { verifyConnection(); name = toEscapedString(name); out.writeLine("SET MIDI_INSTRUMENT_MAP NAME " + + mapId + " '" + name + "'"); if(getPrintOnlyMode()) return; ResultSet rs = getEmptyResultSet(); } /** * Creates or replaces a MIDI instrument map entry. * @param mapId The ID of the map, where this instrument should be mapped. * @param entry Specifies the position of the MIDI instrument in the MIDI instrument map. * @param info Provides the needed information of the * MIDI instrument, which will be mapped to the specified MIDI instrument map. * @throws IOException If some I/O error occurs. * @throws LSException If the mapping failed. * @throws LscpException If LSCP protocol corruption occurs. * @see #unmapMidiInstrument */ public synchronized void mapMidiInstrument(int mapId, MidiInstrumentEntry entry, MidiInstrumentInfo info) throws IOException, LSException, LscpException { mapMidiInstrument(mapId, entry, info, false); } /** * Creates or replaces a MIDI instrument map entry. * @param mapId The ID of the map, where this instrument should be mapped. * @param entry Specifies the position of the MIDI instrument in the MIDI instrument map. * @param info Provides the needed information of the * MIDI instrument, which will be mapped to the specified MIDI instrument map. * @param nonModal If true the function returns immediately * and the mapping is established in the background. * @throws IOException If some I/O error occurs. * @throws LSException If the mapping failed. * @throws LscpException If LSCP protocol corruption occurs. * @see #unmapMidiInstrument */ public synchronized void mapMidiInstrument(int mapId, MidiInstrumentEntry entry, MidiInstrumentInfo info, boolean nonModal) throws IOException, LSException, LscpException { verifyConnection(); StringBuffer cmd = new StringBuffer("MAP MIDI_INSTRUMENT "); if(nonModal) cmd.append("NON_MODAL "); cmd.append(mapId).append(' '); cmd.append(entry.getMidiBank()).append(' '); cmd.append(entry.getMidiProgram()).append(' '); cmd.append(info.getEngine()).append(" '"); cmd.append(info.getFilePath()).append("' "); cmd.append(info.getInstrumentIndex()).append(' '); cmd.append(info.getVolume()); if(!info.getLoadMode().name().equals("DEFAULT")) { cmd.append(' ').append(info.getLoadMode().name()); } if(info.getName() != null) { String s = toEscapedString(info.getName()); cmd.append(" '").append(s).append("'"); } out.writeLine(cmd.toString()); if(getPrintOnlyMode()) return; ResultSet rs = getEmptyResultSet(); } /** * Removes an entry MIDI instrument map. * @param mapId The ID of the map, from which * the specified MIDI instrument should be removed. * @param entry The entry to remove from the specified MIDI instrument map. * @throws IOException If some I/O error occurs. * @throws LSException If the unmapping failed. * @throws LscpException If LSCP protocol corruption occurs. * @see #mapMidiInstrument */ public synchronized void unmapMidiInstrument(int mapId, MidiInstrumentEntry entry) throws IOException, LSException, LscpException { verifyConnection(); StringBuffer cmd = new StringBuffer("UNMAP MIDI_INSTRUMENT "); cmd.append(mapId).append(' '); cmd.append(entry.getMidiBank()).append(' '); cmd.append(entry.getMidiProgram()); out.writeLine(cmd.toString()); if(getPrintOnlyMode()) return; ResultSet rs = getEmptyResultSet(); } /** * Gets the current number of all MIDI instrument in all maps. * @return The current number of all MIDI instrument in all maps. * @throws IOException If some I/O error occurs. * @throws LscpException If LSCP protocol corruption occurs. * @throws LSException If some other error occurs. */ public synchronized int getMidiInstrumentCount() throws IOException, LscpException, LSException { verifyConnection(); out.writeLine("GET MIDI_INSTRUMENTS ALL"); if(getPrintOnlyMode()) return -1; String s = getSingleLineResultSet().getResult(); return parseInt(s); } /** * Gets the current number of MIDI instrument in the specified map. * @param mapId The ID of the map. * @return The current number of MIDI instrument in the specified map. * @throws IOException If some I/O error occurs. * @throws LscpException If LSCP protocol corruption occurs. * @throws LSException If some other error occurs. */ public synchronized int getMidiInstrumentCount(int mapId) throws IOException, LscpException, LSException { verifyConnection(); out.writeLine("GET MIDI_INSTRUMENTS " + String.valueOf(mapId)); if(getPrintOnlyMode()) return -1; String s = getSingleLineResultSet().getResult(); return parseInt(s); } /** * Gets all MIDI instrument from all maps. * @return A MidiInstrumentInfo array providing * all MIDI instruments from all MIDI instrument maps. * @throws IOException If some I/O error occurs. * @throws LscpException If LSCP protocol corruption occurs. * @throws LSException If some other error occurs. */ public synchronized MidiInstrumentInfo[] getMidiInstruments() throws IOException, LscpException, LSException { verifyConnection(); out.writeLine("LIST MIDI_INSTRUMENTS ALL"); if(getPrintOnlyMode()) return null; String[] entries = parseArray(getSingleLineResultSet().getResult()); return getMidiInstruments(entries); } /** * Gets all MIDI instrument contained int the specified MIDI instrument map. * @param mapId The ID of the map, which instruments should be obtained. * @return A MidiInstrumentInfo array providing * all MIDI instruments from all MIDI instrument maps. * @throws IOException If some I/O error occurs. * @throws LscpException If LSCP protocol corruption occurs. * @throws LSException If some other error occurs. */ public synchronized MidiInstrumentInfo[] getMidiInstruments(int mapId) throws IOException, LscpException, LSException { verifyConnection(); out.writeLine("LIST MIDI_INSTRUMENTS " + String.valueOf(mapId)); if(getPrintOnlyMode()) return null; String[] entries = parseArray(getSingleLineResultSet().getResult()); return getMidiInstruments(entries); } private MidiInstrumentInfo[] getMidiInstruments(String[] entries) throws IOException, LscpException, LSException { Vector v = new Vector(); for(String s : entries) { Integer[] vals = parseIntList(s); if(vals.length != 3) { throw new LscpException(LscpI18n.getLogMsg("CommandFailed!")); } v.add(getMidiInstrumentInfo(vals[0], vals[1], vals[2])); } return v.toArray(new MidiInstrumentInfo[v.size()]); } /** * Gets the current settings of the specified MIDI instrument. * @param mapId The ID of the map. * @param bank The index of the MIDI bank. * @param program The MIDI program number of the instrument. * @return MidiInstrumentInfo instance containing * the current settings of the specified MIDI instrument. * @throws IOException If an I/O error occurs. * @throws LscpException If LSCP protocol corruption occurs. * @throws LSException If the specified MIDI instrument is missing. */ public synchronized MidiInstrumentInfo getMidiInstrumentInfo(int mapId, int bank, int program) throws IOException, LscpException, LSException { verifyConnection(); StringBuffer cmd = new StringBuffer("GET MIDI_INSTRUMENT INFO "); cmd.append(mapId).append(' '); cmd.append(bank).append(' '); cmd.append(program); out.writeLine(cmd.toString()); if(getPrintOnlyMode()) return null; ResultSet rs = getMultiLineResultSet(); MidiInstrumentEntry entry = new MidiInstrumentEntry(bank, program); return new MidiInstrumentInfo(mapId, entry, rs.getMultiLineResult()); } /** * Loads and assigns an instrument to a sampler channel. Notice that this function will * return after the instrument is fully loaded and the channel is ready to be used. * @param filename The name of the instrument file * on the LinuxSampler instance's host system. * @param instrIdx The index of the instrument in the instrument file. * @param samplerChn The number of the sampler channel the instrument should be assigned to. * @throws IOException If some I/O error occurs. * @throws LscpException If LSCP protocol corruption occurs. * @throws LSException If the loading of the instrument failed. * @see #loadInstrument(String, int, int, boolean) * @see #getSamplerChannels */ public synchronized void loadInstrument(String filename, int instrIdx, int samplerChn) throws IOException, LscpException, LSException { verifyConnection(); loadInstrument(filename, instrIdx, samplerChn, false); } /** * Loads and assigns an instrument to a sampler channel. * * @param filename The name of the instrument file * on the LinuxSampler instance's host system. * @param instrIdx The index of the instrument in the instrument file. * @param samplerChn The number of the sampler channel the instrument should be assigned to. * @param nonModal If false the function will return after the instrument * has been fully loaded and the channel is ready to be used. If true * the function returns immediately. * * @throws IOException If some I/O error occurs. * @throws LscpException If LSCP protocol corruption occurs. * @throws LSException If the loading of the instrument failed. * * @see #loadInstrument(String, int, int) * @see #getSamplerChannels */ public synchronized void loadInstrument(String filename, int instrIdx, int samplerChn, boolean nonModal) throws IOException, LscpException, LSException { String cmd = nonModal ? "LOAD INSTRUMENT NON_MODAL " : "LOAD INSTRUMENT "; String args = '\'' + filename + "' " + instrIdx + ' ' + samplerChn; out.writeLine(cmd + args); if(getPrintOnlyMode()) return; ResultSet rs = getEmptyResultSet(); } /** * Loads a sampler engine to a specific sampler channel. * @param engineName The name of the engine. * @param samplerChn The number of the sampler channel * the deployed engine should be assigned to. * * @throws IOException If some I/O error occurs. * @throws LscpException If LSCP protocol corruption occurs. * @throws LSException If the loading of the sampler engine failed. * @see #getEngines * @see #getSamplerChannels */ public synchronized void loadSamplerEngine(String engineName, int samplerChn) throws IOException, LscpException, LSException { verifyConnection(); out.writeLine("LOAD ENGINE " + engineName + ' ' + samplerChn); if(getPrintOnlyMode()) return; ResultSet rs = getEmptyResultSet(); } /** * Gets the current number of all created sampler channels. * @return The current number of all created sampler channels. * @throws IOException If some I/O error occurs. * @throws LscpException If LSCP protocol corruption occurs. * @throws LSException If some other error occurs. */ public synchronized int getSamplerChannelCount() throws IOException, LscpException, LSException { verifyConnection(); out.writeLine("GET CHANNELS"); if(getPrintOnlyMode()) return -1; String s = getSingleLineResultSet().getResult(); return parseInt(s); } /** * Gets a list of all created sampler channels. * @return A SamplerChannel array providing all created sampler channels. * @throws IOException If some I/O error occurs. * @throws LscpException If LSCP protocol corruption occurs. * @throws LSException If some other error occurs. * @see #addSamplerChannel * @see #removeSamplerChannel */ public synchronized SamplerChannel[] getSamplerChannels() throws IOException, LscpException, LSException { Integer[] idS = getSamplerChannelIDs(); if(getPrintOnlyMode()) return null; SamplerChannel[] channels = new SamplerChannel[idS.length]; for(int i = 0; i < channels.length; i++) channels[i] = getSamplerChannelInfo(idS[i]); return channels; } /** * Gets a list with numerical IDs of all created sampler channels. * @return An Integer array providing * the numerical IDs of all created sampler channels. * @throws IOException If some I/O error occurs. * @throws LscpException If LSCP protocol corruption occurs. * @throws LSException If some other error occurs. * @see #addSamplerChannel * @see #removeSamplerChannel */ public synchronized Integer[] getSamplerChannelIDs() throws IOException, LscpException, LSException { verifyConnection(); out.writeLine("LIST CHANNELS"); if(getPrintOnlyMode()) return null; return parseIntList(getSingleLineResultSet().getResult()); } /** * Adds a new sampler channel. This method will increment the sampler channel count by one * and the new sampler channel will be appended to the end of the sampler channel list. * * @return The number of the newly created sampler channel. * @throws IOException If some I/O error occurs. * @throws LSException If the creation of the new sampler channel failed. * @throws LscpException If LSCP protocol corruption occurs. * @see #removeSamplerChannel */ public synchronized int addSamplerChannel() throws IOException, LSException, LscpException { verifyConnection(); out.writeLine("ADD CHANNEL"); if(getPrintOnlyMode()) return -1; ResultSet rs = getEmptyResultSet(); return rs.getIndex(); } /** * Removes the specified sampler channel. * * @param samplerChn The numerical ID of the sampler channel to be removed. * * @throws IOException If some I/O error occurs. * @throws LscpException If LSCP protocol corruption occurs. * @throws LSException If the removing of the sampler channel failed. * @see #addSamplerChannel * @see #getSamplerChannels */ public synchronized void removeSamplerChannel(int samplerChn) throws IOException, LscpException, LSException { verifyConnection(); out.writeLine("REMOVE CHANNEL " + samplerChn); if(getPrintOnlyMode()) return; ResultSet rs = getEmptyResultSet(); } /** * Gets the number of all available engines. * @return The number of all available engines. * @throws IOException If some I/O error occurs. * @throws LscpException If LSCP protocol corruption occurs. * @throws LSException If some other error occurs. */ public synchronized int getEngineCount() throws IOException, LscpException, LSException { verifyConnection(); out.writeLine("GET AVAILABLE_ENGINES"); if(getPrintOnlyMode()) return -1; String s = getSingleLineResultSet().getResult(); return parseInt(s); } /** * Gets a list of all available engines. * * @return SamplerEngine array containing all available engines. * @throws IOException If some I/O error occurs. * @throws LscpException If LSCP protocol corruption occurs. * @throws LSException If some other error occurs. */ public synchronized SamplerEngine[] getEngines() throws IOException, LscpException, LSException { String[] engines = getEngineNames(); if(getPrintOnlyMode()) return null; SamplerEngine[] se = new SamplerEngine[engines.length]; for(int i = 0; i < engines.length; i++) se[i] = getEngineInfo(engines[i]); return se; } /** * Gets a list of all available engines' names. * * @return String array with all available engines' names. * @throws IOException If some I/O error occurs. * @throws LscpException If LSCP protocol corruption occurs. * @throws LSException If some other error occurs. */ private synchronized String[] getEngineNames() throws IOException, LscpException, LSException { verifyConnection(); out.writeLine("LIST AVAILABLE_ENGINES"); if(getPrintOnlyMode()) return null; return parseStringList(getSingleLineResultSet().getResult()); } /** * Gets information about a specific sampler engine. * @param engineName The name of the sampler engine. * * @return SamplerEngine instance containing * information about the specified sampler engine. * * @throws IOException If an I/O error occurs. * @throws LscpException If LSCP protocol corruption occurs. * @throws LSException If there is no sampler engine with name engineName. * @see #getEngineNames */ private synchronized SamplerEngine getEngineInfo(String engineName) throws IOException, LscpException, LSException { verifyConnection(); out.writeLine("GET ENGINE INFO " + engineName); if(getPrintOnlyMode()) return null; ResultSet rs = getMultiLineResultSet(); SamplerEngine se = new SamplerEngine(rs.getMultiLineResult()); se.setName(engineName); return se; } /** * Gets the current settings of the specified sampler channel. * @param samplerChn The sampler channel number. * * @return SamplerChannel instance containing * the current settings of the specified sampler channel. * * @throws IOException If an I/O error occurs. * @throws LscpException If LSCP protocol corruption occurs. * @throws LSException If there is no sampler channel with samplerChn number. * @see #getSamplerChannels */ public synchronized SamplerChannel getSamplerChannelInfo(int samplerChn) throws IOException, LscpException, LSException { verifyConnection(); out.writeLine("GET CHANNEL INFO " + samplerChn); if(getPrintOnlyMode()) return null; ResultSet rs = getMultiLineResultSet(); SamplerChannel sc = new SamplerChannel(rs.getMultiLineResult()); sc.setChannelId(samplerChn); if(sc.getEngine() != null) sc.setEngine(getEngineInfo(sc.getEngine().getName())); return sc; } /** * Gets the current number of active voices on the specified sampler channel. * * @param samplerChn The sampler channel number. * @return The current number of active voices on the specified sampler channel. * @throws IOException If some I/O error occurs. * @throws LscpException If LSCP protocol corruption occurs. * @throws LSException If there is no sampler channel with number samplerChn. * @see #getSamplerChannels */ public synchronized int getChannelVoiceCount(int samplerChn) throws IOException, LscpException, LSException { verifyConnection(); out.writeLine("GET CHANNEL VOICE_COUNT " + samplerChn); if(getPrintOnlyMode()) return -1; ResultSet rs = getSingleLineResultSet(); return parseInt(rs.getResult()); } /** * Gets the current number of active disk streams on the specified sampler channel. * * @param samplerChn The sampler channel number. * @return The current number of active disk streams on the specified sampler channel * or -1 if the engine doesn't support disk streaming. * @throws IOException If some I/O error occurs. * @throws LscpException If LSCP protocol corruption occurs. * @throws LSException If there is no sampler channel with number samplerChn. * @see #getSamplerChannels */ public synchronized int getChannelStreamCount(int samplerChn) throws IOException, LscpException, LSException { verifyConnection(); out.writeLine("GET CHANNEL STREAM_COUNT " + samplerChn); if(getPrintOnlyMode()) return -1; ResultSet rs = getSingleLineResultSet(); if(rs.getResult().equals("NA")) return -1; return parseInt(rs.getResult()); } /** * Gets the current fill state of all disk streams on the specified sampler channel * in bytes. * * @param samplerChn The sampler channel number. * @return The current fill state of all disk streams on the specified sampler channel * or null if the engine which is deployed doesn't support disk streaming. * @throws IOException If some I/O error occurs. * @throws LscpException If LSCP protocol corruption occurs. * @throws LSException If there is no sampler channel with number samplerChn. * @see #getChannelBufferFillPercentage * @see #getSamplerChannels */ public synchronized Vector getChannelBufferFillBytes(int samplerChn) throws IOException, LscpException, LSException { verifyConnection(); out.writeLine("GET CHANNEL BUFFER_FILL BYTES " + samplerChn); if(getPrintOnlyMode()) return null; ResultSet rs = getSingleLineResultSet(); if(rs.getResult().equals("NA")) return null; Vector v = new Vector(); String[] args = parseList(rs.getResult()); for(String s : args) { if(s.charAt(0) != '[') throw new LscpException(LscpI18n.getLogMsg("CommandFailed!")); int i = s.indexOf(']'); if(i == -1) throw new LscpException(LscpI18n.getLogMsg("CommandFailed!")); BufferFill bf = new BufferFill(); bf.setStreamId(parseInt(s.substring(1, i))); bf.setValue(parseInt(s.substring(i + 1))); v.add(bf); } return v; } /** * Gets the current fill state of all disk streams on the specified sampler channel * in percent. * * @param samplerChn The sampler channel number. * @return The current fill state of all disk streams on the specified sampler channel * or null if the engine which is deployed doesn't support disk streaming. * @throws IOException If some I/O error occurs. * @throws LscpException If LSCP protocol corruption occurs. * @throws LSException If there is no sampler channel with number samplerChn. * @see #getChannelBufferFillBytes * @see #getSamplerChannels */ public synchronized Vector getChannelBufferFillPercentage(int samplerChn) throws IOException, LscpException, LSException { verifyConnection(); out.writeLine("GET CHANNEL BUFFER_FILL PERCENTAGE " + samplerChn); if(getPrintOnlyMode()) return null; ResultSet rs = getSingleLineResultSet(); return getChannelBufferFillPercentage(rs.getResult()); } private Vector getChannelBufferFillPercentage(String ln) throws LscpException { if(ln.equals("NA")) return null; Vector v = new Vector(); String[] args = parseList(ln); for(String s : args) { if(s.charAt(0) != '[') throw new LscpException(LscpI18n.getLogMsg("CommandFailed!")); int i = s.indexOf(']'); if(i == -1) throw new LscpException(LscpI18n.getLogMsg("CommandFailed!")); if(s.charAt(s.length() - 1) != '%') throw new LscpException(LscpI18n.getLogMsg("CommandFailed!")); BufferFill bf = new BufferFill(); bf.setStreamId(parseInt(s.substring(1, i))); bf.setValue(parseInt(s.substring(i + 1, s.length() - 1))); v.add(bf); } return v; } /** * Sets the audio output device on the specified sampler channel. * * @param samplerChn The sampler channel number. * @param devId The numerical ID of the audio output device. * * @throws IOException If some I/O error occurs. * @throws LscpException If LSCP protocol corruption occurs. * @throws LSException If *
    *
  • samplerChn is not a valid channel number; *
  • devId is not a valid audio output device ID; *
* * @see #getSamplerChannels * @see #getAudioOutputDevices */ public synchronized void setChannelAudioOutputDevice(int samplerChn, int devId) throws IOException, LscpException, LSException { verifyConnection(); out.writeLine("SET CHANNEL AUDIO_OUTPUT_DEVICE " + samplerChn + ' ' + devId); if(getPrintOnlyMode()) return; ResultSet rs = getEmptyResultSet(); } /** * Sets the audio output channel on the specified sampler channel. * * @param samplerChn The sampler channel number. * @param audioOut The sampler channel's audio output channel which should be rerouted. * @param audioIn The audio channel of the selected audio output device * where audioOut should be routed to. * * @throws IOException If some I/O error occurs. * @throws LscpException If LSCP protocol corruption occurs. * @throws LSException If *
    *
  • samplerChn is not a valid channel number; *
  • There is no engine assigned yet to the specified sampler channel. *
  • There is no audio output device connected to the specified sampler channel. *
* * @see #getSamplerChannels */ public synchronized void setChannelAudioOutputChannel(int samplerChn, int audioOut, int audioIn) throws IOException, LscpException, LSException { verifyConnection(); String args = " " + samplerChn + ' ' + audioOut + ' ' + audioIn; out.writeLine("SET CHANNEL AUDIO_OUTPUT_CHANNEL" + args); if(getPrintOnlyMode()) return; ResultSet rs = getEmptyResultSet(); } /** * Sets the MIDI input device on the specified sampler channel. * * @param samplerChn The sampler channel number. * @param devId The numerical ID of the MIDI input device. * * @throws IOException If some I/O error occurs. * @throws LscpException If LSCP protocol corruption occurs. * @throws LSException If *
    *
  • samplerChn is not a valid channel number; *
  • devId is not a valid MIDI input device ID; *
* * @see #getSamplerChannels * @see #getMidiInputDevices */ public synchronized void setChannelMidiInputDevice(int samplerChn, int devId) throws IOException, LscpException, LSException { verifyConnection(); out.writeLine("SET CHANNEL MIDI_INPUT_DEVICE " + samplerChn + ' ' + devId); if(getPrintOnlyMode()) return; ResultSet rs = getEmptyResultSet(); } /** * Sets the MIDI input port on the specified sampler channel. * * @param samplerChn The sampler channel number. * @param port The MIDI input port number of * the MIDI input device connected to the specified sampler channel. * * @throws IOException If some I/O error occurs. * @throws LscpException If LSCP protocol corruption occurs. * @throws LSException If samplerChn is not a valid channel number. * @see #getSamplerChannels */ public synchronized void setChannelMidiInputPort(int samplerChn, int port) throws IOException, LscpException, LSException { verifyConnection(); out.writeLine("SET CHANNEL MIDI_INPUT_PORT " + samplerChn + ' ' + port); if(getPrintOnlyMode()) return; ResultSet rs = getEmptyResultSet(); } /** * Sets the MIDI input channel the specified sampler channel should listen to. * * @param samplerChn The sampler channel number. * @param midiChn The number of the new MIDI input channel where * samplerChn should listen to or -1 to listen on all 16 MIDI channels. * * @throws IOException If some I/O error occurs. * @throws LscpException If LSCP protocol corruption occurs. * @throws LSException If samplerChn is not a valid channel number. * @see #getSamplerChannels */ public synchronized void setChannelMidiInputChannel(int samplerChn, int midiChn) throws IOException, LscpException, LSException { verifyConnection(); String args = String.valueOf(samplerChn) + ' '; args += (midiChn == -1 ? "ALL" : String.valueOf(midiChn)); out.writeLine("SET CHANNEL MIDI_INPUT_CHANNEL " + args); if(getPrintOnlyMode()) return; ResultSet rs = getEmptyResultSet(); } /** * Sets the MIDI instrument map to be used on the specified sampler channel. * * @param samplerChn The sampler channel number. * @param mapId Specifies the numerical ID of the MIDI instrument * map to assign. To remove the current map binding use -1. * To set the current map to be the default map use -2. * * @throws IOException If some I/O error occurs. * @throws LscpException If LSCP protocol corruption occurs. * @throws LSException If *
    *
  • samplerChn is not a valid channel number; *
  • mapId is not a valid MIDI instrument map ID; *
* * @see #getSamplerChannels * @see #getMidiInstrumentMaps */ public synchronized void setChannelMidiInstrumentMap(int samplerChn, int mapId) throws IOException, LscpException, LSException { verifyConnection(); String s; if(mapId == -1) { s = " NONE"; } else if(mapId == -2) { s = " DEFAULT"; } else { s = " " + String.valueOf(mapId); } out.writeLine("SET CHANNEL MIDI_INSTRUMENT_MAP " + samplerChn + s); if(getPrintOnlyMode()) return; ResultSet rs = getEmptyResultSet(); } /** * Sets the volume of the specified sampler channel. * * @param samplerChn The sampler channel number. * @param volume The new volume value. * * @throws IOException If some I/O error occurs. * @throws LscpException If LSCP protocol corruption occurs. * @throws LSException If samplerChn is not a valid channel number or if * there is no engine assigned yet to the specified sampler channel. * @see #getSamplerChannels */ public synchronized void setChannelVolume(int samplerChn, float volume) throws IOException, LscpException, LSException { verifyConnection(); out.writeLine("SET CHANNEL VOLUME " + samplerChn + ' ' + volume); if(getPrintOnlyMode()) return; ResultSet rs = getEmptyResultSet(); } /** * Mute/unmute the specified sampler channel. * * @param samplerChn The sampler channel number. * @param mute If true the specified channel is muted, else the channel * is unmuted. * * @throws IOException If some I/O error occurs. * @throws LscpException If LSCP protocol corruption occurs. * @throws LSException If samplerChn is not a valid channel number or if * there is no engine assigned yet to the specified sampler channel. * @see #getSamplerChannels */ public synchronized void setChannelMute(int samplerChn, boolean mute) throws IOException, LscpException, LSException { verifyConnection(); out.writeLine("SET CHANNEL MUTE " + samplerChn + ' ' + (mute ? 1 : 0)); if(getPrintOnlyMode()) return; ResultSet rs = getEmptyResultSet(); } /** * Solo/unsolo the specified sampler channel. * * @param samplerChn The sampler channel number. * @param solo true to solo the specified channel, false * otherwise. * * @throws IOException If some I/O error occurs. * @throws LscpException If LSCP protocol corruption occurs. * @throws LSException If samplerChn is not a valid channel number or if * there is no engine assigned yet to the specified sampler channel. * @see #getSamplerChannels */ public synchronized void setChannelSolo(int samplerChn, boolean solo) throws IOException, LscpException, LSException { verifyConnection(); out.writeLine("SET CHANNEL SOLO " + samplerChn + ' ' + (solo ? 1 : 0)); if(getPrintOnlyMode()) return; ResultSet rs = getEmptyResultSet(); } /** * Creates an additional effect send on the specified sampler channel. * @param channel The sampler channel, on which a new effect send should be added. * @param midiCtrl Defines the MIDI controller, which * will be able alter the effect send level. * @return The unique ID of the newly created effect send entity. * @throws IOException If some I/O error occurs. * @throws LSException If the creation of the effect send failed. * @throws LscpException If LSCP protocol corruption occurs. * @see #destroyFxSend */ public synchronized int createFxSend(int channel, int midiCtrl) throws IOException, LSException, LscpException { return createFxSend(channel, midiCtrl, null); } /** * Creates an additional effect send on the specified sampler channel. * @param channel The sampler channel, on which the effect send should be created on. * @param midiCtrl Defines the MIDI controller, which can alter the effect send level. * @param name The name of the effect send entity. The name does not have to be unique. * @return The unique ID of the newly created effect send entity. * @throws IOException If some I/O error occurs. * @throws LSException If the creation of the effect send failed. * @throws LscpException If LSCP protocol corruption occurs. * @see #destroyFxSend */ public synchronized int createFxSend(int channel, int midiCtrl, String name) throws IOException, LSException, LscpException { verifyConnection(); String s = String.valueOf(channel) + " " + String.valueOf(midiCtrl); if(name != null) s += " '" + toEscapedString(name) + "'"; out.writeLine("CREATE FX_SEND " + s); if(getPrintOnlyMode()) return -1; ResultSet rs = getEmptyResultSet(); return rs.getIndex(); } /** * Destroys the specified effect send on the specified sampler channel. * @param channel The sampler channel, from which * the specified effect send should be removed. * @param fxSend The ID of the effect send that should be removed. * @throws LSException If some other error occurs. * @throws LscpException If LSCP protocol corruption occurs. * @see #createFxSend */ public synchronized void destroyFxSend(int channel, int fxSend) throws IOException, LSException, LscpException { verifyConnection(); String s = String.valueOf(channel) + " " + String.valueOf(fxSend); out.writeLine("DESTROY FX_SEND " + s); if(getPrintOnlyMode()) return; ResultSet rs = getEmptyResultSet(); } /** * Gets the current number of effect sends on the specified sampler channel. * @param channel The ID of the sampler channel. * @return The current number of effect sends on the specified sampler channels. * @throws IOException If some I/O error occurs. * @throws LscpException If LSCP protocol corruption occurs. * @throws LSException If some other error occurs. */ public synchronized int getFxSoundCount(int channel) throws IOException, LscpException, LSException { verifyConnection(); out.writeLine("GET FX_SENDS " + String.valueOf(channel)); if(getPrintOnlyMode()) return -1; String s = getSingleLineResultSet().getResult(); return parseInt(s); } /** * Gets a list of all created effect sends on the specified sampler channel. * @param channel The sampler channel number. * @return A FxSend array providing all created * effect sends on the specified sampler channel. * @throws IOException If some I/O error occurs. * @throws LscpException If LSCP protocol corruption occurs. * @throws LSException If channel is not a valid sampler channel ID. * @see #createFxSend * @see #destroyFxSend */ public synchronized FxSend[] getFxSends(int channel) throws IOException, LscpException, LSException { Integer[] idS = getFxSendIDs(channel); if(getPrintOnlyMode()) return null; FxSend[] fxSends = new FxSend[idS.length]; for(int i = 0; i < fxSends.length; i++) fxSends[i] = getFxSendInfo(channel, idS[i]); return fxSends; } /** * Gets a list of effect sends on the specified sampler channel. * @param channel The sampler channel number. * @return An Integer array providing * the numerical IDs of all effect sends on the specified sampler channel. * @throws IOException If some I/O error occurs. * @throws LscpException If LSCP protocol corruption occurs. * @throws LSException If channel is not a valid sampler channel ID. * @see #createFxSend * @see #destroyFxSend */ public synchronized Integer[] getFxSendIDs(int channel) throws IOException, LscpException, LSException { verifyConnection(); out.writeLine("LIST FX_SENDS " + channel); if(getPrintOnlyMode()) return null; return parseIntList(getSingleLineResultSet().getResult()); } /** * Gets the current settings of the specified effect send entity. * @param channel The sampler channel number. * @param fxSend The numerical ID of the effect send entity. * @return FxSend instance containing * the current settings of the specified effect send entity. * @throws IOException If an I/O error occurs. * @throws LscpException If LSCP protocol corruption occurs. * @throws LSException If the sampler channel and/or the effect send number are invalid. */ public synchronized FxSend getFxSendInfo(int channel, int fxSend) throws IOException, LscpException, LSException { verifyConnection(); String s = String.valueOf(channel) + " " + String.valueOf(fxSend); out.writeLine("GET FX_SEND INFO " + s); if(getPrintOnlyMode()) return null; ResultSet rs = getMultiLineResultSet(); FxSend fxs = new FxSend(rs.getMultiLineResult()); fxs.setFxSendId(fxSend); return fxs; } /** * Sets the name of the specified effect send. * @param channel The sampler channel number. * @param fxSend The numerical ID of the effect send entity. * @param name The new name for the specified effect send. * @throws IOException If some I/O error occurs. * @throws LscpException If LSCP protocol corruption occurs. * @throws LSException If channel is not a valid channel * number or fxSend is not a valid effect send ID; */ public synchronized void setFxSendName(int channel, int fxSend, String name) throws IOException, LscpException, LSException { verifyConnection(); String args = " " + channel + " " + fxSend + " '" + toEscapedString(name) + "'"; out.writeLine("SET FX_SEND NAME" + args); if(getPrintOnlyMode()) return; ResultSet rs = getEmptyResultSet(); } /** * Sets the destination of an effect send's audio channel in the specified sampler channel. * @param channel The sampler channel number. * @param fxSend The numerical ID of the effect send entity to be rerouted. * @param audioSrc The numerical ID of the effect send's audio output channel, * which should be rerouted. * @param audioDst The audio channel of the selected audio output device * where audioSrc should be routed to. * @throws IOException If some I/O error occurs. * @throws LscpException If LSCP protocol corruption occurs. * @throws LSException If *
    *
  • channel is not a valid channel number; *
  • fxSend is not a valid effect send ID; *
  • There is no engine assigned yet to the specified sampler channel; *
  • There is no audio output device connected to the specified sampler channel. *
*/ public synchronized void setFxSendAudioOutputChannel(int channel, int fxSend, int audioSrc, int audioDst) throws IOException, LscpException, LSException { verifyConnection(); String args = " " + channel + " " + fxSend + " " + audioSrc + " " + audioDst; out.writeLine("SET FX_SEND AUDIO_OUTPUT_CHANNEL" + args); if(getPrintOnlyMode()) return; ResultSet rs = getEmptyResultSet(); } /** * Sets the MIDI controller, which will be able to modify * the send level of the specified effect send in the specified sampler channel. * @param channel The sampler channel number. * @param fxSend The numerical ID of the effect send entity. * @param midiCtrl The MIDI controller which shall be * able to modify the effect send's send level. * @throws IOException If some I/O error occurs. * @throws LscpException If LSCP protocol corruption occurs. * @throws LSException If *
    *
  • channel is not a valid channel number; *
  • fxSend is not a valid effect send ID; *
  • midiCtrl is not a valid controller; *
*/ public synchronized void setFxSendMidiController(int channel, int fxSend, int midiCtrl) throws IOException, LscpException, LSException { verifyConnection(); String args = " " + channel + " " + fxSend + " " + midiCtrl; out.writeLine("SET FX_SEND MIDI_CONTROLLER" + args); if(getPrintOnlyMode()) return; ResultSet rs = getEmptyResultSet(); } /** * Sets the current send level of the specified * effect send entity in the specified sampler channel. * @param channel The sampler channel number. * @param fxSend The numerical ID of the effect send entity. * @param volume The new volume value (a value smaller than 1.0 means * attenuation, whereas a value greater than 1.0 means amplification). * @throws IOException If some I/O error occurs. * @throws LscpException If LSCP protocol corruption occurs. * @throws LSException If some other error occurs. */ public synchronized void setFxSendLevel(int channel, int fxSend, float volume) throws IOException, LscpException, LSException { verifyConnection(); String args = " " + channel + " " + fxSend + " " + String.valueOf(volume); out.writeLine("SET FX_SEND LEVEL" + args); if(getPrintOnlyMode()) return; ResultSet rs = getEmptyResultSet(); } /** * Starts an instrument editor for editing the loaded instrument * on the specified sampler channel. * @param samplerChn The sampler channel number. * @throws IOException If some I/O error occurs. * @throws LscpException If LSCP protocol corruption occurs. * @throws LSException If samplerChn is not a valid channel number or if * there is no instrument loaded on the specified sampler channel. * @see #getSamplerChannels */ public synchronized void editChannelInstrument(int samplerChn) throws IOException, LscpException, LSException { verifyConnection(); out.writeLine("EDIT CHANNEL INSTRUMENT " + samplerChn); if(getPrintOnlyMode()) return; ResultSet rs = getEmptyResultSet(); } /** * Adds the specified directory to the instruments database. * @param dir The absolute (escaped) path name of the directory to add. * @throws IOException If some I/O error occurs. * @throws LSException If the creation of the directory failed. * @throws LscpException If LSCP protocol corruption occurs. */ public synchronized void addDbDirectory(String dir) throws IOException, LSException, LscpException { verifyConnection(); out.writeLine("ADD DB_INSTRUMENT_DIRECTORY '" + dir + "'"); if(getPrintOnlyMode()) return; ResultSet rs = getEmptyResultSet(); } /** * Removes the specified directory from the instruments database. * @param dir The absolute (escaped) path name of the directory to remove. * @throws IOException If some I/O error occurs. * @throws LscpException If LSCP protocol corruption occurs. * @throws LSException If the specified directory is not * empty or if the removal of the directory failed. */ public synchronized void removeDbDirectory(String dir) throws IOException, LscpException, LSException { removeDbDirectory(dir, false); } /** * Removes the specified directory from the instruments database. * @param dir The absolute path name of the directory to remove. * @param force If true forces the removal of non-empty * directory and all its content. * @throws IOException If some I/O error occurs. * @throws LscpException If LSCP protocol corruption occurs. * @throws LSException If the removing of the directory failed. */ public synchronized void removeDbDirectory(String dir, boolean force) throws IOException, LscpException, LSException { verifyConnection(); String s = "REMOVE DB_INSTRUMENT_DIRECTORY "; if(force) s += "FORCE "; out.writeLine(s + "'" + dir + "'"); if(getPrintOnlyMode()) return; ResultSet rs = getEmptyResultSet(); } /** * Removes the specified directories from the instruments database. * @param dirs The absolute (escaped) path names of the directories to remove. * @param force If true forces the removal of non-empty * directories. * @throws IOException If some I/O error occurs. * @throws LscpException If LSCP protocol corruption occurs. * @throws LSException If the removing of the directores failed. */ public synchronized void removeDbDirectories(String[] dirs, boolean force) throws IOException, LscpException, LSException { verifyConnection(); String cmd = "REMOVE DB_INSTRUMENT_DIRECTORY "; if(force) cmd += "FORCE "; for(String s : dirs) out.writeLine(cmd + "'" + s + "'"); if(getPrintOnlyMode()) return; getEmptyResultSets(dirs.length, "Client.dirDeletionFailed!"); } /** * Gets the number of directories in the specified directory. * @return The current number of directories in the specified directory. * @param dir The absolute path name of the directory. * @throws IOException If some I/O error occurs. * @throws LscpException If LSCP protocol corruption occurs. * @throws LSException If some other error occurs. */ public synchronized int getDbDirectoryCount(String dir) throws IOException, LscpException, LSException { return getDbDirectoryCount(dir, false); } /** * Gets the number of directories in the specified directory. * @return The current number of directories in the specified directory. * @param dir The absolute path name of the directory. * @param recursive If true, the number of all directories * in the specified subtree will be returned. * @throws IOException If some I/O error occurs. * @throws LscpException If LSCP protocol corruption occurs. * @throws LSException If some other error occurs. */ public synchronized int getDbDirectoryCount(String dir, boolean recursive) throws IOException, LscpException, LSException { verifyConnection(); String s; if(recursive) s = "GET DB_INSTRUMENT_DIRECTORIES RECURSIVE '"; else s = "GET DB_INSTRUMENT_DIRECTORIES '"; out.writeLine(s + dir + "'"); if(getPrintOnlyMode()) return -1; s = getSingleLineResultSet().getResult(); return parseInt(s); } /** * Gets the list of directories in the specified directory. * @param dir The absolute path name of the directory. * @return A String array providing the names of * all directories in the specified directory. * @throws IOException If some I/O error occurs. * @throws LscpException If LSCP protocol corruption occurs. * @throws LSException If the specified path name is invalid. */ public synchronized String[] getDbDirectoryNames(String dir) throws IOException, LscpException, LSException { verifyConnection(); out.writeLine("LIST DB_INSTRUMENT_DIRECTORIES '" + dir + "'"); if(getPrintOnlyMode()) return null; String[] names = parseEscapedStringList(getSingleLineResultSet().getResult()); for(int i = 0; i < names.length; i++) { names[i] = toNonEscapedString(names[i]); } return names; } /** * Gets information about the specified directory. * @param dir The absolute path name of the directory. * @return A DbDirectoryInfo instance providing information * about the specified directory. * @throws IOException If some I/O error occurs. * @throws LscpException If LSCP protocol corruption occurs. * @throws LSException If the specified directory is not found. */ public synchronized DbDirectoryInfo getDbDirectoryInfo(String dir) throws IOException, LscpException, LSException { verifyConnection(); out.writeLine("GET DB_INSTRUMENT_DIRECTORY INFO '" + dir + "'"); if(getPrintOnlyMode()) return null; ResultSet rs = getMultiLineResultSet(); DbDirectoryInfo info = new DbDirectoryInfo(rs.getMultiLineResult()); if(dir.equals("/")) { info.setName("/"); } else { dir = removeEndingFileSeparator(dir); } String s = getFileName(dir); if(s != null) info.setName(toNonEscapedFileName(s)); s = getParentDirectory(dir); if(s != null) info.setParentDirectoryPath(s); return info; } /** * Gets the list of directories in the specified directory. * @param dir The absolute path name of the directory. * @return A DbDirectoryInfo array providing * information about all directories in the specified directory. * @throws IOException If some I/O error occurs. * @throws LscpException If LSCP protocol corruption occurs. * @throws LSException If the specified path name is invalid. */ public synchronized DbDirectoryInfo[] getDbDirectories(String dir) throws IOException, LscpException, LSException { String[] dirS = getDbDirectoryNames(dir); if(!hasEndingFileSeparator(dir)) dir += "/"; DbDirectoryInfo[] infoS = new DbDirectoryInfo[dirS.length]; for(int i = 0; i < dirS.length; i++) { infoS[i] = getDbDirectoryInfo(dir + toEscapedFileName(dirS[i])); } return infoS; } /** * Gets the list of directories in the specified directory. * @param dir The absolute path name of the directory. * @return A DbDirectoryInfo array providing * information about all directories in the specified directory. * @throws IOException If some I/O error occurs. * @throws LscpException If LSCP protocol corruption occurs. * @throws LSException If the specified path name is invalid. * public synchronized DbDirectoryInfo[] getDbDirectories(String dir) throws IOException, LscpException, LSException { String[] dirS = getDbDirectoryNames(dir); if(dirS.length == 0) return new DbDirectoryInfo[0]; if(dir.charAt(dir.length() - 1) != '/') dir += "/"; for(int i = 0; i < dirS.length; i++) { out.writeLine("GET DB_INSTRUMENT_DIRECTORY INFO '" + dir + dirS[i] + "'"); } if(getPrintOnlyMode()) return null; if(dir.length() > 1) dir = dir.substring(0, dir.length() - 1); StringBuffer sb = new StringBuffer(); DbDirectoryInfo[] infoS = new DbDirectoryInfo[dirS.length]; for(int i = 0; i < dirS.length; i++) { try { ResultSet rs = getMultiLineResultSet(); infoS[i] = new DbDirectoryInfo(rs.getMultiLineResult()); infoS[i].setName(dirS[i]); infoS[i].setParentDirectoryPath(dir); } catch (SocketTimeoutException e) { getLogger().log(Level.FINE, e.getMessage(), e); sb.append(e.getMessage()).append("\n"); break; } catch (Exception e) { getLogger().log(Level.FINE, e.getMessage(), e); sb.append(e.getMessage()).append("\n"); } } String details = sb.toString(); if(details.length() > 0) { String err = LscpI18n.getLogMsg("Client.getInstrsInfoFailed!"); throw new LSException(0, err, details); } return infoS; }*/ /** * Renames the specified directory. * @param dir The absolute path name of the directory to rename. * @param name The new name for the directory. * @throws IOException If some I/O error occurs. * @throws LSException If the renaming of the directory failed. * @throws LscpException If LSCP protocol corruption occurs. */ public synchronized void renameDbDirectory(String dir, String name) throws IOException, LSException, LscpException { verifyConnection(); name = toEscapedString(name); out.writeLine("SET DB_INSTRUMENT_DIRECTORY NAME '" + dir + "' '" + name + "'"); if(getPrintOnlyMode()) return; ResultSet rs = getEmptyResultSet(); } /** * Moves the specified directory into the specified location. * @param dir The absolute path name of the directory to move. * @param dst The location where the directory will be moved to. * @throws IOException If some I/O error occurs. * @throws LSException If the operation failed. * @throws LscpException If LSCP protocol corruption occurs. */ public synchronized void moveDbDirectory(String dir, String dst) throws IOException, LSException, LscpException { verifyConnection(); out.writeLine("MOVE DB_INSTRUMENT_DIRECTORY '" + dir + "' '" + dst + "'"); if(getPrintOnlyMode()) return; ResultSet rs = getEmptyResultSet(); } /** * Moves the specified directories into the specified location. * @param dirs The absolute path names of the directories to move. * @param dst The location where the directories will be moved to. * @throws IOException If some I/O error occurs. * @throws LSException If the operation failed. * @throws LscpException If LSCP protocol corruption occurs. */ public synchronized void moveDbDirectories(String dirs[], String dst) throws IOException, LSException, LscpException { verifyConnection(); for(String s : dirs) { out.writeLine("MOVE DB_INSTRUMENT_DIRECTORY '" + s + "' '" + dst + "'"); } if(getPrintOnlyMode()) return; getEmptyResultSets(dirs.length, "Client.dirMovingFailed!"); } /** * Copies the specified directory into the specified location. * @param dir The absolute path name of the directory to copy. * @param dst The location where the directory will be copied to. * @throws IOException If some I/O error occurs. * @throws LSException If the operation failed. * @throws LscpException If LSCP protocol corruption occurs. */ public synchronized void copyDbDirectory(String dir, String dst) throws IOException, LSException, LscpException { verifyConnection(); out.writeLine("COPY DB_INSTRUMENT_DIRECTORY '" + dir + "' '" + dst + "'"); if(getPrintOnlyMode()) return; ResultSet rs = getEmptyResultSet(); } /** * Copies the specified directories into the specified location. * @param dirs The absolute path names of the directories to copy. * @param dst The location where the directories will be copied to. * @throws IOException If some I/O error occurs. * @throws LSException If the operation failed. * @throws LscpException If LSCP protocol corruption occurs. */ public synchronized void copyDbDirectories(String[] dirs, String dst) throws IOException, LSException, LscpException { verifyConnection(); for(String s : dirs) { out.writeLine("COPY DB_INSTRUMENT_DIRECTORY '" + s + "' '" + dst + "'"); } if(getPrintOnlyMode()) return; getEmptyResultSets(dirs.length, "Client.dirCopyingFailed!"); } /** * Changes the description of the specified directory. * @param dir The absolute path name of the directory. * @param desc The new description for the directory. * @throws IOException If some I/O error occurs. * @throws LSException If failed to change the description. * @throws LscpException If LSCP protocol corruption occurs. */ public synchronized void setDbDirectoryDescription(String dir, String desc) throws IOException, LSException, LscpException { verifyConnection(); String s = "SET DB_INSTRUMENT_DIRECTORY DESCRIPTION '"; out.writeLine(s + dir + "' '" + toEscapedString(desc) + "'"); if(getPrintOnlyMode()) return; ResultSet rs = getEmptyResultSet(); } public static enum ScanMode { RECURSIVE, NON_RECURSIVE, FLAT } /** * Adds the specified instrument to the specified instruments database directory. * @param dbDir The absolute path name of the database directory in which the * specified instrument will be added. * @param filePath The absolute path name of the instrument file. * @param instrIndex The index of the instrument (in the given instrument file) to add. * @throws IOException If some I/O error occurs. * @throws LSException If the operation failed. * @throws LscpException If LSCP protocol corruption occurs. */ public synchronized void addDbInstrument(String dbDir, String filePath, int instrIndex) throws IOException, LSException, LscpException { addDbInstrument(dbDir, filePath, instrIndex, false); } /** * Adds the specified instrument to the specified instruments database directory. * @param dbDir The absolute path name of the database directory in which the * specified instrument will be added. * @param filePath The absolute path name of the instrument file. * @param instrIndex The index of the instrument (in the given instrument file) to add. * @param background If true, the scan will be done * in background and this method may return before the job is finished. * @return If background is true, the ID * of the scan job. * @throws IOException If some I/O error occurs. * @throws LSException If the operation failed. * @throws LscpException If LSCP protocol corruption occurs. * @see #addInstrumentsDbListener */ public synchronized int addDbInstrument(String dbDir, String filePath, int instrIndex, boolean background) throws IOException, LSException, LscpException { verifyConnection(); String s = "ADD DB_INSTRUMENTS"; if(background) s += " NON_MODAL"; s += " '" + dbDir + "' '" + filePath + "' "; out.writeLine(s + String.valueOf(instrIndex)); if(getPrintOnlyMode()) return -1; ResultSet rs = getEmptyResultSet(); return rs.getIndex(); } /** * Adds the instruments in the specified file to the specified * instruments database directory. * @param dbDir The absolute path name of the database directory * in which the the supported instruments will be added. * @param filePath The absolute path name of the file to scan for instruments. * @throws IOException If some I/O error occurs. * @throws LSException If the operation failed. * @throws LscpException If LSCP protocol corruption occurs. */ public synchronized void addDbInstruments(String dbDir, String filePath) throws IOException, LSException, LscpException { addDbInstruments(dbDir, filePath, false); } /** * Adds the instruments in the specified file to the specified * instruments database directory. * @param dbDir The absolute path name of the database directory * in which the the supported instruments will be added. * @param filePath The absolute path name of the file to scan for instruments. * @param background If true, the scan will be done * in background and this method may return before the job is finished. * @return If background is true, the ID * of the scan job. * @throws IOException If some I/O error occurs. * @throws LSException If the operation failed. * @throws LscpException If LSCP protocol corruption occurs. * @see #addInstrumentsDbListener */ public synchronized int addDbInstruments(String dbDir, String filePath, boolean background) throws IOException, LSException, LscpException { verifyConnection(); String s = "ADD DB_INSTRUMENTS"; if(background) s += " NON_MODAL"; out.writeLine(s + " '" + dbDir + "' '" + filePath + "'"); if(getPrintOnlyMode()) return -1; ResultSet rs = getEmptyResultSet(); return rs.getIndex(); } /** * Adds the instruments in the specified file system directory * to the specified instruments database directory. * @param mode Determines the scanning mode. If RECURSIVE is * specified, all supported instruments in the specified file system * direcotry will be added to the specified instruments database * directory, including the instruments in subdirectories * of the supplied directory. If NON_RECURSIVE is specified, * the instruments in the subdirectories will not be processed. * If FLAT is specified, all supported instruments in the specified * file system direcotry will be added, including the instruments in * subdirectories of the supplied directory, but the respective * subdirectory structure will not be recreated in the instruments * database and all instruments will be added directly in the * specified database directory. * @param dbDir The absolute path name of the database directory * in which the supported instruments will be added. * @param fsDir The absolute path name of the file system directory. * @throws IOException If some I/O error occurs. * @throws LSException If the operation failed. * @throws LscpException If LSCP protocol corruption occurs. */ public synchronized void addDbInstruments(ScanMode mode, String dbDir, String fsDir) throws IOException, LSException, LscpException { addDbInstruments(mode, dbDir, fsDir, false); } /** * Adds the instruments in the specified file system directory * to the specified instruments database directory. * @param mode Determines the scanning mode. If RECURSIVE is * specified, all supported instruments in the specified file system * direcotry will be added to the specified instruments database * directory, including the instruments in subdirectories * of the supplied directory. If NON_RECURSIVE is specified, * the instruments in the subdirectories will not be processed. * If FLAT is specified, all supported instruments in the specified * file system direcotry will be added, including the instruments in * subdirectories of the supplied directory, but the respective * subdirectory structure will not be recreated in the instruments * database and all instruments will be added directly in the * specified database directory. * @param dbDir The absolute path name of the database directory * in which the supported instruments will be added. * @param fsDir The absolute path name of the file system directory. * @param background If true, the scan will be done * in background and this method may return before the job is finished. * @return If background is true, the ID * of the scan job. * @throws IOException If some I/O error occurs. * @throws LSException If the operation failed. * @throws LscpException If LSCP protocol corruption occurs. * @see #addInstrumentsDbListener */ public synchronized int addDbInstruments(ScanMode mode, String dbDir, String fsDir, boolean background) throws IOException, LSException, LscpException { verifyConnection(); StringBuffer sb = new StringBuffer("ADD DB_INSTRUMENTS"); if(background) sb.append(" NON_MODAL"); switch(mode) { case RECURSIVE: sb.append(" RECURSIVE"); break; case NON_RECURSIVE: sb.append(" NON_RECURSIVE"); break; case FLAT: sb.append(" FLAT"); break; } sb.append(" '").append(dbDir).append("' '"); sb.append(fsDir).append("'"); out.writeLine(sb.toString()); if(getPrintOnlyMode()) return -1; ResultSet rs = getEmptyResultSet(); return rs.getIndex(); } /** * Removes the specified instrument from the instruments database. * @param instr The absolute path name of the instrument to remove. * @throws IOException If some I/O error occurs. * @throws LscpException If LSCP protocol corruption occurs. * @throws LSException If the removing of the instrument failed. */ public synchronized void removeDbInstrument(String instr) throws IOException, LscpException, LSException { verifyConnection(); out.writeLine("REMOVE DB_INSTRUMENT '" + instr + "'"); if(getPrintOnlyMode()) return; ResultSet rs = getEmptyResultSet(); } /** * Removes the specified instruments from the instruments database. * @param instrs The absolute path names of the instruments to remove. * @throws IOException If some I/O error occurs. * @throws LscpException If LSCP protocol corruption occurs. * @throws LSException If the removing of the instruments failed. */ public synchronized void removeDbInstruments(String[] instrs) throws IOException, LscpException, LSException { verifyConnection(); for(String s : instrs) { out.writeLine("REMOVE DB_INSTRUMENT '" + s + "'"); } if(getPrintOnlyMode()) return; getEmptyResultSets(instrs.length, "Client.instrDeletionFailed!"); } /** * Gets the number of instruments in the specified directory. * @return The current number of instruments in the specified directory. * @param dir The absolute path name of the directory. * @throws IOException If some I/O error occurs. * @throws LscpException If LSCP protocol corruption occurs. * @throws LSException If some other error occurs. */ public synchronized int getDbInstrumentCount(String dir) throws IOException, LscpException, LSException { return getDbInstrumentCount(dir, false); } /** * Gets the number of instruments in the specified directory. * @return The current number of instruments in the specified directory. * @param dir The absolute path name of the directory. * @param recursive If true, the number of all instruments * in the specified subtree will be returned. * @throws IOException If some I/O error occurs. * @throws LscpException If LSCP protocol corruption occurs. * @throws LSException If some other error occurs. */ public synchronized int getDbInstrumentCount(String dir, boolean recursive) throws IOException, LscpException, LSException { verifyConnection(); String s; if(recursive) s = "GET DB_INSTRUMENTS RECURSIVE '"; else s = "GET DB_INSTRUMENTS '"; out.writeLine(s + dir + "'"); if(getPrintOnlyMode()) return -1; s = getSingleLineResultSet().getResult(); return parseInt(s); } /** * Gets the list of instruments in the specified directory. * @param dir The absolute path name of the directory. * @return A String array providing the names of * all instruments in the specified directory. * @throws IOException If some I/O error occurs. * @throws LscpException If LSCP protocol corruption occurs. * @throws LSException If the specified path name is invalid. */ public synchronized String[] getDbInstrumentNames(String dir) throws IOException, LscpException, LSException { verifyConnection(); out.writeLine("LIST DB_INSTRUMENTS '" + dir + "'"); if(getPrintOnlyMode()) return null; String[] names = parseEscapedStringList(getSingleLineResultSet().getResult()); for(int i = 0; i < names.length; i++) { names[i] = toNonEscapedString(names[i]); } return names; } /** * Gets information about the specified instrument. * @param instr The absolute path name of the instrument. * @return A DbInstrumentInfo instance providing information * about the specified instrument. * @throws IOException If some I/O error occurs. * @throws LscpException If LSCP protocol corruption occurs. * @throws LSException If the specified instrument is not found. */ public synchronized DbInstrumentInfo getDbInstrumentInfo(String instr) throws IOException, LscpException, LSException { verifyConnection(); out.writeLine("GET DB_INSTRUMENT INFO '" + instr + "'"); if(getPrintOnlyMode()) return null; ResultSet rs = getMultiLineResultSet(); DbInstrumentInfo info = new DbInstrumentInfo(rs.getMultiLineResult()); String s = getParentDirectory(instr); if(s != null) info.setDirectoryPath(s); s = getFileName(instr); if(s != null) info.setName(toNonEscapedFileName(s)); return info; } /** * Gets the list of instruments in the specified directory. * @param dir The absolute path name of the directory. * @return A DbInstrumentInfo array providing * information about all instruments in the specified directory. * @throws IOException If some I/O error occurs. * @throws LscpException If LSCP protocol corruption occurs. * @throws LSException If the specified path name is invalid. */ public synchronized DbInstrumentInfo[] getDbInstruments(String dir) throws IOException, LscpException, LSException { String[] instrS = getDbInstrumentNames(dir); if(!hasEndingFileSeparator(dir)) dir += "/"; DbInstrumentInfo[] infoS = new DbInstrumentInfo[instrS.length]; for(int i = 0; i < instrS.length; i++) { infoS[i] = getDbInstrumentInfo(dir + toEscapedFileName(instrS[i])); } return infoS; } /** * Gets the list of instruments in the specified directory. * @param dir The absolute path name of the directory. * @return A DbInstrumentInfo array providing * information about all instruments in the specified directory. * @throws IOException If some I/O error occurs. * @throws LscpException If LSCP protocol corruption occurs. * @throws LSException If the specified path name is invalid. * public synchronized DbInstrumentInfo[] getDbInstruments(String dir) throws IOException, LscpException, LSException { String[] instrS = getDbInstrumentNames(dir); if(instrS.length == 0) return new DbInstrumentInfo[0]; if(dir.charAt(dir.length() - 1) != '/') dir += "/"; for(int i = 0; i < instrS.length; i++) { out.writeLine("GET DB_INSTRUMENT INFO '" + dir + instrS[i] + "'"); } if(getPrintOnlyMode()) return null; if(dir.length() > 1) dir = dir.substring(0, dir.length() - 1); StringBuffer sb = new StringBuffer(); DbInstrumentInfo[] infoS = new DbInstrumentInfo[instrS.length]; for(int i = 0; i < instrS.length; i++) { try { ResultSet rs = getMultiLineResultSet(); infoS[i] = new DbInstrumentInfo(rs.getMultiLineResult()); infoS[i].setName(instrS[i]); infoS[i].setDirectoryPath(dir); } catch (SocketTimeoutException e) { getLogger().log(Level.FINE, e.getMessage(), e); sb.append(e.getMessage()).append("\n"); break; } catch (Exception e) { getLogger().log(Level.FINE, e.getMessage(), e); sb.append(e.getMessage()).append("\n"); } } String details = sb.toString(); if(details.length() > 0) { String err = LscpI18n.getLogMsg("Client.getInstrsInfoFailed!"); throw new LSException(0, err, details); } return infoS; }*/ /** * Renames the specified instrument. * @param instr The absolute path name of the instrument to rename. * @param name The new name for the instrument. * @throws IOException If some I/O error occurs. * @throws LSException If the renaming of the instrument failed. * @throws LscpException If LSCP protocol corruption occurs. */ public synchronized void renameDbInstrument(String instr, String name) throws IOException, LSException, LscpException { verifyConnection(); name = toEscapedString(name); out.writeLine("SET DB_INSTRUMENT NAME '" + instr + "' '" + name + "'"); if(getPrintOnlyMode()) return; ResultSet rs = getEmptyResultSet(); } /** * Moves the specified instrument into the specified location. * @param instr The absolute path name of the instrument to move. * @param dst The directory where the specified instrument will be moved to. * @throws IOException If some I/O error occurs. * @throws LSException If the operation failed. * @throws LscpException If LSCP protocol corruption occurs. */ public synchronized void moveDbInstrument(String instr, String dst) throws IOException, LSException, LscpException { verifyConnection(); out.writeLine("MOVE DB_INSTRUMENT '" + instr + "' '" + dst + "'"); if(getPrintOnlyMode()) return; ResultSet rs = getEmptyResultSet(); } /** * Moves the specified instruments into the specified location. * @param instrs The absolute path names of the instruments to move. * @param dst The directory where the specified instruments will be moved to. * @throws IOException If some I/O error occurs. * @throws LSException If the operation failed. * @throws LscpException If LSCP protocol corruption occurs. */ public synchronized void moveDbInstruments(String[] instrs, String dst) throws IOException, LSException, LscpException { verifyConnection(); for(String s : instrs) { out.writeLine("MOVE DB_INSTRUMENT '" + s + "' '" + dst + "'"); } if(getPrintOnlyMode()) return; getEmptyResultSets(instrs.length, "Client.instrMovingFailed!"); } /** * Copies the specified instrument into the specified location. * @param instr The absolute path name of the instrument to copy. * @param dst The directory where the specified instrument will be copied to. * @throws IOException If some I/O error occurs. * @throws LSException If the operation failed. * @throws LscpException If LSCP protocol corruption occurs. */ public synchronized void copyDbInstrument(String instr, String dst) throws IOException, LSException, LscpException { verifyConnection(); out.writeLine("COPY DB_INSTRUMENT '" + instr + "' '" + dst + "'"); if(getPrintOnlyMode()) return; ResultSet rs = getEmptyResultSet(); } /** * Copies the specified instruments into the specified location. * @param instrs The absolute path name of the instruments to copy. * @param dst The directory where the specified instruments will be copied to. * @throws IOException If some I/O error occurs. * @throws LSException If the operation failed. * @throws LscpException If LSCP protocol corruption occurs. */ public synchronized void copyDbInstruments(String[] instrs, String dst) throws IOException, LSException, LscpException { verifyConnection(); for(String s : instrs) { out.writeLine("COPY DB_INSTRUMENT '" + s + "' '" + dst + "'"); } if(getPrintOnlyMode()) return; getEmptyResultSets(instrs.length, "Client.instrCopyingFailed!"); } /** * Changes the description of the specified instrument. * @param instr The absolute path name of the instrument. * @param desc The new description for the instrument. * @throws IOException If some I/O error occurs. * @throws LSException If failed to change the description. * @throws LscpException If LSCP protocol corruption occurs. */ public synchronized void setDbInstrumentDescription(String instr, String desc) throws IOException, LSException, LscpException { verifyConnection(); desc = toEscapedString(desc); out.writeLine("SET DB_INSTRUMENT DESCRIPTION '" + instr + "' '" + desc + "'"); if(getPrintOnlyMode()) return; ResultSet rs = getEmptyResultSet(); } /** * Finds all directories in the specified directory * that corresponds to the specified search criterias. * @param dir The absolute path name of the directory to search. * @param query Provides the search criterias. * @return A DbDirectoryInfo array providing * information about all directories that are found in the specified directory. * @throws IOException If some I/O error occurs. * @throws LscpException If LSCP protocol corruption occurs. * @throws LSException If the specified path name is invalid. */ public synchronized DbDirectoryInfo[] findDbDirectories(String dir, DbSearchQuery query) throws IOException, LscpException, LSException { return findDbDirectories(dir, query, false); } /** * Finds all directories in the specified directory * that corresponds to the specified search criterias. * @param dir The absolute path name of the directory to search. * @param query Provides the search criterias. * @param nonRecursive If true, the search will be non-recursive. * @return A DbDirectoryInfo array providing * information about all directories that are found in the specified directory. * @throws IOException If some I/O error occurs. * @throws LscpException If LSCP protocol corruption occurs. * @throws LSException If the specified path name is invalid. */ public synchronized DbDirectoryInfo[] findDbDirectories(String dir, DbSearchQuery query, boolean nonRecursive) throws IOException, LscpException, LSException { verifyConnection(); StringBuffer sb = new StringBuffer(); sb.append("FIND DB_INSTRUMENT_DIRECTORIES"); if(nonRecursive) sb.append(" NON_RECURSIVE"); sb.append(" '").append(dir).append("'"); if(query.name != null && query.name.length() > 0) { sb.append(" NAME='").append(toEscapedString(query.name)).append("'"); } String s = query.getCreatedAfter(); String s2 = query.getCreatedBefore(); if(s != null || s2 != null) { sb.append(" CREATED='"); if(s != null) sb.append(s); sb.append(".."); if(s2 != null) sb.append(s2); sb.append("'"); } s = query.getModifiedAfter(); s2 = query.getModifiedBefore(); if(s != null || s2 != null) { sb.append(" MODIFIED='"); if(s != null) sb.append(s); sb.append(".."); if(s2 != null) sb.append(s2); sb.append("'"); } if(query.description != null && query.description.length() > 0) { sb.append(" DESCRIPTION='"); sb.append(toEscapedString(query.description)).append("'"); } out.writeLine(sb.toString()); if(getPrintOnlyMode()) return null; String[] dirS = parseEscapedStringList(getSingleLineResultSet().getResult()); DbDirectoryInfo[] infoS = new DbDirectoryInfo[dirS.length]; for(int i = 0; i < dirS.length; i++) { infoS[i] = getDbDirectoryInfo(dirS[i]); } return infoS; } /** * Finds all instruments in the specified directory * that corresponds to the specified search criterias. * @param dir The absolute path name of the directory to search. * @param query Provides the search criterias. * @return A DbInstrumentInfo array providing * information about all instruments that are found in the specified directory. * @throws IOException If some I/O error occurs. * @throws LscpException If LSCP protocol corruption occurs. * @throws LSException If the specified path name is invalid. */ public synchronized DbInstrumentInfo[] findDbInstruments(String dir, DbSearchQuery query) throws IOException, LscpException, LSException { return findDbInstruments(dir, query, false); } /** * Finds all instruments in the specified directory * that corresponds to the specified search criterias. * @param dir The absolute path name of the directory to search. * @param query Provides the search criterias. * @param nonRecursive If true, the search will be non-recursive. * @return A DbInstrumentInfo array providing * information about all instruments that are found in the specified directory. * @throws IOException If some I/O error occurs. * @throws LscpException If LSCP protocol corruption occurs. * @throws LSException If the specified path name is invalid. */ public synchronized DbInstrumentInfo[] findDbInstruments(String dir, DbSearchQuery query, boolean nonRecursive) throws IOException, LscpException, LSException { verifyConnection(); StringBuffer sb = new StringBuffer(); sb.append("FIND DB_INSTRUMENTS"); if(nonRecursive) sb.append(" NON_RECURSIVE"); sb.append(" '").append(dir).append("'"); if(query.name != null && query.name.length() > 0) { sb.append(" NAME='").append(toEscapedString(query.name)).append("'"); } if(query.formatFamilies.size() > 0) { sb.append(" FORMAT_FAMILIES='").append(query.formatFamilies.get(0)); for(int i = 1; i < query.formatFamilies.size(); i++) { sb.append(',').append(query.formatFamilies.get(i)); } sb.append("'"); } if(query.minSize != -1 || query.maxSize != -1) { sb.append(" SIZE='"); if(query.minSize != -1) sb.append(query.minSize); sb.append(".."); if(query.maxSize != -1) sb.append(query.maxSize); sb.append("'"); } String s = query.getCreatedAfter(); String s2 = query.getCreatedBefore(); if(s != null || s2 != null) { sb.append(" CREATED='"); if(s != null) sb.append(s); sb.append(".."); if(s2 != null) sb.append(s2); sb.append("'"); } s = query.getModifiedAfter(); s2 = query.getModifiedBefore(); if(s != null || s2 != null) { sb.append(" MODIFIED='"); if(s != null) sb.append(s); sb.append(".."); if(s2 != null) sb.append(s2); sb.append("'"); } if(query.description != null && query.description.length() > 0) { sb.append(" DESCRIPTION='"); sb.append(toEscapedString(query.description)).append("'"); } if(query.instrumentType != DbSearchQuery.InstrumentType.BOTH) { sb.append(" IS_DRUM="); if(query.instrumentType == DbSearchQuery.InstrumentType.DRUM) { sb.append("'true'"); } else { sb.append("'false'"); } } if(query.product != null && query.product.length() > 0) { sb.append(" PRODUCT='").append(toEscapedString(query.product)).append("'"); } if(query.artists != null && query.artists.length() > 0) { sb.append(" ARTISTS='").append(toEscapedString(query.artists)).append("'"); } if(query.keywords != null && query.keywords.length() > 0) { sb.append(" KEYWORDS='"); sb.append(toEscapedString(query.keywords)).append("'"); } out.writeLine(sb.toString()); if(getPrintOnlyMode()) return null; String[] instrS = parseEscapedStringList(getSingleLineResultSet().getResult()); DbInstrumentInfo[] infoS = new DbInstrumentInfo[instrS.length]; for(int i = 0; i < instrS.length; i++) { infoS[i] = getDbInstrumentInfo(instrS[i]); } return infoS; } /** * Gets status information about the specified job. * @param jobId The ID of the job. * @return A ScanJobInfo instance providing information * about the specified job. * @throws IOException If some I/O error occurs. * @throws LscpException If LSCP protocol corruption occurs. * @throws LSException If the specified job is not found. */ public synchronized ScanJobInfo getDbInstrumentsJobInfo(int jobId) throws IOException, LscpException, LSException { verifyConnection(); out.writeLine("GET DB_INSTRUMENTS_JOB INFO " + String.valueOf(jobId)); if(getPrintOnlyMode()) return null; ResultSet rs = getMultiLineResultSet(); ScanJobInfo info = new ScanJobInfo(rs.getMultiLineResult()); return info; } /** * Removes all instruments and directories and re-creates * the instruments database structure. * @throws IOException If some I/O error occurs. * @throws LscpException If LSCP protocol corruption occurs. * @throws LSException If the formatting of the instruments database failed. */ public synchronized void formatInstrumentsDb() throws IOException, LscpException, LSException { verifyConnection(); out.writeLine("FORMAT INSTRUMENTS_DB"); if(getPrintOnlyMode()) return; ResultSet rs = getEmptyResultSet(); } /** * Resets the specified sampler channel. * * @param samplerChn The sampler channel number. * * @throws IOException If some I/O error occurs. * @throws LscpException If LSCP protocol corruption occurs. * @throws LSException If samplerChn is not a valid channel number or if * there is no engine assigned yet to the specified sampler channel. * @see #getSamplerChannels */ public synchronized void resetChannel(int samplerChn) throws IOException, LscpException, LSException { verifyConnection(); out.writeLine("RESET CHANNEL " + samplerChn); if(getPrintOnlyMode()) return; ResultSet rs = getEmptyResultSet(); } /** * Resets the whole sampler. * * @throws IOException If some I/O error occurs. * @throws LscpException If LSCP protocol corruption occurs. */ public synchronized void resetSampler() throws IOException, LscpException { verifyConnection(); out.writeLine("RESET"); if(getPrintOnlyMode()) return; try { ResultSet rs = getEmptyResultSet(); } catch(LSException x) { getLogger().warning(x.getMessage()); } } /** * Gets the current number of all active voices. * @return The current number of all active voices. * @throws IOException If some I/O error occurs. * @throws LscpException If LSCP protocol corruption occurs. * @throws LSException If some other error occurs. */ public synchronized int getTotalVoiceCount() throws IOException, LscpException, LSException { verifyConnection(); out.writeLine("GET TOTAL_VOICE_COUNT"); if(getPrintOnlyMode()) return -1; String s = getSingleLineResultSet().getResult(); return parseInt(s); } /** * Gets the maximum number of active voices. * @return The maximum number of active voices. * @throws IOException If some I/O error occurs. * @throws LscpException If LSCP protocol corruption occurs. * @throws LSException If some other error occurs. */ public synchronized int getTotalVoiceCountMax() throws IOException, LscpException, LSException { verifyConnection(); out.writeLine("GET TOTAL_VOICE_COUNT_MAX"); if(getPrintOnlyMode()) return -1; String s = getSingleLineResultSet().getResult(); return parseInt(s); } /** * Gets information about the LinuxSampler instance. * * @return ServerInfo instance containing * information about the LinuxSampler instance. * * @throws IOException If an I/O error occurs. * @throws LscpException If LSCP protocol corruption occurs. * @throws LSException If some other error occurs. */ public synchronized ServerInfo getServerInfo() throws IOException, LscpException, LSException { verifyConnection(); out.writeLine("GET SERVER INFO"); if(getPrintOnlyMode()) return null; ResultSet rs = getMultiLineResultSet(); return new ServerInfo(rs.getMultiLineResult()); } /** * Gets the golobal volume of the sampler. * @return The golobal volume of the sampler. * @throws IOException If some I/O error occurs. * @throws LscpException If LSCP protocol corruption occurs. * @throws LSException If some other error occurs. */ public synchronized float getVolume() throws IOException, LscpException, LSException { verifyConnection(); out.writeLine("GET VOLUME"); if(getPrintOnlyMode()) return -1; String s = getSingleLineResultSet().getResult(); return parseFloat(s); } /** * Sets the global volume of the sampler. * @param volume The new volume value. * @throws IOException If some I/O error occurs. * @throws LscpException If LSCP protocol corruption occurs. * @throws LSException If some other error occurs. * @see #getVolume */ public synchronized void setVolume(float volume) throws IOException, LscpException, LSException { verifyConnection(); out.writeLine("SET VOLUME " + volume); if(getPrintOnlyMode()) return; ResultSet rs = getEmptyResultSet(); } /** * Gets the number of instruments in the specified instrument file. * @param filename The absolute path name of the instrument file. * @return The number of instruments in the specified instrument file. * @throws IOException If some I/O error occurs. * @throws LscpException If LSCP protocol corruption occurs. * @throws LSException If the file is not found, or other error occur. */ public synchronized int getFileInstrumentCount(String filename) throws IOException, LscpException, LSException { verifyConnection(); out.writeLine("GET FILE INSTRUMENTS '" + filename +"'"); if(getPrintOnlyMode()) return -1; String s = getSingleLineResultSet().getResult(); return parseInt(s); } /** * Gets information about the instrument with index * instrIdx in the specified instrument file. * @param filename The absolute path name of the instrument file. * @param instrIdx The index of the instrument in the specified instrument file. * @throws IOException If some I/O error occurs. * @throws LscpException If LSCP protocol corruption occurs. * @throws LSException If failed to retrieve information. */ public synchronized Instrument getFileInstrumentInfo(String filename, int instrIdx) throws IOException, LscpException, LSException { verifyConnection(); out.writeLine("GET FILE INSTRUMENT INFO '" + filename + "' " + String.valueOf(instrIdx)); if(getPrintOnlyMode()) return null; ResultSet rs = getMultiLineResultSet(); Instrument instr = new FileInstrument(rs.getMultiLineResult()) { }; return instr; } /** * Gets the list of instruments in the specified instrument file. * @param filename The absolute path name of the instrument file. * @return An Instrument array providing * information about all instruments in the specified instrument file. * @throws IOException If some I/O error occurs. * @throws LscpException If LSCP protocol corruption occurs. * @throws LSException If the specified file name is invalid. */ public synchronized Instrument[] getFileInstruments(String filename) throws IOException, LscpException, LSException { int l = getFileInstrumentCount(filename); if(l < 0) return null; Instrument[] instrS = new FileInstrument[l]; for(int i = 0; i < instrS.length; i++) { instrS[i] = getFileInstrumentInfo(filename, i); } return instrS; } private static class FileInstrument extends AbstractInstrument { FileInstrument(String[] resultSet) throws LscpException { super(resultSet); } public String getEngine() { // TODO: engine lookup? return getFormatFamily(); } public boolean parse(String s) throws LscpException { if(s.startsWith("PRODUCT: ") || s.startsWith("ARTISTS: ")) return true; return super.parse(s); } } private void getEmptyResultSets(int count, String err) throws LSException { StringBuffer sb = new StringBuffer(); for(int i = 0; i < count; i++) { try { getEmptyResultSet(); } catch (SocketTimeoutException e) { getLogger().log(Level.FINE, e.getMessage(), e); sb.append(e.getMessage()).append("\n"); break; } catch (Exception e) { getLogger().log(Level.FINE, e.getMessage(), e); sb.append(e.getMessage()).append("\n"); } } String details = sb.toString(); if(details.length() > 0) { String s = LscpI18n.getLogMsg(err); throw new LSException(0, s, details); } } /** * Returns the logger for this library. * @return The logger for this library. */ protected static Logger getLogger() { return Logger.getLogger("org.linuxsampler.lscp"); } }