forward port 2.X changes up to and including rev 6714

git-svn-id: svn://localhost/ardour2/branches/3.0@7635 d708f5d6-7413-0410-9779-e7cbd77b26cf
This commit is contained in:
Paul Davis
2010-08-16 19:58:34 +00:00
parent 0b2f156c58
commit a4d9d09af5
35 changed files with 217 additions and 69 deletions

View File

@@ -182,7 +182,7 @@ static const char* translators[] = {
N_("Greek:\n\t Klearchos Gourgourinis <muadib@in.gr>\n"),
N_("Swedish:\n\t Petter Sundlöf <petter.sundlof@gmail.com>\n"),
N_("Polish:\n\t Piotr Zaryk <pzaryk@gmail.com>\n"),
N_("Czech:\n\t Pavel Frich\n"),
N_("Czech:\n\t Pavel Fric <pavelfric@seznam.cz>\n"),
N_("Norwegian:\n\t Eivind Ødegård\n"),
0
};

View File

@@ -29,10 +29,11 @@
<menuitem action='CleanupUnused'/>
<menuitem action='FlushWastebasket'/>
</menu>
#ifndef GTKOSX
<separator/>
#endif
<menuitem action='ToggleSessionOptionsEditor'/>
<separator/>
#ifdef GTKOSX
#ifndef GTKOSX
<menuitem action='ToggleRCOptionsEditor'/>
<menuitem action='About'/>
#endif
@@ -265,6 +266,7 @@
<menuitem action='region-fill-track'/>
<separator/>
<menuitem action='loop-region'/>
<menuitem action='set-loop-from-region'/>
<menuitem action='set-punch-from-region'/>
<menuitem action='add-range-marker-from-region'/>
<menuitem action='add-range-markers-from-region'/>

View File

@@ -732,6 +732,19 @@ ARDOUR_UI::check_memory_locking ()
}
void
ARDOUR_UI::queue_finish ()
{
Glib::signal_idle().connect (mem_fun (*this, &ARDOUR_UI::idle_finish));
}
bool
ARDOUR_UI::idle_finish ()
{
finish ();
return false; /* do not call again */
}
void
ARDOUR_UI::finish()
{
@@ -772,6 +785,7 @@ If you still wish to quit, please use the\n\n\
point_oh_five_second_connection.disconnect ();
point_zero_one_second_connection.disconnect();
_session->set_clean ();
// _session->set_deletion_in_progress ();
_session->remove_pending_capture_state ();
delete _session;

View File

@@ -699,6 +699,11 @@ class ARDOUR_UI : public Gtkmm2ext::UI, public ARDOUR::SessionHandlePtr
PBD::ScopedConnectionList forever_connections;
void step_edit_status_change (bool);
/* these are used only in response to a platform-specific "ShouldQuit" signal
*/
bool idle_finish ();
void queue_finish ();
};
#endif /* __ardour_gui_h__ */

View File

