From 27b022bdebcf324373c01f6aa4dc666630a2d5bf Mon Sep 17 00:00:00 2001 From: Tim Mayberry Date: Thu, 15 Nov 2007 02:31:58 +0000 Subject: Pass a path argument to ImportableSource rather than SNDFILE handle so resource management is contained git-svn-id: svn://localhost/ardour2/trunk@2667 d708f5d6-7413-0410-9779-e7cbd77b26cf --- libs/ardour/ardour/importable_source.h | 25 +++++++++++------ libs/ardour/ardour/resampled_source.h | 4 ++- libs/ardour/import.cc | 50 ++++++++++++++++++++-------------- libs/ardour/resampled_source.cc | 19 +++++++------ 4 files changed, 60 insertions(+), 38 deletions(-) (limited to 'libs') diff --git a/libs/ardour/ardour/importable_source.h b/libs/ardour/ardour/importable_source.h index 4f08498fce..5845d841b6 100644 --- a/libs/ardour/ardour/importable_source.h +++ b/libs/ardour/ardour/importable_source.h @@ -21,30 +21,39 @@ #define __ardour_importable_source_h__ #include +#include #include 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 in; }; } diff --git a/libs/ardour/ardour/resampled_source.h b/libs/ardour/ardour/resampled_source.h index 9a88ca9644..8ca56b52d3 100644 --- a/libs/ardour/ardour/resampled_source.h +++ b/libs/ardour/ardour/resampled_source.h @@ -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); diff --git a/libs/ardour/import.cc b/libs/ardour/import.cc index a116a9ce91..b034824740 100644 --- a/libs/ardour/import.cc +++ b/libs/ardour/import.cc @@ -53,6 +53,21 @@ using namespace ARDOUR; using namespace PBD; +std::auto_ptr +open_importable_source (const string& path, nframes_t samplerate, + ARDOUR::SrcQuality quality) +{ + std::auto_ptr source(new ImportableSource(path)); + + if (source->samplerate() == samplerate) { + return source; + } + + return std::auto_ptr( + 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 new_paths; @@ -155,26 +169,22 @@ Session::import_audiofile (import_status& status) for (vector::iterator p = status.paths.begin(); p != status.paths.end(); ++p, ++cnt) { - boost::shared_ptr in (sf_open (p->c_str(), SFM_READ, &info), sf_close); + std::auto_ptr 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 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 > newfiles; - for (int n = 0; n < info.channels; ++n) { + for (uint n = 0; n < source->channels(); ++n) { newfiles.push_back (boost::shared_ptr()); } @@ -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]); } diff --git a/libs/ardour/resampled_source.cc b/libs/ardour/resampled_source.cc index 38aa3832b9..8330196d8a 100644 --- a/libs/ardour/resampled_source.cc +++ b/libs/ardour/resampled_source.cc @@ -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; } -- cgit v1.2.3