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>
#include <gtkmm/treemodel.h>
#include <gtkmm/treeiter.h>
-#include <ardour/audioregion.h>
-#include <ardour/audioplaylist.h>
-#include <ardour/types.h>
+#include "ardour/audioregion.h"
+#include "ardour/audioplaylist.h"
+#include "ardour/types.h"
#include "analysis_window.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")),
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
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();
// 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()
}
+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()
{
continue;
RouteUI *rui = dynamic_cast<RouteUI *>(*i);
-
+ int n_inputs = rui->route()->n_inputs().n_audio(); // FFT is audio only
+
// Busses don't have playlists, so we need to check that we actually are working with a playlist
if (!pl || !rui)
continue;
for (std::list<AudioRange>::iterator j = ts.begin(); j != ts.end(); ++j) {
- nframes_t i = 0;
int n;
-
- while ( i < (*j).length() ) {
- // TODO: What about stereo+ channels? composite all to one, I guess
+ for (int channel = 0; channel < n_inputs; channel++) {
+ nframes_t x = 0;
- n = fft_graph.windowSize();
+ while ( x < (*j).length() ) {
+ // TODO: What about stereo+ channels? composite all to one, I guess
- if (i + n >= (*j).length() ) {
- n = (*j).length() - i;
- }
-
- n = pl->read(buf, mixbuf, gain, (*j).start + i, n);
-
- if ( n < fft_graph.windowSize()) {
- for (int j = n; j < fft_graph.windowSize(); j++) {
- buf[j] = 0.0;
+ n = fft_graph.windowSize();
+
+ if (x + n >= (*j).length() ) {
+ n = (*j).length() - x;
}
+
+ n = pl->read(buf, mixbuf, gain, (*j).start + x, n, channel);
+
+ if ( n < fft_graph.windowSize()) {
+ for (int j = n; j < fft_graph.windowSize(); j++) {
+ buf[j] = 0.0;
+ }
+ }
+
+ res->analyzeWindow(buf);
+
+ x += n;
}
-
- res->analyzeWindow(buf);
-
- i += n;
}
}
} else if (source_selection_regions_rb.get_active()) {
continue;
// cerr << " - " << (*j)->region().name() << ": " << (*j)->region().length() << " samples starting at " << (*j)->region().position() << endl;
- nframes_t i = 0;
int n;
+ for (int channel = 0; channel < n_inputs; channel++) {
- while ( i < arv->region()->length() ) {
- // TODO: What about stereo+ channels? composite all to one, I guess
+ nframes_t x = 0;
- n = fft_graph.windowSize();
- if (i + n >= arv->region()->length() ) {
- n = arv->region()->length() - i;
- }
+ nframes_t length = arv->region()->length();
- 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++) {
- buf[j] = 0.0;
+ while ( x < length ) {
+ // TODO: What about stereo+ channels? composite all to one, I guess
+
+ n = fft_graph.windowSize();
+ if (x + n >= length ) {
+ n = length - x;
}
+
+ n = arv->audio_region()->read_at(buf, mixbuf, gain, arv->region()->position() + x, n, channel);
+
+ if (n == 0)
+ break;
+
+ if ( n < fft_graph.windowSize()) {
+ for (int j = n; j < fft_graph.windowSize(); j++) {
+ buf[j] = 0.0;
+ }
+ }
+
+ res->analyzeWindow(buf);
+
+ x += n;
}
-
- res->analyzeWindow(buf);
-
- i += n;
}
// cerr << "Found: " << (*j)->get_item_name() << endl;