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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 564 - (hide annotations) (download)
Sun May 22 22:02:00 2005 UTC (18 years, 10 months ago) by capela
File MIME type: text/plain
File size: 49544 byte(s)
* Added support for the newest LSCP command: GET SERVER INFO.

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     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 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    
352     // Initialize the transaction mutex.
353     lscp_mutex_init(pClient->mutex);
354 capela 177 lscp_cond_init(pClient->cond);
355 capela 107
356     // Finally we've some success...
357     return pClient;
358     }
359    
360    
361     /**
362     * Wait for a client instance to terminate graciously.
363     *
364     * @param pClient Pointer to client instance structure.
365     */
366     lscp_status_t lscp_client_join ( lscp_client_t *pClient )
367     {
368     if (pClient == NULL)
369     return LSCP_FAILED;
370    
371     #ifdef DEBUG
372     fprintf(stderr, "lscp_client_join: pClient=%p.\n", pClient);
373     #endif
374    
375 capela 132 // lscp_socket_agent_join(&(pClient->evt));
376     lscp_socket_agent_join(&(pClient->cmd));
377 capela 107
378     return LSCP_OK;
379     }
380    
381    
382     /**
383     * Terminate and destroy a client instance.
384     *
385     * @param pClient Pointer to client instance structure.
386     *
387     * @returns LSCP_OK on success, LSCP_FAILED otherwise.
388     */
389     lscp_status_t lscp_client_destroy ( lscp_client_t *pClient )
390     {
391     if (pClient == NULL)
392     return LSCP_FAILED;
393    
394     #ifdef DEBUG
395     fprintf(stderr, "lscp_client_destroy: pClient=%p.\n", pClient);
396     #endif
397    
398 capela 132 // Lock this section up.
399     lscp_mutex_lock(pClient->mutex);
400 capela 562
401 capela 107 // Free up all cached members.
402 capela 179 lscp_channel_info_free(&(pClient->channel_info));
403     lscp_engine_info_free(&(pClient->engine_info));
404 capela 564 lscp_server_info_free(&(pClient->server_info));
405 capela 179 lscp_param_info_free(&(pClient->midi_port_param_info));
406     lscp_param_info_free(&(pClient->audio_channel_param_info));
407     lscp_device_port_info_free(&(pClient->midi_port_info));
408     lscp_device_port_info_free(&(pClient->audio_channel_info));
409     lscp_param_info_free(&(pClient->midi_param_info));
410     lscp_param_info_free(&(pClient->audio_param_info));
411     lscp_device_info_free(&(pClient->midi_device_info));
412     lscp_device_info_free(&(pClient->audio_device_info));
413     lscp_driver_info_free(&(pClient->midi_driver_info));
414     lscp_driver_info_free(&(pClient->audio_driver_info));
415 capela 107 // Free available engine table.
416     lscp_szsplit_destroy(pClient->audio_drivers);
417     lscp_szsplit_destroy(pClient->midi_drivers);
418 capela 125 lscp_isplit_destroy(pClient->audio_devices);
419     lscp_isplit_destroy(pClient->midi_devices);
420 capela 107 lscp_szsplit_destroy(pClient->engines);
421 capela 125 lscp_isplit_destroy(pClient->channels);
422 capela 107 // Make them null.
423     pClient->audio_drivers = NULL;
424     pClient->midi_drivers = NULL;
425     pClient->engines = NULL;
426     // Free result error stuff.
427 capela 132 lscp_client_set_result(pClient, NULL, 0);
428 capela 167 // Free stream usage stuff.
429 capela 107 if (pClient->buffer_fill)
430     free(pClient->buffer_fill);
431     pClient->buffer_fill = NULL;
432     pClient->iStreamCount = 0;
433     pClient->iTimeout = 0;
434    
435     // Free socket agents.
436 capela 132 lscp_socket_agent_free(&(pClient->evt));
437     lscp_socket_agent_free(&(pClient->cmd));
438 capela 107
439     // Last but not least, free good ol'transaction mutex.
440 capela 132 lscp_mutex_unlock(pClient->mutex);
441 capela 107 lscp_mutex_destroy(pClient->mutex);
442 capela 177 lscp_cond_destroy(pClient->cond);
443 capela 107
444     free(pClient);
445    
446     return LSCP_OK;
447     }
448    
449    
450     /**
451     * Set the client transaction timeout interval.
452     *
453     * @param pClient Pointer to client instance structure.
454     * @param iTimeout Transaction timeout in milliseconds.
455     *
456     * @returns LSCP_OK on success, LSCP_FAILED otherwise.
457     */
458     lscp_status_t lscp_client_set_timeout ( lscp_client_t *pClient, int iTimeout )
459     {
460     if (pClient == NULL)
461     return LSCP_FAILED;
462     if (iTimeout < 0)
463     return LSCP_FAILED;
464    
465     pClient->iTimeout = iTimeout;
466     return LSCP_OK;
467     }
468    
469    
470     /**
471     * Get the client transaction timeout interval.
472     *
473     * @param pClient Pointer to client instance structure.
474     *
475     * @returns The current timeout value milliseconds, -1 in case of failure.
476     */
477     int lscp_client_get_timeout ( lscp_client_t *pClient )
478     {
479     if (pClient == NULL)
480     return -1;
481    
482     return pClient->iTimeout;
483     }
484    
485    
486     //-------------------------------------------------------------------------
487     // Client common protocol functions.
488    
489     /**
490     * Submit a command query line string to the server. The query string
491     * must be cr/lf and null terminated. Besides the return code, the
492     * specific server response to the command request is made available
493     * by the @ref lscp_client_get_result and @ref lscp_client_get_errno
494     * function calls.
495     *
496     * @param pClient Pointer to client instance structure.
497     * @param pszQuery Command request line to be sent to server,
498     * must be cr/lf and null terminated.
499     *
500     * @returns LSCP_OK on success, LSCP_FAILED otherwise.
501     */
502     lscp_status_t lscp_client_query ( lscp_client_t *pClient, const char *pszQuery )
503     {
504 capela 132 lscp_status_t ret;
505 capela 562
506 capela 107 // Lock this section up.
507     lscp_mutex_lock(pClient->mutex);
508    
509 capela 132 // Just make the now guarded call.
510     ret = lscp_client_call(pClient, pszQuery);
511 capela 562
512 capela 132 // Unlock this section down.
513 capela 107 lscp_mutex_unlock(pClient->mutex);
514 capela 562
515 capela 107 return ret;
516     }
517    
518     /**
519     * Get the last received result string. In case of error or warning,
520     * this is the text of the error or warning message issued.
521     *
522     * @param pClient Pointer to client instance structure.
523     *
524     * @returns A pointer to the literal null-terminated result string as
525     * of the last command request.
526     */
527     const char *lscp_client_get_result ( lscp_client_t *pClient )
528     {
529     if (pClient == NULL)
530     return NULL;
531    
532     return pClient->pszResult;
533     }
534    
535    
536     /**
537     * Get the last error/warning number received.
538     *
539     * @param pClient Pointer to client instance structure.
540     *
541     * @returns The numerical value of the last error or warning
542     * response code received.
543     */
544     int lscp_client_get_errno ( lscp_client_t *pClient )
545     {
546     if (pClient == NULL)
547     return -1;
548    
549     return pClient->iErrno;
550     }
551    
552    
553     //-------------------------------------------------------------------------
554     // Client registration protocol functions.
555    
556     /**
557 capela 144 * Register frontend for receiving event messages:
558 capela 562 * SUBSCRIBE CHANNEL_COUNT | VOICE_COUNT | STREAM_COUNT | BUFFER_FILL
559 capela 144 * | CHANNEL_INFO | MISCELLANEOUS
560 capela 107 *
561     * @param pClient Pointer to client instance structure.
562 capela 144 * @param events Bit-wise OR'ed event flags to subscribe.
563 capela 107 *
564     * @returns LSCP_OK on success, LSCP_FAILED otherwise.
565     */
566 capela 144 lscp_status_t lscp_client_subscribe ( lscp_client_t *pClient, lscp_event_t events )
567 capela 107 {
568 capela 144 lscp_status_t ret = LSCP_FAILED;
569 capela 107
570 capela 144 if (pClient == NULL)
571 capela 107 return LSCP_FAILED;
572    
573 capela 132 // Lock this section up.
574     lscp_mutex_lock(pClient->mutex);
575 capela 144
576     // If applicable, start the alternate connection...
577     if (pClient->events == LSCP_EVENT_NONE)
578     ret = _lscp_client_evt_connect(pClient);
579 capela 562
580 capela 144 // Send the subscription commands.
581 capela 562 if (ret == LSCP_OK && (events & LSCP_EVENT_CHANNEL_COUNT))
582     ret = _lscp_client_evt_request(pClient, 1, LSCP_EVENT_CHANNEL_COUNT);
583 capela 144 if (ret == LSCP_OK && (events & LSCP_EVENT_VOICE_COUNT))
584     ret = _lscp_client_evt_request(pClient, 1, LSCP_EVENT_VOICE_COUNT);
585     if (ret == LSCP_OK && (events & LSCP_EVENT_STREAM_COUNT))
586     ret = _lscp_client_evt_request(pClient, 1, LSCP_EVENT_STREAM_COUNT);
587     if (ret == LSCP_OK && (events & LSCP_EVENT_BUFFER_FILL))
588     ret = _lscp_client_evt_request(pClient, 1, LSCP_EVENT_BUFFER_FILL);
589     if (ret == LSCP_OK && (events & LSCP_EVENT_CHANNEL_INFO))
590     ret = _lscp_client_evt_request(pClient, 1, LSCP_EVENT_CHANNEL_INFO);
591     if (ret == LSCP_OK && (events & LSCP_EVENT_MISCELLANEOUS))
592     ret = _lscp_client_evt_request(pClient, 1, LSCP_EVENT_MISCELLANEOUS);
593 capela 107
594 capela 132 // Unlock this section down.
595     lscp_mutex_unlock(pClient->mutex);
596    
597 capela 107 return ret;
598     }
599    
600    
601     /**
602 capela 144 * Deregister frontend from receiving UDP event messages anymore:
603 capela 562 * SUBSCRIBE CHANNEL_COUNT | VOICE_COUNT | STREAM_COUNT | BUFFER_FILL
604 capela 144 * | CHANNEL_INFO | MISCELLANEOUS
605 capela 107 *
606     * @param pClient Pointer to client instance structure.
607 capela 144 * @param events Bit-wise OR'ed event flags to unsubscribe.
608 capela 107 *
609     * @returns LSCP_OK on success, LSCP_FAILED otherwise.
610     */
611 capela 144 lscp_status_t lscp_client_unsubscribe ( lscp_client_t *pClient, lscp_event_t events )
612 capela 107 {
613 capela 144 lscp_status_t ret = LSCP_OK;
614 capela 107
615     if (pClient == NULL)
616     return LSCP_FAILED;
617    
618 capela 132 // Lock this section up.
619     lscp_mutex_lock(pClient->mutex);
620    
621 capela 144 // Send the unsubscription commands.
622 capela 562 if (ret == LSCP_OK && (events & LSCP_EVENT_CHANNEL_COUNT))
623     ret = _lscp_client_evt_request(pClient, 0, LSCP_EVENT_CHANNEL_COUNT);
624 capela 144 if (ret == LSCP_OK && (events & LSCP_EVENT_VOICE_COUNT))
625     ret = _lscp_client_evt_request(pClient, 0, LSCP_EVENT_VOICE_COUNT);
626     if (ret == LSCP_OK && (events & LSCP_EVENT_STREAM_COUNT))
627     ret = _lscp_client_evt_request(pClient, 0, LSCP_EVENT_STREAM_COUNT);
628     if (ret == LSCP_OK && (events & LSCP_EVENT_BUFFER_FILL))
629     ret = _lscp_client_evt_request(pClient, 0, LSCP_EVENT_BUFFER_FILL);
630     if (ret == LSCP_OK && (events & LSCP_EVENT_CHANNEL_INFO))
631     ret = _lscp_client_evt_request(pClient, 0, LSCP_EVENT_CHANNEL_INFO);
632     if (ret == LSCP_OK && (events & LSCP_EVENT_MISCELLANEOUS))
633     ret = _lscp_client_evt_request(pClient, 0, LSCP_EVENT_MISCELLANEOUS);
634 capela 107
635 capela 144 // If necessary, close the alternate connection...
636     if (pClient->events == LSCP_EVENT_NONE)
637     lscp_socket_agent_free(&(pClient->evt));
638    
639 capela 132 // Unlock this section down.
640     lscp_mutex_unlock(pClient->mutex);
641    
642 capela 107 return ret;
643     }
644    
645    
646 capela 213 /**
647     * Getting current subscribed events.
648     *
649     * @param pClient Pointer to client instance structure.
650     *
651     * @returns The current subscrived bit-wise OR'ed event flags.
652     */
653     lscp_event_t lscp_client_get_events ( lscp_client_t *pClient )
654     {
655     if (pClient == NULL)
656     return LSCP_EVENT_NONE;
657    
658     return pClient->events;
659     }
660    
661    
662 capela 107 //-------------------------------------------------------------------------
663     // Client command protocol functions.
664    
665     /**
666     * Loading an instrument:
667     * LOAD INSTRUMENT <filename> <instr-index> <sampler-channel>
668     *
669     * @param pClient Pointer to client instance structure.
670     * @param pszFileName Instrument file name.
671     * @param iInstrIndex Instrument index number.
672     * @param iSamplerChannel Sampler Channel.
673     *
674     * @returns LSCP_OK on success, LSCP_FAILED otherwise.
675     */
676     lscp_status_t lscp_load_instrument ( lscp_client_t *pClient, const char *pszFileName, int iInstrIndex, int iSamplerChannel )
677     {
678     char szQuery[LSCP_BUFSIZ];
679    
680     if (pszFileName == NULL || iSamplerChannel < 0)
681     return LSCP_FAILED;
682    
683 capela 144 sprintf(szQuery, "LOAD INSTRUMENT '%s' %d %d\r\n", pszFileName, iInstrIndex, iSamplerChannel);
684 capela 107 return lscp_client_query(pClient, szQuery);
685     }
686    
687    
688     /**
689 capela 144 * Loading an instrument in the background (non modal):
690     * LOAD INSTRUMENT NON_MODAL <filename> <instr-index> <sampler-channel>
691     *
692     * @param pClient Pointer to client instance structure.
693     * @param pszFileName Instrument file name.
694     * @param iInstrIndex Instrument index number.
695     * @param iSamplerChannel Sampler Channel.
696     *
697     * @returns LSCP_OK on success, LSCP_FAILED otherwise.
698     */
699     lscp_status_t lscp_load_instrument_non_modal ( lscp_client_t *pClient, const char *pszFileName, int iInstrIndex, int iSamplerChannel )
700     {
701     char szQuery[LSCP_BUFSIZ];
702    
703     if (pszFileName == NULL || iSamplerChannel < 0)
704     return LSCP_FAILED;
705    
706     sprintf(szQuery, "LOAD INSTRUMENT NON_MODAL '%s' %d %d\r\n", pszFileName, iInstrIndex, iSamplerChannel);
707     return lscp_client_query(pClient, szQuery);
708     }
709    
710    
711     /**
712 capela 107 * Loading a sampler engine:
713     * LOAD ENGINE <engine-name> <sampler-channel>
714     *
715     * @param pClient Pointer to client instance structure.
716     * @param pszEngineName Engine name.
717     * @param iSamplerChannel Sampler channel number.
718     *
719     * @returns LSCP_OK on success, LSCP_FAILED otherwise.
720     */
721     lscp_status_t lscp_load_engine ( lscp_client_t *pClient, const char *pszEngineName, int iSamplerChannel )
722     {
723     char szQuery[LSCP_BUFSIZ];
724    
725     if (pszEngineName == NULL || iSamplerChannel < 0)
726     return LSCP_FAILED;
727    
728     sprintf(szQuery, "LOAD ENGINE %s %d\r\n", pszEngineName, iSamplerChannel);
729     return lscp_client_query(pClient, szQuery);
730     }
731    
732    
733     /**
734     * Current number of sampler channels:
735     * GET CHANNELS
736     *
737     * @param pClient Pointer to client instance structure.
738     *
739     * @returns The current total number of sampler channels on success,
740     * -1 otherwise.
741     */
742     int lscp_get_channels ( lscp_client_t *pClient )
743     {
744     int iChannels = -1;
745 capela 132
746     // Lock this section up.
747     lscp_mutex_lock(pClient->mutex);
748    
749     if (lscp_client_call(pClient, "GET CHANNELS\r\n") == LSCP_OK)
750 capela 107 iChannels = atoi(lscp_client_get_result(pClient));
751 capela 132
752     // Unlock this section doen.
753     lscp_mutex_unlock(pClient->mutex);
754    
755 capela 107 return iChannels;
756     }
757    
758    
759     /**
760 capela 125 * List current sampler channels number identifiers:
761     * LIST CHANNELS
762     *
763     * @param pClient Pointer to client instance structure.
764     *
765     * @returns An array of the sampler channels identifiers as positive integers,
766     * terminated with -1 on success, NULL otherwise.
767     */
768     int *lscp_list_channels ( lscp_client_t *pClient )
769     {
770     const char *pszSeps = ",";
771    
772     if (pClient == NULL)
773     return NULL;
774 capela 562
775 capela 132 // Lock this section up.
776     lscp_mutex_lock(pClient->mutex);
777    
778 capela 125 if (pClient->channels) {
779     lscp_isplit_destroy(pClient->channels);
780     pClient->channels = NULL;
781     }
782    
783 capela 132 if (lscp_client_call(pClient, "LIST CHANNELS\r\n") == LSCP_OK)
784 capela 125 pClient->channels = lscp_isplit_create(lscp_client_get_result(pClient), pszSeps);
785    
786 capela 132 // Unlock this section down.
787     lscp_mutex_unlock(pClient->mutex);
788    
789 capela 125 return pClient->channels;
790     }
791    
792    
793     /**
794 capela 107 * Adding a new sampler channel:
795     * ADD CHANNEL
796     *
797     * @param pClient Pointer to client instance structure.
798     *
799     * @returns The new sampler channel number identifier,
800     * or -1 in case of failure.
801     */
802     int lscp_add_channel ( lscp_client_t *pClient )
803     {
804     int iSamplerChannel = -1;
805 capela 132
806     // Lock this section up.
807     lscp_mutex_lock(pClient->mutex);
808    
809     if (lscp_client_call(pClient, "ADD CHANNEL\r\n") == LSCP_OK)
810 capela 107 iSamplerChannel = atoi(lscp_client_get_result(pClient));
811 capela 562
812 capela 132 // Unlock this section down.
813     lscp_mutex_unlock(pClient->mutex);
814    
815 capela 107 return iSamplerChannel;
816     }
817    
818    
819     /**
820     * Removing a sampler channel:
821     * REMOVE CHANNEL <sampler-channel>
822     *
823     * @param pClient Pointer to client instance structure.
824     * @param iSamplerChannel Sampler channel number.
825     *
826     * @returns LSCP_OK on success, LSCP_FAILED otherwise.
827     */
828     lscp_status_t lscp_remove_channel ( lscp_client_t *pClient, int iSamplerChannel )
829     {
830     char szQuery[LSCP_BUFSIZ];
831    
832     if (iSamplerChannel < 0)
833     return LSCP_FAILED;
834    
835     sprintf(szQuery, "REMOVE CHANNEL %d\r\n", iSamplerChannel);
836     return lscp_client_query(pClient, szQuery);
837     }
838    
839    
840     /**
841 capela 523 * Getting all available engines count:
842 capela 107 * GET AVAILABLE_ENGINES
843     *
844     * @param pClient Pointer to client instance structure.
845     *
846 capela 523 * @returns The current total number of sampler engines on success,
847     * -1 otherwise.
848     */
849     int lscp_get_available_engines ( lscp_client_t *pClient )
850     {
851 capela 562 int iAvailableEngines = -1;
852 capela 523
853     // Lock this section up.
854     lscp_mutex_lock(pClient->mutex);
855    
856     if (lscp_client_call(pClient, "GET AVAILABLE_ENGINES\r\n") == LSCP_OK)
857     iAvailableEngines = atoi(lscp_client_get_result(pClient));
858    
859     // Unlock this section down.
860     lscp_mutex_unlock(pClient->mutex);
861    
862     return iAvailableEngines;
863     }
864    
865    
866     /**
867     * Getting all available engines:
868     * LIST AVAILABLE_ENGINES
869     *
870     * @param pClient Pointer to client instance structure.
871     *
872 capela 107 * @returns A NULL terminated array of engine name strings,
873     * or NULL in case of failure.
874     */
875 capela 523 const char **lscp_list_available_engines ( lscp_client_t *pClient )
876 capela 107 {
877     const char *pszSeps = ",";
878    
879 capela 132 // Lock this section up.
880     lscp_mutex_lock(pClient->mutex);
881    
882 capela 107 if (pClient->engines) {
883     lscp_szsplit_destroy(pClient->engines);
884     pClient->engines = NULL;
885     }
886    
887 capela 523 if (lscp_client_call(pClient, "LIST AVAILABLE_ENGINES\r\n") == LSCP_OK)
888 capela 107 pClient->engines = lscp_szsplit_create(lscp_client_get_result(pClient), pszSeps);
889    
890 capela 132 // Unlock this section down.
891     lscp_mutex_unlock(pClient->mutex);
892    
893 capela 107 return (const char **) pClient->engines;
894     }
895    
896    
897     /**
898     * Getting information about an engine.
899     * GET ENGINE INFO <engine-name>
900     *
901     * @param pClient Pointer to client instance structure.
902     * @param pszEngineName Engine name.
903     *
904     * @returns A pointer to a @ref lscp_engine_info_t structure, with all the
905     * information of the given sampler engine, or NULL in case of failure.
906     */
907     lscp_engine_info_t *lscp_get_engine_info ( lscp_client_t *pClient, const char *pszEngineName )
908     {
909     lscp_engine_info_t *pEngineInfo;
910     char szQuery[LSCP_BUFSIZ];
911     const char *pszResult;
912     const char *pszSeps = ":";
913     const char *pszCrlf = "\r\n";
914     char *pszToken;
915     char *pch;
916    
917     if (pszEngineName == NULL)
918     return NULL;
919    
920 capela 132 // Lock this section up.
921     lscp_mutex_lock(pClient->mutex);
922    
923 capela 107 pEngineInfo = &(pClient->engine_info);
924     lscp_engine_info_reset(pEngineInfo);
925    
926     sprintf(szQuery, "GET ENGINE INFO %s\r\n", pszEngineName);
927 capela 132 if (lscp_client_call(pClient, szQuery) == LSCP_OK) {
928     pszResult = lscp_client_get_result(pClient);
929     pszToken = lscp_strtok((char *) pszResult, pszSeps, &(pch));
930     while (pszToken) {
931     if (strcasecmp(pszToken, "DESCRIPTION") == 0) {
932     pszToken = lscp_strtok(NULL, pszCrlf, &(pch));
933     if (pszToken)
934 capela 180 lscp_unquote_dup(&(pEngineInfo->description), &pszToken);
935 capela 132 }
936     else if (strcasecmp(pszToken, "VERSION") == 0) {
937     pszToken = lscp_strtok(NULL, pszCrlf, &(pch));
938     if (pszToken)
939 capela 180 lscp_unquote_dup(&(pEngineInfo->version), &pszToken);
940 capela 132 }
941     pszToken = lscp_strtok(NULL, pszSeps, &(pch));
942 capela 107 }
943     }
944 capela 132 else pEngineInfo = NULL;
945 capela 562
946 capela 132 // Unlock this section down.
947     lscp_mutex_unlock(pClient->mutex);
948 capela 107
949     return pEngineInfo;
950     }
951    
952    
953     /**
954     * Getting sampler channel informations:
955     * GET CHANNEL INFO <sampler-channel>
956     *
957     * @param pClient Pointer to client instance structure.
958     * @param iSamplerChannel Sampler channel number.
959     *
960     * @returns A pointer to a @ref lscp_channel_info_t structure, with all the
961     * information of the given sampler channel, or NULL in case of failure.
962     */
963     lscp_channel_info_t *lscp_get_channel_info ( lscp_client_t *pClient, int iSamplerChannel )
964     {
965     lscp_channel_info_t *pChannelInfo;
966     char szQuery[LSCP_BUFSIZ];
967     const char *pszResult;
968     const char *pszSeps = ":";
969     const char *pszCrlf = "\r\n";
970     char *pszToken;
971     char *pch;
972    
973     if (iSamplerChannel < 0)
974     return NULL;
975    
976 capela 132 // Lock this section up.
977     lscp_mutex_lock(pClient->mutex);
978 capela 562
979 capela 107 pChannelInfo = &(pClient->channel_info);
980     lscp_channel_info_reset(pChannelInfo);
981    
982     sprintf(szQuery, "GET CHANNEL INFO %d\r\n", iSamplerChannel);
983 capela 132 if (lscp_client_call(pClient, szQuery) == LSCP_OK) {
984     pszResult = lscp_client_get_result(pClient);
985     pszToken = lscp_strtok((char *) pszResult, pszSeps, &(pch));
986     while (pszToken) {
987     if (strcasecmp(pszToken, "ENGINE_NAME") == 0) {
988     pszToken = lscp_strtok(NULL, pszCrlf, &(pch));
989     if (pszToken)
990 capela 180 lscp_unquote_dup(&(pChannelInfo->engine_name), &pszToken);
991 capela 132 }
992     else if (strcasecmp(pszToken, "AUDIO_OUTPUT_DEVICE") == 0) {
993     pszToken = lscp_strtok(NULL, pszCrlf, &(pch));
994     if (pszToken)
995     pChannelInfo->audio_device = atoi(lscp_ltrim(pszToken));
996     }
997     else if (strcasecmp(pszToken, "AUDIO_OUTPUT_CHANNELS") == 0) {
998     pszToken = lscp_strtok(NULL, pszCrlf, &(pch));
999     if (pszToken)
1000     pChannelInfo->audio_channels = atoi(lscp_ltrim(pszToken));
1001     }
1002     else if (strcasecmp(pszToken, "AUDIO_OUTPUT_ROUTING") == 0) {
1003     pszToken = lscp_strtok(NULL, pszCrlf, &(pch));
1004 capela 180 if (pszToken) {
1005     if (pChannelInfo->audio_routing)
1006     lscp_szsplit_destroy(pChannelInfo->audio_routing);
1007 capela 132 pChannelInfo->audio_routing = lscp_szsplit_create(pszToken, ",");
1008 capela 180 }
1009 capela 132 }
1010     else if (strcasecmp(pszToken, "INSTRUMENT_FILE") == 0) {
1011     pszToken = lscp_strtok(NULL, pszCrlf, &(pch));
1012     if (pszToken)
1013 capela 180 lscp_unquote_dup(&(pChannelInfo->instrument_file), &pszToken);
1014 capela 132 }
1015     else if (strcasecmp(pszToken, "INSTRUMENT_NR") == 0) {
1016     pszToken = lscp_strtok(NULL, pszCrlf, &(pch));
1017     if (pszToken)
1018     pChannelInfo->instrument_nr = atoi(lscp_ltrim(pszToken));
1019     }
1020 capela 378 else if (strcasecmp(pszToken, "INSTRUMENT_NAME") == 0) {
1021     pszToken = lscp_strtok(NULL, pszCrlf, &(pch));
1022     if (pszToken)
1023     lscp_unquote_dup(&(pChannelInfo->instrument_name), &pszToken);
1024     }
1025 capela 132 else if (strcasecmp(pszToken, "INSTRUMENT_STATUS") == 0) {
1026     pszToken = lscp_strtok(NULL, pszCrlf, &(pch));
1027     if (pszToken)
1028     pChannelInfo->instrument_status = atoi(lscp_ltrim(pszToken));
1029     }
1030     else if (strcasecmp(pszToken, "MIDI_INPUT_DEVICE") == 0) {
1031     pszToken = lscp_strtok(NULL, pszCrlf, &(pch));
1032     if (pszToken)
1033     pChannelInfo->midi_device = atoi(lscp_ltrim(pszToken));
1034     }
1035     else if (strcasecmp(pszToken, "MIDI_INPUT_PORT") == 0) {
1036     pszToken = lscp_strtok(NULL, pszCrlf, &(pch));
1037     if (pszToken)
1038     pChannelInfo->midi_port = atoi(lscp_ltrim(pszToken));
1039     }
1040     else if (strcasecmp(pszToken, "MIDI_INPUT_CHANNEL") == 0) {
1041     pszToken = lscp_strtok(NULL, pszCrlf, &(pch));
1042 capela 279 if (pszToken) {
1043     pszToken = lscp_ltrim(pszToken);
1044     if (strcasecmp(pszToken, "ALL") == 0)
1045     pChannelInfo->midi_channel = LSCP_MIDI_CHANNEL_ALL;
1046     else
1047     pChannelInfo->midi_channel = atoi(pszToken);
1048     }
1049 capela 132 }
1050     else if (strcasecmp(pszToken, "VOLUME") == 0) {
1051     pszToken = lscp_strtok(NULL, pszCrlf, &(pch));
1052     if (pszToken)
1053     pChannelInfo->volume = (float) atof(lscp_ltrim(pszToken));
1054     }
1055     pszToken = lscp_strtok(NULL, pszSeps, &(pch));
1056 capela 107 }
1057     }
1058 capela 132 else pChannelInfo = NULL;
1059 capela 562
1060 capela 132 // Unlock this section up.
1061     lscp_mutex_unlock(pClient->mutex);
1062 capela 107
1063     return pChannelInfo;
1064     }
1065    
1066    
1067     /**
1068     * Current number of active voices:
1069     * GET CHANNEL VOICE_COUNT <sampler-channel>
1070     *
1071     * @param pClient Pointer to client instance structure.
1072     * @param iSamplerChannel Sampler channel number.
1073     *
1074     * @returns The number of voices currently active, -1 in case of failure.
1075     */
1076     int lscp_get_channel_voice_count ( lscp_client_t *pClient, int iSamplerChannel )
1077     {
1078     char szQuery[LSCP_BUFSIZ];
1079     int iVoiceCount = -1;
1080    
1081     if (iSamplerChannel < 0)
1082     return iVoiceCount;
1083    
1084 capela 132 // Lock this section up.
1085     lscp_mutex_lock(pClient->mutex);
1086    
1087 capela 107 sprintf(szQuery, "GET CHANNEL VOICE_COUNT %d\r\n", iSamplerChannel);
1088 capela 132 if (lscp_client_call(pClient, szQuery) == LSCP_OK)
1089 capela 107 iVoiceCount = atoi(lscp_client_get_result(pClient));
1090    
1091 capela 132 // Unlock this section down.
1092     lscp_mutex_unlock(pClient->mutex);
1093    
1094 capela 107 return iVoiceCount;
1095     }
1096    
1097    
1098     /**
1099     * Current number of active disk streams:
1100     * GET CHANNEL STREAM_COUNT <sampler-channel>
1101     *
1102 capela 167 * @param pClient Pointer to client instance structure.
1103     * @param iSamplerChannel Sampler channel number.
1104     *
1105 capela 107 * @returns The number of active disk streams on success, -1 otherwise.
1106     */
1107     int lscp_get_channel_stream_count ( lscp_client_t *pClient, int iSamplerChannel )
1108     {
1109     char szQuery[LSCP_BUFSIZ];
1110     int iStreamCount = -1;
1111    
1112     if (iSamplerChannel < 0)
1113     return iStreamCount;
1114    
1115 capela 132 // Lock this section up.
1116     lscp_mutex_lock(pClient->mutex);
1117    
1118 capela 107 sprintf(szQuery, "GET CHANNEL STREAM_COUNT %d\r\n", iSamplerChannel);
1119 capela 132 if (lscp_client_call(pClient, szQuery) == LSCP_OK)
1120 capela 107 iStreamCount = atoi(lscp_client_get_result(pClient));
1121    
1122 capela 132 // Unlock this section down.
1123     lscp_mutex_unlock(pClient->mutex);
1124    
1125 capela 107 return iStreamCount;
1126     }
1127    
1128    
1129     /**
1130 capela 167 * Current least usage of active disk streams.
1131     *
1132     * @param pClient Pointer to client instance structure.
1133     * @param iSamplerChannel Sampler channel number.
1134     *
1135     * @returns The usage percentage of the least filled active disk stream
1136     * on success, -1 otherwise.
1137     */
1138     int lscp_get_channel_stream_usage ( lscp_client_t *pClient, int iSamplerChannel )
1139     {
1140     char szQuery[LSCP_BUFSIZ];
1141     int iStreamUsage = -1;
1142     const char *pszResult;
1143     const char *pszSeps = "[]%,";
1144     char *pszToken;
1145     char *pch;
1146     int iStream;
1147     int iPercent;
1148    
1149     if (iSamplerChannel < 0)
1150     return iStreamUsage;
1151    
1152     // Lock this section up.
1153     lscp_mutex_lock(pClient->mutex);
1154    
1155     iStream = 0;
1156     sprintf(szQuery, "GET CHANNEL BUFFER_FILL PERCENTAGE %d\r\n", iSamplerChannel);
1157     if (lscp_client_call(pClient, szQuery) == LSCP_OK) {
1158     pszResult = lscp_client_get_result(pClient);
1159     pszToken = lscp_strtok((char *) pszResult, pszSeps, &(pch));
1160     while (pszToken) {
1161     if (*pszToken) {
1162     // Skip stream id.
1163     pszToken = lscp_strtok(NULL, pszSeps, &(pch));
1164     if (pszToken == NULL)
1165     break;
1166     // Get least buffer fill percentage.
1167     iPercent = atol(pszToken);
1168     if (iStreamUsage > iPercent || iStream == 0)
1169     iStreamUsage = iPercent;
1170     iStream++;
1171     }
1172     pszToken = lscp_strtok(NULL, pszSeps, &(pch));
1173     }
1174     }
1175    
1176     // Unlock this section down.
1177     lscp_mutex_unlock(pClient->mutex);
1178    
1179     return iStreamUsage;
1180     }
1181    
1182    
1183     /**
1184 capela 107 * Current fill state of disk stream buffers:
1185     * GET CHANNEL BUFFER_FILL {BYTES|PERCENTAGE} <sampler-channel>
1186     *
1187     * @param pClient Pointer to client instance structure.
1188     * @param usage_type Usage type to be returned, either
1189     * @ref LSCP_USAGE_BYTES, or
1190     * @ref LSCP_USAGE_PERCENTAGE.
1191     * @param iSamplerChannel Sampler channel number.
1192     *
1193     * @returns A pointer to a @ref lscp_buffer_fill_t structure, with the
1194     * information of the current disk stream buffer fill usage, for the given
1195     * sampler channel, or NULL in case of failure.
1196     */
1197     lscp_buffer_fill_t *lscp_get_channel_buffer_fill ( lscp_client_t *pClient, lscp_usage_t usage_type, int iSamplerChannel )
1198     {
1199     lscp_buffer_fill_t *pBufferFill;
1200     char szQuery[LSCP_BUFSIZ];
1201     int iStreamCount;
1202     const char *pszUsageType = (usage_type == LSCP_USAGE_BYTES ? "BYTES" : "PERCENTAGE");
1203     const char *pszResult;
1204     const char *pszSeps = "[]%,";
1205     char *pszToken;
1206     char *pch;
1207     int iStream;
1208    
1209 capela 132 // Retrieve a channel stream estimation.
1210 capela 107 iStreamCount = lscp_get_channel_stream_count(pClient, iSamplerChannel);
1211 capela 132 if (pClient->iStreamCount < 0)
1212     return NULL;
1213    
1214     // Lock this section up.
1215     lscp_mutex_lock(pClient->mutex);
1216    
1217     // Check if we need to reallocate the stream usage array.
1218 capela 107 if (pClient->iStreamCount != iStreamCount) {
1219     if (pClient->buffer_fill)
1220     free(pClient->buffer_fill);
1221     if (iStreamCount > 0)
1222     pClient->buffer_fill = (lscp_buffer_fill_t *) malloc(iStreamCount * sizeof(lscp_buffer_fill_t));
1223     else
1224     pClient->buffer_fill = NULL;
1225     pClient->iStreamCount = iStreamCount;
1226     }
1227    
1228 capela 132 // Get buffer fill usage...
1229 capela 107 pBufferFill = pClient->buffer_fill;
1230 capela 132 if (pBufferFill && iStreamCount > 0) {
1231     iStream = 0;
1232     pBufferFill = pClient->buffer_fill;
1233     sprintf(szQuery, "GET CHANNEL BUFFER_FILL %s %d\r\n", pszUsageType, iSamplerChannel);
1234     if (lscp_client_call(pClient, szQuery) == LSCP_OK) {
1235     pszResult = lscp_client_get_result(pClient);
1236     pszToken = lscp_strtok((char *) pszResult, pszSeps, &(pch));
1237     while (pszToken && iStream < pClient->iStreamCount) {
1238     if (*pszToken) {
1239     pBufferFill[iStream].stream_id = atol(pszToken);
1240     pszToken = lscp_strtok(NULL, pszSeps, &(pch));
1241     if (pszToken == NULL)
1242     break;
1243     pBufferFill[iStream].stream_usage = atol(pszToken);
1244     iStream++;
1245     }
1246 capela 107 pszToken = lscp_strtok(NULL, pszSeps, &(pch));
1247     }
1248 capela 132 } // Reset the usage, whatever it was before.
1249     else while (iStream < pClient->iStreamCount)
1250     pBufferFill[iStream++].stream_usage = 0;
1251     }
1252 capela 562
1253 capela 132 // Unlock this section down.
1254     lscp_mutex_unlock(pClient->mutex);
1255 capela 107
1256     return pBufferFill;
1257     }
1258    
1259    
1260     /**
1261     * Setting audio output type:
1262     * SET CHANNEL AUDIO_OUTPUT_TYPE <sampler-channel> <audio-output-type>
1263     *
1264     * @param pClient Pointer to client instance structure.
1265     * @param iSamplerChannel Sampler channel number.
1266     * @param pszAudioDriver Audio output driver type (e.g. "ALSA" or "JACK").
1267     */
1268     lscp_status_t lscp_set_channel_audio_type ( lscp_client_t *pClient, int iSamplerChannel, const char *pszAudioDriver )
1269     {
1270     char szQuery[LSCP_BUFSIZ];
1271    
1272     if (iSamplerChannel < 0 || pszAudioDriver == NULL)
1273     return LSCP_FAILED;
1274    
1275     sprintf(szQuery, "SET CHANNEL AUDIO_OUTPUT_TYPE %d %s\r\n", iSamplerChannel, pszAudioDriver);
1276     return lscp_client_query(pClient, szQuery);
1277     }
1278    
1279    
1280     /**
1281 capela 144 * Setting audio output device:
1282     * SET CHANNEL AUDIO_OUTPUT_DEVICE <sampler-channel> <device-id>
1283     *
1284     * @param pClient Pointer to client instance structure.
1285     * @param iSamplerChannel Sampler channel number.
1286     * @param iAudioDevice Audio output device number identifier.
1287     */
1288     lscp_status_t lscp_set_channel_audio_device ( lscp_client_t *pClient, int iSamplerChannel, int iAudioDevice )
1289     {
1290     char szQuery[LSCP_BUFSIZ];
1291    
1292     if (iSamplerChannel < 0 || iAudioDevice < 0)
1293     return LSCP_FAILED;
1294    
1295     sprintf(szQuery, "SET CHANNEL AUDIO_OUTPUT_DEVICE %d %d\r\n", iSamplerChannel, iAudioDevice);
1296     return lscp_client_query(pClient, szQuery);
1297     }
1298    
1299    
1300     /**
1301 capela 107 * Setting audio output channel:
1302     * SET CHANNEL AUDIO_OUTPUT_CHANNEL <sampler-channel> <audio-output-chan> <audio-input-chan>
1303     *
1304     * @param pClient Pointer to client instance structure.
1305     * @param iSamplerChannel Sampler channel number.
1306     * @param iAudioOut Audio output device channel to be routed from.
1307     * @param iAudioIn Audio output device channel to be routed into.
1308     *
1309     * @returns LSCP_OK on success, LSCP_FAILED otherwise.
1310     */
1311     lscp_status_t lscp_set_channel_audio_channel ( lscp_client_t *pClient, int iSamplerChannel, int iAudioOut, int iAudioIn )
1312     {
1313     char szQuery[LSCP_BUFSIZ];
1314    
1315     if (iSamplerChannel < 0 || iAudioOut < 0 || iAudioIn < 0)
1316     return LSCP_FAILED;
1317    
1318 capela 188 sprintf(szQuery, "SET CHANNEL AUDIO_OUTPUT_CHANNEL %d %d %d\r\n", iSamplerChannel, iAudioOut, iAudioIn);
1319 capela 107 return lscp_client_query(pClient, szQuery);
1320     }
1321    
1322    
1323     /**
1324     * Setting MIDI input type:
1325     * SET CHANNEL MIDI_INPUT_TYPE <sampler-channel> <midi-input-type>
1326     *
1327     * @param pClient Pointer to client instance structure.
1328     * @param iSamplerChannel Sampler channel number.
1329     * @param pszMidiDriver MIDI input driver type (e.g. "ALSA").
1330     *
1331     * @returns LSCP_OK on success, LSCP_FAILED otherwise.
1332     */
1333     lscp_status_t lscp_set_channel_midi_type ( lscp_client_t *pClient, int iSamplerChannel, const char *pszMidiDriver )
1334     {
1335     char szQuery[LSCP_BUFSIZ];
1336    
1337     if (iSamplerChannel < 0 || pszMidiDriver == NULL)
1338     return LSCP_FAILED;
1339    
1340     sprintf(szQuery, "SET CHANNEL MIDI_INPUT_TYPE %d %s\r\n", iSamplerChannel, pszMidiDriver);
1341     return lscp_client_query(pClient, szQuery);
1342     }
1343    
1344    
1345     /**
1346 capela 144 * Setting MIDI input device:
1347     * SET CHANNEL MIDI_INPUT_DEVICE <sampler-channel> <device-id>
1348     *
1349     * @param pClient Pointer to client instance structure.
1350     * @param iSamplerChannel Sampler channel number.
1351     * @param iMidiDevice MIDI input device number identifier.
1352     */
1353     lscp_status_t lscp_set_channel_midi_device ( lscp_client_t *pClient, int iSamplerChannel, int iMidiDevice )
1354     {
1355     char szQuery[LSCP_BUFSIZ];
1356    
1357     if (iSamplerChannel < 0 || iMidiDevice < 0)
1358     return LSCP_FAILED;
1359    
1360     sprintf(szQuery, "SET CHANNEL MIDI_INPUT_DEVICE %d %d\r\n", iSamplerChannel, iMidiDevice);
1361     return lscp_client_query(pClient, szQuery);
1362     }
1363    
1364    
1365     /**
1366 capela 107 * Setting MIDI input port:
1367     * SET CHANNEL MIDI_INPUT_PORT <sampler-channel> <midi-input-port>
1368     *
1369     * @param pClient Pointer to client instance structure.
1370     * @param iSamplerChannel Sampler channel number.
1371     * @param iMidiPort MIDI input driver virtual port number.
1372     *
1373     * @returns LSCP_OK on success, LSCP_FAILED otherwise.
1374     */
1375     lscp_status_t lscp_set_channel_midi_port ( lscp_client_t *pClient, int iSamplerChannel, int iMidiPort )
1376     {
1377     char szQuery[LSCP_BUFSIZ];
1378    
1379     if (iSamplerChannel < 0 || iMidiPort < 0)
1380     return LSCP_FAILED;
1381    
1382     sprintf(szQuery, "SET CHANNEL MIDI_INPUT_PORT %d %d\r\n", iSamplerChannel, iMidiPort);
1383     return lscp_client_query(pClient, szQuery);
1384     }
1385    
1386    
1387     /**
1388     * Setting MIDI input channel:
1389     * SET CHANNEL MIDI_INPUT_CHANNEL <sampler-channel> <midi-input-chan>
1390     *
1391     * @param pClient Pointer to client instance structure.
1392     * @param iSamplerChannel Sampler channel number.
1393 capela 278 * @param iMidiChannel MIDI channel address number to listen (0-15) or
1394     * LSCP_MIDI_CHANNEL_ALL (16) to listen on all channels.
1395 capela 107 *
1396     * @returns LSCP_OK on success, LSCP_FAILED otherwise.
1397     */
1398     lscp_status_t lscp_set_channel_midi_channel ( lscp_client_t *pClient, int iSamplerChannel, int iMidiChannel )
1399     {
1400     char szQuery[LSCP_BUFSIZ];
1401    
1402 capela 254 if (iSamplerChannel < 0 || iMidiChannel < 0 || iMidiChannel > 16)
1403 capela 107 return LSCP_FAILED;
1404    
1405 capela 278 if (iMidiChannel == LSCP_MIDI_CHANNEL_ALL)
1406     sprintf(szQuery, "SET CHANNEL MIDI_INPUT_CHANNEL %d ALL\r\n", iSamplerChannel);
1407     else
1408 capela 107 sprintf(szQuery, "SET CHANNEL MIDI_INPUT_CHANNEL %d %d\r\n", iSamplerChannel, iMidiChannel);
1409     return lscp_client_query(pClient, szQuery);
1410     }
1411    
1412    
1413     /**
1414     * Setting channel volume:
1415     * SET CHANNEL VOLUME <sampler-channel> <volume>
1416     *
1417     * @param pClient Pointer to client instance structure.
1418     * @param iSamplerChannel Sampler channel number.
1419     * @param fVolume Sampler channel volume as a positive floating point
1420     * number, where a value less than 1.0 for attenuation,
1421     * and greater than 1.0 for amplification.
1422     *
1423     * @returns LSCP_OK on success, LSCP_FAILED otherwise.
1424     */
1425     lscp_status_t lscp_set_channel_volume ( lscp_client_t *pClient, int iSamplerChannel, float fVolume )
1426     {
1427     char szQuery[LSCP_BUFSIZ];
1428    
1429     if (iSamplerChannel < 0 || fVolume < 0.0)
1430     return LSCP_FAILED;
1431    
1432     sprintf(szQuery, "SET CHANNEL VOLUME %d %g\r\n", iSamplerChannel, fVolume);
1433     return lscp_client_query(pClient, szQuery);
1434     }
1435    
1436    
1437     /**
1438     * Resetting a sampler channel:
1439     * RESET CHANNEL <sampler-channel>
1440     *
1441     * @param pClient Pointer to client instance structure.
1442     * @param iSamplerChannel Sampler channel number.
1443     *
1444     * @returns LSCP_OK on success, LSCP_FAILED otherwise.
1445     */
1446     lscp_status_t lscp_reset_channel ( lscp_client_t *pClient, int iSamplerChannel )
1447     {
1448     char szQuery[LSCP_BUFSIZ];
1449    
1450     if (iSamplerChannel < 0)
1451     return LSCP_FAILED;
1452    
1453     sprintf(szQuery, "RESET CHANNEL %d\r\n", iSamplerChannel);
1454     return lscp_client_query(pClient, szQuery);
1455     }
1456    
1457    
1458 capela 213 /**
1459     * Resetting the sampler:
1460     * RESET
1461     *
1462     * @param pClient Pointer to client instance structure.
1463     *
1464     * @returns LSCP_OK on success, LSCP_FAILED otherwise.
1465     */
1466     lscp_status_t lscp_reset_sampler ( lscp_client_t *pClient )
1467     {
1468     return lscp_client_query(pClient, "RESET\r\n");
1469     }
1470    
1471    
1472 capela 564 /**
1473     * Getting information about the server.
1474     * GET SERVER INFO
1475     *
1476     * @param pClient Pointer to client instance structure.
1477     *
1478     * @returns A pointer to a @ref lscp_server_info_t structure, with all the
1479     * information of the current connected server, or NULL in case of failure.
1480     */
1481     lscp_server_info_t *lscp_get_server_info ( lscp_client_t *pClient )
1482     {
1483     lscp_server_info_t *pServerInfo;
1484     const char *pszResult;
1485     const char *pszSeps = ":";
1486     const char *pszCrlf = "\r\n";
1487     char *pszToken;
1488     char *pch;
1489    
1490     // Lock this section up.
1491     lscp_mutex_lock(pClient->mutex);
1492    
1493     pServerInfo = &(pClient->server_info);
1494     lscp_engine_info_reset(pServerInfo);
1495    
1496     if (lscp_client_call(pClient, "GET SERVER INFO\r\n") == LSCP_OK) {
1497     pszResult = lscp_client_get_result(pClient);
1498     pszToken = lscp_strtok((char *) pszResult, pszSeps, &(pch));
1499     while (pszToken) {
1500     if (strcasecmp(pszToken, "DESCRIPTION") == 0) {
1501     pszToken = lscp_strtok(NULL, pszCrlf, &(pch));
1502     if (pszToken)
1503     lscp_unquote_dup(&(pServerInfo->description), &pszToken);
1504     }
1505     else if (strcasecmp(pszToken, "VERSION") == 0) {
1506     pszToken = lscp_strtok(NULL, pszCrlf, &(pch));
1507     if (pszToken)
1508     lscp_unquote_dup(&(pServerInfo->version), &pszToken);
1509     }
1510     pszToken = lscp_strtok(NULL, pszSeps, &(pch));
1511     }
1512     }
1513     else pServerInfo = NULL;
1514    
1515     // Unlock this section down.
1516     lscp_mutex_unlock(pClient->mutex);
1517    
1518     return pServerInfo;
1519     }
1520    
1521    
1522 capela 107 // end of client.c

  ViewVC Help
Powered by ViewVC