/[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 952 by capela, Tue Nov 28 22:46:32 2006 UTC revision 1806 by schoenebeck, Thu Dec 11 01:28:42 2008 UTC
# Line 2  Line 2 
2  //  //
3  /****************************************************************************  /****************************************************************************
4     liblscp - LinuxSampler Control Protocol API     liblscp - LinuxSampler Control Protocol API
5     Copyright (C) 2004-2006, rncbc aka Rui Nuno Capela. All rights reserved.     Copyright (C) 2004-2008, 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 20  Line 20 
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).
# Line 35  static lscp_status_t    _lscp_client_evt Line 36  static lscp_status_t    _lscp_client_evt
36    
37    
38  //-------------------------------------------------------------------------  //-------------------------------------------------------------------------
39    // General helper functions.
40    
41    struct _locale_t {
42            char numeric[32];
43            char ctype[32];
44    };
45    
46    // we need to ensure a constant locale setting e.g. for parsing
47    // floating point numbers with atof(), as the floating point separator
48    // character varies by the invidual locale settings
49    static void _save_and_set_c_locale(struct _locale_t* locale)
50    {
51            strncpy(locale->numeric, setlocale(LC_NUMERIC, NULL), 32);
52            strncpy(locale->ctype, setlocale(LC_CTYPE, NULL), 32);
53            setlocale(LC_NUMERIC, "C");
54            setlocale(LC_CTYPE, "C");
55    }
56    
57    // restore the original locale setting as nothing happened
58    static void _restore_locale(struct _locale_t* locale)
59    {
60            setlocale(LC_NUMERIC, locale->numeric);
61            setlocale(LC_CTYPE, locale->ctype);
62    }
63    
64    // seems the standard atof() function doesnt care much about locale
65    // runtime modifications, so we use this workaround
66    static float _atof(const char* txt) {
67            float f;
68            sscanf(txt, "%f", &f); // yeah, you're a good boy sscanf()
69            return f;
70    }
71    
72    
73    //-------------------------------------------------------------------------
74  // Event service (datagram oriented).  // Event service (datagram oriented).
75    
76  static void _lscp_client_evt_proc ( void *pvClient )  static void _lscp_client_evt_proc ( void *pvClient )
# Line 84  static void _lscp_client_evt_proc ( void Line 120  static void _lscp_client_evt_proc ( void
120                          if (cchBuffer > 0) {                          if (cchBuffer > 0) {
121                                  // Make sure received buffer it's null terminated.                                  // Make sure received buffer it's null terminated.
122                                  achBuffer[cchBuffer] = (char) 0;                                  achBuffer[cchBuffer] = (char) 0;
123                                  // Parse for the notification event message...                                  pch = achBuffer;
124                                  pszToken = lscp_strtok(achBuffer, pszSeps, &(pch)); // Have "NOTIFY".                                  do {
125                                  if (strcasecmp(pszToken, "NOTIFY") == 0) {                                          // Parse for the notification event message...
126                                          pszToken = lscp_strtok(NULL, pszSeps, &(pch));                                          pszToken = lscp_strtok(NULL, pszSeps, &(pch)); // Have "NOTIFY"
127                                          event    = lscp_event_from_text(pszToken);                                          if (strcasecmp(pszToken, "NOTIFY") == 0) {
128                                          // And pick the rest of data...                                                  pszToken = lscp_strtok(NULL, pszSeps, &(pch));
129                                          pszToken = lscp_strtok(NULL, pszSeps, &(pch));                                                  event    = lscp_event_from_text(pszToken);
130                                          cchToken = (pszToken == NULL ? 0 : strlen(pszToken));                                                  // And pick the rest of data...
131                                          // Double-check if we're really up to it...                                                  pszToken = lscp_strtok(NULL, pszSeps, &(pch));
132                                          if (pClient->events & event) {                                                  cchToken = (pszToken == NULL ? 0 : strlen(pszToken));
133                                                  // Invoke the client event callback...                                                  // Double-check if we're really up to it...
134                                                  if ((*pClient->pfnCallback)(                                                  if (pClient->events & event) {
135                                                                  pClient,                                                          // Invoke the client event callback...
136                                                                  event,                                                          if ((*pClient->pfnCallback)(
137                                                                  pszToken,                                                                          pClient,
138                                                                  cchToken,                                                                          event,
139                                                                  pClient->pvData) != LSCP_OK) {                                                                          pszToken,
140                                                          pClient->evt.iState = 0;                                                                          cchToken,
141                                                                            pClient->pvData) != LSCP_OK) {
142                                                                    pClient->evt.iState = 0;
143                                                            }
144                                                  }                                                  }
145                                          }                                          }
146                                  }                                  } while (*pch);
147                          } else {                          } else {
148                                  lscp_socket_perror("_lscp_client_evt_proc: recv");                                  lscp_socket_perror("_lscp_client_evt_proc: recv");
149                                  pClient->evt.iState = 0;                                  pClient->evt.iState = 0;
# Line 327  lscp_client_t* lscp_client_create ( cons Line 366  lscp_client_t* lscp_client_create ( cons
366          pClient->midi_devices = NULL;          pClient->midi_devices = NULL;
367          pClient->engines = NULL;          pClient->engines = NULL;
368          pClient->channels = NULL;          pClient->channels = NULL;
369            pClient->fxsends = NULL;
370          pClient->midi_instruments = NULL;          pClient->midi_instruments = NULL;
371            pClient->midi_maps = NULL;
372            pClient->midi_map_name = NULL;
373          lscp_driver_info_init(&(pClient->audio_driver_info));          lscp_driver_info_init(&(pClient->audio_driver_info));
374          lscp_driver_info_init(&(pClient->midi_driver_info));          lscp_driver_info_init(&(pClient->midi_driver_info));
375          lscp_device_info_init(&(pClient->audio_device_info));          lscp_device_info_init(&(pClient->audio_device_info));
# Line 341  lscp_client_t* lscp_client_create ( cons Line 383  lscp_client_t* lscp_client_create ( cons
383          lscp_server_info_init(&(pClient->server_info));          lscp_server_info_init(&(pClient->server_info));
384          lscp_engine_info_init(&(pClient->engine_info));          lscp_engine_info_init(&(pClient->engine_info));
385          lscp_channel_info_init(&(pClient->channel_info));          lscp_channel_info_init(&(pClient->channel_info));
386            lscp_fxsend_info_init(&(pClient->fxsend_info));
387          lscp_midi_instrument_info_init(&(pClient->midi_instrument_info));          lscp_midi_instrument_info_init(&(pClient->midi_instrument_info));
388          // Initialize error stuff.          // Initialize error stuff.
389          pClient->pszResult = NULL;          pClient->pszResult = NULL;
# Line 403  lscp_status_t lscp_client_destroy ( lscp Line 446  lscp_status_t lscp_client_destroy ( lscp
446    
447          // Free up all cached members.          // Free up all cached members.
448          lscp_midi_instrument_info_free(&(pClient->midi_instrument_info));          lscp_midi_instrument_info_free(&(pClient->midi_instrument_info));
449            lscp_fxsend_info_free(&(pClient->fxsend_info));
450          lscp_channel_info_free(&(pClient->channel_info));          lscp_channel_info_free(&(pClient->channel_info));
451          lscp_engine_info_free(&(pClient->engine_info));          lscp_engine_info_free(&(pClient->engine_info));
452          lscp_server_info_free(&(pClient->server_info));          lscp_server_info_free(&(pClient->server_info));
# Line 423  lscp_status_t lscp_client_destroy ( lscp Line 467  lscp_status_t lscp_client_destroy ( lscp
467          lscp_isplit_destroy(pClient->midi_devices);          lscp_isplit_destroy(pClient->midi_devices);
468          lscp_szsplit_destroy(pClient->engines);          lscp_szsplit_destroy(pClient->engines);
469          lscp_isplit_destroy(pClient->channels);          lscp_isplit_destroy(pClient->channels);
470            lscp_isplit_destroy(pClient->fxsends);
471          lscp_midi_instruments_destroy(pClient->midi_instruments);          lscp_midi_instruments_destroy(pClient->midi_instruments);
472            lscp_isplit_destroy(pClient->midi_maps);
473            if (pClient->midi_map_name)
474                    free(pClient->midi_map_name);
475          // Make them null.          // Make them null.
476          pClient->audio_drivers = NULL;          pClient->audio_drivers = NULL;
477          pClient->midi_drivers = NULL;          pClient->midi_drivers = NULL;
# Line 431  lscp_status_t lscp_client_destroy ( lscp Line 479  lscp_status_t lscp_client_destroy ( lscp
479          pClient->midi_devices = NULL;          pClient->midi_devices = NULL;
480          pClient->engines = NULL;          pClient->engines = NULL;
481          pClient->channels = NULL;          pClient->channels = NULL;
482            pClient->fxsends = NULL;
483          pClient->midi_instruments = NULL;          pClient->midi_instruments = NULL;
484            pClient->midi_maps = NULL;
485            pClient->midi_map_name = NULL;
486          // Free result error stuff.          // Free result error stuff.
487          lscp_client_set_result(pClient, NULL, 0);          lscp_client_set_result(pClient, NULL, 0);
488          // Free stream usage stuff.          // Free stream usage stuff.
# Line 512  lscp_status_t lscp_client_query ( lscp_c Line 563  lscp_status_t lscp_client_query ( lscp_c
563  {  {
564          lscp_status_t ret;          lscp_status_t ret;
565    
566            if (pClient == NULL)
567                    return LSCP_FAILED;
568    
569          // Lock this section up.          // Lock this section up.
570          lscp_mutex_lock(pClient->mutex);          lscp_mutex_lock(pClient->mutex);
571    
# Line 563  int lscp_client_get_errno ( lscp_client_ Line 617  int lscp_client_get_errno ( lscp_client_
617  // Client registration protocol functions.  // Client registration protocol functions.
618    
619  /**  /**
620   *  Register frontend for receiving event messages:   *  Register frontend for receiving event messages by the sampler backend.
621   *  SUBSCRIBE CHANNEL_COUNT | VOICE_COUNT | STREAM_COUNT | BUFFER_FILL   *  @e Caution: since liblscp v0.5.5.4 you have to call lscp_client_subscribe()
622   *      | CHANNEL_INFO | MISCELLANEOUS   *  for @e each event you want to subscribe. That is the old bitflag approach
623     *  was abondoned at this point. You can however still register all older
624     *  events with one lscp_client_subscribe() call at once. Thus, the old
625     *  behavior of this functions was not broken. Those older events are namely:
626     *  @code
627     *  SUBSCRIBE CHANNEL_COUNT | VOICE_COUNT | STREAM_COUNT
628     *      | BUFFER_FILL | CHANNEL_INFO | TOTAL_VOICE_COUNT
629     *      | AUDIO_OUTPUT_DEVICE_COUNT | AUDIO_OUTPUT_DEVICE_INFO
630     *      | MIDI_INPUT_DEVICE_COUNT | MIDI_INPUT_DEVICE_INFO
631     *      | MIDI_INSTRUMENT_MAP_COUNT | MIDI_INSTRUMENT_MAP_INFO
632     *      | MIDI_INSTRUMENT_COUNT | MIDI_INSTRUMENT_INFO
633     *      | MISCELLANEOUS
634     *  @endcode
635     *  The old events occupy the lower 16 bits (as bit flags), and all younger
636     *  events enumerate the whole upper 16 bits range. The new, enumerated
637     *  events are namely:
638     *  @code
639     *  SUBSCRIBE CHANNEL_MIDI
640     *  @endcode
641   *   *
642   *  @param pClient  Pointer to client instance structure.   *  @param pClient  Pointer to client instance structure.
643   *  @param events   Bit-wise OR'ed event flags to subscribe.   *  @param events   LSCP event to subscribe.
644   *   *
645   *  @returns LSCP_OK on success, LSCP_FAILED otherwise.   *  @returns LSCP_OK on success, LSCP_FAILED otherwise.
646   */   */
647  lscp_status_t lscp_client_subscribe ( lscp_client_t *pClient, lscp_event_t events )  lscp_status_t lscp_client_subscribe ( lscp_client_t *pClient, lscp_event_t events )
648  {  {
649          lscp_status_t ret = LSCP_FAILED;          lscp_status_t ret = LSCP_OK;
650            lscp_event_t currentEvent;
651    
652          if (pClient == NULL)          if (pClient == NULL)
653                  return LSCP_FAILED;                  return LSCP_FAILED;
# Line 597  lscp_status_t lscp_client_subscribe ( ls Line 670  lscp_status_t lscp_client_subscribe ( ls
670                  ret = _lscp_client_evt_request(pClient, 1, LSCP_EVENT_BUFFER_FILL);                  ret = _lscp_client_evt_request(pClient, 1, LSCP_EVENT_BUFFER_FILL);
671          if (ret == LSCP_OK && (events & LSCP_EVENT_CHANNEL_INFO))          if (ret == LSCP_OK && (events & LSCP_EVENT_CHANNEL_INFO))
672                  ret = _lscp_client_evt_request(pClient, 1, LSCP_EVENT_CHANNEL_INFO);                  ret = _lscp_client_evt_request(pClient, 1, LSCP_EVENT_CHANNEL_INFO);
673            if (ret == LSCP_OK && (events & LSCP_EVENT_TOTAL_VOICE_COUNT))
674                    ret = _lscp_client_evt_request(pClient, 1, LSCP_EVENT_TOTAL_VOICE_COUNT);
675            if (ret == LSCP_OK && (events & LSCP_EVENT_AUDIO_OUTPUT_DEVICE_COUNT))
676                    ret = _lscp_client_evt_request(pClient, 1, LSCP_EVENT_AUDIO_OUTPUT_DEVICE_COUNT);
677            if (ret == LSCP_OK && (events & LSCP_EVENT_AUDIO_OUTPUT_DEVICE_INFO))
678                    ret = _lscp_client_evt_request(pClient, 1, LSCP_EVENT_AUDIO_OUTPUT_DEVICE_INFO);
679            if (ret == LSCP_OK && (events & LSCP_EVENT_MIDI_INPUT_DEVICE_COUNT))
680                    ret = _lscp_client_evt_request(pClient, 1, LSCP_EVENT_MIDI_INPUT_DEVICE_COUNT);
681            if (ret == LSCP_OK && (events & LSCP_EVENT_MIDI_INPUT_DEVICE_INFO))
682                    ret = _lscp_client_evt_request(pClient, 1, LSCP_EVENT_MIDI_INPUT_DEVICE_INFO);
683            if (ret == LSCP_OK && (events & LSCP_EVENT_MIDI_INSTRUMENT_MAP_COUNT))
684                    ret = _lscp_client_evt_request(pClient, 1, LSCP_EVENT_MIDI_INSTRUMENT_MAP_COUNT);
685            if (ret == LSCP_OK && (events & LSCP_EVENT_MIDI_INSTRUMENT_MAP_INFO))
686                    ret = _lscp_client_evt_request(pClient, 1, LSCP_EVENT_MIDI_INSTRUMENT_MAP_INFO);
687            if (ret == LSCP_OK && (events & LSCP_EVENT_MIDI_INSTRUMENT_COUNT))
688                    ret = _lscp_client_evt_request(pClient, 1, LSCP_EVENT_MIDI_INSTRUMENT_COUNT);
689            if (ret == LSCP_OK && (events & LSCP_EVENT_MIDI_INSTRUMENT_INFO))
690                    ret = _lscp_client_evt_request(pClient, 1, LSCP_EVENT_MIDI_INSTRUMENT_INFO);
691          if (ret == LSCP_OK && (events & LSCP_EVENT_MISCELLANEOUS))          if (ret == LSCP_OK && (events & LSCP_EVENT_MISCELLANEOUS))
692                  ret = _lscp_client_evt_request(pClient, 1, LSCP_EVENT_MISCELLANEOUS);                  ret = _lscp_client_evt_request(pClient, 1, LSCP_EVENT_MISCELLANEOUS);
693            // Caution: for the upper 16 bits, we don't use bit flags anymore ...
694            currentEvent = events & 0xffff0000;
695            if (ret == LSCP_OK && currentEvent) {
696                    switch (currentEvent) {
697                            case LSCP_EVENT_CHANNEL_MIDI:
698                            case LSCP_EVENT_DEVICE_MIDI:
699                                    ret = _lscp_client_evt_request(pClient, 1, currentEvent);
700                                    break;
701                            default: // unknown "upper" event type
702                                    ret = LSCP_FAILED;
703                                    break;
704                    }
705            }
706    
707          // Unlock this section down.          // Unlock this section down.
708          lscp_mutex_unlock(pClient->mutex);          lscp_mutex_unlock(pClient->mutex);
# Line 608  lscp_status_t lscp_client_subscribe ( ls Line 712  lscp_status_t lscp_client_subscribe ( ls
712    
713    
714  /**  /**
715   *  Deregister frontend from receiving UDP event messages anymore:   *  Deregister frontend from receiving UDP event messages anymore.
716   *  SUBSCRIBE CHANNEL_COUNT | VOICE_COUNT | STREAM_COUNT | BUFFER_FILL   *  @e Caution: since liblscp v0.5.5.4 you have to call
717   *      | CHANNEL_INFO | MISCELLANEOUS   *  lscp_client_unsubscribe() for @e each event you want to unsubscribe.
718     *  That is the old bitflag approach was abondoned at this point. You can
719     *  however still register all older events with one lscp_client_subscribe()
720     *  call at once. Thus, the old behavior of this functions was not broken.
721     *  Those older events are namely:
722     *  @code
723     *  UNSUBSCRIBE 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     *  UNSUBSCRIBE CHANNEL_MIDI
736     *  @endcode
737   *   *
738   *  @param pClient  Pointer to client instance structure.   *  @param pClient  Pointer to client instance structure.
739   *  @param events   Bit-wise OR'ed event flags to unsubscribe.   *  @param events   LSCP event to unsubscribe.
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_unsubscribe ( lscp_client_t *pClient, lscp_event_t events )  lscp_status_t lscp_client_unsubscribe ( lscp_client_t *pClient, lscp_event_t events )
744  {  {
745          lscp_status_t ret = LSCP_OK;          lscp_status_t ret = LSCP_OK;
746            lscp_event_t currentEvent;
747    
748          if (pClient == NULL)          if (pClient == NULL)
749                  return LSCP_FAILED;                  return LSCP_FAILED;
# Line 638  lscp_status_t lscp_client_unsubscribe ( Line 762  lscp_status_t lscp_client_unsubscribe (
762                  ret = _lscp_client_evt_request(pClient, 0, LSCP_EVENT_BUFFER_FILL);                  ret = _lscp_client_evt_request(pClient, 0, LSCP_EVENT_BUFFER_FILL);
763          if (ret == LSCP_OK && (events & LSCP_EVENT_CHANNEL_INFO))          if (ret == LSCP_OK && (events & LSCP_EVENT_CHANNEL_INFO))
764                  ret = _lscp_client_evt_request(pClient, 0, LSCP_EVENT_CHANNEL_INFO);                  ret = _lscp_client_evt_request(pClient, 0, LSCP_EVENT_CHANNEL_INFO);
765            if (ret == LSCP_OK && (events & LSCP_EVENT_TOTAL_VOICE_COUNT))
766                    ret = _lscp_client_evt_request(pClient, 0, LSCP_EVENT_TOTAL_VOICE_COUNT);
767            if (ret == LSCP_OK && (events & LSCP_EVENT_AUDIO_OUTPUT_DEVICE_COUNT))
768                    ret = _lscp_client_evt_request(pClient, 0, LSCP_EVENT_AUDIO_OUTPUT_DEVICE_COUNT);
769            if (ret == LSCP_OK && (events & LSCP_EVENT_AUDIO_OUTPUT_DEVICE_INFO))
770                    ret = _lscp_client_evt_request(pClient, 0, LSCP_EVENT_AUDIO_OUTPUT_DEVICE_INFO);
771            if (ret == LSCP_OK && (events & LSCP_EVENT_MIDI_INPUT_DEVICE_COUNT))
772                    ret = _lscp_client_evt_request(pClient, 0, LSCP_EVENT_MIDI_INPUT_DEVICE_COUNT);
773            if (ret == LSCP_OK && (events & LSCP_EVENT_MIDI_INPUT_DEVICE_INFO))
774                    ret = _lscp_client_evt_request(pClient, 0, LSCP_EVENT_MIDI_INPUT_DEVICE_INFO);
775            if (ret == LSCP_OK && (events & LSCP_EVENT_MIDI_INSTRUMENT_MAP_COUNT))
776                    ret = _lscp_client_evt_request(pClient, 0, LSCP_EVENT_MIDI_INSTRUMENT_MAP_COUNT);
777            if (ret == LSCP_OK && (events & LSCP_EVENT_MIDI_INSTRUMENT_MAP_INFO))
778                    ret = _lscp_client_evt_request(pClient, 0, LSCP_EVENT_MIDI_INSTRUMENT_MAP_INFO);
779            if (ret == LSCP_OK && (events & LSCP_EVENT_MIDI_INSTRUMENT_COUNT))
780                    ret = _lscp_client_evt_request(pClient, 0, LSCP_EVENT_MIDI_INSTRUMENT_COUNT);
781            if (ret == LSCP_OK && (events & LSCP_EVENT_MIDI_INSTRUMENT_INFO))
782                    ret = _lscp_client_evt_request(pClient, 0, LSCP_EVENT_MIDI_INSTRUMENT_INFO);
783          if (ret == LSCP_OK && (events & LSCP_EVENT_MISCELLANEOUS))          if (ret == LSCP_OK && (events & LSCP_EVENT_MISCELLANEOUS))
784                  ret = _lscp_client_evt_request(pClient, 0, LSCP_EVENT_MISCELLANEOUS);                  ret = _lscp_client_evt_request(pClient, 0, LSCP_EVENT_MISCELLANEOUS);
785            // Caution: for the upper 16 bits, we don't use bit flags anymore ...
786            currentEvent = events & 0xffff0000;
787            if (ret == LSCP_OK && currentEvent) {
788                    switch (currentEvent) {
789                            case LSCP_EVENT_CHANNEL_MIDI:
790                            case LSCP_EVENT_DEVICE_MIDI:
791                                    ret = _lscp_client_evt_request(pClient, 0, currentEvent);
792                                    break;
793                            default: // unknown "upper" event type
794                                    ret = LSCP_FAILED;
795                                    break;
796                    }
797            }
798    
799          // If necessary, close the alternate connection...          // If necessary, close the alternate connection...
800          if (pClient->events == LSCP_EVENT_NONE)          if (pClient->events == LSCP_EVENT_NONE)
# Line 752  int lscp_get_channels ( lscp_client_t *p Line 907  int lscp_get_channels ( lscp_client_t *p
907  {  {
908          int iChannels = -1;          int iChannels = -1;
909    
910            if (pClient == NULL)
911                    return -1;
912    
913          // Lock this section up.          // Lock this section up.
914          lscp_mutex_lock(pClient->mutex);          lscp_mutex_lock(pClient->mutex);
915    
# Line 812  int lscp_add_channel ( lscp_client_t *pC Line 970  int lscp_add_channel ( lscp_client_t *pC
970  {  {
971          int iSamplerChannel = -1;          int iSamplerChannel = -1;
972    
973            if (pClient == NULL)
974                    return -1;
975    
976          // Lock this section up.          // Lock this section up.
977          lscp_mutex_lock(pClient->mutex);          lscp_mutex_lock(pClient->mutex);
978    
# Line 859  int lscp_get_available_engines ( lscp_cl Line 1020  int lscp_get_available_engines ( lscp_cl
1020  {  {
1021          int iAvailableEngines = -1;          int iAvailableEngines = -1;
1022    
1023            if (pClient == NULL)
1024                    return -1;
1025    
1026          // Lock this section up.          // Lock this section up.
1027          lscp_mutex_lock(pClient->mutex);          lscp_mutex_lock(pClient->mutex);
1028    
# Line 885  const char **lscp_list_available_engines Line 1049  const char **lscp_list_available_engines
1049  {  {
1050          const char *pszSeps = ",";          const char *pszSeps = ",";
1051    
1052            if (pClient == NULL)
1053                    return NULL;
1054    
1055          // Lock this section up.          // Lock this section up.
1056          lscp_mutex_lock(pClient->mutex);          lscp_mutex_lock(pClient->mutex);
1057    
# Line 923  lscp_engine_info_t *lscp_get_engine_info Line 1090  lscp_engine_info_t *lscp_get_engine_info
1090          char *pszToken;          char *pszToken;
1091          char *pch;          char *pch;
1092    
1093            if (pClient == NULL)
1094                    return NULL;
1095          if (pszEngineName == NULL)          if (pszEngineName == NULL)
1096                  return NULL;                  return NULL;
1097    
# Line 978  lscp_channel_info_t *lscp_get_channel_in Line 1147  lscp_channel_info_t *lscp_get_channel_in
1147          const char *pszCrlf = "\r\n";          const char *pszCrlf = "\r\n";
1148          char *pszToken;          char *pszToken;
1149          char *pch;          char *pch;
1150            struct _locale_t locale;
1151    
1152            if (pClient == NULL)
1153                    return NULL;
1154          if (iSamplerChannel < 0)          if (iSamplerChannel < 0)
1155                  return NULL;                  return NULL;
1156    
# Line 988  lscp_channel_info_t *lscp_get_channel_in Line 1160  lscp_channel_info_t *lscp_get_channel_in
1160          pChannelInfo = &(pClient->channel_info);          pChannelInfo = &(pClient->channel_info);
1161          lscp_channel_info_reset(pChannelInfo);          lscp_channel_info_reset(pChannelInfo);
1162    
1163            _save_and_set_c_locale(&locale);
1164    
1165          sprintf(szQuery, "GET CHANNEL INFO %d\r\n", iSamplerChannel);          sprintf(szQuery, "GET CHANNEL INFO %d\r\n", iSamplerChannel);
1166          if (lscp_client_call(pClient, szQuery, 1) == LSCP_OK) {          if (lscp_client_call(pClient, szQuery, 1) == LSCP_OK) {
1167                  pszResult = lscp_client_get_result(pClient);                  pszResult = lscp_client_get_result(pClient);
# Line 1012  lscp_channel_info_t *lscp_get_channel_in Line 1186  lscp_channel_info_t *lscp_get_channel_in
1186                                  pszToken = lscp_strtok(NULL, pszCrlf, &(pch));                                  pszToken = lscp_strtok(NULL, pszCrlf, &(pch));
1187                                  if (pszToken) {                                  if (pszToken) {
1188                                          if (pChannelInfo->audio_routing)                                          if (pChannelInfo->audio_routing)
1189                                                  lscp_szsplit_destroy(pChannelInfo->audio_routing);                                                  lscp_isplit_destroy(pChannelInfo->audio_routing);
1190                                          pChannelInfo->audio_routing = lscp_szsplit_create(pszToken, ",");                                          pChannelInfo->audio_routing = lscp_isplit_create(pszToken, ",");
1191                                  }                                  }
1192                          }                          }
1193                          else if (strcasecmp(pszToken, "INSTRUMENT_FILE") == 0) {                          else if (strcasecmp(pszToken, "INSTRUMENT_FILE") == 0) {
# Line 1056  lscp_channel_info_t *lscp_get_channel_in Line 1230  lscp_channel_info_t *lscp_get_channel_in
1230                                                  pChannelInfo->midi_channel = atoi(pszToken);                                                  pChannelInfo->midi_channel = atoi(pszToken);
1231                                  }                                  }
1232                          }                          }
1233                            else if (strcasecmp(pszToken, "MIDI_INSTRUMENT_MAP") == 0) {
1234                                    pszToken = lscp_strtok(NULL, pszCrlf, &(pch));
1235                                    if (pszToken) {
1236                                            pszToken = lscp_ltrim(pszToken);
1237                                            if (strcasecmp(pszToken, "NONE") == 0)
1238                                                    pChannelInfo->midi_map = LSCP_MIDI_MAP_NONE;
1239                                            else
1240                                            if (strcasecmp(pszToken, "DEFAULT") == 0)
1241                                                    pChannelInfo->midi_map = LSCP_MIDI_MAP_DEFAULT;
1242                                            else
1243                                                    pChannelInfo->midi_map = atoi(pszToken);
1244                                    }
1245                            }
1246                          else if (strcasecmp(pszToken, "VOLUME") == 0) {                          else if (strcasecmp(pszToken, "VOLUME") == 0) {
1247                                  pszToken = lscp_strtok(NULL, pszCrlf, &(pch));                                  pszToken = lscp_strtok(NULL, pszCrlf, &(pch));
1248                                  if (pszToken)                                  if (pszToken)
1249                                          pChannelInfo->volume = (float) atof(lscp_ltrim(pszToken));                                          pChannelInfo->volume = _atof(lscp_ltrim(pszToken));
1250                          }                          }
1251                          else if (strcasecmp(pszToken, "MUTE") == 0) {                          else if (strcasecmp(pszToken, "MUTE") == 0) {
1252                                  pszToken = lscp_strtok(NULL, pszCrlf, &(pch));                                  pszToken = lscp_strtok(NULL, pszCrlf, &(pch));
# Line 1076  lscp_channel_info_t *lscp_get_channel_in Line 1263  lscp_channel_info_t *lscp_get_channel_in
1263          }          }
1264          else pChannelInfo = NULL;          else pChannelInfo = NULL;
1265    
1266            _restore_locale(&locale);
1267    
1268          // Unlock this section up.          // Unlock this section up.
1269          lscp_mutex_unlock(pClient->mutex);          lscp_mutex_unlock(pClient->mutex);
1270    
# Line 1097  int lscp_get_channel_voice_count ( lscp_ Line 1286  int lscp_get_channel_voice_count ( lscp_
1286          char szQuery[LSCP_BUFSIZ];          char szQuery[LSCP_BUFSIZ];
1287          int iVoiceCount = -1;          int iVoiceCount = -1;
1288    
1289            if (pClient == NULL)
1290                    return -1;
1291          if (iSamplerChannel < 0)          if (iSamplerChannel < 0)
1292                  return iVoiceCount;                  return -1;
1293    
1294          // Lock this section up.          // Lock this section up.
1295          lscp_mutex_lock(pClient->mutex);          lscp_mutex_lock(pClient->mutex);
# Line 1128  int lscp_get_channel_stream_count ( lscp Line 1319  int lscp_get_channel_stream_count ( lscp
1319          char szQuery[LSCP_BUFSIZ];          char szQuery[LSCP_BUFSIZ];
1320          int iStreamCount = -1;          int iStreamCount = -1;
1321    
1322            if (pClient == NULL)
1323                    return -1;
1324          if (iSamplerChannel < 0)          if (iSamplerChannel < 0)
1325                  return iStreamCount;                  return -1;
1326    
1327          // Lock this section up.          // Lock this section up.
1328          lscp_mutex_lock(pClient->mutex);          lscp_mutex_lock(pClient->mutex);
# Line 1165  int lscp_get_channel_stream_usage ( lscp Line 1358  int lscp_get_channel_stream_usage ( lscp
1358          int   iStream;          int   iStream;
1359          int   iPercent;          int   iPercent;
1360    
1361            if (pClient == NULL)
1362                    return -1;
1363          if (iSamplerChannel < 0)          if (iSamplerChannel < 0)
1364                  return iStreamUsage;                  return -1;
1365    
1366          // Lock this section up.          // Lock this section up.
1367          lscp_mutex_lock(pClient->mutex);          lscp_mutex_lock(pClient->mutex);
# Line 1227  lscp_buffer_fill_t *lscp_get_channel_buf Line 1422  lscp_buffer_fill_t *lscp_get_channel_buf
1422    
1423          // Retrieve a channel stream estimation.          // Retrieve a channel stream estimation.
1424          iStreamCount = lscp_get_channel_stream_count(pClient, iSamplerChannel);          iStreamCount = lscp_get_channel_stream_count(pClient, iSamplerChannel);
1425          if (pClient->iStreamCount < 0)          if (iStreamCount < 0)
1426                  return NULL;                  return NULL;
1427    
1428          // Lock this section up.          // Lock this section up.
# Line 1416  lscp_status_t lscp_set_channel_midi_port Line 1611  lscp_status_t lscp_set_channel_midi_port
1611   *  @param pClient          Pointer to client instance structure.   *  @param pClient          Pointer to client instance structure.
1612   *  @param iSamplerChannel  Sampler channel number.   *  @param iSamplerChannel  Sampler channel number.
1613   *  @param iMidiChannel     MIDI channel address number to listen (0-15) or   *  @param iMidiChannel     MIDI channel address number to listen (0-15) or
1614   *                          LSCP_MIDI_CHANNEL_ALL (16) to listen on all channels.   *                          @ref LSCP_MIDI_CHANNEL_ALL (16) to listen on all channels.
1615   *   *
1616   *  @returns LSCP_OK on success, LSCP_FAILED otherwise.   *  @returns LSCP_OK on success, LSCP_FAILED otherwise.
1617   */   */
# Line 1436  lscp_status_t lscp_set_channel_midi_chan Line 1631  lscp_status_t lscp_set_channel_midi_chan
1631    
1632    
1633  /**  /**
1634     *  Setting MIDI instrument map:
1635     *  SET CHANNEL MIDI_INSTRUMENT_MAP <sampler-channel> <midi-map>
1636     *
1637     *  @param pClient          Pointer to client instance structure.
1638     *  @param iSamplerChannel  Sampler channel number.
1639     *  @param iMidiMap         MIDI instrument map number, or either
1640     *                          @ref LSCP_MIDI_MAP_NONE or
1641     *                          @ref LSCP_MIDI_MAP_DEFAULT .
1642     *
1643     *  @returns LSCP_OK on success, LSCP_FAILED otherwise.
1644     */
1645    lscp_status_t lscp_set_channel_midi_map ( lscp_client_t *pClient, int iSamplerChannel, int iMidiMap )
1646    {
1647            char szQuery[LSCP_BUFSIZ];
1648    
1649            if (iSamplerChannel < 0)
1650                    return LSCP_FAILED;
1651    
1652            sprintf(szQuery, "SET CHANNEL MIDI_INSTRUMENT_MAP %d ", iSamplerChannel);
1653            if (iMidiMap == LSCP_MIDI_MAP_NONE)
1654                    strcat(szQuery , "NONE");
1655            else
1656            if (iMidiMap == LSCP_MIDI_MAP_DEFAULT)
1657                    strcat(szQuery , "DEFAULT");
1658            else
1659                    sprintf(szQuery + strlen(szQuery), "%d", iMidiMap);
1660    
1661            strcat(szQuery, "\r\n");
1662    
1663            return lscp_client_query(pClient, szQuery);
1664    }
1665    
1666    
1667    /**
1668   *  Setting channel volume:   *  Setting channel volume:
1669   *  SET CHANNEL VOLUME <sampler-channel> <volume>   *  SET CHANNEL VOLUME <sampler-channel> <volume>
1670   *   *
# Line 1450  lscp_status_t lscp_set_channel_midi_chan Line 1679  lscp_status_t lscp_set_channel_midi_chan
1679  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, int iSamplerChannel, float fVolume )
1680  {  {
1681          char szQuery[LSCP_BUFSIZ];          char szQuery[LSCP_BUFSIZ];
1682            struct _locale_t locale;
1683    
1684          if (iSamplerChannel < 0 || fVolume < 0.0)          if (iSamplerChannel < 0 || fVolume < 0.0f)
1685                  return LSCP_FAILED;                  return LSCP_FAILED;
1686    
1687            _save_and_set_c_locale(&locale);
1688          sprintf(szQuery, "SET CHANNEL VOLUME %d %g\r\n", iSamplerChannel, fVolume);          sprintf(szQuery, "SET CHANNEL VOLUME %d %g\r\n", iSamplerChannel, fVolume);
1689            _restore_locale(&locale);
1690    
1691          return lscp_client_query(pClient, szQuery);          return lscp_client_query(pClient, szQuery);
1692  }  }
1693    
# Line 1538  lscp_status_t lscp_reset_channel ( lscp_ Line 1771  lscp_status_t lscp_reset_channel ( lscp_
1771   */   */
1772  lscp_status_t lscp_reset_sampler ( lscp_client_t *pClient )  lscp_status_t lscp_reset_sampler ( lscp_client_t *pClient )
1773  {  {
1774            // Do actual whole sampler reset...
1775          return lscp_client_query(pClient, "RESET\r\n");          return lscp_client_query(pClient, "RESET\r\n");
1776  }  }
1777    
# Line 1560  lscp_server_info_t *lscp_get_server_info Line 1794  lscp_server_info_t *lscp_get_server_info
1794          char *pszToken;          char *pszToken;
1795          char *pch;          char *pch;
1796    
1797            if (pClient == NULL)
1798                    return NULL;
1799    
1800          // Lock this section up.          // Lock this section up.
1801          lscp_mutex_lock(pClient->mutex);          lscp_mutex_lock(pClient->mutex);
1802    
# Line 1580  lscp_server_info_t *lscp_get_server_info Line 1817  lscp_server_info_t *lscp_get_server_info
1817                                  if (pszToken)                                  if (pszToken)
1818                                          lscp_unquote_dup(&(pServerInfo->version), &pszToken);                                          lscp_unquote_dup(&(pServerInfo->version), &pszToken);
1819                          }                          }
1820                            else if (strcasecmp(pszToken, "PROTOCOL_VERSION") == 0) {
1821                                    pszToken = lscp_strtok(NULL, pszCrlf, &(pch));
1822                                    if (pszToken)
1823                                            lscp_unquote_dup(&(pServerInfo->protocol_version), &pszToken);
1824                            }
1825                          pszToken = lscp_strtok(NULL, pszSeps, &(pch));                          pszToken = lscp_strtok(NULL, pszSeps, &(pch));
1826                  }                  }
1827          }          }
# Line 1605  int lscp_get_total_voice_count ( lscp_cl Line 1847  int lscp_get_total_voice_count ( lscp_cl
1847  {  {
1848          int iVoiceCount = -1;          int iVoiceCount = -1;
1849    
1850            if (pClient == NULL)
1851                    return -1;
1852    
1853          // Lock this section up.          // Lock this section up.
1854          lscp_mutex_lock(pClient->mutex);          lscp_mutex_lock(pClient->mutex);
1855    
# Line 1631  int lscp_get_total_voice_count_max ( lsc Line 1876  int lscp_get_total_voice_count_max ( lsc
1876  {  {
1877          int iVoiceCount = -1;          int iVoiceCount = -1;
1878    
1879            if (pClient == NULL)
1880                    return -1;
1881    
1882          // Lock this section up.          // Lock this section up.
1883          lscp_mutex_lock(pClient->mutex);          lscp_mutex_lock(pClient->mutex);
1884    
# Line 1645  int lscp_get_total_voice_count_max ( lsc Line 1893  int lscp_get_total_voice_count_max ( lsc
1893    
1894    
1895  /**  /**
1896     *  Get global volume attenuation:
1897     *  GET VOLUME
1898     *
1899     *  @param pClient  Pointer to client instance structure.
1900     *
1901     *  @returns The global volume as positive floating point value usually in
1902     *  the range between 0.0 and 1.0; in case of failure 0.0 is returned.
1903     */
1904    float lscp_get_volume ( lscp_client_t *pClient )
1905    {
1906            float fVolume = 0.0f;
1907            struct _locale_t locale;
1908    
1909            if (pClient == NULL)
1910                    return 0.0f;
1911    
1912            // Lock this section up.
1913            lscp_mutex_lock(pClient->mutex);
1914    
1915            _save_and_set_c_locale(&locale);
1916    
1917            if (lscp_client_call(pClient, "GET VOLUME\r\n", 0) == LSCP_OK)
1918                    fVolume = _atof(lscp_client_get_result(pClient));
1919    
1920            _restore_locale(&locale);
1921    
1922            // Unlock this section down.
1923            lscp_mutex_unlock(pClient->mutex);
1924    
1925            return fVolume;
1926    }
1927    
1928    
1929    /**
1930     *  Setting global volume attenuation:
1931     *  SET VOLUME <volume>
1932     *
1933     *  @param pClient  Pointer to client instance structure.
1934     *  @param fVolume  Global volume parameter as positive floating point
1935     *                  value usually be in the range between 0.0 and 1.0,
1936     *                  that is for attenuating the overall volume.
1937     *
1938     *  @returns LSCP_OK on success, LSCP_FAILED otherwise.
1939     */
1940    lscp_status_t lscp_set_volume ( lscp_client_t *pClient, float fVolume )
1941    {
1942            char szQuery[LSCP_BUFSIZ];
1943            struct _locale_t locale;
1944    
1945            if (fVolume < 0.0f)
1946                    return LSCP_FAILED;
1947    
1948            _save_and_set_c_locale(&locale);
1949            sprintf(szQuery, "SET VOLUME %g\r\n", fVolume);
1950            _restore_locale(&locale);
1951    
1952            return lscp_client_query(pClient, szQuery);
1953    }
1954    
1955    /**
1956     *  Get global voice limit setting:
1957     *  @code
1958     *  GET VOICES
1959     *  @endcode
1960     *  This value reflects the maximum amount of voices a sampler engine
1961     *  processes simultaniously before voice stealing kicks in.
1962     *
1963     *  @param pClient  Pointer to client instance structure.
1964     *
1965     *  @returns The current global maximum amount of voices limit or a
1966     *           negative value on error (e.g. if sampler doesn't support
1967     *           this command).
1968     */
1969    int lscp_get_voices(lscp_client_t *pClient)
1970    {
1971            int iVoices = -1;
1972    
1973            if (pClient == NULL)
1974                    return -1;
1975    
1976            // Lock this section up.
1977            lscp_mutex_lock(pClient->mutex);
1978    
1979            if (lscp_client_call(pClient, "GET VOICES\r\n", 0) == LSCP_OK)
1980                    iVoices = atoi(lscp_client_get_result(pClient));
1981    
1982            // Unlock this section down.
1983            lscp_mutex_unlock(pClient->mutex);
1984    
1985            return iVoices;
1986    }
1987    
1988    /**
1989     *  Setting global voice limit setting:
1990     *  @code
1991     *  SET VOICES <max-voices>
1992     *  @endcode
1993     *  This value reflects the maximum amount of voices a sampler engine
1994     *  processes simultaniously before voice stealing kicks in. Note that
1995     *  this value will be passed to all sampler engine instances, that is
1996     *  the total amount of maximum voices on the running system is thus
1997     *  @param iMaxVoices multiplied with the current amount of sampler
1998     *  engine instances.
1999     *
2000     *  @param pClient     Pointer to client instance structure.
2001     *  @param iMaxVoices  Global voice limit setting as integer value larger
2002     *                     or equal to 1.
2003     *
2004     *  @returns LSCP_OK on success, LSCP_FAILED otherwise.
2005     */
2006    lscp_status_t lscp_set_voices(lscp_client_t *pClient, int iMaxVoices)
2007    {
2008            char szQuery[LSCP_BUFSIZ];
2009    
2010            if (iMaxVoices < 1)
2011                    return LSCP_FAILED;
2012    
2013            sprintf(szQuery, "SET VOICES %d\r\n", iMaxVoices);
2014            return lscp_client_query(pClient, szQuery);
2015    }
2016    
2017    /**
2018     *  Get global disk streams limit setting:
2019     *  @code
2020     *  GET STREAMS
2021     *  @endcode
2022     *  This value reflects the maximum amount of disk streams a sampler
2023     *  engine processes simultaniously.
2024     *
2025     *  @param pClient  Pointer to client instance structure.
2026     *
2027     *  @returns The current global maximum amount of disk streams limit
2028     *           or a negative value on error (e.g. if sampler doesn't
2029     *           support this command).
2030     */
2031    int lscp_get_streams(lscp_client_t *pClient)
2032    {
2033            int iStreams = -1;
2034    
2035            if (pClient == NULL)
2036                    return -1;
2037    
2038            // Lock this section up.
2039            lscp_mutex_lock(pClient->mutex);
2040    
2041            if (lscp_client_call(pClient, "GET STREAMS\r\n", 0) == LSCP_OK)
2042                    iStreams = atoi(lscp_client_get_result(pClient));
2043    
2044            // Unlock this section down.
2045            lscp_mutex_unlock(pClient->mutex);
2046    
2047            return iStreams;
2048    }
2049    
2050    /**
2051     *  Setting global disk streams limit setting:
2052     *  @code
2053     *  SET STREAMS <max-streams>
2054     *  @endcode
2055     *  This value reflects the maximum amount of dist streams a sampler
2056     *  engine instance processes simultaniously. Note that this value will
2057     *  be passed to all sampler engine instances, that is the total amount
2058     *  of maximum disk streams on the running system is thus
2059     *  @param iMaxStreams multiplied with the current amount of sampler
2060     *  engine instances.
2061     *
2062     *  @param pClient      Pointer to client instance structure.
2063     *  @param iMaxStreams  Global streams limit setting as positive integer
2064     *                      value (larger or equal to 0).
2065     *
2066     *  @returns LSCP_OK on success, LSCP_FAILED otherwise.
2067     */
2068    lscp_status_t lscp_set_streams(lscp_client_t *pClient, int iMaxStreams)
2069    {
2070            char szQuery[LSCP_BUFSIZ];
2071    
2072            if (iMaxStreams < 0)
2073                    return LSCP_FAILED;
2074    
2075            sprintf(szQuery, "SET STREAMS %d\r\n", iMaxStreams);
2076            return lscp_client_query(pClient, szQuery);
2077    }
2078    
2079    /**
2080     *  Add an effect send to a sampler channel:
2081     *  CREATE FX_SEND <sampler-channel> <midi-ctrl> [<name>]
2082     *
2083     *  @param pClient          Pointer to client instance structure.
2084     *  @param iSamplerChannel  Sampler channel number.
2085     *  @param iMidiController  MIDI controller used to alter the effect,
2086     *                          usually a number between 0 and 127.
2087     *  @param pszName          Optional name for the effect send entity,
2088     *                          does not have to be unique.
2089     *
2090     *  @returns The new effect send number identifier, or -1 in case of failure.
2091     */
2092    int lscp_create_fxsend ( lscp_client_t *pClient, int iSamplerChannel, int iMidiController, const char *pszFxName )
2093    {
2094            int iFxSend = -1;
2095            char szQuery[LSCP_BUFSIZ];
2096    
2097            if (pClient == NULL)
2098                    return -1;
2099            if (iSamplerChannel < 0 || iMidiController < 0 || iMidiController > 127)
2100                    return -1;
2101    
2102            // Lock this section up.
2103            lscp_mutex_lock(pClient->mutex);
2104    
2105            sprintf(szQuery, "CREATE FX_SEND %d %d", iSamplerChannel, iMidiController);
2106    
2107            if (pszFxName)
2108                    sprintf(szQuery + strlen(szQuery), " '%s'", pszFxName);
2109    
2110            strcat(szQuery, "\r\n");
2111    
2112            if (lscp_client_call(pClient, szQuery, 0) == LSCP_OK)
2113                    iFxSend = atoi(lscp_client_get_result(pClient));
2114    
2115            // Unlock this section down.
2116            lscp_mutex_unlock(pClient->mutex);
2117    
2118            return iFxSend;
2119    }
2120    
2121    
2122    /**
2123     *  Remove an effect send from a sampler channel:
2124     *  DESTROY FX_SEND <sampler-channel> <fx-send-id>
2125     *
2126     *  @param pClient          Pointer to client instance structure.
2127     *  @param iSamplerChannel  Sampler channel number.
2128     *  @param iFxSend          Effect send number.
2129     *
2130     *  @returns LSCP_OK on success, LSCP_FAILED otherwise.
2131     */
2132    lscp_status_t lscp_destroy_fxsend ( lscp_client_t *pClient, int iSamplerChannel, int iFxSend )
2133    {
2134            char szQuery[LSCP_BUFSIZ];
2135    
2136            if (iSamplerChannel < 0 || iFxSend < 0)
2137                    return LSCP_FAILED;
2138    
2139            sprintf(szQuery, "DESTROY FX_SEND %d %d\r\n", iSamplerChannel, iFxSend);
2140    
2141            return lscp_client_query(pClient, szQuery);
2142    }
2143    
2144    
2145    /**
2146     *  Get amount of effect sends on a sampler channel:
2147     *  GET FX_SENDS <sampler-channel>
2148     *
2149     *  @param pClient          Pointer to client instance structure.
2150     *  @param iSamplerChannel  Sampler channel number.
2151     *
2152     *  @returns The current total number of effect sends of the sampler channel
2153     *  on success, -1 otherwise.
2154     */
2155    int lscp_get_fxsends ( lscp_client_t *pClient, int iSamplerChannel )
2156    {
2157            int iFxSends = -1;
2158            char szQuery[LSCP_BUFSIZ];
2159    
2160            if (pClient == NULL)
2161                    return -1;
2162            if (iSamplerChannel < 0)
2163                    return -1;
2164    
2165            // Lock this section up.
2166            lscp_mutex_lock(pClient->mutex);
2167    
2168            sprintf(szQuery, "GET FX_SENDS %d\r\n", iSamplerChannel);
2169    
2170            if (lscp_client_call(pClient, szQuery, 0) == LSCP_OK)
2171                    iFxSends = atoi(lscp_client_get_result(pClient));
2172    
2173            // Unlock this section doen.
2174            lscp_mutex_unlock(pClient->mutex);
2175    
2176            return iFxSends;
2177    }
2178    
2179    
2180    /**
2181     *  List all effect sends on a sampler channel:
2182     *  LIST FX_SENDS <sampler-channel>
2183     *
2184     *  @param pClient          Pointer to client instance structure.
2185     *  @param iSamplerChannel  Sampler channel number.
2186     *
2187     *  @returns An array of the effect sends identifiers as positive integers,
2188     *  terminated with -1 on success, NULL otherwise.
2189     */
2190    int *lscp_list_fxsends ( lscp_client_t *pClient, int iSamplerChannel )
2191    {
2192            const char *pszSeps = ",";
2193            char szQuery[LSCP_BUFSIZ];
2194    
2195            if (pClient == NULL)
2196                    return NULL;
2197    
2198            // Lock this section up.
2199            lscp_mutex_lock(pClient->mutex);
2200    
2201            if (pClient->fxsends) {
2202                    lscp_isplit_destroy(pClient->fxsends);
2203                    pClient->fxsends = NULL;
2204            }
2205    
2206            sprintf(szQuery, "LIST FX_SENDS %d\r\n", iSamplerChannel);
2207    
2208            if (lscp_client_call(pClient, szQuery, 0) == LSCP_OK)
2209                    pClient->fxsends = lscp_isplit_create(lscp_client_get_result(pClient), pszSeps);
2210    
2211            // Unlock this section down.
2212            lscp_mutex_unlock(pClient->mutex);
2213    
2214            return pClient->fxsends;
2215    }
2216    
2217    
2218    /**
2219     *  Getting effect send information
2220     *  GET FX_SEND INFO <sampler-channel> <fx-send-id>
2221     *
2222     *  @param pClient          Pointer to client instance structure.
2223     *  @param iSamplerChannel  Sampler channel number.
2224     *  @param iFxSend          Effect send number.
2225     *
2226     *  @returns A pointer to a @ref lscp_fxsend_info_t structure, with the
2227     *  information of the given FX send, or NULL in case of failure.
2228     */
2229    lscp_fxsend_info_t *lscp_get_fxsend_info ( lscp_client_t *pClient, int iSamplerChannel, int iFxSend )
2230    {
2231            lscp_fxsend_info_t *pFxSendInfo;
2232            char szQuery[LSCP_BUFSIZ];
2233            const char *pszResult;
2234            const char *pszSeps = ":";
2235            const char *pszCrlf = "\r\n";
2236            char *pszToken;
2237            char *pch;
2238            struct _locale_t locale;
2239    
2240            if (pClient == NULL)
2241                    return NULL;
2242            if (iSamplerChannel < 0 || iFxSend < 0)
2243                    return NULL;
2244    
2245            // Lock this section up.
2246            lscp_mutex_lock(pClient->mutex);
2247    
2248            _save_and_set_c_locale(&locale);
2249    
2250            pFxSendInfo = &(pClient->fxsend_info);
2251            lscp_fxsend_info_reset(pFxSendInfo);
2252    
2253            sprintf(szQuery, "GET FX_SEND INFO %d %d\r\n", iSamplerChannel, iFxSend);
2254            if (lscp_client_call(pClient, szQuery, 1) == LSCP_OK) {
2255                    pszResult = lscp_client_get_result(pClient);
2256                    pszToken = lscp_strtok((char *) pszResult, pszSeps, &(pch));
2257                    while (pszToken) {
2258                            if (strcasecmp(pszToken, "NAME") == 0) {
2259                                    pszToken = lscp_strtok(NULL, pszCrlf, &(pch));
2260                                    if (pszToken)
2261                                            lscp_unquote_dup(&(pFxSendInfo->name), &pszToken);
2262                            }
2263                            else if (strcasecmp(pszToken, "MIDI_CONTROLLER") == 0) {
2264                                    pszToken = lscp_strtok(NULL, pszCrlf, &(pch));
2265                                    if (pszToken)
2266                                            pFxSendInfo->midi_controller = atoi(lscp_ltrim(pszToken));
2267                            }
2268                            else if (strcasecmp(pszToken, "AUDIO_OUTPUT_ROUTING") == 0) {
2269                                    pszToken = lscp_strtok(NULL, pszCrlf, &(pch));
2270                                    if (pszToken) {
2271                                            if (pFxSendInfo->audio_routing)
2272                                                    lscp_isplit_destroy(pFxSendInfo->audio_routing);
2273                                            pFxSendInfo->audio_routing = lscp_isplit_create(pszToken, ",");
2274                                    }
2275                            }
2276                            else if (strcasecmp(pszToken, "LEVEL") == 0) {
2277                                    pszToken = lscp_strtok(NULL, pszCrlf, &(pch));
2278                                    if (pszToken)
2279                                            pFxSendInfo->level = _atof(lscp_ltrim(pszToken));
2280                            }
2281                            pszToken = lscp_strtok(NULL, pszSeps, &(pch));
2282                    }
2283            }
2284            else pFxSendInfo = NULL;
2285    
2286            _restore_locale(&locale);
2287    
2288            // Unlock this section up.
2289            lscp_mutex_unlock(pClient->mutex);
2290    
2291            return pFxSendInfo;
2292    }
2293    
2294    /**
2295     *  Alter effect send's name:
2296     *  @code
2297     *  SET FX_SEND NAME <sampler-chan> <fx-send-id> <name>
2298     *  @endcode
2299     *
2300     *  @param pClient          Pointer to client instance structure.
2301     *  @param iSamplerChannel  Sampler channel number.
2302     *  @param iFxSend          Effect send number.
2303     *  @param pszFxName        Effect send's new name.
2304     *
2305     *  @returns LSCP_OK on success, LSCP_FAILED otherwise.
2306     */
2307    lscp_status_t lscp_set_fxsend_name ( lscp_client_t *pClient, int iSamplerChannel, int iFxSend, const char *pszFxName )
2308    {
2309            char szQuery[LSCP_BUFSIZ];
2310    
2311            if (!pClient || iSamplerChannel < 0 || iFxSend < 0 || !pszFxName)
2312                    return LSCP_FAILED;
2313    
2314            snprintf(szQuery, LSCP_BUFSIZ, "SET FX_SEND NAME %d %d '%s'\r\n", iSamplerChannel, iFxSend, pszFxName);
2315            return lscp_client_query(pClient, szQuery);
2316    }
2317    
2318    /**
2319     *  Alter effect send's audio routing:
2320     *  SET FX_SEND AUDIO_OUTPUT_CHANNEL <sampler-chan> <fx-send-id>
2321     *    <audio-src> <audio-dst>
2322     *
2323     *  @param pClient          Pointer to client instance structure.
2324     *  @param iSamplerChannel  Sampler channel number.
2325     *  @param iFxSend          Effect send number.
2326     *  @param iAudioSrc        Audio output device channel to be routed from.
2327     *  @param iAudioDst        Audio output device channel to be routed into.
2328     *
2329     *  @returns LSCP_OK on success, LSCP_FAILED otherwise.
2330     */
2331    lscp_status_t lscp_set_fxsend_audio_channel ( lscp_client_t *pClient, int iSamplerChannel, int iFxSend, int iAudioSrc, int iAudioDst )
2332    {
2333            char szQuery[LSCP_BUFSIZ];
2334    
2335            if (iSamplerChannel < 0 || iFxSend < 0 || iAudioSrc < 0 || iAudioDst < 0)
2336                    return LSCP_FAILED;
2337    
2338            sprintf(szQuery, "SET FX_SEND AUDIO_OUTPUT_CHANNEL %d %d %d %d\r\n", iSamplerChannel, iFxSend, iAudioSrc, iAudioDst);
2339            return lscp_client_query(pClient, szQuery);
2340    }
2341    
2342    
2343    /**
2344     *  Alter effect send's MIDI controller:
2345     *  SET FX_SEND MIDI_CONTROLLER <sampler-chan> <fx-send-id> <midi-ctrl>
2346     *
2347     *  @param pClient          Pointer to client instance structure.
2348     *  @param iSamplerChannel  Sampler channel number.
2349     *  @param iFxSend          Effect send number.
2350     *  @param iMidiController  MIDI controller used to alter the effect,
2351     *                          usually a number between 0 and 127.
2352     *
2353     *  @returns LSCP_OK on success, LSCP_FAILED otherwise.
2354     */
2355    lscp_status_t lscp_set_fxsend_midi_controller ( lscp_client_t *pClient, int iSamplerChannel, int iFxSend, int iMidiController )
2356    {
2357            char szQuery[LSCP_BUFSIZ];
2358    
2359            if (iSamplerChannel < 0 || iFxSend < 0 || iMidiController < 0 || iMidiController > 127)
2360                    return LSCP_FAILED;
2361    
2362            sprintf(szQuery, "SET FX_SEND MIDI_CONTROLLER %d %d %d\r\n", iSamplerChannel, iFxSend, iMidiController);
2363            return lscp_client_query(pClient, szQuery);
2364    }
2365    
2366    
2367    /**
2368     *  Alter effect send's audio level:
2369     *  SET FX_SEND LEVEL <sampler-chan> <fx-send-id> <level>
2370     *
2371     *  @param pClient          Pointer to client instance structure.
2372     *  @param iSamplerChannel  Sampler channel number.
2373     *  @param iFxSend          Effect send number.
2374     *  @param fLevel           Effect send volume level.
2375     *
2376     *  @returns LSCP_OK on success, LSCP_FAILED otherwise.
2377     */
2378    lscp_status_t lscp_set_fxsend_level ( lscp_client_t *pClient, int iSamplerChannel, int iFxSend, float fLevel )
2379    {
2380            char szQuery[LSCP_BUFSIZ];
2381            struct _locale_t locale;
2382    
2383            if (iSamplerChannel < 0 || iFxSend < 0 || fLevel < 0.0f)
2384                    return LSCP_FAILED;
2385    
2386            _save_and_set_c_locale(&locale);
2387            sprintf(szQuery, "SET FX_SEND LEVEL %d %d %f\r\n", iSamplerChannel, iFxSend, fLevel);
2388            _restore_locale(&locale);
2389    
2390            return lscp_client_query(pClient, szQuery);
2391    }
2392    
2393    
2394    /**
2395     *  Create a new MIDI instrument map:
2396     *  ADD MIDI_INSTRUMENT_MAP [<name>]
2397     *
2398     *  @param pClient      Pointer to client instance structure.
2399     *  @param pszMapName   MIDI instrument map name (optional)
2400     *
2401     *  @returns The new MIDI instrument map number identifier,
2402     *  or -1 in case of failure.
2403     */
2404    int lscp_add_midi_instrument_map ( lscp_client_t *pClient, const char *pszMapName )
2405    {
2406            int iMidiMap = -1;
2407            char szQuery[LSCP_BUFSIZ];
2408    
2409            if (pClient == NULL)
2410                    return -1;
2411    
2412            // Lock this section up.
2413            lscp_mutex_lock(pClient->mutex);
2414    
2415            strcpy(szQuery, "ADD MIDI_INSTRUMENT_MAP");
2416    
2417            if (pszMapName)
2418                    sprintf(szQuery + strlen(szQuery), " '%s'", pszMapName);
2419    
2420            strcat(szQuery, "\r\n");
2421    
2422            if (lscp_client_call(pClient, szQuery, 0) == LSCP_OK)
2423                    iMidiMap = atoi(lscp_client_get_result(pClient));
2424    
2425            // Unlock this section down.
2426            lscp_mutex_unlock(pClient->mutex);
2427    
2428            return iMidiMap;
2429    }
2430    
2431    
2432    /**
2433     *  Delete one particular or all MIDI instrument maps:
2434     *  REMOVE MIDI_INSTRUMENT_MAP <midi-map>
2435     *
2436     *  @param pClient  Pointer to client instance structure.
2437     *  @param iMidiMap MIDI instrument map number.
2438     *
2439     *  @returns LSCP_OK on success, LSCP_FAILED otherwise.
2440     */
2441    lscp_status_t lscp_remove_midi_instrument_map ( lscp_client_t *pClient, int iMidiMap )
2442    {
2443            char szQuery[LSCP_BUFSIZ];
2444    
2445            if (iMidiMap < 0)
2446                    return LSCP_FAILED;
2447    
2448            sprintf(szQuery, "REMOVE MIDI_INSTRUMENT_MAP %d\r\n", iMidiMap);
2449    
2450            return lscp_client_query(pClient, szQuery);
2451    }
2452    
2453    
2454    /**
2455     *  Get amount of existing MIDI instrument maps:
2456     *  GET MIDI_INSTRUMENT_MAPS
2457     *
2458     *  @param pClient  Pointer to client instance structure.
2459     *
2460     *  @returns The current total number of MIDI instrument maps
2461     *  on success, -1 otherwise.
2462     */
2463    int lscp_get_midi_instrument_maps ( lscp_client_t *pClient )
2464    {
2465            int iMidiMaps = -1;
2466    
2467            if (pClient == NULL)
2468                    return -1;
2469    
2470            // Lock this section up.
2471            lscp_mutex_lock(pClient->mutex);
2472    
2473            if (lscp_client_call(pClient, "GET MIDI_INSTRUMENT_MAPS\r\n", 0) == LSCP_OK)
2474                    iMidiMaps = atoi(lscp_client_get_result(pClient));
2475    
2476            // Unlock this section doen.
2477            lscp_mutex_unlock(pClient->mutex);
2478    
2479            return iMidiMaps;
2480    }
2481    
2482    
2483    /**
2484     *  Getting all created MIDI instrument maps:
2485     *  LIST MIDI_INSTRUMENT_MAPS
2486     *
2487     *  @param pClient  Pointer to client instance structure.
2488     *
2489     *  @returns An array of the MIDI instrument map identifiers as positive
2490     *  integers, terminated with -1 on success, NULL otherwise.
2491     */
2492    int *lscp_list_midi_instrument_maps ( lscp_client_t *pClient )
2493    {
2494            const char *pszSeps = ",";
2495    
2496            if (pClient == NULL)
2497                    return NULL;
2498    
2499            // Lock this section up.
2500            lscp_mutex_lock(pClient->mutex);
2501    
2502            if (pClient->midi_maps) {
2503                    lscp_isplit_destroy(pClient->midi_maps);
2504                    pClient->midi_maps = NULL;
2505            }
2506    
2507            if (lscp_client_call(pClient, "LIST MIDI_INSTRUMENT_MAPS\r\n", 0) == LSCP_OK)
2508                    pClient->midi_maps = lscp_isplit_create(lscp_client_get_result(pClient), pszSeps);
2509    
2510            // Unlock this section down.
2511            lscp_mutex_unlock(pClient->mutex);
2512    
2513            return pClient->midi_maps;
2514    }
2515    
2516    
2517    /**
2518     *  Getting a MIDI instrument map name:
2519     *  GET MIDI_INSTRUMENT_MAP INFO <midi-map>
2520     *
2521     *  @param pClient  Pointer to client instance structure.
2522     *  @param iMidiMap MIDI instrument map number.
2523     *
2524     *  @returns The MIDI instrument map name on success, NULL on failure.
2525     */
2526    const char *lscp_get_midi_instrument_map_name ( lscp_client_t *pClient, int iMidiMap )
2527    {
2528            char szQuery[LSCP_BUFSIZ];
2529            const char *pszResult;
2530            const char *pszSeps = ":";
2531            const char *pszCrlf = "\r\n";
2532            char *pszToken;
2533            char *pch;
2534    
2535            if (pClient == NULL)
2536                    return NULL;
2537            if (iMidiMap < 0)
2538                    return NULL;
2539    
2540            // Lock this section up.
2541            lscp_mutex_lock(pClient->mutex);
2542    
2543            if (pClient->midi_map_name) {
2544                    free(pClient->midi_map_name);
2545                    pClient->midi_map_name = NULL;
2546            }
2547    
2548            sprintf(szQuery, "GET MIDI_INSTRUMENT_MAP INFO %d\r\n", iMidiMap);
2549            if (lscp_client_call(pClient, szQuery, 1) == LSCP_OK) {
2550                    pszResult = lscp_client_get_result(pClient);
2551                    pszToken = lscp_strtok((char *) pszResult, pszSeps, &(pch));
2552                    while (pszToken) {
2553                            if (strcasecmp(pszToken, "NAME") == 0) {
2554                                    pszToken = lscp_strtok(NULL, pszCrlf, &(pch));
2555                                    if (pszToken)
2556                                            lscp_unquote_dup(&(pClient->midi_map_name), &pszToken);
2557                            }
2558                            pszToken = lscp_strtok(NULL, pszSeps, &(pch));
2559                    }
2560            }
2561    
2562            // Unlock this section down.
2563            lscp_mutex_unlock(pClient->mutex);
2564    
2565            return pClient->midi_map_name;
2566    }
2567    
2568    
2569    /**
2570     *  Renaming a MIDI instrument map:
2571     *  SET MIDI_INSTRUMENT_MAP NAME <midi-map> <map-name>
2572     *
2573     *  @param pClient      Pointer to client instance structure.
2574     *  @param iMidiMap     MIDI instrument map number.
2575     *  @param pszMapName   MIDI instrument map name.
2576     *
2577     *  @returns LSCP_OK on success, LSCP_FAILED otherwise.
2578     */
2579    lscp_status_t lscp_set_midi_instrument_map_name ( lscp_client_t *pClient, int iMidiMap, const char *pszMapName )
2580    {
2581            char szQuery[LSCP_BUFSIZ];
2582    
2583            if (iMidiMap < 0)
2584                    return LSCP_FAILED;
2585            if (pszMapName == NULL)
2586                    return LSCP_FAILED;
2587    
2588            sprintf(szQuery, "SET MIDI_INSTRUMENT_MAP NAME %d '%s'\r\n",
2589                    iMidiMap, pszMapName);
2590    
2591            return lscp_client_query(pClient, szQuery);
2592    }
2593    
2594    
2595    /**
2596   *  Create or replace a MIDI instrumnet map entry:   *  Create or replace a MIDI instrumnet map entry:
2597   *  MAP MIDI_INSTRUMENT <midi-bank-msb> <midi-bank-lsb> <midi-prog>   *  MAP MIDI_INSTRUMENT <midi-map> <midi-bank> <midi-prog>
2598   *      <engine-name> <filename> <instr-index> <volume> <load-mode> [<name>]   *      <engine-name> <filename> <instr-index> <volume> [<load-mode> [<name>]}
2599   *   *
2600   *  @param pClient          Pointer to client instance structure.   *  @param pClient          Pointer to client instance structure.
2601   *  @param pMidiInstr       MIDI instrument bank and program parameter key.   *  @param pMidiInstr       MIDI instrument bank and program parameter key.
# Line 1655  int lscp_get_total_voice_count_max ( lsc Line 2603  int lscp_get_total_voice_count_max ( lsc
2603   *  @param pszFileName      Instrument file name.   *  @param pszFileName      Instrument file name.
2604   *  @param iInstrIndex      Instrument index number.   *  @param iInstrIndex      Instrument index number.
2605   *  @param fVolume          Reflects the master volume of the instrument as   *  @param fVolume          Reflects the master volume of the instrument as
2606   *                          a positive floating point number, where a value   *                          a positive floating point number, where a value
2607   *                          less than 1.0 for attenuation, and greater than   *                          less than 1.0 for attenuation, and greater than
2608   *                          1.0 for amplification.   *                          1.0 for amplification.
2609   *  @param load_mode        Instrument load life-time strategy, either   *  @param load_mode        Instrument load life-time strategy, either
# Line 1663  int lscp_get_total_voice_count_max ( lsc Line 2611  int lscp_get_total_voice_count_max ( lsc
2611   *                          @ref LSCP_LOAD_ON_DEMAND, or   *                          @ref LSCP_LOAD_ON_DEMAND, or
2612   *                          @ref LSCP_LOAD_ON_DEMAND_HOLD, or   *                          @ref LSCP_LOAD_ON_DEMAND_HOLD, or
2613   *                          @ref LSCP_LOAD_PERSISTENT.   *                          @ref LSCP_LOAD_PERSISTENT.
2614   *  @param pszName          Instrument custom name for the map entry.   *  @param pszName         Instrument custom name for the map entry (optional).
2615   *   *
2616   *  @returns LSCP_OK on success, LSCP_FAILED otherwise.   *  @returns LSCP_OK on success, LSCP_FAILED otherwise.
2617   */   */
2618  lscp_status_t lscp_map_midi_instrument ( lscp_client_t *pClient, lscp_midi_instrument_t *pMidiInstr, const char *pszEngineName, const char *pszFileName, int iInstrIndex, float fVolume, lscp_load_mode_t load_mode, const char *pszName )  lscp_status_t lscp_map_midi_instrument ( lscp_client_t *pClient, lscp_midi_instrument_t *pMidiInstr, const char *pszEngineName, const char *pszFileName, int iInstrIndex, float fVolume, lscp_load_mode_t load_mode, const char *pszName )
2619  {  {
2620          char szQuery[LSCP_BUFSIZ];          char szQuery[LSCP_BUFSIZ];
2621                    struct _locale_t locale;
2622          if (pMidiInstr->bank_msb < 0 || pMidiInstr->bank_msb > 127)  
2623            if (pMidiInstr->map < 0)
2624                  return LSCP_FAILED;                  return LSCP_FAILED;
2625          if (pMidiInstr->bank_lsb < 0 || pMidiInstr->bank_lsb > 127)          if (pMidiInstr->bank < 0 || pMidiInstr->bank > 16383)
2626                  return LSCP_FAILED;                  return LSCP_FAILED;
2627          if (pMidiInstr->program < 0 || pMidiInstr->program > 127)          if (pMidiInstr->prog < 0 || pMidiInstr->prog > 127)
2628                  return LSCP_FAILED;                  return LSCP_FAILED;
2629          if (pszEngineName == NULL || pszFileName == NULL)          if (pszEngineName == NULL || pszFileName == NULL)
2630                  return LSCP_FAILED;                  return LSCP_FAILED;
2631            
2632          if (fVolume < 0.0f)          if (fVolume < 0.0f)
2633                  fVolume = 1.0f;                  fVolume = 1.0f;
2634            
2635            _save_and_set_c_locale(&locale);
2636          sprintf(szQuery, "MAP MIDI_INSTRUMENT %d %d %d %s '%s' %d %g",          sprintf(szQuery, "MAP MIDI_INSTRUMENT %d %d %d %s '%s' %d %g",
2637                  pMidiInstr->bank_msb, pMidiInstr->bank_lsb, pMidiInstr->program,                  pMidiInstr->map, pMidiInstr->bank, pMidiInstr->prog,
2638                  pszEngineName, pszFileName, iInstrIndex, fVolume);                  pszEngineName, pszFileName, iInstrIndex, fVolume);
2639                    _restore_locale(&locale);
2640    
2641          switch (load_mode) {          switch (load_mode) {
2642          case LSCP_LOAD_PERSISTENT:          case LSCP_LOAD_PERSISTENT:
2643                  strcat(szQuery, " PERSISTENT");                  strcat(szQuery, " PERSISTENT");
# Line 1695  lscp_status_t lscp_map_midi_instrument ( Line 2646  lscp_status_t lscp_map_midi_instrument (
2646                  strcat(szQuery, " ON_DEMAND_HOLD");                  strcat(szQuery, " ON_DEMAND_HOLD");
2647                  break;                  break;
2648          case LSCP_LOAD_ON_DEMAND:          case LSCP_LOAD_ON_DEMAND:
2649                  strcat(szQuery, " ON_DEMAND_HOLD");                  strcat(szQuery, " ON_DEMAND");
2650                  break;                  break;
2651          case LSCP_LOAD_DEFAULT:          case LSCP_LOAD_DEFAULT:
2652          default:          default:
2653                  break;                  break;
2654          }          }
2655            
2656          if (pszName)          if (pszName)
2657                  sprintf(szQuery + strlen(szQuery), " '%s'", pszName);                  sprintf(szQuery + strlen(szQuery), " '%s'", pszName);
2658            
2659          strcat(szQuery, "\r\n");          strcat(szQuery, "\r\n");
2660            
2661          return lscp_client_query(pClient, szQuery);          return lscp_client_query(pClient, szQuery);
2662  }  }
2663    
2664    
2665  /**  /**
2666   *  Remove an entry from the MIDI instrument map:   *  Remove an entry from the MIDI instrument map:
2667   *  UNMAP MIDI_INSTRUMENT <midi-bank-msb> <midi-bank-lsb> <midi-prog>   *  UNMAP MIDI_INSTRUMENT <midi-map> <midi-bank> <midi-prog>
2668   *   *
2669   *  @param pClient      Pointer to client instance structure.   *  @param pClient      Pointer to client instance structure.
2670   *  @param pMidiInstr   MIDI instrument bank and program parameter key.   *  @param pMidiInstr   MIDI instrument bank and program parameter key.
# Line 1724  lscp_status_t lscp_unmap_midi_instrument Line 2675  lscp_status_t lscp_unmap_midi_instrument
2675  {  {
2676          char szQuery[LSCP_BUFSIZ];          char szQuery[LSCP_BUFSIZ];
2677    
2678          if (pMidiInstr->bank_msb < 0 || pMidiInstr->bank_msb > 127)          if (pMidiInstr->map < 0)
2679                  return LSCP_FAILED;                  return LSCP_FAILED;
2680          if (pMidiInstr->bank_lsb < 0 || pMidiInstr->bank_lsb > 127)          if (pMidiInstr->bank < 0 || pMidiInstr->bank > 16383)
2681                  return LSCP_FAILED;                  return LSCP_FAILED;
2682          if (pMidiInstr->program < 0 || pMidiInstr->program > 127)          if (pMidiInstr->prog < 0 || pMidiInstr->prog > 127)
2683                  return LSCP_FAILED;                  return LSCP_FAILED;
2684    
2685          sprintf(szQuery, "UNMAP MIDI_INSTRUMENT %d %d %d\r\n",          sprintf(szQuery, "UNMAP MIDI_INSTRUMENT %d %d %d\r\n",
2686                  pMidiInstr->bank_msb, pMidiInstr->bank_lsb, pMidiInstr->program);                  pMidiInstr->map, pMidiInstr->bank, pMidiInstr->prog);
2687    
2688          return lscp_client_query(pClient, szQuery);          return lscp_client_query(pClient, szQuery);
2689  }  }
# Line 1740  lscp_status_t lscp_unmap_midi_instrument Line 2691  lscp_status_t lscp_unmap_midi_instrument
2691    
2692  /**  /**
2693   *  Get the total count of MIDI instrument map entries:   *  Get the total count of MIDI instrument map entries:
2694   *  GET MIDI_INSTRUMENTS   *  GET MIDI_INSTRUMENTS ALL|<midi-map>
2695   *   *
2696   *  @param pClient  Pointer to client instance structure.   *  @param pClient  Pointer to client instance structure.
2697     *  @param iMidiMap MIDI instrument map number, or @ref LSCP_MIDI_MAP_ALL .
2698   *   *
2699   *  @returns The current total number of MIDI instrument map entries   *  @returns The current total number of MIDI instrument map entries
2700   *  on success, -1 otherwise.   *  on success, -1 otherwise.
2701   */   */
2702  int lscp_get_midi_instruments ( lscp_client_t *pClient )  int lscp_get_midi_instruments ( lscp_client_t *pClient, int iMidiMap )
2703  {  {
2704          int iInstruments = -1;          int iInstruments = -1;
2705            char szQuery[LSCP_BUFSIZ];
2706    
2707            if (pClient == NULL)
2708                    return -1;
2709    
2710          // Lock this section up.          // Lock this section up.
2711          lscp_mutex_lock(pClient->mutex);          lscp_mutex_lock(pClient->mutex);
2712    
2713          if (lscp_client_call(pClient, "GET MIDI_INSTRUMENTS\r\n", 0) == LSCP_OK)          strcpy(szQuery, "GET MIDI_INSTRUMENTS ");
2714    
2715            if (iMidiMap < 0)
2716                    strcat(szQuery, "ALL");
2717            else
2718                    sprintf(szQuery + strlen(szQuery), "%d", iMidiMap);
2719    
2720            strcat(szQuery, "\r\n");
2721    
2722            if (lscp_client_call(pClient, szQuery, 0) == LSCP_OK)
2723                  iInstruments = atoi(lscp_client_get_result(pClient));                  iInstruments = atoi(lscp_client_get_result(pClient));
2724    
2725          // Unlock this section down.          // Unlock this section down.
# Line 1766  int lscp_get_midi_instruments ( lscp_cli Line 2731  int lscp_get_midi_instruments ( lscp_cli
2731    
2732  /**  /**
2733   *  Getting indeces of all MIDI instrument map entries:   *  Getting indeces of all MIDI instrument map entries:
2734   *  LIST MIDI_INSTRUMENTS   *  LIST MIDI_INSTRUMENTS ALL|<midi-map>
2735   *   *
2736   *  @param pClient  Pointer to client instance structure.   *  @param pClient  Pointer to client instance structure.
2737     *  @param iMidiMap MIDI instrument map number, or @ref LSCP_MIDI_MAP_ALL .
2738   *   *
2739   *  @returns An array of @ref lscp_midi_instrument_t, terminated with the   *  @returns An array of @ref lscp_midi_instrument_t, terminated with the
2740   *  {-1,-1,-1} triplet, NULL otherwise.   *  {-1,-1,-1} triplet, NULL otherwise.
2741   */   */
2742  lscp_midi_instrument_t *lscp_list_midi_instruments ( lscp_client_t *pClient )  lscp_midi_instrument_t *lscp_list_midi_instruments ( lscp_client_t *pClient, int iMidiMap )
2743  {  {
2744            char szQuery[LSCP_BUFSIZ];
2745    
2746          if (pClient == NULL)          if (pClient == NULL)
2747                  return NULL;                  return NULL;
2748    
# Line 1786  lscp_midi_instrument_t *lscp_list_midi_i Line 2754  lscp_midi_instrument_t *lscp_list_midi_i
2754                  pClient->midi_instruments = NULL;                  pClient->midi_instruments = NULL;
2755          }          }
2756    
2757          if (lscp_client_call(pClient, "LIST MIDI_INSTRUMENTS\r\n", 0) == LSCP_OK)          strcpy(szQuery, "LIST MIDI_INSTRUMENTS ");
2758    
2759            if (iMidiMap < 0)
2760                    strcat(szQuery, "ALL");
2761            else
2762                    sprintf(szQuery + strlen(szQuery), "%d", iMidiMap);
2763    
2764            strcat(szQuery, "\r\n");
2765    
2766            if (lscp_client_call(pClient, szQuery, 0) == LSCP_OK)
2767                  pClient->midi_instruments = lscp_midi_instruments_create(lscp_client_get_result(pClient));                  pClient->midi_instruments = lscp_midi_instruments_create(lscp_client_get_result(pClient));
2768    
2769          // Unlock this section down.          // Unlock this section down.
# Line 1798  lscp_midi_instrument_t *lscp_list_midi_i Line 2775  lscp_midi_instrument_t *lscp_list_midi_i
2775    
2776  /**  /**
2777   *  Getting information about a MIDI instrument map entry:   *  Getting information about a MIDI instrument map entry:
2778   *  GET MIDI_INSTRUMENT INFO <midi-bank-msb> <midi-bank-lsb> <midi-prog>   *  GET MIDI_INSTRUMENT INFO <midi-map> <midi-bank> <midi-prog>
2779   *   *
2780   *  @param pClient      Pointer to client instance structure.   *  @param pClient      Pointer to client instance structure.
2781   *  @param pMidiInstr   MIDI instrument bank and program parameter key.   *  @param pMidiInstr   MIDI instrument bank and program parameter key.
# Line 1816  lscp_midi_instrument_info_t *lscp_get_mi Line 2793  lscp_midi_instrument_info_t *lscp_get_mi
2793          const char *pszCrlf = "\r\n";          const char *pszCrlf = "\r\n";
2794          char *pszToken;          char *pszToken;
2795          char *pch;          char *pch;
2796                    struct _locale_t locale;
2797          if (pMidiInstr->bank_msb < 0 || pMidiInstr->bank_msb > 127)  
2798            if (pClient == NULL)
2799                    return NULL;
2800            if (pMidiInstr->map < 0)
2801                  return NULL;                  return NULL;
2802          if (pMidiInstr->bank_lsb < 0 || pMidiInstr->bank_lsb > 127)          if (pMidiInstr->bank < 0 || pMidiInstr->bank > 16383)
2803                  return NULL;                  return NULL;
2804          if (pMidiInstr->program < 0 || pMidiInstr->program > 127)          if (pMidiInstr->prog < 0 || pMidiInstr->prog > 127)
2805                  return NULL;                  return NULL;
2806            
2807          // Lock this section up.          // Lock this section up.
2808          lscp_mutex_lock(pClient->mutex);          lscp_mutex_lock(pClient->mutex);
2809            
2810            _save_and_set_c_locale(&locale);
2811    
2812          pInstrInfo = &(pClient->midi_instrument_info);          pInstrInfo = &(pClient->midi_instrument_info);
2813          lscp_midi_instrument_info_reset(pInstrInfo);          lscp_midi_instrument_info_reset(pInstrInfo);
2814            
2815          sprintf(szQuery, "GET MIDI_INSTRUMENT INFO %d %d %d\r\n",          sprintf(szQuery, "GET MIDI_INSTRUMENT INFO %d %d %d\r\n",
2816                  pMidiInstr->bank_msb, pMidiInstr->bank_lsb, pMidiInstr->program);                  pMidiInstr->map, pMidiInstr->bank, pMidiInstr->prog);
2817          if (lscp_client_call(pClient, szQuery, 1) == LSCP_OK) {          if (lscp_client_call(pClient, szQuery, 1) == LSCP_OK) {
2818                  pszResult = lscp_client_get_result(pClient);                  pszResult = lscp_client_get_result(pClient);
2819                  pszToken = lscp_strtok((char *) pszResult, pszSeps, &(pch));                  pszToken = lscp_strtok((char *) pszResult, pszSeps, &(pch));
# Line 1880  lscp_midi_instrument_info_t *lscp_get_mi Line 2862  lscp_midi_instrument_info_t *lscp_get_mi
2862                          else if (strcasecmp(pszToken, "VOLUME") == 0) {                          else if (strcasecmp(pszToken, "VOLUME") == 0) {
2863                                  pszToken = lscp_strtok(NULL, pszCrlf, &(pch));                                  pszToken = lscp_strtok(NULL, pszCrlf, &(pch));
2864                                  if (pszToken)                                  if (pszToken)
2865                                          pInstrInfo->volume = (float) atof(lscp_ltrim(pszToken));                                          pInstrInfo->volume = _atof(lscp_ltrim(pszToken));
2866                          }                          }
2867                          pszToken = lscp_strtok(NULL, pszSeps, &(pch));                          pszToken = lscp_strtok(NULL, pszSeps, &(pch));
2868                  }                  }
2869          }          }
2870          else pInstrInfo = NULL;          else pInstrInfo = NULL;
2871            
2872            _restore_locale(&locale);
2873    
2874          // Unlock this section down.          // Unlock this section down.
2875          lscp_mutex_unlock(pClient->mutex);          lscp_mutex_unlock(pClient->mutex);
2876            
2877          return pInstrInfo;          return pInstrInfo;
2878  }  }
2879    
2880    
2881  /**  /**
2882   *  Clear the MIDI instrumnet map:   *  Clear the MIDI instrumnet map:
2883   *  CLEAR MIDI_INSTRUMENTS   *  CLEAR MIDI_INSTRUMENTS ALL|<midi-map>
2884   *   *
2885   *  @param pClient         Pointer to client instance structure.   *  @param pClient  Pointer to client instance structure.
2886   *  @param iSamplerChannel  Sampler channel number.   *  @param iMidiMap MIDI instrument map number, or @ref LSCP_MIDI_MAP_ALL .
2887   *   *
2888   *  @returns LSCP_OK on success, LSCP_FAILED otherwise.   *  @returns LSCP_OK on success, LSCP_FAILED otherwise.
2889   */   */
2890  lscp_status_t lscp_clear_midi_instruments  ( lscp_client_t *pClient )  lscp_status_t lscp_clear_midi_instruments  ( lscp_client_t *pClient, int iMidiMap )
2891    {
2892            char szQuery[LSCP_BUFSIZ];
2893    
2894            strcpy(szQuery, "CLEAR MIDI_INSTRUMENTS ");
2895    
2896            if (iMidiMap < 0)
2897                    strcat(szQuery, "ALL");
2898            else
2899                    sprintf(szQuery + strlen(szQuery), "%d", iMidiMap);
2900    
2901            strcat(szQuery, "\r\n");
2902    
2903            return lscp_client_query(pClient, szQuery);
2904    }
2905    
2906    /**
2907     * Open an instrument editor application for the instrument
2908     * on the given sampler channel:
2909     * EDIT CHANNEL INSTRUMENT <sampler-channel>
2910     *
2911     * @param pClient         Pointer to client instance structure.
2912     * @param iSamplerChannel Sampler Channel.
2913     *
2914     * @returns LSCP_OK on success, LSCP_FAILED otherwise.
2915     */
2916    lscp_status_t lscp_edit_channel_instrument ( lscp_client_t *pClient, int iSamplerChannel )
2917  {  {
2918          return lscp_client_query(pClient, "CLEAR MIDI_INSTRUMENTS\r\n");          char szQuery[LSCP_BUFSIZ];
2919    
2920            if (iSamplerChannel < 0)
2921                    return LSCP_FAILED;
2922    
2923            sprintf(szQuery, "EDIT CHANNEL INSTRUMENT %d\r\n", iSamplerChannel);
2924    
2925            return lscp_client_query(pClient, szQuery);
2926  }  }
2927    
2928    

Legend:
Removed from v.952  
changed lines
  Added in v.1806

  ViewVC Help
Powered by ViewVC