| 499 | } |
| 500 | |
| 501 | void DynamicRangeProcessorHistoryPanel::OnTimer(wxTimerEvent& evt) |
| 502 | { |
| 503 | mPacketBuffer.clear(); |
| 504 | DynamicRangeProcessorOutputPacket packet; |
| 505 | while (mOutputQueue->Get(packet)) |
| 506 | mPacketBuffer.push_back(packet); |
| 507 | mHistory->Push(mPacketBuffer); |
| 508 | |
| 509 | if (mHistory->IsEmpty()) |
| 510 | return; |
| 511 | |
| 512 | // Do now get `std::chrono::steady_clock::now()` in the `OnPaint` event, |
| 513 | // because this can be triggered even when playback is paused. |
| 514 | const auto now = mClock.GetNow(); |
| 515 | if (!mSync) |
| 516 | // At the time of writing, the realtime playback doesn't account for |
| 517 | // varying latencies. When it does, the synchronization will have to be |
| 518 | // updated on latency change. See |
| 519 | // https://github.com/audacity/audacity/issues/3223#issuecomment-2137025150. |
| 520 | mSync.emplace( |
| 521 | ClockSynchronization { mHistory->GetSegments().front().front().time + |
| 522 | mCompressorInstance.GetLatencyMs() / 1000, |
| 523 | now }); |
| 524 | mPlaybackAboutToStart = false; |
| 525 | |
| 526 | mSync->now = now; |
| 527 | |
| 528 | Refresh(false); |
| 529 | wxPanelWrapper::Update(); |
| 530 | } |
| 531 | |
| 532 | void DynamicRangeProcessorHistoryPanel::InitializeForPlayback( |
| 533 | CompressorInstance& instance, double sampleRate) |