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
This commit is contained in:
parent
2e6d3b571b
commit
2a4859bd14
|
@ -52,6 +52,7 @@ RtpAudioStream::RtpAudioStream(QObject *parent, rtpstream_info_t *rtpstream, boo
|
||||||
audio_resampler_(0),
|
audio_resampler_(0),
|
||||||
audio_output_(0),
|
audio_output_(0),
|
||||||
max_sample_val_(1),
|
max_sample_val_(1),
|
||||||
|
max_sample_val_used_(1),
|
||||||
color_(0),
|
color_(0),
|
||||||
jitter_buffer_size_(50),
|
jitter_buffer_size_(50),
|
||||||
timing_mode_(RtpAudioStream::JitterBuffer),
|
timing_mode_(RtpAudioStream::JitterBuffer),
|
||||||
|
@ -457,6 +458,7 @@ void RtpAudioStream::decodeVisual()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
max_sample_val_used_ = max_sample_val_;
|
||||||
g_free(resample_buff);
|
g_free(resample_buff);
|
||||||
g_free(read_buff);
|
g_free(read_buff);
|
||||||
}
|
}
|
||||||
|
@ -480,18 +482,15 @@ const QVector<double> RtpAudioStream::visualTimestamps(bool relative)
|
||||||
return adj_timestamps;
|
return adj_timestamps;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Scale the height of the waveform (max_sample_val_) and adjust its Y
|
// Scale the height of the waveform to global scale (max_sample_val_used_)
|
||||||
// offset so that they overlap slightly (stack_offset_).
|
// 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_.
|
|
||||||
static const double stack_offset_ = G_MAXINT16 / 3;
|
static const double stack_offset_ = G_MAXINT16 / 3;
|
||||||
const QVector<double> RtpAudioStream::visualSamples(int y_offset)
|
const QVector<double> RtpAudioStream::visualSamples(int y_offset)
|
||||||
{
|
{
|
||||||
QVector<double> adj_samples;
|
QVector<double> adj_samples;
|
||||||
double scaled_offset = y_offset * stack_offset_;
|
double scaled_offset = y_offset * stack_offset_;
|
||||||
for (int i = 0; i < visual_samples_.size(); i++) {
|
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;
|
return adj_samples;
|
||||||
}
|
}
|
||||||
|
|
|
@ -144,6 +144,8 @@ public:
|
||||||
void pausePlaying();
|
void pausePlaying();
|
||||||
void stopPlaying();
|
void stopPlaying();
|
||||||
void setStereoRequired(bool stereo_required) { stereo_required_ = stereo_required; }
|
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:
|
signals:
|
||||||
void processedSecs(double secs);
|
void processedSecs(double secs);
|
||||||
|
@ -181,6 +183,7 @@ private:
|
||||||
QVector<double> wrong_timestamp_timestamps_;
|
QVector<double> wrong_timestamp_timestamps_;
|
||||||
QVector<double> silence_timestamps_;
|
QVector<double> silence_timestamps_;
|
||||||
qint16 max_sample_val_;
|
qint16 max_sample_val_;
|
||||||
|
qint16 max_sample_val_used_;
|
||||||
QRgb color_;
|
QRgb color_;
|
||||||
|
|
||||||
int jitter_buffer_size_;
|
int jitter_buffer_size_;
|
||||||
|
|
|
@ -411,6 +411,7 @@ void RtpPlayerDialog::createPlot(bool rescale_axes)
|
||||||
bool legend_inserted_silences = false;
|
bool legend_inserted_silences = false;
|
||||||
bool relative_timestamps = !ui->todCheckBox->isChecked();
|
bool relative_timestamps = !ui->todCheckBox->isChecked();
|
||||||
int row_count = ui->streamTreeWidget->topLevelItemCount();
|
int row_count = ui->streamTreeWidget->topLevelItemCount();
|
||||||
|
gint16 total_max_sample_value = 1;
|
||||||
|
|
||||||
ui->audioPlot->clearGraphs();
|
ui->audioPlot->clearGraphs();
|
||||||
|
|
||||||
|
@ -420,6 +421,17 @@ void RtpPlayerDialog::createPlot(bool rescale_axes)
|
||||||
ui->audioPlot->xAxis->setTicker(datetime_ticker_);
|
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<RtpAudioStream*>();
|
||||||
|
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
|
// Clear existing graphs
|
||||||
for (int row = 0; row < row_count; row++) {
|
for (int row = 0; row < row_count; row++) {
|
||||||
QTreeWidgetItem *ti = ui->streamTreeWidget->topLevelItem(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_timestamp_data_col_, Qt::UserRole, QVariant());
|
||||||
ti->setData(graph_silence_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
|
// Waveform
|
||||||
RtpAudioGraph *audio_graph = new RtpAudioGraph(ui->audioPlot, audio_stream->color());
|
RtpAudioGraph *audio_graph = new RtpAudioGraph(ui->audioPlot, audio_stream->color());
|
||||||
audio_graph->setMuted(audio_routing.isMuted());
|
audio_graph->setMuted(audio_routing.isMuted());
|
||||||
|
@ -933,6 +948,22 @@ void RtpPlayerDialog::resetXAxis()
|
||||||
ap->replot();
|
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)
|
void RtpPlayerDialog::playFinished(RtpAudioStream *stream)
|
||||||
{
|
{
|
||||||
playing_streams_.removeOne(stream);
|
playing_streams_.removeOne(stream);
|
||||||
|
@ -1287,7 +1318,12 @@ void RtpPlayerDialog::on_actionRemoveStream_triggered()
|
||||||
|
|
||||||
delete ti;
|
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();
|
updateWidgets();
|
||||||
}
|
}
|
||||||
|
|
|
@ -97,6 +97,7 @@ private slots:
|
||||||
void plotClicked(QCPAbstractPlottable *plottable, int dataIndex, QMouseEvent *event);
|
void plotClicked(QCPAbstractPlottable *plottable, int dataIndex, QMouseEvent *event);
|
||||||
void updateHintLabel();
|
void updateHintLabel();
|
||||||
void resetXAxis();
|
void resetXAxis();
|
||||||
|
void updateGraphs();
|
||||||
void playFinished(RtpAudioStream *stream);
|
void playFinished(RtpAudioStream *stream);
|
||||||
|
|
||||||
void setPlayPosition(double secs);
|
void setPlayPosition(double secs);
|
||||||
|
|
|
@ -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);
|
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
|
#define MAX_SILENCE_FRAMES 14400000
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
|
|
Loading…
Reference in New Issue