| 2439 | } |
| 2440 | |
| 2441 | void NetworkDiagnosticsHistory::sampleNow() |
| 2442 | { |
| 2443 | NetworkDiagnosticsSample sample; |
| 2444 | const qint64 nowMs = QDateTime::currentMSecsSinceEpoch(); |
| 2445 | const double elapsedSeconds = std::max(0.001, (nowMs - m_lastSampleMs) / 1000.0); |
| 2446 | sample.timestampMs = nowMs; |
| 2447 | sample.rttMs = m_model->lastPingRtt(); |
| 2448 | |
| 2449 | static constexpr PanadapterStream::StreamCategory cats[] = { |
| 2450 | PanadapterStream::CatAudio, PanadapterStream::CatFFT, |
| 2451 | PanadapterStream::CatWaterfall, PanadapterStream::CatMeter |
| 2452 | }; |
| 2453 | |
| 2454 | for (PanadapterStream::StreamCategory cat : cats) { |
| 2455 | PanadapterStream::CategoryStats cs = m_model->categoryStats(cat); |
| 2456 | const qint64 delta = std::max<qint64>(0, cs.bytes - m_lastCatBytes[cat]); |
| 2457 | m_lastCatBytes[cat] = cs.bytes; |
| 2458 | const double rateKbps = kbpsFromBytes(delta, elapsedSeconds); |
| 2459 | if (cat == PanadapterStream::CatAudio) { |
| 2460 | sample.audioKbps = rateKbps; |
| 2461 | sample.audioLossPct = lossPercent(cs); |
| 2462 | } else if (cat == PanadapterStream::CatFFT) { |
| 2463 | sample.fftKbps = rateKbps; |
| 2464 | sample.fftLossPct = lossPercent(cs); |
| 2465 | } else if (cat == PanadapterStream::CatWaterfall) { |
| 2466 | sample.waterfallKbps = rateKbps; |
| 2467 | sample.waterfallLossPct = lossPercent(cs); |
| 2468 | } else if (cat == PanadapterStream::CatMeter) { |
| 2469 | sample.meterKbps = rateKbps; |
| 2470 | sample.meterLossPct = lossPercent(cs); |
| 2471 | } |
| 2472 | } |
| 2473 | |
| 2474 | { |
| 2475 | PanadapterStream::CategoryStats cs = m_model->categoryStats(PanadapterStream::CatDAX); |
| 2476 | const qint64 delta = std::max<qint64>(0, cs.bytes - m_lastCatBytes[PanadapterStream::CatDAX]); |
| 2477 | m_lastCatBytes[PanadapterStream::CatDAX] = cs.bytes; |
| 2478 | sample.daxKbps = kbpsFromBytes(delta, elapsedSeconds); |
| 2479 | sample.daxLossPct = lossPercent(cs); |
| 2480 | } |
| 2481 | |
| 2482 | const qint64 curRx = m_model->rxBytes(); |
| 2483 | sample.rxKbps = kbpsFromBytes(std::max<qint64>(0, curRx - m_lastRxBytes), elapsedSeconds); |
| 2484 | m_lastRxBytes = curRx; |
| 2485 | const qint64 curTx = m_model->txBytes(); |
| 2486 | sample.txKbps = kbpsFromBytes(std::max<qint64>(0, curTx - m_lastTxBytes), elapsedSeconds); |
| 2487 | m_lastTxBytes = curTx; |
| 2488 | |
| 2489 | sample.packetLossPct = m_model->packetLossPercent(); |
| 2490 | |
| 2491 | if (m_audio) { |
| 2492 | const int sampleRate = m_audio->rxBufferSampleRate(); |
| 2493 | const quint64 underruns = m_audio->rxBufferUnderrunCount(); |
| 2494 | quint64 underrunDelta = 0; |
| 2495 | if (underruns >= m_lastAudioUnderrunCount) { |
| 2496 | underrunDelta = underruns - m_lastAudioUnderrunCount; |
| 2497 | } |
| 2498 | m_lastAudioUnderrunCount = underruns; |
nothing calls this directly
no test coverage detected