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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 144 - (show annotations) (download)
Thu Jun 24 18:25:11 2004 UTC (19 years, 9 months ago) by capela
File MIME type: text/plain
File size: 42919 byte(s)
* Major change to client event protocol interface on attempt
  to comply with draft-protocol v.11.

* New function entries added: lscp_load_instrument_non_modal(),
  lscp_set_channel_audio_device() and lscp_set_channel_midi_device().

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

  ViewVC Help
Powered by ViewVC