#include "ArrayArithmetic.h"
#include "DspLine.h"
#include "PdGraph.h"
message::Object *DspLine::new_object(pd::Message *init_message, PdGraph *graph) {
return new DspLine(init_message, graph);
}
DspLine::DspLine(pd::Message *init_message, PdGraph *graph) : DspObject(2, 0, 0, 1, graph) {
target = 0.0f;
slope = 0.0f;
numSamplesToTarget = 0.0f;
lastOutputSample = 0.0f;
}
DspLine::~DspLine() {
}
void DspLine::process_message(int inlet_index, pd::Message *message) {
if (inlet_index == 0) { switch (message->get_num_elements()) {
case 0: {
break; }
case 1: {
if (message->is_float(0)) {
target = message->get_float(0);
lastOutputSample = target;
slope = 0.0f;
numSamplesToTarget = 0.0f;
}
break;
}
default: { if (message->is_float(0) && message->is_float(1)) {
target = message->get_float(0);
float timeToTargetMs = message->get_float(1); numSamplesToTarget = utils::millisecondsToSamples(
(timeToTargetMs < 1.0f) ? 1.0f : timeToTargetMs, graph->get_sample_rate());
slope = (target - lastOutputSample) / numSamplesToTarget;
}
break;
}
}
}
}
void DspLine::processDspWithIndex(int fromIndex, int toIndex) {
if (numSamplesToTarget <= 0.0f) { int n = toIndex - fromIndex;
if (n > 0) { ArrayArithmetic::fill(dspBufferAtOutlet[0], target, fromIndex, toIndex);
lastOutputSample = target;
}
} else {
int n = toIndex - fromIndex;
if (n > 0) { if (numSamplesToTarget < n) {
int targetIndexInt = fromIndex + numSamplesToTarget;
#if __APPLE__
vDSP_vramp(&lastOutputSample, &slope, dspBufferAtOutlet[0]+fromIndex, 1, targetIndexInt-fromIndex);
vDSP_vfill(&target, dspBufferAtOutlet[0]+targetIndexInt, 1, toIndex-targetIndexInt);
#else
dspBufferAtOutlet[0][fromIndex] = lastOutputSample;
for (int i = fromIndex+1; i < targetIndexInt; i++) {
dspBufferAtOutlet[0][i] = dspBufferAtOutlet[0][i-1] + slope;
}
for (int i = targetIndexInt; i < toIndex; i++) {
dspBufferAtOutlet[0][i] = target;
}
#endif
lastOutputSample = target;
numSamplesToTarget = 0;
} else {
#if __APPLE__
vDSP_vramp(&lastOutputSample, &slope, dspBufferAtOutlet[0]+fromIndex, 1, n);
#else
dspBufferAtOutlet[0][fromIndex] = lastOutputSample;
for (int i = fromIndex+1; i < toIndex; i++) {
dspBufferAtOutlet[0][i] = dspBufferAtOutlet[0][i-1] + slope;
}
#endif
lastOutputSample = dspBufferAtOutlet[0][toIndex-1] + slope;
numSamplesToTarget -= n;
}
}
}
}