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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 3666 - (show annotations) (download)
Sun Dec 22 13:10:04 2019 UTC (4 years, 3 months ago) by schoenebeck
File MIME type: text/plain
File size: 90729 byte(s)
* Fixed potential missing NULL termination of locale strings.

1 // client.c
2 //
3 /****************************************************************************
4 liblscp - LinuxSampler Control Protocol API
5 Copyright (C) 2004-2019, 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 General Public License along
18 with this program; if not, write to the Free Software Foundation, Inc.,
19 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
20
21 *****************************************************************************/
22
23 #include <locale.h>
24 #include "common.h"
25 #include <sys/time.h>
26 #ifdef WIN32
27 # include <errno.h>
28 #else
29 # include <sys/errno.h>
30 #endif
31
32
33 // Default timeout value (in milliseconds).
34 #define LSCP_TIMEOUT_MSECS 500
35
36
37 // Whether to use getaddrinfo() instead
38 // of deprecated gethostbyname()
39 #if !defined(WIN32)
40 #define USE_GETADDRINFO 1
41 #endif
42
43
44 // Local prototypes.
45
46 static void _lscp_client_evt_proc (void *pvClient);
47
48 static lscp_status_t _lscp_client_evt_connect (lscp_client_t *pClient);
49 static lscp_status_t _lscp_client_evt_request (lscp_client_t *pClient,
50 int iSubscribe, lscp_event_t event);
51
52
53 //-------------------------------------------------------------------------
54 // General helper functions.
55
56 struct _locale_t {
57 char numeric[32+1];
58 char ctype[32+1];
59 };
60
61 // we need to ensure a constant locale setting e.g. for parsing
62 // floating point numbers with atof(), as the floating point separator
63 // character varies by the invidual locale settings
64 static void _save_and_set_c_locale(struct _locale_t* locale)
65 {
66 locale->numeric[32] = locale->ctype[32] = 0;
67 strncpy(locale->numeric, setlocale(LC_NUMERIC, NULL), 32);
68 strncpy(locale->ctype, setlocale(LC_CTYPE, NULL), 32);
69 setlocale(LC_NUMERIC, "C");
70 setlocale(LC_CTYPE, "C");
71 }
72
73 // restore the original locale setting as nothing happened
74 static void _restore_locale(struct _locale_t* locale)
75 {
76 setlocale(LC_NUMERIC, locale->numeric);
77 setlocale(LC_CTYPE, locale->ctype);
78 }
79
80 // seems the standard atof() function doesnt care much about locale
81 // runtime modifications, so we use this workaround
82 static float _atof(const char* txt) {
83 float f;
84 sscanf(txt, "%f", &f); // yeah, you're a good boy sscanf()
85 return f;
86 }
87
88
89 //-------------------------------------------------------------------------
90 // Event service (datagram oriented).
91
92 static void _lscp_client_evt_proc ( void *pvClient )
93 {
94 lscp_client_t *pClient = (lscp_client_t *) pvClient;
95
96 fd_set fds; // File descriptor list for select().
97 int fd, fdmax; // Maximum file descriptor number.
98 struct timeval tv; // For specifying a timeout value.
99 int iSelect; // Holds select return status.
100 int iTimeout;
101
102 char achBuffer[LSCP_BUFSIZ];
103 int cchBuffer;
104 const char *pszSeps = ":\r\n";
105 char *pszToken;
106 char *pch;
107 int cchToken;
108
109 lscp_event_t event;
110
111 #ifdef DEBUG
112 fprintf(stderr, "_lscp_client_evt_proc: Client waiting for events.\n");
113 #endif
114
115 while (pClient->evt.iState) {
116
117 // Prepare for waiting on select...
118 fd = (int) pClient->evt.sock;
119 FD_ZERO(&fds);
120 FD_SET((unsigned int) fd, &fds);
121 fdmax = fd;
122
123 // Use the timeout (x10) select feature ...
124 iTimeout = 10 * pClient->iTimeout;
125 if (iTimeout >= 1000) {
126 tv.tv_sec = iTimeout / 1000;
127 iTimeout -= tv.tv_sec * 1000;
128 }
129 else tv.tv_sec = 0;
130 tv.tv_usec = iTimeout * 1000;
131
132 // Wait for event...
133 iSelect = select(fdmax + 1, &fds, NULL, NULL, &tv);
134 if (iSelect > 0 && FD_ISSET(fd, &fds)) {
135 // May recv now...
136 cchBuffer = recv(pClient->evt.sock, achBuffer, sizeof(achBuffer), 0);
137 if (cchBuffer > 0) {
138 // Make sure received buffer it's null terminated.
139 achBuffer[cchBuffer] = (char) 0;
140 pch = achBuffer;
141 do {
142 // Parse for the notification event message...
143 pszToken = lscp_strtok(NULL, pszSeps, &(pch)); // Have "NOTIFY"
144 if (strcasecmp(pszToken, "NOTIFY") == 0) {
145 pszToken = lscp_strtok(NULL, pszSeps, &(pch));
146 event = lscp_event_from_text(pszToken);
147 // And pick the rest of data...
148 pszToken = lscp_strtok(NULL, pszSeps, &(pch));
149 cchToken = (pszToken == NULL ? 0 : strlen(pszToken));
150 // Double-check if we're really up to it...
151 if (pClient->events & event) {
152 // Invoke the client event callback...
153 if ((*pClient->pfnCallback)(
154 pClient,
155 event,
156 pszToken,
157 cchToken,
158 pClient->pvData) != LSCP_OK) {
159 pClient->evt.iState = 0;
160 }
161 }
162 }
163 } while (*pch);
164 } else {
165 lscp_socket_perror("_lscp_client_evt_proc: recv");
166 pClient->evt.iState = 0;
167 pClient->iErrno = -errno;
168 }
169 } // Check if select has in error.
170 else if (iSelect < 0) {
171 lscp_socket_perror("_lscp_client_evt_proc: select");
172 pClient->evt.iState = 0;
173 pClient->iErrno = -errno;
174 }
175
176 // Finally, always signal the event.
177 lscp_cond_signal(pClient->cond);
178 }
179
180 #ifdef DEBUG
181 fprintf(stderr, "_lscp_client_evt_proc: Client closing.\n");
182 #endif
183 }
184
185
186 //-------------------------------------------------------------------------
187 // Event subscription helpers.
188
189 // Open the event service socket connection.
190 static lscp_status_t _lscp_client_evt_connect ( lscp_client_t *pClient )
191 {
192 lscp_socket_t sock;
193 struct sockaddr_in addr;
194 int cAddr;
195 #if defined(WIN32)
196 int iSockOpt = (-1);
197 #endif
198
199 // Prepare the event connection socket...
200 sock = socket(AF_INET, SOCK_STREAM, 0);
201 if (sock == INVALID_SOCKET) {
202 lscp_socket_perror("_lscp_client_evt_connect: socket");
203 return LSCP_FAILED;
204 }
205
206 #if defined(WIN32)
207 if (setsockopt(sock, SOL_SOCKET, SO_DONTLINGER,
208 (char *) &iSockOpt, sizeof(int)) == SOCKET_ERROR)
209 lscp_socket_perror("lscp_client_evt_connect: setsockopt(SO_DONTLINGER)");
210 #endif
211
212 #ifdef DEBUG
213 lscp_socket_getopts("_lscp_client_evt_connect:", sock);
214 #endif
215
216 // Use same address of the command connection.
217 cAddr = sizeof(struct sockaddr_in);
218 memmove((char *) &addr, &(pClient->cmd.addr), cAddr);
219
220 // Start the connection...
221 if (connect(sock, (struct sockaddr *) &addr, cAddr) == SOCKET_ERROR) {
222 lscp_socket_perror("_lscp_client_evt_connect: connect");
223 closesocket(sock);
224 return LSCP_FAILED;
225 }
226
227 // Set our socket agent struct...
228 lscp_socket_agent_init(&(pClient->evt), sock, &addr, cAddr);
229
230 // And finally the service thread...
231 return lscp_socket_agent_start(&(pClient->evt), _lscp_client_evt_proc, pClient, 0);
232 }
233
234
235 // Subscribe to a single event.
236 static lscp_status_t _lscp_client_evt_request ( lscp_client_t *pClient,
237 int iSubscribe, lscp_event_t event )
238 {
239 const char *pszEvent;
240 char szQuery[LSCP_BUFSIZ];
241 int cchQuery;
242
243 if (pClient == NULL)
244 return LSCP_FAILED;
245
246 // Which (single) event?
247 pszEvent = lscp_event_to_text(event);
248 if (pszEvent == NULL)
249 return LSCP_FAILED;
250
251 // Build the query string...
252 cchQuery = sprintf(szQuery, "%sSUBSCRIBE %s\n\n",
253 (iSubscribe == 0 ? "UN" : ""), pszEvent);
254 // Just send data, forget result...
255 if (send(pClient->evt.sock, szQuery, cchQuery, 0) < cchQuery) {
256 lscp_socket_perror("_lscp_client_evt_request: send");
257 return LSCP_FAILED;
258 }
259
260 // Wait on response.
261 lscp_cond_wait(pClient->cond, pClient->mutex);
262
263 // Update as naively as we can...
264 if (iSubscribe)
265 pClient->events |= event;
266 else
267 pClient->events &= ~event;
268
269 return LSCP_OK;
270 }
271
272
273 //-------------------------------------------------------------------------
274 // Client versioning teller fuunction.
275
276
277 /** Retrieve the current client library version string. */
278 const char* lscp_client_package (void) { return LSCP_PACKAGE; }
279
280 /** Retrieve the current client library version string. */
281 const char* lscp_client_version (void) { return LSCP_VERSION; }
282
283 /** Retrieve the current client library build string. */
284 const char* lscp_client_build (void) { return LSCP_BUILD; }
285
286
287 //-------------------------------------------------------------------------
288 // Client socket functions.
289
290 /**
291 * Create a client instance, estabilishing a connection to a server hostname,
292 * which must be listening on the given port. A client callback function is
293 * also supplied for server notification event handling.
294 *
295 * @param pszHost Hostname of the linuxsampler listening server.
296 * @param iPort Port number of the linuxsampler listening server.
297 * @param pfnCallback Callback function to receive event notifications.
298 * @param pvData User context opaque data, that will be passed
299 * to the callback function.
300 *
301 * @returns The new client instance pointer if successfull, which shall be
302 * used on all subsequent client calls, NULL otherwise.
303 */
304 lscp_client_t* lscp_client_create ( const char *pszHost, int iPort,
305 lscp_client_proc_t pfnCallback, void *pvData )
306 {
307 lscp_client_t *pClient;
308 #if defined(USE_GETADDRINFO)
309 char szPort[33];
310 struct addrinfo hints;
311 struct addrinfo *result, *res;
312 #else
313 struct hostent *pHost;
314 struct sockaddr_in addr;
315 int cAddr;
316 #endif /* !USE_GETADDRINFO */
317 lscp_socket_t sock;
318 #if defined(WIN32)
319 int iSockOpt = (-1);
320 #endif
321
322 if (pfnCallback == NULL) {
323 fprintf(stderr, "lscp_client_create: Invalid client callback function.\n");
324 return NULL;
325 }
326
327 #if defined(USE_GETADDRINFO)
328
329 // Convert port number to string/name...
330 snprintf(szPort, sizeof(szPort), "%d", iPort);
331
332 // Obtain address(es) matching host/port...
333 memset(&hints, 0, sizeof(struct addrinfo));
334 hints.ai_family = AF_INET;
335 hints.ai_socktype = SOCK_STREAM;
336
337 result = NULL;
338
339 if (getaddrinfo(pszHost, szPort, &hints, &result)) {
340 lscp_socket_herror("lscp_client_create: getaddrinfo");
341 return NULL;
342 }
343
344 #else
345
346 // Obtain host matching name...
347 pHost = gethostbyname(pszHost);
348 if (pHost == NULL) {
349 lscp_socket_herror("lscp_client_create: gethostbyname");
350 return NULL;
351 }
352
353 #endif /* !USE_GETADDRINFO */
354
355 // Allocate client descriptor...
356
357 pClient = (lscp_client_t *) malloc(sizeof(lscp_client_t));
358 if (pClient == NULL) {
359 fprintf(stderr, "lscp_client_create: Out of memory.\n");
360 return NULL;
361 }
362 memset(pClient, 0, sizeof(lscp_client_t));
363
364 pClient->pfnCallback = pfnCallback;
365 pClient->pvData = pvData;
366
367 #ifdef DEBUG
368 fprintf(stderr,
369 "lscp_client_create: pClient=%p: pszHost=%s iPort=%d.\n",
370 pClient, pszHost, iPort);
371 #endif
372
373 // Prepare the command connection socket...
374
375 #if defined(USE_GETADDRINFO)
376
377 // getaddrinfo() returns a list of address structures;
378 // try each address until we successfully connect(2);
379 // if socket or connect fails, we close the socket and
380 // try the next address...
381 sock = INVALID_SOCKET;
382
383 for (res = result; res; res = res->ai_next) {
384 sock = socket(res->ai_family, res->ai_socktype, res->ai_protocol);
385 if (sock == INVALID_SOCKET)
386 continue;
387 #if defined(WIN32)
388 if (setsockopt(sock, SOL_SOCKET, SO_DONTLINGER,
389 (char *) &iSockOpt, sizeof(int)) == SOCKET_ERROR)
390 lscp_socket_perror("lscp_client_create: cmd: setsockopt(SO_DONTLINGER)");
391 #endif
392 #ifdef DEBUG
393 lscp_socket_getopts("lscp_client_create: cmd", sock);
394 #endif
395 if (connect(sock, res->ai_addr, res->ai_addrlen) != SOCKET_ERROR)
396 break;
397 closesocket(sock);
398 }
399
400 if (sock == INVALID_SOCKET) {
401 lscp_socket_perror("lscp_client_create: cmd: socket");
402 free(pClient);
403 return NULL;
404 }
405
406 if (res == NULL) {
407 lscp_socket_perror("lscp_client_create: cmd: connect");
408 free(pClient);
409 return NULL;
410 }
411
412 // Initialize the command socket agent struct...
413 lscp_socket_agent_init(&(pClient->cmd), sock,
414 (struct sockaddr_in *) res->ai_addr, res->ai_addrlen);
415
416 // No longer needed...
417 freeaddrinfo(result);
418
419 #else
420
421 sock = socket(AF_INET, SOCK_STREAM, 0);
422 if (sock == INVALID_SOCKET) {
423 lscp_socket_perror("lscp_client_create: cmd: socket");
424 free(pClient);
425 return NULL;
426 }
427
428 #if defined(WIN32)
429 if (setsockopt(sock, SOL_SOCKET, SO_DONTLINGER,
430 (char *) &iSockOpt, sizeof(int)) == SOCKET_ERROR)
431 lscp_socket_perror("lscp_client_create: cmd: setsockopt(SO_DONTLINGER)");
432 #endif
433
434 #ifdef DEBUG
435 lscp_socket_getopts("lscp_client_create: cmd", sock);
436 #endif
437
438 cAddr = sizeof(struct sockaddr_in);
439 memset((char *) &addr, 0, cAddr);
440 addr.sin_family = pHost->h_addrtype;
441 memmove((char *) &(addr.sin_addr), pHost->h_addr, pHost->h_length);
442 addr.sin_port = htons((short) iPort);
443
444 if (connect(sock, (struct sockaddr *) &addr, cAddr) == SOCKET_ERROR) {
445 lscp_socket_perror("lscp_client_create: cmd: connect");
446 closesocket(sock);
447 free(pClient);
448 return NULL;
449 }
450
451 // Initialize the command socket agent struct...
452 lscp_socket_agent_init(&(pClient->cmd), sock, &addr, cAddr);
453
454 #endif /* !USE_GETADDRINFO */
455
456 #ifdef DEBUG
457 fprintf(stderr,
458 "lscp_client_create: cmd: pClient=%p: sock=%d addr=%s port=%d.\n",
459 pClient, pClient->cmd.sock,
460 inet_ntoa(pClient->cmd.addr.sin_addr),
461 ntohs(pClient->cmd.addr.sin_port));
462 #endif
463
464 // Initialize the event service socket struct...
465 lscp_socket_agent_init(&(pClient->evt), INVALID_SOCKET, NULL, 0);
466 // No events subscribed, yet.
467 pClient->events = LSCP_EVENT_NONE;
468 // Initialize cached members.
469 pClient->audio_drivers = NULL;
470 pClient->midi_drivers = NULL;
471 pClient->audio_devices = NULL;
472 pClient->midi_devices = NULL;
473 pClient->engines = NULL;
474 pClient->channels = NULL;
475 pClient->fxsends = NULL;
476 pClient->midi_instruments = NULL;
477 pClient->midi_maps = NULL;
478 pClient->midi_map_name = NULL;
479 lscp_driver_info_init(&(pClient->audio_driver_info));
480 lscp_driver_info_init(&(pClient->midi_driver_info));
481 lscp_device_info_init(&(pClient->audio_device_info));
482 lscp_device_info_init(&(pClient->midi_device_info));
483 lscp_param_info_init(&(pClient->audio_param_info));
484 lscp_param_info_init(&(pClient->midi_param_info));
485 lscp_device_port_info_init(&(pClient->audio_channel_info));
486 lscp_device_port_info_init(&(pClient->midi_port_info));
487 lscp_param_info_init(&(pClient->audio_channel_param_info));
488 lscp_param_info_init(&(pClient->midi_port_param_info));
489 lscp_server_info_init(&(pClient->server_info));
490 lscp_engine_info_init(&(pClient->engine_info));
491 lscp_channel_info_init(&(pClient->channel_info));
492 lscp_fxsend_info_init(&(pClient->fxsend_info));
493 lscp_midi_instrument_info_init(&(pClient->midi_instrument_info));
494 // Initialize error stuff.
495 pClient->pszResult = NULL;
496 pClient->iErrno = -1;
497 // Stream usage stuff.
498 pClient->buffer_fill = NULL;
499 pClient->iStreamCount = 0;
500 // Default timeout value.
501 pClient->iTimeout = LSCP_TIMEOUT_MSECS;
502 pClient->iTimeoutCount = 0;
503
504 // Initialize the transaction mutex.
505 lscp_mutex_init(pClient->mutex);
506 lscp_cond_init(pClient->cond);
507
508 // Finally we've some success...
509 return pClient;
510 }
511
512
513 /**
514 * Wait for a client instance to terminate graciously.
515 *
516 * @param pClient Pointer to client instance structure.
517 */
518 lscp_status_t lscp_client_join ( lscp_client_t *pClient )
519 {
520 if (pClient == NULL)
521 return LSCP_FAILED;
522
523 #ifdef DEBUG
524 fprintf(stderr, "lscp_client_join: pClient=%p.\n", pClient);
525 #endif
526
527 // lscp_socket_agent_join(&(pClient->evt));
528 lscp_socket_agent_join(&(pClient->cmd));
529
530 return LSCP_OK;
531 }
532
533
534 /**
535 * Terminate and destroy a client instance.
536 *
537 * @param pClient Pointer to client instance structure.
538 *
539 * @returns LSCP_OK on success, LSCP_FAILED otherwise.
540 */
541 lscp_status_t lscp_client_destroy ( lscp_client_t *pClient )
542 {
543 if (pClient == NULL)
544 return LSCP_FAILED;
545
546 #ifdef DEBUG
547 fprintf(stderr, "lscp_client_destroy: pClient=%p.\n", pClient);
548 #endif
549
550 // Lock this section up.
551 lscp_mutex_lock(pClient->mutex);
552
553 // Free up all cached members.
554 lscp_midi_instrument_info_free(&(pClient->midi_instrument_info));
555 lscp_fxsend_info_free(&(pClient->fxsend_info));
556 lscp_channel_info_free(&(pClient->channel_info));
557 lscp_engine_info_free(&(pClient->engine_info));
558 lscp_server_info_free(&(pClient->server_info));
559 lscp_param_info_free(&(pClient->midi_port_param_info));
560 lscp_param_info_free(&(pClient->audio_channel_param_info));
561 lscp_device_port_info_free(&(pClient->midi_port_info));
562 lscp_device_port_info_free(&(pClient->audio_channel_info));
563 lscp_param_info_free(&(pClient->midi_param_info));
564 lscp_param_info_free(&(pClient->audio_param_info));
565 lscp_device_info_free(&(pClient->midi_device_info));
566 lscp_device_info_free(&(pClient->audio_device_info));
567 lscp_driver_info_free(&(pClient->midi_driver_info));
568 lscp_driver_info_free(&(pClient->audio_driver_info));
569 // Free available engine table.
570 lscp_szsplit_destroy(pClient->audio_drivers);
571 lscp_szsplit_destroy(pClient->midi_drivers);
572 lscp_isplit_destroy(pClient->audio_devices);
573 lscp_isplit_destroy(pClient->midi_devices);
574 lscp_szsplit_destroy(pClient->engines);
575 lscp_isplit_destroy(pClient->channels);
576 lscp_isplit_destroy(pClient->fxsends);
577 lscp_midi_instruments_destroy(pClient->midi_instruments);
578 lscp_isplit_destroy(pClient->midi_maps);
579 if (pClient->midi_map_name)
580 free(pClient->midi_map_name);
581 // Make them null.
582 pClient->audio_drivers = NULL;
583 pClient->midi_drivers = NULL;
584 pClient->audio_devices = NULL;
585 pClient->midi_devices = NULL;
586 pClient->engines = NULL;
587 pClient->channels = NULL;
588 pClient->fxsends = NULL;
589 pClient->midi_instruments = NULL;
590 pClient->midi_maps = NULL;
591 pClient->midi_map_name = NULL;
592 // Free result error stuff.
593 lscp_client_set_result(pClient, NULL, 0);
594 // Free stream usage stuff.
595 if (pClient->buffer_fill)
596 free(pClient->buffer_fill);
597 pClient->buffer_fill = NULL;
598 pClient->iStreamCount = 0;
599 pClient->iTimeout = 0;
600
601 // Free socket agents.
602 lscp_socket_agent_free(&(pClient->evt));
603 lscp_socket_agent_free(&(pClient->cmd));
604
605 // Last but not least, free good ol'transaction mutex.
606 lscp_mutex_unlock(pClient->mutex);
607 lscp_mutex_destroy(pClient->mutex);
608 lscp_cond_destroy(pClient->cond);
609
610 free(pClient);
611
612 return LSCP_OK;
613 }
614
615
616 /**
617 * Set the client transaction timeout interval.
618 *
619 * @param pClient Pointer to client instance structure.
620 * @param iTimeout Transaction timeout in milliseconds.
621 *
622 * @returns LSCP_OK on success, LSCP_FAILED otherwise.
623 */
624 lscp_status_t lscp_client_set_timeout ( lscp_client_t *pClient, int iTimeout )
625 {
626 if (pClient == NULL)
627 return LSCP_FAILED;
628 if (iTimeout < 0)
629 return LSCP_FAILED;
630
631 pClient->iTimeout = iTimeout;
632 return LSCP_OK;
633 }
634
635
636 /**
637 * Get the client transaction timeout interval.
638 *
639 * @param pClient Pointer to client instance structure.
640 *
641 * @returns The current timeout value milliseconds, -1 in case of failure.
642 */
643 int lscp_client_get_timeout ( lscp_client_t *pClient )
644 {
645 if (pClient == NULL)
646 return -1;
647
648 return pClient->iTimeout;
649 }
650
651 /**
652 * Check whether connection to server is lost.
653 *
654 * @param pClient Pointer to client instance structure.
655 *
656 * @returns @c true if client lost connection to server, @c false otherwise.
657 */
658 bool lscp_client_connection_lost ( lscp_client_t *pClient )
659 {
660 int err = lscp_client_get_errno(pClient);
661 if (err >= 0) return false;
662 return err == -EPIPE || err == -ECONNRESET || err == -ECONNABORTED;
663 }
664
665
666 //-------------------------------------------------------------------------
667 // Client common protocol functions.
668
669 /**
670 * Submit a command query line string to the server. The query string
671 * must be cr/lf and null terminated. Besides the return code, the
672 * specific server response to the command request is made available
673 * by the @ref lscp_client_get_result and @ref lscp_client_get_errno
674 * function calls.
675 *
676 * @param pClient Pointer to client instance structure.
677 * @param pszQuery Command request line to be sent to server,
678 * must be cr/lf and null terminated.
679 *
680 * @returns LSCP_OK on success, LSCP_FAILED otherwise.
681 */
682 lscp_status_t lscp_client_query ( lscp_client_t *pClient, const char *pszQuery )
683 {
684 lscp_status_t ret;
685
686 if (pClient == NULL)
687 return LSCP_FAILED;
688
689 // Lock this section up.
690 lscp_mutex_lock(pClient->mutex);
691
692 // Just make the now guarded call.
693 ret = lscp_client_call(pClient, pszQuery, 0);
694
695 // Unlock this section down.
696 lscp_mutex_unlock(pClient->mutex);
697
698 return ret;
699 }
700
701 /**
702 * Get the last received result string. In case of error or warning,
703 * this is the text of the error or warning message issued.
704 *
705 * @param pClient Pointer to client instance structure.
706 *
707 * @returns A pointer to the literal null-terminated result string as
708 * of the last command request.
709 */
710 const char *lscp_client_get_result ( lscp_client_t *pClient )
711 {
712 if (pClient == NULL)
713 return NULL;
714
715 return pClient->pszResult;
716 }
717
718
719 /**
720 * Get the last error/warning number received.
721 *
722 * @param pClient Pointer to client instance structure.
723 *
724 * @returns The numerical value of the last error or warning
725 * response code received.
726 */
727 int lscp_client_get_errno ( lscp_client_t *pClient )
728 {
729 if (pClient == NULL)
730 return -1;
731
732 return pClient->iErrno;
733 }
734
735
736 //-------------------------------------------------------------------------
737 // Client registration protocol functions.
738
739 /**
740 * Register frontend for receiving event messages by the sampler backend.
741 * @e Caution: since liblscp v0.5.5.4 you have to call lscp_client_subscribe()
742 * for @e each event you want to subscribe. That is the old bitflag approach
743 * was abondoned at this point. You can however still register all older
744 * events with one lscp_client_subscribe() call at once. Thus, the old
745 * behavior of this functions was not broken. Those older events are namely:
746 * @code
747 * SUBSCRIBE CHANNEL_COUNT | VOICE_COUNT | STREAM_COUNT
748 * | BUFFER_FILL | CHANNEL_INFO | TOTAL_VOICE_COUNT
749 * | AUDIO_OUTPUT_DEVICE_COUNT | AUDIO_OUTPUT_DEVICE_INFO
750 * | MIDI_INPUT_DEVICE_COUNT | MIDI_INPUT_DEVICE_INFO
751 * | MIDI_INSTRUMENT_MAP_COUNT | MIDI_INSTRUMENT_MAP_INFO
752 * | MIDI_INSTRUMENT_COUNT | MIDI_INSTRUMENT_INFO
753 * | MISCELLANEOUS
754 * @endcode
755 * The old events occupy the lower 16 bits (as bit flags), and all younger
756 * events enumerate the whole upper 16 bits range. The new, enumerated
757 * events are namely:
758 * @code
759 * SUBSCRIBE CHANNEL_MIDI
760 * @endcode
761 *
762 * @param pClient Pointer to client instance structure.
763 * @param events LSCP event to subscribe.
764 *
765 * @returns LSCP_OK on success, LSCP_FAILED otherwise.
766 */
767 lscp_status_t lscp_client_subscribe ( lscp_client_t *pClient, lscp_event_t events )
768 {
769 lscp_status_t ret = LSCP_OK;
770 lscp_event_t currentEvent;
771
772 if (pClient == NULL)
773 return LSCP_FAILED;
774
775 // Lock this section up.
776 lscp_mutex_lock(pClient->mutex);
777
778 // If applicable, start the alternate connection...
779 if (pClient->events == LSCP_EVENT_NONE)
780 ret = _lscp_client_evt_connect(pClient);
781
782 // Send the subscription commands.
783 if (ret == LSCP_OK && (events & LSCP_EVENT_CHANNEL_COUNT))
784 ret = _lscp_client_evt_request(pClient, 1, LSCP_EVENT_CHANNEL_COUNT);
785 if (ret == LSCP_OK && (events & LSCP_EVENT_VOICE_COUNT))
786 ret = _lscp_client_evt_request(pClient, 1, LSCP_EVENT_VOICE_COUNT);
787 if (ret == LSCP_OK && (events & LSCP_EVENT_STREAM_COUNT))
788 ret = _lscp_client_evt_request(pClient, 1, LSCP_EVENT_STREAM_COUNT);
789 if (ret == LSCP_OK && (events & LSCP_EVENT_BUFFER_FILL))
790 ret = _lscp_client_evt_request(pClient, 1, LSCP_EVENT_BUFFER_FILL);
791 if (ret == LSCP_OK && (events & LSCP_EVENT_CHANNEL_INFO))
792 ret = _lscp_client_evt_request(pClient, 1, LSCP_EVENT_CHANNEL_INFO);
793 if (ret == LSCP_OK && (events & LSCP_EVENT_TOTAL_VOICE_COUNT))
794 ret = _lscp_client_evt_request(pClient, 1, LSCP_EVENT_TOTAL_VOICE_COUNT);
795 if (ret == LSCP_OK && (events & LSCP_EVENT_AUDIO_OUTPUT_DEVICE_COUNT))
796 ret = _lscp_client_evt_request(pClient, 1, LSCP_EVENT_AUDIO_OUTPUT_DEVICE_COUNT);
797 if (ret == LSCP_OK && (events & LSCP_EVENT_AUDIO_OUTPUT_DEVICE_INFO))
798 ret = _lscp_client_evt_request(pClient, 1, LSCP_EVENT_AUDIO_OUTPUT_DEVICE_INFO);
799 if (ret == LSCP_OK && (events & LSCP_EVENT_MIDI_INPUT_DEVICE_COUNT))
800 ret = _lscp_client_evt_request(pClient, 1, LSCP_EVENT_MIDI_INPUT_DEVICE_COUNT);
801 if (ret == LSCP_OK && (events & LSCP_EVENT_MIDI_INPUT_DEVICE_INFO))
802 ret = _lscp_client_evt_request(pClient, 1, LSCP_EVENT_MIDI_INPUT_DEVICE_INFO);
803 if (ret == LSCP_OK && (events & LSCP_EVENT_MIDI_INSTRUMENT_MAP_COUNT))
804 ret = _lscp_client_evt_request(pClient, 1, LSCP_EVENT_MIDI_INSTRUMENT_MAP_COUNT);
805 if (ret == LSCP_OK && (events & LSCP_EVENT_MIDI_INSTRUMENT_MAP_INFO))
806 ret = _lscp_client_evt_request(pClient, 1, LSCP_EVENT_MIDI_INSTRUMENT_MAP_INFO);
807 if (ret == LSCP_OK && (events & LSCP_EVENT_MIDI_INSTRUMENT_COUNT))
808 ret = _lscp_client_evt_request(pClient, 1, LSCP_EVENT_MIDI_INSTRUMENT_COUNT);
809 if (ret == LSCP_OK && (events & LSCP_EVENT_MIDI_INSTRUMENT_INFO))
810 ret = _lscp_client_evt_request(pClient, 1, LSCP_EVENT_MIDI_INSTRUMENT_INFO);
811 if (ret == LSCP_OK && (events & LSCP_EVENT_MISCELLANEOUS))
812 ret = _lscp_client_evt_request(pClient, 1, LSCP_EVENT_MISCELLANEOUS);
813 // Caution: for the upper 16 bits, we don't use bit flags anymore ...
814 currentEvent = events & 0xffff0000;
815 if (ret == LSCP_OK && currentEvent) {
816 switch (currentEvent) {
817 case LSCP_EVENT_CHANNEL_MIDI:
818 case LSCP_EVENT_DEVICE_MIDI:
819 ret = _lscp_client_evt_request(pClient, 1, currentEvent);
820 break;
821 default: // unknown "upper" event type
822 ret = LSCP_FAILED;
823 break;
824 }
825 }
826
827 // Unlock this section down.
828 lscp_mutex_unlock(pClient->mutex);
829
830 return ret;
831 }
832
833
834 /**
835 * Deregister frontend from receiving UDP event messages anymore.
836 * @e Caution: since liblscp v0.5.5.4 you have to call
837 * lscp_client_unsubscribe() for @e each event you want to unsubscribe.
838 * That is the old bitflag approach was abondoned at this point. You can
839 * however still register all older events with one lscp_client_subscribe()
840 * call at once. Thus, the old behavior of this functions was not broken.
841 * Those older events are namely:
842 * @code
843 * UNSUBSCRIBE CHANNEL_COUNT | VOICE_COUNT | STREAM_COUNT
844 * | BUFFER_FILL | CHANNEL_INFO | TOTAL_VOICE_COUNT
845 * | AUDIO_OUTPUT_DEVICE_COUNT | AUDIO_OUTPUT_DEVICE_INFO
846 * | MIDI_INPUT_DEVICE_COUNT | MIDI_INPUT_DEVICE_INFO
847 * | MIDI_INSTRUMENT_MAP_COUNT | MIDI_INSTRUMENT_MAP_INFO
848 * | MIDI_INSTRUMENT_COUNT | MIDI_INSTRUMENT_INFO
849 * | MISCELLANEOUS
850 * @endcode
851 * The old events occupy the lower 16 bits (as bit flags), and all younger
852 * events enumerate the whole upper 16 bits range. The new, enumerated
853 * events are namely:
854 * @code
855 * UNSUBSCRIBE CHANNEL_MIDI
856 * @endcode
857 *
858 * @param pClient Pointer to client instance structure.
859 * @param events LSCP event to unsubscribe.
860 *
861 * @returns LSCP_OK on success, LSCP_FAILED otherwise.
862 */
863 lscp_status_t lscp_client_unsubscribe ( lscp_client_t *pClient, lscp_event_t events )
864 {
865 lscp_status_t ret = LSCP_OK;
866 lscp_event_t currentEvent;
867
868 if (pClient == NULL)
869 return LSCP_FAILED;
870
871 // Lock this section up.
872 lscp_mutex_lock(pClient->mutex);
873
874 // Send the unsubscription commands.
875 if (ret == LSCP_OK && (events & LSCP_EVENT_CHANNEL_COUNT))
876 ret = _lscp_client_evt_request(pClient, 0, LSCP_EVENT_CHANNEL_COUNT);
877 if (ret == LSCP_OK && (events & LSCP_EVENT_VOICE_COUNT))
878 ret = _lscp_client_evt_request(pClient, 0, LSCP_EVENT_VOICE_COUNT);
879 if (ret == LSCP_OK && (events & LSCP_EVENT_STREAM_COUNT))
880 ret = _lscp_client_evt_request(pClient, 0, LSCP_EVENT_STREAM_COUNT);
881 if (ret == LSCP_OK && (events & LSCP_EVENT_BUFFER_FILL))
882 ret = _lscp_client_evt_request(pClient, 0, LSCP_EVENT_BUFFER_FILL);
883 if (ret == LSCP_OK && (events & LSCP_EVENT_CHANNEL_INFO))
884 ret = _lscp_client_evt_request(pClient, 0, LSCP_EVENT_CHANNEL_INFO);
885 if (ret == LSCP_OK && (events & LSCP_EVENT_TOTAL_VOICE_COUNT))
886 ret = _lscp_client_evt_request(pClient, 0, LSCP_EVENT_TOTAL_VOICE_COUNT);
887 if (ret == LSCP_OK && (events & LSCP_EVENT_AUDIO_OUTPUT_DEVICE_COUNT))
888 ret = _lscp_client_evt_request(pClient, 0, LSCP_EVENT_AUDIO_OUTPUT_DEVICE_COUNT);
889 if (ret == LSCP_OK && (events & LSCP_EVENT_AUDIO_OUTPUT_DEVICE_INFO))
890 ret = _lscp_client_evt_request(pClient, 0, LSCP_EVENT_AUDIO_OUTPUT_DEVICE_INFO);
891 if (ret == LSCP_OK && (events & LSCP_EVENT_MIDI_INPUT_DEVICE_COUNT))
892 ret = _lscp_client_evt_request(pClient, 0, LSCP_EVENT_MIDI_INPUT_DEVICE_COUNT);
893 if (ret == LSCP_OK && (events & LSCP_EVENT_MIDI_INPUT_DEVICE_INFO))
894 ret = _lscp_client_evt_request(pClient, 0, LSCP_EVENT_MIDI_INPUT_DEVICE_INFO);
895 if (ret == LSCP_OK && (events & LSCP_EVENT_MIDI_INSTRUMENT_MAP_COUNT))
896 ret = _lscp_client_evt_request(pClient, 0, LSCP_EVENT_MIDI_INSTRUMENT_MAP_COUNT);
897 if (ret == LSCP_OK && (events & LSCP_EVENT_MIDI_INSTRUMENT_MAP_INFO))
898 ret = _lscp_client_evt_request(pClient, 0, LSCP_EVENT_MIDI_INSTRUMENT_MAP_INFO);
899 if (ret == LSCP_OK && (events & LSCP_EVENT_MIDI_INSTRUMENT_COUNT))
900 ret = _lscp_client_evt_request(pClient, 0, LSCP_EVENT_MIDI_INSTRUMENT_COUNT);
901 if (ret == LSCP_OK && (events & LSCP_EVENT_MIDI_INSTRUMENT_INFO))
902 ret = _lscp_client_evt_request(pClient, 0, LSCP_EVENT_MIDI_INSTRUMENT_INFO);
903 if (ret == LSCP_OK && (events & LSCP_EVENT_MISCELLANEOUS))
904 ret = _lscp_client_evt_request(pClient, 0, LSCP_EVENT_MISCELLANEOUS);
905 // Caution: for the upper 16 bits, we don't use bit flags anymore ...
906 currentEvent = events & 0xffff0000;
907 if (ret == LSCP_OK && currentEvent) {
908 switch (currentEvent) {
909 case LSCP_EVENT_CHANNEL_MIDI:
910 case LSCP_EVENT_DEVICE_MIDI:
911 ret = _lscp_client_evt_request(pClient, 0, currentEvent);
912 break;
913 default: // unknown "upper" event type
914 ret = LSCP_FAILED;
915 break;
916 }
917 }
918
919 // If necessary, close the alternate connection...
920 if (pClient->events == LSCP_EVENT_NONE)
921 lscp_socket_agent_free(&(pClient->evt));
922
923 // Unlock this section down.
924 lscp_mutex_unlock(pClient->mutex);
925
926 return ret;
927 }
928
929
930 /**
931 * Getting current subscribed events.
932 *
933 * @param pClient Pointer to client instance structure.
934 *
935 * @returns The current subscrived bit-wise OR'ed event flags.
936 */
937 lscp_event_t lscp_client_get_events ( lscp_client_t *pClient )
938 {
939 if (pClient == NULL)
940 return LSCP_EVENT_NONE;
941
942 return pClient->events;
943 }
944
945
946 //-------------------------------------------------------------------------
947 // Client command protocol functions.
948
949 /**
950 * Loading an instrument:
951 * LOAD INSTRUMENT <filename> <instr-index> <sampler-channel>
952 *
953 * @param pClient Pointer to client instance structure.
954 * @param pszFileName Instrument file name.
955 * @param iInstrIndex Instrument index number.
956 * @param iSamplerChannel Sampler Channel.
957 *
958 * @returns LSCP_OK on success, LSCP_FAILED otherwise.
959 */
960 lscp_status_t lscp_load_instrument ( lscp_client_t *pClient,
961 const char *pszFileName, int iInstrIndex, int iSamplerChannel )
962 {
963 char szQuery[LSCP_BUFSIZ];
964
965 if (pszFileName == NULL || iSamplerChannel < 0)
966 return LSCP_FAILED;
967
968 sprintf(szQuery, "LOAD INSTRUMENT '%s' %d %d\r\n",
969 pszFileName, iInstrIndex, iSamplerChannel);
970 return lscp_client_query(pClient, szQuery);
971 }
972
973
974 /**
975 * Loading an instrument in the background (non modal):
976 * LOAD INSTRUMENT NON_MODAL <filename> <instr-index> <sampler-channel>
977 *
978 * @param pClient Pointer to client instance structure.
979 * @param pszFileName Instrument file name.
980 * @param iInstrIndex Instrument index number.
981 * @param iSamplerChannel Sampler Channel.
982 *
983 * @returns LSCP_OK on success, LSCP_FAILED otherwise.
984 */
985 lscp_status_t lscp_load_instrument_non_modal ( lscp_client_t *pClient,
986 const char *pszFileName, int iInstrIndex, int iSamplerChannel )
987 {
988 char szQuery[LSCP_BUFSIZ];
989
990 if (pszFileName == NULL || iSamplerChannel < 0)
991 return LSCP_FAILED;
992
993 sprintf(szQuery, "LOAD INSTRUMENT NON_MODAL '%s' %d %d\r\n",
994 pszFileName, iInstrIndex, iSamplerChannel);
995 return lscp_client_query(pClient, szQuery);
996 }
997
998
999 /**
1000 * Loading a sampler engine:
1001 * LOAD ENGINE <engine-name> <sampler-channel>
1002 *
1003 * @param pClient Pointer to client instance structure.
1004 * @param pszEngineName Engine name.
1005 * @param iSamplerChannel Sampler channel number.
1006 *
1007 * @returns LSCP_OK on success, LSCP_FAILED otherwise.
1008 */
1009 lscp_status_t lscp_load_engine ( lscp_client_t *pClient, const char *pszEngineName, int iSamplerChannel )
1010 {
1011 char szQuery[LSCP_BUFSIZ];
1012
1013 if (pszEngineName == NULL || iSamplerChannel < 0)
1014 return LSCP_FAILED;
1015
1016 sprintf(szQuery, "LOAD ENGINE %s %d\r\n",
1017 pszEngineName, iSamplerChannel);
1018 return lscp_client_query(pClient, szQuery);
1019 }
1020
1021
1022 /**
1023 * Current number of sampler channels:
1024 * GET CHANNELS
1025 *
1026 * @param pClient Pointer to client instance structure.
1027 *
1028 * @returns The current total number of sampler channels on success,
1029 * -1 otherwise.
1030 */
1031 int lscp_get_channels ( lscp_client_t *pClient )
1032 {
1033 int iChannels = -1;
1034
1035 if (pClient == NULL)
1036 return -1;
1037
1038 // Lock this section up.
1039 lscp_mutex_lock(pClient->mutex);
1040
1041 if (lscp_client_call(pClient, "GET CHANNELS\r\n", 0) == LSCP_OK)
1042 iChannels = atoi(lscp_client_get_result(pClient));
1043
1044 // Unlock this section doen.
1045 lscp_mutex_unlock(pClient->mutex);
1046
1047 return iChannels;
1048 }
1049
1050
1051 /**
1052 * List current sampler channels number identifiers:
1053 * LIST CHANNELS
1054 *
1055 * @param pClient Pointer to client instance structure.
1056 *
1057 * @returns An array of the sampler channels identifiers as positive integers,
1058 * terminated with -1 on success, NULL otherwise.
1059 */
1060 int *lscp_list_channels ( lscp_client_t *pClient )
1061 {
1062 const char *pszSeps = ",";
1063
1064 if (pClient == NULL)
1065 return NULL;
1066
1067 // Lock this section up.
1068 lscp_mutex_lock(pClient->mutex);
1069
1070 if (pClient->channels) {
1071 lscp_isplit_destroy(pClient->channels);
1072 pClient->channels = NULL;
1073 }
1074
1075 if (lscp_client_call(pClient, "LIST CHANNELS\r\n", 0) == LSCP_OK)
1076 pClient->channels = lscp_isplit_create(lscp_client_get_result(pClient), pszSeps);
1077
1078 // Unlock this section down.
1079 lscp_mutex_unlock(pClient->mutex);
1080
1081 return pClient->channels;
1082 }
1083
1084
1085 /**
1086 * Adding a new sampler channel:
1087 * ADD CHANNEL
1088 *
1089 * @param pClient Pointer to client instance structure.
1090 *
1091 * @returns The new sampler channel number identifier,
1092 * or -1 in case of failure.
1093 */
1094 int lscp_add_channel ( lscp_client_t *pClient )
1095 {
1096 int iSamplerChannel = -1;
1097
1098 if (pClient == NULL)
1099 return -1;
1100
1101 // Lock this section up.
1102 lscp_mutex_lock(pClient->mutex);
1103
1104 if (lscp_client_call(pClient, "ADD CHANNEL\r\n", 0) == LSCP_OK)
1105 iSamplerChannel = atoi(lscp_client_get_result(pClient));
1106
1107 // Unlock this section down.
1108 lscp_mutex_unlock(pClient->mutex);
1109
1110 return iSamplerChannel;
1111 }
1112
1113
1114 /**
1115 * Removing a sampler channel:
1116 * REMOVE CHANNEL <sampler-channel>
1117 *
1118 * @param pClient Pointer to client instance structure.
1119 * @param iSamplerChannel Sampler channel number.
1120 *
1121 * @returns LSCP_OK on success, LSCP_FAILED otherwise.
1122 */
1123 lscp_status_t lscp_remove_channel ( lscp_client_t *pClient, int iSamplerChannel )
1124 {
1125 char szQuery[LSCP_BUFSIZ];
1126
1127 if (iSamplerChannel < 0)
1128 return LSCP_FAILED;
1129
1130 sprintf(szQuery, "REMOVE CHANNEL %d\r\n", iSamplerChannel);
1131 return lscp_client_query(pClient, szQuery);
1132 }
1133
1134
1135 /**
1136 * Getting all available engines count:
1137 * GET AVAILABLE_ENGINES
1138 *
1139 * @param pClient Pointer to client instance structure.
1140 *
1141 * @returns The current total number of sampler engines on success,
1142 * -1 otherwise.
1143 */
1144 int lscp_get_available_engines ( lscp_client_t *pClient )
1145 {
1146 int iAvailableEngines = -1;
1147
1148 if (pClient == NULL)
1149 return -1;
1150
1151 // Lock this section up.
1152 lscp_mutex_lock(pClient->mutex);
1153
1154 if (lscp_client_call(pClient, "GET AVAILABLE_ENGINES\r\n", 0) == LSCP_OK)
1155 iAvailableEngines = atoi(lscp_client_get_result(pClient));
1156
1157 // Unlock this section down.
1158 lscp_mutex_unlock(pClient->mutex);
1159
1160 return iAvailableEngines;
1161 }
1162
1163
1164 /**
1165 * Getting all available engines:
1166 * LIST AVAILABLE_ENGINES
1167 *
1168 * @param pClient Pointer to client instance structure.
1169 *
1170 * @returns A NULL terminated array of engine name strings,
1171 * or NULL in case of failure.
1172 */
1173 const char **lscp_list_available_engines ( lscp_client_t *pClient )
1174 {
1175 const char *pszSeps = ",";
1176
1177 if (pClient == NULL)
1178 return NULL;
1179
1180 // Lock this section up.
1181 lscp_mutex_lock(pClient->mutex);
1182
1183 if (pClient->engines) {
1184 lscp_szsplit_destroy(pClient->engines);
1185 pClient->engines = NULL;
1186 }
1187
1188 if (lscp_client_call(pClient, "LIST AVAILABLE_ENGINES\r\n", 0) == LSCP_OK)
1189 pClient->engines = lscp_szsplit_create(lscp_client_get_result(pClient), pszSeps);
1190
1191 // Unlock this section down.
1192 lscp_mutex_unlock(pClient->mutex);
1193
1194 return (const char **) pClient->engines;
1195 }
1196
1197
1198 /**
1199 * Getting information about an engine.
1200 * GET ENGINE INFO <engine-name>
1201 *
1202 * @param pClient Pointer to client instance structure.
1203 * @param pszEngineName Engine name.
1204 *
1205 * @returns A pointer to a @ref lscp_engine_info_t structure, with all the
1206 * information of the given sampler engine, or NULL in case of failure.
1207 */
1208 lscp_engine_info_t *lscp_get_engine_info ( lscp_client_t *pClient,
1209 const char *pszEngineName )
1210 {
1211 lscp_engine_info_t *pEngineInfo;
1212 char szQuery[LSCP_BUFSIZ];
1213 const char *pszResult;
1214 const char *pszSeps = ":";
1215 const char *pszCrlf = "\r\n";
1216 char *pszToken;
1217 char *pch;
1218
1219 if (pClient == NULL)
1220 return NULL;
1221 if (pszEngineName == NULL)
1222 return NULL;
1223
1224 // Lock this section up.
1225 lscp_mutex_lock(pClient->mutex);
1226
1227 pEngineInfo = &(pClient->engine_info);
1228 lscp_engine_info_reset(pEngineInfo);
1229
1230 sprintf(szQuery, "GET ENGINE INFO %s\r\n", pszEngineName);
1231 if (lscp_client_call(pClient, szQuery, 1) == LSCP_OK) {
1232 pszResult = lscp_client_get_result(pClient);
1233 pszToken = lscp_strtok((char *) pszResult, pszSeps, &(pch));
1234 while (pszToken) {
1235 if (strcasecmp(pszToken, "DESCRIPTION") == 0) {
1236 pszToken = lscp_strtok(NULL, pszCrlf, &(pch));
1237 if (pszToken)
1238 lscp_unquote_dup(&(pEngineInfo->description), &pszToken);
1239 }
1240 else if (strcasecmp(pszToken, "VERSION") == 0) {
1241 pszToken = lscp_strtok(NULL, pszCrlf, &(pch));
1242 if (pszToken)
1243 lscp_unquote_dup(&(pEngineInfo->version), &pszToken);
1244 }
1245 pszToken = lscp_strtok(NULL, pszSeps, &(pch));
1246 }
1247 }
1248 else pEngineInfo = NULL;
1249
1250 // Unlock this section down.
1251 lscp_mutex_unlock(pClient->mutex);
1252
1253 return pEngineInfo;
1254 }
1255
1256
1257 /**
1258 * Getting sampler channel informations:
1259 * GET CHANNEL INFO <sampler-channel>
1260 *
1261 * @param pClient Pointer to client instance structure.
1262 * @param iSamplerChannel Sampler channel number.
1263 *
1264 * @returns A pointer to a @ref lscp_channel_info_t structure, with all the
1265 * information of the given sampler channel, or NULL in case of failure.
1266 */
1267 lscp_channel_info_t *lscp_get_channel_info ( lscp_client_t *pClient, int iSamplerChannel )
1268 {
1269 lscp_channel_info_t *pChannelInfo;
1270 char szQuery[LSCP_BUFSIZ];
1271 const char *pszResult;
1272 const char *pszSeps = ":";
1273 const char *pszCrlf = "\r\n";
1274 char *pszToken;
1275 char *pch;
1276 struct _locale_t locale;
1277
1278 if (pClient == NULL)
1279 return NULL;
1280 if (iSamplerChannel < 0)
1281 return NULL;
1282
1283 // Lock this section up.
1284 lscp_mutex_lock(pClient->mutex);
1285
1286 pChannelInfo = &(pClient->channel_info);
1287 lscp_channel_info_reset(pChannelInfo);
1288
1289 _save_and_set_c_locale(&locale);
1290
1291 sprintf(szQuery, "GET CHANNEL INFO %d\r\n", iSamplerChannel);
1292 if (lscp_client_call(pClient, szQuery, 1) == LSCP_OK) {
1293 pszResult = lscp_client_get_result(pClient);
1294 pszToken = lscp_strtok((char *) pszResult, pszSeps, &(pch));
1295 while (pszToken) {
1296 if (strcasecmp(pszToken, "ENGINE_NAME") == 0) {
1297 pszToken = lscp_strtok(NULL, pszCrlf, &(pch));
1298 if (pszToken)
1299 lscp_unquote_dup(&(pChannelInfo->engine_name), &pszToken);
1300 }
1301 else if (strcasecmp(pszToken, "AUDIO_OUTPUT_DEVICE") == 0) {
1302 pszToken = lscp_strtok(NULL, pszCrlf, &(pch));
1303 if (pszToken)
1304 pChannelInfo->audio_device = atoi(lscp_ltrim(pszToken));
1305 }
1306 else if (strcasecmp(pszToken, "AUDIO_OUTPUT_CHANNELS") == 0) {
1307 pszToken = lscp_strtok(NULL, pszCrlf, &(pch));
1308 if (pszToken)
1309 pChannelInfo->audio_channels = atoi(lscp_ltrim(pszToken));
1310 }
1311 else if (strcasecmp(pszToken, "AUDIO_OUTPUT_ROUTING") == 0) {
1312 pszToken = lscp_strtok(NULL, pszCrlf, &(pch));
1313 if (pszToken) {
1314 if (pChannelInfo->audio_routing)
1315 lscp_isplit_destroy(pChannelInfo->audio_routing);
1316 pChannelInfo->audio_routing = lscp_isplit_create(pszToken, ",");
1317 }
1318 }
1319 else if (strcasecmp(pszToken, "INSTRUMENT_FILE") == 0) {
1320 pszToken = lscp_strtok(NULL, pszCrlf, &(pch));
1321 if (pszToken)
1322 lscp_unquote_dup(&(pChannelInfo->instrument_file), &pszToken);
1323 }
1324 else if (strcasecmp(pszToken, "INSTRUMENT_NR") == 0) {
1325 pszToken = lscp_strtok(NULL, pszCrlf, &(pch));
1326 if (pszToken)
1327 pChannelInfo->instrument_nr = atoi(lscp_ltrim(pszToken));
1328 }
1329 else if (strcasecmp(pszToken, "INSTRUMENT_NAME") == 0) {
1330 pszToken = lscp_strtok(NULL, pszCrlf, &(pch));
1331 if (pszToken)
1332 lscp_unquote_dup(&(pChannelInfo->instrument_name), &pszToken);
1333 }
1334 else if (strcasecmp(pszToken, "INSTRUMENT_STATUS") == 0) {
1335 pszToken = lscp_strtok(NULL, pszCrlf, &(pch));
1336 if (pszToken)
1337 pChannelInfo->instrument_status = atoi(lscp_ltrim(pszToken));
1338 }
1339 else if (strcasecmp(pszToken, "MIDI_INPUT_DEVICE") == 0) {
1340 pszToken = lscp_strtok(NULL, pszCrlf, &(pch));
1341 if (pszToken)
1342 pChannelInfo->midi_device = atoi(lscp_ltrim(pszToken));
1343 }
1344 else if (strcasecmp(pszToken, "MIDI_INPUT_PORT") == 0) {
1345 pszToken = lscp_strtok(NULL, pszCrlf, &(pch));
1346 if (pszToken)
1347 pChannelInfo->midi_port = atoi(lscp_ltrim(pszToken));
1348 }
1349 else if (strcasecmp(pszToken, "MIDI_INPUT_CHANNEL") == 0) {
1350 pszToken = lscp_strtok(NULL, pszCrlf, &(pch));
1351 if (pszToken) {
1352 pszToken = lscp_ltrim(pszToken);
1353 if (strcasecmp(pszToken, "ALL") == 0)
1354 pChannelInfo->midi_channel = LSCP_MIDI_CHANNEL_ALL;
1355 else
1356 pChannelInfo->midi_channel = atoi(pszToken);
1357 }
1358 }
1359 else if (strcasecmp(pszToken, "MIDI_INSTRUMENT_MAP") == 0) {
1360 pszToken = lscp_strtok(NULL, pszCrlf, &(pch));
1361 if (pszToken) {
1362 pszToken = lscp_ltrim(pszToken);
1363 if (strcasecmp(pszToken, "NONE") == 0)
1364 pChannelInfo->midi_map = LSCP_MIDI_MAP_NONE;
1365 else
1366 if (strcasecmp(pszToken, "DEFAULT") == 0)
1367 pChannelInfo->midi_map = LSCP_MIDI_MAP_DEFAULT;
1368 else
1369 pChannelInfo->midi_map = atoi(pszToken);
1370 }
1371 }
1372 else if (strcasecmp(pszToken, "VOLUME") == 0) {
1373 pszToken = lscp_strtok(NULL, pszCrlf, &(pch));
1374 if (pszToken)
1375 pChannelInfo->volume = _atof(lscp_ltrim(pszToken));
1376 }
1377 else if (strcasecmp(pszToken, "MUTE") == 0) {
1378 pszToken = lscp_strtok(NULL, pszCrlf, &(pch));
1379 if (pszToken)
1380 pChannelInfo->mute = (strcasecmp(lscp_unquote(&pszToken, 0), "TRUE") == 0);
1381 }
1382 else if (strcasecmp(pszToken, "SOLO") == 0) {
1383 pszToken = lscp_strtok(NULL, pszCrlf, &(pch));
1384 if (pszToken)
1385 pChannelInfo->solo = (strcasecmp(lscp_unquote(&pszToken, 0), "TRUE") == 0);
1386 }
1387 pszToken = lscp_strtok(NULL, pszSeps, &(pch));
1388 }
1389 }
1390 else pChannelInfo = NULL;
1391
1392 _restore_locale(&locale);
1393
1394 // Unlock this section up.
1395 lscp_mutex_unlock(pClient->mutex);
1396
1397 return pChannelInfo;
1398 }
1399
1400
1401 /**
1402 * Current number of active voices:
1403 * GET CHANNEL VOICE_COUNT <sampler-channel>
1404 *
1405 * @param pClient Pointer to client instance structure.
1406 * @param iSamplerChannel Sampler channel number.
1407 *
1408 * @returns The number of voices currently active, -1 in case of failure.
1409 */
1410 int lscp_get_channel_voice_count ( lscp_client_t *pClient, int iSamplerChannel )
1411 {
1412 char szQuery[LSCP_BUFSIZ];
1413 int iVoiceCount = -1;
1414
1415 if (pClient == NULL)
1416 return -1;
1417 if (iSamplerChannel < 0)
1418 return -1;
1419
1420 // Lock this section up.
1421 lscp_mutex_lock(pClient->mutex);
1422
1423 sprintf(szQuery, "GET CHANNEL VOICE_COUNT %d\r\n", iSamplerChannel);
1424 if (lscp_client_call(pClient, szQuery, 0) == LSCP_OK)
1425 iVoiceCount = atoi(lscp_client_get_result(pClient));
1426
1427 // Unlock this section down.
1428 lscp_mutex_unlock(pClient->mutex);
1429
1430 return iVoiceCount;
1431 }
1432
1433
1434 /**
1435 * Current number of active disk streams:
1436 * GET CHANNEL STREAM_COUNT <sampler-channel>
1437 *
1438 * @param pClient Pointer to client instance structure.
1439 * @param iSamplerChannel Sampler channel number.
1440 *
1441 * @returns The number of active disk streams on success, -1 otherwise.
1442 */
1443 int lscp_get_channel_stream_count ( lscp_client_t *pClient, int iSamplerChannel )
1444 {
1445 char szQuery[LSCP_BUFSIZ];
1446 int iStreamCount = -1;
1447
1448 if (pClient == NULL)
1449 return -1;
1450 if (iSamplerChannel < 0)
1451 return -1;
1452
1453 // Lock this section up.
1454 lscp_mutex_lock(pClient->mutex);
1455
1456 sprintf(szQuery, "GET CHANNEL STREAM_COUNT %d\r\n", iSamplerChannel);
1457 if (lscp_client_call(pClient, szQuery, 0) == LSCP_OK)
1458 iStreamCount = atoi(lscp_client_get_result(pClient));
1459
1460 // Unlock this section down.
1461 lscp_mutex_unlock(pClient->mutex);
1462
1463 return iStreamCount;
1464 }
1465
1466
1467 /**
1468 * Current least usage of active disk streams.
1469 *
1470 * @param pClient Pointer to client instance structure.
1471 * @param iSamplerChannel Sampler channel number.
1472 *
1473 * @returns The usage percentage of the least filled active disk stream
1474 * on success, -1 otherwise.
1475 */
1476 int lscp_get_channel_stream_usage ( lscp_client_t *pClient, int iSamplerChannel )
1477 {
1478 char szQuery[LSCP_BUFSIZ];
1479 int iStreamUsage = -1;
1480 const char *pszResult;
1481 const char *pszSeps = "[]%,";
1482 char *pszToken;
1483 char *pch;
1484 int iStream;
1485 int iPercent;
1486
1487 if (pClient == NULL)
1488 return -1;
1489 if (iSamplerChannel < 0)
1490 return -1;
1491
1492 // Lock this section up.
1493 lscp_mutex_lock(pClient->mutex);
1494
1495 iStream = 0;
1496 sprintf(szQuery, "GET CHANNEL BUFFER_FILL PERCENTAGE %d\r\n", iSamplerChannel);
1497 if (lscp_client_call(pClient, szQuery, 0) == LSCP_OK) {
1498 pszResult = lscp_client_get_result(pClient);
1499 pszToken = lscp_strtok((char *) pszResult, pszSeps, &(pch));
1500 while (pszToken) {
1501 if (*pszToken) {
1502 // Skip stream id.
1503 pszToken = lscp_strtok(NULL, pszSeps, &(pch));
1504 if (pszToken == NULL)
1505 break;
1506 // Get least buffer fill percentage.
1507 iPercent = atol(pszToken);
1508 if (iStreamUsage > iPercent || iStream == 0)
1509 iStreamUsage = iPercent;
1510 iStream++;
1511 }
1512 pszToken = lscp_strtok(NULL, pszSeps, &(pch));
1513 }
1514 }
1515
1516 // Unlock this section down.
1517 lscp_mutex_unlock(pClient->mutex);
1518
1519 return iStreamUsage;
1520 }
1521
1522
1523 /**
1524 * Current fill state of disk stream buffers:
1525 * GET CHANNEL BUFFER_FILL {BYTES|PERCENTAGE} <sampler-channel>
1526 *
1527 * @param pClient Pointer to client instance structure.
1528 * @param usage_type Usage type to be returned, either
1529 * @ref LSCP_USAGE_BYTES, or
1530 * @ref LSCP_USAGE_PERCENTAGE.
1531 * @param iSamplerChannel Sampler channel number.
1532 *
1533 * @returns A pointer to a @ref lscp_buffer_fill_t structure, with the
1534 * information of the current disk stream buffer fill usage, for the given
1535 * sampler channel, or NULL in case of failure.
1536 */
1537 lscp_buffer_fill_t *lscp_get_channel_buffer_fill ( lscp_client_t *pClient,
1538 lscp_usage_t usage_type, int iSamplerChannel )
1539 {
1540 lscp_buffer_fill_t *pBufferFill;
1541 char szQuery[LSCP_BUFSIZ];
1542 int iStreamCount;
1543 const char *pszUsageType = (usage_type == LSCP_USAGE_BYTES ? "BYTES" : "PERCENTAGE");
1544 const char *pszResult;
1545 const char *pszSeps = "[]%,";
1546 char *pszToken;
1547 char *pch;
1548 int iStream;
1549
1550 // Retrieve a channel stream estimation.
1551 iStreamCount = lscp_get_channel_stream_count(pClient, iSamplerChannel);
1552 if (iStreamCount < 0)
1553 return NULL;
1554
1555 // Lock this section up.
1556 lscp_mutex_lock(pClient->mutex);
1557
1558 // Check if we need to reallocate the stream usage array.
1559 if (pClient->iStreamCount != iStreamCount) {
1560 if (pClient->buffer_fill)
1561 free(pClient->buffer_fill);
1562 if (iStreamCount > 0)
1563 pClient->buffer_fill = (lscp_buffer_fill_t *) malloc(iStreamCount * sizeof(lscp_buffer_fill_t));
1564 else
1565 pClient->buffer_fill = NULL;
1566 pClient->iStreamCount = iStreamCount;
1567 }
1568
1569 // Get buffer fill usage...
1570 pBufferFill = pClient->buffer_fill;
1571 if (pBufferFill && iStreamCount > 0) {
1572 iStream = 0;
1573 pBufferFill = pClient->buffer_fill;
1574 sprintf(szQuery, "GET CHANNEL BUFFER_FILL %s %d\r\n", pszUsageType, iSamplerChannel);
1575 if (lscp_client_call(pClient, szQuery, 0) == LSCP_OK) {
1576 pszResult = lscp_client_get_result(pClient);
1577 pszToken = lscp_strtok((char *) pszResult, pszSeps, &(pch));
1578 while (pszToken && iStream < pClient->iStreamCount) {
1579 if (*pszToken) {
1580 pBufferFill[iStream].stream_id = atol(pszToken);
1581 pszToken = lscp_strtok(NULL, pszSeps, &(pch));
1582 if (pszToken == NULL)
1583 break;
1584 pBufferFill[iStream].stream_usage = atol(pszToken);
1585 iStream++;
1586 }
1587 pszToken = lscp_strtok(NULL, pszSeps, &(pch));
1588 }
1589 } // Reset the usage, whatever it was before.
1590 else while (iStream < pClient->iStreamCount)
1591 pBufferFill[iStream++].stream_usage = 0;
1592 }
1593
1594 // Unlock this section down.
1595 lscp_mutex_unlock(pClient->mutex);
1596
1597 return pBufferFill;
1598 }
1599
1600
1601 /**
1602 * Setting audio output type:
1603 * SET CHANNEL AUDIO_OUTPUT_TYPE <sampler-channel> <audio-output-type>
1604 *
1605 * @param pClient Pointer to client instance structure.
1606 * @param iSamplerChannel Sampler channel number.
1607 * @param pszAudioDriver Audio output driver type (e.g. "ALSA" or "JACK").
1608 *
1609 * @returns LSCP_OK on success, LSCP_FAILED otherwise.
1610 */
1611 lscp_status_t lscp_set_channel_audio_type ( lscp_client_t *pClient,
1612 int iSamplerChannel, const char *pszAudioDriver )
1613 {
1614 char szQuery[LSCP_BUFSIZ];
1615
1616 if (iSamplerChannel < 0 || pszAudioDriver == NULL)
1617 return LSCP_FAILED;
1618
1619 sprintf(szQuery, "SET CHANNEL AUDIO_OUTPUT_TYPE %d %s\r\n",
1620 iSamplerChannel, pszAudioDriver);
1621 return lscp_client_query(pClient, szQuery);
1622 }
1623
1624
1625 /**
1626 * Setting audio output device:
1627 * SET CHANNEL AUDIO_OUTPUT_DEVICE <sampler-channel> <device-id>
1628 *
1629 * @param pClient Pointer to client instance structure.
1630 * @param iSamplerChannel Sampler channel number.
1631 * @param iAudioDevice Audio output device number identifier.
1632 *
1633 * @returns LSCP_OK on success, LSCP_FAILED otherwise.
1634 */
1635 lscp_status_t lscp_set_channel_audio_device ( lscp_client_t *pClient,
1636 int iSamplerChannel, int iAudioDevice )
1637 {
1638 char szQuery[LSCP_BUFSIZ];
1639
1640 if (iSamplerChannel < 0 || iAudioDevice < 0)
1641 return LSCP_FAILED;
1642
1643 sprintf(szQuery, "SET CHANNEL AUDIO_OUTPUT_DEVICE %d %d\r\n",
1644 iSamplerChannel, iAudioDevice);
1645 return lscp_client_query(pClient, szQuery);
1646 }
1647
1648
1649 /**
1650 * Setting audio output channel:
1651 * SET CHANNEL AUDIO_OUTPUT_CHANNEL <sampler-channel> <audio-output-chan> <audio-input-chan>
1652 *
1653 * @param pClient Pointer to client instance structure.
1654 * @param iSamplerChannel Sampler channel number.
1655 * @param iAudioOut Audio output device channel to be routed from.
1656 * @param iAudioIn Audio output device channel to be routed into.
1657 *
1658 * @returns LSCP_OK on success, LSCP_FAILED otherwise.
1659 */
1660 lscp_status_t lscp_set_channel_audio_channel ( lscp_client_t *pClient,
1661 int iSamplerChannel, int iAudioOut, int iAudioIn )
1662 {
1663 char szQuery[LSCP_BUFSIZ];
1664
1665 if (iSamplerChannel < 0 || iAudioOut < 0 || iAudioIn < 0)
1666 return LSCP_FAILED;
1667
1668 sprintf(szQuery, "SET CHANNEL AUDIO_OUTPUT_CHANNEL %d %d %d\r\n",
1669 iSamplerChannel, iAudioOut, iAudioIn);
1670 return lscp_client_query(pClient, szQuery);
1671 }
1672
1673
1674 /**
1675 * Setting MIDI input type:
1676 * SET CHANNEL MIDI_INPUT_TYPE <sampler-channel> <midi-input-type>
1677 *
1678 * @param pClient Pointer to client instance structure.
1679 * @param iSamplerChannel Sampler channel number.
1680 * @param pszMidiDriver MIDI input driver type (e.g. "ALSA").
1681 *
1682 * @returns LSCP_OK on success, LSCP_FAILED otherwise.
1683 */
1684 lscp_status_t lscp_set_channel_midi_type ( lscp_client_t *pClient,
1685 int iSamplerChannel, const char *pszMidiDriver )
1686 {
1687 char szQuery[LSCP_BUFSIZ];
1688
1689 if (iSamplerChannel < 0 || pszMidiDriver == NULL)
1690 return LSCP_FAILED;
1691
1692 sprintf(szQuery, "SET CHANNEL MIDI_INPUT_TYPE %d %s\r\n",
1693 iSamplerChannel, pszMidiDriver);
1694 return lscp_client_query(pClient, szQuery);
1695 }
1696
1697
1698 /**
1699 * Setting MIDI input device:
1700 * SET CHANNEL MIDI_INPUT_DEVICE <sampler-channel> <device-id>
1701 *
1702 * @param pClient Pointer to client instance structure.
1703 * @param iSamplerChannel Sampler channel number.
1704 * @param iMidiDevice MIDI input device number identifier.
1705 *
1706 * @returns LSCP_OK on success, LSCP_FAILED otherwise.
1707 */
1708 lscp_status_t lscp_set_channel_midi_device ( lscp_client_t *pClient,
1709 int iSamplerChannel, int iMidiDevice )
1710 {
1711 char szQuery[LSCP_BUFSIZ];
1712
1713 if (iSamplerChannel < 0 || iMidiDevice < 0)
1714 return LSCP_FAILED;
1715
1716 sprintf(szQuery, "SET CHANNEL MIDI_INPUT_DEVICE %d %d\r\n",
1717 iSamplerChannel, iMidiDevice);
1718 return lscp_client_query(pClient, szQuery);
1719 }
1720
1721
1722 /**
1723 * Setting MIDI input port:
1724 * SET CHANNEL MIDI_INPUT_PORT <sampler-channel> <midi-input-port>
1725 *
1726 * @param pClient Pointer to client instance structure.
1727 * @param iSamplerChannel Sampler channel number.
1728 * @param iMidiPort MIDI input driver virtual port number.
1729 *
1730 * @returns LSCP_OK on success, LSCP_FAILED otherwise.
1731 */
1732 lscp_status_t lscp_set_channel_midi_port ( lscp_client_t *pClient,
1733 int iSamplerChannel, int iMidiPort )
1734 {
1735 char szQuery[LSCP_BUFSIZ];
1736
1737 if (iSamplerChannel < 0 || iMidiPort < 0)
1738 return LSCP_FAILED;
1739
1740 sprintf(szQuery, "SET CHANNEL MIDI_INPUT_PORT %d %d\r\n",
1741 iSamplerChannel, iMidiPort);
1742 return lscp_client_query(pClient, szQuery);
1743 }
1744
1745
1746 /**
1747 * Setting MIDI input channel:
1748 * SET CHANNEL MIDI_INPUT_CHANNEL <sampler-channel> <midi-input-chan>
1749 *
1750 * @param pClient Pointer to client instance structure.
1751 * @param iSamplerChannel Sampler channel number.
1752 * @param iMidiChannel MIDI channel address number to listen (0-15) or
1753 * @ref LSCP_MIDI_CHANNEL_ALL (16) to listen on all channels.
1754 *
1755 * @returns LSCP_OK on success, LSCP_FAILED otherwise.
1756 */
1757 lscp_status_t lscp_set_channel_midi_channel ( lscp_client_t *pClient,
1758 int iSamplerChannel, int iMidiChannel )
1759 {
1760 char szQuery[LSCP_BUFSIZ];
1761
1762 if (iSamplerChannel < 0 || iMidiChannel < 0 || iMidiChannel > 16)
1763 return LSCP_FAILED;
1764
1765 if (iMidiChannel == LSCP_MIDI_CHANNEL_ALL)
1766 sprintf(szQuery, "SET CHANNEL MIDI_INPUT_CHANNEL %d ALL\r\n",
1767 iSamplerChannel);
1768 else
1769 sprintf(szQuery, "SET CHANNEL MIDI_INPUT_CHANNEL %d %d\r\n",
1770 iSamplerChannel, iMidiChannel);
1771 return lscp_client_query(pClient, szQuery);
1772 }
1773
1774
1775 /**
1776 * Setting MIDI instrument map:
1777 * SET CHANNEL MIDI_INSTRUMENT_MAP <sampler-channel> <midi-map>
1778 *
1779 * @param pClient Pointer to client instance structure.
1780 * @param iSamplerChannel Sampler channel number.
1781 * @param iMidiMap MIDI instrument map number, or either
1782 * @ref LSCP_MIDI_MAP_NONE or
1783 * @ref LSCP_MIDI_MAP_DEFAULT .
1784 *
1785 * @returns LSCP_OK on success, LSCP_FAILED otherwise.
1786 */
1787 lscp_status_t lscp_set_channel_midi_map ( lscp_client_t *pClient,
1788 int iSamplerChannel, int iMidiMap )
1789 {
1790 char szQuery[LSCP_BUFSIZ];
1791
1792 if (iSamplerChannel < 0)
1793 return LSCP_FAILED;
1794
1795 sprintf(szQuery, "SET CHANNEL MIDI_INSTRUMENT_MAP %d ", iSamplerChannel);
1796 if (iMidiMap == LSCP_MIDI_MAP_NONE)
1797 strcat(szQuery , "NONE");
1798 else
1799 if (iMidiMap == LSCP_MIDI_MAP_DEFAULT)
1800 strcat(szQuery , "DEFAULT");
1801 else
1802 sprintf(szQuery + strlen(szQuery), "%d", iMidiMap);
1803
1804 strcat(szQuery, "\r\n");
1805
1806 return lscp_client_query(pClient, szQuery);
1807 }
1808
1809
1810 /**
1811 * Setting channel volume:
1812 * SET CHANNEL VOLUME <sampler-channel> <volume>
1813 *
1814 * @param pClient Pointer to client instance structure.
1815 * @param iSamplerChannel Sampler channel number.
1816 * @param fVolume Sampler channel volume as a positive floating point
1817 * number, where a value less than 1.0 for attenuation,
1818 * and greater than 1.0 for amplification.
1819 *
1820 * @returns LSCP_OK on success, LSCP_FAILED otherwise.
1821 */
1822 lscp_status_t lscp_set_channel_volume ( lscp_client_t *pClient,
1823 int iSamplerChannel, float fVolume )
1824 {
1825 char szQuery[LSCP_BUFSIZ];
1826 struct _locale_t locale;
1827
1828 if (iSamplerChannel < 0 || fVolume < 0.0f)
1829 return LSCP_FAILED;
1830
1831 _save_and_set_c_locale(&locale);
1832 sprintf(szQuery, "SET CHANNEL VOLUME %d %g\r\n",
1833 iSamplerChannel, fVolume);
1834 _restore_locale(&locale);
1835
1836 return lscp_client_query(pClient, szQuery);
1837 }
1838
1839
1840 /**
1841 * Muting a sampler channel:
1842 * SET CHANNEL MUTE <sampler-channel> <mute>
1843 *
1844 * @param pClient Pointer to client instance structure.
1845 * @param iSamplerChannel Sampler channel number.
1846 * @param iMute Sampler channel mute state as a boolean value,
1847 * either 1 (one) to mute the channel or 0 (zero)
1848 * to unmute the channel.
1849 *
1850 * @returns LSCP_OK on success, LSCP_FAILED otherwise.
1851 */
1852 lscp_status_t lscp_set_channel_mute ( lscp_client_t *pClient,
1853 int iSamplerChannel, int iMute )
1854 {
1855 char szQuery[LSCP_BUFSIZ];
1856
1857 if (iSamplerChannel < 0 || iMute < 0 || iMute > 1)
1858 return LSCP_FAILED;
1859
1860 sprintf(szQuery, "SET CHANNEL MUTE %d %d\r\n",
1861 iSamplerChannel, iMute);
1862 return lscp_client_query(pClient, szQuery);
1863 }
1864
1865
1866 /**
1867 * Soloing a sampler channel:
1868 * SET CHANNEL SOLO <sampler-channel> <solo>
1869 *
1870 * @param pClient Pointer to client instance structure.
1871 * @param iSamplerChannel Sampler channel number.
1872 * @param iSolo Sampler channel solo state as a boolean value,
1873 * either 1 (one) to solo the channel or 0 (zero)
1874 * to unsolo the channel.
1875 *
1876 * @returns LSCP_OK on success, LSCP_FAILED otherwise.
1877 */
1878 lscp_status_t lscp_set_channel_solo ( lscp_client_t *pClient,
1879 int iSamplerChannel, int iSolo )
1880 {
1881 char szQuery[LSCP_BUFSIZ];
1882
1883 if (iSamplerChannel < 0 || iSolo < 0 || iSolo > 1)
1884 return LSCP_FAILED;
1885
1886 sprintf(szQuery, "SET CHANNEL SOLO %d %d\r\n",
1887 iSamplerChannel, iSolo);
1888 return lscp_client_query(pClient, szQuery);
1889 }
1890
1891
1892 /**
1893 * Resetting a sampler channel:
1894 * RESET CHANNEL <sampler-channel>
1895 *
1896 * @param pClient Pointer to client instance structure.
1897 * @param iSamplerChannel Sampler channel number.
1898 *
1899 * @returns LSCP_OK on success, LSCP_FAILED otherwise.
1900 */
1901 lscp_status_t lscp_reset_channel ( lscp_client_t *pClient, int iSamplerChannel )
1902 {
1903 char szQuery[LSCP_BUFSIZ];
1904
1905 if (iSamplerChannel < 0)
1906 return LSCP_FAILED;
1907
1908 sprintf(szQuery, "RESET CHANNEL %d\r\n", iSamplerChannel);
1909 return lscp_client_query(pClient, szQuery);
1910 }
1911
1912
1913 /**
1914 * Resetting the sampler:
1915 * RESET
1916 *
1917 * @param pClient Pointer to client instance structure.
1918 *
1919 * @returns LSCP_OK on success, LSCP_FAILED otherwise.
1920 */
1921 lscp_status_t lscp_reset_sampler ( lscp_client_t *pClient )
1922 {
1923 // Do actual whole sampler reset...
1924 return lscp_client_query(pClient, "RESET\r\n");
1925 }
1926
1927
1928 /**
1929 * Getting information about the server.
1930 * GET SERVER INFO
1931 *
1932 * @param pClient Pointer to client instance structure.
1933 *
1934 * @returns A pointer to a @ref lscp_server_info_t structure, with all the
1935 * information of the current connected server, or NULL in case of failure.
1936 */
1937 lscp_server_info_t *lscp_get_server_info ( lscp_client_t *pClient )
1938 {
1939 lscp_server_info_t *pServerInfo;
1940 const char *pszResult;
1941 const char *pszSeps = ":";
1942 const char *pszCrlf = "\r\n";
1943 char *pszToken;
1944 char *pch;
1945
1946 if (pClient == NULL)
1947 return NULL;
1948
1949 // Lock this section up.
1950 lscp_mutex_lock(pClient->mutex);
1951
1952 pServerInfo = &(pClient->server_info);
1953 lscp_server_info_reset(pServerInfo);
1954
1955 if (lscp_client_call(pClient, "GET SERVER INFO\r\n", 1) == LSCP_OK) {
1956 pszResult = lscp_client_get_result(pClient);
1957 pszToken = lscp_strtok((char *) pszResult, pszSeps, &(pch));
1958 while (pszToken) {
1959 if (strcasecmp(pszToken, "DESCRIPTION") == 0) {
1960 pszToken = lscp_strtok(NULL, pszCrlf, &(pch));
1961 if (pszToken)
1962 lscp_unquote_dup(&(pServerInfo->description), &pszToken);
1963 }
1964 else if (strcasecmp(pszToken, "VERSION") == 0) {
1965 pszToken = lscp_strtok(NULL, pszCrlf, &(pch));
1966 if (pszToken)
1967 lscp_unquote_dup(&(pServerInfo->version), &pszToken);
1968 }
1969 else if (strcasecmp(pszToken, "PROTOCOL_VERSION") == 0) {
1970 pszToken = lscp_strtok(NULL, pszCrlf, &(pch));
1971 if (pszToken)
1972 lscp_unquote_dup(&(pServerInfo->protocol_version), &pszToken);
1973 }
1974 pszToken = lscp_strtok(NULL, pszSeps, &(pch));
1975 }
1976 }
1977 else pServerInfo = NULL;
1978
1979 // Unlock this section down.
1980 lscp_mutex_unlock(pClient->mutex);
1981
1982 return pServerInfo;
1983 }
1984
1985
1986 /**
1987 * Current total number of active voices:
1988 * GET TOTAL_VOICE_COUNT
1989 *
1990 * @param pClient Pointer to client instance structure.
1991 *
1992 * @returns The total number of voices currently active,
1993 * -1 in case of failure.
1994 */
1995 int lscp_get_total_voice_count ( lscp_client_t *pClient )
1996 {
1997 int iVoiceCount = -1;
1998
1999 if (pClient == NULL)
2000 return -1;
2001
2002 // Lock this section up.
2003 lscp_mutex_lock(pClient->mutex);
2004
2005 if (lscp_client_call(pClient, "GET TOTAL_VOICE_COUNT\r\n", 0) == LSCP_OK)
2006 iVoiceCount = atoi(lscp_client_get_result(pClient));
2007
2008 // Unlock this section down.
2009 lscp_mutex_unlock(pClient->mutex);
2010
2011 return iVoiceCount;
2012 }
2013
2014
2015 /**
2016 * Maximum amount of active voices:
2017 * GET TOTAL_VOICE_COUNT_MAX
2018 *
2019 * @param pClient Pointer to client instance structure.
2020 *
2021 * @returns The maximum amount of voices currently active,
2022 * -1 in case of failure.
2023 */
2024 int lscp_get_total_voice_count_max ( lscp_client_t *pClient )
2025 {
2026 int iVoiceCount = -1;
2027
2028 if (pClient == NULL)
2029 return -1;
2030
2031 // Lock this section up.
2032 lscp_mutex_lock(pClient->mutex);
2033
2034 if (lscp_client_call(pClient, "GET TOTAL_VOICE_COUNT_MAX\r\n", 0) == LSCP_OK)
2035 iVoiceCount = atoi(lscp_client_get_result(pClient));
2036
2037 // Unlock this section down.
2038 lscp_mutex_unlock(pClient->mutex);
2039
2040 return iVoiceCount;
2041 }
2042
2043
2044 /**
2045 * Get global volume attenuation:
2046 * GET VOLUME
2047 *
2048 * @param pClient Pointer to client instance structure.
2049 *
2050 * @returns The global volume as positive floating point value usually in
2051 * the range between 0.0 and 1.0; in case of failure 0.0 is returned.
2052 */
2053 float lscp_get_volume ( lscp_client_t *pClient )
2054 {
2055 float fVolume = 0.0f;
2056 struct _locale_t locale;
2057
2058 if (pClient == NULL)
2059 return 0.0f;
2060
2061 // Lock this section up.
2062 lscp_mutex_lock(pClient->mutex);
2063
2064 _save_and_set_c_locale(&locale);
2065
2066 if (lscp_client_call(pClient, "GET VOLUME\r\n", 0) == LSCP_OK)
2067 fVolume = _atof(lscp_client_get_result(pClient));
2068
2069 _restore_locale(&locale);
2070
2071 // Unlock this section down.
2072 lscp_mutex_unlock(pClient->mutex);
2073
2074 return fVolume;
2075 }
2076
2077
2078 /**
2079 * Setting global volume attenuation:
2080 * SET VOLUME <volume>
2081 *
2082 * @param pClient Pointer to client instance structure.
2083 * @param fVolume Global volume parameter as positive floating point
2084 * value usually be in the range between 0.0 and 1.0,
2085 * that is for attenuating the overall volume.
2086 *
2087 * @returns LSCP_OK on success, LSCP_FAILED otherwise.
2088 */
2089 lscp_status_t lscp_set_volume ( lscp_client_t *pClient, float fVolume )
2090 {
2091 char szQuery[LSCP_BUFSIZ];
2092 struct _locale_t locale;
2093
2094 if (fVolume < 0.0f)
2095 return LSCP_FAILED;
2096
2097 _save_and_set_c_locale(&locale);
2098 sprintf(szQuery, "SET VOLUME %g\r\n", fVolume);
2099 _restore_locale(&locale);
2100
2101 return lscp_client_query(pClient, szQuery);
2102 }
2103
2104
2105 /**
2106 * Get global voice limit setting:
2107 * @code
2108 * GET VOICES
2109 * @endcode
2110 * This value reflects the maximum amount of voices a sampler engine
2111 * processes simultaniously before voice stealing kicks in.
2112 *
2113 * @param pClient Pointer to client instance structure.
2114 *
2115 * @returns The current global maximum amount of voices limit or a
2116 * negative value on error (e.g. if sampler doesn't support
2117 * this command).
2118 */
2119 int lscp_get_voices ( lscp_client_t *pClient )
2120 {
2121 int iVoices = -1;
2122
2123 if (pClient == NULL)
2124 return -1;
2125
2126 // Lock this section up.
2127 lscp_mutex_lock(pClient->mutex);
2128
2129 if (lscp_client_call(pClient, "GET VOICES\r\n", 0) == LSCP_OK)
2130 iVoices = atoi(lscp_client_get_result(pClient));
2131
2132 // Unlock this section down.
2133 lscp_mutex_unlock(pClient->mutex);
2134
2135 return iVoices;
2136 }
2137
2138
2139 /**
2140 * Setting global voice limit setting:
2141 * @code
2142 * SET VOICES <max-voices>
2143 * @endcode
2144 * This value reflects the maximum amount of voices a sampler engine
2145 * processes simultaniously before voice stealing kicks in. Note that
2146 * this value will be passed to all sampler engine instances, that is
2147 * the total amount of maximum voices on the running system is thus
2148 * @param iMaxVoices multiplied with the current amount of sampler
2149 * engine instances.
2150 *
2151 * @param pClient Pointer to client instance structure.
2152 * @param iMaxVoices Global voice limit setting as integer value larger
2153 * or equal to 1.
2154 *
2155 * @returns LSCP_OK on success, LSCP_FAILED otherwise.
2156 */
2157 lscp_status_t lscp_set_voices ( lscp_client_t *pClient, int iMaxVoices )
2158 {
2159 char szQuery[LSCP_BUFSIZ];
2160
2161 if (iMaxVoices < 1)
2162 return LSCP_FAILED;
2163
2164 sprintf(szQuery, "SET VOICES %d\r\n", iMaxVoices);
2165 return lscp_client_query(pClient, szQuery);
2166 }
2167
2168
2169 /**
2170 * Get global disk streams limit setting:
2171 * @code
2172 * GET STREAMS
2173 * @endcode
2174 * This value reflects the maximum amount of disk streams a sampler
2175 * engine processes simultaniously.
2176 *
2177 * @param pClient Pointer to client instance structure.
2178 *
2179 * @returns The current global maximum amount of disk streams limit
2180 * or a negative value on error (e.g. if sampler doesn't
2181 * support this command).
2182 */
2183 int lscp_get_streams ( lscp_client_t *pClient )
2184 {
2185 int iStreams = -1;
2186
2187 if (pClient == NULL)
2188 return -1;
2189
2190 // Lock this section up.
2191 lscp_mutex_lock(pClient->mutex);
2192
2193 if (lscp_client_call(pClient, "GET STREAMS\r\n", 0) == LSCP_OK)
2194 iStreams = atoi(lscp_client_get_result(pClient));
2195
2196 // Unlock this section down.
2197 lscp_mutex_unlock(pClient->mutex);
2198
2199 return iStreams;
2200 }
2201
2202
2203 /**
2204 * Setting global disk streams limit setting:
2205 * @code
2206 * SET STREAMS <max-streams>
2207 * @endcode
2208 * This value reflects the maximum amount of dist streams a sampler
2209 * engine instance processes simultaniously. Note that this value will
2210 * be passed to all sampler engine instances, that is the total amount
2211 * of maximum disk streams on the running system is thus
2212 * @param iMaxStreams multiplied with the current amount of sampler
2213 * engine instances.
2214 *
2215 * @param pClient Pointer to client instance structure.
2216 * @param iMaxStreams Global streams limit setting as positive integer
2217 * value (larger or equal to 0).
2218 *
2219 * @returns LSCP_OK on success, LSCP_FAILED otherwise.
2220 */
2221 lscp_status_t lscp_set_streams ( lscp_client_t *pClient, int iMaxStreams )
2222 {
2223 char szQuery[LSCP_BUFSIZ];
2224
2225 if (iMaxStreams < 0)
2226 return LSCP_FAILED;
2227
2228 sprintf(szQuery, "SET STREAMS %d\r\n", iMaxStreams);
2229 return lscp_client_query(pClient, szQuery);
2230 }
2231
2232
2233 /**
2234 * Add an effect send to a sampler channel:
2235 * CREATE FX_SEND <sampler-channel> <midi-ctrl> [<fx-name>]
2236 *
2237 * @param pClient Pointer to client instance structure.
2238 * @param iSamplerChannel Sampler channel number.
2239 * @param iMidiController MIDI controller used to alter the effect,
2240 * usually a number between 0 and 127.
2241 * @param pszFxName Optional name for the effect send entity,
2242 * does not have to be unique.
2243 *
2244 * @returns The new effect send number identifier, or -1 in case of failure.
2245 */
2246 int lscp_create_fxsend ( lscp_client_t *pClient,
2247 int iSamplerChannel, int iMidiController, const char *pszFxName )
2248 {
2249 int iFxSend = -1;
2250 char szQuery[LSCP_BUFSIZ];
2251
2252 if (pClient == NULL)
2253 return -1;
2254 if (iSamplerChannel < 0 || iMidiController < 0 || iMidiController > 127)
2255 return -1;
2256
2257 // Lock this section up.
2258 lscp_mutex_lock(pClient->mutex);
2259
2260 sprintf(szQuery, "CREATE FX_SEND %d %d",
2261 iSamplerChannel, iMidiController);
2262
2263 if (pszFxName)
2264 sprintf(szQuery + strlen(szQuery), " '%s'", pszFxName);
2265
2266 strcat(szQuery, "\r\n");
2267
2268 if (lscp_client_call(pClient, szQuery, 0) == LSCP_OK)
2269 iFxSend = atoi(lscp_client_get_result(pClient));
2270
2271 // Unlock this section down.
2272 lscp_mutex_unlock(pClient->mutex);
2273
2274 return iFxSend;
2275 }
2276
2277
2278 /**
2279 * Remove an effect send from a sampler channel:
2280 * DESTROY FX_SEND <sampler-channel> <fx-send-id>
2281 *
2282 * @param pClient Pointer to client instance structure.
2283 * @param iSamplerChannel Sampler channel number.
2284 * @param iFxSend Effect send number.
2285 *
2286 * @returns LSCP_OK on success, LSCP_FAILED otherwise.
2287 */
2288 lscp_status_t lscp_destroy_fxsend ( lscp_client_t *pClient,
2289 int iSamplerChannel, int iFxSend )
2290 {
2291 char szQuery[LSCP_BUFSIZ];
2292
2293 if (iSamplerChannel < 0 || iFxSend < 0)
2294 return LSCP_FAILED;
2295
2296 sprintf(szQuery, "DESTROY FX_SEND %d %d\r\n",
2297 iSamplerChannel, iFxSend);
2298
2299 return lscp_client_query(pClient, szQuery);
2300 }
2301
2302
2303 /**
2304 * Get amount of effect sends on a sampler channel:
2305 * GET FX_SENDS <sampler-channel>
2306 *
2307 * @param pClient Pointer to client instance structure.
2308 * @param iSamplerChannel Sampler channel number.
2309 *
2310 * @returns The current total number of effect sends of the sampler channel
2311 * on success, -1 otherwise.
2312 */
2313 int lscp_get_fxsends ( lscp_client_t *pClient, int iSamplerChannel )
2314 {
2315 int iFxSends = -1;
2316 char szQuery[LSCP_BUFSIZ];
2317
2318 if (pClient == NULL)
2319 return -1;
2320 if (iSamplerChannel < 0)
2321 return -1;
2322
2323 // Lock this section up.
2324 lscp_mutex_lock(pClient->mutex);
2325
2326 sprintf(szQuery, "GET FX_SENDS %d\r\n", iSamplerChannel);
2327
2328 if (lscp_client_call(pClient, szQuery, 0) == LSCP_OK)
2329 iFxSends = atoi(lscp_client_get_result(pClient));
2330
2331 // Unlock this section doen.
2332 lscp_mutex_unlock(pClient->mutex);
2333
2334 return iFxSends;
2335 }
2336
2337
2338 /**
2339 * List all effect sends on a sampler channel:
2340 * LIST FX_SENDS <sampler-channel>
2341 *
2342 * @param pClient Pointer to client instance structure.
2343 * @param iSamplerChannel Sampler channel number.
2344 *
2345 * @returns An array of the effect sends identifiers as positive integers,
2346 * terminated with -1 on success, NULL otherwise.
2347 */
2348 int *lscp_list_fxsends ( lscp_client_t *pClient, int iSamplerChannel )
2349 {
2350 const char *pszSeps = ",";
2351 char szQuery[LSCP_BUFSIZ];
2352
2353 if (pClient == NULL)
2354 return NULL;
2355
2356 // Lock this section up.
2357 lscp_mutex_lock(pClient->mutex);
2358
2359 if (pClient->fxsends) {
2360 lscp_isplit_destroy(pClient->fxsends);
2361 pClient->fxsends = NULL;
2362 }
2363
2364 sprintf(szQuery, "LIST FX_SENDS %d\r\n", iSamplerChannel);
2365
2366 if (lscp_client_call(pClient, szQuery, 0) == LSCP_OK)
2367 pClient->fxsends = lscp_isplit_create(lscp_client_get_result(pClient), pszSeps);
2368
2369 // Unlock this section down.
2370 lscp_mutex_unlock(pClient->mutex);
2371
2372 return pClient->fxsends;
2373 }
2374
2375
2376 /**
2377 * Getting effect send information
2378 * GET FX_SEND INFO <sampler-channel> <fx-send-id>
2379 *
2380 * @param pClient Pointer to client instance structure.
2381 * @param iSamplerChannel Sampler channel number.
2382 * @param iFxSend Effect send number.
2383 *
2384 * @returns A pointer to a @ref lscp_fxsend_info_t structure, with the
2385 * information of the given FX send, or NULL in case of failure.
2386 */
2387 lscp_fxsend_info_t *lscp_get_fxsend_info ( lscp_client_t *pClient,
2388 int iSamplerChannel, int iFxSend )
2389 {
2390 lscp_fxsend_info_t *pFxSendInfo;
2391 char szQuery[LSCP_BUFSIZ];
2392 const char *pszResult;
2393 const char *pszSeps = ":";
2394 const char *pszCrlf = "\r\n";
2395 char *pszToken;
2396 char *pch;
2397 struct _locale_t locale;
2398
2399 if (pClient == NULL)
2400 return NULL;
2401 if (iSamplerChannel < 0 || iFxSend < 0)
2402 return NULL;
2403
2404 // Lock this section up.
2405 lscp_mutex_lock(pClient->mutex);
2406
2407 _save_and_set_c_locale(&locale);
2408
2409 pFxSendInfo = &(pClient->fxsend_info);
2410 lscp_fxsend_info_reset(pFxSendInfo);
2411
2412 sprintf(szQuery, "GET FX_SEND INFO %d %d\r\n", iSamplerChannel, iFxSend);
2413 if (lscp_client_call(pClient, szQuery, 1) == LSCP_OK) {
2414 pszResult = lscp_client_get_result(pClient);
2415 pszToken = lscp_strtok((char *) pszResult, pszSeps, &(pch));
2416 while (pszToken) {
2417 if (strcasecmp(pszToken, "NAME") == 0) {
2418 pszToken = lscp_strtok(NULL, pszCrlf, &(pch));
2419 if (pszToken)
2420 lscp_unquote_dup(&(pFxSendInfo->name), &pszToken);
2421 }
2422 else if (strcasecmp(pszToken, "MIDI_CONTROLLER") == 0) {
2423 pszToken = lscp_strtok(NULL, pszCrlf, &(pch));
2424 if (pszToken)
2425 pFxSendInfo->midi_controller = atoi(lscp_ltrim(pszToken));
2426 }
2427 else if (strcasecmp(pszToken, "AUDIO_OUTPUT_ROUTING") == 0) {
2428 pszToken = lscp_strtok(NULL, pszCrlf, &(pch));
2429 if (pszToken) {
2430 if (pFxSendInfo->audio_routing)
2431 lscp_isplit_destroy(pFxSendInfo->audio_routing);
2432 pFxSendInfo->audio_routing = lscp_isplit_create(pszToken, ",");
2433 }
2434 }
2435 else if (strcasecmp(pszToken, "LEVEL") == 0) {
2436 pszToken = lscp_strtok(NULL, pszCrlf, &(pch));
2437 if (pszToken)
2438 pFxSendInfo->level = _atof(lscp_ltrim(pszToken));
2439 }
2440 pszToken = lscp_strtok(NULL, pszSeps, &(pch));
2441 }
2442 }
2443 else pFxSendInfo = NULL;
2444
2445 _restore_locale(&locale);
2446
2447 // Unlock this section up.
2448 lscp_mutex_unlock(pClient->mutex);
2449
2450 return pFxSendInfo;
2451 }
2452
2453
2454 /**
2455 * Alter effect send's name:
2456 * @code
2457 * SET FX_SEND NAME <sampler-chan> <fx-send-id> <name>
2458 * @endcode
2459 *
2460 * @param pClient Pointer to client instance structure.
2461 * @param iSamplerChannel Sampler channel number.
2462 * @param iFxSend Effect send number.
2463 * @param pszFxName Effect send's new name.
2464 *
2465 * @returns LSCP_OK on success, LSCP_FAILED otherwise.
2466 */
2467 lscp_status_t lscp_set_fxsend_name ( lscp_client_t *pClient,
2468 int iSamplerChannel, int iFxSend, const char *pszFxName )
2469 {
2470 char szQuery[LSCP_BUFSIZ];
2471
2472 if (!pClient || iSamplerChannel < 0 || iFxSend < 0 || !pszFxName)
2473 return LSCP_FAILED;
2474
2475 snprintf(szQuery, LSCP_BUFSIZ, "SET FX_SEND NAME %d %d '%s'\r\n",
2476 iSamplerChannel, iFxSend, pszFxName);
2477 return lscp_client_query(pClient, szQuery);
2478 }
2479
2480
2481 /**
2482 * Alter effect send's audio routing:
2483 * SET FX_SEND AUDIO_OUTPUT_CHANNEL <sampler-chan> <fx-send-id>
2484 * <audio-src> <audio-dst>
2485 *
2486 * @param pClient Pointer to client instance structure.
2487 * @param iSamplerChannel Sampler channel number.
2488 * @param iFxSend Effect send number.
2489 * @param iAudioSrc Audio output device channel to be routed from.
2490 * @param iAudioDst Audio output device channel to be routed into.
2491 *
2492 * @returns LSCP_OK on success, LSCP_FAILED otherwise.
2493 */
2494 lscp_status_t lscp_set_fxsend_audio_channel ( lscp_client_t *pClient,
2495 int iSamplerChannel, int iFxSend, int iAudioSrc, int iAudioDst )
2496 {
2497 char szQuery[LSCP_BUFSIZ];
2498
2499 if (iSamplerChannel < 0 || iFxSend < 0 || iAudioSrc < 0 || iAudioDst < 0)
2500 return LSCP_FAILED;
2501
2502 sprintf(szQuery, "SET FX_SEND AUDIO_OUTPUT_CHANNEL %d %d %d %d\r\n",
2503 iSamplerChannel, iFxSend, iAudioSrc, iAudioDst);
2504 return lscp_client_query(pClient, szQuery);
2505 }
2506
2507
2508 /**
2509 * Alter effect send's MIDI controller:
2510 * SET FX_SEND MIDI_CONTROLLER <sampler-chan> <fx-send-id> <midi-ctrl>
2511 *
2512 * @param pClient Pointer to client instance structure.
2513 * @param iSamplerChannel Sampler channel number.
2514 * @param iFxSend Effect send number.
2515 * @param iMidiController MIDI controller used to alter the effect,
2516 * usually a number between 0 and 127.
2517 *
2518 * @returns LSCP_OK on success, LSCP_FAILED otherwise.
2519 */
2520 lscp_status_t lscp_set_fxsend_midi_controller ( lscp_client_t *pClient,
2521 int iSamplerChannel, int iFxSend, int iMidiController )
2522 {
2523 char szQuery[LSCP_BUFSIZ];
2524
2525 if (iSamplerChannel < 0 || iFxSend < 0 ||
2526 iMidiController < 0 || iMidiController > 127)
2527 return LSCP_FAILED;
2528
2529 sprintf(szQuery, "SET FX_SEND MIDI_CONTROLLER %d %d %d\r\n",
2530 iSamplerChannel, iFxSend, iMidiController);
2531 return lscp_client_query(pClient, szQuery);
2532 }
2533
2534
2535 /**
2536 * Alter effect send's audio level:
2537 * SET FX_SEND LEVEL <sampler-chan> <fx-send-id> <level>
2538 *
2539 * @param pClient Pointer to client instance structure.
2540 * @param iSamplerChannel Sampler channel number.
2541 * @param iFxSend Effect send number.
2542 * @param fLevel Effect send volume level.
2543 *
2544 * @returns LSCP_OK on success, LSCP_FAILED otherwise.
2545 */
2546 lscp_status_t lscp_set_fxsend_level ( lscp_client_t *pClient,
2547 int iSamplerChannel, int iFxSend, float fLevel )
2548 {
2549 char szQuery[LSCP_BUFSIZ];
2550 struct _locale_t locale;
2551
2552 if (iSamplerChannel < 0 || iFxSend < 0 || fLevel < 0.0f)
2553 return LSCP_FAILED;
2554
2555 _save_and_set_c_locale(&locale);
2556 sprintf(szQuery, "SET FX_SEND LEVEL %d %d %f\r\n",
2557 iSamplerChannel, iFxSend, fLevel);
2558 _restore_locale(&locale);
2559
2560 return lscp_client_query(pClient, szQuery);
2561 }
2562
2563
2564 /**
2565 * Create a new MIDI instrument map:
2566 * ADD MIDI_INSTRUMENT_MAP [<name>]
2567 *
2568 * @param pClient Pointer to client instance structure.
2569 * @param pszMapName MIDI instrument map name (optional)
2570 *
2571 * @returns The new MIDI instrument map number identifier,
2572 * or -1 in case of failure.
2573 */
2574 int lscp_add_midi_instrument_map ( lscp_client_t *pClient, const char *pszMapName )
2575 {
2576 int iMidiMap = -1;
2577 char szQuery[LSCP_BUFSIZ];
2578
2579 if (pClient == NULL)
2580 return -1;
2581
2582 // Lock this section up.
2583 lscp_mutex_lock(pClient->mutex);
2584
2585 strcpy(szQuery, "ADD MIDI_INSTRUMENT_MAP");
2586
2587 if (pszMapName)
2588 sprintf(szQuery + strlen(szQuery), " '%s'", pszMapName);
2589
2590 strcat(szQuery, "\r\n");
2591
2592 if (lscp_client_call(pClient, szQuery, 0) == LSCP_OK)
2593 iMidiMap = atoi(lscp_client_get_result(pClient));
2594
2595 // Unlock this section down.
2596 lscp_mutex_unlock(pClient->mutex);
2597
2598 return iMidiMap;
2599 }
2600
2601
2602 /**
2603 * Delete one particular or all MIDI instrument maps:
2604 * REMOVE MIDI_INSTRUMENT_MAP <midi-map>
2605 *
2606 * @param pClient Pointer to client instance structure.
2607 * @param iMidiMap MIDI instrument map number.
2608 *
2609 * @returns LSCP_OK on success, LSCP_FAILED otherwise.
2610 */
2611 lscp_status_t lscp_remove_midi_instrument_map ( lscp_client_t *pClient, int iMidiMap )
2612 {
2613 char szQuery[LSCP_BUFSIZ];
2614
2615 if (iMidiMap < 0)
2616 return LSCP_FAILED;
2617
2618 sprintf(szQuery, "REMOVE MIDI_INSTRUMENT_MAP %d\r\n", iMidiMap);
2619
2620 return lscp_client_query(pClient, szQuery);
2621 }
2622
2623
2624 /**
2625 * Get amount of existing MIDI instrument maps:
2626 * GET MIDI_INSTRUMENT_MAPS
2627 *
2628 * @param pClient Pointer to client instance structure.
2629 *
2630 * @returns The current total number of MIDI instrument maps
2631 * on success, -1 otherwise.
2632 */
2633 int lscp_get_midi_instrument_maps ( lscp_client_t *pClient )
2634 {
2635 int iMidiMaps = -1;
2636
2637 if (pClient == NULL)
2638 return -1;
2639
2640 // Lock this section up.
2641 lscp_mutex_lock(pClient->mutex);
2642
2643 if (lscp_client_call(pClient, "GET MIDI_INSTRUMENT_MAPS\r\n", 0) == LSCP_OK)
2644 iMidiMaps = atoi(lscp_client_get_result(pClient));
2645
2646 // Unlock this section doen.
2647 lscp_mutex_unlock(pClient->mutex);
2648
2649 return iMidiMaps;
2650 }
2651
2652
2653 /**
2654 * Getting all created MIDI instrument maps:
2655 * LIST MIDI_INSTRUMENT_MAPS
2656 *
2657 * @param pClient Pointer to client instance structure.
2658 *
2659 * @returns An array of the MIDI instrument map identifiers as positive
2660 * integers, terminated with -1 on success, NULL otherwise.
2661 */
2662 int *lscp_list_midi_instrument_maps ( lscp_client_t *pClient )
2663 {
2664 const char *pszSeps = ",";
2665
2666 if (pClient == NULL)
2667 return NULL;
2668
2669 // Lock this section up.
2670 lscp_mutex_lock(pClient->mutex);
2671
2672 if (pClient->midi_maps) {
2673 lscp_isplit_destroy(pClient->midi_maps);
2674 pClient->midi_maps = NULL;
2675 }
2676
2677 if (lscp_client_call(pClient, "LIST MIDI_INSTRUMENT_MAPS\r\n", 0) == LSCP_OK)
2678 pClient->midi_maps = lscp_isplit_create(lscp_client_get_result(pClient), pszSeps);
2679
2680 // Unlock this section down.
2681 lscp_mutex_unlock(pClient->mutex);
2682
2683 return pClient->midi_maps;
2684 }
2685
2686
2687 /**
2688 * Getting a MIDI instrument map name:
2689 * GET MIDI_INSTRUMENT_MAP INFO <midi-map>
2690 *
2691 * @param pClient Pointer to client instance structure.
2692 * @param iMidiMap MIDI instrument map number.
2693 *
2694 * @returns The MIDI instrument map name on success, NULL on failure.
2695 */
2696 const char *lscp_get_midi_instrument_map_name ( lscp_client_t *pClient, int iMidiMap )
2697 {
2698 char szQuery[LSCP_BUFSIZ];
2699 const char *pszResult;
2700 const char *pszSeps = ":";
2701 const char *pszCrlf = "\r\n";
2702 char *pszToken;
2703 char *pch;
2704
2705 if (pClient == NULL)
2706 return NULL;
2707 if (iMidiMap < 0)
2708 return NULL;
2709
2710 // Lock this section up.
2711 lscp_mutex_lock(pClient->mutex);
2712
2713 if (pClient->midi_map_name) {
2714 free(pClient->midi_map_name);
2715 pClient->midi_map_name = NULL;
2716 }
2717
2718 sprintf(szQuery, "GET MIDI_INSTRUMENT_MAP INFO %d\r\n", iMidiMap);
2719 if (lscp_client_call(pClient, szQuery, 1) == LSCP_OK) {
2720 pszResult = lscp_client_get_result(pClient);
2721 pszToken = lscp_strtok((char *) pszResult, pszSeps, &(pch));
2722 while (pszToken) {
2723 if (strcasecmp(pszToken, "NAME") == 0) {
2724 pszToken = lscp_strtok(NULL, pszCrlf, &(pch));
2725 if (pszToken)
2726 lscp_unquote_dup(&(pClient->midi_map_name), &pszToken);
2727 }
2728 pszToken = lscp_strtok(NULL, pszSeps, &(pch));
2729 }
2730 }
2731
2732 // Unlock this section down.
2733 lscp_mutex_unlock(pClient->mutex);
2734
2735 return pClient->midi_map_name;
2736 }
2737
2738
2739 /**
2740 * Renaming a MIDI instrument map:
2741 * SET MIDI_INSTRUMENT_MAP NAME <midi-map> <map-name>
2742 *
2743 * @param pClient Pointer to client instance structure.
2744 * @param iMidiMap MIDI instrument map number.
2745 * @param pszMapName MIDI instrument map name.
2746 *
2747 * @returns LSCP_OK on success, LSCP_FAILED otherwise.
2748 */
2749 lscp_status_t lscp_set_midi_instrument_map_name ( lscp_client_t *pClient, int iMidiMap, const char *pszMapName )
2750 {
2751 char szQuery[LSCP_BUFSIZ];
2752
2753 if (iMidiMap < 0)
2754 return LSCP_FAILED;
2755 if (pszMapName == NULL)
2756 return LSCP_FAILED;
2757
2758 sprintf(szQuery, "SET MIDI_INSTRUMENT_MAP NAME %d '%s'\r\n",
2759 iMidiMap, pszMapName);
2760
2761 return lscp_client_query(pClient, szQuery);
2762 }
2763
2764
2765 /**
2766 * Create or replace a MIDI instrumnet map entry:
2767 * MAP MIDI_INSTRUMENT <midi-map> <midi-bank> <midi-prog>
2768 * <engine-name> <filename> <instr-index> <volume> [<load-mode> [<name>]}
2769 *
2770 * @param pClient Pointer to client instance structure.
2771 * @param pMidiInstr MIDI instrument bank and program parameter key.
2772 * @param pszEngineName Engine name.
2773 * @param pszFileName Instrument file name.
2774 * @param iInstrIndex Instrument index number.
2775 * @param fVolume Reflects the master volume of the instrument as
2776 * a positive floating point number, where a value
2777 * less than 1.0 for attenuation, and greater than
2778 * 1.0 for amplification.
2779 * @param load_mode Instrument load life-time strategy, either
2780 * @ref LSCP_LOAD_DEFAULT, or
2781 * @ref LSCP_LOAD_ON_DEMAND, or
2782 * @ref LSCP_LOAD_ON_DEMAND_HOLD, or
2783 * @ref LSCP_LOAD_PERSISTENT.
2784 * @param pszName Instrument custom name for the map entry (optional).
2785 *
2786 * @returns LSCP_OK on success, LSCP_FAILED otherwise.
2787 */
2788 lscp_status_t lscp_map_midi_instrument ( lscp_client_t *pClient,
2789 lscp_midi_instrument_t *pMidiInstr, const char *pszEngineName,
2790 const char *pszFileName, int iInstrIndex, float fVolume,
2791 lscp_load_mode_t load_mode, const char *pszName )
2792 {
2793 char szQuery[LSCP_BUFSIZ];
2794 struct _locale_t locale;
2795
2796 if (pMidiInstr->map < 0)
2797 return LSCP_FAILED;
2798 if (pMidiInstr->bank < 0 || pMidiInstr->bank > 16383)
2799 return LSCP_FAILED;
2800 if (pMidiInstr->prog < 0 || pMidiInstr->prog > 127)
2801 return LSCP_FAILED;
2802 if (pszEngineName == NULL || pszFileName == NULL)
2803 return LSCP_FAILED;
2804
2805 if (fVolume < 0.0f)
2806 fVolume = 1.0f;
2807
2808 _save_and_set_c_locale(&locale);
2809 sprintf(szQuery, "MAP MIDI_INSTRUMENT %d %d %d %s '%s' %d %g",
2810 pMidiInstr->map, pMidiInstr->bank, pMidiInstr->prog,
2811 pszEngineName, pszFileName, iInstrIndex, fVolume);
2812 _restore_locale(&locale);
2813
2814 switch (load_mode) {
2815 case LSCP_LOAD_PERSISTENT:
2816 strcat(szQuery, " PERSISTENT");
2817 break;
2818 case LSCP_LOAD_ON_DEMAND_HOLD:
2819 strcat(szQuery, " ON_DEMAND_HOLD");
2820 break;
2821 case LSCP_LOAD_ON_DEMAND:
2822 strcat(szQuery, " ON_DEMAND");
2823 break;
2824 case LSCP_LOAD_DEFAULT:
2825 default:
2826 break;
2827 }
2828
2829 if (pszName)
2830 sprintf(szQuery + strlen(szQuery), " '%s'", pszName);
2831
2832 strcat(szQuery, "\r\n");
2833
2834 return lscp_client_query(pClient, szQuery);
2835 }
2836
2837
2838 /**
2839 * Remove an entry from the MIDI instrument map:
2840 * UNMAP MIDI_INSTRUMENT <midi-map> <midi-bank> <midi-prog>
2841 *
2842 * @param pClient Pointer to client instance structure.
2843 * @param pMidiInstr MIDI instrument bank and program parameter key.
2844 *
2845 * @returns LSCP_OK on success, LSCP_FAILED otherwise.
2846 */
2847 lscp_status_t lscp_unmap_midi_instrument ( lscp_client_t *pClient,
2848 lscp_midi_instrument_t *pMidiInstr )
2849 {
2850 char szQuery[LSCP_BUFSIZ];
2851
2852 if (pMidiInstr->map < 0)
2853 return LSCP_FAILED;
2854 if (pMidiInstr->bank < 0 || pMidiInstr->bank > 16383)
2855 return LSCP_FAILED;
2856 if (pMidiInstr->prog < 0 || pMidiInstr->prog > 127)
2857 return LSCP_FAILED;
2858
2859 sprintf(szQuery, "UNMAP MIDI_INSTRUMENT %d %d %d\r\n",
2860 pMidiInstr->map, pMidiInstr->bank, pMidiInstr->prog);
2861
2862 return lscp_client_query(pClient, szQuery);
2863 }
2864
2865
2866 /**
2867 * Get the total count of MIDI instrument map entries:
2868 * GET MIDI_INSTRUMENTS ALL|<midi-map>
2869 *
2870 * @param pClient Pointer to client instance structure.
2871 * @param iMidiMap MIDI instrument map number, or @ref LSCP_MIDI_MAP_ALL .
2872 *
2873 * @returns The current total number of MIDI instrument map entries
2874 * on success, -1 otherwise.
2875 */
2876 int lscp_get_midi_instruments ( lscp_client_t *pClient, int iMidiMap )
2877 {
2878 int iInstruments = -1;
2879 char szQuery[LSCP_BUFSIZ];
2880
2881 if (pClient == NULL)
2882 return -1;
2883
2884 // Lock this section up.
2885 lscp_mutex_lock(pClient->mutex);
2886
2887 strcpy(szQuery, "GET MIDI_INSTRUMENTS ");
2888
2889 if (iMidiMap < 0)
2890 strcat(szQuery, "ALL");
2891 else
2892 sprintf(szQuery + strlen(szQuery), "%d", iMidiMap);
2893
2894 strcat(szQuery, "\r\n");
2895
2896 if (lscp_client_call(pClient, szQuery, 0) == LSCP_OK)
2897 iInstruments = atoi(lscp_client_get_result(pClient));
2898
2899 // Unlock this section down.
2900 lscp_mutex_unlock(pClient->mutex);
2901
2902 return iInstruments;
2903 }
2904
2905
2906 /**
2907 * Getting indeces of all MIDI instrument map entries:
2908 * LIST MIDI_INSTRUMENTS ALL|<midi-map>
2909 *
2910 * @param pClient Pointer to client instance structure.
2911 * @param iMidiMap MIDI instrument map number, or @ref LSCP_MIDI_MAP_ALL .
2912 *
2913 * @returns An array of @ref lscp_midi_instrument_t, terminated with the
2914 * {-1,-1,-1} triplet, NULL otherwise.
2915 */
2916 lscp_midi_instrument_t *lscp_list_midi_instruments ( lscp_client_t *pClient, int iMidiMap )
2917 {
2918 char szQuery[LSCP_BUFSIZ];
2919
2920 if (pClient == NULL)
2921 return NULL;
2922
2923 // Lock this section up.
2924 lscp_mutex_lock(pClient->mutex);
2925
2926 if (pClient->midi_instruments) {
2927 lscp_midi_instruments_destroy(pClient->midi_instruments);
2928 pClient->midi_instruments = NULL;
2929 }
2930
2931 strcpy(szQuery, "LIST MIDI_INSTRUMENTS ");
2932
2933 if (iMidiMap < 0)
2934 strcat(szQuery, "ALL");
2935 else
2936 sprintf(szQuery + strlen(szQuery), "%d", iMidiMap);
2937
2938 strcat(szQuery, "\r\n");
2939
2940 if (lscp_client_call(pClient, szQuery, 0) == LSCP_OK)
2941 pClient->midi_instruments = lscp_midi_instruments_create(
2942 lscp_client_get_result(pClient));
2943
2944 // Unlock this section down.
2945 lscp_mutex_unlock(pClient->mutex);
2946
2947 return pClient->midi_instruments;
2948 }
2949
2950
2951 /**
2952 * Getting information about a MIDI instrument map entry:
2953 * GET MIDI_INSTRUMENT INFO <midi-map> <midi-bank> <midi-prog>
2954 *
2955 * @param pClient Pointer to client instance structure.
2956 * @param pMidiInstr MIDI instrument bank and program parameter key.
2957 *
2958 * @returns A pointer to a @ref lscp_midi_instrument_info_t structure,
2959 * with all the information of the given MIDI instrument map entry,
2960 * or NULL in case of failure.
2961 */
2962 lscp_midi_instrument_info_t *lscp_get_midi_instrument_info ( lscp_client_t *pClient,
2963 lscp_midi_instrument_t *pMidiInstr )
2964 {
2965 lscp_midi_instrument_info_t *pInstrInfo;
2966 char szQuery[LSCP_BUFSIZ];
2967 const char *pszResult;
2968 const char *pszSeps = ":";
2969 const char *pszCrlf = "\r\n";
2970 char *pszToken;
2971 char *pch;
2972 struct _locale_t locale;
2973
2974 if (pClient == NULL)
2975 return NULL;
2976 if (pMidiInstr->map < 0)
2977 return NULL;
2978 if (pMidiInstr->bank < 0 || pMidiInstr->bank > 16383)
2979 return NULL;
2980 if (pMidiInstr->prog < 0 || pMidiInstr->prog > 127)
2981 return NULL;
2982
2983 // Lock this section up.
2984 lscp_mutex_lock(pClient->mutex);
2985
2986 _save_and_set_c_locale(&locale);
2987
2988 pInstrInfo = &(pClient->midi_instrument_info);
2989 lscp_midi_instrument_info_reset(pInstrInfo);
2990
2991 sprintf(szQuery, "GET MIDI_INSTRUMENT INFO %d %d %d\r\n",
2992 pMidiInstr->map, pMidiInstr->bank, pMidiInstr->prog);
2993 if (lscp_client_call(pClient, szQuery, 1) == LSCP_OK) {
2994 pszResult = lscp_client_get_result(pClient);
2995 pszToken = lscp_strtok((char *) pszResult, pszSeps, &(pch));
2996 while (pszToken) {
2997 if (strcasecmp(pszToken, "NAME") == 0) {
2998 pszToken = lscp_strtok(NULL, pszCrlf, &(pch));
2999 if (pszToken)
3000 lscp_unquote_dup(&(pInstrInfo->name), &pszToken);
3001 }
3002 else if (strcasecmp(pszToken, "ENGINE_NAME") == 0) {
3003 pszToken = lscp_strtok(NULL, pszCrlf, &(pch));
3004 if (pszToken)
3005 lscp_unquote_dup(&(pInstrInfo->engine_name), &pszToken);
3006 }
3007 else if (strcasecmp(pszToken, "INSTRUMENT_FILE") == 0) {
3008 pszToken = lscp_strtok(NULL, pszCrlf, &(pch));
3009 if (pszToken)
3010 lscp_unquote_dup(&(pInstrInfo->instrument_file), &pszToken);
3011 }
3012 else if (strcasecmp(pszToken, "INSTRUMENT_NR") == 0) {
3013 pszToken = lscp_strtok(NULL, pszCrlf, &(pch));
3014 if (pszToken)
3015 pInstrInfo->instrument_nr = atoi(lscp_ltrim(pszToken));
3016 }
3017 else if (strcasecmp(pszToken, "INSTRUMENT_NAME") == 0) {
3018 pszToken = lscp_strtok(NULL, pszCrlf, &(pch));
3019 if (pszToken)
3020 lscp_unquote_dup(&(pInstrInfo->instrument_name), &pszToken);
3021 }
3022 else if (strcasecmp(pszToken, "LOAD_MODE") == 0) {
3023 pszToken = lscp_strtok(NULL, pszCrlf, &(pch));
3024 if (pszToken) {
3025 pszToken = lscp_ltrim(pszToken);
3026 if (strcasecmp(pszToken, "ON_DEMAND") == 0)
3027 pInstrInfo->load_mode = LSCP_LOAD_ON_DEMAND;
3028 else
3029 if (strcasecmp(pszToken, "ON_DEMAND_HOLD") == 0)
3030 pInstrInfo->load_mode = LSCP_LOAD_ON_DEMAND_HOLD;
3031 else
3032 if (strcasecmp(pszToken, "PERSISTENT") == 0)
3033 pInstrInfo->load_mode = LSCP_LOAD_PERSISTENT;
3034 else
3035 pInstrInfo->load_mode = LSCP_LOAD_DEFAULT;
3036 }
3037 }
3038 else if (strcasecmp(pszToken, "VOLUME") == 0) {
3039 pszToken = lscp_strtok(NULL, pszCrlf, &(pch));
3040 if (pszToken)
3041 pInstrInfo->volume = _atof(lscp_ltrim(pszToken));
3042 }
3043 pszToken = lscp_strtok(NULL, pszSeps, &(pch));
3044 }
3045 }
3046 else pInstrInfo = NULL;
3047
3048 _restore_locale(&locale);
3049
3050 // Unlock this section down.
3051 lscp_mutex_unlock(pClient->mutex);
3052
3053 return pInstrInfo;
3054 }
3055
3056
3057 /**
3058 * Clear the MIDI instrumnet map:
3059 * CLEAR MIDI_INSTRUMENTS ALL|<midi-map>
3060 *
3061 * @param pClient Pointer to client instance structure.
3062 * @param iMidiMap MIDI instrument map number, or @ref LSCP_MIDI_MAP_ALL .
3063 *
3064 * @returns LSCP_OK on success, LSCP_FAILED otherwise.
3065 */
3066 lscp_status_t lscp_clear_midi_instruments ( lscp_client_t *pClient, int iMidiMap )
3067 {
3068 char szQuery[LSCP_BUFSIZ];
3069
3070 strcpy(szQuery, "CLEAR MIDI_INSTRUMENTS ");
3071
3072 if (iMidiMap < 0)
3073 strcat(szQuery, "ALL");
3074 else
3075 sprintf(szQuery + strlen(szQuery), "%d", iMidiMap);
3076
3077 strcat(szQuery, "\r\n");
3078
3079 return lscp_client_query(pClient, szQuery);
3080 }
3081
3082
3083 /**
3084 * Open an instrument editor application for the instrument
3085 * on the given sampler channel:
3086 * EDIT CHANNEL INSTRUMENT <sampler-channel>
3087 *
3088 * @param pClient Pointer to client instance structure.
3089 * @param iSamplerChannel Sampler Channel.
3090 *
3091 * @returns LSCP_OK on success, LSCP_FAILED otherwise.
3092 */
3093 lscp_status_t lscp_edit_channel_instrument ( lscp_client_t *pClient, int iSamplerChannel )
3094 {
3095 char szQuery[LSCP_BUFSIZ];
3096
3097 if (iSamplerChannel < 0)
3098 return LSCP_FAILED;
3099
3100 sprintf(szQuery, "EDIT CHANNEL INSTRUMENT %d\r\n", iSamplerChannel);
3101
3102 return lscp_client_query(pClient, szQuery);
3103 }
3104
3105
3106 // end of client.c

  ViewVC Help
Powered by ViewVC