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