added input clock resolution other than 24ppqn

develop
midilab 6 days ago
parent 4203dbb613
commit c7b081954d
  1. 65
      src/uClock.cpp
  2. 14
      src/uClock.h

@ -130,8 +130,8 @@ uClockClass::uClockClass()
onStepCallback = nullptr; onStepCallback = nullptr;
onClockStartCallback = nullptr; onClockStartCallback = nullptr;
onClockStopCallback = nullptr; onClockStopCallback = nullptr;
// first ppqn references calculus // first ppqn references calculus for ppqn and clock resolution
setPPQN(PPQN_96); calculateReferencedata();
} }
void uClockClass::init() void uClockClass::init()
@ -146,15 +146,30 @@ uint32_t uClockClass::bpmToMicroSeconds(float bpm)
return (60000000.0f / (float)ppqn / bpm); return (60000000.0f / (float)ppqn / bpm);
} }
void uClockClass::calculateReferencedata()
{
mod_clock_ref = ppqn / clock_ppqn;
mod_sync24_ref = ppqn / PPQN_24;
mod_step_ref = ppqn / 4;
}
void uClockClass::setPPQN(PPQNResolution resolution) void uClockClass::setPPQN(PPQNResolution resolution)
{ {
// stop clock to make it safe changing those references // stop clock to make it safe changing those references
// so we avoid volatile then and ATOMIC everyone // so we avoid volatile then and ATOMIC everywhere
stop(); stop();
ppqn = resolution; ppqn = resolution;
// calculate the mod24 and mod_step tick reference trigger calculateReferencedata();
mod24_ref = ppqn / 24; }
mod_step_ref = ppqn / 4;
void uClockClass::setClockPPQN(PPQNResolution resolution)
{
// stop clock to make it safe changing those references
// so we avoid volatile then and ATOMIC everywhere
stop();
clock_ppqn = resolution;
calculateReferencedata();
//mod_clock_ref = ppqn / clock_ppqn;
} }
void uClockClass::start() void uClockClass::start()
@ -238,7 +253,6 @@ void uClockClass::run()
#endif #endif
} }
// this function is based on sync24PPQN
float inline uClockClass::freqToBpm(uint32_t freq) float inline uClockClass::freqToBpm(uint32_t freq)
{ {
float usecs = 1/((float)freq/1000000.0); float usecs = 1/((float)freq/1000000.0);
@ -268,8 +282,10 @@ void uClockClass::resetCounters()
{ {
tick = 0; tick = 0;
int_clock_tick = 0; int_clock_tick = 0;
mod24_counter = 0; sync24_tick = 0;
mod_clock_counter = 0;
mod_step_counter = 0; mod_step_counter = 0;
mod_sync24_counter = 0;
step_counter = 0; step_counter = 0;
ext_clock_tick = 0; ext_clock_tick = 0;
ext_clock_us = 0; ext_clock_us = 0;
@ -371,7 +387,7 @@ bool inline uClockClass::processShuffle()
return false; return false;
} }
// it is expected to be called in 24PPQN // TODO: needs to check clock signals against current phase lock parameters(based on 24ppqn sync)
void uClockClass::handleExternalClock() void uClockClass::handleExternalClock()
{ {
switch (state) { switch (state) {
@ -408,19 +424,19 @@ void uClockClass::handleExternalClock()
void uClockClass::handleTimerInt() void uClockClass::handleTimerInt()
{ {
// reset mod24 counter reference ? // reset mod_clock_counter
if (mod24_counter == mod24_ref) if (mod_clock_counter == mod_clock_ref)
mod24_counter = 0; mod_clock_counter = 0;
// process sync signals first please... // process sync signals first please...
if (mod24_counter == 0) { if (mod_clock_counter == 0) {
if (mode == EXTERNAL_CLOCK) { if (mode == EXTERNAL_CLOCK) {
// sync tick position with external tick clock // sync tick position with external tick clock
if ((int_clock_tick < ext_clock_tick) || (int_clock_tick > (ext_clock_tick + 1))) { if ((int_clock_tick < ext_clock_tick) || (int_clock_tick > (ext_clock_tick + 1))) {
int_clock_tick = ext_clock_tick; int_clock_tick = ext_clock_tick;
tick = int_clock_tick * mod24_ref; tick = int_clock_tick * mod_clock_ref;
mod24_counter = tick % mod24_ref; mod_clock_counter = tick % mod_clock_ref;
mod_step_counter = tick % mod_step_ref; mod_step_counter = tick % mod_step_ref;
} }
@ -446,13 +462,21 @@ void uClockClass::handleTimerInt()
} }
} }
if (onSync24Callback) { // internal clock tick me!
onSync24Callback(int_clock_tick);
}
// internal clock tick me! sync24 tick too
++int_clock_tick; ++int_clock_tick;
} }
// Sync24 callback
if (mod_sync24_counter == mod_sync24_ref)
mod_sync24_counter = 0;
if (onSync24Callback) {
if (mod_sync24_counter == 0) {
onSync24Callback(sync24_tick);
++sync24_tick;
}
}
// PPQNCallback time! // PPQNCallback time!
if (onPPQNCallback) { if (onPPQNCallback) {
onPPQNCallback(tick); onPPQNCallback(tick);
@ -476,7 +500,8 @@ void uClockClass::handleTimerInt()
// tick me! // tick me!
++tick; ++tick;
// increment mod counters // increment mod counters
++mod24_counter; ++mod_clock_counter;
++mod_sync24_counter;
++mod_step_counter; ++mod_step_counter;
} }

@ -84,6 +84,9 @@ class uClockClass {
}; };
enum PPQNResolution { enum PPQNResolution {
PPQN_4 = 4,
PPQN_8 = 8,
PPQN_12 = 12,
PPQN_24 = 24, PPQN_24 = 24,
PPQN_48 = 48, PPQN_48 = 48,
PPQN_96 = 96, PPQN_96 = 96,
@ -118,6 +121,7 @@ class uClockClass {
void init(); void init();
void setPPQN(PPQNResolution resolution); void setPPQN(PPQNResolution resolution);
void setClockPPQN(PPQNResolution resolution);
void handleTimerInt(); void handleTimerInt();
void handleExternalClock(); void handleExternalClock();
@ -162,6 +166,7 @@ class uClockClass {
private: private:
float inline freqToBpm(uint32_t freq); float inline freqToBpm(uint32_t freq);
void calculateReferencedata();
// shuffle // shuffle
bool inline processShuffle(); bool inline processShuffle();
@ -175,14 +180,17 @@ class uClockClass {
// internal clock control // internal clock control
// uint16_t ppqn; // uint16_t ppqn;
PPQNResolution ppqn = PPQN_96; PPQNResolution ppqn = PPQN_96;
PPQNResolution clock_ppqn = PPQN_24;
uint32_t tick; uint32_t tick;
uint32_t int_clock_tick; uint32_t int_clock_tick;
uint8_t mod24_counter; uint32_t sync24_tick;
uint8_t mod24_ref; uint8_t mod_clock_counter;
uint8_t mod_clock_ref;
uint8_t mod_step_counter; uint8_t mod_step_counter;
uint8_t mod_step_ref; uint8_t mod_step_ref;
uint32_t step_counter; // should we go uint16_t? uint32_t step_counter; // should we go uint16_t?
uint8_t mod_sync24_counter;
uint8_t mod_sync24_ref;
// external clock control // external clock control
volatile uint32_t ext_clock_us; volatile uint32_t ext_clock_us;
volatile uint32_t ext_clock_tick; volatile uint32_t ext_clock_tick;

Loading…
Cancel
Save