jack_nframes_t DiskStream::disk_io_chunk_frames;
sigc::signal<void,DiskStream*> DiskStream::DiskStreamCreated;
-sigc::signal<void,DiskStream*> DiskStream::CannotRecordNoInput;
sigc::signal<void,list<Source*>*> DiskStream::DeleteSources;
sigc::signal<void> DiskStream::DiskOverrun;
sigc::signal<void> DiskStream::DiskUnderrun;
/* prevent any write sources from being created */
in_set_state = true;
+
init (flag);
use_new_playlist ();
- in_set_state = false;
- if (destructive()) {
- setup_destructive_playlist ();
- }
+ in_set_state = false;
DiskStreamCreated (this); /* EMIT SIGNAL */
}
{
AudioRegion::SourceList srcs;
- /* make sure we have sources for every channel */
-
- reset_write_sources (true);
-
for (ChannelList::iterator chan = channels.begin(); chan != channels.end(); ++chan) {
srcs.push_back ((*chan).write_source);
}
DiskStream::use_destructive_playlist ()
{
/* use the sources associated with the single full-extent region */
+
+ Playlist::RegionList* rl = _playlist->regions_at (0);
+
+ if (rl->empty()) {
+ reset_write_sources (false, true);
+ return;
+ }
+
+ AudioRegion* region = dynamic_cast<AudioRegion*> (rl->front());
+
+ if (region == 0) {
+ throw failed_constructor();
+ }
+
+ delete rl;
- AudioRegion* region = dynamic_cast<AudioRegion*> (_playlist->regions_at (0)->front());
uint32_t n;
ChannelList::iterator chan;
for (n = 0, chan = channels.begin(); chan != channels.end(); ++chan, ++n) {
(*chan).write_source = dynamic_cast<FileSource*>(®ion->source (n));
+ (*chan).write_source->set_allow_remove_if_empty (false);
}
/* the source list will never be reset for a destructive track */
set_align_style_from_io ();
}
-void
+int
DiskStream::set_name (string str, void *src)
{
if (str != _name) {
_name = str;
if (!in_set_state && recordable()) {
-
- /* open new capture files so that they have the correct name */
-
- reset_write_sources (false);
+ /* rename existing capture files so that they have the correct name */
+ return rename_write_sources ();
+ } else {
+ return -1;
}
}
+
+ return 0;
}
void
for (buffer_position = channels[0].write_source->last_capture_start_frame(), ci = capture_info.begin(); ci != capture_info.end(); ++ci) {
string region_name;
- _session.region_name (region_name, _name, false);
+ _session.region_name (region_name, channels[0].write_source->name(), false);
// cerr << _name << ": based on ci of " << (*ci)->start << " for " << (*ci)->frames << " add a region\n";
*/
get_input_sources ();
-
- if (channels[0].source == 0) {
-
- if (yn) {
- CannotRecordNoInput (this); /* emit signal */
- }
- return;
- }
}
/* yes, i know that this not proof against race conditions, but its
}
}
- if ((prop = node.property ("_flags")) != 0) {
- _flags = atoi (prop->value().c_str());
+ if ((prop = node.property ("flags")) != 0) {
+ _flags = strtol (prop->value().c_str(), 0, 0);
}
if ((prop = node.property ("channels")) != 0) {
if (!had_playlist) {
_playlist->set_orig_diskstream_id (_id);
}
-
- if (capture_pending_node) {
+
+ if (!destructive() && capture_pending_node) {
+ /* destructive streams have one and only one source per channel,
+ and so they never end up in pending capture in any useful
+ sense.
+ */
use_pending_capture_data (*capture_pending_node);
}
capturing_sources.clear ();
- /* write sources are handled elsewhere;
- for destructive tracks: in {setup,use}_destructive_playlist()
- for non-destructive: when we handle the input set up of the IO that owns this DS
+ /* write sources are handled when we handle the input set
+ up of the IO that owns this DS (::non_realtime_input_change())
*/
in_set_state = false;
chan.write_source->use ();
+ /* do not remove destructive files even if they are empty */
+
+ chan.write_source->set_allow_remove_if_empty (!destructive());
+
return 0;
}
return;
}
- if (!force && destructive()) {
+ capturing_sources.clear ();
+
+ for (chan = channels.begin(), n = 0; chan != channels.end(); ++chan, ++n) {
+ if (!destructive()) {
- /* make sure we always have enough sources for the current channel count */
+ if ((*chan).write_source && mark_write_complete) {
+ (*chan).write_source->mark_streaming_write_completed ();
+ }
+ use_new_write_source (n);
+
+ if (record_enabled()) {
+ capturing_sources.push_back ((*chan).write_source);
+ }
- for (chan = channels.begin(), n = 0; chan != channels.end(); ++chan, ++n) {
+ } else {
if ((*chan).write_source == 0) {
- break;
+ use_new_write_source (n);
}
}
+ }
- if (chan == channels.end()) {
- return;
- }
+ if (destructive()) {
+
+ /* we now have all our write sources set up, so create the
+ playlist's single region.
+ */
- /* some channels do not have a write source */
+ if (_playlist->empty()) {
+ setup_destructive_playlist ();
+ }
}
+}
+
+int
+DiskStream::rename_write_sources ()
+{
+ ChannelList::iterator chan;
+ uint32_t n;
- capturing_sources.clear ();
-
for (chan = channels.begin(), n = 0; chan != channels.end(); ++chan, ++n) {
- if ((*chan).write_source && mark_write_complete) {
- (*chan).write_source->mark_streaming_write_completed ();
- }
- use_new_write_source (n);
- if (record_enabled()) {
- capturing_sources.push_back ((*chan).write_source);
+ if ((*chan).write_source != 0) {
+ (*chan).write_source->set_name (_name, destructive());
+ /* XXX what to do if one of them fails ? */
}
}
+
+ return 0;
}
void
}
try {
- fs = new FileSource (prop->value(), _session.frame_rate(), true);
+ fs = new FileSource (prop->value(), _session.frame_rate(), true, Config->get_native_file_data_format());
}
catch (failed_constructor& err) {