| 2635 | } |
| 2636 | |
| 2637 | static void updateAudioStreamTable(QTableWidget* table, |
| 2638 | const RadioModel* model, |
| 2639 | const QVector<PanadapterStream::AudioStreamDiagnostics>& audioStreams) |
| 2640 | { |
| 2641 | if (!table) { |
| 2642 | return; |
| 2643 | } |
| 2644 | |
| 2645 | auto makeItem = [](const QString& text, const QColor& color = QColor("#c2ccdb")) { |
| 2646 | auto* item = new QTableWidgetItem(text); |
| 2647 | item->setForeground(color); |
| 2648 | return item; |
| 2649 | }; |
| 2650 | auto makeNumberItem = [&](const QString& text, bool warning = false) { |
| 2651 | auto* item = makeItem(text, warning ? QColor("#e8b977") : QColor("#c2ccdb")); |
| 2652 | item->setTextAlignment(Qt::AlignRight | Qt::AlignVCenter); |
| 2653 | return item; |
| 2654 | }; |
| 2655 | |
| 2656 | const QStringList sliceLabels = audibleSliceLabels(model); |
| 2657 | table->setRowCount(audioStreams.isEmpty() |
| 2658 | ? 1 |
| 2659 | : static_cast<int>(audioStreams.size())); |
| 2660 | table->clearContents(); |
| 2661 | |
| 2662 | if (audioStreams.isEmpty()) { |
| 2663 | table->setItem(0, 0, makeItem("Waiting")); |
| 2664 | table->setItem(0, 1, makeItem(formatAudioStreamSource(sliceLabels), QColor("#8d99ad"))); |
| 2665 | for (int col = 2; col < table->columnCount(); ++col) { |
| 2666 | table->setItem(0, col, makeItem("--", QColor("#6e7a8d"))); |
| 2667 | } |
| 2668 | table->resizeRowsToContents(); |
| 2669 | return; |
| 2670 | } |
| 2671 | |
| 2672 | for (int row = 0; row < static_cast<int>(audioStreams.size()); ++row) { |
| 2673 | const PanadapterStream::AudioStreamDiagnostics& stream = audioStreams.at(row); |
| 2674 | const bool late = stream.latePackets > 0; |
| 2675 | const bool gaps = stream.sequenceErrors > 0; |
| 2676 | table->setItem(row, 0, makeItem(formatStreamId(stream.streamId))); |
| 2677 | table->setItem(row, 1, makeItem(formatAudioStreamSource(sliceLabels))); |
| 2678 | table->setItem(row, 2, makeItem(formatAudioStreamFormat(stream.packetClassCode))); |
| 2679 | table->setItem(row, 3, makeNumberItem(formatFeedRate(stream.feedRateHz))); |
| 2680 | table->setItem(row, 4, makeNumberItem(formatFeedDeficit(std::max(0.0, stream.deficitMs)), |
| 2681 | stream.deficitMs >= 20.0)); |
| 2682 | table->setItem(row, 5, makeNumberItem(QString::number(stream.latePackets), late)); |
| 2683 | table->setItem(row, 6, makeNumberItem(QString::number(stream.sequenceErrors), gaps)); |
| 2684 | table->setItem(row, 7, makeNumberItem(QString("%1 ms").arg(stream.maxGapMs), |
| 2685 | stream.maxGapMs > stream.expectedPacketMs * 2.0)); |
| 2686 | table->setItem(row, 8, makeNumberItem(QString("%1 ms ago").arg(stream.lastPacketAgeMs), |
| 2687 | stream.lastPacketAgeMs > 1000)); |
| 2688 | } |
| 2689 | |
| 2690 | table->resizeRowsToContents(); |
| 2691 | } |
| 2692 | |
| 2693 | void NetworkDiagnosticsDialog::refresh() |
| 2694 | { |
no test coverage detected