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

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

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 132 by capela, Fri Jun 18 14:19:19 2004 UTC revision 2424 by capela, Sun Feb 24 19:02:30 2013 UTC
# Line 2  Line 2 
2  //  //
3  /****************************************************************************  /****************************************************************************
4     liblscp - LinuxSampler Control Protocol API     liblscp - LinuxSampler Control Protocol API
5     Copyright (C) 2004, rncbc aka Rui Nuno Capela. All rights reserved.     Copyright (C) 2004-2013, rncbc aka Rui Nuno Capela. All rights reserved.
6    
7     This library is free software; you can redistribute it and/or     This library is free software; you can redistribute it and/or
8     modify it under the terms of the GNU Lesser General Public     modify it under the terms of the GNU Lesser General Public
# Line 14  Line 14 
14     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15     Lesser General Public License for more details.     Lesser General Public License for more details.
16    
17     You should have received a copy of the GNU Lesser General Public     You should have received a copy of the GNU General Public License along
18     License along with this library; if not, write to the Free Software     with this program; if not, write to the Free Software Foundation, Inc.,
19     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA     51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
20    
21  *****************************************************************************/  *****************************************************************************/
22    
23    #include <locale.h>
24  #include "common.h"  #include "common.h"
25    
26  // Default timeout value (in milliseconds).  // Default timeout value (in milliseconds).
27  #define LSCP_TIMEOUT_MSECS  500  #define LSCP_TIMEOUT_MSECS  500
28    
29    
30    // Whether to use getaddrinfo() instead
31    // of deprecated gethostbyname()
32    #if !defined(WIN32)
33    #define USE_GETADDRINFO 1
34    #endif
35    
36    
37  // Local prototypes.  // Local prototypes.
38    
39  static void _lscp_client_evt_proc   (void *pvClient);  static void _lscp_client_evt_proc (void *pvClient);
40    
41    static lscp_status_t _lscp_client_evt_connect (lscp_client_t *pClient);
42    static lscp_status_t _lscp_client_evt_request (lscp_client_t *pClient,
43            int iSubscribe, lscp_event_t event);
44    
45    
46    //-------------------------------------------------------------------------
47    // General helper functions.
48    
49    struct _locale_t {
50            char numeric[32];
51            char ctype[32];
52    };
53    
54    // we need to ensure a constant locale setting e.g. for parsing
55    // floating point numbers with atof(), as the floating point separator
56    // character varies by the invidual locale settings
57    static void _save_and_set_c_locale(struct _locale_t* locale)
58    {
59            strncpy(locale->numeric, setlocale(LC_NUMERIC, NULL), 32);
60            strncpy(locale->ctype, setlocale(LC_CTYPE, NULL), 32);
61            setlocale(LC_NUMERIC, "C");
62            setlocale(LC_CTYPE, "C");
63    }
64    
65    // restore the original locale setting as nothing happened
66    static void _restore_locale(struct _locale_t* locale)
67    {
68            setlocale(LC_NUMERIC, locale->numeric);
69            setlocale(LC_CTYPE, locale->ctype);
70    }
71    
72    // seems the standard atof() function doesnt care much about locale
73    // runtime modifications, so we use this workaround
74    static float _atof(const char* txt) {
75            float f;
76            sscanf(txt, "%f", &f); // yeah, you're a good boy sscanf()
77            return f;
78    }
79    
80    
81  //-------------------------------------------------------------------------  //-------------------------------------------------------------------------
# Line 36  static void _lscp_client_evt_proc   (voi Line 83  static void _lscp_client_evt_proc   (voi
83    
84  static void _lscp_client_evt_proc ( void *pvClient )  static void _lscp_client_evt_proc ( void *pvClient )
85  {  {
86      lscp_client_t *pClient = (lscp_client_t *) pvClient;          lscp_client_t *pClient = (lscp_client_t *) pvClient;
87      struct sockaddr_in addr;  
88      int   cAddr;          fd_set fds;                         // File descriptor list for select().
89      char  achBuffer[LSCP_BUFSIZ];          int    fd, fdmax;                   // Maximum file descriptor number.
90      int   cchBuffer;          struct timeval tv;                  // For specifying a timeout value.
91      const char *pszSeps = " \r\n";          int    iSelect;                     // Holds select return status.
92      char *pszToken;          int    iTimeout;
93      char *pch;  
94            char   achBuffer[LSCP_BUFSIZ];
95            int    cchBuffer;
96            const char *pszSeps = ":\r\n";
97            char  *pszToken;
98            char  *pch;
99            int    cchToken;
100    
101            lscp_event_t event;
102    
103  #ifdef DEBUG  #ifdef DEBUG
104      fprintf(stderr, "_lscp_client_evt_proc: Client waiting for events.\n");          fprintf(stderr, "_lscp_client_evt_proc: Client waiting for events.\n");
105  #endif  #endif
106    
107      while (pClient->evt.iState) {          while (pClient->evt.iState) {
108          cAddr = sizeof(struct sockaddr_in);  
109          cchBuffer = recvfrom(pClient->evt.sock, achBuffer, sizeof(achBuffer), 0, (struct sockaddr *) &addr, &cAddr);                  // Prepare for waiting on select...
110          if (cchBuffer > 0) {                  fd = (int) pClient->evt.sock;
111                    FD_ZERO(&fds);
112                    FD_SET((unsigned int) fd, &fds);
113                    fdmax = fd;
114    
115                    // Use the timeout (x10) select feature ...
116                    iTimeout = 10 * pClient->iTimeout;
117                    if (iTimeout >= 1000) {
118                            tv.tv_sec = iTimeout / 1000;
119                            iTimeout -= tv.tv_sec * 1000;
120                    }
121                    else tv.tv_sec = 0;
122                    tv.tv_usec = iTimeout * 1000;
123    
124                    // Wait for event...
125                    iSelect = select(fdmax + 1, &fds, NULL, NULL, &tv);
126                    if (iSelect > 0 && FD_ISSET(fd, &fds)) {
127                            // May recv now...
128                            cchBuffer = recv(pClient->evt.sock, achBuffer, sizeof(achBuffer), 0);
129                            if (cchBuffer > 0) {
130                                    // Make sure received buffer it's null terminated.
131                                    achBuffer[cchBuffer] = (char) 0;
132                                    pch = achBuffer;
133                                    do {
134                                            // Parse for the notification event message...
135                                            pszToken = lscp_strtok(NULL, pszSeps, &(pch)); // Have "NOTIFY"
136                                            if (strcasecmp(pszToken, "NOTIFY") == 0) {
137                                                    pszToken = lscp_strtok(NULL, pszSeps, &(pch));
138                                                    event    = lscp_event_from_text(pszToken);
139                                                    // And pick the rest of data...
140                                                    pszToken = lscp_strtok(NULL, pszSeps, &(pch));
141                                                    cchToken = (pszToken == NULL ? 0 : strlen(pszToken));
142                                                    // Double-check if we're really up to it...
143                                                    if (pClient->events & event) {
144                                                            // Invoke the client event callback...
145                                                            if ((*pClient->pfnCallback)(
146                                                                            pClient,
147                                                                            event,
148                                                                            pszToken,
149                                                                            cchToken,
150                                                                            pClient->pvData) != LSCP_OK) {
151                                                                    pClient->evt.iState = 0;
152                                                            }
153                                                    }
154                                            }
155                                    } while (*pch);
156                            } else {
157                                    lscp_socket_perror("_lscp_client_evt_proc: recv");
158                                    pClient->evt.iState = 0;
159                            }
160                    }   // Check if select has in error.
161                    else if (iSelect < 0) {
162                            lscp_socket_perror("_lscp_client_evt_proc: select");
163                            pClient->evt.iState = 0;
164                    }
165    
166                    // Finally, always signal the event.
167                    lscp_cond_signal(pClient->cond);
168            }
169    
170  #ifdef DEBUG  #ifdef DEBUG
171              lscp_socket_trace("_lscp_client_evt_proc: recvfrom", &addr, achBuffer, cchBuffer);          fprintf(stderr, "_lscp_client_evt_proc: Client closing.\n");
172  #endif  #endif
173              if (strncasecmp(achBuffer, "PING ", 5) == 0) {  }
174                  // Make sure received buffer it's null terminated.  
175                  achBuffer[cchBuffer] = (char) 0;  
176                  lscp_strtok(achBuffer, pszSeps, &(pch));       // Skip "PING"  //-------------------------------------------------------------------------
177                  lscp_strtok(NULL, pszSeps, &(pch));            // Skip port (must be the same as in addr)  // Event subscription helpers.
178                  pszToken = lscp_strtok(NULL, pszSeps, &(pch)); // Have session-id.  
179                  if (pszToken) {  // Open the event service socket connection.
180                      // Set now client's session-id, if not already  static lscp_status_t _lscp_client_evt_connect ( lscp_client_t *pClient )
181                      if (pClient->sessid == NULL)  {
182                          pClient->sessid = strdup(pszToken);          lscp_socket_t sock;
183                      if (pClient->sessid && strcmp(pszToken, pClient->sessid) == 0) {          struct sockaddr_in addr;
184                          sprintf(achBuffer, "PONG %s\r\n", pClient->sessid);          int cAddr;
185                          cchBuffer = strlen(achBuffer);  #if defined(WIN32)
186                          if (sendto(pClient->evt.sock, achBuffer, cchBuffer, 0, (struct sockaddr *) &addr, cAddr) < cchBuffer)          int iSockOpt = (-1);
187                              lscp_socket_perror("_lscp_client_evt_proc: sendto");  #endif
188  #ifdef DEBUG  
189                          fprintf(stderr, "> %s", achBuffer);          // Prepare the event connection socket...
190            sock = socket(AF_INET, SOCK_STREAM, 0);
191            if (sock == INVALID_SOCKET) {
192                    lscp_socket_perror("_lscp_client_evt_connect: socket");
193                    return LSCP_FAILED;
194            }
195    
196    #if defined(WIN32)
197            if (setsockopt(sock, SOL_SOCKET, SO_DONTLINGER,
198                            (char *) &iSockOpt, sizeof(int)) == SOCKET_ERROR)
199                    lscp_socket_perror("lscp_client_evt_connect: setsockopt(SO_DONTLINGER)");
200  #endif  #endif
                     }  
                 }  
                 // Done with life proof.  
             } else {  
                 //  
                 if ((*pClient->pfnCallback)(  
                         pClient,  
                         achBuffer,  
                         cchBuffer,  
                         pClient->pvData) != LSCP_OK) {  
                     pClient->evt.iState = 0;  
                 }  
             }  
         } else {  
             lscp_socket_perror("_lscp_client_evt_proc: recvfrom");  
             pClient->evt.iState = 0;  
         }  
     }  
201    
202  #ifdef DEBUG  #ifdef DEBUG
203      fprintf(stderr, "_lscp_client_evt_proc: Client closing.\n");          lscp_socket_getopts("_lscp_client_evt_connect:", sock);
204  #endif  #endif
205    
206            // Use same address of the command connection.
207            cAddr = sizeof(struct sockaddr_in);
208            memmove((char *) &addr, &(pClient->cmd.addr), cAddr);
209    
210            // Start the connection...
211            if (connect(sock, (struct sockaddr *) &addr, cAddr) == SOCKET_ERROR) {
212                    lscp_socket_perror("_lscp_client_evt_connect: connect");
213                    closesocket(sock);
214                    return LSCP_FAILED;
215            }
216    
217            // Set our socket agent struct...
218            lscp_socket_agent_init(&(pClient->evt), sock, &addr, cAddr);
219    
220            // And finally the service thread...
221            return lscp_socket_agent_start(&(pClient->evt), _lscp_client_evt_proc, pClient, 0);
222    }
223    
224    
225    // Subscribe to a single event.
226    static lscp_status_t _lscp_client_evt_request ( lscp_client_t *pClient,
227            int iSubscribe, lscp_event_t event )
228    {
229            const char *pszEvent;
230            char  szQuery[LSCP_BUFSIZ];
231            int   cchQuery;
232    
233            if (pClient == NULL)
234                    return LSCP_FAILED;
235    
236            // Which (single) event?
237            pszEvent = lscp_event_to_text(event);
238            if (pszEvent == NULL)
239                    return LSCP_FAILED;
240    
241            // Build the query string...
242            cchQuery = sprintf(szQuery, "%sSUBSCRIBE %s\n\n",
243                    (iSubscribe == 0 ? "UN" : ""), pszEvent);
244            // Just send data, forget result...
245            if (send(pClient->evt.sock, szQuery, cchQuery, 0) < cchQuery) {
246                    lscp_socket_perror("_lscp_client_evt_request: send");
247                    return LSCP_FAILED;
248            }
249    
250            // Wait on response.
251            lscp_cond_wait(pClient->cond, pClient->mutex);
252    
253            // Update as naively as we can...
254            if (iSubscribe)
255                    pClient->events |=  event;
256            else
257                    pClient->events &= ~event;
258    
259            return LSCP_OK;
260  }  }
261    
262    
# Line 130  const char* lscp_client_build   (void) { Line 291  const char* lscp_client_build   (void) {
291   *  @returns The new client instance pointer if successfull, which shall be   *  @returns The new client instance pointer if successfull, which shall be
292   *  used on all subsequent client calls, NULL otherwise.   *  used on all subsequent client calls, NULL otherwise.
293   */   */
294  lscp_client_t* lscp_client_create ( const char *pszHost, int iPort, lscp_client_proc_t pfnCallback, void *pvData )  lscp_client_t* lscp_client_create ( const char *pszHost, int iPort,
295            lscp_client_proc_t pfnCallback, void *pvData )
296  {  {
297      lscp_client_t  *pClient;          lscp_client_t  *pClient;
298      struct hostent *pHost;  #if defined(USE_GETADDRINFO)
299      lscp_socket_t sock;          char szPort[33];
300      struct sockaddr_in addr;          struct addrinfo hints;
301      int cAddr;          struct addrinfo *result, *res;
302      int iSockOpt = (-1);  #else
303            struct hostent *pHost;
304      if (pfnCallback == NULL) {          struct sockaddr_in addr;
305          fprintf(stderr, "lscp_client_create: Invalid client callback function.\n");          int cAddr;
306          return NULL;  #endif  /* !USE_GETADDRINFO */
307      }          lscp_socket_t sock;
   
     pHost = gethostbyname(pszHost);  
     if (pHost == NULL) {  
         lscp_socket_herror("lscp_client_create: gethostbyname");  
         return NULL;  
     }  
   
     // Allocate client descriptor...  
   
     pClient = (lscp_client_t *) malloc(sizeof(lscp_client_t));  
     if (pClient == NULL) {  
         fprintf(stderr, "lscp_client_create: Out of memory.\n");  
         return NULL;  
     }  
     memset(pClient, 0, sizeof(lscp_client_t));  
   
     pClient->pfnCallback = pfnCallback;  
     pClient->pvData = pvData;  
   
 #ifdef DEBUG  
     fprintf(stderr, "lscp_client_create: pClient=%p: pszHost=%s iPort=%d.\n", pClient, pszHost, iPort);  
 #endif  
   
     // Prepare the command connection socket...  
   
     sock = socket(AF_INET, SOCK_STREAM, 0);  
     if (sock == INVALID_SOCKET) {  
         lscp_socket_perror("lscp_client_create: cmd: socket");  
         free(pClient);  
         return NULL;  
     }  
   
308  #if defined(WIN32)  #if defined(WIN32)
309      if (setsockopt(sock, SOL_SOCKET, SO_DONTLINGER, (char *) &iSockOpt, sizeof(int)) == SOCKET_ERROR)          int iSockOpt = (-1);
         lscp_socket_perror("lscp_client_create: cmd: setsockopt(SO_DONTLINGER)");  
 #endif  
   
 #ifdef DEBUG  
     lscp_socket_getopts("lscp_client_create: cmd", sock);  
310  #endif  #endif
311    
312      cAddr = sizeof(struct sockaddr_in);          if (pfnCallback == NULL) {
313      memset((char *) &addr, 0, cAddr);                  fprintf(stderr, "lscp_client_create: Invalid client callback function.\n");
314      addr.sin_family = pHost->h_addrtype;                  return NULL;
315      memmove((char *) &(addr.sin_addr), pHost->h_addr, pHost->h_length);          }
316      addr.sin_port = htons((short) iPort);  
317    #if defined(USE_GETADDRINFO)
318      if (connect(sock, (struct sockaddr *) &addr, cAddr) == SOCKET_ERROR) {  
319          lscp_socket_perror("lscp_client_create: cmd: connect");          // Convert port number to string/name...
320          closesocket(sock);          snprintf(szPort, sizeof(szPort), "%d", iPort);
321          free(pClient);  
322          return NULL;          // Obtain address(es) matching host/port...
323      }          memset(&hints, 0, sizeof(struct addrinfo));
324            hints.ai_family = AF_INET;
325            hints.ai_socktype = SOCK_STREAM;
326    
327            result = NULL;
328    
329            if (getaddrinfo(pszHost, szPort, &hints, &result)) {
330                    lscp_socket_herror("lscp_client_create: getaddrinfo");
331                    return NULL;
332            }
333    
334    #else
335    
336            // Obtain host matching name...
337            pHost = gethostbyname(pszHost);
338            if (pHost == NULL) {
339                    lscp_socket_herror("lscp_client_create: gethostbyname");
340                    return NULL;
341            }
342    
343    #endif  /* !USE_GETADDRINFO */
344    
345            // Allocate client descriptor...
346    
347            pClient = (lscp_client_t *) malloc(sizeof(lscp_client_t));
348            if (pClient == NULL) {
349                    fprintf(stderr, "lscp_client_create: Out of memory.\n");
350                    return NULL;
351            }
352            memset(pClient, 0, sizeof(lscp_client_t));
353    
354      lscp_socket_agent_init(&(pClient->cmd), sock, &addr, cAddr);          pClient->pfnCallback = pfnCallback;
355            pClient->pvData = pvData;
356    
357  #ifdef DEBUG  #ifdef DEBUG
358      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));          fprintf(stderr,
359                    "lscp_client_create: pClient=%p: pszHost=%s iPort=%d.\n",
360                     pClient, pszHost, iPort);
361  #endif  #endif
362    
363      // Prepare the event datagram service socket...          // Prepare the command connection socket...
364    
365    #if defined(USE_GETADDRINFO)
366    
367      sock = socket(AF_INET, SOCK_DGRAM, 0);          // getaddrinfo() returns a list of address structures;
368      if (sock == INVALID_SOCKET) {          // try each address until we successfully connect(2);
369          lscp_socket_perror("lscp_client_create: evt: socket");          // if socket or connect fails, we close the socket and
370          lscp_socket_agent_free(&(pClient->cmd));          // try the next address...
371          free(pClient);          sock = INVALID_SOCKET;
372          return NULL;  
373      }          for (res = result; res; res = res->ai_next) {
374                    sock = socket(res->ai_family, res->ai_socktype, res->ai_protocol);
375                    if (sock == INVALID_SOCKET)
376                            continue;
377            #if defined(WIN32)
378                    if (setsockopt(sock, SOL_SOCKET, SO_DONTLINGER,
379                                    (char *) &iSockOpt, sizeof(int)) == SOCKET_ERROR)
380                            lscp_socket_perror("lscp_client_create: cmd: setsockopt(SO_DONTLINGER)");
381            #endif
382            #ifdef DEBUG
383                    lscp_socket_getopts("lscp_client_create: cmd", sock);
384            #endif
385                    if (connect(sock, res->ai_addr, res->ai_addrlen) != SOCKET_ERROR)
386                            break;
387                    closesocket(sock);
388            }
389    
390            if (sock == INVALID_SOCKET) {
391                    lscp_socket_perror("lscp_client_create: cmd: socket");
392                    free(pClient);
393                    return NULL;
394            }
395    
396            if (res == NULL) {
397                    lscp_socket_perror("lscp_client_create: cmd: connect");
398                    free(pClient);
399                    return NULL;
400            }
401    
402            // Initialize the command socket agent struct...
403            lscp_socket_agent_init(&(pClient->cmd), sock,
404                    (struct sockaddr_in *) res->ai_addr, res->ai_addrlen);
405    
406            // No longer needed...
407            freeaddrinfo(result);
408    
409    #else
410    
411            sock = socket(AF_INET, SOCK_STREAM, 0);
412            if (sock == INVALID_SOCKET) {
413                    lscp_socket_perror("lscp_client_create: cmd: socket");
414                    free(pClient);
415                    return NULL;
416            }
417    
418      if (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (char *) &iSockOpt, sizeof(int)) == SOCKET_ERROR)  #if defined(WIN32)
419          lscp_socket_perror("lscp_client_create: evt: setsockopt(SO_REUSEADDR)");          if (setsockopt(sock, SOL_SOCKET, SO_DONTLINGER,
420                            (char *) &iSockOpt, sizeof(int)) == SOCKET_ERROR)
421                    lscp_socket_perror("lscp_client_create: cmd: setsockopt(SO_DONTLINGER)");
422    #endif
423    
424  #ifdef DEBUG  #ifdef DEBUG
425      lscp_socket_getopts("lscp_client_create: evt", sock);          lscp_socket_getopts("lscp_client_create: cmd", sock);
426  #endif  #endif
427    
428      cAddr = sizeof(struct sockaddr_in);          cAddr = sizeof(struct sockaddr_in);
429      memset((char *) &addr, 0, cAddr);          memset((char *) &addr, 0, cAddr);
430      addr.sin_family = AF_INET;          addr.sin_family = pHost->h_addrtype;
431      addr.sin_addr.s_addr = htonl(INADDR_ANY);          memmove((char *) &(addr.sin_addr), pHost->h_addr, pHost->h_length);
432      addr.sin_port = htons(0);          addr.sin_port = htons((short) iPort);
433    
434      if (bind(sock, (const struct sockaddr *) &addr, cAddr) == SOCKET_ERROR) {          if (connect(sock, (struct sockaddr *) &addr, cAddr) == SOCKET_ERROR) {
435          lscp_socket_perror("lscp_client_create: evt: bind");                  lscp_socket_perror("lscp_client_create: cmd: connect");
436          lscp_socket_agent_free(&(pClient->cmd));                  closesocket(sock);
437          closesocket(sock);                  free(pClient);
438          free(pClient);                  return NULL;
439          return NULL;          }
     }  
   
     if (getsockname(sock, (struct sockaddr *) &addr, &cAddr) == SOCKET_ERROR) {  
         lscp_socket_perror("lscp_client_create: evt: getsockname");  
         lscp_socket_agent_free(&(pClient->cmd));  
         closesocket(sock);  
         free(pClient);  
         return NULL;  
     }  
