You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
pa-calculator/source/csong.cpp

195 lines
5.0 KiB
C++

#include "csong.h"
#include <QFileInfo>
#include "getLoudness.h"
#include "getLoudness_terminate.h"
#include "rt_nonfinite.h"
#include "coder_array.h"
#include <cmath>
csong::csong()
{
m_path="";
m_loudness=0;
m_peakLevel=0;
m_widgetItem=new QTableWidgetItem[5];
setWidgetProperties();
}
csong::csong(QString path)
{
m_path=path;
m_widgetItem=new QTableWidgetItem[5];
setWidgetProperties();
}
csong::~csong()
{
delete [] m_widgetItem;
}
void csong::analyze(float preferedLoudness)
{
using namespace nqr;
NyquistIO loader;
try {
std::shared_ptr<AudioData> fileData = std::make_shared<AudioData>();
#ifdef Q_OS_WIN
FILE * audioFile = fopen(m_path.toLatin1().constData(), "rb");
if (!audioFile)
{
throw std::runtime_error("file not found");
}
fseek(audioFile, 0, SEEK_END);
size_t lengthInBytes = ftell(audioFile);
fseek(audioFile, 0, SEEK_SET);
// Allocate temporary buffer
std::vector<uint8_t> fileBuffer(lengthInBytes);
size_t elementsRead = fread(fileBuffer.data(), 1, lengthInBytes, audioFile);
if (elementsRead == 0 || fileBuffer.size() < 64)
{
throw std::runtime_error("error reading file or file too small");
}
NyquistFileBuffer tempdata = {std::move(fileBuffer), elementsRead};
fclose(audioFile);
auto memory=tempdata;
#else
auto memory= ReadFile(m_path.toStdString());
#endif
QFileInfo fi(m_path);
loader.Load(fileData.get(),fi.suffix().toStdString(),memory.buffer);
coder::array<float, 2U> loudness;
loudness.set_size(1,1);
coder::array<float, 2U> data;
data.set_size(fileData->samples.size()/2,fileData->channelCount);
for (int idx0{0}; idx0 < data.size(0); idx0++) {
for (int idx1{0}; idx1 < data.size(1); idx1++) {
data[idx0 + data.size(0) * idx1] = fileData->samples[idx1+data.size(1)*idx0];
}
}
getLoudness(data,fileData->sampleRate,loudness);
//getLoudness_terminate();
m_loudness=loudness[0];
m_widgetItem[1].setData(Qt::EditRole,QVariant(m_loudness));
m_peakLevel=0;
for (unsigned int i=0;i<fileData->samples.size();i++){
if (abs(fileData->samples[i])>m_peakLevel){
m_peakLevel=abs(fileData->samples[i]);
}
}
m_peakLevel=linToDb(m_peakLevel);
if (m_peakLevel>0){
m_peakLevel=0;
}
m_widgetItem[2].setData(Qt::EditRole,QVariant(m_peakLevel));
m_correction=preferedLoudness-m_loudness;
m_widgetItem[4].setData(Qt::EditRole,QVariant(m_correction));
m_correctedPeakLevel=m_peakLevel+m_correction;
m_widgetItem[3].setData(Qt::EditRole,QVariant(m_correctedPeakLevel));
if (m_correctedPeakLevel>0){
m_widgetItem[3].setBackground(Qt::red);
}else {
m_widgetItem[3].setBackground(QBrush());
}
} catch (const UnsupportedExtensionEx & e)
{
//std::cerr << "Caught: " << e.what() << std::endl;
m_widgetItem[1].setText("Nicht unterstützte Dateiendung!");
m_widgetItem[2].setText("-");
m_widgetItem[3].setText("-");
m_widgetItem[4].setText("-");
}
catch (const LoadPathNotImplEx & e)
{
//std::cerr << "Caught: " << e.what() << std::endl;
}
catch (const LoadBufferNotImplEx & e)
{
//std::cerr << "Caught: " << e.what() << std::endl;
}
catch (const std::exception & e)
{
//std::cerr << "Caught: " << e.what() << std::endl;
m_widgetItem[1].setText("Nicht unterstützter Codec!");
m_widgetItem[2].setText("-");
m_widgetItem[3].setText("-");
m_widgetItem[4].setText("-");
}
}
void csong::setNewPreferedLoudness(float preferedLoudness)
{
m_correction=preferedLoudness-m_loudness;
m_widgetItem[4].setText(QString::number(m_correction));
m_correctedPeakLevel=m_peakLevel+m_correction;
m_widgetItem[3].setText(QString::number(m_correctedPeakLevel));
if (m_correctedPeakLevel>0){
m_widgetItem[3].setBackground(Qt::red);
}else {
m_widgetItem[3].setBackground(QBrush());
}
}
void csong::setPath(QString path)
{
m_path=path;
m_widgetItem[0].setText(m_path);
}
float csong::get_PeakLevel() const
{
return m_peakLevel;
}
float csong::get_Loudness() const
{
return m_loudness;
}
float csong::get_correctedPeakLevel() const
{
return m_correctedPeakLevel;
}
float csong::get_correction() const
{
return m_correction;
}
float csong::linToDb(float linValue)
{
return 20*std::log10(linValue);
}
void csong::setWidgetProperties()
{
for (int i=0;i<5;i++){
m_widgetItem[i].setFlags(Qt::ItemIsEnabled | Qt::ItemIsSelectable);
m_widgetItem[i].setTextAlignment(Qt::AlignCenter);
}
m_widgetItem[0].setTextAlignment(Qt::AlignRight | Qt::AlignVCenter);
}
QString csong::get_path() const{
return m_path;
}