#include "UGens.h" #include #include #include #include using namespace std; Patch::Patch() { _start = new Outlet; _end = new Inlet(this); } Patch::~Patch() { delete _start; delete _end; } void Patch::receive_sample(double sample, Inlet* inlet) { _result = sample; } double Patch::sendSample(double sample) { _start->send(sample); return _result; } Inlet::Inlet(PatchNode* node) { _node = node; } void Inlet::receive(double sample) { _node->receive_sample(sample, this); } void Outlet::send(double sample) { for (unsigned i = 0; i < _inlets.size(); i++) { _inlets[i]->receive(sample); } } void Outlet::connect_to(Inlet* inlet) { _inlets.push_back(inlet); } DelayLine::DelayLine(int nSamp) { _inlet = new Inlet(this); _outlet = new Outlet; _buffer_length = nSamp; _sample_buffer = new double[nSamp]; memset((char*)_sample_buffer,'\0',sizeof(double)*nSamp); _p = 0; } void DelayLine::noise_fill() { for (int i = 0; i < _buffer_length; i++) { _sample_buffer[i] = 2 * double(rand())/RAND_MAX - 1; } } void DelayLine::receive_sample(double sample, Inlet* inlet) { double result = writeSample(sample); _outlet->send(result); } DelayLine::~DelayLine() { delete _sample_buffer; } double DelayLine::readSample() { double result; if (_p == _buffer_length - 1) result = _sample_buffer[0]; else result = _sample_buffer[_p+1]; return result; } double DelayLine::writeSample(double samp) { _sample_buffer[_p] = samp; double result = readSample(); _p = (_p + 1)%_buffer_length ; return result; } Mult::Mult() { _factor = 0; _inlet = new Inlet(this); _passive_inlet = new Inlet(this); _outlet = new Outlet; } Mult::Mult(double factor) { _factor = factor; _inlet = new Inlet(this); _passive_inlet = new Inlet(this); _outlet = new Outlet; } void Mult::receive_sample(double sample, Inlet* inlet) { if (inlet == _inlet) { _outlet->send(sample * _factor); } else { // passive inlet _factor = sample; } } Add::Add() { _to_add = 0; _inlet = new Inlet(this); _passive_inlet = new Inlet(this); _outlet = new Outlet; } Add::Add(double to_add) { _to_add = to_add; _inlet = new Inlet(this); _passive_inlet = new Inlet(this); _outlet = new Outlet; } void Add::receive_sample(double sample, Inlet* inlet) { if (inlet == _inlet) { _outlet->send(sample + _to_add); } else { // passive inlet _to_add = sample; } } OneZero::OneZero() { _prev = 0; _inlet = new Inlet(this); _outlet = new Outlet; } void OneZero::receive_sample(double sample, Inlet* inlet) { _outlet->send( .5 * sample + .5 * _prev); _prev = sample; } Karplus::Karplus(double freq) { int delay_len = 1/freq * 44100; _dl = new DelayLine(delay_len); float res = 1 - delay_len * .00005; if (res < .5) res = .5; Mult* mult = new Mult(res); Add* add = new Add; OneZero* oz = new OneZero; _inlet = add->_inlet; _outlet = _dl->_outlet; add->_outlet->connect_to(_dl->_inlet); _dl->_outlet->connect_to(mult->_inlet); mult->_outlet->connect_to(oz->_inlet); oz->_outlet->connect_to(add->_passive_inlet); } void Karplus::pluck() { _dl->noise_fill(); } void Karplus::receive_sample(double sample, Inlet* inlet) { // this shouldn't get called cout << "oh crap" << endl; } KarplusPatch::KarplusPatch(double freq) { _karplus = new Karplus(freq); _start->connect_to(_karplus->_inlet); _karplus->_outlet->connect_to(_end); } void KarplusPatch::pluck() { _karplus->pluck(); }