void CRecordPlayerDlg::WorkerMain() { int nEvents = m_Record.GetEventCount(); if (!nEvents) // if no events return; // nothing to do UINT nTrackPorts = m_TrackMap.GetSize(); // convert start position from relative milliseconds to relative counts LONGLONG StartPos = MillisToCount(m_StartPos); int iFirst = FindEvent(StartPos); // find event at or after start position iFirst = max(iFirst, 0); // enforce event range LONGLONG tStart = GetPerfCount(); // get start time in absolute counts m_StartCount = tStart; // store start time tStart -= StartPos; // deduct start position from start time for (int iEvent = iFirst; iEvent < nEvents; iEvent++) { // for each event // convert event's relative time to target time in absolute counts LONGLONG tTarget = m_EventTime[iEvent] + tStart; do { // spin if (m_Worker.GetStopFlag()) // if stop requested return; } while (GetPerfCount() < tTarget); // while current time less than target const CMidiRecord::EVENT& ev = m_Record[iEvent]; if (ev.Port < nTrackPorts) { // if event port within track map range // use event's port and channel to look up track index int iTrack = m_TrackMap[ev.Port].TrackIdx[MIDI_CHAN(ev.Msg)]; if (m_TrackEnable[iTrack]) { // if track enabled gEngine.OutputMidi(m_Track[iTrack].m_Inst, MIDI_CMD(ev.Msg), MIDI_P1(ev.Msg), MIDI_P2(ev.Msg)); } } } }
//Not terribly sure how this function is suppose to work, //but jday helped to figure most of it out int curses_getch(WINDOW* win) { // standards note: getch is sometimes required to call refresh // see, e.g., http://linux.die.net/man/3/getch // so although it's non-obvious, that refresh() call (and maybe InvalidateRect?) IS supposed to be there uint64_t Frequency; QueryPerformanceFrequency((PLARGE_INTEGER)&Frequency); wrefresh(win); InvalidateRect(WindowHandle,NULL,true); lastchar = ERR; if (inputdelay < 0) { for (; lastchar==ERR; Sleep(1)) CheckMessages(); } else if (inputdelay > 0) { for (uint64_t t0=GetPerfCount(), t1=0; t1 < (t0 + inputdelay*Frequency/1000); t1=GetPerfCount()) { CheckMessages(); if (lastchar!=ERR) break; Sleep(1); } } else { CheckMessages(); }; if (lastchar!=ERR && OPTIONS["HIDE_CURSOR"] == "hidekb" && CursorVisible) { CursorVisible = false; ShowCursor(false); } return lastchar; }
int CRecordPlayerDlg::GetPos() const { return(CountToMillis(GetPerfCount() - m_StartCount) + m_StartPos); }