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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 742 - (show annotations) (download)
Tue Aug 16 17:21:44 2005 UTC (13 years, 9 months ago) by capela
File MIME type: text/plain
File size: 51711 byte(s)
Prepared for 0.3.1 release.

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

  ViewVC Help
Powered by ViewVC