SOUND4 IMPACT.CL Library [1.3.6]
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
72
76 namespace helper {
77 #ifdef _WIN32
83 static inline std::string WStringToUTF8(const std::wstring& wstr) {
84 if (wstr.empty()) return {};
85 int size = WideCharToMultiByte(CP_UTF8, 0, &wstr[0], (int)wstr.size(), NULL, 0, NULL, NULL);
86 std::string str(size, 0);
87 WideCharToMultiByte(CP_UTF8, 0, &wstr[0], (int)wstr.size(), &str[0], size, NULL, NULL);
88 return str;
89 }
95 static inline std::wstring UTF8ToWString(const std::string& str) {
96 if (str.empty()) return std::wstring();
97 int size = MultiByteToWideChar(CP_UTF8, 0, &str[0], (int)str.size(), NULL, 0);
98 std::wstring wstr(size, 0);
99 MultiByteToWideChar(CP_UTF8, 0, &str[0], (int)str.size(), &wstr[0], size);
100 return wstr;
101 }
102 #endif // _WIN32
103
109 template<typename T>
111 };
112 template<>
113 struct SampleFormat<int16_t> {
114 const sound4::SampleFormat format = S16_NATIVE;
115 };
116 template<>
117 struct SampleFormat<int32_t> {
118 const sound4::SampleFormat format = S32_NATIVE;
119 };
120 template<>
121 struct SampleFormat<float> {
122 const sound4::SampleFormat format = F32_NATIVE;
123 };
124
130 template <typename T>
132 // Storage definition, depending on OS
133 #if UNIXLIKE
134 using DynFunc_t = void *;
135 #else
136 using DynFunc_t = FARPROC;
137 #endif
138 private:
139 DynFunc_t m_ptr = NULL;
140 public:
141 DynFuncHolder() = default;
143 operator bool() const { return (m_ptr!=NULL); }
144 bool IsOk() const { return m_ptr!=NULL; }
145 operator T* () const { return reinterpret_cast<T*>(m_ptr); }
146 };
147
153 // Storage definition, depending on OS
154 #if UNIXLIKE
155 using DynLib_t = void *;
156 #else
157 using DynLib_t = HMODULE;
158 #endif
159 private:
160 DynLib_t m_lib {};
161 public:
162 CDynLoader() = default;
163 CDynLoader(CDynLoader&&) = default;
164 // No copy allowed
165 CDynLoader(const CDynLoader&) = delete;
166 CDynLoader& operator=(CDynLoader const&) = delete;
167 operator bool() const {
168 return (m_lib!=NULL);
169 }
170 bool IsOk() const {
171 return (m_lib!=NULL);
172 }
173 #if UNIXLIKE
174 void Close() {
175 if (IsOk()) {
176 #ifndef __SANITIZE_ADDRESS__ // avoid unloading to keep call stack
177 dlclose(m_lib);
178 #endif // __SANITIZE_ADDRESS__
179 m_lib=NULL;
180 }
181 }
182 bool Load(const std::filesystem::path& dynlib)
183 {
184 Close();
185 m_lib=dlopen(dynlib.c_str(), RTLD_NOW|RTLD_LOCAL);
186 return IsOk();
187 }
188 template <typename T>
189 DynFuncHolder<T> GetSymbol(const std::string& name) {
190 auto ptr=dlsym(m_lib, name.c_str());
191 if (!ptr) {
192 throw std::runtime_error("Missing function in library");
193 }
194 return DynFuncHolder<T>(ptr);
195 }
196 template <typename T>
197 DynFuncHolder<T> GetSymbol_safe(const std::string& name) {
198 auto ptr=dlsym(m_lib, name.c_str());
199 return DynFuncHolder<T>(ptr);
200 }
201 static std::filesystem::path GetThisLibraryPath(void) {
202 static Dl_info info;
203 if (! dladdr((void *) GetThisLibraryPath, & info)) return {};
204 auto rp=realpath(info.dli_fname, NULL);
205 std::filesystem::path p(rp);
206 free(rp);
207 return p;
208 }
209 #else
216 void Close() {
217 if (IsOk()) {
218 // NOTE: On Windows, FreeLibrary may create a lot of troubles, should use FreeLibraryAndExitThread but...
219 // So define SOUND4_CALL_FREELIBRARY before including this file if you really want to unload the library dynamically
220 #if defined(SOUND4_CALL_FREELIBRARYANDEXITTHREAD)
221 FreeLibraryAndExitThread(m_lib, 0);
222 #elif defined(SOUND4_CALL_FREELIBRARY)
223 FreeLibrary(m_lib);
224 #endif // SOUND4_CALL_FREELIBRARY
225 m_lib=NULL;
226 }
227 }
228 template <typename T>
229 DynFuncHolder<T> GetSymbol(const std::string& name) {
230 auto ptr=GetProcAddress(m_lib, name.c_str());
231 if (!ptr) {
232 throw std::runtime_error("Missing function in library");
233 }
234 return DynFuncHolder<T>(ptr);
235 }
236 template <typename T>
237 DynFuncHolder<T> GetSymbol_safe(const std::string& name) {
238 auto ptr=GetProcAddress(m_lib, name.c_str());
239 return DynFuncHolder<T>(ptr);
240 }
241 static std::filesystem::path GetThisLibraryPath(void) {
242 static wchar_t path[MAX_PATH]={};
243 HMODULE hm = NULL;
247 {
248 if (GetModuleFileNameW(hm, path, MAX_PATH) > 0) {
249 return std::filesystem::path(path);
250 }
251 }
252 return {};
253 }
254 #endif
255 virtual ~CDynLoader() {
256 Close();
257 }
258 }; // class CDynLoader
259 }; // namespace helper
260
261
266 none = sound4cl_none,
267 fatal = sound4cl_fatal,
268 error = sound4cl_error,
269 warning = sound4cl_warning,
270 info = sound4cl_info,
271 verbose = sound4cl_verbose,
272 verbose2 = sound4cl_verbose2,
273 verbose3 = sound4cl_verbose3,
274 verbose4 = sound4cl_verbose4,
275 verbose5 = sound4cl_verbose5,
276 };
277
281 using log_cb_t = std::function<void(LogSeverity,const std::string&)>;
282
287 extern "C" {
288 static inline void _log_cb_c(sound4cl_LogSeverity severity, const char *c_msg) {
289 _log_cb((LogSeverity)severity, std::string(c_msg));
290 }
291 }
292
300 private:
301 helper::CDynLoader m_lib;
302 bool m_bOK = false;
303 std::string m_prefix; // The prefix of functions, depends on the library (cloud_, impact_...)
304 protected:
305 friend class CBus;
306 friend class CInstance;
307
308 // All those wrapped functions have the same signature as there C sound4cl_XXX
309 helper::DynFuncHolder< decltype(sound4cl_GetVersion ) > fnGetVersion ;
310 helper::DynFuncHolder< decltype(sound4cl_GetChunkSizeInFrames ) > fnGetChunkSizeInFrames ;
311 helper::DynFuncHolder< decltype(sound4cl_GetChannelCount ) > fnGetChannelCount ;
312 helper::DynFuncHolder< decltype(sound4cl_GetAudioInputCount ) > fnGetAudioInputCount ;
313 helper::DynFuncHolder< decltype(sound4cl_GetAudioOutputCount ) > fnGetAudioOutputCount ;
314 helper::DynFuncHolder< decltype(sound4cl_GetSampleRate ) > fnGetSampleRate ;
315 helper::DynFuncHolder< decltype(sound4cl_SetLoggerCallback ) > fnSetLoggerCallback ;
316 helper::DynFuncHolder< decltype(sound4cl_SetLogSeverity ) > fnSetLogSeverity ;
317 helper::DynFuncHolder< decltype(sound4cl_NewParameters ) > fnNewParameters ;
318 helper::DynFuncHolder< decltype(sound4cl_FreeParameters ) > fnFreeParameters ;
319 helper::DynFuncHolder< decltype(sound4cl_SetParameter ) > fnSetParameter ;
320 helper::DynFuncHolder< decltype(sound4cl_GetParameter ) > fnGetParameter ;
321 helper::DynFuncHolder< decltype(sound4cl_FreeParameterValue ) > fnFreeParameterValue ;
322 helper::DynFuncHolder< decltype(sound4cl_InitProcess ) > fnInitProcess ;
323 helper::DynFuncHolder< decltype(sound4cl_InitProcess2 ) > fnInitProcess2 ;
324 helper::DynFuncHolder< decltype(sound4cl_TerminateProcess ) > fnTerminateProcess ;
325 helper::DynFuncHolder< decltype(sound4cl_ExitProcess ) > fnExitProcess ;
326 helper::DynFuncHolder< decltype(sound4cl_StartUpdateThread ) > fnStartUpdateThread ;
327 helper::DynFuncHolder< decltype(sound4cl_StopUpdateThread ) > fnStopUpdateThread ;
328 helper::DynFuncHolder< decltype(sound4cl_WaitUpdateThreadReady ) > fnWaitUpdateThreadReady ;
329 helper::DynFuncHolder< decltype(sound4cl_ProcessAudio ) > fnProcessAudio ;
330 helper::DynFuncHolder< decltype(sound4cl_ProcessAudio_Planar ) > fnProcessAudio_Planar ;
331 helper::DynFuncHolder< decltype(sound4cl_GetBufferIn ) > fnGetBufferIn ;
332 helper::DynFuncHolder< decltype(sound4cl_GetBufferOut ) > fnGetBufferOut ;
333 helper::DynFuncHolder< decltype(sound4cl_GetEstimatedDelay ) > fnGetEstimatedDelay ;
334 helper::DynFuncHolder< decltype(sound4cl_GetFormatName ) > fnGetFormatName ;
335 helper::DynFuncHolder< decltype(sound4cl_GetFormatFromName ) > fnGetFormatFromName ;
336 helper::DynFuncHolder< decltype(sound4cl_GetBytesFromFormat ) > fnGetBytesFromFormat ;
337 helper::DynFuncHolder< decltype(sound4cl_GetMaxPacketFrame ) > fnGetMaxPacketFrame ;
338 helper::DynFuncHolder< decltype(sound4cl_AddAudio ) > fnAddAudio ;
339 helper::DynFuncHolder< decltype(sound4cl_AddPadAudio ) > fnAddPadAudio ;
340 helper::DynFuncHolder< decltype(sound4cl_GetOutputCount ) > fnGetOutputCount ;
341 helper::DynFuncHolder< decltype(sound4cl_GetAudio ) > fnGetAudio ;
342 helper::DynFuncHolder< decltype(sound4cl_AudioConvertFrom ) > fnAudioConvertFrom ;
343 helper::DynFuncHolder< decltype(sound4cl_AudioConvertTo ) > fnAudioConvertTo ;
344 helper::DynFuncHolder< decltype(sound4cl_StereoToMono ) > fnStereoToMono ;
345 helper::DynFuncHolder< decltype(sound4cl_MonoToStereo ) > fnMonoToStereo ;
346 helper::DynFuncHolder< decltype(sound4cl_AudioMonoFromLiveStereo) > fnAudioMonoFromLiveStereo;
347 helper::DynFuncHolder< decltype(sound4cl_AudioMonoToLiveStereo ) > fnAudioMonoToLiveStereo ;
348 helper::DynFuncHolder< decltype(sound4cl_NewClient ) > fnNewClient ;
349 helper::DynFuncHolder< decltype(sound4cl_DeleteClient ) > fnDeleteClient ;
350 helper::DynFuncHolder< decltype(sound4cl_ProcessJson ) > fnProcessJson ;
351 helper::DynFuncHolder< decltype(sound4cl_FreeJsonAnswer ) > fnFreeJsonAnswer ;
352 helper::DynFuncHolder< decltype(sound4cl_SaveState ) > fnSaveState ;
353
354 // only for processes supporting webserver
355 helper::DynFuncHolder< decltype(sound4cl_Webserver_tcp ) > fnWebserver_tcp ;
356 helper::DynFuncHolder< decltype(sound4cl_Webserver_tcp2 ) > fnWebserver_tcp2 ;
357 helper::DynFuncHolder< decltype(sound4cl_Webserver ) > fnWebserver ;
358 helper::DynFuncHolder< decltype(sound4cl_Webserver_Stop ) > fnWebserver_Stop ;
359 helper::DynFuncHolder< decltype(sound4cl_Webserver_Status ) > fnWebserver_Status ;
360
361 // added 2023-03-22
362 helper::DynFuncHolder< decltype(sound4cl_StereoToMono_Planar ) > fnStereoToMono_Planar ;
363 helper::DynFuncHolder< decltype(sound4cl_MonoToStereo_Planar ) > fnMonoToStereo_Planar ;
364
365 // added 2023-05-22
366 helper::DynFuncHolder< decltype(sound4cl_SetMetadata ) > fnSetMetadata ;
367 helper::DynFuncHolder< decltype(sound4cl_GetMetadataInfos ) > fnGetMetadataInfos ;
368 helper::DynFuncHolder< decltype(sound4cl_FreeMetadataInfos ) > fnFreeMetadataInfos ;
369
370 // added 2023-06-20
371 helper::DynFuncHolder< decltype(sound4cl_SetPresetManager ) > fnSetPresetManager ;
372 helper::DynFuncHolder< decltype(sound4cl_PresetManager_InformChange ) > fnPresetManager_InformChange ;
373
374 // added 2023-09-21
375 helper::DynFuncHolder< decltype(sound4cl_GetPossibleChunkSizeInFrames ) > fnGetPossibleChunkSizeInFrames ;
376 helper::DynFuncHolder< decltype(sound4cl_GetProcessChunkFrames ) > fnGetProcessChunkFrames ;
377 helper::DynFuncHolder< decltype(sound4cl_InitProcess3 ) > fnInitProcess3 ;
378
379 // added 2023-06-26, only for processes supporting bus
380 helper::DynFuncHolder< decltype(sound4cl_NewBus ) > fnNewBus ;
381 helper::DynFuncHolder< decltype(sound4cl_FreeBus ) > fnFreeBus ;
382 helper::DynFuncHolder< decltype(sound4cl_SetInstanceBus ) > fnSetInstanceBus ;
383
384 // added 2024-02-19
385 helper::DynFuncHolder< decltype(sound4cl_SetMetadataMulti ) > fnSetMetadataMulti ;
386
387 // added 2024-05-23
388 helper::DynFuncHolder< decltype(sound4cl_Webserver_SetAppHealth ) > fnWebserver_SetAppHealth ;
389 helper::DynFuncHolder< decltype(sound4cl_Webserver_GetAppHealth ) > fnWebserver_GetAppHealth ;
390 helper::DynFuncHolder< decltype(sound4cl_Webserver_FreeString ) > fnWebserver_FreeString ;
391
392 template <typename T>
393 helper::DynFuncHolder<T> GetPrefixSymbol(const std::string& name) {
394 std::string prefix_name = m_prefix+name;
395 return m_lib.GetSymbol<T>(prefix_name);
396 }
397
398 public:
399 CProcessor() = default;
400
408 bool Load(const std::filesystem::path& filepath) {
409 m_lib.Close();
410 // If a path is given, use it directly and do not try other path
411 if (filepath.has_parent_path() && !m_lib.Load(filepath)) {
412 return false;
413 } else if (!m_lib.IsOk()) {
414 auto thisdir=helper::CDynLoader::GetThisLibraryPath().parent_path();
415 auto filename = filepath.filename();
416 #ifndef _WIN32
417 // Linux: if in a bin directory, try ../lib first
418 if (!m_lib.IsOk() && thisdir.filename()=="bin") {
419 auto libdir = thisdir.parent_path() / "lib";
420 m_lib.Load(libdir / filename);
421 }
422 #endif // !_WIN32
423 if (!m_lib.IsOk()) {
424 // Search in the same directory this code is in
425 m_lib.Load(thisdir / filename);
426 }
427 if (!m_lib.IsOk()) {
428 // Try current path
429 std::error_code ec;
430 auto p = std::filesystem::current_path(ec);
431 if (!ec) {
432 m_lib.Load(p / filename);
433 }
434 }
435 if (!m_lib.IsOk()) {
436 return false;
437 }
438 }
439 // Get information from the library itself
440 try {
441 auto GetInfo = m_lib.GetSymbol< decltype(sound4cl_SOUND4_GetProcessInfo ) >("SOUND4_GetProcessInfo" );
442 auto info = GetInfo();
443 m_prefix = info->prefix;
444 } catch (std::runtime_error& ) {
445 // Compatibility: search in known libraries without this function
446 #ifdef _WIN32
447 std::string filename = helper::WStringToUTF8(filepath.stem());
448 #else // !_WIN32
449 std::string filename = filepath.stem();
450 // remove lib prefix
451 filename=filename.substr(3);
452 #endif // ! _WIN32
453 if (filename=="sound4.x1.cloud") {
454 m_prefix="cloudx1_";
455 } else if (filename=="sound4.impact.cl") {
456 m_prefix="impact_";
457 } else if (filename=="sound4.bigvoice.cl") {
458 m_prefix="bigvoice_";
459 } else {
460 return false;
461 }
462 }
463
464 // Load all C functions
465 try {
466 fnGetVersion = GetPrefixSymbol< decltype(sound4cl_GetVersion ) >("GetVersion" );
467 fnGetChunkSizeInFrames = GetPrefixSymbol< decltype(sound4cl_GetChunkSizeInFrames ) >("GetChunkSizeInFrames" );
468 fnGetChannelCount = GetPrefixSymbol< decltype(sound4cl_GetChannelCount ) >("GetChannelCount" );
469 fnGetAudioInputCount = GetPrefixSymbol< decltype(sound4cl_GetAudioInputCount ) >("GetAudioInputCount" );
470 fnGetAudioOutputCount = GetPrefixSymbol< decltype(sound4cl_GetAudioOutputCount ) >("GetAudioOutputCount" );
471 fnGetSampleRate = GetPrefixSymbol< decltype(sound4cl_GetSampleRate ) >("GetSampleRate" );
472 fnSetLoggerCallback = GetPrefixSymbol< decltype(sound4cl_SetLoggerCallback ) >("SetLoggerCallback" );
473 fnSetLogSeverity = GetPrefixSymbol< decltype(sound4cl_SetLogSeverity ) >("SetLogSeverity" );
474 fnNewParameters = GetPrefixSymbol< decltype(sound4cl_NewParameters ) >("NewParameters" );
475 fnFreeParameters = GetPrefixSymbol< decltype(sound4cl_FreeParameters ) >("FreeParameters" );
476 fnSetParameter = GetPrefixSymbol< decltype(sound4cl_SetParameter ) >("SetParameter" );
477 fnGetParameter = GetPrefixSymbol< decltype(sound4cl_GetParameter ) >("GetParameter" );
478 fnFreeParameterValue = GetPrefixSymbol< decltype(sound4cl_FreeParameterValue ) >("FreeParameterValue" );
479 fnInitProcess = GetPrefixSymbol< decltype(sound4cl_InitProcess ) >("InitProcess" );
480 fnInitProcess2 = GetPrefixSymbol< decltype(sound4cl_InitProcess2 ) >("InitProcess2" );
481 fnTerminateProcess = GetPrefixSymbol< decltype(sound4cl_TerminateProcess ) >("TerminateProcess" );
482 fnExitProcess = GetPrefixSymbol< decltype(sound4cl_ExitProcess ) >("ExitProcess" );
483 fnStartUpdateThread = GetPrefixSymbol< decltype(sound4cl_StartUpdateThread ) >("StartUpdateThread" );
484 fnStopUpdateThread = GetPrefixSymbol< decltype(sound4cl_StopUpdateThread ) >("StopUpdateThread" );
485 fnWaitUpdateThreadReady = GetPrefixSymbol< decltype(sound4cl_WaitUpdateThreadReady ) >("WaitUpdateThreadReady" );
486 fnProcessAudio = GetPrefixSymbol< decltype(sound4cl_ProcessAudio ) >("ProcessAudio" );
487 fnProcessAudio_Planar = GetPrefixSymbol< decltype(sound4cl_ProcessAudio_Planar ) >("ProcessAudio_Planar" );
488 fnGetBufferIn = GetPrefixSymbol< decltype(sound4cl_GetBufferIn ) >("GetBufferIn" );
489 fnGetBufferOut = GetPrefixSymbol< decltype(sound4cl_GetBufferOut ) >("GetBufferOut" );
490 fnGetEstimatedDelay = GetPrefixSymbol< decltype(sound4cl_GetEstimatedDelay ) >("GetEstimatedDelay" );
491 fnGetFormatName = GetPrefixSymbol< decltype(sound4cl_GetFormatName ) >("GetFormatName" );
492 fnGetFormatFromName = GetPrefixSymbol< decltype(sound4cl_GetFormatFromName ) >("GetFormatFromName" );
493 fnGetBytesFromFormat = GetPrefixSymbol< decltype(sound4cl_GetBytesFromFormat ) >("GetBytesFromFormat" );
494 fnGetMaxPacketFrame = GetPrefixSymbol< decltype(sound4cl_GetMaxPacketFrame ) >("GetMaxPacketFrame" );
495 fnAddAudio = GetPrefixSymbol< decltype(sound4cl_AddAudio ) >("AddAudio" );
496 fnAddPadAudio = GetPrefixSymbol< decltype(sound4cl_AddPadAudio ) >("AddPadAudio" );
497 fnGetOutputCount = GetPrefixSymbol< decltype(sound4cl_GetOutputCount ) >("GetOutputCount" );
498 fnGetAudio = GetPrefixSymbol< decltype(sound4cl_GetAudio ) >("GetAudio" );
499 fnAudioConvertFrom = GetPrefixSymbol< decltype(sound4cl_AudioConvertFrom ) >("AudioConvertFrom" );
500 fnAudioConvertTo = GetPrefixSymbol< decltype(sound4cl_AudioConvertTo ) >("AudioConvertTo" );
501 fnStereoToMono = GetPrefixSymbol< decltype(sound4cl_StereoToMono ) >("StereoToMono" );
502 fnMonoToStereo = GetPrefixSymbol< decltype(sound4cl_MonoToStereo ) >("MonoToStereo" );
503 fnAudioMonoFromLiveStereo = GetPrefixSymbol< decltype(sound4cl_AudioMonoFromLiveStereo) >("AudioMonoFromLiveStereo");
504 fnAudioMonoToLiveStereo = GetPrefixSymbol< decltype(sound4cl_AudioMonoToLiveStereo ) >("AudioMonoToLiveStereo" );
505 fnNewClient = GetPrefixSymbol< decltype(sound4cl_NewClient ) >("NewClient" );
506 fnDeleteClient = GetPrefixSymbol< decltype(sound4cl_DeleteClient ) >("DeleteClient" );
507 fnProcessJson = GetPrefixSymbol< decltype(sound4cl_ProcessJson ) >("ProcessJson" );
508 fnFreeJsonAnswer = GetPrefixSymbol< decltype(sound4cl_FreeJsonAnswer ) >("FreeJsonAnswer" );
509 fnSaveState = GetPrefixSymbol< decltype(sound4cl_SaveState ) >("SaveState" );
510 } catch (std::runtime_error& ) {
511 return false;
512 }
513 // Webserver : not for all projects
514 try {
515 fnWebserver_tcp = GetPrefixSymbol< decltype(sound4cl_Webserver_tcp ) >("Webserver_tcp" );
516 fnWebserver_tcp2 = GetPrefixSymbol< decltype(sound4cl_Webserver_tcp2 ) >("Webserver_tcp2" );
517 fnWebserver = GetPrefixSymbol< decltype(sound4cl_Webserver ) >("Webserver" );
518 fnWebserver_Stop = GetPrefixSymbol< decltype(sound4cl_Webserver_Stop ) >("Webserver_Stop" );
519 fnWebserver_Status = GetPrefixSymbol< decltype(sound4cl_Webserver_Status ) >("Webserver_Status" );
520 } catch (std::runtime_error& ) {
521 // Ignored, handler will take care
522 }
523 // Stereo/Mono conversion : must be present
524 try {
525 // added 2023-03-22
526 fnStereoToMono_Planar = GetPrefixSymbol< decltype(sound4cl_StereoToMono_Planar ) >("StereoToMono_Planar" );
527 fnMonoToStereo_Planar = GetPrefixSymbol< decltype(sound4cl_MonoToStereo_Planar ) >("MonoToStereo_Planar" );
528
529 } catch (std::runtime_error& ) {
530 return false;
531 }
532 // C functions allowed to be missing
533 try {
534 // added 2023-05-22
535 fnSetMetadata = GetPrefixSymbol< decltype(sound4cl_SetMetadata ) >("SetMetadata" );
536 fnGetMetadataInfos = GetPrefixSymbol< decltype(sound4cl_GetMetadataInfos ) >("GetMetadataInfos" );
537 fnFreeMetadataInfos = GetPrefixSymbol< decltype(sound4cl_FreeMetadataInfos ) >("FreeMetadataInfos" );
538 // added 2023-06-20
539 fnSetPresetManager = GetPrefixSymbol< decltype(sound4cl_SetPresetManager ) >("SetPresetManager" );
540 fnPresetManager_InformChange = GetPrefixSymbol< decltype(sound4cl_PresetManager_InformChange ) >("PresetManager_InformChange" );
541
542 // added 2023-09-21
543 fnGetPossibleChunkSizeInFrames = GetPrefixSymbol< decltype(sound4cl_GetPossibleChunkSizeInFrames ) >("GetPossibleChunkSizeInFrames" );
544 fnGetProcessChunkFrames = GetPrefixSymbol< decltype(sound4cl_GetProcessChunkFrames ) >("GetProcessChunkFrames" );
545 fnInitProcess3 = GetPrefixSymbol< decltype(sound4cl_InitProcess3 ) >("InitProcess3" );
546 } catch (std::runtime_error& ) {
547 // Ignored, handler will take care
548 }
549
550 // bus: not for all projects
551 try {
552 // added 2023-06-26
553 fnNewBus = GetPrefixSymbol< decltype(sound4cl_NewBus ) >("NewBus" );
554 fnFreeBus = GetPrefixSymbol< decltype(sound4cl_FreeBus ) >("FreeBus" );
555 fnSetInstanceBus = GetPrefixSymbol< decltype(sound4cl_SetInstanceBus ) >("SetInstanceBus" );
556 } catch (std::runtime_error& ) {
557 // Ignored, handler will take care
558 }
559
560 // Other optional
561 try {
562 // added 2024-02-19
563 fnSetMetadataMulti = GetPrefixSymbol< decltype(sound4cl_SetMetadataMulti ) >("SetMetadataMulti" );
564
565 } catch (std::runtime_error& ) {
566 // Ignored, handler will take care
567 }
568
569 // Other optional, web server only
570 try {
571 // added 2024-05-23
572 fnWebserver_SetAppHealth = GetPrefixSymbol< decltype(sound4cl_Webserver_SetAppHealth ) >("Webserver_SetAppHealth" );
573 fnWebserver_GetAppHealth = GetPrefixSymbol< decltype(sound4cl_Webserver_GetAppHealth ) >("Webserver_GetAppHealth" );
574 fnWebserver_FreeString = GetPrefixSymbol< decltype(sound4cl_Webserver_FreeString ) >("Webserver_FreeString" );
575 } catch (std::runtime_error& ) {
576 // Ignored, handler will take care
577 }
578
579 m_bOK=true;
580 return true;
581 }
588 bool IsOk() const {
589 return m_bOK;
590 }
591
592 // --------------------------------------------------------------
599 // --------------------------------------------------------------
610 void AudioConvertFrom(const uint8_t *payload, float *output, size_t nSpl, SampleFormat fmt)
611 { fnAudioConvertFrom(payload, output, nSpl, (sound4cl_SampleFormat)fmt); }
612
623 void AudioConvertTo(const float *input, uint8_t *payload, size_t nSpl, SampleFormat fmt)
624 { fnAudioConvertTo(input, payload, nSpl, (sound4cl_SampleFormat)fmt); }
625
635 void StereoToMono(const float *input, float *output, size_t nFrame)
636 { fnStereoToMono(input, output, nFrame); }
637
647 void MonoToStereo(const float *input, float *output, size_t nFrame)
648 { fnMonoToStereo(input, output, nFrame); }
649
660 void StereoToMono_Planar(const float *inputL, const float *inputR, float *output, size_t nFrame)
661 { fnStereoToMono_Planar(inputL, inputR, output, nFrame); }
662
673 void MonoToStereo_Planar(const float *input, float *outputL, float *outputR, size_t nFrame)
674 { fnMonoToStereo_Planar(input, outputL, outputR, nFrame); }
675
682 void AudioMonoFromLiveStereo(const uint8_t *payload, float *output)
683 { fnAudioMonoFromLiveStereo(payload, output); }
684
691 void AudioMonoToLiveStereo(const float *input, uint8_t *payload)
692 { fnAudioMonoToLiveStereo(input, payload); }
693
701 std::string GetVersion()
702 { return std::string(fnGetVersion()); }
703
714 unsigned int GetChunkSizeInFrames()
715 { return fnGetChunkSizeInFrames(); }
716
725 std::vector<unsigned int> GetPossibleChunkSizeInFrames()
726 {
727 std::vector<unsigned int> list;
728 if (fnGetPossibleChunkSizeInFrames) {
729 for (unsigned int* src=fnGetPossibleChunkSizeInFrames();*src;src++) {
730 list.push_back(*src);
731 }
732 } else {
733 list.push_back(fnGetChunkSizeInFrames());
734 }
735 return list;
736 }
737
743 unsigned int GetChannelCount()
744 { return fnGetChannelCount(); }
745
753 unsigned int GetAudioInputCount()
754 { return fnGetAudioInputCount(); }
755
763 unsigned int GetAudioOutputCount()
764 { return fnGetAudioOutputCount(); }
765
773 unsigned int GetSampleRate()
774 { return fnGetSampleRate(); }
775
782 std::string GetFormatName( const SampleFormat fmt)
783 { return std::string(fnGetFormatName((sound4cl_SampleFormat)fmt)); }
784
791 SampleFormat GetFormatFromName( const std::string& name)
792 { return SampleFormat(fnGetFormatFromName(name.c_str())); }
793
800 unsigned int GetBytesFromFormat( const SampleFormat fmt)
801 { return fnGetBytesFromFormat((sound4cl_SampleFormat)fmt); }
802
807 { fnSetLogSeverity((sound4cl_LogSeverity)severity); }
808
813 { _log_cb=cb; fnSetLoggerCallback(&_log_cb_c); }
814 };
815
821 class CBus {
822 public:
824 : m_dynlib(dynlib)
825 {
826 if (m_dynlib.fnNewBus) {
827 m_bus=m_dynlib.fnNewBus();
828 }
829 }
831 {
832 if (m_bus && m_dynlib.fnFreeBus) {
833 m_dynlib.fnFreeBus(m_bus);
834 }
835 m_bus = nullptr;
836 }
837 protected:
838 friend class CInstance;
839 sound4cl_CBus *Get() const { return m_bus; }
840 private:
841 CProcessor& m_dynlib;
842 sound4cl_CBus *m_bus;
843 };
844
851 public:
852 CPresetLoader() = default;
853 virtual ~CPresetLoader() = default;
854
855 virtual bool IsReadOnly() = 0;
856 virtual bool Exists(const std::filesystem::path &name) = 0;
857 virtual bool Remove(const std::filesystem::path &name) = 0;
858 virtual bool Rename(const std::filesystem::path &from, const std::filesystem::path &to) = 0;
859 virtual std::vector<std::filesystem::path> GetAll() = 0;
860 virtual std::string Read(const std::filesystem::path &filename) = 0;
861 virtual bool Write(const std::filesystem::path &filename, const std::string &content) =0;
862 };
873 class CInstance {
874 public:
881 : m_dynlib(dynlib)
882 {
883 params = m_dynlib.fnNewParameters();
884 if (!params) throw std::bad_alloc();
885 }
886
895 CInstance(CProcessor& dynlib, void* _instance)
896 : m_dynlib(dynlib)
897 , instance(reinterpret_cast<sound4cl_CInstance*>(_instance))
898 , m_bOwned(false)
899 {
900 }
901 // non-copyable
902 CInstance( const CInstance& ) = delete;
903 CInstance& operator=( const CInstance& ) = delete;
907 virtual ~CInstance()
908 {
909 Stop();
910 if (params) m_dynlib.fnFreeParameters(params);
911 }
915 bool IsOk() const { return instance!=nullptr; }
925 void SetParam(const std::string& name, const std::string& value)
926 {
927 assert(params);
928 m_dynlib.fnSetParameter(params, name.c_str(), value.c_str());
929 }
936 std::string GetParam(const std::string& name)
937 {
938 assert(params);
939 auto c_value=m_dynlib.fnGetParameter(params, name.c_str());
940 std::string ret(c_value);
941 m_dynlib.fnFreeParameterValue(c_value);
942 return ret;
943 }
944
953 void SetBus(const CBus& bus) {
954 assert(params);
955 if (m_dynlib.fnSetInstanceBus) {
956 m_dynlib.fnSetInstanceBus(params,bus.Get());
957 }
958 }
959
970 void SetPresetManager(CPresetLoader *preset_manager)
971 {
972 if (!preset_manager) return;
973 if (!m_dynlib.fnSetPresetManager) return;
974 assert(params);
975 m_dynlib.fnSetPresetManager(params,
976 sound4cl_custom_reader,
977 sound4cl_custom_reader_free,
978 sound4cl_custom_writer,
979 sound4cl_custom_exists,
980 sound4cl_custom_getall,
981 sound4cl_custom_getall_free,
982 sound4cl_custom_remove,
983 sound4cl_custom_rename,
984 preset_manager->IsReadOnly(),
985 preset_manager
986 );
987 }
988
1011 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)
1012 {
1013 assert(!instance);
1014 std::string l_save_path;
1015 if (!save_path.empty()) {
1016 l_save_path = save_path.u8string();
1017 }
1018 if (frames_per_chunk==0) {
1019 frames_per_chunk=m_dynlib.GetChunkSizeInFrames();
1020 }
1021 if (m_dynlib.fnInitProcess3) {
1022 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);
1023 } else if (frames_per_chunk!=m_dynlib.GetChunkSizeInFrames()) {
1024 return false;
1025 } else {
1026 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);
1027 }
1028 if (!instance) return false;
1029 if (!init_metadata.empty()) {
1030 for (auto&& [key,value]: init_metadata) {
1031 m_dynlib.fnSetMetadata(instance, key.c_str(), value.c_str());
1032 }
1033 init_metadata.clear();
1034 }
1035 update_thread = std::thread([this, json_port](){
1037 m_dynlib.fnStartUpdateThread(instance, json_port);
1039 });
1040 int timeout=5000;
1041 #ifdef DEBUG
1042 timeout=60*1000; // For debugger pauses
1043 #endif
1044 if (m_dynlib.fnWaitUpdateThreadReady(instance, timeout)<0) {
1045 return false;
1046 }
1047 return true;
1048 }
1049
1057 unsigned int GetChunkFrames() {
1058 if (instance && m_dynlib.fnGetProcessChunkFrames) {
1059 return m_dynlib.fnGetProcessChunkFrames(instance);
1060 }
1061 return m_dynlib.fnGetChunkSizeInFrames();
1062 }
1063
1071 void PresetManager_InformChange(const std::filesystem::path& relative_path, PresetChange_Kind change_kind)
1072 {
1073 if (m_dynlib.fnPresetManager_InformChange) {
1074 m_dynlib.fnPresetManager_InformChange(instance, relative_path.c_str(), (sound4cl_PresetChange_Kind) change_kind);
1075 }
1076 }
1077
1089 void SetMetadata(const std::string& key, const char* value)
1090 {
1091 if (m_dynlib.fnSetMetadata) {
1092 if (instance) {
1093 m_dynlib.fnSetMetadata(instance, key.c_str(), value);
1094 } else {
1095 init_metadata.push_back( {key, value} );
1096 }
1097 }
1098 }
1099
1109 void SetMetadataMulti(const std::unordered_map<std::string, const char*>& list)
1110 {
1111 if (instance) {
1112 if (m_dynlib.fnSetMetadataMulti) {
1113 typedef const char* pchar;
1114 pchar* keyvalue=new pchar[2*list.size()+1];
1115 size_t n=0;
1116 for (auto&& [key,value]: list) {
1117 keyvalue[2*n+0]=key.c_str();
1118 keyvalue[2*n+1]=value;
1119 n++;
1120 }
1121 keyvalue[2*n+0]=nullptr;
1122
1123 sound4cl_SetMetadataMulti(instance, keyvalue);
1124
1125 delete[] keyvalue;
1126 } else {
1127 for (auto&& [key,value]: list) {
1128 SetMetadata(key, value);
1129 }
1130 }
1131 } else {
1132 for (auto&& [key,value]: list) {
1133 if (value) {
1134 init_metadata.push_back( {key, value} );
1135 }
1136 }
1137 }
1138 }
1139
1145 std::vector< std::tuple<std::string,std::string> > GetMetadataInfos()
1146 {
1147 std::vector< std::tuple<std::string,std::string> > values;
1148 if (m_dynlib.fnGetMetadataInfos) {
1149 const char** c_values = m_dynlib.fnGetMetadataInfos(instance);
1150 if (c_values) {
1151 for (const char** c_value=c_values; *c_value; ) {
1152 std::string key(*c_value);
1153 c_value++;
1154 if (*c_value) {
1155 std::string descr(*c_value);
1156 c_value++;
1157 values.push_back( {key,descr} );
1158 }
1159 }
1160 m_dynlib.fnFreeMetadataInfos(instance, c_values);
1161 }
1162 }
1163 return values;
1164 }
1165
1169 virtual void OnUpdateThreadStart() {}
1173 virtual void OnUpdateThreadStop() {}
1174
1175
1189 bool StartWebServer(int http_port, int https_port=0)
1190 {
1191 assert(instance);
1192 assert(webserver==SOUND4_INVALID_WEBSERVER_ID);
1193 if (!m_dynlib.fnWebserver) {
1194 return false;
1195 }
1196 webserver = m_dynlib.fnWebserver(http_port,https_port,instance);
1197 if (webserver==SOUND4_INVALID_WEBSERVER_ID) {
1198 return false;
1199 }
1200 int web_status=m_dynlib.fnWebserver_Status(webserver);
1201 if (http_port && (web_status & SOUND4_WEBSERVER_HTTP_OK) == 0) {
1202 return false;
1203 }
1204 if (https_port && (web_status & SOUND4_WEBSERVER_HTTPS_OK) == 0) {
1205 return false;
1206 }
1207 return true;
1208 }
1209
1217 void StopWebServer(int timeout_ms = 1000)
1218 {
1219 if (!m_dynlib.fnWebserver_Stop) return;
1220 if (webserver != SOUND4_INVALID_WEBSERVER_ID) {
1221 m_dynlib.fnWebserver_Stop(webserver, timeout_ms);
1222 webserver = SOUND4_INVALID_WEBSERVER_ID;
1223 }
1224 }
1225
1229 void SetWebServerAppHealth(int httpcode, const std::string& contenttype, const std::string& content)
1230 {
1231 assert(instance);
1232 if (!m_dynlib.fnWebserver_SetAppHealth) return;
1233 m_dynlib.fnWebserver_SetAppHealth(instance, httpcode, contenttype.c_str(), content.c_str());
1234 }
1238 void GetWebServerAppHealth(int &httpcode, std::string& contenttype, std::string& content)
1239 {
1240 assert(instance);
1241 if (!m_dynlib.fnWebserver_GetAppHealth) return;
1242 char* c_contenttype=nullptr;
1243 char* c_content=nullptr;
1244 m_dynlib.fnWebserver_GetAppHealth(instance, &httpcode, &c_contenttype, &c_content);
1245 contenttype=c_contenttype;
1246 content=c_content;
1247 m_dynlib.fnWebserver_FreeString(c_contenttype);
1248 m_dynlib.fnWebserver_FreeString(c_content);
1249 }
1259 {
1260 if (!instance) return 0;
1261 return m_dynlib.fnTerminateProcess(instance);
1262 }
1263
1269 void Stop()
1270 {
1271 if (!instance) return;
1272 if (m_bOwned) {
1273 StopWebServer();
1274 if (update_thread.joinable()) {
1275 m_dynlib.fnStopUpdateThread(instance); // this will exit the update thread
1276 update_thread.join();
1277 }
1278 m_dynlib.fnExitProcess(instance);
1279 }
1280 instance=nullptr;
1281 }
1282
1292 unsigned int GetEstimatedDelay()
1293 {
1294 assert(instance);
1295 return m_dynlib.fnGetEstimatedDelay(instance);
1296 }
1297
1311 {
1312 assert(instance);
1313 return m_dynlib.fnGetBufferIn(instance);
1314
1315 }
1328 {
1329 assert(instance);
1330 return m_dynlib.fnGetBufferOut(instance);
1331 }
1336 {
1337 assert(instance);
1338 m_dynlib.fnProcessAudio(instance, GetBufferIn(), GetBufferOut());
1339 }
1351 void ProcessAudio_Planar(float const * const *input, float * const *output)
1352 {
1353 assert(instance);
1354 m_dynlib.fnProcessAudio_Planar(instance, input, output);
1355 }
1356
1368 template<typename T>
1369 std::vector<T> ProcessAnyAudio(const std::vector<T> input)
1370 {
1371 assert(instance);
1372 std::vector<T> output;
1373 unsigned int out_offset=0;
1374 unsigned int in_offset=0;
1375 unsigned int todo = input.size();
1376 while (todo>0) {
1377 unsigned int left = AddAudio(&input[in_offset], todo);
1378 unsigned int out_avail = m_dynlib.fnGetOutputCount(instance);
1379 output.resize(out_offset + out_avail);
1380 GetAudio(&output[out_offset], out_avail);
1381 out_offset+=out_avail;
1382 in_offset += todo-left;
1383 todo=left;
1384 }
1385 return output;
1386 }
1387
1393 class CClient {
1394 public:
1395 CClient(sound4cl_CInstance* instance, CProcessor& dynlib)
1396 : m_dynlib(dynlib)
1397 {
1398 assert(instance);
1399 client=m_dynlib.fnNewClient(instance);
1400 if (!client) throw std::bad_alloc();
1401 }
1402 // non-copyable
1403 CClient( const CInstance& ) = delete;
1404 CClient& operator=( const CInstance& ) = delete;
1406 {
1407 if (client) {
1408 m_dynlib.fnDeleteClient(client);
1409 client=nullptr;
1410 }
1411 }
1419 std::string ProcessJson(const std::string &request, bool *NeedSave = nullptr)
1420 {
1421 assert(client);
1422 int need_save=0;
1423 const char *canswer = m_dynlib.fnProcessJson(client, request.c_str(), &need_save);
1424 if (!canswer) return {};
1425 std::string answer(canswer);
1426 m_dynlib.fnFreeJsonAnswer (canswer);
1427 if (NeedSave) {
1428 *NeedSave=(need_save!=0);
1429 }
1430 return answer;
1431 }
1432 private:
1433 CProcessor& m_dynlib;
1434 sound4cl_CClientInstance *client = nullptr;
1435 };
1443 std::shared_ptr<CClient> NewClient()
1444 {
1445 assert(instance);
1446 return std::make_shared<CClient>(instance, m_dynlib);
1447 }
1448
1459 bool SaveState() {
1460 assert(instance);
1461 if (!m_dynlib.fnSaveState || m_dynlib.fnSaveState(instance)!=0) {
1462 return false;
1463 }
1464 return true;
1465 }
1466
1467 protected:
1468 template<typename T>
1469 unsigned int AddAudio(const T* payload, unsigned int nFrame)
1470 {
1471 assert(instance);
1472 return m_dynlib.fnAddAudio(instance, reinterpret_cast<const T*>(payload), nFrame, helper::SampleFormat<T>::format);
1473 }
1474 template<typename T>
1475 unsigned int GetAudio(T* payload, unsigned int max_nFrame)
1476 {
1477 assert(instance);
1478 return m_dynlib.fnGetAudio(instance, reinterpret_cast<T*>(payload), max_nFrame, helper::SampleFormat<T>::format);
1479 }
1480
1481 private:
1482 CProcessor& m_dynlib;
1483 sound4cl_CParameters* params = nullptr;
1484 sound4cl_CInstance* instance = nullptr;
1485 std::thread update_thread;
1486 std::vector< std::pair<std::string,std::string> > init_metadata;
1487 uint64_t webserver = SOUND4_INVALID_WEBSERVER_ID;
1488 bool m_bOwned = true;
1489 };
1490
1491}; // namespace sound4
1492
1493
1494// bridge C callbacks to CPresetLoader
1495extern "C" {
1496 static char *sound4cl_custom_reader(const fs_char *filename, void* userdata) {
1497 sound4::CPresetLoader *preset_loader=reinterpret_cast<sound4::CPresetLoader*>(userdata);
1498 std::string content=preset_loader->Read(filename);
1499 return strdup(content.c_str());
1500 }
1501 static void sound4cl_custom_reader_free(char *content, void* userdata) {
1502 if (!content) return;
1503 free(content);
1504 }
1505 static int sound4cl_custom_writer(const fs_char *filename, const char *content, void* userdata) {
1506 sound4::CPresetLoader *preset_loader=reinterpret_cast<sound4::CPresetLoader*>(userdata);
1507 auto res=preset_loader->Write(filename,content);
1508 return res?0:-1;
1509 }
1510 static int sound4cl_custom_exists(const fs_char *filename, void* userdata) {
1511 sound4::CPresetLoader *preset_loader=reinterpret_cast<sound4::CPresetLoader*>(userdata);
1512 auto res=preset_loader->Exists(filename);
1513 return res?0:-1;
1514 }
1515 static fs_char** sound4cl_custom_getall(void* userdata) {
1516 sound4::CPresetLoader *preset_loader=reinterpret_cast<sound4::CPresetLoader*>(userdata);
1517 auto res=preset_loader->GetAll();
1518 fs_char**all=(fs_char**)malloc((res.size()+1)*sizeof(const fs_char*));
1519 for (size_t n=0;n<res.size();n++) {
1520 all[n]=fs_strdup(res[n].c_str());
1521 }
1522 all[res.size()]=nullptr;
1523 return all;
1524 }
1525 static void sound4cl_custom_getall_free(fs_char** all, void* userdata) {
1526 if (!all) return;
1527 for (fs_char** one=all;*one;one++) {
1528 free(*one);
1529 }
1530 free(all);
1531 }
1532 static int sound4cl_custom_remove(const fs_char *filename, void* userdata) {
1533 sound4::CPresetLoader *preset_loader=reinterpret_cast<sound4::CPresetLoader*>(userdata);
1534 auto res=preset_loader->Remove(filename);
1535 return res?0:-1;
1536 }
1537 static int sound4cl_custom_rename(const fs_char *from, const fs_char *to, void* userdata) {
1538 sound4::CPresetLoader *preset_loader=reinterpret_cast<sound4::CPresetLoader*>(userdata);
1539 auto res=preset_loader->Rename(from,to);
1540 return res?0:-1;
1541 }
1542
1543};
Shared Bus.
Definition sound4cl.hpp:821
sound4cl_CBus * Get() const
Definition sound4cl.hpp:839
CBus(CProcessor &dynlib)
Definition sound4cl.hpp:823
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:873
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)
void ProcessAudio_Planar(float const *const *input, float *const *output)
std::vector< T > ProcessAnyAudio(const std::vector< T > input)
virtual ~CInstance()
Definition sound4cl.hpp:907
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:970
void SetBus(const CBus &bus)
Definition sound4cl.hpp:953
virtual void OnUpdateThreadStop()
unsigned int GetChunkFrames()
CInstance(CProcessor &dynlib, void *_instance)
Definition sound4cl.hpp:895
void SetWebServerAppHealth(int httpcode, const std::string &contenttype, const std::string &content)
CInstance(CProcessor &dynlib)
Definition sound4cl.hpp:880
void SetParam(const std::string &name, const std::string &value)
Definition sound4cl.hpp:925
virtual void OnUpdateThreadStart()
bool IsOk() const
Definition sound4cl.hpp:915
bool StartWebServer(int http_port, int https_port=0)
void StopWebServer(int timeout_ms=1000)
void PresetManager_InformChange(const std::filesystem::path &relative_path, PresetChange_Kind change_kind)
void SetMetadataMulti(const std::unordered_map< std::string, const char * > &list)
unsigned int AddAudio(const T *payload, unsigned int nFrame)
unsigned int GetEstimatedDelay()
std::vector< std::tuple< std::string, std::string > > GetMetadataInfos()
std::shared_ptr< CClient > NewClient()
float * GetBufferOut()
void SetMetadata(const std::string &key, const char *value)
float * GetBufferIn()
unsigned int GetAudio(T *payload, unsigned int max_nFrame)
std::string GetParam(const std::string &name)
Definition sound4cl.hpp:936
Custom preset handler helper.
Definition sound4cl.hpp:850
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:299
bool Load(const std::filesystem::path &filepath)
Loads the library.
Definition sound4cl.hpp:408
void SetLogSeverity(LogSeverity severity)
Definition sound4cl.hpp:806
unsigned int GetAudioInputCount()
Definition sound4cl.hpp:753
void SetLoggerCallback(log_cb_t cb)
Definition sound4cl.hpp:812
unsigned int GetChunkSizeInFrames()
Definition sound4cl.hpp:714
SampleFormat GetFormatFromName(const std::string &name)
Definition sound4cl.hpp:791
std::vector< unsigned int > GetPossibleChunkSizeInFrames()
Definition sound4cl.hpp:725
std::string GetFormatName(const SampleFormat fmt)
Definition sound4cl.hpp:782
unsigned int GetBytesFromFormat(const SampleFormat fmt)
Definition sound4cl.hpp:800
unsigned int GetAudioOutputCount()
Definition sound4cl.hpp:763
helper::DynFuncHolder< T > GetPrefixSymbol(const std::string &name)
Definition sound4cl.hpp:393
unsigned int GetSampleRate()
Definition sound4cl.hpp:773
std::string GetVersion()
Definition sound4cl.hpp:701
bool IsOk() const
Check if the library was loaded correctly.
Definition sound4cl.hpp:588
unsigned int GetChannelCount()
Definition sound4cl.hpp:743
CProcessor()=default
Helper to load dynamic library.
Definition sound4cl.hpp:152
DynFuncHolder< T > GetSymbol_safe(const std::string &name)
Definition sound4cl.hpp:237
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:210
CDynLoader(const CDynLoader &)=delete
static std::filesystem::path GetThisLibraryPath(void)
Definition sound4cl.hpp:241
CDynLoader(CDynLoader &&)=default
DynFuncHolder< T > GetSymbol(const std::string &name)
Definition sound4cl.hpp:229
Helper to wrap a function pointer.
Definition sound4cl.hpp:131
DynFuncHolder(DynFunc_t a_ptr)
Definition sound4cl.hpp:142
void AudioConvertTo(const float *input, uint8_t *payload, size_t nSpl, SampleFormat fmt)
Definition sound4cl.hpp:623
void AudioMonoToLiveStereo(const float *input, uint8_t *payload)
Definition sound4cl.hpp:691
void StereoToMono_Planar(const float *inputL, const float *inputR, float *output, size_t nFrame)
Definition sound4cl.hpp:660
void MonoToStereo(const float *input, float *output, size_t nFrame)
Definition sound4cl.hpp:647
void AudioConvertFrom(const uint8_t *payload, float *output, size_t nSpl, SampleFormat fmt)
Definition sound4cl.hpp:610
void StereoToMono(const float *input, float *output, size_t nFrame)
Definition sound4cl.hpp:635
void AudioMonoFromLiveStereo(const uint8_t *payload, float *output)
Definition sound4cl.hpp:682
void MonoToStereo_Planar(const float *input, float *outputL, float *outputR, size_t nFrame)
Definition sound4cl.hpp:673
wchar_t fs_char
#define SOUND4_WEBSERVER_HTTPS_OK
#define SOUND4_WEBSERVER_HTTP_OK
#define SOUND4_INVALID_WEBSERVER_ID
static std::string WStringToUTF8(const std::wstring &wstr)
Definition sound4cl.hpp:83
static std::wstring UTF8ToWString(const std::string &str)
Definition sound4cl.hpp:95
@ S32_NATIVE
32-bit signed integer, native
Definition sound4cl.hpp:69
@ S16_LE
16-bit signed integer, little-endian
Definition sound4cl.hpp:59
@ S24_BE
24-bit signed integer, big-endian
Definition sound4cl.hpp:62
@ F32_LE
32-bit floating-point, little-endian
Definition sound4cl.hpp:65
@ S24_LE
24-bit signed integer, little-endian
Definition sound4cl.hpp:61
@ S32_LE
32-bit signed integer, little-endian
Definition sound4cl.hpp:63
@ F32_BE
32-bit floating-point, big-endian
Definition sound4cl.hpp:66
@ S16_BE
16-bit signed integer, big-endian
Definition sound4cl.hpp:60
@ S32_BE
32-bit signed integer, big-endian
Definition sound4cl.hpp:64
@ INVALID_FORMAT
Invalid.
Definition sound4cl.hpp:58
@ F32_NATIVE
32-bit floating-point, native
Definition sound4cl.hpp:70
@ S24_NATIVE
24-bit signed integer, native
Definition sound4cl.hpp:68
@ S16_NATIVE
16-bit signed integer, native
Definition sound4cl.hpp:67
@ fatal
fatal error
Definition sound4cl.hpp:267
@ verbose
verbose
Definition sound4cl.hpp:271
@ none
Not used.
Definition sound4cl.hpp:266
@ verbose3
verbose3
Definition sound4cl.hpp:273
@ verbose5
verbose5
Definition sound4cl.hpp:275
@ verbose2
verbose2
Definition sound4cl.hpp:272
@ warning
warning
Definition sound4cl.hpp:269
@ error
error
Definition sound4cl.hpp:268
@ info
info
Definition sound4cl.hpp:270
@ verbose4
verbose4
Definition sound4cl.hpp:274
static void _log_cb_c(sound4cl_LogSeverity severity, const char *c_msg)
Definition sound4cl.hpp:288
std::function< void(LogSeverity, const std::string &)> log_cb_t
Definition sound4cl.hpp:281
static log_cb_t _log_cb
Definition sound4cl.hpp:286
PresetChange_Kind
Definition sound4cl.hpp:863
@ change_kind_created
has been created
Definition sound4cl.hpp:864
@ change_kind_deleted
has been deleted
Definition sound4cl.hpp:866
@ change_kind_modified
has been modified
Definition sound4cl.hpp:865
@ F32_NATIVE
32-bit floating-point, native
@ change_kind_modified
Path has been modified.
@ INVALID_FORMAT
Invalid.
@ S16_NATIVE
16-bit signed integer, native
@ change_kind_created
Path has been created.
@ F32_LE
32-bit floating-point, little-endian
@ S16_BE
16-bit signed integer, big-endian
@ S32_BE
32-bit signed integer, big-endian
@ S24_BE
24-bit signed integer, big-endian
@ S16_LE
16-bit signed integer, little-endian
@ F32_BE
32-bit floating-point, big-endian
@ S32_NATIVE
32-bit signed integer, native
@ change_kind_deleted
Path has been deleted.
@ S24_LE
24-bit signed integer, little-endian
@ S32_LE
32-bit signed integer, little-endian
@ S24_NATIVE
24-bit signed integer, native
Helper for Sample format types.
Definition sound4cl.hpp:110