88 lines
2.5 KiB
C++
88 lines
2.5 KiB
C++
#include <cmath>
|
|
#include <VulcanoLE/Audio/AudioGrabber.h>
|
|
#include <VUtils/Logging.h>
|
|
#include <VulcanoLE/Audio/JackClient.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<stereoSample *>(calloc(BUFFER_SIZE, sizeof(stereoSample)));
|
|
if (env != nullptr)
|
|
m_scale = env->getAsDouble("audio_scale", 1.0);
|
|
DBG("SET Audio Scale: %.3f", m_scale)
|
|
loudness = { 0.0, 0.0 };
|
|
}
|
|
|
|
void AudioGrabber::calculateRMS(stereoSample *pFrame) {
|
|
float squareL = 0, meanL;
|
|
float squareR = 0, meanR;
|
|
for (int i = 0; i < availableData; i++) {
|
|
squareL += std::pow(pFrame[0].l * m_scale, 2);
|
|
squareR += std::pow(pFrame[0].r * m_scale, 2);
|
|
}
|
|
meanL = (squareL / (float) (BUFFER_SIZE));
|
|
meanR = (squareR / (float) (BUFFER_SIZE));
|
|
loudness = { std::sqrt(meanL), std::sqrt(meanR) };
|
|
}
|
|
|
|
void AudioGrabber::calculatePEAK(stereoSample *pFrame) {
|
|
stereoSampleFrame max = { 0, 0 };
|
|
for (int i = 0; i < availableData; i++) {
|
|
float left = std::abs(pFrame[0].l * m_scale);
|
|
float right = std::abs(pFrame[0].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<std::mutex> lck(m_mtx);
|
|
return loudness;
|
|
}
|
|
|
|
bool AudioGrabber::work() {
|
|
std::unique_lock<std::mutex> 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;
|
|
default: {
|
|
calculateRMS(m_buffer);
|
|
calculatePEAK(m_buffer);
|
|
fft.process(m_buffer, m_scale);
|
|
}
|
|
}
|
|
return true;
|
|
} else {
|
|
return false;
|
|
}
|
|
}
|