Here’s what I came up with tonight when creating an oscilloscope;
getValue returns a Hz / clock accurate sine wave
getAll returns a vector of multiple sine values going back in time set (set by int fidelity)
class PerfectSine {
public:
float frequency = 0;
float timestamp = 0;
vector<float> all;
OscGui offset, freq, amp;
void setup(ofxDatGui * gui, string name, int maxFreq = 100) {
offset.setup(gui, name + " offset", "slider", 0, 0, 1); // gui, label, type, value, min, max
freq.setup(gui, name + " freq", "slider", 20, 0, maxFreq); // gui, label, type, value, min, max
amp.setup(gui, name + " amp", "slider", 1, 0, 1); // gui, label, type, value, min, max
}
float getSine(float elapsed) {
float scaled = elapsed * (M_TWO_PI * freq.getValue());
frequency = (scaled > M_TWO_PI) ? 0 + (scaled - M_TWO_PI): frequency + scaled;
timestamp = ofGetElapsedTimef();
float sine = sin(frequency) * amp.getValue();
return sine;
}
float getValue(float min = -1, float max = 1) {
float elapsed = ofGetElapsedTimef() - timestamp;
return ofMap(getSine(elapsed), -1, 1, min, max);
}
vector<float> getAll(int fidelity, float min = -1, float max = 1) {
all.clear();
for (int i = 0; i < fidelity; i ++) {
float elapsed = (ofGetElapsedTimef() - (i * 0.00001)) - timestamp;
all.push_back(ofMap(getSine(elapsed), -1, 1, min, max));
}
return all;
}
};
NB. OscGui is a class wrapping in some ofxDatGui sliders