added input clock resolution other than 24ppqn

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

@ -130,8 +130,8 @@ uClockClass::uClockClass()
onStepCallback = nullptr;
onClockStartCallback = nullptr;
onClockStopCallback = nullptr;
// first ppqn references calculus
setPPQN(PPQN_96);
// first ppqn references calculus for ppqn and clock resolution
calculateReferencedata();
}
void uClockClass::init()
@ -146,15 +146,30 @@ uint32_t uClockClass::bpmToMicroSeconds(float 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)
{
// 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();
ppqn = resolution;
// calculate the mod24 and mod_step tick reference trigger
mod24_ref = ppqn / 24;
mod_step_ref = ppqn / 4;
calculateReferencedata();
}
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()
@ -238,7 +253,6 @@ void uClockClass::run()
#endif
}
// this function is based on sync24PPQN
float inline uClockClass::freqToBpm(uint32_t freq)
{
float usecs = 1/((float)freq/1000000.0);
@ -268,8 +282,10 @@ void uClockClass::resetCounters()
{
tick = 0;
int_clock_tick = 0;
mod24_counter = 0;
sync24_tick = 0;
mod_clock_counter = 0;
mod_step_counter = 0;
mod_sync24_counter = 0;
step_counter = 0;
ext_clock_tick = 0;
ext_clock_us = 0;
@ -371,7 +387,7 @@ bool inline uClockClass::processShuffle()
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()
{
switch (state) {
@ -408,19 +424,19 @@ void uClockClass::handleExternalClock()
void uClockClass::handleTimerInt()
{
// reset mod24 counter reference ?
if (mod24_counter == mod24_ref)
mod24_counter = 0;
// reset mod_clock_counter
if (mod_clock_counter == mod_clock_ref)
mod_clock_counter = 0;
// process sync signals first please...
if (mod24_counter == 0) {
if (mod_clock_counter == 0) {
if (mode == EXTERNAL_CLOCK) {
// sync tick position with external tick clock
if ((int_clock_tick < ext_clock_tick) || (int_clock_tick > (ext_clock_tick + 1))) {
int_clock_tick = ext_clock_tick;
tick = int_clock_tick * mod24_ref;
mod24_counter = tick % mod24_ref;
tick = int_clock_tick * mod_clock_ref;
mod_clock_counter = tick % mod_clock_ref;
mod_step_counter = tick % mod_step_ref;
}
@ -446,11 +462,19 @@ void uClockClass::handleTimerInt()
}
}
// internal clock tick me!
++int_clock_tick;
}
// Sync24 callback
if (mod_sync24_counter == mod_sync24_ref)
mod_sync24_counter = 0;
if (onSync24Callback) {
onSync24Callback(int_clock_tick);
if (mod_sync24_counter == 0) {
onSync24Callback(sync24_tick);
++sync24_tick;
}
// internal clock tick me! sync24 tick too
++int_clock_tick;
}
// PPQNCallback time!
@ -476,7 +500,8 @@ void uClockClass::handleTimerInt()
// tick me!
++tick;
// increment mod counters
++mod24_counter;
++mod_clock_counter;
++mod_sync24_counter;
++mod_step_counter;
}

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

Loading…
Cancel
Save