Skip to content

Commit 6a71b49

Browse files
committed
Add qdft #8
1 parent 08bb1ae commit 6a71b49

File tree

16 files changed

+198
-30
lines changed

16 files changed

+198
-30
lines changed

CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ include("${CMAKE_CURRENT_LIST_DIR}/lib/cpm.cmake")
1212
include("${CMAKE_CURRENT_LIST_DIR}/lib/juce.cmake")
1313
include("${CMAKE_CURRENT_LIST_DIR}/lib/juce_jingles.cmake")
1414
include("${CMAKE_CURRENT_LIST_DIR}/lib/samplerate.cmake")
15+
include("${CMAKE_CURRENT_LIST_DIR}/lib/qdft.cmake")
1516
include("${CMAKE_CURRENT_LIST_DIR}/lib/sdft.cmake")
1617
include("${CMAKE_CURRENT_LIST_DIR}/lib/pluginval.cmake")
1718

lib/qdft.cmake

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
# https://github.com/jurihock/qdft
2+
3+
CPMAddPackage(
4+
NAME qdft
5+
VERSION main
6+
GIT_TAG main
7+
GITHUB_REPOSITORY jurihock/qdft
8+
DOWNLOAD_ONLY YES)
9+
10+
if(qdft_ADDED)
11+
12+
add_library(qdft INTERFACE)
13+
14+
target_include_directories(qdft
15+
INTERFACE "${qdft_SOURCE_DIR}/cpp/src")
16+
17+
endif()

