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
This commit is contained in:
@@ -21,30 +21,39 @@
|
||||
#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;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -53,6 +53,21 @@
|
||||
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) {
|
||||
error << string_compose(_("Import: cannot open input sound file \"%1\""), (*p)) << endmsg;
|
||||
status.done = 1;
|
||||
status.cancel = 1;
|
||||
return -1;
|
||||
try
|
||||
{
|
||||
source = open_importable_source (*p, frame_rate(), status.quality);
|
||||
}
|
||||
|
||||
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));
|
||||
catch (const failed_constructor& err)
|
||||
{
|
||||
error << string_compose(_("Import: cannot open input sound file \"%1\""), (*p)) << endmsg;
|
||||
status.done = status.cancel = true;
|
||||
return -1;
|
||||
}
|
||||
|
||||
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]);
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user