Remove CannotRecordNoInput signal (allowing recording without input connections)...
[ardour.git] / libs / ardour / diskstream.cc
index 78f6d1333553ad008802bf03c8b10a259e812775..4fb13210fa6ff6bd4cf409c66ffae9cc3aa77610 100644 (file)
@@ -57,7 +57,6 @@ using namespace ARDOUR;
 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;
@@ -69,13 +68,11 @@ DiskStream::DiskStream (Session &sess, const string &name, Flag flag)
        /* 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 */
 }
@@ -454,10 +451,6 @@ DiskStream::setup_destructive_playlist ()
 {
        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);
        }
@@ -472,13 +465,28 @@ void
 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*>(&region->source (n));
+               (*chan).write_source->set_allow_remove_if_empty (false);
        }
 
        /* the source list will never be reset for a destructive track */
@@ -491,7 +499,7 @@ DiskStream::set_io (IO& io)
        set_align_style_from_io ();
 }
 
-void
+int
 DiskStream::set_name (string str, void *src)
 {
        if (str != _name) {
@@ -499,12 +507,14 @@ DiskStream::set_name (string str, void *src)
                _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
@@ -1797,7 +1807,7 @@ DiskStream::transport_stopped (struct tm& when, time_t twhen, bool abort_capture
                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";
                        
@@ -1907,14 +1917,6 @@ DiskStream::set_record_enabled (bool yn, void* src)
                */
 
                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
@@ -2048,8 +2050,8 @@ DiskStream::set_state (const XMLNode& node)
                }
        }
 
-       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) {
@@ -2097,8 +2099,12 @@ DiskStream::set_state (const XMLNode& node)
                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);
                }
 
@@ -2120,9 +2126,8 @@ DiskStream::set_state (const XMLNode& 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;
@@ -2170,6 +2175,10 @@ DiskStream::use_new_write_source (uint32_t n)
 
        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;
 }
 
@@ -2183,34 +2192,53 @@ DiskStream::reset_write_sources (bool mark_write_complete, bool force)
                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
@@ -2447,7 +2475,7 @@ DiskStream::use_pending_capture_data (XMLNode& node)
                        }
 
                        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) {