src/Robocode/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ target_sources(${PROJECT_NAME}
2020
target_link_libraries(${PROJECT_NAME}
2121
PUBLIC
2222
samplerate
23+
qdft
2324
sdft)
2425

2526
target_link_libraries(${PROJECT_NAME}

src/Robocode/Channel.cpp

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,6 @@
11
#include <Robocode/Channel.h>
22

3-
Channel::Channel()
4-
{
5-
}
6-
7-
Channel::Channel(const size_t index, const double samplerate, const std::vector<double>& frequencies, const double concertpitch)
3+
Channel::Channel(const size_t index, const double samplerate, const std::span<const double> frequencies, const double concertpitch)
84
{
95
const size_t dftsize = frequencies.size();
106

@@ -25,7 +21,7 @@ Channel::Channel(const size_t index, const double samplerate, const std::vector<
2521

2622
for (size_t i = 0; i < dftsize; ++i)
2723
{
28-
config.chnfreqs[i] = (frequencies[i] / samplerate) * hz;
24+
config.chnfreqs[i] = hz * frequencies[i];
2925
}
3026
}
3127

src/Robocode/Channel.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,8 @@ class Channel final
77

88
public:
99

10-
Channel();
11-
Channel(const size_t index, const double samplerate, const std::vector<double>& frequencies, const double concertpitch);
10+
Channel(){}
11+
Channel(const size_t index, const double samplerate, const std::span<const double> frequencies, const double concertpitch);
1212
Channel(const Channel& other);
1313
Channel& operator=(const Channel& other);
1414

src/Robocode/Channels.cpp

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
#include <Robocode/Channels.h>
22

3-
Channels::Channels(const double samplerate, const std::vector<double>& frequencies, const double concertpitch) :
4-
frequencies(frequencies)
3+
Channels::Channels(const double samplerate, const std::span<const double> frequencies, const double concertpitch)
54
{
65
for (size_t i = 0; i < channels.size(); ++i)
76
{
@@ -13,11 +12,10 @@ Channels::Channels(const double samplerate, const std::vector<double>& frequenci
1312

1413
void Channels::synthesize(const std::span<const std::complex<double>> dftanal,
1514
const std::span<std::complex<double>> dftsynth,
15+
const std::span<const double> dftfreqs,
1616
const std::span<const double> pvcfreqs,
1717
const int gestalt)
1818
{
19-
const std::span<const double> dftfreqs(frequencies.data(), frequencies.size());
20-
2119
double sum = 0;
2220

2321
for (size_t channel : mask)

src/Robocode/Channels.h

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,19 +8,18 @@ class Channels final
88

99
public:
1010

11-
Channels(const double samplerate, const std::vector<double>& frequencies, const double concertpitch);
11+
Channels(const double samplerate, const std::span<const double> frequencies, const double concertpitch);
1212

1313
void synthesize(const std::span<const std::complex<double>> dftanal,
1414
const std::span<std::complex<double>> dftsynth,
15+
const std::span<const double> dftfreqs,
1516
const std::span<const double> pvcfreqs,
1617
const int gestalt);
1718

1819
void update(const int channel, const double gain);
1920

2021
private:
2122

22-
const std::vector<double> frequencies;
23-
2423
std::array<Channel, 128> channels;
2524
std::vector<size_t> mask;
2625

src/Robocode/DFT.h

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
#pragma once
2+
3+
#include <Robocode/Header.h>
4+
5+
class DFT
6+
{
7+
8+
public:
9+
10+
virtual ~DFT() = default;
11+
12+
virtual size_t size() const = 0;
13+
virtual double samplerate() const = 0;
14+
virtual std::span<const double> frequencies(const bool normalize = false) const = 0;
15+
16+
virtual float transform(const float x, const std::function<void(
17+
const std::span<const std::complex<double>> dftanal,
18+
const std::span<std::complex<double>> dftsynth,
19+
const std::span<const double> dftfreqs)> callback) = 0;
20+
21+
};

src/Robocode/QDFT.cpp

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
#include <Robocode/QDFT.h>
2+
3+
auto bw1 = std::pow(2, (double(021) - 69) / 12) * 440; // A0 ~ 27.5 Hz
4+
auto bw2 = std::pow(2, (double(108) - 69) / 12) * 440; // C8 ~ 4186 Hz
5+
auto bw = std::make_pair(bw1, bw2);
6+
7+
QDFT::QDFT(const double samplerate) :
8+
qdft::QDFT<float, double>(samplerate, bw),
9+
input(size()),
10+
output(size())
11+
{
12+
assert_true(size() > 0, "Invalid DFT size!");
13+
14+
const auto resolution = qdft::QDFT<float, double>::resolution();
15+
16+
factors.resize(size());
17+
18+
for (size_t i = 0; i < factors.size(); ++i)
19+
{
20+
factors[i] = std::pow(2.0, i / resolution);
21+
}
22+
}
23+
24+
size_t QDFT::size() const
25+
{
26+
return qdft::QDFT<float, double>::size();
27+
}
28+
29+
double QDFT::samplerate() const
30+
{
31+
return qdft::QDFT<float, double>::samplerate();
32+
}
33+
34+
std::span<const double> QDFT::frequencies(const bool normalize) const
35+
{
36+
if (normalize)
37+
{
38+
return factors;
39+
}
40+
41+
return qdft::QDFT<float, double>::frequencies();
42+
}
43+
44+
float QDFT::transform(const float x, const std::function<void(
45+
const std::span<const std::complex<double>> dftanal,
46+
const std::span<std::complex<double>> dftsynth,
47+
const std::span<const double> dftfreqs)> callback)
48+
{
49+
qdft(x, input.data());
50+
51+
std::fill(output.begin(), output.end(), std::complex<double>(0));
52+
callback(input, output, frequencies());
53+
output[0] = output[output.size() - 1] = 0;
54+
55+
float y = iqdft(output.data());
56+
y = std::clamp<float>(y, -1, +1);
57+
58+
return y;
59+
}

src/Robocode/QDFT.h

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
#pragma once
2+
3+
#include <Robocode/Header.h>
4+
#include <Robocode/DFT.h>
5+
6+
#include <qdft/qdft.h>
7+
8+
class QDFT final : public DFT, private qdft::QDFT<float, double>
9+
{
10+
11+
public:
12+
13+
QDFT(const double samplerate);
14+
~QDFT() = default;
15+
16+
size_t size() const override;
17+
double samplerate() const override;
18+
std::span<const double> frequencies(const bool normalize = false) const override;
19+
20+
float transform(const float x, const std::function<void(
21+
const std::span<const std::complex<double>> dftanal,
22+
const std::span<std::complex<double>> dftsynth,
23+
const std::span<const double> dftfreqs)> callback) override;
24+
25+
private:
26+
27+
std::vector<double> factors;
28+
29+
std::vector<std::complex<double>> input;
30+
std::vector<std::complex<double>> output;
31+
32+
};

0 commit comments

Comments
 (0)