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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 963 - (show annotations) (download)
Sun Dec 3 18:30:04 2006 UTC (17 years, 3 months ago) by capela
File MIME type: text/plain
File size: 57881 byte(s)
* MIDI instrument mapping fixed, previously missing
  the regular ON_DEMAND load mode.

* Server error reporting is now effective; all server
  numerical error and warning codes are added to 100,
  thus giving a proper non-zero lscp_client_get_errno()
  return value.

1 // client.c
2 //
3 /****************************************************************************
4 liblscp - LinuxSampler Control Protocol API
5 Copyright (C) 2004-2006, 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->midi_instruments = NULL;
331 lscp_driver_info_init(&(pClient->audio_driver_info));
332 lscp_driver_info_init(&(pClient->midi_driver_info));
333 lscp_device_info_init(&(pClient->audio_device_info));
334 lscp_device_info_init(&(pClient->midi_device_info));
335 lscp_param_info_init(&(pClient->audio_param_info));
336 lscp_param_info_init(&(pClient->midi_param_info));
337 lscp_device_port_info_init(&(pClient->audio_channel_info));
338 lscp_device_port_info_init(&(pClient->midi_port_info));
339 lscp_param_info_init(&(pClient->audio_channel_param_info));
340 lscp_param_info_init(&(pClient->midi_port_param_info));
341 lscp_server_info_init(&(pClient->server_info));
342 lscp_engine_info_init(&(pClient->engine_info));
343 lscp_channel_info_init(&(pClient->channel_info));
344 lscp_midi_instrument_info_init(&(pClient->midi_instrument_info));
345 // Initialize error stuff.
346 pClient->pszResult = NULL;
347 pClient->iErrno = -1;
348 // Stream usage stuff.
349 pClient->buffer_fill = NULL;
350 pClient->iStreamCount = 0;
351 // Default timeout value.
352 pClient->iTimeout = LSCP_TIMEOUT_MSECS;
353 pClient->iTimeoutCount = 0;
354
355 // Initialize the transaction mutex.
356 lscp_mutex_init(pClient->mutex);
357 lscp_cond_init(pClient->cond);
358
359 // Finally we've some success...
360 return pClient;
361 }
362
363
364 /**
365 * Wait for a client instance to terminate graciously.
366 *
367 * @param pClient Pointer to client instance structure.
368 */
369 lscp_status_t lscp_client_join ( lscp_client_t *pClient )
370 {
371 if (pClient == NULL)
372 return LSCP_FAILED;
373
374 #ifdef DEBUG
375 fprintf(stderr, "lscp_client_join: pClient=%p.\n", pClient);
376 #endif
377
378 // lscp_socket_agent_join(&(pClient->evt));
379 lscp_socket_agent_join(&(pClient->cmd));
380
381 return LSCP_OK;
382 }
383
384
385 /**
386 * Terminate and destroy a client instance.
387 *
388 * @param pClient Pointer to client instance structure.
389 *
390 * @returns LSCP_OK on success, LSCP_FAILED otherwise.
391 */
392 lscp_status_t lscp_client_destroy ( lscp_client_t *pClient )
393 {
394 if (pClient == NULL)
395 return LSCP_FAILED;
396
397 #ifdef DEBUG
398 fprintf(stderr, "lscp_client_destroy: pClient=%p.\n", pClient);
399 #endif
400
401 // Lock this section up.
402 lscp_mutex_lock(pClient->mutex);
403
404 // Free up all cached members.
405 lscp_midi_instrument_info_free(&(pClient->midi_instrument_info));
406 lscp_channel_info_free(&(pClient->channel_info));
407 lscp_engine_info_free(&(pClient->engine_info));
408 lscp_server_info_free(&(pClient->server_info));
409 lscp_param_info_free(&(pClient->midi_port_param_info));
410 lscp_param_info_free(&(pClient->audio_channel_param_info));
411 lscp_device_port_info_free(&(pClient->midi_port_info));
412 lscp_device_port_info_free(&(pClient->audio_channel_info));
413 lscp_param_info_free(&(pClient->midi_param_info));
414 lscp_param_info_free(&(pClient->audio_param_info));
415 lscp_device_info_free(&(pClient->midi_device_info));
416 lscp_device_info_free(&(pClient->audio_device_info));
417 lscp_driver_info_free(&(pClient->midi_driver_info));
418 lscp_driver_info_free(&(pClient->audio_driver_info));
419 // Free available engine table.
420 lscp_szsplit_destroy(pClient->audio_drivers);
421 lscp_szsplit_destroy(pClient->midi_drivers);
422 lscp_isplit_destroy(pClient->audio_devices);
423 lscp_isplit_destroy(pClient->midi_devices);
424 lscp_szsplit_destroy(pClient->engines);
425 lscp_isplit_destroy(pClient->channels);
426 lscp_midi_instruments_destroy(pClient->midi_instruments);
427 // Make them null.
428 pClient->audio_drivers = NULL;
429 pClient->midi_drivers = NULL;
430 pClient->audio_devices = NULL;
431 pClient->midi_devices = NULL;
432 pClient->engines = NULL;
433 pClient->channels = NULL;
434 pClient->midi_instruments = NULL;
435 // Free result error stuff.
436 lscp_client_set_result(pClient, NULL, 0);
437 // Free stream usage stuff.
438 if (pClient->buffer_fill)
439 free(pClient->buffer_fill);
440 pClient->buffer_fill = NULL;
441 pClient->iStreamCount = 0;
442 pClient->iTimeout = 0;
443
444 // Free socket agents.
445 lscp_socket_agent_free(&(pClient->evt));
446 lscp_socket_agent_free(&(pClient->cmd));
447
448 // Last but not least, free good ol'transaction mutex.
449 lscp_mutex_unlock(pClient->mutex);
450 lscp_mutex_destroy(pClient->mutex);
451 lscp_cond_destroy(pClient->cond);
452
453 free(pClient);
454
455 return LSCP_OK;
456 }
457
458
459 /**
460 * Set the client transaction timeout interval.
461 *
462 * @param pClient Pointer to client instance structure.
463 * @param iTimeout Transaction timeout in milliseconds.
464 *
465 * @returns LSCP_OK on success, LSCP_FAILED otherwise.
466 */
467 lscp_status_t lscp_client_set_timeout ( lscp_client_t *pClient, int iTimeout )
468 {
469 if (pClient == NULL)
470 return LSCP_FAILED;
471 if (iTimeout < 0)
472 return LSCP_FAILED;
473
474 pClient->iTimeout = iTimeout;
475 return LSCP_OK;
476 }
477
478
479 /**
480 * Get the client transaction timeout interval.
481 *
482 * @param pClient Pointer to client instance structure.
483 *
484 * @returns The current timeout value milliseconds, -1 in case of failure.
485 */
486 int lscp_client_get_timeout ( lscp_client_t *pClient )
487 {
488 if (pClient == NULL)
489 return -1;
490
491 return pClient->iTimeout;
492 }
493
494
495 //-------------------------------------------------------------------------
496 // Client common protocol functions.
497
498 /**
499 * Submit a command query line string to the server. The query string
500 * must be cr/lf and null terminated. Besides the return code, the
501 * specific server response to the command request is made available
502 * by the @ref lscp_client_get_result and @ref lscp_client_get_errno
503 * function calls.
504 *
505 * @param pClient Pointer to client instance structure.
506 * @param pszQuery Command request line to be sent to server,
507 * must be cr/lf and null terminated.
508 *
509 * @returns LSCP_OK on success, LSCP_FAILED otherwise.
510 */
511 lscp_status_t lscp_client_query ( lscp_client_t *pClient, const char *pszQuery )
512 {
513 lscp_status_t ret;
514
515 // Lock this section up.
516 lscp_mutex_lock(pClient->mutex);
517
518 // Just make the now guarded call.
519 ret = lscp_client_call(pClient, pszQuery, 0);
520
521 // Unlock this section down.
522 lscp_mutex_unlock(pClient->mutex);
523
524 return ret;
525 }
526
527 /**
528 * Get the last received result string. In case of error or warning,
529 * this is the text of the error or warning message issued.
530 *
531 * @param pClient Pointer to client instance structure.
532 *
533 * @returns A pointer to the literal null-terminated result string as
534 * of the last command request.
535 */
536 const char *lscp_client_get_result ( lscp_client_t *pClient )
537 {
538 if (pClient == NULL)
539 return NULL;
540
541 return pClient->pszResult;
542 }
543
544
545 /**
546 * Get the last error/warning number received.
547 *
548 * @param pClient Pointer to client instance structure.
549 *
550 * @returns The numerical value of the last error or warning
551 * response code received.
552 */
553 int lscp_client_get_errno ( lscp_client_t *pClient )
554 {
555 if (pClient == NULL)
556 return -1;
557
558 return pClient->iErrno;
559 }
560
561
562 //-------------------------------------------------------------------------
563 // Client registration protocol functions.
564
565 /**
566 * Register frontend for receiving event messages:
567 * SUBSCRIBE CHANNEL_COUNT | VOICE_COUNT | STREAM_COUNT | BUFFER_FILL
568 * | CHANNEL_INFO | MISCELLANEOUS
569 *
570 * @param pClient Pointer to client instance structure.
571 * @param events Bit-wise OR'ed event flags to subscribe.
572 *
573 * @returns LSCP_OK on success, LSCP_FAILED otherwise.
574 */
575 lscp_status_t lscp_client_subscribe ( lscp_client_t *pClient, lscp_event_t events )
576 {
577 lscp_status_t ret = LSCP_FAILED;
578
579 if (pClient == NULL)
580 return LSCP_FAILED;
581
582 // Lock this section up.
583 lscp_mutex_lock(pClient->mutex);
584
585 // If applicable, start the alternate connection...
586 if (pClient->events == LSCP_EVENT_NONE)
587 ret = _lscp_client_evt_connect(pClient);
588
589 // Send the subscription commands.
590 if (ret == LSCP_OK && (events & LSCP_EVENT_CHANNEL_COUNT))
591 ret = _lscp_client_evt_request(pClient, 1, LSCP_EVENT_CHANNEL_COUNT);
592 if (ret == LSCP_OK && (events & LSCP_EVENT_VOICE_COUNT))
593 ret = _lscp_client_evt_request(pClient, 1, LSCP_EVENT_VOICE_COUNT);
594 if (ret == LSCP_OK && (events & LSCP_EVENT_STREAM_COUNT))
595 ret = _lscp_client_evt_request(pClient, 1, LSCP_EVENT_STREAM_COUNT);
596 if (ret == LSCP_OK && (events & LSCP_EVENT_BUFFER_FILL))
597 ret = _lscp_client_evt_request(pClient, 1, LSCP_EVENT_BUFFER_FILL);
598 if (ret == LSCP_OK && (events & LSCP_EVENT_CHANNEL_INFO))
599 ret = _lscp_client_evt_request(pClient, 1, LSCP_EVENT_CHANNEL_INFO);
600 if (ret == LSCP_OK && (events & LSCP_EVENT_MISCELLANEOUS))
601 ret = _lscp_client_evt_request(pClient, 1, LSCP_EVENT_MISCELLANEOUS);
602
603 // Unlock this section down.
604 lscp_mutex_unlock(pClient->mutex);
605
606 return ret;
607 }
608
609
610 /**
611 * Deregister frontend from receiving UDP event messages anymore:
612 * SUBSCRIBE CHANNEL_COUNT | VOICE_COUNT | STREAM_COUNT | BUFFER_FILL
613 * | CHANNEL_INFO | MISCELLANEOUS
614 *
615 * @param pClient Pointer to client instance structure.
616 * @param events Bit-wise OR'ed event flags to unsubscribe.
617 *
618 * @returns LSCP_OK on success, LSCP_FAILED otherwise.
619 */
620 lscp_status_t lscp_client_unsubscribe ( lscp_client_t *pClient, lscp_event_t events )
621 {
622 lscp_status_t ret = LSCP_OK;
623
624 if (pClient == NULL)
625 return LSCP_FAILED;
626
627 // Lock this section up.
628 lscp_mutex_lock(pClient->mutex);
629
630 // Send the unsubscription commands.
631 if (ret == LSCP_OK && (events & LSCP_EVENT_CHANNEL_COUNT))
632 ret = _lscp_client_evt_request(pClient, 0, LSCP_EVENT_CHANNEL_COUNT);
633 if (ret == LSCP_OK && (events & LSCP_EVENT_VOICE_COUNT))
634 ret = _lscp_client_evt_request(pClient, 0, LSCP_EVENT_VOICE_COUNT);
635 if (ret == LSCP_OK && (events & LSCP_EVENT_STREAM_COUNT))
636 ret = _lscp_client_evt_request(pClient, 0, LSCP_EVENT_STREAM_COUNT);
637 if (ret == LSCP_OK && (events & LSCP_EVENT_BUFFER_FILL))
638 ret = _lscp_client_evt_request(pClient, 0, LSCP_EVENT_BUFFER_FILL);
639 if (ret == LSCP_OK && (events & LSCP_EVENT_CHANNEL_INFO))
640 ret = _lscp_client_evt_request(pClient, 0, LSCP_EVENT_CHANNEL_INFO);
641 if (ret == LSCP_OK && (events & LSCP_EVENT_MISCELLANEOUS))
642 ret = _lscp_client_evt_request(pClient, 0, LSCP_EVENT_MISCELLANEOUS);
643
644 // If necessary, close the alternate connection...
645 if (pClient->events == LSCP_EVENT_NONE)
646 lscp_socket_agent_free(&(pClient->evt));
647
648 // Unlock this section down.
649 lscp_mutex_unlock(pClient->mutex);
650
651 return ret;
652 }
653
654
655 /**
656 * Getting current subscribed events.
657 *
658 * @param pClient Pointer to client instance structure.
659 *
660 * @returns The current subscrived bit-wise OR'ed event flags.
661 */
662 lscp_event_t lscp_client_get_events ( lscp_client_t *pClient )
663 {
664 if (pClient == NULL)
665 return LSCP_EVENT_NONE;
666
667 return pClient->events;
668 }
669
670
671 //-------------------------------------------------------------------------
672 // Client command protocol functions.
673
674 /**
675 * Loading an instrument:
676 * LOAD INSTRUMENT <filename> <instr-index> <sampler-channel>
677 *
678 * @param pClient Pointer to client instance structure.
679 * @param pszFileName Instrument file name.
680 * @param iInstrIndex Instrument index number.
681 * @param iSamplerChannel Sampler Channel.
682 *
683 * @returns LSCP_OK on success, LSCP_FAILED otherwise.
684 */
685 lscp_status_t lscp_load_instrument ( lscp_client_t *pClient, const char *pszFileName, int iInstrIndex, int iSamplerChannel )
686 {
687 char szQuery[LSCP_BUFSIZ];
688
689 if (pszFileName == NULL || iSamplerChannel < 0)
690 return LSCP_FAILED;
691
692 sprintf(szQuery, "LOAD INSTRUMENT '%s' %d %d\r\n", pszFileName, iInstrIndex, iSamplerChannel);
693 return lscp_client_query(pClient, szQuery);
694 }
695
696
697 /**
698 * Loading an instrument in the background (non modal):
699 * LOAD INSTRUMENT NON_MODAL <filename> <instr-index> <sampler-channel>
700 *
701 * @param pClient Pointer to client instance structure.
702 * @param pszFileName Instrument file name.
703 * @param iInstrIndex Instrument index number.
704 * @param iSamplerChannel Sampler Channel.
705 *
706 * @returns LSCP_OK on success, LSCP_FAILED otherwise.
707 */
708 lscp_status_t lscp_load_instrument_non_modal ( lscp_client_t *pClient, const char *pszFileName, int iInstrIndex, int iSamplerChannel )
709 {
710 char szQuery[LSCP_BUFSIZ];
711
712 if (pszFileName == NULL || iSamplerChannel < 0)
713 return LSCP_FAILED;
714
715 sprintf(szQuery, "LOAD INSTRUMENT NON_MODAL '%s' %d %d\r\n", pszFileName, iInstrIndex, iSamplerChannel);
716 return lscp_client_query(pClient, szQuery);
717 }
718
719
720 /**
721 * Loading a sampler engine:
722 * LOAD ENGINE <engine-name> <sampler-channel>
723 *
724 * @param pClient Pointer to client instance structure.
725 * @param pszEngineName Engine name.
726 * @param iSamplerChannel Sampler channel number.
727 *
728 * @returns LSCP_OK on success, LSCP_FAILED otherwise.
729 */
730 lscp_status_t lscp_load_engine ( lscp_client_t *pClient, const char *pszEngineName, int iSamplerChannel )
731 {
732 char szQuery[LSCP_BUFSIZ];
733
734 if (pszEngineName == NULL || iSamplerChannel < 0)
735 return LSCP_FAILED;
736
737 sprintf(szQuery, "LOAD ENGINE %s %d\r\n", pszEngineName, iSamplerChannel);
738 return lscp_client_query(pClient, szQuery);
739 }
740
741
742 /**
743 * Current number of sampler channels:
744 * GET CHANNELS
745 *
746 * @param pClient Pointer to client instance structure.
747 *
748 * @returns The current total number of sampler channels on success,
749 * -1 otherwise.
750 */
751 int lscp_get_channels ( lscp_client_t *pClient )
752 {
753 int iChannels = -1;
754
755 // Lock this section up.
756 lscp_mutex_lock(pClient->mutex);
757
758 if (lscp_client_call(pClient, "GET CHANNELS\r\n", 0) == LSCP_OK)
759 iChannels = atoi(lscp_client_get_result(pClient));
760
761 // Unlock this section doen.
762 lscp_mutex_unlock(pClient->mutex);
763
764 return iChannels;
765 }
766
767
768 /**
769 * List current sampler channels number identifiers:
770 * LIST CHANNELS
771 *
772 * @param pClient Pointer to client instance structure.
773 *
774 * @returns An array of the sampler channels identifiers as positive integers,
775 * terminated with -1 on success, NULL otherwise.
776 */
777 int *lscp_list_channels ( lscp_client_t *pClient )
778 {
779 const char *pszSeps = ",";
780
781 if (pClient == NULL)
782 return NULL;
783
784 // Lock this section up.
785 lscp_mutex_lock(pClient->mutex);
786
787 if (pClient->channels) {
788 lscp_isplit_destroy(pClient->channels);
789 pClient->channels = NULL;
790 }
791
792 if (lscp_client_call(pClient, "LIST CHANNELS\r\n", 0) == LSCP_OK)
793 pClient->channels = lscp_isplit_create(lscp_client_get_result(pClient), pszSeps);
794
795 // Unlock this section down.
796 lscp_mutex_unlock(pClient->mutex);
797
798 return pClient->channels;
799 }
800
801
802 /**
803 * Adding a new sampler channel:
804 * ADD CHANNEL
805 *
806 * @param pClient Pointer to client instance structure.
807 *
808 * @returns The new sampler channel number identifier,
809 * or -1 in case of failure.
810 */
811 int lscp_add_channel ( lscp_client_t *pClient )
812 {
813 int iSamplerChannel = -1;
814
815 // Lock this section up.
816 lscp_mutex_lock(pClient->mutex);
817
818 if (lscp_client_call(pClient, "ADD CHANNEL\r\n", 0) == LSCP_OK)
819 iSamplerChannel = atoi(lscp_client_get_result(pClient));
820
821 // Unlock this section down.
822 lscp_mutex_unlock(pClient->mutex);
823
824 return iSamplerChannel;
825 }
826
827
828 /**
829 * Removing a sampler channel:
830 * REMOVE CHANNEL <sampler-channel>
831 *
832 * @param pClient Pointer to client instance structure.
833 * @param iSamplerChannel Sampler channel number.
834 *
835 * @returns LSCP_OK on success, LSCP_FAILED otherwise.
836 */
837 lscp_status_t lscp_remove_channel ( lscp_client_t *pClient, int iSamplerChannel )
838 {
839 char szQuery[LSCP_BUFSIZ];
840
841 if (iSamplerChannel < 0)
842 return LSCP_FAILED;
843
844 sprintf(szQuery, "REMOVE CHANNEL %d\r\n", iSamplerChannel);
845 return lscp_client_query(pClient, szQuery);
846 }
847
848
849 /**
850 * Getting all available engines count:
851 * GET AVAILABLE_ENGINES
852 *
853 * @param pClient Pointer to client instance structure.
854 *
855 * @returns The current total number of sampler engines on success,
856 * -1 otherwise.
857 */
858 int lscp_get_available_engines ( lscp_client_t *pClient )
859 {
860 int iAvailableEngines = -1;
861
862 // Lock this section up.
863 lscp_mutex_lock(pClient->mutex);
864
865 if (lscp_client_call(pClient, "GET AVAILABLE_ENGINES\r\n", 0) == LSCP_OK)
866 iAvailableEngines = atoi(lscp_client_get_result(pClient));
867
868 // Unlock this section down.
869 lscp_mutex_unlock(pClient->mutex);
870
871 return iAvailableEngines;
872 }
873
874
875 /**
876 * Getting all available engines:
877 * LIST AVAILABLE_ENGINES
878 *
879 * @param pClient Pointer to client instance structure.
880 *
881 * @returns A NULL terminated array of engine name strings,
882 * or NULL in case of failure.
883 */
884 const char **lscp_list_available_engines ( lscp_client_t *pClient )
885 {
886 const char *pszSeps = ",";
887
888 // Lock this section up.
889 lscp_mutex_lock(pClient->mutex);
890
891 if (pClient->engines) {
892 lscp_szsplit_destroy(pClient->engines);
893 pClient->engines = NULL;
894 }
895
896 if (lscp_client_call(pClient, "LIST AVAILABLE_ENGINES\r\n", 0) == LSCP_OK)
897 pClient->engines = lscp_szsplit_create(lscp_client_get_result(pClient), pszSeps);
898
899 // Unlock this section down.
900 lscp_mutex_unlock(pClient->mutex);
901
902 return (const char **) pClient->engines;
903 }
904
905
906 /**
907 * Getting information about an engine.
908 * GET ENGINE INFO <engine-name>
909 *
910 * @param pClient Pointer to client instance structure.
911 * @param pszEngineName Engine name.
912 *
913 * @returns A pointer to a @ref lscp_engine_info_t structure, with all the
914 * information of the given sampler engine, or NULL in case of failure.
915 */
916 lscp_engine_info_t *lscp_get_engine_info ( lscp_client_t *pClient, const char *pszEngineName )
917 {
918 lscp_engine_info_t *pEngineInfo;
919 char szQuery[LSCP_BUFSIZ];
920 const char *pszResult;
921 const char *pszSeps = ":";
922 const char *pszCrlf = "\r\n";
923 char *pszToken;
924 char *pch;
925
926 if (pszEngineName == NULL)
927 return NULL;
928
929 // Lock this section up.
930 lscp_mutex_lock(pClient->mutex);
931
932 pEngineInfo = &(pClient->engine_info);
933 lscp_engine_info_reset(pEngineInfo);
934
935 sprintf(szQuery, "GET ENGINE INFO %s\r\n", pszEngineName);
936 if (lscp_client_call(pClient, szQuery, 1) == LSCP_OK) {
937 pszResult = lscp_client_get_result(pClient);
938 pszToken = lscp_strtok((char *) pszResult, pszSeps, &(pch));
939 while (pszToken) {
940 if (strcasecmp(pszToken, "DESCRIPTION") == 0) {
941 pszToken = lscp_strtok(NULL, pszCrlf, &(pch));
942 if (pszToken)
943 lscp_unquote_dup(&(pEngineInfo->description), &pszToken);
944 }
945 else if (strcasecmp(pszToken, "VERSION") == 0) {
946 pszToken = lscp_strtok(NULL, pszCrlf, &(pch));
947 if (pszToken)
948 lscp_unquote_dup(&(pEngineInfo->version), &pszToken);
949 }
950 pszToken = lscp_strtok(NULL, pszSeps, &(pch));
951 }
952 }
953 else pEngineInfo = NULL;
954
955 // Unlock this section down.
956 lscp_mutex_unlock(pClient->mutex);
957
958 return pEngineInfo;
959 }
960
961
962 /**
963 * Getting sampler channel informations:
964 * GET CHANNEL INFO <sampler-channel>
965 *
966 * @param pClient Pointer to client instance structure.
967 * @param iSamplerChannel Sampler channel number.
968 *
969 * @returns A pointer to a @ref lscp_channel_info_t structure, with all the
970 * information of the given sampler channel, or NULL in case of failure.
971 */
972 lscp_channel_info_t *lscp_get_channel_info ( lscp_client_t *pClient, int iSamplerChannel )
973 {
974 lscp_channel_info_t *pChannelInfo;
975 char szQuery[LSCP_BUFSIZ];
976 const char *pszResult;
977 const char *pszSeps = ":";
978 const char *pszCrlf = "\r\n";
979 char *pszToken;
980 char *pch;
981
982 if (iSamplerChannel < 0)
983 return NULL;
984
985 // Lock this section up.
986 lscp_mutex_lock(pClient->mutex);
987
988 pChannelInfo = &(pClient->channel_info);
989 lscp_channel_info_reset(pChannelInfo);
990
991 sprintf(szQuery, "GET CHANNEL INFO %d\r\n", iSamplerChannel);
992 if (lscp_client_call(pClient, szQuery, 1) == LSCP_OK) {
993 pszResult = lscp_client_get_result(pClient);
994 pszToken = lscp_strtok((char *) pszResult, pszSeps, &(pch));
995 while (pszToken) {
996 if (strcasecmp(pszToken, "ENGINE_NAME") == 0) {
997 pszToken = lscp_strtok(NULL, pszCrlf, &(pch));
998 if (pszToken)
999 lscp_unquote_dup(&(pChannelInfo->engine_name), &pszToken);
1000 }
1001 else if (strcasecmp(pszToken, "AUDIO_OUTPUT_DEVICE") == 0) {
1002 pszToken = lscp_strtok(NULL, pszCrlf, &(pch));
1003 if (pszToken)
1004 pChannelInfo->audio_device = atoi(lscp_ltrim(pszToken));
1005 }
1006 else if (strcasecmp(pszToken, "AUDIO_OUTPUT_CHANNELS") == 0) {
1007 pszToken = lscp_strtok(NULL, pszCrlf, &(pch));
1008 if (pszToken)
1009 pChannelInfo->audio_channels = atoi(lscp_ltrim(pszToken));
1010 }
1011 else if (strcasecmp(pszToken, "AUDIO_OUTPUT_ROUTING") == 0) {
1012 pszToken = lscp_strtok(NULL, pszCrlf, &(pch));
1013 if (pszToken) {
1014 if (pChannelInfo->audio_routing)
1015 lscp_szsplit_destroy(pChannelInfo->audio_routing);
1016 pChannelInfo->audio_routing = lscp_szsplit_create(pszToken, ",");
1017 }
1018 }
1019 else if (strcasecmp(pszToken, "INSTRUMENT_FILE") == 0) {
1020 pszToken = lscp_strtok(NULL, pszCrlf, &(pch));
1021 if (pszToken)
1022 lscp_unquote_dup(&(pChannelInfo->instrument_file), &pszToken);
1023 }
1024 else if (strcasecmp(pszToken, "INSTRUMENT_NR") == 0) {
1025 pszToken = lscp_strtok(NULL, pszCrlf, &(pch));
1026 if (pszToken)
1027 pChannelInfo->instrument_nr = atoi(lscp_ltrim(pszToken));
1028 }
1029 else if (strcasecmp(pszToken, "INSTRUMENT_NAME") == 0) {
1030 pszToken = lscp_strtok(NULL, pszCrlf, &(pch));
1031 if (pszToken)
1032 lscp_unquote_dup(&(pChannelInfo->instrument_name), &pszToken);
1033 }
1034 else if (strcasecmp(pszToken, "INSTRUMENT_STATUS") == 0) {
1035 pszToken = lscp_strtok(NULL, pszCrlf, &(pch));
1036 if (pszToken)
1037 pChannelInfo->instrument_status = atoi(lscp_ltrim(pszToken));
1038 }
1039 else if (strcasecmp(pszToken, "MIDI_INPUT_DEVICE") == 0) {
1040 pszToken = lscp_strtok(NULL, pszCrlf, &(pch));
1041 if (pszToken)
1042 pChannelInfo->midi_device = atoi(lscp_ltrim(pszToken));
1043 }
1044 else if (strcasecmp(pszToken, "MIDI_INPUT_PORT") == 0) {
1045 pszToken = lscp_strtok(NULL, pszCrlf, &(pch));
1046 if (pszToken)
1047 pChannelInfo->midi_port = atoi(lscp_ltrim(pszToken));
1048 }
1049 else if (strcasecmp(pszToken, "MIDI_INPUT_CHANNEL") == 0) {
1050 pszToken = lscp_strtok(NULL, pszCrlf, &(pch));
1051 if (pszToken) {
1052 pszToken = lscp_ltrim(pszToken);
1053 if (strcasecmp(pszToken, "ALL") == 0)
1054 pChannelInfo->midi_channel = LSCP_MIDI_CHANNEL_ALL;
1055 else
1056 pChannelInfo->midi_channel = atoi(pszToken);
1057 }
1058 }
1059 else if (strcasecmp(pszToken, "VOLUME") == 0) {
1060 pszToken = lscp_strtok(NULL, pszCrlf, &(pch));
1061 if (pszToken)
1062 pChannelInfo->volume = (float) atof(lscp_ltrim(pszToken));
1063 }
1064 else if (strcasecmp(pszToken, "MUTE") == 0) {
1065 pszToken = lscp_strtok(NULL, pszCrlf, &(pch));
1066 if (pszToken)
1067 pChannelInfo->mute = (strcasecmp(lscp_unquote(&pszToken, 0), "TRUE") == 0);
1068 }
1069 else if (strcasecmp(pszToken, "SOLO") == 0) {
1070 pszToken = lscp_strtok(NULL, pszCrlf, &(pch));
1071 if (pszToken)
1072 pChannelInfo->solo = (strcasecmp(lscp_unquote(&pszToken, 0), "TRUE") == 0);
1073 }
1074 pszToken = lscp_strtok(NULL, pszSeps, &(pch));
1075 }
1076 }
1077 else pChannelInfo = NULL;
1078
1079 // Unlock this section up.
1080 lscp_mutex_unlock(pClient->mutex);
1081
1082 return pChannelInfo;
1083 }
1084
1085
1086 /**
1087 * Current number of active voices:
1088 * GET CHANNEL VOICE_COUNT <sampler-channel>
1089 *
1090 * @param pClient Pointer to client instance structure.
1091 * @param iSamplerChannel Sampler channel number.
1092 *
1093 * @returns The number of voices currently active, -1 in case of failure.
1094 */
1095 int lscp_get_channel_voice_count ( lscp_client_t *pClient, int iSamplerChannel )
1096 {
1097 char szQuery[LSCP_BUFSIZ];
1098 int iVoiceCount = -1;
1099
1100 if (iSamplerChannel < 0)
1101 return iVoiceCount;
1102
1103 // Lock this section up.
1104 lscp_mutex_lock(pClient->mutex);
1105
1106 sprintf(szQuery, "GET CHANNEL VOICE_COUNT %d\r\n", iSamplerChannel);
1107 if (lscp_client_call(pClient, szQuery, 0) == LSCP_OK)
1108 iVoiceCount = atoi(lscp_client_get_result(pClient));
1109
1110 // Unlock this section down.
1111 lscp_mutex_unlock(pClient->mutex);
1112
1113 return iVoiceCount;
1114 }
1115
1116
1117 /**
1118 * Current number of active disk streams:
1119 * GET CHANNEL STREAM_COUNT <sampler-channel>
1120 *
1121 * @param pClient Pointer to client instance structure.
1122 * @param iSamplerChannel Sampler channel number.
1123 *
1124 * @returns The number of active disk streams on success, -1 otherwise.
1125 */
1126 int lscp_get_channel_stream_count ( lscp_client_t *pClient, int iSamplerChannel )
1127 {
1128 char szQuery[LSCP_BUFSIZ];
1129 int iStreamCount = -1;
1130
1131 if (iSamplerChannel < 0)
1132 return iStreamCount;
1133
1134 // Lock this section up.
1135 lscp_mutex_lock(pClient->mutex);
1136
1137 sprintf(szQuery, "GET CHANNEL STREAM_COUNT %d\r\n", iSamplerChannel);
1138 if (lscp_client_call(pClient, szQuery, 0) == LSCP_OK)
1139 iStreamCount = atoi(lscp_client_get_result(pClient));
1140
1141 // Unlock this section down.
1142 lscp_mutex_unlock(pClient->mutex);
1143
1144 return iStreamCount;
1145 }
1146
1147
1148 /**
1149 * Current least usage of active disk streams.
1150 *
1151 * @param pClient Pointer to client instance structure.
1152 * @param iSamplerChannel Sampler channel number.
1153 *
1154 * @returns The usage percentage of the least filled active disk stream
1155 * on success, -1 otherwise.
1156 */
1157 int lscp_get_channel_stream_usage ( lscp_client_t *pClient, int iSamplerChannel )
1158 {
1159 char szQuery[LSCP_BUFSIZ];
1160 int iStreamUsage = -1;
1161 const char *pszResult;
1162 const char *pszSeps = "[]%,";
1163 char *pszToken;
1164 char *pch;
1165 int iStream;
1166 int iPercent;
1167
1168 if (iSamplerChannel < 0)
1169 return iStreamUsage;
1170
1171 // Lock this section up.
1172 lscp_mutex_lock(pClient->mutex);
1173
1174 iStream = 0;
1175 sprintf(szQuery, "GET CHANNEL BUFFER_FILL PERCENTAGE %d\r\n", iSamplerChannel);
1176 if (lscp_client_call(pClient, szQuery, 0) == LSCP_OK) {
1177 pszResult = lscp_client_get_result(pClient);
1178 pszToken = lscp_strtok((char *) pszResult, pszSeps, &(pch));
1179 while (pszToken) {
1180 if (*pszToken) {
1181 // Skip stream id.
1182 pszToken = lscp_strtok(NULL, pszSeps, &(pch));
1183 if (pszToken == NULL)
1184 break;
1185 // Get least buffer fill percentage.
1186 iPercent = atol(pszToken);
1187 if (iStreamUsage > iPercent || iStream == 0)
1188 iStreamUsage = iPercent;
1189 iStream++;
1190 }
1191 pszToken = lscp_strtok(NULL, pszSeps, &(pch));
1192 }
1193 }
1194
1195 // Unlock this section down.
1196 lscp_mutex_unlock(pClient->mutex);
1197
1198 return iStreamUsage;
1199 }
1200
1201
1202 /**
1203 * Current fill state of disk stream buffers:
1204 * GET CHANNEL BUFFER_FILL {BYTES|PERCENTAGE} <sampler-channel>
1205 *
1206 * @param pClient Pointer to client instance structure.
1207 * @param usage_type Usage type to be returned, either
1208 * @ref LSCP_USAGE_BYTES, or
1209 * @ref LSCP_USAGE_PERCENTAGE.
1210 * @param iSamplerChannel Sampler channel number.
1211 *
1212 * @returns A pointer to a @ref lscp_buffer_fill_t structure, with the
1213 * information of the current disk stream buffer fill usage, for the given
1214 * sampler channel, or NULL in case of failure.
1215 */
1216 lscp_buffer_fill_t *lscp_get_channel_buffer_fill ( lscp_client_t *pClient, lscp_usage_t usage_type, int iSamplerChannel )
1217 {
1218 lscp_buffer_fill_t *pBufferFill;
1219 char szQuery[LSCP_BUFSIZ];
1220 int iStreamCount;
1221 const char *pszUsageType = (usage_type == LSCP_USAGE_BYTES ? "BYTES" : "PERCENTAGE");
1222 const char *pszResult;
1223 const char *pszSeps = "[]%,";
1224 char *pszToken;
1225 char *pch;
1226 int iStream;
1227
1228 // Retrieve a channel stream estimation.
1229 iStreamCount = lscp_get_channel_stream_count(pClient, iSamplerChannel);
1230 if (pClient->iStreamCount < 0)
1231 return NULL;
1232
1233 // Lock this section up.
1234 lscp_mutex_lock(pClient->mutex);
1235
1236 // Check if we need to reallocate the stream usage array.
1237 if (pClient->iStreamCount != iStreamCount) {
1238 if (pClient->buffer_fill)
1239 free(pClient->buffer_fill);
1240 if (iStreamCount > 0)
1241 pClient->buffer_fill = (lscp_buffer_fill_t *) malloc(iStreamCount * sizeof(lscp_buffer_fill_t));
1242 else
1243 pClient->buffer_fill = NULL;
1244 pClient->iStreamCount = iStreamCount;
1245 }
1246
1247 // Get buffer fill usage...
1248 pBufferFill = pClient->buffer_fill;
1249 if (pBufferFill && iStreamCount > 0) {
1250 iStream = 0;
1251 pBufferFill = pClient->buffer_fill;
1252 sprintf(szQuery, "GET CHANNEL BUFFER_FILL %s %d\r\n", pszUsageType, iSamplerChannel);
1253 if (lscp_client_call(pClient, szQuery, 0) == LSCP_OK) {
1254 pszResult = lscp_client_get_result(pClient);
1255 pszToken = lscp_strtok((char *) pszResult, pszSeps, &(pch));
1256 while (pszToken && iStream < pClient->iStreamCount) {
1257 if (*pszToken) {
1258 pBufferFill[iStream].stream_id = atol(pszToken);
1259 pszToken = lscp_strtok(NULL, pszSeps, &(pch));
1260 if (pszToken == NULL)
1261 break;
1262 pBufferFill[iStream].stream_usage = atol(pszToken);
1263 iStream++;
1264 }
1265 pszToken = lscp_strtok(NULL, pszSeps, &(pch));
1266 }
1267 } // Reset the usage, whatever it was before.
1268 else while (iStream < pClient->iStreamCount)
1269 pBufferFill[iStream++].stream_usage = 0;
1270 }
1271
1272 // Unlock this section down.
1273 lscp_mutex_unlock(pClient->mutex);
1274
1275 return pBufferFill;
1276 }
1277
1278
1279 /**
1280 * Setting audio output type:
1281 * SET CHANNEL AUDIO_OUTPUT_TYPE <sampler-channel> <audio-output-type>
1282 *
1283 * @param pClient Pointer to client instance structure.
1284 * @param iSamplerChannel Sampler channel number.
1285 * @param pszAudioDriver Audio output driver type (e.g. "ALSA" or "JACK").
1286 *
1287 * @returns LSCP_OK on success, LSCP_FAILED otherwise.
1288 */
1289 lscp_status_t lscp_set_channel_audio_type ( lscp_client_t *pClient, int iSamplerChannel, const char *pszAudioDriver )
1290 {
1291 char szQuery[LSCP_BUFSIZ];
1292
1293 if (iSamplerChannel < 0 || pszAudioDriver == NULL)
1294 return LSCP_FAILED;
1295
1296 sprintf(szQuery, "SET CHANNEL AUDIO_OUTPUT_TYPE %d %s\r\n", iSamplerChannel, pszAudioDriver);
1297 return lscp_client_query(pClient, szQuery);
1298 }
1299
1300
1301 /**
1302 * Setting audio output device:
1303 * SET CHANNEL AUDIO_OUTPUT_DEVICE <sampler-channel> <device-id>
1304 *
1305 * @param pClient Pointer to client instance structure.
1306 * @param iSamplerChannel Sampler channel number.
1307 * @param iAudioDevice Audio output device number identifier.
1308 *
1309 * @returns LSCP_OK on success, LSCP_FAILED otherwise.
1310 */
1311 lscp_status_t lscp_set_channel_audio_device ( lscp_client_t *pClient, int iSamplerChannel, int iAudioDevice )
1312 {
1313 char szQuery[LSCP_BUFSIZ];
1314
1315 if (iSamplerChannel < 0 || iAudioDevice < 0)
1316 return LSCP_FAILED;
1317
1318 sprintf(szQuery, "SET CHANNEL AUDIO_OUTPUT_DEVICE %d %d\r\n", iSamplerChannel, iAudioDevice);
1319 return lscp_client_query(pClient, szQuery);
1320 }
1321
1322
1323 /**
1324 * Setting audio output channel:
1325 * SET CHANNEL AUDIO_OUTPUT_CHANNEL <sampler-channel> <audio-output-chan> <audio-input-chan>
1326 *
1327 * @param pClient Pointer to client instance structure.
1328 * @param iSamplerChannel Sampler channel number.
1329 * @param iAudioOut Audio output device channel to be routed from.
1330 * @param iAudioIn Audio output device channel to be routed into.
1331 *
1332 * @returns LSCP_OK on success, LSCP_FAILED otherwise.
1333 */
1334 lscp_status_t lscp_set_channel_audio_channel ( lscp_client_t *pClient, int iSamplerChannel, int iAudioOut, int iAudioIn )
1335 {
1336 char szQuery[LSCP_BUFSIZ];
1337
1338 if (iSamplerChannel < 0 || iAudioOut < 0 || iAudioIn < 0)
1339 return LSCP_FAILED;
1340
1341 sprintf(szQuery, "SET CHANNEL AUDIO_OUTPUT_CHANNEL %d %d %d\r\n", iSamplerChannel, iAudioOut, iAudioIn);
1342 return lscp_client_query(pClient, szQuery);
1343 }
1344
1345
1346 /**
1347 * Setting MIDI input type:
1348 * SET CHANNEL MIDI_INPUT_TYPE <sampler-channel> <midi-input-type>
1349 *
1350 * @param pClient Pointer to client instance structure.
1351 * @param iSamplerChannel Sampler channel number.
1352 * @param pszMidiDriver MIDI input driver type (e.g. "ALSA").
1353 *
1354 * @returns LSCP_OK on success, LSCP_FAILED otherwise.
1355 */
1356 lscp_status_t lscp_set_channel_midi_type ( lscp_client_t *pClient, int iSamplerChannel, const char *pszMidiDriver )
1357 {
1358 char szQuery[LSCP_BUFSIZ];
1359
1360 if (iSamplerChannel < 0 || pszMidiDriver == NULL)
1361 return LSCP_FAILED;
1362
1363 sprintf(szQuery, "SET CHANNEL MIDI_INPUT_TYPE %d %s\r\n", iSamplerChannel, pszMidiDriver);
1364 return lscp_client_query(pClient, szQuery);
1365 }
1366
1367
1368 /**
1369 * Setting MIDI input device:
1370 * SET CHANNEL MIDI_INPUT_DEVICE <sampler-channel> <device-id>
1371 *
1372 * @param pClient Pointer to client instance structure.
1373 * @param iSamplerChannel Sampler channel number.
1374 * @param iMidiDevice MIDI input device number identifier.
1375 *
1376 * @returns LSCP_OK on success, LSCP_FAILED otherwise.
1377 */
1378 lscp_status_t lscp_set_channel_midi_device ( lscp_client_t *pClient, int iSamplerChannel, int iMidiDevice )
1379 {
1380 char szQuery[LSCP_BUFSIZ];
1381
1382 if (iSamplerChannel < 0 || iMidiDevice < 0)
1383 return LSCP_FAILED;
1384
1385 sprintf(szQuery, "SET CHANNEL MIDI_INPUT_DEVICE %d %d\r\n", iSamplerChannel, iMidiDevice);
1386 return lscp_client_query(pClient, szQuery);
1387 }
1388
1389
1390 /**
1391 * Setting MIDI input port:
1392 * SET CHANNEL MIDI_INPUT_PORT <sampler-channel> <midi-input-port>
1393 *
1394 * @param pClient Pointer to client instance structure.
1395 * @param iSamplerChannel Sampler channel number.
1396 * @param iMidiPort MIDI input driver virtual port number.
1397 *
1398 * @returns LSCP_OK on success, LSCP_FAILED otherwise.
1399 */
1400 lscp_status_t lscp_set_channel_midi_port ( lscp_client_t *pClient, int iSamplerChannel, int iMidiPort )
1401 {
1402 char szQuery[LSCP_BUFSIZ];
1403
1404 if (iSamplerChannel < 0 || iMidiPort < 0)
1405 return LSCP_FAILED;
1406
1407 sprintf(szQuery, "SET CHANNEL MIDI_INPUT_PORT %d %d\r\n", iSamplerChannel, iMidiPort);
1408 return lscp_client_query(pClient, szQuery);
1409 }
1410
1411
1412 /**
1413 * Setting MIDI input channel:
1414 * SET CHANNEL MIDI_INPUT_CHANNEL <sampler-channel> <midi-input-chan>
1415 *
1416 * @param pClient Pointer to client instance structure.
1417 * @param iSamplerChannel Sampler channel number.
1418 * @param iMidiChannel MIDI channel address number to listen (0-15) or
1419 * LSCP_MIDI_CHANNEL_ALL (16) to listen on all channels.
1420 *
1421 * @returns LSCP_OK on success, LSCP_FAILED otherwise.
1422 */
1423 lscp_status_t lscp_set_channel_midi_channel ( lscp_client_t *pClient, int iSamplerChannel, int iMidiChannel )
1424 {
1425 char szQuery[LSCP_BUFSIZ];
1426
1427 if (iSamplerChannel < 0 || iMidiChannel < 0 || iMidiChannel > 16)
1428 return LSCP_FAILED;
1429
1430 if (iMidiChannel == LSCP_MIDI_CHANNEL_ALL)
1431 sprintf(szQuery, "SET CHANNEL MIDI_INPUT_CHANNEL %d ALL\r\n", iSamplerChannel);
1432 else
1433 sprintf(szQuery, "SET CHANNEL MIDI_INPUT_CHANNEL %d %d\r\n", iSamplerChannel, iMidiChannel);
1434 return lscp_client_query(pClient, szQuery);
1435 }
1436
1437
1438 /**
1439 * Setting channel volume:
1440 * SET CHANNEL VOLUME <sampler-channel> <volume>
1441 *
1442 * @param pClient Pointer to client instance structure.
1443 * @param iSamplerChannel Sampler channel number.
1444 * @param fVolume Sampler channel volume as a positive floating point
1445 * number, where a value less than 1.0 for attenuation,
1446 * and greater than 1.0 for amplification.
1447 *
1448 * @returns LSCP_OK on success, LSCP_FAILED otherwise.
1449 */
1450 lscp_status_t lscp_set_channel_volume ( lscp_client_t *pClient, int iSamplerChannel, float fVolume )
1451 {
1452 char szQuery[LSCP_BUFSIZ];
1453
1454 if (iSamplerChannel < 0 || fVolume < 0.0)
1455 return LSCP_FAILED;
1456
1457 sprintf(szQuery, "SET CHANNEL VOLUME %d %g\r\n", iSamplerChannel, fVolume);
1458 return lscp_client_query(pClient, szQuery);
1459 }
1460
1461
1462 /**
1463 * Muting a sampler channel:
1464 * SET CHANNEL MUTE <sampler-channel> <mute>
1465 *
1466 * @param pClient Pointer to client instance structure.
1467 * @param iSamplerChannel Sampler channel number.
1468 * @param iMute Sampler channel mute state as a boolean value,
1469 * either 1 (one) to mute the channel or 0 (zero)
1470 * to unmute the channel.
1471 *
1472 * @returns LSCP_OK on success, LSCP_FAILED otherwise.
1473 */
1474 lscp_status_t lscp_set_channel_mute ( lscp_client_t *pClient, int iSamplerChannel, int iMute )
1475 {
1476 char szQuery[LSCP_BUFSIZ];
1477
1478 if (iSamplerChannel < 0 || iMute < 0 || iMute > 1)
1479 return LSCP_FAILED;
1480
1481 sprintf(szQuery, "SET CHANNEL MUTE %d %d\r\n", iSamplerChannel, iMute);
1482 return lscp_client_query(pClient, szQuery);
1483 }
1484
1485
1486 /**
1487 * Soloing a sampler channel:
1488 * SET CHANNEL SOLO <sampler-channel> <solo>
1489 *
1490 * @param pClient Pointer to client instance structure.
1491 * @param iSamplerChannel Sampler channel number.
1492 * @param iSolo Sampler channel solo state as a boolean value,
1493 * either 1 (one) to solo the channel or 0 (zero)
1494 * to unsolo the channel.
1495 *
1496 * @returns LSCP_OK on success, LSCP_FAILED otherwise.
1497 */
1498 lscp_status_t lscp_set_channel_solo ( lscp_client_t *pClient, int iSamplerChannel, int iSolo )
1499 {
1500 char szQuery[LSCP_BUFSIZ];
1501
1502 if (iSamplerChannel < 0 || iSolo < 0 || iSolo > 1)
1503 return LSCP_FAILED;
1504
1505 sprintf(szQuery, "SET CHANNEL SOLO %d %d\r\n", iSamplerChannel, iSolo);
1506 return lscp_client_query(pClient, szQuery);
1507 }
1508
1509
1510 /**
1511 * Resetting a sampler channel:
1512 * RESET CHANNEL <sampler-channel>
1513 *
1514 * @param pClient Pointer to client instance structure.
1515 * @param iSamplerChannel Sampler channel number.
1516 *
1517 * @returns LSCP_OK on success, LSCP_FAILED otherwise.
1518 */
1519 lscp_status_t lscp_reset_channel ( lscp_client_t *pClient, int iSamplerChannel )
1520 {
1521 char szQuery[LSCP_BUFSIZ];
1522
1523 if (iSamplerChannel < 0)
1524 return LSCP_FAILED;
1525
1526 sprintf(szQuery, "RESET CHANNEL %d\r\n", iSamplerChannel);
1527 return lscp_client_query(pClient, szQuery);
1528 }
1529
1530
1531 /**
1532 * Resetting the sampler:
1533 * RESET
1534 *
1535 * @param pClient Pointer to client instance structure.
1536 *
1537 * @returns LSCP_OK on success, LSCP_FAILED otherwise.
1538 */
1539 lscp_status_t lscp_reset_sampler ( lscp_client_t *pClient )
1540 {
1541 return lscp_client_query(pClient, "RESET\r\n");
1542 }
1543
1544
1545 /**
1546 * Getting information about the server.
1547 * GET SERVER INFO
1548 *
1549 * @param pClient Pointer to client instance structure.
1550 *
1551 * @returns A pointer to a @ref lscp_server_info_t structure, with all the
1552 * information of the current connected server, or NULL in case of failure.
1553 */
1554 lscp_server_info_t *lscp_get_server_info ( lscp_client_t *pClient )
1555 {
1556 lscp_server_info_t *pServerInfo;
1557 const char *pszResult;
1558 const char *pszSeps = ":";
1559 const char *pszCrlf = "\r\n";
1560 char *pszToken;
1561 char *pch;
1562
1563 // Lock this section up.
1564 lscp_mutex_lock(pClient->mutex);
1565
1566 pServerInfo = &(pClient->server_info);
1567 lscp_server_info_reset(pServerInfo);
1568
1569 if (lscp_client_call(pClient, "GET SERVER INFO\r\n", 1) == LSCP_OK) {
1570 pszResult = lscp_client_get_result(pClient);
1571 pszToken = lscp_strtok((char *) pszResult, pszSeps, &(pch));
1572 while (pszToken) {
1573 if (strcasecmp(pszToken, "DESCRIPTION") == 0) {
1574 pszToken = lscp_strtok(NULL, pszCrlf, &(pch));
1575 if (pszToken)
1576 lscp_unquote_dup(&(pServerInfo->description), &pszToken);
1577 }
1578 else if (strcasecmp(pszToken, "VERSION") == 0) {
1579 pszToken = lscp_strtok(NULL, pszCrlf, &(pch));
1580 if (pszToken)
1581 lscp_unquote_dup(&(pServerInfo->version), &pszToken);
1582 }
1583 pszToken = lscp_strtok(NULL, pszSeps, &(pch));
1584 }
1585 }
1586 else pServerInfo = NULL;
1587
1588 // Unlock this section down.
1589 lscp_mutex_unlock(pClient->mutex);
1590
1591 return pServerInfo;
1592 }
1593
1594
1595 /**
1596 * Current total number of active voices:
1597 * GET TOTAL_VOICE_COUNT
1598 *
1599 * @param pClient Pointer to client instance structure.
1600 *
1601 * @returns The total number of voices currently active,
1602 * -1 in case of failure.
1603 */
1604 int lscp_get_total_voice_count ( lscp_client_t *pClient )
1605 {
1606 int iVoiceCount = -1;
1607
1608 // Lock this section up.
1609 lscp_mutex_lock(pClient->mutex);
1610
1611 if (lscp_client_call(pClient, "GET TOTAL_VOICE_COUNT\r\n", 0) == LSCP_OK)
1612 iVoiceCount = atoi(lscp_client_get_result(pClient));
1613
1614 // Unlock this section down.
1615 lscp_mutex_unlock(pClient->mutex);
1616
1617 return iVoiceCount;
1618 }
1619
1620
1621 /**
1622 * Maximum amount of active voices:
1623 * GET TOTAL_VOICE_COUNT_MAX
1624 *
1625 * @param pClient Pointer to client instance structure.
1626 *
1627 * @returns The maximum amount of voices currently active,
1628 * -1 in case of failure.
1629 */
1630 int lscp_get_total_voice_count_max ( lscp_client_t *pClient )
1631 {
1632 int iVoiceCount = -1;
1633
1634 // Lock this section up.
1635 lscp_mutex_lock(pClient->mutex);
1636
1637 if (lscp_client_call(pClient, "GET TOTAL_VOICE_COUNT_MAX\r\n", 0) == LSCP_OK)
1638 iVoiceCount = atoi(lscp_client_get_result(pClient));
1639
1640 // Unlock this section down.
1641 lscp_mutex_unlock(pClient->mutex);
1642
1643 return iVoiceCount;
1644 }
1645
1646
1647 /**
1648 * Create or replace a MIDI instrumnet map entry:
1649 * MAP MIDI_INSTRUMENT <midi-bank-msb> <midi-bank-lsb> <midi-prog>
1650 * <engine-name> <filename> <instr-index> <volume> <load-mode> [<name>]
1651 *
1652 * @param pClient Pointer to client instance structure.
1653 * @param pMidiInstr MIDI instrument bank and program parameter key.
1654 * @param pszEngineName Engine name.
1655 * @param pszFileName Instrument file name.
1656 * @param iInstrIndex Instrument index number.
1657 * @param fVolume Reflects the master volume of the instrument as
1658 * a positive floating point number, where a value
1659 * less than 1.0 for attenuation, and greater than
1660 * 1.0 for amplification.
1661 * @param load_mode Instrument load life-time strategy, either
1662 * @ref LSCP_LOAD_DEFAULT, or
1663 * @ref LSCP_LOAD_ON_DEMAND, or
1664 * @ref LSCP_LOAD_ON_DEMAND_HOLD, or
1665 * @ref LSCP_LOAD_PERSISTENT.
1666 * @param pszName Instrument custom name for the map entry.
1667 *
1668 * @returns LSCP_OK on success, LSCP_FAILED otherwise.
1669 */
1670 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 )
1671 {
1672 char szQuery[LSCP_BUFSIZ];
1673
1674 if (pMidiInstr->bank_msb < 0 || pMidiInstr->bank_msb > 127)
1675 return LSCP_FAILED;
1676 if (pMidiInstr->bank_lsb < 0 || pMidiInstr->bank_lsb > 127)
1677 return LSCP_FAILED;
1678 if (pMidiInstr->program < 0 || pMidiInstr->program > 127)
1679 return LSCP_FAILED;
1680 if (pszEngineName == NULL || pszFileName == NULL)
1681 return LSCP_FAILED;
1682
1683 if (fVolume < 0.0f)
1684 fVolume = 1.0f;
1685
1686 sprintf(szQuery, "MAP MIDI_INSTRUMENT %d %d %d %s '%s' %d %g",
1687 pMidiInstr->bank_msb, pMidiInstr->bank_lsb, pMidiInstr->program,
1688 pszEngineName, pszFileName, iInstrIndex, fVolume);
1689
1690 switch (load_mode) {
1691 case LSCP_LOAD_PERSISTENT:
1692 strcat(szQuery, " PERSISTENT");
1693 break;
1694 case LSCP_LOAD_ON_DEMAND_HOLD:
1695 strcat(szQuery, " ON_DEMAND_HOLD");
1696 break;
1697 case LSCP_LOAD_ON_DEMAND:
1698 strcat(szQuery, " ON_DEMAND");
1699 break;
1700 case LSCP_LOAD_DEFAULT:
1701 default:
1702 break;
1703 }
1704
1705 if (pszName)
1706 sprintf(szQuery + strlen(szQuery), " '%s'", pszName);
1707
1708 strcat(szQuery, "\r\n");
1709
1710 return lscp_client_query(pClient, szQuery);
1711 }
1712
1713
1714 /**
1715 * Remove an entry from the MIDI instrument map:
1716 * UNMAP MIDI_INSTRUMENT <midi-bank-msb> <midi-bank-lsb> <midi-prog>
1717 *
1718 * @param pClient Pointer to client instance structure.
1719 * @param pMidiInstr MIDI instrument bank and program parameter key.
1720 *
1721 * @returns LSCP_OK on success, LSCP_FAILED otherwise.
1722 */
1723 lscp_status_t lscp_unmap_midi_instrument ( lscp_client_t *pClient, lscp_midi_instrument_t *pMidiInstr )
1724 {
1725 char szQuery[LSCP_BUFSIZ];
1726
1727 if (pMidiInstr->bank_msb < 0 || pMidiInstr->bank_msb > 127)
1728 return LSCP_FAILED;
1729 if (pMidiInstr->bank_lsb < 0 || pMidiInstr->bank_lsb > 127)
1730 return LSCP_FAILED;
1731 if (pMidiInstr->program < 0 || pMidiInstr->program > 127)
1732 return LSCP_FAILED;
1733
1734 sprintf(szQuery, "UNMAP MIDI_INSTRUMENT %d %d %d\r\n",
1735 pMidiInstr->bank_msb, pMidiInstr->bank_lsb, pMidiInstr->program);
1736
1737 return lscp_client_query(pClient, szQuery);
1738 }
1739
1740
1741 /**
1742 * Get the total count of MIDI instrument map entries:
1743 * GET MIDI_INSTRUMENTS
1744 *
1745 * @param pClient Pointer to client instance structure.
1746 *
1747 * @returns The current total number of MIDI instrument map entries
1748 * on success, -1 otherwise.
1749 */
1750 int lscp_get_midi_instruments ( lscp_client_t *pClient )
1751 {
1752 int iInstruments = -1;
1753
1754 // Lock this section up.
1755 lscp_mutex_lock(pClient->mutex);
1756
1757 if (lscp_client_call(pClient, "GET MIDI_INSTRUMENTS\r\n", 0) == LSCP_OK)
1758 iInstruments = atoi(lscp_client_get_result(pClient));
1759
1760 // Unlock this section down.
1761 lscp_mutex_unlock(pClient->mutex);
1762
1763 return iInstruments;
1764 }
1765
1766
1767 /**
1768 * Getting indeces of all MIDI instrument map entries:
1769 * LIST MIDI_INSTRUMENTS
1770 *
1771 * @param pClient Pointer to client instance structure.
1772 *
1773 * @returns An array of @ref lscp_midi_instrument_t, terminated with the
1774 * {-1,-1,-1} triplet, NULL otherwise.
1775 */
1776 lscp_midi_instrument_t *lscp_list_midi_instruments ( lscp_client_t *pClient )
1777 {
1778 if (pClient == NULL)
1779 return NULL;
1780
1781 // Lock this section up.
1782 lscp_mutex_lock(pClient->mutex);
1783
1784 if (pClient->midi_instruments) {
1785 lscp_midi_instruments_destroy(pClient->midi_instruments);
1786 pClient->midi_instruments = NULL;
1787 }
1788
1789 if (lscp_client_call(pClient, "LIST MIDI_INSTRUMENTS\r\n", 0) == LSCP_OK)
1790 pClient->midi_instruments = lscp_midi_instruments_create(lscp_client_get_result(pClient));
1791
1792 // Unlock this section down.
1793 lscp_mutex_unlock(pClient->mutex);
1794
1795 return pClient->midi_instruments;
1796 }
1797
1798
1799 /**
1800 * Getting information about a MIDI instrument map entry:
1801 * GET MIDI_INSTRUMENT INFO <midi-bank-msb> <midi-bank-lsb> <midi-prog>
1802 *
1803 * @param pClient Pointer to client instance structure.
1804 * @param pMidiInstr MIDI instrument bank and program parameter key.
1805 *
1806 * @returns A pointer to a @ref lscp_midi_instrument_info_t structure,
1807 * with all the information of the given MIDI instrument map entry,
1808 * or NULL in case of failure.
1809 */
1810 lscp_midi_instrument_info_t *lscp_get_midi_instrument_info ( lscp_client_t *pClient, lscp_midi_instrument_t *pMidiInstr )
1811 {
1812 lscp_midi_instrument_info_t *pInstrInfo;
1813 char szQuery[LSCP_BUFSIZ];
1814 const char *pszResult;
1815 const char *pszSeps = ":";
1816 const char *pszCrlf = "\r\n";
1817 char *pszToken;
1818 char *pch;
1819
1820 if (pMidiInstr->bank_msb < 0 || pMidiInstr->bank_msb > 127)
1821 return NULL;
1822 if (pMidiInstr->bank_lsb < 0 || pMidiInstr->bank_lsb > 127)
1823 return NULL;
1824 if (pMidiInstr->program < 0 || pMidiInstr->program > 127)
1825 return NULL;
1826
1827 // Lock this section up.
1828 lscp_mutex_lock(pClient->mutex);
1829
1830 pInstrInfo = &(pClient->midi_instrument_info);
1831 lscp_midi_instrument_info_reset(pInstrInfo);
1832
1833 sprintf(szQuery, "GET MIDI_INSTRUMENT INFO %d %d %d\r\n",
1834 pMidiInstr->bank_msb, pMidiInstr->bank_lsb, pMidiInstr->program);
1835 if (lscp_client_call(pClient, szQuery, 1) == LSCP_OK) {
1836 pszResult = lscp_client_get_result(pClient);
1837 pszToken = lscp_strtok((char *) pszResult, pszSeps, &(pch));
1838 while (pszToken) {
1839 if (strcasecmp(pszToken, "NAME") == 0) {
1840 pszToken = lscp_strtok(NULL, pszCrlf, &(pch));
1841 if (pszToken)
1842 lscp_unquote_dup(&(pInstrInfo->name), &pszToken);
1843 }
1844 else if (strcasecmp(pszToken, "ENGINE_NAME") == 0) {
1845 pszToken = lscp_strtok(NULL, pszCrlf, &(pch));
1846 if (pszToken)
1847 lscp_unquote_dup(&(pInstrInfo->engine_name), &pszToken);
1848 }
1849 else if (strcasecmp(pszToken, "INSTRUMENT_FILE") == 0) {
1850 pszToken = lscp_strtok(NULL, pszCrlf, &(pch));
1851 if (pszToken)
1852 lscp_unquote_dup(&(pInstrInfo->instrument_file), &pszToken);
1853 }
1854 else if (strcasecmp(pszToken, "INSTRUMENT_NR") == 0) {
1855 pszToken = lscp_strtok(NULL, pszCrlf, &(pch));
1856 if (pszToken)
1857 pInstrInfo->instrument_nr = atoi(lscp_ltrim(pszToken));
1858 }
1859 else if (strcasecmp(pszToken, "INSTRUMENT_NAME") == 0) {
1860 pszToken = lscp_strtok(NULL, pszCrlf, &(pch));
1861 if (pszToken)
1862 lscp_unquote_dup(&(pInstrInfo->instrument_name), &pszToken);
1863 }
1864 else if (strcasecmp(pszToken, "LOAD_MODE") == 0) {
1865 pszToken = lscp_strtok(NULL, pszCrlf, &(pch));
1866 if (pszToken) {
1867 pszToken = lscp_ltrim(pszToken);
1868 if (strcasecmp(pszToken, "ON_DEMAND") == 0)
1869 pInstrInfo->load_mode = LSCP_LOAD_ON_DEMAND;
1870 else
1871 if (strcasecmp(pszToken, "ON_DEMAND_HOLD") == 0)
1872 pInstrInfo->load_mode = LSCP_LOAD_ON_DEMAND_HOLD;
1873 else
1874 if (strcasecmp(pszToken, "PERSISTENT") == 0)
1875 pInstrInfo->load_mode = LSCP_LOAD_PERSISTENT;
1876 else
1877 pInstrInfo->load_mode = LSCP_LOAD_DEFAULT;
1878 }
1879 }
1880 else if (strcasecmp(pszToken, "VOLUME") == 0) {
1881 pszToken = lscp_strtok(NULL, pszCrlf, &(pch));
1882 if (pszToken)
1883 pInstrInfo->volume = (float) atof(lscp_ltrim(pszToken));
1884 }
1885 pszToken = lscp_strtok(NULL, pszSeps, &(pch));
1886 }
1887 }
1888 else pInstrInfo = NULL;
1889
1890 // Unlock this section down.
1891 lscp_mutex_unlock(pClient->mutex);
1892
1893 return pInstrInfo;
1894 }
1895
1896
1897 /**
1898 * Clear the MIDI instrumnet map:
1899 * CLEAR MIDI_INSTRUMENTS
1900 *
1901 * @param pClient Pointer to client instance structure.
1902 * @param iSamplerChannel Sampler channel number.
1903 *
1904 * @returns LSCP_OK on success, LSCP_FAILED otherwise.
1905 */
1906 lscp_status_t lscp_clear_midi_instruments ( lscp_client_t *pClient )
1907 {
1908 return lscp_client_query(pClient, "CLEAR MIDI_INSTRUMENTS\r\n");
1909 }
1910
1911
1912 // end of client.c

  ViewVC Help
Powered by ViewVC