From 2a4859bd143c04bf2ac3b8051672cedfcc5cd5b5 Mon Sep 17 00:00:00 2001 From: Jirka Novak Date: Tue, 23 Mar 2021 09:48:20 +0100 Subject: [PATCH] RTP Player: UI improvements Changes: - all waveforms has common scale therefore louder/quiter signal is visible - when stream/streams are deleted from view, Y axis is rescaled and waveforms are rearranged to reuse empty space --- ui/qt/rtp_audio_stream.cpp | 11 +++++------ ui/qt/rtp_audio_stream.h | 3 +++ ui/qt/rtp_player_dialog.cpp | 38 ++++++++++++++++++++++++++++++++++++- ui/qt/rtp_player_dialog.h | 1 + ui/rtp_stream.h | 3 +++ 5 files changed, 49 insertions(+), 7 deletions(-) diff --git a/ui/qt/rtp_audio_stream.cpp b/ui/qt/rtp_audio_stream.cpp index 44fe3b8f42..324d9f20a5 100644 --- a/ui/qt/rtp_audio_stream.cpp +++ b/ui/qt/rtp_audio_stream.cpp @@ -52,6 +52,7 @@ RtpAudioStream::RtpAudioStream(QObject *parent, rtpstream_info_t *rtpstream, boo audio_resampler_(0), audio_output_(0), max_sample_val_(1), + max_sample_val_used_(1), color_(0), jitter_buffer_size_(50), timing_mode_(RtpAudioStream::JitterBuffer), @@ -457,6 +458,7 @@ void RtpAudioStream::decodeVisual() } } + max_sample_val_used_ = max_sample_val_; g_free(resample_buff); g_free(read_buff); } @@ -480,18 +482,15 @@ const QVector RtpAudioStream::visualTimestamps(bool relative) return adj_timestamps; } -// Scale the height of the waveform (max_sample_val_) and adjust its Y -// offset so that they overlap slightly (stack_offset_). - -// XXX This means that waveforms can be misleading with respect to relative -// amplitude. We might want to add a "global" max_sample_val_. +// Scale the height of the waveform to global scale (max_sample_val_used_) +// and adjust its Y offset so that they overlap slightly (stack_offset_). static const double stack_offset_ = G_MAXINT16 / 3; const QVector RtpAudioStream::visualSamples(int y_offset) { QVector adj_samples; double scaled_offset = y_offset * stack_offset_; for (int i = 0; i < visual_samples_.size(); i++) { - adj_samples.append(((double)visual_samples_[i] * G_MAXINT16 / max_sample_val_) + scaled_offset); + adj_samples.append(((double)visual_samples_[i] * G_MAXINT16 / max_sample_val_used_) + scaled_offset); } return adj_samples; } diff --git a/ui/qt/rtp_audio_stream.h b/ui/qt/rtp_audio_stream.h index 78eafbdbc1..b254b6fda4 100644 --- a/ui/qt/rtp_audio_stream.h +++ b/ui/qt/rtp_audio_stream.h @@ -144,6 +144,8 @@ public: void pausePlaying(); void stopPlaying(); void setStereoRequired(bool stereo_required) { stereo_required_ = stereo_required; } + qint16 getMaxSampleValue() { return max_sample_val_; } + void setMaxSampleValue(gint16 max_sample_val) { max_sample_val_used_ = max_sample_val; } signals: void processedSecs(double secs); @@ -181,6 +183,7 @@ private: QVector wrong_timestamp_timestamps_; QVector silence_timestamps_; qint16 max_sample_val_; + qint16 max_sample_val_used_; QRgb color_; int jitter_buffer_size_; diff --git a/ui/qt/rtp_player_dialog.cpp b/ui/qt/rtp_player_dialog.cpp index 3bf74d8370..a28e24d27a 100644 --- a/ui/qt/rtp_player_dialog.cpp +++ b/ui/qt/rtp_player_dialog.cpp @@ -411,6 +411,7 @@ void RtpPlayerDialog::createPlot(bool rescale_axes) bool legend_inserted_silences = false; bool relative_timestamps = !ui->todCheckBox->isChecked(); int row_count = ui->streamTreeWidget->topLevelItemCount(); + gint16 total_max_sample_value = 1; ui->audioPlot->clearGraphs(); @@ -420,6 +421,17 @@ void RtpPlayerDialog::createPlot(bool rescale_axes) ui->audioPlot->xAxis->setTicker(datetime_ticker_); } + // Calculate common Y scale for graphs + for (int row = 0; row < row_count; row++) { + QTreeWidgetItem *ti = ui->streamTreeWidget->topLevelItem(row); + RtpAudioStream *audio_stream = ti->data(stream_data_col_, Qt::UserRole).value(); + gint16 max_sample_value = audio_stream->getMaxSampleValue(); + + if (max_sample_value > total_max_sample_value) { + total_max_sample_value = max_sample_value; + } + } + // Clear existing graphs for (int row = 0; row < row_count; row++) { QTreeWidgetItem *ti = ui->streamTreeWidget->topLevelItem(row); @@ -433,6 +445,9 @@ void RtpPlayerDialog::createPlot(bool rescale_axes) ti->setData(graph_timestamp_data_col_, Qt::UserRole, QVariant()); ti->setData(graph_silence_data_col_, Qt::UserRole, QVariant()); + // Set common scale + audio_stream->setMaxSampleValue(total_max_sample_value); + // Waveform RtpAudioGraph *audio_graph = new RtpAudioGraph(ui->audioPlot, audio_stream->color()); audio_graph->setMuted(audio_routing.isMuted()); @@ -933,6 +948,22 @@ void RtpPlayerDialog::resetXAxis() ap->replot(); } +void RtpPlayerDialog::updateGraphs() +{ + QCustomPlot *ap = ui->audioPlot; + + // Create new plots, just existing ones + createPlot(false); + + // Rescale Y axis + double pixel_pad = 10.0; // per side + double axis_pixels = ap->yAxis->axisRect()->height(); + ap->yAxis->rescale(true); + ap->yAxis->scaleRange((axis_pixels + (pixel_pad * 2)) / axis_pixels, ap->yAxis->range().center()); + + ap->replot(); +} + void RtpPlayerDialog::playFinished(RtpAudioStream *stream) { playing_streams_.removeOne(stream); @@ -1287,7 +1318,12 @@ void RtpPlayerDialog::on_actionRemoveStream_triggered() delete ti; } - ui->audioPlot->replot(); + // TODO: Recalculate legend + // - Graphs used for legend could be removed above and we must add new + // - If no legend is required, it should be removed + + // Redraw existing waveforms and rescale Y axis + updateGraphs(); updateWidgets(); } diff --git a/ui/qt/rtp_player_dialog.h b/ui/qt/rtp_player_dialog.h index f9aa19e5a8..8b0668102a 100644 --- a/ui/qt/rtp_player_dialog.h +++ b/ui/qt/rtp_player_dialog.h @@ -97,6 +97,7 @@ private slots: void plotClicked(QCPAbstractPlottable *plottable, int dataIndex, QMouseEvent *event); void updateHintLabel(); void resetXAxis(); + void updateGraphs(); void playFinished(RtpAudioStream *stream); void setPlayPosition(double secs); diff --git a/ui/rtp_stream.h b/ui/rtp_stream.h index 92f52acf23..d92af1267a 100644 --- a/ui/rtp_stream.h +++ b/ui/rtp_stream.h @@ -134,6 +134,9 @@ gboolean rtpstream_save(rtpstream_tapinfo_t *tapinfo, capture_file *cap_file, rt */ void rtpstream_mark(rtpstream_tapinfo_t *tapinfo, capture_file *cap_file, rtpstream_info_t* stream_fwd, rtpstream_info_t* stream_rev); +/* Constant based on fix for bug 4119/5902: don't insert too many silence + * frames. + */ #define MAX_SILENCE_FRAMES 14400000 #ifdef __cplusplus