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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1806 - (show annotations) (download)
Thu Dec 11 01:28:42 2008 UTC (15 years, 4 months ago) by schoenebeck
File MIME type: text/plain
File size: 88006 byte(s)
* fixed locale related parser bug (fixes #59)
* bumped version to 0.5.5.10

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

  ViewVC Help
Powered by ViewVC