/[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 671 - (hide annotations) (download)
Wed Jun 22 06:18:33 2005 UTC (18 years, 10 months ago) by iliev
File size: 70065 byte(s)
Updating to version 0.2a

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

  ViewVC Help
Powered by ViewVC