Add time reset signal when transport relocates
Signed-off-by: falkTX <falktx@falktx.com>
This commit is contained in:
parent
3898ea976e
commit
9eb1583671
4 changed files with 37 additions and 13 deletions
|
|
@ -26,13 +26,14 @@ struct HostTime : Module {
|
||||||
};
|
};
|
||||||
enum HostTimeIds {
|
enum HostTimeIds {
|
||||||
kHostTimeRolling,
|
kHostTimeRolling,
|
||||||
|
kHostTimeReset,
|
||||||
kHostTimeBar,
|
kHostTimeBar,
|
||||||
kHostTimeBeat,
|
kHostTimeBeat,
|
||||||
kHostTimeClock,
|
kHostTimeClock,
|
||||||
kHostTimeCount
|
kHostTimeCount
|
||||||
};
|
};
|
||||||
|
|
||||||
rack::dsp::PulseGenerator pulseBar, pulseBeat, pulseClock;
|
rack::dsp::PulseGenerator pulseReset, pulseBar, pulseBeat, pulseClock;
|
||||||
float sampleTime = 0.0f;
|
float sampleTime = 0.0f;
|
||||||
|
|
||||||
HostTime()
|
HostTime()
|
||||||
|
|
@ -55,12 +56,19 @@ struct HostTime : Module {
|
||||||
{
|
{
|
||||||
if (pcontext->tick == 0.0)
|
if (pcontext->tick == 0.0)
|
||||||
{
|
{
|
||||||
|
pulseReset.trigger();
|
||||||
pulseClock.trigger();
|
pulseClock.trigger();
|
||||||
pulseBeat.trigger();
|
pulseBeat.trigger();
|
||||||
if (pcontext->beat == 1)
|
if (pcontext->beat == 1)
|
||||||
pulseBar.trigger();
|
pulseBar.trigger();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (pcontext->reset)
|
||||||
|
{
|
||||||
|
pcontext->reset = false;
|
||||||
|
pulseReset.trigger();
|
||||||
|
}
|
||||||
|
|
||||||
if ((pcontext->tick += pcontext->ticksPerFrame) >= pcontext->ticksPerBeat)
|
if ((pcontext->tick += pcontext->ticksPerFrame) >= pcontext->ticksPerBeat)
|
||||||
{
|
{
|
||||||
pcontext->tick -= pcontext->ticksPerBeat;
|
pcontext->tick -= pcontext->ticksPerBeat;
|
||||||
|
|
@ -81,16 +89,19 @@ struct HostTime : Module {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const bool hasReset = pulseReset.process(args.sampleTime);
|
||||||
const bool hasBar = pulseBar.process(args.sampleTime);
|
const bool hasBar = pulseBar.process(args.sampleTime);
|
||||||
const bool hasBeat = pulseBeat.process(args.sampleTime);
|
const bool hasBeat = pulseBeat.process(args.sampleTime);
|
||||||
const bool hasClock = pulseClock.process(args.sampleTime);
|
const bool hasClock = pulseClock.process(args.sampleTime);
|
||||||
|
|
||||||
lights[kHostTimeRolling].setBrightness(playing ? 1.0f : 0.0f);
|
lights[kHostTimeRolling].setBrightness(playing ? 1.0f : 0.0f);
|
||||||
|
lights[kHostTimeReset].setBrightnessSmooth(hasReset ? 1.0f : 0.0f, args.sampleTime * 0.5f);
|
||||||
lights[kHostTimeBar].setBrightnessSmooth(hasBar ? 1.0f : 0.0f, args.sampleTime * 0.5f);
|
lights[kHostTimeBar].setBrightnessSmooth(hasBar ? 1.0f : 0.0f, args.sampleTime * 0.5f);
|
||||||
lights[kHostTimeBeat].setBrightnessSmooth(hasBeat ? 1.0f : 0.0f, args.sampleTime);
|
lights[kHostTimeBeat].setBrightnessSmooth(hasBeat ? 1.0f : 0.0f, args.sampleTime);
|
||||||
lights[kHostTimeClock].setBrightnessSmooth(hasClock ? 1.0f : 0.0f, args.sampleTime * 2.0f);
|
lights[kHostTimeClock].setBrightnessSmooth(hasClock ? 1.0f : 0.0f, args.sampleTime * 2.0f);
|
||||||
|
|
||||||
outputs[kHostTimeRolling].setVoltage(playing ? 10.0f : 0.0f);
|
outputs[kHostTimeRolling].setVoltage(playing ? 10.0f : 0.0f);
|
||||||
|
outputs[kHostTimeReset].setVoltage(hasReset ? 10.0f : 0.0f);
|
||||||
outputs[kHostTimeBar].setVoltage(hasBar ? 10.0f : 0.0f);
|
outputs[kHostTimeBar].setVoltage(hasBar ? 10.0f : 0.0f);
|
||||||
outputs[kHostTimeBeat].setVoltage(hasBeat ? 10.0f : 0.0f);
|
outputs[kHostTimeBeat].setVoltage(hasBeat ? 10.0f : 0.0f);
|
||||||
outputs[kHostTimeClock].setVoltage(hasClock ? 10.0f : 0.0f);
|
outputs[kHostTimeClock].setVoltage(hasClock ? 10.0f : 0.0f);
|
||||||
|
|
@ -114,15 +125,17 @@ struct HostTimeWidget : ModuleWidget {
|
||||||
addChild(createWidget<ScrewBlack>(Vec(box.size.x - 2 * RACK_GRID_WIDTH, RACK_GRID_HEIGHT - RACK_GRID_WIDTH)));
|
addChild(createWidget<ScrewBlack>(Vec(box.size.x - 2 * RACK_GRID_WIDTH, RACK_GRID_HEIGHT - RACK_GRID_WIDTH)));
|
||||||
|
|
||||||
addOutput(createOutput<PJ301MPort>(Vec(startX, startY + 0 * padding), module, HostTime::kHostTimeRolling));
|
addOutput(createOutput<PJ301MPort>(Vec(startX, startY + 0 * padding), module, HostTime::kHostTimeRolling));
|
||||||
addOutput(createOutput<PJ301MPort>(Vec(startX, startY + 1 * padding), module, HostTime::kHostTimeBar));
|
addOutput(createOutput<PJ301MPort>(Vec(startX, startY + 1 * padding), module, HostTime::kHostTimeReset));
|
||||||
addOutput(createOutput<PJ301MPort>(Vec(startX, startY + 2 * padding), module, HostTime::kHostTimeBeat));
|
addOutput(createOutput<PJ301MPort>(Vec(startX, startY + 2 * padding), module, HostTime::kHostTimeBar));
|
||||||
addOutput(createOutput<PJ301MPort>(Vec(startX, startY + 3 * padding), module, HostTime::kHostTimeClock));
|
addOutput(createOutput<PJ301MPort>(Vec(startX, startY + 3 * padding), module, HostTime::kHostTimeBeat));
|
||||||
|
addOutput(createOutput<PJ301MPort>(Vec(startX, startY + 4 * padding), module, HostTime::kHostTimeClock));
|
||||||
|
|
||||||
const float x = startX + 28;
|
const float x = startX + 28;
|
||||||
addChild(createLightCentered<SmallLight<GreenLight>> (Vec(x, startY + 0 * padding + 12), module, HostTime::kHostTimeRolling));
|
addChild(createLightCentered<SmallLight<GreenLight>> (Vec(x, startY + 0 * padding + 12), module, HostTime::kHostTimeRolling));
|
||||||
addChild(createLightCentered<SmallLight<RedLight>> (Vec(x, startY + 1 * padding + 12), module, HostTime::kHostTimeBar));
|
addChild(createLightCentered<SmallLight<WhiteLight>> (Vec(x, startY + 1 * padding + 12), module, HostTime::kHostTimeReset));
|
||||||
addChild(createLightCentered<SmallLight<YellowLight>>(Vec(x, startY + 2 * padding + 12), module, HostTime::kHostTimeBeat));
|
addChild(createLightCentered<SmallLight<RedLight>> (Vec(x, startY + 2 * padding + 12), module, HostTime::kHostTimeBar));
|
||||||
addChild(createLightCentered<SmallLight<YellowLight>>(Vec(x, startY + 3 * padding + 12), module, HostTime::kHostTimeClock));
|
addChild(createLightCentered<SmallLight<YellowLight>>(Vec(x, startY + 3 * padding + 12), module, HostTime::kHostTimeBeat));
|
||||||
|
addChild(createLightCentered<SmallLight<YellowLight>>(Vec(x, startY + 4 * padding + 12), module, HostTime::kHostTimeClock));
|
||||||
}
|
}
|
||||||
|
|
||||||
void drawOutputLine(NVGcontext* const vg, const uint offset, const char* const text)
|
void drawOutputLine(NVGcontext* const vg, const uint offset, const char* const text)
|
||||||
|
|
@ -151,9 +164,10 @@ struct HostTimeWidget : ModuleWidget {
|
||||||
nvgFontSize(args.vg, 14);
|
nvgFontSize(args.vg, 14);
|
||||||
|
|
||||||
drawOutputLine(args.vg, 0, "Playing");
|
drawOutputLine(args.vg, 0, "Playing");
|
||||||
drawOutputLine(args.vg, 1, "Bar");
|
drawOutputLine(args.vg, 1, "Reset");
|
||||||
drawOutputLine(args.vg, 2, "Beat");
|
drawOutputLine(args.vg, 2, "Bar");
|
||||||
drawOutputLine(args.vg, 3, "Clock");
|
drawOutputLine(args.vg, 3, "Beat");
|
||||||
|
drawOutputLine(args.vg, 4, "Clock");
|
||||||
|
|
||||||
ModuleWidget::draw(args);
|
ModuleWidget::draw(args);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -33,7 +33,7 @@ struct CardinalPluginContext : rack::Context {
|
||||||
uint32_t bufferSize;
|
uint32_t bufferSize;
|
||||||
double sampleRate;
|
double sampleRate;
|
||||||
float parameters[kModuleParameters];
|
float parameters[kModuleParameters];
|
||||||
bool playing;
|
bool playing, reset;
|
||||||
int32_t bar, beat, beatsPerBar;
|
int32_t bar, beat, beatsPerBar;
|
||||||
double tick, tickClock, ticksPerBeat, ticksPerClock, ticksPerFrame;
|
double tick, tickClock, ticksPerBeat, ticksPerClock, ticksPerFrame;
|
||||||
Plugin* const plugin;
|
Plugin* const plugin;
|
||||||
|
|
|
||||||
|
|
@ -316,6 +316,7 @@ class CardinalPlugin : public CardinalBasePlugin
|
||||||
CardinalAudioDevice* fCurrentAudioDevice;
|
CardinalAudioDevice* fCurrentAudioDevice;
|
||||||
CardinalMidiOutputDevice* fCurrentMidiOutput;
|
CardinalMidiOutputDevice* fCurrentMidiOutput;
|
||||||
std::list<CardinalMidiInputDevice*> fMidiInputs;
|
std::list<CardinalMidiInputDevice*> fMidiInputs;
|
||||||
|
uint64_t fPreviousFrame;
|
||||||
Mutex fDeviceMutex;
|
Mutex fDeviceMutex;
|
||||||
|
|
||||||
// real values, not VCV interpreted ones
|
// real values, not VCV interpreted ones
|
||||||
|
|
@ -331,7 +332,8 @@ public:
|
||||||
fAudioBufferOut(nullptr),
|
fAudioBufferOut(nullptr),
|
||||||
fIsActive(false),
|
fIsActive(false),
|
||||||
fCurrentAudioDevice(nullptr),
|
fCurrentAudioDevice(nullptr),
|
||||||
fCurrentMidiOutput(nullptr)
|
fCurrentMidiOutput(nullptr),
|
||||||
|
fPreviousFrame(0)
|
||||||
{
|
{
|
||||||
fWindowParameters[kWindowParameterShowTooltips] = 1.0f;
|
fWindowParameters[kWindowParameterShowTooltips] = 1.0f;
|
||||||
fWindowParameters[kWindowParameterCableOpacity] = 50.0f;
|
fWindowParameters[kWindowParameterCableOpacity] = 50.0f;
|
||||||
|
|
@ -760,6 +762,8 @@ protected:
|
||||||
std::memset(fAudioBufferIn, 0, sizeof(float)*bufferSize);
|
std::memset(fAudioBufferIn, 0, sizeof(float)*bufferSize);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
fPreviousFrame = 0;
|
||||||
|
|
||||||
{
|
{
|
||||||
const MutexLocker cml(fDeviceMutex);
|
const MutexLocker cml(fDeviceMutex);
|
||||||
|
|
||||||
|
|
@ -829,6 +833,11 @@ protected:
|
||||||
context->ticksPerFrame = 1.0 / samplesPerTick;
|
context->ticksPerFrame = 1.0 / samplesPerTick;
|
||||||
context->tickClock = std::fmod(timePos.bbt.tick, context->ticksPerClock);
|
context->tickClock = std::fmod(timePos.bbt.tick, context->ticksPerClock);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (timePos.playing && fPreviousFrame + frames != timePos.frame)
|
||||||
|
context->reset = true;
|
||||||
|
|
||||||
|
fPreviousFrame = timePos.frame;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::memset(fAudioBufferOut, 0, sizeof(float)*frames*DISTRHO_PLUGIN_NUM_OUTPUTS);
|
std::memset(fAudioBufferOut, 0, sizeof(float)*frames*DISTRHO_PLUGIN_NUM_OUTPUTS);
|
||||||
|
|
|
||||||
|
|
@ -40,7 +40,7 @@ struct CardinalPluginContext : rack::Context {
|
||||||
uint32_t bufferSize;
|
uint32_t bufferSize;
|
||||||
double sampleRate;
|
double sampleRate;
|
||||||
float parameters[kModuleParameters];
|
float parameters[kModuleParameters];
|
||||||
bool playing;
|
bool playing, reset;
|
||||||
int32_t bar, beat, beatsPerBar;
|
int32_t bar, beat, beatsPerBar;
|
||||||
double tick, tickClock, ticksPerBeat, ticksPerClock, ticksPerFrame;
|
double tick, tickClock, ticksPerBeat, ticksPerClock, ticksPerFrame;
|
||||||
Plugin* const plugin;
|
Plugin* const plugin;
|
||||||
|
|
@ -49,6 +49,7 @@ struct CardinalPluginContext : rack::Context {
|
||||||
: bufferSize(p->getBufferSize()),
|
: bufferSize(p->getBufferSize()),
|
||||||
sampleRate(p->getSampleRate()),
|
sampleRate(p->getSampleRate()),
|
||||||
playing(false),
|
playing(false),
|
||||||
|
reset(false),
|
||||||
bar(0),
|
bar(0),
|
||||||
beat(0),
|
beat(0),
|
||||||
beatsPerBar(0),
|
beatsPerBar(0),
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue