SOUND4 x1.CLOUD Library [1.5.5]
Loading...
Searching...
No Matches
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#if defined(__unix__) || defined(__APPLE__)
22 #define UNIXLIKE 1
23#else
24 #define UNIXLIKE 0
25#endif
26
27#if UNIXLIKE
28 #include <dlfcn.h>
29#elif defined(_WIN32)
30 #include <libloaderapi.h>
31#else
32 #error "Unsupported OS"
33#endif
34
35#include "sound4cl_cdef.h"
36
37 // bridge C callbacks to CPresetLoader
38 extern "C" {
39 static char *sound4cl_custom_reader(const fs_char *filename, void* userdata);
40 static void sound4cl_custom_reader_free(char *content, void* userdata);
41 static int sound4cl_custom_writer(const fs_char *filename, const char *content, void* userdata);
42 static int sound4cl_custom_exists(const fs_char *filename, void* userdata);
43 static fs_char** sound4cl_custom_getall(void* userdata);
44 static void sound4cl_custom_getall_free(fs_char** all, void* userdata);
45 static int sound4cl_custom_remove(const fs_char *filename, void* userdata);
46 static int sound4cl_custom_rename(const fs_char *from, const fs_char *to, void* userdata);
47 };
48
52namespace sound4 {
53
57 namespace helper {
58 #ifdef _WIN32
64 static inline std::string WStringToUTF8(const std::wstring& wstr) {
65 if (wstr.empty()) return {};
66 int size = WideCharToMultiByte(CP_UTF8, 0, &wstr[0], (int)wstr.size(), NULL, 0, NULL, NULL);
67 std::string str(size, 0);
68 WideCharToMultiByte(CP_UTF8, 0, &wstr[0], (int)wstr.size(), &str[0], size, NULL, NULL);
69 return str;
70 }
76 static inline std::wstring UTF8ToWString(const std::string& str) {
77 if (str.empty()) return std::wstring();
78 int size = MultiByteToWideChar(CP_UTF8, 0, &str[0], (int)str.size(), NULL, 0);
79 std::wstring wstr(size, 0);
80 MultiByteToWideChar(CP_UTF8, 0, &str[0], (int)str.size(), &wstr[0], size);
81 return wstr;
82 }
83 #endif // _WIN32
84
90 template<typename T>
91 struct SampleFormat {
92 };
93 template<>
97 template<>
100 };
101 template<>
104 };
105
106 // Storage definition, depending on OS
107 #if UNIXLIKE
108 using DynLib_t = void *;
109 using DynFunc_t = void *;
110 #else
113 #endif
114
120 template <typename T>
122 private:
123 DynFunc_t m_ptr = NULL;
124 public:
125 DynFuncHolder() = default;
127 operator bool() const { return (m_ptr!=NULL); }
128 bool IsOk() const { return m_ptr!=NULL; }
129 operator T* () const { return reinterpret_cast<T*>(m_ptr); }
130 };
131
137 private:
138 DynLib_t m_lib {};
139 public:
140 CDynLoader() = default;
141 CDynLoader(CDynLoader&&) = default;
142 // No copy allowed
143 CDynLoader(const CDynLoader&) = delete;
144 CDynLoader& operator=(CDynLoader const&) = delete;
145 operator bool() const {
146 return (m_lib!=NULL);
147 }
148 bool IsOk() const {
149 return (m_lib!=NULL);
150 }
151 #if UNIXLIKE
152 void Close() {
153 if (IsOk()) {
154 #ifndef __SANITIZE_ADDRESS__ // avoid unloading to keep call stack
155 dlclose(m_lib);
156 #endif // __SANITIZE_ADDRESS__
157 m_lib=NULL;
158 }
159 }
160 bool Load(const std::filesystem::path& dynlib)
161 {
162 Close();
163 m_lib=dlopen(dynlib.c_str(), RTLD_NOW|RTLD_LOCAL);
164 return IsOk();
165 }
166 template <typename T>
167 DynFuncHolder<T> GetSymbol(const std::string& name) {
168 auto ptr=dlsym(m_lib, name.c_str());
169 if (!ptr) {
170 throw std::runtime_error("Missing function in library");
171 }
172 return DynFuncHolder<T>(ptr);
173 }
174 template <typename T>
175 DynFuncHolder<T> GetSymbol_safe(const std::string& name) {
176 auto ptr=dlsym(m_lib, name.c_str());
177 return DynFuncHolder<T>(ptr);
178 }
179 static std::filesystem::path GetThisLibraryPath(void) {
180 static Dl_info info;
181 if (! dladdr((void *) GetThisLibraryPath, & info)) return {};
182 auto rp=realpath(info.dli_fname, NULL);
183 std::filesystem::path p(rp);
184 free(rp);
185 return p;
186 }
187 #else
194 void Close() {
195 if (IsOk()) {
196 // NOTE: On Windows, FreeLibrary may create a lot of troubles, should use FreeLibraryAndExitThread but...
197 // So define SOUND4_CALL_FREELIBRARY before including this file if you really want to unload the library dynamically
198 #if defined(SOUND4_CALL_FREELIBRARYANDEXITTHREAD)
199 FreeLibraryAndExitThread(m_lib, 0);
200 #elif defined(SOUND4_CALL_FREELIBRARY)
201 FreeLibrary(m_lib);
202 #endif // SOUND4_CALL_FREELIBRARY
203 m_lib=NULL;
204 }
205 }
206 template <typename T>
207 DynFuncHolder<T> GetSymbol(const std::string& name) {
208 auto ptr=GetProcAddress(m_lib, name.c_str());
209 if (!ptr) {
210 throw std::runtime_error("Missing function in library");
211 }
212 return DynFuncHolder<T>(ptr);
213 }
214 template <typename T>
215 DynFuncHolder<T> GetSymbol_safe(const std::string& name) {
216 auto ptr=GetProcAddress(m_lib, name.c_str());
217 return DynFuncHolder<T>(ptr);
218 }
219 static std::filesystem::path GetThisLibraryPath(void) {
220 static wchar_t path[MAX_PATH]={};
221 HMODULE hm = NULL;
225 {
226 if (GetModuleFileNameW(hm, path, MAX_PATH) > 0) {
227 return std::filesystem::path(path);
228 }
229 }
230 return {};
231 }
232 #endif
233 virtual ~CDynLoader() {
234 Close();
235 }
236 }; // class CDynLoader
237 }; // namespace helper
238
239
254
258 using log_cb_t = std::function<void(LogSeverity,const std::string&)>;
259
263 static log_cb_t _log_cb;
264 extern "C" {
265 static inline void _log_cb_c(LogSeverity severity, const char *c_msg) {
266 _log_cb(severity, std::string(c_msg));
267 }
268 }
269
277 private:
278 helper::CDynLoader m_lib;
279 bool m_bOK = false;
280 std::string m_prefix; // The prefix of functions, depends on the library (cloud_, impact_...)
281 protected:
282 friend class CBus;
283 friend class CInstance;
284
285 // All those wrapped functions have the same signature as there C sound4cl_XXX
330
331 // only for processes supporting webserver
337
338 // added 2023-03-22
341
342 // added 2023-05-22
346
347 // added 2023-06-20
350
351 // added 2023-09-21
355
356 // added 2023-06-26, only for processes supporting bus
360
361 // added 2024-02-19
363
364 // added 2024-05-23
368
369 template <typename T>
370 helper::DynFuncHolder<T> GetPrefixSymbol(const std::string& name) {
371 std::string prefix_name = m_prefix+name;
372 return m_lib.GetSymbol<T>(prefix_name);
373 }
374
375 public:
376 CProcessor() = default;
377
385 bool Load(const std::filesystem::path& filepath) {
386 m_lib.Close();
387 // If a path is given, use it directly and do not try other path
388 if (filepath.has_parent_path() && !m_lib.Load(filepath)) {
389 return false;
390 } else if (!m_lib.IsOk()) {
391 auto thisdir=helper::CDynLoader::GetThisLibraryPath().parent_path();
392 auto filename = filepath.filename();
393 #ifndef _WIN32
394 // Linux: if in a bin directory, try ../lib first
395 if (!m_lib.IsOk() && thisdir.filename()=="bin") {
396 auto libdir = thisdir.parent_path() / "lib";
397 m_lib.Load(libdir / filename);
398 }
399 #endif // !_WIN32
400 if (!m_lib.IsOk()) {
401 // Search in the same directory this code is in
402 m_lib.Load(thisdir / filename);
403 }
404 if (!m_lib.IsOk()) {
405 // Try current path
406 std::error_code ec;
407 auto p = std::filesystem::current_path(ec);
408 if (!ec) {
409 m_lib.Load(p / filename);
410 }
411 }
412 if (!m_lib.IsOk()) {
413 return false;
414 }
415 }
416 // Get information from the library itself
417 try {
418 auto GetInfo = m_lib.GetSymbol< decltype(sound4cl_SOUND4_GetProcessInfo ) >("SOUND4_GetProcessInfo" );
419 auto info = GetInfo();
420 m_prefix = info->prefix;
421 } catch (std::runtime_error& ) {
422 // Compatibility: search in known libraries without this function
423 #ifdef _WIN32
424 std::string filename = helper::WStringToUTF8(filepath.stem());
425 #else // !_WIN32
426 std::string filename = filepath.stem();
427 // remove lib prefix
428 filename=filename.substr(3);
429 #endif // ! _WIN32
430 if (filename=="sound4.x1.cloud") {
431 m_prefix="cloudx1_";
432 } else if (filename=="sound4.impact.cl") {
433 m_prefix="impact_";
434 } else if (filename=="sound4.bigvoice.cl") {
435 m_prefix="bigvoice_";
436 } else {
437 return false;
438 }
439 }
440
441 // Load all C functions
442 try {
443 fnGetVersion = GetPrefixSymbol< decltype(sound4cl_GetVersion ) >("GetVersion" );
444 fnGetChunkSizeInFrames = GetPrefixSymbol< decltype(sound4cl_GetChunkSizeInFrames ) >("GetChunkSizeInFrames" );
445 fnGetChannelCount = GetPrefixSymbol< decltype(sound4cl_GetChannelCount ) >("GetChannelCount" );
446 fnGetAudioInputCount = GetPrefixSymbol< decltype(sound4cl_GetAudioInputCount ) >("GetAudioInputCount" );
447 fnGetAudioOutputCount = GetPrefixSymbol< decltype(sound4cl_GetAudioOutputCount ) >("GetAudioOutputCount" );
448 fnGetSampleRate = GetPrefixSymbol< decltype(sound4cl_GetSampleRate ) >("GetSampleRate" );
449 fnSetLoggerCallback = GetPrefixSymbol< decltype(sound4cl_SetLoggerCallback ) >("SetLoggerCallback" );
450 fnSetLogSeverity = GetPrefixSymbol< decltype(sound4cl_SetLogSeverity ) >("SetLogSeverity" );
451 fnNewParameters = GetPrefixSymbol< decltype(sound4cl_NewParameters ) >("NewParameters" );
452 fnFreeParameters = GetPrefixSymbol< decltype(sound4cl_FreeParameters ) >("FreeParameters" );
453 fnSetParameter = GetPrefixSymbol< decltype(sound4cl_SetParameter ) >("SetParameter" );
454 fnGetParameter = GetPrefixSymbol< decltype(sound4cl_GetParameter ) >("GetParameter" );
455 fnFreeParameterValue = GetPrefixSymbol< decltype(sound4cl_FreeParameterValue ) >("FreeParameterValue" );
456 fnInitProcess = GetPrefixSymbol< decltype(sound4cl_InitProcess ) >("InitProcess" );
457 fnInitProcess2 = GetPrefixSymbol< decltype(sound4cl_InitProcess2 ) >("InitProcess2" );
458 fnTerminateProcess = GetPrefixSymbol< decltype(sound4cl_TerminateProcess ) >("TerminateProcess" );
459 fnExitProcess = GetPrefixSymbol< decltype(sound4cl_ExitProcess ) >("ExitProcess" );
460 fnStartUpdateThread = GetPrefixSymbol< decltype(sound4cl_StartUpdateThread ) >("StartUpdateThread" );
461 fnStopUpdateThread = GetPrefixSymbol< decltype(sound4cl_StopUpdateThread ) >("StopUpdateThread" );
462 fnWaitUpdateThreadReady = GetPrefixSymbol< decltype(sound4cl_WaitUpdateThreadReady ) >("WaitUpdateThreadReady" );
463 fnProcessAudio = GetPrefixSymbol< decltype(sound4cl_ProcessAudio ) >("ProcessAudio" );
464 fnProcessAudio_Planar = GetPrefixSymbol< decltype(sound4cl_ProcessAudio_Planar ) >("ProcessAudio_Planar" );
465 fnGetBufferIn = GetPrefixSymbol< decltype(sound4cl_GetBufferIn ) >("GetBufferIn" );
466 fnGetBufferOut = GetPrefixSymbol< decltype(sound4cl_GetBufferOut ) >("GetBufferOut" );
467 fnGetEstimatedDelay = GetPrefixSymbol< decltype(sound4cl_GetEstimatedDelay ) >("GetEstimatedDelay" );
468 fnGetFormatName = GetPrefixSymbol< decltype(sound4cl_GetFormatName ) >("GetFormatName" );
469 fnGetFormatFromName = GetPrefixSymbol< decltype(sound4cl_GetFormatFromName ) >("GetFormatFromName" );
470 fnGetBytesFromFormat = GetPrefixSymbol< decltype(sound4cl_GetBytesFromFormat ) >("GetBytesFromFormat" );
471 fnGetMaxPacketFrame = GetPrefixSymbol< decltype(sound4cl_GetMaxPacketFrame ) >("GetMaxPacketFrame" );
472 fnAddAudio = GetPrefixSymbol< decltype(sound4cl_AddAudio ) >("AddAudio" );
473 fnAddPadAudio = GetPrefixSymbol< decltype(sound4cl_AddPadAudio ) >("AddPadAudio" );
474 fnGetOutputCount = GetPrefixSymbol< decltype(sound4cl_GetOutputCount ) >("GetOutputCount" );
475 fnGetAudio = GetPrefixSymbol< decltype(sound4cl_GetAudio ) >("GetAudio" );
476 fnAudioConvertFrom = GetPrefixSymbol< decltype(sound4cl_AudioConvertFrom ) >("AudioConvertFrom" );
477 fnAudioConvertTo = GetPrefixSymbol< decltype(sound4cl_AudioConvertTo ) >("AudioConvertTo" );
478 fnStereoToMono = GetPrefixSymbol< decltype(sound4cl_StereoToMono ) >("StereoToMono" );
479 fnMonoToStereo = GetPrefixSymbol< decltype(sound4cl_MonoToStereo ) >("MonoToStereo" );
480 fnAudioMonoFromLiveStereo = GetPrefixSymbol< decltype(sound4cl_AudioMonoFromLiveStereo) >("AudioMonoFromLiveStereo");
481 fnAudioMonoToLiveStereo = GetPrefixSymbol< decltype(sound4cl_AudioMonoToLiveStereo ) >("AudioMonoToLiveStereo" );
482 fnNewClient = GetPrefixSymbol< decltype(sound4cl_NewClient ) >("NewClient" );
483 fnDeleteClient = GetPrefixSymbol< decltype(sound4cl_DeleteClient ) >("DeleteClient" );
484 fnProcessJson = GetPrefixSymbol< decltype(sound4cl_ProcessJson ) >("ProcessJson" );
485 fnFreeJsonAnswer = GetPrefixSymbol< decltype(sound4cl_FreeJsonAnswer ) >("FreeJsonAnswer" );
486 fnSaveState = GetPrefixSymbol< decltype(sound4cl_SaveState ) >("SaveState" );
487 } catch (std::runtime_error& ) {
488 return false;
489 }
490 // Webserver : not for all projects
491 try {
492 fnWebserver_tcp = GetPrefixSymbol< decltype(sound4cl_Webserver_tcp ) >("Webserver_tcp" );
493 fnWebserver_tcp2 = GetPrefixSymbol< decltype(sound4cl_Webserver_tcp2 ) >("Webserver_tcp2" );
494 fnWebserver = GetPrefixSymbol< decltype(sound4cl_Webserver ) >("Webserver" );
495 fnWebserver_Stop = GetPrefixSymbol< decltype(sound4cl_Webserver_Stop ) >("Webserver_Stop" );
496 fnWebserver_Status = GetPrefixSymbol< decltype(sound4cl_Webserver_Status ) >("Webserver_Status" );
497 } catch (std::runtime_error& ) {
498 // Ignored, handler will take care
499 }
500 // Stereo/Mono conversion : must be present
501 try {
502 // added 2023-03-22
503 fnStereoToMono_Planar = GetPrefixSymbol< decltype(sound4cl_StereoToMono_Planar ) >("StereoToMono_Planar" );
504 fnMonoToStereo_Planar = GetPrefixSymbol< decltype(sound4cl_MonoToStereo_Planar ) >("MonoToStereo_Planar" );
505
506 } catch (std::runtime_error& ) {
507 return false;
508 }
509 // C functions allowed to be missing
510 try {
511 // added 2023-05-22
512 fnSetMetadata = GetPrefixSymbol< decltype(sound4cl_SetMetadata ) >("SetMetadata" );
513 fnGetMetadataInfos = GetPrefixSymbol< decltype(sound4cl_GetMetadataInfos ) >("GetMetadataInfos" );
514 fnFreeMetadataInfos = GetPrefixSymbol< decltype(sound4cl_FreeMetadataInfos ) >("FreeMetadataInfos" );
515 // added 2023-06-20
516 fnSetPresetManager = GetPrefixSymbol< decltype(sound4cl_SetPresetManager ) >("SetPresetManager" );
517 fnPresetManager_InformChange = GetPrefixSymbol< decltype(sound4cl_PresetManager_InformChange ) >("PresetManager_InformChange" );
518
519 // added 2023-09-21
520 fnGetPossibleChunkSizeInFrames = GetPrefixSymbol< decltype(sound4cl_GetPossibleChunkSizeInFrames ) >("GetPossibleChunkSizeInFrames" );
521 fnGetProcessChunkFrames = GetPrefixSymbol< decltype(sound4cl_GetProcessChunkFrames ) >("GetProcessChunkFrames" );
522 fnInitProcess3 = GetPrefixSymbol< decltype(sound4cl_InitProcess3 ) >("InitProcess3" );
523 } catch (std::runtime_error& ) {
524 // Ignored, handler will take care
525 }
526
527 // bus: not for all projects
528 try {
529 // added 2023-06-26
530 fnNewBus = GetPrefixSymbol< decltype(sound4cl_NewBus ) >("NewBus" );
531 fnFreeBus = GetPrefixSymbol< decltype(sound4cl_FreeBus ) >("FreeBus" );
532 fnSetInstanceBus = GetPrefixSymbol< decltype(sound4cl_SetInstanceBus ) >("SetInstanceBus" );
533 } catch (std::runtime_error& ) {
534 // Ignored, handler will take care
535 }
536
537 // Other optional
538 try {
539 // added 2024-02-19
540 fnSetMetadataMulti = GetPrefixSymbol< decltype(sound4cl_SetMetadataMulti ) >("SetMetadataMulti" );
541
542 } catch (std::runtime_error& ) {
543 // Ignored, handler will take care
544 }
545
546 // Other optional, web server only
547 try {
548 // added 2024-05-23
549 fnWebserver_SetAppHealth = GetPrefixSymbol< decltype(sound4cl_Webserver_SetAppHealth ) >("Webserver_SetAppHealth" );
550 fnWebserver_GetAppHealth = GetPrefixSymbol< decltype(sound4cl_Webserver_GetAppHealth ) >("Webserver_GetAppHealth" );
551 fnWebserver_FreeString = GetPrefixSymbol< decltype(sound4cl_Webserver_FreeString ) >("Webserver_FreeString" );
552 } catch (std::runtime_error& ) {
553 // Ignored, handler will take care
554 }
555
556 m_bOK=true;
557 return true;
558 }
565 bool IsOk() const {
566 return m_bOK;
567 }
568
573 void AudioConvertFrom(const uint8_t *payload, float *output, size_t nSpl, sound4cl_SampleFormat fmt)
574 { fnAudioConvertFrom(payload, output, nSpl, fmt); }
575 void AudioConvertTo(const float *input, uint8_t *payload, size_t nSpl, sound4cl_SampleFormat fmt)
576 { fnAudioConvertTo(input, payload, nSpl, fmt); }
577 void StereoToMono(const float *input, float *output, size_t nSpl)
578 { fnStereoToMono(input, output, nSpl); }
579 void MonoToStereo(const float *input, float *output, size_t nSpl)
580 { fnMonoToStereo(input, output, nSpl); }
581 void StereoToMono_Planar(const float *inputL, const float *inputR, float *output, size_t nSpl)
582 { fnStereoToMono_Planar(inputL, inputR, output, nSpl); }
583 void MonoToStereo_Planar(const float *input, float *outputL, float *outputR, size_t nSpl)
584 { fnMonoToStereo_Planar(input, outputL, outputR, nSpl); }
585 void AudioMonoFromLiveStereo(const uint8_t *payload, float *output)
586 { fnAudioMonoFromLiveStereo(payload, output); }
587 void AudioMonoToLiveStereo(const float *input, uint8_t *payload)
588 { fnAudioMonoToLiveStereo(input, payload); }
589
595 std::string GetVersion()
596 { return std::string(fnGetVersion()); }
597
606 unsigned int GetChunkSizeInFrames()
607 { return fnGetChunkSizeInFrames(); }
608
617 std::vector<unsigned int> GetPossibleChunkSizeInFrames()
618 {
619 std::vector<unsigned int> list;
621 for (unsigned int* src=fnGetPossibleChunkSizeInFrames();*src;src++) {
622 list.push_back(*src);
623 }
624 } else {
625 list.push_back(fnGetChunkSizeInFrames());
626 }
627 return list;
628 }
629
635 unsigned int GetChannelCount()
636 { return fnGetChannelCount(); }
637
645 unsigned int GetAudioInputCount()
646 { return fnGetAudioInputCount(); }
647
655 unsigned int GetAudioOutputCount()
656 { return fnGetAudioOutputCount(); }
657
665 unsigned int GetSampleRate()
666 { return fnGetSampleRate(); }
667
674 std::string GetFormatName( const sound4cl_SampleFormat fmt)
675 { return std::string(fnGetFormatName(fmt)); }
676
683 sound4cl_SampleFormat GetFormatFromName( const std::string& name)
684 { return fnGetFormatFromName(name.c_str()); }
685
693 { return fnGetBytesFromFormat(fmt); }
694
699 { fnSetLogSeverity(severity); }
700
705 { _log_cb=cb; fnSetLoggerCallback(&_log_cb_c); }
706 };
707
713 class CBus {
714 public:
716 : m_dynlib(dynlib)
717 {
718 if (m_dynlib.fnNewBus) {
719 m_bus=m_dynlib.fnNewBus();
720 }
721 }
723 {
724 if (m_bus && m_dynlib.fnFreeBus) {
725 m_dynlib.fnFreeBus(m_bus);
726 }
727 m_bus = nullptr;
728 }
729 sound4cl_CBus *Get() const { return m_bus; }
730 private:
731 CProcessor& m_dynlib;
732 sound4cl_CBus *m_bus;
733 };
734
741 public:
742 CPresetLoader() = default;
743 virtual ~CPresetLoader() = default;
744
745 virtual bool IsReadOnly() = 0;
746 virtual bool Exists(const std::filesystem::path &name) = 0;
747 virtual bool Remove(const std::filesystem::path &name) = 0;
748 virtual bool Rename(const std::filesystem::path &from, const std::filesystem::path &to) = 0;
749 virtual std::vector<std::filesystem::path> GetAll() = 0;
750 virtual std::string Read(const std::filesystem::path &filename) = 0;
751 virtual bool Write(const std::filesystem::path &filename, const std::string &content) =0;
752 };
754
760 class CInstance {
761 public:
766 : m_dynlib(dynlib)
767 {
768 params = m_dynlib.fnNewParameters();
769 if (!params) throw std::bad_alloc();
770 }
771 // non-copyable
772 CInstance( const CInstance& ) = delete;
773 CInstance& operator=( const CInstance& ) = delete;
777 virtual ~CInstance()
778 {
779 Stop();
780 if (params) m_dynlib.fnFreeParameters(params);
781 }
785 bool IsOk() const { return instance!=nullptr; }
793 void SetParam(const std::string& name, const std::string& value)
794 {
795 assert(params);
796 m_dynlib.fnSetParameter(params, name.c_str(), value.c_str());
797 }
803 std::string GetParam(const std::string& name)
804 {
805 assert(params);
806 auto c_value=m_dynlib.fnGetParameter(params, name.c_str());
807 std::string ret(c_value);
808 m_dynlib.fnFreeParameterValue(c_value);
809 return ret;
810 }
811
815 void SetBus(const CBus& bus) {
816 assert(params);
817 if (m_dynlib.fnSetInstanceBus) {
818 m_dynlib.fnSetInstanceBus(params,bus.Get());
819 }
820 }
821
831 void SetPresetManager(CPresetLoader *preset_manager)
832 {
833 if (!preset_manager) return;
834 if (!m_dynlib.fnSetPresetManager) return;
835 assert(params);
836 m_dynlib.fnSetPresetManager(params,
837 sound4cl_custom_reader,
838 sound4cl_custom_reader_free,
839 sound4cl_custom_writer,
840 sound4cl_custom_exists,
841 sound4cl_custom_getall,
842 sound4cl_custom_getall_free,
843 sound4cl_custom_remove,
844 sound4cl_custom_rename,
845 preset_manager->IsReadOnly(),
846 preset_manager
847 );
848 }
849
864 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)
865 {
866 assert(!instance);
867 std::string l_save_path;
868 if (!save_path.empty()) {
869 l_save_path = save_path.u8string();
870 }
871 if (frames_per_chunk==0) {
872 frames_per_chunk=m_dynlib.GetChunkSizeInFrames();
873 }
874 if (m_dynlib.fnInitProcess3) {
875 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);
876 } else if (frames_per_chunk!=m_dynlib.GetChunkSizeInFrames()) {
877 return false;
878 } else {
879 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);
880 }
881 if (!instance) return false;
882 if (!init_metadata.empty()) {
883 for (auto&& [key,value]: init_metadata) {
884 m_dynlib.fnSetMetadata(instance, key.c_str(), value.c_str());
885 }
886 init_metadata.clear();
887 }
888 update_thread = std::thread([this, json_port](){
890 m_dynlib.fnStartUpdateThread(instance, json_port);
892 });
893 int timeout=5000;
894 #ifdef DEBUG
895 timeout=60*1000; // For debugger pauses
896 #endif
897 if (m_dynlib.fnWaitUpdateThreadReady(instance, timeout)<0) {
898 return false;
899 }
900 return true;
901 }
902
910 unsigned int GetChunkFrames() {
911 if (instance && m_dynlib.fnGetProcessChunkFrames) {
912 return m_dynlib.fnGetProcessChunkFrames(instance);
913 }
914 return m_dynlib.fnGetChunkSizeInFrames();
915 }
916
924 void PresetManager_InformChange(const std::filesystem::path& relative_path, PresetChange_Kind change_kind)
925 {
926 if (m_dynlib.fnPresetManager_InformChange) {
927 m_dynlib.fnPresetManager_InformChange(instance, relative_path.c_str(), (sound4cl_PresetChange_Kind) change_kind);
928 }
929 }
930
942 void SetMetadata(const std::string& key, const char* value)
943 {
944 if (m_dynlib.fnSetMetadata) {
945 if (instance) {
946 m_dynlib.fnSetMetadata(instance, key.c_str(), value);
947 } else {
948 init_metadata.push_back( {key, value} );
949 }
950 }
951 }
952
953
963 void SetMetadataMulti(const std::unordered_map<std::string, const char*>& list)
964 {
965 if (instance) {
966 if (m_dynlib.fnSetMetadataMulti) {
967 typedef const char* pchar;
968 pchar* keyvalue=new pchar[2*list.size()+1];
969 size_t n=0;
970 for (auto&& [key,value]: list) {
971 keyvalue[2*n+0]=key.c_str();
972 keyvalue[2*n+1]=value;
973 n++;
974 }
975 keyvalue[2*n+0]=nullptr;
976
977 sound4cl_SetMetadataMulti(instance, keyvalue);
978
979 delete[] keyvalue;
980 } else {
981 for (auto&& [key,value]: list) {
982 SetMetadata(key, value);
983 }
984 }
985 } else {
986 for (auto&& [key,value]: list) {
987 if (value) {
988 init_metadata.push_back( {key, value} );
989 }
990 }
991 }
992 }
993
999 std::vector< std::tuple<std::string,std::string> > GetMetadataInfos()
1000 {
1001 std::vector< std::tuple<std::string,std::string> > values;
1002 if (m_dynlib.fnGetMetadataInfos) {
1003 const char** c_values = m_dynlib.fnGetMetadataInfos(instance);
1004 if (c_values) {
1005 for (const char** c_value=c_values; *c_value; ) {
1006 std::string key(*c_value);
1007 c_value++;
1008 if (*c_value) {
1009 std::string descr(*c_value);
1010 c_value++;
1011 values.push_back( {key,descr} );
1012 }
1013 }
1014 m_dynlib.fnFreeMetadataInfos(instance, c_values);
1015 }
1016 }
1017 return values;
1018 }
1019
1020 // Can be overloaded, called at start of UpdateThread in the thread
1021 virtual void OnUpdateThreadStart() {}
1022 // Can be overloaded to call at end of UpdateThread in the thread
1023 virtual void OnUpdateThreadStop() {}
1024
1030 bool StartWebServer(int http_port, int https_port=0)
1031 {
1032 assert(instance);
1033 assert(webserver==SOUND4_INVALID_WEBSERVER_ID);
1034 if (!m_dynlib.fnWebserver) {
1035 return false;
1036 }
1037 webserver = m_dynlib.fnWebserver(http_port,https_port,instance);
1038 if (webserver==SOUND4_INVALID_WEBSERVER_ID) {
1039 return false;
1040 }
1041 int web_status=m_dynlib.fnWebserver_Status(webserver);
1042 if (http_port && (web_status & SOUND4_WEBSERVER_HTTP_OK) == 0) {
1043 return false;
1044 }
1045 if (https_port && (web_status & SOUND4_WEBSERVER_HTTPS_OK) == 0) {
1046 return false;
1047 }
1048 return true;
1049 }
1056 {
1057 if (!m_dynlib.fnWebserver_Stop) return;
1058 if (webserver != SOUND4_INVALID_WEBSERVER_ID) {
1059 m_dynlib.fnWebserver_Stop(webserver, 1000);
1060 webserver = SOUND4_INVALID_WEBSERVER_ID;
1061 }
1062 }
1063
1067 void SetWebServerAppHealth(int httpcode, const std::string& contenttype, const std::string& content)
1068 {
1069 assert(instance);
1070 if (!m_dynlib.fnWebserver_SetAppHealth) return;
1071 m_dynlib.fnWebserver_SetAppHealth(instance, httpcode, contenttype.c_str(), content.c_str());
1072 }
1076 void GetWebServerAppHealth(int &httpcode, std::string& contenttype, std::string& content)
1077 {
1078 assert(instance);
1079 if (!m_dynlib.fnWebserver_GetAppHealth) return;
1080 char* c_contenttype=nullptr;
1081 char* c_content=nullptr;
1082 m_dynlib.fnWebserver_GetAppHealth(instance, &httpcode, &c_contenttype, &c_content);
1083 contenttype=c_contenttype;
1084 content=c_content;
1085 m_dynlib.fnWebserver_FreeString(c_contenttype);
1086 m_dynlib.fnWebserver_FreeString(c_content);
1087 }
1095 {
1096 if (!instance) return 0;
1097 return m_dynlib.fnTerminateProcess(instance);
1098 }
1099
1105 void Stop()
1106 {
1107 if (!instance) return;
1108 StopWebServer();
1109 if (update_thread.joinable()) {
1110 m_dynlib.fnStopUpdateThread(instance); // this will exit the update thread
1111 update_thread.join();
1112 }
1113 m_dynlib.fnExitProcess(instance);
1114 instance=nullptr;
1115 }
1116
1122 unsigned int GetEstimatedDelay()
1123 {
1124 assert(instance);
1125 return m_dynlib.fnGetEstimatedDelay(instance);
1126 }
1127
1139 {
1140 assert(instance);
1141 return m_dynlib.fnGetBufferIn(instance);
1142
1143 }
1155 {
1156 assert(instance);
1157 return m_dynlib.fnGetBufferOut(instance);
1158 }
1165 {
1166 assert(instance);
1167 m_dynlib.fnProcessAudio(instance, m_dynlib.fnGetBufferIn(instance), m_dynlib.fnGetBufferOut(instance));
1168 }
1182 // void ProcessAudio_Planar(const std::array< const std::array<const float,ChunkFrames>, InputChannels>& input, std::array< std::array<float,ChunkFrames>, OutputChannels>& output)
1183 void ProcessAudio_Planar(float const * const *input, float * const *output)
1184 {
1185 assert(instance);
1186 m_dynlib.fnProcessAudio_Planar(instance, input, output);
1187 }
1188
1200 template<typename T>
1201 std::vector<T> ProcessAnyAudio(const std::vector<T> input)
1202 {
1203 assert(instance);
1204 std::vector<T> output;
1205 unsigned int out_offset=0;
1206 unsigned int in_offset=0;
1207 unsigned int todo = input.size();
1208 while (todo>0) {
1209 unsigned int left = AddAudio(&input[in_offset], todo);
1210 unsigned int out_avail = m_dynlib.fnGetOutputCount(instance);
1211 output.resize(out_offset + out_avail);
1212 GetAudio(&output[out_offset], out_avail);
1213 out_offset+=out_avail;
1214 in_offset += todo-left;
1215 todo=left;
1216 }
1217 return output;
1218 }
1219
1225 class CClient {
1226 public:
1227 CClient(sound4cl_CInstance* instance, CProcessor& dynlib)
1228 : m_dynlib(dynlib)
1229 {
1230 assert(instance);
1231 client=m_dynlib.fnNewClient(instance);
1232 if (!client) throw std::bad_alloc();
1233 }
1234 // non-copyable
1235 CClient( const CInstance& ) = delete;
1236 CClient& operator=( const CInstance& ) = delete;
1238 {
1239 if (client) {
1240 m_dynlib.fnDeleteClient(client);
1241 client=nullptr;
1242 }
1243 }
1251 std::string ProcessJson(const std::string &request, bool *NeedSave = nullptr)
1252 {
1253 assert(client);
1254 int need_save=0;
1255 const char *canswer = m_dynlib.fnProcessJson(client, request.c_str(), &need_save);
1256 if (!canswer) return {};
1257 std::string answer(canswer);
1258 m_dynlib.fnFreeJsonAnswer (canswer);
1259 if (NeedSave) {
1260 *NeedSave=(need_save!=0);
1261 }
1262 return answer;
1263 }
1264 private:
1265 CProcessor& m_dynlib;
1266 sound4cl_CClientInstance *client = nullptr;
1267 };
1275 std::shared_ptr<CClient> NewClient()
1276 {
1277 assert(instance);
1278 return std::make_shared<CClient>(instance, m_dynlib);
1279 }
1280
1281 protected:
1282 template<typename T>
1283 unsigned int AddAudio(const T* payload, unsigned int nFrame)
1284 {
1285 assert(instance);
1286 return m_dynlib.fnAddAudio(instance, reinterpret_cast<const T*>(payload), nFrame, helper::SampleFormat<T>::format);
1287 }
1288 template<typename T>
1289 unsigned int GetAudio(T* payload, unsigned int max_nFrame)
1290 {
1291 assert(instance);
1292 return m_dynlib.fnGetAudio(instance, reinterpret_cast<T*>(payload), max_nFrame, helper::SampleFormat<T>::format);
1293 }
1294
1295 private:
1296 CProcessor& m_dynlib;
1297 sound4cl_CParameters* params = nullptr;
1298 sound4cl_CInstance* instance = nullptr;
1299 std::thread update_thread;
1300 std::vector< std::pair<std::string,std::string> > init_metadata;
1301 uint64_t webserver = SOUND4_INVALID_WEBSERVER_ID;
1302 };
1303
1304}; // namespace sound4
1305
1306
1307// bridge C callbacks to CPresetLoader
1308extern "C" {
1309 static char *sound4cl_custom_reader(const fs_char *filename, void* userdata) {
1310 sound4::CPresetLoader *preset_loader=reinterpret_cast<sound4::CPresetLoader*>(userdata);
1311 std::string content=preset_loader->Read(filename);
1312 return strdup(content.c_str());
1313 }
1314 static void sound4cl_custom_reader_free(char *content, void* userdata) {
1315 if (!content) return;
1316 free(content);
1317 }
1318 static int sound4cl_custom_writer(const fs_char *filename, const char *content, void* userdata) {
1319 sound4::CPresetLoader *preset_loader=reinterpret_cast<sound4::CPresetLoader*>(userdata);
1320 auto res=preset_loader->Write(filename,content);
1321 return res?0:-1;
1322 }
1323 static int sound4cl_custom_exists(const fs_char *filename, void* userdata) {
1324 sound4::CPresetLoader *preset_loader=reinterpret_cast<sound4::CPresetLoader*>(userdata);
1325 auto res=preset_loader->Exists(filename);
1326 return res?0:-1;
1327 }
1328 static fs_char** sound4cl_custom_getall(void* userdata) {
1329 sound4::CPresetLoader *preset_loader=reinterpret_cast<sound4::CPresetLoader*>(userdata);
1330 auto res=preset_loader->GetAll();
1331 fs_char**all=(fs_char**)malloc((res.size()+1)*sizeof(const fs_char*));
1332 for (size_t n=0;n<res.size();n++) {
1333 all[n]=fs_strdup(res[n].c_str());
1334 }
1335 all[res.size()]=nullptr;
1336 return all;
1337 }
1338 static void sound4cl_custom_getall_free(fs_char** all, void* userdata) {
1339 if (!all) return;
1340 for (fs_char** one=all;*one;one++) {
1341 free(*one);
1342 }
1343 free(all);
1344 }
1345 static int sound4cl_custom_remove(const fs_char *filename, void* userdata) {
1346 sound4::CPresetLoader *preset_loader=reinterpret_cast<sound4::CPresetLoader*>(userdata);
1347 auto res=preset_loader->Remove(filename);
1348 return res?0:-1;
1349 }
1350 static int sound4cl_custom_rename(const fs_char *from, const fs_char *to, void* userdata) {
1351 sound4::CPresetLoader *preset_loader=reinterpret_cast<sound4::CPresetLoader*>(userdata);
1352 auto res=preset_loader->Rename(from,to);
1353 return res?0:-1;
1354 }
1355
1356};
Shared Bus.
Definition sound4cl.hpp:713
sound4cl_CBus * Get() const
Definition sound4cl.hpp:729
CBus(CProcessor &dynlib)
Definition sound4cl.hpp:715
CClient(const CInstance &)=delete
CClient(sound4cl_CInstance *instance, CProcessor &dynlib)
std::string ProcessJson(const std::string &request, bool *NeedSave=nullptr)
Process a JSON request and returns the answer.
CClient & operator=(const CInstance &)=delete
Instance handling class.
Definition sound4cl.hpp:760
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:864
void ProcessAudio_Planar(float const *const *input, float *const *output)
std::vector< T > ProcessAnyAudio(const std::vector< T > input)
virtual ~CInstance()
Definition sound4cl.hpp:777
CInstance & operator=(const CInstance &)=delete
CInstance(const CInstance &)=delete
void GetWebServerAppHealth(int &httpcode, std::string &contenttype, std::string &content)
void SetPresetManager(CPresetLoader *preset_manager)
Definition sound4cl.hpp:831
void SetBus(const CBus &bus)
Definition sound4cl.hpp:815
virtual void OnUpdateThreadStop()
unsigned int GetChunkFrames()
Definition sound4cl.hpp:910
void SetWebServerAppHealth(int httpcode, const std::string &contenttype, const std::string &content)
CInstance(CProcessor &dynlib)
Definition sound4cl.hpp:765
void SetParam(const std::string &name, const std::string &value)
Definition sound4cl.hpp:793
virtual void OnUpdateThreadStart()
bool IsOk() const
Definition sound4cl.hpp:785
bool StartWebServer(int http_port, int https_port=0)
void PresetManager_InformChange(const std::filesystem::path &relative_path, PresetChange_Kind change_kind)
Definition sound4cl.hpp:924
void SetMetadataMulti(const std::unordered_map< std::string, const char * > &list)
Definition sound4cl.hpp:963
unsigned int AddAudio(const T *payload, unsigned int nFrame)
unsigned int GetEstimatedDelay()
std::vector< std::tuple< std::string, std::string > > GetMetadataInfos()
Definition sound4cl.hpp:999
std::shared_ptr< CClient > NewClient()
float * GetBufferOut()
void SetMetadata(const std::string &key, const char *value)
Definition sound4cl.hpp:942
float * GetBufferIn()
unsigned int GetAudio(T *payload, unsigned int max_nFrame)
std::string GetParam(const std::string &name)
Definition sound4cl.hpp:803
Custom preset handler helper.
Definition sound4cl.hpp:740
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:276
helper::DynFuncHolder< decltype(sound4cl_SetMetadataMulti) > fnSetMetadataMulti
Definition sound4cl.hpp:362
helper::DynFuncHolder< decltype(sound4cl_MonoToStereo_Planar) > fnMonoToStereo_Planar
Definition sound4cl.hpp:340
helper::DynFuncHolder< decltype(sound4cl_SetParameter) > fnSetParameter
Definition sound4cl.hpp:296
void StereoToMono_Planar(const float *inputL, const float *inputR, float *output, size_t nSpl)
Definition sound4cl.hpp:581
helper::DynFuncHolder< decltype(sound4cl_GetAudioOutputCount) > fnGetAudioOutputCount
Definition sound4cl.hpp:290
helper::DynFuncHolder< decltype(sound4cl_Webserver_FreeString) > fnWebserver_FreeString
Definition sound4cl.hpp:367
helper::DynFuncHolder< decltype(sound4cl_NewClient) > fnNewClient
Definition sound4cl.hpp:325
helper::DynFuncHolder< decltype(sound4cl_StereoToMono_Planar) > fnStereoToMono_Planar
Definition sound4cl.hpp:339
unsigned int GetBytesFromFormat(const sound4cl_SampleFormat fmt)
Definition sound4cl.hpp:692
void AudioConvertTo(const float *input, uint8_t *payload, size_t nSpl, sound4cl_SampleFormat fmt)
Definition sound4cl.hpp:575
helper::DynFuncHolder< decltype(sound4cl_DeleteClient) > fnDeleteClient
Definition sound4cl.hpp:326
helper::DynFuncHolder< decltype(sound4cl_AudioMonoToLiveStereo) > fnAudioMonoToLiveStereo
Definition sound4cl.hpp:324
helper::DynFuncHolder< decltype(sound4cl_GetParameter) > fnGetParameter
Definition sound4cl.hpp:297
bool Load(const std::filesystem::path &filepath)
Loads the library.
Definition sound4cl.hpp:385
void SetLogSeverity(LogSeverity severity)
Definition sound4cl.hpp:698
helper::DynFuncHolder< decltype(sound4cl_Webserver_Stop) > fnWebserver_Stop
Definition sound4cl.hpp:335
helper::DynFuncHolder< decltype(sound4cl_SetInstanceBus) > fnSetInstanceBus
Definition sound4cl.hpp:359
void AudioConvertFrom(const uint8_t *payload, float *output, size_t nSpl, sound4cl_SampleFormat fmt)
Definition sound4cl.hpp:573
helper::DynFuncHolder< decltype(sound4cl_GetMetadataInfos) > fnGetMetadataInfos
Definition sound4cl.hpp:344
helper::DynFuncHolder< decltype(sound4cl_Webserver_Status) > fnWebserver_Status
Definition sound4cl.hpp:336
helper::DynFuncHolder< decltype(sound4cl_NewParameters) > fnNewParameters
Definition sound4cl.hpp:294
helper::DynFuncHolder< decltype(sound4cl_WaitUpdateThreadReady) > fnWaitUpdateThreadReady
Definition sound4cl.hpp:305
helper::DynFuncHolder< decltype(sound4cl_Webserver_SetAppHealth) > fnWebserver_SetAppHealth
Definition sound4cl.hpp:365
unsigned int GetAudioInputCount()
Definition sound4cl.hpp:645
void AudioMonoToLiveStereo(const float *input, uint8_t *payload)
Definition sound4cl.hpp:587
helper::DynFuncHolder< decltype(sound4cl_NewBus) > fnNewBus
Definition sound4cl.hpp:357
helper::DynFuncHolder< decltype(sound4cl_AudioConvertFrom) > fnAudioConvertFrom
Definition sound4cl.hpp:319
helper::DynFuncHolder< decltype(sound4cl_InitProcess3) > fnInitProcess3
Definition sound4cl.hpp:354
void SetLoggerCallback(log_cb_t cb)
Definition sound4cl.hpp:704
helper::DynFuncHolder< decltype(sound4cl_GetBytesFromFormat) > fnGetBytesFromFormat
Definition sound4cl.hpp:313
helper::DynFuncHolder< decltype(sound4cl_AudioConvertTo) > fnAudioConvertTo
Definition sound4cl.hpp:320
helper::DynFuncHolder< decltype(sound4cl_FreeMetadataInfos) > fnFreeMetadataInfos
Definition sound4cl.hpp:345
helper::DynFuncHolder< decltype(sound4cl_SetMetadata) > fnSetMetadata
Definition sound4cl.hpp:343
unsigned int GetChunkSizeInFrames()
Definition sound4cl.hpp:606
helper::DynFuncHolder< decltype(sound4cl_MonoToStereo) > fnMonoToStereo
Definition sound4cl.hpp:322
helper::DynFuncHolder< decltype(sound4cl_GetBufferIn) > fnGetBufferIn
Definition sound4cl.hpp:308
helper::DynFuncHolder< decltype(sound4cl_StereoToMono) > fnStereoToMono
Definition sound4cl.hpp:321
helper::DynFuncHolder< decltype(sound4cl_SaveState) > fnSaveState
Definition sound4cl.hpp:329
helper::DynFuncHolder< decltype(sound4cl_SetLoggerCallback) > fnSetLoggerCallback
Definition sound4cl.hpp:292
std::vector< unsigned int > GetPossibleChunkSizeInFrames()
Definition sound4cl.hpp:617
helper::DynFuncHolder< decltype(sound4cl_InitProcess2) > fnInitProcess2
Definition sound4cl.hpp:300
helper::DynFuncHolder< decltype(sound4cl_GetOutputCount) > fnGetOutputCount
Definition sound4cl.hpp:317
helper::DynFuncHolder< decltype(sound4cl_ProcessAudio) > fnProcessAudio
Definition sound4cl.hpp:306
helper::DynFuncHolder< decltype(sound4cl_GetSampleRate) > fnGetSampleRate
Definition sound4cl.hpp:291
helper::DynFuncHolder< decltype(sound4cl_Webserver) > fnWebserver
Definition sound4cl.hpp:334
helper::DynFuncHolder< decltype(sound4cl_GetChannelCount) > fnGetChannelCount
Definition sound4cl.hpp:288
helper::DynFuncHolder< decltype(sound4cl_TerminateProcess) > fnTerminateProcess
Definition sound4cl.hpp:301
helper::DynFuncHolder< decltype(sound4cl_ProcessJson) > fnProcessJson
Definition sound4cl.hpp:327
helper::DynFuncHolder< decltype(sound4cl_GetMaxPacketFrame) > fnGetMaxPacketFrame
Definition sound4cl.hpp:314
helper::DynFuncHolder< decltype(sound4cl_FreeBus) > fnFreeBus
Definition sound4cl.hpp:358
helper::DynFuncHolder< decltype(sound4cl_Webserver_tcp2) > fnWebserver_tcp2
Definition sound4cl.hpp:333
helper::DynFuncHolder< decltype(sound4cl_GetProcessChunkFrames) > fnGetProcessChunkFrames
Definition sound4cl.hpp:353
helper::DynFuncHolder< decltype(sound4cl_StartUpdateThread) > fnStartUpdateThread
Definition sound4cl.hpp:303
helper::DynFuncHolder< decltype(sound4cl_AddPadAudio) > fnAddPadAudio
Definition sound4cl.hpp:316
unsigned int GetAudioOutputCount()
Definition sound4cl.hpp:655
helper::DynFuncHolder< T > GetPrefixSymbol(const std::string &name)
Definition sound4cl.hpp:370
sound4cl_SampleFormat GetFormatFromName(const std::string &name)
Definition sound4cl.hpp:683
helper::DynFuncHolder< decltype(sound4cl_Webserver_GetAppHealth) > fnWebserver_GetAppHealth
Definition sound4cl.hpp:366
std::string GetFormatName(const sound4cl_SampleFormat fmt)
Definition sound4cl.hpp:674
helper::DynFuncHolder< decltype(sound4cl_SetLogSeverity) > fnSetLogSeverity
Definition sound4cl.hpp:293
helper::DynFuncHolder< decltype(sound4cl_AddAudio) > fnAddAudio
Definition sound4cl.hpp:315
helper::DynFuncHolder< decltype(sound4cl_GetAudio) > fnGetAudio
Definition sound4cl.hpp:318
unsigned int GetSampleRate()
Definition sound4cl.hpp:665
helper::DynFuncHolder< decltype(sound4cl_InitProcess) > fnInitProcess
Definition sound4cl.hpp:299
helper::DynFuncHolder< decltype(sound4cl_AudioMonoFromLiveStereo) > fnAudioMonoFromLiveStereo
Definition sound4cl.hpp:323
void MonoToStereo(const float *input, float *output, size_t nSpl)
Definition sound4cl.hpp:579
helper::DynFuncHolder< decltype(sound4cl_GetVersion) > fnGetVersion
Definition sound4cl.hpp:286
helper::DynFuncHolder< decltype(sound4cl_FreeParameters) > fnFreeParameters
Definition sound4cl.hpp:295
helper::DynFuncHolder< decltype(sound4cl_GetPossibleChunkSizeInFrames) > fnGetPossibleChunkSizeInFrames
Definition sound4cl.hpp:352
std::string GetVersion()
Definition sound4cl.hpp:595
void AudioMonoFromLiveStereo(const uint8_t *payload, float *output)
Definition sound4cl.hpp:585
helper::DynFuncHolder< decltype(sound4cl_GetChunkSizeInFrames) > fnGetChunkSizeInFrames
Definition sound4cl.hpp:287
helper::DynFuncHolder< decltype(sound4cl_StopUpdateThread) > fnStopUpdateThread
Definition sound4cl.hpp:304
helper::DynFuncHolder< decltype(sound4cl_ProcessAudio_Planar) > fnProcessAudio_Planar
Definition sound4cl.hpp:307
bool IsOk() const
Check if the library was loaded correctly.
Definition sound4cl.hpp:565
helper::DynFuncHolder< decltype(sound4cl_GetFormatName) > fnGetFormatName
Definition sound4cl.hpp:311
helper::DynFuncHolder< decltype(sound4cl_FreeParameterValue) > fnFreeParameterValue
Definition sound4cl.hpp:298
helper::DynFuncHolder< decltype(sound4cl_GetFormatFromName) > fnGetFormatFromName
Definition sound4cl.hpp:312
helper::DynFuncHolder< decltype(sound4cl_GetAudioInputCount) > fnGetAudioInputCount
Definition sound4cl.hpp:289
void MonoToStereo_Planar(const float *input, float *outputL, float *outputR, size_t nSpl)
Definition sound4cl.hpp:583
helper::DynFuncHolder< decltype(sound4cl_ExitProcess) > fnExitProcess
Definition sound4cl.hpp:302
helper::DynFuncHolder< decltype(sound4cl_SetPresetManager) > fnSetPresetManager
Definition sound4cl.hpp:348
void StereoToMono(const float *input, float *output, size_t nSpl)
Definition sound4cl.hpp:577
unsigned int GetChannelCount()
Definition sound4cl.hpp:635
helper::DynFuncHolder< decltype(sound4cl_GetEstimatedDelay) > fnGetEstimatedDelay
Definition sound4cl.hpp:310
helper::DynFuncHolder< decltype(sound4cl_FreeJsonAnswer) > fnFreeJsonAnswer
Definition sound4cl.hpp:328
helper::DynFuncHolder< decltype(sound4cl_GetBufferOut) > fnGetBufferOut
Definition sound4cl.hpp:309
CProcessor()=default
helper::DynFuncHolder< decltype(sound4cl_Webserver_tcp) > fnWebserver_tcp
Definition sound4cl.hpp:332
helper::DynFuncHolder< decltype(sound4cl_PresetManager_InformChange) > fnPresetManager_InformChange
Definition sound4cl.hpp:349
Helper to load dynamic library.
Definition sound4cl.hpp:136
DynFuncHolder< T > GetSymbol_safe(const std::string &name)
Definition sound4cl.hpp:215
CDynLoader & operator=(CDynLoader const &)=delete
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:188
CDynLoader(const CDynLoader &)=delete
static std::filesystem::path GetThisLibraryPath(void)
Definition sound4cl.hpp:219
CDynLoader(CDynLoader &&)=default
DynFuncHolder< T > GetSymbol(const std::string &name)
Definition sound4cl.hpp:207
Helper to wrap a function pointer.
Definition sound4cl.hpp:121
DynFuncHolder(DynFunc_t a_ptr)
Definition sound4cl.hpp:126
@ 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
const LogSeverity info
Definition sound4cl.hpp:248
const LogSeverity verbose5
Definition sound4cl.hpp:253
const LogSeverity fatal
Definition sound4cl.hpp:245
std::function< void(LogSeverity, const std::string &)> log_cb_t
Definition sound4cl.hpp:258
const LogSeverity verbose4
Definition sound4cl.hpp:252
const LogSeverity verbose
Definition sound4cl.hpp:249
const LogSeverity warning
Definition sound4cl.hpp:247
const LogSeverity error
Definition sound4cl.hpp:246
sound4cl_LogSeverity LogSeverity
Definition sound4cl.hpp:243
const LogSeverity none
Definition sound4cl.hpp:244
const LogSeverity verbose3
Definition sound4cl.hpp:251
const LogSeverity verbose2
Definition sound4cl.hpp:250
#define fs_strdup
helper for OS dependant file name copy
C function signature definition for all sound4.cl libraries.
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)
const struct sound4cl_SOUND4_ProcessInfo * sound4cl_SOUND4_GetProcessInfo()
void sound4cl_Webserver_SetAppHealth(struct sound4cl_CInstance *instance, int httpcode, const char *contenttype, const char *content)
void sound4cl_FreeMetadataInfos(struct sound4cl_CInstance *instance, const char **infos)
const char * sound4cl_ProcessJson(struct sound4cl_CClientInstance *client, const char *json_str, int *need_save)
struct sound4cl_CBus * sound4cl_NewBus()
const char ** sound4cl_GetMetadataInfos(struct sound4cl_CInstance *instance)
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)
struct sound4cl_CParameters * sound4cl_NewParameters()
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)
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)
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)
struct sound4cl_CClientInstance * sound4cl_NewClient(struct sound4cl_CInstance *instance)
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)
unsigned int * sound4cl_GetPossibleChunkSizeInFrames()
void sound4cl_StartUpdateThread(struct sound4cl_CInstance *instance, unsigned int port)
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)
float * sound4cl_GetBufferOut(struct sound4cl_CInstance *instance)
void sound4cl_SetMetadata(struct sound4cl_CInstance *instance, const char *key, const char *value)
void sound4cl_AudioMonoFromLiveStereo(const uint8_t *payload, float *output)
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)
void sound4cl_FreeParameterValue(const char *value)
sound4cl_LogSeverity
@ sound4cl_info
@ sound4cl_none
@ sound4cl_verbose5
@ sound4cl_warning
@ sound4cl_verbose4
@ sound4cl_verbose2
@ sound4cl_verbose3
@ sound4cl_error
@ sound4cl_verbose
@ sound4cl_fatal
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)
const char * sound4cl_GetFormatName(const enum sound4cl_SampleFormat fmt)
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_AudioMonoToLiveStereo(const float *input, uint8_t *payload)
float * sound4cl_GetBufferIn(struct sound4cl_CInstance *instance)
void sound4cl_ExitProcess(struct sound4cl_CInstance *instance)
void sound4cl_StopUpdateThread(struct sound4cl_CInstance *instance)
const char * sound4cl_GetVersion()
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)
sound4cl_SampleFormat
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
unsigned int sound4cl_GetSampleRate()
const char * sound4cl_GetParameter(struct sound4cl_CParameters *params, const char *name)
unsigned int sound4cl_GetOutputCount(struct sound4cl_CInstance *instance)
void sound4cl_SetLoggerCallback(sound4cl_loggerfn logger)
Helper for Sample format types.
Definition sound4cl.hpp:91