/* * jlscp - a java LinuxSampler control protocol API * * Copyright (C) 2005 Grigor Kirilov 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.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 static org.linuxsampler.lscp.Parser.*; import org.linuxsampler.lscp.event.*; /** * This class is the abstraction representing a client endpoint for communication with LinuxSampler * instance. Since it implements all commands specified in the LSCP protocol version 1.0, for more * information look at * 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.
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();
// 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);
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
);
}
if(hasSubscriptions()) eventThread.start();
if(!llM.isEmpty()) subscribe("MISCELLANEOUS");
if(!llBF.isEmpty()) subscribe("BUFFER_FILL");
if(!llCC.isEmpty()) subscribe("CHANNEL_COUNT");
if(!llCI.isEmpty()) subscribe("CHANNEL_INFO");
if(!llSC.isEmpty()) subscribe("STREAM_COUNT");
if(!llVC.isEmpty()) subscribe("VOICE_COUNT");
}
/**
* Closes the connection to LinuxSampler.
*/
public synchronized void
disconnect() {
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(!isConnected())
throw new IOException(LscpI18n.getLogMsg("Client.notConnected!"));
}
private String
getLine() throws IOException, LscpException {
String s;
for(;;) {
s = in.readLine();
if(s.startsWith("NOTIFY:")) fireEvent(s.substring("NOTIFY:".length()));
else break;
}
return s;
}
/** Processes the notifications send 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;
}
private final Vectortrue
if there is at least one subscription for notification events,
* false
otherwise.
*/
private boolean
hasSubscriptions() {
return !llBF.isEmpty() ||
!llCC.isEmpty() ||
!llCI.isEmpty() ||
!llM.isEmpty() ||
!llSC.isEmpty() ||
!llVC.isEmpty();
}
private void
fireEvent(String s) {
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());
int i = s.indexOf(' ');
if(i == -1) {
getLogger().warning("Unknown VOICE_COUNT format");
return;
}
int j = Integer.parseInt(s.substring(0, i));
i = Integer.parseInt(s.substring(i + 1));
VoiceCountEvent e = new VoiceCountEvent(this, j, i);
for(VoiceCountListener l : llVC) l.voiceCountChanged(e);
} catch(NumberFormatException x) {
getLogger().log(Level.WARNING, "Unknown VOICE_COUNT format", x);
}
} else if(s.startsWith("STREAM_COUNT:")) {
try {
s = s.substring("STREAM_COUNT:".length());
int i = s.indexOf(' ');
if(i == -1) {
getLogger().warning("Unknown STREAM_COUNT format");
return;
}
int j = Integer.parseInt(s.substring(0, i));
i = Integer.parseInt(s.substring(i + 1));
StreamCountEvent e = new StreamCountEvent(this, j, i);
for(StreamCountListener l : llSC) l.streamCountChanged(e);
} catch(NumberFormatException 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 STREAM_COUNT format");
return;
}
int j = Integer.parseInt(s.substring(0, i));
VectorBufferFillListener
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 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");
}
/**
* 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");
String s = getSingleLineResultSet().getResult();
return parseInt(s);
}
/**
* Gets all audio output drivers currently available for the LinuxSampler instance.
*
* @return String
array with 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 String[]
getAudioOutputDrivers() throws IOException, LscpException, LSException {
verifyConnection();
out.writeLine("LIST AVAILABLE_AUDIO_OUTPUT_DRIVERS");
return parseList(getSingleLineResultSet().getResult());
}
/**
* Gets detailed information about a specific audio output driver.
* @param driverName The name of the audio output driver.
*
* @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 #getAudioOutputDrivers
*/
public synchronized AudioOutputDriver
getAudioOutputDriverInfo(String driverName) throws IOException, LscpException, LSException {
verifyConnection();
out.writeLine("GET AUDIO_OUTPUT_DRIVER INFO " + driverName);
ResultSet rs = getMultiLineResultSet();
AudioOutputDriver aod = new AudioOutputDriver(rs.getMultiLineResult());
aod.setName(driverName);
for(String s : aod.getParameterNames())
aod.addParameter(getAudioOutputDriverParameterInfo(driverName, s));
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)
args.append(' ').append(p.getName()).append('=').append(p.getStringValue());
out.writeLine("GET AUDIO_OUTPUT_DRIVER_PARAMETER INFO " + args.toString());
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!"));
}
}
/**
* 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)
args.append(' ').append(p.getName()).append('=').append(p.getStringValue());
out.writeLine("CREATE AUDIO_OUTPUT_DEVICE " + args.toString());
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);
ResultSet rs = getEmptyResultSet();
}
/**
* 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");
String s = getSingleLineResultSet().getResult();
return parseInt(s);
}
/**
* Gets a list of numerical IDs of all created audio output devices.
* @return An Integer
array with 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[]
getAudioOutputDevices() throws IOException, LscpException, LSException {
verifyConnection();
out.writeLine("LIST AUDIO_OUTPUT_DEVICES");
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);
ResultSet rs = getMultiLineResultSet();
String[] lnS = rs.getMultiLineResult();
AudioOutputDevice aod = new AudioOutputDevice();
ParameterParameter
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
* deviceID
;
* 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
* deviceID
;
* audioChn
is not a valid channel number;
* 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;
* 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
* devID
;
* chn
is not a valid channel number;
* String
array with all MIDI input drivers currently available for
* the LinuxSampler instance or null
if there are no MIDI input drivers
* currently available.
*
* @throws IOException If an I/O error occurs.
* @throws LscpException If LSCP protocol corruption occurs.
* @throws LSException If some other error occurs.
*/
public synchronized String[]
getMidiInputDrivers() throws IOException, LscpException, LSException {
verifyConnection();
out.writeLine("LIST AVAILABLE_MIDI_INPUT_DRIVERS");
return parseList(getSingleLineResultSet().getResult());
}
/**
* Gets detailed information about a specific MIDI input driver.
* @param driverName The name of the MIDI input driver.
*
* @return An 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 #getMidiInputDrivers
*/
public synchronized MidiInputDriver
getMidiInputDriverInfo(String driverName) throws IOException, LscpException, LSException {
verifyConnection();
out.writeLine("GET MIDI_INPUT_DRIVER INFO " + driverName);
ResultSet rs = getMultiLineResultSet();
MidiInputDriver mid = new MidiInputDriver(rs.getMultiLineResult());
mid.setName(driverName);
for(String s : mid.getParameterNames())
mid.addParameter(getMidiInputDriverParameterInfo(driverName, s));
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 An 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)
args.append(' ').append(p.getName()).append('=').append(p.getStringValue());
out.writeLine("GET MIDI_INPUT_DRIVER_PARAMETER INFO " + args.toString());
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!"));
}
}
/**
* 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)
args.append(' ').append(p.getName()).append('=').append(p.getStringValue());
out.writeLine("CREATE MIDI_INPUT_DEVICE " + args.toString());
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);
ResultSet rs = getEmptyResultSet();
}
/**
* 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");
String s = getSingleLineResultSet().getResult();
return parseInt(s);
}
/**
* Gets a list of numerical IDs of all created MIDI input devices.
* @return An Integer
array with 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[]
getMidiInputDevices() throws IOException, LscpException, LSException {
verifyConnection();
out.writeLine("LIST MIDI_INPUT_DEVICES");
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 An 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);
ResultSet rs = getMultiLineResultSet();
String[] lnS = rs.getMultiLineResult();
MidiInputDevice mid = new MidiInputDevice();
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 {
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
* deviceID
;
* 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);
ResultSet rs = getMultiLineResultSet();
MidiPort mp = new MidiPort();
String[] lnS = rs.getMultiLineResult();
for(String s : lnS) {
if(s.startsWith("NAME: ")) {
mp.setName(s.substring("NAME: ".length()));
} 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
* deviceID
;
* port
is not a valid MIDI port number;
* param
is not a valid parameter for the specified MIDI port.
* 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
* deviceID
;
* port
is not a valid MIDI port number;
* prm
is not a valid parameter;
* 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);
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);
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");
String s = getSingleLineResultSet().getResult();
return parseInt(s);
}
/**
* Gets a list with numerical IDs of all created sampler channels.
* @return An Integer
array with 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[]
getSamplerChannels() throws IOException, LscpException, LSException {
verifyConnection();
out.writeLine("LIST CHANNELS");
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");
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);
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");
String s = getSingleLineResultSet().getResult();
return parseInt(s);
}
/**
* 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.
*/
public synchronized String[]
getEngines() throws IOException, LscpException, LSException {
verifyConnection();
out.writeLine("LIST AVAILABLE_ENGINES");
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 #getEngines
*/
public synchronized SamplerEngine
getEngineInfo(String engineName) throws IOException, LscpException, LSException {
verifyConnection();
out.writeLine("GET ENGINE INFO " + engineName);
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);
ResultSet rs = getMultiLineResultSet();
SamplerChannel sc = new SamplerChannel(rs.getMultiLineResult());
sc.setChannelID(samplerChn);
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);
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);
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 Vectornull
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 VectorsamplerChn
is not a valid channel number;
* devID
is not a valid audio output device ID;
* 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;
* samplerChn
is not a valid channel number;
* devID
is not a valid MIDI input device ID;
* 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);
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);
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);
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);
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");
try { ResultSet rs = getEmptyResultSet(); }
catch(LSException x) { getLogger().warning(x.getMessage()); }
}
/**
* 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");
ResultSet rs = getMultiLineResultSet();
return new ServerInfo(rs.getMultiLineResult());
}
/**
* Returns the logger for this library.
* @return The logger for this library.
*/
protected static Logger
getLogger() { return Logger.getLogger("org.linuxsampler.lscp"); }
}