initial commit
commit
3f50d7bbf7
|
@ -0,0 +1,9 @@
|
||||||
|
.DS_STORE
|
||||||
|
*.o
|
||||||
|
fmtest
|
||||||
|
*.w16
|
||||||
|
*.wav
|
||||||
|
.#a
|
||||||
|
build/
|
||||||
|
*.dSYM
|
||||||
|
a.out
|
|
@ -0,0 +1,109 @@
|
||||||
|
/*
|
||||||
|
* 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 FM {
|
||||||
|
template <int T>
|
||||||
|
class Engine {
|
||||||
|
Matrix<double,T> gains;
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
|
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(){
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Local Variables: */
|
||||||
|
/* mode: c++ */
|
||||||
|
/* End: */
|
||||||
|
/* vim: ft=cpp: */
|
|
@ -0,0 +1,102 @@
|
||||||
|
/*
|
||||||
|
* Filename: Envelope.cpp
|
||||||
|
*
|
||||||
|
* Description:
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* Version:
|
||||||
|
* Created: Sun Mar 8 08:41:17 2020
|
||||||
|
* Revision: None
|
||||||
|
* Author: Rachel Fae Fox (foxiepaws),fox@foxiepa.ws
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#include "Envelope.h"
|
||||||
|
namespace FM {
|
||||||
|
float Envelope::process () {
|
||||||
|
switch (envstate) {
|
||||||
|
case _e_off:
|
||||||
|
if (*gate) {
|
||||||
|
t = 0;
|
||||||
|
envstate = _e_attack;
|
||||||
|
return process();
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case _e_attack:
|
||||||
|
if (*gate) {
|
||||||
|
if ( t < attack ) {
|
||||||
|
float stepsize = (max_level - min_level) / attack;
|
||||||
|
t++;
|
||||||
|
return t * stepsize;
|
||||||
|
} else {
|
||||||
|
t = 0;
|
||||||
|
envstate = _e_decay;
|
||||||
|
return max_level;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
envstate = _e_attackrelease;
|
||||||
|
return process();
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case _e_decay:
|
||||||
|
if (*gate) {
|
||||||
|
if (t < decay) {
|
||||||
|
float stepsize = (max_level - sustain_level) / decay;
|
||||||
|
t++;
|
||||||
|
return (max_level - (t * stepsize));
|
||||||
|
|
||||||
|
} else {
|
||||||
|
envstate = _e_sustain;
|
||||||
|
return sustain_level;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
envstate = _e_attackrelease;
|
||||||
|
return process();
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case _e_sustain:
|
||||||
|
if (!sustain) {
|
||||||
|
envstate = _e_release;
|
||||||
|
t = 0;
|
||||||
|
return process();
|
||||||
|
}
|
||||||
|
if (!*gate) {
|
||||||
|
t = 0;
|
||||||
|
envstate = _e_release;
|
||||||
|
return sustain_level;
|
||||||
|
}
|
||||||
|
return sustain_level;
|
||||||
|
break;
|
||||||
|
case _e_release:
|
||||||
|
if (*gate) {
|
||||||
|
// reset envelope.
|
||||||
|
envstate=_e_off;
|
||||||
|
return process();
|
||||||
|
}
|
||||||
|
if (modMode) {
|
||||||
|
return sustain_level;
|
||||||
|
}
|
||||||
|
if (t < release) {
|
||||||
|
float stepsize = (sustain_level - min_level) / release;
|
||||||
|
t++;
|
||||||
|
return sustain_level - (stepsize * t);
|
||||||
|
} else {
|
||||||
|
envstate = _e_off;
|
||||||
|
return min_level;
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
case _e_attackrelease:
|
||||||
|
if (*gate) {
|
||||||
|
//reset envelope
|
||||||
|
envstate=_e_off;
|
||||||
|
return process();
|
||||||
|
}
|
||||||
|
return 0.0f;
|
||||||
|
break;
|
||||||
|
|
||||||
|
}
|
||||||
|
return 0.0f; // if this is reached, something went wrong or an unhandled function was used.
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,80 @@
|
||||||
|
/*
|
||||||
|
* Filename: Envelope.h
|
||||||
|
*
|
||||||
|
* Description:
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* Version:
|
||||||
|
* Created: Sun Mar 8 07:48:47 2020
|
||||||
|
* Revision: None
|
||||||
|
* Author: Rachel Fae Fox (foxiepaws),fox@foxiepa.ws
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
#pragma once
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <math.h>
|
||||||
|
namespace FM {
|
||||||
|
class Envelope {
|
||||||
|
enum EnvState {_e_off,_e_attack, _e_attackrelease, _e_decay, _e_sustain,_e_release, _e_finished};
|
||||||
|
// Time Params
|
||||||
|
unsigned int attack = 0; // attack length in samples
|
||||||
|
unsigned int decay = 0; // decay length in samples
|
||||||
|
unsigned int release = 0; // release time in samples
|
||||||
|
bool sustain = true; // boolean if sustain is enabled.
|
||||||
|
bool modMode = false; // boolean if we just use SL instead of minlevel till reset.
|
||||||
|
|
||||||
|
// Level Params
|
||||||
|
float max_level = 1.0;
|
||||||
|
float sustain_level = 1.0; // level that decay phase drops to.
|
||||||
|
float min_level = 0.0;
|
||||||
|
bool* gate; // pointer to gate
|
||||||
|
|
||||||
|
// Internal use
|
||||||
|
unsigned long int t = 0; // samples;
|
||||||
|
unsigned int smpRate; // sample rate
|
||||||
|
EnvState envstate = _e_off; // envelope state.
|
||||||
|
public:
|
||||||
|
// getters
|
||||||
|
unsigned int getAttackSamples() { return attack; }
|
||||||
|
unsigned int getDecaySamples() { return decay; }
|
||||||
|
unsigned int getReleaseSamples() { return release; }
|
||||||
|
float getAttackTime() { return (double) attack / (double) smpRate; }
|
||||||
|
float getDecayTime() { return (double) decay / (double) smpRate; }
|
||||||
|
float getReleaseTime() { return (double) release / (double) smpRate; }
|
||||||
|
bool getSustain() { return sustain; }
|
||||||
|
float getMaxLevel() { return max_level; }
|
||||||
|
float getMinLevel() { return min_level; }
|
||||||
|
float getSustainLevel() { return sustain_level; }
|
||||||
|
bool getModMode() { return modMode; }
|
||||||
|
bool* getGate() { return gate; }
|
||||||
|
// setters
|
||||||
|
void setAttackSamples(unsigned int a) { attack = a; }
|
||||||
|
void setAttackTime(float a) { attack = floor(smpRate * a); }
|
||||||
|
void setDecaySamples(unsigned int d) { decay = d; }
|
||||||
|
void setDecayTime(float d) { decay = floor(smpRate * d); }
|
||||||
|
void setReleaseSamples(unsigned int r) { release = r; }
|
||||||
|
void setReleaseTime(float r) { release = floor(smpRate * r); }
|
||||||
|
void setSustain(bool s) { sustain = s; }
|
||||||
|
void setModMode(bool m) { modMode = m; }
|
||||||
|
void setMaxLevel(float ml) { max_level = ml; }
|
||||||
|
void setMinLevel(float ml) { min_level = ml; }
|
||||||
|
void setSustainLevel(float sl) { sustain_level = sl; }
|
||||||
|
void setGate(bool* g) { gate = g; }
|
||||||
|
void setRate(unsigned int sr) { smpRate = sr; }
|
||||||
|
// helpers
|
||||||
|
// note : if you make use of these functions YOU must manage their memory.
|
||||||
|
void makeGate() { gate = (bool*) malloc(sizeof(bool)); }
|
||||||
|
void freeGate() { free(gate); }
|
||||||
|
// constructors
|
||||||
|
Envelope(){}
|
||||||
|
Envelope(unsigned int sr, unsigned int a, unsigned int d, bool s, unsigned int r, float sl, bool* g);
|
||||||
|
// methods
|
||||||
|
float process();
|
||||||
|
float operator()() { return process(); }
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Local Variables: */
|
||||||
|
/* mode: c++ */
|
||||||
|
/* End: */
|
||||||
|
/* vim: ft=cpp: */
|
|
@ -0,0 +1,34 @@
|
||||||
|
/*
|
||||||
|
* Filename: Matrix.h
|
||||||
|
*
|
||||||
|
* Description:
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* Version:
|
||||||
|
* Created: Sun Mar 8 08:11:11 2020
|
||||||
|
* Revision: None
|
||||||
|
* Author: Rachel Fae Fox (foxiepaws),fox@foxiepa.ws
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
#include <array>
|
||||||
|
|
||||||
|
namespace FM {
|
||||||
|
template <class T, int N>
|
||||||
|
class Matrix {
|
||||||
|
public:
|
||||||
|
std::array<std::array<T, N+1>, N> v; // gain
|
||||||
|
std::array<T,N+1> *operator[] (int row){
|
||||||
|
return &v[row];
|
||||||
|
}
|
||||||
|
T *operator()(int row, int col) {
|
||||||
|
return &v[row][col];
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Local Variables: */
|
||||||
|
/* mode: c++ */
|
||||||
|
/* End: */
|
||||||
|
/* vim: ft=cpp: */
|
|
@ -0,0 +1,61 @@
|
||||||
|
/*
|
||||||
|
* Filename: Operator.cpp
|
||||||
|
*
|
||||||
|
* Description:
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* Version:
|
||||||
|
* Created: Sun Mar 8 08:36:21 2020
|
||||||
|
* Revision: None
|
||||||
|
* Author: Rachel Fae Fox (foxiepaws),fox@foxiepa.ws
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "Operator.h"
|
||||||
|
namespace FM {
|
||||||
|
void Operator::process(){
|
||||||
|
phase += smpTime * (((*freq * mul) + detune));
|
||||||
|
_out=last=sin((2*M_PI*phase) + _in + (fbgain*last));
|
||||||
|
}
|
||||||
|
double Operator::operator()(){
|
||||||
|
process();
|
||||||
|
elast = e();
|
||||||
|
return elast * _out;
|
||||||
|
}
|
||||||
|
double Operator::operator()(double in){
|
||||||
|
_in = in;
|
||||||
|
process();
|
||||||
|
elast = e();
|
||||||
|
return elast * _out;
|
||||||
|
}
|
||||||
|
void Operator::setAll(double mul, double detune, double fbgain) {
|
||||||
|
this->mul = mul;
|
||||||
|
this->detune = detune;
|
||||||
|
this->fbgain = fbgain;
|
||||||
|
}
|
||||||
|
Operator::Operator(){
|
||||||
|
__m = true;
|
||||||
|
freq = (double*) malloc(sizeof(double));
|
||||||
|
gate = (bool*) malloc(sizeof(bool));
|
||||||
|
e.setGate(gate);
|
||||||
|
}
|
||||||
|
Operator::Operator(double* f, bool* g) {
|
||||||
|
gate = g;
|
||||||
|
freq = f;
|
||||||
|
e.setGate(gate);
|
||||||
|
}
|
||||||
|
Operator::Operator(double* f, bool* g, unsigned int sr) {
|
||||||
|
gate = g;
|
||||||
|
freq = f;
|
||||||
|
smpRate = sr;
|
||||||
|
smpTime = 1.0/sr;
|
||||||
|
e.setRate(sr);
|
||||||
|
e.setGate(gate);
|
||||||
|
}
|
||||||
|
Operator::~Operator(){
|
||||||
|
if (__m) {
|
||||||
|
free(freq);
|
||||||
|
free(gate);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,51 @@
|
||||||
|
/*
|
||||||
|
* Filename: Operator.h
|
||||||
|
*
|
||||||
|
* Description:
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* Version:
|
||||||
|
* Created: Sun Mar 8 07:57:26 2020
|
||||||
|
* Revision: None
|
||||||
|
* Author: Rachel Fae Fox (foxiepaws),fox@foxiepa.ws
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
#include "Envelope.h"
|
||||||
|
namespace FM {
|
||||||
|
class Operator {
|
||||||
|
double mul = 1.0;
|
||||||
|
double detune = 0.0;
|
||||||
|
double fbgain = 0.0;
|
||||||
|
bool __m;
|
||||||
|
double *freq; // frequency
|
||||||
|
bool *gate;
|
||||||
|
double _in = 0.0; // fm input
|
||||||
|
double _out = 0.0;
|
||||||
|
double last = 0.0; // for feedback
|
||||||
|
double phase = 0.0;
|
||||||
|
Envelope e;
|
||||||
|
double elast = 0.0;
|
||||||
|
double smpTime;
|
||||||
|
double smpRate;
|
||||||
|
public:
|
||||||
|
void process();
|
||||||
|
double operator()();
|
||||||
|
double operator()(double in);
|
||||||
|
double out() { return elast * _out; }
|
||||||
|
Envelope* getEnvelope() { return &e; }
|
||||||
|
void setAll(double mul, double detune, double fbgain);
|
||||||
|
void setMul(double mul) { this->mul = mul; }
|
||||||
|
void setDetune(double mul) { this->mul = mul; }
|
||||||
|
void setFeedbackLevel(double fbgain) { this->fbgain = fbgain; };
|
||||||
|
Operator();
|
||||||
|
Operator(double* f, bool* g);
|
||||||
|
Operator(double* f, bool* g, unsigned int sr);
|
||||||
|
~Operator();
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Local Variables: */
|
||||||
|
/* mode: c++ */
|
||||||
|
/* End: */
|
|
@ -0,0 +1,96 @@
|
||||||
|
/*
|
||||||
|
* Filename: fmtest.cpp
|
||||||
|
*
|
||||||
|
* Description:
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* Version:
|
||||||
|
* Created: Sun Mar 8 08:12:43 2020
|
||||||
|
* Revision: None
|
||||||
|
* Author: Rachel Fae Fox (foxiepaws),fox@foxiepa.ws
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "Engine.h"
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <math.h>
|
||||||
|
|
||||||
|
int16_t toint16(double i) {
|
||||||
|
double temp = i *= 32767;
|
||||||
|
return floor(temp);
|
||||||
|
}
|
||||||
|
void writeBytes(FILE* file, char* bytes, unsigned int count) {
|
||||||
|
for (int i = 0; i < count ; i++)
|
||||||
|
putc(bytes[i],file);
|
||||||
|
}
|
||||||
|
int main(int argc, char** argv){
|
||||||
|
FM::Engine<2> *f = new FM::Engine<2>();
|
||||||
|
f->getOperator(0)->setAll(2.0,0.0,0.0);
|
||||||
|
f->getOperator(0)->getEnvelope()->setAttackTime(1.0);
|
||||||
|
f->getOperator(0)->getEnvelope()->setDecayTime(0.5);
|
||||||
|
f->getOperator(0)->getEnvelope()->setMaxLevel(1.0);
|
||||||
|
f->getOperator(0)->getEnvelope()->setModMode(true); // play until reset.
|
||||||
|
f->getOperator(1)->getEnvelope()->setReleaseTime(2.5);
|
||||||
|
f->getOperator(1)->setAll(1.0,0.0,0.0);
|
||||||
|
f->setGainMatrix(0,0,0.0); // op1 fbl = 0
|
||||||
|
f->setGainMatrix(0,1,1.0); // op1 -> op2 = 1
|
||||||
|
f->setGainMatrix(1,0,0.0); // op2 -> op1 = 0
|
||||||
|
f->setGainMatrix(1,2,1.0); // op2 -> out = 1
|
||||||
|
f->freq = 440;
|
||||||
|
f->gate = true;
|
||||||
|
FM::Engine<2> *g = new FM::Engine<2>();
|
||||||
|
g->getOperator(0)->setAll(2.0,0.0,0.0);
|
||||||
|
g->getOperator(0)->getEnvelope()->setAttackTime(1.0);
|
||||||
|
g->getOperator(0)->getEnvelope()->setDecayTime(0.5);
|
||||||
|
g->getOperator(0)->getEnvelope()->setMaxLevel(1.0);
|
||||||
|
g->getOperator(0)->getEnvelope()->setModMode(true); // play until reset.
|
||||||
|
g->getOperator(1)->getEnvelope()->setReleaseTime(2.5);
|
||||||
|
g->getOperator(1)->setAll(1.0,0.0,0.0);
|
||||||
|
g->setGainMatrix(0,0,0.0); // op1 fbl = 0
|
||||||
|
g->setGainMatrix(0,1,1.0); // op1 -> op2 = 1
|
||||||
|
g->setGainMatrix(1,0,0.0); // op2 -> op1 = 0
|
||||||
|
g->setGainMatrix(1,2,1.0); // op2 -> out = 1
|
||||||
|
g->freq = 256;
|
||||||
|
g->gate = true;
|
||||||
|
FILE* w = fopen("testwav.wav", "w");
|
||||||
|
fprintf(w,"RIFF");
|
||||||
|
double seconds = 20;
|
||||||
|
uint32_t srate = 44100;
|
||||||
|
unsigned int samples= floor(seconds*srate);
|
||||||
|
uint16_t bps = 16;
|
||||||
|
uint16_t channels = 2;
|
||||||
|
uint32_t datasize = ((bps/8)*channels*samples);
|
||||||
|
uint32_t fmtsize = 16;
|
||||||
|
uint16_t type = 1;
|
||||||
|
uint32_t riffsize = 20 + fmtsize + datasize;
|
||||||
|
uint32_t byterate = srate * 1 * (bps/8);
|
||||||
|
uint16_t blockalign = channels * (bps/8);
|
||||||
|
char* l;
|
||||||
|
writeBytes(w,(char*) &riffsize,4);
|
||||||
|
fprintf(w,"WAVEfmt ");
|
||||||
|
// size
|
||||||
|
writeBytes(w,(char*) &fmtsize,4);
|
||||||
|
// type
|
||||||
|
writeBytes(w,(char*) &type,2);
|
||||||
|
writeBytes(w,(char*) &channels,2);
|
||||||
|
writeBytes(w,(char*) &srate,4);
|
||||||
|
writeBytes(w,(char*) &byterate,4);
|
||||||
|
writeBytes(w,(char*) &blockalign,2);
|
||||||
|
writeBytes(w,(char*) &bps, 2);
|
||||||
|
fprintf(w,"data");
|
||||||
|
writeBytes(w,(char*) &datasize, 4);
|
||||||
|
|
||||||
|
for (int s = 0; s < samples; s++) {
|
||||||
|
double ld = (*f)();
|
||||||
|
double rd = (*g)();
|
||||||
|
int16_t l = toint16(ld/4.0);
|
||||||
|
int16_t r = toint16(rd/4.0);
|
||||||
|
writeBytes(w,(char*) &l,2);
|
||||||
|
writeBytes(w,(char*) &r,2);
|
||||||
|
}
|
||||||
|
fclose(w);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,24 @@
|
||||||
|
Copyright 2020 Rachel Fae Fox
|
||||||
|
|
||||||
|
Redistribution and use in source and binary forms, with or without
|
||||||
|
modification, are permitted provided that the following conditions are
|
||||||
|
met:
|
||||||
|
|
||||||
|
1. Redistributions of source code must retain the above copyright
|
||||||
|
notice, this list of conditions and the following disclaimer.
|
||||||
|
|
||||||
|
2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
notice, this list of conditions and the following disclaimer in the
|
||||||
|
documentation and/or other materials provided with the distribution.
|
||||||
|
|
||||||
|
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
@ -0,0 +1,49 @@
|
||||||
|
CXX ?= clang++
|
||||||
|
SRCDIR ?= FM
|
||||||
|
INCDIR += -I${SRCDIR}
|
||||||
|
OBJDIR ?= FM
|
||||||
|
BINDIR ?= bin
|
||||||
|
INSTALLDIR ?= /usr/local/bin
|
||||||
|
|
||||||
|
TARGET ?= synththing
|
||||||
|
|
||||||
|
CFLAGS += -std=c++11
|
||||||
|
#CFLAGS += `pkg-config --cflags portaudio-2.0`
|
||||||
|
#LDFLAGS += `pkg-config --libs portaudio-2.0`
|
||||||
|
|
||||||
|
UNAME=$(shell uname -s)
|
||||||
|
ifeq (${UNAME},FreeBSD)
|
||||||
|
INCDIR += -I/sys/
|
||||||
|
endif
|
||||||
|
|
||||||
|
SHELL=/bin/sh
|
||||||
|
SRC = $(wildcard ${SRCDIR}/*.cpp ${SRCDIR}/*/*.cpp)
|
||||||
|
OBJ = ${SRC:${SRCDIR}/%.cpp=${OBJDIR}/%.o}
|
||||||
|
|
||||||
|
|
||||||
|
all: fmtest
|
||||||
|
|
||||||
|
${OBJ}: $(OBJDIR)/%.o : $(SRCDIR)/%.cpp
|
||||||
|
@echo CXX $<
|
||||||
|
${CXX} -o $@ ${INCDIR} -c ${CFLAGS} ${DEFINES} $<
|
||||||
|
|
||||||
|
fmtest: ${OBJ}
|
||||||
|
@echo CXX -o ${BINDIR}/fmtest
|
||||||
|
@mkdir -p ${BINDIR}
|
||||||
|
${CXX} ${INCDIR} -o ${BINDIR}/fmtest ${OBJ} ${LDFLAGS} ${CFLAGS} ${DEFINES}
|
||||||
|
|
||||||
|
clean:
|
||||||
|
@echo cleaning
|
||||||
|
@rm -f ${OBJ}
|
||||||
|
|
||||||
|
remove: clean
|
||||||
|
@echo deleting binary
|
||||||
|
@rm -f ${BINDIR}/${TARGET}
|
||||||
|
@rm -r ${BINDIR}
|
||||||
|
|
||||||
|
install: fmtest
|
||||||
|
mkdir -p ${INSTALLDIR}
|
||||||
|
cp ${BINDIR}/${TARGET} ${INSTALLDIR}/${TARGET}
|
||||||
|
chmod 4555 ${INSTALLDIR}/${TARGET}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue