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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 623 - (hide annotations) (download)
Thu Jun 9 10:37:19 2005 UTC (17 years, 2 months ago) by capela
File MIME type: text/plain
File size: 49578 byte(s)
* [bug #11] Timeout flush idiosyncrasy is now a feature;
  this just tries to flush the receive buffer whenever
  any previous transaction has failed due to a timeout.

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

  ViewVC Help
Powered by ViewVC