Pass a path argument to ImportableSource rather than SNDFILE handle so resource manag...
authorTim Mayberry <mojofunk@gmail.com>
Thu, 15 Nov 2007 02:31:58 +0000 (02:31 +0000)
committerTim Mayberry <mojofunk@gmail.com>
Thu, 15 Nov 2007 02:31:58 +0000 (02:31 +0000)
git-svn-id: svn://localhost/ardour2/trunk@2667 d708f5d6-7413-0410-9779-e7cbd77b26cf

libs/ardour/ardour/importable_source.h
libs/ardour/ardour/resampled_source.h
libs/ardour/import.cc
libs/ardour/resampled_source.cc

index 4f08498fce1ac9e334c13ab9a35ef5e578521e2a..5845d841b6344e6b84cd4718a1d25bcd6308c12d 100644 (file)
 #define __ardour_importable_source_h__
 
 #include <sndfile.h>
+#include <pbd/failed_constructor.h>
 #include <ardour/types.h>
 
 namespace ARDOUR {
 
 class ImportableSource {
 public:
-       ImportableSource (SNDFILE* sf, SF_INFO* info) : in (sf), sf_info (info) {}
+       ImportableSource (const std::string& path)
+               : in (sf_open (path.c_str(), SFM_READ, &sf_info), sf_close)
+       {
+               if (!in) throw failed_constructor();
+       
+       }
+       
        virtual ~ImportableSource() {}
 
        virtual nframes_t read (Sample* buffer, nframes_t nframes) {
-               nframes_t per_channel = nframes / sf_info->channels;
-               per_channel = sf_readf_float (in, buffer, per_channel);
-               return per_channel * sf_info->channels;
+               nframes_t per_channel = nframes / sf_info.channels;
+               per_channel = sf_readf_float (in.get(), buffer, per_channel);
+               return per_channel * sf_info.channels;
        }
 
        virtual float ratio() const { return 1.0f; }
 
-       uint channels() const { return sf_info->channels; }
+       uint channels() const { return sf_info.channels; }
+
+       nframes_t length() const { return sf_info.frames; }
 
-       nframes_t length() const { return sf_info->frames; }
+       nframes_t samplerate() const { return sf_info.samplerate; }
 
 protected:
-       SNDFILE* in;
-       SF_INFO* sf_info;
+       SF_INFO sf_info;
+       boost::shared_ptr<SNDFILE> in;
 };
 
 }
