From bbd208aacffc2279fd2b433deb89fc337db74b56 Mon Sep 17 00:00:00 2001 From: VersusTuneZ Date: Sat, 1 Nov 2025 22:08:48 +0100 Subject: [PATCH] Fixes --- README.md | 6 + headers/VUtils/StringUtils.h | 33 ++--- src/VUtils/StringUtils.cpp | 193 ++++++++++++++------------- src/VulcanoLE/Audio/AudioGrabber.cpp | 153 +++++++++++---------- src/VulcanoLE/Audio/FFT.cpp | 2 + src/VulcanoLE/Scripts/TheUnknown.cpp | 75 ++++++----- 6 files changed, 238 insertions(+), 224 deletions(-) diff --git a/README.md b/README.md index 0922256..f21e9d4 100644 --- a/README.md +++ b/README.md @@ -33,6 +33,12 @@ cmake -DCMAKE_BUILD_TYPE=Debug .. make -DCMAKE_BUILD_TYPE=Release .. ``` +## UDEV +```udev +ACTION=="add", SUBSYSTEMS=="usb", ATTRS{idVendor}=="1e7d", ATTRS{idProduct}=="307a", MODE="660", GROUP="wheel" +ACTION=="add", SUBSYSTEMS=="usb", ATTRS{idVendor}=="1e7d", ATTRS{idProduct}=="3098", MODE="660", GROUP="wheel" +``` + ## RUN `./anyVulcanoLE` diff --git a/headers/VUtils/StringUtils.h b/headers/VUtils/StringUtils.h index ee7d491..21fa5e5 100644 --- a/headers/VUtils/StringUtils.h +++ b/headers/VUtils/StringUtils.h @@ -2,30 +2,33 @@ #include #include +#include namespace VUtils { - class StringUtils { - public: - static void leftTrim(std::string &s); +class StringUtils { +public: + static void leftTrim(std::string &s); - static void rightTrim(std::string &s); + static void rightTrim(std::string &s); - static void trim(std::string &s); + static void trim(std::string &s); - static std::string leftTrimCopy(std::string s); + static std::string leftTrimCopy(std::string s); - static std::string rightTrimCopy(std::string s); + static std::string rightTrimCopy(std::string s); - static std::string trimCopy(std::string s); + static std::string trimCopy(std::string s); - static std::vector split(const std::string &s, const std::string &delimiter); + static std::vector split(const std::string &s, + const std::string &delimiter); - static std::string urlDecode(const std::string &url); + static std::string urlDecode(const std::string &url); - static std::string urlEncode(const std::string &url); + static std::string urlEncode(const std::string &url); - static std::string join(const std::vector& vector, const std::string& delimiter); + static std::string join(const std::vector &vector, + const std::string &delimiter); - static bool hasNullByte(int size, const char string[1024]); - }; -}// namespace VUtils + static bool hasNullByte(int size, const char string[1024]); +}; +} // namespace VUtils diff --git a/src/VUtils/StringUtils.cpp b/src/VUtils/StringUtils.cpp index 5efff71..0ab9dae 100644 --- a/src/VUtils/StringUtils.cpp +++ b/src/VUtils/StringUtils.cpp @@ -2,105 +2,108 @@ #include #include +#include namespace VUtils { - void StringUtils::leftTrim(std::string &s) { - s.erase(s.begin(), std::find_if(s.begin(), s.end(), - std::not1(std::ptr_fun(std::isspace)))); +void StringUtils::leftTrim(std::string &s) { + s.erase(s.begin(), + std::find_if(s.begin(), s.end(), + std::not1(std::ptr_fun(std::isspace)))); +} + +void StringUtils::rightTrim(std::string &s) { + s.erase(std::find_if(s.rbegin(), s.rend(), + std::not1(std::ptr_fun(std::isspace))) + .base(), + s.end()); +} + +void StringUtils::trim(std::string &s) { + leftTrim(s); + rightTrim(s); +} + +std::string StringUtils::leftTrimCopy(std::string s) { + leftTrim(s); + return s; +} + +std::string StringUtils::rightTrimCopy(std::string s) { + rightTrim(s); + return s; +} + +std::string StringUtils::trimCopy(std::string s) { + trim(s); + return s; +} + +std::vector StringUtils::split(const std::string &s, + const std::string &delimiter) { + size_t pos_start = 0, pos_end, delim_len = delimiter.length(); + std::string token; + std::vector res; + + while ((pos_end = s.find(delimiter, pos_start)) != std::string::npos) { + token = s.substr(pos_start, pos_end - pos_start); + pos_start = pos_end + delim_len; + res.push_back(token); + } + + res.push_back(s.substr(pos_start)); + return res; +} + +std::string StringUtils::urlDecode(const std::string &val) { + std::string ret; + char ch; + int i, ii; + for (i = 0; i < val.length(); i++) { + if (int(val[i]) == 37) { + sscanf(val.substr(i + 1, 2).c_str(), "%x", &ii); + ch = static_cast(ii); + ret += ch; + i = i + 2; + } else { + ret += val[i]; } + } + return (ret); +} - void StringUtils::rightTrim(std::string &s) { - s.erase(std::find_if(s.rbegin(), s.rend(), - std::not1(std::ptr_fun(std::isspace))) - .base(), - s.end()); +std::string StringUtils::urlEncode(const std::string &value) { + std::ostringstream escaped; + escaped.fill('0'); + escaped << std::hex; + + for (char c : value) { + if (isalnum(c) || c == '-' || c == '_' || c == '.' || c == '~') { + escaped << c; + continue; } + escaped << std::uppercase; + escaped << '%' << std::setw(2) << int((unsigned char)c); + escaped << std::nouppercase; + } - void StringUtils::trim(std::string &s) { - leftTrim(s); - rightTrim(s); + return escaped.str(); +} +std::string StringUtils::join(const std::vector &vector, + const std::string &delimiter) { + std::stringstream string; + for (int i = 0; i < vector.size(); ++i) { + if (i != 0) + string << delimiter; + string << vector[i]; + } + return string.str(); +} +bool StringUtils::hasNullByte(int size, const char *string) { + for (int i = 0; i < size; ++i) { + if (string[i] == '\0') { + return true; } - - std::string StringUtils::leftTrimCopy(std::string s) { - leftTrim(s); - return s; - } - - std::string StringUtils::rightTrimCopy(std::string s) { - rightTrim(s); - return s; - } - - std::string StringUtils::trimCopy(std::string s) { - trim(s); - return s; - } - - std::vector StringUtils::split(const std::string &s, const std::string &delimiter) { - size_t pos_start = 0, pos_end, delim_len = delimiter.length(); - std::string token; - std::vector res; - - while ((pos_end = s.find(delimiter, pos_start)) != std::string::npos) { - token = s.substr(pos_start, pos_end - pos_start); - pos_start = pos_end + delim_len; - res.push_back(token); - } - - res.push_back(s.substr(pos_start)); - return res; - } - - std::string StringUtils::urlDecode(const std::string &val) { - std::string ret; - char ch; - int i, ii; - for (i = 0; i < val.length(); i++) { - if (int(val[ i ]) == 37) { - sscanf(val.substr(i + 1, 2).c_str(), "%x", &ii); - ch = static_cast(ii); - ret += ch; - i = i + 2; - } else { - ret += val[ i ]; - } - } - return (ret); - } - - std::string StringUtils::urlEncode(const std::string &value) { - std::ostringstream escaped; - escaped.fill('0'); - escaped << std::hex; - - for (char c : value) { - if (isalnum(c) || c == '-' || c == '_' || c == '.' || c == '~') { - escaped << c; - continue; - } - escaped << std::uppercase; - escaped << '%' << std::setw(2) << int((unsigned char) c); - escaped << std::nouppercase; - } - - return escaped.str(); - } - std::string StringUtils::join(const std::vector &vector, const std::string &delimiter) { - std::stringstream string; - for (int i = 0; i < vector.size(); ++i) { - if (i != 0) - string << delimiter; - string << vector[ i ]; - - } - return string.str(); - } - bool StringUtils::hasNullByte(int size, const char *string) { - for (int i = 0; i < size; ++i) { - if (string[ i ] == '\0') { - return true; - } - } - return false; - } -}// namespace VUtils \ No newline at end of file + } + return false; +} +} // namespace VUtils diff --git a/src/VulcanoLE/Audio/AudioGrabber.cpp b/src/VulcanoLE/Audio/AudioGrabber.cpp index 5c4b791..20d6941 100644 --- a/src/VulcanoLE/Audio/AudioGrabber.cpp +++ b/src/VulcanoLE/Audio/AudioGrabber.cpp @@ -1,105 +1,104 @@ -#include -#include -#include -#include #include "VUtils/Math.h" - +#include +#include +#include +#include +#include AudioGrabber::AudioGrabber() = default; AudioGrabber::~AudioGrabber() = default; bool AudioGrabber::read(stereoSample *buffer, uint32_t bufferSize) { - auto &client = JackClient::get(); - if (!client.isData()) - return false; - availableData = client.getFrames(); - client.fillSamples(buffer, availableData); - return true; + auto &client = JackClient::get(); + if (!client.isData()) + return false; + availableData = client.getFrames(); + client.fillSamples(buffer, availableData); + return true; } AudioGrabber *AudioGrabber::createAudioGrabber() { - JackClient::get().start(); - auto *grabber = new AudioGrabber(); - JackClient::get().grabber = grabber; - return grabber; + JackClient::get().start(); + auto *grabber = new AudioGrabber(); + JackClient::get().grabber = grabber; + return grabber; } void AudioGrabber::init() { - m_buffer = static_cast(calloc(BUFFER_SIZE, sizeof(stereoSample))); - if (env != nullptr) - m_scale = env->getAsDouble("audio_scale", 1.0); - m_filter.scale = 1.0; - DBG("SET Audio Scale: %.3f", m_scale) - loudness = { 0.0, 0.0 }; + m_buffer = + static_cast(calloc(BUFFER_SIZE, sizeof(stereoSample))); + if (env != nullptr) + m_scale = env->getAsDouble("audio_scale", 1.0); + m_filter.scale = 1.0; + DBG("SET Audio Scale: %.3f", m_scale) + loudness = {0.0, 0.0}; } void AudioGrabber::calculateRMS(stereoSample *pFrame) { - double squareL = 0, meanL; - double squareR = 0, meanR; - for (int i = 0; i < availableData; i++) { - squareL += std::pow(pFrame[i].l * m_scale, 2); - squareR += std::pow(pFrame[i].r * m_scale, 2); - } - meanL = (squareL / (float) (availableData)); - meanR = (squareR / (float) (availableData)); - loudness = { (float) std::sqrt(meanL), (float) std::sqrt(meanR) }; + double squareL = 0, meanL; + double squareR = 0, meanR; + for (int i = 0; i < availableData; i++) { + squareL += std::pow(pFrame[i].l * m_scale, 2); + squareR += std::pow(pFrame[i].r * m_scale, 2); + } + meanL = (squareL / (float)(availableData)); + meanR = (squareR / (float)(availableData)); + loudness = {(float)std::sqrt(meanL), (float)std::sqrt(meanR)}; } void AudioGrabber::calculatePEAK(stereoSample *pFrame) { - stereoSampleFrame max = { 0, 0 }; - for (int i = 0; i < availableData; i++) { - auto left = (float) std::abs(pFrame[i].l * m_scale); - auto right = (float) std::abs(pFrame[i].r * m_scale); - if (left > max.l) - max.l = left; - if (right > max.r) - max.r = right; - } - loudness = max; + stereoSampleFrame max = {0, 0}; + for (int i = 0; i < availableData; i++) { + auto left = (float)std::abs(pFrame[i].l * m_scale); + auto right = (float)std::abs(pFrame[i].r * m_scale); + if (left > max.l) + max.l = left; + if (right > max.r) + max.r = right; + } + loudness = max; } stereoSampleFrame AudioGrabber::getLoudness() { - std::unique_lock lck(m_mtx); - return loudness; + std::unique_lock lck(m_mtx); + return loudness; } bool AudioGrabber::work() { - std::unique_lock lck(m_mtx); - if (this->read(m_buffer, BUFFER_SIZE)) { - switch (requestMode) { - case ReqMode::FFT: - fft.process(m_buffer, m_scale); - break; - case ReqMode::RMS: - calculateRMS(m_buffer); - break; - case ReqMode::PEAK: - calculatePEAK(m_buffer); - break; - case ReqMode::FILTER: - loudness = m_filter.work(m_buffer, availableData); - break; - default: { - calculateRMS(m_buffer); - calculatePEAK(m_buffer); - fft.process(m_buffer, m_scale); - } - } - return true; - } else { - return false; + std::unique_lock lck(m_mtx); + if (this->read(m_buffer, BUFFER_SIZE)) { + switch (requestMode) { + case ReqMode::FFT: + fft.process(m_buffer, m_scale); + break; + case ReqMode::RMS: + calculateRMS(m_buffer); + break; + case ReqMode::PEAK: + calculatePEAK(m_buffer); + break; + case ReqMode::FILTER: + loudness = m_filter.work(m_buffer, availableData); + break; + default: { + calculateRMS(m_buffer); + calculatePEAK(m_buffer); + fft.process(m_buffer, m_scale); } + } + return true; + } else { + return false; + } } -Audio::FilterHelper &AudioGrabber::getFilter() { - return m_filter; -} +Audio::FilterHelper &AudioGrabber::getFilter() { return m_filter; } double AudioGrabber::getBass() { - auto fftData = fft.getData(); - auto val = 0.0; - for (int i = 1; i < 4; ++i) { - auto avg = (fftData->leftChannel[i] + fftData->rightChannel[i]) / 2.0; - if (avg > val) - val = avg; - } - return VUtils::Math::clamp(val, 1, 255); + auto fftData = fft.getData(); + auto val = 0.0; + for (int i = 1; i < 4; ++i) { + auto avg = (fftData->leftChannel[i] + fftData->rightChannel[i]) / 2.0; + if (avg > val) + val = avg; + } + return VUtils::Math::clamp(val, 1, 255); } diff --git a/src/VulcanoLE/Audio/FFT.cpp b/src/VulcanoLE/Audio/FFT.cpp index bd2c349..5932822 100644 --- a/src/VulcanoLE/Audio/FFT.cpp +++ b/src/VulcanoLE/Audio/FFT.cpp @@ -49,6 +49,8 @@ bool FFT::prepareInput(stereoSample *buffer, uint32_t sampleSize, double scale) for (size_t i = 0; i < sampleSize; ++i) { m_fftwInputLeft[i][0] = VUtils::Math::clamp(buffer[i].r * scale, -1, 1) * hannWindow[i]; m_fftwInputRight[i][0] = VUtils::Math::clamp(buffer[i].r * scale, -1, 1) * hannWindow[i]; + m_fftwInputLeft[i][1] = 0; + m_fftwInputRight[i][1] = 0; if (is_silent && (m_fftwInputLeft[i][0] != 0 || m_fftwInputRight[i][0] != 0)) is_silent = false; } return is_silent; diff --git a/src/VulcanoLE/Scripts/TheUnknown.cpp b/src/VulcanoLE/Scripts/TheUnknown.cpp index 87d0dc9..f4d0671 100644 --- a/src/VulcanoLE/Scripts/TheUnknown.cpp +++ b/src/VulcanoLE/Scripts/TheUnknown.cpp @@ -1,41 +1,42 @@ -#include #include +#include + +#include namespace VIZ { - TheUnknown::TheUnknown(AudioGrabber *pGrabber, Vulcan121 *vulcan) : VIZ(pGrabber, vulcan) { - m_random.setDist(0, 128); - for (int i = 0; i < NUM_KEYS; i++) { - m_keyHeightMap[i] = std::abs(SimplexNoise::noise(i + 1.0f)) * 0.1; - m_keyOffset[i] = m_random.getFast(); - } - m_random.setDist(0.005, 0.01); - } - void TheUnknown::onSetup() { - keyboard->sendToLEDs({ 0, 0, 0, 0 }); - Vulcan121::setColor(map, { 202, 35, 13, 255 }); - grabber->requestMode = AudioGrabber::ReqMode::PEAK; - } - void TheUnknown::onTick(float delta) { - auto loudness = grabber->getLoudness(); - auto factor = (((loudness.r + loudness.l) / 2.0) * 0.9) + 0.05; - for (size_t i = 0; i < keyboardData.num_keys; i++) { - auto &color = map.key[i]; - auto noise = SimplexNoise::noise(m_keyOffset[i]) * factor; - noise = std::abs(noise) + 0.02; - auto newAlpha = std::clamp((noise + m_keyHeightMap[i]) * 255, 0.0, 255.0); - color.a = (color.a + newAlpha) / 2; +TheUnknown::TheUnknown(AudioGrabber *pGrabber, Vulcan121 *vulcan) + : VIZ(pGrabber, vulcan) { + m_random.setDist(0, 128); + for (int i = 0; i < NUM_KEYS; i++) { + m_keyHeightMap[i] = std::abs(SimplexNoise::noise(i + 1.0f)) * 0.1; + m_keyOffset[i] = m_random.getFast(); + } + m_random.setDist(0.005, 0.01); +} +void TheUnknown::onSetup() { + keyboard->sendToLEDs({0, 0, 0, 0}); + Vulcan121::setColor(map, {202, 35, 13, 255}); + grabber->requestMode = AudioGrabber::ReqMode::PEAK; +} +void TheUnknown::onTick(float delta) { + auto loudness = grabber->getLoudness(); + auto factor = (((loudness.r + loudness.l) / 2.0) * 0.9) + 0.05; + for (size_t i = 0; i < keyboardData.num_keys; i++) { + auto &color = map.key[i]; + auto noise = SimplexNoise::noise(m_keyOffset[i]) * factor; + noise = std::abs(noise) + 0.02; + auto newAlpha = std::clamp((noise + m_keyHeightMap[i]) * 255, 0.0, 255.0); + color.a = (color.a + newAlpha) / 2; - auto offset = std::sin(m_angle) * m_random.getFast(); - m_keyOffset[i] += (delta * (1.5 * factor)) + offset; - m_angle += 0.0005; - if (m_keyOffset[i] > 20000000) - m_keyOffset[i] = 0.0; - if (m_angle > 1.0) - m_angle -= 1; - } - keyboard->sendLedMap(map); - } - const char *TheUnknown::name() { - return "TheUnknown"; - } -} \ No newline at end of file + auto offset = std::sin(m_angle) * m_random.getFast(); + m_keyOffset[i] += (delta * (1.5 * factor)) + offset; + m_angle += 0.0005; + if (m_keyOffset[i] > 20000000) + m_keyOffset[i] = 0.0; + if (m_angle > 1.0) + m_angle -= 1; + } + keyboard->sendLedMap(map); +} +const char *TheUnknown::name() { return "TheUnknown"; } +} // namespace VIZ