diff options
author | Paul Davis <paul@linuxaudiosystems.com> | 2008-02-27 02:09:03 +0000 |
---|---|---|
committer | Paul Davis <paul@linuxaudiosystems.com> | 2008-02-27 02:09:03 +0000 |
commit | f31e8c3935fa6eed48d805021935cef38622b7ca (patch) | |
tree | 0954c96ab73c92c068bc39581eb432e5be4af9bc /libs/ardour | |
parent | 295b2da733f3080c2a96219bb169829ef4a2c0ce (diff) |
rearrange icons/presets on xfade editor to be symmetric; refactor importable source/resampled importable source to allow for both sndfile and coreaudio handled file i/o
git-svn-id: svn://localhost/ardour2/branches/2.0-ongoing@3124 d708f5d6-7413-0410-9779-e7cbd77b26cf
Diffstat (limited to 'libs/ardour')
-rw-r--r-- | libs/ardour/SConscript | 1 | ||||
-rw-r--r-- | libs/ardour/ardour/importable_source.h | 30 | ||||
-rw-r--r-- | libs/ardour/ardour/resampled_source.h | 9 | ||||
-rw-r--r-- | libs/ardour/ardour/sndfileimportable.h | 50 | ||||
-rw-r--r-- | libs/ardour/import.cc | 57 | ||||
-rw-r--r-- | libs/ardour/resampled_source.cc | 25 | ||||
-rw-r--r-- | libs/ardour/sndfileimportable.cc | 47 |
7 files changed, 171 insertions, 48 deletions
diff --git a/libs/ardour/SConscript b/libs/ardour/SConscript index ed2da88de7..a2e4c13db0 100644 --- a/libs/ardour/SConscript +++ b/libs/ardour/SConscript @@ -95,6 +95,7 @@ session_transport.cc silentfilesource.cc sndfile_helpers.cc sndfilesource.cc +sndfileimportable.cc source.cc source_factory.cc tempo.cc diff --git a/libs/ardour/ardour/importable_source.h b/libs/ardour/ardour/importable_source.h index 5845d841b6..a33cf567e7 100644 --- a/libs/ardour/ardour/importable_source.h +++ b/libs/ardour/ardour/importable_source.h @@ -20,7 +20,6 @@ #ifndef __ardour_importable_source_h__ #define __ardour_importable_source_h__ -#include <sndfile.h> #include <pbd/failed_constructor.h> #include <ardour/types.h> @@ -28,32 +27,15 @@ namespace ARDOUR { class ImportableSource { public: - ImportableSource (const std::string& path) - : in (sf_open (path.c_str(), SFM_READ, &sf_info), sf_close) - { - if (!in) throw failed_constructor(); - - } - + ImportableSource () {} 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.get(), buffer, per_channel); - return per_channel * sf_info.channels; - } - + virtual nframes_t read (Sample* buffer, nframes_t nframes) = 0; virtual float ratio() const { return 1.0f; } - - uint channels() const { return sf_info.channels; } - - nframes_t length() const { return sf_info.frames; } - - nframes_t samplerate() const { return sf_info.samplerate; } - -protected: - SF_INFO sf_info; - boost::shared_ptr<SNDFILE> in; + virtual uint32_t channels() const = 0; + virtual nframes_t length() const = 0; + virtual nframes_t samplerate() const = 0; + virtual void seek (nframes_t pos) = 0; }; } diff --git a/libs/ardour/ardour/resampled_source.h b/libs/ardour/ardour/resampled_source.h index 8ca56b52d3..6eca4cda98 100644 --- a/libs/ardour/ardour/resampled_source.h +++ b/libs/ardour/ardour/resampled_source.h @@ -30,18 +30,21 @@ namespace ARDOUR { class ResampledImportableSource : public ImportableSource { public: - ResampledImportableSource (const std::string& path, - nframes_t rate, SrcQuality); + ResampledImportableSource (boost::shared_ptr<ImportableSource>, nframes_t rate, SrcQuality); ~ResampledImportableSource (); nframes_t read (Sample* buffer, nframes_t nframes); - float ratio() const { return src_data.src_ratio; } + uint32_t channels() const { return source->channels(); } + nframes_t length() const { return source->length(); } + nframes_t samplerate() const { return source->samplerate(); } + void seek (nframes_t pos) { source->seek (pos); } static const uint32_t blocksize; private: + boost::shared_ptr<ImportableSource> source; float* input; SRC_STATE* src_state; SRC_DATA src_data; diff --git a/libs/ardour/ardour/sndfileimportable.h b/libs/ardour/ardour/sndfileimportable.h new file mode 100644 index 0000000000..5cd84f4f5f --- /dev/null +++ b/libs/ardour/ardour/sndfileimportable.h @@ -0,0 +1,50 @@ +/* + Copyright (C) 2007 Paul Davis + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + +*/ + +#ifndef __ardour_sndfile_importable_source_h__ +#define __ardour_sndfile_importable_source_h__ + +#include <boost/shared_ptr.hpp> +#include <sndfile.h> +#include <pbd/failed_constructor.h> +#include <ardour/types.h> +#include <ardour/importable_source.h> + +namespace ARDOUR { + +class SndFileImportableSource : public ImportableSource { + public: + SndFileImportableSource (const std::string& path); + virtual ~SndFileImportableSource(); + + nframes_t read (Sample* buffer, nframes_t nframes); + uint32_t channels() const; + nframes_t length() const; + nframes_t samplerate() const; + void seek (nframes_t pos); + + protected: + SF_INFO sf_info; + boost::shared_ptr<SNDFILE> in; + +}; + +} + +#endif /* __ardour_sndfile_importable_source_h__ */ diff --git a/libs/ardour/import.cc b/libs/ardour/import.cc index edf8f03373..c71d162dd3 100644 --- a/libs/ardour/import.cc +++ b/libs/ardour/import.cc @@ -46,23 +46,63 @@ #include <ardour/region_factory.h> #include <ardour/source_factory.h> #include <ardour/resampled_source.h> +#include <ardour/sndfileimportable.h> #include <ardour/analyser.h> +#ifdef HAVE_COREAUDIO +#include <ardour/caimportable.h> +#endif + #include "i18n.h" using namespace ARDOUR; using namespace PBD; -static std::auto_ptr<ImportableSource> + +static boost::shared_ptr<ImportableSource> open_importable_source (const string& path, nframes_t samplerate, ARDOUR::SrcQuality quality) { - std::auto_ptr<ImportableSource> source(new ImportableSource(path)); +#ifdef HAVE_COREAUDIO - if (source->samplerate() == samplerate) { - return source; - } + /* see if we can use CoreAudio to handle the IO */ - return std::auto_ptr<ImportableSource>(new ResampledImportableSource(path, samplerate, quality)); + try { + boost::shared_ptr<CAImportableSource> source(new CAImportableSource(path)); + + if (source->samplerate() == samplerate) { + return source; + } + + /* rewrap as a resampled source */ + + return boost::shared_ptr<ImportableSource>(new ResampledImportableSource(source, samplerate, quality)); + } + + catch (...) { + + /* fall back to SndFile */ + +#endif + + try { + boost::shared_ptr<SndFileImportableSource> source(new SndFileImportableSource(path)); + + if (source->samplerate() == samplerate) { + return source; + } + + /* rewrap as a resampled source */ + + return boost::shared_ptr<ImportableSource>(new ResampledImportableSource(source, samplerate, quality)); + } + + catch (...) { + throw; // rethrow + } + +#ifdef HAVE_COREAUDIO + } +#endif } static std::string @@ -266,12 +306,13 @@ Session::import_audiofiles (import_status& status) p != status.paths.end() && !status.cancel; ++p, ++cnt) { - std::auto_ptr<ImportableSource> source; - + boost::shared_ptr<ImportableSource> source; + 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; diff --git a/libs/ardour/resampled_source.cc b/libs/ardour/resampled_source.cc index 8330196d8a..cdfdee2604 100644 --- a/libs/ardour/resampled_source.cc +++ b/libs/ardour/resampled_source.cc @@ -28,13 +28,12 @@ using namespace PBD; const uint32_t ResampledImportableSource::blocksize = 4096U; -ResampledImportableSource::ResampledImportableSource (const std::string& path, - nframes_t rate, SrcQuality srcq) - : ImportableSource (path) +ResampledImportableSource::ResampledImportableSource (boost::shared_ptr<ImportableSource> src, nframes_t rate, SrcQuality srcq) + : source (src) { int err; - sf_seek (in.get(), 0, SEEK_SET) ; + source->seek (0); /* Initialize the sample rate converter. */ @@ -58,7 +57,7 @@ ResampledImportableSource::ResampledImportableSource (const std::string& path, break; } - if ((src_state = src_new (src_type, sf_info.channels, &err)) == 0) { + if ((src_state = src_new (src_type, source->channels(), &err)) == 0) { error << string_compose(_("Import: src_new() failed : %1"), src_strerror (err)) << endmsg ; throw failed_constructor (); } @@ -70,7 +69,7 @@ ResampledImportableSource::ResampledImportableSource (const std::string& path, 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) / source->samplerate(); input = new float[blocksize]; } @@ -90,22 +89,22 @@ ResampledImportableSource::read (Sample* output, nframes_t nframes) if (src_data.input_frames == 0) { - src_data.input_frames = ImportableSource::read (input, blocksize); + src_data.input_frames = source->read (input, blocksize); /* The last read will not be a full buffer, so set end_of_input. */ if ((nframes_t) src_data.input_frames < blocksize) { - src_data.end_of_input = SF_TRUE ; + src_data.end_of_input = true; } - src_data.input_frames /= sf_info.channels; - src_data.data_in = input ; + src_data.input_frames /= source->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 / source->channels(); } else { src_data.output_frames = src_data.input_frames; } @@ -121,9 +120,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 * source->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 * source->channels(); } diff --git a/libs/ardour/sndfileimportable.cc b/libs/ardour/sndfileimportable.cc new file mode 100644 index 0000000000..eb0e8a8afb --- /dev/null +++ b/libs/ardour/sndfileimportable.cc @@ -0,0 +1,47 @@ +#include <ardour/sndfileimportable.h> +#include <sndfile.h> + +using namespace ARDOUR; +using namespace std; + +SndFileImportableSource::SndFileImportableSource (const string& path) + : in (sf_open (path.c_str(), SFM_READ, &sf_info), sf_close) +{ + if (!in) throw failed_constructor(); +} + +SndFileImportableSource::~SndFileImportableSource () +{ +} + +nframes_t +SndFileImportableSource::read (Sample* buffer, nframes_t nframes) +{ + nframes_t per_channel = nframes / sf_info.channels; + per_channel = sf_readf_float (in.get(), buffer, per_channel); + return per_channel * sf_info.channels; +} + +uint +SndFileImportableSource::channels () const +{ + return sf_info.channels; +} + +nframes_t +SndFileImportableSource::length () const +{ + return sf_info.frames; +} + +nframes_t +SndFileImportableSource::samplerate() const +{ + return sf_info.samplerate; +} + +void +SndFileImportableSource::seek (nframes_t pos) +{ + sf_seek (in.get(), 0, SEEK_SET); +} |