00001 #ifndef INCLUDE_LORIS_H 00002 #define INCLUDE_LORIS_H 00003 /* 00004 * This is the Loris C++ Class Library, implementing analysis, 00005 * manipulation, and synthesis of digitized sounds using the Reassigned 00006 * Bandwidth-Enhanced Additive Sound Model. 00007 * 00008 * Loris is Copyright (c) 1999-2010 by Kelly Fitz and Lippold Haken 00009 * 00010 * This program is free software; you can redistribute it and/or modify 00011 * it under the terms of the GNU General Public License as published by 00012 * the Free Software Foundation; either version 2 of the License, or 00013 * (at your option) any later version. 00014 * 00015 * This program is distributed in the hope that it will be useful, 00016 * but WITHOUT ANY WARRANTY, without even the implied warranty of 00017 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00018 * GNU General Public License for more details. 00019 * 00020 * You should have received a copy of the GNU General Public License 00021 * along with this program; if not, write to the Free Software 00022 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 00023 * 00024 * 00025 * loris.h 00026 * 00027 * Header specifying C-linkable procedural interface for Loris. 00028 * 00029 * Main components of this interface: 00030 * - version identification symbols 00031 * - type declarations 00032 * - Analyzer configuration 00033 * - LinearEnvelope (formerly BreakpointEnvelope) operations 00034 * - PartialList operations 00035 * - Partial operations 00036 * - Breakpoint operations 00037 * - sound modeling functions for preparing PartialLists 00038 * - utility functions for manipulating PartialLists 00039 * - notification and exception handlers (all exceptions must be caught and 00040 * handled internally, clients can specify an exception handler and 00041 * a notification function. The default one in Loris uses printf()). 00042 * 00043 * loris.h is generated automatically from loris.h.in. Do not modify loris.h 00044 * 00045 * Kelly Fitz, 4 Feb 2002 00046 * loris@cerlsoundgroup.org 00047 * 00048 * http://www.cerlsoundgroup.org/Loris/ 00049 * 00050 */ 00051 00052 /* ---------------------------------------------------------------- */ 00053 /* Version 00054 /* 00055 /* Define symbols that facilitate version/release identification. 00056 */ 00057 00058 #define LORIS_MAJOR_VERSION 1 00059 #define LORIS_MINOR_VERSION 7 00060 #define LORIS_SUBMINOR_VERSION 00061 #define LORIS_VERSION_STR "Loris 1.7" 00062 00063 /* ---------------------------------------------------------------- */ 00064 /* Types 00065 /* 00066 /* The (class) types Breakpoint, LinearEnvelope, Partial, 00067 and PartialList are imported from the Loris namespace. 00068 The first three are classes, the latter is a typedef 00069 for std::list< Loris::Partial >. 00070 */ 00071 #if defined(__cplusplus) 00072 // include std library list header, declaring templates 00073 // is too painful and fragile: 00074 #include <list> 00075 00076 // declare Loris classes in Loris namespace: 00077 namespace Loris 00078 { 00079 class Breakpoint; 00080 class LinearEnvelope; 00081 class Partial; 00082 00083 // this typedef has to be copied from PartialList.h 00084 typedef std::list< Loris::Partial > PartialList; 00085 } 00086 00087 // import those names into the global namespace 00088 using Loris::Breakpoint; 00089 using Loris::LinearEnvelope; 00090 using Loris::Partial; 00091 using Loris::PartialList; 00092 #else 00093 /* no classes, just declare types and use 00094 opaque C pointers 00095 */ 00096 typedef struct Breakpoint Breakpoint; 00097 typedef struct LinearEnvelope LinearEnvelope; 00098 typedef struct PartialList PartialList; 00099 typedef struct Partial Partial; 00100 #endif 00101 00102 /* 00103 TODO 00104 Maybe should also have loris_label_t and loris_size_t 00105 defined, depending on configure. 00106 */ 00107 00108 #if defined(__cplusplus) 00109 extern "C" { 00110 #endif 00111 00112 /* ---------------------------------------------------------------- */ 00113 /* Analyzer configuration 00114 /* 00115 /* An Analyzer represents a configuration of parameters for 00116 performing Reassigned Bandwidth-Enhanced Additive Analysis 00117 of sampled waveforms. This analysis process yields a collection 00118 of Partials, each having a trio of synchronous, non-uniformly- 00119 sampled breakpoint envelopes representing the time-varying 00120 frequency, amplitude, and noisiness of a single bandwidth- 00121 enhanced sinusoid. 00122 00123 For more information about Reassigned Bandwidth-Enhanced 00124 Analysis and the Reassigned Bandwidth-Enhanced Additive Sound 00125 Model, refer to the Loris website: www.cerlsoundgroup.org/Loris/. 00126 00127 In the procedural interface, there is only one Analyzer. 00128 It must be configured by calling analyzer_configure before 00129 any of the other analyzer operations can be performed. 00130 */ 00131 00132 void analyze( const double * buffer, unsigned int bufferSize, 00133 double srate, PartialList * partials ); 00134 /* Analyze an array of bufferSize (mono) samples at the given sample rate 00135 (in Hz) and append the extracted Partials to the given 00136 PartialList. 00137 */ 00138 00139 void analyzer_configure( double resolution, double windowWidth ); 00140 /* Configure the sole Analyzer instance with the specified 00141 frequency resolution (minimum instantaneous frequency 00142 difference between Partials). All other Analyzer parameters 00143 are computed from the specified frequency resolution. 00144 00145 Construct the Analyzer instance if necessary. 00146 00147 In the procedural interface, there is only one Analyzer. 00148 It must be configured by calling analyzer_configure before 00149 any of the other analyzer operations can be performed. 00150 */ 00151 00152 double analyzer_getAmpFloor( void ); 00153 /* Return the amplitude floor (lowest detected spectral amplitude), 00154 in (negative) dB, for the Loris Analyzer. 00155 */ 00156 00157 double analyzer_getCropTime( void ); 00158 /* Return the crop time (maximum temporal displacement of a time- 00159 frequency data point from the time-domain center of the analysis 00160 window, beyond which data points are considered "unreliable") 00161 for the Loris Analyzer. 00162 */ 00163 00164 double analyzer_getFreqDrift( void ); 00165 /* Return the maximum allowable frequency difference between 00166 consecutive Breakpoints in a Partial envelope for the Loris Analyzer. 00167 */ 00168 00169 double analyzer_getFreqFloor( void ); 00170 /* Return the frequency floor (minimum instantaneous Partial 00171 frequency), in Hz, for the Loris Analyzer. 00172 */ 00173 00174 double analyzer_getFreqResolution( void ); 00175 /* Return the frequency resolution (minimum instantaneous frequency 00176 difference between Partials) for the Loris Analyzer. 00177 */ 00178 00179 double analyzer_getHopTime( void ); 00180 /* Return the hop time (which corresponds approximately to the 00181 average density of Partial envelope Breakpoint data) for this 00182 Analyzer. 00183 */ 00184 00185 double analyzer_getSidelobeLevel( void ); 00186 /* Return the sidelobe attenutation level for the Kaiser analysis window in 00187 positive dB. Higher numbers (e.g. 90) give very good sidelobe 00188 rejection but cause the window to be longer in time. Smaller 00189 numbers raise the level of the sidelobes, increasing the likelihood 00190 of frequency-domain interference, but allow the window to be shorter 00191 in time. 00192 */ 00193 00194 double analyzer_getWindowWidth( void ); 00195 /* Return the frequency-domain main lobe width (measured between 00196 zero-crossings) of the analysis window used by the Loris Analyzer. 00197 */ 00198 00199 void analyzer_setAmpFloor( double x ); 00200 /* Set the amplitude floor (lowest detected spectral amplitude), in 00201 (negative) dB, for the Loris Analyzer. 00202 */ 00203 00204 void analyzer_setBwRegionWidth( double x ); 00205 /* Deprecated, use analyzer_setStoreResidueBandwidth instead. 00206 */ 00207 00208 void analyzer_setCropTime( double x ); 00209 /* Set the crop time (maximum temporal displacement of a time- 00210 frequency data point from the time-domain center of the analysis 00211 window, beyond which data points are considered "unreliable") 00212 for the Loris Analyzer. 00213 */ 00214 00215 void analyzer_setFreqDrift( double x ); 00216 /* Set the maximum allowable frequency difference between 00217 consecutive Breakpoints in a Partial envelope for the Loris Analyzer. 00218 */ 00219 00220 void analyzer_setFreqFloor( double x ); 00221 /* Set the amplitude floor (minimum instantaneous Partial 00222 frequency), in Hz, for the Loris Analyzer. 00223 */ 00224 00225 void analyzer_setFreqResolution( double x ); 00226 /* Set the frequency resolution (minimum instantaneous frequency 00227 difference between Partials) for the Loris Analyzer. (Does not cause 00228 other parameters to be recomputed.) 00229 */ 00230 00231 void analyzer_setHopTime( double x ); 00232 /* Set the hop time (which corresponds approximately to the average 00233 density of Partial envelope Breakpoint data) for the Loris Analyzer. 00234 */ 00235 00236 void analyzer_setSidelobeLevel( double x ); 00237 /* Set the sidelobe attenutation level for the Kaiser analysis window in 00238 positive dB. Larger numbers (e.g. 90) give very good sidelobe 00239 rejection but cause the window to be longer in time. Smaller 00240 numbers raise the level of the sidelobes, increasing the likelihood 00241 of frequency-domain interference, but allow the window to be shorter 00242 in time. 00243 */ 00244 00245 void analyzer_setWindowWidth( double x ); 00246 /* Set the frequency-domain main lobe width (measured between 00247 zero-crossings) of the analysis window used by the Loris Analyzer. 00248 */ 00249 00250 void analyzer_setStoreResidueBandwidth( double regionWidth ); 00251 /* Construct Partial bandwidth envelopes during analysis 00252 by associating residual energy in the spectrum (after 00253 peak extraction) with the selected spectral peaks that 00254 are used to construct Partials. 00255 00256 regionWidth is the width (in Hz) of the bandwidth 00257 association regions used by this process, must be positive. 00258 */ 00259 00260 void analyzer_setStoreConvergenceBandwidth( double tolerancePct ); 00261 /* Construct Partial bandwidth envelopes during analysis 00262 by storing the mixed derivative of short-time phase, 00263 scaled and shifted so that a value of 0 corresponds 00264 to a pure sinusoid, and a value of 1 corresponds to a 00265 bandwidth-enhanced sinusoid with maximal energy spread 00266 (minimum sinusoidal convergence). 00267 00268 tolerance is the amount of range over which the 00269 mixed derivative indicator should be allowed to drift away 00270 from a pure sinusoid before saturating. This range is mapped 00271 to bandwidth values on the range [0,1]. Must be positive and 00272 not greater than 1. 00273 */ 00274 00275 void analyzer_setStoreNoBandwidth( void ); 00276 /* Disable bandwidth envelope construction. Bandwidth 00277 will be zero for all Breakpoints in all Partials. 00278 */ 00279 00280 double analyzer_getBwRegionWidth( void ); 00281 /* Return the width (in Hz) of the Bandwidth Association regions 00282 used by this Analyzer, only if the spectral residue method is 00283 used to compute bandwidth envelopes. Return zero if the mixed 00284 derivative method is used, or if no bandwidth is computed. 00285 */ 00286 00287 double analyzer_getBwConvergenceTolerance( void ); 00288 /* Return the mixed derivative convergence tolerance 00289 only if the convergence indicator is used to compute 00290 bandwidth envelopes. Return zero if the spectral residue 00291 method is used or if no bandwidth is computed. 00292 */ 00293 00294 00295 /* ---------------------------------------------------------------- */ 00296 /* LinearEnvelope object interface 00297 /* 00298 /* A LinearEnvelope represents a linear segment breakpoint 00299 function with infinite extension at each end (that is, the 00300 values past either end of the breakpoint function have the 00301 values at the nearest end). 00302 00303 In C++, a LinearEnvelope is a Loris::LinearEnvelope. 00304 */ 00305 00306 LinearEnvelope * createLinearEnvelope( void ); 00307 /* Construct and return a new LinearEnvelope having no 00308 breakpoints and an implicit value of 0. everywhere, 00309 until the first breakpoint is inserted. 00310 */ 00311 00312 LinearEnvelope * copyLinearEnvelope( const LinearEnvelope * ptr_this ); 00313 /* Construct and return a new LinearEnvelope that is an 00314 exact copy of the specified LinearEnvelopes, having 00315 an identical set of breakpoints. 00316 */ 00317 00318 void destroyLinearEnvelope( LinearEnvelope * ptr_this ); 00319 /* Destroy this LinearEnvelope. 00320 */ 00321 00322 void linearEnvelope_insertBreakpoint( LinearEnvelope * ptr_this, 00323 double time, double val ); 00324 /* Insert a breakpoint representing the specified (time, value) 00325 pair into this LinearEnvelope. If there is already a 00326 breakpoint at the specified time, it will be replaced with 00327 the new breakpoint. 00328 */ 00329 00330 double linearEnvelope_valueAt( const LinearEnvelope * ptr_this, 00331 double time ); 00332 /* Return the interpolated value of this LinearEnvelope at the 00333 specified time. 00334 */ 00335 00336 /* ---------------------------------------------------------------- */ 00337 /* PartialList object interface 00338 /* 00339 /* A PartialList represents a collection of Bandwidth-Enhanced 00340 Partials, each having a trio of synchronous, non-uniformly- 00341 sampled breakpoint envelopes representing the time-varying 00342 frequency, amplitude, and noisiness of a single bandwidth- 00343 enhanced sinusoid. 00344 00345 For more information about Bandwidth-Enhanced Partials and the 00346 Reassigned Bandwidth-Enhanced Additive Sound Model, refer to 00347 the Loris website: www.cerlsoundgroup.org/Loris/. 00348 00349 In C++, a PartialList is a Loris::PartialList. 00350 */ 00351 PartialList * createPartialList( void ); 00352 /* Return a new empty PartialList. 00353 */ 00354 00355 void destroyPartialList( PartialList * ptr_this ); 00356 /* Destroy this PartialList. 00357 */ 00358 00359 void partialList_clear( PartialList * ptr_this ); 00360 /* Remove (and destroy) all the Partials from this PartialList, 00361 leaving it empty. 00362 */ 00363 00364 void partialList_copy( PartialList * ptr_this, 00365 const PartialList * src ); 00366 /* Make this PartialList a copy of the source PartialList by making 00367 copies of all of the Partials in the source and adding them to 00368 this PartialList. 00369 */ 00370 00371 unsigned long partialList_size( const PartialList * ptr_this ); 00372 /* Return the number of Partials in this PartialList. 00373 */ 00374 00375 void partialList_splice( PartialList * ptr_this, 00376 PartialList * src ); 00377 /* Splice all the Partials in the source PartialList onto the end of 00378 this PartialList, leaving the source empty. 00379 */ 00380 00381 /* ---------------------------------------------------------------- */ 00382 /* Partial object interface 00383 /* 00384 /* A Partial represents a single component in the 00385 reassigned bandwidth-enhanced additive model. A Partial consists of a 00386 chain of Breakpoints describing the time-varying frequency, amplitude, 00387 and bandwidth (or noisiness) envelopes of the component, and a 4-byte 00388 label. The Breakpoints are non-uniformly distributed in time. For more 00389 information about Reassigned Bandwidth-Enhanced Analysis and the 00390 Reassigned Bandwidth-Enhanced Additive Sound Model, refer to the Loris 00391 website: www.cerlsoundgroup.org/Loris/. 00392 */ 00393 00394 double partial_startTime( const Partial * p ); 00395 /* Return the start time (seconds) for the specified Partial. 00396 */ 00397 00398 double partial_endTime( const Partial * p ); 00399 /* Return the end time (seconds) for the specified Partial. 00400 */ 00401 00402 double partial_duration( const Partial * p ); 00403 /* Return the duration (seconds) for the specified Partial. 00404 */ 00405 00406 double partial_initialPhase( const Partial * p ); 00407 /* Return the initial phase (radians) for the specified Partial. 00408 */ 00409 00410 int partial_label( const Partial * p ); 00411 /* Return the integer label for the specified Partial. 00412 */ 00413 00414 unsigned long partial_numBreakpoints( const Partial * p ); 00415 /* Return the number of Breakpoints in the specified Partial. 00416 */ 00417 00418 double partial_frequencyAt( const Partial * p, double t ); 00419 /* Return the frequency (Hz) of the specified Partial interpolated 00420 at a particular time. It is an error to apply this function to 00421 a Partial having no Breakpoints. 00422 */ 00423 00424 double partial_bandwidthAt( const Partial * p, double t ); 00425 /* Return the bandwidth of the specified Partial interpolated 00426 at a particular time. It is an error to apply this function to 00427 a Partial having no Breakpoints. 00428 */ 00429 00430 double partial_phaseAt( const Partial * p, double t ); 00431 /* Return the phase (radians) of the specified Partial interpolated 00432 at a particular time. It is an error to apply this function to 00433 a Partial having no Breakpoints. 00434 */ 00435 00436 double partial_amplitudeAt( const Partial * p, double t ); 00437 /* Return the (absolute) amplitude of the specified Partial interpolated 00438 at a particular time. Partials are assumed to fade out 00439 over 1 millisecond at the ends (rather than instantaneously). 00440 It is an error to apply this function to a Partial having no Breakpoints. 00441 */ 00442 00443 void partial_setLabel( Partial * p, int label ); 00444 /* Assign a new integer label to the specified Partial. 00445 */ 00446 00447 /* ---------------------------------------------------------------- */ 00448 /* Breakpoint object interface 00449 /* 00450 /* A Breakpoint represents a single breakpoint in the 00451 Partial parameter (frequency, amplitude, bandwidth) envelope. 00452 Instantaneous phase is also stored, but is only used at the onset of 00453 a partial, or when it makes a transition from zero to nonzero amplitude. 00454 00455 Loris Partials represent reassigned bandwidth-enhanced model components. 00456 A Partial consists of a chain of Breakpoints describing the time-varying 00457 frequency, amplitude, and bandwidth (noisiness) of the component. 00458 For more information about Reassigned Bandwidth-Enhanced 00459 Analysis and the Reassigned Bandwidth-Enhanced Additive Sound 00460 Model, refer to the Loris website: 00461 www.cerlsoundgroup.org/Loris/. 00462 */ 00463 00464 double breakpoint_getAmplitude( const Breakpoint * bp ); 00465 /* Return the (absolute) amplitude of the specified Breakpoint. 00466 */ 00467 00468 double breakpoint_getBandwidth( const Breakpoint * bp ); 00469 /* Return the bandwidth coefficient of the specified Breakpoint. 00470 */ 00471 00472 double breakpoint_getFrequency( const Breakpoint * bp ); 00473 /* Return the frequency (Hz) of the specified Breakpoint. 00474 */ 00475 00476 double breakpoint_getPhase( const Breakpoint * bp ); 00477 /* Return the phase (radians) of the specified Breakpoint. 00478 */ 00479 00480 void breakpoint_setAmplitude( Breakpoint * bp, double a ); 00481 /* Assign a new (absolute) amplitude to the specified Breakpoint. 00482 */ 00483 00484 void breakpoint_setBandwidth( Breakpoint * bp, double bw ); 00485 /* Assign a new bandwidth coefficient to the specified Breakpoint. 00486 */ 00487 00488 void breakpoint_setFrequency( Breakpoint * bp, double f ); 00489 /* Assign a new frequency (Hz) to the specified Breakpoint. 00490 */ 00491 00492 void breakpoint_setPhase( Breakpoint * bp, double phi ); 00493 /* Assign a new phase (radians) to the specified Breakpoint. 00494 */ 00495 00496 /* ---------------------------------------------------------------- */ 00497 /* non-object-based procedures 00498 /* 00499 /* Operations in Loris that need not be accessed though object 00500 interfaces are represented as simple functions. 00501 */ 00502 00503 void channelize( PartialList * partials, 00504 LinearEnvelope * refFreqEnvelope, int refLabel ); 00505 /* Label Partials in a PartialList with the integer nearest to 00506 the amplitude-weighted average ratio of their frequency envelope 00507 to a reference frequency envelope. The frequency spectrum is 00508 partitioned into non-overlapping channels whose time-varying 00509 center frequencies track the reference frequency envelope. 00510 The reference label indicates which channel's center frequency 00511 is exactly equal to the reference envelope frequency, and other 00512 channels' center frequencies are multiples of the reference 00513 envelope frequency divided by the reference label. Each Partial 00514 in the PartialList is labeled with the number of the channel 00515 that best fits its frequency envelope. The quality of the fit 00516 is evaluated at the breakpoints in the Partial envelope and 00517 weighted by the amplitude at each breakpoint, so that high- 00518 amplitude breakpoints contribute more to the channel decision. 00519 Partials are labeled, but otherwise unmodified. In particular, 00520 their frequencies are not modified in any way. 00521 */ 00522 00523 void collate( PartialList * partials ); 00524 /* Collate unlabeled (zero-labeled) Partials into the smallest-possible 00525 number of Partials that does not combine any overlapping Partials. 00526 Collated Partials appear at the end of the sequence, after all 00527 labeled Partials. 00528 */ 00529 00530 LinearEnvelope * 00531 createFreqReference( PartialList * partials, 00532 double minFreq, double maxFreq, long numSamps ); 00533 /* Return a newly-constructed LinearEnvelope using the legacy 00534 FrequencyReference class. The envelope will have approximately 00535 the specified number of samples. The specified number of samples 00536 must be greater than 1. Uses the FundamentalEstimator 00537 (FundamentalFromPartials) class to construct an estimator of 00538 fundamental frequency, configured to emulate the behavior of 00539 the FrequencyReference class in Loris 1.4-1.5.2. If numSamps 00540 is zero, construct the reference envelope from fundamental 00541 estimates taken every five milliseconds. 00542 00543 For simple sounds, this frequency reference may be a 00544 good first approximation to a reference envelope for 00545 channelization (see channelize()). 00546 00547 Clients are responsible for disposing of the newly-constructed 00548 LinearEnvelope. 00549 */ 00550 00551 LinearEnvelope * 00552 createF0Estimate( PartialList * partials, double minFreq, double maxFreq, 00553 double interval ); 00554 /* Return a newly-constructed LinearEnvelope that estimates 00555 the time-varying fundamental frequency of the sound 00556 represented by the Partials in a PartialList. This uses 00557 the FundamentalEstimator (FundamentalFromPartials) 00558 class to construct an estimator of fundamental frequency, 00559 and returns a LinearEnvelope that samples the estimator at the 00560 specified time interval (in seconds). Default values are used 00561 to configure the estimator. Only estimates in the specified 00562 frequency range will be considered valid, estimates outside this 00563 range will be ignored. 00564 00565 Clients are responsible for disposing of the newly-constructed 00566 LinearEnvelope. 00567 */ 00568 00569 void dilate( PartialList * partials, 00570 const double * initial, const double * target, int npts ); 00571 /* Dilate Partials in a PartialList according to the given 00572 initial and target time points. Partial envelopes are 00573 stretched and compressed so that temporal features at 00574 the initial time points are aligned with the final time 00575 points. Time points are sorted, so Partial envelopes are 00576 are only stretched and compressed, but breakpoints are not 00577 reordered. Duplicate time points are allowed. There must be 00578 the same number of initial and target time points. 00579 */ 00580 00581 void distill( PartialList * partials ); 00582 /* Distill labeled (channelized) Partials in a PartialList into a 00583 PartialList containing at most one Partial per label. Unlabeled 00584 (zero-labeled) Partials are left unmodified at the end of the 00585 distilled Partials. 00586 */ 00587 00588 void exportAiff( const char * path, const double * buffer, 00589 unsigned int bufferSize, double samplerate, int bitsPerSamp ); 00590 /* Export mono audio samples stored in an array of size bufferSize to 00591 an AIFF file having the specified sample rate at the given file path 00592 (or name). The floating point samples in the buffer are clamped to the 00593 range (-1.,1.) and converted to integers having bitsPerSamp bits. 00594 */ 00595 00596 void exportSdif( const char * path, PartialList * partials ); 00597 /* Export Partials in a PartialList to a SDIF file at the specified 00598 file path (or name). SDIF data is described by RBEM and RBEL 00599 matrices. 00600 For more information about SDIF, see the SDIF web site at: 00601 www.ircam.fr/equipes/analyse-synthese/sdif/ 00602 */ 00603 00604 void exportSpc( const char * path, PartialList * partials, double midiPitch, 00605 int enhanced, double endApproachTime ); 00606 /* Export Partials in a PartialList to a Spc file at the specified file 00607 path (or name). The fractional MIDI pitch must be specified. The 00608 enhanced parameter defaults to true (for bandwidth-enhanced spc files), 00609 but an be specified false for pure-sines spc files. The endApproachTime 00610 parameter is in seconds. A nonzero endApproachTime indicates that the plist does 00611 not include a release, but rather ends in a static spectrum corresponding 00612 to the final breakpoint values of the partials. The endApproachTime 00613 specifies how long before the end of the sound the amplitude, frequency, 00614 and bandwidth values are to be modified to make a gradual transition to 00615 the static spectrum. 00616 */ 00617 00618 /* Apply a reference Partial to fix the frequencies of Breakpoints 00619 whose amplitude is below threshold_dB. 0 harmonifies full-amplitude 00620 Partials, to apply only to quiet Partials, specify a lower 00621 threshold like -90). The reference Partial is the first Partial 00622 in the PartialList labeled refLabel (usually 1). The LinearEnvelope 00623 is a time-varying weighting on the harmonifing process. When 1, 00624 harmonic frequencies are used, when 0, breakpoint frequencies are 00625 unmodified. 00626 */ 00627 void harmonify( PartialList * partials, long refLabel, 00628 const LinearEnvelope * env, double threshold_dB ); 00629 00630 unsigned int importAiff( const char * path, double * buffer, unsigned int bufferSize, 00631 double * samplerate ); 00632 /* Import audio samples stored in an AIFF file at the given file 00633 path (or name). The samples are converted to floating point 00634 values on the range (-1.,1.) and stored in an array of doubles. 00635 The value returned is the number of samples in buffer, and it is at 00636 most bufferSize. If samplerate is not a NULL pointer, 00637 then, on return, it points to the value of the sample rate (in 00638 Hz) of the AIFF samples. The AIFF file must contain only a single 00639 channel of audio data. The prior contents of buffer, if any, are 00640 overwritten. 00641 */ 00642 00643 void importSdif( const char * path, PartialList * partials ); 00644 /* Import Partials from an SDIF file at the given file path (or 00645 name), and append them to a PartialList. 00646 */ 00647 00648 void importSpc( const char * path, PartialList * partials ); 00649 /* Import Partials from an Spc file at the given file path (or 00650 name), and return them in a PartialList. 00651 */ 00652 00653 void morph( const PartialList * src0, const PartialList * src1, 00654 const LinearEnvelope * ffreq, 00655 const LinearEnvelope * famp, 00656 const LinearEnvelope * fbw, 00657 PartialList * dst ); 00658 /* Morph labeled Partials in two PartialLists according to the 00659 given frequency, amplitude, and bandwidth (noisiness) morphing 00660 envelopes, and append the morphed Partials to the destination 00661 PartialList. Loris morphs Partials by interpolating frequency, 00662 amplitude, and bandwidth envelopes of corresponding Partials in 00663 the source PartialLists. For more information about the Loris 00664 morphing algorithm, see the Loris website: 00665 www.cerlsoundgroup.org/Loris/ 00666 */ 00667 00668 void morphWithReference( const PartialList * src0, 00669 const PartialList * src1, 00670 long src0RefLabel, 00671 long src1RefLabel, 00672 const LinearEnvelope * ffreq, 00673 const LinearEnvelope * famp, 00674 const LinearEnvelope * fbw, 00675 PartialList * dst ); 00676 /* Morph labeled Partials in two PartialLists according to the 00677 given frequency, amplitude, and bandwidth (noisiness) morphing 00678 envelopes, and append the morphed Partials to the destination 00679 PartialList. Specify the labels of the Partials to be used as 00680 reference Partial for the two morph sources. The reference 00681 partial is used to compute frequencies for very low-amplitude 00682 Partials whose frequency estimates are not considered reliable. 00683 The reference Partial is considered to have good frequency 00684 estimates throughout. A reference label of 0 indicates that 00685 no reference Partial should be used for the corresponding 00686 morph source. 00687 00688 Loris morphs Partials by interpolating frequency, 00689 amplitude, and bandwidth envelopes of corresponding Partials in 00690 the source PartialLists. For more information about the Loris 00691 morphing algorithm, see the Loris website: 00692 www.cerlsoundgroup.org/Loris/ 00693 */ 00694 00695 void morpher_setAmplitudeShape( double shape ); 00696 /* Set the shaping parameter for the amplitude morphing 00697 function. This shaping parameter controls the slope of 00698 the amplitude morphing function, for values greater than 00699 1, this function gets nearly linear (like the old 00700 amplitude morphing function), for values much less than 00701 1 (e.g. 1E-5) the slope is gently curved and sounds 00702 pretty "linear", for very small values (e.g. 1E-12) the 00703 curve is very steep and sounds un-natural because of the 00704 huge jump from zero amplitude to very small amplitude. 00705 00706 Use LORIS_DEFAULT_AMPMORPHSHAPE to obtain the default 00707 amplitude morphing shape for Loris, (equal to 1E-5, 00708 which works well for many musical instrument morphs, 00709 unless Loris was compiled with the symbol 00710 LINEAR_AMP_MORPHS defined, in which case 00711 LORIS_DEFAULT_AMPMORPHSHAPE is equal to 00712 LORIS_LINEAR_AMPMORPHSHAPE). 00713 00714 Use LORIS_LINEAR_AMPMORPHSHAPE to approximate the linear 00715 amplitude morphs performed by older versions of Loris. 00716 00717 The amplitude shape must be positive. 00718 */ 00719 00720 extern const double LORIS_DEFAULT_AMPMORPHSHAPE; 00721 extern const double LORIS_LINEAR_AMPMORPHSHAPE; 00722 00723 void resample( PartialList * partials, double interval ); 00724 /* Resample all Partials in a PartialList using the specified 00725 sampling interval, so that the Breakpoints in the Partial 00726 envelopes will all lie on a common temporal grid. 00727 The Breakpoint times in resampled Partials will comprise a 00728 contiguous sequence of integer multiples of the sampling interval, 00729 beginning with the multiple nearest to the Partial's start time and 00730 ending with the multiple nearest to the Partial's end time. Resampling 00731 is performed in-place. 00732 00733 */ 00734 00735 void shapeSpectrum( PartialList * partials, PartialList * surface, 00736 double stretchFreq, double stretchTime ); 00737 /* Scale the amplitudes of a set of Partials by applying 00738 a spectral suface constructed from another set. 00739 Stretch the spectral surface in time and frequency 00740 using the specified stretch factors. Set the stretch 00741 factors to one for no stretching. 00742 */ 00743 00744 void sift( PartialList * partials ); 00745 /* Identify overlapping Partials having the same (nonzero) 00746 label. If any two partials with same label 00747 overlap in time, set the label of the weaker 00748 (having less total energy) partial to zero. 00749 00750 */ 00751 00752 unsigned int 00753 synthesize( const PartialList * partials, 00754 double * buffer, unsigned int bufferSize, 00755 double srate ); 00756 /* Synthesize Partials in a PartialList at the given sample 00757 rate, and store the (floating point) samples in a buffer of 00758 size bufferSize. The buffer is neither resized nor 00759 cleared before synthesis, so newly synthesized samples are 00760 added to any previously computed samples in the buffer, and 00761 samples beyond the end of the buffer are lost. Return the 00762 number of samples synthesized, that is, the index of the 00763 latest sample in the buffer that was modified. 00764 */ 00765 00766 /* ---------------------------------------------------------------- */ 00767 /* utility functions 00768 /* 00769 /* Operations for transforming and manipulating collections 00770 of Partials. 00771 */ 00772 00773 double avgAmplitude( const Partial * p ); 00774 /* Return the average amplitude over all Breakpoints in this Partial. 00775 Return zero if the Partial has no Breakpoints. 00776 */ 00777 00778 double avgFrequency( const Partial * p ); 00779 /* Return the average frequency over all Breakpoints in this Partial. 00780 Return zero if the Partial has no Breakpoints. 00781 */ 00782 00783 void copyIf( const PartialList * src, PartialList * dst, 00784 int ( * predicate )( const Partial * p, void * data ), 00785 void * data ); 00786 /* Append copies of Partials in the source PartialList satisfying the 00787 specified predicate to the destination PartialList. The source list 00788 is unmodified. The data parameter can be used to 00789 supply extra user-defined data to the function. Pass 0 if no 00790 additional data is needed. 00791 */ 00792 00793 void copyLabeled( const PartialList * src, long label, PartialList * dst ); 00794 /* Append copies of Partials in the source PartialList having the 00795 specified label to the destination PartialList. The source list 00796 is unmodified. 00797 */ 00798 00799 void crop( PartialList * partials, double t1, double t2 ); 00800 /* Trim Partials by removing Breakpoints outside a specified time span. 00801 Insert a Breakpoint at the boundary when cropping occurs. Remove 00802 any Partials that are left empty after cropping (Partials having no 00803 Breakpoints between t1 and t2). 00804 */ 00805 00806 void extractIf( PartialList * src, PartialList * dst, 00807 int ( * predicate )( const Partial * p, void * data ), 00808 void * data ); 00809 /* Remove Partials in the source PartialList satisfying the 00810 specified predicate from the source list and append them to 00811 the destination PartialList. The data parameter can be used to 00812 supply extra user-defined data to the function. Pass 0 if no 00813 additional data is needed. 00814 */ 00815 00816 void extractLabeled( PartialList * src, long label, PartialList * dst ); 00817 /* Remove Partials in the source PartialList having the specified 00818 label from the source list and append them to the destination 00819 PartialList. 00820 */ 00821 00822 void fixPhaseAfter( PartialList * partials, double time ); 00823 /* Recompute phases of all Breakpoints later than the specified 00824 time so that the synthesized phases of those later Breakpoints 00825 matches the stored phase, as long as the synthesized phase at 00826 the specified time matches the stored (not recomputed) phase. 00827 00828 Phase fixing is only applied to non-null (nonzero-amplitude) 00829 Breakpoints, because null Breakpoints are interpreted as phase 00830 reset points in Loris. If a null is encountered, its phase is 00831 corrected from its non-Null successor, if it has one, otherwise 00832 it is unmodified. 00833 */ 00834 00835 void fixPhaseAt( PartialList * partials, double time ); 00836 /* Recompute phases of all Breakpoints in a Partial 00837 so that the synthesized phases match the stored phases, 00838 and the synthesized phase at (nearest) the specified 00839 time matches the stored (not recomputed) phase. 00840 00841 Backward phase-fixing stops if a null (zero-amplitude) 00842 Breakpoint is encountered, because nulls are interpreted as 00843 phase reset points in Loris. If a null is encountered, the 00844 remainder of the Partial (the front part) is fixed in the 00845 forward direction, beginning at the start of the Partial. 00846 Forward phase fixing is only applied to non-null 00847 (nonzero-amplitude) Breakpoints. If a null is encountered, 00848 its phase is corrected from its non-Null successor, if 00849 it has one, otherwise it is unmodified. 00850 */ 00851 00852 void fixPhaseBefore( PartialList * partials, double time ); 00853 /* Recompute phases of all Breakpoints earlier than the specified 00854 time so that the synthesized phases of those earlier Breakpoints 00855 matches the stored phase, and the synthesized phase at the 00856 specified time matches the stored (not recomputed) phase. 00857 00858 Backward phase-fixing stops if a null (zero-amplitude) Breakpoint 00859 is encountered, because nulls are interpreted as phase reset 00860 points in Loris. If a null is encountered, the remainder of the 00861 Partial (the front part) is fixed in the forward direction, 00862 beginning at the start of the Partial. 00863 */ 00864 00865 void fixPhaseBetween( PartialList * partials, double tbeg, double tend ); 00866 /* 00867 Fix the phase travel between two times by adjusting the 00868 frequency and phase of Breakpoints between those two times. 00869 00870 This algorithm assumes that there is nothing interesting 00871 about the phases of the intervening Breakpoints, and modifies 00872 their frequencies as little as possible to achieve the correct 00873 amount of phase travel such that the frequencies and phases at 00874 the specified times match the stored values. The phases of all 00875 the Breakpoints between the specified times are recomputed. 00876 */ 00877 00878 void fixPhaseForward( PartialList * partials, double tbeg, double tend ); 00879 /* Recompute phases of all Breakpoints later than the specified 00880 time so that the synthesized phases of those later Breakpoints 00881 matches the stored phase, as long as the synthesized phase at 00882 the specified time matches the stored (not recomputed) phase. 00883 Breakpoints later than tend are unmodified. 00884 00885 Phase fixing is only applied to non-null (nonzero-amplitude) 00886 Breakpoints, because null Breakpoints are interpreted as phase 00887 reset points in Loris. If a null is encountered, its phase is 00888 corrected from its non-Null successor, if it has one, otherwise 00889 it is unmodified. 00890 */ 00891 00892 int forEachBreakpoint( Partial * p, 00893 int ( * func )( Breakpoint * p, double time, void * data ), 00894 void * data ); 00895 /* Apply a function to each Breakpoint in a Partial. The function 00896 is called once for each Breakpoint in the source Partial. The 00897 function may modify the Breakpoint (but should not otherwise attempt 00898 to modify the Partial). The data parameter can be used to supply extra 00899 user-defined data to the function. Pass 0 if no additional data is needed. 00900 The function should return 0 if successful. If the function returns 00901 a non-zero value, then forEachBreakpoint immediately returns that value 00902 without applying the function to any other Breakpoints in the Partial. 00903 forEachBreakpoint returns zero if all calls to func return zero. 00904 */ 00905 00906 int forEachPartial( PartialList * src, 00907 int ( * func )( Partial * p, void * data ), 00908 void * data ); 00909 /* Apply a function to each Partial in a PartialList. The function 00910 is called once for each Partial in the source PartialList. The 00911 function may modify the Partial (but should not attempt to modify 00912 the PartialList). The data parameter can be used to supply extra 00913 user-defined data to the function. Pass 0 if no additional data 00914 is needed. The function should return 0 if successful. If the 00915 function returns a non-zero value, then forEachPartial immediately 00916 returns that value without applying the function to any other 00917 Partials in the PartialList. forEachPartial returns zero if all 00918 calls to func return zero. 00919 */ 00920 00921 double peakAmplitude( const Partial * p ); 00922 /* Return the maximum amplitude achieved by a Partial. 00923 */ 00924 00925 void removeIf( PartialList * src, 00926 int ( * predicate )( const Partial * p, void * data ), 00927 void * data ); 00928 /* Remove from a PartialList all Partials satisfying the 00929 specified predicate. The data parameter can be used to 00930 supply extra user-defined data to the function. Pass 0 if no 00931 additional data is needed. 00932 */ 00933 00934 void removeLabeled( PartialList * src, long label ); 00935 /* Remove from a PartialList all Partials having the specified label. 00936 */ 00937 00938 void scaleAmplitude( PartialList * partials, LinearEnvelope * ampEnv ); 00939 /* Scale the amplitude of the Partials in a PartialList according 00940 to an envelope representing a time-varying amplitude scale value. 00941 */ 00942 00943 void scaleAmp( PartialList * partials, LinearEnvelope * ampEnv ); 00944 /* Bad old name for scaleAmplitude. 00945 */ 00946 00947 void scaleBandwidth( PartialList * partials, LinearEnvelope * bwEnv ); 00948 /* Scale the bandwidth of the Partials in a PartialList according 00949 to an envelope representing a time-varying bandwidth scale value. 00950 */ 00951 00952 void scaleFrequency( PartialList * partials, LinearEnvelope * freqEnv ); 00953 /* Scale the frequency of the Partials in a PartialList according 00954 to an envelope representing a time-varying frequency scale value. 00955 */ 00956 00957 void scaleNoiseRatio( PartialList * partials, LinearEnvelope * noiseEnv ); 00958 /* Scale the relative noise content of the Partials in a PartialList 00959 according to an envelope representing a (time-varying) noise energy 00960 scale value. 00961 */ 00962 00963 void setBandwidth( PartialList * partials, LinearEnvelope * bwEnv ); 00964 /* Set the bandwidth of the Partials in a PartialList according 00965 to an envelope representing a time-varying bandwidth value. 00966 */ 00967 00968 void shiftPitch( PartialList * partials, LinearEnvelope * pitchEnv ); 00969 /* Shift the pitch of all Partials in a PartialList according to 00970 the given pitch envelope. The pitch envelope is assumed to have 00971 units of cents (1/100 of a halfstep). 00972 */ 00973 00974 void shiftTime( PartialList * partials, double offset ); 00975 /* Shift the time of all the Breakpoints in a Partial by a 00976 constant amount. 00977 */ 00978 00979 void sortByLabel( PartialList * partials ); 00980 /* Sort the Partials in a PartialList in order of increasing label. 00981 The sort is stable; Partials having the same label are not 00982 reordered. 00983 */ 00984 00985 void timeSpan( PartialList * partials, double * tmin, double * tmax ); 00986 /* Return the minimum start time and maximum end time 00987 in seconds of all Partials in this PartialList. The v 00988 times are returned in the (non-null) pointers tmin 00989 and tmax. 00990 */ 00991 00992 double weightedAvgFrequency( const Partial * p ); 00993 /* Return the average frequency over all Breakpoints in this Partial, 00994 weighted by the Breakpoint amplitudes. Return zero if the Partial 00995 has no Breakpoints. 00996 */ 00997 00998 /* ---------------------------------------------------------------- */ 00999 /* Notification and exception handlers 01000 /* 01001 /* An exception handler and a notifier may be specified. Both 01002 are functions taking a const char * argument and returning 01003 void. 01004 */ 01005 01006 void setExceptionHandler( void(*f)(const char *) ); 01007 /* Specify a function to call when reporting exceptions. The 01008 function takes a const char * argument, and returns void. 01009 */ 01010 01011 void setNotifier( void(*f)(const char *) ); 01012 /* Specify a notification function. The function takes a 01013 const char * argument, and returns void. 01014 */ 01015 01016 #if defined(__cplusplus) 01017 } /* extern "C" */ 01018 #endif 01019 01020 #endif /* ndef INCLUDE_LORIS_H */