* fixed segfault on MIDI Panic button
[ardour.git] / gtk2_ardour / analysis_window.cc
index 8809c84e7abb477c4d39a7d97b485382600dfaaf..8f84febbba011d6fbff446de695d9f1703d89076 100644 (file)
@@ -16,7 +16,6 @@
     along with this program; if not, write to the Free Software
     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 
-    $Id$
 */
 
 #include <gtkmm2ext/gtk_ui.h>
@@ -26,7 +25,7 @@
 #include <gtkmm/treeiter.h>
 
 #include <ardour/audioregion.h>
-#include <ardour/playlist.h>
+#include <ardour/audioplaylist.h>
 #include <ardour/types.h>
 
 #include "analysis_window.h"
 #include "time_axis_view.h"
 #include "public_editor.h"
 #include "selection.h"
-#include "regionview.h"
+#include "audio_region_view.h"
 
 #include "i18n.h"
 
 using namespace ARDOUR;
 using namespace PBD;
 
-AnalysisWindow::AnalysisWindow()
-       : ArdourDialog(_("analysis window")),
-       
+AnalysisWindow::AnalysisWindow() :
+
          source_selection_label       (_("Signal source")),
          source_selection_ranges_rb   (_("Selected ranges")),
          source_selection_regions_rb  (_("Selected regions")),
@@ -52,16 +50,22 @@ AnalysisWindow::AnalysisWindow()
          display_model_label                   (_("Display model")),
          display_model_composite_separate_rb   (_("Composite graphs for each track")),
          display_model_composite_all_tracks_rb (_("Composite graph of all tracks")),
+         
+         show_minmax_button     (_("Show frequency power range")),
+         show_normalized_button (_("Normalize values")),
 
-         fft_graph (2048)
+         fft_graph (16384)
 {
+       set_name(_("FFT analysis window"));
+       set_title(_("FFT analysis window"));
+
        track_list_ready = false;
        
        // Left side: track list + controls
        tlmodel = Gtk::ListStore::create(tlcols);
        track_list.set_model (tlmodel);
        track_list.append_column(_("Track"), tlcols.trackname);
-       track_list.append_column_editable(_("Visible"), tlcols.visible);
+       track_list.append_column_editable(_("Show"), tlcols.visible);
        track_list.set_headers_visible(true);
        track_list.set_reorderable(false);
        track_list.get_selection()->set_mode (Gtk::SELECTION_NONE);
@@ -125,17 +129,31 @@ AnalysisWindow::AnalysisWindow()
                                bind ( mem_fun(*this, &AnalysisWindow::display_model_changed), &display_model_composite_all_tracks_rb));
        }
 
-       vbox.pack_start(hseparator2, false, false);
+       // Analyze button
 
        refresh_button.set_name("EditorGTKButton");
-       refresh_button.set_label(_("Analyze data"));
+       refresh_button.set_label(_("Re-analyze data"));
 
        refresh_button.signal_clicked().connect ( bind ( mem_fun(*this, &AnalysisWindow::analyze_data), &refresh_button)); 
 
        vbox.pack_start(refresh_button, false, false, 10);
+
+
+       // Feature checkboxes
+
+       // minmax
+       show_minmax_button.signal_toggled().connect( mem_fun(*this, &AnalysisWindow::show_minmax_changed));
+       vbox.pack_start(show_minmax_button, false, false);
+
+       // normalize
+       show_normalized_button.signal_toggled().connect( mem_fun(*this, &AnalysisWindow::show_normalized_changed));
+       vbox.pack_start(show_normalized_button, false, false);
+
+       
+
        
        
-       hbox.pack_start(vbox);
+       hbox.pack_start(vbox, Gtk::PACK_SHRINK);
        
        // Analysis window on the right
        fft_graph.ensure_style();
@@ -145,11 +163,9 @@ AnalysisWindow::AnalysisWindow()
        
 
        // And last we pack the hbox
-       get_vbox()->pack_start(hbox);
-
+       add(hbox);
+       show_all();
        track_list.show_all();
-
-       get_vbox()->show_all();
 }
 
 AnalysisWindow::~AnalysisWindow()
@@ -157,6 +173,18 @@ AnalysisWindow::~AnalysisWindow()
 
 }
 
