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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1666 - (show annotations) (download)
Mon Feb 4 14:06:07 2008 UTC (16 years, 1 month ago) by schoenebeck
File MIME type: text/plain
File size: 80594 byte(s)
- fixed bug of previous commit

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

  ViewVC Help
Powered by ViewVC