X-Git-Url: https://main.carlh.net/gitweb/?a=blobdiff_plain;f=libs%2Fardour%2Fdiskstream.cc;h=ebd11a1887d1e9c71991908e0fa23ee23561ffb8;hb=cf52d6e4b40111eb04b244ec054055a4ec15dbe0;hp=e24e67895936fe03c2be6d3c0312de0ba1e54da6;hpb=ad017365f7a73f8ba57f667cc1aa36478b48c50e;p=ardour.git diff --git a/libs/ardour/diskstream.cc b/libs/ardour/diskstream.cc index e24e678959..ebd11a1887 100644 --- a/libs/ardour/diskstream.cc +++ b/libs/ardour/diskstream.cc @@ -17,7 +17,6 @@ */ -#include #include #include #include @@ -42,23 +41,20 @@ #include "ardour/diskstream.h" #include "ardour/io.h" #include "ardour/pannable.h" +#include "ardour/profile.h" #include "ardour/playlist.h" #include "ardour/session.h" #include "ardour/track.h" -#include "i18n.h" +#include "pbd/i18n.h" #include using namespace std; using namespace ARDOUR; using namespace PBD; -/* XXX This goes uninitialized when there is no ~/.config/ardour3 directory. - * I can't figure out why, so this will do for now (just stole the - * default from configuration_vars.h). 0 is not a good value for - * allocating buffer sizes.. - */ -ARDOUR::framecnt_t Diskstream::disk_io_chunk_frames = 1024 * 256 / sizeof (Sample); +ARDOUR::framecnt_t Diskstream::disk_read_chunk_frames = default_disk_read_chunk_frames (); +ARDOUR::framecnt_t Diskstream::disk_write_chunk_frames = default_disk_write_chunk_frames (); PBD::Signal0 Diskstream::DiskOverrun; PBD::Signal0 Diskstream::DiskUnderrun; @@ -68,6 +64,7 @@ Diskstream::Diskstream (Session &sess, const string &name, Flag flag) , i_am_the_modifier (0) , _track (0) , _record_enabled (0) + , _record_safe (0) , _visible_speed (1.0f) , _actual_speed (1.0f) , _buffer_reallocation_required (false) @@ -106,6 +103,7 @@ Diskstream::Diskstream (Session& sess, const XMLNode& /*node*/) , i_am_the_modifier (0) , _track (0) , _record_enabled (0) + , _record_safe (0) , _visible_speed (1.0f) , _actual_speed (1.0f) , _buffer_reallocation_required (false) @@ -382,11 +380,12 @@ Diskstream::use_playlist (boost::shared_ptr playlist) _playlist = playlist; _playlist->use(); - if (!in_set_state && recordable()) { + if (!in_set_state && destructive() && recordable()) { reset_write_sources (false); } _playlist->ContentsChanged.connect_same_thread (playlist_connections, boost::bind (&Diskstream::playlist_modified, this)); + _playlist->LayeringChanged.connect_same_thread (playlist_connections, boost::bind (&Diskstream::playlist_modified, this)); _playlist->DropReferences.connect_same_thread (playlist_connections, boost::bind (&Diskstream::playlist_deleted, this, boost::weak_ptr(_playlist))); _playlist->RangesMoved.connect_same_thread (playlist_connections, boost::bind (&Diskstream::playlist_ranges_moved, this, _1, _2)); } @@ -462,7 +461,7 @@ Diskstream::get_state () { XMLNode* node = new XMLNode ("Diskstream"); char buf[64]; - LocaleGuard lg (X_("POSIX")); + LocaleGuard lg; node->add_property ("flags", enum_2_string (_flags)); node->add_property ("playlist", _playlist->name()); @@ -472,6 +471,7 @@ Diskstream::get_state () snprintf (buf, sizeof(buf), "%f", _visible_speed); node->add_property ("speed", buf); node->add_property ("capture-alignment", enum_2_string (_alignment_choice)); + node->add_property ("record-safe", _record_safe ? "yes" : "no"); if (_extra_xml) { node->add_child_copy (*_extra_xml); @@ -483,7 +483,7 @@ Diskstream::get_state () int Diskstream::set_state (const XMLNode& node, int /*version*/) { - const XMLProperty* prop; + XMLProperty const * prop; if ((prop = node.property ("name")) != 0) { _name = prop->value(); @@ -499,6 +499,11 @@ Diskstream::set_state (const XMLNode& node, int /*version*/) _flags = Flag (string_2_enum (prop->value(), _flags)); } + if (Profile->get_trx() && (_flags & Destructive)) { + error << string_compose (_("%1: this session uses destructive tracks, which are not supported"), PROGRAM_NAME) << endmsg; + return -1; + } + if ((prop = node.property (X_("capture-alignment"))) != 0) { set_align_choice (AlignChoice (string_2_enum (prop->value(), _alignment_choice)), true); } else { @@ -521,7 +526,11 @@ Diskstream::set_state (const XMLNode& node, int /*version*/) } } - return 0; + if ((prop = node.property ("record-safe")) != 0) { + _record_safe = PBD::string_is_affirmative (prop->value()) ? 1 : 0; + } + + return 0; } void @@ -559,7 +568,9 @@ Diskstream::playlist_ranges_moved (list< Evoral::RangeMove > const & continue; } boost::shared_ptr alist = ac->alist(); - + if (!alist->size()) { + continue; + } XMLNode & before = alist->get_state (); bool const things_moved = alist->move_ranges (movements); if (things_moved) { @@ -589,6 +600,9 @@ Diskstream::move_processor_automation (boost::weak_ptr p, list< Evora for (set::const_iterator i = a.begin (); i != a.end (); ++i) { boost::shared_ptr al = processor->automation_control(*i)->alist(); + if (!al->size()) { + continue; + } XMLNode & before = al->get_state (); bool const things_moved = al->move_ranges (movements); if (things_moved) { @@ -700,16 +714,16 @@ Diskstream::calculate_record_range (Evoral::OverlapType ot, framepos_t transport case Evoral::OverlapInternal: /* ---------- recrange - |---| transrange - */ + * |---| transrange + */ rec_nframes = nframes; rec_offset = 0; break; case Evoral::OverlapStart: /* |--------| recrange - -----| transrange - */ + * -----| transrange + */ rec_nframes = transport_frame + nframes - first_recordable_frame; if (rec_nframes) { rec_offset = first_recordable_frame - transport_frame; @@ -718,16 +732,16 @@ Diskstream::calculate_record_range (Evoral::OverlapType ot, framepos_t transport case Evoral::OverlapEnd: /* |--------| recrange - |-------- transrange - */ + * |-------- transrange + */ rec_nframes = last_recordable_frame - transport_frame; rec_offset = 0; break; case Evoral::OverlapExternal: /* |--------| recrange - -------------- transrange - */ + * -------------- transrange + */ rec_nframes = last_recordable_frame - first_recordable_frame; rec_offset = first_recordable_frame - transport_frame; break; @@ -772,3 +786,86 @@ Diskstream::disengage_record_enable () { g_atomic_int_set (&_record_enabled, 0); } + +void +Diskstream::engage_record_safe () +{ + g_atomic_int_set (&_record_safe, 1); +} + +void +Diskstream::disengage_record_safe () +{ + g_atomic_int_set (&_record_safe, 0); +} + +framecnt_t +Diskstream::default_disk_read_chunk_frames() +{ + return 65536; +} + +framecnt_t +Diskstream::default_disk_write_chunk_frames () +{ + return 65536; +} + +void +Diskstream::set_buffering_parameters (BufferingPreset bp) +{ + framecnt_t read_chunk_size; + framecnt_t read_buffer_size; + framecnt_t write_chunk_size; + framecnt_t write_buffer_size; + + if (!get_buffering_presets (bp, read_chunk_size, read_buffer_size, write_chunk_size, write_buffer_size)) { + return; + } + + disk_read_chunk_frames = read_chunk_size; + disk_write_chunk_frames = write_chunk_size; + Config->set_audio_capture_buffer_seconds (write_buffer_size); + Config->set_audio_playback_buffer_seconds (read_buffer_size); + + cerr << "Set buffering params to " << disk_read_chunk_frames << '|' << disk_write_chunk_frames << '|' + << Config->get_audio_playback_buffer_seconds() << '|' + << Config->get_audio_capture_buffer_seconds () + << endl; +} + +bool +Diskstream::get_buffering_presets (BufferingPreset bp, + framecnt_t& read_chunk_size, + framecnt_t& read_buffer_size, + framecnt_t& write_chunk_size, + framecnt_t& write_buffer_size) +{ + switch (bp) { + case Small: + read_chunk_size = 65536; /* samples */ + write_chunk_size = 65536; /* samples */ + read_buffer_size = 5; /* seconds */ + write_buffer_size = 5; /* seconds */ + break; + + case Medium: + read_chunk_size = 262144; /* samples */ + write_chunk_size = 131072; /* samples */ + read_buffer_size = 10; /* seconds */ + write_buffer_size = 10; /* seconds */ + break; + + case Large: + read_chunk_size = 524288; /* samples */ + write_chunk_size = 131072; /* samples */ + read_buffer_size = 20; /* seconds */ + write_buffer_size = 20; /* seconds */ + break; + + default: + return false; + } + + return true; +}