/* * 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 * * * lorisPartialList_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 contains the procedural interface for the Loris * PartialList (std::list< Partial >) class. * * 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 "Partial.h" #include "Notifier.h" #include using namespace Loris; /* ---------------------------------------------------------------- */ /* PartialList object interface /* /* A PartialList represents a collection of Bandwidth-Enhanced Partials, each having a trio of synchronous, non-uniformly- sampled breakpoint envelopes representing the time-varying frequency, amplitude, and noisiness of a single bandwidth- enhanced sinusoid. For more information about Bandwidth-Enhanced Partials and the Reassigned Bandwidth-Enhanced Additive Sound Model, refer to the Loris website: www.cerlsoundgroup.org/Loris/. In C++, a PartialList * is a Loris::PartialList *. */ /* ---------------------------------------------------------------- */ /* createPartialList /* /* Return a new empty PartialList. */ extern "C" PartialList * createPartialList( void ) { try { debugger << "creating empty PartialList" << endl; return new std::list< Partial >; } catch( Exception & ex ) { std::string s("Loris exception in createPartialList(): " ); s.append( ex.what() ); handleException( s.c_str() ); } catch( std::exception & ex ) { std::string s("std C++ exception in createPartialList(): " ); s.append( ex.what() ); handleException( s.c_str() ); } return NULL; } /* ---------------------------------------------------------------- */ /* destroyPartialList /* /* Destroy this PartialList. */ extern "C" void destroyPartialList( PartialList * ptr_this ) { try { ThrowIfNull((PartialList *) ptr_this); debugger << "deleting PartialList containing " << ptr_this->size() << " Partials" << endl; delete ptr_this; } catch( Exception & ex ) { std::string s("Loris exception in destroyPartialList(): " ); s.append( ex.what() ); handleException( s.c_str() ); } catch( std::exception & ex ) { std::string s("std C++ exception in destroyPartialList(): " ); s.append( ex.what() ); handleException( s.c_str() ); } } /* ---------------------------------------------------------------- */ /* partialList_clear /* /* Remove (and destroy) all the Partials from this PartialList, leaving it empty. */ extern "C" void partialList_clear( PartialList * ptr_this ) { try { ThrowIfNull((PartialList *) ptr_this); ptr_this->clear(); } catch( Exception & ex ) { std::string s("Loris exception in partialList_clear(): " ); s.append( ex.what() ); handleException( s.c_str() ); } catch( std::exception & ex ) { std::string s("std C++ exception in partialList_clear(): " ); s.append( ex.what() ); handleException( s.c_str() ); } } /* ---------------------------------------------------------------- */ /* partialList_copy /* /* Make this PartialList a copy of the source PartialList by making copies of all of the Partials in the source and adding them to this PartialList. */ extern "C" void partialList_copy( PartialList * dst, const PartialList * src ) { try { ThrowIfNull((PartialList *) dst); ThrowIfNull((PartialList *) src); debugger << "copying PartialList containing " << src->size() << " Partials" << endl; *dst = *src; } catch( Exception & ex ) { std::string s("Loris exception in partialList_copy(): " ); s.append( ex.what() ); handleException( s.c_str() ); } catch( std::exception & ex ) { std::string s("std C++ exception in partialList_copy(): " ); s.append( ex.what() ); handleException( s.c_str() ); } } /* ---------------------------------------------------------------- */ /* partialList_size /* /* Return the number of Partials in this PartialList. */ extern "C" unsigned long partialList_size( const PartialList * ptr_this ) { try { ThrowIfNull((PartialList *) ptr_this); return ptr_this->size(); } catch( Exception & ex ) { std::string s("Loris exception in partialList_size(): " ); s.append( ex.what() ); handleException( s.c_str() ); } catch( std::exception & ex ) { std::string s("std C++ exception in partialList_size(): " ); s.append( ex.what() ); handleException( s.c_str() ); } return 0; } /* ---------------------------------------------------------------- */ /* partialList_splice /* /* Splice all the Partials in the source PartialList onto the end of this PartialList, leaving the source empty. */ extern "C" void partialList_splice( PartialList * dst, PartialList * src ) { try { ThrowIfNull((PartialList *) dst); ThrowIfNull((PartialList *) src); debugger << "splicing PartialList containing " << src->size() << " Partials" << " into PartialList containing " << dst->size() << " Partials"<< endl; dst->splice( dst->end(), *src ); } catch( Exception & ex ) { std::string s("Loris exception in partialList_splice(): " ); s.append( ex.what() ); handleException( s.c_str() ); } catch( std::exception & ex ) { std::string s("std C++ exception in partialList_splice(): " ); s.append( ex.what() ); handleException( s.c_str() ); } } /* ---------------------------------------------------------------- */ /* Partial object interface /* /* A Partial represents a single component in the reassigned bandwidth-enhanced additive model. A Partial consists of a chain of Breakpoints describing the time-varying frequency, amplitude, and bandwidth (or noisiness) envelopes of the component, and a 4-byte label. The Breakpoints are non-uniformly distributed in time. For more information about Reassigned Bandwidth-Enhanced Analysis and the Reassigned Bandwidth-Enhanced Additive Sound Model, refer to the Loris website: www.cerlsoundgroup.org/Loris/. */ /* ---------------------------------------------------------------- */ /* partial_startTime /* /* Return the start time (seconds) for the specified Partial. */ double partial_startTime( const Partial * p ) { double ret = 0; try { ThrowIfNull((Partial *) p); ret = p->startTime(); } catch( Exception & ex ) { std::string s("Loris exception in partial_startTime(): " ); s.append( ex.what() ); handleException( s.c_str() ); } catch( std::exception & ex ) { std::string s("std C++ exception in partial_startTime(): " ); s.append( ex.what() ); handleException( s.c_str() ); } return ret; } /* ---------------------------------------------------------------- */ /* partial_endTime /* /* Return the end time (seconds) for the specified Partial. */ double partial_endTime( const Partial * p ) { double ret = 0; try { ThrowIfNull((Partial *) p); ret = p->endTime(); } catch( Exception & ex ) { std::string s("Loris exception in partial_endTime(): " ); s.append( ex.what() ); handleException( s.c_str() ); } catch( std::exception & ex ) { std::string s("std C++ exception in partial_endTime(): " ); s.append( ex.what() ); handleException( s.c_str() ); } return ret; } /* ---------------------------------------------------------------- */ /* partial_duration /* /* Return the duration (seconds) for the specified Partial. */ double partial_duration( const Partial * p ) { double ret = 0; try { ThrowIfNull((Partial *) p); ret = p->duration(); } catch( Exception & ex ) { std::string s("Loris exception in partial_duration(): " ); s.append( ex.what() ); handleException( s.c_str() ); } catch( std::exception & ex ) { std::string s("std C++ exception in partial_duration(): " ); s.append( ex.what() ); handleException( s.c_str() ); } return ret; } /* ---------------------------------------------------------------- */ /* partial_initialPhase /* /* Return the initial phase (radians) for the specified Partial. */ double partial_initialPhase( const Partial * p ) { double ret = 0; try { ThrowIfNull((Partial *) p); ret = p->initialPhase(); } catch( Exception & ex ) { std::string s("Loris exception in partial_initialPhase(): " ); s.append( ex.what() ); handleException( s.c_str() ); } catch( std::exception & ex ) { std::string s("std C++ exception in partial_initialPhase(): " ); s.append( ex.what() ); handleException( s.c_str() ); } return ret; } /* ---------------------------------------------------------------- */ /* partial_label /* /* Return the integer label for the specified Partial. */ int partial_label( const Partial * p ) { int ret = 0; try { ThrowIfNull((Partial *) p); ret = p->label(); } catch( Exception & ex ) { std::string s("Loris exception in partial_label(): " ); s.append( ex.what() ); handleException( s.c_str() ); } catch( std::exception & ex ) { std::string s("std C++ exception in partial_label(): " ); s.append( ex.what() ); handleException( s.c_str() ); } return ret; } /* ---------------------------------------------------------------- */ /* partial_numBreakpoints /* /* Return the number of Breakpoints in the specified Partial. */ unsigned long partial_numBreakpoints( const Partial * p ) { unsigned long ret = 0; try { ThrowIfNull((Partial *) p); ret = p->size(); } catch( Exception & ex ) { std::string s("Loris exception in partial_numBreakpoints(): " ); s.append( ex.what() ); handleException( s.c_str() ); } catch( std::exception & ex ) { std::string s("std C++ exception in partial_numBreakpoints(): " ); s.append( ex.what() ); handleException( s.c_str() ); } return ret; } /* ---------------------------------------------------------------- */ /* partial_frequencyAt /* /* Return the frequency (Hz) of the specified Partial interpolated at a particular time. It is an error to apply this function to a Partial having no Breakpoints. */ double partial_frequencyAt( const Partial * p, double t ) { double ret = 0; try { ThrowIfNull((Partial *) p); ret = p->frequencyAt( t ); } catch( Exception & ex ) { std::string s("Loris exception in partial_frequencyAt(): " ); s.append( ex.what() ); handleException( s.c_str() ); } catch( std::exception & ex ) { std::string s("std C++ exception in partial_frequencyAt(): " ); s.append( ex.what() ); handleException( s.c_str() ); } return ret; } /* ---------------------------------------------------------------- */ /* partial_bandwidthAt /* /* Return the bandwidth of the specified Partial interpolated at a particular time. It is an error to apply this function to a Partial having no Breakpoints. */ double partial_bandwidthAt( const Partial * p, double t ) { double ret = 0; try { ThrowIfNull((Partial *) p); ret = p->bandwidthAt( t ); } catch( Exception & ex ) { std::string s("Loris exception in partial_bandwidthAt(): " ); s.append( ex.what() ); handleException( s.c_str() ); } catch( std::exception & ex ) { std::string s("std C++ exception in partial_bandwidthAt(): " ); s.append( ex.what() ); handleException( s.c_str() ); } return ret; } /* ---------------------------------------------------------------- */ /* partial_phaseAt /* /* Return the phase (radians) of the specified Partial interpolated at a particular time. It is an error to apply this function to a Partial having no Breakpoints. */ double partial_phaseAt( const Partial * p, double t ) { double ret = 0; try { ThrowIfNull((Partial *) p); ret = p->phaseAt( t ); } catch( Exception & ex ) { std::string s("Loris exception in partial_phaseAt(): " ); s.append( ex.what() ); handleException( s.c_str() ); } catch( std::exception & ex ) { std::string s("std C++ exception in partial_phaseAt(): " ); s.append( ex.what() ); handleException( s.c_str() ); } return ret; } /* ---------------------------------------------------------------- */ /* partial_amplitudeAt /* /* Return the (absolute) amplitude of the specified Partial interpolated at a particular time. Partials are assumed to fade out over 1 millisecond at the ends (rather than instantaneously). It is an error to apply this function to a Partial having no Breakpoints. */ double partial_amplitudeAt( const Partial * p, double t ) { double ret = 0; try { ThrowIfNull((Partial *) p); ret = p->amplitudeAt( t, 0.001 ); } catch( Exception & ex ) { std::string s("Loris exception in partial_amplitudeAt(): " ); s.append( ex.what() ); handleException( s.c_str() ); } catch( std::exception & ex ) { std::string s("std C++ exception in partial_amplitudeAt(): " ); s.append( ex.what() ); handleException( s.c_str() ); } return ret; } /* ---------------------------------------------------------------- */ /* partial_setLabel /* /* Assign a new integer label to the specified Partial. */ void partial_setLabel( Partial * p, int label ) { try { ThrowIfNull((Partial *) p); p->setLabel( label ); } catch( Exception & ex ) { std::string s("Loris exception in partial_setLabel(): " ); s.append( ex.what() ); handleException( s.c_str() ); } catch( std::exception & ex ) { std::string s("std C++ exception in partial_setLabel(): " ); s.append( ex.what() ); handleException( s.c_str() ); } } /* ---------------------------------------------------------------- */ /* Breakpoint object interface /* /* A Breakpoint represents a single breakpoint in the Partial parameter (frequency, amplitude, bandwidth) envelope. Instantaneous phase is also stored, but is only used at the onset of a partial, or when it makes a transition from zero to nonzero amplitude. Loris Partials represent reassigned bandwidth-enhanced model components. A Partial consists of a chain of Breakpoints describing the time-varying frequency, amplitude, and bandwidth (noisiness) of the component. For more information about Reassigned Bandwidth-Enhanced Analysis and the Reassigned Bandwidth-Enhanced Additive Sound Model, refer to the Loris website: www.cerlsoundgroup.org/Loris/. */ /* ---------------------------------------------------------------- */ /* breakpoint_getFrequency /* /* Return the frequency (Hz) of the specified Breakpoint. */ double breakpoint_getFrequency( const Breakpoint * bp ) { double ret = 0; try { ThrowIfNull((Breakpoint *) bp); ret = bp->frequency(); } catch( Exception & ex ) { std::string s("Loris exception in breakpoint_getFrequency(): " ); s.append( ex.what() ); handleException( s.c_str() ); } catch( std::exception & ex ) { std::string s("std C++ exception in breakpoint_getFrequency(): " ); s.append( ex.what() ); handleException( s.c_str() ); } return ret; } /* ---------------------------------------------------------------- */ /* breakpoint_getAmplitude /* /* Return the (absolute) amplitude of the specified Breakpoint. */ double breakpoint_getAmplitude( const Breakpoint * bp ) { double ret = 0; try { ThrowIfNull((Breakpoint *) bp); ret = bp->amplitude(); } catch( Exception & ex ) { std::string s("Loris exception in breakpoint_getAmplitude(): " ); s.append( ex.what() ); handleException( s.c_str() ); } catch( std::exception & ex ) { std::string s("std C++ exception in breakpoint_getAmplitude(): " ); s.append( ex.what() ); handleException( s.c_str() ); } return ret; } /* ---------------------------------------------------------------- */ /* breakpoint_getBandwidth /* /* Return the bandwidth coefficient of the specified Breakpoint. */ double breakpoint_getBandwidth( const Breakpoint * bp ) { double ret = 0; try { ThrowIfNull((Breakpoint *) bp); ret = bp->bandwidth(); } catch( Exception & ex ) { std::string s("Loris exception in breakpoint_getBandwidth(): " ); s.append( ex.what() ); handleException( s.c_str() ); } catch( std::exception & ex ) { std::string s("std C++ exception in breakpoint_getBandwidth(): " ); s.append( ex.what() ); handleException( s.c_str() ); } return ret; } /* ---------------------------------------------------------------- */ /* breakpoint_getPhase /* /* Return the phase (radians) of the specified Breakpoint. */ double breakpoint_getPhase( const Breakpoint * bp ) { double ret = 0; try { ThrowIfNull((Breakpoint *) bp); ret = bp->phase(); } catch( Exception & ex ) { std::string s("Loris exception in breakpoint_getPhase(): " ); s.append( ex.what() ); handleException( s.c_str() ); } catch( std::exception & ex ) { std::string s("std C++ exception in breakpoint_getPhase(): " ); s.append( ex.what() ); handleException( s.c_str() ); } return ret; } /* ---------------------------------------------------------------- */ /* breakpoint_setFrequency /* /* Assign a new frequency (Hz) to the specified Breakpoint. */ void breakpoint_setFrequency( Breakpoint * bp, double f ) { try { ThrowIfNull((Breakpoint *) bp); bp->setFrequency( f ); } catch( Exception & ex ) { std::string s("Loris exception in breakpoint_setFrequency(): " ); s.append( ex.what() ); handleException( s.c_str() ); } catch( std::exception & ex ) { std::string s("std C++ exception in breakpoint_setFrequency(): " ); s.append( ex.what() ); handleException( s.c_str() ); } } /* ---------------------------------------------------------------- */ /* breakpoint_setAmplitude /* /* Assign a new (absolute) amplitude to the specified Breakpoint. */ void breakpoint_setAmplitude( Breakpoint * bp, double a ) { try { ThrowIfNull((Breakpoint *) bp); bp->setAmplitude( a ); } catch( Exception & ex ) { std::string s("Loris exception in breakpoint_setAmplitude(): " ); s.append( ex.what() ); handleException( s.c_str() ); } catch( std::exception & ex ) { std::string s("std C++ exception in breakpoint_setAmplitude(): " ); s.append( ex.what() ); handleException( s.c_str() ); } } /* ---------------------------------------------------------------- */ /* breakpoint_setBandwidth /* /* Assign a new bandwidth coefficient to the specified Breakpoint. */ void breakpoint_setBandwidth( Breakpoint * bp, double bw ) { try { ThrowIfNull((Breakpoint *) bp); bp->setBandwidth( bw ); } catch( Exception & ex ) { std::string s("Loris exception in breakpoint_setBandwidth(): " ); s.append( ex.what() ); handleException( s.c_str() ); } catch( std::exception & ex ) { std::string s("std C++ exception in breakpoint_setBandwidth(): " ); s.append( ex.what() ); handleException( s.c_str() ); } } /* ---------------------------------------------------------------- */ /* breakpoint_setPhase /* /* Assign a new phase (radians) to the specified Breakpoint. */ void breakpoint_setPhase( Breakpoint * bp, double phi ) { try { ThrowIfNull((Breakpoint *) bp); bp->setPhase( phi ); } catch( Exception & ex ) { std::string s("Loris exception in breakpoint_setPhase(): " ); s.append( ex.what() ); handleException( s.c_str() ); } catch( std::exception & ex ) { std::string s("std C++ exception in breakpoint_setPhase(): " ); s.append( ex.what() ); handleException( s.c_str() ); } }