#include <fcntl.h>
#include <cstdlib>
#include <ctime>
-#include <sys/stat.h>
-#include <sys/mman.h>
#include "pbd/error.h"
#include "pbd/xml++.h"
void
AudioDiskstream::non_realtime_input_change ()
{
+ bool need_write_sources = false;
+
{
Glib::Threads::Mutex::Lock lm (state_lock);
return;
}
+ boost::shared_ptr<ChannelList> cr = channels.reader();
+ if (!cr->empty() && !cr->front()->write_source) {
+ need_write_sources = true;
+ }
+
if (input_change_pending.type == IOChange::ConfigurationChanged) {
RCUWriter<ChannelList> writer (channels);
boost::shared_ptr<ChannelList> c = writer.get_copy();
} else if (_io->n_ports().n_audio() < _n_channels.n_audio()) {
remove_channel_from (c, _n_channels.n_audio() - _io->n_ports().n_audio());
}
+
+ need_write_sources = true;
}
if (input_change_pending.type & IOChange::ConnectionsChanged) {
/* implicit unlock */
}
- /* reset capture files */
-
- reset_write_sources (false);
+ if (need_write_sources) {
+ reset_write_sources (false);
+ }
/* now refill channel buffers */
if (record_enabled()) {
Evoral::OverlapType ot = Evoral::coverage (first_recordable_frame, last_recordable_frame, transport_frame, transport_frame + nframes);
+ // XXX should this be transport_frame + nframes - 1 ? coverage() expects its parameter ranges to include their end points
+ // XXX also, first_recordable_frame & last_recordable_frame may both be == max_framepos: coverage() will return OverlapNone in that case. Is thak OK?
calculate_record_range (ot, transport_frame, nframes, rec_nframes, rec_offset);
+ DEBUG_TRACE (DEBUG::CaptureAlignment, string_compose ("%1: this time record %2 of %3 frames, offset %4\n", _name, rec_nframes, nframes, rec_offset));
+
if (rec_nframes && !was_recording) {
capture_captured = 0;
was_recording = true;
framecnt_t total = chaninfo->capture_vector.len[0] + chaninfo->capture_vector.len[1];
if (rec_nframes > total) {
+ DEBUG_TRACE (DEBUG::Butler, string_compose ("%1 overrun in %2, rec_nframes = %3 total space = %4\n",
+ DEBUG_THREAD_SELF, name(), rec_nframes, total));
DiskOverrun ();
return -1;
}
if (necessary_samples > total) {
cerr << _name << " Need " << necessary_samples << " total = " << total << endl;
cerr << "underrun for " << _name << endl;
+ DEBUG_TRACE (DEBUG::Butler, string_compose ("%1 underrun in %2, rec_nframes = %3 total space = %4\n",
+ DEBUG_THREAD_SELF, name(), rec_nframes, total));
DiskUnderrun ();
return -1;
error << string_compose(_("AudioDiskstream %1: cannot write to disk"), id()) << endmsg;
return -1;
}
-
+
(*chan)->capture_buf->increment_read_ptr (to_write);
(*chan)->curr_capture_cnt += to_write;
to_write = min ((framecnt_t)(disk_io_chunk_frames - to_write), (framecnt_t) vector.len[1]);
+ DEBUG_TRACE (DEBUG::Butler, string_compose ("%1 additional write of %2\n", name(), to_write));
+
if ((*chan)->write_source->write (vector.buf[1], to_write) != to_write) {
error << string_compose(_("AudioDiskstream %1: cannot write to disk"), id()) << endmsg;
return -1;
}
_last_capture_sources.insert (_last_capture_sources.end(), srcs.begin(), srcs.end());
-
- // cerr << _name << ": there are " << capture_info.size() << " capture_info records\n";
-
+
_playlist->clear_changes ();
_playlist->set_capture_insertion_in_progress (true);
_playlist->freeze ();
accessors, so that invalidation will not occur (both non-realtime).
*/
- // cerr << "Finish capture, add new CI, " << ci->start << '+' << ci->frames << endl;
-
+ DEBUG_TRACE (DEBUG::CaptureAlignment, string_compose ("Finish capture, add new CI, %1 + %2\n", ci->start, ci->frames));
+
capture_info.push_back (ci);
capture_captured = 0;
LocaleGuard lg (X_("POSIX"));
boost::shared_ptr<ChannelList> c = channels.reader();
- snprintf (buf, sizeof(buf), "%zd", c->size());
+ snprintf (buf, sizeof(buf), "%u", (unsigned int) c->size());
node.add_property ("channels", buf);
if (!capturing_sources.empty() && _session.get_record_enabled()) {
try {
if ((chan->write_source = _session.create_audio_source_for_session (
- n_channels().n_audio(), name(), n, destructive())) == 0) {
+ n_channels().n_audio(), write_source_name(), n, destructive())) == 0) {
throw failed_constructor();
}
}
return 0;
}
-list<boost::shared_ptr<Source> >
-AudioDiskstream::steal_write_sources()
-{
- /* not possible to steal audio write sources */
- list<boost::shared_ptr<Source> > ret;
- return ret;
-}
-
void
AudioDiskstream::reset_write_sources (bool mark_write_complete, bool /*force*/)
{
continue;
}
+ /* XXX as of June 2014, we always record to mono
+ files. Since this Source is being created as part of
+ crash recovery, we know that we need the first
+ channel (the final argument to the SourceFactory
+ call below). If we ever support non-mono files for
+ capture, this will need rethinking.
+ */
+
try {
- fs = boost::dynamic_pointer_cast<AudioFileSource> (
- SourceFactory::createWritable (
- DataType::AUDIO, _session,
- prop->value(), false, _session.frame_rate()));
+ fs = boost::dynamic_pointer_cast<AudioFileSource> (SourceFactory::createForRecovery (DataType::AUDIO, _session, prop->value(), 0));
}
catch (failed_constructor& err) {
return -1;
}
- boost::shared_ptr<AudioRegion> region;
-
try {
- PropertyList plist;
+ boost::shared_ptr<AudioRegion> wf_region;
+ boost::shared_ptr<AudioRegion> region;
+
+ /* First create the whole file region */
+ PropertyList plist;
+
plist.add (Properties::start, 0);
plist.add (Properties::length, first_fs->length (first_fs->timeline_position()));
plist.add (Properties::name, region_name_from_path (first_fs->name(), true));
- region = boost::dynamic_pointer_cast<AudioRegion> (RegionFactory::create (pending_sources, plist));
+ wf_region = boost::dynamic_pointer_cast<AudioRegion> (RegionFactory::create (pending_sources, plist));
+
+ wf_region->set_automatic (true);
+ wf_region->set_whole_file (true);
+ wf_region->special_set_position (position);
+
+ /* Now create a region that isn't the whole file for adding to
+ * the playlist */
- region->set_automatic (true);
- region->set_whole_file (true);
- region->special_set_position (0);
+ region = boost::dynamic_pointer_cast<AudioRegion> (RegionFactory::create (pending_sources, plist));
+
+ _playlist->add_region (region, position);
}
catch (failed_constructor& err) {
return -1;
}
- _playlist->add_region (region, position);
return 0;
}
bool
AudioDiskstream::set_name (string const & name)
{
+ if (_name == name) {
+ return true;
+ }
Diskstream::set_name (name);
/* get a new write source so that its name reflects the new diskstream name */
return true;
}
+
+bool
+AudioDiskstream::set_write_source_name (const std::string& str) {
+ if (_write_source_name == str) {
+ return true;
+ }
+
+ Diskstream::set_write_source_name (str);
+
+ if (_write_source_name == name()) {
+ return true;
+ }
+ boost::shared_ptr<ChannelList> c = channels.reader();
+ ChannelList::iterator i;
+ int n = 0;
+
+ for (n = 0, i = c->begin(); i != c->end(); ++i, ++n) {
+ use_new_write_source (n);
+ }
+ return true;
+}