#include <pbd/stacktrace.h>
#include <pbd/file_utils.h>
-#include <ardour/audioengine.h>
-#include <ardour/configuration.h>
-#include <ardour/session.h>
-#include <ardour/session_directory.h>
-#include <ardour/session_metadata.h>
-#include <ardour/utils.h>
+#include <ardour/analyser.h>
+#include <ardour/audio_buffer.h>
#include <ardour/audio_diskstream.h>
+#include <ardour/audio_track.h>
+#include <ardour/audioengine.h>
+#include <ardour/audiofilesource.h>
#include <ardour/audioplaylist.h>
#include <ardour/audioregion.h>
-#include <ardour/audiofilesource.h>
+#include <ardour/auditioner.h>
+#include <ardour/buffer_set.h>
+#include <ardour/bundle.h>
+#include <ardour/click.h>
+#include <ardour/configuration.h>
+#include <ardour/crossfade.h>
+#include <ardour/cycle_timer.h>
+#include <ardour/data_type.h>
+#include <ardour/filename_extensions.h>
+#include <ardour/internal_send.h>
+#include <ardour/io_processor.h>
#include <ardour/midi_diskstream.h>
#include <ardour/midi_playlist.h>
#include <ardour/midi_region.h>
-#include <ardour/smf_source.h>
-#include <ardour/auditioner.h>
-#include <ardour/recent_sessions.h>
-#include <ardour/io_processor.h>
-#include <ardour/send.h>
-#include <ardour/processor.h>
-#include <ardour/plugin_insert.h>
-#include <ardour/port_insert.h>
-#include <ardour/slave.h>
-#include <ardour/tempo.h>
-#include <ardour/audio_track.h>
#include <ardour/midi_track.h>
-#include <ardour/cycle_timer.h>
#include <ardour/named_selection.h>
-#include <ardour/crossfade.h>
#include <ardour/playlist.h>
-#include <ardour/click.h>
-#include <ardour/data_type.h>
-#include <ardour/buffer_set.h>
-#include <ardour/source_factory.h>
+#include <ardour/plugin_insert.h>
+#include <ardour/port_insert.h>
+#include <ardour/processor.h>
+#include <ardour/recent_sessions.h>
#include <ardour/region_factory.h>
-#include <ardour/filename_extensions.h>
+#include <ardour/route_group.h>
+#include <ardour/send.h>
+#include <ardour/session.h>
#include <ardour/session_directory.h>
+#include <ardour/session_directory.h>
+#include <ardour/session_metadata.h>
+#include <ardour/slave.h>
+#include <ardour/smf_source.h>
+#include <ardour/source_factory.h>
#include <ardour/tape_file_matcher.h>
-#include <ardour/analyser.h>
-#include <ardour/bundle.h>
-
-#ifdef HAVE_LIBLO
-#include <ardour/osc.h>
-#endif
+#include <ardour/tempo.h>
+#include <ardour/utils.h>
#include "i18n.h"
string mix_template)
: _engine (eng),
+ _requested_return_frame (-1),
_scratch_buffers(new BufferSet()),
_silent_buffers(new BufferSet()),
_mix_buffers(new BufferSet()),
routes (new RouteList),
auditioner ((Auditioner*) 0),
_total_free_4k_blocks (0),
+ _bundles (new BundleList),
_bundle_xml_node (0),
_click_io ((IO*) 0),
click_data (0),
nframes_t initial_length)
: _engine (eng),
+ _requested_return_frame (-1),
_scratch_buffers(new BufferSet()),
_silent_buffers(new BufferSet()),
_mix_buffers(new BufferSet()),
routes (new RouteList),
auditioner ((Auditioner *) 0),
_total_free_4k_blocks (0),
+ _bundles (new BundleList),
_bundle_xml_node (0),
_click_io ((IO *) 0),
click_data (0),
// XXX HOW TO ALERT UI TO THIS ? DO WE NEED TO?
}
- /* Create a set of Bundle objects that map
- to the physical outputs currently available
- */
-
BootMessage (_("Set up standard connections"));
- /* ONE: MONO */
+ /* Create a set of Bundle objects that map
+ to the physical I/O currently available. We create both
+ mono and stereo bundles, so that the common cases of mono
+ and stereo tracks get bundles to put in their mixer strip
+ in / out menus. There may be a nicer way of achieving that;
+ it doesn't really scale that well to higher channel counts */
for (uint32_t np = 0; np < n_physical_outputs; ++np) {
char buf[32];
snprintf (buf, sizeof (buf), _("out %" PRIu32), np+1);
shared_ptr<Bundle> c (new Bundle (buf, true));
- c->set_nchannels (1);
+ c->add_channel (_("mono"));
c->set_port (0, _engine.get_nth_physical_output (DataType::AUDIO, np));
add_bundle (c);
}
+ for (uint32_t np = 0; np < n_physical_outputs; np += 2) {
+ if (np + 1 < n_physical_outputs) {
+ char buf[32];
+ snprintf (buf, sizeof(buf), _("out %" PRIu32 "+%" PRIu32), np + 1, np + 2);
+ shared_ptr<Bundle> c (new Bundle (buf, true));
+ c->add_channel (_("L"));
+ c->set_port (0, _engine.get_nth_physical_output (DataType::AUDIO, np));
+ c->add_channel (_("R"));
+ c->set_port (1, _engine.get_nth_physical_output (DataType::AUDIO, np + 1));
+
+ add_bundle (c);
+ }
+ }
+
for (uint32_t np = 0; np < n_physical_inputs; ++np) {
char buf[32];
snprintf (buf, sizeof (buf), _("in %" PRIu32), np+1);
shared_ptr<Bundle> c (new Bundle (buf, false));
- c->set_nchannels (1);
+ c->add_channel (_("mono"));
c->set_port (0, _engine.get_nth_physical_input (DataType::AUDIO, np));
add_bundle (c);
}
- /* TWO: STEREO */
-
- for (uint32_t np = 0; np < n_physical_outputs; np +=2) {
- char buf[32];
- snprintf (buf, sizeof (buf), _("out %" PRIu32 "+%" PRIu32), np+1, np+2);
-
- shared_ptr<Bundle> c (new Bundle (buf, true));
- c->set_nchannels (2);
- c->set_port (0, _engine.get_nth_physical_output (DataType::AUDIO, np));
- c->set_port (1, _engine.get_nth_physical_output (DataType::AUDIO, np + 1));
-
- add_bundle (c);
- }
-
- for (uint32_t np = 0; np < n_physical_inputs; np +=2) {
- char buf[32];
- snprintf (buf, sizeof (buf), _("in %" PRIu32 "+%" PRIu32), np+1, np+2);
+ for (uint32_t np = 0; np < n_physical_inputs; np += 2) {
+ if (np + 1 < n_physical_inputs) {
+ char buf[32];
+ snprintf (buf, sizeof(buf), _("in %" PRIu32 "+%" PRIu32), np + 1, np + 2);
- shared_ptr<Bundle> c (new Bundle (buf, false));
- c->set_nchannels (2);
- c->set_port (0, _engine.get_nth_physical_input (DataType::AUDIO, np));
- c->set_port (1, _engine.get_nth_physical_input (DataType::AUDIO, np + 1));
+ shared_ptr<Bundle> c (new Bundle (buf, false));
+ c->add_channel (_("L"));
+ c->set_port (0, _engine.get_nth_physical_input (DataType::AUDIO, np));
+ c->add_channel (_("R"));
+ c->set_port (1, _engine.get_nth_physical_input (DataType::AUDIO, np + 1));
- add_bundle (c);
+ add_bundle (c);
+ }
}
- /* THREE MASTER */
-
if (_master_out) {
/* create master/control ports */
BootMessage (_("Connect to engine"));
_engine.set_session (this);
-
-#ifdef HAVE_LIBLO
- /* and to OSC */
-
- BootMessage (_("OSC startup"));
-
- osc->set_session (*this);
-#endif
-
}
void
/* MOVING */
/* check to see if we have passed the first guaranteed
- audible frame past our last stopping position. if not,
- the return that last stopping point because in terms
+ audible frame past our last start position. if not,
+ return that last start point because in terms
of audible frames, we have not moved yet.
*/
if (_transport_speed > 0.0f) {
if (!play_loop || !have_looped) {
- if (tf < last_stop_frame + offset) {
- return last_stop_frame;
+ if (tf < _last_roll_location + offset) {
+ return _last_roll_location;
}
}
/* XXX wot? no backward looping? */
- if (tf > last_stop_frame - offset) {
- return last_stop_frame;
+ if (tf > _last_roll_location - offset) {
+ return _last_roll_location;
} else {
/* backwards */
ret += offset;
}
-Session::RouteList
+RouteList
Session::new_audio_route (int input_channels, int output_channels, uint32_t how_many)
{
char bus_name[32];
if ((*x)->is_control()) {
_control_out = (*x);
}
-
- /* only busses get automatic bundles formed */
-
- if (!boost::dynamic_pointer_cast<Track> (*x)) {
- add_bundle ((*x)->bundle_for_inputs());
- add_bundle ((*x)->bundle_for_outputs());
- }
}
if (_control_out && IO::connecting_legal) {
_plugin_inserts.insert (_plugin_inserts.begin(), plugin_insert);
} else if ((send = dynamic_cast<Send *> (processor)) != 0) {
_sends.insert (_sends.begin(), send);
+ } else if (dynamic_cast<InternalSend *> (processor) != 0) {
+ /* relax */
} else {
fatal << _("programming error: unknown type of Insert created!") << endmsg;
/*NOTREACHED*/
}
} else if ((plugin_insert = dynamic_cast<PluginInsert *> (processor)) != 0) {
_plugin_inserts.remove (plugin_insert);
+ } else if (dynamic_cast<InternalSend *> (processor) != 0) {
+ /* relax */
} else if ((send = dynamic_cast<Send *> (processor)) != 0) {
list<Send*>::iterator x = find (_sends.begin(), _sends.end(), send);
if (x != _sends.end()) {
Session::add_bundle (shared_ptr<Bundle> bundle)
{
{
- Glib::Mutex::Lock guard (bundle_lock);
- _bundles.push_back (bundle);
+ RCUWriter<BundleList> writer (_bundles);
+ boost::shared_ptr<BundleList> b = writer.get_copy ();
+ b->push_back (bundle);
}
BundleAdded (bundle); /* EMIT SIGNAL */
bool removed = false;
{
- Glib::Mutex::Lock guard (bundle_lock);
- BundleList::iterator i = find (_bundles.begin(), _bundles.end(), bundle);
+ RCUWriter<BundleList> writer (_bundles);
+ boost::shared_ptr<BundleList> b = writer.get_copy ();
+ BundleList::iterator i = find (b->begin(), b->end(), bundle);
- if (i != _bundles.end()) {
- _bundles.erase (i);
+ if (i != b->end()) {
+ b->erase (i);
removed = true;
}
}
shared_ptr<Bundle>
Session::bundle_by_name (string name) const
{
- Glib::Mutex::Lock lm (bundle_lock);
-
- for (BundleList::const_iterator i = _bundles.begin(); i != _bundles.end(); ++i) {
+ boost::shared_ptr<BundleList> b = _bundles.reader ();
+
+ for (BundleList::const_iterator i = b->begin(); i != b->end(); ++i) {
if ((*i)->name() == name) {
return* i;
}
Route::SyncOrderKeys (base); // EMIT SIGNAL
}
-void
-Session::foreach_bundle (sigc::slot<void, boost::shared_ptr<Bundle> > sl)
-{
- Glib::Mutex::Lock lm (bundle_lock);
- for (BundleList::iterator i = _bundles.begin(); i != _bundles.end(); ++i) {
- sl (*i);
- }
-}