Various fixes to make audio analysis sort-of work.
authorCarl Hetherington <cth@carlh.net>
Thu, 20 Jun 2013 16:34:23 +0000 (17:34 +0100)
committerCarl Hetherington <cth@carlh.net>
Thu, 20 Jun 2013 20:20:38 +0000 (21:20 +0100)
35 files changed:
src/lib/analyse_audio_job.cc
src/lib/analyse_audio_job.h
src/lib/audio_analysis.cc
src/lib/audio_analysis.h
src/lib/audio_buffers.cc
src/lib/audio_content.cc
src/lib/audio_content.h
src/lib/audio_decoder.cc
src/lib/content.h
src/lib/encoder.cc
src/lib/encoder.h
src/lib/examine_content_job.cc
src/lib/examine_content_job.h
src/lib/ffmpeg_decoder.cc
src/lib/film.cc
src/lib/film.h
src/lib/job.cc
src/lib/job.h
src/lib/player.cc
src/lib/playlist.cc
src/lib/playlist.h
src/lib/scp_dcp_job.cc
src/lib/scp_dcp_job.h
src/lib/transcode_job.cc
src/lib/transcode_job.h
src/lib/transcoder.cc
src/lib/transcoder.h
src/lib/writer.cc
src/lib/writer.h
src/tools/dcpomatic.cc
src/wx/about_dialog.cc
src/wx/audio_dialog.cc
src/wx/audio_dialog.h
src/wx/audio_plot.cc
src/wx/film_editor.cc

index 3a44a408fe2aec93cb1869f30d044ac90874ef32..2848c1ed773c16dfe5b6acbf0b3c0f6b61f65aac 100644 (file)
@@ -33,8 +33,9 @@ using boost::shared_ptr;
 
 int const AnalyseAudioJob::_num_points = 1024;
 
-AnalyseAudioJob::AnalyseAudioJob (shared_ptr<Film> f)
+AnalyseAudioJob::AnalyseAudioJob (shared_ptr<const Film> f, shared_ptr<AudioContent> c)
        : Job (f)
+       , _content (c)
        , _done (0)
        , _samples_per_point (1)
 {
@@ -44,13 +45,25 @@ AnalyseAudioJob::AnalyseAudioJob (shared_ptr<Film> f)
 string
 AnalyseAudioJob::name () const
 {
-       return String::compose (_("Analyse audio of %1"), _film->name());
+       shared_ptr<AudioContent> content = _content.lock ();
+       if (!content) {
+               return "";
+       }
+       
+       return String::compose (_("Analyse audio of %1"), content->file().filename());
 }
 
 void
 AnalyseAudioJob::run ()
 {
-       shared_ptr<Player> player = _film->player ();
+       shared_ptr<AudioContent> content = _content.lock ();
+       if (!content) {
+               return;
+       }
+
+       shared_ptr<Playlist> playlist (new Playlist);
+       playlist->add (content);
+       shared_ptr<Player> player (new Player (_film, playlist));
        player->disable_video ();
        
        player->Audio.connect (bind (&AnalyseAudioJob::audio, this, _1, _2));
@@ -61,18 +74,18 @@ AnalyseAudioJob::run ()
        _analysis.reset (new AudioAnalysis (_film->dcp_audio_channels ()));
 
        _done = 0;
-       while (player->pass ()) {
-               set_progress (double (_done) / _film->length ());
+       while (!player->pass ()) {
+               set_progress (double (_film->audio_frames_to_time (_done)) / _film->length ());
        }
 
-       _analysis->write (_film->audio_analysis_path ());
+       _analysis->write (content->audio_analysis_path ());
        
        set_progress (1);
        set_state (FINISHED_OK);
 }
 
 void
-AnalyseAudioJob::audio (shared_ptr<const AudioBuffers> b, Time t)
+AnalyseAudioJob::audio (shared_ptr<const AudioBuffers> b, Time)
 {
        for (int i = 0; i < b->frames(); ++i) {
                for (int j = 0; j < b->channels(); ++j) {
@@ -88,12 +101,12 @@ AnalyseAudioJob::audio (shared_ptr<const AudioBuffers> b, Time t)
                        if ((_done % _samples_per_point) == 0) {
                                _current[j][AudioPoint::RMS] = sqrt (_current[j][AudioPoint::RMS] / _samples_per_point);
                                _analysis->add_point (j, _current[j]);
-                               
+
                                _current[j] = AudioPoint ();
                        }
                }
-       }
 
-       _done = t;
+               ++_done;
+       }
 }
 
index a0786a017c8b23cba7133e45c6f78b59ceb35bb9..3d4881983b5234572ce40a47455c5b849a620328 100644 (file)
 #include "types.h"
 
 class AudioBuffers;
+class AudioContent;
 
 class AnalyseAudioJob : public Job
 {
 public:
-       AnalyseAudioJob (boost::shared_ptr<Film> f);
+       AnalyseAudioJob (boost::shared_ptr<const Film>, boost::shared_ptr<AudioContent>);
 
        std::string name () const;
        void run ();
@@ -34,7 +35,8 @@ public:
 private:
        void audio (boost::shared_ptr<const AudioBuffers>, Time);
 
-       Time _done;
+       boost::weak_ptr<AudioContent> _content;
+       OutputAudioFrame _done;
        int64_t _samples_per_point;
        std::vector<AudioPoint> _current;
 
index 9d708bbfdd07f30e07327781cc328828a4ecce06..e1251662089bd543fc3d713eadb8748ca37c8a9d 100644 (file)
@@ -62,9 +62,9 @@ AudioAnalysis::AudioAnalysis (int channels)
        _data.resize (channels);
 }
 
-AudioAnalysis::AudioAnalysis (string filename)
+AudioAnalysis::AudioAnalysis (boost::filesystem::path filename)
 {
-       ifstream f (filename.c_str ());
+       ifstream f (filename.string().c_str ());
 
        int channels;
        f >> channels;
@@ -107,10 +107,10 @@ AudioAnalysis::points (int c) const
 }
 
 void
-AudioAnalysis::write (string filename)
+AudioAnalysis::write (boost::filesystem::path filename)
 {
-       string tmp = filename + ".tmp";
-       
+       string tmp = filename.string() + ".tmp";
+
        ofstream f (tmp.c_str ());
        f << _data.size() << "\n";
        for (vector<vector<AudioPoint> >::iterator i = _data.begin(); i != _data.end(); ++i) {
index ec6905105934cf5cc78b3a48d736a98806c51001..d57eba90a3184200a18619bcb0ac4b0727998038 100644 (file)
@@ -23,6 +23,7 @@
 #include <iostream>
 #include <vector>
 #include <list>
+#include <boost/filesystem.hpp>
 
 class AudioPoint
 {
@@ -50,7 +51,7 @@ class AudioAnalysis
 {
 public:
        AudioAnalysis (int c);
-       AudioAnalysis (std::string);
+       AudioAnalysis (boost::filesystem::path);
 
        void add_point (int c, AudioPoint const & p);
        
@@ -58,7 +59,7 @@ public:
        int points (int c) const;
        int channels () const;
 
-       void write (std::string);
+       void write (boost::filesystem::path);
 
 private:
        std::vector<std::vector<AudioPoint> > _data;
index c3e89f1302e5315e01495c374a994975b19b806b..403babaf7f84bd4b0ff0974d67a4fb5471b93234 100644 (file)
@@ -206,6 +206,9 @@ AudioBuffers::accumulate_channel (AudioBuffers const * from, int from_channel, i
        }
 }
 
+/** Ensure we have space for at least a certain number of frames.  If we extend
+ *  the buffers, fill the new space with silence.
+ */
 void
 AudioBuffers::ensure_size (int frames)
 {
@@ -218,6 +221,9 @@ AudioBuffers::ensure_size (int frames)
                if (!_data[i]) {
                        throw bad_alloc ();
                }
+               for (int j = _allocated_frames; j < frames; ++j) {
+                       _data[i][j] = 0;
+               }
        }
 
        _allocated_frames = frames;
index 9940574f93bf8cbf11c726638a98a2aec1dc5ce6..e93f348f42359aab632c3d9738c6689200a4a9cf 100644 (file)
 
 #include <libcxml/cxml.h>
 #include "audio_content.h"
+#include "analyse_audio_job.h"
+#include "job_manager.h"
 #include "film.h"
 
 using std::string;
 using boost::shared_ptr;
 using boost::lexical_cast;
+using boost::dynamic_pointer_cast;
 
 int const AudioContentProperty::AUDIO_CHANNELS = 200;
 int const AudioContentProperty::AUDIO_LENGTH = 201;
@@ -93,3 +96,27 @@ AudioContent::set_audio_delay (int d)
        
        signal_changed (AudioContentProperty::AUDIO_DELAY);
 }
+
+void
+AudioContent::analyse_audio (boost::function<void()> finished)
+{
+       shared_ptr<const Film> film = _film.lock ();
+       if (!film) {
+               return;
+       }
+       
+       shared_ptr<AnalyseAudioJob> job (new AnalyseAudioJob (film, dynamic_pointer_cast<AudioContent> (shared_from_this())));
+       job->Finished.connect (finished);
+       JobManager::instance()->add (job);
+}
+
+boost::filesystem::path
+AudioContent::audio_analysis_path () const
+{
+       shared_ptr<const Film> film = _film.lock ();
+       if (!film) {
+               return boost::filesystem::path ();
+       }
+
+       return film->audio_analysis_path (dynamic_pointer_cast<const AudioContent> (shared_from_this ()));
+}
index 8fc658a7660177eb47b46eb22f1418f38f87d0c5..73a00ca7d70f3b7862e93accf6168129b1fba4ea 100644 (file)
@@ -1,5 +1,3 @@
-/* -*- c-basic-offset: 8; default-tab-width: 8; -*- */
-
 /*
     Copyright (C) 2013 Carl Hetherington <cth@carlh.net>
 
@@ -57,6 +55,9 @@ public:
        virtual AudioMapping audio_mapping () const = 0;
        virtual void set_audio_mapping (AudioMapping) = 0;
 
+       void analyse_audio (boost::function<void()>);
+       boost::filesystem::path audio_analysis_path () const;
+
        void set_audio_gain (float);
        void set_audio_delay (int);
        
index bbd4ced6c1a2c114f337729f8fe609f71e1eb353..a9e01908c4782a6095821d080800b0568ce71214 100644 (file)
@@ -59,10 +59,10 @@ AudioDecoder::AudioDecoder (shared_ptr<const Film> f, shared_ptr<const AudioCont
 
                _swr_context = swr_alloc_set_opts (
                        0,
-                       av_get_default_channel_layout (MAX_AUDIO_CHANNELS),
+                       av_get_default_channel_layout (_audio_content->audio_channels ()),
                        AV_SAMPLE_FMT_FLTP,
                        _audio_content->output_audio_frame_rate(),
-                       av_get_default_channel_layout (MAX_AUDIO_CHANNELS),
+                       av_get_default_channel_layout (_audio_content->audio_channels ()),
                        AV_SAMPLE_FMT_FLTP,
                        _audio_content->content_audio_frame_rate(),
                        0, 0
@@ -152,7 +152,6 @@ AudioDecoder::audio (shared_ptr<const AudioBuffers> data, Time time)
        }
 
        Audio (dcp_mapped, time);
-       cout << "bumping n.a. by " << data->frames() << " ie " << film->audio_frames_to_time(data->frames()) << "\n";
        _next_audio = time + film->audio_frames_to_time (data->frames());
 }
 
index 5e8f98428dd1314b68f3551617a0f576c9e3a11e..e33f517abf1f9e6205a208ccc44539c6b592f7ed 100644 (file)
@@ -1,5 +1,3 @@
-/* -*- c-basic-offset: 8; default-tab-width: 8; -*- */
-
 /*
     Copyright (C) 2013 Carl Hetherington <cth@carlh.net>
 
index 4dff19ea6dbd8bc93f0fd7573c77cc206e6768e5..8b2db0eb3113767594264b6ca8367e2022bbbe8b 100644 (file)
@@ -47,7 +47,7 @@ using boost::optional;
 int const Encoder::_history_size = 25;
 
 /** @param f Film that we are encoding */
-Encoder::Encoder (shared_ptr<Film> f, shared_ptr<Job> j)
+Encoder::Encoder (shared_ptr<const Film> f, shared_ptr<Job> j)
        : _film (f)
        , _job (j)
        , _video_frames_out (0)
index 8f724525cbe791c965d67c3b1e13f06f08f7a1b4..3fe707b511e717b38b001788db4a35d601ae8dfd 100644 (file)
@@ -58,7 +58,7 @@ class Job;
 class Encoder : public VideoSink, public AudioSink
 {
 public:
-       Encoder (boost::shared_ptr<Film> f, boost::shared_ptr<Job>);
+       Encoder (boost::shared_ptr<const Film> f, boost::shared_ptr<Job>);
        virtual ~Encoder ();
 
        /** Called to indicate that a processing run is about to begin */
@@ -87,7 +87,7 @@ private:
        void terminate_threads ();
 
        /** Film that we are encoding */
-       boost::shared_ptr<Film> _film;
+       boost::shared_ptr<const Film> _film;
        boost::shared_ptr<Job> _job;
 
        /** Mutex for _time_history and _last_frame */
index f68a1eea0e7e765301292c6ff1b66496e5b754cd..3cab9716de3783576d92cd9e441d50e6d1765df8 100644 (file)
@@ -28,7 +28,7 @@
 using std::string;
 using boost::shared_ptr;
 
-ExamineContentJob::ExamineContentJob (shared_ptr<Film> f, shared_ptr<Content> c)
+ExamineContentJob::ExamineContentJob (shared_ptr<const Film> f, shared_ptr<Content> c)
        : Job (f)
        , _content (c)
 {
@@ -49,7 +49,6 @@ void
 ExamineContentJob::run ()
 {
        _content->examine (shared_from_this ());
-       _film->add_content (_content);
        set_progress (1);
        set_state (FINISHED_OK);
 }
index 86f1ab111d81284f4e95aa34b8fb507ff6c48e11..b6903b86bebf0ed9e80970a7382c0f07628301cc 100644 (file)
@@ -26,7 +26,7 @@ class Log;
 class ExamineContentJob : public Job
 {
 public:
-       ExamineContentJob (boost::shared_ptr<Film>, boost::shared_ptr<Content>);
+       ExamineContentJob (boost::shared_ptr<const Film>, boost::shared_ptr<Content>);
        ~ExamineContentJob ();
 
        std::string name () const;
index 36078a463502ad91e5b7422c8f43794601740364..2e586b8f7fcdfc486abec542c052297ac1bb8bea 100644 (file)
@@ -1,5 +1,3 @@
-/* -*- c-basic-offset: 8; default-tab-width: 8; -*- */
-
 /*
     Copyright (C) 2012 Carl Hetherington <cth@carlh.net>
 
@@ -278,8 +276,6 @@ FFmpegDecoder::pass ()
                        }
                        avsubtitle_free (&sub);
                }
-       } else {
-               cout << "[ffmpeg] other packet.\n";
        }
 
        av_free_packet (&_packet);
@@ -541,7 +537,7 @@ FFmpegDecoder::decode_audio_packet ()
                                        );
                                
                                assert (_audio_codec_context->channels == _ffmpeg_content->audio_channels());
-                               audio (deinterleave_audio (_frame->data, data_size), source_pts_seconds);
+                               audio (deinterleave_audio (_frame->data, data_size), source_pts_seconds * TIME_HZ);
                        }
                        
                        copy_packet.data += decode_result;
index a29f6c331a974740ad67a34592c4e95780504c50..ad565aca0b2e6bcd16717fd9f64f6d31f0ec8187 100644 (file)
@@ -45,7 +45,6 @@
 #include "config.h"
 #include "version.h"
 #include "ui_signaller.h"
-#include "analyse_audio_job.h"
 #include "playlist.h"
 #include "player.h"
 #include "ffmpeg_content.h"
@@ -72,6 +71,7 @@ using std::endl;
 using std::cout;
 using std::list;
 using boost::shared_ptr;
+using boost::weak_ptr;
 using boost::lexical_cast;
 using boost::dynamic_pointer_cast;
 using boost::to_upper_copy;
@@ -222,13 +222,12 @@ Film::filename_safe_name () const
        return o;
 }
 
-string
-Film::audio_analysis_path () const
+boost::filesystem::path
+Film::audio_analysis_path (shared_ptr<const AudioContent> c) const
 {
-       boost::filesystem::path p;
-       p /= "analysis";
-       p /= _playlist->audio_digest();
-       return file (p.string ());
+       boost::filesystem::path p = dir ("analysis");
+       p /= c->digest();
+       return p;
 }
 
 /** Add suitable Jobs to the JobManager to create a DCP for this Film */
@@ -289,31 +288,6 @@ Film::make_dcp ()
        JobManager::instance()->add (shared_ptr<Job> (new TranscodeJob (shared_from_this())));
 }
 
-/** Start a job to analyse the audio in our Playlist */
-void
-Film::analyse_audio ()
-{
-       if (_analyse_audio_job) {
-               return;
-       }
-
-       _analyse_audio_job.reset (new AnalyseAudioJob (shared_from_this()));
-       _analyse_audio_job->Finished.connect (bind (&Film::analyse_audio_finished, this));
-       JobManager::instance()->add (_analyse_audio_job);
-}
-
-void
-Film::analyse_audio_finished ()
-{
-       ensure_ui_thread ();
-
-       if (_analyse_audio_job->finished_ok ()) {
-               AudioAnalysisSucceeded ();
-       }
-       
-       _analyse_audio_job.reset ();
-}
-
 /** Start a job to send our DCP to the configured TMS */
 void
 Film::send_dcp_to_tms ()
@@ -782,9 +756,19 @@ void
 Film::examine_and_add_content (shared_ptr<Content> c)
 {
        shared_ptr<Job> j (new ExamineContentJob (shared_from_this(), c));
+       j->Finished.connect (bind (&Film::add_content_weak, this, boost::weak_ptr<Content> (c)));
        JobManager::instance()->add (j);
 }
 
+void
+Film::add_content_weak (weak_ptr<Content> c)
+{
+       shared_ptr<Content> content = c.lock ();
+       if (content) {
+               add_content (content);
+       }
+}
+
 void
 Film::add_content (shared_ptr<Content> c)
 {
index 5f06a1dc73242c1eb3b1e1757aedf1752d745f42..5bb9acf297be8091ef7db70934eed336aa657c39 100644 (file)
@@ -63,12 +63,11 @@ public:
        std::string info_path (int f) const;
        std::string internal_video_mxf_dir () const;
        std::string internal_video_mxf_filename () const;
-       std::string audio_analysis_path () const;
+       boost::filesystem::path audio_analysis_path (boost::shared_ptr<const AudioContent>) const;
 
        std::string dcp_video_mxf_filename () const;
        std::string dcp_audio_mxf_filename () const;
 
-       void analyse_audio ();
        void send_dcp_to_tms ();
        void make_dcp ();
 
@@ -244,24 +243,20 @@ public:
        /** Emitted when some property of our content has changed */
        mutable boost::signals2::signal<void (boost::weak_ptr<Content>, int)> ContentChanged;
 
-       boost::signals2::signal<void ()> AudioAnalysisSucceeded;
-
        /** Current version number of the state file */
        static int const state_version;
 
 private:
        
        void signal_changed (Property);
-       void analyse_audio_finished ();
        std::string video_state_identifier () const;
        void playlist_changed ();
        void playlist_content_changed (boost::weak_ptr<Content>, int);
        std::string filename_safe_name () const;
+       void add_content_weak (boost::weak_ptr<Content>);
 
        /** Log to write to */
        boost::shared_ptr<Log> _log;
-       /** Any running AnalyseAudioJob, or 0 */
-       boost::shared_ptr<AnalyseAudioJob> _analyse_audio_job;
        boost::shared_ptr<Playlist> _playlist;
 
        /** Complete path to directory containing the film metadata;
index 2e6385d62e8499a37ed427fb3650c1e22aec5196..4969c4099c8aae60a4e7c22db6618ded9c8a1c93 100644 (file)
@@ -35,7 +35,7 @@ using std::list;
 using std::stringstream;
 using boost::shared_ptr;
 
-Job::Job (shared_ptr<Film> f)
+Job::Job (shared_ptr<const Film> f)
        : _film (f)
        , _thread (0)
        , _state (NEW)
index 40e90b73c72b3c136f0570cf7198018746610a29..5a4775180586e7dbed363c6e4ac1bc3bb06ae97b 100644 (file)
@@ -38,7 +38,7 @@ class Film;
 class Job : public boost::enable_shared_from_this<Job>
 {
 public:
-       Job (boost::shared_ptr<Film>);
+       Job (boost::shared_ptr<const Film>);
        virtual ~Job() {}
 
        /** @return user-readable name of this job */
@@ -91,7 +91,7 @@ protected:
        void set_state (State);
        void set_error (std::string s, std::string d);
 
-       boost::shared_ptr<Film> _film;
+       boost::shared_ptr<const Film> _film;
 
 private:
 
index 60686e78178e00276513e248a51a97623c861764..c05897c23b02adfc64d233c88d900ff14264a749 100644 (file)
@@ -95,11 +95,6 @@ Player::pass ()
         shared_ptr<Piece> earliest;
 
        for (list<shared_ptr<Piece> >::iterator i = _pieces.begin(); i != _pieces.end(); ++i) {
-               cout << "check " << (*i)->content->file()
-                    << " start=" << (*i)->content->start()
-                    << ", position=" << (*i)->decoder->position()
-                    << ", end=" << (*i)->content->end() << "\n";
-               
                if ((*i)->decoder->done ()) {
                        continue;
                }
@@ -110,7 +105,6 @@ Player::pass ()
                
                Time const t = (*i)->content->start() + (*i)->decoder->position();
                if (t < earliest_t) {
-                       cout << "\t candidate; " << t << " " << (t / TIME_HZ) << ".\n";
                        earliest_t = t;
                        earliest = *i;
                }
@@ -121,23 +115,8 @@ Player::pass ()
                return true;
        }
 
-       cout << "PASS:\n";
-       cout << "\tpass " << earliest->content->file() << " ";
-       if (dynamic_pointer_cast<FFmpegContent> (earliest->content)) {
-               cout << " FFmpeg.\n";
-       } else if (dynamic_pointer_cast<ImageMagickContent> (earliest->content)) {
-               cout << " ImageMagickContent.\n";
-       } else if (dynamic_pointer_cast<SndfileContent> (earliest->content)) {
-               cout << " SndfileContent.\n";
-       } else if (dynamic_pointer_cast<BlackDecoder> (earliest->decoder)) {
-               cout << " Black.\n";
-       } else if (dynamic_pointer_cast<SilenceDecoder> (earliest->decoder)) {
-               cout << " Silence.\n";
-       }
-       
        earliest->decoder->pass ();
        _position = earliest->content->start() + earliest->decoder->position ();
-       cout << "\tpassed to " << _position << " " << (_position / TIME_HZ) << "\n";
 
         return false;
 }
@@ -169,6 +148,8 @@ Player::process_audio (weak_ptr<Content> weak_content, shared_ptr<const AudioBuf
 
        time += content->start ();
 
+       cout << "Player gets " << audio->frames() << " @ " << time << " cf " << _next_audio << "\n";
+
         if (time > _next_audio) {
                 /* We can emit some audio from our buffers */
                 OutputAudioFrame const N = _film->time_to_audio_frames (time - _next_audio);
@@ -216,13 +197,10 @@ Player::seek (Time t)
                return;
        }
 
-//     cout << "seek to " << t << " " << (t / TIME_HZ) << "\n";
-
        for (list<shared_ptr<Piece> >::iterator i = _pieces.begin(); i != _pieces.end(); ++i) {
                Time s = t - (*i)->content->start ();
                s = max (static_cast<Time> (0), s);
                s = min ((*i)->content->length(), s);
-//             cout << "seek [" << (*i)->content->file() << "," << (*i)->content->start() << "," << (*i)->content->end() << "] to " << s << "\n";
                (*i)->decoder->seek (s);
        }
 
@@ -250,7 +228,6 @@ Player::add_black_piece (Time s, Time len)
        shared_ptr<BlackDecoder> bd (new BlackDecoder (_film, nc));
        bd->Video.connect (bind (&Player::process_video, this, nc, _1, _2, _3));
        _pieces.push_back (shared_ptr<Piece> (new Piece (nc, bd)));
-       cout << "\tblack @ " << s << " -- " << (s + len) << "\n";
 }
 
 void
@@ -260,15 +237,12 @@ Player::add_silent_piece (Time s, Time len)
        shared_ptr<SilenceDecoder> sd (new SilenceDecoder (_film, nc));
        sd->Audio.connect (bind (&Player::process_audio, this, nc, _1, _2));
        _pieces.push_back (shared_ptr<Piece> (new Piece (nc, sd)));
-       cout << "\tsilence @ " << s << " -- " << (s + len) << "\n";
 }
 
 
 void
 Player::setup_pieces ()
 {
-       cout << "----- Player SETUP PIECES.\n";
-
        list<shared_ptr<Piece> > old_pieces = _pieces;
 
        _pieces.clear ();
@@ -293,7 +267,6 @@ Player::setup_pieces ()
                        }
 
                        decoder = fd;
-                       cout << "\tFFmpeg @ " << fc->start() << " -- " << fc->end() << "\n";
                }
                
                shared_ptr<const ImageMagickContent> ic = dynamic_pointer_cast<const ImageMagickContent> (*i);
@@ -317,7 +290,6 @@ Player::setup_pieces ()
                        }
 
                        decoder = id;
-                       cout << "\tImageMagick @ " << ic->start() << " -- " << ic->end() << "\n";
                }
 
                shared_ptr<const SndfileContent> sc = dynamic_pointer_cast<const SndfileContent> (*i);
@@ -326,7 +298,6 @@ Player::setup_pieces ()
                        sd->Audio.connect (bind (&Player::process_audio, this, *i, _1, _2));
 
                        decoder = sd;
-                       cout << "\tSndfile @ " << sc->start() << " -- " << sc->end() << "\n";
                }
 
                _pieces.push_back (shared_ptr<Piece> (new Piece (*i, decoder)));
