added window functions

This commit is contained in:
Robert 2021-04-29 14:00:53 +02:00
parent 0dc3cadc52
commit ef770e3bb4
5 changed files with 166 additions and 88 deletions

View file

@ -1,6 +1,7 @@
#include <iostream>
#include <fstream>
#include <iomanip>
#include <map>
#include <filesystem>
#include "AudioFile.h"
@ -10,6 +11,12 @@
#define PRINTER(s, x) if(!s.quiet) { std::cout << x; }
const std::map<std::string, WindowFunctions> FUNCTIONS {
{"rectangle", WindowFunctions::RECTANGLE},
{"von-hann", WindowFunctions::VON_HANN},
{"gauss", WindowFunctions::GAUSS}
};
struct Settings {
std::vector<std::filesystem::path> files;
bool quiet;
@ -17,6 +24,7 @@ struct Settings {
double minFreq, maxFreq;
unsigned int analyzeChannel;
unsigned int zeropadding;
WindowFunctions window;
};
Settings Parse(int argc, char** argv);
@ -61,7 +69,8 @@ int main(int argc, char** argv)
audioFile.samples[c-1].cend(),
sampleRate,
setts.minFreq, setts.maxFreq,
setts.zeropadding
setts.zeropadding,
setts.window, audioFile.samples[c-1].size(), 0
);
output[chName] = nlohmann::json::array();
@ -77,14 +86,15 @@ int main(int argc, char** argv)
{
std::vector<std::pair<double, double>> spectrum =
FFT(
audioFile.samples[c-1].cbegin() + currentSample,
audioFile.samples[c - 1].cbegin() + currentSample,
std::min(
audioFile.samples[c-1].cbegin() + currentSample + sampleInterval,
audioFile.samples[c-1].cend()
),
audioFile.samples[c - 1].cbegin() + currentSample + sampleInterval,
audioFile.samples[c - 1].cend()
),
sampleRate,
setts.minFreq, setts.maxFreq,
setts.zeropadding
setts.zeropadding,
setts.window, sampleInterval, 0
);
output[chName].push_back({
@ -127,6 +137,7 @@ Settings Parse(int argc, char** argv)
("i,interval", "Splits audio file into intervals of length i milliseconds and transforms them individually (0 to not split file)", cxxopts::value<float>())
("f,frequency", "Defines the frequency range of the output spectrum (Default: all the frequencies)", cxxopts::value<std::vector<double>>())
("p,pad", "Add extra zero-padding. By default, the program will pad the signals with 0s until the number of samples is a power of 2 (this would be equivalent to -p 1). With this option you can tell the program to instead pad until the power of 2 after the next one (-p 2) etc. This increases frequency resolution", cxxopts::value<unsigned int>())
("w,window", "Specify the window function used (rectangle (default), von-hann, gauss)", cxxopts::value<std::string>()->default_value("rectangle"))
("m,mono", "Analyze only the given channel", cxxopts::value<unsigned int>()->default_value("0"))
("files", "Files to fourier transform", cxxopts::value<std::vector<std::filesystem::path>>())
("h,help", "Print usage")
@ -163,6 +174,26 @@ Settings Parse(int argc, char** argv)
setts.splitInterval = (result.count("interval") ? result["interval"].as<float>() : 0.0f);
setts.analyzeChannel = (result.count("mono") ? result["mono"].as<unsigned int>() : 0);
setts.zeropadding = (result.count("pad") ? result["pad"].as<unsigned int>() : 1);
if (!result.count("window"))
{
setts.window = WindowFunctions::RECTANGLE;
}
else
{
std::string data = result["window"].as<std::string>();
std::transform(data.begin(), data.end(), data.begin(), [](unsigned char c) { return std::tolower(c); });
auto it = FUNCTIONS.find(data);
if (it == FUNCTIONS.end())
{
setts.window = WindowFunctions::RECTANGLE;
}
else
{
setts.window = it->second;
}
}
if (setts.maxFreq <= setts.minFreq && (setts.maxFreq != 0))