36#define DEF_SAMPLES 16000
38#define MAX_RECOGNITION_TIME 2500
39#define MAX_BUFFER DEF_SAMPLES*10
40#define DEF_BUFFER DEF_SAMPLES
48using json = nlohmann::json;
57 DWORD fileAttributes = GetFileAttributes(filePath.c_str());
58 return (fileAttributes != INVALID_FILE_ATTRIBUTES);
67 return (stat(filePath.c_str(), &buffer) == 0);
74#include <android/asset_manager.h>
77void copyAssetFile(AAssetManager* manager,
const std::string& assetFilePath,
const std::string& destFilePath)
79 AAsset* asset = AAssetManager_open(manager, assetFilePath.c_str(), AASSET_MODE_STREAMING);
87 off_t assetSize = AAsset_getLength(asset);
90 std::ofstream destFile(destFilePath, std::ios::out | std::ios::binary);
91 if (!destFile.is_open())
99 const int bufferSize = 8192;
100 std::array<char, bufferSize> buffer;
105 int bytesRead = AAsset_read(asset, buffer.data(), bufferSize);
106 if (bytesRead <= 0) {
111 destFile.write(buffer.data(), bytesRead);
121void copyAssetDirectory(AAssetManager* manager,
const std::string& assetDir,
const std::string& destDir)
124 mkdir(destDir.c_str(), S_IRWXU | S_IRWXG | S_IRWXO);
126 AAssetDir* assetDirObj = AAssetManager_openDir(manager, assetDir.c_str());
127 if (assetDirObj ==
nullptr)
133 const char* fileName =
nullptr;
134 while ((fileName = AAssetDir_getNextFileName(assetDirObj)) !=
nullptr)
136 std::string assetFilePath = assetDir +
P_SLASH + std::string(fileName);
137 std::string destFilePath = destDir +
P_SLASH + std::string(fileName);
139 copyAssetFile(manager, assetFilePath, destFilePath);
143 AAssetDir_close(assetDirObj);
147std::string android_extract_dir(std::string dir)
149 std::string assetDir = dir;
152 std::transform(assetDir.begin(), assetDir.end(), assetDir.begin(), ::tolower);
153 if (assetDir.compare(0, 4,
"apk/") != 0)
156 assetDir = assetDir.substr(4).c_str();
158 struct android_app* mApp = (
struct android_app*)SCgetExtra(
"this_inst");
160 const char* internalPath = mApp->activity->internalDataPath;
161 destDir = std::string(internalPath) +
P_SLASH + assetDir;
163 AAssetManager* manager = mApp->activity->assetManager;
170 for (
const char& c : destDir)
174 mkdir(subPath.c_str(), S_IRWXU | S_IRWXG | S_IRWXO);
177 copyAssetDirectory(manager, assetDir, destDir);
178 copyAssetDirectory(manager, assetDir +
P_SLASH +
"am", destDir +
P_SLASH +
"am");
179 copyAssetDirectory(manager, assetDir +
P_SLASH +
"conf", destDir +
P_SLASH +
"conf");
180 copyAssetDirectory(manager, assetDir +
P_SLASH +
"graph", destDir +
P_SLASH +
"graph");
181 copyAssetDirectory(manager, assetDir +
P_SLASH +
"ivector", destDir +
P_SLASH +
"ivector");
189 size_t found = filePath.find_last_of(
"/\\");
191 if (found != std::string::npos)
192 return filePath.substr(0, found);
199 size_t lastSlash = filePath.find_last_of(
"/\\");
200 size_t lastDot = filePath.find_last_of(
".");
201 if (lastDot != std::string::npos && (lastSlash == std::string::npos || lastDot > lastSlash))
202 return filePath.substr(lastSlash + 1, lastDot - lastSlash - 1);
204 return filePath.substr(lastSlash + 1);
211 json jsonData = json::parse(jsonString);
212 if (jsonData.contains(key))
214 return jsonData[key].get<std::string>();
222 catch (
const json::parse_error&)
231 std::istringstream iss(text);
266 pathDir = android_extract_dir(pathDir);
269 mModel = vosk_model_new(pathDir.c_str());
271 mRecognizer = vosk_recognizer_new(mModel,
DEF_SAMPLES);
273 if (mRecognizer != NULL)
278 if (mRecognizer != NULL)
279 vosk_recognizer_free(mRecognizer);
282 vosk_model_free(mModel);
298 if (mThread.joinable())
301 if (mRecognizer != NULL)
302 vosk_recognizer_free(mRecognizer);
305 vosk_model_free(mModel);
307 SAFE_DELETE(mBuffer);
316 mBuffer->
fill(data, lenght);
326 int bufferCursor = 0;
328 int remainingSamples = mTimeOutSamples;
329 std::string lastPartial;
333 const std::lock_guard<std::mutex> lock(mMutexConfig);
336 if (remainingSamples <= 0)
342 vosk_recognizer_reset(mRecognizer);
346 remainingSamples = mTimeOutSamples;
353 std::this_thread::sleep_for(std::chrono::milliseconds(1));
364 remainingSamples = mTimeOutSamples;
368 remainingSamples = 0;
373 frameSize = std::min(dataSize, FRAMESIZE);
374 dataSize -= frameSize;
375 remainingSamples -= frameSize;
377 final = vosk_recognizer_accept_waveform(mRecognizer, buffer + bufferCursor, frameSize);
378 bufferCursor += frameSize;
382 std::string partial =
getValueFromJson(vosk_recognizer_partial_result(mRecognizer),
"partial").c_str();
383 if (!partial.empty() && (partial !=
"[unk]"))
388 if (lastPartial != partial)
394 lastPartial = partial;
400 std::string result =
getValueFromJson(vosk_recognizer_result(mRecognizer),
"text").c_str();
402 if (!result.empty() && (result !=
"[unk]"))
407 if (lastPartial != result)
416 remainingSamples = mTimeOutSamples;
438 const std::lock_guard<std::mutex> lock(mMutexConfig);
439 mKeyWords.push_back(s_Word);
441 std::string wlist =
"[";
442 for (
unsigned int i = 0; i < mKeyWords.size(); i++)
444 std::string w = mKeyWords[i];
445 std::transform(w.begin(), w.end(), w.begin(), ::tolower);
447 wlist +=
"\"" + to_utf8(w) +
"\"";
449 wlist +=
",\"" + to_utf8(w) +
"\"";
451 if (mKeyWords.size() > 0)
452 wlist +=
", \"[unk]\"";
456 vosk_recognizer_set_grm(mRecognizer, wlist.c_str());
size_t ProcessBuffer(char *buffer, size_t length, float threshold)
void fill(const char *newData, size_t newDataSize)
void setVolume(int volume)
Set The volume for the recognition.
void AddWord(std::string s_Rule, std::string s_Word)
Add word to recognition.
void fillAudioBuffer(const char *data, size_t lenght)
Recognition()
utils libraries
bool initializeObjects()
Init Recognition Objects.
int getVolume()
Get The volume from recognition.
~Recognition()
Recognition Destructor.
basic_json<> json
default specialization
std::string getDirectoryFromFilePath(const std::string &filePath)
bool fileExists(const std::string &filePath)
std::string getDirectoryFromFilePath(const std::string &filePath)
int countWords(const std::string &text)
#define DEF_SAMPLES
utils libraries
#define MAX_RECOGNITION_TIME
std::string getValueFromJson(const std::string &jsonString, const std::string &key)
std::string getFileNameWithoutExtension(const std::string &filePath)