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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 523 - (show annotations) (download)
Mon May 9 10:17:12 2005 UTC (18 years, 10 months ago) by capela
File MIME type: text/plain
File size: 47900 byte(s)
* [bug #9] Fixed for a LSCP command syntax convention
consistency, regarding the enumeration of available
sampler engines, Audio and MIDI drivers; this has
affected the signature of the following functions:
  lscp_get_available_engines();
  lscp_get_available_audio_drivers();
  lscp_get_available_midi_drivers();
which are now returning an integer count of engines
and drivers, respectively, while the following
functions are now being introduced:
  lscp_list_available_engines();
  lscp_list_available_audio_drivers();
  lscp_list_available_midi_drivers();
taking on the previous functionality, returning
a comma separated list of names.

1 // client.c
2 //
3 /****************************************************************************
4 liblscp - LinuxSampler Control Protocol API
5 Copyright (C) 2004-2005, 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 Lesser General Public
18 License along with this library; if not, write to the Free Software
19 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20
21 *****************************************************************************/
22
23 #include "common.h"
24
25 // Default timeout value (in milliseconds).
26 #define LSCP_TIMEOUT_MSECS 500
27
28
29 // Local prototypes.
30
31 static void _lscp_client_evt_proc (void *pvClient);
32
33 static lscp_status_t _lscp_client_evt_connect (lscp_client_t *pClient);
34 static lscp_status_t _lscp_client_evt_request (lscp_client_t *pClient, int iSubscribe, lscp_event_t event);
35
36
37 //-------------------------------------------------------------------------
38 // Event service (datagram oriented).
39
40 static void _lscp_client_evt_proc ( void *pvClient )
41 {
42 lscp_client_t *pClient = (lscp_client_t *) pvClient;
43
44 fd_set fds; // File descriptor list for select().
45 int fd, fdmax; // Maximum file descriptor number.
46 struct timeval tv; // For specifying a timeout value.
47 int iSelect; // Holds select return status.
48 int iTimeout;
49
50 char achBuffer[LSCP_BUFSIZ];
51 int cchBuffer;
52 const char *pszSeps = ":\r\n";
53 char * pszToken;
54 char * pch;
55 int cchToken;
56 lscp_event_t event;
57
58 #ifdef DEBUG
59 fprintf(stderr, "_lscp_client_evt_proc: Client waiting for events.\n");
60 #endif
61
62 while (pClient->evt.iState) {
63
64 // Prepare for waiting on select...
65 fd = (int) pClient->evt.sock;
66 FD_ZERO(&fds);
67 FD_SET((unsigned int) fd, &fds);
68 fdmax = fd;
69
70 // Use the timeout (x10) select feature ...
71 iTimeout = 10 * pClient->iTimeout;
72 if (iTimeout > 1000) {
73 tv.tv_sec = iTimeout / 1000;
74 iTimeout -= tv.tv_sec * 1000;
75 }
76 else tv.tv_sec = 0;
77 tv.tv_usec = iTimeout * 1000;
78
79 // Wait for event...
80 iSelect = select(fdmax + 1, &fds, NULL, NULL, &tv);
81 if (iSelect > 0 && FD_ISSET(fd, &fds)) {
82 // May recv now...
83 cchBuffer = recv(pClient->evt.sock, achBuffer, sizeof(achBuffer), 0);
84 if (cchBuffer > 0) {
85 // Make sure received buffer it's null terminated.
86 achBuffer[cchBuffer] = (char) 0;
87 // Parse for the notification event message...
88 pszToken = lscp_strtok(achBuffer, pszSeps, &(pch)); // Have "NOTIFY".
89 if (strcasecmp(pszToken, "NOTIFY") == 0) {
90 pszToken = lscp_strtok(NULL, pszSeps, &(pch));
91 event = lscp_event_from_text(pszToken);
92 // And pick the rest of data...
93 pszToken = lscp_strtok(NULL, pszSeps, &(pch));
94 cchToken = (pszToken == NULL ? 0 : strlen(pszToken));
95 // Double-check if we're really up to it...
96 if (pClient->events & event) {
97 // Invoke the client event callback...
98 if ((*pClient->pfnCallback)(
99 pClient,
100 event,
101 pszToken,
102 cchToken,
103 pClient->pvData) != LSCP_OK) {
104 pClient->evt.iState = 0;
105 }
106 }
107 }
108 } else {
109 lscp_socket_perror("_lscp_client_evt_proc: recv");
110 pClient->evt.iState = 0;
111 }
112 } // Check if select has in error.
113 else if (iSelect < 0) {
114 lscp_socket_perror("_lscp_client_evt_proc: select");
115 pClient->evt.iState = 0;
116 }
117
118 // Finally, always signal the event.
119 lscp_cond_signal(pClient->cond);
120 }
121
122 #ifdef DEBUG
123 fprintf(stderr, "_lscp_client_evt_proc: Client closing.\n");
124 #endif
125 }
126
127
128 //-------------------------------------------------------------------------
129 // Event subscription helpers.
130
131 // Open the event service socket connection.
132 static lscp_status_t _lscp_client_evt_connect ( lscp_client_t *pClient )
133 {
134 lscp_socket_t sock;
135 struct sockaddr_in addr;
136 int cAddr;
137 #if defined(WIN32)
138 int iSockOpt = (-1);
139 #endif
140
141 // Prepare the event connection socket...
142 sock = socket(AF_INET, SOCK_STREAM, 0);
143 if (sock == INVALID_SOCKET) {
144 lscp_socket_perror("_lscp_client_evt_connect: socket");
145 return LSCP_FAILED;
146 }
147
148 #if defined(WIN32)
149 if (setsockopt(sock, SOL_SOCKET, SO_DONTLINGER, (char *) &iSockOpt, sizeof(int)) == SOCKET_ERROR)
150 lscp_socket_perror("lscp_client_evt_connect: setsockopt(SO_DONTLINGER)");
151 #endif
152
153 #ifdef DEBUG
154 lscp_socket_getopts("_lscp_client_evt_connect:", sock);
155 #endif
156
157 // Use same address of the command connection.
158 cAddr = sizeof(struct sockaddr_in);
159 memmove((char *) &addr, &(pClient->cmd.addr), cAddr);
160
161 // Start the connection...
162 if (connect(sock, (struct sockaddr *) &addr, cAddr) == SOCKET_ERROR) {
163 lscp_socket_perror("_lscp_client_evt_connect: connect");
164 closesocket(sock);
165 return LSCP_FAILED;
166 }
167
168 // Set our socket agent struct...
169 lscp_socket_agent_init(&(pClient->evt), sock, &addr, cAddr);
170
171 // And finally the service thread...
172 return lscp_socket_agent_start(&(pClient->evt), _lscp_client_evt_proc, pClient, 0);
173 }
174
175
176 // Subscribe to a single event.
177 static lscp_status_t _lscp_client_evt_request ( lscp_client_t *pClient, int iSubscribe, lscp_event_t event )
178 {
179 const char *pszEvent;
180 char szQuery[LSCP_BUFSIZ];
181 int cchQuery;
182
183 if (pClient == NULL)
184 return LSCP_FAILED;
185
186 // Which (single) event?
187 pszEvent = lscp_event_to_text(event);
188 if (pszEvent == NULL)
189 return LSCP_FAILED;
190
191 // Build the query string...
192 cchQuery = sprintf(szQuery, "%sSUBSCRIBE %s\n\n", (iSubscribe == 0 ? "UN" : ""), pszEvent);
193 // Just send data, forget result...
194 if (send(pClient->evt.sock, szQuery, cchQuery, 0) < cchQuery) {
195 lscp_socket_perror("_lscp_client_evt_request: send");
196 return LSCP_FAILED;
197 }
198
199 // Wait on response.
200 lscp_cond_wait(pClient->cond, pClient->mutex);
201
202 // Update as naively as we can...
203 if (iSubscribe)
204 pClient->events |= event;
205 else
206 pClient->events &= ~event;
207
208 return LSCP_OK;
209 }
210
211
212 //-------------------------------------------------------------------------
213 // Client versioning teller fuunction.
214
215
216 /** Retrieve the current client library version string. */
217 const char* lscp_client_package (void) { return LSCP_PACKAGE; }
218
219 /** Retrieve the current client library version string. */
220 const char* lscp_client_version (void) { return LSCP_VERSION; }
221
222 /** Retrieve the current client library build timestamp string. */
223 const char* lscp_client_build (void) { return __DATE__ " " __TIME__; }
224
225
226 //-------------------------------------------------------------------------
227 // Client socket functions.
228
229 /**
230 * Create a client instance, estabilishing a connection to a server hostname,
231 * which must be listening on the given port. A client callback function is
232 * also supplied for server notification event handling.
233 *
234 * @param pszHost Hostname of the linuxsampler listening server.
235 * @param iPort Port number of the linuxsampler listening server.
236 * @param pfnCallback Callback function to receive event notifications.
237 * @param pvData User context opaque data, that will be passed
238 * to the callback function.
239 *
240 * @returns The new client instance pointer if successfull, which shall be
241 * used on all subsequent client calls, NULL otherwise.
242 */
243 lscp_client_t* lscp_client_create ( const char *pszHost, int iPort, lscp_client_proc_t pfnCallback, void *pvData )
244 {
245 lscp_client_t *pClient;
246 struct hostent *pHost;
247 lscp_socket_t sock;
248 struct sockaddr_in addr;
249 int cAddr;
250 #if defined(WIN32)
251 int iSockOpt = (-1);
252 #endif
253
254 if (pfnCallback == NULL) {
255 fprintf(stderr, "lscp_client_create: Invalid client callback function.\n");
256 return NULL;
257 }
258
259 pHost = gethostbyname(pszHost);
260 if (pHost == NULL) {
261 lscp_socket_herror("lscp_client_create: gethostbyname");
262 return NULL;
263 }
264
265 // Allocate client descriptor...
266
267 pClient = (lscp_client_t *) malloc(sizeof(lscp_client_t));
268 if (pClient == NULL) {
269 fprintf(stderr, "lscp_client_create: Out of memory.\n");
270 return NULL;
271 }
272 memset(pClient, 0, sizeof(lscp_client_t));
273
274 pClient->pfnCallback = pfnCallback;
275 pClient->pvData = pvData;
276
277 #ifdef DEBUG
278 fprintf(stderr, "lscp_client_create: pClient=%p: pszHost=%s iPort=%d.\n", pClient, pszHost, iPort);
279 #endif
280
281 // Prepare the command connection socket...
282
283 sock = socket(AF_INET, SOCK_STREAM, 0);
284 if (sock == INVALID_SOCKET) {
285 lscp_socket_perror("lscp_client_create: cmd: socket");
286 free(pClient);
287 return NULL;
288 }
289
290 #if defined(WIN32)
291 if (setsockopt(sock, SOL_SOCKET, SO_DONTLINGER, (char *) &iSockOpt, sizeof(int)) == SOCKET_ERROR)
292 lscp_socket_perror("lscp_client_create: cmd: setsockopt(SO_DONTLINGER)");
293 #endif
294
295 #ifdef DEBUG
296 lscp_socket_getopts("lscp_client_create: cmd", sock);
297 #endif
298
299 cAddr = sizeof(struct sockaddr_in);
300 memset((char *) &addr, 0, cAddr);
301 addr.sin_family = pHost->h_addrtype;
302 memmove((char *) &(addr.sin_addr), pHost->h_addr, pHost->h_length);
303 addr.sin_port = htons((short) iPort);
304
305 if (connect(sock, (struct sockaddr *) &addr, cAddr) == SOCKET_ERROR) {
306 lscp_socket_perror("lscp_client_create: cmd: connect");
307 closesocket(sock);
308 free(pClient);
309 return NULL;
310 }
311
312 // Initialize the command socket agent struct...
313 lscp_socket_agent_init(&(pClient->cmd), sock, &addr, cAddr);
314
315 #ifdef DEBUG
316 fprintf(stderr, "lscp_client_create: cmd: pClient=%p: sock=%d addr=%s port=%d.\n", pClient, pClient->cmd.sock, inet_ntoa(pClient->cmd.addr.sin_addr), ntohs(pClient->cmd.addr.sin_port));
317 #endif
318
319 // Initialize the event service socket struct...
320 lscp_socket_agent_init(&(pClient->evt), INVALID_SOCKET, NULL, 0);
321 // No events subscribed, yet.
322 pClient->events = LSCP_EVENT_NONE;
323 // Initialize cached members.
324 pClient->audio_drivers = NULL;
325 pClient->midi_drivers = NULL;
326 pClient->audio_devices = NULL;
327 pClient->midi_devices = NULL;
328 pClient->engines = NULL;
329 pClient->channels = NULL;
330 lscp_driver_info_init(&(pClient->audio_driver_info));
331 lscp_driver_info_init(&(pClient->midi_driver_info));
332 lscp_device_info_init(&(pClient->audio_device_info));
333 lscp_device_info_init(&(pClient->midi_device_info));
334 lscp_param_info_init(&(pClient->audio_param_info));
335 lscp_param_info_init(&(pClient->midi_param_info));
336 lscp_device_port_info_init(&(pClient->audio_channel_info));
337 lscp_device_port_info_init(&(pClient->midi_port_info));
338 lscp_param_info_init(&(pClient->audio_channel_param_info));
339 lscp_param_info_init(&(pClient->midi_port_param_info));
340 lscp_engine_info_init(&(pClient->engine_info));
341 lscp_channel_info_init(&(pClient->channel_info));
342 // Initialize error stuff.
343 pClient->pszResult = NULL;
344 pClient->iErrno = -1;
345 // Stream usage stuff.
346 pClient->buffer_fill = NULL;
347 pClient->iStreamCount = 0;
348 // Default timeout value.
349 pClient->iTimeout = LSCP_TIMEOUT_MSECS;
350
351 // Initialize the transaction mutex.
352 lscp_mutex_init(pClient->mutex);
353 lscp_cond_init(pClient->cond);
354
355 // Finally we've some success...
356 return pClient;
357 }
358
359
360 /**
361 * Wait for a client instance to terminate graciously.
362 *
363 * @param pClient Pointer to client instance structure.
364 */
365 lscp_status_t lscp_client_join ( lscp_client_t *pClient )
366 {
367 if (pClient == NULL)
368 return LSCP_FAILED;
369
370 #ifdef DEBUG
371 fprintf(stderr, "lscp_client_join: pClient=%p.\n", pClient);
372 #endif
373
374 // lscp_socket_agent_join(&(pClient->evt));
375 lscp_socket_agent_join(&(pClient->cmd));
376
377 return LSCP_OK;
378 }
379
380
381 /**
382 * Terminate and destroy a client instance.
383 *
384 * @param pClient Pointer to client instance structure.
385 *
386 * @returns LSCP_OK on success, LSCP_FAILED otherwise.
387 */
388 lscp_status_t lscp_client_destroy ( lscp_client_t *pClient )
389 {
390 if (pClient == NULL)
391 return LSCP_FAILED;
392
393 #ifdef DEBUG
394 fprintf(stderr, "lscp_client_destroy: pClient=%p.\n", pClient);
395 #endif
396
397 // Lock this section up.
398 lscp_mutex_lock(pClient->mutex);
399
400 // Free up all cached members.
401 lscp_channel_info_free(&(pClient->channel_info));
402 lscp_engine_info_free(&(pClient->engine_info));
403 lscp_param_info_free(&(pClient->midi_port_param_info));
404 lscp_param_info_free(&(pClient->audio_channel_param_info));
405 lscp_device_port_info_free(&(pClient->midi_port_info));
406 lscp_device_port_info_free(&(pClient->audio_channel_info));
407 lscp_param_info_free(&(pClient->midi_param_info));
408 lscp_param_info_free(&(pClient->audio_param_info));
409 lscp_device_info_free(&(pClient->midi_device_info));
410 lscp_device_info_free(&(pClient->audio_device_info));
411 lscp_driver_info_free(&(pClient->midi_driver_info));
412 lscp_driver_info_free(&(pClient->audio_driver_info));
413 // Free available engine table.
414 lscp_szsplit_destroy(pClient->audio_drivers);
415 lscp_szsplit_destroy(pClient->midi_drivers);
416 lscp_isplit_destroy(pClient->audio_devices);
417 lscp_isplit_destroy(pClient->midi_devices);
418 lscp_szsplit_destroy(pClient->engines);
419 lscp_isplit_destroy(pClient->channels);
420 // Make them null.
421 pClient->audio_drivers = NULL;
422 pClient->midi_drivers = NULL;
423 pClient->engines = NULL;
424 // Free result error stuff.
425 lscp_client_set_result(pClient, NULL, 0);
426 // Free stream usage stuff.
427 if (pClient->buffer_fill)
428 free(pClient->buffer_fill);
429 pClient->buffer_fill = NULL;
430 pClient->iStreamCount = 0;
431 pClient->iTimeout = 0;
432
433 // Free socket agents.
434 lscp_socket_agent_free(&(pClient->evt));
435 lscp_socket_agent_free(&(pClient->cmd));
436
437 // Last but not least, free good ol'transaction mutex.
438 lscp_mutex_unlock(pClient->mutex);
439 lscp_mutex_destroy(pClient->mutex);
440 lscp_cond_destroy(pClient->cond);
441
442 free(pClient);
443
444 return LSCP_OK;
445 }
446
447
448 /**
449 * Set the client transaction timeout interval.
450 *
451 * @param pClient Pointer to client instance structure.
452 * @param iTimeout Transaction timeout in milliseconds.
453 *
454 * @returns LSCP_OK on success, LSCP_FAILED otherwise.
455 */
456 lscp_status_t lscp_client_set_timeout ( lscp_client_t *pClient, int iTimeout )
457 {
458 if (pClient == NULL)
459 return LSCP_FAILED;
460 if (iTimeout < 0)
461 return LSCP_FAILED;
462
463 pClient->iTimeout = iTimeout;
464 return LSCP_OK;
465 }
466
467
468 /**
469 * Get the client transaction timeout interval.
470 *
471 * @param pClient Pointer to client instance structure.
472 *
473 * @returns The current timeout value milliseconds, -1 in case of failure.
474 */
475 int lscp_client_get_timeout ( lscp_client_t *pClient )
476 {
477 if (pClient == NULL)
478 return -1;
479
480 return pClient->iTimeout;
481 }
482
483
484 //-------------------------------------------------------------------------
485 // Client common protocol functions.
486
487 /**
488 * Submit a command query line string to the server. The query string
489 * must be cr/lf and null terminated. Besides the return code, the
490 * specific server response to the command request is made available
491 * by the @ref lscp_client_get_result and @ref lscp_client_get_errno
492 * function calls.
493 *
494 * @param pClient Pointer to client instance structure.
495 * @param pszQuery Command request line to be sent to server,
496 * must be cr/lf and null terminated.
497 *
498 * @returns LSCP_OK on success, LSCP_FAILED otherwise.
499 */
500 lscp_status_t lscp_client_query ( lscp_client_t *pClient, const char *pszQuery )
501 {
502 lscp_status_t ret;
503
504 // Lock this section up.
505 lscp_mutex_lock(pClient->mutex);
506
507 // Just make the now guarded call.
508 ret = lscp_client_call(pClient, pszQuery);
509
510 // Unlock this section down.
511 lscp_mutex_unlock(pClient->mutex);
512
513 return ret;
514 }
515
516 /**
517 * Get the last received result string. In case of error or warning,
518 * this is the text of the error or warning message issued.
519 *
520 * @param pClient Pointer to client instance structure.
521 *
522 * @returns A pointer to the literal null-terminated result string as
523 * of the last command request.
524 */
525 const char *lscp_client_get_result ( lscp_client_t *pClient )
526 {
527 if (pClient == NULL)
528 return NULL;
529
530 return pClient->pszResult;
531 }
532
533
534 /**
535 * Get the last error/warning number received.
536 *
537 * @param pClient Pointer to client instance structure.
538 *
539 * @returns The numerical value of the last error or warning
540 * response code received.
541 */
542 int lscp_client_get_errno ( lscp_client_t *pClient )
543 {
544 if (pClient == NULL)
545 return -1;
546
547 return pClient->iErrno;
548 }
549
550
551 //-------------------------------------------------------------------------
552 // Client registration protocol functions.
553
554 /**
555 * Register frontend for receiving event messages:
556 * SUBSCRIBE CHANNELS | VOICE_COUNT | STREAM_COUNT | BUFFER_FILL
557 * | CHANNEL_INFO | MISCELLANEOUS
558 *
559 * @param pClient Pointer to client instance structure.
560 * @param events Bit-wise OR'ed event flags to subscribe.
561 *
562 * @returns LSCP_OK on success, LSCP_FAILED otherwise.
563 */
564 lscp_status_t lscp_client_subscribe ( lscp_client_t *pClient, lscp_event_t events )
565 {
566 lscp_status_t ret = LSCP_FAILED;
567
568 if (pClient == NULL)
569 return LSCP_FAILED;
570
571 // Lock this section up.
572 lscp_mutex_lock(pClient->mutex);
573
574 // If applicable, start the alternate connection...
575 if (pClient->events == LSCP_EVENT_NONE)
576 ret = _lscp_client_evt_connect(pClient);
577
578 // Send the subscription commands.
579 if (ret == LSCP_OK && (events & LSCP_EVENT_CHANNELS))
580 ret = _lscp_client_evt_request(pClient, 1, LSCP_EVENT_CHANNELS);
581 if (ret == LSCP_OK && (events & LSCP_EVENT_VOICE_COUNT))
582 ret = _lscp_client_evt_request(pClient, 1, LSCP_EVENT_VOICE_COUNT);
583 if (ret == LSCP_OK && (events & LSCP_EVENT_STREAM_COUNT))
584 ret = _lscp_client_evt_request(pClient, 1, LSCP_EVENT_STREAM_COUNT);
585 if (ret == LSCP_OK && (events & LSCP_EVENT_BUFFER_FILL))
586 ret = _lscp_client_evt_request(pClient, 1, LSCP_EVENT_BUFFER_FILL);
587 if (ret == LSCP_OK && (events & LSCP_EVENT_CHANNEL_INFO))
588 ret = _lscp_client_evt_request(pClient, 1, LSCP_EVENT_CHANNEL_INFO);
589 if (ret == LSCP_OK && (events & LSCP_EVENT_MISCELLANEOUS))
590 ret = _lscp_client_evt_request(pClient, 1, LSCP_EVENT_MISCELLANEOUS);
591
592 // Unlock this section down.
593 lscp_mutex_unlock(pClient->mutex);
594
595 return ret;
596 }
597
598
599 /**
600 * Deregister frontend from receiving UDP event messages anymore:
601 * SUBSCRIBE CHANNELS | VOICE_COUNT | STREAM_COUNT | BUFFER_FILL
602 * | CHANNEL_INFO | MISCELLANEOUS
603 *
604 * @param pClient Pointer to client instance structure.
605 * @param events Bit-wise OR'ed event flags to unsubscribe.
606 *
607 * @returns LSCP_OK on success, LSCP_FAILED otherwise.
608 */
609 lscp_status_t lscp_client_unsubscribe ( lscp_client_t *pClient, lscp_event_t events )
610 {
611 lscp_status_t ret = LSCP_OK;
612
613 if (pClient == NULL)
614 return LSCP_FAILED;
615
616 // Lock this section up.
617 lscp_mutex_lock(pClient->mutex);
618
619 // Send the unsubscription commands.
620 if (ret == LSCP_OK && (events & LSCP_EVENT_CHANNELS))
621 ret = _lscp_client_evt_request(pClient, 0, LSCP_EVENT_CHANNELS);
622 if (ret == LSCP_OK && (events & LSCP_EVENT_VOICE_COUNT))
623 ret = _lscp_client_evt_request(pClient, 0, LSCP_EVENT_VOICE_COUNT);
624 if (ret == LSCP_OK && (events & LSCP_EVENT_STREAM_COUNT))
625 ret = _lscp_client_evt_request(pClient, 0, LSCP_EVENT_STREAM_COUNT);
626 if (ret == LSCP_OK && (events & LSCP_EVENT_BUFFER_FILL))
627 ret = _lscp_client_evt_request(pClient, 0, LSCP_EVENT_BUFFER_FILL);
628 if (ret == LSCP_OK && (events & LSCP_EVENT_CHANNEL_INFO))
629 ret = _lscp_client_evt_request(pClient, 0, LSCP_EVENT_CHANNEL_INFO);
630 if (ret == LSCP_OK && (events & LSCP_EVENT_MISCELLANEOUS))
631 ret = _lscp_client_evt_request(pClient, 0, LSCP_EVENT_MISCELLANEOUS);
632
633 // If necessary, close the alternate connection...
634 if (pClient->events == LSCP_EVENT_NONE)
635 lscp_socket_agent_free(&(pClient->evt));
636
637 // Unlock this section down.
638 lscp_mutex_unlock(pClient->mutex);
639
640 return ret;
641 }
642
643
644 /**
645 * Getting current subscribed events.
646 *
647 * @param pClient Pointer to client instance structure.
648 *
649 * @returns The current subscrived bit-wise OR'ed event flags.
650 */
651 lscp_event_t lscp_client_get_events ( lscp_client_t *pClient )
652 {
653 if (pClient == NULL)
654 return LSCP_EVENT_NONE;
655
656 return pClient->events;
657 }
658
659
660 //-------------------------------------------------------------------------
661 // Client command protocol functions.
662
663 /**
664 * Loading an instrument:
665 * LOAD INSTRUMENT <filename> <instr-index> <sampler-channel>
666 *
667 * @param pClient Pointer to client instance structure.
668 * @param pszFileName Instrument file name.
669 * @param iInstrIndex Instrument index number.
670 * @param iSamplerChannel Sampler Channel.
671 *
672 * @returns LSCP_OK on success, LSCP_FAILED otherwise.
673 */
674 lscp_status_t lscp_load_instrument ( lscp_client_t *pClient, const char *pszFileName, int iInstrIndex, int iSamplerChannel )
675 {
676 char szQuery[LSCP_BUFSIZ];
677
678 if (pszFileName == NULL || iSamplerChannel < 0)
679 return LSCP_FAILED;
680
681 sprintf(szQuery, "LOAD INSTRUMENT '%s' %d %d\r\n", pszFileName, iInstrIndex, iSamplerChannel);
682 return lscp_client_query(pClient, szQuery);
683 }
684
685
686 /**
687 * Loading an instrument in the background (non modal):
688 * LOAD INSTRUMENT NON_MODAL <filename> <instr-index> <sampler-channel>
689 *
690 * @param pClient Pointer to client instance structure.
691 * @param pszFileName Instrument file name.
692 * @param iInstrIndex Instrument index number.
693 * @param iSamplerChannel Sampler Channel.
694 *
695 * @returns LSCP_OK on success, LSCP_FAILED otherwise.
696 */
697 lscp_status_t lscp_load_instrument_non_modal ( lscp_client_t *pClient, const char *pszFileName, int iInstrIndex, int iSamplerChannel )
698 {
699 char szQuery[LSCP_BUFSIZ];
700
701 if (pszFileName == NULL || iSamplerChannel < 0)
702 return LSCP_FAILED;
703
704 sprintf(szQuery, "LOAD INSTRUMENT NON_MODAL '%s' %d %d\r\n", pszFileName, iInstrIndex, iSamplerChannel);
705 return lscp_client_query(pClient, szQuery);
706 }
707
708
709 /**
710 * Loading a sampler engine:
711 * LOAD ENGINE <engine-name> <sampler-channel>
712 *
713 * @param pClient Pointer to client instance structure.
714 * @param pszEngineName Engine name.
715 * @param iSamplerChannel Sampler channel number.
716 *
717 * @returns LSCP_OK on success, LSCP_FAILED otherwise.
718 */
719 lscp_status_t lscp_load_engine ( lscp_client_t *pClient, const char *pszEngineName, int iSamplerChannel )
720 {
721 char szQuery[LSCP_BUFSIZ];
722
723 if (pszEngineName == NULL || iSamplerChannel < 0)
724 return LSCP_FAILED;
725
726 sprintf(szQuery, "LOAD ENGINE %s %d\r\n", pszEngineName, iSamplerChannel);
727 return lscp_client_query(pClient, szQuery);
728 }
729
730
731 /**
732 * Current number of sampler channels:
733 * GET CHANNELS
734 *
735 * @param pClient Pointer to client instance structure.
736 *
737 * @returns The current total number of sampler channels on success,
738 * -1 otherwise.
739 */
740 int lscp_get_channels ( lscp_client_t *pClient )
741 {
742 int iChannels = -1;
743
744 // Lock this section up.
745 lscp_mutex_lock(pClient->mutex);
746
747 if (lscp_client_call(pClient, "GET CHANNELS\r\n") == LSCP_OK)
748 iChannels = atoi(lscp_client_get_result(pClient));
749
750 // Unlock this section doen.
751 lscp_mutex_unlock(pClient->mutex);
752
753 return iChannels;
754 }
755
756
757 /**
758 * List current sampler channels number identifiers:
759 * LIST CHANNELS
760 *
761 * @param pClient Pointer to client instance structure.
762 *
763 * @returns An array of the sampler channels identifiers as positive integers,
764 * terminated with -1 on success, NULL otherwise.
765 */
766 int *lscp_list_channels ( lscp_client_t *pClient )
767 {
768 const char *pszSeps = ",";
769
770 if (pClient == NULL)
771 return NULL;
772
773 // Lock this section up.
774 lscp_mutex_lock(pClient->mutex);
775
776 if (pClient->channels) {
777 lscp_isplit_destroy(pClient->channels);
778 pClient->channels = NULL;
779 }
780
781 if (lscp_client_call(pClient, "LIST CHANNELS\r\n") == LSCP_OK)
782 pClient->channels = lscp_isplit_create(lscp_client_get_result(pClient), pszSeps);
783
784 // Unlock this section down.
785 lscp_mutex_unlock(pClient->mutex);
786
787 return pClient->channels;
788 }
789
790
791 /**
792 * Adding a new sampler channel:
793 * ADD CHANNEL
794 *
795 * @param pClient Pointer to client instance structure.
796 *
797 * @returns The new sampler channel number identifier,
798 * or -1 in case of failure.
799 */
800 int lscp_add_channel ( lscp_client_t *pClient )
801 {
802 int iSamplerChannel = -1;
803
804 // Lock this section up.
805 lscp_mutex_lock(pClient->mutex);
806
807 if (lscp_client_call(pClient, "ADD CHANNEL\r\n") == LSCP_OK)
808 iSamplerChannel = atoi(lscp_client_get_result(pClient));
809
810 // Unlock this section down.
811 lscp_mutex_unlock(pClient->mutex);
812
813 return iSamplerChannel;
814 }
815
816
817 /**
818 * Removing a sampler channel:
819 * REMOVE CHANNEL <sampler-channel>
820 *
821 * @param pClient Pointer to client instance structure.
822 * @param iSamplerChannel Sampler channel number.
823 *
824 * @returns LSCP_OK on success, LSCP_FAILED otherwise.
825 */
826 lscp_status_t lscp_remove_channel ( lscp_client_t *pClient, int iSamplerChannel )
827 {
828 char szQuery[LSCP_BUFSIZ];
829
830 if (iSamplerChannel < 0)
831 return LSCP_FAILED;
832
833 sprintf(szQuery, "REMOVE CHANNEL %d\r\n", iSamplerChannel);
834 return lscp_client_query(pClient, szQuery);
835 }
836
837
838 /**
839 * Getting all available engines count:
840 * GET AVAILABLE_ENGINES
841 *
842 * @param pClient Pointer to client instance structure.
843 *
844 * @returns The current total number of sampler engines on success,
845 * -1 otherwise.
846 */
847 int lscp_get_available_engines ( lscp_client_t *pClient )
848 {
849 int iAvailableEngines = -1;
850
851 // Lock this section up.
852 lscp_mutex_lock(pClient->mutex);
853
854 if (lscp_client_call(pClient, "GET AVAILABLE_ENGINES\r\n") == LSCP_OK)
855 iAvailableEngines = atoi(lscp_client_get_result(pClient));
856
857 // Unlock this section down.
858 lscp_mutex_unlock(pClient->mutex);
859
860 return iAvailableEngines;
861 }
862
863
864 /**
865 * Getting all available engines:
866 * LIST AVAILABLE_ENGINES
867 *
868 * @param pClient Pointer to client instance structure.
869 *
870 * @returns A NULL terminated array of engine name strings,
871 * or NULL in case of failure.
872 */
873 const char **lscp_list_available_engines ( lscp_client_t *pClient )
874 {
875 const char *pszSeps = ",";
876
877 // Lock this section up.
878 lscp_mutex_lock(pClient->mutex);
879
880 if (pClient->engines) {
881 lscp_szsplit_destroy(pClient->engines);
882 pClient->engines = NULL;
883 }
884
885 if (lscp_client_call(pClient, "LIST AVAILABLE_ENGINES\r\n") == LSCP_OK)
886 pClient->engines = lscp_szsplit_create(lscp_client_get_result(pClient), pszSeps);
887
888 // Unlock this section down.
889 lscp_mutex_unlock(pClient->mutex);
890
891 return (const char **) pClient->engines;
892 }
893
894
895 /**
896 * Getting information about an engine.
897 * GET ENGINE INFO <engine-name>
898 *
899 * @param pClient Pointer to client instance structure.
900 * @param pszEngineName Engine name.
901 *
902 * @returns A pointer to a @ref lscp_engine_info_t structure, with all the
903 * information of the given sampler engine, or NULL in case of failure.
904 */
905 lscp_engine_info_t *lscp_get_engine_info ( lscp_client_t *pClient, const char *pszEngineName )
906 {
907 lscp_engine_info_t *pEngineInfo;
908 char szQuery[LSCP_BUFSIZ];
909 const char *pszResult;
910 const char *pszSeps = ":";
911 const char *pszCrlf = "\r\n";
912 char *pszToken;
913 char *pch;
914
915 if (pszEngineName == NULL)
916 return NULL;
917
918 // Lock this section up.
919 lscp_mutex_lock(pClient->mutex);
920
921 pEngineInfo = &(pClient->engine_info);
922 lscp_engine_info_reset(pEngineInfo);
923
924 sprintf(szQuery, "GET ENGINE INFO %s\r\n", pszEngineName);
925 if (lscp_client_call(pClient, szQuery) == LSCP_OK) {
926 pszResult = lscp_client_get_result(pClient);
927 pszToken = lscp_strtok((char *) pszResult, pszSeps, &(pch));
928 while (pszToken) {
929 if (strcasecmp(pszToken, "DESCRIPTION") == 0) {
930 pszToken = lscp_strtok(NULL, pszCrlf, &(pch));
931 if (pszToken)
932 lscp_unquote_dup(&(pEngineInfo->description), &pszToken);
933 }
934 else if (strcasecmp(pszToken, "VERSION") == 0) {
935 pszToken = lscp_strtok(NULL, pszCrlf, &(pch));
936 if (pszToken)
937 lscp_unquote_dup(&(pEngineInfo->version), &pszToken);
938 }
939 pszToken = lscp_strtok(NULL, pszSeps, &(pch));
940 }
941 }
942 else pEngineInfo = NULL;
943
944 // Unlock this section down.
945 lscp_mutex_unlock(pClient->mutex);
946
947 return pEngineInfo;
948 }
949
950
951 /**
952 * Getting sampler channel informations:
953 * GET CHANNEL INFO <sampler-channel>
954 *
955 * @param pClient Pointer to client instance structure.
956 * @param iSamplerChannel Sampler channel number.
957 *
958 * @returns A pointer to a @ref lscp_channel_info_t structure, with all the
959 * information of the given sampler channel, or NULL in case of failure.
960 */
961 lscp_channel_info_t *lscp_get_channel_info ( lscp_client_t *pClient, int iSamplerChannel )
962 {
963 lscp_channel_info_t *pChannelInfo;
964 char szQuery[LSCP_BUFSIZ];
965 const char *pszResult;
966 const char *pszSeps = ":";
967 const char *pszCrlf = "\r\n";
968 char *pszToken;
969 char *pch;
970
971 if (iSamplerChannel < 0)
972 return NULL;
973
974 // Lock this section up.
975 lscp_mutex_lock(pClient->mutex);
976
977 pChannelInfo = &(pClient->channel_info);
978 lscp_channel_info_reset(pChannelInfo);
979
980 sprintf(szQuery, "GET CHANNEL INFO %d\r\n", iSamplerChannel);
981 if (lscp_client_call(pClient, szQuery) == LSCP_OK) {
982 pszResult = lscp_client_get_result(pClient);
983 pszToken = lscp_strtok((char *) pszResult, pszSeps, &(pch));
984 while (pszToken) {
985 if (strcasecmp(pszToken, "ENGINE_NAME") == 0) {
986 pszToken = lscp_strtok(NULL, pszCrlf, &(pch));
987 if (pszToken)
988 lscp_unquote_dup(&(pChannelInfo->engine_name), &pszToken);
989 }
990 else if (strcasecmp(pszToken, "AUDIO_OUTPUT_DEVICE") == 0) {
991 pszToken = lscp_strtok(NULL, pszCrlf, &(pch));
992 if (pszToken)
993 pChannelInfo->audio_device = atoi(lscp_ltrim(pszToken));
994 }
995 else if (strcasecmp(pszToken, "AUDIO_OUTPUT_CHANNELS") == 0) {
996 pszToken = lscp_strtok(NULL, pszCrlf, &(pch));
997 if (pszToken)
998 pChannelInfo->audio_channels = atoi(lscp_ltrim(pszToken));
999 }
1000 else if (strcasecmp(pszToken, "AUDIO_OUTPUT_ROUTING") == 0) {
1001 pszToken = lscp_strtok(NULL, pszCrlf, &(pch));
1002 if (pszToken) {
1003 if (pChannelInfo->audio_routing)
1004 lscp_szsplit_destroy(pChannelInfo->audio_routing);
1005 pChannelInfo->audio_routing = lscp_szsplit_create(pszToken, ",");
1006 }
1007 }
1008 else if (strcasecmp(pszToken, "INSTRUMENT_FILE") == 0) {
1009 pszToken = lscp_strtok(NULL, pszCrlf, &(pch));
1010 if (pszToken)
1011 lscp_unquote_dup(&(pChannelInfo->instrument_file), &pszToken);
1012 }
1013 else if (strcasecmp(pszToken, "INSTRUMENT_NR") == 0) {
1014 pszToken = lscp_strtok(NULL, pszCrlf, &(pch));
1015 if (pszToken)
1016 pChannelInfo->instrument_nr = atoi(lscp_ltrim(pszToken));
1017 }
1018 else if (strcasecmp(pszToken, "INSTRUMENT_NAME") == 0) {
1019 pszToken = lscp_strtok(NULL, pszCrlf, &(pch));
1020 if (pszToken)
1021 lscp_unquote_dup(&(pChannelInfo->instrument_name), &pszToken);
1022 }
1023 else if (strcasecmp(pszToken, "INSTRUMENT_STATUS") == 0) {
1024 pszToken = lscp_strtok(NULL, pszCrlf, &(pch));
1025 if (pszToken)
1026 pChannelInfo->instrument_status = atoi(lscp_ltrim(pszToken));
1027 }
1028 else if (strcasecmp(pszToken, "MIDI_INPUT_DEVICE") == 0) {
1029 pszToken = lscp_strtok(NULL, pszCrlf, &(pch));
1030 if (pszToken)
1031 pChannelInfo->midi_device = atoi(lscp_ltrim(pszToken));
1032 }
1033 else if (strcasecmp(pszToken, "MIDI_INPUT_PORT") == 0) {
1034 pszToken = lscp_strtok(NULL, pszCrlf, &(pch));
1035 if (pszToken)
1036 pChannelInfo->midi_port = atoi(lscp_ltrim(pszToken));
1037 }
1038 else if (strcasecmp(pszToken, "MIDI_INPUT_CHANNEL") == 0) {
1039 pszToken = lscp_strtok(NULL, pszCrlf, &(pch));
1040 if (pszToken) {
1041 pszToken = lscp_ltrim(pszToken);
1042 if (strcasecmp(pszToken, "ALL") == 0)
1043 pChannelInfo->midi_channel = LSCP_MIDI_CHANNEL_ALL;
1044 else
1045 pChannelInfo->midi_channel = atoi(pszToken);
1046 }
1047 }
1048 else if (strcasecmp(pszToken, "VOLUME") == 0) {
1049 pszToken = lscp_strtok(NULL, pszCrlf, &(pch));
1050 if (pszToken)
1051 pChannelInfo->volume = (float) atof(lscp_ltrim(pszToken));
1052 }
1053 pszToken = lscp_strtok(NULL, pszSeps, &(pch));
1054 }
1055 }
1056 else pChannelInfo = NULL;
1057
1058 // Unlock this section up.
1059 lscp_mutex_unlock(pClient->mutex);
1060
1061 return pChannelInfo;
1062 }
1063
1064
1065 /**
1066 * Current number of active voices:
1067 * GET CHANNEL VOICE_COUNT <sampler-channel>
1068 *
1069 * @param pClient Pointer to client instance structure.
1070 * @param iSamplerChannel Sampler channel number.
1071 *
1072 * @returns The number of voices currently active, -1 in case of failure.
1073 */
1074 int lscp_get_channel_voice_count ( lscp_client_t *pClient, int iSamplerChannel )
1075 {
1076 char szQuery[LSCP_BUFSIZ];
1077 int iVoiceCount = -1;
1078
1079 if (iSamplerChannel < 0)
1080 return iVoiceCount;
1081
1082 // Lock this section up.
1083 lscp_mutex_lock(pClient->mutex);
1084
1085 sprintf(szQuery, "GET CHANNEL VOICE_COUNT %d\r\n", iSamplerChannel);
1086 if (lscp_client_call(pClient, szQuery) == LSCP_OK)
1087 iVoiceCount = atoi(lscp_client_get_result(pClient));
1088
1089 // Unlock this section down.
1090 lscp_mutex_unlock(pClient->mutex);
1091
1092 return iVoiceCount;
1093 }
1094
1095
1096 /**
1097 * Current number of active disk streams:
1098 * GET CHANNEL STREAM_COUNT <sampler-channel>
1099 *
1100 * @param pClient Pointer to client instance structure.
1101 * @param iSamplerChannel Sampler channel number.
1102 *
1103 * @returns The number of active disk streams on success, -1 otherwise.
1104 */
1105 int lscp_get_channel_stream_count ( lscp_client_t *pClient, int iSamplerChannel )
1106 {
1107 char szQuery[LSCP_BUFSIZ];
1108 int iStreamCount = -1;
1109
1110 if (iSamplerChannel < 0)
1111 return iStreamCount;
1112
1113 // Lock this section up.
1114 lscp_mutex_lock(pClient->mutex);
1115
1116 sprintf(szQuery, "GET CHANNEL STREAM_COUNT %d\r\n", iSamplerChannel);
1117 if (lscp_client_call(pClient, szQuery) == LSCP_OK)
1118 iStreamCount = atoi(lscp_client_get_result(pClient));
1119
1120 // Unlock this section down.
1121 lscp_mutex_unlock(pClient->mutex);
1122
1123 return iStreamCount;
1124 }
1125
1126
1127 /**
1128 * Current least usage of active disk streams.
1129 *
1130 * @param pClient Pointer to client instance structure.
1131 * @param iSamplerChannel Sampler channel number.
1132 *
1133 * @returns The usage percentage of the least filled active disk stream
1134 * on success, -1 otherwise.
1135 */
1136 int lscp_get_channel_stream_usage ( lscp_client_t *pClient, int iSamplerChannel )
1137 {
1138 char szQuery[LSCP_BUFSIZ];
1139 int iStreamUsage = -1;
1140 const char *pszResult;
1141 const char *pszSeps = "[]%,";
1142 char *pszToken;
1143 char *pch;
1144 int iStream;
1145 int iPercent;
1146
1147 if (iSamplerChannel < 0)
1148 return iStreamUsage;
1149
1150 // Lock this section up.
1151 lscp_mutex_lock(pClient->mutex);
1152
1153 iStream = 0;
1154 sprintf(szQuery, "GET CHANNEL BUFFER_FILL PERCENTAGE %d\r\n", iSamplerChannel);
1155 if (lscp_client_call(pClient, szQuery) == LSCP_OK) {
1156 pszResult = lscp_client_get_result(pClient);
1157 pszToken = lscp_strtok((char *) pszResult, pszSeps, &(pch));
1158 while (pszToken) {
1159 if (*pszToken) {
1160 // Skip stream id.
1161 pszToken = lscp_strtok(NULL, pszSeps, &(pch));
1162 if (pszToken == NULL)
1163 break;
1164 // Get least buffer fill percentage.
1165 iPercent = atol(pszToken);
1166 if (iStreamUsage > iPercent || iStream == 0)
1167 iStreamUsage = iPercent;
1168 iStream++;
1169 }
1170 pszToken = lscp_strtok(NULL, pszSeps, &(pch));
1171 }
1172 }
1173
1174 // Unlock this section down.
1175 lscp_mutex_unlock(pClient->mutex);
1176
1177 return iStreamUsage;
1178 }
1179
1180
1181 /**
1182 * Current fill state of disk stream buffers:
1183 * GET CHANNEL BUFFER_FILL {BYTES|PERCENTAGE} <sampler-channel>
1184 *
1185 * @param pClient Pointer to client instance structure.
1186 * @param usage_type Usage type to be returned, either
1187 * @ref LSCP_USAGE_BYTES, or
1188 * @ref LSCP_USAGE_PERCENTAGE.
1189 * @param iSamplerChannel Sampler channel number.
1190 *
1191 * @returns A pointer to a @ref lscp_buffer_fill_t structure, with the
1192 * information of the current disk stream buffer fill usage, for the given
1193 * sampler channel, or NULL in case of failure.
1194 */
1195 lscp_buffer_fill_t *lscp_get_channel_buffer_fill ( lscp_client_t *pClient, lscp_usage_t usage_type, int iSamplerChannel )
1196 {
1197 lscp_buffer_fill_t *pBufferFill;
1198 char szQuery[LSCP_BUFSIZ];
1199 int iStreamCount;
1200 const char *pszUsageType = (usage_type == LSCP_USAGE_BYTES ? "BYTES" : "PERCENTAGE");
1201 const char *pszResult;
1202 const char *pszSeps = "[]%,";
1203 char *pszToken;
1204 char *pch;
1205 int iStream;
1206
1207 // Retrieve a channel stream estimation.
1208 iStreamCount = lscp_get_channel_stream_count(pClient, iSamplerChannel);
1209 if (pClient->iStreamCount < 0)
1210 return NULL;
1211
1212 // Lock this section up.
1213 lscp_mutex_lock(pClient->mutex);
1214
1215 // Check if we need to reallocate the stream usage array.
1216 if (pClient->iStreamCount != iStreamCount) {
1217 if (pClient->buffer_fill)
1218 free(pClient->buffer_fill);
1219 if (iStreamCount > 0)
1220 pClient->buffer_fill = (lscp_buffer_fill_t *) malloc(iStreamCount * sizeof(lscp_buffer_fill_t));
1221 else
1222 pClient->buffer_fill = NULL;
1223 pClient->iStreamCount = iStreamCount;
1224 }
1225
1226 // Get buffer fill usage...
1227 pBufferFill = pClient->buffer_fill;
1228 if (pBufferFill && iStreamCount > 0) {
1229 iStream = 0;
1230 pBufferFill = pClient->buffer_fill;
1231 sprintf(szQuery, "GET CHANNEL BUFFER_FILL %s %d\r\n", pszUsageType, iSamplerChannel);
1232 if (lscp_client_call(pClient, szQuery) == LSCP_OK) {
1233 pszResult = lscp_client_get_result(pClient);
1234 pszToken = lscp_strtok((char *) pszResult, pszSeps, &(pch));
1235 while (pszToken && iStream < pClient->iStreamCount) {
1236 if (*pszToken) {
1237 pBufferFill[iStream].stream_id = atol(pszToken);
1238 pszToken = lscp_strtok(NULL, pszSeps, &(pch));
1239 if (pszToken == NULL)
1240 break;
1241 pBufferFill[iStream].stream_usage = atol(pszToken);
1242 iStream++;
1243 }
1244 pszToken = lscp_strtok(NULL, pszSeps, &(pch));
1245 }
1246 } // Reset the usage, whatever it was before.
1247 else while (iStream < pClient->iStreamCount)
1248 pBufferFill[iStream++].stream_usage = 0;
1249 }
1250
1251 // Unlock this section down.
1252 lscp_mutex_unlock(pClient->mutex);
1253
1254 return pBufferFill;
1255 }
1256
1257
1258 /**
1259 * Setting audio output type:
1260 * SET CHANNEL AUDIO_OUTPUT_TYPE <sampler-channel> <audio-output-type>
1261 *
1262 * @param pClient Pointer to client instance structure.
1263 * @param iSamplerChannel Sampler channel number.
1264 * @param pszAudioDriver Audio output driver type (e.g. "ALSA" or "JACK").
1265 */
1266 lscp_status_t lscp_set_channel_audio_type ( lscp_client_t *pClient, int iSamplerChannel, const char *pszAudioDriver )
1267 {
1268 char szQuery[LSCP_BUFSIZ];
1269
1270 if (iSamplerChannel < 0 || pszAudioDriver == NULL)
1271 return LSCP_FAILED;
1272
1273 sprintf(szQuery, "SET CHANNEL AUDIO_OUTPUT_TYPE %d %s\r\n", iSamplerChannel, pszAudioDriver);
1274 return lscp_client_query(pClient, szQuery);
1275 }
1276
1277
1278 /**
1279 * Setting audio output device:
1280 * SET CHANNEL AUDIO_OUTPUT_DEVICE <sampler-channel> <device-id>
1281 *
1282 * @param pClient Pointer to client instance structure.
1283 * @param iSamplerChannel Sampler channel number.
1284 * @param iAudioDevice Audio output device number identifier.
1285 */
1286 lscp_status_t lscp_set_channel_audio_device ( lscp_client_t *pClient, int iSamplerChannel, int iAudioDevice )
1287 {
1288 char szQuery[LSCP_BUFSIZ];
1289
1290 if (iSamplerChannel < 0 || iAudioDevice < 0)
1291 return LSCP_FAILED;
1292
1293 sprintf(szQuery, "SET CHANNEL AUDIO_OUTPUT_DEVICE %d %d\r\n", iSamplerChannel, iAudioDevice);
1294 return lscp_client_query(pClient, szQuery);
1295 }
1296
1297
1298 /**
1299 * Setting audio output channel:
1300 * SET CHANNEL AUDIO_OUTPUT_CHANNEL <sampler-channel> <audio-output-chan> <audio-input-chan>
1301 *
1302 * @param pClient Pointer to client instance structure.
1303 * @param iSamplerChannel Sampler channel number.
1304 * @param iAudioOut Audio output device channel to be routed from.
1305 * @param iAudioIn Audio output device channel to be routed into.
1306 *
1307 * @returns LSCP_OK on success, LSCP_FAILED otherwise.
1308 */
1309 lscp_status_t lscp_set_channel_audio_channel ( lscp_client_t *pClient, int iSamplerChannel, int iAudioOut, int iAudioIn )
1310 {
1311 char szQuery[LSCP_BUFSIZ];
1312
1313 if (iSamplerChannel < 0 || iAudioOut < 0 || iAudioIn < 0)
1314 return LSCP_FAILED;
1315
1316 sprintf(szQuery, "SET CHANNEL AUDIO_OUTPUT_CHANNEL %d %d %d\r\n", iSamplerChannel, iAudioOut, iAudioIn);
1317 return lscp_client_query(pClient, szQuery);
1318 }
1319
1320
1321 /**
1322 * Setting MIDI input type:
1323 * SET CHANNEL MIDI_INPUT_TYPE <sampler-channel> <midi-input-type>
1324 *
1325 * @param pClient Pointer to client instance structure.
1326 * @param iSamplerChannel Sampler channel number.
1327 * @param pszMidiDriver MIDI input driver type (e.g. "ALSA").
1328 *
1329 * @returns LSCP_OK on success, LSCP_FAILED otherwise.
1330 */
1331 lscp_status_t lscp_set_channel_midi_type ( lscp_client_t *pClient, int iSamplerChannel, const char *pszMidiDriver )
1332 {
1333 char szQuery[LSCP_BUFSIZ];
1334
1335 if (iSamplerChannel < 0 || pszMidiDriver == NULL)
1336 return LSCP_FAILED;
1337
1338 sprintf(szQuery, "SET CHANNEL MIDI_INPUT_TYPE %d %s\r\n", iSamplerChannel, pszMidiDriver);
1339 return lscp_client_query(pClient, szQuery);
1340 }
1341
1342
1343 /**
1344 * Setting MIDI input device:
1345 * SET CHANNEL MIDI_INPUT_DEVICE <sampler-channel> <device-id>
1346 *
1347 * @param pClient Pointer to client instance structure.
1348 * @param iSamplerChannel Sampler channel number.
1349 * @param iMidiDevice MIDI input device number identifier.
1350 */
1351 lscp_status_t lscp_set_channel_midi_device ( lscp_client_t *pClient, int iSamplerChannel, int iMidiDevice )
1352 {
1353 char szQuery[LSCP_BUFSIZ];
1354
1355 if (iSamplerChannel < 0 || iMidiDevice < 0)
1356 return LSCP_FAILED;
1357
1358 sprintf(szQuery, "SET CHANNEL MIDI_INPUT_DEVICE %d %d\r\n", iSamplerChannel, iMidiDevice);
1359 return lscp_client_query(pClient, szQuery);
1360 }
1361
1362
1363 /**
1364 * Setting MIDI input port:
1365 * SET CHANNEL MIDI_INPUT_PORT <sampler-channel> <midi-input-port>
1366 *
1367 * @param pClient Pointer to client instance structure.
1368 * @param iSamplerChannel Sampler channel number.
1369 * @param iMidiPort MIDI input driver virtual port number.
1370 *
1371 * @returns LSCP_OK on success, LSCP_FAILED otherwise.
1372 */
1373 lscp_status_t lscp_set_channel_midi_port ( lscp_client_t *pClient, int iSamplerChannel, int iMidiPort )
1374 {
1375 char szQuery[LSCP_BUFSIZ];
1376
1377 if (iSamplerChannel < 0 || iMidiPort < 0)
1378 return LSCP_FAILED;
1379
1380 sprintf(szQuery, "SET CHANNEL MIDI_INPUT_PORT %d %d\r\n", iSamplerChannel, iMidiPort);
1381 return lscp_client_query(pClient, szQuery);
1382 }
1383
1384
1385 /**
1386 * Setting MIDI input channel:
1387 * SET CHANNEL MIDI_INPUT_CHANNEL <sampler-channel> <midi-input-chan>
1388 *
1389 * @param pClient Pointer to client instance structure.
1390 * @param iSamplerChannel Sampler channel number.
1391 * @param iMidiChannel MIDI channel address number to listen (0-15) or
1392 * LSCP_MIDI_CHANNEL_ALL (16) to listen on all channels.
1393 *
1394 * @returns LSCP_OK on success, LSCP_FAILED otherwise.
1395 */
1396 lscp_status_t lscp_set_channel_midi_channel ( lscp_client_t *pClient, int iSamplerChannel, int iMidiChannel )
1397 {
1398 char szQuery[LSCP_BUFSIZ];
1399
1400 if (iSamplerChannel < 0 || iMidiChannel < 0 || iMidiChannel > 16)
1401 return LSCP_FAILED;
1402
1403 if (iMidiChannel == LSCP_MIDI_CHANNEL_ALL)
1404 sprintf(szQuery, "SET CHANNEL MIDI_INPUT_CHANNEL %d ALL\r\n", iSamplerChannel);
1405 else
1406 sprintf(szQuery, "SET CHANNEL MIDI_INPUT_CHANNEL %d %d\r\n", iSamplerChannel, iMidiChannel);
1407 return lscp_client_query(pClient, szQuery);
1408 }
1409
1410
1411 /**
1412 * Setting channel volume:
1413 * SET CHANNEL VOLUME <sampler-channel> <volume>
1414 *
1415 * @param pClient Pointer to client instance structure.
1416 * @param iSamplerChannel Sampler channel number.
1417 * @param fVolume Sampler channel volume as a positive floating point
1418 * number, where a value less than 1.0 for attenuation,
1419 * and greater than 1.0 for amplification.
1420 *
1421 * @returns LSCP_OK on success, LSCP_FAILED otherwise.
1422 */
1423 lscp_status_t lscp_set_channel_volume ( lscp_client_t *pClient, int iSamplerChannel, float fVolume )
1424 {
1425 char szQuery[LSCP_BUFSIZ];
1426
1427 if (iSamplerChannel < 0 || fVolume < 0.0)
1428 return LSCP_FAILED;
1429
1430 sprintf(szQuery, "SET CHANNEL VOLUME %d %g\r\n", iSamplerChannel, fVolume);
1431 return lscp_client_query(pClient, szQuery);
1432 }
1433
1434
1435 /**
1436 * Resetting a sampler channel:
1437 * RESET CHANNEL <sampler-channel>
1438 *
1439 * @param pClient Pointer to client instance structure.
1440 * @param iSamplerChannel Sampler channel number.
1441 *
1442 * @returns LSCP_OK on success, LSCP_FAILED otherwise.
1443 */
1444 lscp_status_t lscp_reset_channel ( lscp_client_t *pClient, int iSamplerChannel )
1445 {
1446 char szQuery[LSCP_BUFSIZ];
1447
1448 if (iSamplerChannel < 0)
1449 return LSCP_FAILED;
1450
1451 sprintf(szQuery, "RESET CHANNEL %d\r\n", iSamplerChannel);
1452 return lscp_client_query(pClient, szQuery);
1453 }
1454
1455
1456 /**
1457 * Resetting the sampler:
1458 * RESET
1459 *
1460 * @param pClient Pointer to client instance structure.
1461 *
1462 * @returns LSCP_OK on success, LSCP_FAILED otherwise.
1463 */
1464 lscp_status_t lscp_reset_sampler ( lscp_client_t *pClient )
1465 {
1466 return lscp_client_query(pClient, "RESET\r\n");
1467 }
1468
1469
1470 // end of client.c

  ViewVC Help
Powered by ViewVC