+void
+AnalysisWindow::show_minmax_changed()
+{
+       fft_graph.set_show_minmax(show_minmax_button.get_active());
+}
+
+void
+AnalysisWindow::show_normalized_changed()
+{
+       fft_graph.set_show_normalized(show_normalized_button.get_active());
+}
+
 void
 AnalysisWindow::set_rangemode()
 {
@@ -221,15 +249,18 @@ AnalysisWindow::analyze_data (Gtk::Button *button)
                Sample *buf    = (Sample *) malloc(sizeof(Sample) * fft_graph.windowSize());
                Sample *mixbuf = (Sample *) malloc(sizeof(Sample) * fft_graph.windowSize());
                float  *gain   = (float *)  malloc(sizeof(float) * fft_graph.windowSize());
-               char   *work   = (char *)   malloc(sizeof(char) * fft_graph.windowSize());
        
                Selection s = PublicEditor::instance().get_selection();
                TimeSelection ts = s.time;
-               AudioRegionSelection ars = s.audio_regions;
-       
+               RegionSelection ars = s.regions;
        
                for (TrackSelection::iterator i = s.tracks.begin(); i != s.tracks.end(); ++i) {
-                       ARDOUR::Playlist *pl = (*i)->playlist();
+                       boost::shared_ptr<AudioPlaylist> pl
+                               = boost::dynamic_pointer_cast<AudioPlaylist>((*i)->playlist());
+
+                       if (!pl)
+                               continue;
+
                        RouteUI *rui = dynamic_cast<RouteUI *>(*i);
                        
                        // Busses don't have playlists, so we need to check that we actually are working with a playlist
@@ -242,9 +273,9 @@ AnalysisWindow::analyze_data (Gtk::Button *button)
                        if (source_selection_ranges_rb.get_active()) {
 //                             cerr << "Analyzing ranges on track " << *&rui->route().name() << endl;
                                
-                               for (std::list<ARDOUR::AudioRange>::iterator j = ts.begin(); j != ts.end(); ++j) {
+                               for (std::list<AudioRange>::iterator j = ts.begin(); j != ts.end(); ++j) {
 
-                                       jack_nframes_t i = 0;
+                                       nframes_t i = 0;
                                        int n;
                        
                                        while ( i < (*j).length() ) {
@@ -256,7 +287,7 @@ AnalysisWindow::analyze_data (Gtk::Button *button)
                                                        n = (*j).length() - i;
                                                }
                                
-                                               n = pl->read(buf, mixbuf, gain, work, (*j).start + i, n);
+                                               n = pl->read(buf, mixbuf, gain, (*j).start + i, n);
        
                                                if ( n < fft_graph.windowSize()) {
                                                        for (int j = n; j < fft_graph.windowSize(); j++) {
@@ -274,24 +305,29 @@ AnalysisWindow::analyze_data (Gtk::Button *button)
                                
                                TimeAxisView *current_axis = (*i);
                                
-                               for (std::set<AudioRegionView *>::iterator j = ars.begin(); j != ars.end(); ++j) {
+                               for (RegionSelection::iterator j = ars.begin(); j != ars.end(); ++j) {
+                                       // Check that the region is actually audio (so we can analyze it)
+                                       AudioRegionView* arv = dynamic_cast<AudioRegionView*>(*j);
+                                       if (!arv)
+                                               continue;
+                                       
                                        // Check that the region really is selected on _this_ track/solo
-                                       if ( &(*j)->get_time_axis_view() != current_axis)
+                                       if ( &arv->get_time_axis_view() != current_axis)
                                                continue;
 
-//                                     cerr << " - " << (*j)->region.name() << ": " << (*j)->region.length() << " samples starting at " << (*j)->region.position() << endl;
-                                       jack_nframes_t i = 0;
+//                                     cerr << " - " << (*j)->region().name() << ": " << (*j)->region().length() << " samples starting at " << (*j)->region().position() << endl;
+                                       nframes_t i = 0;
                                        int n;
 
-                                       while ( i < (*j)->region.length() ) {
+                                       while ( i < arv->region()->length() ) {
                                                // TODO: What about stereo+ channels? composite all to one, I guess
 
                                                n = fft_graph.windowSize();
-                                               if (i + n >= (*j)->region.length() ) {
-                                                       n = (*j)->region.length() - i;
+                                               if (i + n >= arv->region()->length() ) {
+                                                       n = arv->region()->length() - i;
                                                }
-                               
-                                               n = (*j)->region.read_at(buf, mixbuf, gain, work, (*j)->region.position() + i, n);
+
+                                               n = arv->audio_region()->read_at(buf, mixbuf, gain, arv->region()->position() + i, n);
        
                                                if ( n < fft_graph.windowSize()) {
                                                        for (int j = n; j < fft_graph.windowSize(); j++) {
@@ -321,7 +357,6 @@ AnalysisWindow::analyze_data (Gtk::Button *button)
        
                free(buf);
                free(mixbuf);
-               free(work);
 
                track_list_ready = true;
        } /* end lock */