HART  0.1.0
High level Audio Regression and Testing
Loading...
Searching...
No Matches
hart_sinewave.hpp
Go to the documentation of this file.
1#pragma once
2
3#include <cmath>
4#include <memory>
5
8#include "signals/hart_signal.hpp"
9#include "hart_utils.hpp"
10
11namespace hart
12{
13
14/// @brief Produces a sine wave at fixed frequency
15/// @details Outputs a signal at 0dB peak (-1.0..+1.0)
16/// @ingroup Signals
17template<typename SampleType>
19 public Signal<SampleType>
20{
21public:
22 SineWave (double frequencyHz = (SampleType) 1000, double phaseRadians = (SampleType) 0):
23 m_frequencyHz (frequencyHz),
24 m_initialPhaseRadians (phaseRadians),
25 m_phaseRadians (phaseRadians)
26 {
27 clampPhase();
28
29 if (frequencyHz <= 0)
30 HART_THROW (hart::ValueError, "Invalid frequency value");
31 }
32
33 bool supportsNumChannels (size_t /* numChannels */) const override { return true; };
34
35 void prepare (double sampleRateHz, size_t /* numOutputChannels */, size_t /*maxBlockSizeFrames*/) override
36 {
37 m_sampleRateHz = sampleRateHz;
38 }
39
40 void renderNextBlock (AudioBuffer<SampleType>& output) override
41 {
42 const double phaseIncrement = hart::twoPi * m_frequencyHz / m_sampleRateHz;
43
44 for (size_t frame = 0; frame < output.getNumFrames(); ++frame)
45 {
46 SampleType value = static_cast<SampleType> (std::sin (m_phaseRadians));
47
48 for (size_t channel = 0; channel < output.getNumChannels(); ++channel)
49 output[channel][frame] = value;
50
51 m_phaseRadians += phaseIncrement;
52 clampPhase();
53 }
54 }
55
56 void reset() override
57 {
58 m_phaseRadians = m_initialPhaseRadians;
59 }
60
61 void represent (std::ostream& stream) const override
62 {
63 stream << "SineWave ("
64 << hzPrecision << m_frequencyHz << "_Hz, "
65 << radPrecision << m_initialPhaseRadians << "_rad)";
66 }
67
69
70private:
71 const double m_frequencyHz;
72 const double m_initialPhaseRadians;
73 double m_phaseRadians;
74 double m_sampleRateHz;
75
76 void clampPhase()
77 {
78 while (m_phaseRadians < 0)
79 m_phaseRadians += hart::twoPi;
80
81 if (m_phaseRadians > hart::twoPi)
82 m_phaseRadians = std::fmod (m_phaseRadians, hart::twoPi);
83 }
84};
85
87
88} // namespace hart
Base class for signals.
Produces a sine wave at fixed frequency.
void renderNextBlock(AudioBuffer< SampleType > &output) override
Renders next block audio for the signal.
SineWave(double frequencyHz=(SampleType) 1000, double phaseRadians=(SampleType) 0)
void represent(std::ostream &stream) const override
Makes a text representation of this Signal for test failure outputs.
bool supportsNumChannels(size_t) const override
Tells the host whether this Signal is capable of generating audio for a certain amount of cchannels.
void prepare(double sampleRateHz, size_t, size_t) override
Prepare the signal for rendering.
void reset() override
Resets the Signal to initial state.
std::ostream & radPrecision(std::ostream &stream)
Sets number of decimal places for values in radians.
std::ostream & hzPrecision(std::ostream &stream)
Sets number of decimal places for values in hertz.
#define HART_SIGNAL_DEFINE_COPY_AND_MOVE(ClassName)
Defines hart::Signal::copy() and hart::Signal::move() methods.
constexpr double twoPi
2 * pi
#define HART_THROW(ExceptionType, message)
#define HART_SIGNAL_DECLARE_ALIASES_FOR(ClassName)