|
|
@@ -79,55 +79,54 @@ struct MIDI_Map : Module { |
|
|
|
} |
|
|
|
|
|
|
|
void process(const ProcessArgs& args) override { |
|
|
|
if (divider.process()) { |
|
|
|
// Process MIDI messages only if they arrived `stepFrames` frames ago. |
|
|
|
while (!midiInput.queue.empty()) { |
|
|
|
midi::Message& msg = midiInput.queue.front(); |
|
|
|
int64_t msgTime = msg.timestamp + int64_t(APP->engine->getStepFrames() * APP->engine->getSampleTime() * 1e9); |
|
|
|
int64_t frameTime = APP->engine->getStepTime() + int64_t((APP->engine->getFrame() - APP->engine->getStepFrame()) * APP->engine->getSampleTime() * 1e9); |
|
|
|
if (msgTime > frameTime) |
|
|
|
break; |
|
|
|
processMessage(msg); |
|
|
|
midiInput.queue.pop(); |
|
|
|
} |
|
|
|
if (!divider.process()) |
|
|
|
return; |
|
|
|
|
|
|
|
// Step channels |
|
|
|
for (int id = 0; id < mapLen; id++) { |
|
|
|
int cc = ccs[id]; |
|
|
|
if (cc < 0) |
|
|
|
continue; |
|
|
|
// Get Module |
|
|
|
Module* module = paramHandles[id].module; |
|
|
|
if (!module) |
|
|
|
continue; |
|
|
|
// Get ParamQuantity from ParamHandle |
|
|
|
int paramId = paramHandles[id].paramId; |
|
|
|
ParamQuantity* paramQuantity = module->paramQuantities[paramId]; |
|
|
|
if (!paramQuantity) |
|
|
|
continue; |
|
|
|
if (!paramQuantity->isBounded()) |
|
|
|
continue; |
|
|
|
// Set filter from param value if filter is uninitialized |
|
|
|
if (!filterInitialized[id]) { |
|
|
|
valueFilters[id].out = paramQuantity->getScaledValue(); |
|
|
|
filterInitialized[id] = true; |
|
|
|
continue; |
|
|
|
} |
|
|
|
// Check if CC has been set by the MIDI device |
|
|
|
if (values[cc] < 0) |
|
|
|
continue; |
|
|
|
float value = values[cc] / 127.f; |
|
|
|
// Detect behavior from MIDI buttons. |
|
|
|
if (smooth && std::fabs(valueFilters[id].out - value) < 1.f) { |
|
|
|
// Smooth value with filter |
|
|
|
valueFilters[id].process(args.sampleTime * divider.getDivision(), value); |
|
|
|
} |
|
|
|
else { |
|
|
|
// Jump value |
|
|
|
valueFilters[id].out = value; |
|
|
|
} |
|
|
|
paramQuantity->setScaledValue(valueFilters[id].out); |
|
|
|
while (!midiInput.queue.empty()) { |
|
|
|
midi::Message& msg = midiInput.queue.front(); |
|
|
|
// Don't process MIDI message until its timestamp corresponds with the audio frame time when played back in the next block. |
|
|
|
if (msg.timestamp + APP->engine->getStepDuration() > APP->engine->getFrameTime()) |
|
|
|
break; |
|
|
|
processMessage(msg); |
|
|
|
midiInput.queue.pop(); |
|
|
|
} |
|
|
|
|
|
|
|
// Step channels |
|
|
|
for (int id = 0; id < mapLen; id++) { |
|
|
|
int cc = ccs[id]; |
|
|
|
if (cc < 0) |
|
|
|
continue; |
|
|
|
// Get Module |
|
|
|
Module* module = paramHandles[id].module; |
|
|
|
if (!module) |
|
|
|
continue; |
|
|
|
// Get ParamQuantity from ParamHandle |
|
|
|
int paramId = paramHandles[id].paramId; |
|
|
|
ParamQuantity* paramQuantity = module->paramQuantities[paramId]; |
|
|
|
if (!paramQuantity) |
|
|
|
continue; |
|
|
|
if (!paramQuantity->isBounded()) |
|
|
|
continue; |
|
|
|
// Set filter from param value if filter is uninitialized |
|
|
|
if (!filterInitialized[id]) { |
|
|
|
valueFilters[id].out = paramQuantity->getScaledValue(); |
|
|
|
filterInitialized[id] = true; |
|
|
|
continue; |
|
|
|
} |
|
|
|
// Check if CC has been set by the MIDI device |
|
|
|
if (values[cc] < 0) |
|
|
|
continue; |
|
|
|
float value = values[cc] / 127.f; |
|
|
|
// Detect behavior from MIDI buttons. |
|
|
|
if (smooth && std::fabs(valueFilters[id].out - value) < 1.f) { |
|
|
|
// Smooth value with filter |
|
|
|
valueFilters[id].process(args.sampleTime * divider.getDivision(), value); |
|
|
|
} |
|
|
|
else { |
|
|
|
// Jump value |
|
|
|
valueFilters[id].out = value; |
|
|
|
} |
|
|
|
paramQuantity->setScaledValue(valueFilters[id].out); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|