summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorCarl Hetherington <cth@carlh.net>2013-02-25 20:21:29 +0000
committerCarl Hetherington <cth@carlh.net>2013-02-25 20:21:29 +0000
commit6e0f2a39c9deeb51f05c0c8c9bd46632c2c6483a (patch)
treed9c09a4858bdfc2f56ca2e76f79700a00e0eaea2 /src
parent8bfb6ae0780b0bf3318c345df78518ad3fabc9fc (diff)
Multiple simultaneous plots.
Diffstat (limited to 'src')
-rw-r--r--src/lib/audio_analysis.cc13
-rw-r--r--src/lib/audio_analysis.h1
-rw-r--r--src/wx/audio_dialog.cc68
-rw-r--r--src/wx/audio_dialog.h7
-rw-r--r--src/wx/audio_plot.cc88
-rw-r--r--src/wx/audio_plot.h12
6 files changed, 148 insertions, 41 deletions
diff --git a/src/lib/audio_analysis.cc b/src/lib/audio_analysis.cc
index fffafc4d4..b29ed1707 100644
--- a/src/lib/audio_analysis.cc
+++ b/src/lib/audio_analysis.cc
@@ -80,22 +80,27 @@ AudioAnalysis::AudioAnalysis (string filename)
void
AudioAnalysis::add_point (int c, AudioPoint const & p)
{
- assert (c < int (_data.size ()));
+ assert (c < channels ());
_data[c].push_back (p);
}
AudioPoint
AudioAnalysis::get_point (int c, int p) const
{
- assert (c < int (_data.size ()));
- assert (p < int (_data[c].size ()));
+ assert (p < points (c));
return _data[c][p];
}
int
+AudioAnalysis::channels () const
+{
+ return _data.size ();
+}
+
+int
AudioAnalysis::points (int c) const
{
- assert (c < int (_data.size ()));
+ assert (c < channels ());
return _data[c].size ();
}
diff --git a/src/lib/audio_analysis.h b/src/lib/audio_analysis.h
index c26c0584c..c2d8db876 100644
--- a/src/lib/audio_analysis.h
+++ b/src/lib/audio_analysis.h
@@ -55,6 +55,7 @@ public:
AudioPoint get_point (int c, int p) const;
int points (int c) const;
+ int channels () const;
void write (std::string);
diff --git a/src/wx/audio_dialog.cc b/src/wx/audio_dialog.cc
index 89b04409a..dc297e246 100644
--- a/src/wx/audio_dialog.cc
+++ b/src/wx/audio_dialog.cc
@@ -38,17 +38,33 @@ AudioDialog::AudioDialog (wxWindow* parent)
wxFlexGridSizer* table = new wxFlexGridSizer (2, 6, 6);
- add_label_to_sizer (table, this, _("Channel"));
- _channel = new wxChoice (this, wxID_ANY);
- table->Add (_channel, 1, wxEXPAND | wxALL, 6);
+ for (int i = 0; i < MAX_AUDIO_CHANNELS; ++i) {
+ _channel_checkbox[i] = new wxCheckBox (this, wxID_ANY, audio_channel_name (i));
+ table->Add (_channel_checkbox[i], 1, wxEXPAND);
+ table->AddSpacer (0);
+ _channel_checkbox[i]->Connect (wxID_ANY, wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler (AudioDialog::channel_clicked), 0, this);
+ }
+
+ table->AddSpacer (0);
+ table->AddSpacer (0);
+
+ wxString const types[] = {
+ _("Peak"),
+ _("RMS")
+ };
+
+ for (int i = 0; i < AudioPoint::COUNT; ++i) {
+ _type_checkbox[i] = new wxCheckBox (this, wxID_ANY, types[i]);
+ table->Add (_type_checkbox[i], 1, wxEXPAND);
+ table->AddSpacer (0);
+ _type_checkbox[i]->Connect (wxID_ANY, wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler (AudioDialog::type_clicked), 0, this);
+ }
sizer->Add (table);
SetSizer (sizer);
sizer->Layout ();
sizer->SetSizeHints (this);
-
- _channel->Connect (wxID_ANY, wxEVT_COMMAND_CHOICE_SELECTED, wxCommandEventHandler (AudioDialog::channel_changed), 0, this);
}
void
@@ -61,8 +77,7 @@ AudioDialog::set_film (boost::shared_ptr<Film> f)
try_to_load_analysis ();
setup_channels ();
-
- _channel->SetSelection (0);
+ _plot->set_gain (_film->audio_gain ());
_film_changed_connection = _film->Changed.connect (bind (&AudioDialog::film_changed, this, _1));
_film_audio_analysis_finished_connection = _film->AudioAnalysisFinished.connect (bind (&AudioDialog::try_to_load_analysis, this));
@@ -71,14 +86,16 @@ AudioDialog::set_film (boost::shared_ptr<Film> f)
void
AudioDialog::setup_channels ()
{
- _channel->Clear ();
-
if (!_film->audio_stream()) {
return;
}
for (int i = 0; i < _film->audio_stream()->channels(); ++i) {
- _channel->Append (audio_channel_name (i));
+ _channel_checkbox[i]->Show ();
+ }
+
+ for (int i = _film->audio_stream()->channels(); i < MAX_AUDIO_CHANNELS; ++i) {
+ _channel_checkbox[i]->Hide ();
}
}
@@ -96,12 +113,26 @@ AudioDialog::try_to_load_analysis ()
}
_plot->set_analysis (a);
+ _channel_checkbox[0]->SetValue (true);
+ _plot->set_channel_visible (0, true);
+
+ for (int i = 0; i < AudioPoint::COUNT; ++i) {
+ _type_checkbox[i]->SetValue (true);
+ _plot->set_type_visible (i, true);
+ }
}
void
-AudioDialog::channel_changed (wxCommandEvent &)
+AudioDialog::channel_clicked (wxCommandEvent& ev)
{
- _plot->set_channel (_channel->GetSelection ());
+ int c = 0;
+ while (c < MAX_AUDIO_CHANNELS && ev.GetEventObject() != _channel_checkbox[c]) {
+ ++c;
+ }
+
+ assert (c < MAX_AUDIO_CHANNELS);
+
+ _plot->set_channel_visible (c, _channel_checkbox[c]->GetValue ());
}
void
@@ -120,3 +151,16 @@ AudioDialog::film_changed (Film::Property p)
break;
}
}
+
+void
+AudioDialog::type_clicked (wxCommandEvent& ev)
+{
+ int t = 0;
+ while (t < AudioPoint::COUNT && ev.GetEventObject() != _type_checkbox[t]) {
+ ++t;
+ }
+
+ assert (t < AudioPoint::COUNT);
+
+ _plot->set_type_visible (t, _type_checkbox[t]->GetValue ());
+}
diff --git a/src/wx/audio_dialog.h b/src/wx/audio_dialog.h
index 623c9a067..c3875023f 100644
--- a/src/wx/audio_dialog.h
+++ b/src/wx/audio_dialog.h
@@ -21,6 +21,7 @@
#include <boost/signals2.hpp>
#include <wx/wx.h>
#include "lib/film.h"
+#include "lib/audio_analysis.h"
class AudioPlot;
class Film;
@@ -34,13 +35,15 @@ public:
private:
void film_changed (Film::Property);
- void channel_changed (wxCommandEvent &);
+ void channel_clicked (wxCommandEvent &);
+ void type_clicked (wxCommandEvent &);
void try_to_load_analysis ();
void setup_channels ();
boost::shared_ptr<Film> _film;
AudioPlot* _plot;
- wxChoice* _channel;
+ wxCheckBox* _channel_checkbox[MAX_AUDIO_CHANNELS];
+ wxCheckBox* _type_checkbox[AudioPoint::COUNT];
boost::signals2::scoped_connection _film_changed_connection;
boost::signals2::scoped_connection _film_audio_analysis_finished_connection;
};
diff --git a/src/wx/audio_plot.cc b/src/wx/audio_plot.cc
index 41d074dad..cccdaed34 100644
--- a/src/wx/audio_plot.cc
+++ b/src/wx/audio_plot.cc
@@ -37,11 +37,25 @@ int const AudioPlot::_minimum = -90;
AudioPlot::AudioPlot (wxWindow* parent)
: wxPanel (parent)
- , _channel (0)
, _gain (0)
{
- Connect (wxID_ANY, wxEVT_PAINT, wxPaintEventHandler (AudioPlot::paint), 0, this);
+ for (int i = 0; i < MAX_AUDIO_CHANNELS; ++i) {
+ _channel_visible[i] = false;
+ }
+ for (int i = 0; i < AudioPoint::COUNT; ++i) {
+ _type_visible[i] = false;
+ }
+
+ _colours.push_back (wxColour ( 0, 0, 0));
+ _colours.push_back (wxColour (255, 0, 0));
+ _colours.push_back (wxColour ( 0, 255, 0));
+ _colours.push_back (wxColour (139, 0, 204));
+ _colours.push_back (wxColour ( 0, 0, 255));
+ _colours.push_back (wxColour (100, 100, 100));
+
+ Connect (wxID_ANY, wxEVT_PAINT, wxPaintEventHandler (AudioPlot::paint), 0, this);
+
SetMinSize (wxSize (640, 512));
}
@@ -49,14 +63,29 @@ void
AudioPlot::set_analysis (shared_ptr<AudioAnalysis> a)
{
_analysis = a;
- _channel = 0;
+
+ for (int i = 0; i < MAX_AUDIO_CHANNELS; ++i) {
+ _channel_visible[i] = false;
+ }
+
+ for (int i = 0; i < AudioPoint::COUNT; ++i) {
+ _type_visible[i] = false;
+ }
+
Refresh ();
}
void
-AudioPlot::set_channel (int c)
+AudioPlot::set_channel_visible (int c, bool v)
{
- _channel = c;
+ _channel_visible[c] = v;
+ Refresh ();
+}
+
+void
+AudioPlot::set_type_visible (int t, bool v)
+{
+ _type_visible[t] = v;
Refresh ();
}
@@ -77,7 +106,8 @@ AudioPlot::paint (wxPaintEvent &)
}
int const width = GetSize().GetWidth();
- float const xs = width / float (_analysis->points (_channel));
+ /* Assume all channels have the same number of points */
+ float const xs = width / float (_analysis->points (0));
int const height = GetSize().GetHeight ();
float const ys = height / -_minimum;
@@ -92,24 +122,44 @@ AudioPlot::paint (wxPaintEvent &)
gc->SetPen (*wxLIGHT_GREY_PEN);
gc->StrokePath (grid);
- wxGraphicsPath path[AudioPoint::COUNT];
+ for (int c = 0; c < MAX_AUDIO_CHANNELS; ++c) {
+ if (!_channel_visible[c] || c >= _analysis->channels()) {
+ continue;
+ }
- for (int i = 0; i < AudioPoint::COUNT; ++i) {
- path[i] = gc->CreatePath ();
- path[i].MoveToPoint (0, height - (max (_analysis->get_point(_channel, 0)[i], float (_minimum)) - _minimum + _gain) * ys);
- }
+ wxGraphicsPath path[AudioPoint::COUNT];
+
+ for (int i = 0; i < AudioPoint::COUNT; ++i) {
+ if (!_type_visible[i]) {
+ continue;
+ }
+
+ path[i] = gc->CreatePath ();
+ path[i].MoveToPoint (0, height - (max (_analysis->get_point(c, 0)[i], float (_minimum)) - _minimum + _gain) * ys);
+ }
- for (int i = 0; i < _analysis->points(_channel); ++i) {
- for (int j = 0; j < AudioPoint::COUNT; ++j) {
- path[j].AddLineToPoint (i * xs, height - (max (_analysis->get_point(_channel, i)[j], float (_minimum)) - _minimum + _gain) * ys);
+ for (int i = 0; i < _analysis->points(c); ++i) {
+ for (int j = 0; j < AudioPoint::COUNT; ++j) {
+ if (!_type_visible[j]) {
+ continue;
+ }
+
+ path[j].AddLineToPoint (i * xs, height - (max (_analysis->get_point(c, i)[j], float (_minimum)) - _minimum + _gain) * ys);
+ }
}
- }
- gc->SetPen (*wxBLUE_PEN);
- gc->StrokePath (path[AudioPoint::RMS]);
+ wxColour const col = _colours[c];
- gc->SetPen (*wxRED_PEN);
- gc->StrokePath (path[AudioPoint::PEAK]);
+ if (_type_visible[AudioPoint::RMS]) {
+ gc->SetPen (*wxThePenList->FindOrCreatePen (col));
+ gc->StrokePath (path[AudioPoint::RMS]);
+ }
+
+ if (_type_visible[AudioPoint::PEAK]) {
+ gc->SetPen (*wxThePenList->FindOrCreatePen (wxColour (col.Red(), col.Green(), col.Blue(), col.Alpha() / 2)));
+ gc->StrokePath (path[AudioPoint::PEAK]);
+ }
+ }
delete gc;
}
diff --git a/src/wx/audio_plot.h b/src/wx/audio_plot.h
index b2ae139d1..4ac7f848c 100644
--- a/src/wx/audio_plot.h
+++ b/src/wx/audio_plot.h
@@ -20,8 +20,8 @@
#include <vector>
#include <boost/shared_ptr.hpp>
#include <wx/wx.h>
-
-class AudioAnalysis;
+#include "util.h"
+#include "audio_analysis.h"
class AudioPlot : public wxPanel
{
@@ -29,16 +29,20 @@ public:
AudioPlot (wxWindow *);
void set_analysis (boost::shared_ptr<AudioAnalysis>);
- void set_channel (int c);
+ void set_channel_visible (int c, bool v);
+ void set_type_visible (int t, bool v);
void set_gain (float);
private:
void paint (wxPaintEvent &);
boost::shared_ptr<AudioAnalysis> _analysis;
- int _channel;
+ bool _channel_visible[MAX_AUDIO_CHANNELS];
+ bool _type_visible[AudioPoint::COUNT];
/** gain to apply in dB */
float _gain;
+ std::vector<wxColour> _colours;
+
static const int _minimum;
};