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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1802 - (show annotations) (download)
Sun Dec 7 13:50:08 2008 UTC (11 years, 3 months ago) by schoenebeck
File MIME type: text/plain
File size: 86278 byte(s)
* added new client interface functions, for managing the global limit of
  maximum voices and disk streams: lscp_get_voices(), lscp_set_voices(),
  lscp_get_streams(), lscp_set_streams()
* bumped version to 0.5.5.9

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 by the sampler backend.
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 LSCP event 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 lscp_event_t currentEvent;
615
616 if (pClient == NULL)
617 return LSCP_FAILED;
618
619 // Lock this section up.
620 lscp_mutex_lock(pClient->mutex);
621
622 // If applicable, start the alternate connection...
623 if (pClient->events == LSCP_EVENT_NONE)
624 ret = _lscp_client_evt_connect(pClient);
625
626 // Send the subscription commands.
627 if (ret == LSCP_OK && (events & LSCP_EVENT_CHANNEL_COUNT))
628 ret = _lscp_client_evt_request(pClient, 1, LSCP_EVENT_CHANNEL_COUNT);
629 if (ret == LSCP_OK && (events & LSCP_EVENT_VOICE_COUNT))
630 ret = _lscp_client_evt_request(pClient, 1, LSCP_EVENT_VOICE_COUNT);
631 if (ret == LSCP_OK && (events & LSCP_EVENT_STREAM_COUNT))
632 ret = _lscp_client_evt_request(pClient, 1, LSCP_EVENT_STREAM_COUNT);
633 if (ret == LSCP_OK && (events & LSCP_EVENT_BUFFER_FILL))
634 ret = _lscp_client_evt_request(pClient, 1, LSCP_EVENT_BUFFER_FILL);
635 if (ret == LSCP_OK && (events & LSCP_EVENT_CHANNEL_INFO))
636 ret = _lscp_client_evt_request(pClient, 1, LSCP_EVENT_CHANNEL_INFO);
637 if (ret == LSCP_OK && (events & LSCP_EVENT_TOTAL_VOICE_COUNT))
638 ret = _lscp_client_evt_request(pClient, 1, LSCP_EVENT_TOTAL_VOICE_COUNT);
639 if (ret == LSCP_OK && (events & LSCP_EVENT_AUDIO_OUTPUT_DEVICE_COUNT))
640 ret = _lscp_client_evt_request(pClient, 1, LSCP_EVENT_AUDIO_OUTPUT_DEVICE_COUNT);
641 if (ret == LSCP_OK && (events & LSCP_EVENT_AUDIO_OUTPUT_DEVICE_INFO))
642 ret = _lscp_client_evt_request(pClient, 1, LSCP_EVENT_AUDIO_OUTPUT_DEVICE_INFO);
643 if (ret == LSCP_OK && (events & LSCP_EVENT_MIDI_INPUT_DEVICE_COUNT))
644 ret = _lscp_client_evt_request(pClient, 1, LSCP_EVENT_MIDI_INPUT_DEVICE_COUNT);
645 if (ret == LSCP_OK && (events & LSCP_EVENT_MIDI_INPUT_DEVICE_INFO))
646 ret = _lscp_client_evt_request(pClient, 1, LSCP_EVENT_MIDI_INPUT_DEVICE_INFO);
647 if (ret == LSCP_OK && (events & LSCP_EVENT_MIDI_INSTRUMENT_MAP_COUNT))
648 ret = _lscp_client_evt_request(pClient, 1, LSCP_EVENT_MIDI_INSTRUMENT_MAP_COUNT);
649 if (ret == LSCP_OK && (events & LSCP_EVENT_MIDI_INSTRUMENT_MAP_INFO))
650 ret = _lscp_client_evt_request(pClient, 1, LSCP_EVENT_MIDI_INSTRUMENT_MAP_INFO);
651 if (ret == LSCP_OK && (events & LSCP_EVENT_MIDI_INSTRUMENT_COUNT))
652 ret = _lscp_client_evt_request(pClient, 1, LSCP_EVENT_MIDI_INSTRUMENT_COUNT);
653 if (ret == LSCP_OK && (events & LSCP_EVENT_MIDI_INSTRUMENT_INFO))
654 ret = _lscp_client_evt_request(pClient, 1, LSCP_EVENT_MIDI_INSTRUMENT_INFO);
655 if (ret == LSCP_OK && (events & LSCP_EVENT_MISCELLANEOUS))
656 ret = _lscp_client_evt_request(pClient, 1, LSCP_EVENT_MISCELLANEOUS);
657 // Caution: for the upper 16 bits, we don't use bit flags anymore ...
658 currentEvent = events & 0xffff0000;
659 if (ret == LSCP_OK && currentEvent) {
660 switch (currentEvent) {
661 case LSCP_EVENT_CHANNEL_MIDI:
662 case LSCP_EVENT_DEVICE_MIDI:
663 ret = _lscp_client_evt_request(pClient, 1, currentEvent);
664 break;
665 default: // unknown "upper" event type
666 ret = LSCP_FAILED;
667 break;
668 }
669 }
670
671 // Unlock this section down.
672 lscp_mutex_unlock(pClient->mutex);
673
674 return ret;
675 }
676
677
678 /**
679 * Deregister frontend from receiving UDP event messages anymore.
680 * @e Caution: since liblscp v0.5.5.4 you have to call
681 * lscp_client_unsubscribe() for @e each event you want to unsubscribe.
682 * That is the old bitflag approach was abondoned at this point. You can
683 * however still register all older events with one lscp_client_subscribe()
684 * call at once. Thus, the old behavior of this functions was not broken.
685 * Those older events are namely:
686 * @code
687 * UNSUBSCRIBE CHANNEL_COUNT | VOICE_COUNT | STREAM_COUNT
688 * | BUFFER_FILL | CHANNEL_INFO | TOTAL_VOICE_COUNT
689 * | AUDIO_OUTPUT_DEVICE_COUNT | AUDIO_OUTPUT_DEVICE_INFO
690 * | MIDI_INPUT_DEVICE_COUNT | MIDI_INPUT_DEVICE_INFO
691 * | MIDI_INSTRUMENT_MAP_COUNT | MIDI_INSTRUMENT_MAP_INFO
692 * | MIDI_INSTRUMENT_COUNT | MIDI_INSTRUMENT_INFO
693 * | MISCELLANEOUS
694 * @endcode
695 * The old events occupy the lower 16 bits (as bit flags), and all younger
696 * events enumerate the whole upper 16 bits range. The new, enumerated
697 * events are namely:
698 * @code
699 * UNSUBSCRIBE CHANNEL_MIDI
700 * @endcode
701 *
702 * @param pClient Pointer to client instance structure.
703 * @param events LSCP event to unsubscribe.
704 *
705 * @returns LSCP_OK on success, LSCP_FAILED otherwise.
706 */
707 lscp_status_t lscp_client_unsubscribe ( lscp_client_t *pClient, lscp_event_t events )
708 {
709 lscp_status_t ret = LSCP_OK;
710 lscp_event_t currentEvent;
711
712 if (pClient == NULL)
713 return LSCP_FAILED;
714
715 // Lock this section up.
716 lscp_mutex_lock(pClient->mutex);
717
718 // Send the unsubscription commands.
719 if (ret == LSCP_OK && (events & LSCP_EVENT_CHANNEL_COUNT))
720 ret = _lscp_client_evt_request(pClient, 0, LSCP_EVENT_CHANNEL_COUNT);
721 if (ret == LSCP_OK && (events & LSCP_EVENT_VOICE_COUNT))
722 ret = _lscp_client_evt_request(pClient, 0, LSCP_EVENT_VOICE_COUNT);
723 if (ret == LSCP_OK && (events & LSCP_EVENT_STREAM_COUNT))
724 ret = _lscp_client_evt_request(pClient, 0, LSCP_EVENT_STREAM_COUNT);
725 if (ret == LSCP_OK && (events & LSCP_EVENT_BUFFER_FILL))
726 ret = _lscp_client_evt_request(pClient, 0, LSCP_EVENT_BUFFER_FILL);
727 if (ret == LSCP_OK && (events & LSCP_EVENT_CHANNEL_INFO))
728 ret = _lscp_client_evt_request(pClient, 0, LSCP_EVENT_CHANNEL_INFO);
729 if (ret == LSCP_OK && (events & LSCP_EVENT_TOTAL_VOICE_COUNT))
730 ret = _lscp_client_evt_request(pClient, 0, LSCP_EVENT_TOTAL_VOICE_COUNT);
731 if (ret == LSCP_OK && (events & LSCP_EVENT_AUDIO_OUTPUT_DEVICE_COUNT))
732 ret = _lscp_client_evt_request(pClient, 0, LSCP_EVENT_AUDIO_OUTPUT_DEVICE_COUNT);
733 if (ret == LSCP_OK && (events & LSCP_EVENT_AUDIO_OUTPUT_DEVICE_INFO))
734 ret = _lscp_client_evt_request(pClient, 0, LSCP_EVENT_AUDIO_OUTPUT_DEVICE_INFO);
735 if (ret == LSCP_OK && (events & LSCP_EVENT_MIDI_INPUT_DEVICE_COUNT))
736 ret = _lscp_client_evt_request(pClient, 0, LSCP_EVENT_MIDI_INPUT_DEVICE_COUNT);
737 if (ret == LSCP_OK && (events & LSCP_EVENT_MIDI_INPUT_DEVICE_INFO))
738 ret = _lscp_client_evt_request(pClient, 0, LSCP_EVENT_MIDI_INPUT_DEVICE_INFO);
739 if (ret == LSCP_OK && (events & LSCP_EVENT_MIDI_INSTRUMENT_MAP_COUNT))
740 ret = _lscp_client_evt_request(pClient, 0, LSCP_EVENT_MIDI_INSTRUMENT_MAP_COUNT);
741 if (ret == LSCP_OK && (events & LSCP_EVENT_MIDI_INSTRUMENT_MAP_INFO))
742 ret = _lscp_client_evt_request(pClient, 0, LSCP_EVENT_MIDI_INSTRUMENT_MAP_INFO);
743 if (ret == LSCP_OK && (events & LSCP_EVENT_MIDI_INSTRUMENT_COUNT))
744 ret = _lscp_client_evt_request(pClient, 0, LSCP_EVENT_MIDI_INSTRUMENT_COUNT);
745 if (ret == LSCP_OK && (events & LSCP_EVENT_MIDI_INSTRUMENT_INFO))
746 ret = _lscp_client_evt_request(pClient, 0, LSCP_EVENT_MIDI_INSTRUMENT_INFO);
747 if (ret == LSCP_OK && (events & LSCP_EVENT_MISCELLANEOUS))
748 ret = _lscp_client_evt_request(pClient, 0, LSCP_EVENT_MISCELLANEOUS);
749 // Caution: for the upper 16 bits, we don't use bit flags anymore ...
750 currentEvent = events & 0xffff0000;
751 if (ret == LSCP_OK && currentEvent) {
752 switch (currentEvent) {
753 case LSCP_EVENT_CHANNEL_MIDI:
754 case LSCP_EVENT_DEVICE_MIDI:
755 ret = _lscp_client_evt_request(pClient, 0, currentEvent);
756 break;
757 default: // unknown "upper" event type
758 ret = LSCP_FAILED;
759 break;
760 }
761 }
762
763 // If necessary, close the alternate connection...
764 if (pClient->events == LSCP_EVENT_NONE)
765 lscp_socket_agent_free(&(pClient->evt));
766
767 // Unlock this section down.
768 lscp_mutex_unlock(pClient->mutex);
769
770 return ret;
771 }
772
773
774 /**
775 * Getting current subscribed events.
776 *
777 * @param pClient Pointer to client instance structure.
778 *
779 * @returns The current subscrived bit-wise OR'ed event flags.
780 */
781 lscp_event_t lscp_client_get_events ( lscp_client_t *pClient )
782 {
783 if (pClient == NULL)
784 return LSCP_EVENT_NONE;
785
786 return pClient->events;
787 }
788
789
790 //-------------------------------------------------------------------------
791 // Client command protocol functions.
792
793 /**
794 * Loading an instrument:
795 * LOAD INSTRUMENT <filename> <instr-index> <sampler-channel>
796 *
797 * @param pClient Pointer to client instance structure.
798 * @param pszFileName Instrument file name.
799 * @param iInstrIndex Instrument index number.
800 * @param iSamplerChannel Sampler Channel.
801 *
802 * @returns LSCP_OK on success, LSCP_FAILED otherwise.
803 */
804 lscp_status_t lscp_load_instrument ( lscp_client_t *pClient, const char *pszFileName, int iInstrIndex, int iSamplerChannel )
805 {
806 char szQuery[LSCP_BUFSIZ];
807
808 if (pszFileName == NULL || iSamplerChannel < 0)
809 return LSCP_FAILED;
810
811 sprintf(szQuery, "LOAD INSTRUMENT '%s' %d %d\r\n", pszFileName, iInstrIndex, iSamplerChannel);
812 return lscp_client_query(pClient, szQuery);
813 }
814
815
816 /**
817 * Loading an instrument in the background (non modal):
818 * LOAD INSTRUMENT NON_MODAL <filename> <instr-index> <sampler-channel>
819 *
820 * @param pClient Pointer to client instance structure.
821 * @param pszFileName Instrument file name.
822 * @param iInstrIndex Instrument index number.
823 * @param iSamplerChannel Sampler Channel.
824 *
825 * @returns LSCP_OK on success, LSCP_FAILED otherwise.
826 */
827 lscp_status_t lscp_load_instrument_non_modal ( lscp_client_t *pClient, const char *pszFileName, int iInstrIndex, int iSamplerChannel )
828 {
829 char szQuery[LSCP_BUFSIZ];
830
831 if (pszFileName == NULL || iSamplerChannel < 0)
832 return LSCP_FAILED;
833
834 sprintf(szQuery, "LOAD INSTRUMENT NON_MODAL '%s' %d %d\r\n", pszFileName, iInstrIndex, iSamplerChannel);
835 return lscp_client_query(pClient, szQuery);
836 }
837
838
839 /**
840 * Loading a sampler engine:
841 * LOAD ENGINE <engine-name> <sampler-channel>
842 *
843 * @param pClient Pointer to client instance structure.
844 * @param pszEngineName Engine name.
845 * @param iSamplerChannel Sampler channel number.
846 *
847 * @returns LSCP_OK on success, LSCP_FAILED otherwise.
848 */
849 lscp_status_t lscp_load_engine ( lscp_client_t *pClient, const char *pszEngineName, int iSamplerChannel )
850 {
851 char szQuery[LSCP_BUFSIZ];
852
853 if (pszEngineName == NULL || iSamplerChannel < 0)
854 return LSCP_FAILED;
855
856 sprintf(szQuery, "LOAD ENGINE %s %d\r\n", pszEngineName, iSamplerChannel);
857 return lscp_client_query(pClient, szQuery);
858 }
859
860
861 /**
862 * Current number of sampler channels:
863 * GET CHANNELS
864 *
865 * @param pClient Pointer to client instance structure.
866 *
867 * @returns The current total number of sampler channels on success,
868 * -1 otherwise.
869 */
870 int lscp_get_channels ( lscp_client_t *pClient )
871 {
872 int iChannels = -1;
873
874 if (pClient == NULL)
875 return -1;
876
877 // Lock this section up.
878 lscp_mutex_lock(pClient->mutex);
879
880 if (lscp_client_call(pClient, "GET CHANNELS\r\n", 0) == LSCP_OK)
881 iChannels = atoi(lscp_client_get_result(pClient));
882
883 // Unlock this section doen.
884 lscp_mutex_unlock(pClient->mutex);
885
886 return iChannels;
887 }
888
889
890 /**
891 * List current sampler channels number identifiers:
892 * LIST CHANNELS
893 *
894 * @param pClient Pointer to client instance structure.
895 *
896 * @returns An array of the sampler channels identifiers as positive integers,
897 * terminated with -1 on success, NULL otherwise.
898 */
899 int *lscp_list_channels ( lscp_client_t *pClient )
900 {
901 const char *pszSeps = ",";
902
903 if (pClient == NULL)
904 return NULL;
905
906 // Lock this section up.
907 lscp_mutex_lock(pClient->mutex);
908
909 if (pClient->channels) {
910 lscp_isplit_destroy(pClient->channels);
911 pClient->channels = NULL;
912 }
913
914 if (lscp_client_call(pClient, "LIST CHANNELS\r\n", 0) == LSCP_OK)
915 pClient->channels = lscp_isplit_create(lscp_client_get_result(pClient), pszSeps);
916
917 // Unlock this section down.
918 lscp_mutex_unlock(pClient->mutex);
919
920 return pClient->channels;
921 }
922
923
924 /**
925 * Adding a new sampler channel:
926 * ADD CHANNEL
927 *
928 * @param pClient Pointer to client instance structure.
929 *
930 * @returns The new sampler channel number identifier,
931 * or -1 in case of failure.
932 */
933 int lscp_add_channel ( lscp_client_t *pClient )
934 {
935 int iSamplerChannel = -1;
936
937 if (pClient == NULL)
938 return -1;
939
940 // Lock this section up.
941 lscp_mutex_lock(pClient->mutex);
942
943 if (lscp_client_call(pClient, "ADD CHANNEL\r\n", 0) == LSCP_OK)
944 iSamplerChannel = atoi(lscp_client_get_result(pClient));
945
946 // Unlock this section down.
947 lscp_mutex_unlock(pClient->mutex);
948
949 return iSamplerChannel;
950 }
951
952
953 /**
954 * Removing a sampler channel:
955 * REMOVE CHANNEL <sampler-channel>
956 *
957 * @param pClient Pointer to client instance structure.
958 * @param iSamplerChannel Sampler channel number.
959 *
960 * @returns LSCP_OK on success, LSCP_FAILED otherwise.
961 */
962 lscp_status_t lscp_remove_channel ( lscp_client_t *pClient, int iSamplerChannel )
963 {
964 char szQuery[LSCP_BUFSIZ];
965
966 if (iSamplerChannel < 0)
967 return LSCP_FAILED;
968
969 sprintf(szQuery, "REMOVE CHANNEL %d\r\n", iSamplerChannel);
970 return lscp_client_query(pClient, szQuery);
971 }
972
973
974 /**
975 * Getting all available engines count:
976 * GET AVAILABLE_ENGINES
977 *
978 * @param pClient Pointer to client instance structure.
979 *
980 * @returns The current total number of sampler engines on success,
981 * -1 otherwise.
982 */
983 int lscp_get_available_engines ( lscp_client_t *pClient )
984 {
985 int iAvailableEngines = -1;
986
987 if (pClient == NULL)
988 return -1;
989
990 // Lock this section up.
991 lscp_mutex_lock(pClient->mutex);
992
993 if (lscp_client_call(pClient, "GET AVAILABLE_ENGINES\r\n", 0) == LSCP_OK)
994 iAvailableEngines = atoi(lscp_client_get_result(pClient));
995
996 // Unlock this section down.
997 lscp_mutex_unlock(pClient->mutex);
998
999 return iAvailableEngines;
1000 }
1001
1002
1003 /**
1004 * Getting all available engines:
1005 * LIST AVAILABLE_ENGINES
1006 *
1007 * @param pClient Pointer to client instance structure.
1008 *
1009 * @returns A NULL terminated array of engine name strings,
1010 * or NULL in case of failure.
1011 */
1012 const char **lscp_list_available_engines ( lscp_client_t *pClient )
1013 {
1014 const char *pszSeps = ",";
1015
1016 if (pClient == NULL)
1017 return NULL;
1018
1019 // Lock this section up.
1020 lscp_mutex_lock(pClient->mutex);
1021
1022 if (pClient->engines) {
1023 lscp_szsplit_destroy(pClient->engines);
1024 pClient->engines = NULL;
1025 }
1026
1027 if (lscp_client_call(pClient, "LIST AVAILABLE_ENGINES\r\n", 0) == LSCP_OK)
1028 pClient->engines = lscp_szsplit_create(lscp_client_get_result(pClient), pszSeps);
1029
1030 // Unlock this section down.
1031 lscp_mutex_unlock(pClient->mutex);
1032
1033 return (const char **) pClient->engines;
1034 }
1035
1036
1037 /**
1038 * Getting information about an engine.
1039 * GET ENGINE INFO <engine-name>
1040 *
1041 * @param pClient Pointer to client instance structure.
1042 * @param pszEngineName Engine name.
1043 *
1044 * @returns A pointer to a @ref lscp_engine_info_t structure, with all the
1045 * information of the given sampler engine, or NULL in case of failure.
1046 */
1047 lscp_engine_info_t *lscp_get_engine_info ( lscp_client_t *pClient, const char *pszEngineName )
1048 {
1049 lscp_engine_info_t *pEngineInfo;
1050 char szQuery[LSCP_BUFSIZ];
1051 const char *pszResult;
1052 const char *pszSeps = ":";
1053 const char *pszCrlf = "\r\n";
1054 char *pszToken;
1055 char *pch;
1056
1057 if (pClient == NULL)
1058 return NULL;
1059 if (pszEngineName == NULL)
1060 return NULL;
1061
1062 // Lock this section up.
1063 lscp_mutex_lock(pClient->mutex);
1064
1065 pEngineInfo = &(pClient->engine_info);
1066 lscp_engine_info_reset(pEngineInfo);
1067
1068 sprintf(szQuery, "GET ENGINE INFO %s\r\n", pszEngineName);
1069 if (lscp_client_call(pClient, szQuery, 1) == LSCP_OK) {
1070 pszResult = lscp_client_get_result(pClient);
1071 pszToken = lscp_strtok((char *) pszResult, pszSeps, &(pch));
1072 while (pszToken) {
1073 if (strcasecmp(pszToken, "DESCRIPTION") == 0) {
1074 pszToken = lscp_strtok(NULL, pszCrlf, &(pch));
1075 if (pszToken)
1076 lscp_unquote_dup(&(pEngineInfo->description), &pszToken);
1077 }
1078 else if (strcasecmp(pszToken, "VERSION") == 0) {
1079 pszToken = lscp_strtok(NULL, pszCrlf, &(pch));
1080 if (pszToken)
1081 lscp_unquote_dup(&(pEngineInfo->version), &pszToken);
1082 }
1083 pszToken = lscp_strtok(NULL, pszSeps, &(pch));
1084 }
1085 }
1086 else pEngineInfo = NULL;
1087
1088 // Unlock this section down.
1089 lscp_mutex_unlock(pClient->mutex);
1090
1091 return pEngineInfo;
1092 }
1093
1094
1095 /**
1096 * Getting sampler channel informations:
1097 * GET CHANNEL INFO <sampler-channel>
1098 *
1099 * @param pClient Pointer to client instance structure.
1100 * @param iSamplerChannel Sampler channel number.
1101 *
1102 * @returns A pointer to a @ref lscp_channel_info_t structure, with all the
1103 * information of the given sampler channel, or NULL in case of failure.
1104 */
1105 lscp_channel_info_t *lscp_get_channel_info ( lscp_client_t *pClient, int iSamplerChannel )
1106 {
1107 lscp_channel_info_t *pChannelInfo;
1108 char szQuery[LSCP_BUFSIZ];
1109 const char *pszResult;
1110 const char *pszSeps = ":";
1111 const char *pszCrlf = "\r\n";
1112 char *pszToken;
1113 char *pch;
1114
1115 if (pClient == NULL)
1116 return NULL;
1117 if (iSamplerChannel < 0)
1118 return NULL;
1119
1120 // Lock this section up.
1121 lscp_mutex_lock(pClient->mutex);
1122
1123 pChannelInfo = &(pClient->channel_info);
1124 lscp_channel_info_reset(pChannelInfo);
1125
1126 sprintf(szQuery, "GET CHANNEL INFO %d\r\n", iSamplerChannel);
1127 if (lscp_client_call(pClient, szQuery, 1) == LSCP_OK) {
1128 pszResult = lscp_client_get_result(pClient);
1129 pszToken = lscp_strtok((char *) pszResult, pszSeps, &(pch));
1130 while (pszToken) {
1131 if (strcasecmp(pszToken, "ENGINE_NAME") == 0) {
1132 pszToken = lscp_strtok(NULL, pszCrlf, &(pch));
1133 if (pszToken)
1134 lscp_unquote_dup(&(pChannelInfo->engine_name), &pszToken);
1135 }
1136 else if (strcasecmp(pszToken, "AUDIO_OUTPUT_DEVICE") == 0) {
1137 pszToken = lscp_strtok(NULL, pszCrlf, &(pch));
1138 if (pszToken)
1139 pChannelInfo->audio_device = atoi(lscp_ltrim(pszToken));
1140 }
1141 else if (strcasecmp(pszToken, "AUDIO_OUTPUT_CHANNELS") == 0) {
1142 pszToken = lscp_strtok(NULL, pszCrlf, &(pch));
1143 if (pszToken)
1144 pChannelInfo->audio_channels = atoi(lscp_ltrim(pszToken));
1145 }
1146 else if (strcasecmp(pszToken, "AUDIO_OUTPUT_ROUTING") == 0) {
1147 pszToken = lscp_strtok(NULL, pszCrlf, &(pch));
1148 if (pszToken) {
1149 if (pChannelInfo->audio_routing)
1150 lscp_isplit_destroy(pChannelInfo->audio_routing);
1151 pChannelInfo->audio_routing = lscp_isplit_create(pszToken, ",");
1152 }
1153 }
1154 else if (strcasecmp(pszToken, "INSTRUMENT_FILE") == 0) {
1155 pszToken = lscp_strtok(NULL, pszCrlf, &(pch));
1156 if (pszToken)
1157 lscp_unquote_dup(&(pChannelInfo->instrument_file), &pszToken);
1158 }
1159 else if (strcasecmp(pszToken, "INSTRUMENT_NR") == 0) {
1160 pszToken = lscp_strtok(NULL, pszCrlf, &(pch));
1161 if (pszToken)
1162 pChannelInfo->instrument_nr = atoi(lscp_ltrim(pszToken));
1163 }
1164 else if (strcasecmp(pszToken, "INSTRUMENT_NAME") == 0) {
1165 pszToken = lscp_strtok(NULL, pszCrlf, &(pch));
1166 if (pszToken)
1167 lscp_unquote_dup(&(pChannelInfo->instrument_name), &pszToken);
1168 }
1169 else if (strcasecmp(pszToken, "INSTRUMENT_STATUS") == 0) {
1170 pszToken = lscp_strtok(NULL, pszCrlf, &(pch));
1171 if (pszToken)
1172 pChannelInfo->instrument_status = atoi(lscp_ltrim(pszToken));
1173 }
1174 else if (strcasecmp(pszToken, "MIDI_INPUT_DEVICE") == 0) {
1175 pszToken = lscp_strtok(NULL, pszCrlf, &(pch));
1176 if (pszToken)
1177 pChannelInfo->midi_device = atoi(lscp_ltrim(pszToken));
1178 }
1179 else if (strcasecmp(pszToken, "MIDI_INPUT_PORT") == 0) {
1180 pszToken = lscp_strtok(NULL, pszCrlf, &(pch));
1181 if (pszToken)
1182 pChannelInfo->midi_port = atoi(lscp_ltrim(pszToken));
1183 }
1184 else if (strcasecmp(pszToken, "MIDI_INPUT_CHANNEL") == 0) {
1185 pszToken = lscp_strtok(NULL, pszCrlf, &(pch));
1186 if (pszToken) {
1187 pszToken = lscp_ltrim(pszToken);
1188 if (strcasecmp(pszToken, "ALL") == 0)
1189 pChannelInfo->midi_channel = LSCP_MIDI_CHANNEL_ALL;
1190 else
1191 pChannelInfo->midi_channel = atoi(pszToken);
1192 }
1193 }
1194 else if (strcasecmp(pszToken, "MIDI_INSTRUMENT_MAP") == 0) {
1195 pszToken = lscp_strtok(NULL, pszCrlf, &(pch));
1196 if (pszToken) {
1197 pszToken = lscp_ltrim(pszToken);
1198 if (strcasecmp(pszToken, "NONE") == 0)
1199 pChannelInfo->midi_map = LSCP_MIDI_MAP_NONE;
1200 else
1201 if (strcasecmp(pszToken, "DEFAULT") == 0)
1202 pChannelInfo->midi_map = LSCP_MIDI_MAP_DEFAULT;
1203 else
1204 pChannelInfo->midi_map = atoi(pszToken);
1205 }
1206 }
1207 else if (strcasecmp(pszToken, "VOLUME") == 0) {
1208 pszToken = lscp_strtok(NULL, pszCrlf, &(pch));
1209 if (pszToken)
1210 pChannelInfo->volume = (float) atof(lscp_ltrim(pszToken));
1211 }
1212 else if (strcasecmp(pszToken, "MUTE") == 0) {
1213 pszToken = lscp_strtok(NULL, pszCrlf, &(pch));
1214 if (pszToken)
1215 pChannelInfo->mute = (strcasecmp(lscp_unquote(&pszToken, 0), "TRUE") == 0);
1216 }
1217 else if (strcasecmp(pszToken, "SOLO") == 0) {
1218 pszToken = lscp_strtok(NULL, pszCrlf, &(pch));
1219 if (pszToken)
1220 pChannelInfo->solo = (strcasecmp(lscp_unquote(&pszToken, 0), "TRUE") == 0);
1221 }
1222 pszToken = lscp_strtok(NULL, pszSeps, &(pch));
1223 }
1224 }
1225 else pChannelInfo = NULL;
1226
1227 // Unlock this section up.
1228 lscp_mutex_unlock(pClient->mutex);
1229
1230 return pChannelInfo;
1231 }
1232
1233
1234 /**
1235 * Current number of active voices:
1236 * GET CHANNEL VOICE_COUNT <sampler-channel>
1237 *
1238 * @param pClient Pointer to client instance structure.
1239 * @param iSamplerChannel Sampler channel number.
1240 *
1241 * @returns The number of voices currently active, -1 in case of failure.
1242 */
1243 int lscp_get_channel_voice_count ( lscp_client_t *pClient, int iSamplerChannel )
1244 {
1245 char szQuery[LSCP_BUFSIZ];
1246 int iVoiceCount = -1;
1247
1248 if (pClient == NULL)
1249 return -1;
1250 if (iSamplerChannel < 0)
1251 return -1;
1252
1253 // Lock this section up.
1254 lscp_mutex_lock(pClient->mutex);
1255
1256 sprintf(szQuery, "GET CHANNEL VOICE_COUNT %d\r\n", iSamplerChannel);
1257 if (lscp_client_call(pClient, szQuery, 0) == LSCP_OK)
1258 iVoiceCount = atoi(lscp_client_get_result(pClient));
1259
1260 // Unlock this section down.
1261 lscp_mutex_unlock(pClient->mutex);
1262
1263 return iVoiceCount;
1264 }
1265
1266
1267 /**
1268 * Current number of active disk streams:
1269 * GET CHANNEL STREAM_COUNT <sampler-channel>
1270 *
1271 * @param pClient Pointer to client instance structure.
1272 * @param iSamplerChannel Sampler channel number.
1273 *
1274 * @returns The number of active disk streams on success, -1 otherwise.
1275 */
1276 int lscp_get_channel_stream_count ( lscp_client_t *pClient, int iSamplerChannel )
1277 {
1278 char szQuery[LSCP_BUFSIZ];
1279 int iStreamCount = -1;
1280
1281 if (pClient == NULL)
1282 return -1;
1283 if (iSamplerChannel < 0)
1284 return -1;
1285
1286 // Lock this section up.
1287 lscp_mutex_lock(pClient->mutex);
1288
1289 sprintf(szQuery, "GET CHANNEL STREAM_COUNT %d\r\n", iSamplerChannel);
1290 if (lscp_client_call(pClient, szQuery, 0) == LSCP_OK)
1291 iStreamCount = atoi(lscp_client_get_result(pClient));
1292
1293 // Unlock this section down.
1294 lscp_mutex_unlock(pClient->mutex);
1295
1296 return iStreamCount;
1297 }
1298
1299
1300 /**
1301 * Current least usage of active disk streams.
1302 *
1303 * @param pClient Pointer to client instance structure.
1304 * @param iSamplerChannel Sampler channel number.
1305 *
1306 * @returns The usage percentage of the least filled active disk stream
1307 * on success, -1 otherwise.
1308 */
1309 int lscp_get_channel_stream_usage ( lscp_client_t *pClient, int iSamplerChannel )
1310 {
1311 char szQuery[LSCP_BUFSIZ];
1312 int iStreamUsage = -1;
1313 const char *pszResult;
1314 const char *pszSeps = "[]%,";
1315 char *pszToken;
1316 char *pch;
1317 int iStream;
1318 int iPercent;
1319
1320 if (pClient == NULL)
1321 return -1;
1322 if (iSamplerChannel < 0)
1323 return -1;
1324
1325 // Lock this section up.
1326 lscp_mutex_lock(pClient->mutex);
1327
1328 iStream = 0;
1329 sprintf(szQuery, "GET CHANNEL BUFFER_FILL PERCENTAGE %d\r\n", iSamplerChannel);
1330 if (lscp_client_call(pClient, szQuery, 0) == LSCP_OK) {
1331 pszResult = lscp_client_get_result(pClient);
1332 pszToken = lscp_strtok((char *) pszResult, pszSeps, &(pch));
1333 while (pszToken) {
1334 if (*pszToken) {
1335 // Skip stream id.
1336 pszToken = lscp_strtok(NULL, pszSeps, &(pch));
1337 if (pszToken == NULL)
1338 break;
1339 // Get least buffer fill percentage.
1340 iPercent = atol(pszToken);
1341 if (iStreamUsage > iPercent || iStream == 0)
1342 iStreamUsage = iPercent;
1343 iStream++;
1344 }
1345 pszToken = lscp_strtok(NULL, pszSeps, &(pch));
1346 }
1347 }
1348
1349 // Unlock this section down.
1350 lscp_mutex_unlock(pClient->mutex);
1351
1352 return iStreamUsage;
1353 }
1354
1355
1356 /**
1357 * Current fill state of disk stream buffers:
1358 * GET CHANNEL BUFFER_FILL {BYTES|PERCENTAGE} <sampler-channel>
1359 *
1360 * @param pClient Pointer to client instance structure.
1361 * @param usage_type Usage type to be returned, either
1362 * @ref LSCP_USAGE_BYTES, or
1363 * @ref LSCP_USAGE_PERCENTAGE.
1364 * @param iSamplerChannel Sampler channel number.
1365 *
1366 * @returns A pointer to a @ref lscp_buffer_fill_t structure, with the
1367 * information of the current disk stream buffer fill usage, for the given
1368 * sampler channel, or NULL in case of failure.
1369 */
1370 lscp_buffer_fill_t *lscp_get_channel_buffer_fill ( lscp_client_t *pClient, lscp_usage_t usage_type, int iSamplerChannel )
1371 {
1372 lscp_buffer_fill_t *pBufferFill;
1373 char szQuery[LSCP_BUFSIZ];
1374 int iStreamCount;
1375 const char *pszUsageType = (usage_type == LSCP_USAGE_BYTES ? "BYTES" : "PERCENTAGE");
1376 const char *pszResult;
1377 const char *pszSeps = "[]%,";
1378 char *pszToken;
1379 char *pch;
1380 int iStream;
1381
1382 // Retrieve a channel stream estimation.
1383 iStreamCount = lscp_get_channel_stream_count(pClient, iSamplerChannel);
1384 if (iStreamCount < 0)
1385 return NULL;
1386
1387 // Lock this section up.
1388 lscp_mutex_lock(pClient->mutex);
1389
1390 // Check if we need to reallocate the stream usage array.
1391 if (pClient->iStreamCount != iStreamCount) {
1392 if (pClient->buffer_fill)
1393 free(pClient->buffer_fill);
1394 if (iStreamCount > 0)
1395 pClient->buffer_fill = (lscp_buffer_fill_t *) malloc(iStreamCount * sizeof(lscp_buffer_fill_t));
1396 else
1397 pClient->buffer_fill = NULL;
1398 pClient->iStreamCount = iStreamCount;
1399 }
1400
1401 // Get buffer fill usage...
1402 pBufferFill = pClient->buffer_fill;
1403 if (pBufferFill && iStreamCount > 0) {
1404 iStream = 0;
1405 pBufferFill = pClient->buffer_fill;
1406 sprintf(szQuery, "GET CHANNEL BUFFER_FILL %s %d\r\n", pszUsageType, iSamplerChannel);
1407 if (lscp_client_call(pClient, szQuery, 0) == LSCP_OK) {
1408 pszResult = lscp_client_get_result(pClient);
1409 pszToken = lscp_strtok((char *) pszResult, pszSeps, &(pch));
1410 while (pszToken && iStream < pClient->iStreamCount) {
1411 if (*pszToken) {
1412 pBufferFill[iStream].stream_id = atol(pszToken);
1413 pszToken = lscp_strtok(NULL, pszSeps, &(pch));
1414 if (pszToken == NULL)
1415 break;
1416 pBufferFill[iStream].stream_usage = atol(pszToken);
1417 iStream++;
1418 }
1419 pszToken = lscp_strtok(NULL, pszSeps, &(pch));
1420 }
1421 } // Reset the usage, whatever it was before.
1422 else while (iStream < pClient->iStreamCount)
1423 pBufferFill[iStream++].stream_usage = 0;
1424 }
1425
1426 // Unlock this section down.
1427 lscp_mutex_unlock(pClient->mutex);
1428
1429 return pBufferFill;
1430 }
1431
1432
1433 /**
1434 * Setting audio output type:
1435 * SET CHANNEL AUDIO_OUTPUT_TYPE <sampler-channel> <audio-output-type>
1436 *
1437 * @param pClient Pointer to client instance structure.
1438 * @param iSamplerChannel Sampler channel number.
1439 * @param pszAudioDriver Audio output driver type (e.g. "ALSA" or "JACK").
1440 *
1441 * @returns LSCP_OK on success, LSCP_FAILED otherwise.
1442 */
1443 lscp_status_t lscp_set_channel_audio_type ( lscp_client_t *pClient, int iSamplerChannel, const char *pszAudioDriver )
1444 {
1445 char szQuery[LSCP_BUFSIZ];
1446
1447 if (iSamplerChannel < 0 || pszAudioDriver == NULL)
1448 return LSCP_FAILED;
1449
1450 sprintf(szQuery, "SET CHANNEL AUDIO_OUTPUT_TYPE %d %s\r\n", iSamplerChannel, pszAudioDriver);
1451 return lscp_client_query(pClient, szQuery);
1452 }
1453
1454
1455 /**
1456 * Setting audio output device:
1457 * SET CHANNEL AUDIO_OUTPUT_DEVICE <sampler-channel> <device-id>
1458 *
1459 * @param pClient Pointer to client instance structure.
1460 * @param iSamplerChannel Sampler channel number.
1461 * @param iAudioDevice Audio output device number identifier.
1462 *
1463 * @returns LSCP_OK on success, LSCP_FAILED otherwise.
1464 */
1465 lscp_status_t lscp_set_channel_audio_device ( lscp_client_t *pClient, int iSamplerChannel, int iAudioDevice )
1466 {
1467 char szQuery[LSCP_BUFSIZ];
1468
1469 if (iSamplerChannel < 0 || iAudioDevice < 0)
1470 return LSCP_FAILED;
1471
1472 sprintf(szQuery, "SET CHANNEL AUDIO_OUTPUT_DEVICE %d %d\r\n", iSamplerChannel, iAudioDevice);
1473 return lscp_client_query(pClient, szQuery);
1474 }
1475
1476
1477 /**
1478 * Setting audio output channel:
1479 * SET CHANNEL AUDIO_OUTPUT_CHANNEL <sampler-channel> <audio-output-chan> <audio-input-chan>
1480 *
1481 * @param pClient Pointer to client instance structure.
1482 * @param iSamplerChannel Sampler channel number.
1483 * @param iAudioOut Audio output device channel to be routed from.
1484 * @param iAudioIn Audio output device channel to be routed into.
1485 *
1486 * @returns LSCP_OK on success, LSCP_FAILED otherwise.
1487 */
1488 lscp_status_t lscp_set_channel_audio_channel ( lscp_client_t *pClient, int iSamplerChannel, int iAudioOut, int iAudioIn )
1489 {
1490 char szQuery[LSCP_BUFSIZ];
1491
1492 if (iSamplerChannel < 0 || iAudioOut < 0 || iAudioIn < 0)
1493 return LSCP_FAILED;
1494
1495 sprintf(szQuery, "SET CHANNEL AUDIO_OUTPUT_CHANNEL %d %d %d\r\n", iSamplerChannel, iAudioOut, iAudioIn);
1496 return lscp_client_query(pClient, szQuery);
1497 }
1498
1499
1500 /**
1501 * Setting MIDI input type:
1502 * SET CHANNEL MIDI_INPUT_TYPE <sampler-channel> <midi-input-type>
1503 *
1504 * @param pClient Pointer to client instance structure.
1505 * @param iSamplerChannel Sampler channel number.
1506 * @param pszMidiDriver MIDI input driver type (e.g. "ALSA").
1507 *
1508 * @returns LSCP_OK on success, LSCP_FAILED otherwise.
1509 */
1510 lscp_status_t lscp_set_channel_midi_type ( lscp_client_t *pClient, int iSamplerChannel, const char *pszMidiDriver )
1511 {
1512 char szQuery[LSCP_BUFSIZ];
1513
1514 if (iSamplerChannel < 0 || pszMidiDriver == NULL)
1515 return LSCP_FAILED;
1516
1517 sprintf(szQuery, "SET CHANNEL MIDI_INPUT_TYPE %d %s\r\n", iSamplerChannel, pszMidiDriver);
1518 return lscp_client_query(pClient, szQuery);
1519 }
1520
1521
1522 /**
1523 * Setting MIDI input device:
1524 * SET CHANNEL MIDI_INPUT_DEVICE <sampler-channel> <device-id>
1525 *
1526 * @param pClient Pointer to client instance structure.
1527 * @param iSamplerChannel Sampler channel number.
1528 * @param iMidiDevice MIDI input device number identifier.
1529 *
1530 * @returns LSCP_OK on success, LSCP_FAILED otherwise.
1531 */
1532 lscp_status_t lscp_set_channel_midi_device ( lscp_client_t *pClient, int iSamplerChannel, int iMidiDevice )
1533 {
1534 char szQuery[LSCP_BUFSIZ];
1535
1536 if (iSamplerChannel < 0 || iMidiDevice < 0)
1537 return LSCP_FAILED;
1538
1539 sprintf(szQuery, "SET CHANNEL MIDI_INPUT_DEVICE %d %d\r\n", iSamplerChannel, iMidiDevice);
1540 return lscp_client_query(pClient, szQuery);
1541 }
1542
1543
1544 /**
1545 * Setting MIDI input port:
1546 * SET CHANNEL MIDI_INPUT_PORT <sampler-channel> <midi-input-port>
1547 *
1548 * @param pClient Pointer to client instance structure.
1549 * @param iSamplerChannel Sampler channel number.
1550 * @param iMidiPort MIDI input driver virtual port number.
1551 *
1552 * @returns LSCP_OK on success, LSCP_FAILED otherwise.
1553 */
1554 lscp_status_t lscp_set_channel_midi_port ( lscp_client_t *pClient, int iSamplerChannel, int iMidiPort )
1555 {
1556 char szQuery[LSCP_BUFSIZ];
1557
1558 if (iSamplerChannel < 0 || iMidiPort < 0)
1559 return LSCP_FAILED;
1560
1561 sprintf(szQuery, "SET CHANNEL MIDI_INPUT_PORT %d %d\r\n", iSamplerChannel, iMidiPort);
1562 return lscp_client_query(pClient, szQuery);
1563 }
1564
1565
1566 /**
1567 * Setting MIDI input channel:
1568 * SET CHANNEL MIDI_INPUT_CHANNEL <sampler-channel> <midi-input-chan>
1569 *
1570 * @param pClient Pointer to client instance structure.
1571 * @param iSamplerChannel Sampler channel number.
1572 * @param iMidiChannel MIDI channel address number to listen (0-15) or
1573 * @ref LSCP_MIDI_CHANNEL_ALL (16) to listen on all channels.
1574 *
1575 * @returns LSCP_OK on success, LSCP_FAILED otherwise.
1576 */
1577 lscp_status_t lscp_set_channel_midi_channel ( lscp_client_t *pClient, int iSamplerChannel, int iMidiChannel )
1578 {
1579 char szQuery[LSCP_BUFSIZ];
1580
1581 if (iSamplerChannel < 0 || iMidiChannel < 0 || iMidiChannel > 16)
1582 return LSCP_FAILED;
1583
1584 if (iMidiChannel == LSCP_MIDI_CHANNEL_ALL)
1585 sprintf(szQuery, "SET CHANNEL MIDI_INPUT_CHANNEL %d ALL\r\n", iSamplerChannel);
1586 else
1587 sprintf(szQuery, "SET CHANNEL MIDI_INPUT_CHANNEL %d %d\r\n", iSamplerChannel, iMidiChannel);
1588 return lscp_client_query(pClient, szQuery);
1589 }
1590
1591
1592 /**
1593 * Setting MIDI instrument map:
1594 * SET CHANNEL MIDI_INSTRUMENT_MAP <sampler-channel> <midi-map>
1595 *
1596 * @param pClient Pointer to client instance structure.
1597 * @param iSamplerChannel Sampler channel number.
1598 * @param iMidiMap MIDI instrument map number, or either
1599 * @ref LSCP_MIDI_MAP_NONE or
1600 * @ref LSCP_MIDI_MAP_DEFAULT .
1601 *
1602 * @returns LSCP_OK on success, LSCP_FAILED otherwise.
1603 */
1604 lscp_status_t lscp_set_channel_midi_map ( lscp_client_t *pClient, int iSamplerChannel, int iMidiMap )
1605 {
1606 char szQuery[LSCP_BUFSIZ];
1607
1608 if (iSamplerChannel < 0)
1609 return LSCP_FAILED;
1610
1611 sprintf(szQuery, "SET CHANNEL MIDI_INSTRUMENT_MAP %d ", iSamplerChannel);
1612 if (iMidiMap == LSCP_MIDI_MAP_NONE)
1613 strcat(szQuery , "NONE");
1614 else
1615 if (iMidiMap == LSCP_MIDI_MAP_DEFAULT)
1616 strcat(szQuery , "DEFAULT");
1617 else
1618 sprintf(szQuery + strlen(szQuery), "%d", iMidiMap);
1619
1620 strcat(szQuery, "\r\n");
1621
1622 return lscp_client_query(pClient, szQuery);
1623 }
1624
1625
1626 /**
1627 * Setting channel volume:
1628 * SET CHANNEL VOLUME <sampler-channel> <volume>
1629 *
1630 * @param pClient Pointer to client instance structure.
1631 * @param iSamplerChannel Sampler channel number.
1632 * @param fVolume Sampler channel volume as a positive floating point
1633 * number, where a value less than 1.0 for attenuation,
1634 * and greater than 1.0 for amplification.
1635 *
1636 * @returns LSCP_OK on success, LSCP_FAILED otherwise.
1637 */
1638 lscp_status_t lscp_set_channel_volume ( lscp_client_t *pClient, int iSamplerChannel, float fVolume )
1639 {
1640 char szQuery[LSCP_BUFSIZ];
1641
1642 if (iSamplerChannel < 0 || fVolume < 0.0f)
1643 return LSCP_FAILED;
1644
1645 sprintf(szQuery, "SET CHANNEL VOLUME %d %g\r\n", iSamplerChannel, fVolume);
1646 return lscp_client_query(pClient, szQuery);
1647 }
1648
1649
1650 /**
1651 * Muting a sampler channel:
1652 * SET CHANNEL MUTE <sampler-channel> <mute>
1653 *
1654 * @param pClient Pointer to client instance structure.
1655 * @param iSamplerChannel Sampler channel number.
1656 * @param iMute Sampler channel mute state as a boolean value,
1657 * either 1 (one) to mute the channel or 0 (zero)
1658 * to unmute the channel.
1659 *
1660 * @returns LSCP_OK on success, LSCP_FAILED otherwise.
1661 */
1662 lscp_status_t lscp_set_channel_mute ( lscp_client_t *pClient, int iSamplerChannel, int iMute )
1663 {
1664 char szQuery[LSCP_BUFSIZ];
1665
1666 if (iSamplerChannel < 0 || iMute < 0 || iMute > 1)
1667 return LSCP_FAILED;
1668
1669 sprintf(szQuery, "SET CHANNEL MUTE %d %d\r\n", iSamplerChannel, iMute);
1670 return lscp_client_query(pClient, szQuery);
1671 }
1672
1673
1674 /**
1675 * Soloing a sampler channel:
1676 * SET CHANNEL SOLO <sampler-channel> <solo>
1677 *
1678 * @param pClient Pointer to client instance structure.
1679 * @param iSamplerChannel Sampler channel number.
1680 * @param iSolo Sampler channel solo state as a boolean value,
1681 * either 1 (one) to solo the channel or 0 (zero)
1682 * to unsolo the channel.
1683 *
1684 * @returns LSCP_OK on success, LSCP_FAILED otherwise.
1685 */
1686 lscp_status_t lscp_set_channel_solo ( lscp_client_t *pClient, int iSamplerChannel, int iSolo )
1687 {
1688 char szQuery[LSCP_BUFSIZ];
1689
1690 if (iSamplerChannel < 0 || iSolo < 0 || iSolo > 1)
1691 return LSCP_FAILED;
1692
1693 sprintf(szQuery, "SET CHANNEL SOLO %d %d\r\n", iSamplerChannel, iSolo);
1694 return lscp_client_query(pClient, szQuery);
1695 }
1696
1697
1698 /**
1699 * Resetting a sampler channel:
1700 * RESET CHANNEL <sampler-channel>
1701 *
1702 * @param pClient Pointer to client instance structure.
1703 * @param iSamplerChannel Sampler channel number.
1704 *
1705 * @returns LSCP_OK on success, LSCP_FAILED otherwise.
1706 */
1707 lscp_status_t lscp_reset_channel ( lscp_client_t *pClient, int iSamplerChannel )
1708 {
1709 char szQuery[LSCP_BUFSIZ];
1710
1711 if (iSamplerChannel < 0)
1712 return LSCP_FAILED;
1713
1714 sprintf(szQuery, "RESET CHANNEL %d\r\n", iSamplerChannel);
1715 return lscp_client_query(pClient, szQuery);
1716 }
1717
1718
1719 /**
1720 * Resetting the sampler:
1721 * RESET
1722 *
1723 * @param pClient Pointer to client instance structure.
1724 *
1725 * @returns LSCP_OK on success, LSCP_FAILED otherwise.
1726 */
1727 lscp_status_t lscp_reset_sampler ( lscp_client_t *pClient )
1728 {
1729 // Do actual whole sampler reset...
1730 return lscp_client_query(pClient, "RESET\r\n");
1731 }
1732
1733
1734 /**
1735 * Getting information about the server.
1736 * GET SERVER INFO
1737 *
1738 * @param pClient Pointer to client instance structure.
1739 *
1740 * @returns A pointer to a @ref lscp_server_info_t structure, with all the
1741 * information of the current connected server, or NULL in case of failure.
1742 */
1743 lscp_server_info_t *lscp_get_server_info ( lscp_client_t *pClient )
1744 {
1745 lscp_server_info_t *pServerInfo;
1746 const char *pszResult;
1747 const char *pszSeps = ":";
1748 const char *pszCrlf = "\r\n";
1749 char *pszToken;
1750 char *pch;
1751
1752 if (pClient == NULL)
1753 return NULL;
1754
1755 // Lock this section up.
1756 lscp_mutex_lock(pClient->mutex);
1757
1758 pServerInfo = &(pClient->server_info);
1759 lscp_server_info_reset(pServerInfo);
1760
1761 if (lscp_client_call(pClient, "GET SERVER INFO\r\n", 1) == LSCP_OK) {
1762 pszResult = lscp_client_get_result(pClient);
1763 pszToken = lscp_strtok((char *) pszResult, pszSeps, &(pch));
1764 while (pszToken) {
1765 if (strcasecmp(pszToken, "DESCRIPTION") == 0) {
1766 pszToken = lscp_strtok(NULL, pszCrlf, &(pch));
1767 if (pszToken)
1768 lscp_unquote_dup(&(pServerInfo->description), &pszToken);
1769 }
1770 else if (strcasecmp(pszToken, "VERSION") == 0) {
1771 pszToken = lscp_strtok(NULL, pszCrlf, &(pch));
1772 if (pszToken)
1773 lscp_unquote_dup(&(pServerInfo->version), &pszToken);
1774 }
1775 else if (strcasecmp(pszToken, "PROTOCOL_VERSION") == 0) {
1776 pszToken = lscp_strtok(NULL, pszCrlf, &(pch));
1777 if (pszToken)
1778 lscp_unquote_dup(&(pServerInfo->protocol_version), &pszToken);
1779 }
1780 pszToken = lscp_strtok(NULL, pszSeps, &(pch));
1781 }
1782 }
1783 else pServerInfo = NULL;
1784
1785 // Unlock this section down.
1786 lscp_mutex_unlock(pClient->mutex);
1787
1788 return pServerInfo;
1789 }
1790
1791
1792 /**
1793 * Current total number of active voices:
1794 * GET TOTAL_VOICE_COUNT
1795 *
1796 * @param pClient Pointer to client instance structure.
1797 *
1798 * @returns The total number of voices currently active,
1799 * -1 in case of failure.
1800 */
1801 int lscp_get_total_voice_count ( lscp_client_t *pClient )
1802 {
1803 int iVoiceCount = -1;
1804
1805 if (pClient == NULL)
1806 return -1;
1807
1808 // Lock this section up.
1809 lscp_mutex_lock(pClient->mutex);
1810
1811 if (lscp_client_call(pClient, "GET TOTAL_VOICE_COUNT\r\n", 0) == LSCP_OK)
1812 iVoiceCount = atoi(lscp_client_get_result(pClient));
1813
1814 // Unlock this section down.
1815 lscp_mutex_unlock(pClient->mutex);
1816
1817 return iVoiceCount;
1818 }
1819
1820
1821 /**
1822 * Maximum amount of active voices:
1823 * GET TOTAL_VOICE_COUNT_MAX
1824 *
1825 * @param pClient Pointer to client instance structure.
1826 *
1827 * @returns The maximum amount of voices currently active,
1828 * -1 in case of failure.
1829 */
1830 int lscp_get_total_voice_count_max ( lscp_client_t *pClient )
1831 {
1832 int iVoiceCount = -1;
1833
1834 if (pClient == NULL)
1835 return -1;
1836
1837 // Lock this section up.
1838 lscp_mutex_lock(pClient->mutex);
1839
1840 if (lscp_client_call(pClient, "GET TOTAL_VOICE_COUNT_MAX\r\n", 0) == LSCP_OK)
1841 iVoiceCount = atoi(lscp_client_get_result(pClient));
1842
1843 // Unlock this section down.
1844 lscp_mutex_unlock(pClient->mutex);
1845
1846 return iVoiceCount;
1847 }
1848
1849
1850 /**
1851 * Get global volume attenuation:
1852 * GET VOLUME
1853 *
1854 * @param pClient Pointer to client instance structure.
1855 *
1856 * @returns The global volume as positive floating point value usually in
1857 * the range between 0.0 and 1.0; in case of failure 0.0 is returned.
1858 */
1859 float lscp_get_volume ( lscp_client_t *pClient )
1860 {
1861 float fVolume = 0.0f;
1862
1863 if (pClient == NULL)
1864 return 0.0f;
1865
1866 // Lock this section up.
1867 lscp_mutex_lock(pClient->mutex);
1868
1869 if (lscp_client_call(pClient, "GET VOLUME\r\n", 0) == LSCP_OK)
1870 fVolume = (float) atof(lscp_client_get_result(pClient));
1871
1872 // Unlock this section down.
1873 lscp_mutex_unlock(pClient->mutex);
1874
1875 return fVolume;
1876 }
1877
1878
1879 /**
1880 * Setting global volume attenuation:
1881 * SET VOLUME <volume>
1882 *
1883 * @param pClient Pointer to client instance structure.
1884 * @param fVolume Global volume parameter as positive floating point
1885 * value usually be in the range between 0.0 and 1.0,
1886 * that is for attenuating the overall volume.
1887 *
1888 * @returns LSCP_OK on success, LSCP_FAILED otherwise.
1889 */
1890 lscp_status_t lscp_set_volume ( lscp_client_t *pClient, float fVolume )
1891 {
1892 char szQuery[LSCP_BUFSIZ];
1893
1894 if (fVolume < 0.0f)
1895 return LSCP_FAILED;
1896
1897 sprintf(szQuery, "SET VOLUME %g\r\n", fVolume);
1898 return lscp_client_query(pClient, szQuery);
1899 }
1900
1901 /**
1902 * Get global voice limit setting:
1903 * @code
1904 * GET VOICES
1905 * @endcode
1906 * This value reflects the maximum amount of voices a sampler engine
1907 * processes simultaniously before voice stealing kicks in.
1908 *
1909 * @param pClient Pointer to client instance structure.
1910 *
1911 * @returns The current global maximum amount of voices limit or a
1912 * negative value on error (e.g. if sampler doesn't support
1913 * this command).
1914 */
1915 int lscp_get_voices(lscp_client_t *pClient)
1916 {
1917 int iVoices = -1;
1918
1919 if (pClient == NULL)
1920 return -1;
1921
1922 // Lock this section up.
1923 lscp_mutex_lock(pClient->mutex);
1924
1925 if (lscp_client_call(pClient, "GET VOICES\r\n", 0) == LSCP_OK)
1926 iVoices = atoi(lscp_client_get_result(pClient));
1927
1928 // Unlock this section down.
1929 lscp_mutex_unlock(pClient->mutex);
1930
1931 return iVoices;
1932 }
1933
1934 /**
1935 * Setting global voice limit setting:
1936 * @code
1937 * SET VOICES <max-voices>
1938 * @endcode
1939 * This value reflects the maximum amount of voices a sampler engine
1940 * processes simultaniously before voice stealing kicks in. Note that
1941 * this value will be passed to all sampler engine instances, that is
1942 * the total amount of maximum voices on the running system is thus
1943 * @param iMaxVoices multiplied with the current amount of sampler
1944 * engine instances.
1945 *
1946 * @param pClient Pointer to client instance structure.
1947 * @param iMaxVoices Global voice limit setting as integer value larger
1948 * or equal to 1.
1949 *
1950 * @returns LSCP_OK on success, LSCP_FAILED otherwise.
1951 */
1952 lscp_status_t lscp_set_voices(lscp_client_t *pClient, int iMaxVoices)
1953 {
1954 char szQuery[LSCP_BUFSIZ];
1955
1956 if (iMaxVoices < 1)
1957 return LSCP_FAILED;
1958
1959 sprintf(szQuery, "SET VOICES %d\r\n", iMaxVoices);
1960 return lscp_client_query(pClient, szQuery);
1961 }
1962
1963 /**
1964 * Get global disk streams limit setting:
1965 * @code
1966 * GET STREAMS
1967 * @endcode
1968 * This value reflects the maximum amount of disk streams a sampler
1969 * engine processes simultaniously.
1970 *
1971 * @param pClient Pointer to client instance structure.
1972 *
1973 * @returns The current global maximum amount of disk streams limit
1974 * or a negative value on error (e.g. if sampler doesn't
1975 * support this command).
1976 */
1977 int lscp_get_streams(lscp_client_t *pClient)
1978 {
1979 int iStreams = -1;
1980
1981 if (pClient == NULL)
1982 return -1;
1983
1984 // Lock this section up.
1985 lscp_mutex_lock(pClient->mutex);
1986
1987 if (lscp_client_call(pClient, "GET STREAMS\r\n", 0) == LSCP_OK)
1988 iStreams = atoi(lscp_client_get_result(pClient));
1989
1990 // Unlock this section down.
1991 lscp_mutex_unlock(pClient->mutex);
1992
1993 return iStreams;
1994 }
1995
1996 /**
1997 * Setting global disk streams limit setting:
1998 * @code
1999 * SET STREAMS <max-streams>
2000 * @endcode
2001 * This value reflects the maximum amount of dist streams a sampler
2002 * engine instance processes simultaniously. Note that this value will
2003 * be passed to all sampler engine instances, that is the total amount
2004 * of maximum disk streams on the running system is thus
2005 * @param iMaxStreams multiplied with the current amount of sampler
2006 * engine instances.
2007 *
2008 * @param pClient Pointer to client instance structure.
2009 * @param iMaxStreams Global streams limit setting as positive integer
2010 * value (larger or equal to 0).
2011 *
2012 * @returns LSCP_OK on success, LSCP_FAILED otherwise.
2013 */
2014 lscp_status_t lscp_set_streams(lscp_client_t *pClient, int iMaxStreams)
2015 {
2016 char szQuery[LSCP_BUFSIZ];
2017
2018 if (iMaxStreams < 0)
2019 return LSCP_FAILED;
2020
2021 sprintf(szQuery, "SET STREAMS %d\r\n", iMaxStreams);
2022 return lscp_client_query(pClient, szQuery);
2023 }
2024
2025 /**
2026 * Add an effect send to a sampler channel:
2027 * CREATE FX_SEND <sampler-channel> <midi-ctrl> [<name>]
2028 *
2029 * @param pClient Pointer to client instance structure.
2030 * @param iSamplerChannel Sampler channel number.
2031 * @param iMidiController MIDI controller used to alter the effect,
2032 * usually a number between 0 and 127.
2033 * @param pszName Optional name for the effect send entity,
2034 * does not have to be unique.
2035 *
2036 * @returns The new effect send number identifier, or -1 in case of failure.
2037 */
2038 int lscp_create_fxsend ( lscp_client_t *pClient, int iSamplerChannel, int iMidiController, const char *pszFxName )
2039 {
2040 int iFxSend = -1;
2041 char szQuery[LSCP_BUFSIZ];
2042
2043 if (pClient == NULL)
2044 return -1;
2045 if (iSamplerChannel < 0 || iMidiController < 0 || iMidiController > 127)
2046 return -1;
2047
2048 // Lock this section up.
2049 lscp_mutex_lock(pClient->mutex);
2050
2051 sprintf(szQuery, "CREATE FX_SEND %d %d", iSamplerChannel, iMidiController);
2052
2053 if (pszFxName)
2054 sprintf(szQuery + strlen(szQuery), " '%s'", pszFxName);
2055
2056 strcat(szQuery, "\r\n");
2057
2058 if (lscp_client_call(pClient, szQuery, 0) == LSCP_OK)
2059 iFxSend = atoi(lscp_client_get_result(pClient));
2060
2061 // Unlock this section down.
2062 lscp_mutex_unlock(pClient->mutex);
2063
2064 return iFxSend;
2065 }
2066
2067
2068 /**
2069 * Remove an effect send from a sampler channel:
2070 * DESTROY FX_SEND <sampler-channel> <fx-send-id>
2071 *
2072 * @param pClient Pointer to client instance structure.
2073 * @param iSamplerChannel Sampler channel number.
2074 * @param iFxSend Effect send number.
2075 *
2076 * @returns LSCP_OK on success, LSCP_FAILED otherwise.
2077 */
2078 lscp_status_t lscp_destroy_fxsend ( lscp_client_t *pClient, int iSamplerChannel, int iFxSend )
2079 {
2080 char szQuery[LSCP_BUFSIZ];
2081
2082 if (iSamplerChannel < 0 || iFxSend < 0)
2083 return LSCP_FAILED;
2084
2085 sprintf(szQuery, "DESTROY FX_SEND %d %d\r\n", iSamplerChannel, iFxSend);
2086
2087 return lscp_client_query(pClient, szQuery);
2088 }
2089
2090
2091 /**
2092 * Get amount of effect sends on a sampler channel:
2093 * GET FX_SENDS <sampler-channel>
2094 *
2095 * @param pClient Pointer to client instance structure.
2096 * @param iSamplerChannel Sampler channel number.
2097 *
2098 * @returns The current total number of effect sends of the sampler channel
2099 * on success, -1 otherwise.
2100 */
2101 int lscp_get_fxsends ( lscp_client_t *pClient, int iSamplerChannel )
2102 {
2103 int iFxSends = -1;
2104 char szQuery[LSCP_BUFSIZ];
2105
2106 if (pClient == NULL)
2107 return -1;
2108 if (iSamplerChannel < 0)
2109 return -1;
2110
2111 // Lock this section up.
2112 lscp_mutex_lock(pClient->mutex);
2113
2114 sprintf(szQuery, "GET FX_SENDS %d\r\n", iSamplerChannel);
2115
2116 if (lscp_client_call(pClient, szQuery, 0) == LSCP_OK)
2117 iFxSends = atoi(lscp_client_get_result(pClient));
2118
2119 // Unlock this section doen.
2120 lscp_mutex_unlock(pClient->mutex);
2121
2122 return iFxSends;
2123 }
2124
2125
2126 /**
2127 * List all effect sends on a sampler channel:
2128 * LIST FX_SENDS <sampler-channel>
2129 *
2130 * @param pClient Pointer to client instance structure.
2131 * @param iSamplerChannel Sampler channel number.
2132 *
2133 * @returns An array of the effect sends identifiers as positive integers,
2134 * terminated with -1 on success, NULL otherwise.
2135 */
2136 int *lscp_list_fxsends ( lscp_client_t *pClient, int iSamplerChannel )
2137 {
2138 const char *pszSeps = ",";
2139 char szQuery[LSCP_BUFSIZ];
2140
2141 if (pClient == NULL)
2142 return NULL;
2143
2144 // Lock this section up.
2145 lscp_mutex_lock(pClient->mutex);
2146
2147 if (pClient->fxsends) {
2148 lscp_isplit_destroy(pClient->fxsends);
2149 pClient->fxsends = NULL;
2150 }
2151
2152 sprintf(szQuery, "LIST FX_SENDS %d\r\n", iSamplerChannel);
2153
2154 if (lscp_client_call(pClient, szQuery, 0) == LSCP_OK)
2155 pClient->fxsends = lscp_isplit_create(lscp_client_get_result(pClient), pszSeps);
2156
2157 // Unlock this section down.
2158 lscp_mutex_unlock(pClient->mutex);
2159
2160 return pClient->fxsends;
2161 }
2162
2163
2164 /**
2165 * Getting effect send information
2166 * GET FX_SEND INFO <sampler-channel> <fx-send-id>
2167 *
2168 * @param pClient Pointer to client instance structure.
2169 * @param iSamplerChannel Sampler channel number.
2170 * @param iFxSend Effect send number.
2171 *
2172 * @returns A pointer to a @ref lscp_fxsend_info_t structure, with the
2173 * information of the given FX send, or NULL in case of failure.
2174 */
2175 lscp_fxsend_info_t *lscp_get_fxsend_info ( lscp_client_t *pClient, int iSamplerChannel, int iFxSend )
2176 {
2177 lscp_fxsend_info_t *pFxSendInfo;
2178 char szQuery[LSCP_BUFSIZ];
2179 const char *pszResult;
2180 const char *pszSeps = ":";
2181 const char *pszCrlf = "\r\n";
2182 char *pszToken;
2183 char *pch;
2184
2185 if (pClient == NULL)
2186 return NULL;
2187 if (iSamplerChannel < 0 || iFxSend < 0)
2188 return NULL;
2189
2190 // Lock this section up.
2191 lscp_mutex_lock(pClient->mutex);
2192
2193 pFxSendInfo = &(pClient->fxsend_info);
2194 lscp_fxsend_info_reset(pFxSendInfo);
2195
2196 sprintf(szQuery, "GET FX_SEND INFO %d %d\r\n", iSamplerChannel, iFxSend);
2197 if (lscp_client_call(pClient, szQuery, 1) == LSCP_OK) {
2198 pszResult = lscp_client_get_result(pClient);
2199 pszToken = lscp_strtok((char *) pszResult, pszSeps, &(pch));
2200 while (pszToken) {
2201 if (strcasecmp(pszToken, "NAME") == 0) {
2202 pszToken = lscp_strtok(NULL, pszCrlf, &(pch));
2203 if (pszToken)
2204 lscp_unquote_dup(&(pFxSendInfo->name), &pszToken);
2205 }
2206 else if (strcasecmp(pszToken, "MIDI_CONTROLLER") == 0) {
2207 pszToken = lscp_strtok(NULL, pszCrlf, &(pch));
2208 if (pszToken)
2209 pFxSendInfo->midi_controller = atoi(lscp_ltrim(pszToken));
2210 }
2211 else if (strcasecmp(pszToken, "AUDIO_OUTPUT_ROUTING") == 0) {
2212 pszToken = lscp_strtok(NULL, pszCrlf, &(pch));
2213 if (pszToken) {
2214 if (pFxSendInfo->audio_routing)
2215 lscp_isplit_destroy(pFxSendInfo->audio_routing);
2216 pFxSendInfo->audio_routing = lscp_isplit_create(pszToken, ",");
2217 }
2218 }
2219 else if (strcasecmp(pszToken, "LEVEL") == 0) {
2220 pszToken = lscp_strtok(NULL, pszCrlf, &(pch));
2221 if (pszToken)
2222 pFxSendInfo->level = (float) atof(lscp_ltrim(pszToken));
2223 }
2224 pszToken = lscp_strtok(NULL, pszSeps, &(pch));
2225 }
2226 }
2227 else pFxSendInfo = NULL;
2228
2229 // Unlock this section up.
2230 lscp_mutex_unlock(pClient->mutex);
2231
2232 return pFxSendInfo;
2233 }
2234
2235 /**
2236 * Alter effect send's name:
2237 * @code
2238 * SET FX_SEND NAME <sampler-chan> <fx-send-id> <name>
2239 * @endcode
2240 *
2241 * @param pClient Pointer to client instance structure.
2242 * @param iSamplerChannel Sampler channel number.
2243 * @param iFxSend Effect send number.
2244 * @param pszFxName Effect send's new name.
2245 *
2246 * @returns LSCP_OK on success, LSCP_FAILED otherwise.
2247 */
2248 lscp_status_t lscp_set_fxsend_name ( lscp_client_t *pClient, int iSamplerChannel, int iFxSend, const char *pszFxName )
2249 {
2250 char szQuery[LSCP_BUFSIZ];
2251
2252 if (!pClient || iSamplerChannel < 0 || iFxSend < 0 || !pszFxName)
2253 return LSCP_FAILED;
2254
2255 snprintf(szQuery, LSCP_BUFSIZ, "SET FX_SEND NAME %d %d '%s'\r\n", iSamplerChannel, iFxSend, pszFxName);
2256 return lscp_client_query(pClient, szQuery);
2257 }
2258
2259 /**
2260 * Alter effect send's audio routing:
2261 * SET FX_SEND AUDIO_OUTPUT_CHANNEL <sampler-chan> <fx-send-id>
2262 * <audio-src> <audio-dst>
2263 *
2264 * @param pClient Pointer to client instance structure.
2265 * @param iSamplerChannel Sampler channel number.
2266 * @param iFxSend Effect send number.
2267 * @param iAudioSrc Audio output device channel to be routed from.
2268 * @param iAudioDst Audio output device channel to be routed into.
2269 *
2270 * @returns LSCP_OK on success, LSCP_FAILED otherwise.
2271 */
2272 lscp_status_t lscp_set_fxsend_audio_channel ( lscp_client_t *pClient, int iSamplerChannel, int iFxSend, int iAudioSrc, int iAudioDst )
2273 {
2274 char szQuery[LSCP_BUFSIZ];
2275
2276 if (iSamplerChannel < 0 || iFxSend < 0 || iAudioSrc < 0 || iAudioDst < 0)
2277 return LSCP_FAILED;
2278
2279 sprintf(szQuery, "SET FX_SEND AUDIO_OUTPUT_CHANNEL %d %d %d %d\r\n", iSamplerChannel, iFxSend, iAudioSrc, iAudioDst);
2280 return lscp_client_query(pClient, szQuery);
2281 }
2282
2283
2284 /**
2285 * Alter effect send's MIDI controller:
2286 * SET FX_SEND MIDI_CONTROLLER <sampler-chan> <fx-send-id> <midi-ctrl>
2287 *
2288 * @param pClient Pointer to client instance structure.
2289 * @param iSamplerChannel Sampler channel number.
2290 * @param iFxSend Effect send number.
2291 * @param iMidiController MIDI controller used to alter the effect,
2292 * usually a number between 0 and 127.
2293 *
2294 * @returns LSCP_OK on success, LSCP_FAILED otherwise.
2295 */
2296 lscp_status_t lscp_set_fxsend_midi_controller ( lscp_client_t *pClient, int iSamplerChannel, int iFxSend, int iMidiController )
2297 {
2298 char szQuery[LSCP_BUFSIZ];
2299
2300 if (iSamplerChannel < 0 || iFxSend < 0 || iMidiController < 0 || iMidiController > 127)
2301 return LSCP_FAILED;
2302
2303 sprintf(szQuery, "SET FX_SEND MIDI_CONTROLLER %d %d %d\r\n", iSamplerChannel, iFxSend, iMidiController);
2304 return lscp_client_query(pClient, szQuery);
2305 }
2306
2307
2308 /**
2309 * Alter effect send's audio level:
2310 * SET FX_SEND LEVEL <sampler-chan> <fx-send-id> <level>
2311 *
2312 * @param pClient Pointer to client instance structure.
2313 * @param iSamplerChannel Sampler channel number.
2314 * @param iFxSend Effect send number.
2315 * @param fLevel Effect send volume level.
2316 *
2317 * @returns LSCP_OK on success, LSCP_FAILED otherwise.
2318 */
2319 lscp_status_t lscp_set_fxsend_level ( lscp_client_t *pClient, int iSamplerChannel, int iFxSend, float fLevel )
2320 {
2321 char szQuery[LSCP_BUFSIZ];
2322
2323 if (iSamplerChannel < 0 || iFxSend < 0 || fLevel < 0.0f)
2324 return LSCP_FAILED;
2325
2326 sprintf(szQuery, "SET FX_SEND LEVEL %d %d %f\r\n", iSamplerChannel, iFxSend, fLevel);
2327 return lscp_client_query(pClient, szQuery);
2328 }
2329
2330
2331 /**
2332 * Create a new MIDI instrument map:
2333 * ADD MIDI_INSTRUMENT_MAP [<name>]
2334 *
2335 * @param pClient Pointer to client instance structure.
2336 * @param pszMapName MIDI instrument map name (optional)
2337 *
2338 * @returns The new MIDI instrument map number identifier,
2339 * or -1 in case of failure.
2340 */
2341 int lscp_add_midi_instrument_map ( lscp_client_t *pClient, const char *pszMapName )
2342 {
2343 int iMidiMap = -1;
2344 char szQuery[LSCP_BUFSIZ];
2345
2346 if (pClient == NULL)
2347 return -1;
2348
2349 // Lock this section up.
2350 lscp_mutex_lock(pClient->mutex);
2351
2352 strcpy(szQuery, "ADD MIDI_INSTRUMENT_MAP");
2353
2354 if (pszMapName)
2355 sprintf(szQuery + strlen(szQuery), " '%s'", pszMapName);
2356
2357 strcat(szQuery, "\r\n");
2358
2359 if (lscp_client_call(pClient, szQuery, 0) == LSCP_OK)
2360 iMidiMap = atoi(lscp_client_get_result(pClient));
2361
2362 // Unlock this section down.
2363 lscp_mutex_unlock(pClient->mutex);
2364
2365 return iMidiMap;
2366 }
2367
2368
2369 /**
2370 * Delete one particular or all MIDI instrument maps:
2371 * REMOVE MIDI_INSTRUMENT_MAP <midi-map>
2372 *
2373 * @param pClient Pointer to client instance structure.
2374 * @param iMidiMap MIDI instrument map number.
2375 *
2376 * @returns LSCP_OK on success, LSCP_FAILED otherwise.
2377 */
2378 lscp_status_t lscp_remove_midi_instrument_map ( lscp_client_t *pClient, int iMidiMap )
2379 {
2380 char szQuery[LSCP_BUFSIZ];
2381
2382 if (iMidiMap < 0)
2383 return LSCP_FAILED;
2384
2385 sprintf(szQuery, "REMOVE MIDI_INSTRUMENT_MAP %d\r\n", iMidiMap);
2386
2387 return lscp_client_query(pClient, szQuery);
2388 }
2389
2390
2391 /**
2392 * Get amount of existing MIDI instrument maps:
2393 * GET MIDI_INSTRUMENT_MAPS
2394 *
2395 * @param pClient Pointer to client instance structure.
2396 *
2397 * @returns The current total number of MIDI instrument maps
2398 * on success, -1 otherwise.
2399 */
2400 int lscp_get_midi_instrument_maps ( lscp_client_t *pClient )
2401 {
2402 int iMidiMaps = -1;
2403
2404 if (pClient == NULL)
2405 return -1;
2406
2407 // Lock this section up.
2408 lscp_mutex_lock(pClient->mutex);
2409
2410 if (lscp_client_call(pClient, "GET MIDI_INSTRUMENT_MAPS\r\n", 0) == LSCP_OK)
2411 iMidiMaps = atoi(lscp_client_get_result(pClient));
2412
2413 // Unlock this section doen.
2414 lscp_mutex_unlock(pClient->mutex);
2415
2416 return iMidiMaps;
2417 }
2418
2419
2420 /**
2421 * Getting all created MIDI instrument maps:
2422 * LIST MIDI_INSTRUMENT_MAPS
2423 *
2424 * @param pClient Pointer to client instance structure.
2425 *
2426 * @returns An array of the MIDI instrument map identifiers as positive
2427 * integers, terminated with -1 on success, NULL otherwise.
2428 */
2429 int *lscp_list_midi_instrument_maps ( lscp_client_t *pClient )
2430 {
2431 const char *pszSeps = ",";
2432
2433 if (pClient == NULL)
2434 return NULL;
2435
2436 // Lock this section up.
2437 lscp_mutex_lock(pClient->mutex);
2438
2439 if (pClient->midi_maps) {
2440 lscp_isplit_destroy(pClient->midi_maps);
2441 pClient->midi_maps = NULL;
2442 }
2443
2444 if (lscp_client_call(pClient, "LIST MIDI_INSTRUMENT_MAPS\r\n", 0) == LSCP_OK)
2445 pClient->midi_maps = lscp_isplit_create(lscp_client_get_result(pClient), pszSeps);
2446
2447 // Unlock this section down.
2448 lscp_mutex_unlock(pClient->mutex);
2449
2450 return pClient->midi_maps;
2451 }
2452
2453
2454 /**
2455 * Getting a MIDI instrument map name:
2456 * GET MIDI_INSTRUMENT_MAP INFO <midi-map>
2457 *
2458 * @param pClient Pointer to client instance structure.
2459 * @param iMidiMap MIDI instrument map number.
2460 *
2461 * @returns The MIDI instrument map name on success, NULL on failure.
2462 */
2463 const char *lscp_get_midi_instrument_map_name ( lscp_client_t *pClient, int iMidiMap )
2464 {
2465 char szQuery[LSCP_BUFSIZ];
2466 const char *pszResult;
2467 const char *pszSeps = ":";
2468 const char *pszCrlf = "\r\n";
2469 char *pszToken;
2470 char *pch;
2471
2472 if (pClient == NULL)
2473 return NULL;
2474 if (iMidiMap < 0)
2475 return NULL;
2476
2477 // Lock this section up.
2478 lscp_mutex_lock(pClient->mutex);
2479
2480 if (pClient->midi_map_name) {
2481 free(pClient->midi_map_name);
2482 pClient->midi_map_name = NULL;
2483 }
2484
2485 sprintf(szQuery, "GET MIDI_INSTRUMENT_MAP INFO %d\r\n", iMidiMap);
2486 if (lscp_client_call(pClient, szQuery, 1) == LSCP_OK) {
2487 pszResult = lscp_client_get_result(pClient);
2488 pszToken = lscp_strtok((char *) pszResult, pszSeps, &(pch));
2489 while (pszToken) {
2490 if (strcasecmp(pszToken, "NAME") == 0) {
2491 pszToken = lscp_strtok(NULL, pszCrlf, &(pch));
2492 if (pszToken)
2493 lscp_unquote_dup(&(pClient->midi_map_name), &pszToken);
2494 }
2495 pszToken = lscp_strtok(NULL, pszSeps, &(pch));
2496 }
2497 }
2498
2499 // Unlock this section down.
2500 lscp_mutex_unlock(pClient->mutex);
2501
2502 return pClient->midi_map_name;
2503 }
2504
2505
2506 /**
2507 * Renaming a MIDI instrument map:
2508 * SET MIDI_INSTRUMENT_MAP NAME <midi-map> <map-name>
2509 *
2510 * @param pClient Pointer to client instance structure.
2511 * @param iMidiMap MIDI instrument map number.
2512 * @param pszMapName MIDI instrument map name.
2513 *
2514 * @returns LSCP_OK on success, LSCP_FAILED otherwise.
2515 */
2516 lscp_status_t lscp_set_midi_instrument_map_name ( lscp_client_t *pClient, int iMidiMap, const char *pszMapName )
2517 {
2518 char szQuery[LSCP_BUFSIZ];
2519
2520 if (iMidiMap < 0)
2521 return LSCP_FAILED;
2522 if (pszMapName == NULL)
2523 return LSCP_FAILED;
2524
2525 sprintf(szQuery, "SET MIDI_INSTRUMENT_MAP NAME %d '%s'\r\n",
2526 iMidiMap, pszMapName);
2527
2528 return lscp_client_query(pClient, szQuery);
2529 }
2530
2531
2532 /**
2533 * Create or replace a MIDI instrumnet map entry:
2534 * MAP MIDI_INSTRUMENT <midi-map> <midi-bank> <midi-prog>
2535 * <engine-name> <filename> <instr-index> <volume> [<load-mode> [<name>]}
2536 *
2537 * @param pClient Pointer to client instance structure.
2538 * @param pMidiInstr MIDI instrument bank and program parameter key.
2539 * @param pszEngineName Engine name.
2540 * @param pszFileName Instrument file name.
2541 * @param iInstrIndex Instrument index number.
2542 * @param fVolume Reflects the master volume of the instrument as
2543 * a positive floating point number, where a value
2544 * less than 1.0 for attenuation, and greater than
2545 * 1.0 for amplification.
2546 * @param load_mode Instrument load life-time strategy, either
2547 * @ref LSCP_LOAD_DEFAULT, or
2548 * @ref LSCP_LOAD_ON_DEMAND, or
2549 * @ref LSCP_LOAD_ON_DEMAND_HOLD, or
2550 * @ref LSCP_LOAD_PERSISTENT.
2551 * @param pszName Instrument custom name for the map entry (optional).
2552 *
2553 * @returns LSCP_OK on success, LSCP_FAILED otherwise.
2554 */
2555 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 )
2556 {
2557 char szQuery[LSCP_BUFSIZ];
2558
2559 if (pMidiInstr->map < 0)
2560 return LSCP_FAILED;
2561 if (pMidiInstr->bank < 0 || pMidiInstr->bank > 16383)
2562 return LSCP_FAILED;
2563 if (pMidiInstr->prog < 0 || pMidiInstr->prog > 127)
2564 return LSCP_FAILED;
2565 if (pszEngineName == NULL || pszFileName == NULL)
2566 return LSCP_FAILED;
2567
2568 if (fVolume < 0.0f)
2569 fVolume = 1.0f;
2570
2571 sprintf(szQuery, "MAP MIDI_INSTRUMENT %d %d %d %s '%s' %d %g",
2572 pMidiInstr->map, pMidiInstr->bank, pMidiInstr->prog,
2573 pszEngineName, pszFileName, iInstrIndex, fVolume);
2574
2575 switch (load_mode) {
2576 case LSCP_LOAD_PERSISTENT:
2577 strcat(szQuery, " PERSISTENT");
2578 break;
2579 case LSCP_LOAD_ON_DEMAND_HOLD:
2580 strcat(szQuery, " ON_DEMAND_HOLD");
2581 break;
2582 case LSCP_LOAD_ON_DEMAND:
2583 strcat(szQuery, " ON_DEMAND");
2584 break;
2585 case LSCP_LOAD_DEFAULT:
2586 default:
2587 break;
2588 }
2589
2590 if (pszName)
2591 sprintf(szQuery + strlen(szQuery), " '%s'", pszName);
2592
2593 strcat(szQuery, "\r\n");
2594
2595 return lscp_client_query(pClient, szQuery);
2596 }
2597
2598
2599 /**
2600 * Remove an entry from the MIDI instrument map:
2601 * UNMAP MIDI_INSTRUMENT <midi-map> <midi-bank> <midi-prog>
2602 *
2603 * @param pClient Pointer to client instance structure.
2604 * @param pMidiInstr MIDI instrument bank and program parameter key.
2605 *
2606 * @returns LSCP_OK on success, LSCP_FAILED otherwise.
2607 */
2608 lscp_status_t lscp_unmap_midi_instrument ( lscp_client_t *pClient, lscp_midi_instrument_t *pMidiInstr )
2609 {
2610 char szQuery[LSCP_BUFSIZ];
2611
2612 if (pMidiInstr->map < 0)
2613 return LSCP_FAILED;
2614 if (pMidiInstr->bank < 0 || pMidiInstr->bank > 16383)
2615 return LSCP_FAILED;
2616 if (pMidiInstr->prog < 0 || pMidiInstr->prog > 127)
2617 return LSCP_FAILED;
2618
2619 sprintf(szQuery, "UNMAP MIDI_INSTRUMENT %d %d %d\r\n",
2620 pMidiInstr->map, pMidiInstr->bank, pMidiInstr->prog);
2621
2622 return lscp_client_query(pClient, szQuery);
2623 }
2624
2625
2626 /**
2627 * Get the total count of MIDI instrument map entries:
2628 * GET MIDI_INSTRUMENTS ALL|<midi-map>
2629 *
2630 * @param pClient Pointer to client instance structure.
2631 * @param iMidiMap MIDI instrument map number, or @ref LSCP_MIDI_MAP_ALL .
2632 *
2633 * @returns The current total number of MIDI instrument map entries
2634 * on success, -1 otherwise.
2635 */
2636 int lscp_get_midi_instruments ( lscp_client_t *pClient, int iMidiMap )
2637 {
2638 int iInstruments = -1;
2639 char szQuery[LSCP_BUFSIZ];
2640
2641 if (pClient == NULL)
2642 return -1;
2643
2644 // Lock this section up.
2645 lscp_mutex_lock(pClient->mutex);
2646
2647 strcpy(szQuery, "GET MIDI_INSTRUMENTS ");
2648
2649 if (iMidiMap < 0)
2650 strcat(szQuery, "ALL");
2651 else
2652 sprintf(szQuery + strlen(szQuery), "%d", iMidiMap);
2653
2654 strcat(szQuery, "\r\n");
2655
2656 if (lscp_client_call(pClient, szQuery, 0) == LSCP_OK)
2657 iInstruments = atoi(lscp_client_get_result(pClient));
2658
2659 // Unlock this section down.
2660 lscp_mutex_unlock(pClient->mutex);
2661
2662 return iInstruments;
2663 }
2664
2665
2666 /**
2667 * Getting indeces of all MIDI instrument map entries:
2668 * LIST MIDI_INSTRUMENTS ALL|<midi-map>
2669 *
2670 * @param pClient Pointer to client instance structure.
2671 * @param iMidiMap MIDI instrument map number, or @ref LSCP_MIDI_MAP_ALL .
2672 *
2673 * @returns An array of @ref lscp_midi_instrument_t, terminated with the
2674 * {-1,-1,-1} triplet, NULL otherwise.
2675 */
2676 lscp_midi_instrument_t *lscp_list_midi_instruments ( lscp_client_t *pClient, int iMidiMap )
2677 {
2678 char szQuery[LSCP_BUFSIZ];
2679
2680 if (pClient == NULL)
2681 return NULL;
2682
2683 // Lock this section up.
2684 lscp_mutex_lock(pClient->mutex);
2685
2686 if (pClient->midi_instruments) {
2687 lscp_midi_instruments_destroy(pClient->midi_instruments);
2688 pClient->midi_instruments = NULL;
2689 }
2690
2691 strcpy(szQuery, "LIST MIDI_INSTRUMENTS ");
2692
2693 if (iMidiMap < 0)
2694 strcat(szQuery, "ALL");
2695 else
2696 sprintf(szQuery + strlen(szQuery), "%d", iMidiMap);
2697
2698 strcat(szQuery, "\r\n");
2699
2700 if (lscp_client_call(pClient, szQuery, 0) == LSCP_OK)
2701 pClient->midi_instruments = lscp_midi_instruments_create(lscp_client_get_result(pClient));
2702
2703 // Unlock this section down.
2704 lscp_mutex_unlock(pClient->mutex);
2705
2706 return pClient->midi_instruments;
2707 }
2708
2709
2710 /**
2711 * Getting information about a MIDI instrument map entry:
2712 * GET MIDI_INSTRUMENT INFO <midi-map> <midi-bank> <midi-prog>
2713 *
2714 * @param pClient Pointer to client instance structure.
2715 * @param pMidiInstr MIDI instrument bank and program parameter key.
2716 *
2717 * @returns A pointer to a @ref lscp_midi_instrument_info_t structure,
2718 * with all the information of the given MIDI instrument map entry,
2719 * or NULL in case of failure.
2720 */
2721 lscp_midi_instrument_info_t *lscp_get_midi_instrument_info ( lscp_client_t *pClient, lscp_midi_instrument_t *pMidiInstr )
2722 {
2723 lscp_midi_instrument_info_t *pInstrInfo;
2724 char szQuery[LSCP_BUFSIZ];
2725 const char *pszResult;
2726 const char *pszSeps = ":";
2727 const char *pszCrlf = "\r\n";
2728 char *pszToken;
2729 char *pch;
2730
2731 if (pClient == NULL)
2732 return NULL;
2733 if (pMidiInstr->map < 0)
2734 return NULL;
2735 if (pMidiInstr->bank < 0 || pMidiInstr->bank > 16383)
2736 return NULL;
2737 if (pMidiInstr->prog < 0 || pMidiInstr->prog > 127)
2738 return NULL;
2739
2740 // Lock this section up.
2741 lscp_mutex_lock(pClient->mutex);
2742
2743 pInstrInfo = &(pClient->midi_instrument_info);
2744 lscp_midi_instrument_info_reset(pInstrInfo);
2745
2746 sprintf(szQuery, "GET MIDI_INSTRUMENT INFO %d %d %d\r\n",
2747 pMidiInstr->map, pMidiInstr->bank, pMidiInstr->prog);
2748 if (lscp_client_call(pClient, szQuery, 1) == LSCP_OK) {
2749 pszResult = lscp_client_get_result(pClient);
2750 pszToken = lscp_strtok((char *) pszResult, pszSeps, &(pch));
2751 while (pszToken) {
2752 if (strcasecmp(pszToken, "NAME") == 0) {
2753 pszToken = lscp_strtok(NULL, pszCrlf, &(pch));
2754 if (pszToken)
2755 lscp_unquote_dup(&(pInstrInfo->name), &pszToken);
2756 }
2757 else if (strcasecmp(pszToken, "ENGINE_NAME") == 0) {
2758 pszToken = lscp_strtok(NULL, pszCrlf, &(pch));
2759 if (pszToken)
2760 lscp_unquote_dup(&(pInstrInfo->engine_name), &pszToken);
2761 }
2762 else if (strcasecmp(pszToken, "INSTRUMENT_FILE") == 0) {
2763 pszToken = lscp_strtok(NULL, pszCrlf, &(pch));
2764 if (pszToken)
2765 lscp_unquote_dup(&(pInstrInfo->instrument_file), &pszToken);
2766 }
2767 else if (strcasecmp(pszToken, "INSTRUMENT_NR") == 0) {
2768 pszToken = lscp_strtok(NULL, pszCrlf, &(pch));
2769 if (pszToken)
2770 pInstrInfo->instrument_nr = atoi(lscp_ltrim(pszToken));
2771 }
2772 else if (strcasecmp(pszToken, "INSTRUMENT_NAME") == 0) {
2773 pszToken = lscp_strtok(NULL, pszCrlf, &(pch));
2774 if (pszToken)
2775 lscp_unquote_dup(&(pInstrInfo->instrument_name), &pszToken);
2776 }
2777 else if (strcasecmp(pszToken, "LOAD_MODE") == 0) {
2778 pszToken = lscp_strtok(NULL, pszCrlf, &(pch));
2779 if (pszToken) {
2780 pszToken = lscp_ltrim(pszToken);
2781 if (strcasecmp(pszToken, "ON_DEMAND") == 0)
2782 pInstrInfo->load_mode = LSCP_LOAD_ON_DEMAND;
2783 else
2784 if (strcasecmp(pszToken, "ON_DEMAND_HOLD") == 0)
2785 pInstrInfo->load_mode = LSCP_LOAD_ON_DEMAND_HOLD;
2786 else
2787 if (strcasecmp(pszToken, "PERSISTENT") == 0)
2788 pInstrInfo->load_mode = LSCP_LOAD_PERSISTENT;
2789 else
2790 pInstrInfo->load_mode = LSCP_LOAD_DEFAULT;
2791 }
2792 }
2793 else if (strcasecmp(pszToken, "VOLUME") == 0) {
2794 pszToken = lscp_strtok(NULL, pszCrlf, &(pch));
2795 if (pszToken)
2796 pInstrInfo->volume = (float) atof(lscp_ltrim(pszToken));
2797 }
2798 pszToken = lscp_strtok(NULL, pszSeps, &(pch));
2799 }
2800 }
2801 else pInstrInfo = NULL;
2802
2803 // Unlock this section down.
2804 lscp_mutex_unlock(pClient->mutex);
2805
2806 return pInstrInfo;
2807 }
2808
2809
2810 /**
2811 * Clear the MIDI instrumnet map:
2812 * CLEAR MIDI_INSTRUMENTS ALL|<midi-map>
2813 *
2814 * @param pClient Pointer to client instance structure.
2815 * @param iMidiMap MIDI instrument map number, or @ref LSCP_MIDI_MAP_ALL .
2816 *
2817 * @returns LSCP_OK on success, LSCP_FAILED otherwise.
2818 */
2819 lscp_status_t lscp_clear_midi_instruments ( lscp_client_t *pClient, int iMidiMap )
2820 {
2821 char szQuery[LSCP_BUFSIZ];
2822
2823 strcpy(szQuery, "CLEAR MIDI_INSTRUMENTS ");
2824
2825 if (iMidiMap < 0)
2826 strcat(szQuery, "ALL");
2827 else
2828 sprintf(szQuery + strlen(szQuery), "%d", iMidiMap);
2829
2830 strcat(szQuery, "\r\n");
2831
2832 return lscp_client_query(pClient, szQuery);
2833 }
2834
2835 /**
2836 * Open an instrument editor application for the instrument
2837 * on the given sampler channel:
2838 * EDIT CHANNEL INSTRUMENT <sampler-channel>
2839 *
2840 * @param pClient Pointer to client instance structure.
2841 * @param iSamplerChannel Sampler Channel.
2842 *
2843 * @returns LSCP_OK on success, LSCP_FAILED otherwise.
2844 */
2845 lscp_status_t lscp_edit_channel_instrument ( lscp_client_t *pClient, int iSamplerChannel )
2846 {
2847 char szQuery[LSCP_BUFSIZ];
2848
2849 if (iSamplerChannel < 0)
2850 return LSCP_FAILED;
2851
2852 sprintf(szQuery, "EDIT CHANNEL INSTRUMENT %d\r\n", iSamplerChannel);
2853
2854 return lscp_client_query(pClient, szQuery);
2855 }
2856
2857
2858 // end of client.c

  ViewVC Help
Powered by ViewVC