Optimize PlotScalar based plots (#1238)
* Remove unused channel option from PlotScalar. * First pass at only drawing the changed area. * Pre-render gridlines. * Fix 22.04 compiler errors. * Allow updated code to work on macOS too. * Need to disable interpolation. * Fix mini plot grid lines. * Add PR #1238 to changelog.pull/1233/head
parent
165525c206
commit
e81b266f50
|
|
@ -886,6 +886,7 @@ LDPC | Low Density Parity Check Codes - a family of powerful FEC codes
|
|||
* FreeDV Reporter: Disable autosizing enable/disable on Linux. (PR #1231)
|
||||
2. Enhancements:
|
||||
* FreeDV Reporter: Use ItemsAdded/ItemsDeleted instead of Cleared() for performance. (PR #1212)
|
||||
* Optimize "From XXX" plot performance. (PR #1238)
|
||||
3. Build system:
|
||||
* Windows/macOS: Update Python to 3.14.3. (PR #1221)
|
||||
* Update Hamlib to 4.7.0. (PR #1226)
|
||||
|
|
|
|||
|
|
@ -24,6 +24,7 @@
|
|||
#include <wx/graphics.h>
|
||||
|
||||
#include <map>
|
||||
#include <vector>
|
||||
|
||||
#include "plot_scalar.h"
|
||||
|
||||
|
|
@ -41,7 +42,6 @@ constexpr int STR_LENGTH = 15;
|
|||
// PlotScalar()
|
||||
//----------------------------------------------------------------
|
||||
PlotScalar::PlotScalar(wxWindow* parent,
|
||||
int channels, // number on channels to plot
|
||||
float t_secs, // time covered by entire x axis in seconds
|
||||
float sample_period_secs, // time between each sample in seconds
|
||||
float a_min, // min ampltude of samples being plotted
|
||||
|
|
@ -57,12 +57,15 @@ PlotScalar::PlotScalar(wxWindow* parent,
|
|||
// for e.g. numbers. Thus, we only need to override layout direction.
|
||||
SetLayoutDirection(wxLayout_LeftToRight);
|
||||
|
||||
plotArea_ = nullptr;
|
||||
plotLines_ = nullptr;
|
||||
addedPoints_ = 0;
|
||||
|
||||
int i;
|
||||
|
||||
m_rCtrl = GetClientRect();
|
||||
|
||||
lineMap_ = nullptr;
|
||||
m_channels = channels;
|
||||
m_t_secs = t_secs;
|
||||
m_sample_period_secs = sample_period_secs;
|
||||
m_a_min = a_min;
|
||||
|
|
@ -81,11 +84,14 @@ PlotScalar::PlotScalar(wxWindow* parent,
|
|||
// work out number of samples we will store and allocate storage
|
||||
|
||||
m_samples = m_t_secs/m_sample_period_secs;
|
||||
m_mem = new float[m_samples*m_channels];
|
||||
for(i = 0; i < m_samples*m_channels; i++)
|
||||
m_mem = new float[m_samples];
|
||||
for(i = 0; i < m_samples; i++)
|
||||
{
|
||||
m_mem[i] = 0.0;
|
||||
}
|
||||
|
||||
plotAreaDC_ = new wxMemoryDC();
|
||||
assert(plotAreaDC_ != nullptr);
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------
|
||||
|
|
@ -95,57 +101,66 @@ PlotScalar::~PlotScalar()
|
|||
{
|
||||
delete[] m_mem;
|
||||
delete[] lineMap_;
|
||||
|
||||
delete plotAreaDC_;
|
||||
|
||||
if (plotArea_ != nullptr)
|
||||
{
|
||||
delete plotArea_;
|
||||
plotArea_ = nullptr;
|
||||
}
|
||||
|
||||
if (plotLines_ != nullptr)
|
||||
{
|
||||
delete plotLines_;
|
||||
plotLines_ = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------
|
||||
// add_new_sample()
|
||||
//----------------------------------------------------------------
|
||||
void PlotScalar::add_new_sample(int channel, float sample)
|
||||
void PlotScalar::add_new_sample(float sample)
|
||||
{
|
||||
int offset = channel*m_samples;
|
||||
|
||||
assert(channel < m_channels);
|
||||
|
||||
for(int i = 0; i < m_samples-1; i++)
|
||||
{
|
||||
m_mem[offset+i] = m_mem[offset+i+1];
|
||||
m_mem[i] = m_mem[i+1];
|
||||
}
|
||||
|
||||
m_mem[offset+m_samples-1] = sample;
|
||||
m_mem[m_samples-1] = sample;
|
||||
addedPoints_++;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------
|
||||
// add_new_samples()
|
||||
//----------------------------------------------------------------
|
||||
void PlotScalar::add_new_samples(int channel, float samples[], int length)
|
||||
void PlotScalar::add_new_samples(float samples[], int length)
|
||||
{
|
||||
int i;
|
||||
int offset = channel*m_samples;
|
||||
|
||||
assert(channel < m_channels);
|
||||
|
||||
for(i = 0; i < m_samples-length; i++)
|
||||
m_mem[offset+i] = m_mem[offset+i+length];
|
||||
m_mem[i] = m_mem[i+length];
|
||||
|
||||
for(i = m_samples-length; i < m_samples; i++)
|
||||
m_mem[offset+i] = *samples++;
|
||||
m_mem[i] = *samples++;
|
||||
|
||||
addedPoints_ += length;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------
|
||||
// add_new_short_samples()
|
||||
//----------------------------------------------------------------
|
||||
void PlotScalar::add_new_short_samples(int channel, short samples[], int length, float scale_factor)
|
||||
void PlotScalar::add_new_short_samples(short samples[], int length, float scale_factor)
|
||||
{
|
||||
int i;
|
||||
int offset = channel*m_samples;
|
||||
|
||||
assert(channel < m_channels);
|
||||
|
||||
for(i = 0; i < m_samples-length; i++)
|
||||
m_mem[offset+i] = m_mem[offset+i+length];
|
||||
m_mem[i] = m_mem[i+length];
|
||||
|
||||
for(i = m_samples-length; i < m_samples; i++)
|
||||
m_mem[offset+i] = (float)*samples++/scale_factor;
|
||||
m_mem[i] = (float)*samples++/scale_factor;
|
||||
|
||||
addedPoints_ += length;
|
||||
}
|
||||
|
||||
bool PlotScalar::repaintAll_(wxPaintEvent&)
|
||||
|
|
@ -215,19 +230,41 @@ void PlotScalar::draw(wxGraphicsContext* ctx, bool repaintDataOnly)
|
|||
|
||||
if (plotWidth <= 0 || plotHeight <= 0) return;
|
||||
|
||||
if (plotArea_ == nullptr)
|
||||
{
|
||||
plotArea_ = new wxBitmap(plotWidth, plotHeight);
|
||||
assert(plotArea_ != nullptr);
|
||||
|
||||
addedPoints_ = 0; // force rendering of all points
|
||||
}
|
||||
|
||||
plotAreaDC_->SelectObject(*plotArea_);
|
||||
|
||||
wxBrush ltGraphBkgBrush = wxBrush(BLACK_COLOR);
|
||||
ctx->SetBrush(ltGraphBkgBrush);
|
||||
ctx->SetPen(wxPen(BLACK_COLOR, 0));
|
||||
ctx->DrawRectangle(plotX, plotY, plotWidth, plotHeight);
|
||||
|
||||
plotAreaDC_->SetBrush(ltGraphBkgBrush);
|
||||
plotAreaDC_->SetPen(wxPen(BLACK_COLOR, 0));
|
||||
|
||||
index_to_px = (float)plotWidth/m_samples;
|
||||
int pixelsUpdated = index_to_px * addedPoints_;
|
||||
|
||||
if (addedPoints_ == 0)
|
||||
{
|
||||
plotAreaDC_->DrawRectangle(0, 0, plotWidth, plotHeight);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Clear only the area that we're updating
|
||||
plotAreaDC_->Blit(0, 0, plotWidth - pixelsUpdated, plotHeight, plotAreaDC_, pixelsUpdated, 0);
|
||||
plotAreaDC_->DrawRectangle(plotWidth - pixelsUpdated, 0, pixelsUpdated, plotHeight);
|
||||
}
|
||||
|
||||
a_to_py = (float)plotHeight/(m_a_max - m_a_min);
|
||||
|
||||
wxPen pen;
|
||||
pen.SetColour(DARK_GREEN_COLOR);
|
||||
pen.SetWidth(1);
|
||||
ctx->SetPen(pen);
|
||||
ctx->SetBrush(wxBrush(DARK_GREEN_COLOR));
|
||||
plotAreaDC_->SetPen(pen);
|
||||
plotAreaDC_->SetBrush(wxBrush(DARK_GREEN_COLOR));
|
||||
|
||||
// plot each channel
|
||||
|
||||
|
|
@ -246,96 +283,92 @@ void PlotScalar::draw(wxGraphicsContext* ctx, bool repaintDataOnly)
|
|||
|
||||
ctx->BeginLayer(1.0);
|
||||
|
||||
int offset, x, y;
|
||||
for(offset=0; offset<m_channels*m_samples; offset+=m_samples) {
|
||||
int x, y;
|
||||
|
||||
for(i = 0; i < m_samples; i++) {
|
||||
a = m_mem[offset + i];
|
||||
if (a < m_a_min) a = m_a_min;
|
||||
if (a > m_a_max) a = m_a_max;
|
||||
for(i = 0; i < m_samples; i++) {
|
||||
a = m_mem[i];
|
||||
if (a < m_a_min) a = m_a_min;
|
||||
if (a > m_a_max) a = m_a_max;
|
||||
|
||||
// invert y axis and offset by minimum
|
||||
// invert y axis and offset by minimum
|
||||
|
||||
y = plotHeight - a_to_py * a + m_a_min*a_to_py;
|
||||
y = plotHeight - a_to_py * a + m_a_min*a_to_py;
|
||||
|
||||
// regular point-point line graph
|
||||
// regular point-point line graph
|
||||
|
||||
x = index_to_px * i;
|
||||
x = index_to_px * i;
|
||||
|
||||
// put inside plot window
|
||||
// put inside plot window
|
||||
|
||||
if (m_bar_graph) {
|
||||
if (m_bar_graph) {
|
||||
|
||||
if (m_logy) {
|
||||
if (m_logy) {
|
||||
|
||||
// can't take log(0)
|
||||
// can't take log(0)
|
||||
|
||||
assert(m_a_min > 0.0);
|
||||
assert(m_a_max > 0.0);
|
||||
assert(m_a_min > 0.0);
|
||||
assert(m_a_max > 0.0);
|
||||
|
||||
float norm = (log10(a) - log10(m_a_min))/(log10(m_a_max) - log10(m_a_min));
|
||||
y = plotHeight*(1.0 - norm);
|
||||
} else {
|
||||
y = plotHeight - a_to_py * a + m_a_min*a_to_py;
|
||||
}
|
||||
|
||||
// use points to make a bar graph
|
||||
|
||||
int x1, x2, y1;
|
||||
|
||||
x1 = index_to_px * ((float)i - 0.5);
|
||||
x2 = index_to_px * ((float)i + 0.5);
|
||||
y1 = plotHeight;
|
||||
x1 += PLOT_BORDER + leftOffset_; x2 += PLOT_BORDER + leftOffset_;
|
||||
y1 += PLOT_BORDER;
|
||||
|
||||
wxGraphicsPath path = ctx->CreatePath();
|
||||
path.MoveToPoint(x1, y1);
|
||||
path.AddLineToPoint(x1, y);
|
||||
path.AddLineToPoint(x2, y);
|
||||
path.AddLineToPoint(x2, y1);
|
||||
ctx->StrokePath(path);
|
||||
float norm = (log10(a) - log10(m_a_min))/(log10(m_a_max) - log10(m_a_min));
|
||||
y = plotHeight*(1.0 - norm);
|
||||
} else {
|
||||
y = plotHeight - a_to_py * a + m_a_min*a_to_py;
|
||||
}
|
||||
else {
|
||||
if (i)
|
||||
{
|
||||
auto item = &lineMap_[x];
|
||||
item->y1 = std::min(item->y1, y);
|
||||
item->y2 = std::max(item->y2, y);
|
||||
}
|
||||
|
||||
// use points to make a bar graph
|
||||
|
||||
int x1, x2, y1;
|
||||
|
||||
x1 = index_to_px * ((float)i - 0.5);
|
||||
x2 = index_to_px * ((float)i + 0.5);
|
||||
y1 = plotHeight;
|
||||
x1 += PLOT_BORDER + leftOffset_; x2 += PLOT_BORDER + leftOffset_;
|
||||
y1 += PLOT_BORDER;
|
||||
|
||||
wxGraphicsPath path = ctx->CreatePath();
|
||||
path.MoveToPoint(x1, y1);
|
||||
path.AddLineToPoint(x1, y);
|
||||
path.AddLineToPoint(x2, y);
|
||||
path.AddLineToPoint(x2, y1);
|
||||
ctx->StrokePath(path);
|
||||
}
|
||||
else {
|
||||
if (i)
|
||||
{
|
||||
auto item = &lineMap_[x];
|
||||
item->y1 = std::min(item->y1, y);
|
||||
item->y2 = std::max(item->y2, y);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!m_bar_graph)
|
||||
{
|
||||
int offsetX = 0;
|
||||
int offsetY = 0;
|
||||
if (!m_mini)
|
||||
{
|
||||
offsetX = PLOT_BORDER + leftOffset_;
|
||||
offsetY = PLOT_BORDER;
|
||||
}
|
||||
wxGraphicsPath path = ctx->CreatePath();
|
||||
for (int index = 0; index < plotWidth; index++)
|
||||
std::vector<wxPoint> points;
|
||||
int from = addedPoints_ > 0 ? plotWidth - pixelsUpdated : 0;
|
||||
for (int index = from; index < plotWidth; index++)
|
||||
{
|
||||
auto item = &lineMap_[index];
|
||||
int x = index + offsetX;
|
||||
if (index == 0) path.MoveToPoint(x, item->y1 + offsetY);
|
||||
else path.AddLineToPoint(x, item->y1 + offsetY);
|
||||
int x = index;
|
||||
if (index == from) points.push_back(wxPoint(x, item->y1));
|
||||
else points.push_back(wxPoint(x, item->y1));
|
||||
}
|
||||
for (int index = plotWidth - 1; index >= 0; index--)
|
||||
for (int index = plotWidth - 1; index >= from; index--)
|
||||
{
|
||||
auto item = &lineMap_[index];
|
||||
int x = index + offsetX;
|
||||
path.AddLineToPoint(x, item->y2 + offsetY);
|
||||
int x = index;
|
||||
points.push_back(wxPoint(x, item->y2));
|
||||
}
|
||||
path.AddLineToPoint(offsetX, lineMap_[0].y1 + offsetY);
|
||||
ctx->FillPath(path);
|
||||
points.push_back(wxPoint(from, lineMap_[from].y1));
|
||||
|
||||
plotAreaDC_->DrawPolygon(points.size(), &points[0]);
|
||||
}
|
||||
|
||||
|
||||
plotAreaDC_->SelectObject(wxNullBitmap);
|
||||
ctx->DrawBitmap(*plotArea_, plotX, plotY, plotWidth, plotHeight);
|
||||
ctx->EndLayer();
|
||||
|
||||
addedPoints_ = 0;
|
||||
drawGraticuleFast(ctx, repaintDataOnly);
|
||||
}
|
||||
|
||||
|
|
@ -353,6 +386,20 @@ void PlotScalar::drawGraticuleFast(wxGraphicsContext* ctx, bool repaintDataOnly)
|
|||
int plotWidth = m_rGrid.GetWidth();
|
||||
int plotHeight = m_rGrid.GetHeight();
|
||||
|
||||
wxGraphicsContext* plotCtx = nullptr;
|
||||
bool drawPlotLines = false;
|
||||
if (plotLines_ == nullptr)
|
||||
{
|
||||
plotLines_ = new wxImage(plotWidth, plotHeight);
|
||||
assert(plotLines_ != nullptr);
|
||||
drawPlotLines = true;
|
||||
|
||||
plotCtx = wxGraphicsContext::Create(*plotLines_);
|
||||
assert(plotCtx != nullptr);
|
||||
plotCtx->SetInterpolationQuality(wxINTERPOLATION_NONE);
|
||||
plotCtx->SetAntialiasMode(wxANTIALIAS_NONE);
|
||||
}
|
||||
|
||||
ctx->SetPen(wxPen(BLACK_COLOR, 1));
|
||||
|
||||
if (!repaintDataOnly)
|
||||
|
|
@ -370,18 +417,18 @@ void PlotScalar::drawGraticuleFast(wxGraphicsContext* ctx, bool repaintDataOnly)
|
|||
|
||||
// Vertical gridlines
|
||||
|
||||
ctx->SetPen(m_penShortDash);
|
||||
if (drawPlotLines) plotCtx->SetPen(m_penShortDash);
|
||||
for(t=0; t<=m_t_secs; t+=m_graticule_t_step)
|
||||
{
|
||||
x = t*sec_to_px;
|
||||
if (m_mini)
|
||||
if (m_mini && drawPlotLines)
|
||||
{
|
||||
ctx->StrokeLine(x, plotHeight, x, 0);
|
||||
plotCtx->StrokeLine(x, plotHeight, x, 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (drawPlotLines) plotCtx->StrokeLine(x, plotHeight, x, 0);
|
||||
x += PLOT_BORDER + leftOffset_;
|
||||
ctx->StrokeLine(x, plotHeight + PLOT_BORDER, x, PLOT_BORDER);
|
||||
if (!repaintDataOnly)
|
||||
{
|
||||
snprintf(buf, STR_LENGTH, "%2.1fs", t);
|
||||
|
|
@ -402,7 +449,7 @@ void PlotScalar::drawGraticuleFast(wxGraphicsContext* ctx, bool repaintDataOnly)
|
|||
|
||||
// Horizontal gridlines
|
||||
|
||||
ctx->SetPen(m_penDotDash);
|
||||
if (drawPlotLines) plotCtx->SetPen(m_penDotDash);
|
||||
for(a=m_a_min; a<m_a_max; )
|
||||
{
|
||||
if (m_logy)
|
||||
|
|
@ -414,15 +461,14 @@ void PlotScalar::drawGraticuleFast(wxGraphicsContext* ctx, bool repaintDataOnly)
|
|||
{
|
||||
y = plotHeight - a*a_to_py + m_a_min*a_to_py;
|
||||
}
|
||||
if (m_mini)
|
||||
if (m_mini && drawPlotLines)
|
||||
{
|
||||
ctx->StrokeLine(0, y, plotWidth, y);
|
||||
plotCtx->StrokeLine(0, y, plotWidth, y);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (drawPlotLines) plotCtx->StrokeLine(0, y, plotWidth, y);
|
||||
y += PLOT_BORDER;
|
||||
ctx->StrokeLine(PLOT_BORDER + leftOffset_, y,
|
||||
(plotWidth + PLOT_BORDER + leftOffset_), y);
|
||||
if (!repaintDataOnly)
|
||||
{
|
||||
auto top = y-text_h/2;
|
||||
|
|
@ -452,6 +498,25 @@ void PlotScalar::drawGraticuleFast(wxGraphicsContext* ctx, bool repaintDataOnly)
|
|||
a += m_graticule_a_step;
|
||||
}
|
||||
}
|
||||
|
||||
if (drawPlotLines)
|
||||
{
|
||||
delete plotCtx;
|
||||
|
||||
plotLines_->SetMaskColour(0, 0, 0);
|
||||
plotLines_->InitAlpha();
|
||||
|
||||
plotLinesBMP_ = ctx->CreateBitmap(*plotLines_);
|
||||
}
|
||||
|
||||
if (m_mini)
|
||||
{
|
||||
ctx->DrawBitmap(plotLinesBMP_, 0, 0, plotWidth, plotHeight);
|
||||
}
|
||||
else
|
||||
{
|
||||
ctx->DrawBitmap(plotLinesBMP_, PLOT_BORDER + leftOffset_, PLOT_BORDER, plotWidth, plotHeight);
|
||||
}
|
||||
}
|
||||
|
||||
void PlotScalar::clearSamples()
|
||||
|
|
@ -464,7 +529,6 @@ void PlotScalar::clearSamples()
|
|||
//----------------------------------------------------------------
|
||||
void PlotScalar::OnSize(wxSizeEvent&)
|
||||
{
|
||||
// Determine correct left offset based on max text width
|
||||
leftOffset_ = 0;
|
||||
bottomOffset_ = 0;
|
||||
for(auto a=m_a_min; a<m_a_max; )
|
||||
|
|
@ -493,11 +557,29 @@ void PlotScalar::OnSize(wxSizeEvent&)
|
|||
if (!m_mini)
|
||||
m_rGrid = m_rGrid.Deflate(PLOT_BORDER + (leftOffset_/2), (PLOT_BORDER + (bottomOffset_/2)));
|
||||
|
||||
if (plotArea_ != nullptr)
|
||||
{
|
||||
delete plotArea_;
|
||||
plotArea_ = nullptr;
|
||||
}
|
||||
|
||||
if (plotLines_ != nullptr)
|
||||
{
|
||||
delete plotLines_;
|
||||
plotLines_ = nullptr;
|
||||
}
|
||||
|
||||
int plotWidth = m_rGrid.GetWidth();
|
||||
delete[] lineMap_;
|
||||
|
||||
lineMap_ = new MinMaxPoints[plotWidth];
|
||||
assert(lineMap_ != nullptr);
|
||||
|
||||
int plotHeight = m_rGrid.GetHeight();
|
||||
if (plotWidth <= 0 || plotHeight <= 0) return;
|
||||
|
||||
plotArea_ = new wxBitmap(plotWidth, plotHeight);
|
||||
assert(plotArea_ != nullptr);
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------
|
||||
|
|
|
|||
|
|
@ -34,7 +34,6 @@ class PlotScalar: public PlotPanel
|
|||
public:
|
||||
|
||||
PlotScalar(wxWindow* parent,
|
||||
int channels,
|
||||
float t_secs,
|
||||
float sample_period_secs,
|
||||
float a_min,
|
||||
|
|
@ -46,9 +45,9 @@ class PlotScalar: public PlotPanel
|
|||
const char* plotName = ""
|
||||
);
|
||||
~PlotScalar();
|
||||
void add_new_sample(int channel, float sample);
|
||||
void add_new_samples(int channel, float samples[], int length);
|
||||
void add_new_short_samples(int channel, short samples[], int length, float scale_factor);
|
||||
void add_new_sample(float sample);
|
||||
void add_new_samples(float samples[], int length);
|
||||
void add_new_short_samples(short samples[], int length, float scale_factor);
|
||||
void setBarGraph(int bar_graph) { m_bar_graph = bar_graph; }
|
||||
void setLogY(int logy) { m_logy = logy; }
|
||||
|
||||
|
|
@ -66,7 +65,6 @@ class PlotScalar: public PlotPanel
|
|||
|
||||
protected:
|
||||
|
||||
int m_channels;
|
||||
float m_t_secs;
|
||||
float m_sample_period_secs;
|
||||
float m_a_min;
|
||||
|
|
@ -82,6 +80,12 @@ class PlotScalar: public PlotPanel
|
|||
int leftOffset_;
|
||||
int bottomOffset_;
|
||||
|
||||
wxBitmap* plotArea_;
|
||||
wxImage* plotLines_;
|
||||
int addedPoints_;
|
||||
wxMemoryDC* plotAreaDC_;
|
||||
wxGraphicsBitmap plotLinesBMP_;
|
||||
|
||||
void draw(wxGraphicsContext* ctx, bool repaintDataOnly = false) override;
|
||||
void drawGraticuleFast(wxGraphicsContext* ctx, bool repaintDataOnly);
|
||||
void OnSize(wxSizeEvent& event) override;
|
||||
|
|
|
|||
|
|
@ -79,7 +79,7 @@ void AudioOptsDialog::buildTestControls(PlotScalar **plotScalar, wxButton **btnT
|
|||
wxBoxSizer* bSizer1 = new wxBoxSizer(wxVERTICAL);
|
||||
|
||||
//wxPanel *panel = new wxPanel(parentPanel, wxID_ANY, wxDefaultPosition, wxDefaultSize, 0);
|
||||
*plotScalar = new PlotScalar(parentPanel, 1, TEST_WAVEFORM_PLOT_TIME, 1.0/TEST_WAVEFORM_PLOT_FS, -1, 1, 1, 0.2, "", 1, "Test audio plot");
|
||||
*plotScalar = new PlotScalar(parentPanel, TEST_WAVEFORM_PLOT_TIME, 1.0/TEST_WAVEFORM_PLOT_FS, -1, 1, 1, 0.2, "", 1, "Test audio plot");
|
||||
(*plotScalar)->SetToolTip("Shows test audio waveform");
|
||||
(*plotScalar)->SetClientSize(wxSize(TEST_WAVEFORM_X,TEST_WAVEFORM_Y));
|
||||
(*plotScalar)->SetMinSize(wxSize(150,150));
|
||||
|
|
@ -933,7 +933,7 @@ void AudioOptsDialog::plotDeviceInputForAFewSecs(wxString const& devName, PlotSc
|
|||
std::condition_variable plotUpdateCV;
|
||||
CallAfter([&]() {
|
||||
{
|
||||
ps->add_new_short_samples(0, plotSamples, TEST_WAVEFORM_PLOT_BUF, 32767);
|
||||
ps->add_new_short_samples(plotSamples, TEST_WAVEFORM_PLOT_BUF, 32767);
|
||||
UpdatePlot(ps);
|
||||
}
|
||||
plotUpdateCV.notify_one();
|
||||
|
|
@ -1074,7 +1074,7 @@ void AudioOptsDialog::plotDeviceOutputForAFewSecs(wxString const& devName, PlotS
|
|||
std::condition_variable plotUpdateCV;
|
||||
CallAfter([&]() {
|
||||
{
|
||||
ps->add_new_short_samples(0, plotSamples, TEST_WAVEFORM_PLOT_BUF, 32767);
|
||||
ps->add_new_short_samples(plotSamples, TEST_WAVEFORM_PLOT_BUF, 32767);
|
||||
UpdatePlot(ps);
|
||||
}
|
||||
plotUpdateCV.notify_one();
|
||||
|
|
|
|||
12
src/main.cpp
12
src/main.cpp
|
|
@ -1079,15 +1079,15 @@ MainFrame::MainFrame(wxWindow *parent) : TopFrame(parent, wxID_ANY, _("FreeDV ")
|
|||
m_auiNbookCtrl->AddPage(m_panelSpectrum, _("Spectrum"), false, wxNullBitmap);
|
||||
|
||||
// Add Demod Input window
|
||||
m_panelDemodIn = new PlotScalar(m_auiNbookCtrl, 1, WAVEFORM_PLOT_TIME, 1.0/WAVEFORM_PLOT_FS, -1, 1, 1, 0.2, "%2.1f", 0);
|
||||
m_panelDemodIn = new PlotScalar(m_auiNbookCtrl, WAVEFORM_PLOT_TIME, 1.0/WAVEFORM_PLOT_FS, -1, 1, 1, 0.2, "%2.1f", 0);
|
||||
m_auiNbookCtrl->AddPage(m_panelDemodIn, _("Frm Radio"), false, wxNullBitmap);
|
||||
|
||||
// Add Speech Input window
|
||||
m_panelSpeechIn = new PlotScalar(m_auiNbookCtrl, 1, WAVEFORM_PLOT_TIME, 1.0/WAVEFORM_PLOT_FS, -1, 1, 1, 0.2, "%2.1f", 0);
|
||||
m_panelSpeechIn = new PlotScalar(m_auiNbookCtrl, WAVEFORM_PLOT_TIME, 1.0/WAVEFORM_PLOT_FS, -1, 1, 1, 0.2, "%2.1f", 0);
|
||||
m_auiNbookCtrl->AddPage(m_panelSpeechIn, _("Frm Mic"), false, wxNullBitmap);
|
||||
|
||||
// Add Speech Output window
|
||||
m_panelSpeechOut = new PlotScalar(m_auiNbookCtrl, 1, WAVEFORM_PLOT_TIME, 1.0/WAVEFORM_PLOT_FS, -1, 1, 1, 0.2, "%2.1f", 0);
|
||||
m_panelSpeechOut = new PlotScalar(m_auiNbookCtrl, WAVEFORM_PLOT_TIME, 1.0/WAVEFORM_PLOT_FS, -1, 1, 1, 0.2, "%2.1f", 0);
|
||||
m_auiNbookCtrl->AddPage(m_panelSpeechOut, _("Frm Decoder"), false, wxNullBitmap);
|
||||
|
||||
// this->Connect(m_menuItemHelpUpdates->GetId(), wxEVT_UPDATE_UI, wxUpdateUIEventHandler(TopFrame::OnHelpCheckUpdatesUI));
|
||||
|
|
@ -1540,14 +1540,14 @@ void MainFrame::OnTimer(wxTimerEvent &evt)
|
|||
if (g_plotSpeechInFifo.read(speechInPlotSamples, WAVEFORM_PLOT_BUF)) {
|
||||
memset(speechInPlotSamples, 0, WAVEFORM_PLOT_BUF*sizeof(short));
|
||||
}
|
||||
m_panelSpeechIn->add_new_short_samples(0, speechInPlotSamples, WAVEFORM_PLOT_BUF, 32767);
|
||||
m_panelSpeechIn->add_new_short_samples(speechInPlotSamples, WAVEFORM_PLOT_BUF, 32767);
|
||||
m_panelSpeechIn->refreshData();
|
||||
}
|
||||
else if (timerId == ID_TIMER_SPEECH_OUT)
|
||||
{
|
||||
if (g_plotSpeechOutFifo.read(speechOutPlotSamples, WAVEFORM_PLOT_BUF))
|
||||
memset(speechOutPlotSamples, 0, WAVEFORM_PLOT_BUF*sizeof(short));
|
||||
m_panelSpeechOut->add_new_short_samples(0, speechOutPlotSamples, WAVEFORM_PLOT_BUF, 32767);
|
||||
m_panelSpeechOut->add_new_short_samples(speechOutPlotSamples, WAVEFORM_PLOT_BUF, 32767);
|
||||
m_panelSpeechOut->refreshData();
|
||||
}
|
||||
else if (timerId == ID_TIMER_DEMOD_IN)
|
||||
|
|
@ -1555,7 +1555,7 @@ void MainFrame::OnTimer(wxTimerEvent &evt)
|
|||
if (g_plotDemodInFifo.read(demodInPlotSamples, WAVEFORM_PLOT_BUF)) {
|
||||
memset(demodInPlotSamples, 0, WAVEFORM_PLOT_BUF*sizeof(short));
|
||||
}
|
||||
m_panelDemodIn->add_new_short_samples(0,demodInPlotSamples, WAVEFORM_PLOT_BUF, 32767);
|
||||
m_panelDemodIn->add_new_short_samples(demodInPlotSamples, WAVEFORM_PLOT_BUF, 32767);
|
||||
m_panelDemodIn->refreshData();
|
||||
}
|
||||
else
|
||||
|
|
|
|||
Loading…
Reference in New Issue