summaryrefslogtreecommitdiff
path: root/src/loris/lorisUtilities_pi.C
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/lorisUtilities_pi.C
parent641688b252da468eb374674a0dbaae1bbac70b2b (diff)
downloadsimpl-d6073e01c933c77f1e2bc3c3fe1126d617003549.tar.gz
simpl-d6073e01c933c77f1e2bc3c3fe1126d617003549.tar.bz2
simpl-d6073e01c933c77f1e2bc3c3fe1126d617003549.zip
Start adding Loris files
Diffstat (limited to 'src/loris/lorisUtilities_pi.C')
-rw-r--r--src/loris/lorisUtilities_pi.C1075
1 files changed, 1075 insertions, 0 deletions
diff --git a/src/loris/lorisUtilities_pi.C b/src/loris/lorisUtilities_pi.C
new file mode 100644
index 0000000..0b401a4
--- /dev/null
+++ b/src/loris/lorisUtilities_pi.C
@@ -0,0 +1,1075 @@
+/*
+ * 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
+ *
+ *
+ * lorisUtilities_pi.C
+ *
+ * A component of the C-linkable procedural interface for Loris.
+ *
+ * Main components of the Loris procedural interface:
+ * - object interfaces - Analyzer, Synthesizer, Partial, PartialIterator,
+ * PartialList, PartialListIterator, Breakpoint, BreakpointEnvelope,
+ * and SampleVector need to be (opaque) objects in the interface,
+ * either because they hold state (e.g. Analyzer) or because they are
+ * fundamental data types (e.g. Partial), so they need a procedural
+ * interface to their member functions. All these things need to be
+ * opaque pointers for the benefit of C.
+ * - non-object-based procedures - other classes in Loris are not so stateful,
+ * and have sufficiently narrow functionality that they need only
+ * procedures, and no object representation.
+ * - utility functions - some procedures that are generally useful but are
+ * not yet part of the Loris core are also defined.
+ * - notification and exception handlers - all exceptions must be caught and
+ * handled internally, clients can specify an exception handler and
+ * a notification function (the default one in Loris uses printf()).
+ *
+ * This file defines the utility functions that are useful, and in many
+ * cases trivial in C++ (usign the STL for example) but are not represented
+ * by classes in the Loris core.
+ *
+ * Kelly Fitz, 10 Nov 2000
+ * loris@cerlsoundgroup.org
+ *
+ * http://www.cerlsoundgroup.org/Loris/
+ *
+ */
+#if HAVE_CONFIG_H
+ #include "config.h"
+#endif
+
+#include "loris.h"
+#include "lorisException_pi.h"
+
+#include "BreakpointEnvelope.h"
+#include "LorisExceptions.h"
+#include "Notifier.h"
+#include "Partial.h"
+#include "PartialUtils.h"
+
+#include <algorithm>
+#include <cmath>
+#include <functional>
+#include <iterator>
+#include <list>
+#include <memory>
+
+using namespace Loris;
+
+// ---------------------------------------------------------------------------
+// Functors to help apply C-callbacks to lists of Partials
+// by converting Partial references to pointer arguments.
+//
+
+struct CallWithPointer : public std::unary_function< Partial, void >
+{
+ typedef void (* Func)( Partial *, void * );
+ Func func;
+ void * data;
+
+ CallWithPointer( Func f, void * d ) : func( f ), data( d ) {}
+
+ void operator()( Partial & partial ) const
+ {
+ func( &partial, data );
+ }
+};
+
+struct PredWithPointer : public std::unary_function< const Partial, bool >
+{
+ typedef int (* Pred)( const Partial *, void * );
+ Pred pred;
+ void * data;
+
+ PredWithPointer( Pred p, void * d ) : pred( p ), data( d ) {}
+
+ bool operator()( const Partial & partial ) const
+ {
+ return 0 != pred( &partial, data );
+ }
+};
+
+/* ---------------------------------------------------------------- */
+/* utility functions
+/*
+/* Operations for transforming and manipulating collections
+ of Partials.
+ */
+
+/* ---------------------------------------------------------------- */
+/* avgAmplitude
+/*
+/* Return the average amplitude over all Breakpoints in this Partial.
+ Return zero if the Partial has no Breakpoints.
+ */
+extern "C"
+double avgAmplitude( const Partial * p )
+{
+ try
+ {
+ ThrowIfNull((Partial *) p);
+ return PartialUtils::avgAmplitude( *p );
+ }
+ catch( Exception & ex )
+ {
+ std::string s("Loris exception in avgAmplitude(): " );
+ s.append( ex.what() );
+ handleException( s.c_str() );
+ }
+ catch( std::exception & ex )
+ {
+ std::string s("std C++ exception in avgAmplitude(): " );
+ s.append( ex.what() );
+ handleException( s.c_str() );
+ }
+
+ return 0;
+}
+
+/* ---------------------------------------------------------------- */
+/* avgFrequency
+/*
+/* Return the average frequency over all Breakpoints in this Partial.
+ Return zero if the Partial has no Breakpoints.
+ */
+extern "C"
+double avgFrequency( const Partial * p )
+{
+ try
+ {
+ ThrowIfNull((Partial *) p);
+ return PartialUtils::avgFrequency( *p );
+ }
+ catch( Exception & ex )
+ {
+ std::string s("Loris exception in avgFrequency(): " );
+ s.append( ex.what() );
+ handleException( s.c_str() );
+ }
+ catch( std::exception & ex )
+ {
+ std::string s("std C++ exception in avgFrequency(): " );
+ s.append( ex.what() );
+ handleException( s.c_str() );
+ }
+
+ return 0;}
+
+
+/* ---------------------------------------------------------------- */
+/* copyIf
+/*
+/* Append copies of Partials in the source PartialList satisfying the
+ specified predicate to the destination PartialList. The source list
+ is unmodified. The data parameter can be used to
+ supply extra user-defined data to the function. Pass 0 if no
+ additional data is needed.
+ */
+extern "C"
+void copyIf( const PartialList * src, PartialList * dst,
+ int ( * predicate )( const Partial * p, void * data ),
+ void * data )
+{
+ try
+ {
+ ThrowIfNull((PartialList *) src);
+ ThrowIfNull((PartialList *) dst);
+
+ std::remove_copy_if( src->begin(), src->end(), std::back_inserter( *dst ),
+ std::not1( PredWithPointer( predicate, data ) ) );
+ }
+ catch( Exception & ex )
+ {
+ std::string s("Loris exception in copyIf(): " );
+ s.append( ex.what() );
+ handleException( s.c_str() );
+ }
+ catch( std::exception & ex )
+ {
+ std::string s("std C++ exception in copyIf(): " );
+ s.append( ex.what() );
+ handleException( s.c_str() );
+ }
+}
+
+/* ---------------------------------------------------------------- */
+/* copyLabeled
+/*
+/* Append copies of Partials in the source PartialList having the
+ specified label to the destination PartialList. The source list
+ is unmodified.
+ */
+extern "C"
+void copyLabeled( const PartialList * src, long label, PartialList * dst )
+{
+ try
+ {
+ ThrowIfNull((PartialList *) src);
+ ThrowIfNull((PartialList *) dst);
+
+ std::remove_copy_if( src->begin(), src->end(), std::back_inserter( *dst ),
+ std::not1( PartialUtils::isLabelEqual(label) ) );
+ }
+ catch( Exception & ex )
+ {
+ std::string s("Loris exception in copyLabeled(): " );
+ s.append( ex.what() );
+ handleException( s.c_str() );
+ }
+ catch( std::exception & ex )
+ {
+ std::string s("std C++ exception in copyLabeled(): " );
+ s.append( ex.what() );
+ handleException( s.c_str() );
+ }
+}
+
+/* ---------------------------------------------------------------- */
+/* crop
+/*
+/* Trim Partials by removing Breakpoints outside a specified time span.
+ Insert a Breakpoint at the boundary when cropping occurs. Remove
+ any Partials that are left empty after cropping (Partials having no
+ Breakpoints between t1 and t2).
+ */
+extern "C"
+void crop( PartialList * partials, double t1, double t2 )
+{
+ try
+ {
+ ThrowIfNull((PartialList *) partials);
+
+ notifier << "cropping " << partials->size() << " Partials" << endl;
+
+ PartialUtils::crop( partials->begin(), partials->end(), t1, t2 );
+
+ // remove empty Partials:
+ PartialList::iterator it = partials->begin();
+ while ( it != partials->end() )
+ {
+ if ( 0 == it->numBreakpoints() )
+ {
+ it = partials->erase( it );
+ }
+ else
+ {
+ ++it;
+ }
+ }
+ }
+ catch( Exception & ex )
+ {
+ std::string s("Loris exception in crop(): " );
+ s.append( ex.what() );
+ handleException( s.c_str() );
+ }
+ catch( std::exception & ex )
+ {
+ std::string s("std C++ exception in crop(): " );
+ s.append( ex.what() );
+ handleException( s.c_str() );
+ }
+}
+
+/* ---------------------------------------------------------------- */
+/* extractIf
+/*
+/* Remove Partials in the source PartialList satisfying the
+ specified predicate from the source list and append them to
+ the destination PartialList. The data parameter can be used to
+ supply extra user-defined data to the function. Pass 0 if no
+ additional data is needed.
+ */
+extern "C"
+void extractIf( PartialList * src, PartialList * dst,
+ int ( * predicate )( const Partial * p, void * data ),
+ void * data )
+{
+ try
+ {
+ ThrowIfNull((PartialList *) src);
+ ThrowIfNull((PartialList *) dst);
+
+ /*
+ std::list< Partial >::iterator it =
+ std::stable_partition( src->begin(), src->end(),
+ std::not1( PredWithPointer( predicate, data ) ) );
+
+ stable_partition should work, but seems sometimes to hang,
+ especially when there are lots and lots of Partials. Do it
+ efficiently by hand instead.
+
+ dst->splice( dst->end(), *src, it, src->end() );
+ */
+ std::list< Partial >::iterator it;
+ for ( it = std::find_if( src->begin(), src->end(), PredWithPointer( predicate, data ) );
+ it != src->end();
+ it = std::find_if( it, src->end(), PredWithPointer( predicate, data ) ) )
+ {
+ // the iterator passed to splice is a copy of it
+ // before the increment, so it is not corrupted
+ // by the splice, it is advanced to the next
+ // position before the splice is performed.
+ dst->splice( dst->end(), *src, it++ );
+ }
+
+ }
+ catch( Exception & ex )
+ {
+ std::string s("Loris exception in extractIf(): " );
+ s.append( ex.what() );
+ handleException( s.c_str() );
+ }
+ catch( std::exception & ex )
+ {
+ std::string s("std C++ exception in extractIf(): " );
+ s.append( ex.what() );
+ handleException( s.c_str() );
+ }
+}
+
+/* ---------------------------------------------------------------- */
+/* extractLabeled
+/*
+/* Remove Partials in the source PartialList having the specified
+ label from the source list and append them to the destination
+ PartialList.
+ */
+extern "C"
+void extractLabeled( PartialList * src, long label, PartialList * dst )
+{
+ try
+ {
+ ThrowIfNull((PartialList *) src);
+ ThrowIfNull((PartialList *) dst);
+
+ /*
+ std::list< Partial >::iterator it =
+ std::stable_partition( src->begin(), src->end(),
+ std::not1( PartialUtils::isLabelEqual(label) ) );
+
+ stable_partition should work, but seems sometimes to hang,
+ especially when there are lots and lots of Partials. Do it
+ efficiently by hand instead.
+
+ dst->splice( dst->end(), *src, it, src->end() );
+ */
+ std::list< Partial >::iterator it;
+ for ( it = std::find_if( src->begin(), src->end(), PartialUtils::isLabelEqual(label) );
+ it != src->end();
+ it = std::find_if( it, src->end(), PartialUtils::isLabelEqual(label) ) )
+ {
+ // the iterator passed to splice is a copy of it
+ // before the increment, so it is not corrupted
+ // by the splice, it is advanced to the next
+ // position before the splice is performed.
+ dst->splice( dst->end(), *src, it++ );
+ }
+ }
+ catch( Exception & ex )
+ {
+ std::string s("Loris exception in extractLabeled(): " );
+ s.append( ex.what() );
+ handleException( s.c_str() );
+ }
+ catch( std::exception & ex )
+ {
+ std::string s("std C++ exception in extractLabeled(): " );
+ s.append( ex.what() );
+ handleException( s.c_str() );
+ }
+}
+
+/* ---------------------------------------------------------------- */
+/* fixPhaseAfter
+/*
+/* Recompute phases of all Breakpoints later than the specified
+ time so that the synthesized phases of those later Breakpoints
+ matches the stored phase, as long as the synthesized phase at
+ the specified time matches the stored (not recomputed) phase.
+
+ Phase fixing is only applied to non-null (nonzero-amplitude)
+ Breakpoints, because null Breakpoints are interpreted as phase
+ reset points in Loris. If a null is encountered, its phase is
+ simply left unmodified, and future phases wil be recomputed
+ from that one.
+ */
+extern "C"
+void fixPhaseAfter( PartialList * partials, double time )
+{
+ try
+ {
+ ThrowIfNull((PartialList *) partials);
+ PartialUtils::fixPhaseAfter( partials->begin(), partials->end(), time );
+ }
+ catch( Exception & ex )
+ {
+ std::string s("Loris exception in fixPhaseAfter(): " );
+ s.append( ex.what() );
+ handleException( s.c_str() );
+ }
+ catch( std::exception & ex )
+ {
+ std::string s("std C++ exception in fixPhaseAfter(): " );
+ s.append( ex.what() );
+ handleException( s.c_str() );
+ }
+}
+
+/* ---------------------------------------------------------------- */
+/* fixPhaseAt
+/*
+/* Recompute phases of all Breakpoints in a Partial
+ so that the synthesized phases match the stored phases,
+ and the synthesized phase at (nearest) the specified
+ time matches the stored (not recomputed) phase.
+
+ Backward phase-fixing stops if a null (zero-amplitude)
+ Breakpoint is encountered, because nulls are interpreted as
+ phase reset points in Loris. If a null is encountered, the
+ remainder of the Partial (the front part) is fixed in the
+ forward direction, beginning at the start of the Partial.
+ Forward phase fixing is only applied to non-null
+ (nonzero-amplitude) Breakpoints. If a null is encountered,
+ its phase is simply left unmodified, and future phases wil be
+ recomputed from that one.
+ */
+extern "C"
+void fixPhaseAt( PartialList * partials, double time )
+{
+ try
+ {
+ ThrowIfNull((PartialList *) partials);
+ PartialUtils::fixPhaseAt( partials->begin(), partials->end(), time );
+ }
+ catch( Exception & ex )
+ {
+ std::string s("Loris exception in fixPhaseAt(): " );
+ s.append( ex.what() );
+ handleException( s.c_str() );
+ }
+ catch( std::exception & ex )
+ {
+ std::string s("std C++ exception in fixPhaseAt(): " );
+ s.append( ex.what() );
+ handleException( s.c_str() );
+ }
+}
+
+/* ---------------------------------------------------------------- */
+/* fixPhaseBefore
+/*
+/* Recompute phases of all Breakpoints earlier than the specified
+ time so that the synthesized phases of those earlier Breakpoints
+ matches the stored phase, and the synthesized phase at the
+ specified time matches the stored (not recomputed) phase.
+
+ Backward phase-fixing stops if a null (zero-amplitude) Breakpoint
+ is encountered, because nulls are interpreted as phase reset
+ points in Loris. If a null is encountered, the remainder of the
+ Partial (the front part) is fixed in the forward direction,
+ beginning at the start of the Partial.
+ */
+extern "C"
+void fixPhaseBefore( PartialList * partials, double time )
+{
+ try
+ {
+ ThrowIfNull((PartialList *) partials);
+ PartialUtils::fixPhaseBefore( partials->begin(), partials->end(), time );
+ }
+ catch( Exception & ex )
+ {
+ std::string s("Loris exception in fixPhaseBefore(): " );
+ s.append( ex.what() );
+ handleException( s.c_str() );
+ }
+ catch( std::exception & ex )
+ {
+ std::string s("std C++ exception in fixPhaseBefore(): " );
+ s.append( ex.what() );
+ handleException( s.c_str() );
+ }
+}
+
+/* ---------------------------------------------------------------- */
+/* fixPhaseBetween
+/*
+ Fix the phase travel between two times by adjusting the
+ frequency and phase of Breakpoints between those two times.
+
+ This algorithm assumes that there is nothing interesting
+ about the phases of the intervening Breakpoints, and modifies
+ their frequencies as little as possible to achieve the correct
+ amount of phase travel such that the frequencies and phases at
+ the specified times match the stored values. The phases of all
+ the Breakpoints between the specified times are recomputed.
+ */
+extern "C"
+void fixPhaseBetween( PartialList * partials, double tbeg, double tend )
+{
+ try
+ {
+ ThrowIfNull((PartialList *) partials);
+ PartialUtils::fixPhaseBetween( partials->begin(), partials->end(),
+ tbeg, tend );
+ }
+ catch( Exception & ex )
+ {
+ std::string s("Loris exception in fixPhaseBetween(): " );
+ s.append( ex.what() );
+ handleException( s.c_str() );
+ }
+ catch( std::exception & ex )
+ {
+ std::string s("std C++ exception in fixPhaseBetween(): " );
+ s.append( ex.what() );
+ handleException( s.c_str() );
+ }
+}
+
+
+/* ---------------------------------------------------------------- */
+/* fixPhaseForward
+/*
+/* Recompute phases of all Breakpoints later than the specified
+ time so that the synthesized phases of those later Breakpoints
+ matches the stored phase, as long as the synthesized phase at
+ the specified time matches the stored (not recomputed) phase.
+ Breakpoints later than tend are unmodified.
+
+ Phase fixing is only applied to non-null (nonzero-amplitude)
+ Breakpoints, because null Breakpoints are interpreted as phase
+ reset points in Loris. If a null is encountered, its phase is
+ simply left unmodified, and future phases wil be recomputed
+ from that one.
+ */
+extern "C"
+void fixPhaseForward( PartialList * partials, double tbeg, double tend )
+{
+ try
+ {
+ ThrowIfNull((PartialList *) partials);
+ PartialUtils::fixPhaseForward( partials->begin(), partials->end(),
+ tbeg, tend );
+ }
+ catch( Exception & ex )
+ {
+ std::string s("Loris exception in fixPhaseForward(): " );
+ s.append( ex.what() );
+ handleException( s.c_str() );
+ }
+ catch( std::exception & ex )
+ {
+ std::string s("std C++ exception in fixPhaseForward(): " );
+ s.append( ex.what() );
+ handleException( s.c_str() );
+ }
+}
+
+
+/* ---------------------------------------------------------------- */
+/* forEachBreakpoint
+/*
+/* Apply a function to each Breakpoint in a Partial. The function
+ is called once for each Breakpoint in the source Partial. The
+ function may modify the Breakpoint (but should not otherwise attempt
+ to modify the Partial). The data parameter can be used to supply extra
+ user-defined data to the function. Pass 0 if no additional data is needed.
+ The function should return 0 if successful. If the function returns
+ a non-zero value, then forEachBreakpoint immediately returns that value
+ without applying the function to any other Breakpoints in the Partial.
+ forEachBreakpoint returns zero if all calls to func return zero.
+ */
+int forEachBreakpoint( Partial * p,
+ int ( * func )( Breakpoint * p, double time, void * data ),
+ void * data )
+{
+ int result = 0;
+ try
+ {
+ ThrowIfNull((Partial *) p);
+
+ Partial::iterator it;
+ for ( it = p->begin(); 0 == result && it != p->end(); ++it )
+ {
+ result = func( &(it.breakpoint()), it.time(), data );
+ }
+ }
+ catch( Exception & ex )
+ {
+ std::string s("Loris exception in forEachBreakpoint(): " );
+ s.append( ex.what() );
+ handleException( s.c_str() );
+ }
+ catch( std::exception & ex )
+ {
+ std::string s("std C++ exception in forEachBreakpoint(): " );
+ s.append( ex.what() );
+ handleException( s.c_str() );
+ }
+
+ return result;
+}
+
+
+/* ---------------------------------------------------------------- */
+/* forEachPartial
+/*
+/* Apply a function to each Partial in a PartialList. The function
+ is called once for each Partial in the source PartialList. The
+ function may modify the Partial (but should not attempt to modify
+ the PartialList). The data parameter can be used to supply extra
+ user-defined data to the function. Pass 0 if no additional data
+ is needed. The function should return 0 if successful. If the
+ function returns a non-zero value, then forEachPartial immediately
+ returns that value without applying the function to any other
+ Partials in the PartialList. forEachPartial returns zero if all
+ calls to func return zero.
+ */
+int forEachPartial( PartialList * src,
+ int ( * func )( Partial * p, void * data ),
+ void * data )
+{
+ int result = 0;
+ try
+ {
+ ThrowIfNull((PartialList *) src);
+
+ PartialList::iterator it;
+ for ( it = src->begin(); 0 == result && it != src->end(); ++it )
+ {
+ result = func( &(*it), data );
+ }
+ }
+ catch( Exception & ex )
+ {
+ std::string s("Loris exception in forEachPartial(): " );
+ s.append( ex.what() );
+ handleException( s.c_str() );
+ }
+ catch( std::exception & ex )
+ {
+ std::string s("std C++ exception in forEachPartial(): " );
+ s.append( ex.what() );
+ handleException( s.c_str() );
+ }
+
+ return result;
+}
+
+
+/* ---------------------------------------------------------------- */
+/* peakAmplitude
+/*
+/* Return the maximum amplitude achieved by a Partial.
+ */
+extern "C"
+double peakAmplitude( const Partial * p )
+{
+ try
+ {
+ ThrowIfNull((Partial *) p);
+ return PartialUtils::peakAmplitude( *p );
+ }
+ catch( Exception & ex )
+ {
+ std::string s("Loris exception in peakAmplitude(): " );
+ s.append( ex.what() );
+ handleException( s.c_str() );
+ }
+ catch( std::exception & ex )
+ {
+ std::string s("std C++ exception in peakAmplitude(): " );
+ s.append( ex.what() );
+ handleException( s.c_str() );
+ }
+
+ return 0;
+}
+
+/* ---------------------------------------------------------------- */
+/* removeIf
+/*
+/* Remove from a PartialList all Partials satisfying the
+ specified predicate. The data parameter can be used to
+ supply extra user-defined data to the function. Pass 0 if no
+ additional data is needed.
+ */
+extern "C"
+void removeIf( PartialList * src,
+ int ( * predicate )( const Partial * p, void * data ),
+ void * data )
+{
+ try
+ {
+ ThrowIfNull((PartialList *) src);
+ std::list< Partial >::iterator it =
+ std::remove_if( src->begin(), src->end(),
+ PredWithPointer( predicate, data ) );
+ src->erase( it, src->end() );
+ }
+ catch( Exception & ex )
+ {
+ std::string s("Loris exception in removeIf(): " );
+ s.append( ex.what() );
+ handleException( s.c_str() );
+ }
+ catch( std::exception & ex )
+ {
+ std::string s("std C++ exception in removeIf(): " );
+ s.append( ex.what() );
+ handleException( s.c_str() );
+ }
+}
+
+
+/* ---------------------------------------------------------------- */
+/* removeLabeled
+/*
+/* Remove from a PartialList all Partials having the specified label.
+ */
+extern "C"
+void removeLabeled( PartialList * src, long label )
+{
+ try
+ {
+ ThrowIfNull((PartialList *) src);
+ std::list< Partial >::iterator it =
+ std::remove_if( src->begin(), src->end(),
+ PartialUtils::isLabelEqual( label ) );
+ src->erase( it, src->end() );
+ }
+ catch( Exception & ex )
+ {
+ std::string s("Loris exception in removeLabeled(): " );
+ s.append( ex.what() );
+ handleException( s.c_str() );
+ }
+ catch( std::exception & ex )
+ {
+ std::string s("std C++ exception in removeLabeled(): " );
+ s.append( ex.what() );
+ handleException( s.c_str() );
+ }
+}
+
+/* ---------------------------------------------------------------- */
+/* scaleAmp
+/*
+/* Bad old name for scaleAmplitude.
+ */
+extern "C"
+void scaleAmp( PartialList * partials, BreakpointEnvelope * ampEnv )
+{
+ scaleAmplitude( partials, ampEnv );
+}
+
+/* ---------------------------------------------------------------- */
+/* scaleAmplitude
+/*
+/* Scale the amplitude of the Partials in a PartialList according
+ to an envelope representing a time-varying amplitude scale value.
+ */
+extern "C"
+void scaleAmplitude( PartialList * partials, BreakpointEnvelope * ampEnv )
+{
+ try
+ {
+ ThrowIfNull((PartialList *) partials);
+ ThrowIfNull((BreakpointEnvelope *) ampEnv);
+
+ notifier << "scaling amplitude of " << partials->size() << " Partials" << endl;
+
+ PartialUtils::scaleAmplitude( partials->begin(), partials->end(), *ampEnv );
+ }
+ catch( Exception & ex )
+ {
+ std::string s("Loris exception in scaleAmplitude(): " );
+ s.append( ex.what() );
+ handleException( s.c_str() );
+ }
+ catch( std::exception & ex )
+ {
+ std::string s("std C++ exception in scaleAmplitude(): " );
+ s.append( ex.what() );
+ handleException( s.c_str() );
+ }
+}
+
+/* ---------------------------------------------------------------- */
+/* scaleBandwidth
+/*
+/* Scale the bandwidth of the Partials in a PartialList according
+ to an envelope representing a time-varying bandwidth scale value.
+ */
+extern "C"
+void scaleBandwidth( PartialList * partials, BreakpointEnvelope * bwEnv )
+{
+ try
+ {
+ ThrowIfNull((PartialList *) partials);
+ ThrowIfNull((BreakpointEnvelope *) bwEnv);
+
+ notifier << "scaling bandwidth of " << partials->size() << " Partials" << endl;
+
+ PartialUtils::scaleBandwidth( partials->begin(), partials->end(), *bwEnv );
+ }
+ catch( Exception & ex )
+ {
+ std::string s("Loris exception in scaleBandwidth(): " );
+ s.append( ex.what() );
+ handleException( s.c_str() );
+ }
+ catch( std::exception & ex )
+ {
+ std::string s("std C++ exception in scaleBandwidth(): " );
+ s.append( ex.what() );
+ handleException( s.c_str() );
+ }
+}
+
+/* ---------------------------------------------------------------- */
+/* setBandwidth
+/*
+/* Assign the bandwidth of the Partials in a PartialList according
+ to an envelope representing a time-varying bandwidth scale value.
+ */
+extern "C"
+void setBandwidth( PartialList * partials, BreakpointEnvelope * bwEnv )
+{
+ try
+ {
+ ThrowIfNull((PartialList *) partials);
+ ThrowIfNull((BreakpointEnvelope *) bwEnv);
+
+ notifier << "setting bandwidth of " << partials->size() << " Partials" << endl;
+
+ PartialUtils::setBandwidth( partials->begin(), partials->end(), *bwEnv );
+ }
+ catch( Exception & ex )
+ {
+ std::string s("Loris exception in setBandwidth(): " );
+ s.append( ex.what() );
+ handleException( s.c_str() );
+ }
+ catch( std::exception & ex )
+ {
+ std::string s("std C++ exception in setBandwidth(): " );
+ s.append( ex.what() );
+ handleException( s.c_str() );
+ }
+}
+
+/* ---------------------------------------------------------------- */
+/* scaleFrequency
+/*
+/* Scale the frequency of the Partials in a PartialList according
+ to an envelope representing a time-varying frequency scale value.
+ */
+extern "C"
+void scaleFrequency( PartialList * partials, BreakpointEnvelope * freqEnv )
+{
+ try
+ {
+ ThrowIfNull((PartialList *) partials);
+ ThrowIfNull((BreakpointEnvelope *) freqEnv);
+
+ notifier << "scaling frequency of " << partials->size() << " Partials" << endl;
+
+ PartialUtils::scaleFrequency( partials->begin(), partials->end(), *freqEnv );
+ }
+ catch( Exception & ex )
+ {
+ std::string s("Loris exception in scaleFrequency(): " );
+ s.append( ex.what() );
+ handleException( s.c_str() );
+ }
+ catch( std::exception & ex )
+ {
+ std::string s("std C++ exception in scaleFrequency(): " );
+ s.append( ex.what() );
+ handleException( s.c_str() );
+ }
+}
+
+/* ---------------------------------------------------------------- */
+/* scaleNoiseRatio
+/*
+/* Scale the relative noise content of the Partials in a PartialList
+ according to an envelope representing a (time-varying) noise energy
+ scale value.
+ */
+extern "C"
+void scaleNoiseRatio( PartialList * partials, BreakpointEnvelope * noiseEnv )
+{
+ try
+ {
+ ThrowIfNull((PartialList *) partials);
+ ThrowIfNull((BreakpointEnvelope *) noiseEnv);
+
+ notifier << "scaling noise ratio of " << partials->size() << " Partials" << endl;
+
+ PartialUtils::scaleNoiseRatio( partials->begin(), partials->end(), *noiseEnv );
+ }
+ catch( Exception & ex )
+ {
+ std::string s("Loris exception in scaleNoiseRatio(): " );
+ s.append( ex.what() );
+ handleException( s.c_str() );
+ }
+ catch( std::exception & ex )
+ {
+ std::string s("std C++ exception in scaleNoiseRatio(): " );
+ s.append( ex.what() );
+ handleException( s.c_str() );
+ }
+}
+
+/* ---------------------------------------------------------------- */
+/* shiftPitch
+/*
+/* Shift the pitch of all Partials in a PartialList according to
+ the given pitch envelope. The pitch envelope is assumed to have
+ units of cents (1/100 of a halfstep).
+ */
+extern "C"
+void shiftPitch( PartialList * partials, BreakpointEnvelope * pitchEnv )
+{
+ try
+ {
+ ThrowIfNull((PartialList *) partials);
+ ThrowIfNull((BreakpointEnvelope *) pitchEnv);
+
+ notifier << "shifting pitch of " << partials->size() << " Partials" << endl;
+
+ PartialUtils::shiftPitch( partials->begin(), partials->end(), *pitchEnv );
+ }
+ catch( Exception & ex )
+ {
+ std::string s("Loris exception in shiftPitch(): " );
+ s.append( ex.what() );
+ handleException( s.c_str() );
+ }
+ catch( std::exception & ex )
+ {
+ std::string s("std C++ exception in shiftPitch(): " );
+ s.append( ex.what() );
+ handleException( s.c_str() );
+ }
+}
+
+/* ---------------------------------------------------------------- */
+/* shiftTime
+/*
+/* Shift the time of all the Breakpoints in all Partials in a
+ PartialList by a constant amount.
+ */
+extern "C"
+void shiftTime( PartialList * partials, double offset )
+{
+ try
+ {
+ ThrowIfNull((PartialList *) partials);
+
+ notifier << "shifting time of " << partials->size() << " Partials" << endl;
+
+ PartialUtils::shiftTime( partials->begin(), partials->end(), offset );
+ }
+ catch( Exception & ex )
+ {
+ std::string s("Loris exception in shiftTime(): " );
+ s.append( ex.what() );
+ handleException( s.c_str() );
+ }
+ catch( std::exception & ex )
+ {
+ std::string s("std C++ exception in shiftTime(): " );
+ s.append( ex.what() );
+ handleException( s.c_str() );
+ }
+}
+
+/* ---------------------------------------------------------------- */
+/* sortByLabel
+/*
+/* Sort the Partials in a PartialList in order of increasing label.
+ * The sort is stable; Partials having the same label are not
+ * reordered.
+ */
+extern "C"
+void sortByLabel( PartialList * partials )
+{
+ partials->sort( PartialUtils::compareLabelLess() );
+}
+
+/* ---------------------------------------------------------------- */
+/* timeSpan
+/*
+/* Return the minimum start time and maximum end time
+ * in seconds of all Partials in this PartialList. The v
+ * times are returned in the (non-null) pointers tmin
+ * and tmax.
+ */
+extern "C"
+void timeSpan( PartialList * partials, double * tmin, double * tmax )
+{
+ std::pair< double, double > times =
+ PartialUtils::timeSpan( partials->begin(), partials->end() );
+ if ( 0 != tmin )
+ {
+ *tmin = times.first;
+ }
+ if ( 0 != tmax )
+ {
+ *tmax = times.second;
+ }
+}
+
+/* ---------------------------------------------------------------- */
+/* weightedAvgFrequency
+/*
+/* Return the average frequency over all Breakpoints in this Partial,
+ weighted by the Breakpoint amplitudes. Return zero if the Partial
+ has no Breakpoints.
+ */
+extern "C"
+double weightedAvgFrequency( const Partial * p )
+{
+ try
+ {
+ ThrowIfNull((Partial *) p);
+ return PartialUtils::weightedAvgFrequency( *p );
+ }
+ catch( Exception & ex )
+ {
+ std::string s("Loris exception in weightedAvgFrequency(): " );
+ s.append( ex.what() );
+ handleException( s.c_str() );
+ }
+ catch( std::exception & ex )
+ {
+ std::string s("std C++ exception in weightedAvgFrequency(): " );
+ s.append( ex.what() );
+ handleException( s.c_str() );
+ }
+
+ return 0;
+}