use SilentFileSource when sources cannot be found

git-svn-id: svn://localhost/ardour2/trunk@1424 d708f5d6-7413-0410-9779-e7cbd77b26cf
This commit is contained in:
Paul Davis 2007-02-05 22:57:38 +00:00
parent 87ee8fd71f
commit 672a31a552
10 changed files with 167 additions and 15 deletions

View File

@ -112,7 +112,6 @@
(gtk_accel_path "<Actions>/Editor/extend-range-to-end-of-region" "rightanglebracket")
(gtk_accel_path "<Actions>/Editor/scroll-backward" "leftarrow")
(gtk_accel_path "<Actions>/Editor/start-range" "<Control>KP_Down")
; (gtk_accel_path "<Actions>/Editor/ToggleTranzportSurface" "")
; (gtk_accel_path "<Actions>/ShuttleActions/SetShuttleUnitsSemitones" "")
; (gtk_accel_path "<Actions>/JACK/JACKLatency128" "")
; (gtk_accel_path "<Actions>/Snap/snap-to-beat" "")

View File

@ -87,6 +87,7 @@ session_state.cc
session_time.cc
session_timefx.cc
session_transport.cc
silentfilesource.cc
sndfile_helpers.cc
sndfilesource.cc
source.cc

View File

@ -20,12 +20,19 @@
#ifndef __ardour_audiofilesource_h__
#define __ardour_audiofilesource_h__
#include <exception>
#include <time.h>
#include <ardour/audiosource.h>
namespace ARDOUR {
class non_existent_source : public std::exception {
public:
virtual const char *what() const throw() { return "audio file does not exist"; }
};
struct SoundFileInfo {
float samplerate;
uint16_t channels;
@ -125,7 +132,7 @@ class AudioFileSource : public AudioSource {
/* constructor to be called for existing in-session files */
AudioFileSource (Session&, const XMLNode&);
AudioFileSource (Session&, const XMLNode&, bool must_exit = true);
int init (string idstr, bool must_exist);

View File

@ -0,0 +1,66 @@
/*
Copyright (C) 2007 Paul Davis
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#ifndef __ardour_silentfilesource_h__
#define __ardour_silentfilesource_h__
#include <ardour/audiofilesource.h>
namespace ARDOUR {
class SilentFileSource : public AudioFileSource {
public:
virtual ~SilentFileSource ();
int update_header (nframes_t when, struct tm&, time_t) { return 0; }
int flush_header () { return 0; }
float sample_rate () const { return _sample_rate; }
void set_length (nframes_t len);
int read_peaks (PeakData *peaks, nframes_t npeaks, nframes_t start, nframes_t cnt, double samples_per_unit) const {
memset (peaks, 0, sizeof (PeakData) * npeaks);
return 0;
}
bool destructive() const { return false; }
protected:
float _sample_rate;
SilentFileSource (Session&, const XMLNode&, nframes_t nframes, float sample_rate);
friend class SourceFactory;
nframes_t read_unlocked (Sample *dst, nframes_t start, nframes_t cnt) const {
memset (dst, 0, sizeof (Sample) * cnt);
return cnt;
}
nframes_t write_unlocked (Sample *dst, nframes_t cnt) { return 0; }
void set_header_timeline_position () {}
};
} // namespace ARDOUR
#endif /* __ardour_audiofilesource_h__ */

View File

@ -20,6 +20,7 @@ class SourceFactory {
static sigc::signal<void,boost::shared_ptr<Source> > SourceCreated;
static boost::shared_ptr<Source> create (Session&, const XMLNode& node);
static boost::shared_ptr<Source> createSilent (Session&, const XMLNode& node, nframes_t nframes, float sample_rate);
// MIDI sources will have to be hacked in here somehow
static boost::shared_ptr<Source> createReadable (Session&, std::string path, int chn, AudioFileSource::Flag flags, bool announce = true);

View File

@ -1480,7 +1480,7 @@ AudioDiskstream::transport_stopped (struct tm& when, time_t twhen, bool abort_ca
srcs.push_back (s);
s->update_header (capture_info.front()->start, when, twhen);
s->set_captured_for (_name);
s->mark_immutable ();
}
}

View File

@ -88,7 +88,7 @@ AudioFileSource::AudioFileSource (Session& s, std::string path, Flag flags, Samp
}
}
AudioFileSource::AudioFileSource (Session& s, const XMLNode& node)
AudioFileSource::AudioFileSource (Session& s, const XMLNode& node, bool must_exist)
: AudioSource (s, node), _flags (Flag (Writable|CanRename))
/* channel is set in set_state() */
{
@ -98,7 +98,7 @@ AudioFileSource::AudioFileSource (Session& s, const XMLNode& node)
throw failed_constructor ();
}
if (init (_name, true)) {
if (init (_name, must_exist)) {
throw failed_constructor ();
}
}
@ -135,7 +135,7 @@ AudioFileSource::init (string pathstr, bool must_exist)
file_is_new = false;
if (!find (pathstr, must_exist, is_new)) {
return -1;
throw non_existent_source ();
}
if (is_new && must_exist) {

View File

@ -64,6 +64,7 @@
#include <ardour/utils.h>
#include <ardour/audioplaylist.h>
#include <ardour/audiofilesource.h>
#include <ardour/silentfilesource.h>
#include <ardour/destructive_filesource.h>
#include <ardour/sndfile_helpers.h>
#include <ardour/auditioner.h>
@ -1391,6 +1392,19 @@ Session::XMLRegionFactory (const XMLNode& node, bool full)
try {
boost::shared_ptr<AudioRegion> region (boost::dynamic_pointer_cast<AudioRegion> (RegionFactory::create (sources, node)));
/* a final detail: this is the one and only place that we know how long missing files are */
if (region->whole_file()) {
for (SourceList::iterator sx = sources.begin(); sx != sources.end(); ++sx) {
boost::shared_ptr<SilentFileSource> sfp = boost::dynamic_pointer_cast<SilentFileSource> (*sx);
if (sfp) {
sfp->set_length (region->length());
}
}
}
return region;
}
@ -1452,10 +1466,16 @@ Session::load_sources (const XMLNode& node)
for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
if ((source = XMLSourceFactory (**niter)) == 0) {
error << _("Session: cannot create Source from XML description.") << endmsg;
try {
if ((source = XMLSourceFactory (**niter)) == 0) {
error << _("Session: cannot create Source from XML description.") << endmsg;
}
}
catch (non_existent_source& err) {
warning << _("A sound file is missing. It will be replaced by silence.") << endmsg;
source = SourceFactory::createSilent (*this, **niter, max_frames, _current_frame_rate);
}
}
return 0;
@ -1471,7 +1491,7 @@ Session::XMLSourceFactory (const XMLNode& node)
try {
return SourceFactory::create (*this, node);
}
catch (failed_constructor& err) {
error << _("Found a sound file that cannot be used by Ardour. Talk to the progammers.") << endmsg;
return boost::shared_ptr<Source>();

View File

@ -0,0 +1,39 @@
/*
Copyright (C) 2007 Paul Davis
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include <ardour/silentfilesource.h>
using namespace ARDOUR;
SilentFileSource::SilentFileSource (Session& s, const XMLNode& node, nframes_t len, float sr)
: AudioFileSource (s, node, false)
{
_length = len;
_sample_rate = sr;
}
SilentFileSource::~SilentFileSource ()
{
}
void
SilentFileSource::set_length (nframes_t len)
{
_length = len;
}

View File

@ -22,6 +22,7 @@
#include <ardour/source_factory.h>
#include <ardour/sndfilesource.h>
#include <ardour/silentfilesource.h>
#include <ardour/destructive_filesource.h>
#include <ardour/configuration.h>
@ -51,6 +52,17 @@ SourceFactory::setup_peakfile (boost::shared_ptr<Source> s)
return 0;
}
boost::shared_ptr<Source>
SourceFactory::createSilent (Session& s, const XMLNode& node, nframes_t nframes, float sr)
{
boost::shared_ptr<Source> ret (new SilentFileSource (s, node, nframes, sr));
if (setup_peakfile (ret)) {
return boost::shared_ptr<Source>();
}
SourceCreated (ret);
return ret;
}
#ifdef HAVE_COREAUDIO
boost::shared_ptr<Source>
SourceFactory::create (Session& s, const XMLNode& node)
@ -63,9 +75,12 @@ SourceFactory::create (Session& s, const XMLNode& node)
SourceCreated (ret);
return ret;
}
catch (failed_constructor& err) {
catch (failed_constructor& err) {
/* this is allowed to throw */
boost::shared_ptr<Source> ret (new SndFileSource (s, node));
if (setup_peakfile (ret)) {
return boost::shared_ptr<Source>();
@ -82,14 +97,15 @@ SourceFactory::create (Session& s, const XMLNode& node)
boost::shared_ptr<Source>
SourceFactory::create (Session& s, const XMLNode& node)
{
boost::shared_ptr<Source> ret (new SndFileSource (s, node));
/* this is allowed to throw */
boost::shared_ptr<Source> ret (new SndFileSource (s, node));
if (setup_peakfile (ret)) {
return boost::shared_ptr<Source>();
}
SourceCreated (ret);
return ret;
}
@ -113,6 +129,9 @@ SourceFactory::createReadable (Session& s, string path, int chn, AudioFileSource
}
catch (failed_constructor& err) {
/* this is allowed to throw */
boost::shared_ptr<Source> ret (new SndFileSource (s, path, chn, flags));
if (setup_peakfile (ret)) {
return boost::shared_ptr<Source>();