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.
188 lines
4.6 KiB
C++
188 lines
4.6 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;
|
|
}
|
|
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;
|
|
}
|
|
|
|
}
|
|
|
|
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;
|
|
}
|