(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" "")
session_time.cc
session_timefx.cc
session_transport.cc
+silentfilesource.cc
sndfile_helpers.cc
sndfilesource.cc
source.cc
#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;
/* 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);
--- /dev/null
+/*
+ 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__ */
+
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);
srcs.push_back (s);
s->update_header (capture_info.front()->start, when, twhen);
s->set_captured_for (_name);
-
+ s->mark_immutable ();
}
}
}
}
-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() */
{
throw failed_constructor ();
}
- if (init (_name, true)) {
+ if (init (_name, must_exist)) {
throw failed_constructor ();
}
}
file_is_new = false;
if (!find (pathstr, must_exist, is_new)) {
- return -1;
+ throw non_existent_source ();
}
if (is_new && must_exist) {
#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>
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;
}
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;
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>();
--- /dev/null
+/*
+ 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;
+}
#include <ardour/source_factory.h>
#include <ardour/sndfilesource.h>
+#include <ardour/silentfilesource.h>
#include <ardour/destructive_filesource.h>
#include <ardour/configuration.h>
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)
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>();
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;
}
}
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>();