amalgam/src/FM/Engine.h

120 lines
2.5 KiB
C++

/*
* Filename: Engine.h
*
* Description:
*
*
* Version:
* Created: Sun Mar 8 08:04:38 2020
* Revision: None
* Author: Rachel Fae Fox (foxiepaws),fox@foxiepa.ws
*
*/
#pragma once
#include "Envelope.h"
#include "Operator.h"
#include "Matrix.h"
#include <array>
namespace amalgam {
namespace FM {
template <int T>
class Engine {
Matrix<double,T> gains;
std::array<std::pair<float,float>, T> _pans; // panning on master channels.
std::array<float, T> pans; // panning on master channels.
Matrix<bool,T> mutes;
std::array<Operator*,T> operators;
std::pair<double,double> out;
public:
double freq;
bool gate;
Operator* getOperator(int n) { return operators[n]; }
void setMuteMatrix(int from, int to, float v) { *mutes(from,to) = v; }
void setGainMatrix(int from, int to, float v) { *gains(from,to) = v; }
Engine() {
for (auto iter = operators.begin(); iter != operators.end(); ++iter) {
*iter = new Operator(&freq, &gate, 44100.0);
}
}
void doFeedback(int n){
Operator* o = operators[n];
double fbg = (!*mutes(n,n)) ? *gains(n,n) : 0.0;
o->setFeedbackLevel(fbg);
}
// this isn't going to work, unfortunately.
// TODO: figure out some way handle panning
// that doesn't suck
std::pair<double,double> calcPan(float p) {
double l,r;
if (p > 0) {
l = p;
r = 1.0-p;
}else{
l = abs(p);
r = 1.0-abs(p);
}
}
void process(){
double out = 0.0;
for (int o = 0; o < T; o++) {
// do matrix
doFeedback(o);
Operator *op = operators[o];
double m = 0.0;
//for (int from = 0; from < o; from++) {
for (int from = 0; from < T; from++) { // experiment with last.
if (!*mutes(from,o)) {
auto v = operators[from]->out();
//printf("op %d to %d = %f\n",from,o,v);
m += *gains(from,o) * v;
}
}
auto preg = (*op)(m);
auto postg = *gains(o,T) * preg;
//printf("op %d in %f toSelf %f toOut %f\n",o,m,preg,postg);
out += postg;
}
this->out = {out,out};
}
double sampleMono() {
process();
return out.first + out.second;
}
std::pair<double,double> sampleStereo() {
process();
return out;
}
double getMono() {
return out.first + out.second;
}
std::pair<double,double> getStereo() {
return out;
}
std::pair<double,double> operator()(){
process();
return out;
}
};
template class Engine<1>;
template class Engine<4>;
template class Engine<6>;
template class Engine<8>;
}
}
/* Local Variables: */
/* mode: c++ */
/* End: */
/* vim: ft=cpp: */