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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 565 - (show annotations) (download)
Sun May 22 22:22:26 2005 UTC (16 years, 1 month ago) by capela
File MIME type: text/plain
File size: 49546 byte(s)
* Fixed support for the newest LSCP command: GET SERVER INFO.

1 // client.c
2 //
3 /****************************************************************************
4 liblscp - LinuxSampler Control Protocol API
5 Copyright (C) 2004-2005, 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 14have 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 static void _lscp_client_evt_proc (void *pvClient);
32
33 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
36
37 //-------------------------------------------------------------------------
38 // Event service (datagram oriented).
39
40 static void _lscp_client_evt_proc ( void *pvClient )
41 {
42 lscp_client_t *pClient = (lscp_client_t *) pvClient;
43
44 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
50 char achBuffer[LSCP_BUFSIZ];
51 int cchBuffer;
52 const char *pszSeps = ":\r\n";
53 char * pszToken;
54 char * pch;
55 int cchToken;
56 lscp_event_t event;
57
58 #ifdef DEBUG
59 fprintf(stderr, "_lscp_client_evt_proc: Client waiting for events.\n");
60 #endif
61
62 while (pClient->evt.iState) {
63
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 // Wait for event...
80 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 }
107 }
108 } else {
109 lscp_socket_perror("_lscp_client_evt_proc: recv");
110 pClient->evt.iState = 0;
111 }
112 } // Check if select has in error.
113 else if (iSelect < 0) {
114 lscp_socket_perror("_lscp_client_evt_proc: select");
115 pClient->evt.iState = 0;
116 }
117
118 // Finally, always signal the event.
119 lscp_cond_signal(pClient->cond);
120 }
121
122 #ifdef DEBUG
123 fprintf(stderr, "_lscp_client_evt_proc: Client closing.\n");
124 #endif
125 }
126
127
128 //-------------------------------------------------------------------------
129 // 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
168 // Set our socket agent struct...
169 lscp_socket_agent_init(&(pClient->evt), sock, &addr, cAddr);
170
171 // 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 const char *pszEvent;
180 char szQuery[LSCP_BUFSIZ];
181 int cchQuery;
182
183 if (pClient == NULL)
184 return LSCP_FAILED;
185
186 // Which (single) event?
187 pszEvent = lscp_event_to_text(event);
188 if (pszEvent == NULL)
189 return LSCP_FAILED;
190
191 // 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 // Wait on response.
200 lscp_cond_wait(pClient->cond, pClient->mutex);
201
202 // 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 // 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 #if defined(WIN32)
251 int iSockOpt = (-1);
252 #endif
253
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 lscp_socket_herror("lscp_client_create: gethostbyname");
262 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 // Prepare the command connection socket...
282
283 sock = socket(AF_INET, SOCK_STREAM, 0);
284 if (sock == INVALID_SOCKET) {
285 lscp_socket_perror("lscp_client_create: cmd: socket");
286 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 lscp_socket_perror("lscp_client_create: cmd: setsockopt(SO_DONTLINGER)");
293 #endif
294
295 #ifdef DEBUG
296 lscp_socket_getopts("lscp_client_create: cmd", sock);
297 #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 lscp_socket_perror("lscp_client_create: cmd: connect");
307 closesocket(sock);
308 free(pClient);
309 return NULL;
310 }
311
312 // Initialize the command socket agent struct...
313 lscp_socket_agent_init(&(pClient->cmd), sock, &addr, cAddr);
314
315 #ifdef DEBUG
316 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 #endif
318
319 // 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 // Initialize cached members.
324 pClient->audio_drivers = NULL;
325 pClient->midi_drivers = NULL;
326 pClient->audio_devices = NULL;
327 pClient->midi_devices = NULL;
328 pClient->engines = NULL;
329 pClient->channels = NULL;
330 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 lscp_param_info_init(&(pClient->audio_param_info));
335 lscp_param_info_init(&(pClient->midi_param_info));
336 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 lscp_server_info_init(&(pClient->server_info));
341 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 lscp_cond_init(pClient->cond);
355
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 // lscp_socket_agent_join(&(pClient->evt));
376 lscp_socket_agent_join(&(pClient->cmd));
377
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 // Lock this section up.
399 lscp_mutex_lock(pClient->mutex);
400
401 // Free up all cached members.
402 lscp_channel_info_free(&(pClient->channel_info));
403 lscp_engine_info_free(&(pClient->engine_info));
404 lscp_server_info_free(&(pClient->server_info));
405 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 // Free available engine table.
416 lscp_szsplit_destroy(pClient->audio_drivers);
417 lscp_szsplit_destroy(pClient->midi_drivers);
418 lscp_isplit_destroy(pClient->audio_devices);
419 lscp_isplit_destroy(pClient->midi_devices);
420 lscp_szsplit_destroy(pClient->engines);
421 lscp_isplit_destroy(pClient->channels);
422 // Make them null.
423 pClient->audio_drivers = NULL;
424 pClient->midi_drivers = NULL;
425 pClient->engines = NULL;
426 // Free result error stuff.
427 lscp_client_set_result(pClient, NULL, 0);
428 // Free stream usage stuff.
429 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 lscp_socket_agent_free(&(pClient->evt));
437 lscp_socket_agent_free(&(pClient->cmd));
438
439 // Last but not least, free good ol'transaction mutex.
440 lscp_mutex_unlock(pClient->mutex);
441 lscp_mutex_destroy(pClient->mutex);
442 lscp_cond_destroy(pClient->cond);
443
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 lscp_status_t ret;
505
506 // Lock this section up.
507 lscp_mutex_lock(pClient->mutex);
508
509 // Just make the now guarded call.
510 ret = lscp_client_call(pClient, pszQuery);
511
512 // Unlock this section down.
513 lscp_mutex_unlock(pClient->mutex);
514
515 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 * Register frontend for receiving event messages:
558 * SUBSCRIBE CHANNEL_COUNT | VOICE_COUNT | STREAM_COUNT | BUFFER_FILL
559 * | CHANNEL_INFO | MISCELLANEOUS
560 *
561 * @param pClient Pointer to client instance structure.
562 * @param events Bit-wise OR'ed event flags to subscribe.
563 *
564 * @returns LSCP_OK on success, LSCP_FAILED otherwise.
565 */
566 lscp_status_t lscp_client_subscribe ( lscp_client_t *pClient, lscp_event_t events )
567 {
568 lscp_status_t ret = LSCP_FAILED;
569
570 if (pClient == NULL)
571 return LSCP_FAILED;
572
573 // Lock this section up.
574 lscp_mutex_lock(pClient->mutex);
575
576 // If applicable, start the alternate connection...
577 if (pClient->events == LSCP_EVENT_NONE)
578 ret = _lscp_client_evt_connect(pClient);
579
580 // Send the subscription commands.
581 if (ret == LSCP_OK && (events & LSCP_EVENT_CHANNEL_COUNT))
582 ret = _lscp_client_evt_request(pClient, 1, LSCP_EVENT_CHANNEL_COUNT);
583 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
594 // Unlock this section down.
595 lscp_mutex_unlock(pClient->mutex);
596
597 return ret;
598 }
599
600
601 /**
602 * Deregister frontend from receiving UDP event messages anymore:
603 * SUBSCRIBE CHANNEL_COUNT | VOICE_COUNT | STREAM_COUNT | BUFFER_FILL
604 * | CHANNEL_INFO | MISCELLANEOUS
605 *
606 * @param pClient Pointer to client instance structure.
607 * @param events Bit-wise OR'ed event flags to unsubscribe.
608 *
609 * @returns LSCP_OK on success, LSCP_FAILED otherwise.
610 */
611 lscp_status_t lscp_client_unsubscribe ( lscp_client_t *pClient, lscp_event_t events )
612 {
613 lscp_status_t ret = LSCP_OK;
614
615 if (pClient == NULL)
616 return LSCP_FAILED;
617
618 // Lock this section up.
619 lscp_mutex_lock(pClient->mutex);
620
621 // Send the unsubscription commands.
622 if (ret == LSCP_OK && (events & LSCP_EVENT_CHANNEL_COUNT))
623 ret = _lscp_client_evt_request(pClient, 0, LSCP_EVENT_CHANNEL_COUNT);
624 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
635 // If necessary, close the alternate connection...
636 if (pClient->events == LSCP_EVENT_NONE)
637 lscp_socket_agent_free(&(pClient->evt));
638
639 // Unlock this section down.
640 lscp_mutex_unlock(pClient->mutex);
641
642 return ret;
643 }
644
645
646 /**
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 //-------------------------------------------------------------------------
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 sprintf(szQuery, "LOAD INSTRUMENT '%s' %d %d\r\n", pszFileName, iInstrIndex, iSamplerChannel);
684 return lscp_client_query(pClient, szQuery);
685 }
686
687
688 /**
689 * 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 * 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
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 iChannels = atoi(lscp_client_get_result(pClient));
751
752 // Unlock this section doen.
753 lscp_mutex_unlock(pClient->mutex);
754
755 return iChannels;
756 }
757
758
759 /**
760 * 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
775 // Lock this section up.
776 lscp_mutex_lock(pClient->mutex);
777
778 if (pClient->channels) {
779 lscp_isplit_destroy(pClient->channels);
780 pClient->channels = NULL;
781 }
782
783 if (lscp_client_call(pClient, "LIST CHANNELS\r\n") == LSCP_OK)
784 pClient->channels = lscp_isplit_create(lscp_client_get_result(pClient), pszSeps);
785
786 // Unlock this section down.
787 lscp_mutex_unlock(pClient->mutex);
788
789 return pClient->channels;
790 }
791
792
793 /**
794 * 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
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 iSamplerChannel = atoi(lscp_client_get_result(pClient));
811
812 // Unlock this section down.
813 lscp_mutex_unlock(pClient->mutex);
814
815 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 * Getting all available engines count:
842 * GET AVAILABLE_ENGINES
843 *
844 * @param pClient Pointer to client instance structure.
845 *
846 * @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 int iAvailableEngines = -1;
852
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 * @returns A NULL terminated array of engine name strings,
873 * or NULL in case of failure.
874 */
875 const char **lscp_list_available_engines ( lscp_client_t *pClient )
876 {
877 const char *pszSeps = ",";
878
879 // Lock this section up.
880 lscp_mutex_lock(pClient->mutex);
881
882 if (pClient->engines) {
883 lscp_szsplit_destroy(pClient->engines);
884 pClient->engines = NULL;
885 }
886
887 if (lscp_client_call(pClient, "LIST AVAILABLE_ENGINES\r\n") == LSCP_OK)
888 pClient->engines = lscp_szsplit_create(lscp_client_get_result(pClient), pszSeps);
889
890 // Unlock this section down.
891 lscp_mutex_unlock(pClient->mutex);
892
893 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 // Lock this section up.
921 lscp_mutex_lock(pClient->mutex);
922
923 pEngineInfo = &(pClient->engine_info);
924 lscp_engine_info_reset(pEngineInfo);
925
926 sprintf(szQuery, "GET ENGINE INFO %s\r\n", pszEngineName);
927 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 lscp_unquote_dup(&(pEngineInfo->description), &pszToken);
935 }
936 else if (strcasecmp(pszToken, "VERSION") == 0) {
937 pszToken = lscp_strtok(NULL, pszCrlf, &(pch));
938 if (pszToken)
939 lscp_unquote_dup(&(pEngineInfo->version), &pszToken);
940 }
941 pszToken = lscp_strtok(NULL, pszSeps, &(pch));
942 }
943 }
944 else pEngineInfo = NULL;
945
946 // Unlock this section down.
947 lscp_mutex_unlock(pClient->mutex);
948
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 // Lock this section up.
977 lscp_mutex_lock(pClient->mutex);
978
979 pChannelInfo = &(pClient->channel_info);
980 lscp_channel_info_reset(pChannelInfo);
981
982 sprintf(szQuery, "GET CHANNEL INFO %d\r\n", iSamplerChannel);
983 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 lscp_unquote_dup(&(pChannelInfo->engine_name), &pszToken);
991 }
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 if (pszToken) {
1005 if (pChannelInfo->audio_routing)
1006 lscp_szsplit_destroy(pChannelInfo->audio_routing);
1007 pChannelInfo->audio_routing = lscp_szsplit_create(pszToken, ",");
1008 }
1009 }
1010 else if (strcasecmp(pszToken, "INSTRUMENT_FILE") == 0) {
1011 pszToken = lscp_strtok(NULL, pszCrlf, &(pch));
1012 if (pszToken)
1013 lscp_unquote_dup(&(pChannelInfo->instrument_file), &pszToken);
1014 }
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 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 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 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 }
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 }
1057 }
1058 else pChannelInfo = NULL;
1059
1060 // Unlock this section up.
1061 lscp_mutex_unlock(pClient->mutex);
1062
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 // Lock this section up.
1085 lscp_mutex_lock(pClient->mutex);
1086
1087 sprintf(szQuery, "GET CHANNEL VOICE_COUNT %d\r\n", iSamplerChannel);
1088 if (lscp_client_call(pClient, szQuery) == LSCP_OK)
1089 iVoiceCount = atoi(lscp_client_get_result(pClient));
1090
1091 // Unlock this section down.
1092 lscp_mutex_unlock(pClient->mutex);
1093
1094 return iVoiceCount;
1095 }
1096
1097
1098 /**
1099 * Current number of active disk streams:
1100 * GET CHANNEL STREAM_COUNT <sampler-channel>
1101 *
1102 * @param pClient Pointer to client instance structure.
1103 * @param iSamplerChannel Sampler channel number.
1104 *
1105 * @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 // Lock this section up.
1116 lscp_mutex_lock(pClient->mutex);
1117
1118 sprintf(szQuery, "GET CHANNEL STREAM_COUNT %d\r\n", iSamplerChannel);
1119 if (lscp_client_call(pClient, szQuery) == LSCP_OK)
1120 iStreamCount = atoi(lscp_client_get_result(pClient));
1121
1122 // Unlock this section down.
1123 lscp_mutex_unlock(pClient->mutex);
1124
1125 return iStreamCount;
1126 }
1127
1128
1129 /**
1130 * 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 * 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 // Retrieve a channel stream estimation.
1210 iStreamCount = lscp_get_channel_stream_count(pClient, iSamplerChannel);
1211 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 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 // Get buffer fill usage...
1229 pBufferFill = pClient->buffer_fill;
1230 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 pszToken = lscp_strtok(NULL, pszSeps, &(pch));
1247 }
1248 } // Reset the usage, whatever it was before.
1249 else while (iStream < pClient->iStreamCount)
1250 pBufferFill[iStream++].stream_usage = 0;
1251 }
1252
1253 // Unlock this section down.
1254 lscp_mutex_unlock(pClient->mutex);
1255
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 * 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 * 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 sprintf(szQuery, "SET CHANNEL AUDIO_OUTPUT_CHANNEL %d %d %d\r\n", iSamplerChannel, iAudioOut, iAudioIn);
1319 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 * 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 * 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 * @param iMidiChannel MIDI channel address number to listen (0-15) or
1394 * LSCP_MIDI_CHANNEL_ALL (16) to listen on all channels.
1395 *
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 if (iSamplerChannel < 0 || iMidiChannel < 0 || iMidiChannel > 16)
1403 return LSCP_FAILED;
1404
1405 if (iMidiChannel == LSCP_MIDI_CHANNEL_ALL)
1406 sprintf(szQuery, "SET CHANNEL MIDI_INPUT_CHANNEL %d ALL\r\n", iSamplerChannel);
1407 else
1408 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 /**
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 /**
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_server_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 // end of client.c

  ViewVC Help
Powered by ViewVC