diff options
Diffstat (limited to 'src/loris/Sieve.h')
-rw-r--r-- | src/loris/Sieve.h | 269 |
1 files changed, 269 insertions, 0 deletions
diff --git a/src/loris/Sieve.h b/src/loris/Sieve.h new file mode 100644 index 0000000..aff3f16 --- /dev/null +++ b/src/loris/Sieve.h @@ -0,0 +1,269 @@ +#ifndef INCLUDE_SIEVE_H +#define INCLUDE_SIEVE_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 + * + * + * Sieve.h + * + * Definition of class Sieve. + * + * Lippold Haken, 20 Jan 2001 + * loris@cerlsoundgroup.org + * + * http://www.cerlsoundgroup.org/Loris/ + * + */ + +#include "Distiller.h" // for default fade time and silent time + +#if defined(NO_TEMPLATE_MEMBERS) +#include "PartialList.h" +#endif + +#include "PartialPtrs.h" + +// begin namespace +namespace Loris { + +// --------------------------------------------------------------------------- +// class Sieve +// +//! A Sieve eliminating temporal overlap among Partials. +//! +//! Class Sieve represents an algorithm for identifying channelized (see also +//! Channelizer) Partials that overlap in time, and selecting the longer +//! one to represent the channel. The identification of overlap includes +//! the time needed for Partials to fade to and from zero amplitude in +//! synthesis (see also Synthesizer) or distillation. (see also Distiller) +//! +//! In some cases, the energy redistribution effected by the distiller +//! (see also Distiller) is undesirable. In such cases, the partials can be +//! sifted before distillation. The sifting process in Loris identifies +//! all the partials that would be rejected (and converted to noise +//! energy) by the distiller and assigns them a label of 0. These sifted +//! partials can then be identified and treated sepearately or removed +//! altogether, or they can be passed through the distiller unlabeled, and +//! crossfaded in the morphing process (see also Morpher). +//! +//! \sa Channelizer, Distiller, Morpher, Synthesizer +// +class Sieve +{ +// -- instance variables -- + + double _fadeTime; //! extra time (in seconds) added to each end of + //! a Partial when determining overlap, to accomodate + //! the fade to and from zero amplitude. + +// -- public interface -- +public: + +// -- global defaults and constants -- + + enum + { + + //! Default time in milliseconds over which Partials joined by + //! distillation fade to and from zero amplitude. Divide by + //! 1000 to use as a member function parameter. This parameter + //! should be the same in Distiller, Sieve, and Collator. + DefaultFadeTimeMs = Distiller::DefaultFadeTimeMs, + + //! Default minimum duration in milliseconds of the silent + //! (zero-amplitude) gap between two Partials joined by + //! distillation. Divide by 1000 to use as a member function + //! parameter. This parameter should be the same in Distiller, + //! Sieve, and Collator. + DefaultSilentTimeMs = Distiller::DefaultSilentTimeMs + }; + +// -- construction -- + + //! Construct a new Sieve using the specified partial fade + //! time. If unspecified, the default fade time (same as the + //! default fade time for the Distiller) is used. + //! + //! \param partialFadeTime is the extra time (in seconds) + //! added to each end of a Partial to accomodate + //! the fade to and from zero amplitude. Fade time + //! must be non-negative. A default value is used + //! if unspecified. + //! \throw InvalidArgument if partialFadeTime is negative. + explicit Sieve( double partialFadeTime = Sieve::DefaultFadeTimeMs/1000.0 ); + + // Use compiler-generated copy, assign, and destroy. + +// -- sifting -- + + //! Sift labeled Partials on the specified half-open (STL-style) + //! range. If any two Partials having same label overlap in time, keep + //! only the longer of the two Partials. Set the label of the shorter + //! duration partial to zero. No Partials are removed from the + //! sequence and the sequence order is unaltered. + //! + //! \param sift_begin is the beginning of the range of Partials to sift + //! \param sift_end is (one-past) the end of the range of Partials to sift + //! + //! If compiled with NO_TEMPLATE_MEMBERS defined, then sift_begin and + //! sift_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 sift( Iter sift_begin, Iter sift_end ); +#else + inline + void sift( PartialList::iterator sift_begin, PartialList::iterator sift_end ); +#endif + + //! Sift labeled Partials in the specified container + //! If any two Partials having same label overlap in time, keep + //! only the longer of the two Partials. Set the label of the shorter + //! duration partial to zero. No Partials are removed from the + //! container and the container order is unaltered. + //! + //! \param partials is the collection of Partials to sift in-place + //! + //! If compiled with NO_TEMPLATE_MEMBERS defined, then partials + //! must be a PartialList, otherwise it can be any container type + //! storing Partials that supports at least bidirectional iterators. +#if ! defined(NO_TEMPLATE_MEMBERS) + template< typename Container > + void sift( Container & partials ) +#else + inline + void sift( PartialList & partials ) +#endif + { + sift( partials.begin(), partials.end() ); + } + +// -- static members -- + + //! Static member that constructs an instance and applies + //! it to a sequence of Partials. + //! Construct a Sieve using the specified Partial + //! fade time (in seconds), and use it to sift a + //! sequence of Partials. + //! + //! \param sift_begin is the beginning of the range of Partials to sift + //! \param sift_end is (one-past) the end of the range of Partials to sift + //! \param partialFadeTime is the extra time (in seconds) + //! added to each end of a Partial to accomodate + //! the fade to and from zero amplitude. The Partial fade time + //! must be non-negative. + //! \throw InvalidArgument if partialFadeTime is negative. + //! + //! 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 sift( Iter sift_begin, Iter sift_end, + double partialFadeTime ); +#else + static inline + void sift( PartialList::iterator sift_begin, PartialList::iterator sift_end, + double partialFadeTime ); +#endif + +// -- helper -- +private: + + //! Sift labeled Partials. If any two Partials having the same (non-zero) + //! label overlap in time (where overlap includes the fade time at both + //! ends of each Partial), then set the label of the Partial having the + //! shorter duration to zero. Sifting is performed on a collection of + //! pointers to Partials so that the it can be performed without changing + //! the order of the Partials in the sequence. + //! + //! \param ptrs is a collection of pointers to the Partials in the + //! sequence to be sifted. + void sift_ptrs( PartialPtrs & ptrs ); + +}; // end of class Sieve + +// --------------------------------------------------------------------------- +// sift +// --------------------------------------------------------------------------- +//! Sift labeled Partials on the specified half-open (STL-style) +//! range. If any two Partials having same label overlap in time, keep +//! only the longer of the two Partials. Set the label of the shorter +//! duration partial to zero. No Partials are removed from the +//! sequence and the sequence order is unaltered. +//! +//! \param sift_begin is the beginning of the range of Partials to sift +//! \param sift_end is (one-past) the end of the range of Partials to sift +//! +//! If compiled with NO_TEMPLATE_MEMBERS defined, then sift_begin and +//! sift_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 Sieve::sift( Iter sift_begin, Iter sift_end ) +#else +inline +void Sieve::sift( PartialList::iterator sift_begin, PartialList::iterator sift_end ) +#endif +{ + PartialPtrs ptrs; + fillPartialPtrs( sift_begin, sift_end, ptrs ); + sift_ptrs( ptrs ); +} + +// --------------------------------------------------------------------------- +// sift (static) +// --------------------------------------------------------------------------- +//! Static member that constructs an instance and applies +//! it to a sequence of Partials. +//! Construct a Sieve using the specified Partial +//! fade time (in seconds), and use it to sift a +//! sequence of Partials. +//! +//! \param sift_begin is the beginning of the range of Partials to sift +//! \param sift_end is (one-past) the end of the range of Partials to sift +//! \param partialFadeTime is the extra time (in seconds) +//! added to each end of a Partial to accomodate +//! the fade to and from zero amplitude. The Partial fade time +//! must be non-negative. +//! \throw InvalidArgument if partialFadeTime is negative. +//! +//! 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 Sieve::sift( Iter sift_begin, Iter sift_end, + double partialFadeTime ) +#else +inline +void Sieve::sift( PartialList::iterator sift_begin, PartialList::iterator sift_end, + double partialFadeTime ) +#endif +{ + Sieve instance( partialFadeTime ); + instance.sift( sift_begin, sift_end ); +} + +} // end of namespace Loris + +#endif /* ndef INCLUDE_SIEVE_H */ |