index 9a88ca9644bda2c8e66b86bb45fde065378b0dd7..8ca56b52d3d14c0726a190b281a1b6028bd90026 100644 (file)
@@ -30,7 +30,9 @@ namespace ARDOUR {
 class ResampledImportableSource : public ImportableSource 
 {
   public:
-       ResampledImportableSource (SNDFILE* sf, SF_INFO* info, nframes_t rate, SrcQuality);
+       ResampledImportableSource (const std::string& path,
+                       nframes_t rate, SrcQuality);
+
        ~ResampledImportableSource ();
        
        nframes_t read (Sample* buffer, nframes_t nframes);
index a116a9ce912a2d88c46130902eaa8419da932fc4..b0348247402465b16b07dc5853c129e6c499c945 100644 (file)
 using namespace ARDOUR;
 using namespace PBD;
 
+std::auto_ptr<ImportableSource>
+open_importable_source (const string& path, nframes_t samplerate,
+               ARDOUR::SrcQuality quality)
+{
+       std::auto_ptr<ImportableSource> source(new ImportableSource(path));
+
+       if (source->samplerate() == samplerate) {
+               return source;
+       }
+
+       return std::auto_ptr<ImportableSource>(
+                       new ResampledImportableSource(path, samplerate, quality)
+                       );
+}
+
 std::string
 get_non_existent_filename (const std::string& basename, uint channel, uint channels)
 {
@@ -144,7 +159,6 @@ write_audio_data_to_new_files (ImportableSource* source, Session::import_status&
 int
 Session::import_audiofile (import_status& status)
 {
-       SF_INFO info;
        string basepath;
        int ret = -1;
        vector<string> new_paths;
@@ -155,26 +169,22 @@ Session::import_audiofile (import_status& status)
        
        for (vector<Glib::ustring>::iterator p = status.paths.begin(); p != status.paths.end(); ++p, ++cnt) {
 
-               boost::shared_ptr<SNDFILE> in (sf_open (p->c_str(), SFM_READ, &info), sf_close);
+               std::auto_ptr<ImportableSource> source;
 
-               if (!in) {
+               try
+               {
+                       source = open_importable_source (*p, frame_rate(), status.quality);
+               }
+               catch (const failed_constructor& err)
+               {
                        error << string_compose(_("Import: cannot open input sound file \"%1\""), (*p)) << endmsg;
-                       status.done = 1;
-                       status.cancel = 1;
+                       status.done = status.cancel = true;
                        return -1;
                }
-       
-               std::auto_ptr<ImportableSource> importable;
-
-               if ((nframes_t) info.samplerate != frame_rate()) {
-                       importable.reset(new ResampledImportableSource (in.get(), &info, frame_rate(), status.quality));
-               } else {
-                       importable.reset(new ImportableSource (in.get(), &info));
-               }
 
                vector<boost::shared_ptr<AudioFileSource> > newfiles;
 
-               for (int n = 0; n < info.channels; ++n) {
+               for (uint n = 0; n < source->channels(); ++n) {
                        newfiles.push_back (boost::shared_ptr<AudioFileSource>());
                }
 
@@ -182,9 +192,9 @@ Session::import_audiofile (import_status& status)
 
                basepath = PBD::basename_nosuffix ((*p));
                
-               for (int n = 0; n < info.channels; ++n) {
+               for (uint n = 0; n < source->channels(); ++n) {
 
-                       std::string filename = get_non_existent_filename (basepath, n, info.channels); 
+                       std::string filename = get_non_existent_filename (basepath, n, source->channels()); 
 
                        sys::path filepath = sdir.sound_path() / filename;
 
@@ -201,10 +211,10 @@ Session::import_audiofile (import_status& status)
                        newfiles[n]->prepare_for_peakfile_writes ();
                }
 
-               if ((nframes_t) info.samplerate != frame_rate()) {
+               if ((nframes_t) source->samplerate() != frame_rate()) {
                        status.doing_what = string_compose (_("converting %1\n(resample from %2KHz to %3KHz)\n(%4 of %5)"),
                                                            basepath,
-                                                           info.samplerate/1000.0f,
+                                                           source->samplerate()/1000.0f,
                                                            frame_rate()/1000.0f,
                                                            cnt, status.paths.size());
                                                            
@@ -215,13 +225,13 @@ Session::import_audiofile (import_status& status)
 
                }
 
-               write_audio_data_to_new_files (importable.get(), status, newfiles);
+               write_audio_data_to_new_files (source.get(), status, newfiles);
 
                if (status.cancel) {
                        goto out;
                }
                
-               for (int n = 0; n < info.channels; ++n) {
+               for (uint n = 0; n < source->channels(); ++n) {
                        status.sources.push_back (newfiles[n]);
                }
 
index 38aa3832b93d352fa22363200eb349a62ff7281a..8330196d8abd24988353f427cef9c4149f84c730 100644 (file)
@@ -28,12 +28,13 @@ using namespace PBD;
 
 const uint32_t ResampledImportableSource::blocksize = 4096U;
 
-ResampledImportableSource::ResampledImportableSource (SNDFILE* sf, SF_INFO* info, nframes_t rate, SrcQuality srcq)
-       : ImportableSource (sf, info) 
+ResampledImportableSource::ResampledImportableSource (const std::string& path,
+               nframes_t rate, SrcQuality srcq)
+       : ImportableSource (path) 
 {
        int err;
        
-       sf_seek (in, 0, SEEK_SET) ;
+       sf_seek (in.get(), 0, SEEK_SET) ;
        
        /* Initialize the sample rate converter. */
        
@@ -57,7 +58,7 @@ ResampledImportableSource::ResampledImportableSource (SNDFILE* sf, SF_INFO* info
                break;
        }
        
-       if ((src_state = src_new (src_type, sf_info->channels, &err)) == 0) {   
+       if ((src_state = src_new (src_type, sf_info.channels, &err)) == 0) {    
                error << string_compose(_("Import: src_new() failed : %1"), src_strerror (err)) << endmsg ;
                throw failed_constructor ();
        }
@@ -69,7 +70,7 @@ ResampledImportableSource::ResampledImportableSource (SNDFILE* sf, SF_INFO* info
        src_data.input_frames = 0 ;
        src_data.data_in = input ;
        
-       src_data.src_ratio = ((float) rate) / sf_info->samplerate ;
+       src_data.src_ratio = ((float) rate) / sf_info.samplerate ;
        
        input = new float[blocksize];
 }
@@ -97,14 +98,14 @@ ResampledImportableSource::read (Sample* output, nframes_t nframes)
                        src_data.end_of_input = SF_TRUE ;
                }               
 
-               src_data.input_frames /= sf_info->channels;
+               src_data.input_frames /= sf_info.channels;
                src_data.data_in = input ;
        } 
        
        src_data.data_out = output;
 
        if (!src_data.end_of_input) {
-               src_data.output_frames = nframes / sf_info->channels ;
+               src_data.output_frames = nframes / sf_info.channels ;
        } else {
                src_data.output_frames = src_data.input_frames;
        }
@@ -120,9 +121,9 @@ ResampledImportableSource::read (Sample* output, nframes_t nframes)
                return 0;
        }
        
-       src_data.data_in += src_data.input_frames_used * sf_info->channels ;
+       src_data.data_in += src_data.input_frames_used * sf_info.channels ;
        src_data.input_frames -= src_data.input_frames_used ;
 
-       return src_data.output_frames_gen * sf_info->channels;
+       return src_data.output_frames_gen * sf_info.channels;
 }