kopia lustrzana https://github.com/vsamy/DiFipp
rodzic
24df3ddedc
commit
5db13b6c0f
|
@ -63,8 +63,6 @@ if(MSVC)
|
||||||
set(CMAKE_MSVCIDE_RUN_PATH "\$(SolutionDir)/src/\$(Configuration)")
|
set(CMAKE_MSVCIDE_RUN_PATH "\$(SolutionDir)/src/\$(Configuration)")
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
add_compile_options("-D_USE_MATH_DEFINES")
|
|
||||||
|
|
||||||
# Eigen
|
# Eigen
|
||||||
set(Eigen_REQUIRED "eigen3 >= 3.3")
|
set(Eigen_REQUIRED "eigen3 >= 3.3")
|
||||||
search_for_eigen()
|
search_for_eigen()
|
||||||
|
|
|
@ -27,7 +27,6 @@
|
||||||
|
|
||||||
#include "DigitalFilter.h"
|
#include "DigitalFilter.h"
|
||||||
#include "typedefs.h"
|
#include "typedefs.h"
|
||||||
#include <cmath>
|
|
||||||
#include <complex>
|
#include <complex>
|
||||||
|
|
||||||
namespace difi {
|
namespace difi {
|
||||||
|
@ -44,9 +43,6 @@ namespace difi {
|
||||||
*/
|
*/
|
||||||
template <typename T>
|
template <typename T>
|
||||||
class Butterworth : public DigitalFilter<T> {
|
class Butterworth : public DigitalFilter<T> {
|
||||||
public:
|
|
||||||
static T PI; /*!< pi depending on the type T */
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
/*! \brief Type of butterworth filter0 */
|
/*! \brief Type of butterworth filter0 */
|
||||||
enum class Type {
|
enum class Type {
|
||||||
|
|
|
@ -28,9 +28,6 @@
|
||||||
|
|
||||||
namespace difi {
|
namespace difi {
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
T Butterworth<T>::PI = static_cast<T>(M_PI);
|
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
std::pair<int, T> Butterworth<T>::findMinimumButter(T wPass, T wStop, T APass, T AStop)
|
std::pair<int, T> Butterworth<T>::findMinimumButter(T wPass, T wStop, T APass, T AStop)
|
||||||
{
|
{
|
||||||
|
@ -38,8 +35,8 @@ std::pair<int, T> Butterworth<T>::findMinimumButter(T wPass, T wStop, T APass, T
|
||||||
Expects(wStop > T(0) && wPass < T(1));
|
Expects(wStop > T(0) && wPass < T(1));
|
||||||
T num = std::log10((std::pow(T(10), T(0.1) * std::abs(AStop)) - 1) / (std::pow(T(10), T(0.1) * std::abs(APass)) - 1));
|
T num = std::log10((std::pow(T(10), T(0.1) * std::abs(AStop)) - 1) / (std::pow(T(10), T(0.1) * std::abs(APass)) - 1));
|
||||||
// pre-warp
|
// pre-warp
|
||||||
T fwPass = std::tan(T(0.5) * PI * wPass);
|
T fwPass = std::tan(T(0.5) * pi<T> * wPass);
|
||||||
T fwStop = std::tan(T(0.5) * PI * wStop);
|
T fwStop = std::tan(T(0.5) * pi<T> * wStop);
|
||||||
T w;
|
T w;
|
||||||
if (wPass < wStop)
|
if (wPass < wStop)
|
||||||
w = std::abs(fwStop / fwPass);
|
w = std::abs(fwStop / fwPass);
|
||||||
|
@ -54,7 +51,7 @@ std::pair<int, T> Butterworth<T>::findMinimumButter(T wPass, T wStop, T APass, T
|
||||||
else
|
else
|
||||||
ctf = fwPass / ctf;
|
ctf = fwPass / ctf;
|
||||||
|
|
||||||
return std::pair<int, T>(order, T(2) * std::atan(ctf) / PI);
|
return std::pair<int, T>(order, T(2) * std::atan(ctf) / pi<T>);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
|
@ -111,7 +108,7 @@ template <typename T>
|
||||||
void Butterworth<T>::computeDigitalRep(T fc)
|
void Butterworth<T>::computeDigitalRep(T fc)
|
||||||
{
|
{
|
||||||
// Continuous pre-warped frequency
|
// Continuous pre-warped frequency
|
||||||
T fpw = (m_fs / PI) * std::tan(PI * fc / m_fs);
|
T fpw = (m_fs / pi<T>)*std::tan(pi<T> * fc / m_fs);
|
||||||
|
|
||||||
// Compute poles
|
// Compute poles
|
||||||
vectXc_t<T> poles(m_order);
|
vectXc_t<T> poles(m_order);
|
||||||
|
@ -138,8 +135,8 @@ void Butterworth<T>::computeDigitalRep(T fc)
|
||||||
template <typename T>
|
template <typename T>
|
||||||
void Butterworth<T>::computeBandDigitalRep(T fLower, T fUpper)
|
void Butterworth<T>::computeBandDigitalRep(T fLower, T fUpper)
|
||||||
{
|
{
|
||||||
T fpw1 = (m_fs / PI) * std::tan(PI * fLower / m_fs);
|
T fpw1 = (m_fs / pi<T>)*std::tan(pi<T> * fLower / m_fs);
|
||||||
T fpw2 = (m_fs / PI) * std::tan(PI * fUpper / m_fs);
|
T fpw2 = (m_fs / pi<T>)*std::tan(pi<T> * fUpper / m_fs);
|
||||||
T fpw0 = std::sqrt(fpw1 * fpw2);
|
T fpw0 = std::sqrt(fpw1 * fpw2);
|
||||||
|
|
||||||
vectXc_t<T> poles(2 * m_order);
|
vectXc_t<T> poles(2 * m_order);
|
||||||
|
@ -161,7 +158,7 @@ void Butterworth<T>::computeBandDigitalRep(T fLower, T fUpper)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (m_type == Type::BandPass)
|
if (m_type == Type::BandPass)
|
||||||
scaleAmplitude(aCoeff, bCoeff, std::exp(std::complex<T>(T(0), T(2) * PI * std::sqrt(fLower * fUpper) / m_fs)));
|
scaleAmplitude(aCoeff, bCoeff, std::exp(std::complex<T>(T(0), T(2) * pi<T> * std::sqrt(fLower * fUpper) / m_fs)));
|
||||||
else
|
else
|
||||||
scaleAmplitude(aCoeff, bCoeff);
|
scaleAmplitude(aCoeff, bCoeff);
|
||||||
|
|
||||||
|
@ -171,16 +168,16 @@ void Butterworth<T>::computeBandDigitalRep(T fLower, T fUpper)
|
||||||
template <typename T>
|
template <typename T>
|
||||||
std::complex<T> Butterworth<T>::generateAnalogPole(int k, T fpw1)
|
std::complex<T> Butterworth<T>::generateAnalogPole(int k, T fpw1)
|
||||||
{
|
{
|
||||||
auto thetaK = [pi = PI, order = m_order](int k) -> T {
|
auto thetaK = [pi = pi<T>, order = m_order](int k) -> T {
|
||||||
return (2 * k - 1) * pi / (2 * order);
|
return (2 * k - 1) * pi / (2 * order);
|
||||||
};
|
};
|
||||||
|
|
||||||
std::complex<T> analogPole(-std::sin(thetaK(k)), std::cos(thetaK(k)));
|
std::complex<T> analogPole(-std::sin(thetaK(k)), std::cos(thetaK(k)));
|
||||||
switch (m_type) {
|
switch (m_type) {
|
||||||
case Type::HighPass:
|
case Type::HighPass:
|
||||||
return T(2) * PI * fpw1 / analogPole;
|
return T(2) * pi<T> * fpw1 / analogPole;
|
||||||
case Type::LowPass:
|
case Type::LowPass:
|
||||||
return T(2) * PI * fpw1 * analogPole;
|
return T(2) * pi<T> * fpw1 * analogPole;
|
||||||
default:
|
default:
|
||||||
GSL_ASSUME(0);
|
GSL_ASSUME(0);
|
||||||
}
|
}
|
||||||
|
@ -189,13 +186,13 @@ std::complex<T> Butterworth<T>::generateAnalogPole(int k, T fpw1)
|
||||||
template <typename T>
|
template <typename T>
|
||||||
std::pair<std::complex<T>, std::complex<T>> Butterworth<T>::generateBandAnalogPole(int k, T fpw0, T bw)
|
std::pair<std::complex<T>, std::complex<T>> Butterworth<T>::generateBandAnalogPole(int k, T fpw0, T bw)
|
||||||
{
|
{
|
||||||
auto thetaK = [pi = PI, order = m_order](int k) -> T {
|
auto thetaK = [pi = pi<T>, order = m_order](int k) -> T {
|
||||||
return (2 * k - 1) * pi / (2 * order);
|
return (2 * k - 1) * pi / (2 * order);
|
||||||
};
|
};
|
||||||
|
|
||||||
std::complex<T> analogPole(-std::sin(thetaK(k)), std::cos(thetaK(k)));
|
std::complex<T> analogPole(-std::sin(thetaK(k)), std::cos(thetaK(k)));
|
||||||
std::pair<std::complex<T>, std::complex<T>> poles;
|
std::pair<std::complex<T>, std::complex<T>> poles;
|
||||||
std::complex<T> s0 = T(2) * PI * fpw0;
|
std::complex<T> s0 = T(2) * pi<T> * fpw0;
|
||||||
std::complex<T> s = T(0.5) * bw / fpw0;
|
std::complex<T> s = T(0.5) * bw / fpw0;
|
||||||
switch (m_type) {
|
switch (m_type) {
|
||||||
case Type::BandReject:
|
case Type::BandReject:
|
||||||
|
@ -222,7 +219,7 @@ vectXc_t<T> Butterworth<T>::generateAnalogZeros(T fpw0)
|
||||||
case Type::BandPass:
|
case Type::BandPass:
|
||||||
return (vectXc_t<T>(2 * m_order) << vectXc_t<T>::Constant(m_order, std::complex<T>(-1)), vectXc_t<T>::Constant(m_order, std::complex<T>(1))).finished();
|
return (vectXc_t<T>(2 * m_order) << vectXc_t<T>::Constant(m_order, std::complex<T>(-1)), vectXc_t<T>::Constant(m_order, std::complex<T>(1))).finished();
|
||||||
case Type::BandReject: {
|
case Type::BandReject: {
|
||||||
T w0 = T(2) * std::atan(PI * fpw0 / m_fs);
|
T w0 = T(2) * std::atan(pi<T> * fpw0 / m_fs);
|
||||||
return (vectXc_t<T>(2 * m_order) << vectXc_t<T>::Constant(m_order, std::exp(std::complex<T>(0, w0))), vectXc_t<T>::Constant(m_order, std::exp(std::complex<T>(0, -w0)))).finished();
|
return (vectXc_t<T>(2 * m_order) << vectXc_t<T>::Constant(m_order, std::exp(std::complex<T>(0, w0))), vectXc_t<T>::Constant(m_order, std::exp(std::complex<T>(0, -w0)))).finished();
|
||||||
}
|
}
|
||||||
case Type::LowPass:
|
case Type::LowPass:
|
||||||
|
|
|
@ -24,7 +24,6 @@
|
||||||
# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
set(HEADERS
|
set(HEADERS
|
||||||
gsl/gsl_assert.h
|
|
||||||
BilinearTransform.h
|
BilinearTransform.h
|
||||||
Butterworth.h
|
Butterworth.h
|
||||||
Butterworth.tpp
|
Butterworth.tpp
|
||||||
|
@ -38,10 +37,13 @@ set(HEADERS
|
||||||
typedefs.h
|
typedefs.h
|
||||||
)
|
)
|
||||||
|
|
||||||
|
set(GSL_HEADERS gsl/gsl_assert.h)
|
||||||
|
|
||||||
add_library(${PROJECT_NAME} INTERFACE)
|
add_library(${PROJECT_NAME} INTERFACE)
|
||||||
target_include_directories(${PROJECT_NAME} INTERFACE ${HEADERS})
|
target_include_directories(${PROJECT_NAME} INTERFACE ${HEADERS} ${GSL_HEADERS})
|
||||||
install(TARGETS ${PROJECT_NAME}
|
install(TARGETS ${PROJECT_NAME}
|
||||||
RUNTIME DESTINATION bin
|
RUNTIME DESTINATION bin
|
||||||
LIBRARY DESTINATION lib
|
LIBRARY DESTINATION lib
|
||||||
ARCHIVE DESTINATION lib)
|
ARCHIVE DESTINATION lib)
|
||||||
install(FILES ${HEADERS} DESTINATION ${INCLUDE_INSTALL_DESTINATION})
|
install(FILES ${HEADERS} DESTINATION ${INCLUDE_INSTALL_DESTINATION})
|
||||||
|
install(FILES ${GSL_HEADERS} DESTINATION ${INCLUDE_INSTALL_DESTINATION}/gsl)
|
|
@ -25,6 +25,7 @@
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include "gsl/gsl_assert.h"
|
||||||
#include "type_checks.h"
|
#include "type_checks.h"
|
||||||
#include "typedefs.h"
|
#include "typedefs.h"
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
|
|
|
@ -26,6 +26,7 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "DigitalFilter.h"
|
#include "DigitalFilter.h"
|
||||||
|
#include "gsl/gsl_assert.h"
|
||||||
#include "typedefs.h"
|
#include "typedefs.h"
|
||||||
|
|
||||||
namespace difi {
|
namespace difi {
|
||||||
|
|
|
@ -29,6 +29,9 @@
|
||||||
|
|
||||||
namespace difi {
|
namespace difi {
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
constexpr T pi = T(3.14159265358979323846264338327950288419716939937510582097494459230781L);
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
using vectX_t = Eigen::Matrix<T, Eigen::Dynamic, 1>; /*!< Eigen column-vector */
|
using vectX_t = Eigen::Matrix<T, Eigen::Dynamic, 1>; /*!< Eigen column-vector */
|
||||||
|
|
||||||
|
|
Ładowanie…
Reference in New Issue