Skip to content

Commit

Permalink
move host transport events to separate template and allow without mid…
Browse files Browse the repository at this point in the history
…i input
  • Loading branch information
dromer committed Oct 13, 2024
1 parent 1c6947e commit 4300592
Show file tree
Hide file tree
Showing 6 changed files with 74 additions and 67 deletions.
3 changes: 2 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,8 @@ Next Release
Features:

* Migrating to poetry for project management
* Allow modgui on desktop
* DPF: Allow modgui on desktop
* DPF: Allow host transport events without midi input

Bugfixes:

Expand Down
2 changes: 2 additions & 0 deletions hvcc/generators/c2dpf/templates/HeavyDPF.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -193,6 +193,7 @@ void {{class_name}}::setOutputParameter(uint32_t sendHash, const HvMessage *m)
#endif
{% endif %}

{% include 'hostTransportEvents.cpp' %}


// -------------------------------------------------------------------
Expand All @@ -206,6 +207,7 @@ void {{class_name}}::run(const float** inputs, float** outputs, uint32_t frames,
void {{class_name}}::run(const float** inputs, float** outputs, uint32_t frames)
{
#endif
hostTransportEvents(frames);
{% if meta.denormals is sameas false %}
const ScopedDenormalDisable sdd;
{% endif %}
Expand Down
1 change: 1 addition & 0 deletions hvcc/generators/c2dpf/templates/HeavyDPF.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ class {{class_name}} : public Plugin

void handleMidiInput(uint32_t frames, const MidiEvent* midiEvents, uint32_t midiEventCount);
void handleMidiSend(uint32_t sendHash, const HvMessage *m);
void hostTransportEvents(uint32_t frames);
void setOutputParameter(uint32_t sendHash, const HvMessage *m);

protected:
Expand Down
66 changes: 66 additions & 0 deletions hvcc/generators/c2dpf/templates/hostTransportEvents.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
// -------------------------------------------------------------------
// Host Transport Events handler

void {{class_name}}::hostTransportEvents(uint32_t frames)
{
// Realtime events
const TimePosition& timePos(getTimePosition());
bool reset = false;

if (timePos.playing)
{
if (timePos.frame == 0)
{
_context->sendMessageToReceiverV(HV_HASH_MIDIREALTIMEIN, 0,
"ff", (float) MIDI_RT_RESET, 0);
reset = true;
}

if (! this->wasPlaying)
{
if (timePos.frame == 0)
{
_context->sendMessageToReceiverV(HV_HASH_MIDIREALTIMEIN, 0,
"ff", (float) MIDI_RT_START, 0);
}
if (! reset)
{
_context->sendMessageToReceiverV(HV_HASH_MIDIREALTIMEIN, 0,
"ff", (float) MIDI_RT_CONTINUE, 0);
}
}
}
else if (this->wasPlaying)
{
_context->sendMessageToReceiverV(HV_HASH_MIDIREALTIMEIN, 0,
"ff", (float) MIDI_RT_STOP, 0);
}
this->wasPlaying = timePos.playing;

// sending clock ticks
if (timePos.playing && timePos.bbt.valid)
{
float samplesPerBeat = 60 * getSampleRate() / timePos.bbt.beatsPerMinute;
float samplesPerTick = samplesPerBeat / 24.0;

/* get state */
double nextClockTick = this->nextClockTick;
double sampleAtCycleStart = this->sampleAtCycleStart;
double sampleAtCycleEnd = sampleAtCycleStart + frames;

if (nextClockTick >= 0 && sampleAtCycleStart >= 0 && sampleAtCycleEnd > sampleAtCycleStart) {
while (nextClockTick < sampleAtCycleEnd) {
double delayMs = 1000*(nextClockTick - sampleAtCycleStart)/getSampleRate();
if (delayMs >= 0.0) {
_context->sendMessageToReceiverV(HV_HASH_MIDIREALTIMEIN, delayMs,
"ff", (float) MIDI_RT_CLOCK, 0);
}
nextClockTick += samplesPerTick;
}
}

/* save variables for next cycle */
this->sampleAtCycleStart = sampleAtCycleEnd;
this->nextClockTick = nextClockTick;
}
}
61 changes: 0 additions & 61 deletions hvcc/generators/c2dpf/templates/midiInput.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,67 +3,6 @@

void {{class_name}}::handleMidiInput(uint32_t frames, const MidiEvent* midiEvents, uint32_t midiEventCount)
{
// Realtime events
const TimePosition& timePos(getTimePosition());
bool reset = false;

if (timePos.playing)
{
if (timePos.frame == 0)
{
_context->sendMessageToReceiverV(HV_HASH_MIDIREALTIMEIN, 0,
"ff", (float) MIDI_RT_RESET);
reset = true;
}

if (! this->wasPlaying)
{
if (timePos.frame == 0)
{
_context->sendMessageToReceiverV(HV_HASH_MIDIREALTIMEIN, 0,
"ff", (float) MIDI_RT_START);
}
if (! reset)
{
_context->sendMessageToReceiverV(HV_HASH_MIDIREALTIMEIN, 0,
"ff", (float) MIDI_RT_CONTINUE);
}
}
}
else if (this->wasPlaying)
{
_context->sendMessageToReceiverV(HV_HASH_MIDIREALTIMEIN, 0,
"ff", (float) MIDI_RT_STOP);
}
this->wasPlaying = timePos.playing;

// sending clock ticks
if (timePos.playing && timePos.bbt.valid)
{
float samplesPerBeat = 60 * getSampleRate() / timePos.bbt.beatsPerMinute;
float samplesPerTick = samplesPerBeat / 24.0;

/* get state */
double nextClockTick = this->nextClockTick;
double sampleAtCycleStart = this->sampleAtCycleStart;
double sampleAtCycleEnd = sampleAtCycleStart + frames;

if (nextClockTick >= 0 && sampleAtCycleStart >= 0 && sampleAtCycleEnd > sampleAtCycleStart) {
while (nextClockTick < sampleAtCycleEnd) {
double delayMs = 1000*(nextClockTick - sampleAtCycleStart)/getSampleRate();
if (delayMs >= 0.0) {
_context->sendMessageToReceiverV(HV_HASH_MIDIREALTIMEIN, delayMs,
"ff", (float) MIDI_RT_CLOCK);
}
nextClockTick += samplesPerTick;
}
}

/* save variables for next cycle */
this->sampleAtCycleStart = sampleAtCycleEnd;
this->nextClockTick = nextClockTick;
}

// Midi events
for (uint32_t i=0; i < midiEventCount; ++i)
{
Expand Down
8 changes: 3 additions & 5 deletions hvcc/interpreters/pd2hv/libs/pd/midirealtimein.pd
Original file line number Diff line number Diff line change
@@ -1,11 +1,9 @@
#N canvas 951 312 204 190 12;
#X obj 87 127 outlet;
#X obj 86 148 outlet;
#X obj 20 148 outlet;
#X text 23 13 data port;
#X obj 20 61 unpack f f;
#X obj 87 94 + 1;
#X obj 20 37 r __hv_midirealtimein;
#X connect 3 0 1 0;
#X connect 3 1 4 0;
#X connect 4 0 0 0;
#X connect 5 0 3 0;
#X connect 3 1 0 0;
#X connect 4 0 3 0;

0 comments on commit 4300592

Please sign in to comment.