120 lines
2.5 KiB
C++
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: */
|