SOUND4 BIGVOICE.CL Library [1.1.2]
Loading...
Searching...
No Matches
sound4.bigvoice.cl-pipe-dyn.cpp
Go to the documentation of this file.
1
4#include <unistd.h>
5#include <iostream>
6#include <strings.h>
7#include <sys/types.h>
8#include <filesystem>
9#include <fstream>
10#include <sstream>
11#if defined(_WIN32) || defined(WIN32)
12 #include <io.h>
13 #include <fcntl.h>
14#endif
15
17
18// --------------------------------------------------------------
51std::string GetEnv(const std::string& name)
52{
53 char *data=getenv(name.c_str());
54 if (!data) return {};
55 return std::string(data);
56}
57
58
59// Reads from stdin, write to stdout
61{
62bool stopthread=false;
63
64 #if defined(_WIN32) || defined(WIN32)
65 // Windows: The stdin, stdout, and stderr streams always open in text mode by default
66 _setmode(_fileno(stdin), _O_BINARY);
67 _setmode(_fileno(stdout), _O_BINARY);
68 #endif
69
71 while (!stopthread)
72 {
73 // Read a chunk from stdin
74 if (std::fread(instance.GetBufferIn().data(), sizeof(float), sound4::bigvoice::dyn::InputSampleSize, stdin) != sound4::bigvoice::dyn::InputSampleSize) {
75 std::cerr << "ProcessLoop: input stopped"<< std::endl;
76 stopthread=true;
77 break;
78 }
79 if (stopthread) break;
80 // Process it
81 instance.ProcessAudio();
82 // Write it to stdout
83 if (fwrite(instance.GetBufferOut().data(), sizeof(float), sound4::bigvoice::dyn::OutputSampleSize, stdout) != sound4::bigvoice::dyn::OutputSampleSize) {
84 std::cerr << "Failed to write audio output" << std::endl;
85 stopthread=true;
86 }
87 }
89}
90
91void Usage(const char *progname, sound4::bigvoice::dyn::CDynLib &dynlib)
92{
93 std::cerr << "Usage: " << progname << std::endl;;
94 std::cerr << " Reads audio from stdin and return processed audio in stdout" << std::endl;
95 std::cerr << "Environment:"<< std::endl;;
96 std::cerr << " - S4STORE_PATH : path to store config [default: (no storage)]"<< std::endl;;
97 std::cerr << " - S4LOGINKEY : SOUND4 Login key (or S4USERID)"<< std::endl;;
98 std::cerr << " - RADIO_NAME : SOUND4 Radio Name"<< std::endl;;
99 std::cerr << " - ACCESS_KEY_ID : SOUND4 Access Key ID"<< std::endl;;
100 std::cerr << " - ACCESS_KEY_SECRET : SOUND4 Access Key Secret"<< std::endl;;
101 if (dynlib.IsOk()) {
102 std::cerr << std::endl;
103 std::cerr << "Example:"<< std::endl;
104 std::cerr << "ffmpeg -re -i file.wav -ar "<<dynlib.GetSampleRate()<<" -ac "<<dynlib.GetChannelCount()<<" -f f32le - | "<<progname<<" | ffplay -f f32le -ar "<<dynlib.GetSampleRate()<<" -ac "<<dynlib.GetChannelCount()<<" -i -" << std::endl;;
105 #if defined(_WIN32) || defined(WIN32)
106 std::cerr << "ffmpeg -f dshow -i audio=\"Microphone\" -ar "<<dynlib.GetSampleRate()<<" -ac "<<dynlib.GetChannelCount()<<" -f f32le - | "<<progname<<" | ffplay -f f32le -ar "<<dynlib.GetSampleRate()<<" -ac "<<dynlib.GetChannelCount()<<" -i -" << std::endl;;
107 #else
108 std::cerr << "ffmpeg -f pulse -i default -ar "<<dynlib.GetSampleRate()<<" -ac "<<dynlib.GetChannelCount()<<" -f f32le - | "<<progname<<" | ffplay -f f32le -ar "<<dynlib.GetSampleRate()<<" -ac "<<dynlib.GetChannelCount()<<" -i -" << std::endl;;
109 #endif
110 }
111}
112
113void MyLogger(sound4::bigvoice::dyn::LogSeverity severity,const std::string& msg)
114{
115 std::cerr << msg << std::endl;
116}
117
120public:
121 MyPresetManager() = default;
122 virtual ~MyPresetManager() = default;
123
124 bool SetupPath(const std::filesystem::path& a_preset_path)
125 {
126 m_preset_path=a_preset_path;
127 if ( !std::filesystem::exists(m_preset_path ) ) {
128 return false;
129 }
130 std::error_code ec;
131 if ( !std::filesystem::is_directory(m_preset_path, ec) ) {
132 return false;
133 }
134 return true;
135 }
136 virtual bool IsReadOnly() override { return false; };
137 virtual bool Exists(const std::filesystem::path &name) override
138 {
139 std::error_code ec;
140 return std::filesystem::exists(GetRealPath(name), ec);
141 }
142 virtual bool Remove(const std::filesystem::path &name) override
143 {
144 std::error_code ec;
145 return std::filesystem::remove(GetRealPath(name), ec);
146 }
147 virtual bool Rename(const std::filesystem::path &from, const std::filesystem::path &to) override
148 {
149 std::error_code ec;
150 std::filesystem::rename(GetRealPath(from), GetRealPath(to), ec);
151 return (!ec);
152 }
153 virtual std::vector<std::filesystem::path> GetAll() override
154 {
155 std::vector<std::filesystem::path> list;
156 for (const auto & entry : std::filesystem::directory_iterator(m_preset_path.c_str(), std::filesystem::directory_options::skip_permission_denied)) {
157 if (entry.is_regular_file()) {
158 list.push_back(entry.path().lexically_relative(m_preset_path));
159 }
160 }
161 return list;
162 }
163 virtual std::string Read(const std::filesystem::path &filename) override
164 {
165 std::ifstream f(GetRealPath(filename));
166 if ( f.fail() ) {
167 return std::string();
168 }
169 std::ostringstream ss;
170 ss << f.rdbuf();
171 return ss.str();
172 }
173 virtual bool Write(const std::filesystem::path &filename, const std::string &content) override
174 {
175 std::ofstream f(GetRealPath(filename));
176 if ( f.fail() ) {
177 return false;
178 }
179 f << content;
180 if ( f.fail() ) {
181 return false;
182 }
183 return true;
184 }
185private:
186 std::filesystem::path m_preset_path;
187 std::filesystem::path GetRealPath(const std::filesystem::path &name)
188 {
189 return m_preset_path / name;
190 }
191};
193
194int main(int argc, const char **argv)
195{
196#if (BIGVOICE_HAS_WEBSERVER)
197 int listen_port = 8080;
198#endif // (BIGVOICE_HAS_WEBSERVER)
199 auto store_path_str=GetEnv("S4STORE_PATH");
200
201 // Get credentials from environment
202 auto LoginKey=GetEnv("S4LOGINKEY");
203 if (LoginKey.empty()) {
204 LoginKey=GetEnv("S4USERID");
205 }
206 auto RadioName=GetEnv("RADIO_NAME");
207 auto KeyId=GetEnv("ACCESS_KEY_ID");
208 auto AccessKey=GetEnv("ACCESS_KEY_SECRET");
209
210 const char *progname=argv[0];
211
212
215 if (!dynlib.Load()) {
216 std::cerr << "Failed to load processing library" << std::endl;
217 return 1;
218 }
220
221 if (argc>1) {
222 if ((strcasecmp(argv[1],"-h")==0) || (strcasecmp(argv[1],"--help")==0)) {
223 Usage(progname,dynlib);
224 return 0;
225 }
226 }
227 if (LoginKey.empty() || RadioName.empty() || KeyId.empty() || AccessKey.empty()) {
228 std::cerr << "Missing credentials in environment" << std::endl;
229 Usage(progname,dynlib);
230 return 1;
231 }
232 std::filesystem::path store_path;
233 if (!store_path_str.empty()) {
234 store_path = std::filesystem::path(store_path_str);
235 if (!std::filesystem::exists(store_path) || !std::filesystem::is_directory(store_path)) {
236 std::cerr << "Storage folder '"<<store_path.c_str()<<"' is not a valid directory" << std::endl;
237 Usage(progname,dynlib);
238 return 1;
239 }
240 }
241
243 sound4::bigvoice::dyn::SetLogSeverity(dynlib, verbose5);
244 sound4::bigvoice::dyn::SetLoggerCallback(dynlib, MyLogger);
245
246 sound4::bigvoice::dyn::CInstance instance(dynlib);
247 instance.SetParam("ADMIN_USER","admin");
248 instance.SetParam("ADMIN_SECRET","admin");
250
252 MyPresetManager preset_manager;
253 if (!store_path.empty()) {
254 if (!preset_manager.SetupPath(store_path)) {
255 std::cerr << "Failed to setup the custom preset manager on path " << store_path.c_str() << std::endl;
256 return 1;
257 }
258 instance.SetPresetManager(&preset_manager);
259 }
261
262 std::cerr << "Creating" << std::endl;
264 if (!instance.Create(LoginKey, RadioName, KeyId, AccessKey, {})) {
265 std::cerr << "Failed to create the processing instance" << std::endl;
266 return 1;
267 }
269
270#if (BIGVOICE_HAS_WEBSERVER)
271 std::cerr << "Starting web server" << std::endl;
273 if (!instance.StartWebServer(listen_port,0)) {
274 std::cerr << "Failed to create the web server on port " << listen_port << std::endl;
275 return 1;
276 }
278#endif // (BIGVOICE_HAS_WEBSERVER)
279
280 {
282 auto client = instance.NewClient();
283 auto answer = client->ProcessJson(R"JSON({"get":{"processorname":null}})JSON");
284 std::cerr << "Request for processor name returned "<<answer<<std::endl;
286 }
287
288 ProcessLoop(instance);
289
290 std::cerr << "Stopping now" << std::endl;
291 instance.Stop();
292
293 std::cerr << "End" << std::endl;
294 return 0;
295}
[Custom preset manager]
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)
helper::DynFuncHolder< decltype(bigvoice_GetSampleRate) > GetSampleRate
bool Load(const std::filesystem::path &path={})
Loads the library.
bool IsOk() const
Check if the library was loaded correctly.
helper::DynFuncHolder< decltype(bigvoice_GetChannelCount) > GetChannelCount
std::array< float, InputSampleSize > & GetBufferIn()
void SetParam(const std::string &name, const std::string &value)
bool StartWebServer(int http_port, int https_port=0)
void SetPresetManager(CPresetLoader *preset_manager)
std::array< float, OutputSampleSize > & GetBufferOut()
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=12)
bigvoice_LogSeverity
void ProcessLoop(sound4::bigvoice::dyn::CInstance &instance)
int main(int argc, const char **argv)
[Custom preset manager]
std::string GetEnv(const std::string &name)
void Usage(const char *progname, sound4::bigvoice::dyn::CDynLib &dynlib)
void MyLogger(sound4::bigvoice::dyn::LogSeverity severity, const std::string &msg)
C++ wrapper for dynamic loading library.