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)
{
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));
_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) {
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;
+ }
}
#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 ();
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;
_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;
}
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) {
#include <iostream>
#include <vector>
#include <list>
+#include <boost/filesystem.hpp>
class AudioPoint
{
{
public:
AudioAnalysis (int c);
- AudioAnalysis (std::string);
+ AudioAnalysis (boost::filesystem::path);
void add_point (int c, AudioPoint const & p);
int points (int c) const;
int channels () const;
- void write (std::string);
+ void write (boost::filesystem::path);
private:
std::vector<std::vector<AudioPoint> > _data;
}
}
+/** 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)
{
if (!_data[i]) {
throw bad_alloc ();
}
+ for (int j = _allocated_frames; j < frames; ++j) {
+ _data[i][j] = 0;
+ }
}
_allocated_frames = frames;
#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;
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 ()));
+}
-/* -*- c-basic-offset: 8; default-tab-width: 8; -*- */
-
/*
Copyright (C) 2013 Carl Hetherington <cth@carlh.net>
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);
_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
}
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());
}
-/* -*- c-basic-offset: 8; default-tab-width: 8; -*- */
-
/*
Copyright (C) 2013 Carl Hetherington <cth@carlh.net>
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)
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 */
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 */
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)
{
ExamineContentJob::run ()
{
_content->examine (shared_from_this ());
- _film->add_content (_content);
set_progress (1);
set_state (FINISHED_OK);
}
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;
-/* -*- c-basic-offset: 8; default-tab-width: 8; -*- */
-
/*
Copyright (C) 2012 Carl Hetherington <cth@carlh.net>
}
avsubtitle_free (&sub);
}
- } else {
- cout << "[ffmpeg] other packet.\n";
}
av_free_packet (&_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;
#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"
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;
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 */
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 ()
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)
{
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 ();
/** 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;
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)
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 */
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:
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;
}
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;
}
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;
}
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);
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);
}
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
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 ();
}
decoder = fd;
- cout << "\tFFmpeg @ " << fc->start() << " -- " << fc->end() << "\n";
}
shared_ptr<const ImageMagickContent> ic = dynamic_pointer_cast<const ImageMagickContent> (*i);
}
decoder = id;
- cout << "\tImageMagick @ " << ic->start() << " -- " << ic->end() << "\n";
}
shared_ptr<const SndfileContent> sc = dynamic_pointer_cast<const SndfileContent> (*i);
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)));
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
{
return _content;
}
- std::string audio_digest () const;
std::string video_digest () const;
int loop () const {
};
-SCPDCPJob::SCPDCPJob (shared_ptr<Film> f)
+SCPDCPJob::SCPDCPJob (shared_ptr<const Film> f)
: Job (f)
, _status (_("Waiting"))
{
class SCPDCPJob : public Job
{
public:
- SCPDCPJob (boost::shared_ptr<Film>);
+ SCPDCPJob (boost::shared_ptr<const Film>);
std::string name () const;
void run ();
/** @param s Film to use.
*/
-TranscodeJob::TranscodeJob (shared_ptr<Film> f)
+TranscodeJob::TranscodeJob (shared_ptr<const Film> f)
: Job (f)
{
class TranscodeJob : public Job
{
public:
- TranscodeJob (boost::shared_ptr<Film> f);
+ TranscodeJob (boost::shared_ptr<const Film> f);
std::string name () const;
void run ();
* @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))
{
public:
Transcoder (
- boost::shared_ptr<Film> f,
+ boost::shared_ptr<const Film> f,
boost::shared_ptr<Job> j
);
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)
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;
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;
ID_jobs_make_dcp,
ID_jobs_send_dcp_to_tms,
ID_jobs_show_dcp,
- ID_jobs_analyse_audio,
};
void
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__
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));
#endif
}
- void jobs_analyse_audio (wxCommandEvent &)
- {
- film->analyse_audio ();
- }
-
void help_about (wxCommandEvent &)
{
AboutDialog* d = new AboutDialog (this);
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());
-/* -*- c-basic-offset: 8; default-tab-width: 8; -*- */
-
/*
Copyright (C) 2013 Carl Hetherington <cth@carlh.net>
}
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()));
}
{
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));
}
}
}
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 ());
}
}
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;
};
-/* -*- c-basic-offset: 8; default-tab-width: 8; -*- */
-
/*
Copyright (C) 2013 Carl Hetherington <cth@carlh.net>
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;
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;
FileChanged ("");
}
- if (_audio_dialog) {
- _audio_dialog->set_film (_film);
- }
-
film_changed (Film::NAME);
film_changed (Film::USE_DCI_NAME);
film_changed (Film::CONTENT);
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.
_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
{
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);