Skip to content

Commit c4b19af

Browse files
committed
Allow to configure atracdenc to use float instead of double
The default is double for hystorical reason. Actually no any reason to use double precision float point calculation for all processing. AT3P encoding will use float except places were we really need double precision. So this default will be changed to float in near future and this option will be removed.
1 parent f8eabde commit c4b19af

13 files changed

+107
-34
lines changed

CMakeLists.txt

+3
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,9 @@ CMAKE_MINIMUM_REQUIRED(VERSION 3.1)
22

33
project(atracdenc)
44
include_directories(src)
5+
6+
option(ATDE_USE_FLOAT "use float32 precision for dsp" OFF)
7+
58
if (UNIX)
69
find_package(GTest)
710
if (GTest_FOUND)

src/CMakeLists.txt

+11-1
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,10 @@ set(CMAKE_MODULE_PATH "${PROJECT_SOURCE_DIR}/cmake/modules")
3232
enable_cxx_compiler_flag_if_supported("-Wall")
3333
enable_cxx_compiler_flag_if_supported("-Wextra")
3434

35+
if (ATDE_USE_FLOAT)
36+
add_compile_definitions(ATDE_USE_FLOAT)
37+
endif()
38+
3539
if (WIN32)
3640
add_compile_definitions(PLATFORM_WINDOWS)
3741
add_compile_definitions(_CRT_SECURE_NO_WARNINGS)
@@ -62,7 +66,13 @@ include_directories(
6266
)
6367

6468
set(SOURCE_FFT_LIB lib/fft/kissfft_impl/kiss_fft.c)
65-
set_source_files_properties(lib/fft/kissfft_impl/kiss_fft.c PROPERTIES COMPILE_FLAGS -Dkiss_fft_scalar=double)
69+
70+
if (ATDE_USE_FLOAT)
71+
set_source_files_properties(lib/fft/kissfft_impl/kiss_fft.c PROPERTIES COMPILE_FLAGS -Dkiss_fft_scalar=float)
72+
else()
73+
set_source_files_properties(lib/fft/kissfft_impl/kiss_fft.c PROPERTIES COMPILE_FLAGS -Dkiss_fft_scalar=double)
74+
endif()
75+
6676
set(SOURCE_OMA_LIB lib/liboma/src/liboma.c)
6777
set(SOURCE_BITSTREAM_LIB lib/bitstream/bitstream.cpp)
6878
set(SOURCE_ATRACDENC_IMPL

src/atrac/atrac1.cpp

+2-2
Original file line numberDiff line numberDiff line change
@@ -26,8 +26,8 @@ constexpr uint32_t TAtrac1Data::SpecsPerBlock[MaxBfus];
2626
constexpr uint32_t TAtrac1Data::SpecsStartLong[MaxBfus];
2727
constexpr uint32_t TAtrac1Data::SpecsStartShort[MaxBfus];
2828
constexpr uint32_t TAtrac1Data::BfuAmountTab[8];
29-
double TAtrac1Data::ScaleTable[64] = {0};
30-
double TAtrac1Data::SineWindow[32] = {0};
29+
TFloat TAtrac1Data::ScaleTable[64] = {0};
30+
TFloat TAtrac1Data::SineWindow[32] = {0};
3131

3232
} //namespace NAtrac1
3333
} //namespace NAtracDEnc

src/atrac/atrac1.h

