/* $Id: Pm.h,v 1.15 1999/10/14 18:22:59 schwarz Exp $ LIBRARY Pm DESCRIPTION Pm --- A Library for Additive Analysis/Transformation/Synthesis Complete documentation of Pm can be found at http://www.ircam.fr/anasyn/pm. Équipe Analyse-Synthèse / Analysis-Synthesis Team Copyright (C) 1999 IRCAM - Centre Georges Pompidou INTERNAL DATA FORMAT There's three things to note regarding the interpretation of the PmPartialSet data structure:
  • index is harmonic number - 1 (This is referred to as "internal format" in PmReadPartialSet2 and PmWritePartialSet2.)
  • The harmonic partial i is at index [i - 1], a sort of expanded format, as opposed to the direct, packed format after loading. (This is called "Format interne de "synt" et des programmes de control".) The conversion between the packed and expanded format is done in PmReadPartialSet2 by pm_ext_to_intSYNT, and vice versa in PmWritePartialSet2 by pm_intSYNT_to_ext_copy.
  • Finally, after analysis (using PmDetectSpectralPeaks2 and PmSeeve), the generated partial data (freq/ampl/phase [i]) is not at the same array positions as their indices index [i]! Instead, index is an array of indirection: freq of partial i in PmPartialSet p is at p->freq [p->index [i]]! LOG $Log: Pm.h,v $ Revision 1.15 1999/10/14 18:22:59 schwarz Added functions PmLoadBreakPoint2, PmGetBreakPointVect(X|Y), necessary for PmDoF0Smooth. Fixed bug in PmSdifReadBreakPoint. Revision 1.14 1999/10/07 12:54:42 schwarz Added enum PmFormat for the different file formats known to Pm. Its members are still called PM_ASCII, PM_SDIF_*, etc. but a proper typedef is cleaner than the #defines before. Added PmWriteOneBreakPoint, PmSdifWriteOneBreakPoint. Revision 1.13 1999/10/01 09:51:27 schwarz Added Pm[Sdif]WriteOneBreakPoint, completed version string. Revision 1.12 1999/09/27 13:36:25 schwarz Fixed bug in synthesis with ignored buffer size. New PmAddSynt works like fwrite now. Moved init of sinus table to PmAddSyntInit, auto- matically called by PmInit. Revision 1.11 1999/09/23 16:12:06 schwarz Added sdif breakpoint i/o, functions to load/save a whole bpf in one go, and the convenient PmLoadBreakPointOrConst. Moved file type checking into the library. Revision 1.10 1999/09/22 15:03:15 schwarz Reconciled changes from Ivan (perry) and Adrien (lefevre). Revision 1.9 1999/09/22 13:53:41 lefevre Today, add project_preincluded.h and XpGuiCalls.h for CrossPlatform compatibility. Revision 1.8 1999/09/22 12:10:41 perry Added function PmReadPeaksSet2 to allow picstosdif convertor. Revision 1.7 1999/08/26 15:34:24 schwarz Sorry, had to put return types on same line with prototypes for cocoon to recognise them. Revision 1.6 1999/08/09 19:38:34 schwarz Added pmPrintPartial. Revision 1.5 1999/08/09 15:05:48 schwarz Documentation of PmPartialSet semantics. Revision 1.4 1999/07/22 19:58:17 schwarz Sdif input/output for Pm. This entails new functions Pm(De)Init and Pm(Open|Close)File, which must be used. As added value, by using PmOpenFile, you gain automatic compression/decompression using gzip of the output and input files. Revision 1.3 1998/05/14 09:56:59 schwarz Changed definition of PM_MAXFLOAT / PM_MINFLOAT. Made includeable by C++. Added prototypes for functions PmGetAllPartial(Freq|Ampl|Phase) to access the complete partial data arrays. Revision 1.2 1997/05/21 13:17:36 woehrman Back to original API. Revision 1.1 1997/05/14 14:01:23 woehrman Pm for MAC and UNIX version 1.0dev. Compiles under UNIX. MAC? First version under CVS after Garcia's sources. */ #ifndef _PARAM_H_ #define _PARAM_H_ #ifdef __cplusplus extern "C" { #endif /* Les include */ /* ADRIEN_MODIF #include pour avoir les macro MAXFLOAT et MINFLOAT */ #include /* pour avoir les macro MAXFLOAT et MINFLOAT */ #include /* pour avoir la definition de FILE */ /* Version */ #ifndef _Pm_USER_ # if HOST_OS_MAC # define _Pm_USER_ "unknown Mac user" # elseif HOST_OS_WIN32 # define _Pm_USER_ "unknown Windows user" # else # define _Pm_USER_ "unknown Unix user" # endif #endif #define PmVersionString "Pm library version " _Pm_VERSION_ \ " by Adrien Lefevre (MAC), Diemo Schwarz, Rolf Woehrmann (UNIX), " \ "after Guillermo Garcia.\n" \ "Compiled " __DATE__ " " __TIME__" by " _Pm_USER_ ".\n" /* // DATA GROUP: Basic Data Types */ /* Macros pour les types propres a la bibliotheque */ #define PM_NB_OF_TYPES 7 #define PM_CHAR 0 #define PM_SHORT 1 #define PM_INT 2 #define PM_LONG 3 #define PM_FLOAT 4 #define PM_DOUBLE 5 #define PM_PARTIAL 6 /* Macros pour les modes d'acces fichier propres a la bibliotheque et les formats */ #define PM_READ 0 #define PM_WRITE 1 #define PM_APPEND 2 #define PM_NMODE 3 /* number of file modes */ /* File formats known to Pm */ typedef enum { PM_ASCII, PM_BIN, PM_SDIF, /* default, same as PM_SDIF_TRACKS */ PM_SDIF_TRACKS = PM_SDIF, PM_SDIF_HARMONICS, PM_SDIF_PEAKS, PM_ASCII_PEAKS, /* old ascii peaks file */ PM_BIN_PEAKS, /* old bin peaks file */ PM_SDIF_F0, /* f0 SDIF break point function file */ PM_SDIF_BPF, /* general SDIF bpf file */ PM_ASCII_BPF, /* ASCII break point function file */ PM_BIN_BPF, /* binary break point function file */ PM_COMPRESSED, /* flag for gz compressed files */ PM_MAX_FORMAT /* number of formats, must always be last! */ } PmFormat; typedef int PmParamSetId; /* // DATA GROUP: Structures generiques */ typedef struct _pmFrame { float time; /* caracteristiques locales des paramSets */ struct _ParamSetLocalAttr { int allocSize; int nb; void *data; } *paramSet; } *pmFrame; typedef struct _pmFrameBlock { int nbOfFrames; /* nombre de trames du bloc */ int nbOfAllocParamSets; pmFrame *frame; /* pointeur vers la premiere trame du bloc */ struct _pmFrameBlock *prev; /* pointeur vers le bloc precedent */ struct _pmFrameBlock *next; /* pointeur vers le bloc suivant */ } *pmFrameBlock; typedef struct _PmFrameSet { /* un FrameSet est defini dans l'intervalle [beginTime - endTime] */ float beginTime; /* beginTime <= premiere trame */ float endTime; /* endTime >= derniere trame */ int nbOfFrames; /* nombre de trames utilisees */ int nbOfAllocFrames; /* nombre de trames allouees */ int nbOfFrameBlocks; pmFrameBlock firstFrameBlock; /* le premier bloc de trames */ PmParamSetId *freeParamSetIds; /* Ids non utilises */ PmParamSetId *activeParamSetIds; /* Ids utilises */ int *sizeofType; /* sizeof de chaque type connu de la bibliotheque */ int nbOfTypes; /* nombre de types connus */ /* caracteristiques globales des paramSets */ int nbOfParamSets; int nbOfAllocParamSets; struct _ParamSetGlobalAttr { int type; char *name; int elemSize; } *paramSet; } *PmFrameSet; /* // DATA GROUP: Structures specifiques */ /* PmPartialSet Pour l'instant on garde la compatibilite avec l'ancienne structure des partiels, sauf pour l'element "float_index" qui est elimine, et l'element "tSec" qui devient "time" DS: TODO: add field "flags", as bitfield with bits: typedef enum { pmSortedIndex = 1, // partial set is sorted by index pmSortedFreq = 2, // partial set is sorted by frequency pmHarmonicFormat = 4 // partial set is in "internal" format, // i.e. index [i] = i } PmFlags; and field nbpresent which counts existing partials, and keep them up-to-date when loading and modifying partials. */ typedef struct _pmPartial { float time; int nb; int allocSize; int *index; float *freq; float *ampl; float *phase; float *confidence; } pmPartial, *PmPartialSet; typedef struct _PmBreakPoint { int allocSize; int nb; float *x; float *y; } *PmBreakPoint; /* // FUNCTION GROUP: Procedure de liberation de la memoire static */ void PmCed_FreeStatic(void); void PmFftMayer_FreeStatic(void); void Pmlo_FreeStatic(void); void PmPeaks_FreeStatic(void); void PmSynth_FreeStatic(void); /* // FUNCTION GROUP: Declarations des fonctions de la bibliotheque */ /* // FUNCTION GROUP: Initialisation and File Handling */ int PmInit (void); int PmDeInit (void); FILE *PmOpenFile (const char *name, int mode, PmFormat format); void PmCloseFile (FILE *f, PmFormat format); char *PmGetExtension (const char *name); PmFormat PmNameToFormat (char *name); PmFormat PmGetFileFormat (const char *name, PmFormat defnonsdif, PmFormat defsdif); void PmCheckFileType (char* inFileName, PmFormat* ioFileType); int PmGetFilePos (FILE *f, PmFormat format); int PmIsSdifFile (const char *name); /* // FUNCTION GROUP: Creation et Destruction */ PmFrameSet PmCreateFrameSet( int, int ); pmFrameBlock pmCreateFrameBlock( int, int ); pmFrame pmCreateFrame( int ); PmParamSetId PmCreateParamSet( PmFrameSet, int, int, char * ); PmFrameSet PmReallocFrameSet( PmFrameSet, int, int ); void PmFreeParamSet( PmFrameSet, PmParamSetId ); void pmFreeFrame( pmFrame ); void pmFreeFrameBlock( PmFrameSet, pmFrameBlock ); void PmFreeFrameSet( PmFrameSet ); /* // FUNCTION GROUP: Acces aux parametres */ pmFrame pm_search_frame( PmFrameSet, int, pmFrameBlock* ); int pm_search_frame_by_time( PmFrameSet, float, pmFrame* ); int pm_search_frame_index( PmFrameSet, float, pmFrameBlock* ); int pm_search_rel_frame_index( PmFrameSet, int, pmFrameBlock * ); int PmGetNbOfFrames( PmFrameSet ); void PmDecrNbOfFrames( PmFrameSet, int ); int PmGetNbOfParamSets( PmFrameSet ); int PmGetNbOfAllocParamSets( PmFrameSet ); PmParamSetId PmGetActiveParamSetId( PmFrameSet, int ); float PmGetFrameTime( PmFrameSet, int ); float PmGetBeginTime( PmFrameSet ); float PmGetEndTime( PmFrameSet ); int PmGetParamSetAllocSize( PmFrameSet, int, PmParamSetId ); int PmGetParamSetNb( PmFrameSet, int, PmParamSetId ); void * PmGetParamSetPtr( PmFrameSet, int, PmParamSetId ); int PmGetParamSetType( PmFrameSet, PmParamSetId ); char * PmGetParamSetName( PmFrameSet, PmParamSetId ); int PmGetParamSetElemSize( PmFrameSet, PmParamSetId ); void PmPutFrameTime( PmFrameSet, int, float ); void pm_put_frame_time( PmFrameSet, pmFrame, float ); void PmPutBeginTime( PmFrameSet, float ); void PmPutEndTime( PmFrameSet, float ); void * pmGetFrameDataPtr( pmFrame, PmParamSetId ); int pmGetFrameDataNb( pmFrame, PmParamSetId ); int pmGetFrameDataAllocSize( pmFrame, PmParamSetId ); void pmPutFrameDataNb( pmFrame, PmParamSetId, int ); int PmGetParamSet( PmFrameSet, int, PmParamSetId, void *, int ); int PmPutParamSet( PmFrameSet, int, PmParamSetId, void *, int ); int PmAddFrameData( PmFrameSet, float, PmParamSetId*, void **, int *, int ); int PmGetFrameData( PmFrameSet, int, float*, PmParamSetId*, void **, int *, int ); /* // FUNCTION GROUP: Edition */ PmFrameSet PmCutFrameSet( PmFrameSet, float, float ); int PmInsertFrameSet( PmFrameSet, PmFrameSet, float ); PmFrameSet PmCopyFrameSet( PmFrameSet, float, float ); int pmCopyFrame( PmFrameSet, pmFrame, pmFrame ); int PmShiftFrameSet( PmFrameSet, int ); /* // FUNCTION GROUP: traitement */ int PmSmoothParamSet( PmFrameSet, PmParamSetId, float, float ); void PmReverseFrameSet( PmFrameSet, float, float ); /* // FUNCTION GROUP: Partiels */ PmPartialSet PmCreatePartialSet( int ); PmPartialSet PmReallocPartialSet( PmPartialSet, int ); /* corr nombres a partir de aqui */ void PmFreePartialSet( PmPartialSet ); int PmCopyPartialSet(PmPartialSet, PmPartialSet); int PmReadPartialSet( FILE *, PmPartialSet, PmFormat); int PmReadPartialSet2( FILE *, PmPartialSet, PmFormat, int); int PmReadPeaksSet2( FILE *, PmPartialSet, PmFormat, int, float); int PmWritePartialSet( FILE *, PmPartialSet, PmFormat); int PmWritePartialSet2( FILE *, PmPartialSet, PmFormat, int); void pmPrintPartial (FILE *f, PmPartialSet p, char *msg); int PmDetectSpectralPeaks( float *, PmPartialSet, float, int, int); int PmDetectSpectralPeaks2( float *, PmPartialSet, float, int, int, float ); int PmSeeve( PmPartialSet, PmPartialSet, float, float, float, int ); int PmCedEnv( PmPartialSet, float *, float, int, int, float ); int PmCedCoef( PmPartialSet, float *, float, int, float ); /* // FUNCTION GROUP: Acces aux donnees */ void PmPutPartialSetTime( PmPartialSet, float ); float PmGetPartialSetTime( PmPartialSet ); void PmPutPartialSetNb( PmPartialSet, float ); int PmGetPartialSetNb( PmPartialSet ); int PmGetPartialSetAllocSize( PmPartialSet ); int PmAddPartial( PmPartialSet, int, float, float, float ); int PmDeletePartial( PmPartialSet, int ); int PmDeleteSubPartialSet( PmPartialSet, int*, int ); int PmGetPartialIndex( PmPartialSet, int ); void PmPutPartialFreq( PmPartialSet, int, float ); float PmGetPartialFreq( PmPartialSet, int ); float * PmGetAllPartialFreq( PmPartialSet ); void PmCopyAllPartialFreq (PmPartialSet ps, float *dest); void PmPutPartialAmpl( PmPartialSet, int, float ); float PmGetPartialAmpl( PmPartialSet, int ); float * PmGetAllPartialAmpl( PmPartialSet ); void PmCopyAllPartialAmpl (PmPartialSet ps, float *dest); void PmPutPartialPhase( PmPartialSet, int, float ); float PmGetPartialPhase( PmPartialSet, int ); float * PmGetAllPartialPhase( PmPartialSet ); void PmCopyAllPartialPhase (PmPartialSet ps, float *dest); /* // FUNCTION GROUP: Passage du format externe a l'interne et viceversa */ int pm_intSYNT_to_ext_copy( PmPartialSet in, PmPartialSet ext, float * findex ); int pm_ext_to_intSYNT( PmPartialSet ); /* Check if partial in internal format is present. */ #define pmPartialExists(p, i) ((p)->index [i] != -1) /* // FUNCTION GROUP: Fonctions auxiliaires de traitement */ float PmUnwrapPhase( float, float, float, float, float ); float PmWrapPhase( float ); int PmPresentPartial( PmPartialSet, int ); /* // FUNCTION GROUP: Fonctions de traitement */ int PmFreqTransp( PmPartialSet, PmPartialSet, PmPartialSet, PmPartialSet, float, float ); int PmIvarFreqTransp(PmPartialSet,PmPartialSet,PmPartialSet,PmPartialSet, PmBreakPoint,PmBreakPoint); int PmFvarFreqTransp(PmPartialSet,PmPartialSet,PmPartialSet,PmPartialSet, PmBreakPoint,PmBreakPoint); int PmTimeScaling( PmPartialSet, PmPartialSet, PmPartialSet, PmPartialSet, float ); int PmFadeHarmEnds(PmFrameSet, PmParamSetId, float, float, int); void pmReversePartialSet( PmPartialSet ); int PmInterpPartialSet(PmPartialSet, PmPartialSet, PmPartialSet, int); PmFrameSet PmScaleFrameSetTime(PmFrameSet, PmBreakPoint); int PmSetSpectralEnv( PmPartialSet, PmPartialSet, float *, float, float, int, int ); int PmMultSpectralEnv( PmPartialSet, PmPartialSet, float *, float, float, int, int ); int PmCopySubPartialSet( PmPartialSet, PmPartialSet, int *, int ); int PmMoveSubPartialSet( PmPartialSet, PmPartialSet, int *, int ); void PmAmplSortPartials( PmPartialSet ); void PmFreqSortPartials( PmPartialSet ); /* Synthese additive */ int PmAddSyntInit (void); int PmAddSynt( PmPartialSet, PmPartialSet, float *, int maxsize, int sample_done, float, int ); /* // FUNCTION GROUP: Fonctions pour trier des tableaux */ void pm_sort_int_array(int* , int); int pm_sort_ex_situ (const int *ind, const int num, int *perm); void pm_sort_partials(PmPartialSet); /* Resolution d'un systeme matriciel Ax = b par decomposition de Cholesky */ int pmSystchol( float *A, float *b, float *x, int p_plus_1 ); /* // FUNCTION GROUP: PmBreakPoint */ PmBreakPoint PmCreateBreakPoint( int ); PmBreakPoint PmReallocBreakPoint( PmBreakPoint, int ); void PmFreeBreakPoint( PmBreakPoint ); int PmReadBreakPoint( FILE *, PmBreakPoint, PmFormat ); void PmWriteBreakPoint( FILE *, PmBreakPoint, PmFormat ); void PmWriteOneBreakPoint (FILE *file, float x, float y, PmFormat format); /* Load bpf from file given by name in format determined by name. */ PmBreakPoint PmLoadBreakPoint (char *name); /* Load bpf from file given by name in format determined by name, return format. */ PmBreakPoint PmLoadBreakPoint2 (char *name, /*out*/ PmFormat *format); /* If nameorconst looks like a number, return a constant PmBreakPoint with that value, else, use it as filename and load a bpf from it On load, the function tries to auto-detect the file format, if it is not sdif, for now we assume PM_ASCII_BPF. [] return: A freshly created PmBreakPoint (which must be PmFreeBreakPoint'ed by the calling program) */ PmBreakPoint PmLoadBreakPointOrConst (char *nameorconst); int PmSaveBreakPoint (char *name, PmBreakPoint bp, PmFormat format); float PmEvalBreakPoint( PmBreakPoint, float ); int PmAddBreakPoint( PmBreakPoint, float, float ); void PmExtractBreakPoint( PmBreakPoint, float ); int PmGetBreakPoint( PmBreakPoint, int, float*, float* ); int PmGetBreakPointNb( PmBreakPoint ); /* Get pointer to float vector of x values (which are in ascending order). */ float *PmGetBreakPointVectX (PmBreakPoint aBP); /* Get pointer to float vector of y values. */ float *PmGetBreakPointVectY (PmBreakPoint aBP); void PmEliminateZeroValueInBreakPoint(PmBreakPoint aBP); void PmEliminateZeroValueInBreakPoint2(PmBreakPoint aBP); /* // FUNCTION GROUP: Fast Fourier Transform and window functions */ /* La fft */ void pmRealfft(float*, float*, long, int); void pmBkman(float*, long, short); void pmHamm(float*, long); void pmHann(float*, long); void pmTrian(float*, long); /* // FUNCTION GROUP: SDIF */ /* you can switch off SDIF support by defining NO_SDIF */ /* Initialize SDIF Library, called by init */ int PmSdifInit (void); /* Deinitialize SDIF Library, called by init */ int PmSdifDeInit (void); void PmSdifPrintVersion (void); /* internal */ char *pmCutSdifSelection (char *name, char *save); /* Open an SDIF file for reading, called by PmOpenFile. [return] SdifFileT*, casted to FILE* */ FILE* PmSdifOpenRead (const char *infile, int stdio, FILE *pipe, PmFormat format); /* Open an SDIF file for writing, write header and useful information in NVTs, called by PmOpenFile. [return] an SdifFileT*, casted to FILE* */ FILE *PmSdifOpenWrite (const char *infile, int stdio, FILE *pipe, PmFormat format); /* Close file */ void PmSdifClose (FILE *f); /* Get pointer pos in a file */ int PmSdifGetFilePos (FILE *f); /* Called by PmReadPartialSet when format_flag is PM_SDIF. */ int PmSdifReadFrame (FILE *file, PmPartialSet osc, int inNbPartial, PmFormat format); /* Called by PmWritePartialSet when format_flag is PM_SDIF. */ int PmSdifWriteFrame (FILE *file, PmPartialSet osc, int *perm, int nbpartial, PmFormat format); /* Called by PmReadBreakPoint when format_flag is PM_SDIF_BPF. */ int PmSdifReadBreakPoint (FILE *fp, PmBreakPoint bp, PmFormat format_flag); /* Called by PmWriteBreakPoint when format_flag is PM_SDIF_BPF. */ void PmSdifWriteBreakPoint (FILE *fp, PmBreakPoint bp, PmFormat format_flag); /* Write one break point frame only */ void PmSdifWriteOneBreakPoint (FILE *file, float x, float y, PmFormat format); /* Macros pour les valeurs de retour des fonctions de la bibliotheque */ /* Diemo Schwarz, 23.4.98: MINFLOAT generates underflow on compilation with cc on alpha. What's more, it is different from MINFLOAT on SGI. Therefore, it's better to use FLT_MIN from float.h, since it's the same on both machines. */ #if 0 /*old*/ #define PM_MAXFLOAT MAXFLOAT /* MAXFLOAT est cense etre defini dans values.h */ #define PM_MINFLOAT MINFLOAT /* MINFLOAT est cense etre defini dans values.h */ #else #define PM_MAXFLOAT FLT_MAX #define PM_MINFLOAT FLT_MIN #endif #ifndef M_PI #define M_PI 3.1415926535897932385 #endif #ifndef M_2PI #define M_2PI 6.2831853071795864769 #endif #ifndef M_PI_2 #define M_PI_2 1.5707963267948966192 #endif #ifndef M_PI_4 #define M_PI_4 0.7853981633974483096 #endif #ifndef FALSE #define FALSE 0 #endif #ifndef TRUE #define TRUE 1 #endif #ifdef __cplusplus } #endif #endif /* _PARAM_H_ */