21#if defined(__unix__) || defined(__APPLE__)
30 #include <libloaderapi.h>
32 #pragma warning(disable : 4996)
35 #error "Unsupported OS"
42 static char *sound4cl_custom_reader(
const fs_char *filename,
void* userdata);
43 static void sound4cl_custom_reader_free(
char *content,
void* userdata);
44 static int sound4cl_custom_writer(
const fs_char *filename,
const char *content,
void* userdata);
45 static int sound4cl_custom_exists(
const fs_char *filename,
void* userdata);
46 static fs_char** sound4cl_custom_getall(
void* userdata);
47 static void sound4cl_custom_getall_free(
fs_char** all,
void* userdata);
48 static int sound4cl_custom_remove(
const fs_char *filename,
void* userdata);
49 static int sound4cl_custom_rename(
const fs_char *from,
const fs_char *to,
void* userdata);
87 if (
wstr.empty())
return {};
99 if (
str.empty())
return std::wstring();
124 struct SampleFormat<float> {
133 template <
typename T>
148 operator T* ()
const {
return reinterpret_cast<T*
>(m_ptr); }
175 return (m_lib!=
NULL);
178 return (m_lib!=
NULL);
183 #ifndef __SANITIZE_ADDRESS__
189 bool Load(
const std::filesystem::path& dynlib)
192 m_lib=dlopen(dynlib.c_str(), RTLD_NOW|RTLD_LOCAL);
195 template <
typename T>
196 DynFuncHolder<T>
GetSymbol(
const std::string& name) {
197 auto ptr=dlsym(m_lib, name.c_str());
199 throw std::runtime_error(
"Missing function in library");
201 return DynFuncHolder<T>(ptr);
203 template <
typename T>
205 auto ptr=dlsym(m_lib, name.c_str());
206 return DynFuncHolder<T>(ptr);
211 auto rp=realpath(
info.dli_fname, NULL);
213 #if defined(__unix__)
214 rp=realpath(
"/proc/self/exe", NULL);
215 #elif defined(__APPLE__)
220 std::filesystem::path p(rp);
235 #if defined(SOUND4_CALL_FREELIBRARYANDEXITTHREAD)
237 #elif defined(SOUND4_CALL_FREELIBRARY)
243 template <
typename T>
247 throw std::runtime_error(
"Missing function in library");
251 template <
typename T>
264 return std::filesystem::path(
path);
303 static inline void _log_cb_c(sound4cl_LogSeverity severity,
const char *c_msg) {
318 std::string m_prefix;
388 helper::DynFuncHolder<
decltype(sound4cl_PresetManager_InformChange ) > fnPresetManager_InformChange ;
391 helper::DynFuncHolder<
decltype(sound4cl_GetPossibleChunkSizeInFrames ) > fnGetPossibleChunkSizeInFrames ;
411 helper::DynFuncHolder<
decltype(sound4cl_SetInstanceTracingProcessActivity ) > fnSetInstanceTracingProcessActivity ;
420 template <
typename T>
422 std::string prefix_name = m_prefix+name;
436 bool Load(
const std::filesystem::path& filepath) {
439 if (filepath.has_parent_path() && !m_lib.
Load(filepath)) {
441 }
else if (!m_lib.
IsOk()) {
443 auto filename = filepath.filename();
446 if (!m_lib.
IsOk() && thisdir.filename()==
"bin") {
447 auto libdir = thisdir.parent_path() /
"lib";
448 m_lib.
Load(libdir / filename);
453 m_lib.
Load(thisdir / filename);
458 auto p = std::filesystem::current_path(ec);
460 m_lib.
Load(p / filename);
469 auto GetInfo = m_lib.
GetSymbol<
decltype(sound4cl_SOUND4_GetProcessInfo ) >(
"SOUND4_GetProcessInfo" );
470 auto info = GetInfo();
471 m_prefix =
info->prefix;
472 }
catch (std::runtime_error& ) {
477 std::string filename = filepath.stem();
479 filename=filename.substr(3);
481 if (filename==
"sound4.x1.cloud") {
483 }
else if (filename==
"sound4.impact.cl") {
485 }
else if (filename==
"sound4.bigvoice.cl") {
486 m_prefix=
"bigvoice_";
494 fnGetVersion = GetPrefixSymbol< decltype(sound4cl_GetVersion ) >(
"GetVersion" );
495 fnGetChunkSizeInFrames = GetPrefixSymbol< decltype(sound4cl_GetChunkSizeInFrames ) >(
"GetChunkSizeInFrames" );
496 fnGetChannelCount = GetPrefixSymbol< decltype(sound4cl_GetChannelCount ) >(
"GetChannelCount" );
497 fnGetAudioInputCount = GetPrefixSymbol< decltype(sound4cl_GetAudioInputCount ) >(
"GetAudioInputCount" );
498 fnGetAudioOutputCount = GetPrefixSymbol< decltype(sound4cl_GetAudioOutputCount ) >(
"GetAudioOutputCount" );
499 fnGetSampleRate = GetPrefixSymbol< decltype(sound4cl_GetSampleRate ) >(
"GetSampleRate" );
500 fnSetLoggerCallback = GetPrefixSymbol< decltype(sound4cl_SetLoggerCallback ) >(
"SetLoggerCallback" );
501 fnSetLogSeverity = GetPrefixSymbol< decltype(sound4cl_SetLogSeverity ) >(
"SetLogSeverity" );
502 fnNewParameters = GetPrefixSymbol< decltype(sound4cl_NewParameters ) >(
"NewParameters" );
503 fnFreeParameters = GetPrefixSymbol< decltype(sound4cl_FreeParameters ) >(
"FreeParameters" );
504 fnSetParameter = GetPrefixSymbol< decltype(sound4cl_SetParameter ) >(
"SetParameter" );
505 fnGetParameter = GetPrefixSymbol< decltype(sound4cl_GetParameter ) >(
"GetParameter" );
506 fnFreeParameterValue = GetPrefixSymbol< decltype(sound4cl_FreeParameterValue ) >(
"FreeParameterValue" );
507 fnInitProcess = GetPrefixSymbol< decltype(sound4cl_InitProcess ) >(
"InitProcess" );
508 fnInitProcess2 = GetPrefixSymbol< decltype(sound4cl_InitProcess2 ) >(
"InitProcess2" );
509 fnTerminateProcess = GetPrefixSymbol< decltype(sound4cl_TerminateProcess ) >(
"TerminateProcess" );
510 fnExitProcess = GetPrefixSymbol< decltype(sound4cl_ExitProcess ) >(
"ExitProcess" );
511 fnStartUpdateThread = GetPrefixSymbol< decltype(sound4cl_StartUpdateThread ) >(
"StartUpdateThread" );
512 fnStopUpdateThread = GetPrefixSymbol< decltype(sound4cl_StopUpdateThread ) >(
"StopUpdateThread" );
513 fnWaitUpdateThreadReady = GetPrefixSymbol< decltype(sound4cl_WaitUpdateThreadReady ) >(
"WaitUpdateThreadReady" );
514 fnProcessAudio = GetPrefixSymbol< decltype(sound4cl_ProcessAudio ) >(
"ProcessAudio" );
515 fnProcessAudio_Planar = GetPrefixSymbol< decltype(sound4cl_ProcessAudio_Planar ) >(
"ProcessAudio_Planar" );
516 fnGetBufferIn = GetPrefixSymbol< decltype(sound4cl_GetBufferIn ) >(
"GetBufferIn" );
517 fnGetBufferOut = GetPrefixSymbol< decltype(sound4cl_GetBufferOut ) >(
"GetBufferOut" );
518 fnGetEstimatedDelay = GetPrefixSymbol< decltype(sound4cl_GetEstimatedDelay ) >(
"GetEstimatedDelay" );
519 fnGetFormatName = GetPrefixSymbol< decltype(sound4cl_GetFormatName ) >(
"GetFormatName" );
520 fnGetFormatFromName = GetPrefixSymbol< decltype(sound4cl_GetFormatFromName ) >(
"GetFormatFromName" );
521 fnGetBytesFromFormat = GetPrefixSymbol< decltype(sound4cl_GetBytesFromFormat ) >(
"GetBytesFromFormat" );
522 fnGetMaxPacketFrame = GetPrefixSymbol< decltype(sound4cl_GetMaxPacketFrame ) >(
"GetMaxPacketFrame" );
523 fnAddAudio = GetPrefixSymbol< decltype(sound4cl_AddAudio ) >(
"AddAudio" );
524 fnAddPadAudio = GetPrefixSymbol< decltype(sound4cl_AddPadAudio ) >(
"AddPadAudio" );
525 fnGetOutputCount = GetPrefixSymbol< decltype(sound4cl_GetOutputCount ) >(
"GetOutputCount" );
526 fnGetAudio = GetPrefixSymbol< decltype(sound4cl_GetAudio ) >(
"GetAudio" );
527 fnAudioConvertFrom = GetPrefixSymbol< decltype(sound4cl_AudioConvertFrom ) >(
"AudioConvertFrom" );
528 fnAudioConvertTo = GetPrefixSymbol< decltype(sound4cl_AudioConvertTo ) >(
"AudioConvertTo" );
529 fnStereoToMono = GetPrefixSymbol< decltype(sound4cl_StereoToMono ) >(
"StereoToMono" );
530 fnMonoToStereo = GetPrefixSymbol< decltype(sound4cl_MonoToStereo ) >(
"MonoToStereo" );
531 fnAudioMonoFromLiveStereo = GetPrefixSymbol< decltype(sound4cl_AudioMonoFromLiveStereo) >(
"AudioMonoFromLiveStereo");
532 fnAudioMonoToLiveStereo = GetPrefixSymbol< decltype(sound4cl_AudioMonoToLiveStereo ) >(
"AudioMonoToLiveStereo" );
533 fnNewClient = GetPrefixSymbol< decltype(sound4cl_NewClient ) >(
"NewClient" );
534 fnDeleteClient = GetPrefixSymbol< decltype(sound4cl_DeleteClient ) >(
"DeleteClient" );
535 fnProcessJson = GetPrefixSymbol< decltype(sound4cl_ProcessJson ) >(
"ProcessJson" );
536 fnFreeJsonAnswer = GetPrefixSymbol< decltype(sound4cl_FreeJsonAnswer ) >(
"FreeJsonAnswer" );
537 fnSaveState = GetPrefixSymbol< decltype(sound4cl_SaveState ) >(
"SaveState" );
538 }
catch (std::runtime_error& ) {
543 fnWebserver_tcp = GetPrefixSymbol< decltype(sound4cl_Webserver_tcp ) >(
"Webserver_tcp" );
544 fnWebserver_tcp2 = GetPrefixSymbol< decltype(sound4cl_Webserver_tcp2 ) >(
"Webserver_tcp2" );
545 fnWebserver = GetPrefixSymbol< decltype(sound4cl_Webserver ) >(
"Webserver" );
546 fnWebserver_Stop = GetPrefixSymbol< decltype(sound4cl_Webserver_Stop ) >(
"Webserver_Stop" );
547 fnWebserver_Status = GetPrefixSymbol< decltype(sound4cl_Webserver_Status ) >(
"Webserver_Status" );
548 }
catch (std::runtime_error& ) {
554 fnStereoToMono_Planar = GetPrefixSymbol< decltype(sound4cl_StereoToMono_Planar ) >(
"StereoToMono_Planar" );
555 fnMonoToStereo_Planar = GetPrefixSymbol< decltype(sound4cl_MonoToStereo_Planar ) >(
"MonoToStereo_Planar" );
557 }
catch (std::runtime_error& ) {
563 fnSetMetadata = GetPrefixSymbol< decltype(sound4cl_SetMetadata ) >(
"SetMetadata" );
564 fnGetMetadataInfos = GetPrefixSymbol< decltype(sound4cl_GetMetadataInfos ) >(
"GetMetadataInfos" );
565 fnFreeMetadataInfos = GetPrefixSymbol< decltype(sound4cl_FreeMetadataInfos ) >(
"FreeMetadataInfos" );
567 fnSetPresetManager = GetPrefixSymbol< decltype(sound4cl_SetPresetManager ) >(
"SetPresetManager" );
568 fnPresetManager_InformChange = GetPrefixSymbol< decltype(sound4cl_PresetManager_InformChange ) >(
"PresetManager_InformChange" );
571 fnGetPossibleChunkSizeInFrames = GetPrefixSymbol< decltype(sound4cl_GetPossibleChunkSizeInFrames ) >(
"GetPossibleChunkSizeInFrames" );
572 fnGetProcessChunkFrames = GetPrefixSymbol< decltype(sound4cl_GetProcessChunkFrames ) >(
"GetProcessChunkFrames" );
573 fnInitProcess3 = GetPrefixSymbol< decltype(sound4cl_InitProcess3 ) >(
"InitProcess3" );
574 }
catch (std::runtime_error& ) {
581 fnNewBus = GetPrefixSymbol< decltype(sound4cl_NewBus ) >(
"NewBus" );
582 fnFreeBus = GetPrefixSymbol< decltype(sound4cl_FreeBus ) >(
"FreeBus" );
583 fnSetInstanceBus = GetPrefixSymbol< decltype(sound4cl_SetInstanceBus ) >(
"SetInstanceBus" );
584 }
catch (std::runtime_error& ) {
591 fnSetMetadataMulti = GetPrefixSymbol< decltype(sound4cl_SetMetadataMulti ) >(
"SetMetadataMulti" );
593 }
catch (std::runtime_error& ) {
600 fnWebserver_SetAppHealth = GetPrefixSymbol< decltype(sound4cl_Webserver_SetAppHealth ) >(
"Webserver_SetAppHealth" );
601 fnWebserver_GetAppHealth = GetPrefixSymbol< decltype(sound4cl_Webserver_GetAppHealth ) >(
"Webserver_GetAppHealth" );
602 fnWebserver_FreeString = GetPrefixSymbol< decltype(sound4cl_Webserver_FreeString ) >(
"Webserver_FreeString" );
603 }
catch (std::runtime_error& ) {
611 fnSetInstanceTracing = GetPrefixSymbol< decltype(sound4cl_SetInstanceTracing ) >(
"SetInstanceTracing" );
612 fnSetInstanceTracingProcessActivity= GetPrefixSymbol< decltype(sound4cl_SetInstanceTracingProcessActivity ) >(
"SetInstanceTracingProcessActivity");
613 }
catch (std::runtime_error& ) {
621 fnGetAudioConverter = GetPrefixSymbol< decltype(sound4cl_GetAudioConverter ) >(
"GetAudioConverter" );
622 fnFreeAudioConverter = GetPrefixSymbol< decltype(sound4cl_FreeAudioConverter ) >(
"FreeAudioConverter" );
623 fnAudioConverter_From = GetPrefixSymbol< decltype(sound4cl_AudioConverter_From ) >(
"AudioConverter_From" );
624 fnAudioConverter_To = GetPrefixSymbol< decltype(sound4cl_AudioConverter_To ) >(
"AudioConverter_To" );
625 }
catch (std::runtime_error& ) {
661 { fnAudioConvertFrom(payload, output, nSpl, (sound4cl_SampleFormat)fmt); }
674 { fnAudioConvertTo(input, payload, nSpl, (sound4cl_SampleFormat)fmt); }
686 { fnStereoToMono(input, output, nFrame); }
698 { fnMonoToStereo(input, output, nFrame); }
711 { fnStereoToMono_Planar(inputL, inputR, output, nFrame); }
724 { fnMonoToStereo_Planar(input, outputL, outputR, nFrame); }
733 { fnAudioMonoFromLiveStereo(payload, output); }
742 { fnAudioMonoToLiveStereo(input, payload); }
752 {
return std::string(fnGetVersion()); }
765 {
return fnGetChunkSizeInFrames(); }
777 std::vector<unsigned int> list;
778 if (fnGetPossibleChunkSizeInFrames) {
779 for (
unsigned int* src=fnGetPossibleChunkSizeInFrames();*src;src++) {
780 list.push_back(*src);
783 list.push_back(fnGetChunkSizeInFrames());
794 {
return fnGetChannelCount(); }
804 {
return fnGetAudioInputCount(); }
814 {
return fnGetAudioOutputCount(); }
824 {
return fnGetSampleRate(); }
833 {
return std::string(fnGetFormatName((sound4cl_SampleFormat)fmt)); }
842 {
return SampleFormat(fnGetFormatFromName(name.c_str())); }
851 {
return fnGetBytesFromFormat((sound4cl_SampleFormat)fmt); }
857 { fnSetLogSeverity((sound4cl_LogSeverity)severity); }
876 if (m_dynlib.fnNewBus) {
877 m_bus=m_dynlib.fnNewBus();
882 if (m_bus && m_dynlib.fnFreeBus) {
883 m_dynlib.fnFreeBus(m_bus);
889 sound4cl_CBus *
Get()
const {
return m_bus; }
892 sound4cl_CBus *m_bus;
906 virtual bool Exists(
const std::filesystem::path &name) = 0;
907 virtual bool Remove(
const std::filesystem::path &name) = 0;
908 virtual bool Rename(
const std::filesystem::path &from,
const std::filesystem::path &to) = 0;
909 virtual std::vector<std::filesystem::path>
GetAll() = 0;
910 virtual std::string
Read(
const std::filesystem::path &filename) = 0;
911 virtual bool Write(
const std::filesystem::path &filename,
const std::string &content) =0;
933 params = m_dynlib.fnNewParameters();
934 if (!params)
throw std::bad_alloc();
947 , instance(reinterpret_cast<sound4cl_CInstance*>(_instance))
960 if (params) m_dynlib.fnFreeParameters(params);
965 bool IsOk()
const {
return instance!=
nullptr; }
975 void SetParam(
const std::string& name,
const std::string& value)
978 m_dynlib.fnSetParameter(params, name.c_str(), value.c_str());
989 auto c_value=m_dynlib.fnGetParameter(params, name.c_str());
990 std::string ret(c_value);
991 m_dynlib.fnFreeParameterValue(c_value);
1005 if (m_dynlib.fnSetInstanceBus) {
1006 m_dynlib.fnSetInstanceBus(params,bus.
Get());
1022 if (!preset_manager)
return;
1023 if (!m_dynlib.fnSetPresetManager)
return;
1025 m_dynlib.fnSetPresetManager(params,
1026 sound4cl_custom_reader,
1027 sound4cl_custom_reader_free,
1028 sound4cl_custom_writer,
1029 sound4cl_custom_exists,
1030 sound4cl_custom_getall,
1031 sound4cl_custom_getall_free,
1032 sound4cl_custom_remove,
1033 sound4cl_custom_rename,
1061 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)
1064 std::string l_save_path;
1065 if (!save_path.empty()) {
1066 #if (__cplusplus<202002L)
1067 l_save_path = save_path.u8string();
1069 l_save_path = (
const char*)save_path.u8string().c_str();
1072 if (frames_per_chunk==0) {
1075 if (m_dynlib.fnInitProcess3) {
1076 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);
1080 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);
1082 if (!instance)
return false;
1083 if (!init_metadata.empty()) {
1084 for (
auto&& [key,value]: init_metadata) {
1085 m_dynlib.fnSetMetadata(instance, key.c_str(), value.c_str());
1087 init_metadata.clear();
1089 update_thread = std::thread([
this, json_port](){
1091 m_dynlib.fnStartUpdateThread(instance, json_port);
1098 if (m_dynlib.fnWaitUpdateThreadReady(instance, timeout)<0) {
1112 if (instance && m_dynlib.fnGetProcessChunkFrames) {
1113 return m_dynlib.fnGetProcessChunkFrames(instance);
1115 return m_dynlib.fnGetChunkSizeInFrames();
1127 if (m_dynlib.fnPresetManager_InformChange) {
1128 m_dynlib.fnPresetManager_InformChange(instance, relative_path.c_str(), (sound4cl_PresetChange_Kind) change_kind);
1145 if (m_dynlib.fnSetMetadata) {
1147 m_dynlib.fnSetMetadata(instance, key.c_str(), value);
1149 init_metadata.push_back( {key, value} );
1166 if (m_dynlib.fnSetMetadataMulti) {
1167 typedef const char* pchar;
1168 pchar* keyvalue=
new pchar[2*list.size()+1];
1170 for (
auto&& [key,value]: list) {
1171 keyvalue[2*n+0]=key.c_str();
1172 keyvalue[2*n+1]=value;
1175 keyvalue[2*n+0]=
nullptr;
1177 sound4cl_SetMetadataMulti(instance, keyvalue);
1181 for (
auto&& [key,value]: list) {
1186 for (
auto&& [key,value]: list) {
1188 init_metadata.push_back( {key, value} );
1201 std::vector< std::tuple<std::string,std::string> > values;
1202 if (m_dynlib.fnGetMetadataInfos) {
1203 const char** c_values = m_dynlib.fnGetMetadataInfos(instance);
1205 for (
const char** c_value=c_values; *c_value; ) {
1206 std::string key(*c_value);
1209 std::string descr(*c_value);
1211 values.push_back( {key,descr} );
1214 m_dynlib.fnFreeMetadataInfos(instance, c_values);
1247 if (!m_dynlib.fnWebserver) {
1250 webserver = m_dynlib.fnWebserver(http_port,https_port,instance);
1254 int web_status=m_dynlib.fnWebserver_Status(webserver);
1273 if (!m_dynlib.fnWebserver_Stop)
return;
1275 m_dynlib.fnWebserver_Stop(webserver, timeout_ms);
1286 if (!m_dynlib.fnWebserver_SetAppHealth)
return;
1287 m_dynlib.fnWebserver_SetAppHealth(instance, httpcode, contenttype.c_str(), content.c_str());
1295 if (!m_dynlib.fnWebserver_GetAppHealth)
return;
1296 char* c_contenttype=
nullptr;
1297 char* c_content=
nullptr;
1298 m_dynlib.fnWebserver_GetAppHealth(instance, &httpcode, &c_contenttype, &c_content);
1299 contenttype=c_contenttype;
1301 m_dynlib.fnWebserver_FreeString(c_contenttype);
1302 m_dynlib.fnWebserver_FreeString(c_content);
1314 if (!instance)
return 0;
1315 return m_dynlib.fnTerminateProcess(instance);
1325 if (!instance)
return;
1328 if (update_thread.joinable()) {
1329 m_dynlib.fnStopUpdateThread(instance);
1330 update_thread.join();
1332 m_dynlib.fnExitProcess(instance);
1349 return m_dynlib.fnGetEstimatedDelay(instance);
1367 return m_dynlib.fnGetBufferIn(instance);
1384 return m_dynlib.fnGetBufferOut(instance);
1408 m_dynlib.fnProcessAudio_Planar(instance, input, output);
1422 template<
typename T>
1426 std::vector<T> output;
1427 unsigned int out_offset=0;
1428 unsigned int in_offset=0;
1429 unsigned int todo = input.size();
1431 unsigned int left =
AddAudio(&input[in_offset], todo);
1432 unsigned int out_avail = m_dynlib.fnGetOutputCount(instance);
1433 output.resize(out_offset + out_avail);
1434 GetAudio(&output[out_offset], out_avail);
1435 out_offset+=out_avail;
1436 in_offset += todo-left;
1453 client=m_dynlib.fnNewClient(instance);
1454 if (!client)
throw std::bad_alloc();
1462 m_dynlib.fnDeleteClient(client);
1473 std::string
ProcessJson(
const std::string &request,
bool *NeedSave =
nullptr)
1477 const char *canswer = m_dynlib.fnProcessJson(client, request.c_str(), &need_save);
1478 if (!canswer)
return {};
1479 std::string answer(canswer);
1480 m_dynlib.fnFreeJsonAnswer (canswer);
1482 *NeedSave=(need_save!=0);
1488 sound4cl_CClientInstance *client =
nullptr;
1500 return std::make_shared<CClient>(instance, m_dynlib);
1515 if (!m_dynlib.fnSaveState || m_dynlib.fnSaveState(instance)!=0) {
1528 if (m_dynlib.fnSetInstanceTracing) {
1529 m_dynlib.fnSetInstanceTracing(params, tracing_provider, activity_guid);
1540 if (m_dynlib.fnSetInstanceTracingProcessActivity) {
1541 m_dynlib.fnSetInstanceTracingProcessActivity(instance, activity_guid);
1546 template<
typename T>
1547 unsigned int AddAudio(
const T* payload,
unsigned int nFrame)
1552 template<
typename T>
1553 unsigned int GetAudio(T* payload,
unsigned int max_nFrame)
1561 sound4cl_CParameters* params =
nullptr;
1562 sound4cl_CInstance* instance =
nullptr;
1563 std::thread update_thread;
1564 std::vector< std::pair<std::string,std::string> > init_metadata;
1566 bool m_bOwned =
true;
1628 if (m_dynlib.fnGetAudioConverter)
1629 m_cvt = m_dynlib.fnGetAudioConverter((sound4cl_SampleFormat)fmt, nFrame, payl_ch, payl_ch_offset, (sound4cl_ConverterTargetMode)target_mode);
1634 if (m_cvt && m_dynlib.fnFreeAudioConverter) {
1635 m_dynlib.fnFreeAudioConverter(m_cvt);
1639 bool IsOK()
const {
return (m_cvt!=
nullptr); }
1650 { m_dynlib.fnAudioConverter_From(m_cvt, payload, output); }
1661 { m_dynlib.fnAudioConverter_To(m_cvt, input, payload); }
1665 sound4cl_CAudioConverter *m_cvt =
nullptr;
1673 static char *sound4cl_custom_reader(
const fs_char *filename,
void* userdata) {
1675 std::string content=preset_loader->
Read(filename);
1676 return strdup(content.c_str());
1678 static void sound4cl_custom_reader_free(
char *content,
void* userdata) {
1679 if (!content)
return;
1682 static int sound4cl_custom_writer(
const fs_char *filename,
const char *content,
void* userdata) {
1684 auto res=preset_loader->
Write(filename,content);
1687 static int sound4cl_custom_exists(
const fs_char *filename,
void* userdata) {
1689 auto res=preset_loader->
Exists(filename);
1692 static fs_char** sound4cl_custom_getall(
void* userdata) {
1694 auto res=preset_loader->
GetAll();
1696 for (
size_t n=0;n<res.size();n++) {
1697 all[n]=fs_strdup(res[n].c_str());
1699 all[res.size()]=
nullptr;
1702 static void sound4cl_custom_getall_free(
fs_char** all,
void* userdata) {
1704 for (
fs_char** one=all;*one;one++) {
1709 static int sound4cl_custom_remove(
const fs_char *filename,
void* userdata) {
1711 auto res=preset_loader->
Remove(filename);
1714 static int sound4cl_custom_rename(
const fs_char *from,
const fs_char *to,
void* userdata) {
1716 auto res=preset_loader->
Rename(from,to);
void ConvertFrom(const uint8_t *payload, float *output)
virtual ~CAudioConverter()
Destroy the CAudioConverter object.
void ConvertTo(const float *input, uint8_t *payload)
bool Configure(SampleFormat fmt, size_t nFrame, size_t payl_ch, size_t payl_ch_offset, ConverterTargetMode target_mode)
CAudioConverter(CProcessor &dynlib)
Construct a new empty CAudioConverter object.
sound4cl_CBus * Get() const
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
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)
CInstance & operator=(const CInstance &)=delete
CInstance(const CInstance &)=delete
void GetWebServerAppHealth(int &httpcode, std::string &contenttype, std::string &content)
void SetPresetManager(CPresetLoader *preset_manager)
void SetBus(const CBus &bus)
virtual void OnUpdateThreadStop()
unsigned int GetChunkFrames()
CInstance(CProcessor &dynlib, void *_instance)
void SetWebServerAppHealth(int httpcode, const std::string &contenttype, const std::string &content)
CInstance(CProcessor &dynlib)
void SetParam(const std::string &name, const std::string &value)
virtual void OnUpdateThreadStart()
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()
void SetMetadata(const std::string &key, const char *value)
void SetInstanceTracing(TraceLoggingHProvider tracing_provider, GUID activity_guid={})
unsigned int GetAudio(T *payload, unsigned int max_nFrame)
std::string GetParam(const std::string &name)
void SetInstanceTracingProcessActivity(GUID activity_guid)
Custom preset handler helper.
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.
bool Load(const std::filesystem::path &filepath)
Loads the library.
void SetLogSeverity(LogSeverity severity)
unsigned int GetAudioInputCount()
void SetLoggerCallback(log_cb_t cb)
unsigned int GetChunkSizeInFrames()
SampleFormat GetFormatFromName(const std::string &name)
std::vector< unsigned int > GetPossibleChunkSizeInFrames()
std::string GetFormatName(const SampleFormat fmt)
unsigned int GetBytesFromFormat(const SampleFormat fmt)
unsigned int GetAudioOutputCount()
helper::DynFuncHolder< T > GetPrefixSymbol(const std::string &name)
unsigned int GetSampleRate()
bool IsOk() const
Check if the library was loaded correctly.
unsigned int GetChannelCount()
Helper to load dynamic library.
DynFuncHolder< T > GetSymbol_safe(const std::string &name)
CDynLoader(CDynLoader &&other) noexcept
CDynLoader & operator=(CDynLoader const &)=delete
CDynLoader & operator=(CDynLoader &&other) noexcept
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)
CDynLoader(const CDynLoader &)=delete
static std::filesystem::path GetThisLibraryPath(void)
DynFuncHolder< T > GetSymbol(const std::string &name)
Helper to wrap a function pointer.
DynFuncHolder(DynFunc_t a_ptr)
void AudioConvertTo(const float *input, uint8_t *payload, size_t nSpl, SampleFormat fmt)
void AudioMonoToLiveStereo(const float *input, uint8_t *payload)
void StereoToMono_Planar(const float *inputL, const float *inputR, float *output, size_t nFrame)
void MonoToStereo(const float *input, float *output, size_t nFrame)
void AudioConvertFrom(const uint8_t *payload, float *output, size_t nSpl, SampleFormat fmt)
void StereoToMono(const float *input, float *output, size_t nFrame)
void AudioMonoFromLiveStereo(const uint8_t *payload, float *output)
void MonoToStereo_Planar(const float *input, float *outputL, float *outputR, size_t nFrame)
@ ConverterTargetMode_MonoToStereo
Stereo process, using mono extract/payload (converts mono to stereo)
@ ConverterTargetMode_Mono
Mono process (using mono extract/payload)
@ ConverterTargetMode_Stereo
Stereo process (using stereo extract/payload)
@ ConverterTargetMode_AsInput
Same channels as input (no extract/insert)
@ ConverterTargetMode_StereoToMono
Mono process, using stereo extract/payload (converts stereo to mono)
#define SOUND4_WEBSERVER_HTTPS_OK
#define SOUND4_WEBSERVER_HTTP_OK
#define SOUND4_INVALID_WEBSERVER_ID
static std::string WStringToUTF8(const std::wstring &wstr)
static std::wstring UTF8ToWString(const std::string &str)
@ S32_NATIVE
32-bit signed integer, native
@ S16_LE
16-bit signed integer, little-endian
@ S24_BE
24-bit signed integer, big-endian
@ F32_LE
32-bit floating-point, little-endian
@ S24_LE
24-bit signed integer, little-endian
@ S32_LE
32-bit signed integer, little-endian
@ F32_BE
32-bit floating-point, big-endian
@ S16_BE
16-bit signed integer, big-endian
@ S32_BE
32-bit signed integer, big-endian
@ F32_NATIVE
32-bit floating-point, native
@ S24_NATIVE
24-bit signed integer, native
@ S16_NATIVE
16-bit signed integer, native
static void _log_cb_c(sound4cl_LogSeverity severity, const char *c_msg)
std::function< void(LogSeverity, const std::string &)> log_cb_t
@ change_kind_created
has been created
@ change_kind_deleted
has been deleted
@ change_kind_modified
has been modified
struct _tlgProvider_t const * TraceLoggingHProvider
@ F32_NATIVE
32-bit floating-point, native
@ change_kind_modified
Path has been modified.
@ 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