index 5ee764a8e73d4e14491e3bac9d6333b19fb87392..9cc1789d135d5c38a66e416b4c90888421d7142e 100644 (file)
@@ -93,29 +93,6 @@ Playlist::content_changed (weak_ptr<Content> c, int p)
        ContentChanged (c, p);
 }
 
-string
-Playlist::audio_digest () const
-{
-       string t;
-       
-       for (ContentList::const_iterator i = _content.begin(); i != _content.end(); ++i) {
-               if (!dynamic_pointer_cast<const AudioContent> (*i)) {
-                       continue;
-               }
-               
-               t += (*i)->digest ();
-
-               shared_ptr<const FFmpegContent> fc = dynamic_pointer_cast<const FFmpegContent> (*i);
-               if (fc) {
-                       t += lexical_cast<string> (fc->audio_stream()->id);
-               }
-       }
-
-       t += lexical_cast<string> (_loop);
-
-       return md5_digest (t.c_str(), t.length());
-}
-
 string
 Playlist::video_digest () const
 {
index 3a7ca73bf3dcf4f3e772c024ab41c8c92439e5b6..e4f4c79f00ee5c8fcaa46e0a7ad17ca014105e81 100644 (file)
@@ -77,7 +77,6 @@ public:
                return _content;
        }
 
