From 5ee3e58718f65ef9eb62a1b90d424dac68e770ff Mon Sep 17 00:00:00 2001 From: Paul Davis Date: Thu, 25 Jan 2007 17:42:19 +0000 Subject: fix import/embed of multichannel audiofiles, as per #1433 git-svn-id: svn://localhost/ardour2/trunk@1386 d708f5d6-7413-0410-9779-e7cbd77b26cf --- libs/ardour/ardour/audiofilesource.h | 6 +++++- libs/ardour/ardour/coreaudiosource.h | 2 +- libs/ardour/ardour/sndfilesource.h | 4 ++-- libs/ardour/ardour/source_factory.h | 2 +- libs/ardour/audiofilesource.cc | 35 +++++++++++++++++++++--------- libs/ardour/coreaudiosource.cc | 23 ++++++-------------- libs/ardour/session.cc | 4 ++++ libs/ardour/sndfilesource.cc | 41 +++++++++++++++++------------------- libs/ardour/source_factory.cc | 12 +++++------ 9 files changed, 69 insertions(+), 60 deletions(-) (limited to 'libs') diff --git a/libs/ardour/ardour/audiofilesource.h b/libs/ardour/ardour/audiofilesource.h index 2133136e68..f91f78f6d9 100644 --- a/libs/ardour/ardour/audiofilesource.h +++ b/libs/ardour/ardour/audiofilesource.h @@ -101,6 +101,10 @@ class AudioFileSource : public AudioSource { bool destructive() const { return (_flags & Destructive); } virtual bool set_destructive (bool yn) { return false; } + Flag flags() const { return _flags; } + + void mark_immutable (); + /* this should really be protected, but C++ is getting stricter and creating slots from protected member functions is starting to cause issues. @@ -125,12 +129,12 @@ class AudioFileSource : public AudioSource { int init (string idstr, bool must_exist); - uint16_t channel; string _path; Flag _flags; string _take_id; int64_t timeline_position; bool file_is_new; + uint16_t channel; bool _is_embedded; static bool determine_embeddedness(string path); diff --git a/libs/ardour/ardour/coreaudiosource.h b/libs/ardour/ardour/coreaudiosource.h index bd69c78e18..63c50d7cfb 100644 --- a/libs/ardour/ardour/coreaudiosource.h +++ b/libs/ardour/ardour/coreaudiosource.h @@ -29,7 +29,7 @@ namespace ARDOUR { class CoreAudioSource : public AudioFileSource { public: CoreAudioSource (ARDOUR::Session&, const XMLNode&); - CoreAudioSource (ARDOUR::Session&, const string& path_plus_channel, Flag); + CoreAudioSource (ARDOUR::Session&, const string& path, int chn, Flag); ~CoreAudioSource (); float sample_rate() const; diff --git a/libs/ardour/ardour/sndfilesource.h b/libs/ardour/ardour/sndfilesource.h index 1d07f6888d..a5000a4b63 100644 --- a/libs/ardour/ardour/sndfilesource.h +++ b/libs/ardour/ardour/sndfilesource.h @@ -31,7 +31,7 @@ class SndFileSource : public AudioFileSource { public: /* constructor to be called for existing external-to-session files */ - SndFileSource (Session&, std::string path, Flag flags); + SndFileSource (Session&, std::string path, int chn, Flag flags); /* constructor to be called for new in-session files */ @@ -78,7 +78,7 @@ class SndFileSource : public AudioFileSource { mutable float *interleave_buf; mutable nframes_t interleave_bufsize; - void init (string str); + void init (); int open(); void close(); int setup_broadcast_info (nframes_t when, struct tm&, time_t); diff --git a/libs/ardour/ardour/source_factory.h b/libs/ardour/ardour/source_factory.h index 6cb262a299..207015a253 100644 --- a/libs/ardour/ardour/source_factory.h +++ b/libs/ardour/ardour/source_factory.h @@ -22,7 +22,7 @@ class SourceFactory { static boost::shared_ptr create (Session&, const XMLNode& node); // MIDI sources will have to be hacked in here somehow - static boost::shared_ptr createReadable (Session&, std::string idstr, AudioFileSource::Flag flags, bool announce = true); + static boost::shared_ptr createReadable (Session&, std::string path, int chn, AudioFileSource::Flag flags, bool announce = true); static boost::shared_ptr createWritable (Session&, std::string name, bool destructive, nframes_t rate, bool announce = true); private: diff --git a/libs/ardour/audiofilesource.cc b/libs/ardour/audiofilesource.cc index 95fc0d2766..b74f6b370f 100644 --- a/libs/ardour/audiofilesource.cc +++ b/libs/ardour/audiofilesource.cc @@ -63,20 +63,22 @@ uint64_t AudioFileSource::header_position_offset = 0; /* XXX maybe this too */ char AudioFileSource::bwf_serial_number[13] = "000000000000"; -AudioFileSource::AudioFileSource (Session& s, string idstr, Flag flags) - : AudioSource (s, idstr), _flags (flags) +AudioFileSource::AudioFileSource (Session& s, string path, Flag flags) + : AudioSource (s, path), _flags (flags), + channel (0) { /* constructor used for existing external to session files. file must exist already */ - _is_embedded = AudioFileSource::determine_embeddedness (idstr); + _is_embedded = AudioFileSource::determine_embeddedness (path); - if (init (idstr, true)) { + if (init (path, true)) { throw failed_constructor (); } } AudioFileSource::AudioFileSource (Session& s, std::string path, Flag flags, SampleFormat samp_format, HeaderFormat hdr_format) - : AudioSource (s, path), _flags (flags) + : AudioSource (s, path), _flags (flags), + channel (0) { /* constructor used for new internal-to-session files. file cannot exist */ _is_embedded = false; @@ -88,6 +90,7 @@ AudioFileSource::AudioFileSource (Session& s, std::string path, Flag flags, Samp AudioFileSource::AudioFileSource (Session& s, const XMLNode& node) : AudioSource (s, node), _flags (Flag (Writable|CanRename)) + /* channel is set in set_state() */ { /* constructor used for existing internal-to-session files. file must exist */ @@ -195,7 +198,10 @@ XMLNode& AudioFileSource::get_state () { XMLNode& root (AudioSource::get_state()); - root.add_property ("flags", enum_2_string (_flags)); + char buf[32]; + root.add_property (X_("flags"), enum_2_string (_flags)); + snprintf (buf, sizeof (buf), "%d", channel); + root.add_property (X_("channel"), buf); return root; } @@ -209,15 +215,18 @@ AudioFileSource::set_state (const XMLNode& node) } if ((prop = node.property (X_("flags"))) != 0) { - _flags = Flag (string_2_enum (prop->value(), _flags)); - } else { - _flags = Flag (0); } + if ((prop = node.property (X_("channel"))) != 0) { + channel = atoi (prop->value()); + } else { + channel = 0; + } + if ((prop = node.property (X_("name"))) != 0) { _is_embedded = AudioFileSource::determine_embeddedness (prop->value()); } else { @@ -527,7 +536,7 @@ bool AudioFileSource::is_empty (Session& s, string path) { bool ret = false; - boost::shared_ptr afs = boost::dynamic_pointer_cast (SourceFactory::createReadable (s, path, NoPeakFile, false)); + boost::shared_ptr afs = boost::dynamic_pointer_cast (SourceFactory::createReadable (s, path, 0, NoPeakFile, false)); if (afs) { ret = (afs->length() == 0); @@ -568,3 +577,9 @@ AudioFileSource::safe_file_extension(string file) #endif // HAVE_COREAUDIO file.rfind(".voc") == string::npos); } + +void +AudioFileSource::mark_immutable () +{ + _flags = Flag (_flags & ~(Writable|Removable|RemovableIfEmpty|RemoveAtDestroy|CanRename)); +} diff --git a/libs/ardour/coreaudiosource.cc b/libs/ardour/coreaudiosource.cc index e38a34e378..572fd9ef81 100644 --- a/libs/ardour/coreaudiosource.cc +++ b/libs/ardour/coreaudiosource.cc @@ -34,33 +34,22 @@ using namespace PBD; CoreAudioSource::CoreAudioSource (Session& s, const XMLNode& node) : AudioFileSource (s, node) { - init (_name); + init (); } -CoreAudioSource::CoreAudioSource (Session& s, const string& idstr, Flag flags) - : AudioFileSource(s, idstr, flags) +CoreAudioSource::CoreAudioSource (Session& s, const string& path, int chn, Flag flags) + : AudioFileSource(s, path, flags), { - init (idstr); + channel = chn; + init (); } void -CoreAudioSource::init (string idstr) +CoreAudioSource::init () { - string::size_type pos; - tmpbuf = 0; tmpbufsize = 0; - _name = idstr; - - if ((pos = idstr.find_last_of (':')) == string::npos) { - channel = 0; - _path = idstr; - } else { - channel = atoi (idstr.substr (pos+1).c_str()); - _path = idstr.substr (0, pos); - } - cerr << "CoreAudioSource::init() " << name() << endl; /* note that we temporarily truncated _id at the colon */ diff --git a/libs/ardour/session.cc b/libs/ardour/session.cc index 0b668607dd..9b09f45ee8 100644 --- a/libs/ardour/session.cc +++ b/libs/ardour/session.cc @@ -1738,6 +1738,10 @@ Session::new_audio_track (int input_channels, int output_channels, TrackMode mod track->set_control_outs (cports); } + + // assert (current_thread != RT_thread) + + track->audio_diskstream()->non_realtime_input_change(); track->DiskstreamChanged.connect (mem_fun (this, &Session::resort_routes)); track->set_remote_control_id (control_id); diff --git a/libs/ardour/sndfilesource.cc b/libs/ardour/sndfilesource.cc index fa2f432ee6..850aa6bc6c 100644 --- a/libs/ardour/sndfilesource.cc +++ b/libs/ardour/sndfilesource.cc @@ -48,30 +48,34 @@ const AudioFileSource::Flag SndFileSource::default_writable_flags = AudioFileSou SndFileSource::SndFileSource (Session& s, const XMLNode& node) : AudioFileSource (s, node) { - init (_name); + init (); + + cerr << "SndFileSource @ " << _path << " channel = " << channel << endl; if (open()) { throw failed_constructor (); } } -SndFileSource::SndFileSource (Session& s, string idstr, Flag flags) - /* files created this way are never writable or removable */ - : AudioFileSource (s, idstr, Flag (flags & ~(Writable|Removable|RemovableIfEmpty|RemoveAtDestroy))) +SndFileSource::SndFileSource (Session& s, string path, int chn, Flag flags) + /* files created this way are never writable or removable */ + : AudioFileSource (s, path, Flag (flags & ~(Writable|Removable|RemovableIfEmpty|RemoveAtDestroy))) { - init (idstr); + channel = chn; + + init (); if (open()) { throw failed_constructor (); } } -SndFileSource::SndFileSource (Session& s, string idstr, SampleFormat sfmt, HeaderFormat hf, nframes_t rate, Flag flags) - : AudioFileSource (s, idstr, flags, sfmt, hf) +SndFileSource::SndFileSource (Session& s, string path, SampleFormat sfmt, HeaderFormat hf, nframes_t rate, Flag flags) + : AudioFileSource (s, path, flags, sfmt, hf) { int fmt = 0; - init (idstr); + init (); /* this constructor is used to construct new files, not open existing ones. @@ -174,9 +178,8 @@ SndFileSource::SndFileSource (Session& s, string idstr, SampleFormat sfmt, Heade } void -SndFileSource::init (string idstr) +SndFileSource::init () { - string::size_type pos; string file; // lets try to keep the object initalizations here at the top @@ -186,20 +189,10 @@ SndFileSource::init (string idstr) sf = 0; _broadcast_info = 0; - string tmp_name; - - if ((pos = idstr.find_last_of (':')) == string::npos) { - channel = 0; - tmp_name = idstr; - } else { - channel = atoi (idstr.substr (pos+1).c_str()); - tmp_name = idstr.substr (0, pos); - } - if (is_embedded()) { - _name = tmp_name; + _name = _path; } else { - _name = Glib::path_get_basename (tmp_name); + _name = Glib::path_get_basename (_path); } /* although libsndfile says we don't need to set this, @@ -385,6 +378,7 @@ nframes_t SndFileSource::nondestructive_write_unlocked (Sample *data, nframes_t cnt) { if (!writable()) { + warning << string_compose (_("attempt to write a non-writable audio file source (%1)"), _path) << endmsg; return 0; } @@ -440,6 +434,7 @@ SndFileSource::destructive_write_unlocked (Sample* data, nframes_t cnt) nframes_t old_file_pos; if (!writable()) { + warning << string_compose (_("attempt to write a non-writable audio file source (%1)"), _path) << endmsg; return 0; } @@ -563,6 +558,7 @@ int SndFileSource::flush_header () { if (!writable() || (sf == 0)) { + warning << string_compose (_("attempt to flush a non-writable audio file source (%1)"), _path) << endmsg; return -1; } return (sf_command (sf, SFC_UPDATE_HEADER_NOW, 0, 0) != SF_TRUE); @@ -572,6 +568,7 @@ int SndFileSource::setup_broadcast_info (nframes_t when, struct tm& now, time_t tnow) { if (!writable()) { + warning << string_compose (_("attempt to store broadcast info in a non-writable audio file source (%1)"), _path) << endmsg; return -1; } diff --git a/libs/ardour/source_factory.cc b/libs/ardour/source_factory.cc index 9b8382c39f..2cbd7624be 100644 --- a/libs/ardour/source_factory.cc +++ b/libs/ardour/source_factory.cc @@ -97,12 +97,12 @@ SourceFactory::create (Session& s, const XMLNode& node) #ifdef HAVE_COREAUDIO boost::shared_ptr -SourceFactory::createReadable (Session& s, string idstr, AudioFileSource::Flag flags, bool announce) +SourceFactory::createReadable (Session& s, string path, int chn, AudioFileSource::Flag flags, bool announce) { if (!(flags & Destructive)) { try { - boost::shared_ptr ret (new CoreAudioSource (s, idstr, flags)); + boost::shared_ptr ret (new CoreAudioSource (s, path, chn, flags)); if (setup_peakfile (ret)) { return boost::shared_ptr(); } @@ -113,7 +113,7 @@ SourceFactory::createReadable (Session& s, string idstr, AudioFileSource::Flag f } catch (failed_constructor& err) { - boost::shared_ptr ret (new SndFileSource (s, idstr, flags)); + boost::shared_ptr ret (new SndFileSource (s, path, chn, flags)); if (setup_peakfile (ret)) { return boost::shared_ptr(); } @@ -125,7 +125,7 @@ SourceFactory::createReadable (Session& s, string idstr, AudioFileSource::Flag f } else { - boost::shared_ptr ret (new SndFileSource (s, idstr, flags)); + boost::shared_ptr ret (new SndFileSource (s, path, chn, flags)); if (setup_peakfile (ret)) { return boost::shared_ptr(); } @@ -141,9 +141,9 @@ SourceFactory::createReadable (Session& s, string idstr, AudioFileSource::Flag f #else boost::shared_ptr -SourceFactory::createReadable (Session& s, string idstr, AudioFileSource::Flag flags, bool announce) +SourceFactory::createReadable (Session& s, string path, int chn, AudioFileSource::Flag flags, bool announce) { - boost::shared_ptr ret (new SndFileSource (s, idstr, flags)); + boost::shared_ptr ret (new SndFileSource (s, path, chn, flags)); if (setup_peakfile (ret)) { return boost::shared_ptr(); -- cgit v1.2.3