<commit_before>/*
 * Copyright 2015 C. <NAME>
 */

#ifndef OSCILLATOR_HPP_
#define OSCILLATOR_HPP_

#include <complex>

namespace comm {

template<class T>
class oscillator
{
public:
  using sample_type = T;

  oscillator(double frequency, double sample_rate, double amplitude=1)
    : m_freq(frequency),
      m_rate(sample_rate),
      m_ampl(amplitude)
  {
    static_assert(std::is_floating_point<sample_type>::value,
                  "Sample type must be a floating point type");

    m_y1 = 0;
    m_y2 = -m_ampl * sin(2 * M_PI * m_freq / m_rate);
    m_2cos_omega  = 2 * cos(2 * M_PI * m_freq / m_rate);
  }

  template<size_t N>
  void operator()(std::array<sample_type, N> &output)
  {
    for (auto &y0 : output)
    {
      y0 = m_2cos_omega * m_y1 - m_y2;
      m_y2 = m_y1;
      m_y1 = y0;
    }
  }

  double frequency() { return m_freq; }

  double sample_rate() { return m_rate; }

  double amplitude() { return m_ampl; }

private:
  double m_freq;
  double m_rate;
  double m_ampl;

  double m_y1;
  double m_y2;
  double m_2cos_omega;
};

template<>
template<class T>
class oscillator<std::complex<T>>
{
public:
  using sample_type = std::complex<T>;

  oscillator(double frequency, double sample_rate, double amplitude = 1)
    : m_freq(frequency),
      m_rate(sample_rate),
      m_ampl(amplitude)
  {
    static_assert(std::is_floating_point<T>::value,
                  "Sample type must be a floating point type");

    m_cos_omega = cos(2 * M_PI * m_freq / m_rate);
    m_sin_omega = sin(2 * M_PI * m_freq / m_rate);
    m_cos1 = m_ampl * m_cos_omega;
    m_sin1 = -m_ampl * m_sin_omega;
  }

  template<size_t N>
  void operator()(std::array<sample_type, N> &output)
  {
    T cos0;
    T sin0;

    for (auto &out : output)
    {
      cos0 = m_cos_omega * m_cos1 - m_sin_omega * m_sin1;
      sin0 = m_sin_omega * m_cos1 + m_cos_omega * m_sin1;
      m_cos1 = cos0;
      m_sin1 = sin0;
      out = std::complex<T>(cos0, sin0);
    }
  }

  double frequency() { return m_freq; }

  double sample_rate() { return m_rate; }

  double amplitude() { return m_ampl; }

private:
  double m_freq;
  double m_rate;
  double m_ampl;

  double m_cos1;
  double m_sin1;
  double m_cos_omega;
  double m_sin_omega;
};

} /* namespace comm */<commit_msg>oscillator: refactor<commit_after>/*
 * Copyright 2015 <NAME>
 */

#ifndef OSCILLATOR_HPP_
#define OSCILLATOR_HPP_

#include <complex>

namespace comm
{
/**
 *
 */
template<typename T>
class oscillator
{
public:
  using sample_type = T;

  oscillator(T frequency, T sample_rate, T amplitude = 1);

  template<typename U> void operator()(U& output);

  T frequency() { return m_freq; }

  T sample_rate() { return m_rate; }

  T amplitude() { return m_ampl; }

private:
  T m_freq;
  T m_rate;
  T m_ampl;
  T m_out1;
  T m_out2;
  T m_2cos_omega;
};

///////////////////////////////////////////////////////////////////////////////

template<typename T>
oscillator<T>::oscillator(T frequency, T sample_rate, T amplitude)
  : m_freq(frequency),
    m_rate(sample_rate),
    m_ampl(amplitude)
{
  static_assert(std::is_floating_point<sample_type>::value,
    "Sample type must be a floating point type");

  m_out1 = 0;
  m_out2 = -m_ampl * sin(2 * M_PI * m_freq / m_rate);
  m_2cos_omega  = 2 * cos(2 * M_PI * m_freq / m_rate);
}

template<typename T>
template<typename U>
void oscillator<T>::operator()(U& output)
{
  for (auto &out0 : output)
  {
    out0 = m_2cos_omega * m_out1 - m_out2;
    m_out2 = m_out1;
    m_out1 = out0;
  }
}

///////////////////////////////////////////////////////////////////////////////

/**
 *
 */
template<typename T>
class oscillator<std::complex<T>>
{
public:
  using sample_type = std::complex<T>;

  oscillator(T frequency, T sample_rate, T amplitude = 1);

  template<typename U> void operator()(U& output);

  T frequency() { return m_freq; }

  T sample_rate() { return m_rate; }

  T amplitude() { return m_ampl; }

private:
  T m_freq;
  T m_rate;
  T m_ampl;
  T m_cos1;
  T m_sin1;
  T m_cos_omega;
  T m_sin_omega;
};

///////////////////////////////////////////////////////////////////////////////

template<typename T>
oscillator<std::complex<T>>::oscillator(T frequency, T sample_rate, T amplitude)
  : m_freq(frequency),
    m_rate(sample_rate),
    m_ampl(amplitude)
{
  static_assert(std::is_floating_point<T>::value,
    "Sample type must be a floating point type");

  m_cos_omega = cos(2 * M_PI * m_freq / m_rate);
  m_sin_omega = sin(2 * M_PI * m_freq / m_rate);
  m_cos1 = m_ampl * m_cos_omega;
  m_sin1 = -m_ampl * m_sin_omega;
}

template<typename T>
template<typename U>
void oscillator<std::complex<T>>::operator()(U& output)
{
  T cos0;
  T sin0;

  for (auto &out : output)
  {
    cos0 = m_cos_omega * m_cos1 - m_sin_omega * m_sin1;
    sin0 = m_sin_omega * m_cos1 + m_cos_omega * m_sin1;
    m_cos1 = cos0;
    m_sin1 = sin0;
    out = std::complex<T>(cos0, sin0);
  }
}

} /* namespace comm */
{'fraction_non_alphanumeric': 0.16700487012987014, 'fraction_numerical': 0.018262987012987012, 'mean_word_length': 2.7312641937925815, 'pattern_counts': {'":': 0, '<': 42, '<?xml version=': 0, '>': 42, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '7431597', 'n_tokens_mistral': 1939, 'n_tokens_neox': 1861, 'n_words': 428}