13#if defined(_WIN32) || defined(WIN32)
60std::string
GetEnv(
const std::string& name)
62 char *data=getenv(name.c_str());
64 return std::string(data);
73 #if defined(_WIN32) || defined(WIN32)
75 _setmode(_fileno(stdin), _O_BINARY);
76 _setmode(_fileno(stdout), _O_BINARY);
85 if (std::fread(instance.
GetBufferIn(),
sizeof(
float), input_sample_count, stdin) != input_sample_count) {
86 std::cerr <<
"ProcessLoop: input stopped"<< std::endl;
90 if (stopthread)
break;
94 if (fwrite(instance.
GetBufferOut(),
sizeof(
float), output_sample_count, stdout) != output_sample_count) {
95 std::cerr <<
"Failed to write audio output" << std::endl;
108 bool SetupPath(
const std::filesystem::path& a_preset_path)
110 m_preset_path=a_preset_path;
111 if ( !std::filesystem::exists(m_preset_path ) ) {
115 if ( !std::filesystem::is_directory(m_preset_path, ec) ) {
121 virtual bool Exists(
const std::filesystem::path &name)
override
124 return std::filesystem::exists(GetRealPath(name), ec);
126 virtual bool Remove(
const std::filesystem::path &name)
override
129 return std::filesystem::remove(GetRealPath(name), ec);
131 virtual bool Rename(
const std::filesystem::path &from,
const std::filesystem::path &to)
override
134 std::filesystem::rename(GetRealPath(from), GetRealPath(to), ec);
137 virtual std::vector<std::filesystem::path>
GetAll()
override
139 std::vector<std::filesystem::path> list;
140 for (
const auto & entry : std::filesystem::directory_iterator(m_preset_path.c_str(), std::filesystem::directory_options::skip_permission_denied)) {
141 if (entry.is_regular_file()) {
142 list.push_back(entry.path().lexically_relative(m_preset_path));
147 virtual std::string
Read(
const std::filesystem::path &filename)
override
149 std::ifstream f(GetRealPath(filename));
151 return std::string();
153 std::ostringstream ss;
157 virtual bool Write(
const std::filesystem::path &filename,
const std::string &content)
override
159 std::ofstream f(GetRealPath(filename));
170 std::filesystem::path m_preset_path;
171 std::filesystem::path GetRealPath(
const std::filesystem::path &name)
173 return m_preset_path / name;
178int main(
int argc,
const char **argv)
180 int listen_port = 8080;
181 auto store_path_str=
GetEnv(
"S4STORE_PATH");
183 std::string libname =
"libsound4.bigvoice.cl.so";
188 auto LoginKey=
GetEnv(
"S4LOGINKEY");
189 if (LoginKey.empty()) {
190 LoginKey=
GetEnv(
"S4USERID");
192 auto RadioName=
GetEnv(
"RADIO_NAME");
193 auto KeyId=
GetEnv(
"ACCESS_KEY_ID");
194 auto AccessKey=
GetEnv(
"ACCESS_KEY_SECRET");
196 const char *progname=argv[0];
197 for (
int n=1;n<argc;n++) {
198 std::string arg = argv[n];
199 if (arg==
"-p" || arg==
"--port") {
201 std::cerr <<
"--port needs a number"<< std::endl;
205 listen_port=atoi(argv[n]);
206 }
else if (arg==
"-l" || arg==
"--lib") {
208 std::cerr <<
"--port needs a number"<< std::endl;
213 }
else if (arg==
"-h" || arg==
"--help") {
214 std::cerr <<
"Usage: " << progname <<
" [-p port] [-l libname.so]"<<std::endl;;
215 std::cerr <<
" Reads audio from stdin and return processed audio in stdout" << std::endl;
216 std::cerr <<
" -l, --lib : library to load ["<<libname<<
"]" << std::endl;
217 std::cerr <<
" -p, --port : port for web server ["<<listen_port<<
"]" << std::endl;
218 std::cerr << std::endl;
219 std::cerr <<
"Environment:"<< std::endl;;
220 std::cerr <<
" - S4STORE_PATH : path to store config [default: (no storage)]"<< std::endl;;
221 std::cerr <<
" - S4LOGINKEY : SOUND4 Login key (or S4USERID)"<< std::endl;;
222 std::cerr <<
" - RADIO_NAME : SOUND4 Radio Name"<< std::endl;;
223 std::cerr <<
" - ACCESS_KEY_ID : SOUND4 Access Key ID"<< std::endl;;
224 std::cerr <<
" - ACCESS_KEY_SECRET : SOUND4 Access Key Secret"<< std::endl;
225 std::cerr << std::endl;
226 std::cerr <<
"Example:"<< std::endl;
227 std::cerr <<
" ffmpeg -re -i file.wav -ar 48000 -ac 1 -f f32le - | "<<progname<<
" | ffplay -f f32le -ar 48000 -ac 1 -i -" << std::endl;;
228 #if defined(_WIN32) || defined(WIN32)
229 std::cerr <<
" ffmpeg -f dshow -i audio=\"Microphone\" -ar 48000 -ac 1 -f f32le - | "<<progname<<
" | ffplay -f f32le -ar 48000 -ac 1 -i -" << std::endl;;
231 std::cerr <<
" ffmpeg -f pulse -i default -ar 48000 -ac 1 -f f32le - | "<<progname<<
" | ffplay -f f32le -ar 48000 -ac 1 -i -" << std::endl;;
235 std::cerr <<
"unknown argument '"<<arg<<
"'"<< std::endl;
243 if (!processor.
Load(libname)) {
244 std::cerr <<
"Failed to load processing library" << std::endl;
249 if (LoginKey.empty() || RadioName.empty() || KeyId.empty() || AccessKey.empty()) {
250 std::cerr <<
"Missing credentials in environment" << std::endl;
253 std::filesystem::path store_path;
254 if (!store_path_str.empty()) {
255 store_path = std::filesystem::path(store_path_str);
256 if (!std::filesystem::exists(store_path) || !std::filesystem::is_directory(store_path)) {
257 std::cerr <<
"Storage folder '"<<store_path.c_str()<<
"' is not a valid directory" << std::endl;
265 std::cerr << msg << std::endl;
269 instance.
SetParam(
"ADMIN_USER",
"admin");
270 instance.
SetParam(
"ADMIN_SECRET",
"admin");
275 if (!store_path.empty()) {
276 if (!preset_manager.
SetupPath(store_path)) {
277 std::cerr <<
"Failed to setup the custom preset manager on path " << store_path.c_str() << std::endl;
284 std::cerr <<
"Creating" << std::endl;
286 if (!instance.
Create(LoginKey, RadioName, KeyId, AccessKey, {})) {
287 std::cerr <<
"Failed to create the processing instance" << std::endl;
292 std::cerr <<
"Starting web server" << std::endl;
295 std::cerr <<
"Failed to create the web server on port " << listen_port << std::endl;
303 auto answer = client->ProcessJson(R
"JSON({"get":{"processorname":null}})JSON");
304 std::cerr << "Request for processor name returned "<<answer<<std::endl;
310 std::cerr <<
"Stopping now" << std::endl;
313 std::cerr <<
"End" << std::endl;
virtual bool Rename(const std::filesystem::path &from, const std::filesystem::path &to) override
virtual ~MyPresetManager()=default
virtual bool Exists(const std::filesystem::path &name) override
virtual bool IsReadOnly() override
virtual bool Write(const std::filesystem::path &filename, const std::string &content) override
MyPresetManager()=default
virtual bool Remove(const std::filesystem::path &name) override
virtual std::vector< std::filesystem::path > GetAll() override
virtual std::string Read(const std::filesystem::path &filename) override
bool SetupPath(const std::filesystem::path &a_preset_path)
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 SetPresetManager(CPresetLoader *preset_manager)
unsigned int GetChunkFrames()
void SetParam(const std::string &name, const std::string &value)
bool StartWebServer(int http_port, int https_port=0)
std::shared_ptr< CClient > NewClient()
Custom preset handler helper.
Dynamic library interface.
bool Load(const std::filesystem::path &filepath)
Loads the library.
void SetLogSeverity(LogSeverity severity)
void SetLoggerCallback(log_cb_t cb)
unsigned int GetChannelCount()
const LogSeverity verbose5
int main(int argc, const char **argv)
[Custom preset manager]
std::string GetEnv(const std::string &name)
void ProcessLoop(sound4::CInstance &instance, sound4::CProcessor &processor)
C++ wrapper for dynamic loading library.