Page MenuHomePhabricator

ebur128_tool.cpp
No OneTemporary

ebur128_tool.cpp

//
// Created by Administrator on 2024/7/8.
//
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <iostream>
#include "alimiter.h"
#include "ebur128.h"
#include "WaveFile.h"
#define PROC_LEN 1024
/**
* 获取增益
* @param nChannel
* @param nSampleRate
* @param pData
* @param nLength
* @param gain
* @return
*/
int ebur128_whole(int nChannel, int nSampleRate, short *pData, const int nLength, double &gated_loudness)
{
ebur128_state *st = NULL;
st = ebur128_init(nChannel, nSampleRate, EBUR128_MODE_I);
if (NULL == st)
{
return -1;
}
int nPos = 0;
int nTmpLength = 0;
int nRet;
while (nPos < nLength)
{
nTmpLength = PROC_LEN;
if (nLength - nPos < PROC_LEN)
{
nTmpLength = nLength - nPos;
}
nRet = ebur128_add_frames_short(st, pData + nPos, nTmpLength / nChannel);
if (nRet != 0)
{
return -2;
}
nPos += nTmpLength;
}
gated_loudness = -1;
ebur128_loudness_global(st, &gated_loudness);
ebur128_destroy(&st);
return 0;
}
int main(int argc, char* argv[]) {
if (argc < 4)
{
printf("input error! example: ./main input_wav target_loudness dst_wav\n");
return -1;
}
std::string vocal_path = argv[1];
double target_loudness = atof(argv[2]);
std::string out_vocal_path = argv[3];
// 读取数据
CWaveFile vocal_wav = CWaveFile(vocal_path.c_str(), false);
if (!vocal_wav.GetStatus())
{
printf("%s not ok!\n", vocal_path.c_str());
return -2;
}
int vocal_buf_len = vocal_wav.GetChannels() * vocal_wav.GetTotalFrames();
float *vocal_buf = new float[vocal_buf_len];
short *short_vocal_buf = new short[vocal_buf_len];
vocal_wav.ReadFrameAsfloat(vocal_buf, vocal_wav.GetTotalFrames());
for(int i = 0; i < vocal_wav.GetTotalFrames() * vocal_wav.GetChannels(); i++)
{
short_vocal_buf[i] = float(vocal_buf[i]) * 32767.f;
}
double vocal_gated_loudness = 0;
ebur128_whole(vocal_wav.GetChannels(), vocal_wav.GetSampleRate(), short_vocal_buf,
vocal_wav.GetTotalFrames() * vocal_wav.GetChannels(), vocal_gated_loudness);
if (std::isnan(vocal_gated_loudness))
{
printf("vocal_gated_loudness is nan\n");
vocal_gated_loudness = target_loudness;
}
float db = (target_loudness - vocal_gated_loudness) / 20.f;
float ebur128_rate = pow(10, db);
if (ebur128_rate > 100) {
printf("ebur128_rate=%f bigger than 100\n", ebur128_rate);
ebur128_rate = 100;
} else if (ebur128_rate < 0.01) {
printf("ebur128_rate=%f little than 100\n", ebur128_rate);
ebur128_rate = 0.01;
}
printf("vocal_gated_loudness = %f, db = %f, gain = %f\n", vocal_gated_loudness, db, ebur128_rate);
SUPERSOUND::Alimiter limiter;
limiter.SetParam(vocal_wav.GetSampleRate(), vocal_wav.GetChannels());
for (int i = 0; i < vocal_buf_len; i++)
{
float out = vocal_buf[i] * ebur128_rate;
limiter.Filter(&out, &out, 1);
vocal_buf[i] = out;
}
CWaveFile out_wav = CWaveFile(out_vocal_path.c_str(), true);
out_wav.SetChannels(vocal_wav.GetChannels());
out_wav.SetSampleRate(vocal_wav.GetSampleRate());
out_wav.SetSampleFormat(SF_IEEE_FLOAT);
out_wav.SetupDone();
out_wav.WriteFrame(vocal_buf, vocal_wav.GetTotalFrames());
delete[] vocal_buf;
delete[] short_vocal_buf;
return 0;
}

File Metadata

Mime Type
text/x-c
Expires
Sun, Jan 12, 01:54 (1 d, 4 h)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
1347130
Default Alt Text
ebur128_tool.cpp (3 KB)

Event Timeline