- BPM display use BPM calculation from LFO

- LFO: fixed S&H waveforms

git-svn-id: http://moon:8086/svn/software/trunk/projects/JaySynth@737 b431acfa-c32f-4a4a-93f1-934dc6c82436
This commit is contained in:
2020-08-24 11:46:40 +00:00
parent ef6d5fdb7e
commit 62a2d47cb3
6 changed files with 25 additions and 28 deletions
+8 -18
View File
@@ -129,8 +129,6 @@ JaySynth::JaySynth (int num_voices, String pathToWaves)
} }
m_clock_cnt_bar = 0; m_clock_cnt_bar = 0;
m_lastTime_ms = 0;
m_estimatedTime_ms = 0;
m_numMidiClocksPerBeat = 1; m_numMidiClocksPerBeat = 1;
m_numMidiClocksPerBar = 1; m_numMidiClocksPerBar = 1;
m_isMidiClockStarted = false; m_isMidiClockStarted = false;
@@ -1132,7 +1130,6 @@ void JaySynth::handleMidiEvent (const MidiMessage& m)
SynthDebug("SongPositionPointer\n"); SynthDebug("SongPositionPointer\n");
m_clock_cnt_bar = (6 * m.getSongPositionPointerMidiBeat()) % m_numMidiClocksPerBar; m_clock_cnt_bar = (6 * m.getSongPositionPointerMidiBeat()) % m_numMidiClocksPerBar;
SynthDebug("getSongPositionPointerMidiBeat(): %u -> %u clocks\n", m.getSongPositionPointerMidiBeat(), m_clock_cnt_bar); SynthDebug("getSongPositionPointerMidiBeat(): %u -> %u clocks\n", m.getSongPositionPointerMidiBeat(), m_clock_cnt_bar);
m_lastTime_ms = 0;
} }
if (m.isQuarterFrame()) if (m.isQuarterFrame())
{ {
@@ -1150,30 +1147,20 @@ void JaySynth::handleMidiEvent (const MidiMessage& m)
} }
if (m.isMidiClock()) if (m.isMidiClock())
{ {
const double alpha_1 = 2.0/m_numMidiclocksPerQuarterNote;
const double currTime_ms = juce::Time::getMillisecondCounterHiRes();
// BPM Estimation
double deltaTime_ms = currTime_ms - m_lastTime_ms;
if (m_lastTime_ms > 0.0)
{
m_estimatedTime_ms = (1.0-alpha_1)*m_estimatedTime_ms + alpha_1*deltaTime_ms;
}
m_lastTime_ms = currTime_ms;
// Quarter clock generation // Quarter clock generation
m_clock_cnt_bar = m_clock_cnt_bar % m_numMidiClocksPerBar; m_clock_cnt_bar = m_clock_cnt_bar % m_numMidiClocksPerBar;
if (m_isMidiClockStarted) if (m_isMidiClockStarted)
{ {
#if WITH_DEV_SYNCED_LFO #if WITH_DEV_SYNCED_LFO
voiceSetMidiBeat(m_clock_cnt_bar); // Sync LFO and BPM Estimation
synth_float_t bpm = voiceSetMidiBeat(m_clock_cnt_bar);
#endif #endif
if (m_clock_cnt_bar % m_numMidiClocksPerBeat == 0) if (m_clock_cnt_bar % m_numMidiClocksPerBeat == 0)
{ {
// Send quarter pulse with current BPM estimation // Send quarter pulse with current BPM estimation
midi_quarter_clock_info_t info; midi_quarter_clock_info_t info;
info.bpm = (uint32_t)(m_numMidiclocksPerQuarterNote*m_estimatedTime_ms + 0.5); info.bpm = (uint32_t)(bpm + 0.5);
info.type = 1; info.type = 1;
if (m_clock_cnt_bar == 0) if (m_clock_cnt_bar == 0)
{ {
@@ -1186,13 +1173,14 @@ void JaySynth::handleMidiEvent (const MidiMessage& m)
} }
} }
void JaySynth::voiceSetMidiBeat(int barBeatCount) synth_float_t JaySynth::voiceSetMidiBeat(int barBeatCount)
{ {
synth_float_t bpm = 0;
for (int i=0; i < VOICE_NUM_LFO; i++) for (int i=0; i < VOICE_NUM_LFO; i++)
{ {
lfo_t *pLfo = &m_pVoices[0].pCom->glfo[i]; lfo_t *pLfo = &m_pVoices[0].pCom->glfo[i];
synth_float_t phase = Sync_mod((synth_float_t)barBeatCount/m_numMidiClocksPerBar); synth_float_t phase = Sync_mod((synth_float_t)barBeatCount/m_numMidiClocksPerBar);
LFO_sync(pLfo, phase); bpm += LFO_sync(pLfo, phase)/VOICE_NUM_LFO;
} }
for (int i=0; i < max_num_voices; i++) for (int i=0; i < max_num_voices; i++)
@@ -1200,6 +1188,8 @@ void JaySynth::voiceSetMidiBeat(int barBeatCount)
JaySynthVoice* const voice = voices.getUnchecked (i); JaySynthVoice* const voice = voices.getUnchecked (i);
voice->setMidiBeat(barBeatCount); voice->setMidiBeat(barBeatCount);
} }
return bpm;
} }
//============================================================================== //==============================================================================
+1 -3
View File
@@ -87,7 +87,7 @@ public:
const float velocity, bool doTrigger); const float velocity, bool doTrigger);
void Voicestop (JaySynthVoice* voice, const bool allowTailOff); void Voicestop (JaySynthVoice* voice, const bool allowTailOff);
void voiceSetMidiBeat(int quarterBeatCount); synth_float_t voiceSetMidiBeat(int quarterBeatCount);
int getNumVoicesPlaying (SynthesiserSound* soundToPlay); int getNumVoicesPlaying (SynthesiserSound* soundToPlay);
void clearKeysPressed(void); void clearKeysPressed(void);
@@ -258,8 +258,6 @@ private:
int m_clock_cnt_bar; int m_clock_cnt_bar;
int m_numMidiClocksPerBeat; int m_numMidiClocksPerBeat;
int m_numMidiClocksPerBar; int m_numMidiClocksPerBar;
double m_lastTime_ms;
double m_estimatedTime_ms;
bool m_isMidiClockStarted; bool m_isMidiClockStarted;
void updateMidiTiming(const MidiMessage& m); void updateMidiTiming(const MidiMessage& m);
+1 -2
View File
@@ -5184,10 +5184,9 @@ void JaySynthAudioProcessorEditor::actionListenerCallback (const String &message
case JaySynthActionListener::JAYSYNTH_CHANGED_MIDICLOCK: case JaySynthActionListener::JAYSYNTH_CHANGED_MIDICLOCK:
{ {
uint32_t deltaTime_ms = spa.getValue("deltatime", "-1").getIntValue(); uint32_t bpm = spa.getValue("bpm", "-1").getIntValue();
uint32_t brightness = spa.getValue("brightness", "-1").getIntValue(); uint32_t brightness = spa.getValue("brightness", "-1").getIntValue();
m_btn_midiClockLed->flash(brightness*50, brightness); m_btn_midiClockLed->flash(brightness*50, brightness);
uint32_t bpm = (uint32_t)(60*1000.0/deltaTime_ms + 0.5);
m_labelDebug->setText(String("BPM = ") + String(bpm), juce::NotificationType::dontSendNotification); m_labelDebug->setText(String("BPM = ") + String(bpm), juce::NotificationType::dontSendNotification);
} }
break; break;
+2 -2
View File
@@ -113,12 +113,12 @@ public:
sendActionMessage(s); sendActionMessage(s);
} }
void callMidiClock (uint32_t deltaTime_ms, uint32_t type) void callMidiClock (uint32_t bpm, uint32_t type)
{ {
String s; String s;
s = String("type=") + String(JAYSYNTH_CHANGED_MIDICLOCK); s = String("type=") + String(JAYSYNTH_CHANGED_MIDICLOCK);
s = s + String(" "); s = s + String(" ");
s = s + String("deltatime=") + String(deltaTime_ms); s = s + String("bpm=") + String(bpm);
s = s + String(" "); s = s + String(" ");
s = s + String("brightness=") + String(type); s = s + String("brightness=") + String(type);
s = s + String(" "); s = s + String(" ");
+12 -2
View File
@@ -178,7 +178,9 @@ void Sync_processV(lfo_t* pObj, int len)
for (int i=0; i < len; i++) for (int i=0; i < len; i++)
{ {
pObj->pPhase[i].phase = pSync->phase; pObj->pPhase[i].phase = pSync->phase;
synth_float_t phase = pSync->phase;
pSync->phase = Sync_mod(pSync->phase + omega_base); pSync->phase = Sync_mod(pSync->phase + omega_base);
pObj->pPhase[i].is_cycle_start = (phase > pSync->phase);
} }
} }
break; break;
@@ -188,7 +190,9 @@ void Sync_processV(lfo_t* pObj, int len)
for (int i=0; i < len; i++) for (int i=0; i < len; i++)
{ {
pObj->pPhase[i].phase = pSync->phase; pObj->pPhase[i].phase = pSync->phase;
synth_float_t phase = pSync->phase;
pSync->phase = Sync_mod(pSync->phase + pSync->omega); pSync->phase = Sync_mod(pSync->phase + pSync->omega);
pObj->pPhase[i].is_cycle_start = (phase > pSync->phase);
} }
} }
break; break;
@@ -197,7 +201,10 @@ void Sync_processV(lfo_t* pObj, int len)
{ {
for (int i=0; i < len; i++) for (int i=0; i < len; i++)
{ {
pObj->pPhase[i].phase = pObj->pPhase[i].phase_int; synth_float_t phase = pSync->phase;
pSync->phase = pObj->pPhase[i].phase_int;
pObj->pPhase[i].is_cycle_start = (phase > pSync->phase);
pObj->pPhase[i].phase = pSync->phase;
} }
} }
break; break;
@@ -292,11 +299,14 @@ void LFO_Reset(lfo_t *pObj, synth_float_t initial_phase)
} }
void LFO_sync(lfo_t *pObj, synth_float_t phase_ref) synth_float_t LFO_sync(lfo_t *pObj, synth_float_t phase_ref)
{ {
synth_float_t note_1_x = pObj->param[LFO_PARAM2_MIDISYNC_BEATDIV]; synth_float_t note_1_x = pObj->param[LFO_PARAM2_MIDISYNC_BEATDIV];
phase_ref = Sync_mod(note_1_x*phase_ref); phase_ref = Sync_mod(note_1_x*phase_ref);
Sync_phase_update(&pObj->sync, phase_ref); Sync_phase_update(&pObj->sync, phase_ref);
// Return BPM
return 4*60*pObj->fs*pObj->sync.omega/note_1_x;
} }
void LFO_Param2Set(lfo_t *pObj, UINT32 type, synth_float_t value) void LFO_Param2Set(lfo_t *pObj, UINT32 type, synth_float_t value)
+1 -1
View File
@@ -123,7 +123,7 @@ void LFO_Free(lfo_t *pObj);
void LFO_SetFS(lfo_t *pObj, synth_float_t fs); void LFO_SetFS(lfo_t *pObj, synth_float_t fs);
void LFO_SetBufsize(lfo_t *pObj, UINT32 bufsize); void LFO_SetBufsize(lfo_t *pObj, UINT32 bufsize);
void LFO_Reset(lfo_t *pObj, synth_float_t initial_phase); void LFO_Reset(lfo_t *pObj, synth_float_t initial_phase);
void LFO_sync(lfo_t *pObj, synth_float_t phase); synth_float_t LFO_sync(lfo_t *pObj, synth_float_t phase);
void LFO_Param2Set(lfo_t *pObj, UINT32 type, synth_float_t value); void LFO_Param2Set(lfo_t *pObj, UINT32 type, synth_float_t value);
synth_float_t* LFO_ProcessDataV(lfo_t *pObj, UINT32 len); synth_float_t* LFO_ProcessDataV(lfo_t *pObj, UINT32 len);
void Sync_processV(lfo_t *pObj, int len); void Sync_processV(lfo_t *pObj, int len);