예제 #1
0
void AnalogLowPass::design (int numPoles,
                            WorkspaceBase* w)
{
  if (m_numPoles != numPoles)
  {
    m_numPoles = numPoles;

    reset ();

    RootFinderBase& solver (w->roots);
    for (int i = 0; i < numPoles + 1; ++i)
      solver.coef()[i] = reversebessel (i, numPoles);
    solver.solve (numPoles);

    const int pairs = numPoles / 2;
    for (int i = 0; i < pairs; ++i)
    {
      complex_t c = solver.root()[i];
      addPoleZeroConjugatePairs (c, infinity());
    }

    if (numPoles & 1)
      add (solver.root()[pairs].real(), infinity());
  }
}
예제 #2
0
void AnalogLowShelf::design (int numPoles, double gainDb)
{
  if (m_numPoles != numPoles ||
      m_gainDb != gainDb)
  {
    m_numPoles = numPoles;
    m_gainDb = gainDb;

    reset ();

    const double n2 = numPoles * 2;
    const double g = pow (pow (10., gainDb/20), 1. / n2);
    const double gp = -1. / g;
    const double gz = -g;

    const int pairs = numPoles / 2;
    for (int i = 1; i <= pairs; ++i)
    {
      const double theta = doublePi * (0.5 - (2 * i - 1) / n2);
      addPoleZeroConjugatePairs (std::polar (std::abs(gp), theta), std::polar (std::abs(gz), theta));
    }
    
    if (numPoles & 1)
      add (gp, gz);
  }
}
예제 #3
0
void AnalogLowPass::design (int numPoles,
                            double stopBandDb)
{
  if (m_numPoles != numPoles ||
      m_stopBandDb != stopBandDb)
  {
    m_numPoles = numPoles;
    m_stopBandDb = stopBandDb;

    reset ();

    const double eps = std::sqrt (1. / (std::exp (stopBandDb * 0.1 * doubleLn10) - 1));
    const double v0 = asinh (1 / eps) / numPoles;
    const double sinh_v0 = -sinh (v0);
    const double cosh_v0 = cosh (v0);
    const double fn = doublePi / (2 * numPoles);

    int k = 1;
    for (int i = numPoles / 2; --i >= 0; k+=2)
    {
      const double a = sinh_v0 * cos ((k - numPoles) * fn);
      const double b = cosh_v0 * sin ((k - numPoles) * fn);
      const double d2 = a * a + b * b;
      const double im = 1 / cos (k * fn);
      addPoleZeroConjugatePairs (complex_t (a / d2, b / d2),
                                       complex_t (0, im));
    }

    if (numPoles & 1)
    {
      add (1 / sinh_v0, infinity());
    }
  }
}
예제 #4
0
void AnalogLowShelf::design (int numPoles,
                             double gainDb,
                             double stopBandDb)
{
  if (m_numPoles != numPoles ||
      m_stopBandDb != stopBandDb ||
      m_gainDb != gainDb)
  {
    m_numPoles = numPoles;
    m_stopBandDb = stopBandDb;
    m_gainDb = gainDb;

    reset ();

    gainDb = -gainDb;

    if (stopBandDb >= fabs(gainDb))
      stopBandDb = fabs (gainDb);
    if (gainDb<0)
      stopBandDb = -stopBandDb;

    const double G  = std::pow (10., gainDb / 20.0 );
    const double Gb = std::pow (10., (gainDb - stopBandDb) / 20.0);
    const double G0 = 1;
    const double g0 = pow (G0 , 1. / numPoles);

    double eps;
    if (Gb != G0 )
      eps = sqrt((G*G-Gb*Gb)/(Gb*Gb-G0*G0));
    else
      eps = G-1; // This is surely wrong

    const double b = pow (G/eps+Gb*sqrt(1+1/(eps*eps)), 1./numPoles);
    const double u = log (b / g0);
    const double v = log (pow (1. / eps+sqrt(1+1/(eps*eps)),1./numPoles));
    
    const double sinh_u = sinh (u);
    const double sinh_v = sinh (v);
    const double cosh_u = cosh (u);
    const double cosh_v = cosh (v);
    const double n2 = 2 * numPoles;
    const int pairs = numPoles / 2;
    for (int i = 1; i <= pairs; ++i)
    {
      const double a = doublePi * (2 * i - 1) / n2;
      const double sn = sin (a);
      const double cs = cos (a);
      addPoleZeroConjugatePairs (complex_t (-sn * sinh_u, cs * cosh_u),
                                       complex_t (-sn * sinh_v, cs * cosh_v));
    }

    if (numPoles & 1)
      add (-sinh_u, -sinh_v);
  }
}
예제 #5
0
void AnalogLowPass::design (int numPoles,
                            WorkspaceBase* w)
{
  if (m_numPoles != numPoles)
  {
    m_numPoles = numPoles;

    reset ();

    PolynomialFinderBase& poly (w->poly);
    RootFinderBase& poles (w->roots);

    poly.solve (numPoles);
    int degree = numPoles * 2;

    poles.coef()[0] = 1 + poly.coef()[0];
    poles.coef()[1] = 0;
    for (int i = 1; i <= degree; ++i)
    {
      poles.coef()[2*i] = poly.coef()[i] * ((i & 1) ? -1 : 1);
      poles.coef()[2*i+1] = 0;
    }
    poles.solve (degree);

    int j = 0;
    for (int i = 0; i < degree; ++i)
      if (poles.root()[i].real() <= 0)
        poles.root()[j++] = poles.root()[i];
    // sort descending imag() and cut degree in half
    poles.sort (degree/2);

    const int pairs = numPoles / 2;
    for (int i = 0; i < pairs; ++i)
    {
      complex_t c = poles.root()[i];
      addPoleZeroConjugatePairs (c, infinity());
    }

    if (numPoles & 1)
      add (poles.root()[pairs].real(), infinity());
  }
}
예제 #6
0
void AnalogLowPass::design (int numPoles)
{
  if (m_numPoles != numPoles)
  {
    m_numPoles = numPoles;

    reset ();

    const double n2 = 2 * numPoles;
    const int pairs = numPoles / 2;
    for (int i = 0; i < pairs; ++i)
    {
      complex_t c = std::polar (1., doublePi_2 + (2 * i + 1) * doublePi / n2);
      addPoleZeroConjugatePairs (c, infinity());
    }

    if (numPoles & 1)
      add (-1, infinity());
  }
}
예제 #7
0
파일: ChebyshevI.cpp 프로젝트: AGenews/GUI
void AnalogLowPass::design(int numPoles,
                           double rippleDb)
{
    if (m_numPoles != numPoles ||
        m_rippleDb != rippleDb)
    {
        m_numPoles = numPoles;
        m_rippleDb = rippleDb;

        reset();

        const double eps = std::sqrt(1. / std::exp(-rippleDb * 0.1 * doubleLn10) - 1);
        const double v0 = asinh(1 / eps) / numPoles;
        const double sinh_v0 = -sinh(v0);
        const double cosh_v0 = cosh(v0);

        const double n2 = 2 * numPoles;
        const int pairs = numPoles / 2;
        for (int i = 0; i < pairs; ++i)
        {
            const int k = 2 * i + 1 - numPoles;
            double a = sinh_v0 * cos(k * doublePi / n2);
            double b = cosh_v0 * sin(k * doublePi / n2);

            //addPoleZero (complex_t (a, b), infinity());
            //addPoleZero (complex_t (a, -b), infinity());
            addPoleZeroConjugatePairs(complex_t (a, b), infinity());
        }

        if (numPoles & 1)
        {
            add(complex_t (sinh_v0, 0), infinity());
            setNormal(0, 1);
        }
        else
        {
            setNormal(0, pow(10, -rippleDb/20.));
        }
    }
}
예제 #8
0
void AnalogLowShelf::design (int numPoles,
                             double gainDb,
                             WorkspaceBase* w)
{
  if (m_numPoles != numPoles ||
      m_gainDb != gainDb)
  {
    m_numPoles = numPoles;
    m_gainDb = gainDb;

    reset ();

    const double G = pow (10., gainDb / 20) - 1;

    RootFinderBase& poles (w->roots);
    for (int i = 0; i < numPoles + 1; ++i)
      poles.coef()[i] = reversebessel (i, numPoles);
    poles.solve (numPoles);

    RootFinder<50> zeros;
    for (int i = 0; i < numPoles + 1; ++i)
      zeros.coef()[i] = reversebessel (i, numPoles);
    double a0 = reversebessel (0, numPoles);
    zeros.coef()[0] += G * a0;
    zeros.solve (numPoles);

    const int pairs = numPoles / 2;
    for (int i = 0; i < pairs; ++i)
    {
      complex_t p = poles.root()[i];
      complex_t z = zeros.root()[i];
      addPoleZeroConjugatePairs (p, z);
    }

    if (numPoles & 1)
      add (poles.root()[pairs].real(), zeros.root()[pairs].real());
  }
}