-
Notifications
You must be signed in to change notification settings - Fork 2
/
spectrum.h
131 lines (105 loc) · 3.66 KB
/
spectrum.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
/*
* Copyright (C) 2019 - 2023 Judd Niemann - All Rights Reserved.
* You may use, distribute and modify this code under the
* terms of the GNU Lesser General Public License, version 2.1
*
* You should have received a copy of GNU Lesser General Public License v2.1
* with this file. If not, please refer to: https://github.com/jniemann66/ReSampler
*/
#ifndef SPECTRUM_H
#define SPECTRUM_H
#include <fftw3.h>
#include <vector>
#include "parameters.h"
namespace Sndspec {
static std::string replaceFileExt(const std::string &filename, const std::string &newExt);
static std::string getFilenameOnly(const std::string &path);
static std::string enforceTrailingSeparator(const std::string &directory);
class Spectrum
{
public:
Spectrum(int fft_size);
~Spectrum();
void exec();
double* getTdBuf() const;
const fftw_complex *getFdBuf() const;
void getMag(std::vector<double>& buf);
void getMagSquared(std::vector<double> &buf);
void getPhase(std::vector<double>& buf);
int getFFTSize() const;
int getSpectrumSize() const;
static void makeSpectrumFromFile(const Sndspec::Parameters ¶meters);
static int convertSpectrumSizeToFFTSize(int spectrum_size);
static int convertFFTSizeToSpectrumSize(int fft_size);
static int selectBestFFTSizeFromSpectrumSize(int spectrum_size);
static int selectBestFFTSize(int requested_size); // pick a good FFT size for FFTW (of the form 2^a * 3^b * 5^c * 7^d * [1|11|13] )
static bool convertToDb(std::vector<std::vector<double>> &s, bool fromMagSquared);
static bool convertToLinear(std::vector<std::vector<double>> &s, bool fromMagSquared);
private:
fftw_plan plan;
int fftSize;
int spectrumSize;
// C facing:
double* tdBuf; // time-domain buffer
fftw_complex* fdBuf; // frequency-domain buffer
};
std::string replaceFileExt(const std::string& filename, const std::string &newExt)
{
auto lastDot = filename.rfind('.', filename.length());
if(lastDot != std::string::npos) {
std::string _fn{filename};
_fn.replace(lastDot + 1, std::string::npos, newExt);
return _fn;
}
return filename + "." + newExt;
}
std::string getFilenameOnly(const std::string& path)
{
static const char universalPathSeparator{'/'};
auto lastSep = path.rfind(universalPathSeparator, path.length());
#ifdef _WIN32
static const char nativePathSeparator{'\\'};
auto lastNSep = path.rfind(nativePathSeparator, path.length());
if(lastNSep != std::string::npos) {
if(lastSep == std::string::npos) {
lastSep = lastNSep;
} else {
lastSep = std::max(lastSep, lastNSep);
}
}
#endif
if(lastSep == path.length() - 1) { // ends in separator; cannot be a file
return {};
} else if(lastSep == std::string::npos) { // no separator; path is already just a filename
return path;
}
return path.substr(lastSep + 1);
}
std::string enforceTrailingSeparator(const std::string& directory)
{
static const char universalPathSeparator{'/'};
auto lastSep = directory.rfind(universalPathSeparator, directory.length());
#ifdef _WIN32
static const char nativePathSeparator{'\\'};
auto lastNSep = directory.rfind(nativePathSeparator, directory.length());
if(lastNSep != std::string::npos) {
if(lastSep == std::string::npos) {
lastSep = lastNSep;
} else {
lastSep = std::max(lastSep, lastNSep);
}
}
#else
static const char nativePathSeparator{'/'};
#endif
if(lastSep == directory.length() - 1) { // ends in separator; good to go ...
return directory;
}
// need to append a separator, but what kind ?
if(nativePathSeparator != universalPathSeparator && directory.find(universalPathSeparator, directory.length()) != std::string::npos) {
return directory + universalPathSeparator;
}
return directory + nativePathSeparator;
}
} // namespace Sndspec
#endif // SPECTRUM_H