diff --git a/CMakeLists.txt b/CMakeLists.txt index b60106d..086a090 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -83,6 +83,11 @@ set(Aquila_HEADERS aquila/source/window/HammingWindow.h aquila/source/window/HannWindow.h aquila/source/window/RectangularWindow.h + aquila/source/window/WelchWindow.h + aquila/source/window/CosineWindow.h + aquila/source/window/NuttallWindow.h + aquila/source/window/BlackmanNuttallWindow.h + aquila/source/window/BlackmanHarrisWindow.h aquila/transform/Fft.h aquila/transform/Dft.h aquila/transform/AquilaFft.h @@ -117,6 +122,11 @@ set(Aquila_SOURCES aquila/source/window/GaussianWindow.cpp aquila/source/window/HammingWindow.cpp aquila/source/window/HannWindow.cpp + aquila/source/window/WelchWindow.cpp + aquila/source/window/CosineWindow.cpp + aquila/source/window/NuttallWindow.cpp + aquila/source/window/BlackmanNuttallWindow.cpp + aquila/source/window/BlackmanHarrisWindow.cpp aquila/transform/Dft.cpp aquila/transform/AquilaFft.cpp aquila/transform/OouraFft.cpp diff --git a/aquila/source.h b/aquila/source.h index fe39dc8..f648095 100644 --- a/aquila/source.h +++ b/aquila/source.h @@ -39,5 +39,10 @@ #include "source/window/HammingWindow.h" #include "source/window/HannWindow.h" #include "source/window/RectangularWindow.h" +#include "source/window/WelchWindow.h" +#include "source/window/BlackmanHarrisWindow.h" +#include "source/window/NuttallWindow.h" +#include "source/window/BlackmanNuttallWindow.h" +#include "source/window/CosineWindow.h" #endif // AQUILA_SOURCE_H diff --git a/aquila/source/window/BlackmanHarrisWindow.cpp b/aquila/source/window/BlackmanHarrisWindow.cpp new file mode 100644 index 0000000..7c39fd4 --- /dev/null +++ b/aquila/source/window/BlackmanHarrisWindow.cpp @@ -0,0 +1,41 @@ +/** + * @file BlackmanHarrisWindow.cpp + * + * Blackman-Harris window. + * + * This file is part of the Aquila DSP library. + * Aquila is free software, licensed under the MIT/X11 License. A copy of + * the license is provided with the library in the LICENSE file. + * + * @package Aquila + * @version 3.0.0-dev + * @author Zbigniew Siciarz + * @date 2007-2014 + * @license http://www.opensource.org/licenses/mit-license.php MIT + * @since 3.0.0 + */ + +#include "BlackmanHarrisWindow.h" +#include + +namespace Aquila +{ + /** + * Creates Blackman-Harris window of given size. + * + * @param size window length + */ + BlackmanHarrisWindow::BlackmanHarrisWindow(std::size_t size): + SignalSource() + { + m_data.reserve(size); + for (std::size_t n = 0; n < size; ++n) + { + m_data.push_back( + 0.35875 - 0.48829 * std::cos(2.0 * M_PI * n / double(size - 1)) + + 0.14128 * std::cos(4.0 * M_PI * n / double(size - 1)) - + 0.01168 * std::cos(6.0 * M_PI * n / double(size - 1)) + ); + } + } +} diff --git a/aquila/source/window/BlackmanHarrisWindow.h b/aquila/source/window/BlackmanHarrisWindow.h new file mode 100644 index 0000000..7a3ce5c --- /dev/null +++ b/aquila/source/window/BlackmanHarrisWindow.h @@ -0,0 +1,37 @@ +/** + * @file BlackmanHarrisWindow.h + * + * Blackman-Harris window. + * + * This file is part of the Aquila DSP library. + * Aquila is free software, licensed under the MIT/X11 License. A copy of + * the license is provided with the library in the LICENSE file. + * + * @package Aquila + * @version 3.0.0-dev + * @author Zbigniew Siciarz + * @date 2007-2014 + * @license http://www.opensource.org/licenses/mit-license.php MIT + * @since 3.0.0 + */ + +#ifndef BLACKMANHARRISWINDOW_H +#define BLACKMANHARRISWINDOW_H + +#include "../../global.h" +#include "../SignalSource.h" +#include + +namespace Aquila +{ + /** + * Nuttall window. + */ + class AQUILA_EXPORT BlackmanHarrisWindow : public SignalSource + { + public: + BlackmanHarrisWindow(std::size_t size); + }; +} + +#endif // BLACKMANHARRISWINDOW_H diff --git a/aquila/source/window/BlackmanNuttallWindow.cpp b/aquila/source/window/BlackmanNuttallWindow.cpp new file mode 100644 index 0000000..4fd5db9 --- /dev/null +++ b/aquila/source/window/BlackmanNuttallWindow.cpp @@ -0,0 +1,41 @@ +/** + * @file BlackmanNuttallWindow.cpp + * + * Blackman-Nuttall window. + * + * This file is part of the Aquila DSP library. + * Aquila is free software, licensed under the MIT/X11 License. A copy of + * the license is provided with the library in the LICENSE file. + * + * @package Aquila + * @version 3.0.0-dev + * @author Zbigniew Siciarz + * @date 2007-2014 + * @license http://www.opensource.org/licenses/mit-license.php MIT + * @since 3.0.0 + */ + +#include "BlackmanNuttallWindow.h" +#include + +namespace Aquila +{ + /** + * Creates Blackman-Nuttall window of given size. + * + * @param size window length + */ + BlackmanNuttallWindow::BlackmanNuttallWindow(std::size_t size): + SignalSource() + { + m_data.reserve(size); + for (std::size_t n = 0; n < size; ++n) + { + m_data.push_back( + 0.3635819 - 0.4891775 * std::cos(2.0 * M_PI * n / double(size - 1)) + + 0.1365995 * std::cos(4.0 * M_PI * n / double(size - 1)) - + 0.0106411 * std::cos(6.0 * M_PI * n / double(size - 1)) + ); + } + } +} diff --git a/aquila/source/window/BlackmanNuttallWindow.h b/aquila/source/window/BlackmanNuttallWindow.h new file mode 100644 index 0000000..5139258 --- /dev/null +++ b/aquila/source/window/BlackmanNuttallWindow.h @@ -0,0 +1,37 @@ +/** + * @file BlackmanNuttallWindow.h + * + * Blackman-Nuttall window. + * + * This file is part of the Aquila DSP library. + * Aquila is free software, licensed under the MIT/X11 License. A copy of + * the license is provided with the library in the LICENSE file. + * + * @package Aquila + * @version 3.0.0-dev + * @author Zbigniew Siciarz + * @date 2007-2014 + * @license http://www.opensource.org/licenses/mit-license.php MIT + * @since 3.0.0 + */ + +#ifndef BLACKMANNUTTALLWINDOW_H +#define BLACKMANNUTTALLWINDOW_H + +#include "../../global.h" +#include "../SignalSource.h" +#include + +namespace Aquila +{ + /** + * Nuttall window. + */ + class AQUILA_EXPORT BlackmanNuttallWindow : public SignalSource + { + public: + BlackmanNuttallWindow(std::size_t size); + }; +} + +#endif // BLACKMANNUTTALLWINDOW_H diff --git a/aquila/source/window/CosineWindow.cpp b/aquila/source/window/CosineWindow.cpp new file mode 100644 index 0000000..de2ddf5 --- /dev/null +++ b/aquila/source/window/CosineWindow.cpp @@ -0,0 +1,38 @@ +/** + * @file CosineWindow.cpp + * + * Cosine window. + * + * This file is part of the Aquila DSP library. + * Aquila is free software, licensed under the MIT/X11 License. A copy of + * the license is provided with the library in the LICENSE file. + * + * @package Aquila + * @version 3.0.0-dev + * @author Zbigniew Siciarz + * @date 2007-2014 + * @license http://www.opensource.org/licenses/mit-license.php MIT + * @since 3.0.0 + */ + +#include "CosineWindow.h" +#include + +namespace Aquila +{ + /** + * Creates Cosine window of given size. + * + * @param size window length + */ + CosineWindow::CosineWindow(std::size_t size): + SignalSource() + { + + const double lhalf = ((double)size - 1.0) / 2.0; // L / 2 + m_data.reserve(size); + for (std::size_t n = 0; n < size; ++n) { + m_data.push_back(std::sin(n * M_PI / double(size - 1))); + } + } +} diff --git a/aquila/source/window/CosineWindow.h b/aquila/source/window/CosineWindow.h new file mode 100644 index 0000000..8acd82f --- /dev/null +++ b/aquila/source/window/CosineWindow.h @@ -0,0 +1,37 @@ +/** + * @file CosineWindow.h + * + * Cosine window. + * + * This file is part of the Aquila DSP library. + * Aquila is free software, licensed under the MIT/X11 License. A copy of + * the license is provided with the library in the LICENSE file. + * + * @package Aquila + * @version 3.0.0-dev + * @author Zbigniew Siciarz + * @date 2007-2014 + * @license http://www.opensource.org/licenses/mit-license.php MIT + * @since 3.0.0 + */ + +#ifndef COSINEWINDOW_H +#define COSINEWINDOW_H + +#include "../../global.h" +#include "../SignalSource.h" +#include + +namespace Aquila +{ + /** + * Cosine window. + */ + class AQUILA_EXPORT CosineWindow : public SignalSource + { + public: + CosineWindow(std::size_t size); + }; +} + +#endif // COSINEWINDOW_H diff --git a/aquila/source/window/NuttallWindow.cpp b/aquila/source/window/NuttallWindow.cpp new file mode 100644 index 0000000..3bad40e --- /dev/null +++ b/aquila/source/window/NuttallWindow.cpp @@ -0,0 +1,41 @@ +/** + * @file NuttallWindow.cpp + * + * Nuttall window. + * + * This file is part of the Aquila DSP library. + * Aquila is free software, licensed under the MIT/X11 License. A copy of + * the license is provided with the library in the LICENSE file. + * + * @package Aquila + * @version 3.0.0-dev + * @author Zbigniew Siciarz + * @date 2007-2014 + * @license http://www.opensource.org/licenses/mit-license.php MIT + * @since 3.0.0 + */ + +#include "NuttallWindow.h" +#include + +namespace Aquila +{ + /** + * Creates Nuttall window of given size. + * + * @param size window length + */ + NuttallWindow::NuttallWindow(std::size_t size): + SignalSource() + { + m_data.reserve(size); + for (std::size_t n = 0; n < size; ++n) + { + m_data.push_back( + 0.355768 - 0.487396 * std::cos(2.0 * M_PI * n / double(size - 1)) + + 0.144232 * std::cos(4.0 * M_PI * n / double(size - 1)) - + 0.012604 * std::cos(6.0 * M_PI * n / double(size - 1)) + ); + } + } +} diff --git a/aquila/source/window/NuttallWindow.h b/aquila/source/window/NuttallWindow.h new file mode 100644 index 0000000..f5c2de3 --- /dev/null +++ b/aquila/source/window/NuttallWindow.h @@ -0,0 +1,37 @@ +/** + * @file NuttallWindow.h + * + * Nuttall window. + * + * This file is part of the Aquila DSP library. + * Aquila is free software, licensed under the MIT/X11 License. A copy of + * the license is provided with the library in the LICENSE file. + * + * @package Aquila + * @version 3.0.0-dev + * @author Zbigniew Siciarz + * @date 2007-2014 + * @license http://www.opensource.org/licenses/mit-license.php MIT + * @since 3.0.0 + */ + +#ifndef NUTTALWINDOW_H +#define NUTTALWINDOW_H + +#include "../../global.h" +#include "../SignalSource.h" +#include + +namespace Aquila +{ + /** + * Nuttall window. + */ + class AQUILA_EXPORT NuttallWindow : public SignalSource + { + public: + NuttallWindow(std::size_t size); + }; +} + +#endif // NUTTALWINDOW_H diff --git a/aquila/source/window/WelchWindow.cpp b/aquila/source/window/WelchWindow.cpp new file mode 100644 index 0000000..127bc37 --- /dev/null +++ b/aquila/source/window/WelchWindow.cpp @@ -0,0 +1,40 @@ +/** + * @file WelchWindow.cpp + * + * Welch window. + * + * This file is part of the Aquila DSP library. + * Aquila is free software, licensed under the MIT/X11 License. A copy of + * the license is provided with the library in the LICENSE file. + * + * @package Aquila + * @version 3.0.0-dev + * @author Zbigniew Siciarz + * @date 2007-2014 + * @license http://www.opensource.org/licenses/mit-license.php MIT + * @since 3.0.0 + */ + +#include "WelchWindow.h" +#include + +namespace Aquila +{ + /** + * Creates Welch window of given size. + * + * @param size window length + */ + WelchWindow::WelchWindow(std::size_t size): + SignalSource() + { + + const double lhalf = ((double)size - 1.0) / 2.0; // L / 2 + m_data.reserve(size); + for (std::size_t n = 0; n < size; ++n) + { + double v = ((double)n - lhalf) / lhalf; + m_data.push_back(1 - (v * v)); + } + } +} diff --git a/aquila/source/window/WelchWindow.h b/aquila/source/window/WelchWindow.h new file mode 100644 index 0000000..bf8eeda --- /dev/null +++ b/aquila/source/window/WelchWindow.h @@ -0,0 +1,37 @@ +/** + * @file WelchWindow.h + * + * Welch window. + * + * This file is part of the Aquila DSP library. + * Aquila is free software, licensed under the MIT/X11 License. A copy of + * the license is provided with the library in the LICENSE file. + * + * @package Aquila + * @version 3.0.0-dev + * @author Zbigniew Siciarz + * @date 2007-2014 + * @license http://www.opensource.org/licenses/mit-license.php MIT + * @since 3.0.0 + */ + +#ifndef WELCHWINDOW_H +#define WELCHWINDOW_H + +#include "../../global.h" +#include "../SignalSource.h" +#include + +namespace Aquila +{ + /** + * Welch window. + */ + class AQUILA_EXPORT WelchWindow : public SignalSource + { + public: + WelchWindow(std::size_t size); + }; +} + +#endif // WELCHWINDOW_H diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 2b8571a..caa7bf4 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -39,6 +39,11 @@ set(Aquila_Test_SOURCES source/window/HammingWindow.cpp source/window/HannWindow.cpp source/window/RectangularWindow.cpp + source/window/BlackmanHarrisWindow.cpp + source/window/BlackmanNuttallWindow.cpp + source/window/NuttallWindow.cpp + source/window/WelchWindow.cpp + source/window/CosineWindow.cpp tools/TextPlot.cpp transform/AquilaFft.cpp transform/Dft.cpp diff --git a/tests/source/window/BlackmanHarrisWindow.cpp b/tests/source/window/BlackmanHarrisWindow.cpp new file mode 100644 index 0000000..abac7c1 --- /dev/null +++ b/tests/source/window/BlackmanHarrisWindow.cpp @@ -0,0 +1,31 @@ +#include "aquila/global.h" +#include "aquila/source/window/BlackmanHarrisWindow.h" +#include "aquila/source/generator/SquareGenerator.h" +#include "UnitTest++/UnitTest++.h" +#include + +SUITE(BlackmanHarrisWindow) +{ + TEST(ZeroAtEnds) + { + const std::size_t SIZE = 4; + Aquila::BlackmanHarrisWindow w(SIZE); + // 0.00006 has been manually calculated using: + // 0.35875 - 0.48829 * cos(0) + 0.14128 * cos(0) - 0.01168 * cos(0) + CHECK_CLOSE(0.00006, w.sample(0), 0.000001); + CHECK_CLOSE(0.00006, w.sample(SIZE - 1), 0.000001); + } + + TEST(Multiplication) + { + const std::size_t SIZE = 1024; + Aquila::SquareGenerator generator(44100); + generator.setFrequency(1000).setAmplitude(500).generate(SIZE); + Aquila::BlackmanHarrisWindow w(SIZE); + auto result = generator * w; + // 0.03 = 0.00006 (see above) * 500 (amplitude) + CHECK_CLOSE(0.03, result.sample(0), 0.000001); + CHECK_CLOSE(0.03, result.sample(SIZE - 1), 0.000001); + } +} + diff --git a/tests/source/window/BlackmanNuttallWindow.cpp b/tests/source/window/BlackmanNuttallWindow.cpp new file mode 100644 index 0000000..54d1109 --- /dev/null +++ b/tests/source/window/BlackmanNuttallWindow.cpp @@ -0,0 +1,31 @@ +#include "aquila/global.h" +#include "aquila/source/window/BlackmanNuttallWindow.h" +#include "aquila/source/generator/SquareGenerator.h" +#include "UnitTest++/UnitTest++.h" +#include + +SUITE(BlackmanNuttallWindow) +{ + TEST(ZeroAtEnds) + { + const std::size_t SIZE = 4; + Aquila::BlackmanNuttallWindow w(SIZE); + // 0.0003628 has been manually calculated using: + // 0.3635819 - 0.4891775 * cos(0) + 0.1365995 * cos(0) - 0.0106411 * cos(0) + CHECK_CLOSE(0.0003628, w.sample(0), 0.000001); + CHECK_CLOSE(0.0003628, w.sample(SIZE - 1), 0.000001); + } + + TEST(Multiplication) + { + const std::size_t SIZE = 1024; + Aquila::SquareGenerator generator(44100); + generator.setFrequency(1000).setAmplitude(500).generate(SIZE); + Aquila::BlackmanNuttallWindow w(SIZE); + auto result = generator * w; + // 0.1814 = 0.0003628 (see above) * 500 (amplitude) + CHECK_CLOSE(0.1814, result.sample(0), 0.000001); + CHECK_CLOSE(0.1814, result.sample(SIZE - 1), 0.000001); + } +} + diff --git a/tests/source/window/CosineWindow.cpp b/tests/source/window/CosineWindow.cpp new file mode 100644 index 0000000..4f7dac6 --- /dev/null +++ b/tests/source/window/CosineWindow.cpp @@ -0,0 +1,29 @@ +#include "aquila/global.h" +#include "aquila/source/window/CosineWindow.h" +#include "aquila/source/generator/SquareGenerator.h" +#include "UnitTest++/UnitTest++.h" +#include + +SUITE(CosineWindow) +{ + TEST(ZeroAtEnds) + { + const std::size_t SIZE = 4; + Aquila::CosineWindow w(SIZE); + CHECK_CLOSE(0, w.sample(0), 0.000001); + CHECK_CLOSE(0, w.sample(SIZE - 1), 0.000001); + } + + TEST(Multiplication) + { + const std::size_t SIZE = 1024; + Aquila::SquareGenerator generator(44100); + generator.setFrequency(1000).setAmplitude(500).generate(SIZE); + Aquila::CosineWindow w(SIZE); + auto result = generator * w; + // 0.1814 = 0.0003628 (see above) * 500 (amplitude) + CHECK_CLOSE(0, result.sample(0), 0.000001); + CHECK_CLOSE(0, result.sample(SIZE - 1), 0.000001); + } +} + diff --git a/tests/source/window/NuttallWindow.cpp b/tests/source/window/NuttallWindow.cpp new file mode 100644 index 0000000..cb36d3c --- /dev/null +++ b/tests/source/window/NuttallWindow.cpp @@ -0,0 +1,28 @@ +#include "aquila/global.h" +#include "aquila/source/window/NuttallWindow.h" +#include "aquila/source/generator/SquareGenerator.h" +#include "UnitTest++/UnitTest++.h" +#include + +SUITE(NuttallWindow) +{ + TEST(ZeroAtEnds) + { + const std::size_t SIZE = 4; + Aquila::NuttallWindow w(SIZE); + CHECK_CLOSE(0, w.sample(0), 0.000001); + CHECK_CLOSE(0, w.sample(SIZE - 1), 0.000001); + } + + TEST(Multiplication) + { + const std::size_t SIZE = 1024; + Aquila::SquareGenerator generator(44100); + generator.setFrequency(1000).setAmplitude(500).generate(SIZE); + Aquila::NuttallWindow w(SIZE); + auto result = generator * w; + CHECK_CLOSE(0, result.sample(0), 0.000001); + CHECK_CLOSE(0, result.sample(SIZE - 1), 0.000001); + } +} + diff --git a/tests/source/window/WelchWindow.cpp b/tests/source/window/WelchWindow.cpp new file mode 100644 index 0000000..d4d41ec --- /dev/null +++ b/tests/source/window/WelchWindow.cpp @@ -0,0 +1,29 @@ +#include "aquila/global.h" +#include "aquila/source/window/WelchWindow.h" +#include "aquila/source/generator/SquareGenerator.h" +#include "UnitTest++/UnitTest++.h" +#include + +SUITE(WelchWindow) +{ + TEST(ZeroAtEnds) + { + const std::size_t SIZE = 4; + Aquila::WelchWindow w(SIZE); + CHECK_CLOSE(0, w.sample(0), 0.000001); + CHECK_CLOSE(0, w.sample(SIZE - 1), 0.000001); + } + + TEST(Multiplication) + { + const std::size_t SIZE = 1024; + Aquila::SquareGenerator generator(44100); + generator.setFrequency(1000).setAmplitude(500).generate(SIZE); + Aquila::WelchWindow w(SIZE); + auto result = generator * w; + // 0.1814 = 0.0003628 (see above) * 500 (amplitude) + CHECK_CLOSE(0, result.sample(0), 0.000001); + CHECK_CLOSE(0, result.sample(SIZE - 1), 0.000001); + } +} +