summaryrefslogtreecommitdiff
path: root/libs/ardour
diff options
context:
space:
mode:
authorPaul Davis <paul@linuxaudiosystems.com>2008-02-27 02:09:03 +0000
committerPaul Davis <paul@linuxaudiosystems.com>2008-02-27 02:09:03 +0000
commitf31e8c3935fa6eed48d805021935cef38622b7ca (patch)
tree0954c96ab73c92c068bc39581eb432e5be4af9bc /libs/ardour
parent295b2da733f3080c2a96219bb169829ef4a2c0ce (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/SConscript1
-rw-r--r--libs/ardour/ardour/importable_source.h30
-rw-r--r--libs/ardour/ardour/resampled_source.h9
-rw-r--r--libs/ardour/ardour/sndfileimportable.h50
-rw-r--r--libs/ardour/import.cc57
-rw-r--r--libs/ardour/resampled_source.cc25
-rw-r--r--libs/ardour/sndfileimportable.cc47
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);
+}