From cb6b6dd6f04db2b58d81b395bd3d1c7ae47e65dc Mon Sep 17 00:00:00 2001 From: Kaz Kylheku Date: Tue, 17 Sep 2013 10:38:59 -0700 Subject: Fixing a bug: the accented beat of the metronome does not play reliably. Steps to reproduce: - rewind the position - press record Sometimes, the accented beat is not heard. I suspected race conditions at first, so I restructured the order of operations in CSekaijuApp::StartRecording so that the MIDI clock is not started until the very end, when all the state variables have been assigned, like m_bPlaying and m_bRecording. I'm keeping these changes. But the real problem was in CSekaijuApp::PlayRecordProc, in the block of code that plays the metronome. There, the check "pSekaijuDoc->m_lOldTime == pSekaijuDoc->m_lNewTime" was causing the issue. Although StartRecording sets up this condition, there is no way for the truth of the condition to be maintained through to that block of code. The clock runs freely, and is periodically sampled by the thread whenever it wakes up from sleep. The condition is not necessary. --- src/SekaijuApp.cpp | 53 ++++++++++++++++++++++++++--------------------------- 1 file changed, 26 insertions(+), 27 deletions(-) diff --git a/src/SekaijuApp.cpp b/src/SekaijuApp.cpp index 0b64aa2..c7f92d4 100644 --- a/src/SekaijuApp.cpp +++ b/src/SekaijuApp.cpp @@ -1646,8 +1646,7 @@ BOOL CSekaijuApp::PlayRecordProc (LPVOID pInfo) { long lOutputPort = CLIP (0, m_theMetronomeDlgStatus.m_nOutputPort, 15); long lOutputChannel = CLIP (0, m_theMetronomeDlgStatus.m_nOutputChannel, 15); // 最初の1小節目の強打を鳴らすためのトリック - if (pSekaijuDoc->m_lOldTime == pSekaijuDoc->m_lNewTime && - lOldBeat == 0 && lOldTick == 0 && this->m_bFirstMetronome == TRUE) { + if (lOldBeat == 0 && lOldTick == 0 && m_bFirstMetronome == TRUE) { lOldMeasure --; } m_bFirstMetronome = FALSE; @@ -2697,6 +2696,30 @@ long CSekaijuApp::StartRecording (CDocument* pDocument) { CMainFrame* pMainFrame = (CMainFrame*)AfxGetMainWnd (); CSekaijuDoc* pSekaijuDoc = (CSekaijuDoc*)pDocument; long lCurTime = MIDIClock_GetTickCount (pSekaijuDoc->m_pMIDIClock); + + // 履歴記録 + MIDITrack* pMIDITrack = NULL; + MIDIEvent* pLastEvent = NULL; + MIDIEvent* pCloneEvent = NULL; + CHistoryUnit* pCurHistoryUnit = NULL; + pSekaijuDoc->AddHistoryUnit (_T("リアルタイム入力")); + VERIFY (pCurHistoryUnit = pSekaijuDoc->GetCurHistoryUnit ()); + // EOTの履歴記録 + forEachTrack (pSekaijuDoc->m_pMIDIData, pMIDITrack) { + pLastEvent = MIDITrack_GetLastEvent (pMIDITrack); + if (pLastEvent) { + if (MIDIEvent_IsEndofTrack (pLastEvent)) { + VERIFY (pCurHistoryUnit->AddHistoryRecord (HISTORYRECORD_REMOVEEVENT, pLastEvent)); + VERIFY (pCloneEvent = pSekaijuDoc->ReplaceMIDIEvent (pLastEvent)); + } + } + } + // 記録開始 + pSekaijuDoc->SetModifiedFlag (TRUE); + m_theTempRecordedEventArray.RemoveAll (); + m_bFirstMetronome = TRUE; + m_bRecording = TRUE; + pSekaijuDoc->UpdateAllViews (NULL, SEKAIJUDOC_RECORDSTARTED | SEKAIJUDOC_MIDIEVENTCHANGED); // 演奏中でない場合 if (!m_bPlaying) { long lOutputPort; @@ -2719,33 +2742,9 @@ long CSekaijuApp::StartRecording (CDocument* pDocument) { pSekaijuDoc->TimeMIDIStatus (lCurTime, m_pTempMIDIStatus); // 20090626修正 SendDifferentStatus (m_theGeneralOption.m_bPlayUpdate ? SDS_ALL : SDS_NOTE); m_bIgnoreNoteEvent = TRUE; // 20090626修正 - pSekaijuDoc->m_lOldTime = lCurTime; + m_bPlaying = TRUE; MIDIClock_Start (pSekaijuDoc->m_pMIDIClock); - m_bPlaying = TRUE; } - // 履歴記録 - MIDITrack* pMIDITrack = NULL; - MIDIEvent* pLastEvent = NULL; - MIDIEvent* pCloneEvent = NULL; - CHistoryUnit* pCurHistoryUnit = NULL; - pSekaijuDoc->AddHistoryUnit (_T("リアルタイム入力")); - VERIFY (pCurHistoryUnit = pSekaijuDoc->GetCurHistoryUnit ()); - // EOTの履歴記録 - forEachTrack (pSekaijuDoc->m_pMIDIData, pMIDITrack) { - pLastEvent = MIDITrack_GetLastEvent (pMIDITrack); - if (pLastEvent) { - if (MIDIEvent_IsEndofTrack (pLastEvent)) { - VERIFY (pCurHistoryUnit->AddHistoryRecord (HISTORYRECORD_REMOVEEVENT, pLastEvent)); - VERIFY (pCloneEvent = pSekaijuDoc->ReplaceMIDIEvent (pLastEvent)); - } - } - } - // 記録開始 - pSekaijuDoc->SetModifiedFlag (TRUE); - m_theTempRecordedEventArray.RemoveAll (); - m_bFirstMetronome = TRUE; - m_bRecording = TRUE; - pSekaijuDoc->UpdateAllViews (NULL, SEKAIJUDOC_RECORDSTARTED | SEKAIJUDOC_MIDIEVENTCHANGED); return 1; } -- cgit v1.2.3