@@ -159,7 +159,7 @@ IOSelector::get_state (ARDOUR::BundleChannel c[2]) const
ARDOUR::Bundle::PortList const & our_ports = c[_ours].bundle->channel_ports (c[_ours].channel);
ARDOUR::Bundle::PortList const & other_ports = c[_other].bundle->channel_ports (c[_other].channel);
if (our_ports.empty() || other_ports.empty()) {
if (!_session || our_ports.empty() || other_ports.empty()) {
/* we're looking at a bundle with no parts associated with this channel,
so nothing to connect */
return PortMatrixNode::NOT_ASSOCIATED;
@@ -286,9 +286,26 @@ PortInsertUI::PortInsertUI (Gtk::Window* parent, ARDOUR::Session* sess, boost::s
pack_start (output_selector, true, true);
pack_start (input_selector, true, true);
update_latency_display ();
latency_button.signal_toggled().connect (mem_fun (*this, &PortInsertUI::latency_button_toggled));
}
void
PortInsertUI::update_latency_display ()
{
nframes_t sample_rate = input_selector.session()->engine().frame_rate();
if (sample_rate == 0) {
latency_display.set_text (_("Disconnected from audio engine"));
} else {
char buf[64];
snprintf (buf, sizeof (buf), "%10.3lf frames %10.3lf ms",
(float)_pi->latency(), (float)_pi->latency() * 1000.0f/sample_rate);
latency_display.set_text(buf);
}
}
bool
PortInsertUI::check_latency_measurement ()
{
@@ -304,7 +321,7 @@ PortInsertUI::check_latency_measurement ()
mtdm->resolve ();
}
char buf[64];
char buf[128];
nframes_t sample_rate = AudioEngine::instance()->frame_rate();
if (sample_rate == 0) {
@@ -329,6 +346,7 @@ PortInsertUI::check_latency_measurement ()
if (solid) {
_pi->set_measured_latency ((nframes_t) rint (mtdm->del()));
latency_button.set_active (false);
strcat (buf, " (set)");
}

View File

@@ -38,6 +38,8 @@ class IOSelector : public PortMatrix
std::string disassociation_verb () const;
std::string channel_noun () const;
ARDOUR::Session* session() const { return _session; }
uint32_t n_io_ports () const;
boost::shared_ptr<ARDOUR::IO> const io () { return _io; }
void setup_ports (int);
@@ -109,6 +111,7 @@ class PortInsertUI : public Gtk::HBox
bool check_latency_measurement ();
void latency_button_toggled ();
void update_latency_display ();
};
class PortInsertWindow : public ArdourDialog

View File

@@ -70,7 +70,7 @@ public:
/* supplemental method used with MIDI */
void flush (nframes_t nframes, nframes64_t time);
void flush_buffers (nframes_t nframes, nframes64_t time);
void transport_stopped ();
void no_outs_cuz_we_no_monitor(bool);

View File

@@ -41,7 +41,7 @@ class InternalReturn : public Return
void run (BufferSet& bufs, sframes_t start_frame, sframes_t end_frame, nframes_t nframes, bool);
bool configure_io (ChanCount in, ChanCount out);
bool can_support_io_configuration (const ChanCount& in, ChanCount& out) const;
void set_block_size (nframes_t);
int set_block_size (nframes_t);
BufferSet* get_buffers();
void release_buffers();

View File

@@ -43,7 +43,7 @@ class InternalSend : public Send
bool feeds (boost::shared_ptr<Route> other) const;
bool can_support_io_configuration (const ChanCount& in, ChanCount& out) const;
bool configure_io (ChanCount in, ChanCount out);
void set_block_size (nframes_t);
int set_block_size (nframes_t);
boost::shared_ptr<Route> target_route() const { return _send_to; }
const PBD::ID& target_id() const { return _send_to_id; }

View File

@@ -81,7 +81,7 @@ class LadspaPlugin : public ARDOUR::Plugin
_descriptor->cleanup (_handle);
}
void set_block_size (nframes_t /*nframes*/) {}
int set_block_size (nframes_t /*nframes*/) { return 0; }
int connect_and_run (BufferSet& bufs,
ChanMapping in, ChanMapping out,

View File

@@ -94,7 +94,7 @@ class LV2Plugin : public ARDOUR::Plugin
_instance = NULL;
}
void set_block_size (nframes_t /*nframes*/) {}
int set_block_size (nframes_t /*nframes*/) { return 0; }
int connect_and_run (BufferSet& bufs,
ChanMapping in, ChanMapping out,

View File

@@ -110,7 +110,9 @@ class Plugin : public PBD::StatefulDestructible, public Latent
virtual uint32_t nth_parameter (uint32_t which, bool& ok) const = 0;
virtual void activate () = 0;
virtual void deactivate () = 0;
virtual void set_block_size (nframes_t nframes) = 0;
virtual void flush () { deactivate(); activate(); }
virtual int set_block_size (nframes_t nframes) = 0;
virtual int connect_and_run (BufferSet& bufs,
ChanMapping in, ChanMapping out,

View File

@@ -57,8 +57,9 @@ class PluginInsert : public Processor
void activate ();
void deactivate ();
void flush ();
void set_block_size (nframes_t nframes);
int set_block_size (nframes_t nframes);
ChanCount output_streams() const;
ChanCount input_streams() const;

View File

@@ -69,6 +69,7 @@ class PortInsert : public IOProcessor
MTDM* mtdm () const { return _mtdm; }
void set_measured_latency (nframes_t);
nframes_t latency() const;
private:
/* disallow copy construction */

View File

@@ -65,7 +65,8 @@ class Processor : public SessionObject, public Automatable, public Latent
virtual void transport_stopped (sframes_t /*frame*/) {}
virtual void set_block_size (nframes_t /*nframes*/) {}
virtual int set_block_size (nframes_t /*nframes*/) { return 0; }
virtual bool requires_fixed_sized_buffers() const { return false; }
/** @param result_required true if, on return from this method, bufs is required to contain valid data;
* if false, the method need not bother writing to bufs if it doesn't want to.
@@ -75,6 +76,7 @@ class Processor : public SessionObject, public Automatable, public Latent
virtual void activate () { _pending_active = true; ActiveChanged(); }
virtual void deactivate () { _pending_active = false; ActiveChanged(); }
virtual void flush() {}
virtual bool configure_io (ChanCount in, ChanCount out);

View File

@@ -576,7 +576,7 @@ class Session : public PBD::StatefulDestructible, public PBD::ScopedConnectionLi
/* flattening stuff */
boost::shared_ptr<Region> write_one_track (AudioTrack&, nframes_t start, nframes_t end,
boost::shared_ptr<Region> write_one_track (AudioTrack&, framepos_t start, framepos_t end,
bool overwrite, std::vector<boost::shared_ptr<Source> >&, InterThreadInfo& wot,
bool enable_processing = true);
int freeze_all (InterThreadInfo&);

View File

@@ -64,7 +64,7 @@ class VSTPlugin : public ARDOUR::Plugin
uint32_t nth_parameter (uint32_t port, bool& ok) const;
void activate ();
void deactivate ();
void set_block_size (nframes_t nframes);
int set_block_size (nframes_t nframes);
int connect_and_run (BufferSet&,
ChanMapping in, ChanMapping out,

View File

@@ -266,6 +266,10 @@ AudioEngine::stop (bool forever)
}
}
if (forever) {
stop_metering_thread ();
}
return _running ? -1 : 0;
}

View File

@@ -339,27 +339,42 @@ bool
AudioFileSource::safe_audio_file_extension(const ustring& file)
{
const char* suffixes[] = {
".wav", ".WAV",
".aiff", ".AIFF",
".caf", ".CAF",
".aif", ".AIF",
".aifc", ".AIFC",
".aiff", ".AIFF",
".amb", ".AMB",
".snd", ".SND",
".au", ".AU",
".raw", ".RAW",
".sf", ".SF",
".caf", ".CAF",
".cdr", ".CDR",
".smp", ".SMP",
".maud", ".MAUD",
".vwe", ".VWE",
".paf", ".PAF",
".voc", ".VOC",
".ogg", ".OGG",
".flac", ".FLAC",
".htk", ".HTK",
".iff", ".IFF",
".mat", ".MAT",
".oga", ".OGA",
".ogg", ".OGG",
".paf", ".PAF",
".pvf", ".PVF",
".sf", ".SF",
".smp", ".SMP",
".snd", ".SND",
".maud", ".MAUD",
".voc", ".VOC"
".vwe", ".VWE",
".w64", ".W64",
".wav", ".WAV",
#ifdef HAVE_COREAUDIO
".mp3", ".MP3",
".aac", ".AAC",
".adts", ".ADTS",
".ac3", ".AC3",
".amr", ".AMR",
".mpa", ".MPA",
".mpeg", ".MPEG",
".mp1", ".MP1",
".mp2", ".MP2",
".mp3", ".MP3",
".mp4", ".MP4",
".m4a", ".M4A",
".sd2", ".SD2", // libsndfile supports sd2 also, but the resource fork is required to open.
#endif // HAVE_COREAUDIO
};

View File

@@ -24,7 +24,9 @@ CAImportableSource::CAImportableSource (const string& path)
af.SetClientFormat (client_format);
} catch (CAXException& cax) {
error << string_compose ("CAImportable: %1", cax.mOperation) << endmsg;
//Don't report an error here since there is one higher up in import.
//Since libsndfile gets tried second, any failures here may show as
//invalid errors in the Error log.
throw failed_constructor ();
}

View File

@@ -441,7 +441,7 @@ Delivery::transport_stopped (sframes_t frame)
}
void
Delivery::flush (nframes_t nframes, nframes64_t time)
Delivery::flush_buffers (nframes_t nframes, nframes64_t time)
{
/* io_lock, not taken: function must be called from Session::process() calltree */

View File

@@ -62,10 +62,11 @@ InternalReturn::configure_io (ChanCount in, ChanCount out)
return true;
}
void
int
InternalReturn::set_block_size (nframes_t nframes)
{
allocate_buffers (nframes);
return 0;
}
void

View File

@@ -145,10 +145,11 @@ InternalSend::run (BufferSet& bufs, sframes_t start_frame, sframes_t end_frame,
_active = _pending_active;
}
void
int
InternalSend::set_block_size (nframes_t nframes)
{
mixbufs.ensure_buffers (_configured_input, nframes);
return 0;
}
bool

View File

@@ -909,6 +909,8 @@ MidiModel::resolve_overlaps_unlocked (const NotePtr note, void* arg)
TimeType note_time = note->time();
TimeType note_length = note->length();
DEBUG_TRACE (DEBUG::Sequence, string_compose ("%1 checking overlaps for note %2 @ %3\n", this, (int)note->note(), note->time()));
for (Pitches::const_iterator i = p.lower_bound (search_note);
i != p.end() && (*i)->note() == note->note(); ++i) {
@@ -916,6 +918,7 @@ MidiModel::resolve_overlaps_unlocked (const NotePtr note, void* arg)
TimeType eb = (*i)->end_time();
OverlapType overlap = OverlapNone;
if ((sb > sa) && (eb <= ea)) {
overlap = OverlapInternal;
} else if ((eb >= sa) && (eb <= ea)) {
@@ -929,7 +932,11 @@ MidiModel::resolve_overlaps_unlocked (const NotePtr note, void* arg)
continue;
}
DEBUG_TRACE (DEBUG::Sequence, string_compose ("\toverlap is %1 for (%2,%3) vs (%4,%5)\n", enum_2_string(overlap),
sa, ea, sb, eb));
if (insert_merge_policy() == InsertMergeReject) {
DEBUG_TRACE (DEBUG::Sequence, string_compose ("%1 just reject\n", this));
return -1;
}

View File

@@ -375,7 +375,7 @@ MidiTrack::roll (nframes_t nframes, framepos_t start_frame, framepos_t end_frame
}
_main_outs->flush (nframes, end_frame - start_frame - 1);
_main_outs->flush_buffers (nframes, end_frame - start_frame - 1);
return 0;
}

View File

@@ -221,12 +221,16 @@ PluginInsert::parameter_changed (Evoral::Parameter which, float val)
}
}
void
int
PluginInsert::set_block_size (nframes_t nframes)
{
int ret = 0;
for (Plugins::iterator i = _plugins.begin(); i != _plugins.end(); ++i) {
(*i)->set_block_size (nframes);
if ((*i)->set_block_size (nframes) != 0) {
ret = -1;
}
}
return ret;
}
void
@@ -249,6 +253,14 @@ PluginInsert::deactivate ()
}
}
void
PluginInsert::flush ()
{
for (vector<boost::shared_ptr<Plugin> >::iterator i = _plugins.begin(); i != _plugins.end(); ++i) {
(*i)->flush ();
}
}
void
PluginInsert::connect_and_run (BufferSet& bufs, nframes_t nframes, nframes_t offset, bool with_auto, nframes_t now)
{
@@ -436,7 +448,7 @@ PluginInsert::automation_run (BufferSet& bufs, nframes_t nframes)
return;
}
if (!find_next_event (now, end, next_event)) {
if (!find_next_event (now, end, next_event) || requires_fixed_sized_buffers()) {
/* no events have a time within the relevant range */

View File

@@ -83,6 +83,23 @@ PortInsert::set_measured_latency (nframes_t n)
_measured_latency = n;
}
nframes_t
PortInsert::latency() const
{
/* because we deliver and collect within the same cycle,
all I/O is necessarily delayed by at least frames_per_cycle().
if the return port for insert has its own latency, we
need to take that into account too.
*/
if (_measured_latency == 0) {
return _session.engine().frames_per_cycle() + _input->latency();
} else {
return _measured_latency;
}
}
void
PortInsert::run (BufferSet& bufs, sframes_t start_frame, sframes_t end_frame, nframes_t nframes, bool)
{
@@ -149,6 +166,10 @@ PortInsert::state (bool full)
node.add_property ("type", "port");
snprintf (buf, sizeof (buf), "%" PRIu32, bitslot);
node.add_property ("bitslot", buf);
snprintf (buf, sizeof (buf), "%u", _measured_latency);
node.add_property("latency", buf);
snprintf (buf, sizeof (buf), "%u", _session.get_block_size());
node.add_property("block_size", buf);
return node;
}
@@ -183,6 +204,18 @@ PortInsert::set_state (const XMLNode& node, int version)
return -1;
}
uint32_t blocksize = 0;
if ((prop = node.property ("block_size")) != 0) {
sscanf (prop->value().c_str(), "%u", &blocksize);
}
//if the jack period is the same as when the value was saved, we can recall our latency..
if ( (_session.get_block_size() == blocksize) && (prop = node.property ("latency")) != 0) {
uint32_t latency = 0;
sscanf (prop->value().c_str(), "%u", &latency);
_measured_latency = latency;
}
if ((prop = node.property ("bitslot")) == 0) {
bitslot = _session.next_insert_id();
} else {

View File

@@ -2635,6 +2635,7 @@ Route::handle_transport_stopped (bool /*abort_ignored*/, bool did_locate, bool c
if (Config->get_plugins_stop_with_transport() && can_flush_processors) {
(*i)->deactivate ();
(*i)->activate ();
(*i)->flush ();
}
(*i)->transport_stopped (now);
@@ -2827,8 +2828,7 @@ Route::flush_processors ()
Glib::RWLock::ReaderLock lm (_processor_lock);
for (ProcessorList::iterator i = _processors.begin(); i != _processors.end(); ++i) {
(*i)->deactivate ();
(*i)->activate ();
(*i)->flush ();
}
}

View File

@@ -3532,7 +3532,7 @@ Session::freeze_all (InterThreadInfo& itt)
}
boost::shared_ptr<Region>
Session::write_one_track (AudioTrack& track, nframes_t start, nframes_t end,
Session::write_one_track (AudioTrack& track, framepos_t start, framepos_t end,
bool /*overwrite*/, vector<boost::shared_ptr<Source> >& srcs,
InterThreadInfo& itt, bool enable_processing)
{
@@ -3542,13 +3542,14 @@ Session::write_one_track (AudioTrack& track, nframes_t start, nframes_t end,
uint32_t x;
char buf[PATH_MAX+1];
ChanCount nchans(track.n_channels());
nframes_t position;
nframes_t this_chunk;
nframes_t to_do;
framepos_t position;
framecnt_t this_chunk;
framepos_t to_do;
BufferSet buffers;
SessionDirectory sdir(get_best_session_directory_for_new_source ());
const string sound_dir = sdir.sound_path().to_string();
nframes_t len = end - start;
framepos_t len = end - start;
bool need_block_size_reset = false;
string ext;
if (end <= start) {
@@ -3557,7 +3558,7 @@ Session::write_one_track (AudioTrack& track, nframes_t start, nframes_t end,
return result;
}
const nframes_t chunk_size = (256 * 1024)/4;
const framecnt_t chunk_size = (256 * 1024)/4;
// block all process callback handling
@@ -3604,6 +3605,11 @@ Session::write_one_track (AudioTrack& track, nframes_t start, nframes_t end,
srcs.push_back (fsource);
}
/* tell redirects that care that we are about to use a much larger blocksize */
need_block_size_reset = true;
track.set_block_size (chunk_size);
/* XXX need to flush all redirects */
position = start;
@@ -3694,6 +3700,11 @@ Session::write_one_track (AudioTrack& track, nframes_t start, nframes_t end,
}
}
if (need_block_size_reset) {
track.set_block_size (get_block_size());
}
unblock_processing ();
return result;

View File

@@ -328,7 +328,7 @@ Track::no_roll (nframes_t nframes, framepos_t start_frame, framepos_t end_frame,
passthru (start_frame, end_frame, nframes, false);
}
_main_outs->flush (nframes, end_frame - start_frame - 1);
_main_outs->flush_buffers (nframes, end_frame - start_frame - 1);
return 0;
}

View File

@@ -107,12 +107,13 @@ VSTPlugin::~VSTPlugin ()
fst_close (_fst);
}
void
int
VSTPlugin::set_block_size (nframes_t nframes)
{
deactivate ();
_plugin->dispatcher (_plugin, effSetBlockSize, 0, nframes, NULL, 0.0f);
activate ();
return 0;
}
float

View File

@@ -599,6 +599,7 @@ Sequence<Time>::add_note_unlocked(const NotePtr note, void* arg)
DEBUG_TRACE (DEBUG::Sequence, string_compose ("%1 add note %2 @ %3\n", this, (int)note->note(), note->time()));
if (resolve_overlaps_unlocked (note, arg)) {
DEBUG_TRACE (DEBUG::Sequence, string_compose ("%1 DISALLOWED: note %2 @ %3\n", this, (int)note->note(), note->time()));
return false;
}

View File

@@ -25,6 +25,7 @@
#include <algorithm>
#include <pbd/controllable.h>
#include <pbd/locale_guard.h>
#include "gtkmm2ext/gtk_ui.h"
#include "gtkmm2ext/utils.h"
@@ -471,13 +472,19 @@ BarController::entry_input (double* new_value)
// extract a double from the string and take its log
Entry *entry = dynamic_cast<Entry *>(&spinner);
stringstream stream(entry->get_text());
stream.imbue(std::locale(""));
double value;
stream >> value;
{
// Switch to user's preferred locale so that
// if they use different LC_NUMERIC conventions,
// we will honor them.
PBD::LocaleGuard lg ("");
sscanf (entry->get_text().c_str(), "%lf", &value);
}
*new_value = log(value);
return true;
}
@@ -502,29 +509,20 @@ BarController::entry_output ()
stringstream stream;
string str;
size_t found;
// Gtk.Entry does not like the thousands separator, so we have to
// remove it after conversion from float to string.
char buf[128];
stream.imbue(std::locale(""));
stream.precision(spinner.get_digits());
stream << fixed << exp(spinner.get_adjustment()->get_value());
str=stream.str();
// find thousands separators, remove them
found = str.find(use_facet<numpunct<char> >(std::locale("")).thousands_sep());
while(found != str.npos) {
str.erase(found,1);
//find next
found = str.find(use_facet<numpunct<char> >(std::locale("")).thousands_sep());
{
// Switch to user's preferred locale so that
// if they use different LC_NUMERIC conventions,
// we will honor them.
PBD::LocaleGuard lg ("");
snprintf (buf, sizeof (buf), "%g", exp (spinner.get_adjustment()->get_value()));
}
Entry *entry = dynamic_cast<Entry *>(&spinner);
entry->set_text(str);
entry->set_text(buf);
return true;
}

View File

@@ -22,11 +22,16 @@
#include <string>
namespace Glib {
class ustring;
}
namespace PBD {
// returns the empty string if the entire string is whitespace
// so check length after calling.
extern void strip_whitespace_edges (std::string& str);
extern void strip_whitespace_edges (Glib::ustring& str);
} // namespace PBD

View File

@@ -18,6 +18,7 @@
*/
#include "pbd/whitespace.h"
#include <glibmm/ustring.h>
using namespace std;
@@ -77,4 +78,12 @@ strip_whitespace_edges (string& str)
}
}
void
strip_whitespace_edges (Glib::ustring& str)
{
string copy (str.raw());
strip_whitespace_edges (copy);
str = copy;
}
} // namespace PBD