diff options
| author | Carl Hetherington <cth@carlh.net> | 2013-02-25 20:21:29 +0000 |
|---|---|---|
| committer | Carl Hetherington <cth@carlh.net> | 2013-02-25 20:21:29 +0000 |
| commit | 6e0f2a39c9deeb51f05c0c8c9bd46632c2c6483a (patch) | |
| tree | d9c09a4858bdfc2f56ca2e76f79700a00e0eaea2 /src | |
| parent | 8bfb6ae0780b0bf3318c345df78518ad3fabc9fc (diff) | |
Multiple simultaneous plots.
Diffstat (limited to 'src')
| -rw-r--r-- | src/lib/audio_analysis.cc | 13 | ||||
| -rw-r--r-- | src/lib/audio_analysis.h | 1 | ||||
| -rw-r--r-- | src/wx/audio_dialog.cc | 68 | ||||
| -rw-r--r-- | src/wx/audio_dialog.h | 7 | ||||
| -rw-r--r-- | src/wx/audio_plot.cc | 88 | ||||
| -rw-r--r-- | src/wx/audio_plot.h | 12 |
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; }; |
