summaryrefslogtreecommitdiff
path: root/src/loris/Resampler.h
diff options
context:
space:
mode:
authorJohn Glover <glover.john@gmail.com>2011-07-08 18:06:21 +0100
committerJohn Glover <glover.john@gmail.com>2011-07-08 18:06:21 +0100
commitd6073e01c933c77f1e2bc3c3fe1126d617003549 (patch)
tree695d23677c5b84bf3a0f88fbd4959b4f7cbc0e90 /src/loris/Resampler.h
parent641688b252da468eb374674a0dbaae1bbac70b2b (diff)
downloadsimpl-d6073e01c933c77f1e2bc3c3fe1126d617003549.tar.gz
simpl-d6073e01c933c77f1e2bc3c3fe1126d617003549.tar.bz2
simpl-d6073e01c933c77f1e2bc3c3fe1126d617003549.zip
Start adding Loris files
Diffstat (limited to 'src/loris/Resampler.h')
-rw-r--r--src/loris/Resampler.h449
1 files changed, 449 insertions, 0 deletions
diff --git a/src/loris/Resampler.h b/src/loris/Resampler.h
new file mode 100644
index 0000000..bc45eb3
--- /dev/null
+++ b/src/loris/Resampler.h
@@ -0,0 +1,449 @@
+#ifndef INCLUDE_RESAMPLER_H
+#define INCLUDE_RESAMPLER_H
+/*
+ * This is the Loris C++ Class Library, implementing analysis,
+ * manipulation, and synthesis of digitized sounds using the Reassigned
+ * Bandwidth-Enhanced Additive Sound Model.
+ *
+ * Loris is Copyright (c) 1999-2010 by Kelly Fitz and Lippold Haken
+ *
+ * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ *
+ * Resampler.h
+ *
+ * Definition of class Resampler, for converting reassigned Partial envelopes
+ * into more conventional additive synthesis envelopes, having data points
+ * at regular time intervals. The benefits of reassigned analysis are NOT
+ * lost in this process, since the elimination of unreliable data and the
+ * reduction of temporal smearing are reflected in the resampled data.
+ *
+ * Lippold, 7 Aug 2003
+ * loris@cerlsoundgroup.org
+ *
+ * http://www.cerlsoundgroup.org/Loris/
+ *
+ */
+
+#include "PartialList.h"
+#include "LinearEnvelope.h"
+
+// begin namespace
+namespace Loris {
+
+class Partial;
+
+// ---------------------------------------------------------------------------
+// class Resampler
+//
+//! Class Resampler represents an algorithm for resampling Partial envelopes
+//! at regular time intervals. Resampling makes the envelope data more suitable
+//! for exchange (as SDIF data, for example) with other applications that
+//! cannot process raw (continuously-distributed) reassigned data. Resampling
+//! will often greatly reduce the size of the data (by greatly reducing the
+//! number of Breakpoints in the Partials) without adversely affecting the
+//! quality of the reconstruction.
+//
+class Resampler
+{
+// --- public interface ---
+public:
+// --- lifecycle ---
+
+ //! Initialize a Resampler having the specified uniform sampling
+ //! interval. Enable phase-correct resampling, in which frequencies
+ //! of resampled Partials are modified (using fixFrequency) such
+ //! that the resampled phases are achieved in synthesis. Phase-
+ //! correct resampling can be disabled using setPhaseCorrect.
+ //!
+ //! Resampled Partials will be composed of Breakpoints at every
+ //! integer multiple of the resampling interval.
+ //!
+ //! \sa setPhaseCorrect
+ //! \sa fixFrequency
+ //!
+ //! \param sampleInterval is the resampling interval in seconds,
+ //! Breakpoint data is computed at integer multiples of
+ //! sampleInterval seconds.
+ //!
+ //! \throw InvalidArgument if sampleInterval is not positive.
+ explicit Resampler( double sampleInterval );
+
+
+ // --- use compiler-generated copy/assign/destroy ---
+
+// --- parameters ---
+
+ //! Specify phase-corrected resampling, or not. If phase
+ //! correct, Partial frequencies are altered slightly
+ //! to match, as nearly as possible, the Breakpoint
+ //! phases after resampling. Phases are updated so that
+ //! the Partial frequencies and phases are consistent after
+ //! resampling.
+ //!
+ //! \param correctPhase is a boolean flag specifying that
+ //! (if true) frequency/phase correction should be
+ //! applied after resampling.
+ void setPhaseCorrect( bool correctPhase );
+
+// --- resampling ---
+
+ //! Resample the specified Partial using the stored quanitization interval.
+ //! The Breakpoint times will comprise a contiguous sequence of all integer
+ //! multiples of the sampling interval, starting and ending with the nearest
+ //! multiples to the ends of the Partial. If phase correct resampling is
+ //! specified (the default)≤ frequencies and phases are corrected to be in
+ //! agreement and to match as nearly as possible the resampled phases.
+ //!
+ //! Resampling is performed in-place.
+ //!
+ //! \param p is the Partial to resample
+ void resample( Partial & p ) const;
+
+ //! Function call operator: same as resample( p ).
+ void operator() ( Partial & p ) const
+ {
+ resample( p );
+ }
+
+ //! Resample the specified Partial using the stored quanitization interval.
+ //! The Breakpoint times will comprise a contiguous sequence of all integer
+ //! multiples of the sampling interval, starting and ending with the nearest
+ //! multiples to the ends of the Partial. If phase correct resampling is
+ //! specified (the default)≤ frequencies and phases are corrected to be in
+ //! agreement and to match as nearly as possible the resampled phases.
+ //!
+ //! The timing envelope represents a warping of the time axis that is
+ //! applied during resampling. The Breakpoint times in resampled Partials
+ //! will a comprise contiguous sequence of all integer multiples of the
+ //! sampling interval between the first and last breakpoints in the timing
+ //! envelope, and each Breakpoint will represent the parameters of the
+ //! original Partial at the time that is the value of the timing envelope
+ //! at that instant.
+ //!
+ //! Resampling is performed in-place.
+ //!
+ //! \param p is the Partial to resample
+ //!
+ //! \param timingEnv is the timing envelope, a map of Breakpoint
+ //! times in resampled Partials onto parameter sampling
+ //! instants in the original Partials.
+ //!
+ //! \throw InvalidArgument if timingEnv has any negative breakpoint
+ //! times or values.
+ void resample( Partial & p, const LinearEnvelope & timingEnv ) const;
+
+ //! Quantize the Breakpoint times using the specified Partial using the
+ //! stored quanitization interval. Each Breakpoint in the Partial is
+ //! replaced by a Breakpoint constructed by resampling the Partial at
+ //! the nearest integer multiple of the of the resampling interval.
+ //!
+ //! Quantization is performed in-place.
+ //!
+ //! \param p is the Partial to resample
+ void quantize( Partial & p ) const;
+
+
+ //! Resample all Partials in the specified (half-open) range using this
+ //! Resampler's stored quanitization interval. The Breakpoint times in
+ //! resampled Partials will comprise a contiguous sequence of all integer
+ //! multiples of the sampling interval, starting and ending with the nearest
+ //! multiples to the ends of the Partial. If phase correct resampling is
+ //! specified (the default)≤ frequencies and phases are corrected to be in
+ //! agreement and to match as nearly as possible the resampled phases.
+ //!
+ //! Resampling is performed in-place.
+ //!
+ //! \param begin is the beginning of the range of Partials to resample
+ //! \param end is (one-past) the end of the range of Partials to resample
+ //!
+ //! If compiled with NO_TEMPLATE_MEMBERS defined, then begin and end
+ //! must be PartialList::iterators, otherwise they can be any type
+ //! of iterators over a sequence of Partials.
+#if ! defined(NO_TEMPLATE_MEMBERS)
+ template<typename Iter>
+ void resample( Iter begin, Iter end ) const;
+#else
+ inline
+ void resample( PartialList::iterator begin, PartialList::iterator end ) const;
+#endif
+
+ //! Function call operator: same as resample( begin, end ).
+#if ! defined(NO_TEMPLATE_MEMBERS)
+ template<typename Iter>
+ void operator()( Iter begin, Iter end ) const
+#else
+ void operator()( PartialList::iterator begin, PartialList::iterator end ) const
+#endif
+ {
+ resample( begin, end );
+ }
+
+ //! Resample all Partials in the specified (half-open) range using this
+ //! Resampler's stored quanitization interval. The Breakpoint times in
+ //! resampled Partials will comprise a contiguous sequence of all integer
+ //! multiples of the sampling interval, starting and ending with the nearest
+ //! multiples to the ends of the Partial. If phase correct resampling is
+ //! specified (the default)≤ frequencies and phases are corrected to be in
+ //! agreement and to match as nearly as possible the resampled phases.
+ //!
+ //! The timing envelope represents a warping of the time axis that is
+ //! applied during resampling. The Breakpoint times in resampled Partials
+ //! will a comprise contiguous sequence of all integer multiples of the
+ //! sampling interval between the first and last breakpoints in the timing
+ //! envelope, and each Breakpoint will represent the parameters of the
+ //! original Partial at the time that is the value of the timing envelope
+ //! at that instant.
+ //!
+ //! Resampling is performed in-place.
+ //!
+ //! \param begin is the beginning of the range of Partials to resample
+ //! \param end is (one-past) the end of the range of Partials to resample
+ //! \param timingEnv is the timing envelope, a map of Breakpoint
+ //! times in resampled Partials onto parameter sampling
+ //! instants in the original Partials.
+ //!
+ //! If compiled with NO_TEMPLATE_MEMBERS defined, then begin and end
+ //! must be PartialList::iterators, otherwise they can be any type
+ //! of iterators over a sequence of Partials.
+#if ! defined(NO_TEMPLATE_MEMBERS)
+ template<typename Iter>
+ void resample( Iter begin, Iter end, const LinearEnvelope & timingEnv ) const;
+#else
+ inline
+ void resample( PartialList::iterator begin, PartialList::iterator end,
+ const LinearEnvelope & timingEnv) const;
+#endif
+
+ //! Quantize all Partials in the specified (half-open) range.
+ //! Each Breakpoint in the Partials is replaced by a Breakpoint
+ //! constructed by resampling the Partial at the nearest
+ //! integer multiple of the of the resampling interval.
+ //!
+ //! \param begin is the beginning of the range of Partials to quantize
+ //! \param end is (one-past) the end of the range of Partials to quantize
+ //!
+ //! If compiled with NO_TEMPLATE_MEMBERS defined, then begin and end
+ //! must be PartialList::iterators, otherwise they can be any type
+ //! of iterators over a sequence of Partials.
+#if ! defined(NO_TEMPLATE_MEMBERS)
+ template<typename Iter>
+ void quantize( Iter begin, Iter end ) const;
+#else
+ inline
+ void quantize( PartialList::iterator begin, PartialList::iterator end ) const;
+#endif
+
+// -- static members --
+
+ //! Static member that constructs an instance and applies
+ //! it to a sequence of Partials.
+ //! Construct a Resampler using the specified resampling
+ //! interval, and use it to channelize a sequence of Partials.
+ //!
+ //! \param begin is the beginning of a sequence of Partials to
+ //! resample.
+ //! \param end is the end of a sequence of Partials to
+ //! resample.
+ //! \param sampleInterval is the resampling interval in seconds,
+ //! Breakpoint data is computed at integer multiples of
+ //! sampleInterval seconds.
+ //! \param denseResampling is a boolean flag indicating that dense
+ //! resamping (Breakpoint at every integer multiple of the
+ //! resampling interval) should be performed. If false (the
+ //! default), sparse resampling (Breakpoints only at multiples
+ //! of the resampling interval near Breakpoint times in the
+ //! original Partial) is performed.
+ //! \throw InvalidArgument if sampleInterval is not positive.
+ //!
+ //! If compiled with NO_TEMPLATE_MEMBERS defined, then begin and end
+ //! must be PartialList::iterators, otherwise they can be any type
+ //! of iterators over a sequence of Partials.
+#if ! defined(NO_TEMPLATE_MEMBERS)
+ template< typename Iter >
+ static
+ void resample( Iter begin, Iter end, double sampleInterval,
+ bool denseResampling = false );
+#else
+ static inline
+ void resample( PartialList::iterator begin, PartialList::iterator end,
+ double sampleInterval, bool denseResampling = false );
+#endif
+
+// --- instance variables ---
+private:
+
+ //! the resampling interval in seconds
+ double interval_;
+
+ //! boolean flag selecting phase-corrected resampling
+ //! (default is true)
+ bool phaseCorrect_;
+
+}; // end of class Resampler
+
+// ---------------------------------------------------------------------------
+// resample (sequence of Partials)
+// ---------------------------------------------------------------------------
+//! Resample all Partials in the specified (half-open) range using this
+//! Resampler's stored sampling interval, so that the Breakpoints in
+//! the Partial envelopes will all lie on a common temporal grid.
+//! The Breakpoint times in the resampled Partial will comprise a
+//! contiguous sequence of integer multiples of the sampling interval,
+//! beginning with the multiple nearest to the Partial's start time and
+//! ending with the multiple nearest to the Partial's end time. Resampling
+//! is performed in-place.
+//!
+//! \param begin is the beginning of the range of Partials to resample
+//! \param end is (one-past) the end of the range of Partials to resample
+//!
+//! If compiled with NO_TEMPLATE_MEMBERS defined, then begin and end
+//! must be PartialList::iterators, otherwise they can be any type
+//! of iterators over a sequence of Partials.
+//
+#if ! defined(NO_TEMPLATE_MEMBERS)
+template<typename Iter>
+void Resampler::resample( Iter begin, Iter end ) const
+#else
+inline
+void Resampler::resample( PartialList::iterator begin, PartialList::iterator end ) const
+#endif
+{
+ while ( begin != end )
+ {
+ resample( *begin++ );
+ }
+}
+
+// ---------------------------------------------------------------------------
+// resample (sequence of Partials, with timing envelope)
+// ---------------------------------------------------------------------------
+//! Resample all Partials in the specified (half-open) range using this
+//! Resampler's stored sampling interval, so that the Breakpoints in
+//! the Partial envelopes will all lie on a common temporal grid.
+//! The Breakpoint times in the resampled Partial will comprise a
+//! contiguous sequence of integer multiples of the sampling interval,
+//! beginning with the multiple nearest to the Partial's start time and
+//! ending with the multiple nearest to the Partial's end time. Resampling
+//! is performed in-place.
+//!
+//! \param begin is the beginning of the range of Partials to resample
+//! \param end is (one-past) the end of the range of Partials to resample
+//! \param timingEnv is the timing envelope, a map of Breakpoint
+//! times in resampled Partials onto parameter sampling
+//! instants in the original Partials.
+//!
+//! If compiled with NO_TEMPLATE_MEMBERS defined, then begin and end
+//! must be PartialList::iterators, otherwise they can be any type
+//! of iterators over a sequence of Partials.
+//
+#if ! defined(NO_TEMPLATE_MEMBERS)
+template<typename Iter>
+void Resampler::resample( Iter begin, Iter end, const LinearEnvelope & timingEnv ) const
+#else
+inline
+void Resampler::resample( PartialList::iterator begin, PartialList::iterator end,
+ const LinearEnvelope & timingEnv ) const
+#endif
+{
+ while ( begin != end )
+ {
+ resample( *begin++, timingEnv );
+ }
+}
+
+// ---------------------------------------------------------------------------
+// quantize (sequence of Partials)
+// ---------------------------------------------------------------------------
+//! Quantize all Partials in the specified (half-open) range.
+//! Each Breakpoint in the Partials is replaced by a Breakpoint
+//! constructed by resampling the Partial at the nearest
+//! integer multiple of the of the resampling interval.
+//!
+//! \param begin is the beginning of the range of Partials to quantize
+//! \param end is (one-past) the end of the range of Partials to quantize
+//!
+//! If compiled with NO_TEMPLATE_MEMBERS defined, then begin and end
+//! must be PartialList::iterators, otherwise they can be any type
+//! of iterators over a sequence of Partials.
+//
+#if ! defined(NO_TEMPLATE_MEMBERS)
+template<typename Iter>
+void Resampler::quantize( Iter begin, Iter end ) const
+#else
+inline
+void Resampler::quantize( PartialList::iterator begin, PartialList::iterator end ) const
+#endif
+{
+ while ( begin != end )
+ {
+ quantize( *begin++ );
+ }
+}
+
+
+// ---------------------------------------------------------------------------
+// resample (static)
+// ---------------------------------------------------------------------------
+//! Static member that constructs an instance and applies
+//! phase-correct resampling to a sequence of Partials.
+//! Construct a Resampler using the specified resampling
+//! interval, and use it to channelize a sequence of Partials.
+//!
+//! \param begin is the beginning of a sequence of Partials to
+//! resample.
+//! \param end is the end of a sequence of Partials to
+//! resample.
+//! \param sampleInterval is the resampling interval in seconds,
+//! Breakpoint data is computed at integer multiples of
+//! sampleInterval seconds.
+//! \param denseResampling is a boolean flag indicating that dense
+//! resamping (Breakpoint at every integer multiple of the
+//! resampling interval) should be performed. If false (the
+//! default), sparse resampling (Breakpoints only at multiples
+//! of the resampling interval near Breakpoint times in the
+//! original Partial) is performed.
+//! \throw InvalidArgument if sampleInterval is not positive.
+//!
+//! If compiled with NO_TEMPLATE_MEMBERS defined, then begin and end
+//! must be PartialList::iterators, otherwise they can be any type
+//! of iterators over a sequence of Partials.
+//
+#if ! defined(NO_TEMPLATE_MEMBERS)
+template< typename Iter >
+void Resampler::resample( Iter begin, Iter end, double sampleInterval,
+ bool denseResampling )
+#else
+inline
+void Resampler::resample( PartialList::iterator begin, PartialList::iterator end,
+ double sampleInterval, bool denseResampling )
+#endif
+{
+ Resampler instance( sampleInterval );
+
+ if ( denseResampling )
+ {
+ instance.resample( begin, end );
+ }
+ else
+ {
+ instance.quantize( begin, end );
+ }
+}
+
+} // end of namespace Loris
+
+#endif /* ndef INCLUDE_RESAMPLER_H */
+