#include <sys/param.h>
#endif
+#include <glibmm.h>
+
#include <midi++/mmc.h>
#include <midi++/port.h>
#include <pbd/error.h>
-#include <pbd/dirname.h>
-#include <pbd/lockmonitor.h>
+
+#include <glibmm/thread.h>
#include <pbd/pathscanner.h>
#include <pbd/pthread_utils.h>
-#include <pbd/basename.h>
#include <pbd/strsplit.h>
#include <ardour/audioengine.h>
#include <ardour/location.h>
#include <ardour/audioregion.h>
#include <ardour/crossfade.h>
+#include <ardour/control_protocol_manager.h>
#include "i18n.h"
#include <locale.h>
_tempo_map = new TempoMap (_current_frame_rate);
_tempo_map->StateChanged.connect (mem_fun (*this, &Session::tempo_map_changed));
- atomic_set (&processing_prohibited, 0);
+ g_atomic_int_set (&processing_prohibited, 0);
send_cnt = 0;
insert_cnt = 0;
_transport_speed = 0;
_transport_frame = 0;
last_stop_frame = 0;
end_location = new Location (0, 0, _("end"), Location::Flags ((Location::IsMark|Location::IsEnd)));
+ start_location = new Location (0, 0, _("start"), Location::Flags ((Location::IsMark|Location::IsStart)));
_end_location_is_free = true;
- atomic_set (&_record_status, Disabled);
+ g_atomic_int_set (&_record_status, Disabled);
auto_play = false;
punch_in = false;
punch_out = false;
_solo_model = InverseMute;
solo_update_disabled = false;
currently_soloing = false;
+ _have_captured = false;
_worst_output_latency = 0;
_worst_input_latency = 0;
_worst_track_latency = 0;
butler_gain_buffer = 0;
auditioner = 0;
mmc_control = false;
- midi_feedback = false;
midi_control = true;
mmc = 0;
post_transport_work = PostTransportWork (0);
- atomic_set (&butler_should_do_transport_work, 0);
- atomic_set (&butler_active, 0);
- atomic_set (&_playback_load, 100);
- atomic_set (&_capture_load, 100);
- atomic_set (&_playback_load_min, 100);
- atomic_set (&_capture_load_min, 100);
+ g_atomic_int_set (&butler_should_do_transport_work, 0);
+ g_atomic_int_set (&butler_active, 0);
+ g_atomic_int_set (&_playback_load, 100);
+ g_atomic_int_set (&_capture_load, 100);
+ g_atomic_int_set (&_playback_load_min, 100);
+ g_atomic_int_set (&_capture_load_min, 100);
pending_audition_region = 0;
_edit_mode = Slide;
pending_edit_mode = _edit_mode;
_master_out = 0;
input_auto_connect = AutoConnectOption (0);
output_auto_connect = AutoConnectOption (0);
- _have_captured = false;
waiting_to_start = false;
_exporting = false;
_gain_automation_buffer = 0;
pending_abort = false;
layer_model = MoveAddHigher;
xfade_model = ShortCrossfade;
+ destructive_index = 0;
/* allocate conversion buffers */
_conversion_buffers[ButlerContext] = new char[DiskStream::disk_io_frames() * 4];
int
Session::second_stage_init (bool new_session)
{
- SndFileSource::set_peak_dir (peak_dir());
+ ExternalSource::set_peak_dir (peak_dir());
if (!new_session) {
if (load_state (_current_snapshot_name)) {
return -1;
}
- if (init_feedback ()) {
- return -1;
- }
-
if (state_tree) {
if (set_state (*state_tree->root())) {
return -1;
_engine.transport_locate (0);
deliver_mmc (MIDI::MachineControl::cmdMmcReset, 0);
deliver_mmc (MIDI::MachineControl::cmdLocate, 0);
- send_all_midi_feedback();
+
+ ControlProtocolManager::instance().set_session (*this);
if (new_session) {
_end_location_is_free = true;
if (colons == 0) {
- /* no multiple search path, just one directory (common case) */
+ /* no multiple search path, just one location (common case) */
sp.path = path;
sp.blocks = 0;
session_dirs.push_back (sp);
+
+ string fspath;
+
+ /* sounds dir */
+
+ fspath += sp.path;
+ if (fspath[fspath.length()-1] != '/') {
+ fspath += '/';
+ }
+ fspath += sound_dir_name;
+ fspath += ':';
+
+ /* tape dir */
+
+ fspath += sp.path;
+ if (fspath[fspath.length()-1] != '/') {
+ fspath += '/';
+ }
+ fspath += tape_dir_name;
- FileSource::set_search_path (path + sound_dir_name);
+ FileSource::set_search_path (fspath);
return;
}
sp.blocks = 0;
sp.path = remaining.substr (0, colon);
+ session_dirs.push_back (sp);
+
+ /* add sounds to file search path */
fspath += sp.path;
if (fspath[fspath.length()-1] != '/') {
fspath += sound_dir_name;
fspath += ':';
- session_dirs.push_back (sp);
+ /* add tape dir to file search path */
+
+ fspath += sp.path;
+ if (fspath[fspath.length()-1] != '/') {
+ fspath += '/';
+ }
+ fspath += tape_dir_name;
+ fspath += ':';
remaining = remaining.substr (colon+1);
}
sp.blocks = 0;
sp.path = remaining;
+ fspath += ':';
fspath += sp.path;
if (fspath[fspath.length()-1] != '/') {
fspath += '/';
}
fspath += sound_dir_name;
+ fspath += ':';
+
+ fspath += sp.path;
+ if (fspath[fspath.length()-1] != '/') {
+ fspath += '/';
+ }
+ fspath += tape_dir_name;
session_dirs.push_back (sp);
}
if (new_session) {
- /* set an initial end point */
+ /* set initial start + end point */
+
+ start_location->set_end (0);
+ _locations.add (start_location);
end_location->set_end (initial_length);
_locations.add (end_location);
-
+
_state_of_the_state = Clean;
if (save_state (_current_snapshot_name)) {
if (!pending) {
bool was_dirty = dirty();
-
+
_state_of_the_state = StateOfTheState (_state_of_the_state & ~Dirty);
if (was_dirty) {
}
}
+ if ((child = find_named_node (node, "end-marker-is-free")) != 0) {
+ if ((prop = child->property ("val")) != 0) {
+ _end_location_is_free = (prop->value() == "yes");
+ }
+ }
+
if ((child = find_named_node (node, "layer-model")) != 0) {
if ((prop = child->property ("val")) != 0) {
if (prop->value() == X_("LaterHigher")) {
child->add_property ("val", get_crossfades_active () ? "yes" : "no");
child = opthead->add_child ("audible-click");
child->add_property ("val", get_clicking () ? "yes" : "no");
+ child = opthead->add_child ("end-marker-is-free");
+ child->add_property ("val", _end_location_is_free ? "yes" : "no");
if (click_sound.length()) {
child = opthead->add_child ("click-sound");
sources in their state node.
*/
- disable_record ();
+ disable_record (false);
return state(false);
}
child = node->add_child ("Sources");
if (full_state) {
- LockMonitor sl (source_lock, __LINE__, __FILE__);
+ Glib::Mutex::Lock sl (source_lock);
for (SourceList::iterator siter = sources.begin(); siter != sources.end(); ++siter) {
/* Don't save information about FileSources that are empty */
FileSource* fs;
-
+
if ((fs = dynamic_cast<FileSource*> ((*siter).second)) != 0) {
- if (fs->length() == 0) {
- continue;
+ DestructiveFileSource* dfs = dynamic_cast<DestructiveFileSource*> (fs);
+
+ /* destructive file sources are OK if they are empty, because
+ we will re-use them every time.
+ */
+
+ if (!dfs) {
+ if (fs->length() == 0) {
+ continue;
+ }
}
}
child = node->add_child ("Regions");
if (full_state) {
- LockMonitor rl (region_lock, __LINE__, __FILE__);
+ Glib::Mutex::Lock rl (region_lock);
for (AudioRegionList::const_iterator i = audio_regions.begin(); i != audio_regions.end(); ++i) {
child = node->add_child ("DiskStreams");
{
- RWLockMonitor dl (diskstream_lock, false, __LINE__, __FILE__);
+ Glib::RWLock::ReaderLock dl (diskstream_lock);
for (DiskStreamList::iterator i = diskstreams.begin(); i != diskstreams.end(); ++i) {
if (!(*i)->hidden()) {
child->add_child_nocopy ((*i)->get_state());
child = node->add_child ("Connections");
{
- LockMonitor lm (connection_lock, __LINE__, __FILE__);
+ Glib::Mutex::Lock lm (connection_lock);
for (ConnectionList::iterator i = _connections.begin(); i != _connections.end(); ++i) {
if (!(*i)->system_dependent()) {
child->add_child_nocopy ((*i)->get_state());
child = node->add_child ("Routes");
{
- RWLockMonitor lm (route_lock, false, __LINE__, __FILE__);
+ Glib::RWLock::ReaderLock lm (route_lock);
RoutePublicOrderSorter cmp;
RouteList public_order(routes);
if ((location = _locations.end_location()) == 0) {
_locations.add (end_location);
} else {
+ delete end_location;
end_location = location;
}
+ if ((location = _locations.start_location()) == 0) {
+ _locations.add (start_location);
+ } else {
+ delete start_location;
+ start_location = location;
+ }
+
_locations.save_state (_("initial state"));
if ((child = find_named_node (node, "EditGroups")) == 0) {
{
XMLNode* node = new XMLNode (X_("Sources"));
- LockMonitor lm (source_lock, __LINE__, __FILE__);
+ Glib::Mutex::Lock lm (source_lock);
for (SourceList::iterator i = sources.begin(); i != sources.end(); ++i) {
node->add_child_nocopy ((*i).second->get_state());
return 0;
}
-
try {
if (node.property (X_("destructive")) != 0) {
src = new DestructiveFileSource (node, frame_rate());
catch (failed_constructor& err) {
try {
- src = new SndFileSource (node);
+ src = ExternalSource::create (node);
}
catch (failed_constructor& err) {
#if HAVE_SYS_VFS_H
struct statfs statfsbuf;
vector<space_and_path>::iterator i;
- LockMonitor lm (space_lock, __LINE__, __FILE__);
+ Glib::Mutex::Lock lm (space_lock);
double scale;
/* get freespace on every FS that is part of the session path */
string
Session::tape_dir () const
{
- string res = Config->get_tape_dir();
-
- if (!res.empty()) {
- return res;
- }
-
- res = _path;
+ string res = _path;
res += tape_dir_name;
res += '/';
return res;
string
Session::template_dir ()
{
- string path = Config->get_user_ardour_path();
+ string path = get_user_ardour_path();
path += "templates/";
return path;
}
string
-Session::template_path ()
+Session::suffixed_search_path (string suffix, bool data)
{
string path;
- path += Config->get_user_ardour_path();
+ path += get_user_ardour_path();
if (path[path.length()-1] != ':') {
path += ':';
}
- path += Config->get_system_ardour_path();
+
+ if (data) {
+ path += get_system_data_path();
+ } else {
+ path += get_system_module_path();
+ }
vector<string> split_path;
for (vector<string>::iterator i = split_path.begin(); i != split_path.end(); ++i) {
path += *i;
- path += "templates/";
+ path += suffix;
+ path += '/';
if (distance (i, split_path.end()) != 1) {
path += ':';
return path;
}
+string
+Session::template_path ()
+{
+ return suffixed_search_path (X_("templates"), true);
+}
+
+string
+Session::control_protocol_path ()
+{
+ return suffixed_search_path (X_("surfaces"), false);
+}
+
int
Session::load_connections (const XMLNode& node)
{
{
XMLNodeList nlist = node.children();
XMLNodeConstIterator niter;
- RouteGroup* route;
+ RouteGroup* rg;
set_dirty();
for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
if ((*niter)->name() == "RouteGroup") {
if (edit) {
- route = add_edit_group ("");
- route->set_state (**niter);
+ rg = add_edit_group ("");
+ rg->set_state (**niter);
} else {
- route = add_mix_group ("");
- route->set_state (**niter);
+ rg = add_mix_group ("");
+ rg->set_state (**niter);
}
}
}
void
Session::swap_configuration(Configuration** new_config)
{
- RWLockMonitor lm (route_lock, true, __LINE__, __FILE__); // jlc - WHY?
+ Glib::RWLock::WriterLock lm (route_lock); // jlc - WHY?
Configuration* tmp = *new_config;
*new_config = Config;
Config = tmp;
void
Session::copy_configuration(Configuration* new_config)
{
- RWLockMonitor lm (route_lock, true, __LINE__, __FILE__);
+ Glib::RWLock::WriterLock lm (route_lock);
new_config = new Configuration(*Config);
}
RouteGroup *
Session::add_edit_group (string name)
{
- RouteGroup* rg = new RouteGroup (name);
+ RouteGroup* rg = new RouteGroup (*this, name);
edit_groups.push_back (rg);
edit_group_added (rg); /* EMIT SIGNAL */
set_dirty();
RouteGroup *
Session::add_mix_group (string name)
{
- RouteGroup* rg = new RouteGroup (name, RouteGroup::Relative);
+ RouteGroup* rg = new RouteGroup (*this, name, RouteGroup::Relative);
mix_groups.push_back (rg);
mix_group_added (rg); /* EMIT SIGNAL */
set_dirty();
Session::get_global_route_boolean (bool (Route::*method)(void) const)
{
GlobalRouteBooleanState s;
- RWLockMonitor lm (route_lock, false, __LINE__, __FILE__);
+ Glib::RWLock::ReaderLock lm (route_lock);
for (RouteList::iterator i = routes.begin(); i != routes.end(); ++i) {
if (!(*i)->hidden()) {
Session::get_global_route_metering ()
{
GlobalRouteMeterState s;
- RWLockMonitor lm (route_lock, false, __LINE__, __FILE__);
+ Glib::RWLock::ReaderLock lm (route_lock);
for (RouteList::iterator i = routes.begin(); i != routes.end(); ++i) {
if (!(*i)->hidden()) {
int
Session::read_favorite_dirs (FavoriteDirs & favs)
{
- string path = Config->get_user_ardour_path();
+ string path = get_user_ardour_path();
path += "/favorite_dirs";
ifstream fav (path.c_str());
int
Session::write_favorite_dirs (FavoriteDirs & favs)
{
- string path = Config->get_user_ardour_path();
+ string path = get_user_ardour_path();
path += "/favorite_dirs";
ofstream fav (path.c_str());
for (SourceList::iterator i = sources.begin(); i != sources.end(); ++i) {
FileSource* fs;
- SndFileSource* sfs;
+ ExternalSource* sfs;
if ((fs = dynamic_cast<FileSource*> ((*i).second)) != 0) {
all_sources.insert (fs->path());
- } else if ((sfs = dynamic_cast<SndFileSource*> ((*i).second)) != 0) {
+ } else if ((sfs = dynamic_cast<ExternalSource*> ((*i).second)) != 0) {
all_sources.insert (sfs->path());
}
}
on whichever filesystem it was already on.
*/
- newpath = PBD::dirname (*x);
- newpath = PBD::dirname (newpath);
+ newpath = Glib::path_get_dirname (*x);
+ newpath = Glib::path_get_dirname (newpath);
newpath += '/';
newpath += dead_sound_dir_name;
newpath += '/';
- newpath += PBD::basename ((*x));
+ newpath += Glib::path_get_basename ((*x));
if (access (newpath.c_str(), F_OK) == 0) {
Session::set_dirty ()
{
bool was_dirty = dirty();
-
+
_state_of_the_state = StateOfTheState (_state_of_the_state | Dirty);
if (!was_dirty) {