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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1692 - (show annotations) (download)
Fri Feb 15 17:04:34 2008 UTC (13 years, 2 months ago) by schoenebeck
File MIME type: text/plain
File size: 82351 byte(s)
* bugfix: _lscp_client_evt_proc() dropped LSCP events

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

  ViewVC Help
Powered by ViewVC