-       std::string audio_digest () const;
        std::string video_digest () const;
 
        int loop () const {
index a9fdfefda2f01671698c83279a624e5102ed894d..8cde44f0258a2d65ad8a4a44fa437b653f216c2d 100644 (file)
@@ -96,7 +96,7 @@ public:
 };
 
 
-SCPDCPJob::SCPDCPJob (shared_ptr<Film> f)
+SCPDCPJob::SCPDCPJob (shared_ptr<const Film> f)
        : Job (f)
        , _status (_("Waiting"))
 {
index 8c16d53fbf7c6867cb4ebebed4a3440a528c7172..bdc83af187f85a0091d31e107d554ee9dd07ef4c 100644 (file)
@@ -26,7 +26,7 @@
 class SCPDCPJob : public Job
 {
 public:
-       SCPDCPJob (boost::shared_ptr<Film>);
+       SCPDCPJob (boost::shared_ptr<const Film>);
 
        std::string name () const;
        void run ();
index ce02fa57e7d302c0b7fc392a98f366bb38b639d9..6d5edd7c060c662dc404445c1e3ed1a1175d4ace 100644 (file)
@@ -38,7 +38,7 @@ using boost::shared_ptr;
 
 /** @param s Film to use.
  */
-TranscodeJob::TranscodeJob (shared_ptr<Film> f)
+TranscodeJob::TranscodeJob (shared_ptr<const Film> f)
        : Job (f)
 {
        
index 7880a925ebb56e4921fea0b2745ab1b3f1882788..9128206d29dc9c9e42460cafecfa4748f0a1c0db 100644 (file)
@@ -32,7 +32,7 @@ class Transcoder;
 class TranscodeJob : public Job
 {
 public:
-       TranscodeJob (boost::shared_ptr<Film> f);
+       TranscodeJob (boost::shared_ptr<const Film> f);
        
        std::string name () const;
        void run ();
index 847be2f1c9f6b61d2cde0bdd3d53185a47132a89..f4637a05cf1c0f983d9a26bff6edca680b6f5d39 100644 (file)
@@ -43,7 +43,7 @@ using boost::dynamic_pointer_cast;
  *  @param j Job that we are running under, or 0.
  *  @param e Encoder to use.
  */
-Transcoder::Transcoder (shared_ptr<Film> f, shared_ptr<Job> j)
+Transcoder::Transcoder (shared_ptr<const Film> f, shared_ptr<Job> j)
        : _job (j)
        , _player (f->player ())
        , _encoder (new Encoder (f, j))
index f7da3bd013eb9241d0b2cb4b550558145ff09ca0..b3c8f888b1106dfd4ffb6753ae247672ded2fff4 100644 (file)
@@ -40,7 +40,7 @@ class Transcoder
 {
 public:
        Transcoder (
-               boost::shared_ptr<Film> f,
+               boost::shared_ptr<const Film> f,
                boost::shared_ptr<Job> j
                );
 
index e9f7ab582a8ed95b489859288e46f7cb11d63478..35874581b62d829b74d9b1399f6fce36a20ee620 100644 (file)
@@ -48,7 +48,7 @@ using boost::shared_ptr;
 
 int const Writer::_maximum_frames_in_memory = 8;
 
-Writer::Writer (shared_ptr<Film> f, shared_ptr<Job> j)
+Writer::Writer (shared_ptr<const Film> f, shared_ptr<Job> j)
        : _film (f)
        , _job (j)
        , _first_nonexistant_frame (0)
index 62714edf39f675e6354510434618e695a214576c..e56e12e75a2255ac95bab0b1563733f3a5521e94 100644 (file)
@@ -64,7 +64,7 @@ bool operator== (QueueItem const & a, QueueItem const & b);
 class Writer : public ExceptionStore
 {
 public:
-       Writer (boost::shared_ptr<Film>, boost::shared_ptr<Job>);
+       Writer (boost::shared_ptr<const Film>, boost::shared_ptr<Job>);
 
        bool can_fake_write (int) const;
        
@@ -80,7 +80,7 @@ private:
        void check_existing_picture_mxf ();
 
        /** our Film */
-       boost::shared_ptr<Film> _film;
+       boost::shared_ptr<const Film> _film;
        boost::shared_ptr<Job> _job;
        /** the first frame index that does not already exist in our MXF */
        int _first_nonexistant_frame;
index 77800b5fdfcfe9d8101c252fa007f012b059cb56..683e60ceb2b930e56b23c492ac889d23a4dca38b 100644 (file)
@@ -149,7 +149,6 @@ enum {
        ID_jobs_make_dcp,
        ID_jobs_send_dcp_to_tms,
        ID_jobs_show_dcp,
-       ID_jobs_analyse_audio,
 };
 
 void
@@ -178,8 +177,6 @@ setup_menu (wxMenuBar* m)
        add_item (jobs_menu, _("&Make DCP"), ID_jobs_make_dcp, NEEDS_FILM);
        add_item (jobs_menu, _("&Send DCP to TMS"), ID_jobs_send_dcp_to_tms, NEEDS_FILM);
        add_item (jobs_menu, _("S&how DCP"), ID_jobs_show_dcp, NEEDS_FILM);
-       jobs_menu->AppendSeparator ();
-       add_item (jobs_menu, _("&Analyse audio"), ID_jobs_analyse_audio, NEEDS_FILM);
 
        wxMenu* help = new wxMenu;
 #ifdef __WXOSX__       
@@ -222,7 +219,6 @@ public:
                Connect (ID_jobs_make_dcp, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler (Frame::jobs_make_dcp));
                Connect (ID_jobs_send_dcp_to_tms, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler (Frame::jobs_send_dcp_to_tms));
                Connect (ID_jobs_show_dcp, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler (Frame::jobs_show_dcp));
-               Connect (ID_jobs_analyse_audio, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler (Frame::jobs_analyse_audio));
                Connect (wxID_ABOUT, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler (Frame::help_about));
 
                Connect (wxID_ANY, wxEVT_MENU_OPEN, wxMenuEventHandler (Frame::menu_opened));
@@ -399,11 +395,6 @@ private:
 #endif         
        }
 
-       void jobs_analyse_audio (wxCommandEvent &)
-       {
-               film->analyse_audio ();
-       }
-       
        void help_about (wxCommandEvent &)
        {
                AboutDialog* d = new AboutDialog (this);
index 7844180fa25b6ecb63ac003b848fd756f34cbeda..0c56cf1be0ea56c865922f93c590e006f6c4346d 100644 (file)
@@ -62,8 +62,8 @@ AboutDialog::AboutDialog (wxWindow* parent)
 
        wxHyperlinkCtrl* h = new wxHyperlinkCtrl (
                this, wxID_ANY,
-               wxT ("www.carlh.net/software/dcpomatic"),
-               wxT ("http://www.carlh.net/software/dcpomatic")
+               wxT ("dcpomatic.com"),
+               wxT ("http://dcpomatic.com")
                );
 
        sizer->Add (h, wxSizerFlags().Centre().Border());
index 1241b61fb079cd1f4d9f108d153dcd7ba6f75157..ea7cc60dd0d135044ce8acc94c452bcc5fc8ffa0 100644 (file)
@@ -1,5 +1,3 @@
-/* -*- c-basic-offset: 8; default-tab-width: 8; -*- */
-
 /*
     Copyright (C) 2013 Carl Hetherington <cth@carlh.net>
 
@@ -85,20 +83,18 @@ AudioDialog::AudioDialog (wxWindow* parent)
 }
 
 void
-AudioDialog::set_film (shared_ptr<Film> f)
+AudioDialog::set_content (shared_ptr<AudioContent> c)
 {
-       _film_changed_connection.disconnect ();
-       _film_audio_analysis_succeeded_connection.disconnect ();
+       _content_changed_connection.disconnect ();
        
-       _film = f;
+       _content = c;
 
        try_to_load_analysis ();
-//     _plot->set_gain (_film->audio_gain ());
+       _plot->set_gain (_content->audio_gain ());
 
-       _film_changed_connection = _film->Changed.connect (bind (&AudioDialog::film_changed, this, _1));
-       _film_audio_analysis_succeeded_connection = _film->AudioAnalysisSucceeded.connect (bind (&AudioDialog::try_to_load_analysis, this));
+       _content_changed_connection = _content->Changed.connect (bind (&AudioDialog::content_changed, this, _2));
 
-       SetTitle (wxString::Format (_("DCP-o-matic audio - %s"), std_to_wx(_film->name()).data()));
+       SetTitle (wxString::Format (_("DCP-o-matic audio - %s"), std_to_wx(_content->file().filename().string()).data()));
 }
 
 
@@ -107,11 +103,11 @@ AudioDialog::try_to_load_analysis ()
 {
        shared_ptr<AudioAnalysis> a;
 
-       if (boost::filesystem::exists (_film->audio_analysis_path())) {
-               a.reset (new AudioAnalysis (_film->audio_analysis_path ()));
+       if (boost::filesystem::exists (_content->audio_analysis_path())) {
+               a.reset (new AudioAnalysis (_content->audio_analysis_path ()));
        } else {
                if (IsShown ()) {
-                       _film->analyse_audio ();
+                       _content->analyse_audio (bind (&AudioDialog::try_to_load_analysis, this));
                }
        }
                
@@ -142,14 +138,10 @@ AudioDialog::channel_clicked (wxCommandEvent& ev)
 }
 
 void
-AudioDialog::film_changed (Film::Property p)
+AudioDialog::content_changed (int p)
 {
-       switch (p) {
-//     case Film::AUDIO_GAIN:
-//             _plot->set_gain (_film->audio_gain ());
-               break;
-       default:
-               break;
+       if (p == AudioContentProperty::AUDIO_GAIN) {
+               _plot->set_gain (_content->audio_gain ());
        }
 }
 
index db1d74f306393ceaf9860919aefe82434a92ea36..c69baf282fc1f893a2a992d0b2cff717d5a6f090 100644 (file)
@@ -31,20 +31,19 @@ class AudioDialog : public wxDialog
 public:
        AudioDialog (wxWindow *);
 
-       void set_film (boost::shared_ptr<Film>);
+       void set_content (boost::shared_ptr<AudioContent>);
 
 private:
-       void film_changed (Film::Property);
+       void content_changed (int);
        void channel_clicked (wxCommandEvent &);
        void type_clicked (wxCommandEvent &);
        void smoothing_changed (wxScrollEvent &);
        void try_to_load_analysis ();
 
-       boost::shared_ptr<Film> _film;
+       boost::shared_ptr<AudioContent> _content;
        AudioPlot* _plot;
        wxCheckBox* _channel_checkbox[MAX_AUDIO_CHANNELS];
        wxCheckBox* _type_checkbox[AudioPoint::COUNT];
        wxSlider* _smoothing;
-       boost::signals2::scoped_connection _film_changed_connection;
-       boost::signals2::scoped_connection _film_audio_analysis_succeeded_connection;
+       boost::signals2::scoped_connection _content_changed_connection;
 };
index fb02fea7b9ebe734c8b43571998e95a0ca88688c..e2e2cdf764026eddc9a8f73b3728698aaf051bb2 100644 (file)
@@ -1,5 +1,3 @@
-/* -*- c-basic-offset: 8; default-tab-width: 8; -*- */
-
 /*
     Copyright (C) 2013 Carl Hetherington <cth@carlh.net>
 
@@ -193,6 +191,10 @@ AudioPlot::y_for_linear (float p) const
 void
 AudioPlot::plot_peak (wxGraphicsPath& path, int channel) const
 {
+       if (_analysis->points (channel) == 0) {
+               return;
+       }
+       
        path.MoveToPoint (_db_label_width, y_for_linear (_analysis->get_point(channel, 0)[AudioPoint::PEAK]));
 
        float peak = 0;
@@ -213,6 +215,10 @@ AudioPlot::plot_peak (wxGraphicsPath& path, int channel) const
 void
 AudioPlot::plot_rms (wxGraphicsPath& path, int channel) const
 {
+       if (_analysis->points (channel) == 0) {
+               return;
+       }
+       
        path.MoveToPoint (_db_label_width, y_for_linear (_analysis->get_point(channel, 0)[AudioPoint::RMS]));
 
        list<float> smoothing;
index 12b316dffd66e0c106b97b56979341e327280611..27803fb9a7e2464778a2eae26f0fb76c811d8d7d 100644 (file)
@@ -848,10 +848,6 @@ FilmEditor::set_film (shared_ptr<Film> f)
                FileChanged ("");
        }
 
-       if (_audio_dialog) {
-               _audio_dialog->set_film (_film);
-       }
-       
        film_changed (Film::NAME);
        film_changed (Film::USE_DCI_NAME);
        film_changed (Film::CONTENT);
@@ -867,19 +863,8 @@ FilmEditor::set_film (shared_ptr<Film> f)
        film_changed (Film::DCI_METADATA);
        film_changed (Film::DCP_VIDEO_FRAME_RATE);
 
-       shared_ptr<Content> s = selected_content ();
-       film_content_changed (s, ContentProperty::START);
-       film_content_changed (s, ContentProperty::LENGTH);
-       film_content_changed (s, VideoContentProperty::VIDEO_CROP);
-       film_content_changed (s, VideoContentProperty::VIDEO_RATIO);
-       film_content_changed (s, AudioContentProperty::AUDIO_GAIN);
-       film_content_changed (s, AudioContentProperty::AUDIO_DELAY);
-       film_content_changed (s, AudioContentProperty::AUDIO_MAPPING);
-       film_content_changed (s, FFmpegContentProperty::SUBTITLE_STREAMS);
-       film_content_changed (s, FFmpegContentProperty::SUBTITLE_STREAM);
-       film_content_changed (s, FFmpegContentProperty::AUDIO_STREAMS);
-       film_content_changed (s, FFmpegContentProperty::AUDIO_STREAM);
-       film_content_changed (s, FFmpegContentProperty::FILTERS);
+       wxListEvent ev;
+       content_selection_changed (ev);
 }
 
 /** Updates the sensitivity of lots of widgets to a given value.
@@ -1106,10 +1091,20 @@ FilmEditor::show_audio_clicked (wxCommandEvent &)
                _audio_dialog->Destroy ();
                _audio_dialog = 0;
        }
+
+       shared_ptr<Content> c = selected_content ();
+       if (!c) {
+               return;
+       }
+
+       shared_ptr<AudioContent> ac = dynamic_pointer_cast<AudioContent> (c);
+       if (!ac) {
+               return;
+       }
        
        _audio_dialog = new AudioDialog (this);
        _audio_dialog->Show ();
-       _audio_dialog->set_film (_film);
+       _audio_dialog->set_content (ac);
 }
 
 void
@@ -1199,6 +1194,11 @@ FilmEditor::content_selection_changed (wxListEvent &)
 {
         setup_content_sensitivity ();
        shared_ptr<Content> s = selected_content ();
+       
+       if (_audio_dialog && s && dynamic_pointer_cast<AudioContent> (s)) {
+               _audio_dialog->set_content (dynamic_pointer_cast<AudioContent> (s));
+       }
+       
        film_content_changed (s, ContentProperty::START);
        film_content_changed (s, ContentProperty::LENGTH);
        film_content_changed (s, VideoContentProperty::VIDEO_CROP);