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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 132 - (hide annotations) (download)
Fri Jun 18 14:19:19 2004 UTC (19 years, 9 months ago) by capela
File MIME type: text/plain
File size: 38352 byte(s)
* Overall mutexing of client command calls;
  preparation of forthcoming v.09 LSCP document draft.

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

  ViewVC Help
Powered by ViewVC