/[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 1031 by capela, Mon Jan 15 11:08:28 2007 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-2007, 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 578  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     *  @e Caution: since liblscp v0.5.5.4 you have to call lscp_client_subscribe()
622     *  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   *  SUBSCRIBE CHANNEL_COUNT | VOICE_COUNT | STREAM_COUNT
628   *      | BUFFER_FILL | CHANNEL_INFO | TOTAL_VOICE_COUNT   *      | BUFFER_FILL | CHANNEL_INFO | TOTAL_VOICE_COUNT
629   *      | AUDIO_OUTPUT_DEVICE_COUNT | AUDIO_OUTPUT_DEVICE_INFO   *      | AUDIO_OUTPUT_DEVICE_COUNT | AUDIO_OUTPUT_DEVICE_INFO
# Line 586  int lscp_client_get_errno ( lscp_client_ Line 631  int lscp_client_get_errno ( lscp_client_
631   *      | MIDI_INSTRUMENT_MAP_COUNT | MIDI_INSTRUMENT_MAP_INFO   *      | MIDI_INSTRUMENT_MAP_COUNT | MIDI_INSTRUMENT_MAP_INFO
632   *      | MIDI_INSTRUMENT_COUNT | MIDI_INSTRUMENT_INFO   *      | MIDI_INSTRUMENT_COUNT | MIDI_INSTRUMENT_INFO
633   *      | MISCELLANEOUS   *      | 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 637  lscp_status_t lscp_client_subscribe ( ls Line 690  lscp_status_t lscp_client_subscribe ( ls
690                  ret = _lscp_client_evt_request(pClient, 1, LSCP_EVENT_MIDI_INSTRUMENT_INFO);                  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 646  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     *  @e Caution: since liblscp v0.5.5.4 you have to call
717     *  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   *  UNSUBSCRIBE CHANNEL_COUNT | VOICE_COUNT | STREAM_COUNT
724   *      | BUFFER_FILL | CHANNEL_INFO | TOTAL_VOICE_COUNT   *      | BUFFER_FILL | CHANNEL_INFO | TOTAL_VOICE_COUNT
725   *      | AUDIO_OUTPUT_DEVICE_COUNT | AUDIO_OUTPUT_DEVICE_INFO   *      | AUDIO_OUTPUT_DEVICE_COUNT | AUDIO_OUTPUT_DEVICE_INFO
# Line 654  lscp_status_t lscp_client_subscribe ( ls Line 727  lscp_status_t lscp_client_subscribe ( ls
727   *      | MIDI_INSTRUMENT_MAP_COUNT | MIDI_INSTRUMENT_MAP_INFO   *      | MIDI_INSTRUMENT_MAP_COUNT | MIDI_INSTRUMENT_MAP_INFO
728   *      | MIDI_INSTRUMENT_COUNT | MIDI_INSTRUMENT_INFO   *      | MIDI_INSTRUMENT_COUNT | MIDI_INSTRUMENT_INFO
729   *      | MISCELLANEOUS   *      | 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 701  lscp_status_t lscp_client_unsubscribe ( Line 782  lscp_status_t lscp_client_unsubscribe (
782                  ret = _lscp_client_evt_request(pClient, 0, LSCP_EVENT_MIDI_INSTRUMENT_INFO);                  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 1053  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)          if (pClient == NULL)
1153                  return NULL;                  return NULL;
# Line 1065  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 1149  lscp_channel_info_t *lscp_get_channel_in Line 1246  lscp_channel_info_t *lscp_get_channel_in
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 1166  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 1580  lscp_status_t lscp_set_channel_midi_map Line 1679  lscp_status_t lscp_set_channel_midi_map
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.0f)          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 1668  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...          // 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 1801  int lscp_get_total_voice_count_max ( lsc Line 1904  int lscp_get_total_voice_count_max ( lsc
1904  float lscp_get_volume ( lscp_client_t *pClient )  float lscp_get_volume ( lscp_client_t *pClient )
1905  {  {
1906          float fVolume = 0.0f;          float fVolume = 0.0f;
1907            struct _locale_t locale;
1908    
1909          if (pClient == NULL)          if (pClient == NULL)
1910                  return 0.0f;                  return 0.0f;
# Line 1808  float lscp_get_volume ( lscp_client_t *p Line 1912  float lscp_get_volume ( lscp_client_t *p
1912          // Lock this section up.          // Lock this section up.
1913          lscp_mutex_lock(pClient->mutex);          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)          if (lscp_client_call(pClient, "GET VOLUME\r\n", 0) == LSCP_OK)
1918                  fVolume = (float) atof(lscp_client_get_result(pClient));                  fVolume = _atof(lscp_client_get_result(pClient));
1919    
1920            _restore_locale(&locale);
1921    
1922          // Unlock this section down.          // Unlock this section down.
1923          lscp_mutex_unlock(pClient->mutex);          lscp_mutex_unlock(pClient->mutex);
# Line 1832  float lscp_get_volume ( lscp_client_t *p Line 1940  float lscp_get_volume ( lscp_client_t *p
1940  lscp_status_t lscp_set_volume ( lscp_client_t *pClient, float fVolume )  lscp_status_t lscp_set_volume ( lscp_client_t *pClient, float fVolume )
1941  {  {
1942          char szQuery[LSCP_BUFSIZ];          char szQuery[LSCP_BUFSIZ];
1943            struct _locale_t locale;
1944    
1945          if (fVolume < 0.0f)          if (fVolume < 0.0f)
1946                  return LSCP_FAILED;                  return LSCP_FAILED;
1947    
1948            _save_and_set_c_locale(&locale);
1949          sprintf(szQuery, "SET VOLUME %g\r\n", fVolume);          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);          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:   *  Add an effect send to a sampler channel:
# Line 1868  int lscp_create_fxsend ( lscp_client_t * Line 2103  int lscp_create_fxsend ( lscp_client_t *
2103          lscp_mutex_lock(pClient->mutex);          lscp_mutex_lock(pClient->mutex);
2104    
2105          sprintf(szQuery, "CREATE FX_SEND %d %d", iSamplerChannel, iMidiController);          sprintf(szQuery, "CREATE FX_SEND %d %d", iSamplerChannel, iMidiController);
2106            
2107          if (pszFxName)          if (pszFxName)
2108                  sprintf(szQuery + strlen(szQuery), " '%s'", pszFxName);                  sprintf(szQuery + strlen(szQuery), " '%s'", pszFxName);
2109    
# Line 2000  lscp_fxsend_info_t *lscp_get_fxsend_info Line 2235  lscp_fxsend_info_t *lscp_get_fxsend_info
2235          const char *pszCrlf = "\r\n";          const char *pszCrlf = "\r\n";
2236          char *pszToken;          char *pszToken;
2237          char *pch;          char *pch;
2238            struct _locale_t locale;
2239    
2240          if (pClient == NULL)          if (pClient == NULL)
2241                  return NULL;                  return NULL;
# Line 2009  lscp_fxsend_info_t *lscp_get_fxsend_info Line 2245  lscp_fxsend_info_t *lscp_get_fxsend_info
2245          // Lock this section up.          // Lock this section up.
2246          lscp_mutex_lock(pClient->mutex);          lscp_mutex_lock(pClient->mutex);
2247    
2248            _save_and_set_c_locale(&locale);
2249    
2250          pFxSendInfo = &(pClient->fxsend_info);          pFxSendInfo = &(pClient->fxsend_info);
2251          lscp_fxsend_info_reset(pFxSendInfo);          lscp_fxsend_info_reset(pFxSendInfo);
2252    
# Line 2038  lscp_fxsend_info_t *lscp_get_fxsend_info Line 2276  lscp_fxsend_info_t *lscp_get_fxsend_info
2276                          else if (strcasecmp(pszToken, "LEVEL") == 0) {                          else if (strcasecmp(pszToken, "LEVEL") == 0) {
2277                                  pszToken = lscp_strtok(NULL, pszCrlf, &(pch));                                  pszToken = lscp_strtok(NULL, pszCrlf, &(pch));
2278                                  if (pszToken)                                  if (pszToken)
2279                                          pFxSendInfo->level = (float) atof(lscp_ltrim(pszToken));                                          pFxSendInfo->level = _atof(lscp_ltrim(pszToken));
2280                          }                          }
2281                          pszToken = lscp_strtok(NULL, pszSeps, &(pch));                          pszToken = lscp_strtok(NULL, pszSeps, &(pch));
2282                  }                  }
2283          }          }
2284          else pFxSendInfo = NULL;          else pFxSendInfo = NULL;
2285    
2286            _restore_locale(&locale);
2287    
2288          // Unlock this section up.          // Unlock this section up.
2289          lscp_mutex_unlock(pClient->mutex);          lscp_mutex_unlock(pClient->mutex);
2290    
2291          return pFxSendInfo;          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:   *  Alter effect send's audio routing:
# Line 2096  lscp_status_t lscp_set_fxsend_midi_contr Line 2359  lscp_status_t lscp_set_fxsend_midi_contr
2359          if (iSamplerChannel < 0 || iFxSend < 0 || iMidiController < 0 || iMidiController > 127)          if (iSamplerChannel < 0 || iFxSend < 0 || iMidiController < 0 || iMidiController > 127)
2360                  return LSCP_FAILED;                  return LSCP_FAILED;
2361    
2362          sprintf(szQuery, "SET FX_SEND MIDI_CONTROLLER %d %d %d %d\r\n", iSamplerChannel, iFxSend, iMidiController);          sprintf(szQuery, "SET FX_SEND MIDI_CONTROLLER %d %d %d\r\n", iSamplerChannel, iFxSend, iMidiController);
2363          return lscp_client_query(pClient, szQuery);          return lscp_client_query(pClient, szQuery);
2364  }  }
2365    
# Line 2115  lscp_status_t lscp_set_fxsend_midi_contr Line 2378  lscp_status_t lscp_set_fxsend_midi_contr
2378  lscp_status_t lscp_set_fxsend_level ( lscp_client_t *pClient, int iSamplerChannel, int iFxSend, float fLevel )  lscp_status_t lscp_set_fxsend_level ( lscp_client_t *pClient, int iSamplerChannel, int iFxSend, float fLevel )
2379  {  {
2380          char szQuery[LSCP_BUFSIZ];          char szQuery[LSCP_BUFSIZ];
2381            struct _locale_t locale;
2382    
2383          if (iSamplerChannel < 0 || iFxSend < 0 || fLevel < 0.0f)          if (iSamplerChannel < 0 || iFxSend < 0 || fLevel < 0.0f)
2384                  return LSCP_FAILED;                  return LSCP_FAILED;
2385    
2386          sprintf(szQuery, "SET FX_SEND LEVEL %d %d %d %g\r\n", iSamplerChannel, iFxSend, fLevel);          _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);          return lscp_client_query(pClient, szQuery);
2391  }  }
2392    
# Line 2146  int lscp_add_midi_instrument_map ( lscp_ Line 2413  int lscp_add_midi_instrument_map ( lscp_
2413          lscp_mutex_lock(pClient->mutex);          lscp_mutex_lock(pClient->mutex);
2414    
2415          strcpy(szQuery, "ADD MIDI_INSTRUMENT_MAP");          strcpy(szQuery, "ADD MIDI_INSTRUMENT_MAP");
2416            
2417          if (pszMapName)          if (pszMapName)
2418                  sprintf(szQuery + strlen(szQuery), " '%s'", pszMapName);                  sprintf(szQuery + strlen(szQuery), " '%s'", pszMapName);
2419    
# Line 2272  const char *lscp_get_midi_instrument_map Line 2539  const char *lscp_get_midi_instrument_map
2539    
2540          // Lock this section up.          // Lock this section up.
2541          lscp_mutex_lock(pClient->mutex);          lscp_mutex_lock(pClient->mutex);
2542            
2543          if (pClient->midi_map_name) {          if (pClient->midi_map_name) {
2544                  free(pClient->midi_map_name);                  free(pClient->midi_map_name);
2545                  pClient->midi_map_name = NULL;                  pClient->midi_map_name = NULL;
# Line 2336  lscp_status_t lscp_set_midi_instrument_m Line 2603  lscp_status_t lscp_set_midi_instrument_m
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 2351  lscp_status_t lscp_set_midi_instrument_m Line 2618  lscp_status_t lscp_set_midi_instrument_m
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    
2623          if (pMidiInstr->map < 0)          if (pMidiInstr->map < 0)
2624                  return LSCP_FAILED;                  return LSCP_FAILED;
# Line 2364  lscp_status_t lscp_map_midi_instrument ( Line 2632  lscp_status_t lscp_map_midi_instrument (
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->map, pMidiInstr->bank, pMidiInstr->prog,                  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:
# Line 2523  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    
2798          if (pClient == NULL)          if (pClient == NULL)
2799                  return NULL;                  return NULL;
# Line 2535  lscp_midi_instrument_info_t *lscp_get_mi Line 2806  lscp_midi_instrument_info_t *lscp_get_mi
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    
# Line 2589  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    
# Line 2627  lscp_status_t lscp_clear_midi_instrument Line 2902  lscp_status_t lscp_clear_midi_instrument
2902    
2903          return lscp_client_query(pClient, szQuery);          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            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    
2929  // end of client.c  // end of client.c

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

  ViewVC Help
Powered by ViewVC