440    
441      lscp_socket_agent_init(&(pClient->evt), sock, &addr, cAddr);          // Initialize the command socket agent struct...
442            lscp_socket_agent_init(&(pClient->cmd), sock, &addr, cAddr);
443    
444    #endif  /* !USE_GETADDRINFO */
445    
446  #ifdef DEBUG  #ifdef DEBUG
447      fprintf(stderr, "lscp_client_create: evt: pClient=%p: sock=%d addr=%s port=%d.\n", pClient, pClient->evt.sock, inet_ntoa(pClient->evt.addr.sin_addr), ntohs(pClient->evt.addr.sin_port));          fprintf(stderr,
448                    "lscp_client_create: cmd: pClient=%p: sock=%d addr=%s port=%d.\n",
449                    pClient, pClient->cmd.sock,
450                    inet_ntoa(pClient->cmd.addr.sin_addr),
451                    ntohs(pClient->cmd.addr.sin_port));
452  #endif  #endif
453    
454      // No session id, yet.          // Initialize the event service socket struct...
455      pClient->sessid = NULL;          lscp_socket_agent_init(&(pClient->evt), INVALID_SOCKET, NULL, 0);
456      // Initialize cached members.          // No events subscribed, yet.
457      pClient->audio_drivers = NULL;          pClient->events = LSCP_EVENT_NONE;
458      pClient->midi_drivers = NULL;          // Initialize cached members.
459      pClient->audio_devices = NULL;          pClient->audio_drivers = NULL;
460      pClient->midi_devices = NULL;          pClient->midi_drivers = NULL;
461      pClient->engines = NULL;          pClient->audio_devices = NULL;
462      pClient->channels = NULL;          pClient->midi_devices = NULL;
463      lscp_driver_info_init(&(pClient->audio_info));          pClient->engines = NULL;
464      lscp_driver_info_init(&(pClient->midi_info));          pClient->channels = NULL;
465      lscp_engine_info_init(&(pClient->engine_info));          pClient->fxsends = NULL;
466      lscp_channel_info_init(&(pClient->channel_info));          pClient->midi_instruments = NULL;
467      // Initialize error stuff.          pClient->midi_maps = NULL;
468      pClient->pszResult = NULL;          pClient->midi_map_name = NULL;
469      pClient->iErrno = -1;          lscp_driver_info_init(&(pClient->audio_driver_info));
470      // Stream usage stuff.          lscp_driver_info_init(&(pClient->midi_driver_info));
471      pClient->buffer_fill = NULL;          lscp_device_info_init(&(pClient->audio_device_info));
472      pClient->iStreamCount = 0;          lscp_device_info_init(&(pClient->midi_device_info));
473      // Default timeout value.          lscp_param_info_init(&(pClient->audio_param_info));
474      pClient->iTimeout = LSCP_TIMEOUT_MSECS;          lscp_param_info_init(&(pClient->midi_param_info));
475            lscp_device_port_info_init(&(pClient->audio_channel_info));
476      // Initialize the transaction mutex.          lscp_device_port_info_init(&(pClient->midi_port_info));
477      lscp_mutex_init(pClient->mutex);          lscp_param_info_init(&(pClient->audio_channel_param_info));
478            lscp_param_info_init(&(pClient->midi_port_param_info));
479      // Now's finally time to startup threads...          lscp_server_info_init(&(pClient->server_info));
480      // Event service thread...          lscp_engine_info_init(&(pClient->engine_info));
481      if (lscp_socket_agent_start(&(pClient->evt), _lscp_client_evt_proc, pClient, 0) != LSCP_OK) {          lscp_channel_info_init(&(pClient->channel_info));
482          lscp_socket_agent_free(&(pClient->cmd));          lscp_fxsend_info_init(&(pClient->fxsend_info));
483          lscp_socket_agent_free(&(pClient->evt));          lscp_midi_instrument_info_init(&(pClient->midi_instrument_info));
484          lscp_mutex_destroy(pClient->mutex);          // Initialize error stuff.
485          free(pClient);          pClient->pszResult = NULL;
486          return NULL;          pClient->iErrno = -1;
487      }          // Stream usage stuff.
488            pClient->buffer_fill = NULL;
489            pClient->iStreamCount = 0;
490            // Default timeout value.
491            pClient->iTimeout = LSCP_TIMEOUT_MSECS;
492            pClient->iTimeoutCount = 0;
493    
494            // Initialize the transaction mutex.
495            lscp_mutex_init(pClient->mutex);
496            lscp_cond_init(pClient->cond);
497    
498      // Finally we've some success...          // Finally we've some success...
499      return pClient;          return pClient;
500  }  }
501    
502    
# Line 295  lscp_client_t* lscp_client_create ( cons Line 507  lscp_client_t* lscp_client_create ( cons
507   */   */
508  lscp_status_t lscp_client_join ( lscp_client_t *pClient )  lscp_status_t lscp_client_join ( lscp_client_t *pClient )
509  {  {
510      if (pClient == NULL)          if (pClient == NULL)
511          return LSCP_FAILED;                  return LSCP_FAILED;
512    
513  #ifdef DEBUG  #ifdef DEBUG
514      fprintf(stderr, "lscp_client_join: pClient=%p.\n", pClient);          fprintf(stderr, "lscp_client_join: pClient=%p.\n", pClient);
515  #endif  #endif
516    
517  //  lscp_socket_agent_join(&(pClient->evt));  //  lscp_socket_agent_join(&(pClient->evt));
518      lscp_socket_agent_join(&(pClient->cmd));          lscp_socket_agent_join(&(pClient->cmd));
519    
520      return LSCP_OK;          return LSCP_OK;
521  }  }
522    
523    
# Line 318  lscp_status_t lscp_client_join ( lscp_cl Line 530  lscp_status_t lscp_client_join ( lscp_cl
530   */   */
531  lscp_status_t lscp_client_destroy ( lscp_client_t *pClient )  lscp_status_t lscp_client_destroy ( lscp_client_t *pClient )
532  {  {
533      if (pClient == NULL)          if (pClient == NULL)
534          return LSCP_FAILED;                  return LSCP_FAILED;
535    
536  #ifdef DEBUG  #ifdef DEBUG
537      fprintf(stderr, "lscp_client_destroy: pClient=%p.\n", pClient);          fprintf(stderr, "lscp_client_destroy: pClient=%p.\n", pClient);
538  #endif  #endif
539    
540      // Lock this section up.          // Lock this section up.
541      lscp_mutex_lock(pClient->mutex);          lscp_mutex_lock(pClient->mutex);
542        
543     // Free session-id, if any.          // Free up all cached members.
544      if (pClient->sessid)          lscp_midi_instrument_info_free(&(pClient->midi_instrument_info));
545          free(pClient->sessid);          lscp_fxsend_info_free(&(pClient->fxsend_info));
546      pClient->sessid = NULL;          lscp_channel_info_free(&(pClient->channel_info));
547      // Free up all cached members.          lscp_engine_info_free(&(pClient->engine_info));
548      lscp_channel_info_reset(&(pClient->channel_info));          lscp_server_info_free(&(pClient->server_info));
549      lscp_engine_info_reset(&(pClient->engine_info));          lscp_param_info_free(&(pClient->midi_port_param_info));
550      lscp_driver_info_reset(&(pClient->midi_info));          lscp_param_info_free(&(pClient->audio_channel_param_info));
551      lscp_driver_info_reset(&(pClient->audio_info));          lscp_device_port_info_free(&(pClient->midi_port_info));
552      // Free available engine table.          lscp_device_port_info_free(&(pClient->audio_channel_info));
553      lscp_szsplit_destroy(pClient->audio_drivers);          lscp_param_info_free(&(pClient->midi_param_info));
554      lscp_szsplit_destroy(pClient->midi_drivers);          lscp_param_info_free(&(pClient->audio_param_info));
555      lscp_isplit_destroy(pClient->audio_devices);          lscp_device_info_free(&(pClient->midi_device_info));
556      lscp_isplit_destroy(pClient->midi_devices);          lscp_device_info_free(&(pClient->audio_device_info));
557      lscp_szsplit_destroy(pClient->engines);          lscp_driver_info_free(&(pClient->midi_driver_info));
558      lscp_isplit_destroy(pClient->channels);          lscp_driver_info_free(&(pClient->audio_driver_info));
559      // Make them null.          // Free available engine table.
560      pClient->audio_drivers = NULL;          lscp_szsplit_destroy(pClient->audio_drivers);
561      pClient->midi_drivers = NULL;          lscp_szsplit_destroy(pClient->midi_drivers);
562      pClient->engines = NULL;          lscp_isplit_destroy(pClient->audio_devices);
563      // Free result error stuff.          lscp_isplit_destroy(pClient->midi_devices);
564      lscp_client_set_result(pClient, NULL, 0);          lscp_szsplit_destroy(pClient->engines);
565      // Frre stream usage stuff.          lscp_isplit_destroy(pClient->channels);
566      if (pClient->buffer_fill)          lscp_isplit_destroy(pClient->fxsends);
567          free(pClient->buffer_fill);          lscp_midi_instruments_destroy(pClient->midi_instruments);
568      pClient->buffer_fill = NULL;          lscp_isplit_destroy(pClient->midi_maps);
569      pClient->iStreamCount = 0;          if (pClient->midi_map_name)
570      pClient->iTimeout = 0;                  free(pClient->midi_map_name);
571            // Make them null.
572      // Free socket agents.          pClient->audio_drivers = NULL;
573      lscp_socket_agent_free(&(pClient->evt));          pClient->midi_drivers = NULL;
574      lscp_socket_agent_free(&(pClient->cmd));          pClient->audio_devices = NULL;
575            pClient->midi_devices = NULL;
576      // Last but not least, free good ol'transaction mutex.          pClient->engines = NULL;
577      lscp_mutex_unlock(pClient->mutex);          pClient->channels = NULL;
578      lscp_mutex_destroy(pClient->mutex);          pClient->fxsends = NULL;
579            pClient->midi_instruments = NULL;
580            pClient->midi_maps = NULL;
581            pClient->midi_map_name = NULL;
582            // Free result error stuff.
583            lscp_client_set_result(pClient, NULL, 0);
584            // Free stream usage stuff.
585            if (pClient->buffer_fill)
586                    free(pClient->buffer_fill);
587            pClient->buffer_fill = NULL;
588            pClient->iStreamCount = 0;
589            pClient->iTimeout = 0;
590    
591            // Free socket agents.
592            lscp_socket_agent_free(&(pClient->evt));
593            lscp_socket_agent_free(&(pClient->cmd));
594    
595            // Last but not least, free good ol'transaction mutex.
596            lscp_mutex_unlock(pClient->mutex);
597            lscp_mutex_destroy(pClient->mutex);
598            lscp_cond_destroy(pClient->cond);
599    
600      free(pClient);          free(pClient);
601    
602      return LSCP_OK;          return LSCP_OK;
603  }  }
604    
605    
# Line 381  lscp_status_t lscp_client_destroy ( lscp Line 613  lscp_status_t lscp_client_destroy ( lscp
613   */   */
614  lscp_status_t lscp_client_set_timeout ( lscp_client_t *pClient, int iTimeout )  lscp_status_t lscp_client_set_timeout ( lscp_client_t *pClient, int iTimeout )
615  {  {
616      if (pClient == NULL)          if (pClient == NULL)
617          return LSCP_FAILED;                  return LSCP_FAILED;
618      if (iTimeout < 0)          if (iTimeout < 0)
619          return LSCP_FAILED;                  return LSCP_FAILED;
620    
621      pClient->iTimeout = iTimeout;          pClient->iTimeout = iTimeout;
622      return LSCP_OK;          return LSCP_OK;
623  }  }
624    
625    
# Line 400  lscp_status_t lscp_client_set_timeout ( Line 632  lscp_status_t lscp_client_set_timeout (
632   */   */
633  int lscp_client_get_timeout ( lscp_client_t *pClient )  int lscp_client_get_timeout ( lscp_client_t *pClient )
634  {  {
635      if (pClient == NULL)          if (pClient == NULL)
636          return -1;                  return -1;
637    
638      return pClient->iTimeout;          return pClient->iTimeout;
639  }  }
640    
641    
# Line 425  int lscp_client_get_timeout ( lscp_clien Line 657  int lscp_client_get_timeout ( lscp_clien
657   */   */
658  lscp_status_t lscp_client_query ( lscp_client_t *pClient, const char *pszQuery )  lscp_status_t lscp_client_query ( lscp_client_t *pClient, const char *pszQuery )
659  {  {
660      lscp_status_t ret;          lscp_status_t ret;
661        
662      // Lock this section up.          if (pClient == NULL)
663      lscp_mutex_lock(pClient->mutex);                  return LSCP_FAILED;
664    
665      // Just make the now guarded call.          // Lock this section up.
666      ret = lscp_client_call(pClient, pszQuery);          lscp_mutex_lock(pClient->mutex);
667        
668      // Unlock this section down.          // Just make the now guarded call.
669      lscp_mutex_unlock(pClient->mutex);          ret = lscp_client_call(pClient, pszQuery, 0);
670        
671      return ret;          // Unlock this section down.
672            lscp_mutex_unlock(pClient->mutex);
673    
674            return ret;
675  }  }
676    
677  /**  /**
# Line 450  lscp_status_t lscp_client_query ( lscp_c Line 685  lscp_status_t lscp_client_query ( lscp_c
685   */   */
686  const char *lscp_client_get_result ( lscp_client_t *pClient )  const char *lscp_client_get_result ( lscp_client_t *pClient )
687  {  {
688      if (pClient == NULL)          if (pClient == NULL)
689          return NULL;                  return NULL;
690    
691      return pClient->pszResult;          return pClient->pszResult;
692  }  }
693    
694    
# Line 467  const char *lscp_client_get_result ( lsc Line 702  const char *lscp_client_get_result ( lsc
702   */   */
703  int lscp_client_get_errno ( lscp_client_t *pClient )  int lscp_client_get_errno ( lscp_client_t *pClient )
704  {  {
705      if (pClient == NULL)          if (pClient == NULL)
706          return -1;                  return -1;
707    
708      return pClient->iErrno;          return pClient->iErrno;
709  }  }
710    
711    
# Line 478  int lscp_client_get_errno ( lscp_client_ Line 713  int lscp_client_get_errno ( lscp_client_
713  // Client registration protocol functions.  // Client registration protocol functions.
714    
715  /**  /**
716   *  Register frontend for receiving UDP event messages:   *  Register frontend for receiving event messages by the sampler backend.
717   *  SUBSCRIBE NOTIFICATION <udp-port>   *  @e Caution: since liblscp v0.5.5.4 you have to call lscp_client_subscribe()
718     *  for @e each event you want to subscribe. That is the old bitflag approach
719     *  was abondoned at this point. You can however still register all older
720     *  events with one lscp_client_subscribe() call at once. Thus, the old
721     *  behavior of this functions was not broken. Those older events are namely:
722     *  @code
723     *  SUBSCRIBE CHANNEL_COUNT | VOICE_COUNT | STREAM_COUNT
724     *      | BUFFER_FILL | CHANNEL_INFO | TOTAL_VOICE_COUNT
725     *      | AUDIO_OUTPUT_DEVICE_COUNT | AUDIO_OUTPUT_DEVICE_INFO
726     *      | MIDI_INPUT_DEVICE_COUNT | MIDI_INPUT_DEVICE_INFO
727     *      | MIDI_INSTRUMENT_MAP_COUNT | MIDI_INSTRUMENT_MAP_INFO
728     *      | MIDI_INSTRUMENT_COUNT | MIDI_INSTRUMENT_INFO
729     *      | MISCELLANEOUS
730     *  @endcode
731     *  The old events occupy the lower 16 bits (as bit flags), and all younger
732     *  events enumerate the whole upper 16 bits range. The new, enumerated
733     *  events are namely:
734     *  @code
735     *  SUBSCRIBE CHANNEL_MIDI
736     *  @endcode
737   *   *
738   *  @param pClient  Pointer to client instance structure.   *  @param pClient  Pointer to client instance structure.
739     *  @param events   LSCP event to subscribe.
740   *   *
741   *  @returns LSCP_OK on success, LSCP_FAILED otherwise.   *  @returns LSCP_OK on success, LSCP_FAILED otherwise.
742   */   */
743  lscp_status_t lscp_client_subscribe ( lscp_client_t *pClient )  lscp_status_t lscp_client_subscribe ( lscp_client_t *pClient, lscp_event_t events )
744  {  {
745      lscp_status_t ret;          lscp_status_t ret = LSCP_OK;
746      char szQuery[LSCP_BUFSIZ];          lscp_event_t currentEvent;
     const char *pszResult;  
     const char *pszSeps = "[]";  
     char *pszToken;  
     char *pch;  
747    
748      if (pClient == NULL || pClient->sessid)          if (pClient == NULL)
749          return LSCP_FAILED;                  return LSCP_FAILED;
750    
751      // Lock this section up.          // Lock this section up.
752      lscp_mutex_lock(pClient->mutex);          lscp_mutex_lock(pClient->mutex);
753        
754      sprintf(szQuery, "SUBSCRIBE NOTIFICATION %d\r\n", ntohs(pClient->evt.addr.sin_port));          // If applicable, start the alternate connection...
755      ret = lscp_client_call(pClient, szQuery);          if (pClient->events == LSCP_EVENT_NONE)
756      if (ret == LSCP_OK) {                  ret = _lscp_client_evt_connect(pClient);
757          pszResult = lscp_client_get_result(pClient);  
758  #ifdef DEBUG          // Send the subscription commands.
759          fprintf(stderr, "lscp_client_subscribe: %s\n", pszResult);          if (ret == LSCP_OK && (events & LSCP_EVENT_CHANNEL_COUNT))
760  #endif                  ret = _lscp_client_evt_request(pClient, 1, LSCP_EVENT_CHANNEL_COUNT);
761          // Check for the session-id on "OK[sessid]" response.          if (ret == LSCP_OK && (events & LSCP_EVENT_VOICE_COUNT))
762          pszToken = lscp_strtok((char *) pszResult, pszSeps, &(pch));                  ret = _lscp_client_evt_request(pClient, 1, LSCP_EVENT_VOICE_COUNT);
763          if (pszToken && strcasecmp(pszToken, "OK") == 0) {          if (ret == LSCP_OK && (events & LSCP_EVENT_STREAM_COUNT))
764              pszToken = lscp_strtok(NULL, pszSeps, &(pch));                  ret = _lscp_client_evt_request(pClient, 1, LSCP_EVENT_STREAM_COUNT);
765              if (pszToken)          if (ret == LSCP_OK && (events & LSCP_EVENT_BUFFER_FILL))
766                  pClient->sessid = strdup(pszToken);                  ret = _lscp_client_evt_request(pClient, 1, LSCP_EVENT_BUFFER_FILL);
767          }          if (ret == LSCP_OK && (events & LSCP_EVENT_CHANNEL_INFO))
768      }                  ret = _lscp_client_evt_request(pClient, 1, LSCP_EVENT_CHANNEL_INFO);
769            if (ret == LSCP_OK && (events & LSCP_EVENT_TOTAL_VOICE_COUNT))
770                    ret = _lscp_client_evt_request(pClient, 1, LSCP_EVENT_TOTAL_VOICE_COUNT);
771            if (ret == LSCP_OK && (events & LSCP_EVENT_AUDIO_OUTPUT_DEVICE_COUNT))
772                    ret = _lscp_client_evt_request(pClient, 1, LSCP_EVENT_AUDIO_OUTPUT_DEVICE_COUNT);
773            if (ret == LSCP_OK && (events & LSCP_EVENT_AUDIO_OUTPUT_DEVICE_INFO))
774                    ret = _lscp_client_evt_request(pClient, 1, LSCP_EVENT_AUDIO_OUTPUT_DEVICE_INFO);
775            if (ret == LSCP_OK && (events & LSCP_EVENT_MIDI_INPUT_DEVICE_COUNT))
776                    ret = _lscp_client_evt_request(pClient, 1, LSCP_EVENT_MIDI_INPUT_DEVICE_COUNT);
777            if (ret == LSCP_OK && (events & LSCP_EVENT_MIDI_INPUT_DEVICE_INFO))
778                    ret = _lscp_client_evt_request(pClient, 1, LSCP_EVENT_MIDI_INPUT_DEVICE_INFO);
779            if (ret == LSCP_OK && (events & LSCP_EVENT_MIDI_INSTRUMENT_MAP_COUNT))
780                    ret = _lscp_client_evt_request(pClient, 1, LSCP_EVENT_MIDI_INSTRUMENT_MAP_COUNT);
781            if (ret == LSCP_OK && (events & LSCP_EVENT_MIDI_INSTRUMENT_MAP_INFO))
782                    ret = _lscp_client_evt_request(pClient, 1, LSCP_EVENT_MIDI_INSTRUMENT_MAP_INFO);
783            if (ret == LSCP_OK && (events & LSCP_EVENT_MIDI_INSTRUMENT_COUNT))
784                    ret = _lscp_client_evt_request(pClient, 1, LSCP_EVENT_MIDI_INSTRUMENT_COUNT);
785            if (ret == LSCP_OK && (events & LSCP_EVENT_MIDI_INSTRUMENT_INFO))
786                    ret = _lscp_client_evt_request(pClient, 1, LSCP_EVENT_MIDI_INSTRUMENT_INFO);
787            if (ret == LSCP_OK && (events & LSCP_EVENT_MISCELLANEOUS))
788                    ret = _lscp_client_evt_request(pClient, 1, LSCP_EVENT_MISCELLANEOUS);
789            // Caution: for the upper 16 bits, we don't use bit flags anymore ...
790            currentEvent = events & 0xffff0000;
791            if (ret == LSCP_OK && currentEvent) {
792                    switch (currentEvent) {
793                            case LSCP_EVENT_CHANNEL_MIDI:
794                            case LSCP_EVENT_DEVICE_MIDI:
795                                    ret = _lscp_client_evt_request(pClient, 1, currentEvent);
796                                    break;
797                            default: // unknown "upper" event type
798                                    ret = LSCP_FAILED;
799                                    break;
800                    }
801            }
802    
803            // Unlock this section down.
804            lscp_mutex_unlock(pClient->mutex);
805    
806            return ret;
807    }
808    
809    
810    /**
811     *  Deregister frontend from receiving UDP event messages anymore.
812     *  @e Caution: since liblscp v0.5.5.4 you have to call
813     *  lscp_client_unsubscribe() for @e each event you want to unsubscribe.
814     *  That is the old bitflag approach was abondoned at this point. You can
815     *  however still register all older events with one lscp_client_subscribe()
816     *  call at once. Thus, the old behavior of this functions was not broken.
817     *  Those older events are namely:
818     *  @code
819     *  UNSUBSCRIBE CHANNEL_COUNT | VOICE_COUNT | STREAM_COUNT
820     *      | BUFFER_FILL | CHANNEL_INFO | TOTAL_VOICE_COUNT
821     *      | AUDIO_OUTPUT_DEVICE_COUNT | AUDIO_OUTPUT_DEVICE_INFO
822     *      | MIDI_INPUT_DEVICE_COUNT | MIDI_INPUT_DEVICE_INFO
823     *      | MIDI_INSTRUMENT_MAP_COUNT | MIDI_INSTRUMENT_MAP_INFO
824     *      | MIDI_INSTRUMENT_COUNT | MIDI_INSTRUMENT_INFO
825     *      | MISCELLANEOUS
826     *  @endcode
827     *  The old events occupy the lower 16 bits (as bit flags), and all younger
828     *  events enumerate the whole upper 16 bits range. The new, enumerated
829     *  events are namely:
830     *  @code
831     *  UNSUBSCRIBE CHANNEL_MIDI
832     *  @endcode
833     *
834     *  @param pClient  Pointer to client instance structure.
835     *  @param events   LSCP event to unsubscribe.
836     *
837     *  @returns LSCP_OK on success, LSCP_FAILED otherwise.
838     */
839    lscp_status_t lscp_client_unsubscribe ( lscp_client_t *pClient, lscp_event_t events )
840    {
841            lscp_status_t ret = LSCP_OK;
842            lscp_event_t currentEvent;
843    
844      // Unlock this section down.          if (pClient == NULL)
845      lscp_mutex_unlock(pClient->mutex);                  return LSCP_FAILED;
846    
847      return ret;          // Lock this section up.
848            lscp_mutex_lock(pClient->mutex);
849    
850            // Send the unsubscription commands.
851            if (ret == LSCP_OK && (events & LSCP_EVENT_CHANNEL_COUNT))
852                    ret = _lscp_client_evt_request(pClient, 0, LSCP_EVENT_CHANNEL_COUNT);
853            if (ret == LSCP_OK && (events & LSCP_EVENT_VOICE_COUNT))
854                    ret = _lscp_client_evt_request(pClient, 0, LSCP_EVENT_VOICE_COUNT);
855            if (ret == LSCP_OK && (events & LSCP_EVENT_STREAM_COUNT))
856                    ret = _lscp_client_evt_request(pClient, 0, LSCP_EVENT_STREAM_COUNT);
857            if (ret == LSCP_OK && (events & LSCP_EVENT_BUFFER_FILL))
858                    ret = _lscp_client_evt_request(pClient, 0, LSCP_EVENT_BUFFER_FILL);
859            if (ret == LSCP_OK && (events & LSCP_EVENT_CHANNEL_INFO))
860                    ret = _lscp_client_evt_request(pClient, 0, LSCP_EVENT_CHANNEL_INFO);
861            if (ret == LSCP_OK && (events & LSCP_EVENT_TOTAL_VOICE_COUNT))
862                    ret = _lscp_client_evt_request(pClient, 0, LSCP_EVENT_TOTAL_VOICE_COUNT);
863            if (ret == LSCP_OK && (events & LSCP_EVENT_AUDIO_OUTPUT_DEVICE_COUNT))
864                    ret = _lscp_client_evt_request(pClient, 0, LSCP_EVENT_AUDIO_OUTPUT_DEVICE_COUNT);
865            if (ret == LSCP_OK && (events & LSCP_EVENT_AUDIO_OUTPUT_DEVICE_INFO))
866                    ret = _lscp_client_evt_request(pClient, 0, LSCP_EVENT_AUDIO_OUTPUT_DEVICE_INFO);
867            if (ret == LSCP_OK && (events & LSCP_EVENT_MIDI_INPUT_DEVICE_COUNT))
868                    ret = _lscp_client_evt_request(pClient, 0, LSCP_EVENT_MIDI_INPUT_DEVICE_COUNT);
869            if (ret == LSCP_OK && (events & LSCP_EVENT_MIDI_INPUT_DEVICE_INFO))
870                    ret = _lscp_client_evt_request(pClient, 0, LSCP_EVENT_MIDI_INPUT_DEVICE_INFO);
871            if (ret == LSCP_OK && (events & LSCP_EVENT_MIDI_INSTRUMENT_MAP_COUNT))
872                    ret = _lscp_client_evt_request(pClient, 0, LSCP_EVENT_MIDI_INSTRUMENT_MAP_COUNT);
873            if (ret == LSCP_OK && (events & LSCP_EVENT_MIDI_INSTRUMENT_MAP_INFO))
874                    ret = _lscp_client_evt_request(pClient, 0, LSCP_EVENT_MIDI_INSTRUMENT_MAP_INFO);
875            if (ret == LSCP_OK && (events & LSCP_EVENT_MIDI_INSTRUMENT_COUNT))
876                    ret = _lscp_client_evt_request(pClient, 0, LSCP_EVENT_MIDI_INSTRUMENT_COUNT);
877            if (ret == LSCP_OK && (events & LSCP_EVENT_MIDI_INSTRUMENT_INFO))
878                    ret = _lscp_client_evt_request(pClient, 0, LSCP_EVENT_MIDI_INSTRUMENT_INFO);
879            if (ret == LSCP_OK && (events & LSCP_EVENT_MISCELLANEOUS))
880                    ret = _lscp_client_evt_request(pClient, 0, LSCP_EVENT_MISCELLANEOUS);
881            // Caution: for the upper 16 bits, we don't use bit flags anymore ...
882            currentEvent = events & 0xffff0000;
883            if (ret == LSCP_OK && currentEvent) {
884                    switch (currentEvent) {
885                            case LSCP_EVENT_CHANNEL_MIDI:
886                            case LSCP_EVENT_DEVICE_MIDI:
887                                    ret = _lscp_client_evt_request(pClient, 0, currentEvent);
888                                    break;
889                            default: // unknown "upper" event type
890                                    ret = LSCP_FAILED;
891                                    break;
892                    }
893            }
894    
895            // If necessary, close the alternate connection...
896            if (pClient->events == LSCP_EVENT_NONE)
897                    lscp_socket_agent_free(&(pClient->evt));
898    
899            // Unlock this section down.
900            lscp_mutex_unlock(pClient->mutex);
901    
902            return ret;
903  }  }
904    
905    
906  /**  /**
907   *  Deregister frontend for not receiving UDP event messages anymore:   *  Getting current subscribed events.
  *  UNSUBSCRIBE NOTIFICATION <session-id>  
908   *   *
909   *  @param pClient  Pointer to client instance structure.   *  @param pClient  Pointer to client instance structure.
910   *   *
911   *  @returns LSCP_OK on success, LSCP_FAILED otherwise.   *  @returns The current subscrived bit-wise OR'ed event flags.
912   */   */
913  lscp_status_t lscp_client_unsubscribe ( lscp_client_t *pClient )  lscp_event_t lscp_client_get_events ( lscp_client_t *pClient )
914  {  {
915      lscp_status_t ret;          if (pClient == NULL)
916      char szQuery[LSCP_BUFSIZ];                  return LSCP_EVENT_NONE;
   
     if (pClient == NULL)  
         return LSCP_FAILED;  
     if (pClient->sessid == NULL)  
         return LSCP_FAILED;  
   
     // Lock this section up.  
     lscp_mutex_lock(pClient->mutex);  
   
     sprintf(szQuery, "UNSUBSCRIBE NOTIFICATION %s\n\n", pClient->sessid);  
     ret = lscp_client_call(pClient, szQuery);  
     if (ret == LSCP_OK) {  
 #ifdef DEBUG  
         fprintf(stderr, "lscp_client_unsubscribe: %s\n", lscp_client_get_result(pClient));  
 #endif  
         // Bail out session-id string.  
         free(pClient->sessid);  
         pClient->sessid = NULL;  
     }  
   
     // Unlock this section down.  
     lscp_mutex_unlock(pClient->mutex);  
917    
918      return ret;          return pClient->events;
919  }  }
920    
921    
# Line 576  lscp_status_t lscp_client_unsubscribe ( Line 933  lscp_status_t lscp_client_unsubscribe (
933   *   *
934   *  @returns LSCP_OK on success, LSCP_FAILED otherwise.   *  @returns LSCP_OK on success, LSCP_FAILED otherwise.
935   */   */
936  lscp_status_t lscp_load_instrument ( lscp_client_t *pClient, const char *pszFileName, int iInstrIndex, int iSamplerChannel )  lscp_status_t lscp_load_instrument ( lscp_client_t *pClient,
937            const char *pszFileName, int iInstrIndex, int iSamplerChannel )
938    {
939            char szQuery[LSCP_BUFSIZ];
940    
941            if (pszFileName == NULL || iSamplerChannel < 0)
942                    return LSCP_FAILED;
943    
944            sprintf(szQuery, "LOAD INSTRUMENT '%s' %d %d\r\n",
945                    pszFileName, iInstrIndex, iSamplerChannel);
946            return lscp_client_query(pClient, szQuery);
947    }
948    
949    
950    /**
951     *  Loading an instrument in the background (non modal):
952     *  LOAD INSTRUMENT NON_MODAL <filename> <instr-index> <sampler-channel>
953     *
954     *  @param pClient          Pointer to client instance structure.
955     *  @param pszFileName      Instrument file name.
956     *  @param iInstrIndex      Instrument index number.
957     *  @param iSamplerChannel  Sampler Channel.
958     *
959     *  @returns LSCP_OK on success, LSCP_FAILED otherwise.
960     */
961    lscp_status_t lscp_load_instrument_non_modal ( lscp_client_t *pClient,
962            const char *pszFileName, int iInstrIndex, int iSamplerChannel )
963  {  {
964      char szQuery[LSCP_BUFSIZ];          char szQuery[LSCP_BUFSIZ];
965    
966      if (pszFileName == NULL || iSamplerChannel < 0)          if (pszFileName == NULL || iSamplerChannel < 0)
967          return LSCP_FAILED;                  return LSCP_FAILED;
968    
969      sprintf(szQuery, "LOAD INSTRUMENT %s %d %d\r\n", pszFileName, iInstrIndex, iSamplerChannel);          sprintf(szQuery, "LOAD INSTRUMENT NON_MODAL '%s' %d %d\r\n",
970      return lscp_client_query(pClient, szQuery);                  pszFileName, iInstrIndex, iSamplerChannel);
971            return lscp_client_query(pClient, szQuery);
972  }  }
973    
974    
# Line 600  lscp_status_t lscp_load_instrument ( lsc Line 984  lscp_status_t lscp_load_instrument ( lsc
984   */   */
985  lscp_status_t lscp_load_engine ( lscp_client_t *pClient, const char *pszEngineName, int iSamplerChannel )  lscp_status_t lscp_load_engine ( lscp_client_t *pClient, const char *pszEngineName, int iSamplerChannel )
986  {  {
987      char szQuery[LSCP_BUFSIZ];          char szQuery[LSCP_BUFSIZ];
988    
989      if (pszEngineName == NULL || iSamplerChannel < 0)          if (pszEngineName == NULL || iSamplerChannel < 0)
990          return LSCP_FAILED;                  return LSCP_FAILED;
991    
992      sprintf(szQuery, "LOAD ENGINE %s %d\r\n", pszEngineName, iSamplerChannel);          sprintf(szQuery, "LOAD ENGINE %s %d\r\n",
993      return lscp_client_query(pClient, szQuery);                  pszEngineName, iSamplerChannel);
994            return lscp_client_query(pClient, szQuery);
995  }  }
996    
997    
# Line 621  lscp_status_t lscp_load_engine ( lscp_cl Line 1006  lscp_status_t lscp_load_engine ( lscp_cl
1006   */   */
1007  int lscp_get_channels ( lscp_client_t *pClient )  int lscp_get_channels ( lscp_client_t *pClient )
1008  {  {
1009      int iChannels = -1;          int iChannels = -1;
1010    
1011      // Lock this section up.          if (pClient == NULL)
1012      lscp_mutex_lock(pClient->mutex);                  return -1;
1013    
1014      if (lscp_client_call(pClient, "GET CHANNELS\r\n") == LSCP_OK)          // Lock this section up.
1015          iChannels = atoi(lscp_client_get_result(pClient));          lscp_mutex_lock(pClient->mutex);
1016    
1017      // Unlock this section doen.          if (lscp_client_call(pClient, "GET CHANNELS\r\n", 0) == LSCP_OK)
1018      lscp_mutex_unlock(pClient->mutex);                  iChannels = atoi(lscp_client_get_result(pClient));
1019    
1020      return iChannels;          // Unlock this section doen.
1021            lscp_mutex_unlock(pClient->mutex);
1022    
1023            return iChannels;
1024  }  }
1025    
1026    
# Line 647  int lscp_get_channels ( lscp_client_t *p Line 1035  int lscp_get_channels ( lscp_client_t *p
1035   */   */
1036  int *lscp_list_channels ( lscp_client_t *pClient )  int *lscp_list_channels ( lscp_client_t *pClient )
1037  {  {
1038      const char *pszSeps = ",";          const char *pszSeps = ",";
1039    
1040            if (pClient == NULL)
1041                    return NULL;
1042    
1043      if (pClient == NULL)          // Lock this section up.
1044          return NULL;          lscp_mutex_lock(pClient->mutex);
           
     // Lock this section up.  
     lscp_mutex_lock(pClient->mutex);  
   
     if (pClient->channels) {  
         lscp_isplit_destroy(pClient->channels);  
         pClient->channels = NULL;  
     }  
1045    
1046      if (lscp_client_call(pClient, "LIST CHANNELS\r\n") == LSCP_OK)          if (pClient->channels) {
1047          pClient->channels = lscp_isplit_create(lscp_client_get_result(pClient), pszSeps);                  lscp_isplit_destroy(pClient->channels);
1048                    pClient->channels = NULL;
1049            }
1050    
1051      // Unlock this section down.          if (lscp_client_call(pClient, "LIST CHANNELS\r\n", 0) == LSCP_OK)
1052      lscp_mutex_unlock(pClient->mutex);                  pClient->channels = lscp_isplit_create(lscp_client_get_result(pClient), pszSeps);
1053    
1054      return pClient->channels;          // Unlock this section down.
1055            lscp_mutex_unlock(pClient->mutex);
1056    
1057            return pClient->channels;
1058  }  }
1059    
1060    
# Line 681  int *lscp_list_channels ( lscp_client_t Line 1069  int *lscp_list_channels ( lscp_client_t
1069   */   */
1070  int lscp_add_channel ( lscp_client_t *pClient )  int lscp_add_channel ( lscp_client_t *pClient )
1071  {  {
1072      int iSamplerChannel = -1;          int iSamplerChannel = -1;
1073    
1074            if (pClient == NULL)
1075                    return -1;
1076    
1077            // Lock this section up.
1078            lscp_mutex_lock(pClient->mutex);
1079    
1080      // Lock this section up.          if (lscp_client_call(pClient, "ADD CHANNEL\r\n", 0) == LSCP_OK)
1081      lscp_mutex_lock(pClient->mutex);                  iSamplerChannel = atoi(lscp_client_get_result(pClient));
1082    
1083      if (lscp_client_call(pClient, "ADD CHANNEL\r\n") == LSCP_OK)          // Unlock this section down.
1084          iSamplerChannel = atoi(lscp_client_get_result(pClient));          lscp_mutex_unlock(pClient->mutex);
           
     // Unlock this section down.  
     lscp_mutex_unlock(pClient->mutex);  
1085    
1086      return iSamplerChannel;          return iSamplerChannel;
1087  }  }
1088    
1089    
# Line 707  int lscp_add_channel ( lscp_client_t *pC Line 1098  int lscp_add_channel ( lscp_client_t *pC
1098   */   */
1099  lscp_status_t lscp_remove_channel ( lscp_client_t *pClient, int iSamplerChannel )  lscp_status_t lscp_remove_channel ( lscp_client_t *pClient, int iSamplerChannel )
1100  {  {
1101      char szQuery[LSCP_BUFSIZ];          char szQuery[LSCP_BUFSIZ];
1102    
1103      if (iSamplerChannel < 0)          if (iSamplerChannel < 0)
1104          return LSCP_FAILED;                  return LSCP_FAILED;
1105    
1106      sprintf(szQuery, "REMOVE CHANNEL %d\r\n", iSamplerChannel);          sprintf(szQuery, "REMOVE CHANNEL %d\r\n", iSamplerChannel);
1107      return lscp_client_query(pClient, szQuery);          return lscp_client_query(pClient, szQuery);
1108  }  }
1109    
1110    
1111  /**  /**
1112   *  Getting all available engines:   *  Getting all available engines count:
1113   *  GET AVAILABLE_ENGINES   *  GET AVAILABLE_ENGINES
1114   *   *
1115   *  @param pClient  Pointer to client instance structure.   *  @param pClient  Pointer to client instance structure.
1116   *   *
1117     *  @returns The current total number of sampler engines on success,
1118     *  -1 otherwise.
1119     */
1120    int lscp_get_available_engines ( lscp_client_t *pClient )
1121    {
1122            int iAvailableEngines = -1;
1123    
1124            if (pClient == NULL)
1125                    return -1;
1126    
1127            // Lock this section up.
1128            lscp_mutex_lock(pClient->mutex);
1129    
1130            if (lscp_client_call(pClient, "GET AVAILABLE_ENGINES\r\n", 0) == LSCP_OK)
1131                    iAvailableEngines = atoi(lscp_client_get_result(pClient));
1132    
1133            // Unlock this section down.
1134            lscp_mutex_unlock(pClient->mutex);
1135    
1136            return iAvailableEngines;
1137    }
1138    
1139    
1140    /**
1141     *  Getting all available engines:
1142     *  LIST AVAILABLE_ENGINES
1143     *
1144     *  @param pClient  Pointer to client instance structure.
1145     *
1146   *  @returns A NULL terminated array of engine name strings,   *  @returns A NULL terminated array of engine name strings,
1147   *  or NULL in case of failure.   *  or NULL in case of failure.
1148   */   */
1149  const char **lscp_get_available_engines ( lscp_client_t *pClient )  const char **lscp_list_available_engines ( lscp_client_t *pClient )
1150  {  {
1151      const char *pszSeps = ",";          const char *pszSeps = ",";
1152    
1153      // Lock this section up.          if (pClient == NULL)
1154      lscp_mutex_lock(pClient->mutex);                  return NULL;
1155    
1156      if (pClient->engines) {          // Lock this section up.
1157          lscp_szsplit_destroy(pClient->engines);          lscp_mutex_lock(pClient->mutex);
         pClient->engines = NULL;  
     }  
1158    
1159      if (lscp_client_call(pClient, "GET AVAILABLE_ENGINES\r\n") == LSCP_OK)          if (pClient->engines) {
1160          pClient->engines = lscp_szsplit_create(lscp_client_get_result(pClient), pszSeps);                  lscp_szsplit_destroy(pClient->engines);
1161                    pClient->engines = NULL;
1162            }
1163    
1164      // Unlock this section down.          if (lscp_client_call(pClient, "LIST AVAILABLE_ENGINES\r\n", 0) == LSCP_OK)
1165      lscp_mutex_unlock(pClient->mutex);                  pClient->engines = lscp_szsplit_create(lscp_client_get_result(pClient), pszSeps);
1166    
1167      return (const char **) pClient->engines;          // Unlock this section down.
1168            lscp_mutex_unlock(pClient->mutex);
1169    
1170            return (const char **) pClient->engines;
1171  }  }
1172    
1173    
# Line 758  const char **lscp_get_available_engines Line 1181  const char **lscp_get_available_engines
1181   *  @returns A pointer to a @ref lscp_engine_info_t structure, with all the   *  @returns A pointer to a @ref lscp_engine_info_t structure, with all the
1182   *  information of the given sampler engine, or NULL in case of failure.   *  information of the given sampler engine, or NULL in case of failure.
1183   */   */
1184  lscp_engine_info_t *lscp_get_engine_info ( lscp_client_t *pClient, const char *pszEngineName )  lscp_engine_info_t *lscp_get_engine_info ( lscp_client_t *pClient,
1185            const char *pszEngineName )
1186  {  {
1187      lscp_engine_info_t *pEngineInfo;          lscp_engine_info_t *pEngineInfo;
1188      char szQuery[LSCP_BUFSIZ];          char szQuery[LSCP_BUFSIZ];
1189      const char *pszResult;          const char *pszResult;
1190      const char *pszSeps = ":";          const char *pszSeps = ":";
1191      const char *pszCrlf = "\r\n";          const char *pszCrlf = "\r\n";
1192      char *pszToken;          char *pszToken;
1193      char *pch;          char *pch;
1194    
1195      if (pszEngineName == NULL)          if (pClient == NULL)
1196          return NULL;                  return NULL;
1197            if (pszEngineName == NULL)
1198      // Lock this section up.                  return NULL;
1199      lscp_mutex_lock(pClient->mutex);  
1200            // Lock this section up.
1201      pEngineInfo = &(pClient->engine_info);          lscp_mutex_lock(pClient->mutex);
1202      lscp_engine_info_reset(pEngineInfo);  
1203            pEngineInfo = &(pClient->engine_info);
1204      sprintf(szQuery, "GET ENGINE INFO %s\r\n", pszEngineName);          lscp_engine_info_reset(pEngineInfo);
1205      if (lscp_client_call(pClient, szQuery) == LSCP_OK) {  
1206          pszResult = lscp_client_get_result(pClient);          sprintf(szQuery, "GET ENGINE INFO %s\r\n", pszEngineName);
1207          pszToken = lscp_strtok((char *) pszResult, pszSeps, &(pch));          if (lscp_client_call(pClient, szQuery, 1) == LSCP_OK) {
1208          while (pszToken) {                  pszResult = lscp_client_get_result(pClient);
1209              if (strcasecmp(pszToken, "DESCRIPTION") == 0) {                  pszToken = lscp_strtok((char *) pszResult, pszSeps, &(pch));
1210                  pszToken = lscp_strtok(NULL, pszCrlf, &(pch));                  while (pszToken) {
1211                  if (pszToken)                          if (strcasecmp(pszToken, "DESCRIPTION") == 0) {
1212                      pEngineInfo->description = lscp_unquote(&pszToken, 1);                                  pszToken = lscp_strtok(NULL, pszCrlf, &(pch));
1213              }                                  if (pszToken)
1214              else if (strcasecmp(pszToken, "VERSION") == 0) {                                          lscp_unquote_dup(&(pEngineInfo->description), &pszToken);
1215                  pszToken = lscp_strtok(NULL, pszCrlf, &(pch));                          }
1216                  if (pszToken)                          else if (strcasecmp(pszToken, "VERSION") == 0) {
1217                      pEngineInfo->version = lscp_unquote(&pszToken, 1);                                  pszToken = lscp_strtok(NULL, pszCrlf, &(pch));
1218              }                                  if (pszToken)
1219              pszToken = lscp_strtok(NULL, pszSeps, &(pch));                                          lscp_unquote_dup(&(pEngineInfo->version), &pszToken);
1220          }                          }
1221      }                          pszToken = lscp_strtok(NULL, pszSeps, &(pch));
1222      else pEngineInfo = NULL;                  }
1223                }
1224      // Unlock this section down.          else pEngineInfo = NULL;
1225      lscp_mutex_unlock(pClient->mutex);  
1226            // Unlock this section down.
1227            lscp_mutex_unlock(pClient->mutex);
1228    
1229      return pEngineInfo;          return pEngineInfo;
1230  }  }
1231    
1232    
# Line 816  lscp_engine_info_t *lscp_get_engine_info Line 1242  lscp_engine_info_t *lscp_get_engine_info
1242   */   */
1243  lscp_channel_info_t *lscp_get_channel_info ( lscp_client_t *pClient, int iSamplerChannel )  lscp_channel_info_t *lscp_get_channel_info ( lscp_client_t *pClient, int iSamplerChannel )
1244  {  {
1245      lscp_channel_info_t *pChannelInfo;          lscp_channel_info_t *pChannelInfo;
1246      char szQuery[LSCP_BUFSIZ];          char szQuery[LSCP_BUFSIZ];
1247      const char *pszResult;          const char *pszResult;
1248      const char *pszSeps = ":";          const char *pszSeps = ":";
1249      const char *pszCrlf = "\r\n";          const char *pszCrlf = "\r\n";
1250      char *pszToken;          char *pszToken;
1251      char *pch;          char *pch;
1252            struct _locale_t locale;
1253      if (iSamplerChannel < 0)  
1254          return NULL;          if (pClient == NULL)
1255                    return NULL;
1256      // Lock this section up.          if (iSamplerChannel < 0)
1257      lscp_mutex_lock(pClient->mutex);                  return NULL;
1258        
1259      pChannelInfo = &(pClient->channel_info);          // Lock this section up.
1260      lscp_channel_info_reset(pChannelInfo);          lscp_mutex_lock(pClient->mutex);
1261    
1262      sprintf(szQuery, "GET CHANNEL INFO %d\r\n", iSamplerChannel);          pChannelInfo = &(pClient->channel_info);
1263      if (lscp_client_call(pClient, szQuery) == LSCP_OK) {          lscp_channel_info_reset(pChannelInfo);
1264          pszResult = lscp_client_get_result(pClient);  
1265          pszToken = lscp_strtok((char *) pszResult, pszSeps, &(pch));          _save_and_set_c_locale(&locale);
1266          while (pszToken) {  
1267              if (strcasecmp(pszToken, "ENGINE_NAME") == 0) {          sprintf(szQuery, "GET CHANNEL INFO %d\r\n", iSamplerChannel);
1268                  pszToken = lscp_strtok(NULL, pszCrlf, &(pch));          if (lscp_client_call(pClient, szQuery, 1) == LSCP_OK) {
1269                  if (pszToken)                  pszResult = lscp_client_get_result(pClient);
1270                      pChannelInfo->engine_name = lscp_unquote(&pszToken, 1);                  pszToken = lscp_strtok((char *) pszResult, pszSeps, &(pch));
1271              }                  while (pszToken) {
1272              else if (strcasecmp(pszToken, "AUDIO_OUTPUT_DEVICE") == 0) {                          if (strcasecmp(pszToken, "ENGINE_NAME") == 0) {
1273                  pszToken = lscp_strtok(NULL, pszCrlf, &(pch));                                  pszToken = lscp_strtok(NULL, pszCrlf, &(pch));
1274                  if (pszToken)                                  if (pszToken)
1275                      pChannelInfo->audio_device = atoi(lscp_ltrim(pszToken));                                          lscp_unquote_dup(&(pChannelInfo->engine_name), &pszToken);
1276              }                          }
1277              else if (strcasecmp(pszToken, "AUDIO_OUTPUT_CHANNELS") == 0) {                          else if (strcasecmp(pszToken, "AUDIO_OUTPUT_DEVICE") == 0) {
1278                  pszToken = lscp_strtok(NULL, pszCrlf, &(pch));                                  pszToken = lscp_strtok(NULL, pszCrlf, &(pch));
1279                  if (pszToken)                                  if (pszToken)
1280                      pChannelInfo->audio_channels = atoi(lscp_ltrim(pszToken));                                          pChannelInfo->audio_device = atoi(lscp_ltrim(pszToken));
1281              }                          }
1282              else if (strcasecmp(pszToken, "AUDIO_OUTPUT_ROUTING") == 0) {                          else if (strcasecmp(pszToken, "AUDIO_OUTPUT_CHANNELS") == 0) {
1283                  pszToken = lscp_strtok(NULL, pszCrlf, &(pch));                                  pszToken = lscp_strtok(NULL, pszCrlf, &(pch));
1284                  if (pszToken)                                  if (pszToken)
1285                      pChannelInfo->audio_routing = lscp_szsplit_create(pszToken, ",");                                          pChannelInfo->audio_channels = atoi(lscp_ltrim(pszToken));
1286              }                          }
1287              else if (strcasecmp(pszToken, "INSTRUMENT_FILE") == 0) {                          else if (strcasecmp(pszToken, "AUDIO_OUTPUT_ROUTING") == 0) {
1288                  pszToken = lscp_strtok(NULL, pszCrlf, &(pch));                                  pszToken = lscp_strtok(NULL, pszCrlf, &(pch));
1289                  if (pszToken)                                  if (pszToken) {
1290                      pChannelInfo->instrument_file = lscp_unquote(&pszToken, 1);                                          if (pChannelInfo->audio_routing)
1291              }                                                  lscp_isplit_destroy(pChannelInfo->audio_routing);
1292              else if (strcasecmp(pszToken, "INSTRUMENT_NR") == 0) {                                          pChannelInfo->audio_routing = lscp_isplit_create(pszToken, ",");
1293                  pszToken = lscp_strtok(NULL, pszCrlf, &(pch));                                  }
1294                  if (pszToken)                          }
1295                      pChannelInfo->instrument_nr = atoi(lscp_ltrim(pszToken));                          else if (strcasecmp(pszToken, "INSTRUMENT_FILE") == 0) {
1296              }                                  pszToken = lscp_strtok(NULL, pszCrlf, &(pch));
1297              else if (strcasecmp(pszToken, "INSTRUMENT_STATUS") == 0) {                                  if (pszToken)
1298                  pszToken = lscp_strtok(NULL, pszCrlf, &(pch));                                          lscp_unquote_dup(&(pChannelInfo->instrument_file), &pszToken);
1299                  if (pszToken)                          }
1300                      pChannelInfo->instrument_status = atoi(lscp_ltrim(pszToken));                          else if (strcasecmp(pszToken, "INSTRUMENT_NR") == 0) {
1301              }                                  pszToken = lscp_strtok(NULL, pszCrlf, &(pch));
1302              else if (strcasecmp(pszToken, "MIDI_INPUT_DEVICE") == 0) {                                  if (pszToken)
1303                  pszToken = lscp_strtok(NULL, pszCrlf, &(pch));                                          pChannelInfo->instrument_nr = atoi(lscp_ltrim(pszToken));
1304                  if (pszToken)                          }
1305                      pChannelInfo->midi_device = atoi(lscp_ltrim(pszToken));                          else if (strcasecmp(pszToken, "INSTRUMENT_NAME") == 0) {
1306              }                                  pszToken = lscp_strtok(NULL, pszCrlf, &(pch));
1307              else if (strcasecmp(pszToken, "MIDI_INPUT_PORT") == 0) {                                  if (pszToken)
1308                  pszToken = lscp_strtok(NULL, pszCrlf, &(pch));                                          lscp_unquote_dup(&(pChannelInfo->instrument_name), &pszToken);
1309                  if (pszToken)                          }
1310                      pChannelInfo->midi_port = atoi(lscp_ltrim(pszToken));                          else if (strcasecmp(pszToken, "INSTRUMENT_STATUS") == 0) {
1311              }                                  pszToken = lscp_strtok(NULL, pszCrlf, &(pch));
1312              else if (strcasecmp(pszToken, "MIDI_INPUT_CHANNEL") == 0) {                                  if (pszToken)
1313                  pszToken = lscp_strtok(NULL, pszCrlf, &(pch));                                          pChannelInfo->instrument_status = atoi(lscp_ltrim(pszToken));
1314                  if (pszToken)                          }
1315                      pChannelInfo->midi_channel = atoi(lscp_ltrim(pszToken));                          else if (strcasecmp(pszToken, "MIDI_INPUT_DEVICE") == 0) {
1316              }                                  pszToken = lscp_strtok(NULL, pszCrlf, &(pch));
1317              else if (strcasecmp(pszToken, "VOLUME") == 0) {                                  if (pszToken)
1318                  pszToken = lscp_strtok(NULL, pszCrlf, &(pch));                                          pChannelInfo->midi_device = atoi(lscp_ltrim(pszToken));
1319                  if (pszToken)                          }
1320                      pChannelInfo->volume = (float) atof(lscp_ltrim(pszToken));                          else if (strcasecmp(pszToken, "MIDI_INPUT_PORT") == 0) {
1321              }                                  pszToken = lscp_strtok(NULL, pszCrlf, &(pch));
1322              pszToken = lscp_strtok(NULL, pszSeps, &(pch));                                  if (pszToken)
1323          }                                          pChannelInfo->midi_port = atoi(lscp_ltrim(pszToken));
1324      }                          }
1325      else pChannelInfo = NULL;                          else if (strcasecmp(pszToken, "MIDI_INPUT_CHANNEL") == 0) {
1326                                        pszToken = lscp_strtok(NULL, pszCrlf, &(pch));
1327      // Unlock this section up.                                  if (pszToken) {
1328      lscp_mutex_unlock(pClient->mutex);                                          pszToken = lscp_ltrim(pszToken);
1329                                            if (strcasecmp(pszToken, "ALL") == 0)
1330                                                    pChannelInfo->midi_channel = LSCP_MIDI_CHANNEL_ALL;
1331                                            else
1332                                                    pChannelInfo->midi_channel = atoi(pszToken);
1333                                    }
1334                            }
1335                            else if (strcasecmp(pszToken, "MIDI_INSTRUMENT_MAP") == 0) {
1336                                    pszToken = lscp_strtok(NULL, pszCrlf, &(pch));
1337                                    if (pszToken) {
1338                                            pszToken = lscp_ltrim(pszToken);
1339                                            if (strcasecmp(pszToken, "NONE") == 0)
1340                                                    pChannelInfo->midi_map = LSCP_MIDI_MAP_NONE;
1341                                            else
1342                                            if (strcasecmp(pszToken, "DEFAULT") == 0)
1343                                                    pChannelInfo->midi_map = LSCP_MIDI_MAP_DEFAULT;
1344                                            else
1345                                                    pChannelInfo->midi_map = atoi(pszToken);
1346                                    }
1347                            }
1348                            else if (strcasecmp(pszToken, "VOLUME") == 0) {
1349                                    pszToken = lscp_strtok(NULL, pszCrlf, &(pch));
1350                                    if (pszToken)
1351                                            pChannelInfo->volume = _atof(lscp_ltrim(pszToken));
1352                            }
1353                            else if (strcasecmp(pszToken, "MUTE") == 0) {
1354                                    pszToken = lscp_strtok(NULL, pszCrlf, &(pch));
1355                                    if (pszToken)
1356                                            pChannelInfo->mute = (strcasecmp(lscp_unquote(&pszToken, 0), "TRUE") == 0);
1357                            }
1358                            else if (strcasecmp(pszToken, "SOLO") == 0) {
1359                                    pszToken = lscp_strtok(NULL, pszCrlf, &(pch));
1360                                    if (pszToken)
1361                                            pChannelInfo->solo = (strcasecmp(lscp_unquote(&pszToken, 0), "TRUE") == 0);
1362                            }
1363                            pszToken = lscp_strtok(NULL, pszSeps, &(pch));
1364                    }
1365            }
1366            else pChannelInfo = NULL;
1367    
1368            _restore_locale(&locale);
1369    
1370      return pChannelInfo;          // Unlock this section up.
1371            lscp_mutex_unlock(pClient->mutex);
1372    
1373            return pChannelInfo;
1374  }  }
1375    
1376    
# Line 916  lscp_channel_info_t *lscp_get_channel_in Line 1385  lscp_channel_info_t *lscp_get_channel_in
1385   */   */
1386  int lscp_get_channel_voice_count ( lscp_client_t *pClient, int iSamplerChannel )  int lscp_get_channel_voice_count ( lscp_client_t *pClient, int iSamplerChannel )
1387  {  {
1388      char szQuery[LSCP_BUFSIZ];          char szQuery[LSCP_BUFSIZ];
1389      int iVoiceCount = -1;          int iVoiceCount = -1;
1390    
1391      if (iSamplerChannel < 0)          if (pClient == NULL)
1392          return iVoiceCount;                  return -1;
1393            if (iSamplerChannel < 0)
1394                    return -1;
1395    
1396      // Lock this section up.          // Lock this section up.
1397      lscp_mutex_lock(pClient->mutex);          lscp_mutex_lock(pClient->mutex);
1398    
1399      sprintf(szQuery, "GET CHANNEL VOICE_COUNT %d\r\n", iSamplerChannel);          sprintf(szQuery, "GET CHANNEL VOICE_COUNT %d\r\n", iSamplerChannel);
1400      if (lscp_client_call(pClient, szQuery) == LSCP_OK)          if (lscp_client_call(pClient, szQuery, 0) == LSCP_OK)
1401          iVoiceCount = atoi(lscp_client_get_result(pClient));                  iVoiceCount = atoi(lscp_client_get_result(pClient));
1402    
1403      // Unlock this section down.          // Unlock this section down.
1404      lscp_mutex_unlock(pClient->mutex);          lscp_mutex_unlock(pClient->mutex);
1405    
1406      return iVoiceCount;          return iVoiceCount;
1407  }  }
1408    
1409    
# Line 940  int lscp_get_channel_voice_count ( lscp_ Line 1411  int lscp_get_channel_voice_count ( lscp_
1411   *  Current number of active disk streams:   *  Current number of active disk streams:
1412   *  GET CHANNEL STREAM_COUNT <sampler-channel>   *  GET CHANNEL STREAM_COUNT <sampler-channel>
1413   *   *
1414     *  @param pClient          Pointer to client instance structure.
1415     *  @param iSamplerChannel  Sampler channel number.
1416     *
1417   *  @returns The number of active disk streams on success, -1 otherwise.   *  @returns The number of active disk streams on success, -1 otherwise.
1418   */   */
1419  int lscp_get_channel_stream_count ( lscp_client_t *pClient, int iSamplerChannel )  int lscp_get_channel_stream_count ( lscp_client_t *pClient, int iSamplerChannel )
1420  {  {
1421      char szQuery[LSCP_BUFSIZ];          char szQuery[LSCP_BUFSIZ];
1422      int iStreamCount = -1;          int iStreamCount = -1;
1423    
1424            if (pClient == NULL)
1425                    return -1;
1426            if (iSamplerChannel < 0)
1427                    return -1;
1428    
1429            // Lock this section up.
1430            lscp_mutex_lock(pClient->mutex);
1431    
1432            sprintf(szQuery, "GET CHANNEL STREAM_COUNT %d\r\n", iSamplerChannel);
1433            if (lscp_client_call(pClient, szQuery, 0) == LSCP_OK)
1434                    iStreamCount = atoi(lscp_client_get_result(pClient));
1435    
1436      if (iSamplerChannel < 0)          // Unlock this section down.
1437          return iStreamCount;          lscp_mutex_unlock(pClient->mutex);
1438    
1439            return iStreamCount;
1440    }
1441    
     // Lock this section up.  
     lscp_mutex_lock(pClient->mutex);  
1442    
1443      sprintf(szQuery, "GET CHANNEL STREAM_COUNT %d\r\n", iSamplerChannel);  /**
1444      if (lscp_client_call(pClient, szQuery) == LSCP_OK)   *  Current least usage of active disk streams.
1445          iStreamCount = atoi(lscp_client_get_result(pClient));   *
1446     *  @param pClient          Pointer to client instance structure.
1447     *  @param iSamplerChannel  Sampler channel number.
1448     *
1449     *  @returns The usage percentage of the least filled active disk stream
1450     *  on success, -1 otherwise.
1451     */
1452    int lscp_get_channel_stream_usage ( lscp_client_t *pClient, int iSamplerChannel )
1453    {
1454            char szQuery[LSCP_BUFSIZ];
1455            int  iStreamUsage = -1;
1456            const char *pszResult;
1457            const char *pszSeps = "[]%,";
1458            char *pszToken;
1459            char *pch;
1460            int   iStream;
1461            int   iPercent;
1462    
1463            if (pClient == NULL)
1464                    return -1;
1465            if (iSamplerChannel < 0)
1466                    return -1;
1467    
1468            // Lock this section up.
1469            lscp_mutex_lock(pClient->mutex);
1470    
1471            iStream = 0;
1472            sprintf(szQuery, "GET CHANNEL BUFFER_FILL PERCENTAGE %d\r\n", iSamplerChannel);
1473            if (lscp_client_call(pClient, szQuery, 0) == LSCP_OK) {
1474                    pszResult = lscp_client_get_result(pClient);
1475                    pszToken = lscp_strtok((char *) pszResult, pszSeps, &(pch));
1476                    while (pszToken) {
1477                            if (*pszToken) {
1478                                    // Skip stream id.
1479                                    pszToken = lscp_strtok(NULL, pszSeps, &(pch));
1480                                    if (pszToken == NULL)
1481                                            break;
1482                                    // Get least buffer fill percentage.
1483                                    iPercent = atol(pszToken);
1484                                    if (iStreamUsage > iPercent || iStream == 0)
1485                                            iStreamUsage = iPercent;
1486                                    iStream++;
1487                            }
1488                            pszToken = lscp_strtok(NULL, pszSeps, &(pch));
1489                    }
1490            }
1491    
1492      // Unlock this section down.          // Unlock this section down.
1493      lscp_mutex_unlock(pClient->mutex);          lscp_mutex_unlock(pClient->mutex);
1494    
1495      return iStreamCount;          return iStreamUsage;
1496  }  }
1497    
1498    
# Line 978  int lscp_get_channel_stream_count ( lscp Line 1510  int lscp_get_channel_stream_count ( lscp
1510   *  information of the current disk stream buffer fill usage, for the given   *  information of the current disk stream buffer fill usage, for the given
1511   *  sampler channel, or NULL in case of failure.   *  sampler channel, or NULL in case of failure.
1512   */   */
1513  lscp_buffer_fill_t *lscp_get_channel_buffer_fill ( lscp_client_t *pClient, lscp_usage_t usage_type, int iSamplerChannel )  lscp_buffer_fill_t *lscp_get_channel_buffer_fill ( lscp_client_t *pClient,
1514            lscp_usage_t usage_type, int iSamplerChannel )
1515  {  {
1516      lscp_buffer_fill_t *pBufferFill;          lscp_buffer_fill_t *pBufferFill;
1517      char szQuery[LSCP_BUFSIZ];          char szQuery[LSCP_BUFSIZ];
1518      int iStreamCount;          int iStreamCount;
1519      const char *pszUsageType = (usage_type == LSCP_USAGE_BYTES ? "BYTES" : "PERCENTAGE");          const char *pszUsageType = (usage_type == LSCP_USAGE_BYTES ? "BYTES" : "PERCENTAGE");
1520      const char *pszResult;          const char *pszResult;
1521      const char *pszSeps = "[]%,";          const char *pszSeps = "[]%,";
1522      char *pszToken;          char *pszToken;
1523      char *pch;          char *pch;
1524      int   iStream;          int   iStream;
1525    
1526      // Retrieve a channel stream estimation.          // Retrieve a channel stream estimation.
1527      iStreamCount = lscp_get_channel_stream_count(pClient, iSamplerChannel);          iStreamCount = lscp_get_channel_stream_count(pClient, iSamplerChannel);
1528      if (pClient->iStreamCount < 0)          if (iStreamCount < 0)
1529          return NULL;                  return NULL;
1530    
1531      // Lock this section up.          // Lock this section up.
1532      lscp_mutex_lock(pClient->mutex);          lscp_mutex_lock(pClient->mutex);
1533    
1534      // Check if we need to reallocate the stream usage array.          // Check if we need to reallocate the stream usage array.
1535      if (pClient->iStreamCount != iStreamCount) {          if (pClient->iStreamCount != iStreamCount) {
1536          if (pClient->buffer_fill)                  if (pClient->buffer_fill)
1537              free(pClient->buffer_fill);                          free(pClient->buffer_fill);
1538          if (iStreamCount > 0)                  if (iStreamCount > 0)
1539              pClient->buffer_fill = (lscp_buffer_fill_t *) malloc(iStreamCount * sizeof(lscp_buffer_fill_t));                          pClient->buffer_fill = (lscp_buffer_fill_t *) malloc(iStreamCount * sizeof(lscp_buffer_fill_t));
1540          else                  else
1541              pClient->buffer_fill = NULL;                          pClient->buffer_fill = NULL;
1542          pClient->iStreamCount = iStreamCount;                  pClient->iStreamCount = iStreamCount;
1543      }          }
1544    
1545      // Get buffer fill usage...          // Get buffer fill usage...
1546      pBufferFill = pClient->buffer_fill;          pBufferFill = pClient->buffer_fill;
1547      if (pBufferFill && iStreamCount > 0) {          if (pBufferFill && iStreamCount > 0) {
1548          iStream = 0;                  iStream = 0;
1549          pBufferFill = pClient->buffer_fill;                  pBufferFill = pClient->buffer_fill;
1550          sprintf(szQuery, "GET CHANNEL BUFFER_FILL %s %d\r\n", pszUsageType, iSamplerChannel);                  sprintf(szQuery, "GET CHANNEL BUFFER_FILL %s %d\r\n", pszUsageType, iSamplerChannel);
1551          if (lscp_client_call(pClient, szQuery) == LSCP_OK) {                  if (lscp_client_call(pClient, szQuery, 0) == LSCP_OK) {
1552              pszResult = lscp_client_get_result(pClient);                          pszResult = lscp_client_get_result(pClient);
1553              pszToken = lscp_strtok((char *) pszResult, pszSeps, &(pch));                          pszToken = lscp_strtok((char *) pszResult, pszSeps, &(pch));
1554              while (pszToken && iStream < pClient->iStreamCount) {                          while (pszToken && iStream < pClient->iStreamCount) {
1555                  if (*pszToken) {                                  if (*pszToken) {
1556                      pBufferFill[iStream].stream_id = atol(pszToken);                                          pBufferFill[iStream].stream_id = atol(pszToken);
1557                      pszToken = lscp_strtok(NULL, pszSeps, &(pch));                                          pszToken = lscp_strtok(NULL, pszSeps, &(pch));
1558                      if (pszToken == NULL)                                          if (pszToken == NULL)
1559                          break;                                                  break;
1560                      pBufferFill[iStream].stream_usage = atol(pszToken);                                          pBufferFill[iStream].stream_usage = atol(pszToken);
1561                      iStream++;                                          iStream++;
1562                  }                                  }
1563                  pszToken = lscp_strtok(NULL, pszSeps, &(pch));                                  pszToken = lscp_strtok(NULL, pszSeps, &(pch));
1564              }                          }
1565          }   // Reset the usage, whatever it was before.                  }   // Reset the usage, whatever it was before.
1566          else while (iStream < pClient->iStreamCount)                  else while (iStream < pClient->iStreamCount)
1567              pBufferFill[iStream++].stream_usage = 0;                          pBufferFill[iStream++].stream_usage = 0;
1568      }          }
1569        
1570      // Unlock this section down.          // Unlock this section down.
1571      lscp_mutex_unlock(pClient->mutex);          lscp_mutex_unlock(pClient->mutex);
1572    
1573      return pBufferFill;          return pBufferFill;
1574  }  }
1575    
1576    
# Line 1048  lscp_buffer_fill_t *lscp_get_channel_buf Line 1581  lscp_buffer_fill_t *lscp_get_channel_buf
1581   *  @param pClient          Pointer to client instance structure.   *  @param pClient          Pointer to client instance structure.
1582   *  @param iSamplerChannel  Sampler channel number.   *  @param iSamplerChannel  Sampler channel number.
1583   *  @param pszAudioDriver   Audio output driver type (e.g. "ALSA" or "JACK").   *  @param pszAudioDriver   Audio output driver type (e.g. "ALSA" or "JACK").
1584     *
1585     *  @returns LSCP_OK on success, LSCP_FAILED otherwise.
1586     */
1587    lscp_status_t lscp_set_channel_audio_type ( lscp_client_t *pClient,
1588            int iSamplerChannel, const char *pszAudioDriver )
1589    {
1590            char szQuery[LSCP_BUFSIZ];
1591    
1592            if (iSamplerChannel < 0 || pszAudioDriver == NULL)
1593                    return LSCP_FAILED;
1594    
1595            sprintf(szQuery, "SET CHANNEL AUDIO_OUTPUT_TYPE %d %s\r\n",
1596                    iSamplerChannel, pszAudioDriver);
1597            return lscp_client_query(pClient, szQuery);
1598    }
1599    
1600    
1601    /**
1602     *  Setting audio output device:
1603     *  SET CHANNEL AUDIO_OUTPUT_DEVICE <sampler-channel> <device-id>
1604     *
1605     *  @param pClient          Pointer to client instance structure.
1606     *  @param iSamplerChannel  Sampler channel number.
1607     *  @param iAudioDevice     Audio output device number identifier.
1608     *
1609     *  @returns LSCP_OK on success, LSCP_FAILED otherwise.
1610   */   */
1611  lscp_status_t lscp_set_channel_audio_type ( lscp_client_t *pClient, int iSamplerChannel, const char *pszAudioDriver )  lscp_status_t lscp_set_channel_audio_device ( lscp_client_t *pClient,
1612            int iSamplerChannel, int iAudioDevice )
1613  {  {
1614      char szQuery[LSCP_BUFSIZ];          char szQuery[LSCP_BUFSIZ];
1615    
1616      if (iSamplerChannel < 0 || pszAudioDriver == NULL)          if (iSamplerChannel < 0 || iAudioDevice < 0)
1617          return LSCP_FAILED;                  return LSCP_FAILED;
1618    
1619      sprintf(szQuery, "SET CHANNEL AUDIO_OUTPUT_TYPE %d %s\r\n", iSamplerChannel, pszAudioDriver);          sprintf(szQuery, "SET CHANNEL AUDIO_OUTPUT_DEVICE %d %d\r\n",
1620      return lscp_client_query(pClient, szQuery);                  iSamplerChannel, iAudioDevice);
1621            return lscp_client_query(pClient, szQuery);
1622  }  }
1623    
1624    
# Line 1072  lscp_status_t lscp_set_channel_audio_typ Line 1633  lscp_status_t lscp_set_channel_audio_typ
1633   *   *
1634   *  @returns LSCP_OK on success, LSCP_FAILED otherwise.   *  @returns LSCP_OK on success, LSCP_FAILED otherwise.
1635   */   */
1636  lscp_status_t lscp_set_channel_audio_channel ( lscp_client_t *pClient, int iSamplerChannel, int iAudioOut, int iAudioIn )  lscp_status_t lscp_set_channel_audio_channel ( lscp_client_t *pClient,
1637            int iSamplerChannel, int iAudioOut, int iAudioIn )
1638  {  {
1639      char szQuery[LSCP_BUFSIZ];          char szQuery[LSCP_BUFSIZ];
1640    
1641      if (iSamplerChannel < 0 || iAudioOut < 0 || iAudioIn < 0)          if (iSamplerChannel < 0 || iAudioOut < 0 || iAudioIn < 0)
1642          return LSCP_FAILED;                  return LSCP_FAILED;
1643    
1644      sprintf(szQuery, "SET CHANNEL AUDIO_OUTPUT_CHANNELS %d %d %d\r\n", iSamplerChannel, iAudioOut, iAudioIn);          sprintf(szQuery, "SET CHANNEL AUDIO_OUTPUT_CHANNEL %d %d %d\r\n",
1645      return lscp_client_query(pClient, szQuery);                  iSamplerChannel, iAudioOut, iAudioIn);
1646            return lscp_client_query(pClient, szQuery);
1647  }  }
1648    
1649    
# Line 1094  lscp_status_t lscp_set_channel_audio_cha Line 1657  lscp_status_t lscp_set_channel_audio_cha
1657   *   *
1658   *  @returns LSCP_OK on success, LSCP_FAILED otherwise.   *  @returns LSCP_OK on success, LSCP_FAILED otherwise.
1659   */   */
1660  lscp_status_t lscp_set_channel_midi_type ( lscp_client_t *pClient, int iSamplerChannel, const char *pszMidiDriver )  lscp_status_t lscp_set_channel_midi_type ( lscp_client_t *pClient,
1661            int iSamplerChannel, const char *pszMidiDriver )
1662    {
1663            char szQuery[LSCP_BUFSIZ];
1664    
1665            if (iSamplerChannel < 0 || pszMidiDriver == NULL)
1666                    return LSCP_FAILED;
1667    
1668            sprintf(szQuery, "SET CHANNEL MIDI_INPUT_TYPE %d %s\r\n",
1669                    iSamplerChannel, pszMidiDriver);
1670            return lscp_client_query(pClient, szQuery);
1671    }
1672    
1673    
1674    /**
1675     *  Setting MIDI input device:
1676     *  SET CHANNEL MIDI_INPUT_DEVICE <sampler-channel> <device-id>
1677     *
1678     *  @param pClient          Pointer to client instance structure.
1679     *  @param iSamplerChannel  Sampler channel number.
1680     *  @param iMidiDevice      MIDI input device number identifier.
1681     *
1682     *  @returns LSCP_OK on success, LSCP_FAILED otherwise.
1683     */
1684    lscp_status_t lscp_set_channel_midi_device ( lscp_client_t *pClient,
1685            int iSamplerChannel, int iMidiDevice )
1686  {  {
1687      char szQuery[LSCP_BUFSIZ];          char szQuery[LSCP_BUFSIZ];
1688    
1689      if (iSamplerChannel < 0 || pszMidiDriver == NULL)          if (iSamplerChannel < 0 || iMidiDevice < 0)
1690          return LSCP_FAILED;                  return LSCP_FAILED;
1691    
1692      sprintf(szQuery, "SET CHANNEL MIDI_INPUT_TYPE %d %s\r\n", iSamplerChannel, pszMidiDriver);          sprintf(szQuery, "SET CHANNEL MIDI_INPUT_DEVICE %d %d\r\n",
1693      return lscp_client_query(pClient, szQuery);                  iSamplerChannel, iMidiDevice);
1694            return lscp_client_query(pClient, szQuery);
1695  }  }
1696    
1697    
# Line 1116  lscp_status_t lscp_set_channel_midi_type Line 1705  lscp_status_t lscp_set_channel_midi_type
1705   *   *
1706   *  @returns LSCP_OK on success, LSCP_FAILED otherwise.   *  @returns LSCP_OK on success, LSCP_FAILED otherwise.
1707   */   */
1708  lscp_status_t lscp_set_channel_midi_port ( lscp_client_t *pClient, int iSamplerChannel, int iMidiPort )  lscp_status_t lscp_set_channel_midi_port ( lscp_client_t *pClient,
1709            int iSamplerChannel, int iMidiPort )
1710  {  {
1711      char szQuery[LSCP_BUFSIZ];          char szQuery[LSCP_BUFSIZ];
1712    
1713      if (iSamplerChannel < 0 || iMidiPort < 0)          if (iSamplerChannel < 0 || iMidiPort < 0)
1714          return LSCP_FAILED;                  return LSCP_FAILED;
1715    
1716      sprintf(szQuery, "SET CHANNEL MIDI_INPUT_PORT %d %d\r\n", iSamplerChannel, iMidiPort);          sprintf(szQuery, "SET CHANNEL MIDI_INPUT_PORT %d %d\r\n",
1717      return lscp_client_query(pClient, szQuery);                  iSamplerChannel, iMidiPort);
1718            return lscp_client_query(pClient, szQuery);
1719  }  }
1720    
1721    
# Line 1134  lscp_status_t lscp_set_channel_midi_port Line 1725  lscp_status_t lscp_set_channel_midi_port
1725   *   *
1726   *  @param pClient          Pointer to client instance structure.   *  @param pClient          Pointer to client instance structure.
1727   *  @param iSamplerChannel  Sampler channel number.   *  @param iSamplerChannel  Sampler channel number.
1728   *  @param iMidiChannel     MIDI channel number to listen (1-16) or   *  @param iMidiChannel     MIDI channel address number to listen (0-15) or
1729   *                          zero (0) to listen on all channels.   *                          @ref LSCP_MIDI_CHANNEL_ALL (16) to listen on all channels.
1730   *   *
1731   *  @returns LSCP_OK on success, LSCP_FAILED otherwise.   *  @returns LSCP_OK on success, LSCP_FAILED otherwise.
1732   */   */
1733  lscp_status_t lscp_set_channel_midi_channel ( lscp_client_t *pClient, int iSamplerChannel, int iMidiChannel )  lscp_status_t lscp_set_channel_midi_channel ( lscp_client_t *pClient,
1734            int iSamplerChannel, int iMidiChannel )
1735  {  {
1736      char szQuery[LSCP_BUFSIZ];          char szQuery[LSCP_BUFSIZ];
1737    
1738      if (iSamplerChannel < 0 || iMidiChannel < 0 || iMidiChannel > 16)          if (iSamplerChannel < 0 || iMidiChannel < 0 || iMidiChannel > 16)
1739          return LSCP_FAILED;                  return LSCP_FAILED;
1740    
1741      if (iMidiChannel > 0)          if (iMidiChannel == LSCP_MIDI_CHANNEL_ALL)
1742          sprintf(szQuery, "SET CHANNEL MIDI_INPUT_CHANNEL %d %d\r\n", iSamplerChannel, iMidiChannel);                  sprintf(szQuery, "SET CHANNEL MIDI_INPUT_CHANNEL %d ALL\r\n",
1743      else                          iSamplerChannel);
1744          sprintf(szQuery, "SET CHANNEL MIDI_INPUT_CHANNEL %d ALL\r\n", iSamplerChannel);          else
1745      return lscp_client_query(pClient, szQuery);                  sprintf(szQuery, "SET CHANNEL MIDI_INPUT_CHANNEL %d %d\r\n",
1746                            iSamplerChannel, iMidiChannel);
1747            return lscp_client_query(pClient, szQuery);
1748    }
1749    
1750    
1751    /**
1752     *  Setting MIDI instrument map:
1753     *  SET CHANNEL MIDI_INSTRUMENT_MAP <sampler-channel> <midi-map>
1754     *
1755     *  @param pClient          Pointer to client instance structure.
1756     *  @param iSamplerChannel  Sampler channel number.
1757     *  @param iMidiMap         MIDI instrument map number, or either
1758     *                          @ref LSCP_MIDI_MAP_NONE or
1759     *                          @ref LSCP_MIDI_MAP_DEFAULT .
1760     *
1761     *  @returns LSCP_OK on success, LSCP_FAILED otherwise.
1762     */
1763    lscp_status_t lscp_set_channel_midi_map ( lscp_client_t *pClient,
1764            int iSamplerChannel, int iMidiMap )
1765    {
1766            char szQuery[LSCP_BUFSIZ];
1767    
1768            if (iSamplerChannel < 0)
1769                    return LSCP_FAILED;
1770    
1771            sprintf(szQuery, "SET CHANNEL MIDI_INSTRUMENT_MAP %d ", iSamplerChannel);
1772            if (iMidiMap == LSCP_MIDI_MAP_NONE)
1773                    strcat(szQuery , "NONE");
1774            else
1775            if (iMidiMap == LSCP_MIDI_MAP_DEFAULT)
1776                    strcat(szQuery , "DEFAULT");
1777            else
1778                    sprintf(szQuery + strlen(szQuery), "%d", iMidiMap);
1779    
1780            strcat(szQuery, "\r\n");
1781    
1782            return lscp_client_query(pClient, szQuery);
1783  }  }
1784    
1785    
# Line 1166  lscp_status_t lscp_set_channel_midi_chan Line 1795  lscp_status_t lscp_set_channel_midi_chan
1795   *   *
1796   *  @returns LSCP_OK on success, LSCP_FAILED otherwise.   *  @returns LSCP_OK on success, LSCP_FAILED otherwise.
1797   */   */
1798  lscp_status_t lscp_set_channel_volume ( lscp_client_t *pClient, int iSamplerChannel, float fVolume )  lscp_status_t lscp_set_channel_volume ( lscp_client_t *pClient,
1799            int iSamplerChannel, float fVolume )
1800    {
1801            char szQuery[LSCP_BUFSIZ];
1802            struct _locale_t locale;
1803    
1804            if (iSamplerChannel < 0 || fVolume < 0.0f)
1805                    return LSCP_FAILED;
1806    
1807            _save_and_set_c_locale(&locale);
1808            sprintf(szQuery, "SET CHANNEL VOLUME %d %g\r\n",
1809                    iSamplerChannel, fVolume);
1810            _restore_locale(&locale);
1811    
1812            return lscp_client_query(pClient, szQuery);
1813    }
1814    
1815    
1816    /**
1817     *  Muting a sampler channel:
1818     *  SET CHANNEL MUTE <sampler-channel> <mute>
1819     *
1820     *  @param pClient          Pointer to client instance structure.
1821     *  @param iSamplerChannel  Sampler channel number.
1822     *  @param iMute            Sampler channel mute state as a boolean value,
1823     *                          either 1 (one) to mute the channel or 0 (zero)
1824     *                          to unmute the channel.
1825     *
1826     *  @returns LSCP_OK on success, LSCP_FAILED otherwise.
1827     */
1828    lscp_status_t lscp_set_channel_mute ( lscp_client_t *pClient,
1829            int iSamplerChannel, int iMute )
1830    {
1831            char szQuery[LSCP_BUFSIZ];
1832    
1833            if (iSamplerChannel < 0 || iMute < 0 || iMute > 1)
1834                    return LSCP_FAILED;
1835    
1836            sprintf(szQuery, "SET CHANNEL MUTE %d %d\r\n",
1837                    iSamplerChannel, iMute);
1838            return lscp_client_query(pClient, szQuery);
1839    }
1840    
1841    
1842    /**
1843     *  Soloing a sampler channel:
1844     *  SET CHANNEL SOLO <sampler-channel> <solo>
1845     *
1846     *  @param pClient          Pointer to client instance structure.
1847     *  @param iSamplerChannel  Sampler channel number.
1848     *  @param iSolo            Sampler channel solo state as a boolean value,
1849     *                          either 1 (one) to solo the channel or 0 (zero)
1850     *                          to unsolo the channel.
1851     *
1852     *  @returns LSCP_OK on success, LSCP_FAILED otherwise.
1853     */
1854    lscp_status_t lscp_set_channel_solo ( lscp_client_t *pClient,
1855            int iSamplerChannel, int iSolo )
1856  {  {
1857      char szQuery[LSCP_BUFSIZ];          char szQuery[LSCP_BUFSIZ];
1858    
1859      if (iSamplerChannel < 0 || fVolume < 0.0)          if (iSamplerChannel < 0 || iSolo < 0 || iSolo > 1)
1860          return LSCP_FAILED;                  return LSCP_FAILED;
1861    
1862      sprintf(szQuery, "SET CHANNEL VOLUME %d %g\r\n", iSamplerChannel, fVolume);          sprintf(szQuery, "SET CHANNEL SOLO %d %d\r\n",
1863      return lscp_client_query(pClient, szQuery);                  iSamplerChannel, iSolo);
1864            return lscp_client_query(pClient, szQuery);
1865  }  }
1866    
1867    
# Line 1189  lscp_status_t lscp_set_channel_volume ( Line 1876  lscp_status_t lscp_set_channel_volume (
1876   */   */
1877  lscp_status_t lscp_reset_channel ( lscp_client_t *pClient, int iSamplerChannel )  lscp_status_t lscp_reset_channel ( lscp_client_t *pClient, int iSamplerChannel )
1878  {  {
1879      char szQuery[LSCP_BUFSIZ];          char szQuery[LSCP_BUFSIZ];
1880    
1881            if (iSamplerChannel < 0)
1882                    return LSCP_FAILED;
1883    
1884            sprintf(szQuery, "RESET CHANNEL %d\r\n", iSamplerChannel);
1885            return lscp_client_query(pClient, szQuery);
1886    }
1887    
1888    
1889    /**
1890     *  Resetting the sampler:
1891     *  RESET
1892     *
1893     *  @param pClient  Pointer to client instance structure.
1894     *
1895     *  @returns LSCP_OK on success, LSCP_FAILED otherwise.
1896     */
1897    lscp_status_t lscp_reset_sampler ( lscp_client_t *pClient )
1898    {
1899            // Do actual whole sampler reset...
1900            return lscp_client_query(pClient, "RESET\r\n");
1901    }
1902    
1903    
1904    /**
1905     *  Getting information about the server.
1906     *  GET SERVER INFO
1907     *
1908     *  @param pClient  Pointer to client instance structure.
1909     *
1910     *  @returns A pointer to a @ref lscp_server_info_t structure, with all the
1911     *  information of the current connected server, or NULL in case of failure.
1912     */
1913    lscp_server_info_t *lscp_get_server_info ( lscp_client_t *pClient )
1914    {
1915            lscp_server_info_t *pServerInfo;
1916            const char *pszResult;
1917            const char *pszSeps = ":";
1918            const char *pszCrlf = "\r\n";
1919            char *pszToken;
1920            char *pch;
1921    
1922            if (pClient == NULL)
1923                    return NULL;
1924    
1925            // Lock this section up.
1926            lscp_mutex_lock(pClient->mutex);
1927    
1928            pServerInfo = &(pClient->server_info);
1929            lscp_server_info_reset(pServerInfo);
1930    
1931            if (lscp_client_call(pClient, "GET SERVER INFO\r\n", 1) == LSCP_OK) {
1932                    pszResult = lscp_client_get_result(pClient);
1933                    pszToken = lscp_strtok((char *) pszResult, pszSeps, &(pch));
1934                    while (pszToken) {
1935                            if (strcasecmp(pszToken, "DESCRIPTION") == 0) {
1936                                    pszToken = lscp_strtok(NULL, pszCrlf, &(pch));
1937                                    if (pszToken)
1938                                            lscp_unquote_dup(&(pServerInfo->description), &pszToken);
1939                            }
1940                            else if (strcasecmp(pszToken, "VERSION") == 0) {
1941                                    pszToken = lscp_strtok(NULL, pszCrlf, &(pch));
1942                                    if (pszToken)
1943                                            lscp_unquote_dup(&(pServerInfo->version), &pszToken);
1944                            }
1945                            else if (strcasecmp(pszToken, "PROTOCOL_VERSION") == 0) {
1946                                    pszToken = lscp_strtok(NULL, pszCrlf, &(pch));
1947                                    if (pszToken)
1948                                            lscp_unquote_dup(&(pServerInfo->protocol_version), &pszToken);
1949                            }
1950                            pszToken = lscp_strtok(NULL, pszSeps, &(pch));
1951                    }
1952            }
1953            else pServerInfo = NULL;
1954    
1955            // Unlock this section down.
1956            lscp_mutex_unlock(pClient->mutex);
1957    
1958            return pServerInfo;
1959    }
1960    
1961    
1962    /**
1963     *  Current total number of active voices:
1964     *  GET TOTAL_VOICE_COUNT
1965     *
1966     *  @param pClient  Pointer to client instance structure.
1967     *
1968     *  @returns The total number of voices currently active,
1969     *  -1 in case of failure.
1970     */
1971    int lscp_get_total_voice_count ( lscp_client_t *pClient )
1972    {
1973            int iVoiceCount = -1;
1974    
1975            if (pClient == NULL)
1976                    return -1;
1977    
1978            // Lock this section up.
1979            lscp_mutex_lock(pClient->mutex);
1980    
1981            if (lscp_client_call(pClient, "GET TOTAL_VOICE_COUNT\r\n", 0) == LSCP_OK)
1982                    iVoiceCount = atoi(lscp_client_get_result(pClient));
1983    
1984            // Unlock this section down.
1985            lscp_mutex_unlock(pClient->mutex);
1986    
1987            return iVoiceCount;
1988    }
1989    
1990    
1991    /**
1992     *  Maximum amount of active voices:
1993     *  GET TOTAL_VOICE_COUNT_MAX
1994     *
1995     *  @param pClient  Pointer to client instance structure.
1996     *
1997     *  @returns The maximum amount of voices currently active,
1998     *  -1 in case of failure.
1999     */
2000    int lscp_get_total_voice_count_max ( lscp_client_t *pClient )
2001    {
2002            int iVoiceCount = -1;
2003    
2004            if (pClient == NULL)
2005                    return -1;
2006    
2007            // Lock this section up.
2008            lscp_mutex_lock(pClient->mutex);
2009    
2010            if (lscp_client_call(pClient, "GET TOTAL_VOICE_COUNT_MAX\r\n", 0) == LSCP_OK)
2011                    iVoiceCount = atoi(lscp_client_get_result(pClient));
2012    
2013            // Unlock this section down.
2014            lscp_mutex_unlock(pClient->mutex);
2015    
2016            return iVoiceCount;
2017    }
2018    
2019    
2020    /**
2021     *  Get global volume attenuation:
2022     *  GET VOLUME
2023     *
2024     *  @param pClient  Pointer to client instance structure.
2025     *
2026     *  @returns The global volume as positive floating point value usually in
2027     *  the range between 0.0 and 1.0; in case of failure 0.0 is returned.
2028     */
2029    float lscp_get_volume ( lscp_client_t *pClient )
2030    {
2031            float fVolume = 0.0f;
2032            struct _locale_t locale;
2033    
2034            if (pClient == NULL)
2035                    return 0.0f;
2036    
2037            // Lock this section up.
2038            lscp_mutex_lock(pClient->mutex);
2039    
2040            _save_and_set_c_locale(&locale);
2041    
2042            if (lscp_client_call(pClient, "GET VOLUME\r\n", 0) == LSCP_OK)
2043                    fVolume = _atof(lscp_client_get_result(pClient));
2044    
2045            _restore_locale(&locale);
2046    
2047            // Unlock this section down.
2048            lscp_mutex_unlock(pClient->mutex);
2049    
2050            return fVolume;
2051    }
2052    
2053    
2054    /**
2055     *  Setting global volume attenuation:
2056     *  SET VOLUME <volume>
2057     *
2058     *  @param pClient  Pointer to client instance structure.
2059     *  @param fVolume  Global volume parameter as positive floating point
2060     *                  value usually be in the range between 0.0 and 1.0,
2061     *                  that is for attenuating the overall volume.
2062     *
2063     *  @returns LSCP_OK on success, LSCP_FAILED otherwise.
2064     */
2065    lscp_status_t lscp_set_volume ( lscp_client_t *pClient, float fVolume )
2066    {
2067            char szQuery[LSCP_BUFSIZ];
2068            struct _locale_t locale;
2069    
2070            if (fVolume < 0.0f)
2071                    return LSCP_FAILED;
2072    
2073            _save_and_set_c_locale(&locale);
2074            sprintf(szQuery, "SET VOLUME %g\r\n", fVolume);
2075            _restore_locale(&locale);
2076    
2077            return lscp_client_query(pClient, szQuery);
2078    }
2079    
2080    
2081    /**
2082     *  Get global voice limit setting:
2083     *  @code
2084     *  GET VOICES
2085     *  @endcode
2086     *  This value reflects the maximum amount of voices a sampler engine
2087     *  processes simultaniously before voice stealing kicks in.
2088     *
2089     *  @param pClient  Pointer to client instance structure.
2090     *
2091     *  @returns The current global maximum amount of voices limit or a
2092     *           negative value on error (e.g. if sampler doesn't support
2093     *           this command).
2094     */
2095    int lscp_get_voices ( lscp_client_t *pClient )
2096    {
2097            int iVoices = -1;
2098    
2099            if (pClient == NULL)
2100                    return -1;
2101    
2102            // Lock this section up.
2103            lscp_mutex_lock(pClient->mutex);
2104    
2105            if (lscp_client_call(pClient, "GET VOICES\r\n", 0) == LSCP_OK)
2106                    iVoices = atoi(lscp_client_get_result(pClient));
2107    
2108            // Unlock this section down.
2109            lscp_mutex_unlock(pClient->mutex);
2110    
2111            return iVoices;
2112    }
2113    
2114    
2115    /**
2116     *  Setting global voice limit setting:
2117     *  @code
2118     *  SET VOICES <max-voices>
2119     *  @endcode
2120     *  This value reflects the maximum amount of voices a sampler engine
2121     *  processes simultaniously before voice stealing kicks in. Note that
2122     *  this value will be passed to all sampler engine instances, that is
2123     *  the total amount of maximum voices on the running system is thus
2124     *  @param iMaxVoices multiplied with the current amount of sampler
2125     *  engine instances.
2126     *
2127     *  @param pClient     Pointer to client instance structure.
2128     *  @param iMaxVoices  Global voice limit setting as integer value larger
2129     *                     or equal to 1.
2130     *
2131     *  @returns LSCP_OK on success, LSCP_FAILED otherwise.
2132     */
2133    lscp_status_t lscp_set_voices ( lscp_client_t *pClient, int iMaxVoices )
2134    {
2135            char szQuery[LSCP_BUFSIZ];
2136    
2137            if (iMaxVoices < 1)
2138                    return LSCP_FAILED;
2139    
2140            sprintf(szQuery, "SET VOICES %d\r\n", iMaxVoices);
2141            return lscp_client_query(pClient, szQuery);
2142    }
2143    
2144    
2145    /**
2146     *  Get global disk streams limit setting:
2147     *  @code
2148     *  GET STREAMS
2149     *  @endcode
2150     *  This value reflects the maximum amount of disk streams a sampler
2151     *  engine processes simultaniously.
2152     *
2153     *  @param pClient  Pointer to client instance structure.
2154     *
2155     *  @returns The current global maximum amount of disk streams limit
2156     *           or a negative value on error (e.g. if sampler doesn't
2157     *           support this command).
2158     */
2159    int lscp_get_streams ( lscp_client_t *pClient )
2160    {
2161            int iStreams = -1;
2162    
2163            if (pClient == NULL)
2164                    return -1;
2165    
2166            // Lock this section up.
2167            lscp_mutex_lock(pClient->mutex);
2168    
2169            if (lscp_client_call(pClient, "GET STREAMS\r\n", 0) == LSCP_OK)
2170                    iStreams = atoi(lscp_client_get_result(pClient));
2171    
2172            // Unlock this section down.
2173            lscp_mutex_unlock(pClient->mutex);
2174    
2175            return iStreams;
2176    }
2177    
2178    
2179    /**
2180     *  Setting global disk streams limit setting:
2181     *  @code
2182     *  SET STREAMS <max-streams>
2183     *  @endcode
2184     *  This value reflects the maximum amount of dist streams a sampler
2185     *  engine instance processes simultaniously. Note that this value will
2186     *  be passed to all sampler engine instances, that is the total amount
2187     *  of maximum disk streams on the running system is thus
2188     *  @param iMaxStreams multiplied with the current amount of sampler
2189     *  engine instances.
2190     *
2191     *  @param pClient      Pointer to client instance structure.
2192     *  @param iMaxStreams  Global streams limit setting as positive integer
2193     *                      value (larger or equal to 0).
2194     *
2195     *  @returns LSCP_OK on success, LSCP_FAILED otherwise.
2196     */
2197    lscp_status_t lscp_set_streams ( lscp_client_t *pClient, int iMaxStreams )
2198    {
2199            char szQuery[LSCP_BUFSIZ];
2200    
2201            if (iMaxStreams < 0)
2202                    return LSCP_FAILED;
2203    
2204            sprintf(szQuery, "SET STREAMS %d\r\n", iMaxStreams);
2205            return lscp_client_query(pClient, szQuery);
2206    }
2207    
2208    
2209    /**
2210     *  Add an effect send to a sampler channel:
2211     *  CREATE FX_SEND <sampler-channel> <midi-ctrl> [<fx-name>]
2212     *
2213     *  @param pClient          Pointer to client instance structure.
2214     *  @param iSamplerChannel  Sampler channel number.
2215     *  @param iMidiController  MIDI controller used to alter the effect,
2216     *                          usually a number between 0 and 127.
2217     *  @param pszFxName        Optional name for the effect send entity,
2218     *                          does not have to be unique.
2219     *
2220     *  @returns The new effect send number identifier, or -1 in case of failure.
2221     */
2222    int lscp_create_fxsend ( lscp_client_t *pClient,
2223            int iSamplerChannel, int iMidiController, const char *pszFxName )
2224    {
2225            int iFxSend = -1;
2226            char szQuery[LSCP_BUFSIZ];
2227    
2228            if (pClient == NULL)
2229                    return -1;
2230            if (iSamplerChannel < 0 || iMidiController < 0 || iMidiController > 127)
2231                    return -1;
2232    
2233            // Lock this section up.
2234            lscp_mutex_lock(pClient->mutex);
2235    
2236            sprintf(szQuery, "CREATE FX_SEND %d %d",
2237                    iSamplerChannel, iMidiController);
2238    
2239            if (pszFxName)
2240                    sprintf(szQuery + strlen(szQuery), " '%s'", pszFxName);
2241    
2242            strcat(szQuery, "\r\n");
2243    
2244            if (lscp_client_call(pClient, szQuery, 0) == LSCP_OK)
2245                    iFxSend = atoi(lscp_client_get_result(pClient));
2246    
2247            // Unlock this section down.
2248            lscp_mutex_unlock(pClient->mutex);
2249    
2250            return iFxSend;
2251    }
2252    
2253    
2254    /**
2255     *  Remove an effect send from a sampler channel:
2256     *  DESTROY FX_SEND <sampler-channel> <fx-send-id>
2257     *
2258     *  @param pClient          Pointer to client instance structure.
2259     *  @param iSamplerChannel  Sampler channel number.
2260     *  @param iFxSend          Effect send number.
2261     *
2262     *  @returns LSCP_OK on success, LSCP_FAILED otherwise.
2263     */
2264    lscp_status_t lscp_destroy_fxsend ( lscp_client_t *pClient,
2265            int iSamplerChannel, int iFxSend )
2266    {
2267            char szQuery[LSCP_BUFSIZ];
2268    
2269            if (iSamplerChannel < 0 || iFxSend < 0)
2270                    return LSCP_FAILED;
2271    
2272            sprintf(szQuery, "DESTROY FX_SEND %d %d\r\n",
2273                    iSamplerChannel, iFxSend);
2274    
2275            return lscp_client_query(pClient, szQuery);
2276    }
2277    
2278    
2279    /**
2280     *  Get amount of effect sends on a sampler channel:
2281     *  GET FX_SENDS <sampler-channel>
2282     *
2283     *  @param pClient          Pointer to client instance structure.
2284     *  @param iSamplerChannel  Sampler channel number.
2285     *
2286     *  @returns The current total number of effect sends of the sampler channel
2287     *  on success, -1 otherwise.
2288     */
2289    int lscp_get_fxsends ( lscp_client_t *pClient, int iSamplerChannel )
2290    {
2291            int iFxSends = -1;
2292            char szQuery[LSCP_BUFSIZ];
2293    
2294            if (pClient == NULL)
2295                    return -1;
2296            if (iSamplerChannel < 0)
2297                    return -1;
2298    
2299            // Lock this section up.
2300            lscp_mutex_lock(pClient->mutex);
2301    
2302            sprintf(szQuery, "GET FX_SENDS %d\r\n", iSamplerChannel);
2303    
2304            if (lscp_client_call(pClient, szQuery, 0) == LSCP_OK)
2305                    iFxSends = atoi(lscp_client_get_result(pClient));
2306    
2307            // Unlock this section doen.
2308            lscp_mutex_unlock(pClient->mutex);
2309    
2310            return iFxSends;
2311    }
2312    
2313    
2314    /**
2315     *  List all effect sends on a sampler channel:
2316     *  LIST FX_SENDS <sampler-channel>
2317     *
2318     *  @param pClient          Pointer to client instance structure.
2319     *  @param iSamplerChannel  Sampler channel number.
2320     *
2321     *  @returns An array of the effect sends identifiers as positive integers,
2322     *  terminated with -1 on success, NULL otherwise.
2323     */
2324    int *lscp_list_fxsends ( lscp_client_t *pClient, int iSamplerChannel )
2325    {
2326            const char *pszSeps = ",";
2327            char szQuery[LSCP_BUFSIZ];
2328    
2329            if (pClient == NULL)
2330                    return NULL;
2331    
2332            // Lock this section up.
2333            lscp_mutex_lock(pClient->mutex);
2334    
2335            if (pClient->fxsends) {
2336                    lscp_isplit_destroy(pClient->fxsends);
2337                    pClient->fxsends = NULL;
2338            }
2339    
2340            sprintf(szQuery, "LIST FX_SENDS %d\r\n", iSamplerChannel);
2341    
2342            if (lscp_client_call(pClient, szQuery, 0) == LSCP_OK)
2343                    pClient->fxsends = lscp_isplit_create(lscp_client_get_result(pClient), pszSeps);
2344    
2345            // Unlock this section down.
2346            lscp_mutex_unlock(pClient->mutex);
2347    
2348            return pClient->fxsends;
2349    }
2350    
2351    
2352    /**
2353     *  Getting effect send information
2354     *  GET FX_SEND INFO <sampler-channel> <fx-send-id>
2355     *
2356     *  @param pClient          Pointer to client instance structure.
2357     *  @param iSamplerChannel  Sampler channel number.
2358     *  @param iFxSend          Effect send number.
2359     *
2360     *  @returns A pointer to a @ref lscp_fxsend_info_t structure, with the
2361     *  information of the given FX send, or NULL in case of failure.
2362     */
2363    lscp_fxsend_info_t *lscp_get_fxsend_info ( lscp_client_t *pClient,
2364            int iSamplerChannel, int iFxSend )
2365    {
2366            lscp_fxsend_info_t *pFxSendInfo;
2367            char szQuery[LSCP_BUFSIZ];
2368            const char *pszResult;
2369            const char *pszSeps = ":";
2370            const char *pszCrlf = "\r\n";
2371            char *pszToken;
2372            char *pch;
2373            struct _locale_t locale;
2374    
2375            if (pClient == NULL)
2376                    return NULL;
2377            if (iSamplerChannel < 0 || iFxSend < 0)
2378                    return NULL;
2379    
2380            // Lock this section up.
2381            lscp_mutex_lock(pClient->mutex);
2382    
2383            _save_and_set_c_locale(&locale);
2384    
2385            pFxSendInfo = &(pClient->fxsend_info);
2386            lscp_fxsend_info_reset(pFxSendInfo);
2387    
2388            sprintf(szQuery, "GET FX_SEND INFO %d %d\r\n", iSamplerChannel, iFxSend);
2389            if (lscp_client_call(pClient, szQuery, 1) == LSCP_OK) {
2390                    pszResult = lscp_client_get_result(pClient);
2391                    pszToken = lscp_strtok((char *) pszResult, pszSeps, &(pch));
2392                    while (pszToken) {
2393                            if (strcasecmp(pszToken, "NAME") == 0) {
2394                                    pszToken = lscp_strtok(NULL, pszCrlf, &(pch));
2395                                    if (pszToken)
2396                                            lscp_unquote_dup(&(pFxSendInfo->name), &pszToken);
2397                            }
2398                            else if (strcasecmp(pszToken, "MIDI_CONTROLLER") == 0) {
2399                                    pszToken = lscp_strtok(NULL, pszCrlf, &(pch));
2400                                    if (pszToken)
2401                                            pFxSendInfo->midi_controller = atoi(lscp_ltrim(pszToken));
2402                            }
2403                            else if (strcasecmp(pszToken, "AUDIO_OUTPUT_ROUTING") == 0) {
2404                                    pszToken = lscp_strtok(NULL, pszCrlf, &(pch));
2405                                    if (pszToken) {
2406                                            if (pFxSendInfo->audio_routing)
2407                                                    lscp_isplit_destroy(pFxSendInfo->audio_routing);
2408                                            pFxSendInfo->audio_routing = lscp_isplit_create(pszToken, ",");
2409                                    }
2410                            }
2411                            else if (strcasecmp(pszToken, "LEVEL") == 0) {
2412                                    pszToken = lscp_strtok(NULL, pszCrlf, &(pch));
2413                                    if (pszToken)
2414                                            pFxSendInfo->level = _atof(lscp_ltrim(pszToken));
2415                            }
2416                            pszToken = lscp_strtok(NULL, pszSeps, &(pch));
2417                    }
2418            }
2419            else pFxSendInfo = NULL;
2420    
2421            _restore_locale(&locale);
2422    
2423            // Unlock this section up.
2424            lscp_mutex_unlock(pClient->mutex);
2425    
2426            return pFxSendInfo;
2427    }
2428    
2429    
2430    /**
2431     *  Alter effect send's name:
2432     *  @code
2433     *  SET FX_SEND NAME <sampler-chan> <fx-send-id> <name>
2434     *  @endcode
2435     *
2436     *  @param pClient          Pointer to client instance structure.
2437     *  @param iSamplerChannel  Sampler channel number.
2438     *  @param iFxSend          Effect send number.
2439     *  @param pszFxName        Effect send's new name.
2440     *
2441     *  @returns LSCP_OK on success, LSCP_FAILED otherwise.
2442     */
2443    lscp_status_t lscp_set_fxsend_name ( lscp_client_t *pClient,
2444            int iSamplerChannel, int iFxSend, const char *pszFxName )
2445    {
2446            char szQuery[LSCP_BUFSIZ];
2447    
2448            if (!pClient || iSamplerChannel < 0 || iFxSend < 0 || !pszFxName)
2449                    return LSCP_FAILED;
2450    
2451            snprintf(szQuery, LSCP_BUFSIZ, "SET FX_SEND NAME %d %d '%s'\r\n",
2452                    iSamplerChannel, iFxSend, pszFxName);
2453            return lscp_client_query(pClient, szQuery);
2454    }
2455    
2456    
2457    /**
2458     *  Alter effect send's audio routing:
2459     *  SET FX_SEND AUDIO_OUTPUT_CHANNEL <sampler-chan> <fx-send-id>
2460     *    <audio-src> <audio-dst>
2461     *
2462     *  @param pClient          Pointer to client instance structure.
2463     *  @param iSamplerChannel  Sampler channel number.
2464     *  @param iFxSend          Effect send number.
2465     *  @param iAudioSrc        Audio output device channel to be routed from.
2466     *  @param iAudioDst        Audio output device channel to be routed into.
2467     *
2468     *  @returns LSCP_OK on success, LSCP_FAILED otherwise.
2469     */
2470    lscp_status_t lscp_set_fxsend_audio_channel ( lscp_client_t *pClient,
2471            int iSamplerChannel, int iFxSend, int iAudioSrc, int iAudioDst )
2472    {
2473            char szQuery[LSCP_BUFSIZ];
2474    
2475            if (iSamplerChannel < 0 || iFxSend < 0 || iAudioSrc < 0 || iAudioDst < 0)
2476                    return LSCP_FAILED;
2477    
2478            sprintf(szQuery, "SET FX_SEND AUDIO_OUTPUT_CHANNEL %d %d %d %d\r\n",
2479                    iSamplerChannel, iFxSend, iAudioSrc, iAudioDst);
2480            return lscp_client_query(pClient, szQuery);
2481    }
2482    
2483    
2484    /**
2485     *  Alter effect send's MIDI controller:
2486     *  SET FX_SEND MIDI_CONTROLLER <sampler-chan> <fx-send-id> <midi-ctrl>
2487     *
2488     *  @param pClient          Pointer to client instance structure.
2489     *  @param iSamplerChannel  Sampler channel number.
2490     *  @param iFxSend          Effect send number.
2491     *  @param iMidiController  MIDI controller used to alter the effect,
2492     *                          usually a number between 0 and 127.
2493     *
2494     *  @returns LSCP_OK on success, LSCP_FAILED otherwise.
2495     */
2496    lscp_status_t lscp_set_fxsend_midi_controller ( lscp_client_t *pClient,
2497            int iSamplerChannel, int iFxSend, int iMidiController )
2498    {
2499            char szQuery[LSCP_BUFSIZ];
2500    
2501            if (iSamplerChannel < 0 || iFxSend < 0 ||
2502                    iMidiController < 0 || iMidiController > 127)
2503                    return LSCP_FAILED;
2504    
2505            sprintf(szQuery, "SET FX_SEND MIDI_CONTROLLER %d %d %d\r\n",
2506                    iSamplerChannel, iFxSend, iMidiController);
2507            return lscp_client_query(pClient, szQuery);
2508    }
2509    
2510    
2511    /**
2512     *  Alter effect send's audio level:
2513     *  SET FX_SEND LEVEL <sampler-chan> <fx-send-id> <level>
2514     *
2515     *  @param pClient          Pointer to client instance structure.
2516     *  @param iSamplerChannel  Sampler channel number.
2517     *  @param iFxSend          Effect send number.
2518     *  @param fLevel           Effect send volume level.
2519     *
2520     *  @returns LSCP_OK on success, LSCP_FAILED otherwise.
2521     */
2522    lscp_status_t lscp_set_fxsend_level ( lscp_client_t *pClient,
2523            int iSamplerChannel, int iFxSend, float fLevel )
2524    {
2525            char szQuery[LSCP_BUFSIZ];
2526            struct _locale_t locale;
2527    
2528            if (iSamplerChannel < 0 || iFxSend < 0 || fLevel < 0.0f)
2529                    return LSCP_FAILED;
2530    
2531            _save_and_set_c_locale(&locale);
2532            sprintf(szQuery, "SET FX_SEND LEVEL %d %d %f\r\n",
2533                    iSamplerChannel, iFxSend, fLevel);
2534            _restore_locale(&locale);
2535    
2536            return lscp_client_query(pClient, szQuery);
2537    }
2538    
2539    
2540    /**
2541     *  Create a new MIDI instrument map:
2542     *  ADD MIDI_INSTRUMENT_MAP [<name>]
2543     *
2544     *  @param pClient      Pointer to client instance structure.
2545     *  @param pszMapName   MIDI instrument map name (optional)
2546     *
2547     *  @returns The new MIDI instrument map number identifier,
2548     *  or -1 in case of failure.
2549     */
2550    int lscp_add_midi_instrument_map ( lscp_client_t *pClient, const char *pszMapName )
2551    {
2552            int iMidiMap = -1;
2553            char szQuery[LSCP_BUFSIZ];
2554    
2555            if (pClient == NULL)
2556                    return -1;
2557    
2558            // Lock this section up.
2559            lscp_mutex_lock(pClient->mutex);
2560    
2561            strcpy(szQuery, "ADD MIDI_INSTRUMENT_MAP");
2562    
2563            if (pszMapName)
2564                    sprintf(szQuery + strlen(szQuery), " '%s'", pszMapName);
2565    
2566            strcat(szQuery, "\r\n");
2567    
2568            if (lscp_client_call(pClient, szQuery, 0) == LSCP_OK)
2569                    iMidiMap = atoi(lscp_client_get_result(pClient));
2570    
2571            // Unlock this section down.
2572            lscp_mutex_unlock(pClient->mutex);
2573    
2574            return iMidiMap;
2575    }
2576    
2577    
2578    /**
2579     *  Delete one particular or all MIDI instrument maps:
2580     *  REMOVE MIDI_INSTRUMENT_MAP <midi-map>
2581     *
2582     *  @param pClient  Pointer to client instance structure.
2583     *  @param iMidiMap MIDI instrument map number.
2584     *
2585     *  @returns LSCP_OK on success, LSCP_FAILED otherwise.
2586     */
2587    lscp_status_t lscp_remove_midi_instrument_map ( lscp_client_t *pClient, int iMidiMap )
2588    {
2589            char szQuery[LSCP_BUFSIZ];
2590    
2591            if (iMidiMap < 0)
2592                    return LSCP_FAILED;
2593    
2594            sprintf(szQuery, "REMOVE MIDI_INSTRUMENT_MAP %d\r\n", iMidiMap);
2595    
2596            return lscp_client_query(pClient, szQuery);
2597    }
2598    
2599    
2600    /**
2601     *  Get amount of existing MIDI instrument maps:
2602     *  GET MIDI_INSTRUMENT_MAPS
2603     *
2604     *  @param pClient  Pointer to client instance structure.
2605     *
2606     *  @returns The current total number of MIDI instrument maps
2607     *  on success, -1 otherwise.
2608     */
2609    int lscp_get_midi_instrument_maps ( lscp_client_t *pClient )
2610    {
2611            int iMidiMaps = -1;
2612    
2613            if (pClient == NULL)
2614                    return -1;
2615    
2616            // Lock this section up.
2617            lscp_mutex_lock(pClient->mutex);
2618    
2619            if (lscp_client_call(pClient, "GET MIDI_INSTRUMENT_MAPS\r\n", 0) == LSCP_OK)
2620                    iMidiMaps = atoi(lscp_client_get_result(pClient));
2621    
2622            // Unlock this section doen.
2623            lscp_mutex_unlock(pClient->mutex);
2624    
2625            return iMidiMaps;
2626    }
2627    
2628    
2629    /**
2630     *  Getting all created MIDI instrument maps:
2631     *  LIST MIDI_INSTRUMENT_MAPS
2632     *
2633     *  @param pClient  Pointer to client instance structure.
2634     *
2635     *  @returns An array of the MIDI instrument map identifiers as positive
2636     *  integers, terminated with -1 on success, NULL otherwise.
2637     */
2638    int *lscp_list_midi_instrument_maps ( lscp_client_t *pClient )
2639    {
2640            const char *pszSeps = ",";
2641    
2642            if (pClient == NULL)
2643                    return NULL;
2644    
2645            // Lock this section up.
2646            lscp_mutex_lock(pClient->mutex);
2647    
2648            if (pClient->midi_maps) {
2649                    lscp_isplit_destroy(pClient->midi_maps);
2650                    pClient->midi_maps = NULL;
2651            }
2652    
2653            if (lscp_client_call(pClient, "LIST MIDI_INSTRUMENT_MAPS\r\n", 0) == LSCP_OK)
2654                    pClient->midi_maps = lscp_isplit_create(lscp_client_get_result(pClient), pszSeps);
2655    
2656            // Unlock this section down.
2657            lscp_mutex_unlock(pClient->mutex);
2658    
2659            return pClient->midi_maps;
2660    }
2661    
2662    
2663    /**
2664     *  Getting a MIDI instrument map name:
2665     *  GET MIDI_INSTRUMENT_MAP INFO <midi-map>
2666     *
2667     *  @param pClient  Pointer to client instance structure.
2668     *  @param iMidiMap MIDI instrument map number.
2669     *
2670     *  @returns The MIDI instrument map name on success, NULL on failure.
2671     */
2672    const char *lscp_get_midi_instrument_map_name ( lscp_client_t *pClient, int iMidiMap )
2673    {
2674            char szQuery[LSCP_BUFSIZ];
2675            const char *pszResult;
2676            const char *pszSeps = ":";
2677            const char *pszCrlf = "\r\n";
2678            char *pszToken;
2679            char *pch;
2680    
2681            if (pClient == NULL)
2682                    return NULL;
2683            if (iMidiMap < 0)
2684                    return NULL;
2685    
2686            // Lock this section up.
2687            lscp_mutex_lock(pClient->mutex);
2688    
2689            if (pClient->midi_map_name) {
2690                    free(pClient->midi_map_name);
2691                    pClient->midi_map_name = NULL;
2692            }
2693    
2694            sprintf(szQuery, "GET MIDI_INSTRUMENT_MAP INFO %d\r\n", iMidiMap);
2695            if (lscp_client_call(pClient, szQuery, 1) == LSCP_OK) {
2696                    pszResult = lscp_client_get_result(pClient);
2697                    pszToken = lscp_strtok((char *) pszResult, pszSeps, &(pch));
2698                    while (pszToken) {
2699                            if (strcasecmp(pszToken, "NAME") == 0) {
2700                                    pszToken = lscp_strtok(NULL, pszCrlf, &(pch));
2701                                    if (pszToken)
2702                                            lscp_unquote_dup(&(pClient->midi_map_name), &pszToken);
2703                            }
2704                            pszToken = lscp_strtok(NULL, pszSeps, &(pch));
2705                    }
2706            }
2707    
2708            // Unlock this section down.
2709            lscp_mutex_unlock(pClient->mutex);
2710    
2711            return pClient->midi_map_name;
2712    }
2713    
2714    
2715    /**
2716     *  Renaming a MIDI instrument map:
2717     *  SET MIDI_INSTRUMENT_MAP NAME <midi-map> <map-name>
2718     *
2719     *  @param pClient      Pointer to client instance structure.
2720     *  @param iMidiMap     MIDI instrument map number.
2721     *  @param pszMapName   MIDI instrument map name.
2722     *
2723     *  @returns LSCP_OK on success, LSCP_FAILED otherwise.
2724     */
2725    lscp_status_t lscp_set_midi_instrument_map_name ( lscp_client_t *pClient, int iMidiMap, const char *pszMapName )
2726    {
2727            char szQuery[LSCP_BUFSIZ];
2728    
2729            if (iMidiMap < 0)
2730                    return LSCP_FAILED;
2731            if (pszMapName == NULL)
2732                    return LSCP_FAILED;
2733    
2734            sprintf(szQuery, "SET MIDI_INSTRUMENT_MAP NAME %d '%s'\r\n",
2735                    iMidiMap, pszMapName);
2736    
2737            return lscp_client_query(pClient, szQuery);
2738    }
2739    
2740    
2741    /**
2742     *  Create or replace a MIDI instrumnet map entry:
2743     *  MAP MIDI_INSTRUMENT <midi-map> <midi-bank> <midi-prog>
2744     *      <engine-name> <filename> <instr-index> <volume> [<load-mode> [<name>]}
2745     *
2746     *  @param pClient          Pointer to client instance structure.
2747     *  @param pMidiInstr       MIDI instrument bank and program parameter key.
2748     *  @param pszEngineName    Engine name.
2749     *  @param pszFileName      Instrument file name.
2750     *  @param iInstrIndex      Instrument index number.
2751     *  @param fVolume          Reflects the master volume of the instrument as
2752     *                          a positive floating point number, where a value
2753     *                          less than 1.0 for attenuation, and greater than
2754     *                          1.0 for amplification.
2755     *  @param load_mode        Instrument load life-time strategy, either
2756     *                          @ref LSCP_LOAD_DEFAULT, or
2757     *                          @ref LSCP_LOAD_ON_DEMAND, or
2758     *                          @ref LSCP_LOAD_ON_DEMAND_HOLD, or
2759     *                          @ref LSCP_LOAD_PERSISTENT.
2760     *  @param pszName         Instrument custom name for the map entry (optional).
2761     *
2762     *  @returns LSCP_OK on success, LSCP_FAILED otherwise.
2763     */
2764    lscp_status_t lscp_map_midi_instrument ( lscp_client_t *pClient,
2765            lscp_midi_instrument_t *pMidiInstr, const char *pszEngineName,
2766            const char *pszFileName, int iInstrIndex, float fVolume,
2767            lscp_load_mode_t load_mode, const char *pszName )
2768    {
2769            char szQuery[LSCP_BUFSIZ];
2770            struct _locale_t locale;
2771    
2772            if (pMidiInstr->map < 0)
2773                    return LSCP_FAILED;
2774            if (pMidiInstr->bank < 0 || pMidiInstr->bank > 16383)
2775                    return LSCP_FAILED;
2776            if (pMidiInstr->prog < 0 || pMidiInstr->prog > 127)
2777                    return LSCP_FAILED;
2778            if (pszEngineName == NULL || pszFileName == NULL)
2779                    return LSCP_FAILED;
2780    
2781            if (fVolume < 0.0f)
2782                    fVolume = 1.0f;
2783    
2784            _save_and_set_c_locale(&locale);
2785            sprintf(szQuery, "MAP MIDI_INSTRUMENT %d %d %d %s '%s' %d %g",
2786                    pMidiInstr->map, pMidiInstr->bank, pMidiInstr->prog,
2787                    pszEngineName, pszFileName, iInstrIndex, fVolume);
2788            _restore_locale(&locale);
2789    
2790            switch (load_mode) {
2791            case LSCP_LOAD_PERSISTENT:
2792                    strcat(szQuery, " PERSISTENT");
2793                    break;
2794            case LSCP_LOAD_ON_DEMAND_HOLD:
2795                    strcat(szQuery, " ON_DEMAND_HOLD");
2796                    break;
2797            case LSCP_LOAD_ON_DEMAND:
2798                    strcat(szQuery, " ON_DEMAND");
2799                    break;
2800            case LSCP_LOAD_DEFAULT:
2801            default:
2802                    break;
2803            }
2804    
2805            if (pszName)
2806                    sprintf(szQuery + strlen(szQuery), " '%s'", pszName);
2807    
2808            strcat(szQuery, "\r\n");
2809    
2810            return lscp_client_query(pClient, szQuery);
2811    }
2812    
2813    
2814    /**
2815     *  Remove an entry from the MIDI instrument map:
2816     *  UNMAP MIDI_INSTRUMENT <midi-map> <midi-bank> <midi-prog>
2817     *
2818     *  @param pClient      Pointer to client instance structure.
2819     *  @param pMidiInstr   MIDI instrument bank and program parameter key.
2820     *
2821     *  @returns LSCP_OK on success, LSCP_FAILED otherwise.
2822     */
2823    lscp_status_t lscp_unmap_midi_instrument ( lscp_client_t *pClient,
2824            lscp_midi_instrument_t *pMidiInstr )
2825    {
2826            char szQuery[LSCP_BUFSIZ];
2827    
2828            if (pMidiInstr->map < 0)
2829                    return LSCP_FAILED;
2830            if (pMidiInstr->bank < 0 || pMidiInstr->bank > 16383)
2831                    return LSCP_FAILED;
2832            if (pMidiInstr->prog < 0 || pMidiInstr->prog > 127)
2833                    return LSCP_FAILED;
2834    
2835            sprintf(szQuery, "UNMAP MIDI_INSTRUMENT %d %d %d\r\n",
2836                    pMidiInstr->map, pMidiInstr->bank, pMidiInstr->prog);
2837    
2838            return lscp_client_query(pClient, szQuery);
2839    }
2840    
2841    
2842    /**
2843     *  Get the total count of MIDI instrument map entries:
2844     *  GET MIDI_INSTRUMENTS ALL|<midi-map>
2845     *
2846     *  @param pClient  Pointer to client instance structure.
2847     *  @param iMidiMap MIDI instrument map number, or @ref LSCP_MIDI_MAP_ALL .
2848     *
2849     *  @returns The current total number of MIDI instrument map entries
2850     *  on success, -1 otherwise.
2851     */
2852    int lscp_get_midi_instruments ( lscp_client_t *pClient, int iMidiMap )
2853    {
2854            int iInstruments = -1;
2855            char szQuery[LSCP_BUFSIZ];
2856    
2857            if (pClient == NULL)
2858                    return -1;
2859    
2860            // Lock this section up.
2861            lscp_mutex_lock(pClient->mutex);
2862    
2863            strcpy(szQuery, "GET MIDI_INSTRUMENTS ");
2864    
2865            if (iMidiMap < 0)
2866                    strcat(szQuery, "ALL");
2867            else
2868                    sprintf(szQuery + strlen(szQuery), "%d", iMidiMap);
2869    
2870            strcat(szQuery, "\r\n");
2871    
2872            if (lscp_client_call(pClient, szQuery, 0) == LSCP_OK)
2873                    iInstruments = atoi(lscp_client_get_result(pClient));
2874    
2875            // Unlock this section down.
2876            lscp_mutex_unlock(pClient->mutex);
2877    
2878            return iInstruments;
2879    }
2880    
2881    
2882    /**
2883     *  Getting indeces of all MIDI instrument map entries:
2884     *  LIST MIDI_INSTRUMENTS ALL|<midi-map>
2885     *
2886     *  @param pClient  Pointer to client instance structure.
2887     *  @param iMidiMap MIDI instrument map number, or @ref LSCP_MIDI_MAP_ALL .
2888     *
2889     *  @returns An array of @ref lscp_midi_instrument_t, terminated with the
2890     *  {-1,-1,-1} triplet, NULL otherwise.
2891     */
2892    lscp_midi_instrument_t *lscp_list_midi_instruments ( lscp_client_t *pClient, int iMidiMap )
2893    {
2894            char szQuery[LSCP_BUFSIZ];
2895    
2896            if (pClient == NULL)
2897                    return NULL;
2898    
2899            // Lock this section up.
2900            lscp_mutex_lock(pClient->mutex);
2901    
2902            if (pClient->midi_instruments) {
2903                    lscp_midi_instruments_destroy(pClient->midi_instruments);
2904                    pClient->midi_instruments = NULL;
2905            }
2906    
2907            strcpy(szQuery, "LIST MIDI_INSTRUMENTS ");
2908    
2909            if (iMidiMap < 0)
2910                    strcat(szQuery, "ALL");
2911            else
2912                    sprintf(szQuery + strlen(szQuery), "%d", iMidiMap);
2913    
2914            strcat(szQuery, "\r\n");
2915    
2916            if (lscp_client_call(pClient, szQuery, 0) == LSCP_OK)
2917                    pClient->midi_instruments = lscp_midi_instruments_create(
2918                            lscp_client_get_result(pClient));
2919    
2920            // Unlock this section down.
2921            lscp_mutex_unlock(pClient->mutex);
2922    
2923            return pClient->midi_instruments;
2924    }
2925    
2926    
2927    /**
2928     *  Getting information about a MIDI instrument map entry:
2929     *  GET MIDI_INSTRUMENT INFO <midi-map> <midi-bank> <midi-prog>
2930     *
2931     *  @param pClient      Pointer to client instance structure.
2932     *  @param pMidiInstr   MIDI instrument bank and program parameter key.
2933     *
2934     *  @returns A pointer to a @ref lscp_midi_instrument_info_t structure,
2935     *  with all the information of the given MIDI instrument map entry,
2936     *  or NULL in case of failure.
2937     */
2938    lscp_midi_instrument_info_t *lscp_get_midi_instrument_info ( lscp_client_t *pClient,
2939            lscp_midi_instrument_t *pMidiInstr )
2940    {
2941            lscp_midi_instrument_info_t *pInstrInfo;
2942            char szQuery[LSCP_BUFSIZ];
2943            const char *pszResult;
2944            const char *pszSeps = ":";
2945            const char *pszCrlf = "\r\n";
2946            char *pszToken;
2947            char *pch;
2948            struct _locale_t locale;
2949    
2950            if (pClient == NULL)
2951                    return NULL;
2952            if (pMidiInstr->map < 0)
2953                    return NULL;
2954            if (pMidiInstr->bank < 0 || pMidiInstr->bank > 16383)
2955                    return NULL;
2956            if (pMidiInstr->prog < 0 || pMidiInstr->prog > 127)
2957                    return NULL;
2958    
2959            // Lock this section up.
2960            lscp_mutex_lock(pClient->mutex);
2961    
2962            _save_and_set_c_locale(&locale);
2963    
2964            pInstrInfo = &(pClient->midi_instrument_info);
2965            lscp_midi_instrument_info_reset(pInstrInfo);
2966    
2967            sprintf(szQuery, "GET MIDI_INSTRUMENT INFO %d %d %d\r\n",
2968                    pMidiInstr->map, pMidiInstr->bank, pMidiInstr->prog);
2969            if (lscp_client_call(pClient, szQuery, 1) == LSCP_OK) {
2970                    pszResult = lscp_client_get_result(pClient);
2971                    pszToken = lscp_strtok((char *) pszResult, pszSeps, &(pch));
2972                    while (pszToken) {
2973                            if (strcasecmp(pszToken, "NAME") == 0) {
2974                                    pszToken = lscp_strtok(NULL, pszCrlf, &(pch));
2975                                    if (pszToken)
2976                                            lscp_unquote_dup(&(pInstrInfo->name), &pszToken);
2977                            }
2978                            else if (strcasecmp(pszToken, "ENGINE_NAME") == 0) {
2979                                    pszToken = lscp_strtok(NULL, pszCrlf, &(pch));
2980                                    if (pszToken)
2981                                            lscp_unquote_dup(&(pInstrInfo->engine_name), &pszToken);
2982                            }
2983                            else if (strcasecmp(pszToken, "INSTRUMENT_FILE") == 0) {
2984                                    pszToken = lscp_strtok(NULL, pszCrlf, &(pch));
2985                                    if (pszToken)
2986                                            lscp_unquote_dup(&(pInstrInfo->instrument_file), &pszToken);
2987                            }
2988                            else if (strcasecmp(pszToken, "INSTRUMENT_NR") == 0) {
2989                                    pszToken = lscp_strtok(NULL, pszCrlf, &(pch));
2990                                    if (pszToken)
2991                                            pInstrInfo->instrument_nr = atoi(lscp_ltrim(pszToken));
2992                            }
2993                            else if (strcasecmp(pszToken, "INSTRUMENT_NAME") == 0) {
2994                                    pszToken = lscp_strtok(NULL, pszCrlf, &(pch));
2995                                    if (pszToken)
2996                                            lscp_unquote_dup(&(pInstrInfo->instrument_name), &pszToken);
2997                            }
2998                            else if (strcasecmp(pszToken, "LOAD_MODE") == 0) {
2999                                    pszToken = lscp_strtok(NULL, pszCrlf, &(pch));
3000                                    if (pszToken) {
3001                                            pszToken = lscp_ltrim(pszToken);
3002                                            if (strcasecmp(pszToken, "ON_DEMAND") == 0)
3003                                                    pInstrInfo->load_mode = LSCP_LOAD_ON_DEMAND;
3004                                            else
3005                                            if (strcasecmp(pszToken, "ON_DEMAND_HOLD") == 0)
3006                                                    pInstrInfo->load_mode = LSCP_LOAD_ON_DEMAND_HOLD;
3007                                            else
3008                                            if (strcasecmp(pszToken, "PERSISTENT") == 0)
3009                                                    pInstrInfo->load_mode = LSCP_LOAD_PERSISTENT;
3010                                            else
3011                                                    pInstrInfo->load_mode = LSCP_LOAD_DEFAULT;
3012                                    }
3013                            }
3014                            else if (strcasecmp(pszToken, "VOLUME") == 0) {
3015                                    pszToken = lscp_strtok(NULL, pszCrlf, &(pch));
3016                                    if (pszToken)
3017                                            pInstrInfo->volume = _atof(lscp_ltrim(pszToken));
3018                            }
3019                            pszToken = lscp_strtok(NULL, pszSeps, &(pch));
3020                    }
3021            }
3022            else pInstrInfo = NULL;
3023    
3024            _restore_locale(&locale);
3025    
3026            // Unlock this section down.
3027            lscp_mutex_unlock(pClient->mutex);
3028    
3029            return pInstrInfo;
3030    }
3031    
3032    
3033    /**
3034     *  Clear the MIDI instrumnet map:
3035     *  CLEAR MIDI_INSTRUMENTS ALL|<midi-map>
3036     *
3037     *  @param pClient  Pointer to client instance structure.
3038     *  @param iMidiMap MIDI instrument map number, or @ref LSCP_MIDI_MAP_ALL .
3039     *
3040     *  @returns LSCP_OK on success, LSCP_FAILED otherwise.
3041     */
3042    lscp_status_t lscp_clear_midi_instruments  ( lscp_client_t *pClient, int iMidiMap )
3043    {
3044            char szQuery[LSCP_BUFSIZ];
3045    
3046            strcpy(szQuery, "CLEAR MIDI_INSTRUMENTS ");
3047    
3048            if (iMidiMap < 0)
3049                    strcat(szQuery, "ALL");
3050            else
3051                    sprintf(szQuery + strlen(szQuery), "%d", iMidiMap);
3052    
3053            strcat(szQuery, "\r\n");
3054    
3055            return lscp_client_query(pClient, szQuery);
3056    }
3057    
3058    
3059    /**
3060     * Open an instrument editor application for the instrument
3061     * on the given sampler channel:
3062     * EDIT CHANNEL INSTRUMENT <sampler-channel>
3063     *
3064     * @param pClient         Pointer to client instance structure.
3065     * @param iSamplerChannel Sampler Channel.
3066     *
3067     * @returns LSCP_OK on success, LSCP_FAILED otherwise.
3068     */
3069    lscp_status_t lscp_edit_channel_instrument ( lscp_client_t *pClient, int iSamplerChannel )
3070    {
3071            char szQuery[LSCP_BUFSIZ];
3072    
3073            if (iSamplerChannel < 0)
3074                    return LSCP_FAILED;
3075    
3076      if (iSamplerChannel < 0)          sprintf(szQuery, "EDIT CHANNEL INSTRUMENT %d\r\n", iSamplerChannel);
         return LSCP_FAILED;  
3077    
3078      sprintf(szQuery, "RESET CHANNEL %d\r\n", iSamplerChannel);          return lscp_client_query(pClient, szQuery);
     return lscp_client_query(pClient, szQuery);  
3079  }  }
3080    
3081    

Legend:
Removed from v.132  
changed lines
  Added in v.2424

  ViewVC Help
Powered by ViewVC