diff --git a/src/FFT.hpp b/src/FFT.hpp index 3ee1615..51dba4a 100644 --- a/src/FFT.hpp +++ b/src/FFT.hpp @@ -49,7 +49,11 @@ std::vector> radix2dit(const std::vector::const_ite return output; } -std::vector> FFT(const std::vector::const_iterator& begin, const std::vector::const_iterator& end, size_t sampleRate) +std::vector> +FFT(const std::vector::const_iterator& begin, + const std::vector::const_iterator& end, + size_t sampleRate, + double minFreq, double maxFreq) { std::vector signal(begin, end); size_t N = signal.size(); @@ -65,8 +69,11 @@ std::vector> FFT(const std::vector::const_iter double nyquistLimit = (double)sampleRate / 2.0f; std::vector> output; - double freq = 0.0f; - for (int k = 0; freq < nyquistLimit; k++) + double freq = minFreq; + if (maxFreq == 0) + maxFreq = nyquistLimit; + + for (int k = freq / freqRes; freq < nyquistLimit && freq < maxFreq; k++) { output.push_back(std::make_pair(freq, 2.0f * std::abs(spectrum[k]) / (double)N)); freq += freqRes; diff --git a/src/main.cpp b/src/main.cpp index f2914f1..45ce2df 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -14,6 +14,7 @@ struct Settings { std::vector files; bool quiet; float splitInterval; + double minFreq, maxFreq; }; Settings Parse(int argc, char** argv); @@ -46,7 +47,12 @@ int main(int argc, char** argv) if (setts.splitInterval == 0.0f) { - std::vector> spectrum = FFT(audioFile.samples[c-1].cbegin(), audioFile.samples[c-1].cend(), sampleRate); + std::vector> spectrum = + FFT( + audioFile.samples[c-1].cbegin(), + audioFile.samples[c-1].cend(), + sampleRate, + setts.minFreq, setts.maxFreq); output[chName] = nlohmann::json::array(); for (const std::pair& pair : spectrum) { @@ -64,8 +70,10 @@ int main(int argc, char** argv) audioFile.samples[c-1].cbegin() + currentSample, std::min( audioFile.samples[c-1].cbegin() + currentSample + sampleInterval, - audioFile.samples[c-1].cend()), - sampleRate + audioFile.samples[c-1].cend() + ), + sampleRate, + setts.minFreq, setts.maxFreq ); output[chName].push_back({ @@ -102,10 +110,11 @@ Settings Parse(int argc, char** argv) cxxopts::Options options("spectralyze", "Fourier transforms audio files"); options .set_width(70) - .positional_help("file1 [file2...]") + .positional_help("FILE1 [FILE2...]") .add_options() ("q,quiet", "Suppress text output", cxxopts::value()->default_value("false")) ("i,interval", "Splits audio file into intervals of length i milliseconds and transforms them individually (0 to not split file)", cxxopts::value()) + ("f,frequency", "Defines the frequency range of the output spectrum (Default: all the frequencies)", cxxopts::value>()) ("files", "Files to fourier transform", cxxopts::value>()) ("h,help", "Print usage") ; @@ -119,6 +128,17 @@ Settings Parse(int argc, char** argv) exit(0); } + if (!result.count("frequency")) + { + setts.minFreq = 0.0f; + setts.maxFreq = 0.0f; + } + else + { + setts.minFreq = result["frequency"].as>()[0]; + setts.maxFreq = result["frequency"].as>()[1]; + } + if (!result.count("files")) { std::cerr << "At least one positional argument is required." << std::endl; @@ -128,6 +148,13 @@ Settings Parse(int argc, char** argv) setts.files = result["files"].as>(); setts.quiet = (result.count("quiet") ? result["quiet"].as() : false); setts.splitInterval = (result.count("interval") ? result["interval"].as() : 0.0f); + + + if (setts.maxFreq <= setts.minFreq && (setts.maxFreq != 0)) + { + std::cerr << "Maximum frequency cannot be smaller than minimum frequency" << std::endl; + exit(1); + } } catch (const cxxopts::OptionException& e) {