✨ add, sub, mul and div commands.
parent
d023146c65
commit
16f1d8656b
|
@ -2,8 +2,8 @@
|
||||||
Signals
|
Signals
|
||||||
=======
|
=======
|
||||||
|
|
||||||
Signal Types
|
Signal primitives
|
||||||
------------
|
-----------------
|
||||||
|
|
||||||
MuzGen use different kind of signals for sound design.
|
MuzGen use different kind of signals for sound design.
|
||||||
|
|
||||||
|
@ -49,3 +49,50 @@ The noise command generate uniform random frames.
|
||||||
.. code-block::
|
.. code-block::
|
||||||
|
|
||||||
[noise]
|
[noise]
|
||||||
|
|
||||||
|
|
||||||
|
Signal operations
|
||||||
|
-----------------
|
||||||
|
|
||||||
|
The signal operation commands allows us to combine signals in
|
||||||
|
different ways.
|
||||||
|
|
||||||
|
Add
|
||||||
|
^^^
|
||||||
|
|
||||||
|
The ``sum`` command takes two signals as input and outputs their sum.
|
||||||
|
|
||||||
|
.. code-block::
|
||||||
|
|
||||||
|
[sum [sine 220] [sine 220]]
|
||||||
|
|
||||||
|
|
||||||
|
Sub
|
||||||
|
^^^
|
||||||
|
|
||||||
|
The ``sub`` command takes two signals as input and outputs their
|
||||||
|
difference.
|
||||||
|
|
||||||
|
.. code-block::
|
||||||
|
|
||||||
|
[sub [sine 460] [sine 80]]
|
||||||
|
|
||||||
|
|
||||||
|
Mul
|
||||||
|
^^^
|
||||||
|
|
||||||
|
The ``mul`` command takes two signals as input and output their product.
|
||||||
|
|
||||||
|
.. code-block::
|
||||||
|
|
||||||
|
[mul 0.7 [sine 220]]
|
||||||
|
|
||||||
|
|
||||||
|
Div
|
||||||
|
^^^
|
||||||
|
|
||||||
|
The ``div`` command takes two signals as input and output their ratio.
|
||||||
|
|
||||||
|
.. code-block::
|
||||||
|
|
||||||
|
[div [sine 220] 2]
|
||||||
|
|
|
@ -0,0 +1,33 @@
|
||||||
|
#include "Add.hpp"
|
||||||
|
|
||||||
|
namespace muz
|
||||||
|
{
|
||||||
|
/*explicit*/ Add::Add(AudioConf const& conf,
|
||||||
|
std::unique_ptr<Signal> lhs,
|
||||||
|
std::unique_ptr<Signal> rhs)
|
||||||
|
: m_conf { conf }
|
||||||
|
, m_out_left { std::vector<float>(m_conf.channels(), 0.0f) }
|
||||||
|
, m_out_right { std::vector<float>(m_conf.channels(), 0.0f) }
|
||||||
|
, m_lhs { std::move(lhs) }
|
||||||
|
, m_rhs { std::move(rhs) }
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
/*virtual*/ Add::~Add()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void Add::next(std::vector<float>& out) /*override*/
|
||||||
|
{
|
||||||
|
m_lhs->next(m_out_left);
|
||||||
|
m_rhs->next(m_out_right);
|
||||||
|
|
||||||
|
assert(m_out_left.size() == m_out_right.size());
|
||||||
|
assert(m_out_left.size() == static_cast<size_t>(m_conf.channels()));
|
||||||
|
|
||||||
|
for (int i=0; i<m_conf.channels(); i++)
|
||||||
|
{
|
||||||
|
out[i] = m_out_left[i] + m_out_right[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,32 @@
|
||||||
|
#ifndef muz_ADD_HPP
|
||||||
|
#define muz_ADD_HPP
|
||||||
|
|
||||||
|
#include "commons.hpp"
|
||||||
|
#include "Signal.hpp"
|
||||||
|
#include "AudioConf.hpp"
|
||||||
|
|
||||||
|
namespace muz
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Sum of two input signals.
|
||||||
|
**/
|
||||||
|
class Add: public Signal
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
explicit Add(AudioConf const& conf,
|
||||||
|
std::unique_ptr<Signal> lhs,
|
||||||
|
std::unique_ptr<Signal> rhs);
|
||||||
|
|
||||||
|
virtual ~Add();
|
||||||
|
|
||||||
|
void next(std::vector<float>& out) override;
|
||||||
|
private:
|
||||||
|
AudioConf m_conf;
|
||||||
|
std::vector<float> m_out_left;
|
||||||
|
std::vector<float> m_out_right;
|
||||||
|
std::unique_ptr<Signal> m_lhs;
|
||||||
|
std::unique_ptr<Signal> m_rhs;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
|
@ -5,6 +5,7 @@ namespace muz
|
||||||
{
|
{
|
||||||
/*explicit*/ AudioEngine::AudioEngine(AudioConf const& conf)
|
/*explicit*/ AudioEngine::AudioEngine(AudioConf const& conf)
|
||||||
: m_conf { conf }
|
: m_conf { conf }
|
||||||
|
, m_frame { std::vector<float>(m_conf.channels(), 0.0f) }
|
||||||
{
|
{
|
||||||
check_error(Pa_Initialize());
|
check_error(Pa_Initialize());
|
||||||
}
|
}
|
||||||
|
@ -80,15 +81,9 @@ namespace muz
|
||||||
return {0.0f, 0.0f};
|
return {0.0f, 0.0f};
|
||||||
}
|
}
|
||||||
|
|
||||||
auto frame = m_sig_queue.back()->next();
|
m_sig_queue.back()->next(m_frame);
|
||||||
|
|
||||||
if (frame.empty())
|
return m_frame;
|
||||||
{
|
|
||||||
pop_signal();
|
|
||||||
return next();
|
|
||||||
}
|
|
||||||
|
|
||||||
return frame;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*static*/ int AudioEngine::callback(void const*, void* output,
|
/*static*/ int AudioEngine::callback(void const*, void* output,
|
||||||
|
@ -103,7 +98,7 @@ namespace muz
|
||||||
|
|
||||||
for (size_t i=0; i<frames_per_buffer; i++)
|
for (size_t i=0; i<frames_per_buffer; i++)
|
||||||
{
|
{
|
||||||
auto frame = engine->next();
|
auto const& frame = engine->next();
|
||||||
|
|
||||||
for (float val: frame)
|
for (float val: frame)
|
||||||
{
|
{
|
||||||
|
|
|
@ -47,6 +47,7 @@ namespace muz
|
||||||
PaStream* m_stream = nullptr;
|
PaStream* m_stream = nullptr;
|
||||||
std::vector<std::unique_ptr<Signal>> m_sig_queue;
|
std::vector<std::unique_ptr<Signal>> m_sig_queue;
|
||||||
std::mutex m_sig_mtx;
|
std::mutex m_sig_mtx;
|
||||||
|
std::vector<float> m_frame;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Throws an audio_error exception if err is an error.
|
* Throws an audio_error exception if err is an error.
|
||||||
|
|
|
@ -18,6 +18,10 @@ add_library(muz-lib OBJECT
|
||||||
Constant.cpp
|
Constant.cpp
|
||||||
Sine.cpp
|
Sine.cpp
|
||||||
Noise.cpp
|
Noise.cpp
|
||||||
|
Add.cpp
|
||||||
|
Sub.cpp
|
||||||
|
Mul.cpp
|
||||||
|
Div.cpp
|
||||||
|
|
||||||
# Language
|
# Language
|
||||||
# ========
|
# ========
|
||||||
|
|
|
@ -5,6 +5,10 @@
|
||||||
#include "Constant.hpp"
|
#include "Constant.hpp"
|
||||||
#include "Sine.hpp"
|
#include "Sine.hpp"
|
||||||
#include "Noise.hpp"
|
#include "Noise.hpp"
|
||||||
|
#include "Add.hpp"
|
||||||
|
#include "Sub.hpp"
|
||||||
|
#include "Mul.hpp"
|
||||||
|
#include "Div.hpp"
|
||||||
|
|
||||||
namespace muz
|
namespace muz
|
||||||
{
|
{
|
||||||
|
@ -56,10 +60,10 @@ namespace muz
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
throw compile_error {
|
format_error<compile_error>(node->line(),
|
||||||
std::string()
|
"cannot compile unknown directive '"
|
||||||
+ "cannot compile unknown directive '" + name + "'."
|
+ name
|
||||||
};
|
+ "'.");
|
||||||
}
|
}
|
||||||
|
|
||||||
} break;
|
} break;
|
||||||
|
@ -92,12 +96,60 @@ namespace muz
|
||||||
auto signal = std::make_unique<Noise>(m_conf);
|
auto signal = std::make_unique<Noise>(m_conf);
|
||||||
push(std::move(signal));
|
push(std::move(signal));
|
||||||
}
|
}
|
||||||
|
else if (name == "add")
|
||||||
|
{
|
||||||
|
check_cmd_arity(*node, 2);
|
||||||
|
|
||||||
|
auto rhs = pop();
|
||||||
|
auto lhs = pop();
|
||||||
|
|
||||||
|
auto signal = std::make_unique<Add>(m_conf,
|
||||||
|
std::move(lhs),
|
||||||
|
std::move(rhs));
|
||||||
|
push(std::move(signal));
|
||||||
|
}
|
||||||
|
else if (name == "sub")
|
||||||
|
{
|
||||||
|
check_cmd_arity(*node, 2);
|
||||||
|
|
||||||
|
auto rhs = pop();
|
||||||
|
auto lhs = pop();
|
||||||
|
|
||||||
|
auto signal = std::make_unique<Sub>(m_conf,
|
||||||
|
std::move(lhs),
|
||||||
|
std::move(rhs));
|
||||||
|
push(std::move(signal));
|
||||||
|
}
|
||||||
|
else if (name == "mul")
|
||||||
|
{
|
||||||
|
check_cmd_arity(*node, 2);
|
||||||
|
|
||||||
|
auto rhs = pop();
|
||||||
|
auto lhs = pop();
|
||||||
|
|
||||||
|
auto signal = std::make_unique<Mul>(m_conf,
|
||||||
|
std::move(lhs),
|
||||||
|
std::move(rhs));
|
||||||
|
push(std::move(signal));
|
||||||
|
}
|
||||||
|
else if (name == "div")
|
||||||
|
{
|
||||||
|
check_cmd_arity(*node, 2);
|
||||||
|
|
||||||
|
auto rhs = pop();
|
||||||
|
auto lhs = pop();
|
||||||
|
|
||||||
|
auto signal = std::make_unique<Div>(m_conf,
|
||||||
|
std::move(lhs),
|
||||||
|
std::move(rhs));
|
||||||
|
push(std::move(signal));
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
throw compile_error {
|
format_error<compile_error>(node->line(),
|
||||||
std::string()
|
"cannot compile unknown command '"
|
||||||
+ "cannot compile unknown command '" + name + "'."
|
+ name
|
||||||
};
|
+ "'.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -117,15 +169,15 @@ namespace muz
|
||||||
{
|
{
|
||||||
if (node.size() - 1 != static_cast<size_t>(arity))
|
if (node.size() - 1 != static_cast<size_t>(arity))
|
||||||
{
|
{
|
||||||
throw compile_error {
|
format_error<compile_error>(node.line(),
|
||||||
std::string()
|
"arity mismatch for '"
|
||||||
+ "arity mismatch for '"
|
+ node.child(0)->value()
|
||||||
+ node.child(0)->value()
|
+ "': expected <"
|
||||||
+ "': expected <"
|
+ std::to_string(arity)
|
||||||
+ std::to_string(arity)
|
+ ">, got <"
|
||||||
+ ">, got <"
|
+ std::to_string(node.size() - 1)
|
||||||
+ std::to_string(node.size() - 1)
|
+ ">.");
|
||||||
+ ">."};
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,15 +12,11 @@ namespace muz
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<float> Constant::next() /*override*/
|
void Constant::next(std::vector<float>& out) /*override*/
|
||||||
{
|
{
|
||||||
std::vector<float> out;
|
|
||||||
|
|
||||||
for (int i=0; i<m_conf.channels(); i++)
|
for (int i=0; i<m_conf.channels(); i++)
|
||||||
{
|
{
|
||||||
out.push_back(m_value);
|
out[i] = m_value;
|
||||||
}
|
}
|
||||||
|
|
||||||
return out;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,10 +15,11 @@ namespace muz
|
||||||
explicit Constant(AudioConf const& conf, float value=0.0f);
|
explicit Constant(AudioConf const& conf, float value=0.0f);
|
||||||
virtual ~Constant();
|
virtual ~Constant();
|
||||||
|
|
||||||
std::vector<float> next() override;
|
void next(std::vector<float>& out) override;
|
||||||
private:
|
private:
|
||||||
AudioConf m_conf;
|
AudioConf m_conf;
|
||||||
float m_value;
|
float m_value;
|
||||||
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,33 @@
|
||||||
|
#include "Div.hpp"
|
||||||
|
|
||||||
|
namespace muz
|
||||||
|
{
|
||||||
|
/*explicit*/ Div::Div(AudioConf const& conf,
|
||||||
|
std::unique_ptr<Signal> lhs,
|
||||||
|
std::unique_ptr<Signal> rhs)
|
||||||
|
: m_conf { conf }
|
||||||
|
, m_out_left { std::vector<float>(m_conf.channels(), 0.0f) }
|
||||||
|
, m_out_right { std::vector<float>(m_conf.channels(), 0.0f) }
|
||||||
|
, m_lhs { std::move(lhs) }
|
||||||
|
, m_rhs { std::move(rhs) }
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
/*virtual*/ Div::~Div()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void Div::next(std::vector<float>& out) /*override*/
|
||||||
|
{
|
||||||
|
m_lhs->next(m_out_left);
|
||||||
|
m_rhs->next(m_out_right);
|
||||||
|
|
||||||
|
assert(m_out_left.size() == m_out_right.size());
|
||||||
|
assert(m_out_left.size() == static_cast<size_t>(m_conf.channels()));
|
||||||
|
|
||||||
|
for (int i=0; i<m_conf.channels(); i++)
|
||||||
|
{
|
||||||
|
out[i] = m_out_left[i] / m_out_right[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,33 @@
|
||||||
|
#ifndef muz_DIV_HPP
|
||||||
|
#define muz_DIV_HPP
|
||||||
|
|
||||||
|
#include "commons.hpp"
|
||||||
|
#include "Signal.hpp"
|
||||||
|
#include "AudioConf.hpp"
|
||||||
|
|
||||||
|
namespace muz
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Division of two input signals.
|
||||||
|
**/
|
||||||
|
class Div: public Signal
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
explicit Div(AudioConf const& conf,
|
||||||
|
std::unique_ptr<Signal> lhs,
|
||||||
|
std::unique_ptr<Signal> rhs);
|
||||||
|
virtual ~Div();
|
||||||
|
|
||||||
|
void next(std::vector<float>& out) override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
AudioConf m_conf;
|
||||||
|
std::vector<float> m_out_left;
|
||||||
|
std::vector<float> m_out_right;
|
||||||
|
|
||||||
|
std::unique_ptr<Signal> m_lhs;
|
||||||
|
std::unique_ptr<Signal> m_rhs;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
|
@ -0,0 +1,33 @@
|
||||||
|
#include "Mul.hpp"
|
||||||
|
|
||||||
|
namespace muz
|
||||||
|
{
|
||||||
|
/*explicit*/ Mul::Mul(AudioConf const& conf,
|
||||||
|
std::unique_ptr<Signal> lhs,
|
||||||
|
std::unique_ptr<Signal> rhs)
|
||||||
|
: m_conf { conf }
|
||||||
|
, m_out_left { std::vector<float>(m_conf.channels(), 0.0f) }
|
||||||
|
, m_out_right { std::vector<float>(m_conf.channels(), 0.0f) }
|
||||||
|
, m_lhs { std::move(lhs) }
|
||||||
|
, m_rhs { std::move(rhs) }
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
/*virtual*/ Mul::~Mul()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void Mul::next(std::vector<float>& out) /*override*/
|
||||||
|
{
|
||||||
|
m_lhs->next(m_out_left);
|
||||||
|
m_rhs->next(m_out_right);
|
||||||
|
|
||||||
|
assert(m_out_left.size() == m_out_right.size());
|
||||||
|
assert(m_out_left.size() == static_cast<size_t>(m_conf.channels()));
|
||||||
|
|
||||||
|
for (int i=0; i<m_conf.channels(); i++)
|
||||||
|
{
|
||||||
|
out[i] = m_out_left[i] * m_out_right[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,32 @@
|
||||||
|
#ifndef muz_MUL_HPP
|
||||||
|
#define muz_MUL_HPP
|
||||||
|
|
||||||
|
#include "commons.hpp"
|
||||||
|
#include "Signal.hpp"
|
||||||
|
#include "AudioConf.hpp"
|
||||||
|
|
||||||
|
namespace muz
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Product of two input signals.
|
||||||
|
**/
|
||||||
|
class Mul: public Signal
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
explicit Mul(AudioConf const& conf,
|
||||||
|
std::unique_ptr<Signal> lhs,
|
||||||
|
std::unique_ptr<Signal> rhs);
|
||||||
|
virtual ~Mul();
|
||||||
|
|
||||||
|
void next(std::vector<float>& out) override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
AudioConf m_conf;
|
||||||
|
std::vector<float> m_out_left;
|
||||||
|
std::vector<float> m_out_right;
|
||||||
|
std::unique_ptr<Signal> m_lhs;
|
||||||
|
std::unique_ptr<Signal> m_rhs;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
|
@ -12,17 +12,13 @@ namespace muz
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<float> Noise::next() /*override*/
|
void Noise::next(std::vector<float>& out) /*override*/
|
||||||
{
|
{
|
||||||
std::vector<float> out;
|
|
||||||
|
|
||||||
float value = m_distribution(m_rand);
|
float value = m_distribution(m_rand);
|
||||||
|
|
||||||
for (int i=0; i<m_conf.channels(); i++)
|
for (int i=0; i<m_conf.channels(); i++)
|
||||||
{
|
{
|
||||||
out.push_back(value);
|
out[i] = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
return out;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,13 +10,17 @@
|
||||||
|
|
||||||
namespace muz
|
namespace muz
|
||||||
{
|
{
|
||||||
|
/**
|
||||||
|
* White noise signal.
|
||||||
|
* @see Signal
|
||||||
|
**/
|
||||||
class Noise: public Signal
|
class Noise: public Signal
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
explicit Noise(AudioConf const& conf);
|
explicit Noise(AudioConf const& conf);
|
||||||
virtual ~Noise();
|
virtual ~Noise();
|
||||||
|
|
||||||
std::vector<float> next() override;
|
void next(std::vector<float>& out) override;
|
||||||
private:
|
private:
|
||||||
AudioConf m_conf;
|
AudioConf m_conf;
|
||||||
std::mt19937 m_rand;
|
std::mt19937 m_rand;
|
||||||
|
|
|
@ -19,11 +19,10 @@ namespace muz
|
||||||
virtual ~Signal();
|
virtual ~Signal();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the next sample.
|
* Get the next frame.
|
||||||
* @return std::vector<float> of size N for a sample of N channels or an empty vector at end.
|
* @param out the output buffer that will contain the next frame.
|
||||||
*
|
|
||||||
**/
|
**/
|
||||||
virtual std::vector<float> next() = 0;
|
virtual void next(std::vector<float>& out) = 0;
|
||||||
private:
|
private:
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
21
lib/Sine.cpp
21
lib/Sine.cpp
|
@ -6,6 +6,8 @@ namespace muz
|
||||||
std::unique_ptr<Signal> freq,
|
std::unique_ptr<Signal> freq,
|
||||||
std::unique_ptr<Signal> amplitude)
|
std::unique_ptr<Signal> amplitude)
|
||||||
: m_conf { conf }
|
: m_conf { conf }
|
||||||
|
, m_out_freq {std::vector<float> (m_conf.channels(), 0.0f)}
|
||||||
|
, m_out_amp {std::vector<float> (m_conf.channels(), 0.0f)}
|
||||||
, m_freq { std::move(freq) }
|
, m_freq { std::move(freq) }
|
||||||
, m_amplitude { std::move(amplitude) }
|
, m_amplitude { std::move(amplitude) }
|
||||||
{
|
{
|
||||||
|
@ -19,31 +21,28 @@ namespace muz
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<float> Sine::next() /*override*/
|
void Sine::next(std::vector<float>& out) /*override*/
|
||||||
{
|
{
|
||||||
assert(m_freq);
|
assert(m_freq);
|
||||||
assert(m_amplitude);
|
assert(m_amplitude);
|
||||||
|
|
||||||
std::vector<float> out;
|
m_freq->next(m_out_freq);
|
||||||
auto freqs = m_freq->next();
|
m_amplitude->next(m_out_amp);
|
||||||
auto amps = m_amplitude->next();
|
|
||||||
|
|
||||||
if (freqs.size() != amps.size()
|
if (m_out_freq.size() != m_out_amp.size()
|
||||||
|| freqs.size() != m_phases.size())
|
|| m_out_freq.size() != m_phases.size())
|
||||||
{
|
{
|
||||||
throw signal_error {"cannot generate sine: channel number mismatch"};
|
throw signal_error {"cannot generate sine: channel number mismatch"};
|
||||||
}
|
}
|
||||||
|
|
||||||
for (size_t i=0; i<static_cast<size_t>(m_conf.channels()); i++)
|
for (size_t i=0; i<static_cast<size_t>(m_conf.channels()); i++)
|
||||||
{
|
{
|
||||||
float const value = amps[i] * std::sin(m_phases[i]);
|
float const value = m_out_amp[i] * std::sin(m_phases[i]);
|
||||||
|
|
||||||
m_phases[i] += 2 * M_PI * freqs[i]
|
m_phases[i] += 2 * M_PI * m_out_freq[i]
|
||||||
/ static_cast<float>(m_conf.samplerate());
|
/ static_cast<float>(m_conf.samplerate());
|
||||||
|
|
||||||
out.push_back(value);
|
out[i] = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
return out;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,9 +18,12 @@ namespace muz
|
||||||
std::unique_ptr<Signal> amplitude);
|
std::unique_ptr<Signal> amplitude);
|
||||||
virtual ~Sine();
|
virtual ~Sine();
|
||||||
|
|
||||||
std::vector<float> next() override;
|
void next(std::vector<float>& out) override;
|
||||||
private:
|
private:
|
||||||
AudioConf const& m_conf;
|
AudioConf const& m_conf;
|
||||||
|
std::vector<float> m_out_freq;
|
||||||
|
std::vector<float> m_out_amp;
|
||||||
|
|
||||||
std::unique_ptr<Signal> m_freq;
|
std::unique_ptr<Signal> m_freq;
|
||||||
std::unique_ptr<Signal> m_amplitude;
|
std::unique_ptr<Signal> m_amplitude;
|
||||||
std::vector<float> m_phases;
|
std::vector<float> m_phases;
|
||||||
|
|
|
@ -0,0 +1,33 @@
|
||||||
|
#include "Sub.hpp"
|
||||||
|
|
||||||
|
namespace muz
|
||||||
|
{
|
||||||
|
/*explicit*/ Sub::Sub(AudioConf const& conf,
|
||||||
|
std::unique_ptr<Signal> lhs,
|
||||||
|
std::unique_ptr<Signal> rhs)
|
||||||
|
: m_conf { conf }
|
||||||
|
, m_out_left { std::vector<float>(m_conf.channels(), 0.0f) }
|
||||||
|
, m_out_right { std::vector<float>(m_conf.channels(), 0.0f) }
|
||||||
|
, m_lhs { std::move(lhs) }
|
||||||
|
, m_rhs { std::move(rhs) }
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
/*virtual*/ Sub::~Sub()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void Sub::next(std::vector<float>& out) /*override*/
|
||||||
|
{
|
||||||
|
m_lhs->next(m_out_left);
|
||||||
|
m_rhs->next(m_out_right);
|
||||||
|
|
||||||
|
assert(m_out_left.size() == m_out_right.size());
|
||||||
|
assert(m_out_left.size() == static_cast<size_t>(m_conf.channels()));
|
||||||
|
|
||||||
|
for (int i=0; i<m_conf.channels(); i++)
|
||||||
|
{
|
||||||
|
out[i] = m_out_left[i] - m_out_right[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,32 @@
|
||||||
|
#ifndef muz_SUB_HPP
|
||||||
|
#define muz_SUB_HPP
|
||||||
|
|
||||||
|
#include "commons.hpp"
|
||||||
|
#include "Signal.hpp"
|
||||||
|
#include "AudioConf.hpp"
|
||||||
|
|
||||||
|
namespace muz
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Substraction of two input signals.
|
||||||
|
**/
|
||||||
|
class Sub: public Signal
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
explicit Sub(AudioConf const& conf,
|
||||||
|
std::unique_ptr<Signal> lhs,
|
||||||
|
std::unique_ptr<Signal> rhs);
|
||||||
|
virtual ~Sub();
|
||||||
|
|
||||||
|
void next(std::vector<float>& out) override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
AudioConf m_conf;
|
||||||
|
std::vector<float> m_out_left;
|
||||||
|
std::vector<float> m_out_right;
|
||||||
|
std::unique_ptr<Signal> m_lhs;
|
||||||
|
std::unique_ptr<Signal> m_rhs;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
Loading…
Reference in New Issue