SOUND4 IMPACT.CL Library [1.3.2]
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 m_lib.Load(std::filesystem::current_path() / filename);
407 }
408 if (!m_lib.IsOk()) {
409 return false;
410 }
411 }
412 // Get information from the library itself
413 try {
414 auto GetInfo = m_lib.GetSymbol< decltype(sound4cl_SOUND4_GetProcessInfo ) >("SOUND4_GetProcessInfo" );
415 auto info = GetInfo();
416 m_prefix = info->prefix;
417 } catch (std::runtime_error& ) {
418 // Compatibility: search in known libraries without this function
419 #ifdef _WIN32
420 std::string filename = helper::WStringToUTF8(filepath.stem());
421 #else // !_WIN32
422 std::string filename = filepath.stem();
423 // remove lib prefix
424 filename=filename.substr(3);
425 #endif // ! _WIN32
426 if (filename=="sound4.x1.cloud") {
427 m_prefix="cloudx1_";
428 } else if (filename=="sound4.impact.cl") {
429 m_prefix="impact_";
430 } else if (filename=="sound4.bigvoice.cl") {
431 m_prefix="bigvoice_";
432 } else {
433 return false;
434 }
435 }
436
437 // Load all C functions
438 try {
439 fnGetVersion = GetPrefixSymbol< decltype(sound4cl_GetVersion ) >("GetVersion" );
440 fnGetChunkSizeInFrames = GetPrefixSymbol< decltype(sound4cl_GetChunkSizeInFrames ) >("GetChunkSizeInFrames" );
441 fnGetChannelCount = GetPrefixSymbol< decltype(sound4cl_GetChannelCount ) >("GetChannelCount" );
442 fnGetAudioInputCount = GetPrefixSymbol< decltype(sound4cl_GetAudioInputCount ) >("GetAudioInputCount" );
443 fnGetAudioOutputCount = GetPrefixSymbol< decltype(sound4cl_GetAudioOutputCount ) >("GetAudioOutputCount" );
444 fnGetSampleRate = GetPrefixSymbol< decltype(sound4cl_GetSampleRate ) >("GetSampleRate" );
445 fnSetLoggerCallback = GetPrefixSymbol< decltype(sound4cl_SetLoggerCallback ) >("SetLoggerCallback" );
446 fnSetLogSeverity = GetPrefixSymbol< decltype(sound4cl_SetLogSeverity ) >("SetLogSeverity" );
447 fnNewParameters = GetPrefixSymbol< decltype(sound4cl_NewParameters ) >("NewParameters" );
448 fnFreeParameters = GetPrefixSymbol< decltype(sound4cl_FreeParameters ) >("FreeParameters" );
449 fnSetParameter = GetPrefixSymbol< decltype(sound4cl_SetParameter ) >("SetParameter" );
450 fnGetParameter = GetPrefixSymbol< decltype(sound4cl_GetParameter ) >("GetParameter" );
451 fnFreeParameterValue = GetPrefixSymbol< decltype(sound4cl_FreeParameterValue ) >("FreeParameterValue" );
452 fnInitProcess = GetPrefixSymbol< decltype(sound4cl_InitProcess ) >("InitProcess" );
453 fnInitProcess2 = GetPrefixSymbol< decltype(sound4cl_InitProcess2 ) >("InitProcess2" );
454 fnTerminateProcess = GetPrefixSymbol< decltype(sound4cl_TerminateProcess ) >("TerminateProcess" );
455 fnExitProcess = GetPrefixSymbol< decltype(sound4cl_ExitProcess ) >("ExitProcess" );
456 fnStartUpdateThread = GetPrefixSymbol< decltype(sound4cl_StartUpdateThread ) >("StartUpdateThread" );
457 fnStopUpdateThread = GetPrefixSymbol< decltype(sound4cl_StopUpdateThread ) >("StopUpdateThread" );
458 fnWaitUpdateThreadReady = GetPrefixSymbol< decltype(sound4cl_WaitUpdateThreadReady ) >("WaitUpdateThreadReady" );
459 fnProcessAudio = GetPrefixSymbol< decltype(sound4cl_ProcessAudio ) >("ProcessAudio" );
460 fnProcessAudio_Planar = GetPrefixSymbol< decltype(sound4cl_ProcessAudio_Planar ) >("ProcessAudio_Planar" );
461 fnGetBufferIn = GetPrefixSymbol< decltype(sound4cl_GetBufferIn ) >("GetBufferIn" );
462 fnGetBufferOut = GetPrefixSymbol< decltype(sound4cl_GetBufferOut ) >("GetBufferOut" );
463 fnGetEstimatedDelay = GetPrefixSymbol< decltype(sound4cl_GetEstimatedDelay ) >("GetEstimatedDelay" );
464 fnGetFormatName = GetPrefixSymbol< decltype(sound4cl_GetFormatName ) >("GetFormatName" );
465 fnGetFormatFromName = GetPrefixSymbol< decltype(sound4cl_GetFormatFromName ) >("GetFormatFromName" );
466 fnGetBytesFromFormat = GetPrefixSymbol< decltype(sound4cl_GetBytesFromFormat ) >("GetBytesFromFormat" );
467 fnGetMaxPacketFrame = GetPrefixSymbol< decltype(sound4cl_GetMaxPacketFrame ) >("GetMaxPacketFrame" );
468 fnAddAudio = GetPrefixSymbol< decltype(sound4cl_AddAudio ) >("AddAudio" );
469 fnAddPadAudio = GetPrefixSymbol< decltype(sound4cl_AddPadAudio ) >("AddPadAudio" );
470 fnGetOutputCount = GetPrefixSymbol< decltype(sound4cl_GetOutputCount ) >("GetOutputCount" );
471 fnGetAudio = GetPrefixSymbol< decltype(sound4cl_GetAudio ) >("GetAudio" );
472 fnAudioConvertFrom = GetPrefixSymbol< decltype(sound4cl_AudioConvertFrom ) >("AudioConvertFrom" );
473 fnAudioConvertTo = GetPrefixSymbol< decltype(sound4cl_AudioConvertTo ) >("AudioConvertTo" );
474 fnStereoToMono = GetPrefixSymbol< decltype(sound4cl_StereoToMono ) >("StereoToMono" );
475 fnMonoToStereo = GetPrefixSymbol< decltype(sound4cl_MonoToStereo ) >("MonoToStereo" );
476 fnAudioMonoFromLiveStereo = GetPrefixSymbol< decltype(sound4cl_AudioMonoFromLiveStereo) >("AudioMonoFromLiveStereo");
477 fnAudioMonoToLiveStereo = GetPrefixSymbol< decltype(sound4cl_AudioMonoToLiveStereo ) >("AudioMonoToLiveStereo" );
478 fnNewClient = GetPrefixSymbol< decltype(sound4cl_NewClient ) >("NewClient" );
479 fnDeleteClient = GetPrefixSymbol< decltype(sound4cl_DeleteClient ) >("DeleteClient" );
480 fnProcessJson = GetPrefixSymbol< decltype(sound4cl_ProcessJson ) >("ProcessJson" );
481 fnFreeJsonAnswer = GetPrefixSymbol< decltype(sound4cl_FreeJsonAnswer ) >("FreeJsonAnswer" );
482 fnSaveState = GetPrefixSymbol< decltype(sound4cl_SaveState ) >("SaveState" );
483 } catch (std::runtime_error& ) {
484 return false;
485 }
486 // Webserver : not for all projects
487 try {
488 fnWebserver_tcp = GetPrefixSymbol< decltype(sound4cl_Webserver_tcp ) >("Webserver_tcp" );
489 fnWebserver_tcp2 = GetPrefixSymbol< decltype(sound4cl_Webserver_tcp2 ) >("Webserver_tcp2" );
490 fnWebserver = GetPrefixSymbol< decltype(sound4cl_Webserver ) >("Webserver" );
491 fnWebserver_Stop = GetPrefixSymbol< decltype(sound4cl_Webserver_Stop ) >("Webserver_Stop" );
492 fnWebserver_Status = GetPrefixSymbol< decltype(sound4cl_Webserver_Status ) >("Webserver_Status" );
493 } catch (std::runtime_error& ) {
494 // Ignored, handler will take care
495 }
496 // Stereo/Mono conversion : must be present
497 try {
498 // added 2023-03-22
499 fnStereoToMono_Planar = GetPrefixSymbol< decltype(sound4cl_StereoToMono_Planar ) >("StereoToMono_Planar" );
500 fnMonoToStereo_Planar = GetPrefixSymbol< decltype(sound4cl_MonoToStereo_Planar ) >("MonoToStereo_Planar" );
501
502 } catch (std::runtime_error& ) {
503 return false;
504 }
505 // C functions allowed to be missing
506 try {
507 // added 2023-05-22
508 fnSetMetadata = GetPrefixSymbol< decltype(sound4cl_SetMetadata ) >("SetMetadata" );
509 fnGetMetadataInfos = GetPrefixSymbol< decltype(sound4cl_GetMetadataInfos ) >("GetMetadataInfos" );
510 fnFreeMetadataInfos = GetPrefixSymbol< decltype(sound4cl_FreeMetadataInfos ) >("FreeMetadataInfos" );
511 // added 2023-06-20
512 fnSetPresetManager = GetPrefixSymbol< decltype(sound4cl_SetPresetManager ) >("SetPresetManager" );
513 fnPresetManager_InformChange = GetPrefixSymbol< decltype(sound4cl_PresetManager_InformChange ) >("PresetManager_InformChange" );
514
515 // added 2023-09-21
516 fnGetPossibleChunkSizeInFrames = GetPrefixSymbol< decltype(sound4cl_GetPossibleChunkSizeInFrames ) >("GetPossibleChunkSizeInFrames" );
517 fnGetProcessChunkFrames = GetPrefixSymbol< decltype(sound4cl_GetProcessChunkFrames ) >("GetProcessChunkFrames" );
518 fnInitProcess3 = GetPrefixSymbol< decltype(sound4cl_InitProcess3 ) >("InitProcess3" );
519 } catch (std::runtime_error& ) {
520 // Ignored, handler will take care
521 }
522
523 // bus: not for all projects
524 try {
525 // added 2023-06-26
526 fnNewBus = GetPrefixSymbol< decltype(sound4cl_NewBus ) >("NewBus" );
527 fnFreeBus = GetPrefixSymbol< decltype(sound4cl_FreeBus ) >("FreeBus" );
528 fnSetInstanceBus = GetPrefixSymbol< decltype(sound4cl_SetInstanceBus ) >("SetInstanceBus" );
529 } catch (std::runtime_error& ) {
530 // Ignored, handler will take care
531 }
532
533 // Other optional
534 try {
535 // added 2024-02-19
536 fnSetMetadataMulti = GetPrefixSymbol< decltype(sound4cl_SetMetadataMulti ) >("SetMetadataMulti" );
537
538 } catch (std::runtime_error& ) {
539 // Ignored, handler will take care
540 }
541
542 // Other optional, web server only
543 try {
544 // added 2024-05-23
545 fnWebserver_SetAppHealth = GetPrefixSymbol< decltype(sound4cl_Webserver_SetAppHealth ) >("Webserver_SetAppHealth" );
546 fnWebserver_GetAppHealth = GetPrefixSymbol< decltype(sound4cl_Webserver_GetAppHealth ) >("Webserver_GetAppHealth" );
547 fnWebserver_FreeString = GetPrefixSymbol< decltype(sound4cl_Webserver_FreeString ) >("Webserver_FreeString" );
548 } catch (std::runtime_error& ) {
549 // Ignored, handler will take care
550 }
551
552 m_bOK=true;
553 return true;
554 }
561 bool IsOk() const {
562 return m_bOK;
563 }
564
569 void AudioConvertFrom(const uint8_t *payload, float *output, size_t nSpl, sound4cl_SampleFormat fmt)
570 { fnAudioConvertFrom(payload, output, nSpl, fmt); }
571 void AudioConvertTo(const float *input, uint8_t *payload, size_t nSpl, sound4cl_SampleFormat fmt)
572 { fnAudioConvertTo(input, payload, nSpl, fmt); }
573 void StereoToMono(const float *input, float *output, size_t nSpl)
574 { fnStereoToMono(input, output, nSpl); }
575 void MonoToStereo(const float *input, float *output, size_t nSpl)
576 { fnMonoToStereo(input, output, nSpl); }
577 void StereoToMono_Planar(const float *inputL, const float *inputR, float *output, size_t nSpl)
578 { fnStereoToMono_Planar(inputL, inputR, output, nSpl); }
579 void MonoToStereo_Planar(const float *input, float *outputL, float *outputR, size_t nSpl)
580 { fnMonoToStereo_Planar(input, outputL, outputR, nSpl); }
581 void AudioMonoFromLiveStereo(const uint8_t *payload, float *output)
582 { fnAudioMonoFromLiveStereo(payload, output); }
583 void AudioMonoToLiveStereo(const float *input, uint8_t *payload)
584 { fnAudioMonoToLiveStereo(input, payload); }
585
591 std::string GetVersion()
592 { return std::string(fnGetVersion()); }
593
602 unsigned int GetChunkSizeInFrames()
603 { return fnGetChunkSizeInFrames(); }
604
613 std::vector<unsigned int> GetPossibleChunkSizeInFrames()
614 {
615 std::vector<unsigned int> list;
617 for (unsigned int* src=fnGetPossibleChunkSizeInFrames();*src;src++) {
618 list.push_back(*src);
619 }
620 } else {
621 list.push_back(fnGetChunkSizeInFrames());
622 }
623 return list;
624 }
625
631 unsigned int GetChannelCount()
632 { return fnGetChannelCount(); }
633
641 unsigned int GetAudioInputCount()
642 { return fnGetAudioInputCount(); }
643
651 unsigned int GetAudioOutputCount()
652 { return fnGetAudioOutputCount(); }
653
661 unsigned int GetSampleRate()
662 { return fnGetSampleRate(); }
663
670 std::string GetFormatName( const sound4cl_SampleFormat fmt)
671 { return std::string(fnGetFormatName(fmt)); }
672
679 sound4cl_SampleFormat GetFormatFromName( const std::string& name)
680 { return fnGetFormatFromName(name.c_str()); }
681
689 { return fnGetBytesFromFormat(fmt); }
690
695 { fnSetLogSeverity(severity); }
696
701 { _log_cb=cb; fnSetLoggerCallback(&_log_cb_c); }
702 };
703
709 class CBus {
710 public:
712 : m_dynlib(dynlib)
713 {
714 if (m_dynlib.fnNewBus) {
715 m_bus=m_dynlib.fnNewBus();
716 }
717 }
719 {
720 if (m_bus && m_dynlib.fnFreeBus) {
721 m_dynlib.fnFreeBus(m_bus);
722 }
723 m_bus = nullptr;
724 }
725 sound4cl_CBus *Get() const { return m_bus; }
726 private:
727 CProcessor& m_dynlib;
728 sound4cl_CBus *m_bus;
729 };
730
737 public:
738 CPresetLoader() = default;
739 virtual ~CPresetLoader() = default;
740
741 virtual bool IsReadOnly() = 0;
742 virtual bool Exists(const std::filesystem::path &name) = 0;
743 virtual bool Remove(const std::filesystem::path &name) = 0;
744 virtual bool Rename(const std::filesystem::path &from, const std::filesystem::path &to) = 0;
745 virtual std::vector<std::filesystem::path> GetAll() = 0;
746 virtual std::string Read(const std::filesystem::path &filename) = 0;
747 virtual bool Write(const std::filesystem::path &filename, const std::string &content) =0;
748 };
750
756 class CInstance {
757 public:
762 : m_dynlib(dynlib)
763 {
764 params = m_dynlib.fnNewParameters();
765 if (!params) throw std::bad_alloc();
766 }
767 // non-copyable
768 CInstance( const CInstance& ) = delete;
769 CInstance& operator=( const CInstance& ) = delete;
773 virtual ~CInstance()
774 {
775 Stop();
776 if (params) m_dynlib.fnFreeParameters(params);
777 }
781 bool IsOk() const { return instance!=nullptr; }
789 void SetParam(const std::string& name, const std::string& value)
790 {
791 assert(params);
792 m_dynlib.fnSetParameter(params, name.c_str(), value.c_str());
793 }
799 std::string GetParam(const std::string& name)
800 {
801 assert(params);
802 auto c_value=m_dynlib.fnGetParameter(params, name.c_str());
803 std::string ret(c_value);
804 m_dynlib.fnFreeParameterValue(c_value);
805 return ret;
806 }
807
811 void SetBus(const CBus& bus) {
812 assert(params);
813 if (m_dynlib.fnSetInstanceBus) {
814 m_dynlib.fnSetInstanceBus(params,bus.Get());
815 }
816 }
817
827 void SetPresetManager(CPresetLoader *preset_manager)
828 {
829 if (!preset_manager) return;
830 if (!m_dynlib.fnSetPresetManager) return;
831 assert(params);
832 m_dynlib.fnSetPresetManager(params,
833 sound4cl_custom_reader,
834 sound4cl_custom_reader_free,
835 sound4cl_custom_writer,
836 sound4cl_custom_exists,
837 sound4cl_custom_getall,
838 sound4cl_custom_getall_free,
839 sound4cl_custom_remove,
840 sound4cl_custom_rename,
841 preset_manager->IsReadOnly(),
842 preset_manager
843 );
844 }
845
860 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)
861 {
862 assert(!instance);
863 std::string l_save_path;
864 if (!save_path.empty()) {
865 l_save_path = save_path.u8string();
866 }
867 if (frames_per_chunk==0) {
868 frames_per_chunk=m_dynlib.GetChunkSizeInFrames();
869 }
870 if (m_dynlib.fnInitProcess3) {
871 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);
872 } else if (frames_per_chunk!=m_dynlib.GetChunkSizeInFrames()) {
873 return false;
874 } else {
875 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);
876 }
877 if (!instance) return false;
878 if (!init_metadata.empty()) {
879 for (auto&& [key,value]: init_metadata) {
880 m_dynlib.fnSetMetadata(instance, key.c_str(), value.c_str());
881 }
882 init_metadata.clear();
883 }
884 update_thread = std::thread([this, json_port](){
886 m_dynlib.fnStartUpdateThread(instance, json_port);
888 });
889 int timeout=5000;
890 #ifdef DEBUG
891 timeout=60*1000; // For debugger pauses
892 #endif
893 if (m_dynlib.fnWaitUpdateThreadReady(instance, timeout)<0) {
894 return false;
895 }
896 return true;
897 }
898
906 unsigned int GetChunkFrames() {
907 if (instance && m_dynlib.fnGetProcessChunkFrames) {
908 return m_dynlib.fnGetProcessChunkFrames(instance);
909 }
910 return m_dynlib.fnGetChunkSizeInFrames();
911 }
912
920 void PresetManager_InformChange(const std::filesystem::path& relative_path, PresetChange_Kind change_kind)
921 {
922 if (m_dynlib.fnPresetManager_InformChange) {
923 m_dynlib.fnPresetManager_InformChange(instance, relative_path.c_str(), (sound4cl_PresetChange_Kind) change_kind);
924 }
925 }
926
938 void SetMetadata(const std::string& key, const char* value)
939 {
940 if (m_dynlib.fnSetMetadata) {
941 if (instance) {
942 m_dynlib.fnSetMetadata(instance, key.c_str(), value);
943 } else {
944 init_metadata.push_back( {key, value} );
945 }
946 }
947 }
948
949
959 void SetMetadataMulti(const std::unordered_map<std::string, const char*>& list)
960 {
961 if (instance) {
962 if (m_dynlib.fnSetMetadataMulti) {
963 typedef const char* pchar;
964 pchar* keyvalue=new pchar[2*list.size()+1];
965 size_t n=0;
966 for (auto&& [key,value]: list) {
967 keyvalue[2*n+0]=key.c_str();
968 keyvalue[2*n+1]=value;
969 n++;
970 }
971 keyvalue[2*n+0]=nullptr;
972
973 sound4cl_SetMetadataMulti(instance, keyvalue);
974
975 delete[] keyvalue;
976 } else {
977 for (auto&& [key,value]: list) {
978 SetMetadata(key, value);
979 }
980 }
981 } else {
982 for (auto&& [key,value]: list) {
983 if (value) {
984 init_metadata.push_back( {key, value} );
985 }
986 }
987 }
988 }
989
995 std::vector< std::tuple<std::string,std::string> > GetMetadataInfos()
996 {
997 std::vector< std::tuple<std::string,std::string> > values;
998 if (m_dynlib.fnGetMetadataInfos) {
999 const char** c_values = m_dynlib.fnGetMetadataInfos(instance);
1000 if (c_values) {
1001 for (const char** c_value=c_values; *c_value; ) {
1002 std::string key(*c_value);
1003 c_value++;
1004 if (*c_value) {
1005 std::string descr(*c_value);
1006 c_value++;
1007 values.push_back( {key,descr} );
1008 }
1009 }
1010 m_dynlib.fnFreeMetadataInfos(instance, c_values);
1011 }
1012 }
1013 return values;
1014 }
1015
1016 // Can be overloaded, called at start of UpdateThread in the thread
1017 virtual void OnUpdateThreadStart() {}
1018 // Can be overloaded to call at end of UpdateThread in the thread
1019 virtual void OnUpdateThreadStop() {}
1020
1026 bool StartWebServer(int http_port, int https_port=0)
1027 {
1028 assert(instance);
1029 assert(webserver==SOUND4_INVALID_WEBSERVER_ID);
1030 if (!m_dynlib.fnWebserver) {
1031 return false;
1032 }
1033 webserver = m_dynlib.fnWebserver(http_port,https_port,instance);
1034 if (webserver==SOUND4_INVALID_WEBSERVER_ID) {
1035 return false;
1036 }
1037 int web_status=m_dynlib.fnWebserver_Status(webserver);
1038 if (http_port && (web_status & SOUND4_WEBSERVER_HTTP_OK) == 0) {
1039 return false;
1040 }
1041 if (https_port && (web_status & SOUND4_WEBSERVER_HTTPS_OK) == 0) {
1042 return false;
1043 }
1044 return true;
1045 }
1052 {
1053 if (!m_dynlib.fnWebserver_Stop) return;
1054 if (webserver != SOUND4_INVALID_WEBSERVER_ID) {
1055 m_dynlib.fnWebserver_Stop(webserver, 1000);
1056 webserver = SOUND4_INVALID_WEBSERVER_ID;
1057 }
1058 }
1059
1063 void SetWebServerAppHealth(int httpcode, const std::string& contenttype, const std::string& content)
1064 {
1065 assert(instance);
1066 if (!m_dynlib.fnWebserver_SetAppHealth) return;
1067 m_dynlib.fnWebserver_SetAppHealth(instance, httpcode, contenttype.c_str(), content.c_str());
1068 }
1072 void GetWebServerAppHealth(int &httpcode, std::string& contenttype, std::string& content)
1073 {
1074 assert(instance);
1075 if (!m_dynlib.fnWebserver_GetAppHealth) return;
1076 char* c_contenttype=nullptr;
1077 char* c_content=nullptr;
1078 m_dynlib.fnWebserver_GetAppHealth(instance, &httpcode, &c_contenttype, &c_content);
1079 contenttype=c_contenttype;
1080 content=c_content;
1081 m_dynlib.fnWebserver_FreeString(c_contenttype);
1082 m_dynlib.fnWebserver_FreeString(c_content);
1083 }
1091 {
1092 if (!instance) return 0;
1093 return m_dynlib.fnTerminateProcess(instance);
1094 }
1095
1101 void Stop()
1102 {
1103 if (!instance) return;
1104 StopWebServer();
1105 if (update_thread.joinable()) {
1106 m_dynlib.fnStopUpdateThread(instance); // this will exit the update thread
1107 update_thread.join();
1108 }
1109 m_dynlib.fnExitProcess(instance);
1110 instance=nullptr;
1111 }
1112
1118 unsigned int GetEstimatedDelay()
1119 {
1120 assert(instance);
1121 return m_dynlib.fnGetEstimatedDelay(instance);
1122 }
1123
1135 {
1136 assert(instance);
1137 return m_dynlib.fnGetBufferIn(instance);
1138
1139 }
1151 {
1152 assert(instance);
1153 return m_dynlib.fnGetBufferOut(instance);
1154 }
1161 {
1162 assert(instance);
1163 m_dynlib.fnProcessAudio(instance, m_dynlib.fnGetBufferIn(instance), m_dynlib.fnGetBufferOut(instance));
1164 }
1178 // void ProcessAudio_Planar(const std::array< const std::array<const float,ChunkFrames>, InputChannels>& input, std::array< std::array<float,ChunkFrames>, OutputChannels>& output)
1179 void ProcessAudio_Planar(float const * const *input, float * const *output)
1180 {
1181 assert(instance);
1182 m_dynlib.fnProcessAudio_Planar(instance, input, output);
1183 }
1184
1196 template<typename T>
1197 std::vector<T> ProcessAnyAudio(const std::vector<T> input)
1198 {
1199 assert(instance);
1200 std::vector<T> output;
1201 unsigned int out_offset=0;
1202 unsigned int in_offset=0;
1203 unsigned int todo = input.size();
1204 while (todo>0) {
1205 unsigned int left = AddAudio(&input[in_offset], todo);
1206 unsigned int out_avail = m_dynlib.fnGetOutputCount(instance);
1207 output.resize(out_offset + out_avail);
1208 GetAudio(&output[out_offset], out_avail);
1209 out_offset+=out_avail;
1210 in_offset += todo-left;
1211 todo=left;
1212 }
1213 return output;
1214 }
1215
1221 class CClient {
1222 public:
1223 CClient(sound4cl_CInstance* instance, CProcessor& dynlib)
1224 : m_dynlib(dynlib)
1225 {
1226 assert(instance);
1227 client=m_dynlib.fnNewClient(instance);
1228 if (!client) throw std::bad_alloc();
1229 }
1230 // non-copyable
1231 CClient( const CInstance& ) = delete;
1232 CClient& operator=( const CInstance& ) = delete;
1234 {
1235 if (client) {
1236 m_dynlib.fnDeleteClient(client);
1237 client=nullptr;
1238 }
1239 }
1247 std::string ProcessJson(const std::string &request, bool *NeedSave = nullptr)
1248 {
1249 assert(client);
1250 int need_save=0;
1251 const char *canswer = m_dynlib.fnProcessJson(client, request.c_str(), &need_save);
1252 if (!canswer) return {};
1253 std::string answer(canswer);
1254 m_dynlib.fnFreeJsonAnswer (canswer);
1255 if (NeedSave) {
1256 *NeedSave=(need_save!=0);
1257 }
1258 return answer;
1259 }
1260 private:
1261 CProcessor& m_dynlib;
1262 sound4cl_CClientInstance *client = nullptr;
1263 };
1271 std::shared_ptr<CClient> NewClient()
1272 {
1273 assert(instance);
1274 return std::make_shared<CClient>(instance, m_dynlib);
1275 }
1276
1277 protected:
1278 template<typename T>
1279 unsigned int AddAudio(const T* payload, unsigned int nFrame)
1280 {
1281 assert(instance);
1282 return m_dynlib.fnAddAudio(instance, reinterpret_cast<const T*>(payload), nFrame, helper::SampleFormat<T>::format);
1283 }
1284 template<typename T>
1285 unsigned int GetAudio(T* payload, unsigned int max_nFrame)
1286 {
1287 assert(instance);
1288 return m_dynlib.fnGetAudio(instance, reinterpret_cast<T*>(payload), max_nFrame, helper::SampleFormat<T>::format);
1289 }
1290
1291 private:
1292 CProcessor& m_dynlib;
1293 sound4cl_CParameters* params = nullptr;
1294 sound4cl_CInstance* instance = nullptr;
1295 std::thread update_thread;
1296 std::vector< std::pair<std::string,std::string> > init_metadata;
1297 uint64_t webserver = SOUND4_INVALID_WEBSERVER_ID;
1298 };
1299
1300}; // namespace sound4
1301
1302
1303// bridge C callbacks to CPresetLoader
1304extern "C" {
1305 static char *sound4cl_custom_reader(const fs_char *filename, void* userdata) {
1306 sound4::CPresetLoader *preset_loader=reinterpret_cast<sound4::CPresetLoader*>(userdata);
1307 std::string content=preset_loader->Read(filename);
1308 return strdup(content.c_str());
1309 }
1310 static void sound4cl_custom_reader_free(char *content, void* userdata) {
1311 if (!content) return;
1312 free(content);
1313 }
1314 static int sound4cl_custom_writer(const fs_char *filename, const char *content, void* userdata) {
1315 sound4::CPresetLoader *preset_loader=reinterpret_cast<sound4::CPresetLoader*>(userdata);
1316 auto res=preset_loader->Write(filename,content);
1317 return res?0:-1;
1318 }
1319 static int sound4cl_custom_exists(const fs_char *filename, void* userdata) {
1320 sound4::CPresetLoader *preset_loader=reinterpret_cast<sound4::CPresetLoader*>(userdata);
1321 auto res=preset_loader->Exists(filename);
1322 return res?0:-1;
1323 }
1324 static fs_char** sound4cl_custom_getall(void* userdata) {
1325 sound4::CPresetLoader *preset_loader=reinterpret_cast<sound4::CPresetLoader*>(userdata);
1326 auto res=preset_loader->GetAll();
1327 fs_char**all=(fs_char**)malloc((res.size()+1)*sizeof(const fs_char*));
1328 for (size_t n=0;n<res.size();n++) {
1329 all[n]=fs_strdup(res[n].c_str());
1330 }
1331 all[res.size()]=nullptr;
1332 return all;
1333 }
1334 static void sound4cl_custom_getall_free(fs_char** all, void* userdata) {
1335 if (!all) return;
1336 for (fs_char** one=all;*one;one++) {
1337 free(*one);
1338 }
1339 free(all);
1340 }
1341 static int sound4cl_custom_remove(const fs_char *filename, void* userdata) {
1342 sound4::CPresetLoader *preset_loader=reinterpret_cast<sound4::CPresetLoader*>(userdata);
1343 auto res=preset_loader->Remove(filename);
1344 return res?0:-1;
1345 }
1346 static int sound4cl_custom_rename(const fs_char *from, const fs_char *to, void* userdata) {
1347 sound4::CPresetLoader *preset_loader=reinterpret_cast<sound4::CPresetLoader*>(userdata);
1348 auto res=preset_loader->Rename(from,to);
1349 return res?0:-1;
1350 }
1351
1352};
Shared Bus.
Definition sound4cl.hpp:709
sound4cl_CBus * Get() const
Definition sound4cl.hpp:725
CBus(CProcessor &dynlib)
Definition sound4cl.hpp:711
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:756
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:860
void ProcessAudio_Planar(float const *const *input, float *const *output)
std::vector< T > ProcessAnyAudio(const std::vector< T > input)
virtual ~CInstance()
Definition sound4cl.hpp:773
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:827
void SetBus(const CBus &bus)
Definition sound4cl.hpp:811
virtual void OnUpdateThreadStop()
unsigned int GetChunkFrames()
Definition sound4cl.hpp:906
void SetWebServerAppHealth(int httpcode, const std::string &contenttype, const std::string &content)
CInstance(CProcessor &dynlib)
Definition sound4cl.hpp:761
void SetParam(const std::string &name, const std::string &value)
Definition sound4cl.hpp:789
virtual void OnUpdateThreadStart()
bool IsOk() const
Definition sound4cl.hpp:781
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:920
void SetMetadataMulti(const std::unordered_map< std::string, const char * > &list)
Definition sound4cl.hpp:959
unsigned int AddAudio(const T *payload, unsigned int nFrame)
unsigned int GetEstimatedDelay()
std::vector< std::tuple< std::string, std::string > > GetMetadataInfos()
Definition sound4cl.hpp:995
std::shared_ptr< CClient > NewClient()
float * GetBufferOut()
void SetMetadata(const std::string &key, const char *value)
Definition sound4cl.hpp:938
float * GetBufferIn()
unsigned int GetAudio(T *payload, unsigned int max_nFrame)
std::string GetParam(const std::string &name)
Definition sound4cl.hpp:799
Custom preset handler helper.
Definition sound4cl.hpp:736
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:577
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:688
void AudioConvertTo(const float *input, uint8_t *payload, size_t nSpl, sound4cl_SampleFormat fmt)
Definition sound4cl.hpp:571
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:694
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:569
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:641
void AudioMonoToLiveStereo(const float *input, uint8_t *payload)
Definition sound4cl.hpp:583
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:700
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:602
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:613
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:651
helper::DynFuncHolder< T > GetPrefixSymbol(const std::string &name)
Definition sound4cl.hpp:370
sound4cl_SampleFormat GetFormatFromName(const std::string &name)
Definition sound4cl.hpp:679
helper::DynFuncHolder< decltype(sound4cl_Webserver_GetAppHealth) > fnWebserver_GetAppHealth
Definition sound4cl.hpp:366
std::string GetFormatName(const sound4cl_SampleFormat fmt)
Definition sound4cl.hpp:670
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:661
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:575
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:591
void AudioMonoFromLiveStereo(const uint8_t *payload, float *output)
Definition sound4cl.hpp:581
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:561
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:579
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:573
unsigned int GetChannelCount()
Definition sound4cl.hpp:631
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