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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1689 - (show annotations) (download)
Thu Feb 14 17:05:51 2008 UTC (16 years, 1 month ago) by schoenebeck
File MIME type: text/plain
File size: 82290 byte(s)
* added new LSCP event "CHANNEL_MIDI" (CAUTION: behavior change for
  lscp_client_subscribe() and lscp_client_unsubscribe!)
* bumped version to 0.5.5.4

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

  ViewVC Help
Powered by ViewVC