SOUND4 BIGVOICE.CL Library [1.1.1]
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  // added 2024-05-23
362 
363  template <typename T>
364  helper::DynFuncHolder<T> GetPrefixSymbol(const std::string& name) {
365  std::string prefix_name = m_prefix+name;
366  return m_lib.GetSymbol<T>(prefix_name);
367  }
368 
369  public:
370  CProcessor() = default;
371 
379  bool Load(const std::filesystem::path& filepath) {
380  m_lib.Close();
381  // If a path is given, use it directly and do not try other path
382  if (filepath.has_parent_path() && !m_lib.Load(filepath)) {
383  return false;
384  } else if (!m_lib.IsOk()) {
385  auto thisdir=helper::CDynLoader::GetThisLibraryPath().parent_path();
386  auto filename = filepath.filename();
387  #ifndef _WIN32
388  // Linux: if in a bin directory, try ../lib first
389  if (!m_lib.IsOk() && thisdir.filename()=="bin") {
390  auto libdir = thisdir.parent_path() / "lib";
391  m_lib.Load(libdir / filename);
392  }
393  #endif // !_WIN32
394  if (!m_lib.IsOk()) {
395  // Search in the same directory this code is in
396  m_lib.Load(thisdir / filename);
397  }
398  if (!m_lib.IsOk()) {
399  // Try current path
400  m_lib.Load(std::filesystem::current_path() / filename);
401  }
402  if (!m_lib.IsOk()) {
403  return false;
404  }
405  }
406  // Get information from the library itself
407  try {
408  auto GetInfo = m_lib.GetSymbol< decltype(sound4cl_SOUND4_GetProcessInfo ) >("SOUND4_GetProcessInfo" );
409  auto info = GetInfo();
410  m_prefix = info->prefix;
411  } catch (std::runtime_error& ) {
412  // Compatibility: search in known libraries without this function
413  #ifdef _WIN32
414  std::string filename = helper::WStringToUTF8(filepath.stem());
415  #else // !_WIN32
416  std::string filename = filepath.stem();
417  // remove lib prefix
418  filename=filename.substr(3);
419  #endif // ! _WIN32
420  if (filename=="sound4.x1.cloud") {
421  m_prefix="cloudx1_";
422  } else if (filename=="sound4.impact.cl") {
423  m_prefix="impact_";
424  } else if (filename=="sound4.bigvoice.cl") {
425  m_prefix="bigvoice_";
426  } else {
427  return false;
428  }
429  }
430 
431  // Load all C functions
432  try {
433  fnGetVersion = GetPrefixSymbol< decltype(sound4cl_GetVersion ) >("GetVersion" );
434  fnGetChunkSizeInFrames = GetPrefixSymbol< decltype(sound4cl_GetChunkSizeInFrames ) >("GetChunkSizeInFrames" );
435  fnGetChannelCount = GetPrefixSymbol< decltype(sound4cl_GetChannelCount ) >("GetChannelCount" );
436  fnGetAudioInputCount = GetPrefixSymbol< decltype(sound4cl_GetAudioInputCount ) >("GetAudioInputCount" );
437  fnGetAudioOutputCount = GetPrefixSymbol< decltype(sound4cl_GetAudioOutputCount ) >("GetAudioOutputCount" );
438  fnGetSampleRate = GetPrefixSymbol< decltype(sound4cl_GetSampleRate ) >("GetSampleRate" );
439  fnSetLoggerCallback = GetPrefixSymbol< decltype(sound4cl_SetLoggerCallback ) >("SetLoggerCallback" );
440  fnSetLogSeverity = GetPrefixSymbol< decltype(sound4cl_SetLogSeverity ) >("SetLogSeverity" );
441  fnNewParameters = GetPrefixSymbol< decltype(sound4cl_NewParameters ) >("NewParameters" );
442  fnFreeParameters = GetPrefixSymbol< decltype(sound4cl_FreeParameters ) >("FreeParameters" );
443  fnSetParameter = GetPrefixSymbol< decltype(sound4cl_SetParameter ) >("SetParameter" );
444  fnGetParameter = GetPrefixSymbol< decltype(sound4cl_GetParameter ) >("GetParameter" );
445  fnFreeParameterValue = GetPrefixSymbol< decltype(sound4cl_FreeParameterValue ) >("FreeParameterValue" );
446  fnInitProcess = GetPrefixSymbol< decltype(sound4cl_InitProcess ) >("InitProcess" );
447  fnInitProcess2 = GetPrefixSymbol< decltype(sound4cl_InitProcess2 ) >("InitProcess2" );
448  fnTerminateProcess = GetPrefixSymbol< decltype(sound4cl_TerminateProcess ) >("TerminateProcess" );
449  fnExitProcess = GetPrefixSymbol< decltype(sound4cl_ExitProcess ) >("ExitProcess" );
450  fnStartUpdateThread = GetPrefixSymbol< decltype(sound4cl_StartUpdateThread ) >("StartUpdateThread" );
451  fnStopUpdateThread = GetPrefixSymbol< decltype(sound4cl_StopUpdateThread ) >("StopUpdateThread" );
452  fnWaitUpdateThreadReady = GetPrefixSymbol< decltype(sound4cl_WaitUpdateThreadReady ) >("WaitUpdateThreadReady" );
453  fnProcessAudio = GetPrefixSymbol< decltype(sound4cl_ProcessAudio ) >("ProcessAudio" );
454  fnProcessAudio_Planar = GetPrefixSymbol< decltype(sound4cl_ProcessAudio_Planar ) >("ProcessAudio_Planar" );
455  fnGetBufferIn = GetPrefixSymbol< decltype(sound4cl_GetBufferIn ) >("GetBufferIn" );
456  fnGetBufferOut = GetPrefixSymbol< decltype(sound4cl_GetBufferOut ) >("GetBufferOut" );
457  fnGetEstimatedDelay = GetPrefixSymbol< decltype(sound4cl_GetEstimatedDelay ) >("GetEstimatedDelay" );
458  fnGetFormatName = GetPrefixSymbol< decltype(sound4cl_GetFormatName ) >("GetFormatName" );
459  fnGetFormatFromName = GetPrefixSymbol< decltype(sound4cl_GetFormatFromName ) >("GetFormatFromName" );
460  fnGetBytesFromFormat = GetPrefixSymbol< decltype(sound4cl_GetBytesFromFormat ) >("GetBytesFromFormat" );
461  fnGetMaxPacketFrame = GetPrefixSymbol< decltype(sound4cl_GetMaxPacketFrame ) >("GetMaxPacketFrame" );
462  fnAddAudio = GetPrefixSymbol< decltype(sound4cl_AddAudio ) >("AddAudio" );
463  fnAddPadAudio = GetPrefixSymbol< decltype(sound4cl_AddPadAudio ) >("AddPadAudio" );
464  fnGetOutputCount = GetPrefixSymbol< decltype(sound4cl_GetOutputCount ) >("GetOutputCount" );
465  fnGetAudio = GetPrefixSymbol< decltype(sound4cl_GetAudio ) >("GetAudio" );
466  fnAudioConvertFrom = GetPrefixSymbol< decltype(sound4cl_AudioConvertFrom ) >("AudioConvertFrom" );
467  fnAudioConvertTo = GetPrefixSymbol< decltype(sound4cl_AudioConvertTo ) >("AudioConvertTo" );
468  fnStereoToMono = GetPrefixSymbol< decltype(sound4cl_StereoToMono ) >("StereoToMono" );
469  fnMonoToStereo = GetPrefixSymbol< decltype(sound4cl_MonoToStereo ) >("MonoToStereo" );
470  fnAudioMonoFromLiveStereo = GetPrefixSymbol< decltype(sound4cl_AudioMonoFromLiveStereo) >("AudioMonoFromLiveStereo");
471  fnAudioMonoToLiveStereo = GetPrefixSymbol< decltype(sound4cl_AudioMonoToLiveStereo ) >("AudioMonoToLiveStereo" );
472  fnNewClient = GetPrefixSymbol< decltype(sound4cl_NewClient ) >("NewClient" );
473  fnDeleteClient = GetPrefixSymbol< decltype(sound4cl_DeleteClient ) >("DeleteClient" );
474  fnProcessJson = GetPrefixSymbol< decltype(sound4cl_ProcessJson ) >("ProcessJson" );
475  fnFreeJsonAnswer = GetPrefixSymbol< decltype(sound4cl_FreeJsonAnswer ) >("FreeJsonAnswer" );
476  fnSaveState = GetPrefixSymbol< decltype(sound4cl_SaveState ) >("SaveState" );
477  } catch (std::runtime_error& ) {
478  return false;
479  }
480  // Webserver : not for all projects
481  try {
482  fnWebserver_tcp = GetPrefixSymbol< decltype(sound4cl_Webserver_tcp ) >("Webserver_tcp" );
483  fnWebserver_tcp2 = GetPrefixSymbol< decltype(sound4cl_Webserver_tcp2 ) >("Webserver_tcp2" );
484  fnWebserver = GetPrefixSymbol< decltype(sound4cl_Webserver ) >("Webserver" );
485  fnWebserver_Stop = GetPrefixSymbol< decltype(sound4cl_Webserver_Stop ) >("Webserver_Stop" );
486  fnWebserver_Status = GetPrefixSymbol< decltype(sound4cl_Webserver_Status ) >("Webserver_Status" );
487  } catch (std::runtime_error& ) {
488  // Ignored, handler will take care
489  }
490  // Stereo/Mono conversion : must be present
491  try {
492  // added 2023-03-22
493  fnStereoToMono_Planar = GetPrefixSymbol< decltype(sound4cl_StereoToMono_Planar ) >("StereoToMono_Planar" );
494  fnMonoToStereo_Planar = GetPrefixSymbol< decltype(sound4cl_MonoToStereo_Planar ) >("MonoToStereo_Planar" );
495 
496  } catch (std::runtime_error& ) {
497  return false;
498  }
499  // C functions allowed to be missing
500  try {
501  // added 2023-05-22
502  fnSetMetadata = GetPrefixSymbol< decltype(sound4cl_SetMetadata ) >("SetMetadata" );
503  fnGetMetadataInfos = GetPrefixSymbol< decltype(sound4cl_GetMetadataInfos ) >("GetMetadataInfos" );
504  fnFreeMetadataInfos = GetPrefixSymbol< decltype(sound4cl_FreeMetadataInfos ) >("FreeMetadataInfos" );
505  // added 2023-06-20
506  fnSetPresetManager = GetPrefixSymbol< decltype(sound4cl_SetPresetManager ) >("SetPresetManager" );
507  fnPresetManager_InformChange = GetPrefixSymbol< decltype(sound4cl_PresetManager_InformChange ) >("PresetManager_InformChange" );
508 
509  // added 2023-09-21
510  fnGetPossibleChunkSizeInFrames = GetPrefixSymbol< decltype(sound4cl_GetPossibleChunkSizeInFrames ) >("GetPossibleChunkSizeInFrames" );
511  fnGetProcessChunkFrames = GetPrefixSymbol< decltype(sound4cl_GetProcessChunkFrames ) >("GetProcessChunkFrames" );
512  fnInitProcess3 = GetPrefixSymbol< decltype(sound4cl_InitProcess3 ) >("InitProcess3" );
513  } catch (std::runtime_error& ) {
514  // Ignored, handler will take care
515  }
516 
517  // bus: not for all projects
518  try {
519  // added 2023-06-26
520  fnNewBus = GetPrefixSymbol< decltype(sound4cl_NewBus ) >("NewBus" );
521  fnFreeBus = GetPrefixSymbol< decltype(sound4cl_FreeBus ) >("FreeBus" );
522  fnSetInstanceBus = GetPrefixSymbol< decltype(sound4cl_SetInstanceBus ) >("SetInstanceBus" );
523  } catch (std::runtime_error& ) {
524  // Ignored, handler will take care
525  }
526 
527  // Other optional
528  try {
529  // added 2024-02-19
530  fnSetMetadataMulti = GetPrefixSymbol< decltype(sound4cl_SetMetadataMulti ) >("SetMetadataMulti" );
531 
532  } catch (std::runtime_error& ) {
533  // Ignored, handler will take care
534  }
535 
536  // Other optional, web server only
537  try {
538  // added 2024-05-23
539  fnWebserver_SetAppHealth = GetPrefixSymbol< decltype(sound4cl_Webserver_SetAppHealth ) >("Webserver_SetAppHealth" );
540  fnWebserver_GetAppHealth = GetPrefixSymbol< decltype(sound4cl_Webserver_GetAppHealth ) >("Webserver_GetAppHealth" );
541  fnWebserver_FreeString = GetPrefixSymbol< decltype(sound4cl_Webserver_FreeString ) >("Webserver_FreeString" );
542  } catch (std::runtime_error& ) {
543  // Ignored, handler will take care
544  }
545 
546  m_bOK=true;
547  return true;
548  }
555  bool IsOk() const {
556  return m_bOK;
557  }
558 
563  void AudioConvertFrom(const uint8_t *payload, float *output, size_t nSpl, sound4cl_SampleFormat fmt)
564  { fnAudioConvertFrom(payload, output, nSpl, fmt); }
565  void AudioConvertTo(const float *input, uint8_t *payload, size_t nSpl, sound4cl_SampleFormat fmt)
566  { fnAudioConvertTo(input, payload, nSpl, fmt); }
567  void StereoToMono(const float *input, float *output, size_t nSpl)
568  { fnStereoToMono(input, output, nSpl); }
569  void MonoToStereo(const float *input, float *output, size_t nSpl)
570  { fnMonoToStereo(input, output, nSpl); }
571  void StereoToMono_Planar(const float *inputL, const float *inputR, float *output, size_t nSpl)
572  { fnStereoToMono_Planar(inputL, inputR, output, nSpl); }
573  void MonoToStereo_Planar(const float *input, float *outputL, float *outputR, size_t nSpl)
574  { fnMonoToStereo_Planar(input, outputL, outputR, nSpl); }
575  void AudioMonoFromLiveStereo(const uint8_t *payload, float *output)
576  { fnAudioMonoFromLiveStereo(payload, output); }
577  void AudioMonoToLiveStereo(const float *input, uint8_t *payload)
578  { fnAudioMonoToLiveStereo(input, payload); }
579 
585  std::string GetVersion()
586  { return std::string(fnGetVersion()); }
587 
596  unsigned int GetChunkSizeInFrames()
597  { return fnGetChunkSizeInFrames(); }
598 
607  std::vector<unsigned int> GetPossibleChunkSizeInFrames()
608  {
609  std::vector<unsigned int> list;
611  for (unsigned int* src=fnGetPossibleChunkSizeInFrames();*src;src++) {
612  list.push_back(*src);
613  }
614  } else {
615  list.push_back(fnGetChunkSizeInFrames());
616  }
617  return list;
618  }
619 
625  unsigned int GetChannelCount()
626  { return fnGetChannelCount(); }
627 
635  unsigned int GetAudioInputCount()
636  { return fnGetAudioInputCount(); }
637 
645  unsigned int GetAudioOutputCount()
646  { return fnGetAudioOutputCount(); }
647 
655  unsigned int GetSampleRate()
656  { return fnGetSampleRate(); }
657 
664  std::string GetFormatName( const sound4cl_SampleFormat fmt)
665  { return std::string(fnGetFormatName(fmt)); }
666 
673  sound4cl_SampleFormat GetFormatFromName( const std::string& name)
674  { return fnGetFormatFromName(name.c_str()); }
675 
682  unsigned int GetBytesFromFormat( const sound4cl_SampleFormat fmt)
683  { return fnGetBytesFromFormat(fmt); }
684 
689  { fnSetLogSeverity(severity); }
690 
695  { _log_cb=cb; fnSetLoggerCallback(&_log_cb_c); }
696  };
697 
703  class CBus {
704  public:
705  CBus(CProcessor& dynlib)
706  : m_dynlib(dynlib)
707  {
708  if (m_dynlib.fnNewBus) {
709  m_bus=m_dynlib.fnNewBus();
710  }
711  }
713  {
714  if (m_bus && m_dynlib.fnFreeBus) {
715  m_dynlib.fnFreeBus(m_bus);
716  }
717  m_bus = nullptr;
718  }
719  sound4cl_CBus *Get() const { return m_bus; }
720  private:
721  CProcessor& m_dynlib;
722  sound4cl_CBus *m_bus;
723  };
724 
731  public:
732  CPresetLoader() = default;
733  virtual ~CPresetLoader() = default;
734 
735  virtual bool IsReadOnly() = 0;
736  virtual bool Exists(const std::filesystem::path &name) = 0;
737  virtual bool Remove(const std::filesystem::path &name) = 0;
738  virtual bool Rename(const std::filesystem::path &from, const std::filesystem::path &to) = 0;
739  virtual std::vector<std::filesystem::path> GetAll() = 0;
740  virtual std::string Read(const std::filesystem::path &filename) = 0;
741  virtual bool Write(const std::filesystem::path &filename, const std::string &content) =0;
742  };
744 
750  class CInstance {
751  public:
756  : m_dynlib(dynlib)
757  {
758  params = m_dynlib.fnNewParameters();
759  if (!params) throw std::bad_alloc();
760  }
761  // non-copyable
762  CInstance( const CInstance& ) = delete;
763  CInstance& operator=( const CInstance& ) = delete;
768  {
769  Stop();
770  if (params) m_dynlib.fnFreeParameters(params);
771  }
775  bool IsOk() const { return instance!=nullptr; }
783  void SetParam(const std::string& name, const std::string& value)
784  {
785  assert(params);
786  m_dynlib.fnSetParameter(params, name.c_str(), value.c_str());
787  }
793  std::string GetParam(const std::string& name)
794  {
795  assert(params);
796  auto c_value=m_dynlib.fnGetParameter(params, name.c_str());
797  std::string ret(c_value);
798  m_dynlib.fnFreeParameterValue(c_value);
799  return ret;
800  }
801 
805  void SetBus(const CBus& bus) {
806  assert(params);
807  if (m_dynlib.fnSetInstanceBus) {
808  m_dynlib.fnSetInstanceBus(params,bus.Get());
809  }
810  }
811 
821  void SetPresetManager(CPresetLoader *preset_manager)
822  {
823  if (!preset_manager) return;
824  if (!m_dynlib.fnSetPresetManager) return;
825  assert(params);
826  m_dynlib.fnSetPresetManager(params,
827  sound4cl_custom_reader,
828  sound4cl_custom_reader_free,
829  sound4cl_custom_writer,
830  sound4cl_custom_exists,
831  sound4cl_custom_getall,
832  sound4cl_custom_getall_free,
833  sound4cl_custom_remove,
834  sound4cl_custom_rename,
835  preset_manager->IsReadOnly(),
836  preset_manager
837  );
838  }
839 
854  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)
855  {
856  assert(!instance);
857  std::string l_save_path;
858  if (!save_path.empty()) {
859  l_save_path = save_path.u8string();
860  }
861  if (frames_per_chunk==0) {
862  frames_per_chunk=m_dynlib.GetChunkSizeInFrames();
863  }
864  if (m_dynlib.fnInitProcess3) {
865  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);
866  } else if (frames_per_chunk!=m_dynlib.GetChunkSizeInFrames()) {
867  return false;
868  } else {
869  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);
870  }
871  if (!instance) return false;
872  if (!init_metadata.empty()) {
873  for (auto&& [key,value]: init_metadata) {
874  m_dynlib.fnSetMetadata(instance, key.c_str(), value.c_str());
875  }
876  init_metadata.clear();
877  }
878  update_thread = std::thread([this, json_port](){
880  m_dynlib.fnStartUpdateThread(instance, json_port);
882  });
883  int timeout=5000;
884  #ifdef DEBUG
885  timeout=60*1000; // For debugger pauses
886  #endif
887  if (m_dynlib.fnWaitUpdateThreadReady(instance, timeout)<0) {
888  return false;
889  }
890  return true;
891  }
892 
900  unsigned int GetChunkFrames() {
901  if (instance && m_dynlib.fnGetProcessChunkFrames) {
902  return m_dynlib.fnGetProcessChunkFrames(instance);
903  }
904  return m_dynlib.fnGetChunkSizeInFrames();
905  }
906 
914  void PresetManager_InformChange(const std::filesystem::path& relative_path, PresetChange_Kind change_kind)
915  {
916  if (m_dynlib.fnPresetManager_InformChange) {
917  m_dynlib.fnPresetManager_InformChange(instance, relative_path.c_str(), (sound4cl_PresetChange_Kind) change_kind);
918  }
919  }
920 
932  void SetMetadata(const std::string& key, const char* value)
933  {
934  if (m_dynlib.fnSetMetadata) {
935  if (instance) {
936  m_dynlib.fnSetMetadata(instance, key.c_str(), value);
937  } else {
938  init_metadata.push_back( {key, value} );
939  }
940  }
941  }
942 
943 
953  void SetMetadataMulti(const std::unordered_map<std::string, const char*>& list)
954  {
955  if (instance) {
956  if (m_dynlib.fnSetMetadataMulti) {
957  typedef const char* pchar;
958  pchar* keyvalue=new pchar[2*list.size()+1];
959  size_t n=0;
960  for (auto&& [key,value]: list) {
961  keyvalue[2*n+0]=key.c_str();
962  keyvalue[2*n+1]=value;
963  n++;
964  }
965  keyvalue[2*n+0]=nullptr;
966 
967  sound4cl_SetMetadataMulti(instance, keyvalue);
968 
969  delete[] keyvalue;
970  } else {
971  for (auto&& [key,value]: list) {
972  SetMetadata(key, value);
973  }
974  }
975  } else {
976  for (auto&& [key,value]: list) {
977  if (value) {
978  init_metadata.push_back( {key, value} );
979  }
980  }
981  }
982  }
983 
989  std::vector< std::tuple<std::string,std::string> > GetMetadataInfos()
990  {
991  std::vector< std::tuple<std::string,std::string> > values;
992  if (m_dynlib.fnGetMetadataInfos) {
993  const char** c_values = m_dynlib.fnGetMetadataInfos(instance);
994  if (c_values) {
995  for (const char** c_value=c_values; *c_value; ) {
996  std::string key(*c_value);
997  c_value++;
998  if (*c_value) {
999  std::string descr(*c_value);
1000  c_value++;
1001  values.push_back( {key,descr} );
1002  }
1003  }
1004  m_dynlib.fnFreeMetadataInfos(instance, c_values);
1005  }
1006  }
1007  return values;
1008  }
1009 
1010  // Can be overloaded, called at start of UpdateThread in the thread
1011  virtual void OnUpdateThreadStart() {}
1012  // Can be overloaded to call at end of UpdateThread in the thread
1013  virtual void OnUpdateThreadStop() {}
1014 
1020  bool StartWebServer(int http_port, int https_port=0)
1021  {
1022  assert(instance);
1023  assert(webserver==SOUND4_INVALID_WEBSERVER_ID);
1024  if (!m_dynlib.fnWebserver) {
1025  return false;
1026  }
1027  webserver = m_dynlib.fnWebserver(http_port,https_port,instance);
1028  if (webserver==SOUND4_INVALID_WEBSERVER_ID) {
1029  return false;
1030  }
1031  int web_status=m_dynlib.fnWebserver_Status(webserver);
1032  if (http_port && (web_status & SOUND4_WEBSERVER_HTTP_OK) == 0) {
1033  return false;
1034  }
1035  if (https_port && (web_status & SOUND4_WEBSERVER_HTTPS_OK) == 0) {
1036  return false;
1037  }
1038  return true;
1039  }
1046  {
1047  if (!m_dynlib.fnWebserver_Stop) return;
1048  if (webserver != SOUND4_INVALID_WEBSERVER_ID) {
1049  m_dynlib.fnWebserver_Stop(webserver, 1000);
1050  webserver = SOUND4_INVALID_WEBSERVER_ID;
1051  }
1052  }
1053 
1057  void SetWebServerAppHealth(int httpcode, const std::string& contenttype, const std::string& content)
1058  {
1059  assert(instance);
1060  if (!m_dynlib.fnWebserver_SetAppHealth) return;
1061  m_dynlib.fnWebserver_SetAppHealth(instance, httpcode, contenttype.c_str(), content.c_str());
1062  }
1066  void GetWebServerAppHealth(int &httpcode, std::string& contenttype, std::string& content)
1067  {
1068  assert(instance);
1069  if (!m_dynlib.fnWebserver_GetAppHealth) return;
1070  char* c_contenttype=nullptr;
1071  char* c_content=nullptr;
1072  m_dynlib.fnWebserver_GetAppHealth(instance, &httpcode, &c_contenttype, &c_content);
1073  contenttype=c_contenttype;
1074  content=c_content;
1075  m_dynlib.fnWebserver_FreeString(c_contenttype);
1076  m_dynlib.fnWebserver_FreeString(c_content);
1077  }
1085  {
1086  if (!instance) return 0;
1087  return m_dynlib.fnTerminateProcess(instance);
1088  }
1089 
1095  void Stop()
1096  {
1097  if (!instance) return;
1098  StopWebServer();
1099  if (update_thread.joinable()) {
1100  m_dynlib.fnStopUpdateThread(instance); // this will exit the update thread
1101  update_thread.join();
1102  }
1103  m_dynlib.fnExitProcess(instance);
1104  instance=nullptr;
1105  }
1106 
1112  unsigned int GetEstimatedDelay()
1113  {
1114  assert(instance);
1115  return m_dynlib.fnGetEstimatedDelay(instance);
1116  }
1117 
1128  float* GetBufferIn()
1129  {
1130  assert(instance);
1131  return m_dynlib.fnGetBufferIn(instance);
1132 
1133  }
1144  float* GetBufferOut()
1145  {
1146  assert(instance);
1147  return m_dynlib.fnGetBufferOut(instance);
1148  }
1155  {
1156  assert(instance);
1157  m_dynlib.fnProcessAudio(instance, m_dynlib.fnGetBufferIn(instance), m_dynlib.fnGetBufferOut(instance));
1158  }
1172  // void ProcessAudio_Planar(const std::array< const std::array<const float,ChunkFrames>, InputChannels>& input, std::array< std::array<float,ChunkFrames>, OutputChannels>& output)
1173  void ProcessAudio_Planar(float const * const *input, float * const *output)
1174  {
1175  assert(instance);
1176  m_dynlib.fnProcessAudio_Planar(instance, input, output);
1177  }
1178 
1190  template<typename T>
1191  std::vector<T> ProcessAnyAudio(const std::vector<T> input)
1192  {
1193  assert(instance);
1194  std::vector<T> output;
1195  unsigned int out_offset=0;
1196  unsigned int in_offset=0;
1197  unsigned int todo = input.size();
1198  while (todo>0) {
1199  unsigned int left = AddAudio(&input[in_offset], todo);
1200  unsigned int out_avail = m_dynlib.fnGetOutputCount(instance);
1201  output.resize(out_offset + out_avail);
1202  GetAudio(&output[out_offset], out_avail);
1203  out_offset+=out_avail;
1204  in_offset += todo-left;
1205  todo=left;
1206  }
1207  return output;
1208  }
1209 
1215  class CClient {
1216  public:
1217  CClient(sound4cl_CInstance* instance, CProcessor& dynlib)
1218  : m_dynlib(dynlib)
1219  {
1220  assert(instance);
1221  client=m_dynlib.fnNewClient(instance);
1222  if (!client) throw std::bad_alloc();
1223  }
1224  // non-copyable
1225  CClient( const CInstance& ) = delete;
1226  CClient& operator=( const CInstance& ) = delete;
1228  {
1229  if (client) {
1230  m_dynlib.fnDeleteClient(client);
1231  client=nullptr;
1232  }
1233  }
1241  std::string ProcessJson(const std::string &request, bool *NeedSave = nullptr)
1242  {
1243  assert(client);
1244  int need_save=0;
1245  const char *canswer = m_dynlib.fnProcessJson(client, request.c_str(), &need_save);
1246  if (!canswer) return {};
1247  std::string answer(canswer);
1248  m_dynlib.fnFreeJsonAnswer (canswer);
1249  if (NeedSave) {
1250  *NeedSave=(need_save!=0);
1251  }
1252  return answer;
1253  }
1254  private:
1255  CProcessor& m_dynlib;
1256  sound4cl_CClientInstance *client = nullptr;
1257  };
1265  std::shared_ptr<CClient> NewClient()
1266  {
1267  assert(instance);
1268  return std::make_shared<CClient>(instance, m_dynlib);
1269  }
1270 
1271  protected:
1272  template<typename T>
1273  unsigned int AddAudio(const T* payload, unsigned int nFrame)
1274  {
1275  assert(instance);
1276  return m_dynlib.fnAddAudio(instance, reinterpret_cast<const T*>(payload), nFrame, helper::SampleFormat<T>::format);
1277  }
1278  template<typename T>
1279  unsigned int GetAudio(T* payload, unsigned int max_nFrame)
1280  {
1281  assert(instance);
1282  return m_dynlib.fnGetAudio(instance, reinterpret_cast<T*>(payload), max_nFrame, helper::SampleFormat<T>::format);
1283  }
1284 
1285  private:
1286  CProcessor& m_dynlib;
1287  sound4cl_CParameters* params = nullptr;
1288  sound4cl_CInstance* instance = nullptr;
1289  std::thread update_thread;
1290  std::vector< std::pair<std::string,std::string> > init_metadata;
1291  uint64_t webserver = SOUND4_INVALID_WEBSERVER_ID;
1292  };
1293 
1294 }; // namespace sound4
1295 
1296 
1297 // bridge C callbacks to CPresetLoader
1298 extern "C" {
1299  static char *sound4cl_custom_reader(const fs_char *filename, void* userdata) {
1300  sound4::CPresetLoader *preset_loader=reinterpret_cast<sound4::CPresetLoader*>(userdata);
1301  std::string content=preset_loader->Read(filename);
1302  return strdup(content.c_str());
1303  }
1304  static void sound4cl_custom_reader_free(char *content, void* userdata) {
1305  if (!content) return;
1306  free(content);
1307  }
1308  static int sound4cl_custom_writer(const fs_char *filename, const char *content, void* userdata) {
1309  sound4::CPresetLoader *preset_loader=reinterpret_cast<sound4::CPresetLoader*>(userdata);
1310  auto res=preset_loader->Write(filename,content);
1311  return res?0:-1;
1312  }
1313  static int sound4cl_custom_exists(const fs_char *filename, void* userdata) {
1314  sound4::CPresetLoader *preset_loader=reinterpret_cast<sound4::CPresetLoader*>(userdata);
1315  auto res=preset_loader->Exists(filename);
1316  return res?0:-1;
1317  }
1318  static fs_char** sound4cl_custom_getall(void* userdata) {
1319  sound4::CPresetLoader *preset_loader=reinterpret_cast<sound4::CPresetLoader*>(userdata);
1320  auto res=preset_loader->GetAll();
1321  fs_char**all=(fs_char**)malloc((res.size()+1)*sizeof(const fs_char*));
1322  for (size_t n=0;n<res.size();n++) {
1323  all[n]=fs_strdup(res[n].c_str());
1324  }
1325  all[res.size()]=nullptr;
1326  return all;
1327  }
1328  static void sound4cl_custom_getall_free(fs_char** all, void* userdata) {
1329  if (!all) return;
1330  for (fs_char** one=all;*one;one++) {
1331  free(*one);
1332  }
1333  free(all);
1334  }
1335  static int sound4cl_custom_remove(const fs_char *filename, void* userdata) {
1336  sound4::CPresetLoader *preset_loader=reinterpret_cast<sound4::CPresetLoader*>(userdata);
1337  auto res=preset_loader->Remove(filename);
1338  return res?0:-1;
1339  }
1340  static int sound4cl_custom_rename(const fs_char *from, const fs_char *to, void* userdata) {
1341  sound4::CPresetLoader *preset_loader=reinterpret_cast<sound4::CPresetLoader*>(userdata);
1342  auto res=preset_loader->Rename(from,to);
1343  return res?0:-1;
1344  }
1345 
1346 };
Shared Bus.
Definition: sound4cl.hpp:703
sound4cl_CBus * Get() const
Definition: sound4cl.hpp:719
CBus(CProcessor &dynlib)
Definition: sound4cl.hpp:705
CClient(const CInstance &)=delete
CClient(sound4cl_CInstance *instance, CProcessor &dynlib)
Definition: sound4cl.hpp:1217
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:1241
Instance handling class.
Definition: sound4cl.hpp:750
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:854
void ProcessAudio_Planar(float const *const *input, float *const *output)
Definition: sound4cl.hpp:1173
std::shared_ptr< CClient > NewClient()
Definition: sound4cl.hpp:1265
std::vector< std::tuple< std::string, std::string > > GetMetadataInfos()
Definition: sound4cl.hpp:989
float * GetBufferIn()
Definition: sound4cl.hpp:1128
CInstance(const CInstance &)=delete
void GetWebServerAppHealth(int &httpcode, std::string &contenttype, std::string &content)
Definition: sound4cl.hpp:1066
void SetPresetManager(CPresetLoader *preset_manager)
Definition: sound4cl.hpp:821
void SetBus(const CBus &bus)
Definition: sound4cl.hpp:805
virtual void OnUpdateThreadStop()
Definition: sound4cl.hpp:1013
unsigned int GetChunkFrames()
Definition: sound4cl.hpp:900
void SetWebServerAppHealth(int httpcode, const std::string &contenttype, const std::string &content)
Definition: sound4cl.hpp:1057
CInstance(CProcessor &dynlib)
Definition: sound4cl.hpp:755
void SetParam(const std::string &name, const std::string &value)
Definition: sound4cl.hpp:783
virtual void OnUpdateThreadStart()
Definition: sound4cl.hpp:1011
bool IsOk() const
Definition: sound4cl.hpp:775
bool StartWebServer(int http_port, int https_port=0)
Definition: sound4cl.hpp:1020
void PresetManager_InformChange(const std::filesystem::path &relative_path, PresetChange_Kind change_kind)
Definition: sound4cl.hpp:914
void SetMetadataMulti(const std::unordered_map< std::string, const char * > &list)
Definition: sound4cl.hpp:953
unsigned int AddAudio(const T *payload, unsigned int nFrame)
Definition: sound4cl.hpp:1273
unsigned int GetEstimatedDelay()
Definition: sound4cl.hpp:1112
float * GetBufferOut()
Definition: sound4cl.hpp:1144
void SetMetadata(const std::string &key, const char *value)
Definition: sound4cl.hpp:932
std::vector< T > ProcessAnyAudio(const std::vector< T > input)
Definition: sound4cl.hpp:1191
unsigned int GetAudio(T *payload, unsigned int max_nFrame)
Definition: sound4cl.hpp:1279
std::string GetParam(const std::string &name)
Definition: sound4cl.hpp:793
CInstance & operator=(const CInstance &)=delete
Custom preset handler helper.
Definition: sound4cl.hpp:730
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:571
helper::DynFuncHolder< decltype(sound4cl_GetAudioOutputCount) > fnGetAudioOutputCount
Definition: sound4cl.hpp:284
helper::DynFuncHolder< decltype(sound4cl_Webserver_FreeString) > fnWebserver_FreeString
Definition: sound4cl.hpp:361
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:607
unsigned int GetBytesFromFormat(const sound4cl_SampleFormat fmt)
Definition: sound4cl.hpp:682
void AudioConvertTo(const float *input, uint8_t *payload, size_t nSpl, sound4cl_SampleFormat fmt)
Definition: sound4cl.hpp:565
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:379
void SetLogSeverity(LogSeverity severity)
Definition: sound4cl.hpp:688
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:563
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
helper::DynFuncHolder< decltype(sound4cl_Webserver_SetAppHealth) > fnWebserver_SetAppHealth
Definition: sound4cl.hpp:359
unsigned int GetAudioInputCount()
Definition: sound4cl.hpp:635
void AudioMonoToLiveStereo(const float *input, uint8_t *payload)
Definition: sound4cl.hpp:577
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:694
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:596
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:645
sound4cl_SampleFormat GetFormatFromName(const std::string &name)
Definition: sound4cl.hpp:673
helper::DynFuncHolder< decltype(sound4cl_Webserver_GetAppHealth) > fnWebserver_GetAppHealth
Definition: sound4cl.hpp:360
std::string GetFormatName(const sound4cl_SampleFormat fmt)
Definition: sound4cl.hpp:664
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:655
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:569
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:585
void AudioMonoFromLiveStereo(const uint8_t *payload, float *output)
Definition: sound4cl.hpp:575
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:555
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:573
helper::DynFuncHolder< decltype(sound4cl_ExitProcess) > fnExitProcess
Definition: sound4cl.hpp:296
helper::DynFuncHolder< T > GetPrefixSymbol(const std::string &name)
Definition: sound4cl.hpp:364
helper::DynFuncHolder< decltype(sound4cl_SetPresetManager) > fnSetPresetManager
Definition: sound4cl.hpp:342
void StereoToMono(const float *input, float *output, size_t nSpl)
Definition: sound4cl.hpp:567
unsigned int GetChannelCount()
Definition: sound4cl.hpp:625
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)
void sound4cl_Webserver_SetAppHealth(struct sound4cl_CInstance *instance, int httpcode, const char *contenttype, const char *content)
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_Webserver_GetAppHealth(struct sound4cl_CInstance *instance, int *httpcode, char **contenttype, char **content)
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)
void sound4cl_Webserver_FreeString(char *str)
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