/[svn]/jlscp/trunk/src/org/linuxsampler/lscp/Client.java
ViewVC logotype

Annotation of /jlscp/trunk/src/org/linuxsampler/lscp/Client.java

Parent Directory Parent Directory | Revision Log Revision Log


Revision 596 - (hide annotations) (download)
Wed Jun 1 07:11:31 2005 UTC (18 years, 11 months ago) by iliev
File size: 67336 byte(s)
The first alpha-release of jlscp

1 iliev 596 /*
2     * jlscp - a java LinuxSampler control protocol API
3     *
4     * Copyright (C) 2005 Grigor Kirilov Iliev
5     *
6     * This file is part of jlscp.
7     *
8     * jlscp is free software; you can redistribute it and/or modify
9     * it under the terms of the GNU General Public License version 2
10     * as published by the Free Software Foundation.
11     *
12     * jlscp is distributed in the hope that it will be useful,
13     * but WITHOUT ANY WARRANTY; without even the implied warranty of
14     * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15     * GNU General Public License for more details.
16     *
17     * You should have received a copy of the GNU General Public License
18     * along with jlscp; if not, write to the Free Software
19     * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
20     * MA 02111-1307 USA
21     */
22    
23     package org.linuxsampler.lscp;
24    
25     import java.io.IOException;
26    
27     import java.net.InetSocketAddress;
28     import java.net.Socket;
29     import java.net.SocketTimeoutException;
30     import java.net.UnknownHostException;
31    
32     import java.util.Vector;
33     import java.util.logging.Level;
34     import java.util.logging.Logger;
35    
36     import static org.linuxsampler.lscp.Parser.*;
37     import org.linuxsampler.lscp.event.*;
38    
39    
40     /**
41     * This class is the abstraction representing a client endpoint for communication with LinuxSampler
42     * instance. Since it implements all commands specified in the LSCP protocol version 1.0, for more
43     * information look at
44     * <a href=http://www.linuxsampler.org/api/draft-linuxsampler-protocol.html>LSCP</a>
45     * specification.
46     *
47     * <p> The following code establishes connection to LinuxSampler instance and gets the
48     * LinuxSampler version:
49     * <pre>
50     * try {
51     * Client client = new Client();
52     * client.connect();
53     *
54     * String version = client.getServerInfo().getVersion();
55     * System.out.println(version);
56     *
57     * client.disconnect();
58     * } catch(Exception x) { x.printStackTrace(); }
59     * </pre>
60     * </p>
61     *
62     * <p>For more examples look at the <code>examples</code> directory
63     * located in the <b>jlscp</b> distribution.</p>
64     *
65     * All methods are thread safe.
66     * @author Grigor Iliev
67     */
68     public class Client {
69     /** Specifies the current version of jlscp */
70     private final static String VERSION = "0.1a";
71    
72     private String address;
73     private int port;
74     private Socket sock = null;
75     private int soTimeout = 10000;
76    
77     private LscpInputStream in = null;
78     private LscpOutputStream out = null;
79    
80     private EventThread eventThread;
81    
82     class EventThread extends Thread {
83     private boolean terminate = false;
84    
85     EventThread() { super("LSCP-Event-Thread"); }
86    
87     public void
88     run() {
89     while(!mustTerminate()) {
90     try { processNotifications(); }
91     catch(Exception x) {
92     getLogger().log(Level.FINE, x.getMessage(), x);
93     }
94     try { synchronized(this) { wait(100); } }
95     catch(Exception x) {
96     getLogger().log(Level.FINE, x.getMessage(), x);
97     }
98     }
99     }
100    
101     private synchronized boolean
102     mustTerminate() { return terminate; }
103    
104     public synchronized void
105     terminate() {
106     terminate = true;
107     this.notifyAll();
108     }
109     }
110    
111     /**
112     * Creates a new instance of Client with default server address and port.
113     * The default server address and port are 127.0.0.1:8888.
114     */
115     public
116     Client() { this("127.0.0.1"); }
117    
118     /**
119     * Creates a new instance of Client with the specified address and default port.
120     * The default port is 8888.
121     * @param address The address of linux sampler server.
122     */
123     public
124     Client(String address) { this(address, 8888); }
125    
126     /**
127     * Creates a new instance of Client with the specified address and port.
128     * @param address The address of the Linux Sampler.
129     * @param port The Linux Sampler port number.
130     */
131     public
132     Client(String address, int port) {
133     setServerAddress(address);
134     setServerPort(port);
135    
136     eventThread = new EventThread();
137     }
138    
139     /**
140     * Specifies the jlscp version.
141     * @return The jlscp version.
142     */
143     public static String
144     getClientVersion() { return VERSION; }
145    
146     /**
147     * Gets the Linux Sampler address.
148     * @return The Linux Sampler address.
149     */
150     public synchronized String
151     getServerAddress() { return address; }
152    
153     /**
154     * Sets the Linux Sampler address.
155     * @param address The Linux Sampler address.
156     * If <code>address</code> is <code>null</code> sets to default address - 127.0.0.1.
157     */
158     public synchronized void
159     setServerAddress(String address) {
160     this.address = (address == null ? "127.0.0.1" : address);
161     }
162    
163     /**
164     * Gets the Linux Sampler port number.
165     * @return The Linux Sampler port number.
166     */
167     public synchronized int
168     getServerPort() { return port; }
169    
170     /**
171     * Sets the Linux Sampler port number.
172     * @param port The Linux Sampler port number.
173     */
174     public synchronized void
175     setServerPort(int port) { this.port = port; }
176    
177     /**
178     * Connects to the LinuxSampler. If there is already established connection then
179     * the currently available connection is closed berfore connecting.
180     * @throws LscpException If timeout occurs or any other I/O exception.
181     */
182     public synchronized void
183     connect() throws LscpException {
184     if(sock != null) disconnect();
185    
186     // Initializing LSCP event thread
187     if(eventThread.isAlive()) {
188     getLogger().warning("LSCP event thread already running!");
189     eventThread.terminate();
190     }
191    
192     if(eventThread.getState() != Thread.State.NEW) eventThread = new EventThread();
193     ///////
194    
195     InetSocketAddress sockAddr = null;
196    
197     try { sockAddr = new InetSocketAddress(address, port); }
198     catch(IllegalArgumentException x) {
199     String s = String.valueOf(port);
200     throw new LscpException(LscpI18n.getLogMsg("Client.invalidPort!", s), x);
201     }
202    
203     if(sockAddr.isUnresolved()) throw new LscpException (
204     LscpI18n.getLogMsg("Client.unknownHost!", address)
205     );
206    
207     try {
208     sock = new Socket();
209     sock.bind(null);
210     sock.connect(sockAddr, soTimeout);
211     sock.setSoTimeout(soTimeout);
212    
213     in = new LscpInputStream(sock.getInputStream());
214     out = new LscpOutputStream(sock.getOutputStream());
215     } catch(SocketTimeoutException x) {
216     throw new LscpException(LscpI18n.getLogMsg("Client.conTimeout!"), x);
217     } catch(Exception x) {
218     throw new LscpException (
219     LscpI18n.getLogMsg("Client.connectionFailed!"), x
220     );
221     }
222    
223     if(hasSubscriptions()) eventThread.start();
224    
225     if(!llM.isEmpty()) subscribe("MISCELLANEOUS");
226     if(!llBF.isEmpty()) subscribe("BUFFER_FILL");
227     if(!llCC.isEmpty()) subscribe("CHANNEL_COUNT");
228     if(!llCI.isEmpty()) subscribe("CHANNEL_INFO");
229     if(!llSC.isEmpty()) subscribe("STREAM_COUNT");
230     if(!llVC.isEmpty()) subscribe("VOICE_COUNT");
231     }
232    
233     /**
234     * Closes the connection to LinuxSampler.
235     */
236     public synchronized void
237     disconnect() {
238     try { if(sock != null) sock.close(); }
239     catch(Exception x) { getLogger().log(Level.FINE, x.getMessage(), x); }
240     sock = null;
241    
242     if(eventThread.getState() != Thread.State.NEW) {
243     eventThread.terminate();
244     eventThread = new EventThread();
245     }
246     }
247    
248     /**
249     * Determines whether the client is connected.
250     * @return <code>true</code> if there is established connection,
251     * <code>false</code> otherwise.
252     */
253     public synchronized boolean
254     isConnected() {
255     if(sock == null) return false;
256     else return sock.isConnected();
257     }
258    
259     /**
260     * Verifies that there is established connection.
261     * @throws IOException If the connection is not established.
262     */
263     private void
264     verifyConnection() throws IOException {
265     if(!isConnected())
266     throw new IOException(LscpI18n.getLogMsg("Client.notConnected!"));
267     }
268    
269     private String
270     getLine() throws IOException, LscpException {
271     String s;
272     for(;;) {
273     s = in.readLine();
274     if(s.startsWith("NOTIFY:")) fireEvent(s.substring("NOTIFY:".length()));
275     else break;
276     }
277     return s;
278     }
279    
280     /** Processes the notifications send by LinuxSampler */
281     private synchronized void
282     processNotifications() throws IOException, LscpException {
283     while(in.available() > 0) {
284     String s = in.readLine();
285     if(s.startsWith("NOTIFY:")) fireEvent(s.substring("NOTIFY:".length()));
286     else getLogger().severe("Unknown notification format: " + s);
287     }
288     }
289    
290     /**
291     * Gets empty result set.
292     * @return <code>ResultSet</code> instance.
293     */
294     private ResultSet
295     getEmptyResultSet() throws IOException, LscpException, LSException {
296     return parseEmptyResultSet(getLine());
297     }
298    
299     private ResultSet
300     getSingleLineResultSet() throws IOException, LscpException, LSException {
301     ResultSet rs = new ResultSet();
302     String ln = getLine();
303    
304     if(ln.startsWith("WRN")) {
305     parseWarning(ln, rs);
306     getLogger().warning(rs.getMessage());
307     return rs;
308     } else if(ln.startsWith("ERR")) {
309     parseError(ln, rs);
310     throw new LSException(rs.getCode(), rs.getMessage());
311     } else {
312     rs.setResult(ln);
313     return rs;
314     }
315     }
316    
317     private ResultSet
318     getMultiLineResultSet() throws IOException, LscpException, LSException {
319     ResultSet rs = new ResultSet();
320     String ln = getLine();
321    
322     if(ln.startsWith("WRN")) {
323     parseWarning(ln, rs);
324     getLogger().warning(rs.getMessage());
325     return rs;
326     } else if(ln.startsWith("ERR")) {
327     parseError(ln, rs);
328     throw new LSException(rs.getCode(), rs.getMessage());
329     }
330    
331     while(!ln.equals(".")) {
332     rs.addLine(ln);
333     ln = getLine();
334     }
335    
336     return rs;
337     }
338    
339     private final Vector<BufferFillListener> llBF = new Vector<BufferFillListener>();
340     private final Vector<ChannelCountListener> llCC = new Vector<ChannelCountListener>();
341     private final Vector<ChannelInfoListener> llCI = new Vector<ChannelInfoListener>();
342     private final Vector<MiscellaneousListener> llM = new Vector<MiscellaneousListener>();
343     private final Vector<StreamCountListener> llSC = new Vector<StreamCountListener>();
344     private final Vector<VoiceCountListener> llVC = new Vector<VoiceCountListener>();
345    
346     /**
347     * Determines whether there is at least one subscription for notification events.
348     * Do not forget to check for additional listeners if the LSCP specification
349     * extends in the future.
350     * @return <code>true</code> if there is at least one subscription for notification events,
351     * <code>false</code> otherwise.
352     */
353     private boolean
354     hasSubscriptions() {
355     return !llBF.isEmpty() ||
356     !llCC.isEmpty() ||
357     !llCI.isEmpty() ||
358     !llM.isEmpty() ||
359     !llSC.isEmpty() ||
360     !llVC.isEmpty();
361     }
362    
363     private void
364     fireEvent(String s) {
365     if(s.startsWith("CHANNEL_COUNT:")) {
366     try {
367     int i = Integer.parseInt(s.substring("CHANNEL_COUNT:".length()));
368     ChannelCountEvent e = new ChannelCountEvent(this, i);
369     for(ChannelCountListener l : llCC) l.channelCountChanged(e);
370     } catch(NumberFormatException x) {
371     getLogger().log (
372     Level.WARNING, LscpI18n.getLogMsg("CommandFailed!"), x
373     );
374     }
375     } else if(s.startsWith("VOICE_COUNT:")) {
376     try {
377     s = s.substring("VOICE_COUNT:".length());
378     int i = s.indexOf(' ');
379     if(i == -1) {
380     getLogger().warning("Unknown VOICE_COUNT format");
381     return;
382     }
383     int j = Integer.parseInt(s.substring(0, i));
384     i = Integer.parseInt(s.substring(i + 1));
385     VoiceCountEvent e = new VoiceCountEvent(this, j, i);
386     for(VoiceCountListener l : llVC) l.voiceCountChanged(e);
387     } catch(NumberFormatException x) {
388     getLogger().log(Level.WARNING, "Unknown VOICE_COUNT format", x);
389     }
390     } else if(s.startsWith("STREAM_COUNT:")) {
391     try {
392     s = s.substring("STREAM_COUNT:".length());
393     int i = s.indexOf(' ');
394     if(i == -1) {
395     getLogger().warning("Unknown STREAM_COUNT format");
396     return;
397     }
398     int j = Integer.parseInt(s.substring(0, i));
399     i = Integer.parseInt(s.substring(i + 1));
400     StreamCountEvent e = new StreamCountEvent(this, j, i);
401     for(StreamCountListener l : llSC) l.streamCountChanged(e);
402     } catch(NumberFormatException x) {
403     getLogger().log(Level.WARNING, "Unknown STREAM_COUNT format", x);
404     }
405     } else if(s.startsWith("BUFFER_FILL:")) {
406     try {
407     s = s.substring("BUFFER_FILL:".length());
408     int i = s.indexOf(' ');
409     if(i == -1) {
410     getLogger().warning("Unknown STREAM_COUNT format");
411     return;
412     }
413     int j = Integer.parseInt(s.substring(0, i));
414     Vector<BufferFill> v =
415     getChannelBufferFillPercentage(s.substring(i + 1));
416     BufferFillEvent e = new BufferFillEvent(this, j, v);
417     for(BufferFillListener l : llBF) l.bufferFillChanged(e);
418     } catch(Exception x) {
419     getLogger().log(Level.WARNING, "Unknown STREAM_COUNT format", x);
420     }
421     } else if(s.startsWith("CHANNEL_INFO:")) {
422     try {
423     int i = Integer.parseInt(s.substring("CHANNEL_INFO:".length()));
424     ChannelInfoEvent e = new ChannelInfoEvent(this, i);
425     for(ChannelInfoListener l : llCI) l.channelInfoChanged(e);
426     } catch(NumberFormatException x) {
427     getLogger().log(Level.WARNING, "Unknown STREAM_COUNT format", x);
428     }
429     } else if(s.startsWith("MISCELLANEOUS:")) {
430     s = s.substring("MISCELLANEOUS:".length());
431     MiscellaneousEvent e = new MiscellaneousEvent(this, s);
432     for(MiscellaneousListener l : llM) l.miscEventOccured(e);
433     }
434     }
435    
436     private void
437     subscribe(String event) {
438     if(!isConnected()) return;
439    
440     if(!eventThread.isAlive()) eventThread.start();
441    
442     try {
443     out.writeLine("SUBSCRIBE " + event);
444     ResultSet rs = getEmptyResultSet();
445     } catch(Exception x) {
446     getLogger().log (
447     Level.WARNING,
448     LscpI18n.getLogMsg("Client.subscriptionFailed!", event),
449     x
450     );
451     }
452     }
453    
454     private void
455     unsubscribe(String event) {
456     if(!isConnected()) return;
457    
458     try {
459     out.writeLine("UNSUBSCRIBE " + event);
460     ResultSet rs = getEmptyResultSet();
461     } catch(Exception x) {
462     getLogger().log (
463     Level.WARNING,
464     LscpI18n.getLogMsg("Client.unsubscriptionFailed!", event),
465     x
466     );
467     }
468     }
469    
470     /**
471     * Registers the specified listener for receiving event messages.
472     * Listeners can be removed regardless of the connection state.
473     * @param l The <code>BufferFillListener</code> to register.
474     */
475     public synchronized void
476     addBufferFillListener(BufferFillListener l) {
477     if(llBF.isEmpty()) subscribe("BUFFER_FILL");
478     llBF.add(l);
479     }
480    
481     /**
482     * Removes the specified listener.
483     * Listeners can be removed regardless of the connection state.
484     * @param l The <code>BufferFillListener</code> to remove.
485     */
486     public synchronized void
487     removeBufferFillListener(BufferFillListener l) {
488     boolean b = llBF.remove(l);
489     if(b && llBF.isEmpty()) unsubscribe("BUFFER_FILL");
490     }
491    
492     /**
493     * Registers the specified listener for receiving event messages.
494     * Listeners can be registered regardless of the connection state.
495     * @param l The <code>ChannelCountListener</code> to register.
496     */
497     public synchronized void
498     addChannelCountListener(ChannelCountListener l) {
499     if(llCC.isEmpty()) subscribe("CHANNEL_COUNT");
500     llCC.add(l);
501     }
502    
503     /**
504     * Removes the specified listener.
505     * Listeners can be removed regardless of the connection state.
506     * @param l The <code>ChannelCountListener</code> to remove.
507     */
508     public synchronized void
509     removeChannelCountListener(ChannelCountListener l) {
510     boolean b = llCC.remove(l);
511     if(b && llCC.isEmpty()) unsubscribe("CHANNEL_COUNT");
512     }
513    
514     /**
515     * Registers the specified listener for receiving event messages.
516     * Listeners can be registered regardless of the connection state.
517     * @param l The <code>ChannelInfoListener</code> to register.
518     */
519     public synchronized void
520     addChannelInfoListener(ChannelInfoListener l) {
521     if(llCI.isEmpty()) subscribe("CHANNEL_INFO");
522     llCI.add(l);
523     }
524    
525     /**
526     * Removes the specified listener.
527     * Listeners can be removed regardless of the connection state.
528     * @param l The <code>ChannelInfoListener</code> to remove.
529     */
530     public synchronized void
531     removeChannelInfoListener(ChannelInfoListener l) {
532     boolean b = llCI.remove(l);
533     if(b && llCI.isEmpty()) unsubscribe("CHANNEL_INFO");
534     }
535    
536     /**
537     * Registers the specified listener for receiving event messages.
538     * Listeners can be registered regardless of the connection state.
539     * @param l The <code>MiscellaneousListener</code> to register.
540     */
541     public synchronized void
542     addMiscellaneousListener(MiscellaneousListener l) {
543     if(llM.isEmpty()) subscribe("MISCELLANEOUS");
544     llM.add(l);
545     }
546    
547     /**
548     * Removes the specified listener.
549     * Listeners can be removed regardless of the connection state.
550     * @param l The <code>MiscellaneousListener</code> to remove.
551     */
552     public synchronized void
553     removeMiscellaneousListener(MiscellaneousListener l) {
554     boolean b = llM.remove(l);
555     if(b && llM.isEmpty()) unsubscribe("MISCELLANEOUS");
556     }
557    
558     /**
559     * Registers the specified listener for receiving event messages.
560     * Listeners can be registered regardless of the connection state.
561     * @param l The <code>StreamCountListener</code> to register.
562     */
563     public synchronized void
564     addStreamCountListener(StreamCountListener l) {
565     if(llSC.isEmpty()) subscribe("STREAM_COUNT");
566     llSC.add(l);
567     }
568    
569     /**
570     * Removes the specified listener.
571     * Listeners can be removed regardless of the connection state.
572     * @param l The <code>StreamCountListener</code> to remove.
573     */
574     public synchronized void
575     removeStreamCountListener(StreamCountListener l) {
576     boolean b = llSC.remove(l);
577     if(b && llSC.isEmpty()) unsubscribe("STREAM_COUNT");
578     }
579    
580     /**
581     * Registers the specified listener for receiving event messages.
582     * Listeners can be registered regardless of the connection state.
583     * @param l The <code>VoiceCountListener</code> to register.
584     */
585     public synchronized void
586     addVoiceCountListener(VoiceCountListener l) {
587     if(llVC.isEmpty()) subscribe("VOICE_COUNT");
588     llVC.add(l);
589     }
590    
591     /**
592     * Removes the specified listener.
593     * Listeners can be removed regardless of the connection state.
594     * @param l The <code>VoiceCountListener</code> to remove.
595     */
596     public synchronized void
597     removeVoiceCountListener(VoiceCountListener l) {
598     boolean b = llVC.remove(l);
599     if(b && llVC.isEmpty()) unsubscribe("VOICE_COUNT");
600     }
601    
602     /**
603     * Gets the number of all audio output drivers currently
604     * available for the LinuxSampler instance.
605     * @return The number of all audio output drivers currently
606     * available for the LinuxSampler instance.
607     * @throws IOException If some I/O error occurs.
608     * @throws LscpException If LSCP protocol corruption occurs.
609     * @throws LSException If some other error occurs.
610     */
611     public synchronized int
612     getAudioOutputDriverCount() throws IOException, LscpException, LSException {
613     verifyConnection();
614     out.writeLine("GET AVAILABLE_AUDIO_OUTPUT_DRIVERS");
615     String s = getSingleLineResultSet().getResult();
616     return parseInt(s);
617     }
618     /**
619     * Gets all audio output drivers currently available for the LinuxSampler instance.
620     *
621     * @return <code>String</code> array with all audio output drivers currently available for
622     * the LinuxSampler instance.
623     *
624     * @throws IOException If an I/O error occurs.
625     * @throws LscpException If LSCP protocol corruption occurs.
626     * @throws LSException If some other error occurs.
627     */
628     public synchronized String[]
629     getAudioOutputDrivers() throws IOException, LscpException, LSException {
630     verifyConnection();
631     out.writeLine("LIST AVAILABLE_AUDIO_OUTPUT_DRIVERS");
632     return parseList(getSingleLineResultSet().getResult());
633     }
634    
635     /**
636     * Gets detailed information about a specific audio output driver.
637     * @param driverName The name of the audio output driver.
638     *
639     * @return An <code>AudioOutputDriver</code> object containing
640     * information about the specified audio output driver.
641     *
642     * @throws IOException If an I/O error occurs.
643     * @throws LscpException If LSCP protocol corruption occurs.
644     * @throws LSException If there is no driver with name <code>driverName</code>.
645     *
646     * @see #getAudioOutputDrivers
647     */
648     public synchronized AudioOutputDriver
649     getAudioOutputDriverInfo(String driverName) throws IOException, LscpException, LSException {
650     verifyConnection();
651     out.writeLine("GET AUDIO_OUTPUT_DRIVER INFO " + driverName);
652     ResultSet rs = getMultiLineResultSet();
653     AudioOutputDriver aod = new AudioOutputDriver(rs.getMultiLineResult());
654     aod.setName(driverName);
655    
656     for(String s : aod.getParameterNames())
657     aod.addParameter(getAudioOutputDriverParameterInfo(driverName, s));
658    
659     return aod;
660     }
661    
662     /**
663     * Gets detailed information about a specific audio output driver parameter.
664     *
665     * @param driver The name of the audio output driver.
666     * @param param A specific parameter name for which information should be obtained.
667     * @param deplist An optional list of parameters on which the sought parameter
668     * <code>param</code> depends on. <code>Parameter</code> instances can be
669     * easily created using {@link ParameterFactory} factory.
670     *
671     * @return <code>Parameter</code> object containing
672     * information about the specified audio output driver parameter.
673     *
674     * @throws IOException If an I/O error occurs.
675     * @throws LscpException If LSCP protocol corruption occurs.
676     * @throws LSException If <code>driver</code> is not a valid driver name
677     * or <code>param</code> is not a valid parameter for the specified driver.
678     *
679     * @see #getAudioOutputDrivers
680     * @see #getAudioOutputDriverInfo
681     * @see ParameterFactory
682     */
683     public synchronized Parameter
684     getAudioOutputDriverParameterInfo(String driver, String param, Parameter... deplist)
685     throws IOException, LscpException, LSException {
686    
687     verifyConnection();
688     StringBuffer args = new StringBuffer(driver);
689     args.append(' ').append(param);
690    
691     for(Parameter p : deplist)
692     args.append(' ').append(p.getName()).append('=').append(p.getStringValue());
693    
694     out.writeLine("GET AUDIO_OUTPUT_DRIVER_PARAMETER INFO " + args.toString());
695    
696     ResultSet rs = getMultiLineResultSet();
697    
698     String[] lnS = rs.getMultiLineResult();
699     ParameterType type = parseType(lnS);
700     boolean multi = parseMultiplicity(lnS);
701     Parameter prm;
702    
703     switch(type) {
704     case BOOL:
705     if(!multi) prm = new BoolParameter(lnS);
706     else prm = new BoolListParameter(lnS);
707     prm.setName(param);
708     return prm;
709     case INT:
710     if(!multi) prm = new IntParameter(lnS);
711     else prm = new IntListParameter(lnS);
712     prm.setName(param);
713     return prm;
714     case FLOAT:
715     if(!multi) prm = new FloatParameter(lnS);
716     else prm = new FloatListParameter(lnS);
717     prm.setName(param);
718     return prm;
719     case STRING:
720     if(!multi) prm = new StringParameter(lnS);
721     else prm = new StringListParameter(lnS);
722     prm.setName(param);
723     return prm;
724     default: throw new LscpException(LscpI18n.getLogMsg("Client.unknownPrmType!"));
725     }
726     }
727    
728     /**
729     * Creates a new audio output device for the desired audio output system.
730     * @param aoDriver The desired audio output system.
731     * @param paramList An optional list of driver specific parameters. <code>Parameter</code>
732     * instances can be easily created using {@link ParameterFactory} factory.
733     * @return The numerical ID of the newly created device.
734     * @throws IOException If some I/O error occurs.
735     * @throws LSException If the creation of the new audio output device failed.
736     * @throws LscpException If LSCP protocol corruption occurs.
737     * @see #getAudioOutputDrivers
738     * @see #getAudioOutputDriverInfo
739     * @see ParameterFactory
740     */
741     public synchronized int
742     createAudioOutputDevice(String aoDriver, Parameter... paramList)
743     throws IOException, LSException, LscpException {
744    
745     verifyConnection();
746     StringBuffer args = new StringBuffer(aoDriver);
747    
748     for(Parameter p : paramList)
749     args.append(' ').append(p.getName()).append('=').append(p.getStringValue());
750    
751     out.writeLine("CREATE AUDIO_OUTPUT_DEVICE " + args.toString());
752     ResultSet rs = getEmptyResultSet();
753    
754     return rs.getIndex();
755     }
756    
757     /**
758     * Destroys already created audio output device.
759     * @param deviceID The ID of the audio output device to be destroyed.
760     * @throws IOException If some I/O error occurs.
761     * @throws LSException If the destroying of the audio output device failed.
762     * @throws LscpException If LSCP protocol corruption occurs.
763     * @see #getAudioOutputDevices
764     */
765     public synchronized void
766     destroyAudioOutputDevice(int deviceID) throws IOException, LSException, LscpException {
767     verifyConnection();
768     out.writeLine("DESTROY AUDIO_OUTPUT_DEVICE " + deviceID);
769     ResultSet rs = getEmptyResultSet();
770     }
771    
772     /**
773     * Gets the current number of all created audio output devices.
774     * @return The current number of all created audio output devices.
775     * @throws IOException If some I/O error occurs.
776     * @throws LscpException If LSCP protocol corruption occurs.
777     * @throws LSException If some other error occurs.
778     */
779     public synchronized int
780     getAudioOutputDeviceCount() throws IOException, LscpException, LSException {
781     verifyConnection();
782     out.writeLine("GET AUDIO_OUTPUT_DEVICES");
783     String s = getSingleLineResultSet().getResult();
784     return parseInt(s);
785     }
786    
787     /**
788     * Gets a list of numerical IDs of all created audio output devices.
789     * @return An <code>Integer</code> array with numerical IDs of
790     * all created audio output devices.
791     * @throws IOException If some I/O error occurs.
792     * @throws LscpException If LSCP protocol corruption occurs.
793     * @throws LSException If some other error occurs.
794     */
795     public synchronized Integer[]
796     getAudioOutputDevices() throws IOException, LscpException, LSException {
797     verifyConnection();
798     out.writeLine("LIST AUDIO_OUTPUT_DEVICES");
799     return parseIntList(getSingleLineResultSet().getResult());
800     }
801    
802     /**
803     * Gets the current settings of a specific, already created audio output device.
804     *
805     * @param deviceID Specifies the numerical ID of the audio output device.
806     *
807     * @return An <code>AudioOutputDevice</code> instance containing information
808     * about the specified device.
809     *
810     * @throws IOException If some I/O error occurs.
811     * @throws LscpException If LSCP protocol corruption occurs.
812     * @throws LSException If there is no audio output device
813     * with device id <code>deviceID</code>.
814     *
815     * @see #getAudioOutputDevices
816     */
817     public synchronized AudioOutputDevice
818     getAudioOutputDeviceInfo(int deviceID) throws IOException, LscpException, LSException {
819     verifyConnection();
820     out.writeLine("GET AUDIO_OUTPUT_DEVICE INFO " + deviceID);
821    
822     ResultSet rs = getMultiLineResultSet();
823    
824     String[] lnS = rs.getMultiLineResult();
825    
826     AudioOutputDevice aod = new AudioOutputDevice();
827     Parameter<Integer> channels;
828     Parameter<Integer> samplerate;
829    
830     String drv = getCategoryInfo(lnS, "DRIVER");
831     aod.setDriverName(drv);
832    
833     for(String s : lnS) {
834     if(s.startsWith("CHANNELS: ")) {
835     channels = (Parameter<Integer>)
836     getAudioOutputDriverParameterInfo(drv, "CHANNELS");
837    
838     s = s.substring("CHANNELS: ".length(), s.length());
839     channels.parseValue(s);
840     aod.setChannelsParameter(channels);
841     } else if(s.startsWith("SAMPLERATE: ")) {
842     samplerate = (Parameter<Integer>)
843     getAudioOutputDriverParameterInfo(drv, "SAMPLERATE");
844    
845     s = s.substring("SAMPLERATE: ".length(), s.length());
846     samplerate.parseValue(s);
847     aod.setSampleRateParameter(samplerate);
848     } else if(s.startsWith("ACTIVE: ")) {
849     s = s.substring("ACTIVE: ".length(), s.length());
850     aod.setActive(Boolean.parseBoolean(s));
851     } else if(s.startsWith("DRIVER: ")) {
852    
853     } else {
854     int i = s.indexOf(": ");
855     if(i == -1) throw new LscpException (
856     LscpI18n.getLogMsg("CommandFailed!")
857     );
858    
859     Parameter prm =
860     getAudioOutputDriverParameterInfo(drv, s.substring(0, i));
861    
862     s = s.substring(i + 2);
863     prm.parseValue(s);
864    
865     aod.addParameter(prm);
866     }
867     }
868    
869     return aod;
870     }
871    
872     /**
873     * Alters a specific setting of a created audio output device.
874     *
875     * @param deviceID The numerical ID of the audio output device.
876     * @param prm A <code>Parameter</code> instance containing the name of the parameter
877     * and the new value for this parameter.
878     *
879     * @throws IOException If some I/O error occurs.
880     * @throws LscpException If LSCP protocol corruption occurs.
881     * @throws LSException If
882     * <ul>
883     * <li>There is no audio output device with numerical ID <code>deviceID</code>;
884     * <li>There is no device parameter with the specified name;
885     * <li>The device parameter is readonly;
886     * <li>The device parameter is from different type.
887     * </ul>
888     *
889     * @see #getAudioOutputDevices
890     * @see #getAudioOutputDeviceInfo
891     */
892     public synchronized void
893     setAudioOutputDeviceParameter(int deviceID, Parameter prm)
894     throws IOException, LscpException, LSException {
895    
896     verifyConnection();
897     String kv = prm.getName() + '=' + prm.getStringValue();
898     out.writeLine("SET AUDIO_OUTPUT_DEVICE_PARAMETER " + deviceID + ' ' + kv);
899    
900     ResultSet rs = getEmptyResultSet();
901     }
902    
903     /**
904     * Gets information about an audio channel.
905     *
906     * @param deviceID The numerical ID of the audio output device.
907     * @param audioChn The audio channel number.
908     *
909     * @return An <code>AudioOutputChannel</code> instance containing the
910     * information about the specified audio output channel.
911     *
912     * @throws IOException If some I/O error occurs.
913     * @throws LscpException If LSCP protocol corruption occurs.
914     * @throws LSException If
915     * <ul>
916     * <li>There is no audio output device with numerical ID <code>deviceID</code>;
917     * <li><code>audioChn</code> is not a valid channel number;
918     * </ul>
919     *
920     * @see #getAudioOutputDevices
921     * @see #getAudioOutputDeviceInfo
922     */
923     public synchronized AudioOutputChannel
924     getAudioOutputChannelInfo(int deviceID, int audioChn)
925     throws IOException, LscpException, LSException {
926    
927     verifyConnection();
928     out.writeLine("GET AUDIO_OUTPUT_CHANNEL INFO " + deviceID + ' ' + audioChn);
929    
930     ResultSet rs = getMultiLineResultSet();
931    
932     AudioOutputChannel aoc = new AudioOutputChannel();
933    
934     String[] lnS = rs.getMultiLineResult();
935     for(String s : lnS) {
936     if(s.startsWith("NAME: ")) {
937     aoc.setName(s.substring("NAME: ".length()));
938     } else if(s.startsWith("IS_MIX_CHANNEL: ")) {
939     s = s.substring("IS_MIX_CHANNEL: ".length());
940    
941     aoc.setMixChannel(Boolean.parseBoolean(s));
942     } else if(s.startsWith("MIX_CHANNEL_DESTINATION: ")) {
943     s = s.substring("MIX_CHANNEL_DESTINATION: ".length());
944     aoc.setMixChannelDest(parseInt(s));
945     } else {
946     int i = s.indexOf(": ");
947     if(i == -1) throw new LscpException (
948     LscpI18n.getLogMsg("CommandFailed!")
949     );
950    
951     Parameter prm = getAudioOutputChannelParameterInfo (
952     deviceID, audioChn, s.substring(0, i)
953     );
954    
955     s = s.substring(i + 2);
956     prm.parseValue(s);
957    
958     aoc.addParameter(prm);
959     }
960     }
961    
962     return aoc;
963     }
964    
965     /**
966     * Gets detailed information about a specific audio output channel parameter.
967     *
968     * @param devID The numerical ID of the audio output device.
969     * @param chan The audio channel number.
970     * @param param a specific channel parameter name for which information should be obtained.
971     *
972     * @return An <code>Parameter</code> instance containing
973     * information about the specified audio output channel parameter.
974     *
975     * @throws IOException If an I/O error occurs.
976     * @throws LscpException If LSCP protocol corruption occurs.
977     * @throws LSException If
978     * <ul>
979     * <li><code>devID</code> is not a valid device ID;
980     * <li><code>chan</code> is not a valid channel number;
981     * <li>There is no channel parameter with the specified name.
982     * </ul>
983     *
984     * @see #getAudioOutputDevices
985     * @see #getAudioOutputChannelInfo
986     */
987     public synchronized Parameter
988     getAudioOutputChannelParameterInfo(int devID, int chan, String param)
989     throws IOException, LscpException, LSException {
990    
991     verifyConnection();
992     String args = devID + ' ' + chan + ' ' + param;
993     out.writeLine("GET AUDIO_OUTPUT_CHANNEL_PARAMETER INFO " + args);
994    
995     ResultSet rs = getMultiLineResultSet();
996    
997     String[] lnS = rs.getMultiLineResult();
998     ParameterType type = parseType(lnS);
999     boolean multi = parseMultiplicity(lnS);
1000     Parameter prm;
1001    
1002     switch(type) {
1003     case BOOL:
1004     if(!multi) prm = new BoolParameter(lnS);
1005     else prm = new BoolListParameter(lnS);
1006     prm.setName(param);
1007     return prm;
1008     case INT:
1009     if(!multi) prm = new IntParameter(lnS);
1010     else prm = new IntListParameter(lnS);
1011     prm.setName(param);
1012     return prm;
1013     case FLOAT:
1014     if(!multi) prm = new FloatParameter(lnS);
1015     else prm = new FloatListParameter(lnS);
1016     prm.setName(param);
1017     return prm;
1018     case STRING:
1019     if(!multi) prm = new StringParameter(lnS);
1020     else prm = new StringListParameter(lnS);
1021     prm.setName(param);
1022     return prm;
1023     default: throw new LscpException(LscpI18n.getLogMsg("Client.unknownPrmType!"));
1024     }
1025     }
1026    
1027     /**
1028     * Alters a specific setting of an audio output channel.
1029     *
1030     * @param devID The numerical ID of the audio device.
1031     * @param chn The audio channel number.
1032     * @param prm A <code>Parameter</code> instance containing the name of the parameter
1033     * and the new value for this parameter.
1034     *
1035     * @throws IOException If some I/O error occurs.
1036     * @throws LscpException If LSCP protocol corruption occurs.
1037     * @throws LSException If
1038     * <ul>
1039     * <li>There is no audio output device with numerical ID <code>devID</code>;
1040     * <li><code>chn</code> is not a valid channel number;
1041     * <li>There is no channel parameter with the specified name;
1042     * <li>The channel parameter is readonly;
1043     * <li>The channel parameter is from different type.
1044     * </ul>
1045     *
1046     * @see #getAudioOutputDevices
1047     * @see #getAudioOutputChannelInfo
1048     */
1049     public synchronized void
1050     setAudioOutputChannelParameter(int devID, int chn, Parameter prm)
1051     throws IOException, LscpException, LSException {
1052    
1053     verifyConnection();
1054     String args = devID + ' ' + chn + ' ' + prm.getName() + '=' + prm.getStringValue();
1055     out.writeLine("SET AUDIO_OUTPUT_CHANNEL_PARAMETER " + args);
1056    
1057     ResultSet rs = getEmptyResultSet();
1058     }
1059    
1060     /**
1061     * Gets the current number of all MIDI input drivers.
1062     * @return The current number of all MIDI input drivers.
1063     * @throws IOException If some I/O error occurs.
1064     * @throws LscpException If LSCP protocol corruption occurs.
1065     * @throws LSException If some other error occurs.
1066     */
1067     public synchronized int
1068     getMidiInputDriverCount() throws IOException, LscpException, LSException {
1069     verifyConnection();
1070     out.writeLine("GET AVAILABLE_MIDI_INPUT_DRIVERS");
1071     String s = getSingleLineResultSet().getResult();
1072     return parseInt(s);
1073     }
1074    
1075     /**
1076     * Gets all MIDI input drivers currently available for the LinuxSampler instance.
1077     *
1078     * @return <code>String</code> array with all MIDI input drivers currently available for
1079     * the LinuxSampler instance or <code>null</code> if there are no MIDI input drivers
1080     * currently available.
1081     *
1082     * @throws IOException If an I/O error occurs.
1083     * @throws LscpException If LSCP protocol corruption occurs.
1084     * @throws LSException If some other error occurs.
1085     */
1086     public synchronized String[]
1087     getMidiInputDrivers() throws IOException, LscpException, LSException {
1088     verifyConnection();
1089     out.writeLine("LIST AVAILABLE_MIDI_INPUT_DRIVERS");
1090     return parseList(getSingleLineResultSet().getResult());
1091     }
1092    
1093     /**
1094     * Gets detailed information about a specific MIDI input driver.
1095     * @param driverName The name of the MIDI input driver.
1096     *
1097     * @return An <code>MidiInputDriver</code> object containing
1098     * information about the specified MIDI input driver.
1099     *
1100     * @throws IOException If an I/O error occurs.
1101     * @throws LscpException If LSCP protocol corruption occurs.
1102     * @throws LSException If there is no driver with name <code>driverName</code>.
1103     *
1104     * @see #getMidiInputDrivers
1105     */
1106     public synchronized MidiInputDriver
1107     getMidiInputDriverInfo(String driverName) throws IOException, LscpException, LSException {
1108     verifyConnection();
1109     out.writeLine("GET MIDI_INPUT_DRIVER INFO " + driverName);
1110     ResultSet rs = getMultiLineResultSet();
1111    
1112     MidiInputDriver mid = new MidiInputDriver(rs.getMultiLineResult());
1113     mid.setName(driverName);
1114    
1115     for(String s : mid.getParameterNames())
1116     mid.addParameter(getMidiInputDriverParameterInfo(driverName, s));
1117    
1118     return mid;
1119     }
1120    
1121     /**
1122     * Gets detailed information about a specific MIDI input driver parameter.
1123     *
1124     * @param driver The name of the MIDI input driver.
1125     * @param param a specific parameter name for which information should be obtained.
1126     * @param deplist An optional list of parameters on which the sought parameter
1127     * <code>param</code> depends on. <code>Parameter</code> instances can be
1128     * easily created using {@link ParameterFactory} factory.
1129     *
1130     * @return An <code>Parameter</code> object containing
1131     * information about the specified MIDI input driver parameter.
1132     *
1133     * @throws IOException If an I/O error occurs.
1134     * @throws LscpException If LSCP protocol corruption occurs.
1135     * @throws LSException If <code>driver</code> is not a valid driver name
1136     * or <code>param</code> is not a valid parameter for the specified driver.
1137     *
1138     * @see #getMidiInputDrivers
1139     * @see #getMidiInputDriverInfo
1140     * @see ParameterFactory
1141     */
1142     public synchronized Parameter
1143     getMidiInputDriverParameterInfo(String driver, String param, Parameter... deplist)
1144     throws IOException, LscpException, LSException {
1145    
1146     verifyConnection();
1147     StringBuffer args = new StringBuffer(driver);
1148     args.append(' ').append(param);
1149    
1150     for(Parameter p : deplist)
1151     args.append(' ').append(p.getName()).append('=').append(p.getStringValue());
1152    
1153     out.writeLine("GET MIDI_INPUT_DRIVER_PARAMETER INFO " + args.toString());
1154    
1155     ResultSet rs = getMultiLineResultSet();
1156    
1157     String[] lnS = rs.getMultiLineResult();
1158     ParameterType type = parseType(lnS);
1159     boolean multi = parseMultiplicity(lnS);
1160     Parameter prm;
1161    
1162     switch(type) {
1163     case BOOL:
1164     if(!multi) prm = new BoolParameter(lnS);
1165     else prm = new BoolListParameter(lnS);
1166     prm.setName(param);
1167     return prm;
1168     case INT:
1169     if(!multi) prm = new IntParameter(lnS);
1170     else prm = new IntListParameter(lnS);
1171     prm.setName(param);
1172     return prm;
1173     case FLOAT:
1174     if(!multi) prm = new FloatParameter(lnS);
1175     else prm = new FloatListParameter(lnS);
1176     prm.setName(param);
1177     return prm;
1178     case STRING:
1179     if(!multi) prm = new StringParameter(lnS);
1180     else prm = new StringListParameter(lnS);
1181     prm.setName(param);
1182     return prm;
1183     default: throw new LscpException(LscpI18n.getLogMsg("Client.unknownPrmType!"));
1184     }
1185     }
1186    
1187     /**
1188     * Creates a new MIDI input device.
1189     * @param miDriver The desired MIDI input system.
1190     * @param paramList An optional list of driver specific parameters. <code>Parameter</code>
1191     * instances can be easily created using {@link ParameterFactory} factory.
1192     * @return The numerical ID of the newly created device.
1193     * @throws IOException If some I/O error occurs.
1194     * @throws LSException If the creation of the new MIDI input device failed.
1195     * @throws LscpException If LSCP protocol corruption occurs.
1196     *
1197     * @see #getMidiInputDrivers
1198     * @see #getMidiInputDriverInfo
1199     * @see ParameterFactory
1200     */
1201     public synchronized int
1202     createMidiInputDevice(String miDriver, Parameter... paramList)
1203     throws IOException, LSException, LscpException {
1204    
1205     verifyConnection();
1206     StringBuffer args = new StringBuffer(miDriver);
1207    
1208     for(Parameter p : paramList)
1209     args.append(' ').append(p.getName()).append('=').append(p.getStringValue());
1210    
1211     out.writeLine("CREATE MIDI_INPUT_DEVICE " + args.toString());
1212     ResultSet rs = getEmptyResultSet();
1213    
1214     return rs.getIndex();
1215     }
1216    
1217     /**
1218     * Destroys already created MIDI input device.
1219     * @param deviceID The numerical ID of the MIDI input device to be destroyed.
1220     * @throws IOException If some I/O error occurs.
1221     * @throws LSException If the destroying of the MIDI input device failed.
1222     * @throws LscpException If LSCP protocol corruption occurs.
1223     * @see #createMidiInputDevice
1224     * @see #getMidiInputDevices
1225     */
1226     public synchronized void
1227     destroyMidiInputDevice(int deviceID) throws IOException, LSException, LscpException {
1228     verifyConnection();
1229     out.writeLine("DESTROY MIDI_INPUT_DEVICE " + deviceID);
1230     ResultSet rs = getEmptyResultSet();
1231     }
1232    
1233     /**
1234     * Gets the current number of all created MIDI input devices.
1235     * @return The current number of all created MIDI input devices.
1236     * @throws IOException If some I/O error occurs.
1237     * @throws LscpException If LSCP protocol corruption occurs.
1238     * @throws LSException If some other error occurs.
1239     */
1240     public synchronized int
1241     getMidiInputDeviceCount() throws IOException, LscpException, LSException {
1242     verifyConnection();
1243     out.writeLine("GET MIDI_INPUT_DEVICES");
1244     String s = getSingleLineResultSet().getResult();
1245     return parseInt(s);
1246     }
1247    
1248     /**
1249     * Gets a list of numerical IDs of all created MIDI input devices.
1250     * @return An <code>Integer</code> array with numerical IDs of
1251     * all created MIDI input devices.
1252     * @throws IOException If some I/O error occurs.
1253     * @throws LscpException If LSCP protocol corruption occurs.
1254     * @throws LSException If some other error occurs.
1255     *
1256     * @see #createMidiInputDevice
1257     * @see #destroyMidiInputDevice
1258     */
1259     public synchronized Integer[]
1260     getMidiInputDevices() throws IOException, LscpException, LSException {
1261     verifyConnection();
1262     out.writeLine("LIST MIDI_INPUT_DEVICES");
1263     return parseIntList(getSingleLineResultSet().getResult());
1264     }
1265    
1266     /**
1267     * Gets the current settings of a specific, already created MIDI input device.
1268     *
1269     * @param deviceID Specifies the numerical ID of the MIDI input device.
1270     *
1271     * @return An <code>MidiInputDevice</code> instance containing information
1272     * about the specified device.
1273     *
1274     * @throws IOException If some I/O error occurs.
1275     * @throws LscpException If LSCP protocol corruption occurs.
1276     * @throws LSException If there is no MIDI input device
1277     * with device id <code>deviceID</code>.
1278     *
1279     * @see #getMidiInputDevices
1280     */
1281     public synchronized MidiInputDevice
1282     getMidiInputDeviceInfo(int deviceID) throws IOException, LscpException, LSException {
1283     verifyConnection();
1284     out.writeLine("GET MIDI_INPUT_DEVICE INFO " + deviceID);
1285    
1286     ResultSet rs = getMultiLineResultSet();
1287    
1288     String[] lnS = rs.getMultiLineResult();
1289    
1290     MidiInputDevice mid = new MidiInputDevice();
1291    
1292     String drv = getCategoryInfo(lnS, "DRIVER");
1293     mid.setDriverName(drv);
1294    
1295     for(String s : lnS) {
1296     if(s.startsWith("DRIVER: ")) {
1297    
1298     } else if(s.startsWith("ACTIVE: ")) {
1299     s = s.substring("ACTIVE: ".length());
1300     mid.setActive(Boolean.parseBoolean(s));
1301     } else {
1302     int i = s.indexOf(": ");
1303     if(i == -1) throw new LscpException (
1304     LscpI18n.getLogMsg("CommandFailed!")
1305     );
1306    
1307     Parameter prm =
1308     getMidiInputDriverParameterInfo(drv, s.substring(0, i));
1309    
1310     s = s.substring(i + 2);
1311     prm.parseValue(s);
1312    
1313     mid.addParameter(prm);
1314     }
1315     }
1316    
1317     return mid;
1318     }
1319    
1320     /**
1321     * Alters a specific setting of a created MIDI input device.
1322     *
1323     * @param deviceID The numerical ID of the MIDI input device.
1324     * @param prm A <code>Parameter</code> instance containing the name of the parameter
1325     * and the new value for this parameter.
1326     *
1327     * @throws IOException If some I/O error occurs.
1328     * @throws LscpException If LSCP protocol corruption occurs.
1329     * @throws LSException If
1330     * <ul>
1331     * <li>There is no MIDI input device with numerical ID <code>deviceID</code>;
1332     * <li>There is no device parameter with the specified name;
1333     * <li>The device parameter is readonly;
1334     * <li>The device parameter is from different type.
1335     * </ul>
1336     *
1337     * @see #getMidiInputDevices
1338     * @see #getMidiInputDeviceInfo
1339     */
1340     public synchronized void
1341     setMidiInputDeviceParameter(int deviceID, Parameter prm)
1342     throws IOException, LscpException, LSException {
1343    
1344     verifyConnection();
1345     String kv = prm.getName() + '=' + prm.getStringValue();
1346     out.writeLine("SET MIDI_INPUT_DEVICE_PARAMETER " + deviceID + ' ' + kv);
1347    
1348     ResultSet rs = getEmptyResultSet();
1349     }
1350    
1351     /**
1352     * Gets detailed information about a specific MIDI input port.
1353     * @param deviceID The numerical ID of the MIDI input device.
1354     * @param midiPort The MIDI input port number.
1355     *
1356     * @return A <code>MidiPort</code> instance containing
1357     * information about the specified MIDI input port.
1358     *
1359     * @throws IOException If an I/O error occurs.
1360     * @throws LscpException If LSCP protocol corruption occurs.
1361     * @throws LSException If there is no device with ID <code>deviceID</code> or
1362     * if <code>midiPort</code> is not a valid MIDI port number.
1363     *
1364     * @see #getMidiInputDevices
1365     */
1366     public synchronized MidiPort
1367     getMidiInputPortInfo(int deviceID, int midiPort)
1368     throws IOException, LscpException, LSException {
1369    
1370     verifyConnection();
1371     out.writeLine("GET MIDI_INPUT_PORT INFO " + deviceID + " " + midiPort);
1372     ResultSet rs = getMultiLineResultSet();
1373    
1374     MidiPort mp = new MidiPort();
1375     String[] lnS = rs.getMultiLineResult();
1376    
1377     for(String s : lnS) {
1378     if(s.startsWith("NAME: ")) {
1379     mp.setName(s.substring("NAME: ".length()));
1380     } else {
1381     int i = s.indexOf(": ");
1382     if(i == -1) throw new LscpException (
1383     LscpI18n.getLogMsg("CommandFailed!")
1384     );
1385    
1386     Parameter prm = getMidiInputPortParameterInfo (
1387     deviceID, midiPort, s.substring(0, i)
1388     );
1389    
1390     s = s.substring(i + 2);
1391     prm.parseValue(s);
1392    
1393     mp.addParameter(prm);
1394     }
1395     }
1396    
1397     return mp;
1398     }
1399    
1400     /**
1401     * Gets detailed information about a specific MIDI input port parameter.
1402     *
1403     * @param deviceID The numerical ID of the MIDI input device.
1404     * @param port The MIDI port number.
1405     * @param param A specific parameter name for which information should be obtained.
1406     *
1407     * @return A <code>Parameter</code> instance containing
1408     * information about the specified MIDI input port parameter.
1409     *
1410     * @throws IOException If an I/O error occurs.
1411     * @throws LscpException If LSCP protocol corruption occurs.
1412     * @throws LSException If
1413     * <ul>
1414     * <li>There is no MIDI input device with numerical ID <code>deviceID</code>;
1415     * <li> <code>port</code> is not a valid MIDI port number;
1416     * <li><code>param</code> is not a valid parameter for the specified MIDI port.
1417     * </ul>
1418     *
1419     * @see #getMidiInputDevices
1420     * @see #getMidiInputPortInfo
1421     */
1422     public synchronized Parameter
1423     getMidiInputPortParameterInfo(int deviceID, int port, String param)
1424     throws IOException, LscpException, LSException {
1425    
1426     verifyConnection();
1427     String args = deviceID + " " + port + " " + param;
1428     out.writeLine("GET MIDI_INPUT_PORT_PARAMETER INFO " + args);
1429    
1430     ResultSet rs = getMultiLineResultSet();
1431    
1432     String[] lnS = rs.getMultiLineResult();
1433     ParameterType type = parseType(lnS);
1434     boolean multi = parseMultiplicity(lnS);
1435     Parameter prm;
1436    
1437     switch(type) {
1438     case BOOL:
1439     if(!multi) prm = new BoolParameter(lnS);
1440     else prm = new BoolListParameter(lnS);
1441     prm.setName(param);
1442     return prm;
1443     case INT:
1444     if(!multi) prm = new IntParameter(lnS);
1445     else prm = new IntListParameter(lnS);
1446     prm.setName(param);
1447     return prm;
1448     case FLOAT:
1449     if(!multi) prm = new FloatParameter(lnS);
1450     else prm = new FloatListParameter(lnS);
1451     prm.setName(param);
1452     return prm;
1453     case STRING:
1454     if(!multi) prm = new StringParameter(lnS);
1455     else prm = new StringListParameter(lnS);
1456     prm.setName(param);
1457     return prm;
1458     default: throw new LscpException(LscpI18n.getLogMsg("Client.unknownPrmType!"));
1459     }
1460     }
1461    
1462     /**
1463     * Alters a specific setting of a MIDI input port.
1464     *
1465     * @param deviceID The numerical ID of the MIDI device.
1466     * @param port The MIDI port number.
1467     * @param prm A <code>Parameter</code> instance containing the name of the parameter
1468     * and the new value for this parameter.
1469     *
1470     * @throws IOException If some I/O error occurs.
1471     * @throws LscpException If LSCP protocol corruption occurs.
1472     * @throws LSException If
1473     * <ul>
1474     * <li>There is no MIDI device with numerical ID <code>deviceID</code>;
1475     * <li><code>port</code> is not a valid MIDI port number;
1476     * <li><code>prm</code> is not a valid parameter;
1477     * <li>The parameter is readonly;
1478     * <li>The parameter is from different type.
1479     * </ul>
1480     *
1481     * @see #getMidiInputDevices
1482     * @see #getMidiInputPortInfo
1483     */
1484     public synchronized void
1485     setMidiInputPortParameter(int deviceID, int port, Parameter prm)
1486     throws IOException, LscpException, LSException {
1487    
1488     verifyConnection();
1489     String args = deviceID + ' ' + port + ' ' +
1490     prm.getName() + '=' + prm.getStringValue();
1491     out.writeLine("SET MIDI_INPUT_PORT_PARAMETER " + args);
1492    
1493     ResultSet rs = getEmptyResultSet();
1494     }
1495    
1496     /**
1497     * Loads and assigns an instrument to a sampler channel. Notice that this function will
1498     * return after the instrument is fully loaded and the channel is ready to be used.
1499     *
1500     * @param filename The name of the instrument file
1501     * on the LinuxSampler instance's host system.
1502     * @param instrIdx The index of the instrument in the instrument file.
1503     * @param samplerChn The number of the sampler channel the instrument should be assigned to.
1504     *
1505     * @throws IOException If some I/O error occurs.
1506     * @throws LscpException If LSCP protocol corruption occurs.
1507     * @throws LSException If the loading of the instrument failed.
1508     *
1509     * @see #loadInstrument(String, int, int, boolean)
1510     * @see #getSamplerChannels
1511     */
1512     public synchronized void
1513     loadInstrument(String filename, int instrIdx, int samplerChn)
1514     throws IOException, LscpException, LSException {
1515    
1516     verifyConnection();
1517     loadInstrument(filename, instrIdx, samplerChn, false);
1518     }
1519    
1520     /**
1521     * Loads and assigns an instrument to a sampler channel.
1522     *
1523     * @param filename The name of the instrument file
1524     * on the LinuxSampler instance's host system.
1525     * @param instrIdx The index of the instrument in the instrument file.
1526     * @param samplerChn The number of the sampler channel the instrument should be assigned to.
1527     * @param nonModal If <code>false</code> the function will return after the instrument
1528     * has been fully loaded and the channel is ready to be used. If <code>true</code>
1529     * the function returns immediately.
1530     *
1531     * @throws IOException If some I/O error occurs.
1532     * @throws LscpException If LSCP protocol corruption occurs.
1533     * @throws LSException If the loading of the instrument failed.
1534     *
1535     * @see #loadInstrument(String, int, int)
1536     * @see #getSamplerChannels
1537     */
1538     public synchronized void
1539     loadInstrument(String filename, int instrIdx, int samplerChn, boolean nonModal)
1540     throws IOException, LscpException, LSException {
1541    
1542     String cmd = nonModal ? "LOAD INSTRUMENT NON_MODAL " : "LOAD INSTRUMENT ";
1543     String args = '\'' + filename + "' " + instrIdx + ' ' + samplerChn;
1544    
1545     out.writeLine(cmd + args);
1546    
1547     ResultSet rs = getEmptyResultSet();
1548     }
1549    
1550     /**
1551     * Loads a sampler engine to a specific sampler channel.
1552     * @param engineName The name of the engine.
1553     * @param samplerChn The number of the sampler channel
1554     * the deployed engine should be assigned to.
1555     *
1556     * @throws IOException If some I/O error occurs.
1557     * @throws LscpException If LSCP protocol corruption occurs.
1558     * @throws LSException If the loading of the sampler engine failed.
1559     * @see #getEngines
1560     * @see #getSamplerChannels
1561     */
1562     public synchronized void
1563     loadSamplerEngine(String engineName, int samplerChn)
1564     throws IOException, LscpException, LSException {
1565    
1566     verifyConnection();
1567     out.writeLine("LOAD ENGINE " + engineName + ' ' + samplerChn);
1568    
1569     ResultSet rs = getEmptyResultSet();
1570     }
1571    
1572     /**
1573     * Gets the current number of all created sampler channels.
1574     * @return The current number of all created sampler channels.
1575     * @throws IOException If some I/O error occurs.
1576     * @throws LscpException If LSCP protocol corruption occurs.
1577     * @throws LSException If some other error occurs.
1578     */
1579     public synchronized int
1580     getSamplerChannelCount() throws IOException, LscpException, LSException {
1581     verifyConnection();
1582     out.writeLine("GET CHANNELS");
1583     String s = getSingleLineResultSet().getResult();
1584     return parseInt(s);
1585     }
1586    
1587     /**
1588     * Gets a list with numerical IDs of all created sampler channels.
1589     * @return An <code>Integer</code> array with numerical IDs of all created sampler channels.
1590     * @throws IOException If some I/O error occurs.
1591     * @throws LscpException If LSCP protocol corruption occurs.
1592     * @throws LSException If some other error occurs.
1593     * @see #addSamplerChannel
1594     * @see #removeSamplerChannel
1595     */
1596     public synchronized Integer[]
1597     getSamplerChannels() throws IOException, LscpException, LSException {
1598     verifyConnection();
1599     out.writeLine("LIST CHANNELS");
1600     return parseIntList(getSingleLineResultSet().getResult());
1601     }
1602    
1603     /**
1604     * Adds a new sampler channel. This method will increment the sampler channel count by one
1605     * and the new sampler channel will be appended to the end of the sampler channel list.
1606     *
1607     * @return The number of the newly created sampler channel.
1608     * @throws IOException If some I/O error occurs.
1609     * @throws LSException If the creation of the new sampler channel failed.
1610     * @throws LscpException If LSCP protocol corruption occurs.
1611     * @see #removeSamplerChannel
1612     */
1613     public synchronized int
1614     addSamplerChannel() throws IOException, LSException, LscpException {
1615     verifyConnection();
1616     out.writeLine("ADD CHANNEL");
1617     ResultSet rs = getEmptyResultSet();
1618    
1619     return rs.getIndex();
1620     }
1621    
1622     /**
1623     * Removes the specified sampler channel.
1624     *
1625     * @param samplerChn The numerical ID of the sampler channel to be removed.
1626     *
1627     * @throws IOException If some I/O error occurs.
1628     * @throws LscpException If LSCP protocol corruption occurs.
1629     * @throws LSException If the removing of the sampler channel failed.
1630     * @see #addSamplerChannel
1631     * @see #getSamplerChannels
1632     */
1633     public synchronized void
1634     removeSamplerChannel(int samplerChn) throws IOException, LscpException, LSException {
1635     verifyConnection();
1636     out.writeLine("REMOVE CHANNEL " + samplerChn);
1637    
1638     ResultSet rs = getEmptyResultSet();
1639     }
1640    
1641     /**
1642     * Gets the number of all available engines.
1643     * @return The number of all available engines.
1644     * @throws IOException If some I/O error occurs.
1645     * @throws LscpException If LSCP protocol corruption occurs.
1646     * @throws LSException If some other error occurs.
1647     */
1648     public synchronized int
1649     getEngineCount() throws IOException, LscpException, LSException {
1650     verifyConnection();
1651     out.writeLine("GET AVAILABLE_ENGINES");
1652     String s = getSingleLineResultSet().getResult();
1653     return parseInt(s);
1654     }
1655    
1656     /**
1657     * Gets a list of all available engines' names.
1658     *
1659     * @return <code>String</code> array with all available engines' names.
1660     * @throws IOException If some I/O error occurs.
1661     * @throws LscpException If LSCP protocol corruption occurs.
1662     * @throws LSException If some other error occurs.
1663     */
1664     public synchronized String[]
1665     getEngines() throws IOException, LscpException, LSException {
1666     verifyConnection();
1667     out.writeLine("LIST AVAILABLE_ENGINES");
1668     return parseStringList(getSingleLineResultSet().getResult());
1669     }
1670    
1671     /**
1672     * Gets information about a specific sampler engine.
1673     * @param engineName The name of the sampler engine.
1674     *
1675     * @return <code>SamplerEngine</code> instance containing
1676     * information about the specified sampler engine.
1677     *
1678     * @throws IOException If an I/O error occurs.
1679     * @throws LscpException If LSCP protocol corruption occurs.
1680     * @throws LSException If there is no sampler engine with name <code>engineName</code>.
1681     * @see #getEngines
1682     */
1683     public synchronized SamplerEngine
1684     getEngineInfo(String engineName) throws IOException, LscpException, LSException {
1685     verifyConnection();
1686     out.writeLine("GET ENGINE INFO " + engineName);
1687     ResultSet rs = getMultiLineResultSet();
1688     SamplerEngine se = new SamplerEngine(rs.getMultiLineResult());
1689     se.setName(engineName);
1690     return se;
1691     }
1692    
1693     /**
1694     * Gets the current settings of the specified sampler channel.
1695     * @param samplerChn The sampler channel number.
1696     *
1697     * @return <code>SamplerChannel</code> instance containing
1698     * the current settings of the specified sampler channel.
1699     *
1700     * @throws IOException If an I/O error occurs.
1701     * @throws LscpException If LSCP protocol corruption occurs.
1702     * @throws LSException If there is no sampler channel with <code>samplerChn</code> number.
1703     * @see #getSamplerChannels
1704     */
1705     public synchronized SamplerChannel
1706     getSamplerChannelInfo(int samplerChn) throws IOException, LscpException, LSException {
1707     verifyConnection();
1708     out.writeLine("GET CHANNEL INFO " + samplerChn);
1709     ResultSet rs = getMultiLineResultSet();
1710     SamplerChannel sc = new SamplerChannel(rs.getMultiLineResult());
1711     sc.setChannelID(samplerChn);
1712    
1713     return sc;
1714     }
1715    
1716     /**
1717     * Gets the current number of active voices on the specified sampler channel.
1718     *
1719     * @param samplerChn The sampler channel number.
1720     * @return The current number of active voices on the specified sampler channel.
1721     * @throws IOException If some I/O error occurs.
1722     * @throws LscpException If LSCP protocol corruption occurs.
1723     * @throws LSException If there is no sampler channel with number <code>samplerChn</code>.
1724     * @see #getSamplerChannels
1725     */
1726     public synchronized int
1727     getChannelVoiceCount(int samplerChn) throws IOException, LscpException, LSException {
1728     verifyConnection();
1729     out.writeLine("GET CHANNEL VOICE_COUNT " + samplerChn);
1730     ResultSet rs = getSingleLineResultSet();
1731    
1732     return parseInt(rs.getResult());
1733     }
1734    
1735     /**
1736     * Gets the current number of active disk streams on the specified sampler channel.
1737     *
1738     * @param samplerChn The sampler channel number.
1739     * @return The current number of active disk streams on the specified sampler channel
1740     * or -1 if the engine doesn't support disk streaming.
1741     * @throws IOException If some I/O error occurs.
1742     * @throws LscpException If LSCP protocol corruption occurs.
1743     * @throws LSException If there is no sampler channel with number <code>samplerChn</code>.
1744     * @see #getSamplerChannels
1745     */
1746     public synchronized int
1747     getChannelStreamCount(int samplerChn) throws IOException, LscpException, LSException {
1748     verifyConnection();
1749     out.writeLine("GET CHANNEL STREAM_COUNT " + samplerChn);
1750     ResultSet rs = getSingleLineResultSet();
1751    
1752     if(rs.getResult().equals("NA")) return -1;
1753    
1754     return parseInt(rs.getResult());
1755     }
1756    
1757     /**
1758     * Gets the current fill state of all disk streams on the specified sampler channel
1759     * in bytes.
1760     *
1761     * @param samplerChn The sampler channel number.
1762     * @return The current fill state of all disk streams on the specified sampler channel
1763     * or <code>null</code> if the engine which is deployed doesn't support disk streaming.
1764     * @throws IOException If some I/O error occurs.
1765     * @throws LscpException If LSCP protocol corruption occurs.
1766     * @throws LSException If there is no sampler channel with number <code>samplerChn</code>.
1767     * @see #getChannelBufferFillPercentage
1768     * @see #getSamplerChannels
1769     */
1770     public synchronized Vector<BufferFill>
1771     getChannelBufferFillBytes(int samplerChn) throws IOException, LscpException, LSException {
1772     verifyConnection();
1773     out.writeLine("GET CHANNEL BUFFER_FILL BYTES " + samplerChn);
1774     ResultSet rs = getSingleLineResultSet();
1775    
1776     if(rs.getResult().equals("NA")) return null;
1777    
1778     Vector<BufferFill> v = new Vector<BufferFill>();
1779     String[] args = parseList(rs.getResult());
1780    
1781     for(String s : args) {
1782     if(s.charAt(0) != '[')
1783     throw new LscpException(LscpI18n.getLogMsg("CommandFailed!"));
1784    
1785     int i = s.indexOf(']');
1786     if(i == -1) throw new LscpException(LscpI18n.getLogMsg("CommandFailed!"));
1787    
1788     BufferFill bf = new BufferFill();
1789     bf.setStreamID(parseInt(s.substring(1, i)));
1790     bf.setValue(parseInt(s.substring(i + 1)));
1791     v.add(bf);
1792     }
1793    
1794     return v;
1795     }
1796    
1797     /**
1798     * Gets the current fill state of all disk streams on the specified sampler channel
1799     * in percent.
1800     *
1801     * @param samplerChn The sampler channel number.
1802     * @return The current fill state of all disk streams on the specified sampler channel
1803     * or <code>null</code> if the engine which is deployed doesn't support disk streaming.
1804     * @throws IOException If some I/O error occurs.
1805     * @throws LscpException If LSCP protocol corruption occurs.
1806     * @throws LSException If there is no sampler channel with number <code>samplerChn</code>.
1807     * @see #getChannelBufferFillBytes
1808     * @see #getSamplerChannels
1809     */
1810     public synchronized Vector<BufferFill>
1811     getChannelBufferFillPercentage(int samplerChn)
1812     throws IOException, LscpException, LSException {
1813    
1814     verifyConnection();
1815     out.writeLine("GET CHANNEL BUFFER_FILL PERCENTAGE " + samplerChn);
1816     ResultSet rs = getSingleLineResultSet();
1817    
1818     return getChannelBufferFillPercentage(rs.getResult());
1819     }
1820    
1821     private Vector<BufferFill>
1822     getChannelBufferFillPercentage(String ln) throws LscpException {
1823     if(ln.equals("NA")) return null;
1824    
1825     Vector<BufferFill> v = new Vector<BufferFill>();
1826     String[] args = parseList(ln);
1827    
1828     for(String s : args) {
1829     if(s.charAt(0) != '[')
1830     throw new LscpException(LscpI18n.getLogMsg("CommandFailed!"));
1831    
1832     int i = s.indexOf(']');
1833     if(i == -1) throw new LscpException(LscpI18n.getLogMsg("CommandFailed!"));
1834    
1835     if(s.charAt(s.length() - 1) != '%')
1836     throw new LscpException(LscpI18n.getLogMsg("CommandFailed!"));
1837    
1838     BufferFill bf = new BufferFill();
1839     bf.setStreamID(parseInt(s.substring(1, i)));
1840     bf.setValue(parseInt(s.substring(i + 1, s.length() - 1)));
1841     v.add(bf);
1842     }
1843    
1844     return v;
1845     }
1846    
1847     /**
1848     * Sets the audio output device on the specified sampler channel.
1849     *
1850     * @param samplerChn The sampler channel number.
1851     * @param devID The numerical ID of the audio output device.
1852     *
1853     * @throws IOException If some I/O error occurs.
1854     * @throws LscpException If LSCP protocol corruption occurs.
1855     * @throws LSException If
1856     * <ul>
1857     * <li><code>samplerChn</code> is not a valid channel number;
1858     * <li><code>devID</code> is not a valid audio output device ID;
1859     * </ul>
1860     *
1861     * @see #getSamplerChannels
1862     * @see #getAudioOutputDevices
1863     */
1864     public synchronized void
1865     setChannelAudioOutputDevice(int samplerChn, int devID)
1866     throws IOException, LscpException, LSException {
1867    
1868     verifyConnection();
1869     out.writeLine("SET CHANNEL AUDIO_OUTPUT_DEVICE " + samplerChn + ' ' + devID);
1870    
1871     ResultSet rs = getEmptyResultSet();
1872     }
1873    
1874     /**
1875     * Sets the audio output channel on the specified sampler channel.
1876     *
1877     * @param samplerChn The sampler channel number.
1878     * @param audioOut The sampler channel's audio output channel which should be rerouted.
1879     * @param audioIn The audio channel of the selected audio output device
1880     * where <code>audioOut</code> should be routed to.
1881     *
1882     * @throws IOException If some I/O error occurs.
1883     * @throws LscpException If LSCP protocol corruption occurs.
1884     * @throws LSException If
1885     * <ul>
1886     * <li><code>samplerChn</code> is not a valid channel number;
1887     * <li>There is no engine assigned yet to the specified sampler channel.
1888     * <li> There is no audio output device connected to the specified sampler channel.
1889     * </ul>
1890     *
1891     * @see #getSamplerChannels
1892     */
1893     public synchronized void
1894     setChannelAudioOutputChannel(int samplerChn, int audioOut, int audioIn)
1895     throws IOException, LscpException, LSException {
1896    
1897     verifyConnection();
1898     String args = " " + samplerChn + ' ' + audioOut + ' ' + audioIn;
1899     out.writeLine("SET CHANNEL AUDIO_OUTPUT_CHANNEL" + args);
1900    
1901     ResultSet rs = getEmptyResultSet();
1902     }
1903    
1904     /**
1905     * Sets the MIDI input device on the specified sampler channel.
1906     *
1907     * @param samplerChn The sampler channel number.
1908     * @param devID The numerical ID of the MIDI input device.
1909     *
1910     * @throws IOException If some I/O error occurs.
1911     * @throws LscpException If LSCP protocol corruption occurs.
1912     * @throws LSException If
1913     * <ul>
1914     * <li><code>samplerChn</code> is not a valid channel number;
1915     * <li><code>devID</code> is not a valid MIDI input device ID;
1916     * </ul>
1917     *
1918     * @see #getSamplerChannels
1919     * @see #getMidiInputDevices
1920     */
1921     public synchronized void
1922     setChannelMidiInputDevice(int samplerChn, int devID)
1923     throws IOException, LscpException, LSException {
1924    
1925     verifyConnection();
1926     out.writeLine("SET CHANNEL MIDI_INPUT_DEVICE " + samplerChn + ' ' + devID);
1927    
1928     ResultSet rs = getEmptyResultSet();
1929     }
1930    
1931     /**
1932     * Sets the MIDI input port on the specified sampler channel.
1933     *
1934     * @param samplerChn The sampler channel number.
1935     * @param port The MIDI input port number of
1936     * the MIDI input device connected to the specified sampler channel.
1937     *
1938     * @throws IOException If some I/O error occurs.
1939     * @throws LscpException If LSCP protocol corruption occurs.
1940     * @throws LSException If <code>samplerChn</code> is not a valid channel number.
1941     * @see #getSamplerChannels
1942     */
1943     public synchronized void
1944     setChannelMidiInputPort(int samplerChn, int port)
1945     throws IOException, LscpException, LSException {
1946    
1947     verifyConnection();
1948     out.writeLine("SET CHANNEL MIDI_INPUT_PORT " + samplerChn + ' ' + port);
1949    
1950     ResultSet rs = getEmptyResultSet();
1951     }
1952    
1953     /**
1954     * Sets the MIDI input channel the specified sampler channel should listen to.
1955     *
1956     * @param samplerChn The sampler channel number.
1957     * @param midiChn The number of the new MIDI input channel where
1958     * <code>samplerChn</code> should listen to or -1 to listen on all 16 MIDI channels.
1959     *
1960     * @throws IOException If some I/O error occurs.
1961     * @throws LscpException If LSCP protocol corruption occurs.
1962     * @throws LSException If <code>samplerChn</code> is not a valid channel number.
1963     * @see #getSamplerChannels
1964     */
1965     public synchronized void
1966     setChannelMidiInputChannel(int samplerChn, int midiChn)
1967     throws IOException, LscpException, LSException {
1968    
1969     verifyConnection();
1970     String args = String.valueOf(samplerChn) + ' ';
1971     args += (midiChn == -1 ? "ALL" : String.valueOf(midiChn));
1972     out.writeLine("SET CHANNEL MIDI_INPUT_CHANNEL " + args);
1973    
1974     ResultSet rs = getEmptyResultSet();
1975     }
1976    
1977     /**
1978     * Sets the volume of the specified sampler channel.
1979     *
1980     * @param samplerChn The sampler channel number.
1981     * @param volume The new volume value.
1982     *
1983     * @throws IOException If some I/O error occurs.
1984     * @throws LscpException If LSCP protocol corruption occurs.
1985     * @throws LSException If <code>samplerChn</code> is not a valid channel number or if
1986     * there is no engine assigned yet to the specified sampler channel.
1987     * @see #getSamplerChannels
1988     */
1989     public synchronized void
1990     setChannelVolume(int samplerChn, float volume)
1991     throws IOException, LscpException, LSException {
1992    
1993     verifyConnection();
1994     out.writeLine("SET CHANNEL VOLUME " + samplerChn + ' ' + volume);
1995    
1996     ResultSet rs = getEmptyResultSet();
1997     }
1998    
1999     /**
2000     * Resets the specified sampler channel.
2001     *
2002     * @param samplerChn The sampler channel number.
2003     *
2004     * @throws IOException If some I/O error occurs.
2005     * @throws LscpException If LSCP protocol corruption occurs.
2006     * @throws LSException If <code>samplerChn</code> is not a valid channel number or if
2007     * there is no engine assigned yet to the specified sampler channel.
2008     * @see #getSamplerChannels
2009     */
2010     public synchronized void
2011     resetChannel(int samplerChn) throws IOException, LscpException, LSException {
2012     verifyConnection();
2013     out.writeLine("RESET CHANNEL " + samplerChn);
2014    
2015     ResultSet rs = getEmptyResultSet();
2016     }
2017    
2018     /**
2019     * Resets the whole sampler.
2020     *
2021     * @throws IOException If some I/O error occurs.
2022     * @throws LscpException If LSCP protocol corruption occurs.
2023     */
2024     public synchronized void
2025     resetSampler() throws IOException, LscpException {
2026     verifyConnection();
2027     out.writeLine("RESET");
2028     try { ResultSet rs = getEmptyResultSet(); }
2029     catch(LSException x) { getLogger().warning(x.getMessage()); }
2030     }
2031    
2032     /**
2033     * Gets information about the LinuxSampler instance.
2034     *
2035     * @return <code>ServerInfo</code> instance containing
2036     * information about the LinuxSampler instance.
2037     *
2038     * @throws IOException If an I/O error occurs.
2039     * @throws LscpException If LSCP protocol corruption occurs.
2040     * @throws LSException If some other error occurs.
2041     */
2042     public synchronized ServerInfo
2043     getServerInfo() throws IOException, LscpException, LSException {
2044     verifyConnection();
2045     out.writeLine("GET SERVER INFO");
2046     ResultSet rs = getMultiLineResultSet();
2047     return new ServerInfo(rs.getMultiLineResult());
2048     }
2049    
2050     /**
2051     * Returns the logger for this library.
2052     * @return The logger for this library.
2053     */
2054     protected static Logger
2055     getLogger() { return Logger.getLogger("org.linuxsampler.lscp"); }
2056     }

  ViewVC Help
Powered by ViewVC