aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDaniil Cherednik <dan.cherednik@gmail.com>2017-08-05 00:40:20 +0300
committerDaniil Cherednik <dan.cherednik@gmail.com>2017-08-05 00:40:20 +0300
commitfcb5986d9d21d923db2480be5089168fc1d1fcd2 (patch)
treed75a08a92d3ec131727a958109781a9b140f28c5
parent85e2815a6ada9709c90aa7f227e384abdb4f9e59 (diff)
downloadatracdenc-fcb5986d9d21d923db2480be5089168fc1d1fcd2.tar.gz
Refactoring: use normal (previous frame is first) overlap buffer layout
-rw-r--r--src/atrac3denc.cpp27
-rw-r--r--src/atrac3denc.h3
-rw-r--r--src/atrac3denc_ut.cpp6
-rw-r--r--src/delay_buffer.h52
-rw-r--r--test/CMakeLists.txt1
5 files changed, 74 insertions, 15 deletions
diff --git a/src/atrac3denc.cpp b/src/atrac3denc.cpp
index 1a394f0..b5b838b 100644
--- a/src/atrac3denc.cpp
+++ b/src/atrac3denc.cpp
@@ -35,18 +35,17 @@ void TAtrac3MDCT::Mdct(TFloat specs[1024], TFloat* bands[4], TFloat maxLevels[4]
TFloat* srcBuff = bands[band];
TFloat* const curSpec = &specs[band*256];
TGainModulator modFn = gainModulators[band];
- vector<TFloat> tmp(512);
- memcpy(&tmp[0], &srcBuff[256], 256 * sizeof(TFloat));
+ TFloat tmp[512];
+ memcpy(&tmp[0], srcBuff, 256 * sizeof(TFloat));
if (modFn) {
- modFn(tmp.data(), srcBuff);
+ modFn(&tmp[0], &srcBuff[256]);
}
TFloat max = 0.0;
for (int i = 0; i < 256; i++) {
- max = std::max(max, std::abs(srcBuff[i]));
- srcBuff[256+i] = TAtrac3Data::EncodeWindow[i] * srcBuff[i];
- srcBuff[i] = TAtrac3Data::EncodeWindow[255-i] * srcBuff[i];
+ max = std::max(max, std::abs(srcBuff[256+i]));
+ srcBuff[i] = TAtrac3Data::EncodeWindow[i] * srcBuff[256+i];
+ tmp[256+i] = TAtrac3Data::EncodeWindow[255-i] * srcBuff[256+i];
}
- memcpy(&tmp[256], &srcBuff[0], 256 * sizeof(TFloat));
const vector<TFloat>& sp = Mdct512(&tmp[0]);
assert(sp.size() == 256);
memcpy(curSpec, sp.data(), 256 * sizeof(TFloat));
@@ -339,19 +338,25 @@ TPCMEngine<TFloat>::TProcessLambda TAtrac3Processor::GetEncodeLambda()
src[i] = data[i * meta.Channels + channel] / 4.0;
}
- TFloat* p[4] = {&PcmBuffer[channel][0][0], &PcmBuffer[channel][1][0], &PcmBuffer[channel][2][0], &PcmBuffer[channel][3][0]};
- SplitFilterBank[channel].Split(&src[0], p);
+ {
+ TFloat* p[4] = {PcmBuffer.GetSecond(channel), PcmBuffer.GetSecond(channel+2), PcmBuffer.GetSecond(channel+4), PcmBuffer.GetSecond(channel+6)};
+ SplitFilterBank[channel].Split(&src[0], p);
+ }
TSce* sce = &SingleChannelElements[channel];
sce->SubbandInfo.Reset();
if (!Params.NoGainControll) {
- CreateSubbandInfo(p, channel, &TransientDetectors[channel*4], &sce->SubbandInfo); //4 detectors per band
+ //CreateSubbandInfo(p, channel, &TransientDetectors[channel*4], &sce->SubbandInfo); //4 detectors per band
}
TFloat* maxOverlapLevels = PrevPeak[channel];
- Mdct(specs.data(), p, maxOverlapLevels, MakeGainModulatorArray(sce->SubbandInfo));
+ {
+ TFloat* p[4] = {PcmBuffer.GetFirst(channel), PcmBuffer.GetFirst(channel+2), PcmBuffer.GetFirst(channel+4), PcmBuffer.GetFirst(channel+6)};
+ Mdct(specs.data(), p, maxOverlapLevels, MakeGainModulatorArray(sce->SubbandInfo));
+ }
+
tonals[channel] = Params.NoTonalComponents ?
TAtrac3Data::TTonalComponents() : ExtractTonalComponents(specs.data(), [](const TFloat* spec, uint16_t len) {
std::vector<TFloat> magnitude(len);
diff --git a/src/atrac3denc.h b/src/atrac3denc.h
index c77c4ab..95cbaf0 100644
--- a/src/atrac3denc.h
+++ b/src/atrac3denc.h
@@ -24,6 +24,7 @@
#include "atrac/atrac3.h"
#include "atrac/atrac3_qmf.h"
#include "transient_detector.h"
+#include "delay_buffer.h"
#include "atrac/atrac3_bitstream.h"
#include "atrac/atrac_scale.h"
@@ -68,7 +69,7 @@ typedef std::function<float(const TFloat* p, uint16_t len)> TTonalDetector;
class TAtrac3Processor : public IProcessor<TFloat>, public TAtrac3MDCT {
TCompressedIOPtr Oma;
const NAtrac3::TAtrac3EncoderSettings Params;
- TFloat PcmBuffer[2][4][256 + 256]; //2 channel, 4 band, 256 sample + 256 for overlap buffer
+ TDelayBuffer<TFloat, 8, 256> PcmBuffer; //8 = 2 channels * 4 bands
TFloat PrevPeak[2][4]; //2 channel, 4 band - peak level (after windowing), used to check overflow during scalling
diff --git a/src/atrac3denc_ut.cpp b/src/atrac3denc_ut.cpp
index 9f62e6d..a80db5a 100644
--- a/src/atrac3denc_ut.cpp
+++ b/src/atrac3denc_ut.cpp
@@ -134,7 +134,7 @@ TEST(TAtrac3MDCT, TAtrac3MDCTSignal) {
for (size_t pos = 0; pos < len; pos += workSz) {
vector<TFloat> specs(1024);
- memcpy(buff.Band0, signal.data() + pos, workSz * sizeof(TFloat));
+ memcpy(buff.Band0 + workSz, signal.data() + pos, workSz * sizeof(TFloat));
TFloat* p[4] = { buff.Band0, buff.Band1, buff.Band2, buff.Band3 };
mdct.Mdct(specs.data(), p);
@@ -161,7 +161,7 @@ TEST(TAtrac3MDCT, TAtrac3MDCTSignalWithGainCompensation) {
for (size_t pos = 0; pos < len; pos += workSz) {
vector<TFloat> specs(1024);
- memcpy(buff.Band0, signal.data() + pos, workSz * sizeof(TFloat));
+ memcpy(buff.Band0 + workSz, signal.data() + pos, workSz * sizeof(TFloat));
TFloat* p[4] = { buff.Band0, buff.Band1, buff.Band2, buff.Band3 };
@@ -290,7 +290,7 @@ TEST(TAtrac3MDCT, TAtrac3MDCTSignalWithGainCompensationAndManualTransient) {
for (size_t pos = 0; pos < len; pos += workSz) {
vector<TFloat> specs(1024);
- memcpy(buff.Band0, signal.data() + pos, workSz * sizeof(TFloat));
+ memcpy(buff.Band0 + workSz, signal.data() + pos, workSz * sizeof(TFloat));
TFloat* p[4] = { buff.Band0, buff.Band1, buff.Band2, buff.Band3 };
//for (int i = 0; i < 256; i++) {
diff --git a/src/delay_buffer.h b/src/delay_buffer.h
new file mode 100644
index 0000000..9e0cfb1
--- /dev/null
+++ b/src/delay_buffer.h
@@ -0,0 +1,52 @@
+/*
+ * This file is part of AtracDEnc.
+ *
+ * AtracDEnc is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * AtracDEnc is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with FFmpeg; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#pragma once
+#include <cstring>
+
+namespace NAtracDEnc {
+
+template<class T, int N, int S>
+class TDelayBuffer {
+public:
+ TDelayBuffer() {
+ static_assert(std::is_pod<T>::value, "T must be a POD type.");
+ memset(Buffer_, 0, sizeof(T) * N * S * 2);
+ }
+
+ void Shift(bool erace = true) {
+ for (int i = 0; i < N; i++) {
+ memcpy(&Buffer_[i][0], &Buffer_[i][S], sizeof(T) * S);
+ if (erace)
+ memset(&Buffer_[i][S], 0, sizeof(T) * S);
+ }
+ }
+
+ T* GetFirst(int i) {
+ return &Buffer_[i][0];
+ }
+
+ T* GetSecond(int i) {
+ return &Buffer_[i][S];
+ }
+
+private:
+ T Buffer_[N][S*2];
+};
+
+} // namespace NAtracDEnc
diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt
index 11ed95d..fdd974f 100644
--- a/test/CMakeLists.txt
+++ b/test/CMakeLists.txt
@@ -15,6 +15,7 @@ endmacro(use_11)
use_11()
if (CMAKE_SYSTEM_PROCESSOR MATCHES "(x86)|(X86)|(amd64)|(AMD64)")
+ message ("Using -fsanitize=address")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -g -fsanitize=address -fno-omit-frame-pointer")
else ()
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -g -fno-omit-frame-pointer")