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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 171 - (show annotations) (download)
Mon Jul 5 16:26:44 2004 UTC (19 years, 9 months ago) by capela
File MIME type: text/plain
File size: 44485 byte(s)
Milestone for integral implementation of draft-protocol v.11.

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

  ViewVC Help
Powered by ViewVC