/[svn]/liblscp/trunk/src/client.c
ViewVC logotype

Annotation of /liblscp/trunk/src/client.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 171 - (hide annotations) (download)
Mon Jul 5 16:26:44 2004 UTC (19 years, 8 months ago) by capela
File MIME type: text/plain
File size: 44485 byte(s)
Milestone for integral implementation of draft-protocol v.11.

1 capela 107 // client.c
2     //
3     /****************************************************************************
4     liblscp - LinuxSampler Control Protocol API
5     Copyright (C) 2004, rncbc aka Rui Nuno Capela. All rights reserved.
6    
7     This library is free software; you can redistribute it and/or
8     modify it under the terms of the GNU Lesser General Public
9     License as published by the Free Software Foundation; either
10     version 2.1 of the License, or (at your option) any later version.
11    
12     This library 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 GNU
15     Lesser General Public License for more details.
16    
17     You should have received a copy of the GNU Lesser General Public
18     License along with this library; if not, write to the Free Software
19     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20    
21     *****************************************************************************/
22    
23     #include "common.h"
24    
25     // Default timeout value (in milliseconds).
26     #define LSCP_TIMEOUT_MSECS 500
27    
28    
29     // Local prototypes.
30    
31 capela 144 static void _lscp_client_evt_proc (void *pvClient);
32 capela 107
33 capela 144 static lscp_status_t _lscp_client_evt_connect (lscp_client_t *pClient);
34     static lscp_status_t _lscp_client_evt_request (lscp_client_t *pClient, int iSubscribe, lscp_event_t event);
35 capela 107
36 capela 144
37 capela 107 //-------------------------------------------------------------------------
38 capela 132 // Event service (datagram oriented).
39 capela 107
40 capela 132 static void _lscp_client_evt_proc ( void *pvClient )
41 capela 107 {
42     lscp_client_t *pClient = (lscp_client_t *) pvClient;
43     char achBuffer[LSCP_BUFSIZ];
44     int cchBuffer;
45 capela 144 const char *pszSeps = ":\r\n";
46 capela 107 char *pszToken;
47     char *pch;
48 capela 144 int cchToken;
49 capela 146 lscp_event_t event;
50 capela 107
51     #ifdef DEBUG
52 capela 132 fprintf(stderr, "_lscp_client_evt_proc: Client waiting for events.\n");
53 capela 107 #endif
54    
55 capela 132 while (pClient->evt.iState) {
56 capela 144 // Wait for event...
57     cchBuffer = recv(pClient->evt.sock, achBuffer, sizeof(achBuffer), 0);
58 capela 107 if (cchBuffer > 0) {
59 capela 144 // Make sure received buffer it's null terminated.
60     achBuffer[cchBuffer] = (char) 0;
61     // Parse for the notification event message...
62     pszToken = lscp_strtok(achBuffer, pszSeps, &(pch)); // Have "NOTIFY".
63     if (strcasecmp(pszToken, "NOTIFY") == 0) {
64     pszToken = lscp_strtok(NULL, pszSeps, &(pch));
65 capela 146 event = lscp_event_from_text(pszToken);
66 capela 144 // And pick the rest of data...
67     pszToken = lscp_strtok(NULL, pszSeps, &(pch));
68     cchToken = (pszToken == NULL ? 0 : strlen(pszToken));
69     // Double-check if we're really up to it...
70     if (pClient->events & event) {
71     // Invoke the client event callback...
72     if ((*pClient->pfnCallback)(
73     pClient,
74     event,
75     pszToken,
76     cchToken,
77     pClient->pvData) != LSCP_OK) {
78     pClient->evt.iState = 0;
79 capela 107 }
80     }
81     }
82     } else {
83 capela 144 lscp_socket_perror("_lscp_client_evt_proc: recv");
84 capela 132 pClient->evt.iState = 0;
85 capela 107 }
86     }
87    
88     #ifdef DEBUG
89 capela 132 fprintf(stderr, "_lscp_client_evt_proc: Client closing.\n");
90 capela 107 #endif
91     }
92    
93    
94     //-------------------------------------------------------------------------
95 capela 144 // Event subscription helpers.
96    
97     // Open the event service socket connection.
98     static lscp_status_t _lscp_client_evt_connect ( lscp_client_t *pClient )
99     {
100     lscp_socket_t sock;
101     struct sockaddr_in addr;
102     int cAddr;
103     #if defined(WIN32)
104     int iSockOpt = (-1);
105     #endif
106    
107     // Prepare the event connection socket...
108     sock = socket(AF_INET, SOCK_STREAM, 0);
109     if (sock == INVALID_SOCKET) {
110     lscp_socket_perror("_lscp_client_evt_connect: socket");
111     return LSCP_FAILED;
112     }
113    
114     #if defined(WIN32)
115     if (setsockopt(sock, SOL_SOCKET, SO_DONTLINGER, (char *) &iSockOpt, sizeof(int)) == SOCKET_ERROR)
116     lscp_socket_perror("lscp_client_evt_connect: setsockopt(SO_DONTLINGER)");
117     #endif
118    
119     #ifdef DEBUG
120     lscp_socket_getopts("_lscp_client_evt_connect:", sock);
121     #endif
122    
123     // Use same address of the command connection.
124     cAddr = sizeof(struct sockaddr_in);
125     memmove((char *) &addr, &(pClient->cmd.addr), cAddr);
126    
127     // Start the connection...
128     if (connect(sock, (struct sockaddr *) &addr, cAddr) == SOCKET_ERROR) {
129     lscp_socket_perror("_lscp_client_evt_connect: connect");
130     closesocket(sock);
131     return LSCP_FAILED;
132     }
133    
134     // Set our socket agent struct...
135     lscp_socket_agent_init(&(pClient->evt), sock, &addr, cAddr);
136    
137     // And finally the service thread...
138     return lscp_socket_agent_start(&(pClient->evt), _lscp_client_evt_proc, pClient, 0);
139     }
140    
141    
142     // Subscribe to a single event.
143     static lscp_status_t _lscp_client_evt_request ( lscp_client_t *pClient, int iSubscribe, lscp_event_t event )
144     {
145 capela 146 const char *pszEvent;
146 capela 144 char szQuery[LSCP_BUFSIZ];
147     int cchQuery;
148    
149     if (pClient == NULL)
150     return LSCP_FAILED;
151    
152     // Which (single) event?
153 capela 146 pszEvent = lscp_event_to_text(event);
154     if (pszEvent == NULL)
155 capela 144 return LSCP_FAILED;
156 capela 146
157 capela 144 // Build the query string...
158     cchQuery = sprintf(szQuery, "%sSUBSCRIBE %s\n\n", (iSubscribe == 0 ? "UN" : ""), pszEvent);
159     // Just send data, forget result...
160     if (send(pClient->evt.sock, szQuery, cchQuery, 0) < cchQuery) {
161     lscp_socket_perror("_lscp_client_evt_request: send");
162     return LSCP_FAILED;
163     }
164    
165     // Update as naively as we can...
166     if (iSubscribe)
167     pClient->events |= event;
168     else
169     pClient->events &= ~event;
170    
171     return LSCP_OK;
172     }
173    
174    
175     //-------------------------------------------------------------------------
176 capela 107 // Client versioning teller fuunction.
177    
178    
179     /** Retrieve the current client library version string. */
180     const char* lscp_client_package (void) { return LSCP_PACKAGE; }
181    
182     /** Retrieve the current client library version string. */
183     const char* lscp_client_version (void) { return LSCP_VERSION; }
184    
185     /** Retrieve the current client library build timestamp string. */
186     const char* lscp_client_build (void) { return __DATE__ " " __TIME__; }
187    
188    
189     //-------------------------------------------------------------------------
190     // Client socket functions.
191    
192     /**
193     * Create a client instance, estabilishing a connection to a server hostname,
194     * which must be listening on the given port. A client callback function is
195     * also supplied for server notification event handling.
196     *
197     * @param pszHost Hostname of the linuxsampler listening server.
198     * @param iPort Port number of the linuxsampler listening server.
199     * @param pfnCallback Callback function to receive event notifications.
200     * @param pvData User context opaque data, that will be passed
201     * to the callback function.
202     *
203     * @returns The new client instance pointer if successfull, which shall be
204     * used on all subsequent client calls, NULL otherwise.
205     */
206     lscp_client_t* lscp_client_create ( const char *pszHost, int iPort, lscp_client_proc_t pfnCallback, void *pvData )
207     {
208     lscp_client_t *pClient;
209     struct hostent *pHost;
210     lscp_socket_t sock;
211     struct sockaddr_in addr;
212     int cAddr;
213 capela 144 #if defined(WIN32)
214 capela 107 int iSockOpt = (-1);
215 capela 144 #endif
216 capela 107
217     if (pfnCallback == NULL) {
218     fprintf(stderr, "lscp_client_create: Invalid client callback function.\n");
219     return NULL;
220     }
221    
222     pHost = gethostbyname(pszHost);
223     if (pHost == NULL) {
224 capela 114 lscp_socket_herror("lscp_client_create: gethostbyname");
225 capela 107 return NULL;
226     }
227    
228     // Allocate client descriptor...
229    
230     pClient = (lscp_client_t *) malloc(sizeof(lscp_client_t));
231     if (pClient == NULL) {
232     fprintf(stderr, "lscp_client_create: Out of memory.\n");
233     return NULL;
234     }
235     memset(pClient, 0, sizeof(lscp_client_t));
236    
237     pClient->pfnCallback = pfnCallback;
238     pClient->pvData = pvData;
239    
240     #ifdef DEBUG
241     fprintf(stderr, "lscp_client_create: pClient=%p: pszHost=%s iPort=%d.\n", pClient, pszHost, iPort);
242     #endif
243    
244 capela 132 // Prepare the command connection socket...
245 capela 107
246     sock = socket(AF_INET, SOCK_STREAM, 0);
247     if (sock == INVALID_SOCKET) {
248 capela 132 lscp_socket_perror("lscp_client_create: cmd: socket");
249 capela 107 free(pClient);
250     return NULL;
251     }
252    
253     #if defined(WIN32)
254     if (setsockopt(sock, SOL_SOCKET, SO_DONTLINGER, (char *) &iSockOpt, sizeof(int)) == SOCKET_ERROR)
255 capela 132 lscp_socket_perror("lscp_client_create: cmd: setsockopt(SO_DONTLINGER)");
256 capela 107 #endif
257    
258     #ifdef DEBUG
259 capela 132 lscp_socket_getopts("lscp_client_create: cmd", sock);
260 capela 107 #endif
261    
262     cAddr = sizeof(struct sockaddr_in);
263     memset((char *) &addr, 0, cAddr);
264     addr.sin_family = pHost->h_addrtype;
265     memmove((char *) &(addr.sin_addr), pHost->h_addr, pHost->h_length);
266     addr.sin_port = htons((short) iPort);
267    
268     if (connect(sock, (struct sockaddr *) &addr, cAddr) == SOCKET_ERROR) {
269 capela 132 lscp_socket_perror("lscp_client_create: cmd: connect");
270 capela 107 closesocket(sock);
271     free(pClient);
272     return NULL;
273     }
274    
275 capela 144 // Initialize the command socket agent struct...
276 capela 132 lscp_socket_agent_init(&(pClient->cmd), sock, &addr, cAddr);
277 capela 107
278     #ifdef DEBUG
279 capela 132 fprintf(stderr, "lscp_client_create: cmd: pClient=%p: sock=%d addr=%s port=%d.\n", pClient, pClient->cmd.sock, inet_ntoa(pClient->cmd.addr.sin_addr), ntohs(pClient->cmd.addr.sin_port));
280 capela 107 #endif
281    
282 capela 144 // Initialize the event service socket struct...
283     lscp_socket_agent_init(&(pClient->evt), INVALID_SOCKET, NULL, 0);
284     // No events subscribed, yet.
285     pClient->events = LSCP_EVENT_NONE;
286 capela 107 // Initialize cached members.
287     pClient->audio_drivers = NULL;
288     pClient->midi_drivers = NULL;
289 capela 125 pClient->audio_devices = NULL;
290     pClient->midi_devices = NULL;
291 capela 107 pClient->engines = NULL;
292 capela 125 pClient->channels = NULL;
293 capela 171 lscp_driver_info_init(&(pClient->audio_driver_info));
294     lscp_driver_info_init(&(pClient->midi_driver_info));
295     lscp_device_info_init(&(pClient->audio_device_info));
296     lscp_device_info_init(&(pClient->midi_device_info));
297 capela 163 lscp_param_info_init(&(pClient->audio_param_info));
298     lscp_param_info_init(&(pClient->midi_param_info));
299 capela 171 lscp_device_port_info_init(&(pClient->audio_channel_info));
300     lscp_device_port_info_init(&(pClient->midi_port_info));
301     lscp_param_info_init(&(pClient->audio_channel_param_info));
302     lscp_param_info_init(&(pClient->midi_port_param_info));
303 capela 107 lscp_engine_info_init(&(pClient->engine_info));
304     lscp_channel_info_init(&(pClient->channel_info));
305     // Initialize error stuff.
306     pClient->pszResult = NULL;
307     pClient->iErrno = -1;
308     // Stream usage stuff.
309     pClient->buffer_fill = NULL;
310     pClient->iStreamCount = 0;
311     // Default timeout value.
312     pClient->iTimeout = LSCP_TIMEOUT_MSECS;
313    
314     // Initialize the transaction mutex.
315     lscp_mutex_init(pClient->mutex);
316    
317     // Finally we've some success...
318     return pClient;
319     }
320    
321    
322     /**
323     * Wait for a client instance to terminate graciously.
324     *
325     * @param pClient Pointer to client instance structure.
326     */
327     lscp_status_t lscp_client_join ( lscp_client_t *pClient )
328     {
329     if (pClient == NULL)
330     return LSCP_FAILED;
331    
332     #ifdef DEBUG
333     fprintf(stderr, "lscp_client_join: pClient=%p.\n", pClient);
334     #endif
335    
336 capela 132 // lscp_socket_agent_join(&(pClient->evt));
337     lscp_socket_agent_join(&(pClient->cmd));
338 capela 107
339     return LSCP_OK;
340     }
341    
342    
343     /**
344     * Terminate and destroy a client instance.
345     *
346     * @param pClient Pointer to client instance structure.
347     *
348     * @returns LSCP_OK on success, LSCP_FAILED otherwise.
349     */
350     lscp_status_t lscp_client_destroy ( lscp_client_t *pClient )
351     {
352     if (pClient == NULL)
353     return LSCP_FAILED;
354    
355     #ifdef DEBUG
356     fprintf(stderr, "lscp_client_destroy: pClient=%p.\n", pClient);
357     #endif
358    
359 capela 132 // Lock this section up.
360     lscp_mutex_lock(pClient->mutex);
361    
362 capela 107 // Free up all cached members.
363     lscp_channel_info_reset(&(pClient->channel_info));
364     lscp_engine_info_reset(&(pClient->engine_info));
365 capela 171 lscp_param_info_reset(&(pClient->midi_port_param_info));
366     lscp_param_info_reset(&(pClient->audio_channel_param_info));
367     lscp_device_port_info_reset(&(pClient->midi_port_info));
368     lscp_device_port_info_reset(&(pClient->audio_channel_info));
369 capela 163 lscp_param_info_reset(&(pClient->midi_param_info));
370     lscp_param_info_reset(&(pClient->audio_param_info));
371 capela 171 lscp_device_info_reset(&(pClient->midi_device_info));
372     lscp_device_info_reset(&(pClient->audio_device_info));
373     lscp_driver_info_reset(&(pClient->midi_driver_info));
374     lscp_driver_info_reset(&(pClient->audio_driver_info));
375 capela 107 // Free available engine table.
376     lscp_szsplit_destroy(pClient->audio_drivers);
377     lscp_szsplit_destroy(pClient->midi_drivers);
378 capela 125 lscp_isplit_destroy(pClient->audio_devices);
379     lscp_isplit_destroy(pClient->midi_devices);
380 capela 107 lscp_szsplit_destroy(pClient->engines);
381 capela 125 lscp_isplit_destroy(pClient->channels);
382 capela 107 // Make them null.
383     pClient->audio_drivers = NULL;
384     pClient->midi_drivers = NULL;
385     pClient->engines = NULL;
386     // Free result error stuff.
387 capela 132 lscp_client_set_result(pClient, NULL, 0);
388 capela 167 // Free stream usage stuff.
389 capela 107 if (pClient->buffer_fill)
390     free(pClient->buffer_fill);
391     pClient->buffer_fill = NULL;
392     pClient->iStreamCount = 0;
393     pClient->iTimeout = 0;
394    
395     // Free socket agents.
396 capela 132 lscp_socket_agent_free(&(pClient->evt));
397     lscp_socket_agent_free(&(pClient->cmd));
398 capela 107
399     // Last but not least, free good ol'transaction mutex.
400 capela 132 lscp_mutex_unlock(pClient->mutex);
401 capela 107 lscp_mutex_destroy(pClient->mutex);
402    
403     free(pClient);
404    
405     return LSCP_OK;
406     }
407    
408    
409     /**
410     * Set the client transaction timeout interval.
411     *
412     * @param pClient Pointer to client instance structure.
413     * @param iTimeout Transaction timeout in milliseconds.
414     *
415     * @returns LSCP_OK on success, LSCP_FAILED otherwise.
416     */
417     lscp_status_t lscp_client_set_timeout ( lscp_client_t *pClient, int iTimeout )
418     {
419     if (pClient == NULL)
420     return LSCP_FAILED;
421     if (iTimeout < 0)
422     return LSCP_FAILED;
423    
424     pClient->iTimeout = iTimeout;
425     return LSCP_OK;
426     }
427    
428    
429     /**
430     * Get the client transaction timeout interval.
431     *
432     * @param pClient Pointer to client instance structure.
433     *
434     * @returns The current timeout value milliseconds, -1 in case of failure.
435     */
436     int lscp_client_get_timeout ( lscp_client_t *pClient )
437     {
438     if (pClient == NULL)
439     return -1;
440    
441     return pClient->iTimeout;
442     }
443    
444    
445     //-------------------------------------------------------------------------
446     // Client common protocol functions.
447    
448     /**
449     * Submit a command query line string to the server. The query string
450     * must be cr/lf and null terminated. Besides the return code, the
451     * specific server response to the command request is made available
452     * by the @ref lscp_client_get_result and @ref lscp_client_get_errno
453     * function calls.
454     *
455     * @param pClient Pointer to client instance structure.
456     * @param pszQuery Command request line to be sent to server,
457     * must be cr/lf and null terminated.
458     *
459     * @returns LSCP_OK on success, LSCP_FAILED otherwise.
460     */
461     lscp_status_t lscp_client_query ( lscp_client_t *pClient, const char *pszQuery )
462     {
463 capela 132 lscp_status_t ret;
464    
465 capela 107 // Lock this section up.
466     lscp_mutex_lock(pClient->mutex);
467    
468 capela 132 // Just make the now guarded call.
469     ret = lscp_client_call(pClient, pszQuery);
470    
471     // Unlock this section down.
472 capela 107 lscp_mutex_unlock(pClient->mutex);
473 capela 132
474 capela 107 return ret;
475     }
476    
477     /**
478     * Get the last received result string. In case of error or warning,
479     * this is the text of the error or warning message issued.
480     *
481     * @param pClient Pointer to client instance structure.
482     *
483     * @returns A pointer to the literal null-terminated result string as
484     * of the last command request.
485     */
486     const char *lscp_client_get_result ( lscp_client_t *pClient )
487     {
488     if (pClient == NULL)
489     return NULL;
490    
491     return pClient->pszResult;
492     }
493    
494    
495     /**
496     * Get the last error/warning number received.
497     *
498     * @param pClient Pointer to client instance structure.
499     *
500     * @returns The numerical value of the last error or warning
501     * response code received.
502     */
503     int lscp_client_get_errno ( lscp_client_t *pClient )
504     {
505     if (pClient == NULL)
506     return -1;
507    
508     return pClient->iErrno;
509     }
510    
511    
512     //-------------------------------------------------------------------------
513     // Client registration protocol functions.
514    
515     /**
516 capela 144 * Register frontend for receiving event messages:
517     * SUBSCRIBE CHANNELS | VOICE_COUNT | STREAM_COUNT | BUFFER_FILL
518     * | CHANNEL_INFO | MISCELLANEOUS
519 capela 107 *
520     * @param pClient Pointer to client instance structure.
521 capela 144 * @param events Bit-wise OR'ed event flags to subscribe.
522 capela 107 *
523     * @returns LSCP_OK on success, LSCP_FAILED otherwise.
524     */
525 capela 144 lscp_status_t lscp_client_subscribe ( lscp_client_t *pClient, lscp_event_t events )
526 capela 107 {
527 capela 144 lscp_status_t ret = LSCP_FAILED;
528 capela 107
529 capela 144 if (pClient == NULL)
530 capela 107 return LSCP_FAILED;
531    
532 capela 132 // Lock this section up.
533     lscp_mutex_lock(pClient->mutex);
534 capela 144
535     // If applicable, start the alternate connection...
536     if (pClient->events == LSCP_EVENT_NONE)
537     ret = _lscp_client_evt_connect(pClient);
538 capela 132
539 capela 144 // Send the subscription commands.
540     if (ret == LSCP_OK && (events & LSCP_EVENT_CHANNELS))
541     ret = _lscp_client_evt_request(pClient, 1, LSCP_EVENT_CHANNELS);
542     if (ret == LSCP_OK && (events & LSCP_EVENT_VOICE_COUNT))
543     ret = _lscp_client_evt_request(pClient, 1, LSCP_EVENT_VOICE_COUNT);
544     if (ret == LSCP_OK && (events & LSCP_EVENT_STREAM_COUNT))
545     ret = _lscp_client_evt_request(pClient, 1, LSCP_EVENT_STREAM_COUNT);
546     if (ret == LSCP_OK && (events & LSCP_EVENT_BUFFER_FILL))
547     ret = _lscp_client_evt_request(pClient, 1, LSCP_EVENT_BUFFER_FILL);
548     if (ret == LSCP_OK && (events & LSCP_EVENT_CHANNEL_INFO))
549     ret = _lscp_client_evt_request(pClient, 1, LSCP_EVENT_CHANNEL_INFO);
550     if (ret == LSCP_OK && (events & LSCP_EVENT_MISCELLANEOUS))
551     ret = _lscp_client_evt_request(pClient, 1, LSCP_EVENT_MISCELLANEOUS);
552 capela 107
553 capela 132 // Unlock this section down.
554     lscp_mutex_unlock(pClient->mutex);
555    
556 capela 107 return ret;
557     }
558    
559    
560     /**
561 capela 144 * Deregister frontend from receiving UDP event messages anymore:
562     * SUBSCRIBE CHANNELS | VOICE_COUNT | STREAM_COUNT | BUFFER_FILL
563     * | CHANNEL_INFO | MISCELLANEOUS
564 capela 107 *
565     * @param pClient Pointer to client instance structure.
566 capela 144 * @param events Bit-wise OR'ed event flags to unsubscribe.
567 capela 107 *
568     * @returns LSCP_OK on success, LSCP_FAILED otherwise.
569     */
570 capela 144 lscp_status_t lscp_client_unsubscribe ( lscp_client_t *pClient, lscp_event_t events )
571 capela 107 {
572 capela 144 lscp_status_t ret = LSCP_OK;
573 capela 107
574     if (pClient == NULL)
575     return LSCP_FAILED;
576    
577 capela 132 // Lock this section up.
578     lscp_mutex_lock(pClient->mutex);
579    
580 capela 144 // Send the unsubscription commands.
581     if (ret == LSCP_OK && (events & LSCP_EVENT_CHANNELS))
582     ret = _lscp_client_evt_request(pClient, 0, LSCP_EVENT_CHANNELS);
583     if (ret == LSCP_OK && (events & LSCP_EVENT_VOICE_COUNT))
584     ret = _lscp_client_evt_request(pClient, 0, LSCP_EVENT_VOICE_COUNT);
585     if (ret == LSCP_OK && (events & LSCP_EVENT_STREAM_COUNT))
586     ret = _lscp_client_evt_request(pClient, 0, LSCP_EVENT_STREAM_COUNT);
587     if (ret == LSCP_OK && (events & LSCP_EVENT_BUFFER_FILL))
588     ret = _lscp_client_evt_request(pClient, 0, LSCP_EVENT_BUFFER_FILL);
589     if (ret == LSCP_OK && (events & LSCP_EVENT_CHANNEL_INFO))
590     ret = _lscp_client_evt_request(pClient, 0, LSCP_EVENT_CHANNEL_INFO);
591     if (ret == LSCP_OK && (events & LSCP_EVENT_MISCELLANEOUS))
592     ret = _lscp_client_evt_request(pClient, 0, LSCP_EVENT_MISCELLANEOUS);
593 capela 107
594 capela 144 // If necessary, close the alternate connection...
595     if (pClient->events == LSCP_EVENT_NONE)
596     lscp_socket_agent_free(&(pClient->evt));
597    
598 capela 132 // Unlock this section down.
599     lscp_mutex_unlock(pClient->mutex);
600    
601 capela 107 return ret;
602     }
603    
604    
605     //-------------------------------------------------------------------------
606     // Client command protocol functions.
607    
608     /**
609     * Loading an instrument:
610     * LOAD INSTRUMENT <filename> <instr-index> <sampler-channel>
611     *
612     * @param pClient Pointer to client instance structure.
613     * @param pszFileName Instrument file name.
614     * @param iInstrIndex Instrument index number.
615     * @param iSamplerChannel Sampler Channel.
616     *
617     * @returns LSCP_OK on success, LSCP_FAILED otherwise.
618     */
619     lscp_status_t lscp_load_instrument ( lscp_client_t *pClient, const char *pszFileName, int iInstrIndex, int iSamplerChannel )
620     {
621     char szQuery[LSCP_BUFSIZ];
622    
623     if (pszFileName == NULL || iSamplerChannel < 0)
624     return LSCP_FAILED;
625    
626 capela 144 sprintf(szQuery, "LOAD INSTRUMENT '%s' %d %d\r\n", pszFileName, iInstrIndex, iSamplerChannel);
627 capela 107 return lscp_client_query(pClient, szQuery);
628     }
629    
630    
631     /**
632 capela 144 * Loading an instrument in the background (non modal):
633     * LOAD INSTRUMENT NON_MODAL <filename> <instr-index> <sampler-channel>
634     *
635     * @param pClient Pointer to client instance structure.
636     * @param pszFileName Instrument file name.
637     * @param iInstrIndex Instrument index number.
638     * @param iSamplerChannel Sampler Channel.
639     *
640     * @returns LSCP_OK on success, LSCP_FAILED otherwise.
641     */
642     lscp_status_t lscp_load_instrument_non_modal ( lscp_client_t *pClient, const char *pszFileName, int iInstrIndex, int iSamplerChannel )
643     {
644     char szQuery[LSCP_BUFSIZ];
645    
646     if (pszFileName == NULL || iSamplerChannel < 0)
647     return LSCP_FAILED;
648    
649     sprintf(szQuery, "LOAD INSTRUMENT NON_MODAL '%s' %d %d\r\n", pszFileName, iInstrIndex, iSamplerChannel);
650     return lscp_client_query(pClient, szQuery);
651     }
652    
653    
654     /**
655 capela 107 * Loading a sampler engine:
656     * LOAD ENGINE <engine-name> <sampler-channel>
657     *
658     * @param pClient Pointer to client instance structure.
659     * @param pszEngineName Engine name.
660     * @param iSamplerChannel Sampler channel number.
661     *
662     * @returns LSCP_OK on success, LSCP_FAILED otherwise.
663     */
664     lscp_status_t lscp_load_engine ( lscp_client_t *pClient, const char *pszEngineName, int iSamplerChannel )
665     {
666     char szQuery[LSCP_BUFSIZ];
667    
668     if (pszEngineName == NULL || iSamplerChannel < 0)
669     return LSCP_FAILED;
670    
671     sprintf(szQuery, "LOAD ENGINE %s %d\r\n", pszEngineName, iSamplerChannel);
672     return lscp_client_query(pClient, szQuery);
673     }
674    
675    
676     /**
677     * Current number of sampler channels:
678     * GET CHANNELS
679     *
680     * @param pClient Pointer to client instance structure.
681     *
682     * @returns The current total number of sampler channels on success,
683     * -1 otherwise.
684     */
685     int lscp_get_channels ( lscp_client_t *pClient )
686     {
687     int iChannels = -1;
688 capela 132
689     // Lock this section up.
690     lscp_mutex_lock(pClient->mutex);
691    
692     if (lscp_client_call(pClient, "GET CHANNELS\r\n") == LSCP_OK)
693 capela 107 iChannels = atoi(lscp_client_get_result(pClient));
694 capela 132
695     // Unlock this section doen.
696     lscp_mutex_unlock(pClient->mutex);
697    
698 capela 107 return iChannels;
699     }
700    
701    
702     /**
703 capela 125 * List current sampler channels number identifiers:
704     * LIST CHANNELS
705     *
706     * @param pClient Pointer to client instance structure.
707     *
708     * @returns An array of the sampler channels identifiers as positive integers,
709     * terminated with -1 on success, NULL otherwise.
710     */
711     int *lscp_list_channels ( lscp_client_t *pClient )
712     {
713     const char *pszSeps = ",";
714    
715     if (pClient == NULL)
716     return NULL;
717    
718 capela 132 // Lock this section up.
719     lscp_mutex_lock(pClient->mutex);
720    
721 capela 125 if (pClient->channels) {
722     lscp_isplit_destroy(pClient->channels);
723     pClient->channels = NULL;
724     }
725    
726 capela 132 if (lscp_client_call(pClient, "LIST CHANNELS\r\n") == LSCP_OK)
727 capela 125 pClient->channels = lscp_isplit_create(lscp_client_get_result(pClient), pszSeps);
728    
729 capela 132 // Unlock this section down.
730     lscp_mutex_unlock(pClient->mutex);
731    
732 capela 125 return pClient->channels;
733     }
734    
735    
736     /**
737 capela 107 * Adding a new sampler channel:
738     * ADD CHANNEL
739     *
740     * @param pClient Pointer to client instance structure.
741     *
742     * @returns The new sampler channel number identifier,
743     * or -1 in case of failure.
744     */
745     int lscp_add_channel ( lscp_client_t *pClient )
746     {
747     int iSamplerChannel = -1;
748 capela 132
749     // Lock this section up.
750     lscp_mutex_lock(pClient->mutex);
751    
752     if (lscp_client_call(pClient, "ADD CHANNEL\r\n") == LSCP_OK)
753 capela 107 iSamplerChannel = atoi(lscp_client_get_result(pClient));
754 capela 132
755     // Unlock this section down.
756     lscp_mutex_unlock(pClient->mutex);
757    
758 capela 107 return iSamplerChannel;
759     }
760    
761    
762     /**
763     * Removing a sampler channel:
764     * REMOVE CHANNEL <sampler-channel>
765     *
766     * @param pClient Pointer to client instance structure.
767     * @param iSamplerChannel Sampler channel number.
768     *
769     * @returns LSCP_OK on success, LSCP_FAILED otherwise.
770     */
771     lscp_status_t lscp_remove_channel ( lscp_client_t *pClient, int iSamplerChannel )
772     {
773     char szQuery[LSCP_BUFSIZ];
774    
775     if (iSamplerChannel < 0)
776     return LSCP_FAILED;
777    
778     sprintf(szQuery, "REMOVE CHANNEL %d\r\n", iSamplerChannel);
779     return lscp_client_query(pClient, szQuery);
780     }
781    
782    
783     /**
784     * Getting all available engines:
785     * GET AVAILABLE_ENGINES
786     *
787     * @param pClient Pointer to client instance structure.
788     *
789     * @returns A NULL terminated array of engine name strings,
790     * or NULL in case of failure.
791     */
792     const char **lscp_get_available_engines ( lscp_client_t *pClient )
793     {
794     const char *pszSeps = ",";
795    
796 capela 132 // Lock this section up.
797     lscp_mutex_lock(pClient->mutex);
798    
799 capela 107 if (pClient->engines) {
800     lscp_szsplit_destroy(pClient->engines);
801     pClient->engines = NULL;
802     }
803    
804 capela 132 if (lscp_client_call(pClient, "GET AVAILABLE_ENGINES\r\n") == LSCP_OK)
805 capela 107 pClient->engines = lscp_szsplit_create(lscp_client_get_result(pClient), pszSeps);
806    
807 capela 132 // Unlock this section down.
808     lscp_mutex_unlock(pClient->mutex);
809    
810 capela 107 return (const char **) pClient->engines;
811     }
812    
813    
814     /**
815     * Getting information about an engine.
816     * GET ENGINE INFO <engine-name>
817     *
818     * @param pClient Pointer to client instance structure.
819     * @param pszEngineName Engine name.
820     *
821     * @returns A pointer to a @ref lscp_engine_info_t structure, with all the
822     * information of the given sampler engine, or NULL in case of failure.
823     */
824     lscp_engine_info_t *lscp_get_engine_info ( lscp_client_t *pClient, const char *pszEngineName )
825     {
826     lscp_engine_info_t *pEngineInfo;
827     char szQuery[LSCP_BUFSIZ];
828     const char *pszResult;
829     const char *pszSeps = ":";
830     const char *pszCrlf = "\r\n";
831     char *pszToken;
832     char *pch;
833    
834     if (pszEngineName == NULL)
835     return NULL;
836    
837 capela 132 // Lock this section up.
838     lscp_mutex_lock(pClient->mutex);
839    
840 capela 107 pEngineInfo = &(pClient->engine_info);
841     lscp_engine_info_reset(pEngineInfo);
842    
843     sprintf(szQuery, "GET ENGINE INFO %s\r\n", pszEngineName);
844 capela 132 if (lscp_client_call(pClient, szQuery) == LSCP_OK) {
845     pszResult = lscp_client_get_result(pClient);
846     pszToken = lscp_strtok((char *) pszResult, pszSeps, &(pch));
847     while (pszToken) {
848     if (strcasecmp(pszToken, "DESCRIPTION") == 0) {
849     pszToken = lscp_strtok(NULL, pszCrlf, &(pch));
850     if (pszToken)
851     pEngineInfo->description = lscp_unquote(&pszToken, 1);
852     }
853     else if (strcasecmp(pszToken, "VERSION") == 0) {
854     pszToken = lscp_strtok(NULL, pszCrlf, &(pch));
855     if (pszToken)
856     pEngineInfo->version = lscp_unquote(&pszToken, 1);
857     }
858     pszToken = lscp_strtok(NULL, pszSeps, &(pch));
859 capela 107 }
860     }
861 capela 132 else pEngineInfo = NULL;
862    
863     // Unlock this section down.
864     lscp_mutex_unlock(pClient->mutex);
865 capela 107
866     return pEngineInfo;
867     }
868    
869    
870     /**
871     * Getting sampler channel informations:
872     * GET CHANNEL INFO <sampler-channel>
873     *
874     * @param pClient Pointer to client instance structure.
875     * @param iSamplerChannel Sampler channel number.
876     *
877     * @returns A pointer to a @ref lscp_channel_info_t structure, with all the
878     * information of the given sampler channel, or NULL in case of failure.
879     */
880     lscp_channel_info_t *lscp_get_channel_info ( lscp_client_t *pClient, int iSamplerChannel )
881     {
882     lscp_channel_info_t *pChannelInfo;
883     char szQuery[LSCP_BUFSIZ];
884     const char *pszResult;
885     const char *pszSeps = ":";
886     const char *pszCrlf = "\r\n";
887     char *pszToken;
888     char *pch;
889    
890     if (iSamplerChannel < 0)
891     return NULL;
892    
893 capela 132 // Lock this section up.
894     lscp_mutex_lock(pClient->mutex);
895    
896 capela 107 pChannelInfo = &(pClient->channel_info);
897     lscp_channel_info_reset(pChannelInfo);
898    
899     sprintf(szQuery, "GET CHANNEL INFO %d\r\n", iSamplerChannel);
900 capela 132 if (lscp_client_call(pClient, szQuery) == LSCP_OK) {
901     pszResult = lscp_client_get_result(pClient);
902     pszToken = lscp_strtok((char *) pszResult, pszSeps, &(pch));
903     while (pszToken) {
904     if (strcasecmp(pszToken, "ENGINE_NAME") == 0) {
905     pszToken = lscp_strtok(NULL, pszCrlf, &(pch));
906     if (pszToken)
907     pChannelInfo->engine_name = lscp_unquote(&pszToken, 1);
908     }
909     else if (strcasecmp(pszToken, "AUDIO_OUTPUT_DEVICE") == 0) {
910     pszToken = lscp_strtok(NULL, pszCrlf, &(pch));
911     if (pszToken)
912     pChannelInfo->audio_device = atoi(lscp_ltrim(pszToken));
913     }
914     else if (strcasecmp(pszToken, "AUDIO_OUTPUT_CHANNELS") == 0) {
915     pszToken = lscp_strtok(NULL, pszCrlf, &(pch));
916     if (pszToken)
917     pChannelInfo->audio_channels = atoi(lscp_ltrim(pszToken));
918     }
919     else if (strcasecmp(pszToken, "AUDIO_OUTPUT_ROUTING") == 0) {
920     pszToken = lscp_strtok(NULL, pszCrlf, &(pch));
921     if (pszToken)
922     pChannelInfo->audio_routing = lscp_szsplit_create(pszToken, ",");
923     }
924     else if (strcasecmp(pszToken, "INSTRUMENT_FILE") == 0) {
925     pszToken = lscp_strtok(NULL, pszCrlf, &(pch));
926     if (pszToken)
927     pChannelInfo->instrument_file = lscp_unquote(&pszToken, 1);
928     }
929     else if (strcasecmp(pszToken, "INSTRUMENT_NR") == 0) {
930     pszToken = lscp_strtok(NULL, pszCrlf, &(pch));
931     if (pszToken)
932     pChannelInfo->instrument_nr = atoi(lscp_ltrim(pszToken));
933     }
934     else if (strcasecmp(pszToken, "INSTRUMENT_STATUS") == 0) {
935     pszToken = lscp_strtok(NULL, pszCrlf, &(pch));
936     if (pszToken)
937     pChannelInfo->instrument_status = atoi(lscp_ltrim(pszToken));
938     }
939     else if (strcasecmp(pszToken, "MIDI_INPUT_DEVICE") == 0) {
940     pszToken = lscp_strtok(NULL, pszCrlf, &(pch));
941     if (pszToken)
942     pChannelInfo->midi_device = atoi(lscp_ltrim(pszToken));
943     }
944     else if (strcasecmp(pszToken, "MIDI_INPUT_PORT") == 0) {
945     pszToken = lscp_strtok(NULL, pszCrlf, &(pch));
946     if (pszToken)
947     pChannelInfo->midi_port = atoi(lscp_ltrim(pszToken));
948     }
949     else if (strcasecmp(pszToken, "MIDI_INPUT_CHANNEL") == 0) {
950     pszToken = lscp_strtok(NULL, pszCrlf, &(pch));
951     if (pszToken)
952     pChannelInfo->midi_channel = atoi(lscp_ltrim(pszToken));
953     }
954     else if (strcasecmp(pszToken, "VOLUME") == 0) {
955     pszToken = lscp_strtok(NULL, pszCrlf, &(pch));
956     if (pszToken)
957     pChannelInfo->volume = (float) atof(lscp_ltrim(pszToken));
958     }
959     pszToken = lscp_strtok(NULL, pszSeps, &(pch));
960 capela 107 }
961     }
962 capela 132 else pChannelInfo = NULL;
963    
964     // Unlock this section up.
965     lscp_mutex_unlock(pClient->mutex);
966 capela 107
967     return pChannelInfo;
968     }
969    
970    
971     /**
972     * Current number of active voices:
973     * GET CHANNEL VOICE_COUNT <sampler-channel>
974     *
975     * @param pClient Pointer to client instance structure.
976     * @param iSamplerChannel Sampler channel number.
977     *
978     * @returns The number of voices currently active, -1 in case of failure.
979     */
980     int lscp_get_channel_voice_count ( lscp_client_t *pClient, int iSamplerChannel )
981     {
982     char szQuery[LSCP_BUFSIZ];
983     int iVoiceCount = -1;
984    
985     if (iSamplerChannel < 0)
986     return iVoiceCount;
987    
988 capela 132 // Lock this section up.
989     lscp_mutex_lock(pClient->mutex);
990    
991 capela 107 sprintf(szQuery, "GET CHANNEL VOICE_COUNT %d\r\n", iSamplerChannel);
992 capela 132 if (lscp_client_call(pClient, szQuery) == LSCP_OK)
993 capela 107 iVoiceCount = atoi(lscp_client_get_result(pClient));
994    
995 capela 132 // Unlock this section down.
996     lscp_mutex_unlock(pClient->mutex);
997    
998 capela 107 return iVoiceCount;
999     }
1000    
1001    
1002     /**
1003     * Current number of active disk streams:
1004     * GET CHANNEL STREAM_COUNT <sampler-channel>
1005     *
1006 capela 167 * @param pClient Pointer to client instance structure.
1007     * @param iSamplerChannel Sampler channel number.
1008     *
1009 capela 107 * @returns The number of active disk streams on success, -1 otherwise.
1010     */
1011     int lscp_get_channel_stream_count ( lscp_client_t *pClient, int iSamplerChannel )
1012     {
1013     char szQuery[LSCP_BUFSIZ];
1014     int iStreamCount = -1;
1015    
1016     if (iSamplerChannel < 0)
1017     return iStreamCount;
1018    
1019 capela 132 // Lock this section up.
1020     lscp_mutex_lock(pClient->mutex);
1021    
1022 capela 107 sprintf(szQuery, "GET CHANNEL STREAM_COUNT %d\r\n", iSamplerChannel);
1023 capela 132 if (lscp_client_call(pClient, szQuery) == LSCP_OK)
1024 capela 107 iStreamCount = atoi(lscp_client_get_result(pClient));
1025    
1026 capela 132 // Unlock this section down.
1027     lscp_mutex_unlock(pClient->mutex);
1028    
1029 capela 107 return iStreamCount;
1030     }
1031    
1032    
1033     /**
1034 capela 167 * Current least usage of active disk streams.
1035     *
1036     * @param pClient Pointer to client instance structure.
1037     * @param iSamplerChannel Sampler channel number.
1038     *
1039     * @returns The usage percentage of the least filled active disk stream
1040     * on success, -1 otherwise.
1041     */
1042     int lscp_get_channel_stream_usage ( lscp_client_t *pClient, int iSamplerChannel )
1043     {
1044     char szQuery[LSCP_BUFSIZ];
1045     int iStreamUsage = -1;
1046     const char *pszResult;
1047     const char *pszSeps = "[]%,";
1048     char *pszToken;
1049     char *pch;
1050     int iStream;
1051     int iPercent;
1052    
1053     if (iSamplerChannel < 0)
1054     return iStreamUsage;
1055    
1056     // Lock this section up.
1057     lscp_mutex_lock(pClient->mutex);
1058    
1059     iStream = 0;
1060     sprintf(szQuery, "GET CHANNEL BUFFER_FILL PERCENTAGE %d\r\n", iSamplerChannel);
1061     if (lscp_client_call(pClient, szQuery) == LSCP_OK) {
1062     pszResult = lscp_client_get_result(pClient);
1063     pszToken = lscp_strtok((char *) pszResult, pszSeps, &(pch));
1064     while (pszToken) {
1065     if (*pszToken) {
1066     // Skip stream id.
1067     pszToken = lscp_strtok(NULL, pszSeps, &(pch));
1068     if (pszToken == NULL)
1069     break;
1070     // Get least buffer fill percentage.
1071     iPercent = atol(pszToken);
1072     if (iStreamUsage > iPercent || iStream == 0)
1073     iStreamUsage = iPercent;
1074     iStream++;
1075     }
1076     pszToken = lscp_strtok(NULL, pszSeps, &(pch));
1077     }
1078     }
1079    
1080     // Unlock this section down.
1081     lscp_mutex_unlock(pClient->mutex);
1082    
1083     return iStreamUsage;
1084     }
1085    
1086    
1087     /**
1088 capela 107 * Current fill state of disk stream buffers:
1089     * GET CHANNEL BUFFER_FILL {BYTES|PERCENTAGE} <sampler-channel>
1090     *
1091     * @param pClient Pointer to client instance structure.
1092     * @param usage_type Usage type to be returned, either
1093     * @ref LSCP_USAGE_BYTES, or
1094     * @ref LSCP_USAGE_PERCENTAGE.
1095     * @param iSamplerChannel Sampler channel number.
1096     *
1097     * @returns A pointer to a @ref lscp_buffer_fill_t structure, with the
1098     * information of the current disk stream buffer fill usage, for the given
1099     * sampler channel, or NULL in case of failure.
1100     */
1101     lscp_buffer_fill_t *lscp_get_channel_buffer_fill ( lscp_client_t *pClient, lscp_usage_t usage_type, int iSamplerChannel )
1102     {
1103     lscp_buffer_fill_t *pBufferFill;
1104     char szQuery[LSCP_BUFSIZ];
1105     int iStreamCount;
1106     const char *pszUsageType = (usage_type == LSCP_USAGE_BYTES ? "BYTES" : "PERCENTAGE");
1107     const char *pszResult;
1108     const char *pszSeps = "[]%,";
1109     char *pszToken;
1110     char *pch;
1111     int iStream;
1112    
1113 capela 132 // Retrieve a channel stream estimation.
1114 capela 107 iStreamCount = lscp_get_channel_stream_count(pClient, iSamplerChannel);
1115 capela 132 if (pClient->iStreamCount < 0)
1116     return NULL;
1117    
1118     // Lock this section up.
1119     lscp_mutex_lock(pClient->mutex);
1120    
1121     // Check if we need to reallocate the stream usage array.
1122 capela 107 if (pClient->iStreamCount != iStreamCount) {
1123     if (pClient->buffer_fill)
1124     free(pClient->buffer_fill);
1125     if (iStreamCount > 0)
1126     pClient->buffer_fill = (lscp_buffer_fill_t *) malloc(iStreamCount * sizeof(lscp_buffer_fill_t));
1127     else
1128     pClient->buffer_fill = NULL;
1129     pClient->iStreamCount = iStreamCount;
1130     }
1131    
1132 capela 132 // Get buffer fill usage...
1133 capela 107 pBufferFill = pClient->buffer_fill;
1134 capela 132 if (pBufferFill && iStreamCount > 0) {
1135     iStream = 0;
1136     pBufferFill = pClient->buffer_fill;
1137     sprintf(szQuery, "GET CHANNEL BUFFER_FILL %s %d\r\n", pszUsageType, iSamplerChannel);
1138     if (lscp_client_call(pClient, szQuery) == LSCP_OK) {
1139     pszResult = lscp_client_get_result(pClient);
1140     pszToken = lscp_strtok((char *) pszResult, pszSeps, &(pch));
1141     while (pszToken && iStream < pClient->iStreamCount) {
1142     if (*pszToken) {
1143     pBufferFill[iStream].stream_id = atol(pszToken);
1144     pszToken = lscp_strtok(NULL, pszSeps, &(pch));
1145     if (pszToken == NULL)
1146     break;
1147     pBufferFill[iStream].stream_usage = atol(pszToken);
1148     iStream++;
1149     }
1150 capela 107 pszToken = lscp_strtok(NULL, pszSeps, &(pch));
1151     }
1152 capela 132 } // Reset the usage, whatever it was before.
1153     else while (iStream < pClient->iStreamCount)
1154     pBufferFill[iStream++].stream_usage = 0;
1155     }
1156    
1157     // Unlock this section down.
1158     lscp_mutex_unlock(pClient->mutex);
1159 capela 107
1160     return pBufferFill;
1161     }
1162    
1163    
1164     /**
1165     * Setting audio output type:
1166     * SET CHANNEL AUDIO_OUTPUT_TYPE <sampler-channel> <audio-output-type>
1167     *
1168     * @param pClient Pointer to client instance structure.
1169     * @param iSamplerChannel Sampler channel number.
1170     * @param pszAudioDriver Audio output driver type (e.g. "ALSA" or "JACK").
1171     */
1172     lscp_status_t lscp_set_channel_audio_type ( lscp_client_t *pClient, int iSamplerChannel, const char *pszAudioDriver )
1173     {
1174     char szQuery[LSCP_BUFSIZ];
1175    
1176     if (iSamplerChannel < 0 || pszAudioDriver == NULL)
1177     return LSCP_FAILED;
1178    
1179     sprintf(szQuery, "SET CHANNEL AUDIO_OUTPUT_TYPE %d %s\r\n", iSamplerChannel, pszAudioDriver);
1180     return lscp_client_query(pClient, szQuery);
1181     }
1182    
1183    
1184     /**
1185 capela 144 * Setting audio output device:
1186     * SET CHANNEL AUDIO_OUTPUT_DEVICE <sampler-channel> <device-id>
1187     *
1188     * @param pClient Pointer to client instance structure.
1189     * @param iSamplerChannel Sampler channel number.
1190     * @param iAudioDevice Audio output device number identifier.
1191     */
1192     lscp_status_t lscp_set_channel_audio_device ( lscp_client_t *pClient, int iSamplerChannel, int iAudioDevice )
1193     {
1194     char szQuery[LSCP_BUFSIZ];
1195    
1196     if (iSamplerChannel < 0 || iAudioDevice < 0)
1197     return LSCP_FAILED;
1198    
1199     sprintf(szQuery, "SET CHANNEL AUDIO_OUTPUT_DEVICE %d %d\r\n", iSamplerChannel, iAudioDevice);
1200     return lscp_client_query(pClient, szQuery);
1201     }
1202    
1203    
1204     /**
1205 capela 107 * Setting audio output channel:
1206     * SET CHANNEL AUDIO_OUTPUT_CHANNEL <sampler-channel> <audio-output-chan> <audio-input-chan>
1207     *
1208     * @param pClient Pointer to client instance structure.
1209     * @param iSamplerChannel Sampler channel number.
1210     * @param iAudioOut Audio output device channel to be routed from.
1211     * @param iAudioIn Audio output device channel to be routed into.
1212     *
1213     * @returns LSCP_OK on success, LSCP_FAILED otherwise.
1214     */
1215     lscp_status_t lscp_set_channel_audio_channel ( lscp_client_t *pClient, int iSamplerChannel, int iAudioOut, int iAudioIn )
1216     {
1217     char szQuery[LSCP_BUFSIZ];
1218    
1219     if (iSamplerChannel < 0 || iAudioOut < 0 || iAudioIn < 0)
1220     return LSCP_FAILED;
1221    
1222     sprintf(szQuery, "SET CHANNEL AUDIO_OUTPUT_CHANNELS %d %d %d\r\n", iSamplerChannel, iAudioOut, iAudioIn);
1223     return lscp_client_query(pClient, szQuery);
1224     }
1225    
1226    
1227     /**
1228     * Setting MIDI input type:
1229     * SET CHANNEL MIDI_INPUT_TYPE <sampler-channel> <midi-input-type>
1230     *
1231     * @param pClient Pointer to client instance structure.
1232     * @param iSamplerChannel Sampler channel number.
1233     * @param pszMidiDriver MIDI input driver type (e.g. "ALSA").
1234     *
1235     * @returns LSCP_OK on success, LSCP_FAILED otherwise.
1236     */
1237     lscp_status_t lscp_set_channel_midi_type ( lscp_client_t *pClient, int iSamplerChannel, const char *pszMidiDriver )
1238     {
1239     char szQuery[LSCP_BUFSIZ];
1240    
1241     if (iSamplerChannel < 0 || pszMidiDriver == NULL)
1242     return LSCP_FAILED;
1243    
1244     sprintf(szQuery, "SET CHANNEL MIDI_INPUT_TYPE %d %s\r\n", iSamplerChannel, pszMidiDriver);
1245     return lscp_client_query(pClient, szQuery);
1246     }
1247    
1248    
1249     /**
1250 capela 144 * Setting MIDI input device:
1251     * SET CHANNEL MIDI_INPUT_DEVICE <sampler-channel> <device-id>
1252     *
1253     * @param pClient Pointer to client instance structure.
1254     * @param iSamplerChannel Sampler channel number.
1255     * @param iMidiDevice MIDI input device number identifier.
1256     */
1257     lscp_status_t lscp_set_channel_midi_device ( lscp_client_t *pClient, int iSamplerChannel, int iMidiDevice )
1258     {
1259     char szQuery[LSCP_BUFSIZ];
1260    
1261     if (iSamplerChannel < 0 || iMidiDevice < 0)
1262     return LSCP_FAILED;
1263    
1264     sprintf(szQuery, "SET CHANNEL MIDI_INPUT_DEVICE %d %d\r\n", iSamplerChannel, iMidiDevice);
1265     return lscp_client_query(pClient, szQuery);
1266     }
1267    
1268    
1269     /**
1270 capela 107 * Setting MIDI input port:
1271     * SET CHANNEL MIDI_INPUT_PORT <sampler-channel> <midi-input-port>
1272     *
1273     * @param pClient Pointer to client instance structure.
1274     * @param iSamplerChannel Sampler channel number.
1275     * @param iMidiPort MIDI input driver virtual port number.
1276     *
1277     * @returns LSCP_OK on success, LSCP_FAILED otherwise.
1278     */
1279     lscp_status_t lscp_set_channel_midi_port ( lscp_client_t *pClient, int iSamplerChannel, int iMidiPort )
1280     {
1281     char szQuery[LSCP_BUFSIZ];
1282    
1283     if (iSamplerChannel < 0 || iMidiPort < 0)
1284     return LSCP_FAILED;
1285    
1286     sprintf(szQuery, "SET CHANNEL MIDI_INPUT_PORT %d %d\r\n", iSamplerChannel, iMidiPort);
1287     return lscp_client_query(pClient, szQuery);
1288     }
1289    
1290    
1291     /**
1292     * Setting MIDI input channel:
1293     * SET CHANNEL MIDI_INPUT_CHANNEL <sampler-channel> <midi-input-chan>
1294     *
1295     * @param pClient Pointer to client instance structure.
1296     * @param iSamplerChannel Sampler channel number.
1297     * @param iMidiChannel MIDI channel number to listen (1-16) or
1298     * zero (0) to listen on all channels.
1299     *
1300     * @returns LSCP_OK on success, LSCP_FAILED otherwise.
1301     */
1302     lscp_status_t lscp_set_channel_midi_channel ( lscp_client_t *pClient, int iSamplerChannel, int iMidiChannel )
1303     {
1304     char szQuery[LSCP_BUFSIZ];
1305    
1306     if (iSamplerChannel < 0 || iMidiChannel < 0 || iMidiChannel > 16)
1307     return LSCP_FAILED;
1308    
1309     if (iMidiChannel > 0)
1310     sprintf(szQuery, "SET CHANNEL MIDI_INPUT_CHANNEL %d %d\r\n", iSamplerChannel, iMidiChannel);
1311     else
1312     sprintf(szQuery, "SET CHANNEL MIDI_INPUT_CHANNEL %d ALL\r\n", iSamplerChannel);
1313     return lscp_client_query(pClient, szQuery);
1314     }
1315    
1316    
1317     /**
1318     * Setting channel volume:
1319     * SET CHANNEL VOLUME <sampler-channel> <volume>
1320     *
1321     * @param pClient Pointer to client instance structure.
1322     * @param iSamplerChannel Sampler channel number.
1323     * @param fVolume Sampler channel volume as a positive floating point
1324     * number, where a value less than 1.0 for attenuation,
1325     * and greater than 1.0 for amplification.
1326     *
1327     * @returns LSCP_OK on success, LSCP_FAILED otherwise.
1328     */
1329     lscp_status_t lscp_set_channel_volume ( lscp_client_t *pClient, int iSamplerChannel, float fVolume )
1330     {
1331     char szQuery[LSCP_BUFSIZ];
1332    
1333     if (iSamplerChannel < 0 || fVolume < 0.0)
1334     return LSCP_FAILED;
1335    
1336     sprintf(szQuery, "SET CHANNEL VOLUME %d %g\r\n", iSamplerChannel, fVolume);
1337     return lscp_client_query(pClient, szQuery);
1338     }
1339    
1340    
1341     /**
1342     * Resetting a sampler channel:
1343     * RESET CHANNEL <sampler-channel>
1344     *
1345     * @param pClient Pointer to client instance structure.
1346     * @param iSamplerChannel Sampler channel number.
1347     *
1348     * @returns LSCP_OK on success, LSCP_FAILED otherwise.
1349     */
1350     lscp_status_t lscp_reset_channel ( lscp_client_t *pClient, int iSamplerChannel )
1351     {
1352     char szQuery[LSCP_BUFSIZ];
1353    
1354     if (iSamplerChannel < 0)
1355     return LSCP_FAILED;
1356    
1357     sprintf(szQuery, "RESET CHANNEL %d\r\n", iSamplerChannel);
1358     return lscp_client_query(pClient, szQuery);
1359     }
1360    
1361    
1362     // end of client.c

  ViewVC Help
Powered by ViewVC