X-Git-Url: https://main.carlh.net/gitweb/?a=blobdiff_plain;f=libs%2Fardour%2Faudio_track.cc;h=5749afd265a06537ef80a49c006fb63cf109f8b7;hb=ee42a6dd97045253d1a9bb32fc2e571d235f9967;hp=d30899caf8605b44490007c82662f1db3002ab9f;hpb=89e4d352445e9394073804f78fbd6845e6820f20;p=ardour.git diff --git a/libs/ardour/audio_track.cc b/libs/ardour/audio_track.cc index d30899caf8..5749afd265 100644 --- a/libs/ardour/audio_track.cc +++ b/libs/ardour/audio_track.cc @@ -39,6 +39,8 @@ #include #include #include +#include +#include #include "i18n.h" using namespace std; @@ -64,6 +66,8 @@ AudioTrack::AudioTrack (Session& sess, string name, Route::Flag flag, TrackMode _session.add_diskstream (ds); + _session.RouteAdded.connect (mem_fun (*this, &AudioTrack::catch_up_on_busses)); + set_diskstream (boost::dynamic_pointer_cast (ds), this); } @@ -71,12 +75,47 @@ AudioTrack::AudioTrack (Session& sess, const XMLNode& node) : Track (sess, node) { _set_state (node, false); + + _session.RouteAdded.connect (mem_fun (*this, &AudioTrack::catch_up_on_busses)); } AudioTrack::~AudioTrack () { } +void +AudioTrack::catch_up_on_busses (RouteList& added) +{ + if (is_hidden()) { + return; + } + + for (RouteList::iterator x = added.begin(); x != added.end(); ++x) { + if (boost::dynamic_pointer_cast(*x) == 0 && (*x)->default_type() == DataType::AUDIO) { + /* Audio bus */ + if (!(*x)->is_master() && !(*x)->is_control()) { + add_internal_send (*x); + } + } + } +} + +void +AudioTrack::add_internal_send (boost::shared_ptr r) +{ + boost::shared_ptr is (new InternalSend (_session, PreFader, r)); + + cerr << name() << " Adding processor\n"; + + add_processor (is, 0); + + cerr << "After add, we have " << _processors.size() << endl; + + /* note: if adding failed, the InternalSend will be cleaned up automatically when + the shared_ptr goes out of scope. + */ +} + int AudioTrack::set_mode (TrackMode m) { @@ -586,19 +625,74 @@ AudioTrack::roll (nframes_t nframes, nframes_t start_frame, nframes_t end_frame, /* copy the diskstream data to all output buffers */ - - const size_t limit = n_process_buffers().n_audio(); - BufferSet& bufs = _session.get_scratch_buffers (n_process_buffers()); - + + size_t limit = n_process_buffers().n_audio(); + BufferSet& bufs = _session.get_scratch_buffers (); + const size_t blimit = bufs.count().n_audio(); + uint32_t n; uint32_t i; - for (i = 0, n = 1; i < limit; ++i, ++n) { - memcpy (bufs.get_audio(i).data(), b, sizeof (Sample) * nframes); - if (n < diskstream->n_channels().n_audio()) { - tmpb = diskstream->playback_buffer(n); - if (tmpb!=0) { - b = tmpb; + if (limit > blimit) { + + /* example case: auditioner configured for stereo output, + but loaded with an 8 channel file. there are only + 2 passthrough buffers, but n_process_buffers() will + return 8. + + arbitrary decision: map all channels in the diskstream + to the outputs available. + */ + + float scaling = limit/blimit; + + for (i = 0, n = 1; i < blimit; ++i, ++n) { + + /* first time through just copy a channel into + the output buffer. + */ + + Sample* bb = bufs.get_audio (i).data(); + + for (nframes_t xx = 0; xx < nframes; ++xx) { + bb[xx] = b[xx] * scaling; + } + + if (n < diskstream->n_channels().n_audio()) { + tmpb = diskstream->playback_buffer(n); + if (tmpb!=0) { + b = tmpb; + } + } + } + + for (;i < limit; ++i, ++n) { + + /* for all remaining channels, sum with existing + data in the output buffers + */ + + bufs.get_audio (i%blimit).accumulate_with_gain_from (b, nframes, 0, scaling); + + if (n < diskstream->n_channels().n_audio()) { + tmpb = diskstream->playback_buffer(n); + if (tmpb!=0) { + b = tmpb; + } + } + + } + + limit = blimit; + + } else { + for (i = 0, n = 1; i < blimit; ++i, ++n) { + memcpy (bufs.get_audio (i).data(), b, sizeof (Sample) * nframes); + if (n < diskstream->n_channels().n_audio()) { + tmpb = diskstream->playback_buffer(n); + if (tmpb!=0) { + b = tmpb; + } } } } @@ -823,13 +917,18 @@ AudioTrack::freeze (InterThreadInfo& itt) /* now deactivate the processor */ - processor->set_active (false); + processor->deactivate (); _session.set_dirty (); } } } new_playlist = PlaylistFactory::create (DataType::AUDIO, _session, new_playlist_name, false); + + _freeze_record.gain = _gain; + _freeze_record.gain_automation_state = _gain_control->automation_state(); + _freeze_record.pan_automation_state = _panner->automation_state(); + region_name = new_playlist_name; /* create a new region from all filesources, keep it private */ @@ -847,6 +946,12 @@ AudioTrack::freeze (InterThreadInfo& itt) diskstream->use_playlist (boost::dynamic_pointer_cast(new_playlist)); diskstream->set_record_enabled (false); + /* reset stuff that has already been accounted for in the freeze process */ + + set_gain (1.0, this); + _gain_control->set_automation_state (Off); + _panner->set_automation_state (Off); + _freeze_record.state = Frozen; FreezeChange(); /* EMIT SIGNAL */ } @@ -877,6 +982,9 @@ AudioTrack::unfreeze () } _freeze_record.playlist.reset (); + set_gain (_freeze_record.gain, this); + _gain_control->set_automation_state (_freeze_record.gain_automation_state); + _panner->set_automation_state (_freeze_record.pan_automation_state); } _freeze_record.state = UnFrozen;