SOUND4 BIGVOICE.CL Library [1.0.3]
sound4cl.hpp
Go to the documentation of this file.
1 
8 #pragma once
9 
10 #include <string>
11 #include <exception>
12 #include <thread>
13 #include <functional>
14 #include <memory>
15 #include <array>
16 #include <assert.h>
17 #include <stdexcept>
18 #include <filesystem>
19 #include <string.h>
20 
21 #ifdef __unix__
22  #include <dlfcn.h>
23 #elif defined(_WIN32)
24  #include <libloaderapi.h>
25 #else
26  #error "Unsupported OS"
27 #endif
28 
29 #include "sound4cl_cdef.h"
30 
31  // bridge C callbacks to CPresetLoader
32  extern "C" {
33  static char *sound4cl_custom_reader(const fs_char *filename, void* userdata);
34  static void sound4cl_custom_reader_free(char *content, void* userdata);
35  static int sound4cl_custom_writer(const fs_char *filename, const char *content, void* userdata);
36  static int sound4cl_custom_exists(const fs_char *filename, void* userdata);
37  static fs_char** sound4cl_custom_getall(void* userdata);
38  static void sound4cl_custom_getall_free(fs_char** all, void* userdata);
39  static int sound4cl_custom_remove(const fs_char *filename, void* userdata);
40  static int sound4cl_custom_rename(const fs_char *from, const fs_char *to, void* userdata);
41  };
42 
46 namespace sound4 {
47 
51  namespace helper {
52  #ifdef _WIN32
58  static inline std::string WStringToUTF8(const std::wstring& wstr) {
59  if (wstr.empty()) return {};
60  int size = WideCharToMultiByte(CP_UTF8, 0, &wstr[0], (int)wstr.size(), NULL, 0, NULL, NULL);
61  std::string str(size, 0);
62  WideCharToMultiByte(CP_UTF8, 0, &wstr[0], (int)wstr.size(), &str[0], size, NULL, NULL);
63  return str;
64  }
70  static inline std::wstring UTF8ToWString(const std::string& str) {
71  if (str.empty()) return std::wstring();
72  int size = MultiByteToWideChar(CP_UTF8, 0, &str[0], (int)str.size(), NULL, 0);
73  std::wstring wstr(size, 0);
74  MultiByteToWideChar(CP_UTF8, 0, &str[0], (int)str.size(), &wstr[0], size);
75  return wstr;
76  }
77  #endif // _WIN32
78 
84  template<typename T>
85  struct SampleFormat {
86  };
87  template<>
88  struct SampleFormat<int16_t> {
90  };
91  template<>
92  struct SampleFormat<int32_t> {
94  };
95  template<>
96  struct SampleFormat<float> {
98  };
99 
100  // Storage definition, depending on OS
101  #ifdef __unix__
102  using DynLib_t = void *;
103  using DynFunc_t = void *;
104  #else
105  using DynLib_t = HMODULE;
106  using DynFunc_t = FARPROC;
107  #endif
108 
114  template <typename T>
116  private:
117  DynFunc_t m_ptr = NULL;
118  public:
119  DynFuncHolder() = default;
120  DynFuncHolder(DynFunc_t a_ptr) : m_ptr(a_ptr) {}
121  operator bool() const { return (m_ptr!=NULL); }
122  bool IsOk() const { return m_ptr!=NULL; }
123  operator T* () const { return reinterpret_cast<T*>(m_ptr); }
124  };
125 
130  class CDynLoader {
131  private:
132  DynLib_t m_lib {};
133  public:
134  CDynLoader() = default;
135  CDynLoader(CDynLoader&&) = default;
136  // No copy allowed
137  CDynLoader(const CDynLoader&) = delete;
138  CDynLoader& operator=(CDynLoader const&) = delete;
139  operator bool() const {
140  return (m_lib!=NULL);
141  }
142  bool IsOk() const {
143  return (m_lib!=NULL);
144  }
145  #ifdef __unix__
146  void Close() {
147  if (IsOk()) {
148  #ifndef __SANITIZE_ADDRESS__ // avoid unloading to keep call stack
149  dlclose(m_lib);
150  #endif // __SANITIZE_ADDRESS__
151  m_lib=NULL;
152  }
153  }
154  bool Load(const std::filesystem::path& dynlib)
155  {
156  Close();
157  m_lib=dlopen(dynlib.c_str(), RTLD_NOW|RTLD_LOCAL);
158  return IsOk();
159  }
160  template <typename T>
161  DynFuncHolder<T> GetSymbol(const std::string& name) {
162  auto ptr=dlsym(m_lib, name.c_str());
163  if (!ptr) {
164  throw std::runtime_error("Missing function in library");
165  }
166  return DynFuncHolder<T>(ptr);
167  }
168  template <typename T>
169  DynFuncHolder<T> GetSymbol_safe(const std::string& name) {
170  auto ptr=dlsym(m_lib, name.c_str());
171  return DynFuncHolder<T>(ptr);
172  }
173  static std::filesystem::path GetThisLibraryPath(void) {
174  static Dl_info info;
175  if (! dladdr((void *) GetThisLibraryPath, & info)) return {};
176  auto rp=realpath(info.dli_fname, NULL);
177  std::filesystem::path p(rp);
178  free(rp);
179  return p;
180  }
181  #else
182  bool Load(const std::filesystem::path& dynlib, uint32_t loadflags = LOAD_LIBRARY_SEARCH_DLL_LOAD_DIR|LOAD_LIBRARY_SEARCH_APPLICATION_DIR|LOAD_LIBRARY_SEARCH_USER_DIRS|LOAD_LIBRARY_SEARCH_SYSTEM32)
183  {
184  Close();
185  m_lib=LoadLibraryExW(dynlib.c_str(), NULL, loadflags);
186  return IsOk();
187  }
188  void Close() {
189  if (IsOk()) {
190  // NOTE: On Windows, FreeLibrary may create a lot of troubles, should use FreeLibraryAndExitThread but...
191  // So define SOUND4_CALL_FREELIBRARY before including this file if you really want to unload the library dynamically
192  #if defined(SOUND4_CALL_FREELIBRARYANDEXITTHREAD)
193  FreeLibraryAndExitThread(m_lib, 0);
194  #elif defined(SOUND4_CALL_FREELIBRARY)
195  FreeLibrary(m_lib);
196  #endif // SOUND4_CALL_FREELIBRARY
197  m_lib=NULL;
198  }
199  }
200  template <typename T>
201  DynFuncHolder<T> GetSymbol(const std::string& name) {
202  auto ptr=GetProcAddress(m_lib, name.c_str());
203  if (!ptr) {
204  throw std::runtime_error("Missing function in library");
205  }
206  return DynFuncHolder<T>(ptr);
207  }
208  template <typename T>
209  DynFuncHolder<T> GetSymbol_safe(const std::string& name) {
210  auto ptr=GetProcAddress(m_lib, name.c_str());
211  return DynFuncHolder<T>(ptr);
212  }
213  static std::filesystem::path GetThisLibraryPath(void) {
214  static wchar_t path[MAX_PATH]={};
215  HMODULE hm = NULL;
216  if (GetModuleHandleExW(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS |
217  GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT,
218  (LPCWSTR) &GetThisLibraryPath, &hm))
219  {
220  if (GetModuleFileNameW(hm, path, MAX_PATH) > 0) {
221  return std::filesystem::path(path);
222  }
223  }
224  return {};
225  }
226  #endif
227  virtual ~CDynLoader() {
228  Close();
229  }
230  }; // class CDynLoader
231  }; // namespace helper
232 
233 
248 
252  using log_cb_t = std::function<void(LogSeverity,const std::string&)>;
253 
257  static log_cb_t _log_cb;
258  extern "C" {
259  static inline void _log_cb_c(LogSeverity severity, const char *c_msg) {
260  _log_cb(severity, std::string(c_msg));
261  }
262  }
263 
270  class CProcessor {
271  private:
272  helper::CDynLoader m_lib;
273  bool m_bOK = false;
274  std::string m_prefix; // The prefix of functions, depends on the library (cloud_, impact_...)
275  protected:
276  friend class CBus;
277  friend class CInstance;
278 
279  // All those wrapped functions have the same signature as there C sound4cl_XXX
324 
325  // only for processes supporting webserver
331 
332  // added 2023-03-22
335 
336  // added 2023-05-22
340 
341  // added 2023-06-20
344 
345  // added 2023-09-21
349 
350  // added 2023-06-26, only for processes supporting bus
354 
355  // added 2024-02-19
357 
358  template <typename T>
359  helper::DynFuncHolder<T> GetPrefixSymbol(const std::string& name) {
360  std::string prefix_name = m_prefix+name;
361  return m_lib.GetSymbol<T>(prefix_name);
362  }
363 
364  public:
365  CProcessor() = default;
366 
374  bool Load(const std::filesystem::path& filepath) {
375  m_lib.Close();
376  // If a path is given, use it directly and do not try other path
377  if (filepath.has_parent_path() && !m_lib.Load(filepath)) {
378  return false;
379  } else if (!m_lib.IsOk()) {
380  auto thisdir=helper::CDynLoader::GetThisLibraryPath().parent_path();
381  auto filename = filepath.filename();
382  #ifndef _WIN32
383  // Linux: if in a bin directory, try ../lib first
384  if (!m_lib.IsOk() && thisdir.filename()=="bin") {
385  auto libdir = thisdir.parent_path() / "lib";
386  m_lib.Load(libdir / filename);
387  }
388  #endif // !_WIN32
389  if (!m_lib.IsOk()) {
390  // Search in the same directory this code is in
391  m_lib.Load(thisdir / filename);
392  }
393  if (!m_lib.IsOk()) {
394  // Try current path
395  m_lib.Load(std::filesystem::current_path() / filename);
396  }
397  if (!m_lib.IsOk()) {
398  return false;
399  }
400  }
401  // Get information from the library itself
402  try {
403  auto GetInfo = m_lib.GetSymbol< decltype(sound4cl_SOUND4_GetProcessInfo ) >("SOUND4_GetProcessInfo" );
404  auto info = GetInfo();
405  m_prefix = info->prefix;
406  } catch (std::runtime_error& ) {
407  // Compatibility: search in known libraries without this function
408  #ifdef _WIN32
409  std::string filename = helper::WStringToUTF8(filepath.stem());
410  #else // !_WIN32
411  std::string filename = filepath.stem();
412  // remove lib prefix
413  filename=filename.substr(3);
414  #endif // ! _WIN32
415  if (filename=="sound4.x1.cloud") {
416  m_prefix="cloudx1_";
417  } else if (filename=="sound4.impact.cl") {
418  m_prefix="impact_";
419  } else if (filename=="sound4.bigvoice.cl") {
420  m_prefix="bigvoice_";
421  } else {
422  return false;
423  }
424  }
425 
426  // Load all C functions
427  try {
428  fnGetVersion = GetPrefixSymbol< decltype(sound4cl_GetVersion ) >("GetVersion" );
429  fnGetChunkSizeInFrames = GetPrefixSymbol< decltype(sound4cl_GetChunkSizeInFrames ) >("GetChunkSizeInFrames" );
430  fnGetChannelCount = GetPrefixSymbol< decltype(sound4cl_GetChannelCount ) >("GetChannelCount" );
431  fnGetAudioInputCount = GetPrefixSymbol< decltype(sound4cl_GetAudioInputCount ) >("GetAudioInputCount" );
432  fnGetAudioOutputCount = GetPrefixSymbol< decltype(sound4cl_GetAudioOutputCount ) >("GetAudioOutputCount" );
433  fnGetSampleRate = GetPrefixSymbol< decltype(sound4cl_GetSampleRate ) >("GetSampleRate" );
434  fnSetLoggerCallback = GetPrefixSymbol< decltype(sound4cl_SetLoggerCallback ) >("SetLoggerCallback" );
435  fnSetLogSeverity = GetPrefixSymbol< decltype(sound4cl_SetLogSeverity ) >("SetLogSeverity" );
436  fnNewParameters = GetPrefixSymbol< decltype(sound4cl_NewParameters ) >("NewParameters" );
437  fnFreeParameters = GetPrefixSymbol< decltype(sound4cl_FreeParameters ) >("FreeParameters" );
438  fnSetParameter = GetPrefixSymbol< decltype(sound4cl_SetParameter ) >("SetParameter" );
439  fnGetParameter = GetPrefixSymbol< decltype(sound4cl_GetParameter ) >("GetParameter" );
440  fnFreeParameterValue = GetPrefixSymbol< decltype(sound4cl_FreeParameterValue ) >("FreeParameterValue" );
441  fnInitProcess = GetPrefixSymbol< decltype(sound4cl_InitProcess ) >("InitProcess" );
442  fnInitProcess2 = GetPrefixSymbol< decltype(sound4cl_InitProcess2 ) >("InitProcess2" );
443  fnTerminateProcess = GetPrefixSymbol< decltype(sound4cl_TerminateProcess ) >("TerminateProcess" );
444  fnExitProcess = GetPrefixSymbol< decltype(sound4cl_ExitProcess ) >("ExitProcess" );
445  fnStartUpdateThread = GetPrefixSymbol< decltype(sound4cl_StartUpdateThread ) >("StartUpdateThread" );
446  fnStopUpdateThread = GetPrefixSymbol< decltype(sound4cl_StopUpdateThread ) >("StopUpdateThread" );
447  fnWaitUpdateThreadReady = GetPrefixSymbol< decltype(sound4cl_WaitUpdateThreadReady ) >("WaitUpdateThreadReady" );
448  fnProcessAudio = GetPrefixSymbol< decltype(sound4cl_ProcessAudio ) >("ProcessAudio" );
449  fnProcessAudio_Planar = GetPrefixSymbol< decltype(sound4cl_ProcessAudio_Planar ) >("ProcessAudio_Planar" );
450  fnGetBufferIn = GetPrefixSymbol< decltype(sound4cl_GetBufferIn ) >("GetBufferIn" );
451  fnGetBufferOut = GetPrefixSymbol< decltype(sound4cl_GetBufferOut ) >("GetBufferOut" );
452  fnGetEstimatedDelay = GetPrefixSymbol< decltype(sound4cl_GetEstimatedDelay ) >("GetEstimatedDelay" );
453  fnGetFormatName = GetPrefixSymbol< decltype(sound4cl_GetFormatName ) >("GetFormatName" );
454  fnGetFormatFromName = GetPrefixSymbol< decltype(sound4cl_GetFormatFromName ) >("GetFormatFromName" );
455  fnGetBytesFromFormat = GetPrefixSymbol< decltype(sound4cl_GetBytesFromFormat ) >("GetBytesFromFormat" );
456  fnGetMaxPacketFrame = GetPrefixSymbol< decltype(sound4cl_GetMaxPacketFrame ) >("GetMaxPacketFrame" );
457  fnAddAudio = GetPrefixSymbol< decltype(sound4cl_AddAudio ) >("AddAudio" );
458  fnAddPadAudio = GetPrefixSymbol< decltype(sound4cl_AddPadAudio ) >("AddPadAudio" );
459  fnGetOutputCount = GetPrefixSymbol< decltype(sound4cl_GetOutputCount ) >("GetOutputCount" );
460  fnGetAudio = GetPrefixSymbol< decltype(sound4cl_GetAudio ) >("GetAudio" );
461  fnAudioConvertFrom = GetPrefixSymbol< decltype(sound4cl_AudioConvertFrom ) >("AudioConvertFrom" );
462  fnAudioConvertTo = GetPrefixSymbol< decltype(sound4cl_AudioConvertTo ) >("AudioConvertTo" );
463  fnStereoToMono = GetPrefixSymbol< decltype(sound4cl_StereoToMono ) >("StereoToMono" );
464  fnMonoToStereo = GetPrefixSymbol< decltype(sound4cl_MonoToStereo ) >("MonoToStereo" );
465  fnAudioMonoFromLiveStereo = GetPrefixSymbol< decltype(sound4cl_AudioMonoFromLiveStereo) >("AudioMonoFromLiveStereo");
466  fnAudioMonoToLiveStereo = GetPrefixSymbol< decltype(sound4cl_AudioMonoToLiveStereo ) >("AudioMonoToLiveStereo" );
467  fnNewClient = GetPrefixSymbol< decltype(sound4cl_NewClient ) >("NewClient" );
468  fnDeleteClient = GetPrefixSymbol< decltype(sound4cl_DeleteClient ) >("DeleteClient" );
469  fnProcessJson = GetPrefixSymbol< decltype(sound4cl_ProcessJson ) >("ProcessJson" );
470  fnFreeJsonAnswer = GetPrefixSymbol< decltype(sound4cl_FreeJsonAnswer ) >("FreeJsonAnswer" );
471  fnSaveState = GetPrefixSymbol< decltype(sound4cl_SaveState ) >("SaveState" );
472  } catch (std::runtime_error& ) {
473  return false;
474  }
475  // Webserver : not for all projects
476  try {
477  fnWebserver_tcp = GetPrefixSymbol< decltype(sound4cl_Webserver_tcp ) >("Webserver_tcp" );
478  fnWebserver_tcp2 = GetPrefixSymbol< decltype(sound4cl_Webserver_tcp2 ) >("Webserver_tcp2" );
479  fnWebserver = GetPrefixSymbol< decltype(sound4cl_Webserver ) >("Webserver" );
480  fnWebserver_Stop = GetPrefixSymbol< decltype(sound4cl_Webserver_Stop ) >("Webserver_Stop" );
481  fnWebserver_Status = GetPrefixSymbol< decltype(sound4cl_Webserver_Status ) >("Webserver_Status" );
482  } catch (std::runtime_error& ) {
483  // Ignored, handler will take care
484  }
485  // Stereo/Mono conversion : must be present
486  try {
487  // added 2023-03-22
488  fnStereoToMono_Planar = GetPrefixSymbol< decltype(sound4cl_StereoToMono_Planar ) >("StereoToMono_Planar" );
489  fnMonoToStereo_Planar = GetPrefixSymbol< decltype(sound4cl_MonoToStereo_Planar ) >("MonoToStereo_Planar" );
490 
491  } catch (std::runtime_error& ) {
492  return false;
493  }
494  // C functions allowed to be missing
495  try {
496  // added 2023-05-22
497  fnSetMetadata = GetPrefixSymbol< decltype(sound4cl_SetMetadata ) >("SetMetadata" );
498  fnGetMetadataInfos = GetPrefixSymbol< decltype(sound4cl_GetMetadataInfos ) >("GetMetadataInfos" );
499  fnFreeMetadataInfos = GetPrefixSymbol< decltype(sound4cl_FreeMetadataInfos ) >("FreeMetadataInfos" );
500  // added 2023-06-20
501  fnSetPresetManager = GetPrefixSymbol< decltype(sound4cl_SetPresetManager ) >("SetPresetManager" );
502  fnPresetManager_InformChange = GetPrefixSymbol< decltype(sound4cl_PresetManager_InformChange ) >("PresetManager_InformChange" );
503 
504  // added 2023-09-21
505  fnGetPossibleChunkSizeInFrames = GetPrefixSymbol< decltype(sound4cl_GetPossibleChunkSizeInFrames ) >("GetPossibleChunkSizeInFrames" );
506  fnGetProcessChunkFrames = GetPrefixSymbol< decltype(sound4cl_GetProcessChunkFrames ) >("GetProcessChunkFrames" );
507  fnInitProcess3 = GetPrefixSymbol< decltype(sound4cl_InitProcess3 ) >("InitProcess3" );
508  } catch (std::runtime_error& ) {
509  // Ignored, handler will take care
510  }
511 
512  // bus: not for all projects
513  try {
514  // added 2023-06-26
515  fnNewBus = GetPrefixSymbol< decltype(sound4cl_NewBus ) >("NewBus" );
516  fnFreeBus = GetPrefixSymbol< decltype(sound4cl_FreeBus ) >("FreeBus" );
517  fnSetInstanceBus = GetPrefixSymbol< decltype(sound4cl_SetInstanceBus ) >("SetInstanceBus" );
518  } catch (std::runtime_error& ) {
519  // Ignored, handler will take care
520  }
521 
522  // Other optional
523  try {
524  // added 2024-02-19
525  fnSetMetadataMulti = GetPrefixSymbol< decltype(sound4cl_SetMetadataMulti ) >("SetMetadataMulti" );
526 
527  } catch (std::runtime_error& ) {
528  // Ignored, handler will take care
529  }
530 
531  m_bOK=true;
532  return true;
533  }
540  bool IsOk() const {
541  return m_bOK;
542  }
543 
548  void AudioConvertFrom(const uint8_t *payload, float *output, size_t nSpl, sound4cl_SampleFormat fmt)
549  { fnAudioConvertFrom(payload, output, nSpl, fmt); }
550  void AudioConvertTo(const float *input, uint8_t *payload, size_t nSpl, sound4cl_SampleFormat fmt)
551  { fnAudioConvertTo(input, payload, nSpl, fmt); }
552  void StereoToMono(const float *input, float *output, size_t nSpl)
553  { fnStereoToMono(input, output, nSpl); }
554  void MonoToStereo(const float *input, float *output, size_t nSpl)
555  { fnMonoToStereo(input, output, nSpl); }
556  void StereoToMono_Planar(const float *inputL, const float *inputR, float *output, size_t nSpl)
557  { fnStereoToMono_Planar(inputL, inputR, output, nSpl); }
558  void MonoToStereo_Planar(const float *input, float *outputL, float *outputR, size_t nSpl)
559  { fnMonoToStereo_Planar(input, outputL, outputR, nSpl); }
560  void AudioMonoFromLiveStereo(const uint8_t *payload, float *output)
561  { fnAudioMonoFromLiveStereo(payload, output); }
562  void AudioMonoToLiveStereo(const float *input, uint8_t *payload)
563  { fnAudioMonoToLiveStereo(input, payload); }
564 
570  std::string GetVersion()
571  { return std::string(fnGetVersion()); }
572 
581  unsigned int GetChunkSizeInFrames()
582  { return fnGetChunkSizeInFrames(); }
583 
592  std::vector<unsigned int> GetPossibleChunkSizeInFrames()
593  {
594  std::vector<unsigned int> list;
596  for (unsigned int* src=fnGetPossibleChunkSizeInFrames();*src;src++) {
597  list.push_back(*src);
598  }
599  } else {
600  list.push_back(fnGetChunkSizeInFrames());
601  }
602  return list;
603  }
604 
610  unsigned int GetChannelCount()
611  { return fnGetChannelCount(); }
612 
620  unsigned int GetAudioInputCount()
621  { return fnGetAudioInputCount(); }
622 
630  unsigned int GetAudioOutputCount()
631  { return fnGetAudioOutputCount(); }
632 
640  unsigned int GetSampleRate()
641  { return fnGetSampleRate(); }
642 
649  std::string GetFormatName( const sound4cl_SampleFormat fmt)
650  { return std::string(fnGetFormatName(fmt)); }
651 
658  sound4cl_SampleFormat GetFormatFromName( const std::string& name)
659  { return fnGetFormatFromName(name.c_str()); }
660 
667  unsigned int GetBytesFromFormat( const sound4cl_SampleFormat fmt)
668  { return fnGetBytesFromFormat(fmt); }
669 
674  { fnSetLogSeverity(severity); }
675 
680  { _log_cb=cb; fnSetLoggerCallback(&_log_cb_c); }
681  };
682 
688  class CBus {
689  public:
690  CBus(CProcessor& dynlib)
691  : m_dynlib(dynlib)
692  {
693  if (m_dynlib.fnNewBus) {
694  m_bus=m_dynlib.fnNewBus();
695  }
696  }
698  {
699  if (m_bus && m_dynlib.fnFreeBus) {
700  m_dynlib.fnFreeBus(m_bus);
701  }
702  m_bus = nullptr;
703  }
704  sound4cl_CBus *Get() const { return m_bus; }
705  private:
706  CProcessor& m_dynlib;
707  sound4cl_CBus *m_bus;
708  };
709 
716  public:
717  CPresetLoader() = default;
718  virtual ~CPresetLoader() = default;
719 
720  virtual bool IsReadOnly() = 0;
721  virtual bool Exists(const std::filesystem::path &name) = 0;
722  virtual bool Remove(const std::filesystem::path &name) = 0;
723  virtual bool Rename(const std::filesystem::path &from, const std::filesystem::path &to) = 0;
724  virtual std::vector<std::filesystem::path> GetAll() = 0;
725  virtual std::string Read(const std::filesystem::path &filename) = 0;
726  virtual bool Write(const std::filesystem::path &filename, const std::string &content) =0;
727  };
729 
735  class CInstance {
736  public:
741  : m_dynlib(dynlib)
742  {
743  params = m_dynlib.fnNewParameters();
744  if (!params) throw std::bad_alloc();
745  }
746  // non-copyable
747  CInstance( const CInstance& ) = delete;
748  CInstance& operator=( const CInstance& ) = delete;
753  {
754  Stop();
755  if (params) m_dynlib.fnFreeParameters(params);
756  }
760  bool IsOk() const { return instance!=nullptr; }
768  void SetParam(const std::string& name, const std::string& value)
769  {
770  assert(params);
771  m_dynlib.fnSetParameter(params, name.c_str(), value.c_str());
772  }
778  std::string GetParam(const std::string& name)
779  {
780  assert(params);
781  auto c_value=m_dynlib.fnGetParameter(params, name.c_str());
782  std::string ret(c_value);
783  m_dynlib.fnFreeParameterValue(c_value);
784  return ret;
785  }
786 
790  void SetBus(const CBus& bus) {
791  assert(params);
792  if (m_dynlib.fnSetInstanceBus) {
793  m_dynlib.fnSetInstanceBus(params,bus.Get());
794  }
795  }
796 
806  void SetPresetManager(CPresetLoader *preset_manager)
807  {
808  if (!preset_manager) return;
809  if (!m_dynlib.fnSetPresetManager) return;
810  assert(params);
811  m_dynlib.fnSetPresetManager(params,
812  sound4cl_custom_reader,
813  sound4cl_custom_reader_free,
814  sound4cl_custom_writer,
815  sound4cl_custom_exists,
816  sound4cl_custom_getall,
817  sound4cl_custom_getall_free,
818  sound4cl_custom_remove,
819  sound4cl_custom_rename,
820  preset_manager->IsReadOnly(),
821  preset_manager
822  );
823  }
824 
839  bool Create(const std::string& LoginKey, const std::string& RadioName, const std::string& Access_Key_ID, const std::string& Access_Key_Secret, const std::filesystem::path& save_path, int json_port = 0, unsigned int frames_per_chunk=0)
840  {
841  assert(!instance);
842  std::string l_save_path;
843  if (!save_path.empty()) {
844  l_save_path = save_path.u8string();
845  }
846  if (frames_per_chunk==0) {
847  frames_per_chunk=m_dynlib.GetChunkSizeInFrames();
848  }
849  if (m_dynlib.fnInitProcess3) {
850  instance = m_dynlib.fnInitProcess3(LoginKey.c_str(), RadioName.c_str(), Access_Key_ID.c_str(), Access_Key_Secret.c_str(), l_save_path.c_str(), params, frames_per_chunk);
851  } else if (frames_per_chunk!=m_dynlib.GetChunkSizeInFrames()) {
852  return false;
853  } else {
854  instance = m_dynlib.fnInitProcess2(LoginKey.c_str(), RadioName.c_str(), Access_Key_ID.c_str(), Access_Key_Secret.c_str(), l_save_path.c_str(), params);
855  }
856  if (!instance) return false;
857  if (!init_metadata.empty()) {
858  for (auto&& [key,value]: init_metadata) {
859  m_dynlib.fnSetMetadata(instance, key.c_str(), value.c_str());
860  }
861  init_metadata.clear();
862  }
863  update_thread = std::thread([this, json_port](){
865  m_dynlib.fnStartUpdateThread(instance, json_port);
867  });
868  int timeout=5000;
869  #ifdef DEBUG
870  timeout=60*1000; // For debugger pauses
871  #endif
872  if (m_dynlib.fnWaitUpdateThreadReady(instance, timeout)<0) {
873  return false;
874  }
875  return true;
876  }
877 
885  unsigned int GetChunkFrames() {
886  if (instance && m_dynlib.fnGetProcessChunkFrames) {
887  return m_dynlib.fnGetProcessChunkFrames(instance);
888  }
889  return m_dynlib.fnGetChunkSizeInFrames();
890  }
891 
899  void PresetManager_InformChange(const std::filesystem::path& relative_path, PresetChange_Kind change_kind)
900  {
901  if (m_dynlib.fnPresetManager_InformChange) {
902  m_dynlib.fnPresetManager_InformChange(instance, relative_path.c_str(), (sound4cl_PresetChange_Kind) change_kind);
903  }
904  }
905 
917  void SetMetadata(const std::string& key, const char* value)
918  {
919  if (m_dynlib.fnSetMetadata) {
920  if (instance) {
921  m_dynlib.fnSetMetadata(instance, key.c_str(), value);
922  } else {
923  init_metadata.push_back( {key, value} );
924  }
925  }
926  }
927 
928 
938  void SetMetadataMulti(const std::unordered_map<std::string, const char*>& list)
939  {
940  if (instance) {
941  if (m_dynlib.fnSetMetadataMulti) {
942  typedef const char* pchar;
943  pchar* keyvalue=new pchar[2*list.size()+1];
944  size_t n=0;
945  for (auto&& [key,value]: list) {
946  keyvalue[2*n+0]=key.c_str();
947  keyvalue[2*n+1]=value;
948  n++;
949  }
950  keyvalue[2*n+0]=nullptr;
951 
952  sound4cl_SetMetadataMulti(instance, keyvalue);
953 
954  delete[] keyvalue;
955  } else {
956  for (auto&& [key,value]: list) {
957  SetMetadata(key, value);
958  }
959  }
960  } else {
961  for (auto&& [key,value]: list) {
962  if (value) {
963  init_metadata.push_back( {key, value} );
964  }
965  }
966  }
967  }
968 
974  std::vector< std::tuple<std::string,std::string> > GetMetadataInfos()
975  {
976  std::vector< std::tuple<std::string,std::string> > values;
977  if (m_dynlib.fnGetMetadataInfos) {
978  const char** c_values = m_dynlib.fnGetMetadataInfos(instance);
979  if (c_values) {
980  for (const char** c_value=c_values; *c_value; ) {
981  std::string key(*c_value);
982  c_value++;
983  if (*c_value) {
984  std::string descr(*c_value);
985  c_value++;
986  values.push_back( {key,descr} );
987  }
988  }
989  m_dynlib.fnFreeMetadataInfos(instance, c_values);
990  }
991  }
992  return values;
993  }
994 
995  // Can be overloaded, called at start of UpdateThread in the thread
996  virtual void OnUpdateThreadStart() {}
997  // Can be overloaded to call at end of UpdateThread in the thread
998  virtual void OnUpdateThreadStop() {}
999 
1005  bool StartWebServer(int http_port, int https_port=0)
1006  {
1007  assert(instance);
1008  assert(webserver==SOUND4_INVALID_WEBSERVER_ID);
1009  if (!m_dynlib.fnWebserver) {
1010  return false;
1011  }
1012  webserver = m_dynlib.fnWebserver(http_port,https_port,instance);
1013  if (webserver==SOUND4_INVALID_WEBSERVER_ID) {
1014  return false;
1015  }
1016  int web_status=m_dynlib.fnWebserver_Status(webserver);
1017  if (http_port && (web_status & SOUND4_WEBSERVER_HTTP_OK) == 0) {
1018  return false;
1019  }
1020  if (https_port && (web_status & SOUND4_WEBSERVER_HTTPS_OK) == 0) {
1021  return false;
1022  }
1023  return true;
1024  }
1031  {
1032  if (!m_dynlib.fnWebserver_Stop) return;
1033  if (webserver != SOUND4_INVALID_WEBSERVER_ID) {
1034  m_dynlib.fnWebserver_Stop(webserver, 1000);
1035  webserver = SOUND4_INVALID_WEBSERVER_ID;
1036  }
1037  }
1038 
1046  {
1047  if (!instance) return 0;
1048  return m_dynlib.fnTerminateProcess(instance);
1049  }
1050 
1056  void Stop()
1057  {
1058  if (!instance) return;
1059  StopWebServer();
1060  if (update_thread.joinable()) {
1061  m_dynlib.fnStopUpdateThread(instance); // this will exit the update thread
1062  update_thread.join();
1063  }
1064  m_dynlib.fnExitProcess(instance);
1065  instance=nullptr;
1066  }
1067 
1073  unsigned int GetEstimatedDelay()
1074  {
1075  assert(instance);
1076  return m_dynlib.fnGetEstimatedDelay(instance);
1077  }
1078 
1089  float* GetBufferIn()
1090  {
1091  assert(instance);
1092  return m_dynlib.fnGetBufferIn(instance);
1093 
1094  }
1105  float* GetBufferOut()
1106  {
1107  assert(instance);
1108  return m_dynlib.fnGetBufferOut(instance);
1109  }
1116  {
1117  assert(instance);
1118  m_dynlib.fnProcessAudio(instance, m_dynlib.fnGetBufferIn(instance), m_dynlib.fnGetBufferOut(instance));
1119  }
1133  // void ProcessAudio_Planar(const std::array< const std::array<const float,ChunkFrames>, InputChannels>& input, std::array< std::array<float,ChunkFrames>, OutputChannels>& output)
1134  void ProcessAudio_Planar(float const * const *input, float * const *output)
1135  {
1136  assert(instance);
1137  m_dynlib.fnProcessAudio_Planar(instance, input, output);
1138  }
1139 
1151  template<typename T>
1152  std::vector<T> ProcessAnyAudio(const std::vector<T> input)
1153  {
1154  assert(instance);
1155  std::vector<T> output;
1156  unsigned int out_offset=0;
1157  unsigned int in_offset=0;
1158  unsigned int todo = input.size();
1159  while (todo>0) {
1160  unsigned int left = AddAudio(&input[in_offset], todo);
1161  unsigned int out_avail = m_dynlib.fnGetOutputCount(instance);
1162  output.resize(out_offset + out_avail);
1163  GetAudio(&output[out_offset], out_avail);
1164  out_offset+=out_avail;
1165  in_offset += todo-left;
1166  todo=left;
1167  }
1168  return output;
1169  }
1170 
1176  class CClient {
1177  public:
1178  CClient(sound4cl_CInstance* instance, CProcessor& dynlib)
1179  : m_dynlib(dynlib)
1180  {
1181  assert(instance);
1182  client=m_dynlib.fnNewClient(instance);
1183  if (!client) throw std::bad_alloc();
1184  }
1185  // non-copyable
1186  CClient( const CInstance& ) = delete;
1187  CClient& operator=( const CInstance& ) = delete;
1189  {
1190  if (client) {
1191  m_dynlib.fnDeleteClient(client);
1192  client=nullptr;
1193  }
1194  }
1202  std::string ProcessJson(const std::string &request, bool *NeedSave = nullptr)
1203  {
1204  assert(client);
1205  int need_save=0;
1206  const char *canswer = m_dynlib.fnProcessJson(client, request.c_str(), &need_save);
1207  if (!canswer) return {};
1208  std::string answer(canswer);
1209  m_dynlib.fnFreeJsonAnswer (canswer);
1210  if (NeedSave) {
1211  *NeedSave=(need_save!=0);
1212  }
1213  return answer;
1214  }
1215  private:
1216  CProcessor& m_dynlib;
1217  sound4cl_CClientInstance *client = nullptr;
1218  };
1226  std::shared_ptr<CClient> NewClient()
1227  {
1228  assert(instance);
1229  return std::make_shared<CClient>(instance, m_dynlib);
1230  }
1231 
1232  protected:
1233  template<typename T>
1234  unsigned int AddAudio(const T* payload, unsigned int nFrame)
1235  {
1236  assert(instance);
1237  return m_dynlib.fnAddAudio(instance, reinterpret_cast<const T*>(payload), nFrame, helper::SampleFormat<T>::format);
1238  }
1239  template<typename T>
1240  unsigned int GetAudio(T* payload, unsigned int max_nFrame)
1241  {
1242  assert(instance);
1243  return m_dynlib.fnGetAudio(instance, reinterpret_cast<T*>(payload), max_nFrame, helper::SampleFormat<T>::format);
1244  }
1245 
1246  private:
1247  CProcessor& m_dynlib;
1248  sound4cl_CParameters* params = nullptr;
1249  sound4cl_CInstance* instance = nullptr;
1250  std::thread update_thread;
1251  std::vector< std::pair<std::string,std::string> > init_metadata;
1252  uint64_t webserver = SOUND4_INVALID_WEBSERVER_ID;
1253  };
1254 
1255 }; // namespace sound4
1256 
1257 
1258 // bridge C callbacks to CPresetLoader
1259 extern "C" {
1260  static char *sound4cl_custom_reader(const fs_char *filename, void* userdata) {
1261  sound4::CPresetLoader *preset_loader=reinterpret_cast<sound4::CPresetLoader*>(userdata);
1262  std::string content=preset_loader->Read(filename);
1263  return strdup(content.c_str());
1264  }
1265  static void sound4cl_custom_reader_free(char *content, void* userdata) {
1266  if (!content) return;
1267  free(content);
1268  }
1269  static int sound4cl_custom_writer(const fs_char *filename, const char *content, void* userdata) {
1270  sound4::CPresetLoader *preset_loader=reinterpret_cast<sound4::CPresetLoader*>(userdata);
1271  auto res=preset_loader->Write(filename,content);
1272  return res?0:-1;
1273  }
1274  static int sound4cl_custom_exists(const fs_char *filename, void* userdata) {
1275  sound4::CPresetLoader *preset_loader=reinterpret_cast<sound4::CPresetLoader*>(userdata);
1276  auto res=preset_loader->Exists(filename);
1277  return res?0:-1;
1278  }
1279  static fs_char** sound4cl_custom_getall(void* userdata) {
1280  sound4::CPresetLoader *preset_loader=reinterpret_cast<sound4::CPresetLoader*>(userdata);
1281  auto res=preset_loader->GetAll();
1282  fs_char**all=(fs_char**)malloc((res.size()+1)*sizeof(const fs_char*));
1283  for (size_t n=0;n<res.size();n++) {
1284  all[n]=fs_strdup(res[n].c_str());
1285  }
1286  all[res.size()]=nullptr;
1287  return all;
1288  }
1289  static void sound4cl_custom_getall_free(fs_char** all, void* userdata) {
1290  if (!all) return;
1291  for (fs_char** one=all;*one;one++) {
1292  free(*one);
1293  }
1294  free(all);
1295  }
1296  static int sound4cl_custom_remove(const fs_char *filename, void* userdata) {
1297  sound4::CPresetLoader *preset_loader=reinterpret_cast<sound4::CPresetLoader*>(userdata);
1298  auto res=preset_loader->Remove(filename);
1299  return res?0:-1;
1300  }
1301  static int sound4cl_custom_rename(const fs_char *from, const fs_char *to, void* userdata) {
1302  sound4::CPresetLoader *preset_loader=reinterpret_cast<sound4::CPresetLoader*>(userdata);
1303  auto res=preset_loader->Rename(from,to);
1304  return res?0:-1;
1305  }
1306 
1307 };
Shared Bus.
Definition: sound4cl.hpp:688
sound4cl_CBus * Get() const
Definition: sound4cl.hpp:704
CBus(CProcessor &dynlib)
Definition: sound4cl.hpp:690
CClient(const CInstance &)=delete
CClient(sound4cl_CInstance *instance, CProcessor &dynlib)
Definition: sound4cl.hpp:1178
CClient & operator=(const CInstance &)=delete
std::string ProcessJson(const std::string &request, bool *NeedSave=nullptr)
Process a JSON request and returns the answer.
Definition: sound4cl.hpp:1202
Instance handling class.
Definition: sound4cl.hpp:735
bool Create(const std::string &LoginKey, const std::string &RadioName, const std::string &Access_Key_ID, const std::string &Access_Key_Secret, const std::filesystem::path &save_path, int json_port=0, unsigned int frames_per_chunk=0)
Definition: sound4cl.hpp:839
void ProcessAudio_Planar(float const *const *input, float *const *output)
Definition: sound4cl.hpp:1134
std::shared_ptr< CClient > NewClient()
Definition: sound4cl.hpp:1226
std::vector< std::tuple< std::string, std::string > > GetMetadataInfos()
Definition: sound4cl.hpp:974
float * GetBufferIn()
Definition: sound4cl.hpp:1089
CInstance(const CInstance &)=delete
void SetPresetManager(CPresetLoader *preset_manager)
Definition: sound4cl.hpp:806
void SetBus(const CBus &bus)
Definition: sound4cl.hpp:790
virtual void OnUpdateThreadStop()
Definition: sound4cl.hpp:998
unsigned int GetChunkFrames()
Definition: sound4cl.hpp:885
CInstance(CProcessor &dynlib)
Definition: sound4cl.hpp:740
void SetParam(const std::string &name, const std::string &value)
Definition: sound4cl.hpp:768
virtual void OnUpdateThreadStart()
Definition: sound4cl.hpp:996
bool IsOk() const
Definition: sound4cl.hpp:760
bool StartWebServer(int http_port, int https_port=0)
Definition: sound4cl.hpp:1005
void PresetManager_InformChange(const std::filesystem::path &relative_path, PresetChange_Kind change_kind)
Definition: sound4cl.hpp:899
void SetMetadataMulti(const std::unordered_map< std::string, const char * > &list)
Definition: sound4cl.hpp:938
unsigned int AddAudio(const T *payload, unsigned int nFrame)
Definition: sound4cl.hpp:1234
unsigned int GetEstimatedDelay()
Definition: sound4cl.hpp:1073
float * GetBufferOut()
Definition: sound4cl.hpp:1105
void SetMetadata(const std::string &key, const char *value)
Definition: sound4cl.hpp:917
std::vector< T > ProcessAnyAudio(const std::vector< T > input)
Definition: sound4cl.hpp:1152
unsigned int GetAudio(T *payload, unsigned int max_nFrame)
Definition: sound4cl.hpp:1240
std::string GetParam(const std::string &name)
Definition: sound4cl.hpp:778
CInstance & operator=(const CInstance &)=delete
Custom preset handler helper.
Definition: sound4cl.hpp:715
virtual std::string Read(const std::filesystem::path &filename)=0
virtual bool Rename(const std::filesystem::path &from, const std::filesystem::path &to)=0
virtual bool Exists(const std::filesystem::path &name)=0
virtual bool Write(const std::filesystem::path &filename, const std::string &content)=0
virtual ~CPresetLoader()=default
virtual bool Remove(const std::filesystem::path &name)=0
virtual std::vector< std::filesystem::path > GetAll()=0
virtual bool IsReadOnly()=0
Dynamic library interface.
Definition: sound4cl.hpp:270
helper::DynFuncHolder< decltype(sound4cl_SetMetadataMulti) > fnSetMetadataMulti
Definition: sound4cl.hpp:356
helper::DynFuncHolder< decltype(sound4cl_MonoToStereo_Planar) > fnMonoToStereo_Planar
Definition: sound4cl.hpp:334
helper::DynFuncHolder< decltype(sound4cl_SetParameter) > fnSetParameter
Definition: sound4cl.hpp:290
void StereoToMono_Planar(const float *inputL, const float *inputR, float *output, size_t nSpl)
Definition: sound4cl.hpp:556
helper::DynFuncHolder< decltype(sound4cl_GetAudioOutputCount) > fnGetAudioOutputCount
Definition: sound4cl.hpp:284
helper::DynFuncHolder< decltype(sound4cl_NewClient) > fnNewClient
Definition: sound4cl.hpp:319
helper::DynFuncHolder< decltype(sound4cl_StereoToMono_Planar) > fnStereoToMono_Planar
Definition: sound4cl.hpp:333
std::vector< unsigned int > GetPossibleChunkSizeInFrames()
Definition: sound4cl.hpp:592
unsigned int GetBytesFromFormat(const sound4cl_SampleFormat fmt)
Definition: sound4cl.hpp:667
void AudioConvertTo(const float *input, uint8_t *payload, size_t nSpl, sound4cl_SampleFormat fmt)
Definition: sound4cl.hpp:550
helper::DynFuncHolder< decltype(sound4cl_DeleteClient) > fnDeleteClient
Definition: sound4cl.hpp:320
helper::DynFuncHolder< decltype(sound4cl_AudioMonoToLiveStereo) > fnAudioMonoToLiveStereo
Definition: sound4cl.hpp:318
helper::DynFuncHolder< decltype(sound4cl_GetParameter) > fnGetParameter
Definition: sound4cl.hpp:291
bool Load(const std::filesystem::path &filepath)
Loads the library.
Definition: sound4cl.hpp:374
void SetLogSeverity(LogSeverity severity)
Definition: sound4cl.hpp:673
helper::DynFuncHolder< decltype(sound4cl_Webserver_Stop) > fnWebserver_Stop
Definition: sound4cl.hpp:329
helper::DynFuncHolder< decltype(sound4cl_SetInstanceBus) > fnSetInstanceBus
Definition: sound4cl.hpp:353
void AudioConvertFrom(const uint8_t *payload, float *output, size_t nSpl, sound4cl_SampleFormat fmt)
Definition: sound4cl.hpp:548
helper::DynFuncHolder< decltype(sound4cl_GetMetadataInfos) > fnGetMetadataInfos
Definition: sound4cl.hpp:338
helper::DynFuncHolder< decltype(sound4cl_Webserver_Status) > fnWebserver_Status
Definition: sound4cl.hpp:330
helper::DynFuncHolder< decltype(sound4cl_NewParameters) > fnNewParameters
Definition: sound4cl.hpp:288
helper::DynFuncHolder< decltype(sound4cl_WaitUpdateThreadReady) > fnWaitUpdateThreadReady
Definition: sound4cl.hpp:299
unsigned int GetAudioInputCount()
Definition: sound4cl.hpp:620
void AudioMonoToLiveStereo(const float *input, uint8_t *payload)
Definition: sound4cl.hpp:562
helper::DynFuncHolder< decltype(sound4cl_NewBus) > fnNewBus
Definition: sound4cl.hpp:351
helper::DynFuncHolder< decltype(sound4cl_AudioConvertFrom) > fnAudioConvertFrom
Definition: sound4cl.hpp:313
helper::DynFuncHolder< decltype(sound4cl_InitProcess3) > fnInitProcess3
Definition: sound4cl.hpp:348
void SetLoggerCallback(log_cb_t cb)
Definition: sound4cl.hpp:679
helper::DynFuncHolder< decltype(sound4cl_GetBytesFromFormat) > fnGetBytesFromFormat
Definition: sound4cl.hpp:307
helper::DynFuncHolder< decltype(sound4cl_AudioConvertTo) > fnAudioConvertTo
Definition: sound4cl.hpp:314
helper::DynFuncHolder< decltype(sound4cl_FreeMetadataInfos) > fnFreeMetadataInfos
Definition: sound4cl.hpp:339
helper::DynFuncHolder< decltype(sound4cl_SetMetadata) > fnSetMetadata
Definition: sound4cl.hpp:337
unsigned int GetChunkSizeInFrames()
Definition: sound4cl.hpp:581
helper::DynFuncHolder< decltype(sound4cl_MonoToStereo) > fnMonoToStereo
Definition: sound4cl.hpp:316
helper::DynFuncHolder< decltype(sound4cl_GetBufferIn) > fnGetBufferIn
Definition: sound4cl.hpp:302
helper::DynFuncHolder< decltype(sound4cl_StereoToMono) > fnStereoToMono
Definition: sound4cl.hpp:315
helper::DynFuncHolder< decltype(sound4cl_SaveState) > fnSaveState
Definition: sound4cl.hpp:323
helper::DynFuncHolder< decltype(sound4cl_SetLoggerCallback) > fnSetLoggerCallback
Definition: sound4cl.hpp:286
helper::DynFuncHolder< decltype(sound4cl_InitProcess2) > fnInitProcess2
Definition: sound4cl.hpp:294
helper::DynFuncHolder< decltype(sound4cl_GetOutputCount) > fnGetOutputCount
Definition: sound4cl.hpp:311
helper::DynFuncHolder< decltype(sound4cl_ProcessAudio) > fnProcessAudio
Definition: sound4cl.hpp:300
helper::DynFuncHolder< decltype(sound4cl_GetSampleRate) > fnGetSampleRate
Definition: sound4cl.hpp:285
helper::DynFuncHolder< decltype(sound4cl_Webserver) > fnWebserver
Definition: sound4cl.hpp:328
helper::DynFuncHolder< decltype(sound4cl_GetChannelCount) > fnGetChannelCount
Definition: sound4cl.hpp:282
helper::DynFuncHolder< decltype(sound4cl_TerminateProcess) > fnTerminateProcess
Definition: sound4cl.hpp:295
helper::DynFuncHolder< decltype(sound4cl_ProcessJson) > fnProcessJson
Definition: sound4cl.hpp:321
helper::DynFuncHolder< decltype(sound4cl_GetMaxPacketFrame) > fnGetMaxPacketFrame
Definition: sound4cl.hpp:308
helper::DynFuncHolder< decltype(sound4cl_FreeBus) > fnFreeBus
Definition: sound4cl.hpp:352
helper::DynFuncHolder< decltype(sound4cl_Webserver_tcp2) > fnWebserver_tcp2
Definition: sound4cl.hpp:327
helper::DynFuncHolder< decltype(sound4cl_GetProcessChunkFrames) > fnGetProcessChunkFrames
Definition: sound4cl.hpp:347
helper::DynFuncHolder< decltype(sound4cl_StartUpdateThread) > fnStartUpdateThread
Definition: sound4cl.hpp:297
helper::DynFuncHolder< decltype(sound4cl_AddPadAudio) > fnAddPadAudio
Definition: sound4cl.hpp:310
unsigned int GetAudioOutputCount()
Definition: sound4cl.hpp:630
sound4cl_SampleFormat GetFormatFromName(const std::string &name)
Definition: sound4cl.hpp:658
std::string GetFormatName(const sound4cl_SampleFormat fmt)
Definition: sound4cl.hpp:649
helper::DynFuncHolder< decltype(sound4cl_SetLogSeverity) > fnSetLogSeverity
Definition: sound4cl.hpp:287
helper::DynFuncHolder< decltype(sound4cl_AddAudio) > fnAddAudio
Definition: sound4cl.hpp:309
helper::DynFuncHolder< decltype(sound4cl_GetAudio) > fnGetAudio
Definition: sound4cl.hpp:312
unsigned int GetSampleRate()
Definition: sound4cl.hpp:640
helper::DynFuncHolder< decltype(sound4cl_InitProcess) > fnInitProcess
Definition: sound4cl.hpp:293
helper::DynFuncHolder< decltype(sound4cl_AudioMonoFromLiveStereo) > fnAudioMonoFromLiveStereo
Definition: sound4cl.hpp:317
void MonoToStereo(const float *input, float *output, size_t nSpl)
Definition: sound4cl.hpp:554
helper::DynFuncHolder< decltype(sound4cl_GetVersion) > fnGetVersion
Definition: sound4cl.hpp:280
helper::DynFuncHolder< decltype(sound4cl_FreeParameters) > fnFreeParameters
Definition: sound4cl.hpp:289
helper::DynFuncHolder< decltype(sound4cl_GetPossibleChunkSizeInFrames) > fnGetPossibleChunkSizeInFrames
Definition: sound4cl.hpp:346
std::string GetVersion()
Definition: sound4cl.hpp:570
void AudioMonoFromLiveStereo(const uint8_t *payload, float *output)
Definition: sound4cl.hpp:560
helper::DynFuncHolder< decltype(sound4cl_GetChunkSizeInFrames) > fnGetChunkSizeInFrames
Definition: sound4cl.hpp:281
helper::DynFuncHolder< decltype(sound4cl_StopUpdateThread) > fnStopUpdateThread
Definition: sound4cl.hpp:298
helper::DynFuncHolder< decltype(sound4cl_ProcessAudio_Planar) > fnProcessAudio_Planar
Definition: sound4cl.hpp:301
bool IsOk() const
Check if the library was loaded correctly.
Definition: sound4cl.hpp:540
helper::DynFuncHolder< decltype(sound4cl_GetFormatName) > fnGetFormatName
Definition: sound4cl.hpp:305
helper::DynFuncHolder< decltype(sound4cl_FreeParameterValue) > fnFreeParameterValue
Definition: sound4cl.hpp:292
helper::DynFuncHolder< decltype(sound4cl_GetFormatFromName) > fnGetFormatFromName
Definition: sound4cl.hpp:306
helper::DynFuncHolder< decltype(sound4cl_GetAudioInputCount) > fnGetAudioInputCount
Definition: sound4cl.hpp:283
void MonoToStereo_Planar(const float *input, float *outputL, float *outputR, size_t nSpl)
Definition: sound4cl.hpp:558
helper::DynFuncHolder< decltype(sound4cl_ExitProcess) > fnExitProcess
Definition: sound4cl.hpp:296
helper::DynFuncHolder< T > GetPrefixSymbol(const std::string &name)
Definition: sound4cl.hpp:359
helper::DynFuncHolder< decltype(sound4cl_SetPresetManager) > fnSetPresetManager
Definition: sound4cl.hpp:342
void StereoToMono(const float *input, float *output, size_t nSpl)
Definition: sound4cl.hpp:552
unsigned int GetChannelCount()
Definition: sound4cl.hpp:610
helper::DynFuncHolder< decltype(sound4cl_GetEstimatedDelay) > fnGetEstimatedDelay
Definition: sound4cl.hpp:304
helper::DynFuncHolder< decltype(sound4cl_FreeJsonAnswer) > fnFreeJsonAnswer
Definition: sound4cl.hpp:322
helper::DynFuncHolder< decltype(sound4cl_GetBufferOut) > fnGetBufferOut
Definition: sound4cl.hpp:303
CProcessor()=default
helper::DynFuncHolder< decltype(sound4cl_Webserver_tcp) > fnWebserver_tcp
Definition: sound4cl.hpp:326
helper::DynFuncHolder< decltype(sound4cl_PresetManager_InformChange) > fnPresetManager_InformChange
Definition: sound4cl.hpp:343
Helper to load dynamic library.
Definition: sound4cl.hpp:130
DynFuncHolder< T > GetSymbol_safe(const std::string &name)
Definition: sound4cl.hpp:209
bool Load(const std::filesystem::path &dynlib, uint32_t loadflags=LOAD_LIBRARY_SEARCH_DLL_LOAD_DIR|LOAD_LIBRARY_SEARCH_APPLICATION_DIR|LOAD_LIBRARY_SEARCH_USER_DIRS|LOAD_LIBRARY_SEARCH_SYSTEM32)
Definition: sound4cl.hpp:182
DynFuncHolder< T > GetSymbol(const std::string &name)
Definition: sound4cl.hpp:201
CDynLoader & operator=(CDynLoader const &)=delete
CDynLoader(const CDynLoader &)=delete
static std::filesystem::path GetThisLibraryPath(void)
Definition: sound4cl.hpp:213
CDynLoader(CDynLoader &&)=default
Helper to wrap a function pointer.
Definition: sound4cl.hpp:115
DynFuncHolder(DynFunc_t a_ptr)
Definition: sound4cl.hpp:120
@ F32_NATIVE
32-bit floating-point, native
@ S16_NATIVE
16-bit signed integer, native
@ S32_NATIVE
32-bit signed integer, native
wchar_t fs_char
#define SOUND4_WEBSERVER_HTTPS_OK
#define SOUND4_WEBSERVER_HTTP_OK
#define SOUND4_INVALID_WEBSERVER_ID
HMODULE DynLib_t
Definition: sound4cl.hpp:105
FARPROC DynFunc_t
Definition: sound4cl.hpp:106
const LogSeverity info
Definition: sound4cl.hpp:242
const LogSeverity verbose5
Definition: sound4cl.hpp:247
const LogSeverity fatal
Definition: sound4cl.hpp:239
std::function< void(LogSeverity, const std::string &)> log_cb_t
Definition: sound4cl.hpp:252
const LogSeverity verbose4
Definition: sound4cl.hpp:246
const LogSeverity verbose
Definition: sound4cl.hpp:243
const LogSeverity warning
Definition: sound4cl.hpp:241
const LogSeverity error
Definition: sound4cl.hpp:240
sound4cl_LogSeverity LogSeverity
Definition: sound4cl.hpp:237
const LogSeverity none
Definition: sound4cl.hpp:238
const LogSeverity verbose3
Definition: sound4cl.hpp:245
const LogSeverity verbose2
Definition: sound4cl.hpp:244
#define fs_strdup
helper for OS dependant file name copy
C function signature definition for all sound4.cl libraries.
struct sound4cl_CInstance * sound4cl_InitProcess3(const char *LoginKey, const char *RadioName, const char *Access_Key_ID, const char *Access_Key_Secret, const char *save_path, const struct sound4cl_CParameters *parameters, unsigned int frames_per_chunk)
unsigned int sound4cl_AddAudio(struct sound4cl_CInstance *instance, const uint8_t *payload, unsigned int nFrame, enum sound4cl_SampleFormat fmt)
unsigned int sound4cl_GetMaxPacketFrame(struct sound4cl_CInstance *instance)
uint64_t sound4cl_Webserver_tcp(unsigned int listenport, unsigned int listenport_secure, const char *socket_ip, unsigned int socket_port)
struct sound4cl_CBus * sound4cl_NewBus()
void sound4cl_FreeMetadataInfos(struct sound4cl_CInstance *instance, const char **infos)
struct sound4cl_CInstance * sound4cl_InitProcess(const char *LoginKey, const char *RadioName, const char *Access_Key_ID, const char *Access_Key_Secret, const char *save_path)
void sound4cl_SetPresetManager(struct sound4cl_CParameters *params, sound4cl_storage_reader reader, sound4cl_storage_reader_free, sound4cl_storage_writer writer, sound4cl_storage_exists exists, sound4cl_storage_getall getall, sound4cl_storage_getall_free getall_free, sound4cl_storage_remove remove, sound4cl_storage_rename rename, int IsReadOnly, void *userdata)
unsigned int sound4cl_GetAudio(struct sound4cl_CInstance *instance, uint8_t *payload, unsigned int max_nFrame, enum sound4cl_SampleFormat fmt)
void sound4cl_SetParameter(struct sound4cl_CParameters *params, const char *name, const char *value)
unsigned int sound4cl_GetEstimatedDelay(struct sound4cl_CInstance *instance)
void sound4cl_DeleteClient(struct sound4cl_CClientInstance *client)
void sound4cl_FreeParameters(struct sound4cl_CParameters *params)
void sound4cl_MonoToStereo_Planar(const float *input, float *outputL, float *outputR, size_t nFrame)
void sound4cl_StereoToMono_Planar(const float *inputL, const float *inputR, float *output, size_t nFrame)
int sound4cl_Webserver_Stop(uint64_t id, int timeout_ms)
void sound4cl_SetInstanceBus(struct sound4cl_CParameters *params, struct sound4cl_CBus *bus)
void sound4cl_SetMetadataMulti(struct sound4cl_CInstance *instance, const char **keyvalue)
void sound4cl_SetLogSeverity(enum sound4cl_LogSeverity severity)
void sound4cl_StartUpdateThread(struct sound4cl_CInstance *instance, unsigned int port)
const char * sound4cl_ProcessJson(struct sound4cl_CClientInstance *client, const char *json_str, int *need_save)
const char * sound4cl_GetParameter(struct sound4cl_CParameters *params, const char *name)
void sound4cl_ProcessAudio_Planar(struct sound4cl_CInstance *instance, float const *const *input, float *const *output)
void sound4cl_FreeJsonAnswer(const char *json_str)
int sound4cl_SaveState(struct sound4cl_CInstance *instance)
void sound4cl_StereoToMono(const float *input, float *output, size_t nFrame)
unsigned int sound4cl_AddPadAudio(struct sound4cl_CInstance *instance)
int sound4cl_WaitUpdateThreadReady(struct sound4cl_CInstance *instance, int milliseconds)
void sound4cl_SetMetadata(struct sound4cl_CInstance *instance, const char *key, const char *value)
const char * sound4cl_GetVersion()
void sound4cl_AudioMonoFromLiveStereo(const uint8_t *payload, float *output)
float * sound4cl_GetBufferOut(struct sound4cl_CInstance *instance)
struct sound4cl_CParameters * sound4cl_NewParameters()
uint64_t sound4cl_Webserver_tcp2(unsigned int listenport, unsigned int listenport_secure, const char *socket_ip, unsigned int socket_port, const struct sound4cl_CParameters *parameters)
unsigned int sound4cl_GetAudioInputCount()
void sound4cl_AudioConvertFrom(const uint8_t *payload, float *output, size_t nSpl, enum sound4cl_SampleFormat fmt)
unsigned int sound4cl_GetProcessChunkFrames(struct sound4cl_CInstance *instance)
const char ** sound4cl_GetMetadataInfos(struct sound4cl_CInstance *instance)
const struct sound4cl_SOUND4_ProcessInfo * sound4cl_SOUND4_GetProcessInfo()
void sound4cl_FreeParameterValue(const char *value)
sound4cl_LogSeverity
Definition: sound4cl_cdef.h:41
@ sound4cl_info
Definition: sound4cl_cdef.h:46
@ sound4cl_none
Definition: sound4cl_cdef.h:42
@ sound4cl_verbose5
Definition: sound4cl_cdef.h:51
@ sound4cl_warning
Definition: sound4cl_cdef.h:45
@ sound4cl_verbose4
Definition: sound4cl_cdef.h:50
@ sound4cl_verbose2
Definition: sound4cl_cdef.h:48
@ sound4cl_verbose3
Definition: sound4cl_cdef.h:49
@ sound4cl_error
Definition: sound4cl_cdef.h:44
@ sound4cl_verbose
Definition: sound4cl_cdef.h:47
@ sound4cl_fatal
Definition: sound4cl_cdef.h:43
void sound4cl_AudioConvertTo(const float *input, uint8_t *payload, size_t nSpl, enum sound4cl_SampleFormat fmt)
unsigned int sound4cl_GetChannelCount()
void sound4cl_PresetManager_InformChange(struct sound4cl_CInstance *instance, const fs_char *relative_path, enum sound4cl_PresetChange_Kind change_kind)
void sound4cl_ProcessAudio(struct sound4cl_CInstance *instance, const float *input, float *output)
int sound4cl_Webserver_Status(uint64_t id)
enum sound4cl_SampleFormat sound4cl_GetFormatFromName(const char *name)
unsigned int sound4cl_GetChunkSizeInFrames()
int sound4cl_TerminateProcess(struct sound4cl_CInstance *instance)
unsigned int sound4cl_GetAudioOutputCount()
void sound4cl_MonoToStereo(const float *input, float *output, size_t nFrame)
void sound4cl_AudioMonoToLiveStereo(const float *input, uint8_t *payload)
void sound4cl_ExitProcess(struct sound4cl_CInstance *instance)
void sound4cl_StopUpdateThread(struct sound4cl_CInstance *instance)
uint64_t sound4cl_Webserver(unsigned int listenport, unsigned int listenport_secure, struct sound4cl_CInstance *instance)
void sound4cl_FreeBus(struct sound4cl_CBus *bus)
unsigned int sound4cl_GetBytesFromFormat(const enum sound4cl_SampleFormat fmt)
unsigned int * sound4cl_GetPossibleChunkSizeInFrames()
sound4cl_SampleFormat
Definition: sound4cl_cdef.h:69
struct sound4cl_CClientInstance * sound4cl_NewClient(struct sound4cl_CInstance *instance)
const char * sound4cl_GetFormatName(const enum sound4cl_SampleFormat fmt)
struct sound4cl_CInstance * sound4cl_InitProcess2(const char *LoginKey, const char *RadioName, const char *Access_Key_ID, const char *Access_Key_Secret, const char *save_path, const struct sound4cl_CParameters *parameters)
sound4cl_PresetChange_Kind
Definition: sound4cl_cdef.h:57
unsigned int sound4cl_GetSampleRate()
float * sound4cl_GetBufferIn(struct sound4cl_CInstance *instance)
unsigned int sound4cl_GetOutputCount(struct sound4cl_CInstance *instance)
void sound4cl_SetLoggerCallback(sound4cl_loggerfn logger)
Helper for Sample format types.
Definition: sound4cl.hpp:85