#include <cmath>
#include <cassert>
#include <fstream>
+#include <boost/filesystem.hpp>
#include "audio_analysis.h"
using std::ostream;
void
AudioAnalysis::write (string filename)
{
- ofstream f (filename.c_str ());
+ string tmp = filename + ".tmp";
+
+ ofstream f (tmp.c_str ());
f << _data.size() << "\n";
for (vector<vector<AudioPoint> >::iterator i = _data.begin(); i != _data.end(); ++i) {
f << i->size () << "\n";
j->write (f);
}
}
+
+ f.close ();
+ boost::filesystem::rename (tmp, filename);
}
void
Film::analyse_audio_finished ()
{
+ ensure_ui_thread ();
_analyse_audio_job.reset ();
+
+ AudioAnalysisFinished ();
}
void
/** Emitted when some property has changed */
mutable boost::signals2::signal<void (Property)> Changed;
+ boost::signals2::signal<void ()> AudioAnalysisFinished;
+
/** Current version number of the state file */
static int const state_version;
if (_state == FINISHED_OK || _state == FINISHED_ERROR) {
_ran_for = elapsed_time ();
- Finished ();
}
}
void descend (float);
float overall_progress () const;
+ /** Emitted by the JobManagerView from the UI thread */
boost::signals2::signal<void()> Finished;
protected:
*/
+#include <boost/filesystem.hpp>
#include "audio_dialog.h"
#include "audio_plot.h"
#include "audio_analysis.h"
#include "wx_util.h"
using boost::shared_ptr;
+using boost::bind;
-AudioDialog::AudioDialog (wxWindow* parent, boost::shared_ptr<Film> film)
+AudioDialog::AudioDialog (wxWindow* parent)
: wxDialog (parent, wxID_ANY, _("Audio"), wxDefaultPosition, wxSize (640, 512), wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER)
, _plot (0)
{
sizer->Add (table);
- set_film (film);
-
SetSizer (sizer);
sizer->Layout ();
sizer->SetSizeHints (this);
void
AudioDialog::set_film (boost::shared_ptr<Film> f)
{
- _film_connection.disconnect ();
- _film = f;
+ _film_changed_connection.disconnect ();
+ _film_audio_analysis_finished_connection.disconnect ();
- shared_ptr<AudioAnalysis> a;
+ _film = f;
- try {
- a.reset (new AudioAnalysis (f->audio_analysis_path ()));
- } catch (...) {
+ try_to_load_analysis ();
+ setup_channels ();
- }
-
- _plot->set_analysis (a);
+ _channel->SetSelection (0);
+ _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));
+}
+
+void
+AudioDialog::setup_channels ()
+{
_channel->Clear ();
- for (int i = 0; i < f->audio_stream()->channels(); ++i) {
+
+ if (!_film->audio_stream()) {
+ return;
+ }
+
+ for (int i = 0; i < _film->audio_stream()->channels(); ++i) {
_channel->Append (audio_channel_name (i));
}
+}
- _channel->SetSelection (0);
+void
+AudioDialog::try_to_load_analysis ()
+{
+ shared_ptr<AudioAnalysis> a;
- _film_connection = f->Changed.connect (bind (&AudioDialog::film_changed, this, _1));
+ if (boost::filesystem::exists (_film->audio_analysis_path())) {
+ a.reset (new AudioAnalysis (_film->audio_analysis_path ()));
+ } else {
+ if (IsShown ()) {
+ _film->analyse_audio ();
+ }
+ }
+
+ _plot->set_analysis (a);
}
void
void
AudioDialog::film_changed (Film::Property p)
{
- if (p == Film::AUDIO_GAIN) {
+ switch (p) {
+ case Film::AUDIO_GAIN:
_plot->set_gain (_film->audio_gain ());
+ break;
+ case Film::CONTENT_AUDIO_STREAM:
+ case Film::EXTERNAL_AUDIO:
+ case Film::USE_CONTENT_AUDIO:
+ setup_channels ();
+ break;
+ default:
+ break;
}
}
class AudioDialog : public wxDialog
{
public:
- AudioDialog (wxWindow *, boost::shared_ptr<Film>);
+ AudioDialog (wxWindow *);
void set_film (boost::shared_ptr<Film>);
private:
void film_changed (Film::Property);
void channel_changed (wxCommandEvent &);
+ void try_to_load_analysis ();
+ void setup_channels ();
boost::shared_ptr<Film> _film;
AudioPlot* _plot;
wxChoice* _channel;
- boost::signals2::scoped_connection _film_connection;
+ boost::signals2::scoped_connection _film_changed_connection;
+ boost::signals2::scoped_connection _film_audio_analysis_finished_connection;
};
{
wxPaintDC dc (this);
- if (!_analysis) {
- return;
- }
-
wxGraphicsContext* gc = wxGraphicsContext::Create (dc);
if (!gc) {
return;
}
+ if (!_analysis) {
+ gc->SetFont (gc->CreateFont (*wxNORMAL_FONT));
+ gc->DrawText (_("Please wait; audio is being analysed..."), 32, 32);
+ return;
+ }
+
int const width = GetSize().GetWidth();
float const xs = width / float (_analysis->points (_channel));
int const height = GetSize().GetHeight ();
_audio_dialog = 0;
}
- _audio_dialog = new AudioDialog (this, _film);
+ _audio_dialog = new AudioDialog (this);
_audio_dialog->Show ();
+ _audio_dialog->set_film (_film);
}
if ((*i)->finished() && !_job_records[*i].finalised) {
_job_records[*i].gauge->SetValue (100);
checked_set (_job_records[*i].message, st);
+ (*i)->Finished ();
_job_records[*i].finalised = true;
if (!(*i)->error_details().empty ()) {
_job_records[*i].details->Enable (true);