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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 167 - (show annotations) (download)
Fri Jul 2 14:36:43 2004 UTC (16 years, 3 months ago) by capela
File MIME type: text/plain
File size: 43725 byte(s)
* New lscp_get_channel_stream_usage() helper function.

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

  ViewVC Help
Powered by ViewVC