#include #include #include #include #include "VUtils/Math.h" 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; } AudioGrabber *AudioGrabber::createAudioGrabber() { 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 }; } 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) }; } 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 AudioGrabber::getLoudness() { 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; } } 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); }