diff options
author | Daniil Cherednik <dan.cherednik@gmail.com> | 2017-08-05 00:40:20 +0300 |
---|---|---|
committer | Daniil Cherednik <dan.cherednik@gmail.com> | 2017-08-05 00:40:20 +0300 |
commit | fcb5986d9d21d923db2480be5089168fc1d1fcd2 (patch) | |
tree | d75a08a92d3ec131727a958109781a9b140f28c5 | |
parent | 85e2815a6ada9709c90aa7f227e384abdb4f9e59 (diff) | |
download | atracdenc-fcb5986d9d21d923db2480be5089168fc1d1fcd2.tar.gz |
Refactoring: use normal (previous frame is first) overlap buffer layout
-rw-r--r-- | src/atrac3denc.cpp | 27 | ||||
-rw-r--r-- | src/atrac3denc.h | 3 | ||||
-rw-r--r-- | src/atrac3denc_ut.cpp | 6 | ||||
-rw-r--r-- | src/delay_buffer.h | 52 | ||||
-rw-r--r-- | test/CMakeLists.txt | 1 |
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") |