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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 3665 - (show annotations) (download)
Sun Dec 22 13:01:23 2019 UTC (16 months, 3 weeks ago) by schoenebeck
File MIME type: text/plain
File size: 90679 byte(s)
- Fixed compile errors on Windows.

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

  ViewVC Help
Powered by ViewVC