+2-2
Original file line numberDiff line numberDiff line change
@@ -78,8 +78,8 @@ class TAtrac1Data {
7878
static const uint32_t BitsPerIDWL = 4;
7979
static const uint32_t BitsPerIDSF = 6;
8080

81-
static double ScaleTable[64];
82-
static double SineWindow[32];
81+
static TFloat ScaleTable[64];
82+
static TFloat SineWindow[32];
8383
uint32_t BfuToBand(uint32_t i) {
8484
if (i < 20)
8585
return 0;

src/atrac/atrac3plus_pqf/ut/ipqf_ut.cpp

+2-2
Original file line numberDiff line numberDiff line change
@@ -233,7 +233,7 @@ TEST(pqf, Chirp_Short) {
233233

234234
ff_atrac3p_ipqf(&sctx, &subbands[0], &tmp[0]);
235235

236-
const static float err = 1.0 / (float)(1<<22);
236+
const static float err = 1.0 / (float)(1<<21);
237237

238238
for (int i = 368; i < 2048; i++) {
239239
EXPECT_NEAR(tmp[i], x[i - 368], err);
@@ -260,7 +260,7 @@ TEST(pqf, Chirp_Long) {
260260
ff_atrac3p_ipqf(&sctx, &subbands[0], &tmp[0]);
261261
ff_atrac3p_ipqf(&sctx, &subbands[2048], &tmp[2048]);
262262

263-
const static float err = 4096.0 / (float)(1<<22);
263+
const static float err = 1.0 / (float)(1<<21);
264264
for (int i = 368; i < 4096; i++) {
265265
EXPECT_NEAR(tmp[i], x[i-368], err);
266266
}

src/atrac/atrac_psy_common.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,6 @@
2121

2222
namespace NAtracDEnc {
2323

24-
double AnalizeScaleFactorSpread(const std::vector<TScaledBlock>& scaledBlocks);
24+
TFloat AnalizeScaleFactorSpread(const std::vector<TScaledBlock>& scaledBlocks);
2525

2626
} //namespace NAtracDEnc

src/atrac3denc.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -130,7 +130,7 @@ TAtrac3MDCT::TGainModulatorArray TAtrac3MDCT::MakeGainModulatorArray(const TAtra
130130

131131
TFloat TAtrac3Encoder::LimitRel(TFloat x)
132132
{
133-
return std::min(std::max(x, GainLevel[15]), GainLevel[0]);
133+
return std::min(std::max((double)x, GainLevel[15]), GainLevel[0]);
134134
}
135135

136136
void TAtrac3Encoder::ResetTransientParamsHistory(int channel, int band)

src/atracdenc_ut.cpp

+18-2
Original file line numberDiff line numberDiff line change
@@ -17,20 +17,36 @@
1717
*/
1818

1919
#include "atrac1denc.h"
20+
#include <lib/mdct/mdct_ut_common.h>
2021
#include <gtest/gtest.h>
2122

2223
#include <vector>
2324
using std::vector;
2425
using namespace NAtracDEnc;
2526

2627
void CheckResult128(const vector<TFloat>& a, const vector<TFloat>& b) {
28+
float m = 0.0;
29+
for (int i = 0; i < a.size(); i++) {
30+
m = fmax(m, (float)a[i]);
31+
}
32+
33+
auto eps = CalcEps(m);
34+
2735
for (int i = 0; i < 96; ++i ) {
28-
EXPECT_NEAR(a[i], 4 * b[i+32], 0.0000001);
36+
EXPECT_NEAR(a[i], 4 * b[i+32], eps);
2937
}
3038
}
39+
3140
void CheckResult256(const vector<TFloat>& a, const vector<TFloat>& b) {
41+
float m = 0.0;
42+
for (int i = 0; i < a.size(); i++) {
43+
m = fmax(m, (float)a[i]);
44+
}
45+
46+
auto eps = CalcEps(m);
47+
3248
for (int i = 0; i < 192; ++i ) {
33-
EXPECT_NEAR(a[i], 2 * b[i+32], 0.0000001);
49+
EXPECT_NEAR(a[i], 2 * b[i+32], eps);
3450
}
3551
}
3652

src/config.h

+4-7
Original file line numberDiff line numberDiff line change
@@ -18,21 +18,18 @@
1818

1919
#pragma once
2020

21-
#define CONFIG_DOUBLE
22-
2321
#ifndef NOMINMAX
2422
#define NOMINMAX
2523
#endif
2624

27-
#ifdef CONFIG_DOUBLE
28-
# define kiss_fft_scalar double
29-
typedef double TFloat;
30-
#else
25+
#ifdef ATDE_USE_FLOAT
3126
# define kiss_fft_scalar float
3227
typedef float TFloat;
28+
#else
29+
# define kiss_fft_scalar double
30+
typedef double TFloat;
3331
#endif
3432

35-
3633
#ifndef M_PI
3734
#define M_PI (3.14159265358979323846)
3835
#endif

src/lib/mdct/mdct_ut.cpp

+26-11
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
*/
1818

1919
#include "mdct.h"
20+
#include "mdct_ut_common.h"
2021
#include <gtest/gtest.h>
2122

2223
#include <vector>
@@ -35,7 +36,7 @@ static vector<TFloat> mdct(TFloat* x, int N) {
3536
res.push_back(sum);
3637
}
3738
return res;
38-
}
39+
}
3940

4041
static vector<TFloat> midct(TFloat* x, int N) {
4142
vector<TFloat> res;
@@ -59,8 +60,9 @@ TEST(TMdctTest, MDCT32) {
5960
const vector<TFloat> res1 = mdct(&src[0], N/2);
6061
const vector<TFloat> res2 = transform(&src[0]);
6162
EXPECT_EQ(res1.size(), res2.size());
63+
auto eps = CalcEps(N);
6264
for (int i = 0; i < res1.size(); i++) {
63-
EXPECT_NEAR(res1[i], res2[i], 0.0000000001);
65+
EXPECT_NEAR(res1[i], res2[i], eps);
6466
}
6567
}
6668

@@ -74,8 +76,9 @@ TEST(TMdctTest, MDCT64) {
7476
const vector<TFloat> res1 = mdct(&src[0], N/2);
7577
const vector<TFloat> res2 = transform(&src[0]);
7678
EXPECT_EQ(res1.size(), res2.size());
79+
auto eps = CalcEps(N);
7780
for (int i = 0; i < res1.size(); i++) {
78-
EXPECT_NEAR(res1[i], res2[i], 0.0000000001);
81+
EXPECT_NEAR(res1[i], res2[i], eps);
7982
}
8083
}
8184

@@ -89,8 +92,9 @@ TEST(TMdctTest, MDCT128) {
8992
const vector<TFloat> res1 = mdct(&src[0], N/2);
9093
const vector<TFloat> res2 = transform(&src[0]);
9194
EXPECT_EQ(res1.size(), res2.size());
95+
auto eps = CalcEps(N * 4);
9296
for (int i = 0; i < res1.size(); i++) {
93-
EXPECT_NEAR(res1[i], res2[i], 0.0000000001);
97+
EXPECT_NEAR(res1[i], res2[i], eps);
9498
}
9599
}
96100

@@ -104,23 +108,27 @@ TEST(TMdctTest, MDCT256) {
104108
const vector<TFloat> res1 = mdct(&src[0], N/2);
105109
const vector<TFloat> res2 = transform(&src[0]);
106110
EXPECT_EQ(res1.size(), res2.size());
111+
auto eps = CalcEps(N * 4);
107112
for (int i = 0; i < res1.size(); i++) {
108-
EXPECT_NEAR(res1[i], res2[i], 0.00000001);
113+
EXPECT_NEAR(res1[i], res2[i], eps);
109114
}
110115
}
111116

112117
TEST(TMdctTest, MDCT256_RAND) {
113118
const int N = 256;
114119
TMDCT<N> transform(N);
115120
vector<TFloat> src(N);
121+
TFloat m = 0.0;
116122
for (int i = 0; i < N; i++) {
117123
src[i] = rand();
124+
m = std::max(m, src[i]);
118125
}
119126
const vector<TFloat> res1 = mdct(&src[0], N/2);
120127
const vector<TFloat> res2 = transform(&src[0]);
121128
EXPECT_EQ(res1.size(), res2.size());
129+
auto eps = CalcEps(m * 8);
122130
for (int i = 0; i < res1.size(); i++) {
123-
EXPECT_NEAR(res1[i], res2[i], 0.01);
131+
EXPECT_NEAR(res1[i], res2[i], eps);
124132
}
125133
}
126134

@@ -134,8 +142,9 @@ TEST(TMdctTest, MIDCT32) {
134142
const vector<TFloat> res1 = midct(&src[0], N/2);
135143
const vector<TFloat> res2 = transform(&src[0]);
136144
EXPECT_EQ(res1.size(), res2.size());
145+
auto eps = CalcEps(N);
137146
for (int i = 0; i < N; i++) {
138-
EXPECT_NEAR(res1[i], res2[i], 0.0000000001);
147+
EXPECT_NEAR(res1[i], res2[i], eps);
139148
}
140149
}
141150

@@ -149,8 +158,9 @@ TEST(TMdctTest, MIDCT64) {
149158
const vector<TFloat> res1 = midct(&src[0], N/2);
150159
const vector<TFloat> res2 = transform(&src[0]);
151160
EXPECT_EQ(res1.size(), res2.size());
161+
auto eps = CalcEps(N);
152162
for (int i = 0; i < N; i++) {
153-
EXPECT_NEAR(res1[i], res2[i], 0.0000000001);
163+
EXPECT_NEAR(res1[i], res2[i], eps);
154164
}
155165
}
156166

@@ -164,8 +174,9 @@ TEST(TMdctTest, MIDCT128) {
164174
const vector<TFloat> res1 = midct(&src[0], N/2);
165175
const vector<TFloat> res2 = transform(&src[0]);
166176
EXPECT_EQ(res1.size(), res2.size());
177+
auto eps = CalcEps(N);
167178
for (int i = 0; i < N; i++) {
168-
EXPECT_NEAR(res1[i], res2[i], 0.0000000001);
179+
EXPECT_NEAR(res1[i], res2[i], eps);
169180
}
170181
}
171182

@@ -179,22 +190,26 @@ TEST(TMdctTest, MIDCT256) {
179190
const vector<TFloat> res1 = midct(&src[0], N/2);
180191
const vector<TFloat> res2 = transform(&src[0]);
181192
EXPECT_EQ(res1.size(), res2.size());
193+
auto eps = CalcEps(N * 2);
182194
for (int i = 0; i < N; i++) {
183-
EXPECT_NEAR(res1[i], res2[i], 0.000000001);
195+
EXPECT_NEAR(res1[i], res2[i], eps);
184196
}
185197
}
186198

187199
TEST(TMdctTest, MIDCT256_RAND) {
188200
const int N = 256;
189201
TMIDCT<N> transform(N);
190202
vector<TFloat> src(N);
203+
TFloat m = 0.0;
191204
for (int i = 0; i < N/2; i++) {
192205
src[i] = rand();
206+
m = std::max(m, src[i]);
193207
}
194208
const vector<TFloat> res1 = midct(&src[0], N/2);
195209
const vector<TFloat> res2 = transform(&src[0]);
196210
EXPECT_EQ(res1.size(), res2.size());
211+
auto eps = CalcEps(m * 4);
197212
for (int i = 0; i < N; i++) {
198-
EXPECT_NEAR(res1[i], res2[i], 0.01);
213+
EXPECT_NEAR(res1[i], res2[i], eps);
199214
}
200215
}

src/lib/mdct/mdct_ut_common.h

+28
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
/*
2+
* This file is part of AtracDEnc.
3+
*
4+
* AtracDEnc is free software; you can redistribute it and/or
5+
* modify it under the terms of the GNU Lesser General Public
6+
* License as published by the Free Software Foundation; either
7+
* version 2.1 of the License, or (at your option) any later version.
8+
*
9+
* AtracDEnc is distributed in the hope that it will be useful,
10+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
11+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12+
* Lesser General Public License for more details.
13+
*
14+
* You should have received a copy of the GNU Lesser General Public
15+
* License along with AtracDEnc; if not, write to the Free Software
16+
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
17+
*/
18+
19+
#pragma once
20+
21+
#include "mdct.h"
22+
23+
// Calculate value of error for given magnitude
24+
inline TFloat CalcEps(TFloat magn) {
25+
const float snr = (sizeof(TFloat) == 4) ? -114.0 : -240.0;
26+
return magn * pow(10, (snr / 20.0));
27+
}
28+

src/transient_detector.cpp

+5-5
Original file line numberDiff line numberDiff line change
@@ -51,18 +51,18 @@ void TTransientDetector::HPFilter(const TFloat* in, TFloat* out) {
5151
-3.36639e-17 * 2.0, -0.0438162 * 2.0, -1.54175e-17 * 2.0, 0.0931738 * 2.0,
5252
-5.52212e-17 * 2.0, -0.313819 * 2.0
5353
};
54-
memcpy(HPFBuffer.data() + PrevBufSz, in, BlockSz * sizeof(double));
55-
const double* inBuf = HPFBuffer.data();
54+
memcpy(HPFBuffer.data() + PrevBufSz, in, BlockSz * sizeof(TFloat));
55+
const TFloat* inBuf = HPFBuffer.data();
5656
for (size_t i = 0; i < BlockSz; ++i) {
57-
double s = inBuf[i + 10];
58-
double s2 = 0;
57+
TFloat s = inBuf[i + 10];
58+
TFloat s2 = 0;
5959
for (size_t j = 0; j < ((FIRLen - 1) / 2) - 1 ; j += 2) {
6060
s += fircoef[j] * (inBuf[i + j] + inBuf[i + FIRLen - j]);
6161
s2 += fircoef[j + 1] * (inBuf[i + j + 1] + inBuf[i + FIRLen - j - 1]);
6262
}
6363
out[i] = (s + s2)/2;
6464
}
65-
memcpy(HPFBuffer.data(), in + (BlockSz - PrevBufSz), PrevBufSz * sizeof(double));
65+
memcpy(HPFBuffer.data(), in + (BlockSz - PrevBufSz), PrevBufSz * sizeof(TFloat));
6666
}
6767

6868

test/CMakeLists.txt

+4
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,10 @@ CMAKE_MINIMUM_REQUIRED(VERSION 3.1)
33
set (CMAKE_CXX_STANDARD 11)
44
set (CMAKE_C_STANDARD 11)
55

6+
if (ATDE_USE_FLOAT)
7+
add_compile_definitions(ATDE_USE_FLOAT)
8+
endif()
9+
610
set(atracdenc_ut
711
${CMAKE_SOURCE_DIR}/src/lib/mdct/mdct_ut.cpp
812
${CMAKE_SOURCE_DIR}/src/lib/bitstream/bitstream_ut.cpp

0 commit comments

Comments
 (0)