├── stdafx.cpp ├── README.md ├── makefile.defs ├── stdafx.h ├── ReadWavFile.h ├── Pitch_to_PointProcess.h ├── RealTier.h ├── Get_Data_to_Sound.h ├── SystemData.h ├── Pitch.h ├── Sound_to_Pitch.h ├── NUMsort.cpp ├── SoundCompute.h ├── NUM2.h ├── NUM.h ├── Structure.h ├── NUM2.cpp ├── NUMinop.cpp ├── Get_Data_to_Sound.cpp ├── Pich_to_PointProcess.cpp ├── changeSound.cpp ├── RealTier.cpp ├── ReadWavFile.cpp ├── SystemData.cpp ├── Sound_to_Pitch.cpp └── Pitch.cpp /stdafx.cpp: -------------------------------------------------------------------------------- 1 | // stdafx.cpp : source file that includes just the standard includes 2 | // changeSound.pch will be the pre-compiled header 3 | // stdafx.obj will contain the pre-compiled type information 4 | 5 | #include "stdafx.h" 6 | 7 | // TODO: reference any additional headers you need in STDAFX.H 8 | // and not in this file 9 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | Voice-Morphing-Plug-in-on-Skype 2 | =============================== 3 | 4 | - Developed a software of voice morphing that could change the sound to different gender and age while making a phone call on Skype utilizing C++, Java and C#. 5 | - Created a dynamic strategy to decrease the voice morphing delay on Skype. 6 | - Devised a smoothness algorithm for voice quality improvement which improve 50% in fluency. 7 | - Designed UI and tested the range of speech morphing parameters. 8 | -------------------------------------------------------------------------------- /makefile.defs: -------------------------------------------------------------------------------- 1 | # File: makefile.defs.mingw32 2 | 3 | # System: MinGW 4 | # Feng WenJie, 3 October 2012 5 | 6 | CC = D:/mingw/bin/gcc -std=gnu99 -isystem D:/mingw/include 7 | 8 | CXX = D:/mingw/bin/g++ -isystem D:/mingw/include/c++/4.7.0 -isystem D:/mingw/include -Wshadow 9 | 10 | CFLAGS = -DWINVER=0x0500 -D_WIN32_WINNT=0x0500 -D_WIN32_IE=0x0500 -DUNICODE -Dmain=wingwmain -O2 11 | 12 | CXXFLAGS = $(CFLAGS) 13 | 14 | LINK = D:/mingw/bin/g++ 15 | 16 | EXECUTABLE = Morphing.exe 17 | 18 | LIBS = -L/mingw32/lib -Ld:/morphing -lwinmm -lwsock32 -lcomctl32 -lole32 -lgdi32 -lgdiplus -lcomdlg32 -static-libgcc -static-libstdc++ -mwindows 19 | 20 | AR = D:/mingw/bin/ar 21 | RANLIB = D:/mingw/bin/ranlib 22 | WINDRES = D:/mingw/bin/windres 23 | -------------------------------------------------------------------------------- /stdafx.h: -------------------------------------------------------------------------------- 1 | // stdafx.h : include file for standard system include files, 2 | // or project specific include files that are used frequently, but 3 | // are changed infrequently 4 | // 5 | 6 | #if !defined(AFX_STDAFX_H__A7657B15_E3A1_4CAD_B823_5E1E504F79C0__INCLUDED_) 7 | #define AFX_STDAFX_H__A7657B15_E3A1_4CAD_B823_5E1E504F79C0__INCLUDED_ 8 | 9 | #if _MSC_VER > 1000 10 | #pragma once 11 | #endif // _MSC_VER > 1000 12 | 13 | 14 | // Insert your headers here 15 | #define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers 16 | 17 | #include 18 | 19 | // TODO: reference additional headers your program requires here 20 | 21 | //{{AFX_INSERT_LOCATION}} 22 | // Microsoft Visual C++ will insert additional declarations immediately before the previous line. 23 | 24 | #endif // !defined(AFX_STDAFX_H__A7657B15_E3A1_4CAD_B823_5E1E504F79C0__INCLUDED_) 25 | -------------------------------------------------------------------------------- /ReadWavFile.h: -------------------------------------------------------------------------------- 1 | //ReadWavFile.h 2 | #ifndef _READWAVFILE_H_ 3 | #define _READWAVFILE_H_ 4 | 5 | #include 6 | #include 7 | #include "stdint.h" 8 | #include "Structure.h" 9 | 10 | typedef int8_t int8; 11 | typedef uint8_t uint8; 12 | typedef int16_t int16; 13 | typedef uint16_t uint16; 14 | typedef int32_t int32; 15 | typedef uint32_t uint32; 16 | typedef int64_t int64; 17 | typedef uint64_t uint64; 18 | 19 | unsigned int bingetu1 (FILE *f, bool *TF); 20 | 21 | int binget2LE(FILE *f, bool *TF); 22 | 23 | long binget3LE(FILE *f, bool *TF); 24 | 25 | int binget4LE(FILE *f, bool *TF); 26 | 27 | double bingetr4LE (FILE *f, bool *TF); 28 | 29 | int checkWavFile(FILE *f, int *numOfChannels, int *encoding, double *sampleRate, 30 | long *startOfData, long *numOfSamples); 31 | 32 | int readAudioToFloat(FILE *f, int numberOfChannels, int encoding, double **buffer, long numberOfSamples); 33 | 34 | Sound Sound_readFromSoundFile(std::string path); 35 | 36 | int Sound_writeTxt(Sound sound, FILE *fp); 37 | 38 | #endif 39 | -------------------------------------------------------------------------------- /Pitch_to_PointProcess.h: -------------------------------------------------------------------------------- 1 | //Pitch_to_PointProcess.h 2 | 3 | #include "Structure.h" 4 | 5 | //Pitch_to_PointProcess.cpp 6 | static double findExtremum_3 (double *channel1_base, double *channel2_base, long d, long n, int includeMaxima, int includeMinima); 7 | 8 | static double Sound_findExtremum (Sound me, double tmin, double tmax, int includeMaxima, int includeMinima); 9 | 10 | static double Sound_findMaximumCorrelation (Sound me, double t1, double windowLength, double tmin2, double tmax2, double *tout, double *peak); 11 | 12 | long PointProcess_getLowIndex (PointProcess me, double t); 13 | 14 | void PointProcess_addPoint (PointProcess me, double t); 15 | 16 | void PointProcess_init (I, double tmin, double tmax, long initialMaxnt); 17 | 18 | PointProcess PointProcess_create (double tmin, double tmax, long initialMaxnt); 19 | 20 | int Pitch_getVoicedIntervalAfter (Pitch me, double after, double *tleft, double *tright); 21 | 22 | PointProcess Sound_Pitch_to_PointProcess_cc (Sound sound, Pitch pitch); 23 | 24 | long PointProcess_getNearestIndex (PointProcess me, double t); 25 | -------------------------------------------------------------------------------- /RealTier.h: -------------------------------------------------------------------------------- 1 | #ifndef _REALTIER_H 2 | #define _REALTIER_H 3 | 4 | #include "Structure.h" 5 | 6 | void PitchTier_modifyExcursionRange (PitchTier me, double tmin, double tmax, double multiplier, double fref_Hz); 7 | 8 | RealPoint RealPoint_create (double time, double value); 9 | 10 | void RealTier_init (RealTier me, double tmin, double tmax); 11 | 12 | DurationTier DurationTier_create (double tmin, double tmax); 13 | 14 | DurationTier PointProcess_upto_DurationTier (PointProcess me); 15 | 16 | PitchTier PitchTier_create (double tmin, double tmax); 17 | 18 | long SortedSet_getposition(SortedSetOfDouble me, SimpleDouble data); 19 | 20 | void SortedSet_insertItem(SortedSetOfDouble me, SimpleDouble data, long position); 21 | 22 | void SortedSet_addItem(SortedSetOfDouble me, SimpleDouble data); 23 | 24 | void SortedSetOfDouble_init(SortedSetOfDouble me, long initialCapacity); 25 | 26 | SortedSetOfDouble SortedSetOfDouble_create (void); 27 | 28 | void PitchTier_shiftFrequencies (PitchTier me, double tmin, double tmax, double shift, int units); 29 | 30 | void PitchTier_multiplyFrequencies (PitchTier me, double tmin, double tmax, double factor); 31 | 32 | void RealTier_addPoint(RealTier me, double t, double value); 33 | 34 | double RealTier_getValueAtTime(RealTier me, double t); 35 | 36 | PitchTier Pitch_to_PitchTier (Pitch me); 37 | 38 | Pitch Pitch_PuitchTier_to_Pitch(Pitch me, PitchTier tier); 39 | 40 | long AnyTier_timeToLowIndex (I, double time); 41 | 42 | long AnyTier_timeToHighIndex (I, double time); 43 | 44 | double RealTier_getMinimumValue (RealTier me); 45 | 46 | void PitchTier_modifyRange_old (PitchTier me, double tmin, double tmax, double factor, double fmid); 47 | 48 | #endif 49 | -------------------------------------------------------------------------------- /Get_Data_to_Sound.h: -------------------------------------------------------------------------------- 1 | #ifndef _GET_DATA_TO_SOUND_h_ 2 | #define _GET_DATA_TO_SOUND_h_ 3 | 4 | #include "Structure.h" 5 | #include 6 | #include 7 | #include "Structure.h" 8 | #include "Pitch.h" 9 | #include "RealTier.h" 10 | #include "SoundCompute.h" 11 | #include "ReadWavFile.h" 12 | #include "Sound_to_Pitch.h" 13 | #include "Pitch_to_PointProcess.h" 14 | #include 15 | #include 16 | #include "NUM.h" 17 | 18 | 19 | void Get_Data(double *srcdata, double *buff, int *Flag, int datalength); 20 | void Convert_array_to_double(int *int_data, double *double_data, int datalength); 21 | Sound Data_to_Sound(double *data,double samplingFrequency,int numOfChannels, double duration); 22 | void copydata(double *srcdata, double *buff, int start, int end); 23 | void copypitch(const Pitch me, Pitch him, int start, int end); 24 | long pitch_xToIndex(Pitch me, double x); 25 | PointProcess Sound_and_Pitch_to_Pulses (Sound me, Pitch him, double formantRatio,double new_pitch, 26 | double pitchRangeFactor, double durationFactor); 27 | Sound Sound_and_Pitch_and_Pulses_changeGender_old (Sound me, Pitch him, PointProcess pulses, double formantRatio,double new_pitch, 28 | double pitchRangeFactor, double durationFactor); 29 | PointProcess Sound_and_pitch_to_pulses_changespeaker(Sound me, Pitch him, 30 | double formantMultiplier , double pitchMultiplier, 31 | double pitchRangeMultiplier, double durationMultiplier); 32 | Sound Sound_and_pitch_and_pulses_changespeaker(Sound me, Pitch him, PointProcess pulses, 33 | double formantMultiplier , double pitchMultiplier, 34 | double pitchRangeMultiplier, double durationMultiplier); 35 | 36 | double find_proper_endtime(PointProcess pulses, double time); 37 | int find_pulses_vextor_index(PointProcess pulses, double time, int low, int high); 38 | Pitch Pitch_create2(Pitch pitch0, int start, double tmin, double tmax, long nt, double dt, double t1, double ceiling, int maxCandidates); 39 | void copycheckdata(double *from, double *to, int start, int copylength); 40 | #endif 41 | -------------------------------------------------------------------------------- /SystemData.h: -------------------------------------------------------------------------------- 1 | //SystemData.h 2 | #ifndef _SYSTEMDATA_H_ 3 | #define _SYSTEMDATA_H_ 4 | 5 | #include "Structure.h" 6 | 7 | //SystemData.cpp 8 | /**Returns true if ca[0] is the same letter as cb[0] regardless of case.**/ 9 | long int lsame_(const char *ca, const char *cb); 10 | 11 | double pow_di (double *ap, long *bp); 12 | 13 | static int dlamc1_ (long *beta, long *t, long *rnd, long *ieee1); 14 | 15 | static int dlamc2_ (long *beta, long *t, long *rnd, double *eps, long *emin, double *rmin, long *emax, double *rmax); 16 | 17 | static double dlamc3_ (double *a, double *b); 18 | 19 | static int dlamc4_ (long *emin, double *start, long *base); 20 | 21 | static int dlamc5_ (long *beta, long *p, long *emin, long *ieee, long *emax, double *rmax); 22 | 23 | double getSystemData(const char *cmach); 24 | /* Purpose 25 | ======= 26 | NUMblas_dlamch determines double machine parameters. 27 | Arguments 28 | ========= 29 | CMACH (input) char* 30 | Specifies the value to be returned by DLAMCH: 31 | = 'E' or 'e', DLAMCH := eps 32 | = 'S' or 's , DLAMCH := sfmin 33 | = 'B' or 'b', DLAMCH := base 34 | = 'P' or 'p', DLAMCH := eps*base 35 | = 'N' or 'n', DLAMCH := t 36 | = 'R' or 'r', DLAMCH := rnd 37 | = 'M' or 'm', DLAMCH := emin 38 | = 'U' or 'u', DLAMCH := rmin 39 | = 'L' or 'l', DLAMCH := emax 40 | = 'O' or 'o', DLAMCH := rmax 41 | 42 | where 43 | 44 | eps = relative machine precision 45 | sfmin = safe minimum, such that 1/sfmin does not overflow 46 | base = base of the machine 47 | prec = eps*base 48 | t = number of (base) digits in the mantissa 49 | rnd = 1.0 when rounding occurs in addition, 0.0 otherwise 50 | emin = minimum exponent before (gradual) underflow 51 | rmin = underflow threshold - base**(emin-1) 52 | emax = largest exponent before overflow 53 | rmax = overflow threshold - (base**emax)*(1-eps) 54 | ===================================================================== 55 | */ 56 | #endif 57 | -------------------------------------------------------------------------------- /Pitch.h: -------------------------------------------------------------------------------- 1 | //Pitch.h 2 | #include "Structure.h" 3 | 4 | //Pitch.cpp 5 | 6 | #define Pitch_LEVEL_FREQUENCY 1 7 | #define Pitch_LEVEL_STRENGTH 2 8 | 9 | #define Pitch_STRENGTH_UNIT_min 0 10 | #define Pitch_STRENGTH_UNIT_AUTOCORRELATION 0 11 | #define Pitch_STRENGTH_UNIT_NOISE_HARMONICS_RATIO 1 12 | #define Pitch_STRENGTH_UNIT_HARMONICS_NOISE_DB 2 13 | #define Pitch_STRENGTH_UNIT_max 2 14 | 15 | #define Pitch_NEAREST 0 16 | #define Pitch_LINEAR 1 17 | 18 | #define kPitch_unit_HERTZ 0 19 | #define kPitch_unit_HERTZ_LOGARITHMIC 1 20 | #define kPitch_unit_MEL 2 21 | #define kPitch_unit_LOG_HERTZ 3 22 | #define kPitch_unit_SEMITONES_1 4 23 | #define kPitch_unit_SEMITONES_100 5 24 | #define kPitch_unit_SEMITONES_200 6 25 | #define kPitch_unit_SEMITONES_440 7 26 | #define kPitch_unit_ERB 8 27 | #define ERB(f) NUMhertzToErb (f) 28 | 29 | void Pitch_Frame_init (Pitch_Frame frame, int nCandidate); 30 | 31 | Pitch Pitch_create(double tmin, double tmax, long nt, double dt, double t1, double ceiling, int maxCandidates); 32 | 33 | void Pitch_setCeiling (Pitch pitch, double ceiling); 34 | 35 | int Pitch_getMaxnCandidates (Pitch me); 36 | 37 | void Pitch_pathFinder (Pitch me, double silenceThreshold, double voicingThreshold, double octaveCost, 38 | double octaveJumpCost, double voicedUnvoicedCost, double ceiling, int pullFormants); 39 | 40 | double Pitch_getValueAtTime (Pitch me, double time, int unit, int interpolate); 41 | 42 | bool Pitch_isVoiced_i(Pitch me, long iframe); 43 | 44 | double Sampled_getValueAtSample (Pitch me, long isamp, long ilevel, int unit); 45 | 46 | double Sampled_getValueAtX (Pitch me, double x, long ilevel, int unit, int interpolate); 47 | 48 | double v_getValueAtSample (Pitch me, long iframe, long ilevel, int unit); 49 | 50 | double v_convertStandardToSpecialUnit (double value, long ilevel, int unit); 51 | 52 | void Pitch_scaleDuration(Pitch pitch, double multiplier); 53 | 54 | void Pitch_scalePitch(Pitch pitch, double multiplier); 55 | 56 | bool intersectRangeWithDomain(Pitch me, double *x1, double *x2); 57 | 58 | long Sampled_getWindowSamples (Pitch me, double xmin, double xmax, long *ixmin, long *ixmax); 59 | 60 | double getQuantitle(Pitch me, double xmin, double xmax, double quantile, long ilevel, int unit); 61 | 62 | double Pitch_getQuantile (Pitch me, double tmin, double tmax, double quantile, int unit); 63 | 64 | Pitch Pitch_scaleTime_old (Pitch me, double scaleFactor); 65 | 66 | double Pitch_getMinimum (Pitch me, double tmin, double tmax, int unit, int interpolate); 67 | 68 | void Pitch_getMinimumAndTime (Pitch me, double tmin, double tmax, int unit, int interpolate, 69 | double *return_minimum, double *return_timeOfMinimum); 70 | 71 | void Sampled_getMinimumAndX (Pitch me, double xmin, double xmax, long ilevel, int unit, int interpolate, 72 | double *return_minimum, double *return_xOfMinimum); 73 | 74 | bool IntersectRangeWithDomain (Pitch me, double *x1, double *x2); 75 | -------------------------------------------------------------------------------- /Sound_to_Pitch.h: -------------------------------------------------------------------------------- 1 | #ifndef _SOUND_TO_PITCH_H_ 2 | #define _SOUND_TO_PITCH_H_ 3 | 4 | #include "structure.h" 5 | 6 | int Sampled_shortTermAnalysis (Sound me, double windowDuration, double timeStep, long *numberOfFrames, double *firstTime); 7 | 8 | Pitch Sound_to_Pitch_any (Sound me, 9 | double dt, /* time step (seconds); 0.0 = automatic = periodsPerWindow / minimumPitch / 4 */ 10 | double minimumPitch, /* (Hz) */ 11 | double periodsPerWindow, /* ac3 for pitch analysis, 6 or 4.5 for HNR, 1 for FCC */ 12 | int maxnCandidates, /* maximum number of candidates per frame */ 13 | int method, /* 0 or 1 = AC, 2 or 3 = FCC, 0 or 2 = fast, 1 or 3 = accurate */ 14 | 15 | double silenceThreshold, /* relative to purely periodic; default 0.03 */ 16 | double voicingThreshold, /* relative to purely periodic; default 0.45 */ 17 | double octaveCost, /* favours higher pitches; default 0.01 */ 18 | double octaveJumpCost, /* default 0.35 */ 19 | double voicedUnvoicedCost, /* default 0.14 */ 20 | double maximumPitch); /* (Hz) */ 21 | /* 22 | Function: 23 | acoustic periodicity analysis. //ÉùÖÜÆÚ·ÖÎö 24 | Preconditions: 25 | minimumPitch > 0.0; 26 | maxnCandidates >= 2; 27 | Return value: 28 | the resulting pitch contour, or NULL in case of failure. //Óɴ˲úÉúµÄ»ùÒôÂÖÀª 29 | Failures: 30 | Out of memory. 31 | Minimum frequency too low. 32 | Maximum frequency should not be greater than the Sound's Nyquist frequency. 33 | Description for method 0 or 1: 34 | There is a Hanning window (method == 0) or Gaussian window (method == 1) 35 | over the analysis window, in order to avoid phase effects. 36 | Zeroes are appended to the analysis window to avoid edge effects in the FFT. 37 | An FFT is done on the window, giving a complex spectrum. //´°ÉϵÄFFT£¬¸ø³öÒ»¸´ºÏÆ× 38 | This complex spectrum is squared, thus giving the power spectrum. //¸´ºÏÆ×ƽ·½µÃµ½¹¦ÂÊÆ× 39 | The power spectrum is FFTed back, thus giving the autocorrelation of //¹¦ÂÊÆ×µÄ·´FFT£¬µÃµ½´°Ö¡µÄ×ÔÏà¹Ø 40 | the windowed frame. This autocorrelation is expressed relative to the power, 41 | which is the autocorrelation for lag 0. The autocorrelation is divided by 42 | the normalized autocorrelation of the window, in order to bring 43 | all maxima of the autocorrelation of a periodic signal to the same height. 44 | General description: 45 | The maxima are found by sinc interpolation. 46 | The pitch values (frequencies) of the highest 'maxnCandidates' maxima 47 | are saved in 'result', together with their strengths (relative correlations). 48 | A Viterbi algorithm is used to find a smooth path through the candidates, 49 | using the last six arguments of this function. 50 | 51 | The 'maximumPitch' argument has no influence on the search for candidates. 52 | It is directly copied into the Pitch object as a hint for considering 53 | pitches above a certain value "voiceless". 54 | */ 55 | 56 | Pitch Sound_to_Pitch_cc (Sound me, 57 | double dt, 58 | double minimumPitch, 59 | double periodsPerWindow, 60 | int maxnCandidates, 61 | int accurate, 62 | 63 | double silenceThreshold, 64 | double voicingThreshold, 65 | double octaveCost, 66 | double octaveJumpCost, 67 | double voicedUnvoicedCost, 68 | double ceiling); 69 | 70 | Pitch Sound_to_Pitch(Sound me, double timestep, double minimumPitch, double maximumPitch); 71 | 72 | Pitch computePitch(Sound me, double fixedTimeStepStrategy = 0.0, //auto 73 | int method = 1, /* = AUTOCORRELATION*/ /*kTimeSoundAnalysisEditor_pitch_analysisMethod*/ 74 | bool veryAccurate = false, 75 | double floor = 75, double ceiling = 600, /*Pitch settings*/ 76 | long maximumNumberOfCandidates = 15, /*default value, >= 2*/ 77 | double silenceThreshold = 0.03, double voicingThreshold = 0.45, double octaveCost = 0.01, 78 | double octaveJumpCost = 0.35, double voicedUnvoicedCost = 0.14); 79 | 80 | 81 | #endif 82 | -------------------------------------------------------------------------------- /NUMsort.cpp: -------------------------------------------------------------------------------- 1 | #include "NUM.h" 2 | #include 3 | 4 | double NUMhertzToMel (double hertz) { 5 | return hertz < 0 ? NUMundefined : 550.0 * log (1.0 + hertz / 550.0); 6 | } 7 | 8 | double NUMmelToHertz (double mel) { 9 | return mel < 0 ? NUMundefined : 550.0 * (exp (mel / 550.0) - 1); 10 | } 11 | 12 | double NUMhertzToErb (double hertz) { 13 | return hertz < 0 ? NUMundefined : 11.17 * log ((hertz + 312.0) / (hertz + 14680.0)) + 43.0; 14 | } 15 | 16 | double NUMsemitonesToHertz (double semitones) { 17 | return semitones == NUMundefined ? NUMundefined : 100.0 * exp (semitones * (NUMln2 / 12.0)); 18 | } 19 | 20 | double NUMhertzToSemitones (double hertz) { 21 | return hertz <= 0.0 ? NUMundefined : 12.0 * log (hertz / 100.0) / NUMln2; 22 | } 23 | 24 | double NUMerbToHertz (double erb) { 25 | double dum = exp ((erb - 43.0) / 11.17); 26 | return erb < 0 ? NUMundefined : (14680.0 * dum - 312.0) / (1.0 - dum); 27 | } 28 | 29 | 30 | #define MACRO_NUMsort(TYPE) { \ 31 | long l, r, j, i; \ 32 | TYPE k; \ 33 | if (n < 2) return; /* Already sorted. */ \ 34 | /* This n<2 step is absent from Press et al.'s implementation, */ \ 35 | /* which will therefore not terminate on if(--ir==1). */ \ 36 | /* Knuth's initial assumption is now fulfilled: n >= 2. */ \ 37 | if (n == 2) { \ 38 | if (a [1] > a [2]) { TYPE min = a [2]; a [2] = a [1]; a [1] = min; } \ 39 | return; \ 40 | } \ 41 | if (n <= 12) { \ 42 | for (i = 1; i < n; i ++) { \ 43 | TYPE min = a [i]; \ 44 | long pmin = i; \ 45 | for (j = i + 1; j <= n; j ++) if (a [j] < min) { \ 46 | min = a [j]; \ 47 | pmin = j; \ 48 | } \ 49 | a [pmin] = a [i]; \ 50 | a [i] = min; \ 51 | } \ 52 | return; \ 53 | } \ 54 | l = (n >> 1) + 1; \ 55 | r = n; \ 56 | for (;;) { \ 57 | if (l > 1) { \ 58 | l --; \ 59 | k = a [l]; \ 60 | } else /* l == 1 */ { \ 61 | k = a [r]; \ 62 | a [r] = a [1]; \ 63 | r --; \ 64 | if (r == 1) { a [1] = k; return; } \ 65 | } \ 66 | j = l; \ 67 | for (;;) { \ 68 | i = j; \ 69 | j = j << 1; \ 70 | if (j > r) break; \ 71 | if (j < r && a [j] < a [j + 1]) j ++; \ 72 | if (k >= a [j]) break; \ 73 | a [i] = a [j]; \ 74 | } \ 75 | a [i] = k; \ 76 | } \ 77 | } 78 | 79 | void NUMsort_d (long n, double a []) 80 | MACRO_NUMsort (double) 81 | 82 | void NUMsort_i (long n, int a []) 83 | MACRO_NUMsort (int) 84 | 85 | void NUMsort_l (long n, long a []) 86 | MACRO_NUMsort (long) 87 | 88 | void NUMsort_str (long n, wchar_t *a []) { 89 | long l, r, j, i; 90 | wchar_t *k; 91 | if (n < 2) return; 92 | l = (n >> 1) + 1; 93 | r = n; 94 | for (;;) { 95 | if (l > 1) { 96 | l --; 97 | k = a [l]; 98 | } else { 99 | k = a [r]; 100 | a [r] = a [1]; 101 | r --; 102 | if (r == 1) { a [1] = k; return; } 103 | } 104 | j = l; 105 | for (;;) { 106 | i = j; 107 | j = j << 1; 108 | if (j > r) break; 109 | if (j < r && wcscmp (a [j], a [j + 1]) < 0) j ++; 110 | if (wcscmp (k, a [j]) >= 0) break; 111 | a [i] = a [j]; 112 | } 113 | a [i] = k; 114 | } 115 | } 116 | 117 | void NUMsort_p (long n, void *a [], int (*compare) (const void *, const void *)) { 118 | long l, r, j, i; 119 | void *k; 120 | if (n < 2) return; 121 | l = (n >> 1) + 1; 122 | r = n; 123 | for (;;) { 124 | if (l > 1) { 125 | l --; 126 | k = a [l]; 127 | } else { 128 | k = a [r]; 129 | a [r] = a [1]; 130 | r --; 131 | if (r == 1) { a [1] = k; return; } 132 | } 133 | j = l; 134 | for (;;) { 135 | i = j; 136 | j = j << 1; 137 | if (j > r) break; 138 | if (j < r && compare (a [j], a [j + 1]) < 0) j ++; 139 | if (compare (k, a [j]) >= 0) break; 140 | a [i] = a [j]; 141 | } 142 | a [i] = k; 143 | } 144 | } 145 | 146 | double NUMquantile (long n, double a [], double factor) { 147 | double place = factor * n + 0.5; 148 | long left = floor (place); 149 | if (n < 1) return 0.0; 150 | if (n == 1) return a [1]; 151 | if (left < 1) left = 1; 152 | if (left >= n) left = n - 1; 153 | if (a [left + 1] == a [left]) return a [left]; 154 | return a [left] + (place - left) * (a [left + 1] - a [left]); 155 | } 156 | 157 | /* End of file NUMsort.cpp */ 158 | -------------------------------------------------------------------------------- /SoundCompute.h: -------------------------------------------------------------------------------- 1 | #ifndef _SOUNDCOMPUTE_H_ 2 | #define _SOUNDCOMPUTE_H_ 3 | 4 | #include "Structure.h" 5 | //SoundCompute.cpp 6 | MorphingFactor Factor_create(double fm = 1, double pm = 1, double prm = 1, double dm = 1); 7 | 8 | LocationTuple Location_create(double x = 0, double y = 0); 9 | 10 | MorphingFactor location_to_factors(LocationTuple tuple); 11 | 12 | Sound Sound_create(double xmin, double xmax, long nx, double dx, double x1, 13 | long numOfChannels = 1); 14 | 15 | Sound Sound_createSimple(double duration, double samplingFrequency, long numOfChannels = 1); 16 | 17 | Sound Sound_upsample (Sound me); 18 | 19 | Sound Sound_resample(Sound me, double samplingFrequency, long precision); 20 | 21 | void Sound_getMaximumAndX(Sound me, double xmin, double xmax, long channel, int interpolation, 22 | double *return_maximum, double *return_xOfMaximum); 23 | 24 | void Sound_getMinimumAndX(Sound me, double xmin, double xmax, long channel, int interpolation, 25 | double *return_minimum, double *return_xOfMinimum); 26 | 27 | void Sound_getMaximumAndXAndChannel (Sound me, double xmin, double xmax, int interpolation, 28 | double *return_maximum, double *return_xOfMaximum, long *return_channelOfMaximum); 29 | 30 | void Sound_getMinimumAndXAndChannel(Sound me, double xmin, double xmax, int interpolation, 31 | double *return_minimum, double *return_xOfMinimum, long *return_channelOfMinimum); 32 | 33 | double Sound_getMaximum(Sound me, double xmin, double xmax, int interpolation); 34 | double Sound_getMinimum(Sound me, double xmin, double xmax, int interpolation); 35 | 36 | double Sound_getAbsoluteExtremum(Sound me, double xmin, double xmax, int interpolation); 37 | 38 | long Sampled_getWindowSamples (Sound me, double xmin, double xmax, long *ixmin, long *ixmax); 39 | double Sound_getValueAtX (Sound me, double x, long ilevel, int interpolation); 40 | 41 | VoicedUnvoiced GeVicedUnvoiced(Pitch pitch, PointProcess points, 42 | double periodsPerWindow = 3.0, double minimumPitch = 75); 43 | 44 | void Sound_substructMean(Sound me); 45 | 46 | void Sound_overrideSamplingFrequency (Sound me, double rate); 47 | 48 | Sound Sound_changespeaker(Sound me, double pitchMin, double pitchMax, 49 | double formantMultiplier , // > 0 50 | double pitchMultiplier, // > 0 51 | double pitchRaneMultiplier, // any number 52 | double durationMultiplier // > 0 53 | ); 54 | 55 | Sound Sound_and_pitch_changespeaker(Sound me, Pitch him, 56 | double formantMultiplier , // > 0 57 | double pitchMultiplier, // > 0 58 | double pitchRaneMultiplier, // any number 59 | double durationMultiplier // > 0 60 | ); 61 | 62 | /* Outphased */ 63 | Sound Sound_changeGender_old (Sound me, double fmin, double fmax, double formantRatio, 64 | double new_pitch, double pitchRangeFactor, double durationFactor); 65 | 66 | Sound Sound_and_Pitch_changeGender_old (Sound me, Pitch him, double formantRatio, 67 | double new_pitch, double pitchRangeFactor, double durationFactor); 68 | 69 | //long AnyTier_timeToLowIndex (I, double time); 70 | 71 | double RealTier_getValueAtTime (RealTier me, double t); 72 | 73 | double RealTier_getArea (RealTier me, double tmin, double tmax); 74 | /* Inside points: linear intrapolation. */ 75 | /* Outside points: constant extrapolation. */ 76 | /* No points: NUMundefined. */ 77 | 78 | 79 | //TD-PSOLA procedure 80 | 81 | Sound Sound_Point_Pitch_Duration_to_Sound (Sound me, PointProcess pulses, 82 | PitchTier pitch, DurationTier duration, double maxT,double formantMultiplier); 83 | 84 | //Manipulation.cpp 85 | void copyRise (Sound me, double tmin, double tmax, Sound thee, double tmaxTarget); 86 | 87 | void copyFall (Sound me, double tmin, double tmax, Sound thee, double tminTarget); 88 | 89 | void copyBell (Sound me, double tmid, double leftWidth, double rightWidth, 90 | Sound thee, double tmidTarget); 91 | 92 | void copyBell2 (Sound me, PointProcess source, long isource, double leftWidth, 93 | double rightWidth,Sound thee, double tmidTarget, double maxT); 94 | void copyFall2(Sound me, PointProcess source, long isource, double leftWidth, double rightWidth, 95 | Sound thee, double tmidTarget, double maxT); 96 | void copyRise2 (Sound me, PointProcess source, long isource, double leftWidth, double rightWidth, 97 | Sound thee, double tmidTarget, double maxT); 98 | #endif 99 | -------------------------------------------------------------------------------- /NUM2.h: -------------------------------------------------------------------------------- 1 | #ifndef _NUM2_h_ 2 | #define _NUM2_h_ 3 | 4 | #include "Structure.h" 5 | 6 | 7 | NUMfft_Table NUMfft_Table_create(long n = 0, double *trigcache = 0, long *splitcache = 0); 8 | void NUMfft_Table_init (NUMfft_Table table, long n); 9 | 10 | void NUMfft_forward (NUMfft_Table table, double *data); 11 | /* 12 | Function: 13 | Calculates the Fourier Transform of a set of n real-valued data points. 14 | Replaces this data in array data [1...n] by the positive frequency half 15 | of its complex Fourier Transform, with a minus sign in the exponent. 16 | Preconditions: 17 | data != NULL; 18 | table must have been initialised with NUMfft_Table_init_f/d 19 | Postconditions: 20 | data[1] contains real valued first component (Direct Current) 21 | data[2..n-1] even index : real part; odd index: imaginary part of DFT. 22 | data[n] contains real valued last component (Nyquist frequency) 23 | 24 | Output parameters: 25 | 26 | data r(1) = the sum from i=1 to i=n of r(i) 27 | 28 | If l =(int) (n+1)/2 29 | 30 | then for k = 2,...,l 31 | 32 | r(2*k-2) = the sum from i = 1 to i = n of 33 | 34 | r(i)*cos((k-1)*(i-1)*2*pi/n) 35 | 36 | r(2*k-1) = the sum from i = 1 to i = n of 37 | 38 | -r(i)*sin((k-1)*(i-1)*2*pi/n) 39 | 40 | if n is even 41 | 42 | r(n) = the sum from i = 1 to i = n of 43 | 44 | (-1)**(i-1)*r(i) 45 | 46 | i.e., the ordering of the output array will be for n even 47 | r(1),(r(2),i(2)),(r(3),i(3)),...,(r(l-1),i(l-1)),r(l). 48 | Or ...., (r(l),i(l)) for n uneven. 49 | 50 | ***** note 51 | this transform is unnormalized since a call of NUMfft_forward 52 | followed by a call of NUMfft_backward will multiply the input 53 | sequence by n. 54 | */ 55 | 56 | void NUMfft_backward (NUMfft_Table table, double *data); 57 | /* 58 | Function: 59 | Calculates the inverse transform of a complex array if it is the transform of real data. 60 | (Result in this case must be multiplied by 1/n.) 61 | Preconditions: 62 | n is an integer power of 2. 63 | data != NULL; 64 | data [1] contains real valued first component (Direct Current) 65 | data [2..n-1] even index : real part; odd index: imaginary part of DFT. 66 | data [n] contains real valued last component (Nyquist frequency) 67 | 68 | table must have been initialised with NUMfft_Table_init_f/d 69 | 70 | Output parameters 71 | 72 | data for n even and for i = 1,...,n 73 | 74 | r(i) = r(1)+(-1)**(i-1)*r(n) 75 | 76 | plus the sum from k=2 to k=n/2 of 77 | 78 | 2.*r(2*k-2)*cos((k-1)*(i-1)*2*pi/n) 79 | 80 | -2.*r(2*k-1)*sin((k-1)*(i-1)*2*pi/n) 81 | 82 | for n odd and for i = 1,...,n 83 | 84 | r(i) = r(1) plus the sum from k=2 to k=(n+1)/2 of 85 | 86 | 2.*r(2*k-2)*cos((k-1)*(i-1)*2*pi/n) 87 | 88 | -2.*r(2*k-1)*sin((k-1)*(i-1)*2*pi/n) 89 | 90 | ***** note 91 | this transform is unnormalized since a call of NUMfft_forward 92 | followed by a call of NUMfft_backward will multiply the input 93 | sequence by n. 94 | */ 95 | 96 | void NUMrealft (double *data, long n, int isign); 97 | 98 | void NUMforwardRealFastFourierTransform (double *data, long n); 99 | void NUMreverseRealFastFourierTransform (double *data, long n); 100 | 101 | double NUMminimize_brent (double (*f) (double x, void *closure), double a, double b, 102 | void *closure, double tol, double *fx); 103 | /* 104 | The function returns an estimate for the minimum location with accuracy 105 | 3 * SQRT_EPSILON * abs(x) + tol. 106 | The function always obtains a local minimum which coincides with 107 | the global one only if a function under investigation being unimodular. 108 | If a function being examined possesses no local minimum within 109 | the given range, the function returns 'a' (if f(a) < f(b)), otherwise 110 | it returns the right range boundary value b. 111 | 112 | Algorithm 113 | The function makes use of the golden section procedure combined with 114 | parabolic interpolation. 115 | At every step, the program operates at three abscissae - x, v, and w. 116 | x - the last and the best approximation to the minimum location, 117 | i.e. f(x) <= f(a) or/and f(x) <= f(b) 118 | (if the function f has a local minimum in (a,b), then both 119 | conditions are fulfiled after one or two steps). 120 | v, w are previous approximations to the minimum location. They may 121 | coincide with a, b, or x (although the algorithm tries to make all 122 | u, v, and w distinct). Points x, v, and w are used to construct 123 | interpolating parabola whose minimum will be treated as a new 124 | approximation to the minimum location if the former falls within 125 | [a,b] and reduces the range enveloping minimum more efficient than 126 | the golden section procedure. 127 | When f(x) has a second derivative positive at the minimum location 128 | (not coinciding with a or b) the procedure converges superlinearly 129 | at a rate order about 1.324 130 | */ 131 | 132 | #endif 133 | -------------------------------------------------------------------------------- /NUM.h: -------------------------------------------------------------------------------- 1 | #ifndef _NUM_h_ 2 | #define _NUM_h_ 3 | 4 | #include "math.h" 5 | 6 | // print e(1) 7 | #define NUMe 2.7182818284590452353602874713526624977572 8 | // print 1/l(2) 9 | #define NUMlog2e 1.4426950408889634073599246810018921374266 10 | // print l(10)/l(2) 11 | #define NUMlog2_10 3.3219280948873623478703194294893901758648 12 | // print 1/l(10) 13 | #define NUMlog10e 0.4342944819032518276511289189166050822944 14 | // print l(2)/l(10) 15 | #define NUMlog10_2 0.3010299956639811952137388947244930267682 16 | // print l(2) 17 | #define NUMln2 0.6931471805599453094172321214581765680755 18 | // print l(10) 19 | #define NUMln10 2.3025850929940456840179914546843642076011 20 | // print a(1)*8 21 | #define NUM2pi 6.2831853071795864769252867665590057683943 22 | // print a(1)*4 23 | #define NUMpi 3.1415926535897932384626433832795028841972 24 | // print a(1)*2 25 | #define NUMpi_2 1.5707963267948966192313216916397514420986 26 | // print a(1) 27 | #define NUMpi_4 0.7853981633974483096156608458198757210493 28 | // print 0.25/a(1) 29 | #define NUM1_pi 0.3183098861837906715377675267450287240689 30 | // print 0.5/a(1) 31 | #define NUM2_pi 0.6366197723675813430755350534900574481378 32 | // print sqrt(a(1)*4) 33 | #define NUMsqrtpi 1.7724538509055160272981674833411451827975 34 | // print sqrt(a(1)*8) 35 | #define NUMsqrt2pi 2.5066282746310005024157652848110452530070 36 | // print 1/sqrt(a(1)*8) 37 | #define NUM1_sqrt2pi 0.3989422804014326779399460599343818684759 38 | // print 1/sqrt(a(1)) 39 | #define NUM2_sqrtpi 1.1283791670955125738961589031215451716881 40 | // print l(a(1)*4) 41 | #define NUMlnpi 1.1447298858494001741434273513530587116473 42 | // print sqrt(2) 43 | #define NUMsqrt2 1.4142135623730950488016887242096980785697 44 | // print sqrt(0.5) 45 | #define NUMsqrt1_2 0.7071067811865475244008443621048490392848 46 | // print sqrt(3) 47 | #define NUMsqrt3 1.7320508075688772935274463415058723669428 48 | // print sqrt(5) 49 | #define NUMsqrt5 2.2360679774997896964091736687312762354406 50 | // print sqrt(6) 51 | #define NUMsqrt6 2.4494897427831780981972840747058913919659 52 | // print sqrt(7) 53 | #define NUMsqrt7 2.6457513110645905905016157536392604257102 54 | // print sqrt(8) 55 | #define NUMsqrt8 2.8284271247461900976033774484193961571393 56 | // print sqrt(10) 57 | #define NUMsqrt10 3.1622776601683793319988935444327185337196 58 | // print sqrt(5)/2-0.5 59 | #define NUM_goldenSection 0.6180339887498948482045868343656381177203 60 | // The Euler-Mascheroni constant cannot be computed by bc. 61 | // Instead we use the 40 digits computed by Johann von Soldner in 1809. 62 | #define NUM_euler 0.5772156649015328606065120900824024310422 63 | #define NUMundefined HUGE_VAL 64 | #define NUMdefined(x) ((x) != NUMundefined) 65 | #define NUMlog2(x) (log (x) * NUMlog2e) 66 | 67 | 68 | /***** ÔÝ´æÓë NUMsort.cpp ******/ 69 | double NUMhertzToMel (double hertz); 70 | double NUMmelToHertz (double mel); 71 | double NUMhertzToErb (double hertz); 72 | double NUMhertzToMel (double hertz); 73 | double NUMsemitonesToHertz (double semitones); 74 | double NUMhertzToSemitones (double hertz); 75 | double NUMerbToHertz (double erb); 76 | 77 | 78 | /**** Sorting (NUMsort.cpp)****/ 79 | void NUMsort_d (long n, double ra []); /* Heap sort. */ 80 | 81 | void NUMsort_i (long n, int ra []); 82 | 83 | void NUMsort_l (long n, long ra []); 84 | 85 | void NUMsort_str (long n, wchar_t *a []); 86 | 87 | double NUMquantile (long n, double a [], double factor); 88 | 89 | void NUMsort_p (long n, void *a [], int (*compare) (const void *, const void *)); 90 | 91 | 92 | /**** Interpolation and optimization (NUMInOp.cpp)****/ 93 | 94 | #define NUM_VALUE_INTERPOLATE_NEAREST 0 95 | #define NUM_VALUE_INTERPOLATE_LINEAR 1 96 | #define NUM_VALUE_INTERPOLATE_CUBIC 2 97 | 98 | #define NUM_PEAK_INTERPOLATE_NONE 0 99 | #define NUM_PEAK_INTERPOLATE_PARABOLIC 1 100 | #define NUM_PEAK_INTERPOLATE_CUBIC 2 101 | #define NUM_PEAK_INTERPOLATE_SINC70 3 102 | #define NUM_PEAK_INTERPOLATE_SINC700 4 103 | #define NUM_VALUE_INTERPOLATE_SINC70 70 104 | #define NUM_VALUE_INTERPOLATE_SINC700 700 105 | 106 | static double improve_evaluate (double x, void *closure); 107 | 108 | double NUM_interpolate_sinc (double y [], long nx, double x, long interpolationDepth); 109 | 110 | double NUMimproveExtremum (double *y, long nx, long ixmid, int interpolation, double *ixmid_real, int isMaximum); 111 | 112 | double NUMimproveMaximum (double *y, long nx, long ixmid, int interpolation, double *ixmid_real); 113 | 114 | double NUMimproveMinimum (double *y, long nx, long ixmid, int interpolation, double *ixmid_real); 115 | 116 | /******************random part(NUMinop.cpp)***************/ 117 | #define LONG_LAG 100 118 | #define SHORT_LAG 37 119 | #define STREAM_SEPARATION 70 120 | #define QUALITY 1009 121 | #define LAG_DIFF (LONG_LAG - SHORT_LAG) 122 | 123 | #define repeat do 124 | #define until(cond) while (!(cond)) 125 | 126 | 127 | static double randomArray [LONG_LAG]; 128 | static int randomInited = 0; 129 | static long randomArrayPointer1, randomArrayPointer2, iquality; 130 | 131 | void NUMrandomRestart (unsigned long seed); 132 | 133 | double NUMrandomFraction (void); 134 | 135 | double NUMrandomUniform (double lowest, double highest); 136 | 137 | long NUMrandomInteger (long lowest, long highest); 138 | 139 | double NUMrandomGauss (double mean, double standardDeviation); 140 | 141 | #endif 142 | -------------------------------------------------------------------------------- /Structure.h: -------------------------------------------------------------------------------- 1 | #ifndef _STRUCTURE_H_ 2 | #define _STRUCTURE_H_ 3 | /* 4 | * Sructure.h 5 | * Define some useful structure for sound 6 | * Includeing contend: 7 | * Schema for describing the structure and Intermediate structure for handling some result 8 | * Referance: Praat 1992-2011 by Paul Boersma 9 | * Version: 1.0 10 | * Author: Wenjie Feng 11 | * Time: 2012.09.28 12 | */ 13 | 14 | #include 15 | 16 | typedef void *Any; /* Prevent compile-time type checking. */ 17 | 18 | /* 19 | Use the macros 'I' and 'thou' for objects in the formal parameter lists 20 | (if the explicit type cannot be used). 21 | Use the macros 'iam' and 'thouart' as the first declaration in a function definition. 22 | After this, the object 'me' or 'thee' has the right class (for the compiler), 23 | so that you can use the macros 'my' and 'thy' to refer to members. 24 | Example: int Person_getAge (I) { iam (Person); return my age; } 25 | */ 26 | 27 | 28 | #define I Any void_me 29 | #define thou Any void_thee 30 | #define iam(klas) klas me = (klas)void_me 31 | #define thouart(klas) klas thee = (klas)void_thee 32 | #define my me-> 33 | #define thy thee-> 34 | #define his him-> 35 | #define FALSE 0 36 | #define TRUE 1 37 | 38 | #define Vector_CHANNEL_AVERAGE 0 39 | #define Vector_CHANNEL_1 1 40 | #define Vector_CHANNEL_2 2 41 | #define Vector_VALUE_INTERPOLATION_NEAREST 0 42 | #define Vector_VALUE_INTERPOLATION_LINEAR 1 43 | #define Vector_VALUE_INTERPOLATION_CUBIC 2 44 | #define Vector_VALUE_INTERPOLATION_SINC70 3 45 | #define Vector_VALUE_INTERPOLATION_SINC700 4 46 | 47 | struct structSound { 48 | double xmin; // start time(seconds). 49 | double xmax; // end time(secondes). 50 | long nx; // Number of samples. 51 | double dx; // Sampling period (second). 52 | double x1; // Time of the first sample (seconds). 53 | long ny; // channel number 54 | double **z; // z[ny][nx]; // Amplitude 55 | }; 56 | 57 | typedef struct structSound* Sound;//Ö¸Õë 58 | 59 | struct structPitch_Candidate { 60 | double frequency; 61 | double strength; 62 | }; 63 | 64 | typedef struct structPitch_Candidate* Pitch_Candidate; 65 | 66 | struct structPitch_Frame { 67 | double intensity; 68 | long nCandidates; 69 | Pitch_Candidate candidate; // candidate[nCandidate]. 70 | }; 71 | 72 | typedef struct structPitch_Frame* Pitch_Frame; 73 | 74 | struct structPitch { 75 | double xmin; //start time(seconds) 76 | double xmax; //tmax > tmin end time(seconds 77 | long nx; //number of time slices number of frames 78 | double dx; //time step(seconds) analysis step 79 | double x1; //centre of first time slice (seconds). 80 | double ceiling; //candidates with a higher frequency are unvoiced. 81 | int maxnCandidates; //maximum number of candidates per time slice. 82 | Pitch_Frame frame; //frame[1..nx] 83 | /* 84 | frame[1..nx].nCandidates // Number of candidates in each time slice, including the unvoiced candidate. 85 | frame[1..nx].candidate[1..nCandidates].frequency 86 | The frequency of each candidate (Hz), 0 means aperiodic or silent. 87 | candidate[1].frequency is the frequency of the currently best candidate. 88 | frame[1..nx].candidate[1..nCandidates].strength 89 | The strength of each candidate, a real number between 0 and 1: 90 | 0 means not periodic at all, 1 means perfectly periodic; 91 | if the frequency of the candidate is 0, its strength is a real number 92 | that represents the maximum periodicity that 93 | can still be considered to be due to noise (e.g., 0.4). 94 | candidate[1].strength is the strength of the currently best candidate. 95 | frame[1..nx].intensity 96 | The relative intensity of each frame, a real number between 0 and 1. 97 | */ 98 | }; 99 | 100 | typedef struct structPitch* Pitch; 101 | 102 | struct structNUMfft_Table 103 | { 104 | long n; 105 | double *trigcache; 106 | long *splitcache; 107 | }; 108 | 109 | typedef struct structNUMfft_Table *NUMfft_Table; 110 | 111 | struct structPointProcess { 112 | double xmin; // start time (s) 113 | double xmax; // end time (s) 114 | long maxnt; // default 10 maximum number of pitch point 115 | long nt; // number of pitch point 116 | double *t; // t[maxnt] vector of the pitch point 117 | }; 118 | 119 | typedef struct structPointProcess *PointProcess; 120 | 121 | struct structVoicedUnvoiced{ 122 | bool *vuv; 123 | long nt; 124 | }; 125 | 126 | typedef struct structVoicedUnvoiced *VoicedUnvoiced; 127 | 128 | struct structSimpleDouble { 129 | double number; 130 | }; 131 | 132 | typedef struct structSimpleDouble *SimpleDouble, *AnyPoint; 133 | 134 | struct structRealPoint : structSimpleDouble{ 135 | double value; 136 | }; 137 | 138 | typedef struct structRealPoint *RealPoint; 139 | 140 | struct structSortedSetOfDouble { 141 | long _capacity, size; 142 | // bool _dontOwnItems; 143 | 144 | SimpleDouble *item; 145 | /* 146 | Attributes: 147 | _capacity >= size // private; grows as you add items. 148 | size // the current number of items. 149 | item [1..size] // the items. 150 | */ 151 | }; 152 | 153 | typedef struct structSortedSetOfDouble *SortedSetOfDouble; 154 | 155 | struct structRealTier{ 156 | double xmin; 157 | double xmax; 158 | SortedSetOfDouble points; 159 | }; 160 | 161 | typedef struct structRealTier *RealTier; 162 | 163 | struct structPitchTier : structRealTier{ }; 164 | 165 | typedef struct structPitchTier *PitchTier; 166 | 167 | struct structDurationTier : structRealTier{ }; 168 | 169 | typedef struct structDurationTier *DurationTier; 170 | 171 | 172 | struct structLocationTuple{ 173 | double x; 174 | double y; 175 | }; 176 | 177 | typedef struct structLocationTuple *LocationTuple; 178 | 179 | struct structMorphingFactor{ 180 | double formantMultiplier; 181 | double pitchMultiplier; 182 | double pitchRangeMultiplier; 183 | double durationMultiplier; 184 | }; 185 | 186 | typedef struct structMorphingFactor *MorphingFactor; 187 | 188 | #endif 189 | -------------------------------------------------------------------------------- /NUM2.cpp: -------------------------------------------------------------------------------- 1 | #include "NUM2.h" 2 | #include "NUM.h" 3 | #include "NUMfft_core.h" 4 | #include "Structure.h" 5 | #include "SystemData.h" 6 | #include 7 | 8 | NUMfft_Table NUMfft_Table_create(long n, double *trigcache, long *splitcache) 9 | { 10 | NUMfft_Table me = (NUMfft_Table)malloc(sizeof(structNUMfft_Table)); 11 | if(!me) return NULL; 12 | my n = n; 13 | my trigcache = trigcache; 14 | my splitcache = splitcache; 15 | return me; 16 | } 17 | 18 | void NUMfft_Table_init (NUMfft_Table me, long n) { 19 | my n = n; 20 | my trigcache = (double *)malloc(sizeof(double) * 3 * n); /// NUMvector (0, 3 * n - 1); 21 | my splitcache = (long *)malloc(sizeof(long) * 32); /// NUMvector (0, 31); 22 | NUMrffti (n, my trigcache, my splitcache); 23 | } 24 | 25 | void NUMfft_forward (NUMfft_Table me, double *data) { 26 | if (my n == 1) 27 | return; 28 | drftf1 (my n, &data[1], my trigcache, my trigcache + my n, my splitcache); 29 | } 30 | 31 | void NUMfft_backward (NUMfft_Table me, double *data) { 32 | if (my n == 1) 33 | return; 34 | drftb1 (my n, &data[1], my trigcache, my trigcache + my n, my splitcache); 35 | } 36 | 37 | void NUMrealft (double *data, long n, int isign) { 38 | isign == 1 ? NUMforwardRealFastFourierTransform (data, n) : 39 | NUMreverseRealFastFourierTransform (data, n); 40 | } 41 | 42 | void NUMforwardRealFastFourierTransform (double *data, long n) { 43 | NUMfft_Table table = NUMfft_Table_create(); 44 | NUMfft_Table_init (table, n); 45 | NUMfft_forward (table, data); 46 | 47 | if (n > 1) { 48 | // To be compatible with old behaviour 49 | double tmp = data[n - 1]; 50 | for (long i = n; i > 2; i--) { 51 | data[i] = data[i - 1]; 52 | } 53 | data[2] = tmp; 54 | } 55 | } 56 | 57 | void NUMreverseRealFastFourierTransform (double *data, long n) { 58 | NUMfft_Table table = NUMfft_Table_create(); 59 | 60 | if (n > 1) { 61 | // To be compatible with old behaviour 62 | double tmp = data[1]; 63 | for (long i = 2; i < n; i++) { 64 | data[i] = data[i + 1]; 65 | } 66 | data[n] = tmp; 67 | } 68 | 69 | NUMfft_Table_init (table, n); 70 | NUMfft_backward (table, data); 71 | } 72 | 73 | double NUMminimize_brent (double (*f) (double x, void *closure), double a, 74 | double b, void *closure, double tol, double *fx) 75 | /* 76 | The function returns an estimate for the minimum location with accuracy 77 | 3 * SQRT_EPSILON * abs(x) + tol. 78 | The function always obtains a local minimum which coincides with 79 | the global one only if a function under investigation being unimodular. 80 | If a function being examined possesses no local minimum within 81 | the given range, the function returns 'a' (if f(a) < f(b)), otherwise 82 | it returns the right range boundary value b. 83 | 84 | Algorithm 85 | 86 | The function makes use of the golden section procedure combined with 87 | parabolic interpolation. 88 | At every step, the program operates at three abscissae - x, v, and w. 89 | x - the last and the best approximation to the minimum location, 90 | i.e. f(x) <= f(a) or/and f(x) <= f(b) 91 | (if the function f has a local minimum in (a,b), then both 92 | conditions are fulfiled after one or two steps). 93 | v, w are previous approximations to the minimum location. They may 94 | coincide with a, b, or x (although the algorithm tries to make all 95 | u, v, and w distinct). Points x, v, and w are used to construct 96 | interpolating parabola whose minimum will be treated as a new 97 | approximation to the minimum location if the former falls within 98 | [a,b] and reduces the range enveloping minimum more efficient than 99 | the golden section procedure. 100 | When f(x) has a second derivative positive at the minimum location 101 | (not coinciding with a or b) the procedure converges superlinearly 102 | at a rate order about 1.324 103 | */ 104 | { 105 | double x, v, fv, w, fw; 106 | const double golden = 1 - NUM_goldenSection; /// 1 - 0.618... 107 | const double sqrt_epsilon = sqrt (getSystemData("Epsilon")); /// Quantization error (relative machine precision) 108 | long itermax = 60; 109 | 110 | if(tol <= 0 || a >= b){ 111 | std::cout<<"tol = " < 0 && a < b."< 0 && a < b); ****/ 115 | 116 | /* First step - golden section */ 117 | v = a + golden * (b - a); 118 | fv = (*f) (v, closure); 119 | x = v; w = v; 120 | *fx = fv; fw = fv; 121 | 122 | for (long iter = 1; iter <= itermax; iter++) { 123 | double range = b - a; 124 | double middle_range = (a + b) / 2; 125 | double tol_act = sqrt_epsilon * fabs (x) + tol / 3; 126 | double new_step; /* Step at this iteration */ 127 | 128 | if (fabs (x - middle_range) + range / 2 <= 2 * tol_act) 129 | return x; 130 | 131 | /* Obtain the golden section step */ 132 | new_step = golden * (x < middle_range ? b - x : a - x); 133 | 134 | /* Decide if the parabolic interpolation can be tried */ 135 | if (fabs (x - w) >= tol_act) { 136 | /* 137 | Interpolation step is calculated as p/q; 138 | division operation is delayed until last moment. 139 | */ 140 | double p, q, t; 141 | 142 | t = (x - w) * (*fx - fv); 143 | q = (x - v) * (*fx - fw); 144 | p = (x - v) * q - (x - w) * t; 145 | q = 2 * (q - t); 146 | 147 | if (q > 0) 148 | p = -p; 149 | else 150 | q = -q; 151 | 152 | /* 153 | If x+p/q falls in [a,b], not too close to a and b, 154 | and isn't too large, it is accepted. 155 | If p/q is too large then the golden section procedure can 156 | reduce [a,b] range. 157 | */ 158 | if (fabs (p) < fabs (new_step * q) && 159 | p > q * (a - x + 2 * tol_act) && 160 | p < q * (b - x - 2 * tol_act)) { 161 | new_step = p / q; 162 | } 163 | } 164 | 165 | /* Adjust the step to be not less than tolerance. */ 166 | if (fabs (new_step) < tol_act) { 167 | new_step = new_step > 0 ? tol_act : - tol_act; 168 | } 169 | /* Obtain the next approximation to min and reduce the enveloping range */ 170 | { 171 | double t = x + new_step; /* Tentative point for the min */ 172 | double ft = (*f) (t, closure); 173 | 174 | /* 175 | If t is a better approximation, reduce the range so that 176 | t would fall within it. If x remains the best, reduce the range 177 | so that x falls within it. 178 | */ 179 | 180 | if (ft <= *fx) { 181 | if (t < x) { 182 | b = x; 183 | } else { 184 | a = x; 185 | } 186 | 187 | v = w; w = x; x = t; 188 | fv = fw; fw = *fx; *fx = ft; 189 | } else { 190 | if (t < x) { 191 | a = t; 192 | } else { 193 | b = t; 194 | } 195 | 196 | if (ft <= fw || w == x) { 197 | v = w; w = t; 198 | fv = fw; fw = ft; 199 | } else if (ft <= fv || v == x || v == w) { 200 | v = t; 201 | fv = ft; 202 | } 203 | } 204 | } 205 | } 206 | std::cout<<"NUMminimize_brent: maximum number of iterations ("<< (int) itermax << ") exceeded. Position: SoundCompute.cpp: Line 228"< nx) return y[nx]; \ 10 | if (x < 1) return y[1]; \ 11 | if (x == midleft) return y[midleft]; \ 12 | if (maxDepth > midright - 1) maxDepth = midright - 1; \ 13 | if (maxDepth > nx - midleft) maxDepth = nx - midleft; \ 14 | if (maxDepth <= NUM_VALUE_INTERPOLATE_NEAREST) return y[(long) floor (x + 0.5)]; \ 15 | if (maxDepth == NUM_VALUE_INTERPOLATE_LINEAR) return y[midleft] + (x - midleft) * (y[midright] - y[midleft]); \ 16 | if (maxDepth == NUM_VALUE_INTERPOLATE_CUBIC) { \ 17 | double yl = y[midleft], yr = y[midright]; \ 18 | double dyl = 0.5 * (yr - y[midleft - 1]), dyr = 0.5 * (y[midright + 1] - yl); \ 19 | double fil = x - midleft, fir = midright - x; \ 20 | return yl * fir + yr * fil - fil * fir * (0.5 * (dyr - dyl) + (fil - 0.5) * (dyl + dyr - 2 * (yr - yl))); \ 21 | } 22 | /***** 1 < x < nx && x not integer: interpolate. line 5 *****/ 23 | 24 | //NUM.cpp 369 / 403 ? alternative ro error has choosen 369 25 | double NUM_interpolate_sinc (double y [], long nx, double x, long maxDepth) { 26 | long ix, midleft = floor(x), midright = midleft + 1, left, right; 27 | double result = 0.0, a, halfsina, aa, daa, cosaa, sinaa, cosdaa, sindaa; 28 | 29 | NUM_interpolate_simple_cases 30 | 31 | left = midright - maxDepth, right = midleft + maxDepth; 32 | a = NUMpi * (x - midleft); 33 | halfsina = 0.5 * sin (a); 34 | aa = a / (x - left + 1); cosaa = cos (aa); sinaa = sin (aa); 35 | daa = NUMpi / (x - left + 1); cosdaa = cos (daa); sindaa = sin (daa); 36 | 37 | for (ix = midleft; ix >= left; ix --) { 38 | double d = halfsina / a * (1.0 + cosaa), help; 39 | result += y [ix] * d; 40 | a += NUMpi; 41 | help = cosaa * cosdaa - sinaa * sindaa; 42 | sinaa = cosaa * sindaa + sinaa * cosdaa; 43 | cosaa = help; 44 | halfsina = - halfsina; 45 | } 46 | 47 | a = NUMpi * (midright - x); 48 | halfsina = 0.5 * sin (a); 49 | aa = a / (right - x + 1); cosaa = cos (aa); sinaa = sin (aa); 50 | daa = NUMpi / (right - x + 1); cosdaa = cos (daa); sindaa = sin (daa); 51 | 52 | for (ix = midright; ix <= right; ix ++) { 53 | double d = halfsina / a * (1.0 + cosaa), help; 54 | result += y [ix] * d; 55 | a += NUMpi; 56 | help = cosaa * cosdaa - sinaa * sindaa; 57 | sinaa = cosaa * sindaa + sinaa * cosdaa; 58 | cosaa = help; 59 | halfsina = - halfsina; 60 | } 61 | 62 | return result; 63 | } 64 | 65 | struct improve_params { 66 | int depth; 67 | double *y; 68 | long ixmax; 69 | int isMaximum; 70 | }; 71 | 72 | 73 | static double improve_evaluate (double x, void *closure) { 74 | struct improve_params *me = (struct improve_params *) closure; 75 | double y = NUM_interpolate_sinc (my y, my ixmax, x, my depth); 76 | return my isMaximum ? - y : y; 77 | } 78 | 79 | double NUMimproveExtremum (double *y, long nx, long ixmid, int interpolation, double *ixmid_real, int isMaximum) { 80 | struct improve_params params; 81 | double result; 82 | if (ixmid <= 1) { *ixmid_real = 1; return y[1]; } 83 | if (ixmid >= nx) { *ixmid_real = nx; return y[nx]; } 84 | if (interpolation <= NUM_PEAK_INTERPOLATE_NONE) { *ixmid_real = ixmid; return y[ixmid]; } 85 | if (interpolation == NUM_PEAK_INTERPOLATE_PARABOLIC) { 86 | double dy = 0.5 * (y[ixmid + 1] - y[ixmid - 1]); 87 | double d2y = 2 * y[ixmid] - y[ixmid - 1] - y[ixmid + 1]; 88 | *ixmid_real = ixmid + dy / d2y; 89 | return y[ixmid] + 0.5 * dy * dy / d2y; 90 | } 91 | /* Sinc interpolation. */ 92 | params.y = y; 93 | params.depth = interpolation == NUM_PEAK_INTERPOLATE_SINC70 ? 70 : 700; 94 | params.ixmax = nx; 95 | params.isMaximum = isMaximum; 96 | /*return isMaximum ? 97 | - NUM_minimize (ixmid - 1, ixmid, ixmid + 1, improve_evaluate, & params, 1e-10, 1e-11, ixmid_real) : 98 | NUM_minimize (ixmid - 1, ixmid, ixmid + 1, improve_evaluate, & params, 1e-10, 1e-11, ixmid_real);*/ 99 | *ixmid_real = NUMminimize_brent (improve_evaluate, ixmid - 1, ixmid + 1, & params, 1e-10, & result); 100 | return isMaximum ? - result : result; 101 | } 102 | 103 | double NUMimproveMaximum (double *y, long nx, long ixmid, int interpolation, double *ixmid_real) 104 | { return NUMimproveExtremum (y, nx, ixmid, interpolation, ixmid_real, 1); } 105 | 106 | double NUMimproveMinimum (double *y, long nx, long ixmid, int interpolation, double *ixmid_real) 107 | { return NUMimproveExtremum (y, nx, ixmid, interpolation, ixmid_real, 0); } 108 | 109 | 110 | void NUMrandomRestart (unsigned long seed) { 111 | /* 112 | Based on Knuth, p. 187,602. 113 | 114 | Knuth had: 115 | int s = seed; 116 | This is incorrect (even if an int is 32 bit), since a negative value causes a loop in the test 117 | if (s != 0) 118 | s >>= 1; 119 | because the >> operator on negative integers adds a sign bit to the left. 120 | */ 121 | long t, j; 122 | double u [2 * LONG_LAG - 1], ul [2 * LONG_LAG - 1]; 123 | double ulp = 1.0 / (1L << 30) / (1L << 22), ss; 124 | ss = 2.0 * ulp * (seed + 2); /* QUESTION: does this work if seed exceeds 2^32 - 3? See Knuth p. 187. */ 125 | for (j = 0; j < LONG_LAG; j ++) { 126 | u [j] = ss; 127 | ul [j] = 0.0; 128 | ss += ss; 129 | if (ss >= 1.0) ss -= 1.0 - 2 * ulp; 130 | } 131 | for (; j < 2 * LONG_LAG - 1; j ++) 132 | u [j] = ul [j] = 0.0; 133 | u [1] += ulp; 134 | ul [1] = ulp; 135 | t = STREAM_SEPARATION - 1; 136 | while (t > 0) { 137 | for (j = LONG_LAG - 1; j > 0; j --) { 138 | ul [j + j] = ul [j]; 139 | u [j + j] = u [j]; 140 | } 141 | for (j = 2 * LONG_LAG - 2; j > LAG_DIFF; j -= 2) { 142 | ul [2 * LONG_LAG - 1 - j] = 0.0; 143 | u [2 * LONG_LAG - 1 - j] = u [j] - ul [j]; 144 | } 145 | for (j = 2 * LONG_LAG - 2; j >= LONG_LAG; j --) if (ul [j] != 0) { 146 | ul [j - LAG_DIFF] = ulp - ul [j - LAG_DIFF]; 147 | u [j - LAG_DIFF] += u [j]; 148 | if (u [j - LAG_DIFF] >= 1.0) u [j - LAG_DIFF] -= 1.0; 149 | ul [j - LONG_LAG] = ulp - ul [j - LONG_LAG]; 150 | u [j - LONG_LAG] += u [j]; 151 | if (u [j - LONG_LAG] >= 1.0) u [j - LONG_LAG] -= 1.0; 152 | } 153 | if ((seed & 1) != 0) { 154 | for (j = LONG_LAG; j > 0; j --) { 155 | ul [j] = ul [j - 1]; 156 | u [j] = u [j - 1]; 157 | } 158 | ul [0] = ul [LONG_LAG]; 159 | u [0] = u [LONG_LAG]; 160 | if (ul [LONG_LAG] != 0) { 161 | ul [SHORT_LAG] = ulp - ul [SHORT_LAG]; 162 | u [SHORT_LAG] += u [LONG_LAG]; 163 | if (u [SHORT_LAG] >= 1.0) u [SHORT_LAG] -= 1.0; 164 | } 165 | } 166 | if (seed != 0) { 167 | seed >>= 1; 168 | } else { 169 | t --; 170 | } 171 | } 172 | for (j = 0; j < SHORT_LAG; j ++) 173 | randomArray [j + LAG_DIFF] = u [j]; 174 | for (; j < LONG_LAG; j ++) 175 | randomArray [j - SHORT_LAG] = u [j]; 176 | randomArrayPointer1 = 0; 177 | randomArrayPointer2 = LAG_DIFF; 178 | iquality = 0; 179 | randomInited = 1; 180 | } 181 | 182 | double NUMrandomFraction (void) { 183 | /* 184 | Knuth uses a long random array of length QUALITY to copy values from randomArray. 185 | We save 8 kilobytes by using randomArray as a cyclic array (10% speed loss). 186 | */ 187 | long p1, p2; 188 | double newValue; 189 | if (! randomInited) NUMrandomRestart (time (NULL)); 190 | p1 = randomArrayPointer1, p2 = randomArrayPointer2; 191 | if (p1 >= LONG_LAG) p1 = 0; 192 | if (p2 >= LONG_LAG) p2 = 0; 193 | newValue = randomArray [p1] + randomArray [p2]; 194 | if (newValue >= 1.0) newValue -= 1.0; 195 | randomArray [p1] = newValue; 196 | p1 ++; 197 | p2 ++; 198 | if (++ iquality == LONG_LAG) { 199 | for (; iquality < QUALITY; iquality ++) { 200 | double newValue2; 201 | /* 202 | Possible future minor speed improvement: 203 | the cyclic array is walked down instead of up. 204 | The following tests will then be for 0. 205 | */ 206 | if (p1 >= LONG_LAG) p1 = 0; 207 | if (p2 >= LONG_LAG) p2 = 0; 208 | newValue2 = randomArray [p1] + randomArray [p2]; 209 | if (newValue2 >= 1.0) newValue2 -= 1.0; 210 | randomArray [p1] = newValue2; 211 | p1 ++; 212 | p2 ++; 213 | } 214 | iquality = 0; 215 | } 216 | randomArrayPointer1 = p1; 217 | randomArrayPointer2 = p2; 218 | return newValue; 219 | } 220 | 221 | double NUMrandomUniform (double lowest, double highest) { 222 | return lowest + (highest - lowest) * NUMrandomFraction (); 223 | } 224 | 225 | long NUMrandomInteger (long lowest, long highest) { 226 | return lowest + (long) ((highest - lowest + 1) * NUMrandomFraction ()); 227 | } 228 | 229 | double NUMrandomGauss (double mean, double standardDeviation) { 230 | // Knuth, p. 122. 231 | static int secondAvailable = 0; 232 | static double y; 233 | double s, x; 234 | if (secondAvailable) { 235 | secondAvailable = FALSE; 236 | return mean + standardDeviation * y; 237 | } else { 238 | repeat { 239 | x = 2.0 * NUMrandomFraction () - 1.0; /* Inside the square [-1; 1] x [-1; 1]. */ 240 | y = 2.0 * NUMrandomFraction () - 1.0; 241 | s = x * x + y * y; 242 | } until (s < 1.0); /* Inside the unit circle. */ 243 | if (s == 0.0) { 244 | x = y = 0.0; 245 | } else { 246 | double factor = sqrt (-2.0 * log (s) / s); 247 | x *= factor, y *= factor; 248 | } 249 | secondAvailable = TRUE; 250 | return mean + standardDeviation * x; 251 | } 252 | } 253 | -------------------------------------------------------------------------------- /Get_Data_to_Sound.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include "Structure.h" 4 | #include "Pitch.h" 5 | #include "RealTier.h" 6 | #include "SoundCompute.h" 7 | #include "ReadWavFile.h" 8 | #include "Sound_to_Pitch.h" 9 | #include "Pitch_to_PointProcess.h" 10 | #include 11 | #include 12 | #include "NUM.h" 13 | using namespace std; 14 | 15 | #define FREQUENCY 22050.0 16 | #define DURATION 0.1 17 | #define DURATIONSTEP 0.04 18 | #define FRAMESIZE FREQUENCY*0.1 19 | #define FRAMESTEP FREQUENCY*0.04 20 | #define MAX_T 0.02000000001 /* Maximum interval between two voice pulses (otherwise voiceless). */ 21 | 22 | int Pitch_to_Framestep(Pitch srcpitch, Sound me, Pitch thee, int framestep,int pretag) 23 | { 24 | int i = srcpitch->nx, tag = 0; 25 | if(srcpitch->frame[srcpitch->nx].candidate[1].frequency==0)//unvoice 26 | { 27 | while(srcpitch->frame[srcpitch->nx].candidate[1].frequency==0) 28 | { 29 | tag++; 30 | i--; 31 | } 32 | } 33 | else if(srcpitch->frame[srcpitch->nx].candidate[1].frequency>0)//voice 34 | { 35 | while(srcpitch->frame[srcpitch->nx].candidate[1].frequency>0) 36 | { 37 | tag++; 38 | i--; 39 | } 40 | } 41 | if(srcpitch->frame[srcpitch->nx].candidate[1].frequency>0&&tag<3)//·ÅÈëÏÂÒ»²½´¦Àí 42 | { 43 | 44 | } 45 | else//Ö±½ÓÕâÒ»²½¾Í´¦ÀíÁË 46 | { 47 | 48 | } 49 | 50 | return tag; 51 | } 52 | 53 | void Get_Data(double *srcdata, double *buff, int *Flag, int datalength) 54 | { 55 | int i,j; 56 | 57 | for(i = *Flag,j = 1; i < *Flag + FRAMESIZE; i++,j++) 58 | { 59 | buff[j] = srcdata[i%datalength]; 60 | } 61 | int k = (int)FRAMESTEP; 62 | *Flag += k; 63 | } 64 | 65 | void copydata(double *srcdata, double *buff, int start, int end) 66 | { 67 | int i,j; 68 | for(i = start, j = 1; i <= end; i++, j++) 69 | { 70 | buff[j] = srcdata[i]; 71 | } 72 | } 73 | 74 | 75 | 76 | void copypitch(const Pitch me, Pitch him, int start, int end) 77 | { 78 | int i,j,k; 79 | for(i = start,j=1; i <= end; i++, j++) 80 | { 81 | him->frame[j].nCandidates = me->frame[i].nCandidates; 82 | him->frame[j].intensity = me->frame[i].intensity; 83 | 84 | for(k = 1 ; k <= me->frame[i].nCandidates; k++) 85 | { 86 | him->frame[j].candidate[k].frequency = me->frame[i].candidate[k].frequency; 87 | him->frame[j].candidate[k].strength = me->frame[i].candidate[k].strength; 88 | } 89 | 90 | } 91 | } 92 | 93 | 94 | void Convert_array_to_double(int *int_data, double *double_data, int datalength) 95 | { 96 | int i; 97 | for(i = 0; i < datalength; i++) 98 | { 99 | double_data[i] = int_data[i]/FREQUENCY;//ÐèÒªÐÞ¸Ä 100 | } 101 | } 102 | 103 | 104 | Sound Data_to_Sound(double *data,double samplingFrequency,int numOfChannels, double duration) 105 | { 106 | Sound sound = NULL; 107 | sound = Sound_createSimple(duration, samplingFrequency, numOfChannels); 108 | 109 | if(! sound) 110 | return NULL; 111 | return sound; 112 | } 113 | 114 | long pitch_xToIndex(Pitch me, double x) 115 | { 116 | return (long)floor((x-my x1)/my dx); 117 | } 118 | 119 | PointProcess Sound_and_Pitch_to_Pulses (Sound me, Pitch him, double formantRatio,double new_pitch, 120 | double pitchRangeFactor, double durationFactor){ 121 | double samplingFrequency_old = 1 / my dx; 122 | 123 | if(my ny > 1){ 124 | std::cout<<"Change Gender works only on mono sounds."< 1){ 164 | std::cout<<"Change Gender works only on mono sounds."<xmin, sound->xmax, factor);//ƵÂÊͳһ³ËÉÏÁËfactor 204 | PitchTier_modifyRange_old (pitchTier, sound->xmin, sound->xmax, pitchRangeFactor, new_pitch); 205 | //factor=pitchRangeFactorºÍfmid=new_pitchͨ¹ýËã·¨f = fmid + (f - fmid) * factor; 206 | }else{ 207 | std::cout<<"There were no voiced segments found."< 1){ 231 | std::cout<<"Change Gender works only on mono sounds."< 1){ 270 | std::cout<<"Change Gender works only on mono sounds."<xmin, sound->xmax, pitchMultiplier/formantMultiplier); 304 | PitchTier_modifyExcursionRange(pitchTier, sound->xmin, sound->xmax, pitchRangeMultiplier, median); 305 | }else if (pitchMultiplier != 1){ 306 | std::cout<<"Warning: Pitch has not been changed because the sound was entirely voiceless."<nt; i > 0; i--) 327 | { 328 | if(pulses->t[i]t[i]; 330 | } 331 | return 0; 332 | } 333 | 334 | int find_pulses_vextor_index(PointProcess pulses, double time, int low, int high)// low = 1, high = pulses->nt 335 | { 336 | 337 | int mid = (low + high)/2; 338 | if(pulses->t[mid] == time)//Ëã·¨ÓдýÑéÖ¤ 339 | return mid; 340 | else if(pulses->t[high] t[mid] > time) 343 | return find_pulses_vextor_index(pulses,time,low, mid - 1); 344 | else return find_pulses_vextor_index(pulses, time, mid + 1, high); 345 | } 346 | 347 | Pitch Pitch_create2(Pitch pitch0, int start, double tmin, double tmax, long nt, double dt, double t1, double ceiling, int maxCandidates){ 348 | Pitch me = (Pitch)malloc(sizeof(structPitch)); 349 | if(!me) return NULL; 350 | 351 | my xmin = tmin; 352 | my xmax = tmax; 353 | my nx = nt; 354 | my dx = dt; 355 | my x1 = t1; 356 | my ceiling = ceiling; 357 | my maxnCandidates = maxCandidates; 358 | my frame = (Pitch_Frame)malloc(sizeof(structPitch_Frame) * (nt + 1)); 359 | 360 | /* Put one candidate in every frame (unvoiced, silent). */ 361 | for(long i = 1,j = start; i <= nt; ++ i, j++) 362 | Pitch_Frame_init(& my frame[i], pitch0->frame[j].nCandidates); 363 | 364 | return me; 365 | } 366 | 367 | void copycheckdata(double *from, double *to, int start, int copylength) 368 | { 369 | int i; 370 | for(i = 1; i <= copylength; i++) 371 | { 372 | to[start+i-1] = from[i]; 373 | } 374 | 375 | } 376 | -------------------------------------------------------------------------------- /Pich_to_PointProcess.cpp: -------------------------------------------------------------------------------- 1 | // Pitch_to_PointProcess.cpp 2 | /* 3 | *implement the function for pith to pointProcess defined in Structure.cpp 4 | */ 5 | 6 | #include "Pitch_to_PointProcess.h" 7 | #include 8 | #include "Structure.h" 9 | #include "SoundCompute.h" 10 | #include "Pitch.h" 11 | #include "NUM.h" 12 | 13 | static double findExtremum_3 (double *channel1_base, double *channel2_base, long d, long n, int includeMaxima, int includeMinima) { 14 | double *channel1 = channel1_base + d, *channel2 = channel2_base ? channel2_base + d: NULL; 15 | int includeAll = includeMaxima == includeMinima; 16 | long imin = 1, imax = 1, i, iextr; 17 | double minimum, maximum; 18 | if (n < 3) { 19 | if (n <= 0) return 0.0; /* Outside. */ 20 | else if (n == 1) return 1.0; 21 | else { /* n == 2 */ 22 | double x1 = channel2 ? 0.5 * (channel1[0] + channel2[0]) : channel1[0]; 23 | double x2 = channel2 ? 0.5 * (channel1[1] + channel2[1]) : channel1[1]; 24 | double xleft = includeAll ? fabs (x1) : includeMaxima ? x1 : - x1; 25 | double xright = includeAll ? fabs (x2) : includeMaxima ? x2 : - x2; 26 | if (xleft > xright) return 1.0; 27 | else if (xleft < xright) return 2.0; 28 | else return 1.5; 29 | } 30 | } 31 | minimum = maximum = channel2 ? 0.5 * (channel1[1] + channel2[1]) : channel1[1]; 32 | for (i = 2; i <= n; i ++) { 33 | double value = channel2 ? 0.5 * (channel1[i] + channel2[i]) : channel1[i]; 34 | if (value < minimum) { minimum = value; imin = i; } 35 | if (value > maximum) { maximum = value; imax = i; } 36 | } 37 | if (minimum == maximum) { 38 | return 0.5 * (n + 1.0); /* All equal. */ 39 | } 40 | iextr = includeAll ? ( fabs (minimum) > fabs (maximum) ? imin : imax ) : includeMaxima ? imax : imin; 41 | if (iextr == 1) return 1.0; 42 | if (iextr == n) return (double) n; 43 | /* Parabolic interpolation. */ 44 | /* We do NOT need fabs here: we look for a genuine extremum. */ 45 | double valueMid = channel2 ? 0.5 * (channel1[iextr] + channel2[iextr]) : channel1[iextr]; 46 | double valueLeft = channel2 ? 0.5 * (channel1[iextr - 1] + channel2[iextr - 1]) : channel1[iextr - 1]; 47 | double valueRight = channel2 ? 0.5 * (channel1[iextr + 1] + channel2[iextr + 1]) : channel1[iextr + 1]; 48 | return iextr + 0.5 * (valueRight - valueLeft) / (2 * valueMid - valueLeft - valueRight); 49 | } 50 | 51 | static double Sound_findExtremum (Sound me, double tmin, double tmax, int includeMaxima, int includeMinima) { 52 | long imin = (long) floor ((tmin - my x1) / my dx) + 1; /** Sampled_xToLowIndex (me, tmin); **/ 53 | long imax = (long) ceil ((tmin - my x1) / my dx) + 1; /** Sampled_xToHighIndex (me, tmax); **/ 54 | if(! NUMdefined (tmin) || ! NUMdefined (tmax)) { 55 | std::cout<<"tmin = "< my nx) imax = my nx; 62 | double iextremum = findExtremum_3 (my z[1], my ny > 1 ? my z[2] : NULL, imin - 1, imax - imin + 1, includeMaxima, includeMinima); 63 | if (iextremum) 64 | return my x1 + (imin - 1 + iextremum - 1) * my dx; 65 | else 66 | return (tmin + tmax) / 2; 67 | } 68 | 69 | static double Sound_findMaximumCorrelation (Sound me, double t1, double windowLength, double tmin2, 70 | double tmax2, double *tout, double *peak) { 71 | double maximumCorrelation = -1.0, r1 = 0.0, r2 = 0.0, r3 = 0.0, r1_best, r3_best, ir; 72 | double halfWindowLength = 0.5 * windowLength; 73 | long ileft1 = (long) floor ((t1 - halfWindowLength - my x1) / my dx + 1.5); 74 | long iright1 = (long) floor ((t1 + halfWindowLength - my x1) / my dx + 1.5); 75 | long ileft2min = (long) floor ((tmin2 - halfWindowLength - my x1) / my dx) + 1; 76 | long ileft2max = (long) ceil ((tmax2 - halfWindowLength - my x1) / my dx) + 1; 77 | *peak = 0.0; /* Default. */ 78 | for (long ileft2 = ileft2min; ileft2 <= ileft2max; ileft2 ++) { 79 | double norm1 = 0.0, norm2 = 0.0, product = 0.0, localPeak = 0.0; 80 | if (my ny == 1) { 81 | for (long i1 = ileft1, i2 = ileft2; i1 <= iright1; i1 ++, i2 ++) { 82 | if (i1 < 1 || i1 > my nx || i2 < 1 || i2 > my nx) continue; 83 | double amp1 = my z[1][i1], amp2 = my z[1][i2]; 84 | norm1 += amp1 * amp1; 85 | norm2 += amp2 * amp2; 86 | product += amp1 * amp2; 87 | if (fabs (amp2) > localPeak) 88 | localPeak = fabs (amp2); 89 | } 90 | } else { 91 | for (long i1 = ileft1, i2 = ileft2; i1 <= iright1; i1 ++, i2 ++) { 92 | if (i1 < 1 || i1 > my nx || i2 < 1 || i2 > my nx) continue; 93 | double amp1 = 0.5 * (my z[1][i1] + my z[2][i1]), amp2 = 0.5 * (my z[1][i2] + my z[2][i2]); 94 | norm1 += amp1 * amp1; 95 | norm2 += amp2 * amp2; 96 | product += amp1 * amp2; 97 | if (fabs (amp2) > localPeak) 98 | localPeak = fabs (amp2); 99 | } 100 | } 101 | r1 = r2; 102 | r2 = r3; 103 | r3 = product ? product / (sqrt (norm1 * norm2)) : 0.0; 104 | if (r2 > maximumCorrelation && r2 >= r1 && r2 >= r3) { 105 | r1_best = r1; 106 | maximumCorrelation = r2; 107 | r3_best = r3; 108 | ir = ileft2 - 1; 109 | *peak = localPeak; 110 | } 111 | } 112 | 113 | // Improve the result by means of parabolic interpolation. 114 | if (maximumCorrelation > -1.0) { 115 | double d2r = 2 * maximumCorrelation - r1_best - r3_best; 116 | if (d2r != 0.0) { 117 | double dr = 0.5 * (r3_best - r1_best); 118 | maximumCorrelation += 0.5 * dr * dr / d2r; 119 | ir += dr / d2r; 120 | } 121 | *tout = t1 + (ir - ileft1) * my dx; 122 | } 123 | return maximumCorrelation; 124 | } 125 | 126 | long PointProcess_getLowIndex (PointProcess me, double t) { 127 | if (my nt == 0 || t < my t [1]) 128 | return 0; 129 | if (t >= my t[my nt]) /* Special case that often occurs in practice. */ 130 | return my nt; 131 | if(my nt == 1){ 132 | std::cout<<"my nt = 1. Pitch_to_PointProcess.cpp Line 10"<= my t[mid]) left = mid; 143 | else right = mid; 144 | } 145 | /**** !!!???? Melder_assert (right == left + 1); ****/ 146 | return left; 147 | } 148 | 149 | void PointProcess_addPoint (PointProcess me, double t) { 150 | if (t == NUMundefined){ 151 | std::cout<<"Cannot add a point at an undefined time. Pitch_to_PointProcess.cpp: Line9."<= my maxnt) { 156 | // Create without change. 157 | double *dum = (double *)malloc(sizeof(double) * (2 * my nt + 1)); 158 | /**** autoNUMvector dum (1, 2 * my maxnt); ****/ 159 | memset(dum, 0, sizeof(double) * (2 * my nt + 1)); 160 | for(long i = 1; i <= my nt; ++ i) 161 | dum[i] = my t[i]; 162 | // memcpy(dum + sizeof(double), my t + sizeof(double), my nt * sizeof(double)); 163 | /**** NUMvector_copyElements (my t, dum.peek(), 1, my nt); ****/ 164 | 165 | //Change without error. 166 | /* NUMvector_free (my t, 1); 167 | my t = dum.transfer(); */ 168 | my t = dum; 169 | my maxnt = 2 * my nt + 1; 170 | } 171 | if (my nt == 0 || t >= my t[my nt]) { // special case that often occurs in practice 172 | my t[++ my nt] = t; 173 | } else { 174 | long left = PointProcess_getLowIndex (me, t); 175 | if (left == 0 || my t[left] != t) { 176 | for (long i = my nt; i > left; i --) my t[i + 1] = my t[i]; 177 | my nt ++; 178 | my t[left + 1] = t; 179 | } 180 | } 181 | } 182 | 183 | void PointProcess_init(I, double tmin, double tmax, long initialMaxnt) { 184 | iam (PointProcess); 185 | my xmin = tmin; 186 | my xmax = tmax; 187 | if (initialMaxnt < 1) initialMaxnt = 1; 188 | my maxnt = initialMaxnt; 189 | my nt = 0; 190 | my t = (double *) malloc ( sizeof(double) * (my maxnt + 1)); 191 | if(my t == NULL) 192 | return ; 193 | for(long i = 0; i <= my maxnt; ++ i) 194 | my t[i] = 0.0; 195 | } 196 | 197 | PointProcess PointProcess_create(double tmin, double tmax, long initialMaxnt) { 198 | PointProcess me = (PointProcess)malloc(sizeof(structPointProcess)); 199 | PointProcess_init(me, tmin, tmax, initialMaxnt); 200 | return me; 201 | } 202 | 203 | int Pitch_getVoicedIntervalAfter (Pitch me, double after, double *tleft, double *tright) { 204 | long ileft = (long)ceil((after - my x1) / my dx) + 1; /// Sampled_xToHighIndex (me, after); 205 | long iright = 0; 206 | if (ileft > my nx) return 0; /* Offright. */ 207 | if (ileft < 1) ileft = 1; /* Offleft. */ 208 | 209 | /* Search for first voiced frame. */ 210 | for (; ileft <= my nx; ileft ++) 211 | if (Pitch_isVoiced_i (me, ileft)) break; 212 | if (ileft > my nx) return 0; /* Offright. */ 213 | 214 | /* Search for last voiced frame. */ 215 | for (iright = ileft; iright <= my nx; iright ++) 216 | if (! Pitch_isVoiced_i (me, iright)) break; 217 | iright --; 218 | 219 | *tleft = my x1 + (ileft - 1) * my dx - 0.5 * my dx; /* The whole frame is considered voiced. */ 220 | /**Sampled_indexToX (me, ileft) - 0.5 * my dx; ***/ 221 | 222 | *tright = my x1 + (iright - 1) * my dx + 0.5 * my dx; /**** Sampled_indexToX (me, iright) + 0.5 * my dx; ****/ 223 | if (*tleft >= my xmax - 0.5 * my dx) return 0; 224 | if (*tleft < my xmin) *tleft = my xmin; 225 | if (*tright > my xmax) *tright = my xmax; 226 | return 1; 227 | } 228 | 229 | PointProcess Sound_Pitch_to_PointProcess_cc (Sound sound, Pitch pitch){ 230 | PointProcess point = PointProcess_create (sound->xmin, sound->xmax, 10); 231 | double t = pitch->xmin; 232 | double addedRight = -1e300; 233 | double globalPeak = Sound_getAbsoluteExtremum(sound, sound->xmin, sound->xmax, 0), peak; 234 | //¼ÆËãµÃµ½È«¾ÖµÄ¾ø¶ÔÖµ·åÖµ 235 | /**globalPeak = Vector_getAbsoluteExtremum (sound, sound -> xmin, sound -> xmax, 0), peak;**/ 236 | 237 | // Cycle over all voiced intervals. 238 | /**** autoMelderProgress progress (L"Sound & Pitch: To PointProcess..."); ****/ 239 | for (;;) { 240 | double tleft, tright; 241 | if (! Pitch_getVoicedIntervalAfter (pitch, t, & tleft, & tright)) 242 | break; 243 | // Go to the middle of the voice stretch. 244 | double tmiddle = (tleft + tright) / 2; 245 | /**** Melder_progress ((tmiddle - sound->xmin) / (sound->xmax - sound->xmin), L"Sound & Pitch to PointProcess"); ****/ 246 | double f0middle = Pitch_getValueAtTime (pitch, tmiddle, kPitch_unit_HERTZ, Pitch_LINEAR); 247 | /// #define Pitch_LINEAR 1 #define kPitch_unit_HERTZ 0 248 | 249 | // Our first point is near this middle. 250 | if (f0middle == NUMundefined) { 251 | std::cout<<"Sound_Pitch_to_PointProcess_cc: tleft: "<< tleft <<", tright:"<< tright 252 | <<", f0middle: "<< f0middle < 0.7 && peak > 0.023333 * globalPeak && tmax - addedRight > 0.8 / f0) { 283 | PointProcess_addPoint (point, tmax); 284 | } 285 | break; 286 | } 287 | if (correlation > 0.3 && (peak == 0.0 || peak > 0.01 * globalPeak)) { 288 | if (tmax - addedRight > 0.8 / f0) { // do not fill in a short originally unvoiced interval twice 289 | PointProcess_addPoint (point, tmax); 290 | } 291 | } 292 | } 293 | tmax = tsave; 294 | for (;;) { 295 | double f0 = Pitch_getValueAtTime (pitch, tmax, kPitch_unit_HERTZ, Pitch_LINEAR), correlation; 296 | if (f0 == NUMundefined) break; 297 | correlation = Sound_findMaximumCorrelation (sound, tmax, 1.0 / f0, tmax + 0.8 / f0, 298 | tmax + 1.25 / f0, &tmax, &peak); 299 | //¼ÆËãµÃµ½×î´óÏà¹ØÏµÊý£¬Çø¼äÄÚµÄ×î´óÖµÒÔ¼°¾Ö²¿·åÖµ 300 | 301 | if (correlation == -1) /*break*/ tmax += 1.0 / f0; 302 | //Ñ­»·ÖÕÖ¹Ìõ¼þ 303 | if (tmax > tright) { 304 | if (correlation > 0.7 && peak > 0.023333 * globalPeak) { 305 | PointProcess_addPoint (point, tmax); 306 | addedRight = tmax; 307 | } 308 | break; 309 | } 310 | if (correlation > 0.3 && (peak == 0.0 || peak > 0.01 * globalPeak)) { 311 | PointProcess_addPoint (point, tmax); 312 | addedRight = tmax; 313 | } 314 | } 315 | t = tright; 316 | } 317 | return point; 318 | } 319 | 320 | long PointProcess_getNearestIndex (PointProcess me, double t){ 321 | if (my nt == 0) 322 | return 0; 323 | if (t <= my t [1]) 324 | return 1; 325 | if (t >= my t [my nt]) 326 | return my nt; 327 | /* Start binary search. */ 328 | long left = 1, right = my nt; 329 | while (left < right - 1) { 330 | long mid = (left + right) / 2; 331 | if (t >= my t [mid]) left = mid; else right = mid; 332 | } 333 | 334 | if(right != left + 1){ 335 | std::cout<<"right != left + 1"< 2 | #include 3 | #include "Structure.h" 4 | #include "Pitch.h" 5 | #include "SoundCompute.h" 6 | #include "ReadWavFile.h" 7 | #include "Sound_to_Pitch.h" 8 | #include "Pitch_to_PointProcess.h" 9 | #include 10 | #include "Get_Data_to_Sound.h" 11 | #include "math.h" 12 | using namespace std; 13 | 14 | #define FREQUENCY 22050.0 15 | #define DURATION 0.1 16 | #define DURATIONSTEP 0.04 17 | #define FRAMESIZE FREQUENCY*0.1 18 | #define FRAMESTEP FREQUENCY*0.04 19 | 20 | #define formatRatio 1.0 21 | #define pitchmedian 225.0 22 | #define pitchRangeFactor 0.0 23 | #define durationFactor 1.0 24 | #define new_pitch 1.8 25 | 26 | void test() 27 | { 28 | double srcdata[120000];//* 29 | int count=120000;//* 30 | FILE* fd = NULL; 31 | 32 | memset(srcdata, 0, sizeof(double)*count); 33 | 34 | fd = fopen("D:/mf.txt","r"); 35 | if(fd == NULL){ 36 | std::cout<<"the file can't be opened"<z[1], &flag, count); 69 | 70 | if(i == 1)//Õⲿ·ÖÖ»ÊÇΪÁ˲âÊÔ±äÉùµÄÊý¾Ý 71 | { 72 | checkSound = Sound_create(0,6,180000,sound0->dx,sound0->x1,1);//* 73 | for(int t = 0; t <= 180000; ++t)//* 74 | { 75 | checkSound->z[1][t] = 0.0; 76 | } 77 | } 78 | 79 | pitch0 = computePitch(sound0); 80 | 81 | 82 | if(nexttime > lasttime&&lasttime >= 0)// && soundindex > presoundindex nexttime > DURATIONSTEP&& 83 | { 84 | printf("½øÈë±äÉù%d\n",i); 85 | 86 | 87 | //changeSound = Sound_and_Pitch_and_Pulses_changeGender_old (sound0, pitch0, pulses2, formatRatio ,pitchmedian, pitchRangeFactor, durationFactor); 88 | //changeSound = Sound_and_pitch_and_pulses_changespeaker(sound0, pitch0, pulses2, formatRatio ,new_pitch, pitchRangeFactor, durationFactor); 89 | 90 | changeSound = Sound_and_Pitch_changeGender_old(sound0, pitch0, formatRatio ,pitchmedian, pitchRangeFactor, durationFactor); 91 | //changeSound = Sound_and_pitch_changespeaker(sound0, pitch0, formatRatio ,new_pitch, pitchRangeFactor, durationFactor); 92 | 93 | 94 | if(changeSound!=NULL)//there were no voiced segment found 95 | { 96 | what++; 97 | nexttime =changeSound->xmax;//ÕâÀïÔÙ¿¼ÂÇһϠchangeSound->nx/FREQUENCY; 98 | printf("±äÉùÕý³£\n"); 99 | 100 | temp = floor(lasttime * FREQUENCY +0.5); 101 | if(temp == 0) 102 | temp = 1; 103 | for(int a = checkindex,b=0; a <= checkindex + changeSound->nx-temp; a++,b++) 104 | { 105 | checkSound->z[1][a] = changeSound->z[1][temp+b]; 106 | } 107 | checkindex += changeSound->nx - temp + 1; //¼ì²é 108 | cout<<"flag = "<nx-temp; a++,b++) 121 | { 122 | checkSound->z[1][a] = sound0->z[1][temp+b]; 123 | } 124 | checkindex += sound0->nx-temp+1; 125 | lasttime = 0; 126 | flag += sound0->nx+1-FRAMESTEP;//Èç¹û¸Ä±äFRAMESTEP´óС£¬ÕâÀïÒ²Òª±ä£¬Òª²»ÒªÔÙ¼õÈ¥Ò»¸ötemp£¿£¿£¿£¿ 127 | 128 | } 129 | 130 | 131 | free(changeSound); 132 | 133 | } 134 | else 135 | { 136 | printf("nexttime < lasttime£¬copyÔ­Êý¾Ý\n"); 137 | //¸ü½øÒ»²½µÄ»°¾ÍÒªcopy´Ólasttimeµ½sound0->xmax,È»ºó±äÕâÒ»²¿·ÖµÄÉùÒô£¬¶ø²»ÊÇÏÂÃæÕâ¶Î 138 | temp = floor(lasttime * FREQUENCY +0.5); 139 | if(temp == 0) 140 | temp = 1; 141 | for(int a = checkindex,b=0; a <= checkindex + sound0->nx-temp; a++,b++) 142 | { 143 | checkSound->z[1][a] = sound0->z[1][temp+b]; 144 | } 145 | checkindex += sound0->nx-temp+1; 146 | lasttime = 0; 147 | flag += sound0->nx+1-FRAMESTEP;//Èç¹û¸Ä±äFRAMESTEP´óС£¬ÕâÀïÒ²Òª±ä £¿£¿£¿£¿£¿-temp 148 | } 149 | 150 | 151 | free(sound0); 152 | free(pitch0); 153 | 154 | } 155 | std::cout<<"Please Enter the path to .xxx file: "<>cspathto; 157 | 158 | csfp = fopen(cspathto.c_str(), "w+"); 159 | Sound_writeTxt(checkSound, csfp); 160 | 161 | free(checkSound); 162 | cout<<"test end"<z[1][a] = source[b]; 180 | } 181 | pitch0 = computePitch(sound0); 182 | if(button_info == true) 183 | changeSound = Sound_and_Pitch_changeGender_old(sound0, pitch0, formatratio ,pitch_median, pitchrangefactor, durationfactor); 184 | else 185 | changeSound = Sound_and_pitch_changespeaker(sound0, pitch0, formatratio ,newpitch, pitchrangefactor,durationfactor); 186 | if(changeSound!=NULL) 187 | { 188 | for(a = 0, b = 1324; a<882 && b<= changeSound->nx; a++,b++) 189 | { 190 | changedata[a] = changeSound->z[1][b]; 191 | } 192 | } 193 | else 194 | { 195 | for(a = 0, b = 1324; a<882 && b<= sound0->nx; a++,b++) 196 | { 197 | changedata[a] = sound0->z[1][b]; 198 | } 199 | } 200 | return changedata; 201 | } 202 | 203 | 204 | void test4() 205 | { 206 | printf("hello world!\n"); 207 | } 208 | 209 | extern "C" _declspec(dllexport) int add(int a, int b) 210 | { 211 | printf("a+b³ÌÐò"); 212 | return a+b; 213 | } 214 | 215 | int Add(int plus1, int plus2) 216 | { 217 | int add_result = plus1 + plus2; 218 | return add_result; 219 | } 220 | 221 | int test2() 222 | { 223 | Sound sound3 = NULL, changeSound3 = NULL; 224 | Pitch pitch3 = NULL; 225 | 226 | PointProcess pointprocess3 = NULL; 227 | VoicedUnvoiced VUV = NULL; 228 | 229 | std::string pathfrom, sspathto, cspathto; 230 | std::cout<<"Please Enter the path of .wav file: "<>pathfrom; 232 | sound3 = Sound_readFromSoundFile(pathfrom); 233 | 234 | if (!sound3) { 235 | std::cout<<"Error, No Sound read from file.!"<>sspathto; 251 | ssfp = fopen(sspathto.c_str(), "w+"); 252 | std::cout<<"Please Enter the path to .xxx file: "<>cspathto; 254 | csfp = fopen(cspathto.c_str(), "w+"); 255 | if(csfp == NULL || ssfp == NULL) 256 | std::cout<<"open file "<nx - 1; 285 | 286 | memcpy(sound0->z[1] + 1, source, flag*sizeof(double)); 287 | 288 | /* 289 | for(a = 1, b = 0; a < flag2 && b < flag; a++, b++) 290 | { 291 | sound0->z[1][a] = source[b]; 292 | }*/ 293 | 294 | 295 | pitch0 = computePitch(sound0); 296 | if(pitch0 == NULL) 297 | return; 298 | 299 | if(button_info) 300 | changeSound = Sound_and_Pitch_changeGender_old(sound0, pitch0, formatratio ,pitch_median, pitchrangefactor,1.0); 301 | else 302 | changeSound = Sound_and_pitch_changespeaker(sound0, pitch0, formatratio ,newpitch, pitchrangefactor,1.0); 303 | if(changeSound != NULL) 304 | memcpy(changedata, changeSound->z[1] + 1, flag*sizeof(double)); 305 | 306 | free(sound0); 307 | free(pitch0); 308 | free(changeSound); 309 | 310 | } 311 | 312 | 313 | //Ëͺó40ÃëµÄtestº¯Êý 314 | void test40(double source[], double changedata[], double frequency, double formatratio,double pitch_median, 315 | double pitchrangefactor, double newpitch,bool button_info) 316 | { 317 | 318 | Sound sound0 = NULL, changeSound = NULL; 319 | Pitch pitch0 = NULL; 320 | double duration; 321 | int flag; 322 | int start = floor(0.06*frequency) + 1; 323 | 324 | flag = (int)changedata[0]; 325 | 326 | if(flag <= 2) 327 | { 328 | memcpy(changedata, source + start , floor(0.04*frequency)*sizeof(double));//copy the last 40ms 329 | return ; 330 | } 331 | duration = flag/frequency; 332 | sound0 = Sound_createSimple(duration, frequency, 1); 333 | 334 | if(sound0->nx > flag) 335 | memcpy(sound0->z[1] + 1, source, flag*sizeof(double)); 336 | else 337 | memcpy(sound0->z[1] + 1, source, sound0->nx*sizeof(double)); 338 | 339 | pitch0 = computePitch(sound0); 340 | if(pitch0 == NULL) 341 | { 342 | memcpy(changedata, source + start , floor(0.04*frequency)*sizeof(double));//copy the last 40ms 343 | return; 344 | } 345 | if(button_info) 346 | changeSound = Sound_and_Pitch_changeGender_old(sound0, pitch0, formatratio ,pitch_median, pitchrangefactor,1.0); 347 | else 348 | changeSound = Sound_and_pitch_changespeaker(sound0, pitch0, formatratio ,newpitch, pitchrangefactor,1.0); 349 | 350 | if(changeSound != NULL) 351 | memcpy(changedata, changeSound->z[1] + start, floor(0.04*frequency)*sizeof(double)); 352 | else 353 | { 354 | memcpy(changedata, source + start , floor(0.04*frequency)*sizeof(double));//copy the last 40ms 355 | } 356 | 357 | 358 | free(sound0); 359 | free(pitch0); 360 | free(changeSound); 361 | 362 | } 363 | 364 | Sound test_multi(double source[], double changedata[], double frequency, double formatratio,double pitch_median, 365 | double pitchrangefactor, double newpitch,bool button_info) 366 | { 367 | 368 | Sound sound0 = NULL, changeSound = NULL,checkSound = NULL; 369 | Pitch pitch0 = NULL; 370 | double duration; 371 | int flag; 372 | int a; 373 | double max; 374 | 375 | flag = (int)changedata[0]; 376 | max = source[0]; 377 | 378 | for(a = 0; a < flag; a++) 379 | { 380 | if(fabs(source[a]) >= fabs(max)) 381 | max = source[a]; 382 | } 383 | for(a = 0; a < flag; a++) 384 | { 385 | source[a] /= fabs(max); 386 | } 387 | 388 | memcpy(changedata, source, flag*sizeof(double)); 389 | 390 | if(flag <= 2) 391 | return NULL; 392 | 393 | duration = flag/frequency; 394 | sound0 = Sound_createSimple(duration, frequency, 1); 395 | int flag2 = sound0->nx - 1; 396 | 397 | memcpy(sound0->z[1] + 1, source, flag*sizeof(double)); 398 | 399 | pitch0 = computePitch(sound0); 400 | if(pitch0 == NULL) 401 | return NULL; 402 | 403 | if(button_info) 404 | changeSound = Sound_and_Pitch_changeGender_old(sound0, pitch0, formatratio ,pitch_median, pitchrangefactor,1.0); 405 | else 406 | changeSound = Sound_and_pitch_changespeaker(sound0, pitch0, formatratio ,newpitch, pitchrangefactor,1.0); 407 | if(changeSound != NULL) 408 | { 409 | 410 | checkSound = Sound_create(0,6,180000,sound0->dx,sound0->x1,1);//* 411 | for(int t = 0; t <= 180000; ++t)//* 412 | { 413 | checkSound->z[1][t] = 0.0; 414 | } 415 | memcpy(changedata, changeSound->z[1] + 1, flag*sizeof(double)); 416 | for(a = 0; a < flag; a++) 417 | { 418 | changedata[a] *= fabs(max); 419 | } 420 | memcpy(checkSound->z[1], changedata, flag*sizeof(double)); 421 | } 422 | else 423 | { 424 | for(a = 0; a < flag; a++) 425 | { 426 | changedata[a] *= fabs(max); 427 | } 428 | return NULL; 429 | } 430 | 431 | 432 | 433 | free(sound0); 434 | free(pitch0); 435 | free(changeSound); 436 | return checkSound; 437 | } 438 | 439 | void testoftest3() 440 | { 441 | double srcdata[64000];//* 442 | int count=64000;//* 443 | FILE* fd = NULL; 444 | 445 | memset(srcdata, 0, sizeof(double)*count); 446 | 447 | fd = fopen("D:/mf2.txt","r"); 448 | if(fd == NULL){ 449 | std::cout<<"the file can't be opened"<>cspathto; 471 | 472 | csfp = fopen(cspathto.c_str(), "w+"); 473 | Sound_writeTxt(sound, csfp); 474 | 475 | 476 | 477 | } 478 | 479 | 480 | int main(int argc, char *argv[]) 481 | { 482 | //test2(); 483 | //test(); 484 | testoftest3(); 485 | return 0; 486 | } 487 | 488 | -------------------------------------------------------------------------------- /RealTier.cpp: -------------------------------------------------------------------------------- 1 | #include "iostream" 2 | #include "Structure.h" 3 | #include "RealTier.h" 4 | #include "NUM.h" 5 | #include "Pitch.h" 6 | #include "math.h" 7 | 8 | #include 9 | #include 10 | 11 | template 12 | 13 | int compare(T x, T y){ 14 | return x > y ? 1 : (x == y ? 0 : -1); 15 | } 16 | 17 | void PitchTier_modifyExcursionRange(PitchTier me, double tmin, double tmax, double multiplier, double fref_Hz) { 18 | if (fref_Hz <= 0 || multiplier == 1.0) 19 | return; 20 | 21 | double fref_st = 12.0 * log (fref_Hz / 100.0) / NUMln2; 22 | for (long i = 1; i <= my points -> size; i++) { 23 | RealPoint point = (RealPoint)(my points->item[i]); //ÀàÐÍת»» 24 | double f = point -> value; 25 | if (point -> number < tmin || point -> number > tmax) 26 | continue; 27 | if (f > 0) { 28 | double f_st = fref_st + 12.0 * (log(f/fref_Hz)/log(2.0))*multiplier; //Ô´ÂëÖÐΪ£ºlog2(f/fref_Hz) 29 | point -> value = 100.0 * exp (f_st * (NUMln2 / 12.0)); 30 | } 31 | } 32 | } 33 | 34 | RealPoint RealPoint_create (double time, double value) 35 | { 36 | RealPoint me = (RealPoint) malloc(sizeof(structRealPoint)); 37 | my number = time; 38 | my value = value; 39 | return me; 40 | } 41 | 42 | void RealTier_init (RealTier me, double tmin, double tmax) { 43 | my xmin = tmin; 44 | my xmax = tmax; 45 | my points = SortedSetOfDouble_create (); 46 | } 47 | 48 | PitchTier PitchTier_create (double tmin, double tmax) 49 | { 50 | PitchTier me = (PitchTier) malloc(sizeof(structPitchTier)); 51 | RealTier_init (me, tmin,tmax); 52 | return me; 53 | } 54 | 55 | DurationTier DurationTier_create (double tmin, double tmax) 56 | { 57 | DurationTier me = (DurationTier) malloc (sizeof(structDurationTier)); 58 | RealTier_init (me, tmin,tmax); 59 | return me; 60 | } 61 | 62 | DurationTier PointProcess_upto_DurationTier (PointProcess me) { 63 | DurationTier thee = (DurationTier)malloc(sizeof(structDurationTier)); 64 | for(long i = 1; i < my nt; ++ i) 65 | RealTier_addPoint(thee, my t[i], 1.0); 66 | return thee; 67 | } 68 | 69 | void SortedSet_init(SortedSetOfDouble me, long initialCapacity) 70 | { 71 | my _capacity = initialCapacity >= 1 ? initialCapacity : 1; 72 | my size = 0; 73 | my item = (SimpleDouble *)calloc(sizeof(structSimpleDouble *), (initialCapacity + 1)); 74 | // my item --; // base 1 75 | } 76 | 77 | SortedSetOfDouble SortedSetOfDouble_create (void) //Collection.cpp 482 78 | { 79 | SortedSetOfDouble me = (SortedSetOfDouble)calloc(sizeof(structSortedSetOfDouble), 1); 80 | SortedSet_init(me, 10); //Collection.cpp 478 81 | return me; 82 | } 83 | 84 | long SortedSet_getposition(SortedSetOfDouble me, SimpleDouble data) //Collection.cpp 398 85 | { 86 | if(my size == 0) return 1; //empty set? then 'data' is going to be the first item 87 | int pos = compare(data->number, my item[my size]->number); // compare with the last item 88 | if(pos > 0) return my size + 1; // insert at end 89 | if(pos == 0) return 0; 90 | if(data->number < my item[1]->number) // compare with the first item 91 | return 1; 92 | long left = 1, right = my size; 93 | 94 | while(left < right - 1){ 95 | long mid = (left + right) / 2; 96 | if(compare(data->number, my item[mid]->number) > 0) 97 | left = mid; 98 | else 99 | right = mid; 100 | } 101 | 102 | if(!compare(data->number, my item[left]->number) || !compare(data->number, my item[right]->number)) 103 | return 0; 104 | return right; 105 | } 106 | // Collection.cpp 250 107 | void SortedSet_insertItem(SortedSetOfDouble me, SimpleDouble data, long pos) 108 | { 109 | if(my size >= my _capacity){ 110 | SimpleDouble *dum = NULL; 111 | dum = (SimpleDouble *)calloc(sizeof(SimpleDouble), 2 * my _capacity*sizeof(SimpleDouble) + 1); 112 | memcpy(dum, my item, (my _capacity + 1)*sizeof(SimpleDouble)); 113 | free(my item); 114 | my item = dum; 115 | /* 116 | data lose when _capacity == 40 !!!??? 117 | my item = (SimpleDouble *)realloc(my item, 2 * my _capacity * sizeof(SimpleDouble) + 1); // some problem?? start position */ 118 | 119 | my _capacity *= 2; 120 | } 121 | 122 | my size ++; 123 | for (long i = my size; i > pos; i --) 124 | my item [i] = my item[i - 1]; 125 | my item[pos] = data; 126 | } 127 | 128 | //PitchTier.cpp 129 | void SortedSet_addItem(SortedSetOfDouble me, SimpleDouble data) //Collection.cpp 267 130 | { 131 | if(!data){ 132 | std::cout<<"Error, The data is NULL!"<= 1 ? initialCapacity : 1; 154 | my size = 0; 155 | my item = (SimpleDouble *) malloc (sizeof(structSimpleDouble *) * 2);*/ 156 | SortedSet_init(me, initialCapacity); 157 | } 158 | 159 | void PitchTier_shiftFrequencies (PitchTier me, double tmin, double tmax, double shift, int unit) 160 | { 161 | for(long i = 1; i < my points -> size; ++ i){ 162 | RealPoint point = (RealPoint)my points->item[i]; 163 | double frequency = point -> value; 164 | if(point->number < tmin || point->value > tmax) continue; 165 | switch(unit){ 166 | case kPitch_unit_HERTZ: { 167 | frequency += shift; 168 | if (frequency <= 0.0){ 169 | std::cout<<"The resulting frequency has to be greater than 0 Hz."<value = frequency; 200 | } 201 | } 202 | 203 | void PitchTier_multiplyFrequencies (PitchTier me, double tmin, double tmax, double factor) 204 | { 205 | if(factor <= 0.0){ 206 | std::cout<<"Error, factor < 0.0"<size; ++ i){ 215 | RealPoint point = (RealPoint)(my points->item[i]); 216 | if(point->number < tmin || point->number > tmax) 217 | continue; 218 | point->value *= factor; 219 | } 220 | } 221 | 222 | PitchTier Pitch_to_PitchTier (Pitch me) 223 | { 224 | PitchTier thee = PitchTier_create(my xmin, my xmax); 225 | 226 | for(long i = 1; i <= my nx; ++ i){ 227 | double frequency = my frame[i].candidate[1].frequency; 228 | //Count only voiced frames 229 | if(frequency > 0.0 && frequency < my ceiling){ 230 | double time = my x1 + (i - 1) * my dx; 231 | RealTier_addPoint(thee, time, frequency); 232 | } 233 | } 234 | return thee; 235 | } 236 | 237 | void RealTier_addPoint(RealTier me, double t, double value) 238 | { 239 | RealPoint point = RealPoint_create(t, value); 240 | SortedSet_addItem(my points, point); 241 | ///PraatÔ´ÂëÖÐµÄ Collection_addItem (my points, point.transfer()); Collection.cpp 267 242 | } 243 | 244 | //Pitch_PitchTier.cpp 126 245 | Pitch Pitch_PuitchTier_to_Pitch(Pitch me, PitchTier tier){ 246 | if(tier->points->size == 0){ 247 | std::cout<<"Error, tier size is equals to 0"<candidate[1]; 264 | if(cand->frequency > 0.0 && cand->frequency <= my ceiling) 265 | cand->frequency = RealTier_getValueAtTime(tier,my x1 + (iframe - 1) * my dx);//Sampled_indexToX (me, iframe) 266 | cand -> strength = 0.9; 267 | frame -> nCandidates = 1; 268 | } 269 | 270 | return thee; 271 | } 272 | 273 | //RealTier.cpp 130 274 | double RealTier_getValueAtTime(RealTier me, double t){ 275 | long n = my points->size; 276 | if(n == 0) return NUMundefined; 277 | RealPoint pointRight = (RealPoint)(me->points->item[1]); 278 | if(t <= pointRight->number) 279 | return pointRight->value; /* Constant extrapolation. */ 280 | RealPoint pointLeft = (RealPoint)(me->points->item [n]); 281 | if (t >= pointLeft->number) 282 | return pointLeft->value; /* Constant extrapolation. */ 283 | 284 | if(n < 1){ 285 | std::cout<<"RealTier points's size < 0"< n){ 292 | std::cout<<"Error"<points->item[ileft]); 298 | pointRight = (RealPoint)(me->points->item[iright]); 299 | 300 | double tleft = pointLeft->number, fleft = pointLeft->value; 301 | double tright = pointRight->number, fright = pointRight->value; 302 | return t == tright ? fright /* Be very accurate. */ 303 | : tleft == tright ? 0.5 * (fleft + fright) /*Unusual, but possible; no preference.*/ 304 | : fleft + (t - tleft) * (fright - fleft) / (tright - tleft); /*Linear interpolation.*/ 305 | 306 | } 307 | 308 | //RealTier.cpp 171 309 | double RealTier_getArea (RealTier me, double tmin, double tmax){ 310 | long n = my points->size, imin, imax; //long n = my f_getNumberOfPoints () 311 | RealPoint *points = (RealPoint *) my points->item; 312 | if (n == 0) return NUMundefined; 313 | if (n == 1) return (tmax - tmin) * points[1]->value; 314 | imin = AnyTier_timeToLowIndex (me, tmin); 315 | if (imin == n) return (tmax - tmin) * points[n]->value; 316 | imax = AnyTier_timeToHighIndex (me, tmax); 317 | if (imax == 1) return (tmax - tmin) * points[1]->value; 318 | 319 | if(imin >= n || imax <= 1){ 320 | std::cout<<"Error, imin = "<number, fleft = points[i]->value; 333 | if (i + 1 == imax) tright = tmax, fright = RealTier_getValueAtTime (me, tmax); 334 | else tright = points[i + 1]->number, fright = points[i + 1]->value; 335 | area += 0.5 * (fleft + fright) * (tright - tleft); 336 | } 337 | return area; 338 | } 339 | 340 | //AnyTier.cpp 61 341 | long AnyTier_timeToLowIndex (void * tc, double time){ 342 | RealTier me = (RealTier)tc; 343 | if(my points->size == 0) return 0; // undefined 344 | long ileft = 1, iright = my points->size; 345 | AnyPoint *points = (AnyPoint *)(my points->item); 346 | 347 | double tleft = points[ileft]->number; 348 | if (time < tleft) return 0; // offleft 349 | double tright = points[iright]->number; 350 | if (time >= tright) return iright; 351 | 352 | if(time < tleft || time > tright || tright < tleft){ 353 | std::cout<<"get time Error"< ileft + 1) { 359 | long imid = (ileft + iright) / 2; 360 | double tmid = points[imid]->number; 361 | if (time < tmid) { 362 | iright = imid; 363 | tright = tmid; 364 | } else { 365 | ileft = imid; 366 | tleft = tmid; 367 | } 368 | } 369 | 370 | if(iright != ileft + 1 || ileft < 1 || iright > my points->size || 371 | time < points[ileft]->number || time > points[iright]->number){ 372 | std::cout<<"get time result error!"<size == 0) return 0; // undefined; is this right? 384 | long ileft = 1, iright = my points->size; 385 | AnyPoint *points = (AnyPoint *) my points->item; 386 | 387 | double tleft = points [ileft]->number; 388 | if (time <= tleft) return 1; 389 | double tright = points[iright]->number; 390 | if (time > tright) return iright + 1; // offright 391 | 392 | if(time < tleft || time > tright || tright < tleft){ 393 | std::cout<<"get time Error"< ileft + 1) { 399 | long imid = (ileft + iright) / 2; 400 | double tmid = points [imid] -> number; 401 | if (time <= tmid) { 402 | iright = imid; 403 | tright = tmid; 404 | } else { 405 | ileft = imid; 406 | tleft = tmid; 407 | } 408 | } 409 | 410 | if(iright != ileft + 1 || ileft < 1 || iright > my points->size || 411 | time < points[ileft]->number || time > points[iright]->number){ 412 | std::cout<<"get time result error!"< size; 424 | for (long i = 1; i <= n; i ++) { 425 | RealPoint point = (RealPoint) my points->item [i]; 426 | if (result == NUMundefined || point->value < result) 427 | result = point->value; 428 | } 429 | return result; 430 | } 431 | 432 | //Sound_extension.cpp 1489 433 | void PitchTier_modifyRange_old (PitchTier me, double tmin, double tmax, double factor, double fmid){ 434 | for (long i = 1; i <= my points -> size; i ++) { 435 | RealPoint point = (RealPoint) my points->item [i]; 436 | double f = point->value; 437 | if (point->number < tmin || point->number > tmax) { 438 | continue; 439 | } 440 | f = fmid + (f - fmid) * factor; 441 | point->value = f < 0 ? 0 : f; 442 | } 443 | } 444 | -------------------------------------------------------------------------------- /ReadWavFile.cpp: -------------------------------------------------------------------------------- 1 | /*ReadWavFile.cpp 2 | * Read Sound data from given file end with ".wav" 3 | * Sound should have only one sound strack 4 | */ 5 | 6 | #include 7 | #include "stdio.h" 8 | #include "stdlib.h" 9 | #include "string.h" 10 | #include "SoundCompute.h" 11 | #include "ReadWavFile.h" 12 | 13 | static int ulaw2linear [] = 14 | { -32124, -31100, -30076, -29052, -28028, -27004, -25980, -24956, 15 | -23932, -22908, -21884, -20860, -19836, -18812, -17788, -16764, 16 | -15996, -15484, -14972, -14460, -13948, -13436, -12924, -12412, 17 | -11900, -11388, -10876, -10364, -9852, -9340, -8828, -8316, 18 | -7932, -7676, -7420, -7164, -6908, -6652, -6396, -6140, 19 | -5884, -5628, -5372, -5116, -4860, -4604, -4348, -4092, 20 | -3900, -3772, -3644, -3516, -3388, -3260, -3132, -3004, 21 | -2876, -2748, -2620, -2492, -2364, -2236, -2108, -1980, 22 | -1884, -1820, -1756, -1692, -1628, -1564, -1500, -1436, 23 | -1372, -1308, -1244, -1180, -1116, -1052, -988, -924, 24 | -876, -844, -812, -780, -748, -716, -684, -652, 25 | -620, -588, -556, -524, -492, -460, -428, -396, 26 | -372, -356, -340, -324, -308, -292, -276, -260, 27 | -244, -228, -212, -196, -180, -164, -148, -132, 28 | -120, -112, -104, -96, -88, -80, -72, -64, 29 | -56, -48, -40, -32, -24, -16, -8, 0, 30 | 32124, 31100, 30076, 29052, 28028, 27004, 25980, 24956, 31 | 23932, 22908, 21884, 20860, 19836, 18812, 17788, 16764, 32 | 15996, 15484, 14972, 14460, 13948, 13436, 12924, 12412, 33 | 11900, 11388, 10876, 10364, 9852, 9340, 8828, 8316, 34 | 7932, 7676, 7420, 7164, 6908, 6652, 6396, 6140, 35 | 5884, 5628, 5372, 5116, 4860, 4604, 4348, 4092, 36 | 3900, 3772, 3644, 3516, 3388, 3260, 3132, 3004, 37 | 2876, 2748, 2620, 2492, 2364, 2236, 2108, 1980, 38 | 1884, 1820, 1756, 1692, 1628, 1564, 1500, 1436, 39 | 1372, 1308, 1244, 1180, 1116, 1052, 988, 924, 40 | 876, 844, 812, 780, 748, 716, 684, 652, 41 | 620, 588, 556, 524, 492, 460, 428, 396, 42 | 372, 356, 340, 324, 308, 292, 276, 260, 43 | 244, 228, 212, 196, 180, 164, 148, 132, 44 | 120, 112, 104, 96, 88, 80, 72, 64, 45 | 56, 48, 40, 32, 24, 16, 8, 0 46 | }; 47 | 48 | static short alaw2linear[] = 49 | { 50 | -5504, -5248, -6016, -5760, -4480, -4224, -4992, -4736, 51 | -7552, -7296, -8064, -7808, -6528, -6272, -7040, -6784, 52 | -2752, -2624, -3008, -2880, -2240, -2112, -2496, -2368, 53 | -3776, -3648, -4032, -3904, -3264, -3136, -3520, -3392, 54 | -22016, -20992, -24064, -23040, -17920, -16896, -19968, -18944, 55 | -30208, -29184, -32256, -31232, -26112, -25088, -28160, -27136, 56 | -11008, -10496, -12032, -11520, -8960, -8448, -9984, -9472, 57 | -15104, -14592, -16128, -15616, -13056, -12544, -14080, -13568, 58 | -344, -328, -376, -360, -280, -264, -312, -296, 59 | -472, -456, -504, -488, -408, -392, -440, -424, 60 | -88, -72, -120, -104, -24, -8, -56, -40, 61 | -216, -200, -248, -232, -152, -136, -184, -168, 62 | -1376, -1312, -1504, -1440, -1120, -1056, -1248, -1184, 63 | -1888, -1824, -2016, -1952, -1632, -1568, -1760, -1696, 64 | -688, -656, -752, -720, -560, -528, -624, -592, 65 | -944, -912, -1008, -976, -816, -784, -880, -848, 66 | 5504, 5248, 6016, 5760, 4480, 4224, 4992, 4736, 67 | 7552, 7296, 8064, 7808, 6528, 6272, 7040, 6784, 68 | 2752, 2624, 3008, 2880, 2240, 2112, 2496, 2368, 69 | 3776, 3648, 4032, 3904, 3264, 3136, 3520, 3392, 70 | 22016, 20992, 24064, 23040, 17920, 16896, 19968, 18944, 71 | 30208, 29184, 32256, 31232, 26112, 25088, 28160, 27136, 72 | 11008, 10496, 12032, 11520, 8960, 8448, 9984, 9472, 73 | 15104, 14592, 16128, 15616, 13056, 12544, 14080, 13568, 74 | 344, 328, 376, 360, 280, 264, 312, 296, 75 | 472, 456, 504, 488, 408, 392, 440, 424, 76 | 88, 72, 120, 104, 24, 8, 56, 40, 77 | 216, 200, 248, 232, 152, 136, 184, 168, 78 | 1376, 1312, 1504, 1440, 1120, 1056, 1248, 1184, 79 | 1888, 1824, 2016, 1952, 1632, 1568, 1760, 1696, 80 | 688, 656, 752, 720, 560, 528, 624, 592, 81 | 944, 912, 1008, 976, 816, 784, 880, 848 82 | }; 83 | 84 | unsigned int bingetu1 (FILE *f, bool *TF) { 85 | int externalValue = getc (f); // either -1 (EOF) or in the range 0..255 86 | if (externalValue < 0) { 87 | std::cout<<"A byte."< 32){ 238 | std::cout<<"Too few bits per sample"< 24 ? Melder_LINEAR_32_LITTLE_ENDIAN : 246 | numberOfBitsPerSamplePoint > 16 ? Melder_LINEAR_24_LITTLE_ENDIAN : 247 | numberOfBitsPerSamplePoint > 8 ? Melder_LINEAR_16_LITTLE_ENDIAN : 248 | Melder_LINEAR_8_UNSIGNED; 249 | break; 250 | case WAVE_FORMAT_IEEE_FLOAT : 251 | *encoding = Melder_IEEE_FLOAT_32_LITTLE_ENDIAN; 252 | break; 253 | case WAVE_FORMAT_ALAW : 254 | *encoding = Melder_ALAW; 255 | break; 256 | case WAVE_FORMAT_MULAW : 257 | *encoding = Melder_MULAW ; 258 | break; 259 | case WAVE_FORMAT_DVI_ADPCM : 260 | std::cout<<"Cannot read lossy compressed audio files (this one is DVI ADPCM).\n" 261 | "Please use uncompressed audio files. If you must open this file,\n" 262 | "please use an audio converter program to convert it first to normal (PCM) WAV format\n" 263 | "(Praat may have difficulty analysing the poor recording, though)."< (int) sizeof (double) / numberOfBytesPerSamplePerChannel) { 351 | for (long isamp = 1; isamp <= numberOfSamples; isamp ++) { 352 | for (long ichan = 1; ichan <= numberOfChannels; ichan ++) { 353 | buffer[ichan][isamp] = binget2LE (f, &TF) * (1.0 / 32768); 354 | if(!TF) return -1; 355 | } 356 | } 357 | } else { // optimize 358 | long numberOfBytes = numberOfChannels * numberOfSamples * numberOfBytesPerSamplePerChannel; 359 | unsigned char *bytes = (unsigned char *)&buffer[numberOfChannels][numberOfSamples] + sizeof(double) - numberOfBytes; 360 | if (fread (bytes, 1, numberOfBytes, f) < numberOfBytes) /*** throw MelderError (); ***/ // read 16-bit data into last quarter of buffer 361 | { 362 | std::cout<<"Error, read 16-bit data into last quarter of buffer"< (int) sizeof (double) / numberOfBytesPerSamplePerChannel) { 388 | for (long isamp = 1; isamp <= numberOfSamples; isamp ++) { 389 | for (long ichan = 1; ichan <= numberOfChannels; ichan ++) { 390 | buffer[ichan][isamp] = binget3LE(f, &TF) * (1.0 / 8388608); 391 | if(!TF) return -1; 392 | } 393 | } 394 | } else { // optimize 395 | long numberOfBytes = numberOfChannels * numberOfSamples * numberOfBytesPerSamplePerChannel; 396 | unsigned char *bytes = (unsigned char *) & buffer [numberOfChannels - 1] [numberOfSamples] + sizeof (double) - numberOfBytes; 397 | if (fread (bytes, 1, numberOfBytes, f) < numberOfBytes) /*** throw MelderError (); ***/ // read 24-bit data into last three-eights of buffer 398 | { 399 | std::cout<<"Error, read 24-bit data into last quarter of buffer"<xmin); 495 | fprintf(fp, "xmax = %18.17f\n", sound->xmax); 496 | fprintf(fp, "nx = %d \n", sound->nx); 497 | fprintf(fp, "dx = %17.16f \n", sound->dx); 498 | fprintf(fp, "x1 = %17.16f \n", sound->x1); 499 | fprintf(fp, "ymin = 1 \n"); 500 | fprintf(fp, "ymax = 1 \n"); 501 | fprintf(fp, "ny = 1 \n"); 502 | fprintf(fp, "dx = 1 \n"); 503 | fprintf(fp, "y1 = 1 \n"); 504 | fprintf(fp, "z [] []: \n"); 505 | fprintf(fp, " z [1]:\n"); 506 | 507 | for(long i = 1; i <= sound->nx; ++ i) 508 | fprintf(fp, "%17.16f \n", sound->z[1][i]);// z [1] [%d]: = i, 509 | 510 | fclose(fp); 511 | return 1; 512 | } 513 | 514 | -------------------------------------------------------------------------------- /SystemData.cpp: -------------------------------------------------------------------------------- 1 | #include "SystemData.h" 2 | #include "math.h" 3 | #include 4 | 5 | #define MAX(a,b) ((a) > (b) ? (a) : (b)) 6 | #define MIN(a,b) ((a) > (b) ? (b) : (a)) 7 | 8 | long int lsame_ (const char *ca, const char *cb) { 9 | int a = *(unsigned char *)ca; 10 | int b = *(unsigned char *)cb; 11 | return tolower(a) == tolower(b); 12 | } 13 | 14 | double pow_di (double *ap, long *bp) { 15 | double pow, x; 16 | long n; 17 | unsigned long u; 18 | 19 | pow = 1; 20 | x = *ap; 21 | n = *bp; 22 | 23 | if (n != 0) { 24 | if (n < 0) { 25 | n = -n; 26 | x = 1 / x; 27 | } 28 | for (u = n; ;) { 29 | if (u & 01) { ///(u AND 01) == 1? 30 | pow *= x; 31 | } 32 | if (u >>= 1) { 33 | x *= x; 34 | } else { 35 | break; 36 | } 37 | } 38 | } 39 | return (pow); 40 | } 41 | 42 | 43 | static int dlamc1_(long *beta, long *t, long *rnd, long *ieee1) { 44 | /* -- LAPACK auxiliary routine (version 3.0) -- Univ. of Tennessee, Univ. 45 | of California Berkeley, NAG Ltd., Courant Institute, Argonne National 46 | Lab, and Rice University October 31, 1992 47 | 48 | Purpose ======= 49 | DLAMC1 determines the machine parameters given by BETA, T, RND, and 50 | IEEE1. 51 | 52 | Arguments ========= 53 | 54 | BETA (output) INTEGER The base of the machine. 55 | 56 | T (output) INTEGER The number of ( BETA ) digits in the mantissa. 57 | 58 | RND (output) LOGICAL Specifies whether proper rounding ( RND = .TRUE. 59 | ) or chopping ( RND = .FALSE. ) occurs in addition. This may not 60 | 61 | be a reliable guide to the way in which the machine performs 62 | 63 | its arithmetic. 64 | 65 | IEEE1 (output) LOGICAL Specifies whether rounding appears to be done 66 | in the IEEE 'round to nearest' style. 67 | 68 | Further Details =============== 69 | 70 | The routine is based on the routine ENVRON by Malcolm and incorporates 71 | suggestions by Gentleman and Marovich. See 72 | 73 | Malcolm M. A. (1972) Algorithms to reveal properties of floating-point 74 | arithmetic. Comms. of the ACM, 15, 949-951. 75 | 76 | Gentleman W. M. and Marovich S. B. (1974) More on algorithms that 77 | reveal properties of floating point arithmetic units. Comms. of the 78 | ACM, 17, 276-277. 79 | 80 | ===================================================================== */ 81 | /* Initialized data */ 82 | static long first = TRUE; 83 | 84 | /* System generated locals */ 85 | double d__1, d__2; 86 | 87 | /* Local variables */ 88 | static long lrnd; 89 | static double a, b, c, f; 90 | static long lbeta; 91 | static double savec; 92 | static long lieee1; 93 | static double t1, t2; 94 | static long lt; 95 | static double one, qtr; 96 | 97 | if (first) { 98 | first = FALSE; 99 | one = 1.; 100 | 101 | /* LBETA, LIEEE1, LT and LRND are the local values of BETA, IEEE1, T 102 | and RND. 103 | 104 | Throughout this routine we use the function DLAMC3 to ensure that 105 | relevant values are stored and not held in registers, or are not 106 | affected by optimizers. Compute a = 2.0**m with the smallest 107 | positive integer m such that fl( a + 1.0 ) = a. */ 108 | 109 | a = 1.; 110 | c = 1.; 111 | 112 | /* + WHILE( C.EQ.ONE )LOOP */ 113 | L10: 114 | if (c == one) { 115 | a *= 2; 116 | c = dlamc3_(&a, &one); 117 | d__1 = -a; 118 | c = dlamc3_(&c, &d__1); 119 | goto L10; 120 | } 121 | /* + END WHILE 122 | 123 | Now compute b = 2.0**m with the smallest positive integer m such 124 | that fl( a + b ) .gt. a. */ 125 | 126 | b = 1.; 127 | c = dlamc3_(&a, &b); 128 | 129 | /* + WHILE( C.EQ.A )LOOP */ 130 | L20: 131 | if (c == a) { 132 | b *= 2; 133 | c = dlamc3_(&a, &b); 134 | goto L20; 135 | } 136 | /* + END WHILE 137 | 138 | Now compute the base. a and c are neighbouring floating point 139 | numbers in the interval ( beta**t, beta**( t + 1 ) ) and so their 140 | difference is beta. Adding 0.25 to c is to ensure that it is 141 | truncated to beta and not ( beta - 1 ). */ 142 | 143 | qtr = one / 4; 144 | savec = c; 145 | d__1 = -a; 146 | c = dlamc3_(&c, &d__1); 147 | lbeta = (long)(c + qtr); 148 | 149 | /* Now determine whether rounding or chopping occurs, by adding a bit 150 | less than beta/2 and a bit more than beta/2 to a. */ 151 | 152 | b = (double) lbeta; 153 | d__1 = b / 2; 154 | d__2 = -b / 100; 155 | f = dlamc3_(&d__1, &d__2); 156 | c = dlamc3_(&f, &a); 157 | if (c == a) 158 | lrnd = TRUE; 159 | else 160 | lrnd = FALSE; 161 | 162 | d__1 = b / 2; 163 | d__2 = b / 100; 164 | f = dlamc3_(&d__1, &d__2); 165 | c = dlamc3_(&f, &a); 166 | if (lrnd && c == a) { 167 | lrnd = FALSE; 168 | } 169 | 170 | /* Try and decide whether rounding is done in the IEEE 'round to 171 | nearest' style. B/2 is half a unit in the last place of the two 172 | numbers A and SAVEC. Furthermore, A is even, i.e. has last bit 173 | zero, and SAVEC is odd. Thus adding B/2 to A should not change A, 174 | but adding B/2 to SAVEC should change SAVEC. */ 175 | 176 | d__1 = b / 2; 177 | t1 = dlamc3_(&d__1, &a); 178 | d__1 = b / 2; 179 | t2 = dlamc3_(&d__1, &savec); 180 | lieee1 = t1 == a && t2 > savec && lrnd; 181 | 182 | /* Now find the mantissa, t. It should be the integer part of log to 183 | the base beta of a, however it is safer to determine t by 184 | powering. So we find t as the smallest positive integer for which 185 | fl( beta**t + 1.0 ) = 1.0. */ 186 | 187 | lt = 0; 188 | a = 1.; 189 | c = 1.; 190 | 191 | /* + WHILE( C.EQ.ONE )LOOP */ 192 | L30: 193 | if (c == one) { 194 | ++lt; 195 | a *= lbeta; 196 | c = dlamc3_(&a, &one); 197 | d__1 = -a; 198 | c = dlamc3_(&c, &d__1); 199 | goto L30; 200 | } 201 | /* + END WHILE */ 202 | } 203 | 204 | *beta = lbeta; 205 | *t = lt; 206 | *rnd = lrnd; 207 | *ieee1 = lieee1; 208 | return 0; 209 | } /* dlamc1_ */ 210 | 211 | static int dlamc2_(long *beta, long *t, long *rnd, double *eps, long *emin, double *rmin, long *emax, double *rmax) { 212 | /* -- LAPACK auxiliary routine (version 3.0) -- Univ. of Tennessee, Univ. 213 | of California Berkeley, NAG Ltd., Courant Institute, Argonne National 214 | Lab, and Rice University October 31, 1992 215 | Purpose ======= 216 | DLAMC2 determines the machine parameters specified in its argument 217 | list. 218 | Arguments ========= 219 | 220 | BETA (output) INTEGER The base of the machine. 221 | 222 | T (output) INTEGER The number of ( BETA ) digits in the mantissa. 223 | 224 | RND (output) LOGICAL Specifies whether proper rounding ( RND = .TRUE. 225 | ) or chopping ( RND = .FALSE. ) occurs in addition. This may not 226 | be a reliable guide to the way in which the machine performs 227 | its arithmetic. 228 | 229 | EPS (output) DOUBLE PRECISION The smallest positive number such that 230 | fl( 1.0 - EPS ) .LT. 1.0, where fl denotes the computed value. 231 | 232 | EMIN (output) INTEGER The minimum exponent before (gradual) underflow 233 | occurs. 234 | 235 | RMIN (output) DOUBLE PRECISION The smallest normalized number for the 236 | machine, given by BASE**( EMIN - 1 ), where BASE is the floating point 237 | value of BETA. 238 | 239 | EMAX (output) INTEGER The maximum exponent before overflow occurs. 240 | 241 | RMAX (output) DOUBLE PRECISION The largest positive number for the 242 | machine, given by BASE**EMAX * ( 1 - EPS ), where BASE is the floating 243 | point value of BETA. 244 | 245 | Further Details =============== 246 | 247 | The computation of EPS is based on a routine PARANOIA by W. Kahan of 248 | the University of California at Berkeley. 249 | 250 | ===================================================================== */ 251 | /* Table of constant values */ 252 | /* Initialized data */ 253 | static long first = TRUE; 254 | static long iwarn = FALSE; 255 | 256 | /* System generated locals */ 257 | long i__1; 258 | double d__1, d__2, d__3, d__4, d__5; 259 | 260 | /* Builtin functions */ 261 | /* Local variables */ 262 | static long ieee; 263 | static double half; 264 | static long lrnd; 265 | static double leps, zero, a, b, c; 266 | static long i, lbeta; 267 | static double rbase; 268 | static long lemin, lemax, gnmin; 269 | static double smal; 270 | static long gpmin; 271 | static double third, lrmin, lrmax, sixth; 272 | static long lieee1; 273 | static long lt, ngnmin, ngpmin; 274 | static double one, two; 275 | 276 | if (first) { 277 | first = FALSE; 278 | zero = 0.; 279 | one = 1.; 280 | two = 2.; 281 | 282 | /* LBETA, LT, LRND, LEPS, LEMIN and LRMIN are the local values of 283 | BETA, T, RND, EPS, EMIN and RMIN. Throughout this routine we use 284 | the function DLAMC3 to ensure that relevant values are stored and 285 | not held in registers, or are not affected by optimizers. DLAMC1 286 | returns the parameters LBETA, LT, LRND and LIEEE1. */ 287 | 288 | dlamc1_(&lbeta, <, &lrnd, &lieee1); ///lbeta = -20.0, lt = 1, lrnd = FALSE, lieee1 = 0(FALSE) 289 | 290 | /* Start to find EPS. */ 291 | 292 | b = (double)lbeta; 293 | i__1 = -lt; 294 | a = pow_di(&b, &i__1); 295 | leps = a; 296 | 297 | /* Try some tricks to see whether or not this is the correct EPS. */ 298 | b = two / 3; 299 | half = one / 2; 300 | d__1 = -half; 301 | sixth = dlamc3_(&b, &d__1); 302 | third = dlamc3_(&sixth, &sixth); 303 | d__1 = -half; 304 | b = dlamc3_(&third, &d__1); 305 | b = dlamc3_(&b, &sixth); 306 | b = fabs(b); 307 | if (b < leps) { 308 | b = leps; 309 | } 310 | leps = 1.; 311 | 312 | /* + WHILE( ( LEPS.GT.B ).AND.( B.GT.ZERO ) )LOOP */ 313 | L10: 314 | if (leps > b && b > zero) { 315 | leps = b; 316 | d__1 = half * leps; 317 | /* Computing 5th power */ 318 | d__3 = two, d__4 = d__3, d__3 *= d__3; 319 | /* Computing 2nd power */ 320 | d__5 = leps; 321 | d__2 = d__4 * (d__3 * d__3) * (d__5 * d__5); 322 | c = dlamc3_(&d__1, &d__2); 323 | d__1 = -c; 324 | c = dlamc3_(&half, &d__1); 325 | b = dlamc3_(&half, &c); 326 | d__1 = -b; 327 | c = dlamc3_(&half, &d__1); 328 | b = dlamc3_(&half, &c); 329 | goto L10; 330 | } 331 | /* + END WHILE */ 332 | 333 | if (a < leps) { 334 | leps = a; 335 | } 336 | 337 | /* Computation of EPS complete. Now find EMIN. Let A = + or - 1, and 338 | + or - (1 + BASE**(-3)). Keep dividing A by BETA until (gradual) 339 | underflow occurs. This is detected when we cannot recover the 340 | previous A. */ 341 | 342 | rbase = one / lbeta; 343 | smal = one; 344 | for (i = 1; i <= 3; ++i) { 345 | d__1 = smal * rbase; 346 | smal = dlamc3_(&d__1, &zero); 347 | /* L20: */ 348 | } 349 | a = dlamc3_(&one, &smal); 350 | dlamc4_(&ngpmin, &one, &lbeta); 351 | d__1 = -one; 352 | dlamc4_(&ngnmin, &d__1, &lbeta); 353 | dlamc4_(&gpmin, &a, &lbeta); 354 | d__1 = -a; 355 | dlamc4_(&gnmin, &d__1, &lbeta); 356 | ieee = FALSE; 357 | 358 | if (ngpmin == ngnmin && gpmin == gnmin) { 359 | if (ngpmin == gpmin) { 360 | lemin = ngpmin; 361 | /* ( Non twos-complement machines, no gradual underflow; 362 | e.g., VAX ) */ 363 | } else if (gpmin - ngpmin == 3) { 364 | lemin = ngpmin - 1 + lt; 365 | ieee = TRUE; 366 | /* ( Non twos-complement machines, with gradual underflow; 367 | e.g., IEEE standard followers ) */ 368 | } else { 369 | lemin = MIN (ngpmin, gpmin); 370 | /* ( A guess; no known machine ) */ 371 | iwarn = TRUE; 372 | } 373 | 374 | } else if (ngpmin == gpmin && ngnmin == gnmin) { 375 | if ( (i__1 = ngpmin - ngnmin, abs(i__1)) == 1) { 376 | lemin = MAX (ngpmin, ngnmin); 377 | /* ( Twos-complement machines, no gradual underflow; e.g., 378 | CYBER 205 ) */ 379 | } else { 380 | lemin = MIN (ngpmin, ngnmin); 381 | /* ( A guess; no known machine ) */ 382 | iwarn = TRUE; 383 | } 384 | 385 | } else if ( (i__1 = ngpmin - ngnmin, abs (i__1)) == 1 && gpmin == gnmin) { 386 | if (gpmin - MIN (ngpmin, ngnmin) == 3) { 387 | lemin = MAX (ngpmin, ngnmin) - 1 + lt; 388 | /* ( Twos-complement machines with gradual underflow; no 389 | known machine ) */ 390 | } else { 391 | lemin = MIN (ngpmin, ngnmin); 392 | /* ( A guess; no known machine ) */ 393 | iwarn = TRUE; 394 | } 395 | 396 | } else { 397 | /* Computing MIN */ 398 | i__1 = MIN (ngpmin, ngnmin), i__1 = MIN (i__1, gpmin); 399 | lemin = MIN (i__1, gnmin); 400 | /* ( A guess; no known machine ) */ 401 | iwarn = TRUE; 402 | } 403 | /* Comment out this if block if EMIN is ok */ 404 | if (iwarn) { 405 | first = TRUE; 406 | std::cout<<"\n WARNING. The value EMIN may be incorrect:- EMIN = "< -lexp - *emin) 587 | expsum = lexp << 1; 588 | else 589 | expsum = uexp << 1; 590 | 591 | /* EXPSUM is the exponent range, approximately equal to EMAX - EMIN + 1 . */ 592 | 593 | *emax = expsum + *emin - 1; 594 | nbits = exbits + 1 + *p; 595 | 596 | /* NBITS is the total number of bits needed to store a floating-point number. */ 597 | 598 | if (nbits % 2 == 1 && *beta == 2) { 599 | /* Either there are an odd number of bits used to store a 600 | floating-point number, which is unlikely, or some bits are not 601 | used in the representation of numbers, which is possible, (e.g. 602 | Cray machines) or the mantissa has an implicit bit, (e.g. IEEE 603 | machines, Dec Vax machines), which is perhaps the most likely. We 604 | have to assume the last alternative. If this is true, then we need 605 | to reduce EMAX by one because there must be some way of 606 | representing zero in an implicit-bit system. On machines like 607 | Cray, we are reducing EMAX by one unnecessarily. */ 608 | -- (*emax); 609 | } 610 | 611 | if (*ieee) { 612 | /* Assume we are on an IEEE machine which reserves one exponent for infinity and NaN. */ 613 | -- (*emax); 614 | } 615 | 616 | /* Now create RMAX, the largest machine number, which should be equal to 617 | (1.0 - BETA**(-P)) * BETA**EMAX . First compute 1.0 - BETA**(-P), 618 | being careful that the result is less than 1.0 . */ 619 | 620 | recbas = 1. / *beta; 621 | z = *beta - 1.; 622 | y = 0.; 623 | i__1 = *p; 624 | for (i = 1; i <= *p; ++i) { 625 | z *= recbas; 626 | if (y < 1.) 627 | oldy = y; 628 | y = dlamc3_ (&y, &z); 629 | /* L20: */ 630 | } 631 | if (y >= 1.) { 632 | y = oldy; 633 | } 634 | 635 | /* Now multiply by BETA**EMAX to get RMAX. */ 636 | i__1 = *emax; 637 | for (i = 1; i <= *emax; ++i) { 638 | d__1 = y * (*beta); 639 | y = dlamc3_ (&d__1, &c_b5); 640 | /* L30: */ 641 | } 642 | 643 | *rmax = y; 644 | return 0; 645 | } /* dlamc5_ */ 646 | 647 | double getSystemData(const char *cmach){ 648 | /* Initialized data */ 649 | static long first = TRUE; 650 | 651 | /* System generated locals */ 652 | long i__1; 653 | double ret_val; 654 | 655 | /* Builtin functions */ 656 | /* Local variables */ 657 | static double base; 658 | static long beta; 659 | static double emin, prec, emax; 660 | static long imin, imax; 661 | static long lrnd; 662 | static double rmin, rmax, t, rmach; 663 | static double smal, sfmin; 664 | static long it; 665 | static double rnd, eps; 666 | 667 | if (first) { 668 | first = FALSE; 669 | dlamc2_ (&beta, &it, &lrnd, &eps, &imin, &rmin, &imax, &rmax); 670 | base = (double) beta; 671 | t = (double) it; 672 | if (lrnd) { 673 | rnd = 1.; 674 | i__1 = 1 - it; 675 | eps = pow_di (&base, &i__1) / 2; 676 | } else { 677 | rnd = 0.; 678 | i__1 = 1 - it; 679 | eps = pow_di (&base, &i__1); 680 | } 681 | prec = eps * base; 682 | emin = (double) imin; 683 | emax = (double) imax; 684 | sfmin = rmin; 685 | smal = 1. / rmax; 686 | if (smal >= sfmin) { 687 | /* Use smal plus a bit, to avoid the possibility of rounding 688 | causing overflow when computing 1/sfmin. */ 689 | sfmin = smal * (eps + 1.); 690 | } 691 | } 692 | 693 | if (lsame_ (cmach, "E")) { 694 | rmach = eps; 695 | } else if (lsame_ (cmach, "S")) { 696 | rmach = sfmin; 697 | } else if (lsame_ (cmach, "B")) { 698 | rmach = base; 699 | } else if (lsame_ (cmach, "P")) { 700 | rmach = prec; 701 | } else if (lsame_ (cmach, "N")) { 702 | rmach = t; 703 | } else if (lsame_ (cmach, "R")) { 704 | rmach = rnd; 705 | } else if (lsame_ (cmach, "M")) { 706 | rmach = emin; 707 | } else if (lsame_ (cmach, "U")) { 708 | rmach = rmin; 709 | } else if (lsame_ (cmach, "L")) { 710 | rmach = emax; 711 | } else if (lsame_ (cmach, "O")) { 712 | rmach = rmax; 713 | } 714 | 715 | ret_val = rmach; 716 | return ret_val; 717 | } 718 | 719 | #undef MAX 720 | #undef MIN 721 | -------------------------------------------------------------------------------- /Sound_to_Pitch.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include 3 | #include "Sound_to_Pitch.h" 4 | #include "Structure.h" 5 | #include "SoundCompute.h" 6 | #include "Pitch.h" 7 | #include "NUM.h" 8 | #include "NUM2.h" 9 | 10 | //timeStepStrategy value 11 | #define kTimeSoundAnalysisEditor_timeStepStrategy_AUTOMATIC 1 12 | #define kTimeSoundAnalysisEditor_timeStepStrategy_FIXED 2 13 | #define kTimeSoundAnalysisEditor_timeStepStrategy_VIEW_DEPENDENT 3 14 | 15 | //method value 16 | #define kTimeSoundAnalysisEditor_pitch_analysisMethod_AUTOCORRELATION 1 17 | #define kTimeSoundAnalysisEditor_pitch_analysisMethod_CROSS_CORRELATION 2 18 | 19 | //windows kinds 20 | #define AC_HANNING 0 21 | #define AC_GAUSS 1 22 | #define FCC_NORMAL 2 23 | #define FCC_ACCURATE 3 24 | 25 | #define NUM_PEAK_INTERPOLATE_SINC70 3 26 | #define NUM_PEAK_INTERPOLATE_SINC700 4 27 | 28 | 29 | int Sampled_shortTermAnalysis (Sound me, double windowDuration, double timeStep, long *numberOfFrames, double *firstTime) { 30 | if (windowDuration <= 0.0) return 0; 31 | if (timeStep <= 0.0) return 0; 32 | 33 | double myDuration = my dx * my nx; 34 | if (windowDuration > myDuration){ 35 | std::cout<<"Sound shorter than window length."< FCC_ACCURATE) 69 | { 70 | std::cout<<"Error: maxnCandidates: "< 0.5 / my dx) ceiling = 0.5 / my dx; 118 | 119 | // Determine window length in seconds and in samples. 120 | dt_window = periodsPerWindow / minimumPitch; 121 | nsamp_window = floor (dt_window / my dx); 122 | halfnsamp_window = nsamp_window / 2 - 1; 123 | if (halfnsamp_window < 2){ 124 | std::cout<<"Analysis window too short."< nsamp_window) maximumLag = nsamp_window; 135 | 136 | /* 137 | * Determine the number of frames. 138 | * Fit as many frames as possible symmetrically in the total duration. 139 | * We do this even for the forward cross-correlation method, 140 | * because that allows us to compare the two methods. 141 | */ 142 | if(!Sampled_shortTermAnalysis (me, method >= FCC_NORMAL ? 1 / minimumPitch + dt_window : dt_window, dt, & nFrames, & t1)){ 143 | std::cout<<"The pitch analysis would give zero pitch frames."< globalPeak) globalPeak = value; 162 | } 163 | } 164 | if (globalPeak == 0.0) return thee; 165 | 166 | double **frame, *ac, *window, *windowR; 167 | 168 | if (method >= FCC_NORMAL) { /* For cross-correlation analysis. */ 169 | // Create buffer for cross-correlation analysis. 170 | frame = (double **)malloc(sizeof(double *) * (my ny + 1)); 171 | for(long i = 1; i <= my ny; ++ i){ 172 | frame[i] = (double *)malloc(sizeof(double) * (nsamp_window + 1)); 173 | for(long j = 1; j <= nsamp_window; ++ j) 174 | frame[i][j] = 0.0; 175 | } /****frame.reset (1, my ny, 1, nsamp_window);****/ 176 | 177 | brent_ixmax = nsamp_window * interpolation_depth; 178 | } else { /* For autocorrelation analysis. */ 179 | /* 180 | * Compute the number of samples needed for doing FFT. 181 | * To avoid edge effects, we have to append zeroes to the window. 182 | * The maximum lag considered for maxima is maximumLag. 183 | * The maximum lag used in interpolation is nsamp_window * interpolation_depth. 184 | */ 185 | nsampFFT = 1; 186 | while (nsampFFT < nsamp_window * (1 + interpolation_depth)) nsampFFT *= 2; 187 | 188 | // Create buffers for autocorrelation analysis. 189 | frame = (double **)malloc(sizeof(double *) * (my ny + 1)); 190 | for(long i = 1; i <= my ny; ++ i){ 191 | frame [i] = (double *)malloc(sizeof(double) * (nsampFFT + 1)); 192 | for(long j = 0; j <= nsampFFT; ++ j) 193 | frame[i][j] = 0.0; 194 | } /****frame.reset (1, my ny, 1, nsampFFT);****/ 195 | 196 | window = (double *)malloc(sizeof(double) * (nsamp_window + 1)); 197 | for(long i = 0; i <= nsamp_window; ++ i) 198 | window[i] = 0.0; 199 | /****window.reset (1, nsamp_window);****/ 200 | 201 | windowR = (double *)malloc(sizeof(double) * (nsampFFT + 1)); 202 | ac = (double *)malloc(sizeof(double) * (nsampFFT + 1)); 203 | for(long i = 0; i <= nsampFFT; ++ i) 204 | windowR[i] = ac[i] = 0.0; 205 | /****windowR.reset (1, nsampFFT); ac.reset (1, nsampFFT); ****/ 206 | 207 | NUMfft_Table_init (fftTable, nsampFFT); 208 | 209 | /* 210 | * A Gaussian or Hanning window is applied against phase effects. 211 | * The Hanning window is 2 to 5 dB better for 3 periods/window. 212 | * The Gaussian window is 25 to 29 dB better for 6 periods/window. 213 | */ 214 | if (method == AC_GAUSS) { /* Gaussian window. */ 215 | double imid = 0.5 * (nsamp_window + 1), edge = exp (-12.0); 216 | for (long i = 1; i <= nsamp_window; i ++) 217 | window[i] = (exp(-48.0*(i-imid)*(i-imid) / 218 | (nsamp_window + 1) / (nsamp_window + 1)) - edge) / (1 - edge); 219 | } else { /* Hanning window*/ 220 | for (long i = 1; i <= nsamp_window; i ++) 221 | window [i] = 0.5 - 0.5 * cos (i * 2 * NUMpi / (nsamp_window + 1)); 222 | } 223 | 224 | // Compute the normalized autocorrelation of the window. 225 | for (long i = 1; i <= nsamp_window; i ++) windowR [i] = window [i]; 226 | NUMfft_forward (fftTable, windowR); 227 | windowR [1] *= windowR [1]; // DC component 228 | for (long i = 2; i < nsampFFT; i += 2) { 229 | windowR [i] = windowR [i] * windowR [i] + windowR [i+1] * windowR [i+1]; 230 | windowR [i + 1] = 0.0; // power spectrum: square and zero 231 | } 232 | windowR [nsampFFT] *= windowR [nsampFFT]; // Nyquist frequency 233 | NUMfft_backward (fftTable, windowR); // autocorrelation 234 | for (long i = 2; i <= nsamp_window; i ++) windowR [i] /= windowR [1]; // normalize 235 | windowR [1] = 1.0; // normalize 236 | 237 | brent_ixmax = nsamp_window * interpolation_depth; 238 | } 239 | 240 | double *r = (double *) malloc( sizeof(double) * (2 * (nsamp_window + 1) + 1) ); 241 | r += nsamp_window + 1; //make "r" become a symetrical vectr 242 | long *imax = (long *) malloc( sizeof(long) * (maxnCandidates + 1)); 243 | double *localMean = (double *) malloc( sizeof(double) * (my ny + 1)); 244 | 245 | for(iframe = 1; iframe <= nFrames; iframe ++){ 246 | Pitch_Frame pitchFrame = & thy frame[iframe]; 247 | double t = thy x1 + (iframe - 1) *(thy dx), localPeak; 248 | long leftSample = (long) floor((t - my x1) / my dx) + 1; 249 | long rightSample = leftSample + 1; 250 | long startSample, endSample; 251 | 252 | for(long channel = 1; channel <= my ny; ++ channel){ //Compute the local mean; look one longest period to both sides. 253 | startSample = rightSample - nsamp_period; 254 | endSample = leftSample + nsamp_period; 255 | if ( startSample < 0 ) { 256 | std::cout<<"StartSample < 1"< my nx){ 262 | std::cout<<"EndSample > my nx"< my nx){ 284 | std::cout<<"EndSample > my nx"< nsamp_window) endSample = nsamp_window; 304 | for (long channel = 1; channel <= my ny; channel ++) { 305 | for (long j = startSample; j <= endSample; j ++) { 306 | double value = fabs (frame [channel] [j]); 307 | if (value > localPeak) localPeak = value; 308 | } 309 | } 310 | pitchFrame->intensity = localPeak > globalPeak ? 1.0 : localPeak / globalPeak; 311 | 312 | // Compute the correlation into the array 'r'. 313 | if (method >= FCC_NORMAL) { 314 | double startTime = t - 0.5 * (1.0 / minimumPitch + dt_window); 315 | long localSpan = maximumLag + nsamp_window, localMaximumLag, offset; 316 | if ((startSample = (long) floor ((startTime - my x1) / my dx)) + 1 < 1) 317 | startSample = 1; 318 | if (localSpan > my nx + 1 - startSample) localSpan = my nx + 1 - startSample; 319 | localMaximumLag = localSpan - nsamp_window; 320 | offset = startSample - 1; 321 | double sumx2 = 0; /* Sum of squares. */ 322 | for (long channel = 1; channel <= my ny; channel ++) { ///channel = 1; channel <= my ny 323 | double *amp = my z[channel] + offset; 324 | for (long i = 1; i <= nsamp_window; i ++) { ///i = 1; i <= nsamp_window 325 | double x = amp[i] - localMean[channel]; 326 | sumx2 += x * x; 327 | } 328 | } 329 | double sumy2 = sumx2; /* At zero lag, these are still equal. */ 330 | r[0] = 1.0; 331 | for (long i = 1; i <= localMaximumLag; i ++) { 332 | double product = 0.0; 333 | for (long channel = 1; channel <= my ny; channel ++) { ///channel = 1; channel <= my ny 334 | double *amp = my z[channel] + offset; 335 | double y0 = amp[i] - localMean[channel]; 336 | double yZ = amp[i + nsamp_window] - localMean[channel]; 337 | sumy2 += yZ * yZ - y0 * y0; 338 | for (long j = 1; j <= nsamp_window; j ++) { ///j = 1; j <= nsamp_window 339 | double x = amp[j] - localMean[channel]; 340 | double y = amp[i + j] - localMean[channel]; 341 | product += x * y; 342 | } 343 | } 344 | r[- i] = r[i] = product / sqrt (sumx2 * sumy2); 345 | } 346 | } else { 347 | // The FFT of the autocorrelation is the power spectrum. 348 | for (long i = 1; i <= nsampFFT; i ++) 349 | ac [i] = 0.0; 350 | for (long channel = 1; channel <= my ny; channel ++) { 351 | NUMfft_forward (fftTable, frame [channel]); /* Complex spectrum. */ 352 | ac [1] += frame [channel] [1] * frame [channel] [1]; /* DC component. */ 353 | for (long i = 2; i < nsampFFT; i += 2) { 354 | ac [i] += frame [channel] [i] * frame [channel] [i] + frame [channel] [i+1] * frame [channel] [i+1]; /* Power spectrum. */ 355 | } 356 | ac [nsampFFT] += frame [channel] [nsampFFT] * frame [channel] [nsampFFT]; /* Nyquist frequency. */ 357 | } 358 | NUMfft_backward (fftTable, ac); /* Autocorrelation. */ 359 | 360 | /* 361 | * Normalize the autocorrelation to the value with zero lag, 362 | * and divide it by the normalized autocorrelation of the window. 363 | */ 364 | r [0] = 1.0; 365 | for (long i = 1; i <= brent_ixmax; i ++) 366 | r [- i] = r [i] = ac [i + 1] / (ac [1] * windowR [i + 1]); 367 | } 368 | 369 | // Create (too much) space for candidates 370 | Pitch_Frame_init (pitchFrame, maxnCandidates); 371 | 372 | // Register the first candidate, which is always present: voicelessness. 373 | pitchFrame->nCandidates = 1; 374 | pitchFrame->candidate[1].frequency = 0.0; /* Voiceless: always present. */ 375 | pitchFrame->candidate[1].strength = 0.0; 376 | 377 | /* 378 | * Shortcut: absolute silence is always voiceless. 379 | * Go to next frame. 380 | */ 381 | if (localPeak == 0) continue; 382 | 383 | /* 384 | * Find the strongest maxima of the correlation of this frame, 385 | * and register them as candidates. 386 | */ 387 | imax[1] = 0; 388 | for (long i = 2; i < maximumLag && i < brent_ixmax; i ++) 389 | if (r[i] > 0.5 * voicingThreshold && /* Not too unvoiced? */ 390 | r[i] > r[i-1] && r[i] >= r[i+1]) /* Maximum ? */ 391 | { 392 | int place = 0; 393 | // Use parabolic interpolation for first estimate of frequency,and sin(x)/x interpolation to compute the strength of this frequency. 394 | double dr = 0.5 * (r[i+1] - r[i-1]); 395 | double d2r = 2 * r[i] - r[i-1] - r[i+1]; 396 | double frequencyOfMaximum = 1 / my dx / (i + dr / d2r); 397 | long offset = - brent_ixmax - 1; 398 | double strengthOfMaximum = /* method & 1 ? */ 399 | NUM_interpolate_sinc (& r[offset], brent_ixmax - offset, 1 / my dx / frequencyOfMaximum - offset, 30) 400 | /* : r [i] + 0.5 * dr * dr / d2r */; 401 | /* High values due to short windows are to be reflected around 1. */ 402 | if (strengthOfMaximum > 1.0) strengthOfMaximum = 1.0 / strengthOfMaximum; 403 | 404 | // Find a place for this maximum. 405 | if (pitchFrame->nCandidates < thy maxnCandidates) { /* Is there still a free place? */ 406 | place = ++ pitchFrame->nCandidates; 407 | } else { 408 | /* Try the place of the weakest candidate so far. */ 409 | double weakest = 2; 410 | for (int iweak = 2; iweak <= thy maxnCandidates; iweak ++) { //iweak = 2; iweak <= thy maxnCandidates; 411 | /* High frequencies are to be favoured */ 412 | /* if we want to analyze a perfectly periodic signal correctly. */ 413 | double localStrength = pitchFrame->candidate[iweak].strength - octaveCost * 414 | NUMlog2 (minimumPitch / pitchFrame->candidate[iweak].frequency); 415 | if (localStrength < weakest) { 416 | weakest = localStrength; 417 | place = iweak; 418 | } 419 | } 420 | /* If this maximum is weaker than the weakest candidate so far, give it no place. */ 421 | if (strengthOfMaximum - octaveCost * NUMlog2 (minimumPitch / frequencyOfMaximum) <= weakest) 422 | place = 0; 423 | } 424 | if (place) { /* Have we found a place for this candidate? */ 425 | pitchFrame->candidate[place].frequency = frequencyOfMaximum; 426 | pitchFrame->candidate[place].strength = strengthOfMaximum; 427 | imax [place] = i; 428 | } 429 | } 430 | 431 | // Second pass: for extra precision, maximize sin(x)/x interpolation ('sinc'). 432 | for (long i = 2; i <= pitchFrame->nCandidates; i ++) { 433 | if (method != AC_HANNING || pitchFrame->candidate[i].frequency > 0.0 / my dx) { 434 | double xmid, ymid; 435 | long offset = - brent_ixmax - 1; 436 | ymid = NUMimproveMaximum (& r[offset], brent_ixmax - offset, imax[i] - offset, 437 | pitchFrame->candidate[i].frequency > 0.3 / my dx ? NUM_PEAK_INTERPOLATE_SINC700 : brent_depth, & xmid); 438 | xmid += offset; 439 | pitchFrame->candidate[i].frequency = 1.0 / my dx / xmid; 440 | if (ymid > 1.0) ymid = 1.0 / ymid; 441 | pitchFrame->candidate[i].strength = ymid; 442 | } 443 | } 444 | } /* Next frame. */ 445 | 446 | Pitch_pathFinder (thee, silenceThreshold, voicingThreshold,octaveCost, octaveJumpCost, 447 | voicedUnvoicedCost, ceiling, false); 448 | //false: Melder_debug == 31 ? true : false Melder_debug 31: Pitch analysis: formant pulling on 449 | return thee; 450 | } 451 | 452 | Pitch Sound_to_Pitch_cc (Sound me, 453 | double dt, double minimumPitch, double periodsPerWindow, int maxnCandidates, int accurate, 454 | double silenceThreshold, double voicingThreshold, 455 | double octaveCost, double octaveJumpCost, double voicedUnvoicedCost, double ceiling) 456 | { 457 | return Sound_to_Pitch_any (me, dt, minimumPitch, periodsPerWindow, maxnCandidates, 2 + accurate, 458 | silenceThreshold, voicingThreshold, octaveCost, octaveJumpCost, voicedUnvoicedCost, ceiling); 459 | } 460 | 461 | Pitch Sound_to_Pitch(Sound me, double timestep, double minimumPitch, double maximumPitch) 462 | { 463 | return Sound_to_Pitch_any(me, timestep, minimumPitch, 3.0, 15, FALSE, 0.03, 0.45, 0.01, 0.35, 0.14, maximumPitch); 464 | } 465 | 466 | Pitch computePitch(Sound me, double fixedTimeStepStrategy, int method, bool veryAccurate, double floor, double ceiling, 467 | long maximumNumberOfCandidates,double silenceThreshold, double voicingThreshold, double octaveCost, 468 | double octaveJumpCost, double voicedUnvoicedCost) 469 | { 470 | return Sound_to_Pitch_any(me, fixedTimeStepStrategy, 471 | floor, 472 | method == kTimeSoundAnalysisEditor_pitch_analysisMethod_AUTOCORRELATION ? 3.0 : 1.0, 473 | maximumNumberOfCandidates, 474 | (method - 1) *2 + veryAccurate, ///veryAccurate + 2, 475 | silenceThreshold, voicingThreshold, octaveCost, octaveJumpCost, 476 | voicedUnvoicedCost, ceiling); 477 | } 478 | 479 | /* Reference 480 | static void computePitch_inside (TimeSoundAnalysisEditor me) { 481 | double margin = my pitch.veryAccurate ? 3.0 / my pitch.floor : 1.5 / my pitch.floor; 482 | forget (my pitch.data); 483 | try { 484 | autoSound sound = extractSound (me, my startWindow - margin, my endWindow + margin); 485 | double pitchTimeStep = 486 | my timeStepStrategy == kTimeSoundAnalysisEditor_timeStepStrategy_FIXED ? my fixedTimeStep : 487 | my timeStepStrategy == kTimeSoundAnalysisEditor_timeStepStrategy_VIEW_DEPENDENT ? (my endWindow - my startWindow) / my numberOfTimeStepsPerView : 488 | 0.0; // the default: determined by pitch floor 489 | 490 | my pitch.data = Sound_to_Pitch_any (sound.peek(), pitchTimeStep, 491 | my pitch.floor, 492 | my pitch.method == kTimeSoundAnalysisEditor_pitch_analysisMethod_AUTOCORRELATION ? 3.0 : 1.0, 493 | my pitch.maximumNumberOfCandidates, 494 | (my pitch.method - 1) * 2 + my pitch.veryAccurate, 495 | my pitch.silenceThreshold, my pitch.voicingThreshold, 496 | my pitch.octaveCost, my pitch.octaveJumpCost, my pitch.voicedUnvoicedCost, my pitch.ceiling); 497 | my pitch.data -> xmin = my startWindow; 498 | my pitch.data -> xmax = my endWindow; 499 | } catch (MelderError) { 500 | Melder_clearError (); 501 | } 502 | }*/ 503 | -------------------------------------------------------------------------------- /Pitch.cpp: -------------------------------------------------------------------------------- 1 | /*Pitch.cpp 2 | *implementation for function of computing pitch 3 | */ 4 | 5 | #include 6 | #include "Pitch.h" 7 | #include "SoundCompute.h" 8 | #include "NUM.h" 9 | 10 | 11 | #define doesUnitAllowNegativeValues(unit) \ 12 | ( (unit) == kPitch_unit_HERTZ_LOGARITHMIC || (unit) == kPitch_unit_LOG_HERTZ || \ 13 | (unit) == kPitch_unit_SEMITONES_1 || (unit) == kPitch_unit_SEMITONES_100 || \ 14 | (unit) == kPitch_unit_SEMITONES_200 || (unit) == kPitch_unit_SEMITONES_440 ) 15 | 16 | void Pitch_Frame_init (Pitch_Frame me, int nCandidate) 17 | { 18 | my nCandidates = nCandidate; 19 | my candidate = (Pitch_Candidate)malloc((nCandidate + 1) * sizeof(structPitch_Candidate)); 20 | 21 | for(int i = 1; i <= nCandidate; ++ i){ 22 | my candidate[i].frequency = 0.0; 23 | my candidate[i].strength = 0.0; 24 | } 25 | } 26 | 27 | Pitch Pitch_create(double tmin, double tmax, long nt, double dt, double t1, double ceiling, int maxCandidates){ 28 | Pitch me = (Pitch)malloc(sizeof(structPitch)); 29 | if(!me) return NULL; 30 | 31 | my xmin = tmin; 32 | my xmax = tmax; 33 | my nx = nt; 34 | my dx = dt; 35 | my x1 = t1; 36 | my ceiling = ceiling; 37 | my maxnCandidates = maxCandidates; 38 | my frame = (Pitch_Frame)malloc(sizeof(structPitch_Frame) * (nt + 1)); 39 | 40 | /* Put one candidate in every frame (unvoiced, silent). */ 41 | for(long i = 0; i <= nt; ++ i) 42 | Pitch_Frame_init(& my frame[i], 1); 43 | 44 | return me; 45 | } 46 | 47 | void Pitch_setCeiling (Pitch me, double ceiling) { 48 | my ceiling = ceiling; 49 | } 50 | 51 | int Pitch_getMaxnCandidates (Pitch me) { 52 | int result = 0; 53 | for (long i = 1; i <= my nx; i ++) { 54 | int nCandidates = my frame[i].nCandidates; 55 | if (nCandidates > result) result = nCandidates; 56 | } 57 | return result; 58 | } 59 | 60 | void Pitch_pathFinder (Pitch me, double silenceThreshold, double voicingThreshold, double octaveCost, 61 | double octaveJumpCost, double voicedUnvoicedCost, double ceiling, int pullFormants) 62 | { 63 | long maxnCandidates = Pitch_getMaxnCandidates (me); 64 | long place; 65 | double maximum, value; //volatile 66 | double ceiling2 = pullFormants ? 2 * ceiling : ceiling; 67 | double timeStepCorrection = 0.01 / my dx; 68 | octaveJumpCost *= timeStepCorrection; 69 | voicedUnvoicedCost *= timeStepCorrection; 70 | 71 | my ceiling = ceiling; 72 | 73 | double **delta = (double **) malloc ( sizeof(double *) * (my nx + 1)); 74 | for(long i = 1; i <= my nx; ++ i) 75 | delta[i] = (double *) malloc (sizeof(double) * maxnCandidates); 76 | long **psi = (long **) malloc ( sizeof(long *) * (my nx + 1)); 77 | for(long i = 1; i <= my nx; ++ i) 78 | psi[i] = (long *) malloc(sizeof(long) * (maxnCandidates + 1)); 79 | /// autoNUMmatrix delta (1, my nx, 1, maxnCandidates); 80 | /// autoNUMmatrix psi (1, my nx, 1, maxnCandidates); 81 | 82 | for (long iframe = 1; iframe <= my nx; iframe ++) { 83 | Pitch_Frame frame = & my frame [iframe]; 84 | double unvoicedStrength = silenceThreshold <= 0 ? 0 : 85 | 2 - frame->intensity / (silenceThreshold / (1 + voicingThreshold)); 86 | unvoicedStrength = voicingThreshold + (unvoicedStrength > 0 ? unvoicedStrength : 0); 87 | for (long icand = 1; icand <= frame->nCandidates; icand ++) { 88 | Pitch_Candidate candidate = & frame->candidate [icand]; 89 | int voiceless = candidate->frequency == 0 || candidate->frequency > ceiling2; 90 | delta [iframe] [icand] = voiceless ? unvoicedStrength : 91 | candidate->strength - octaveCost * NUMlog2 (ceiling / candidate->frequency); 92 | } 93 | } 94 | 95 | /* Look for the most probable path through the maxima. 96 | There is a cost for the voiced/unvoiced transition, 97 | and a cost for a frequency jump. */ 98 | for (long iframe = 2; iframe <= my nx; iframe ++) { 99 | Pitch_Frame prevFrame = & my frame[iframe - 1], curFrame = & my frame[iframe]; 100 | double *prevDelta = delta [iframe - 1], *curDelta = delta [iframe]; 101 | long *curPsi = psi[iframe]; 102 | for (long icand2 = 1; icand2 <= curFrame -> nCandidates; icand2 ++) { /// icand2 = 1; icand2 <= curFrame -> nCandidates 103 | double f2 = curFrame -> candidate [icand2]. frequency; 104 | maximum = -1e30; 105 | place = 0; 106 | for (long icand1 = 1; icand1 <= prevFrame->nCandidates; icand1 ++) { // icand1 = 1; icand1 <= prevFrame -> nCandidates 107 | double f1 = prevFrame -> candidate [icand1]. frequency; 108 | double transitionCost; 109 | bool previousVoiceless = f1 <= 0 || f1 >= ceiling2; 110 | bool currentVoiceless = f2 <= 0 || f2 >= ceiling2; 111 | if (currentVoiceless) { 112 | if (previousVoiceless) 113 | transitionCost = 0; // both voiceless 114 | else 115 | transitionCost = voicedUnvoicedCost; // voiced-to-unvoiced transition 116 | } else { 117 | if (previousVoiceless) { 118 | transitionCost = voicedUnvoicedCost; // unvoiced-to-voiced transition 119 | /******** Melder_debug 30: pitch path finder: use octave jump cost across voiceless parts 120 | /// if (Melder_debug == 30) { 121 | // Try to take into account a frequency jump across a voiceless stretch. 122 | long place1 = icand1; 123 | for (long jframe = iframe - 2; jframe >= 1; jframe --) { 124 | place1 = psi [jframe + 1] [place1]; 125 | f1 = my frame [jframe]. candidate [place1]. frequency; 126 | if (f1 > 0 && f1 < ceiling) { 127 | transitionCost += octaveJumpCost * fabs (NUMlog2 (f1 / f2)) / (iframe - jframe); 128 | break; 129 | } 130 | } 131 | } ***********/ 132 | } else { 133 | transitionCost = octaveJumpCost * fabs (NUMlog2 (f1 / f2)); // both voiced 134 | } 135 | } 136 | value = prevDelta [icand1] - transitionCost + curDelta [icand2]; 137 | //if (Melder_debug == 33) Melder_casual ("Frame %ld, current candidate %ld (delta %g), previous candidate %ld (delta %g), " 138 | // "transition cost %g, value %g, maximum %g", iframe, icand2, curDelta [icand2], icand1, prevDelta [icand1], transitionCost, value, maximum); 139 | if (value > maximum) { 140 | maximum = value; 141 | place = icand1; 142 | } else if (value == maximum) { 143 | /*** if (Melder_debug == 33) Melder_casual ("A tie in frame %ld, current candidate %ld, previous candidate %ld", iframe, icand2, icand1); ***/ 144 | // std::cout<<"A tie in frame "< maximum) { 158 | place = icand; 159 | maximum = delta [my nx] [place]; 160 | } 161 | } 162 | 163 | /* Backtracking: follow the path backwards. */ 164 | for (long iframe = my nx; iframe >= 1; iframe --) { 165 | /****** if (Melder_debug == 33) Melder_casual ("Frame %ld: swapping candidates 1 and %ld", iframe, place); ******/ 166 | Pitch_Frame frame = & my frame[iframe]; 167 | structPitch_Candidate help = frame->candidate[1]; 168 | frame->candidate[1] = frame->candidate [place]; 169 | frame->candidate[place] = help; 170 | place = psi[iframe][place]; 171 | } 172 | 173 | /* Pull formants: devoice frames with frequencies between ceiling and ceiling2. */ 174 | if (ceiling2 > ceiling) { 175 | /****** if (Melder_debug == 33) Melder_casual ("Pulling formants..."); *******/ 176 | for (long iframe = my nx; iframe >= 1; iframe --) { 177 | Pitch_Frame frame = & my frame[iframe]; 178 | Pitch_Candidate winner = & frame->candidate[1]; 179 | double f = winner->frequency; 180 | if (f > ceiling && f <= ceiling2) { 181 | for (long icand = 2; icand <= frame->nCandidates; icand ++) { 182 | Pitch_Candidate loser = & frame->candidate[icand]; 183 | if (loser->frequency == 0.0) { 184 | structPitch_Candidate help = *winner; 185 | *winner = *loser; 186 | *loser = help; 187 | break; 188 | } 189 | } 190 | } 191 | } 192 | } 193 | } 194 | 195 | double Pitch_getValueAtTime (Pitch me, double x, int unit, int interpolate) { 196 | /// return Sampled_getValueAtX (me, time, Pitch_LEVEL_FREQUENCY, unit, interpolate); 197 | long ilevel = Pitch_LEVEL_FREQUENCY; 198 | if (x < my xmin || x > my xmax) return NUMundefined; 199 | if (interpolate) { 200 | double ireal = (x - my x1)/my dx + 1; 201 | long ileft = floor(ireal), inear, ifar; 202 | double phase = ireal - ileft; 203 | if (phase < 0.5) { 204 | inear = ileft, ifar = ileft + 1; 205 | } else { 206 | ifar = ileft, inear = ileft + 1; 207 | phase = 1.0 - phase; 208 | } 209 | if (inear < 1 || inear > my nx) return NUMundefined; // x out of range? 210 | double fnear = v_getValueAtSample (me, inear, ilevel, unit); 211 | if (fnear == NUMundefined) return NUMundefined; // function value not defined? 212 | if (ifar < 1 || ifar > my nx) return fnear; // at edge? Extrapolate 213 | double ffar = v_getValueAtSample (me, ifar, ilevel, unit); 214 | if (ffar == NUMundefined) return fnear; // neighbour undefined? Extrapolate 215 | return fnear + phase * (ffar - fnear); // interpolate 216 | } 217 | 218 | long isample = (long)((x - my x1) / my dx + 1.5); 219 | return Sampled_getValueAtSample (me, isample, ilevel, unit); 220 | } 221 | 222 | /* Reference: 223 | double Sampled_getValueAtX (Sampled me, double x, long ilevel, int unit, int interpolate) { 224 | if (x < my xmin || x > my xmax) return NUMundefined; 225 | if (interpolate) { 226 | double ireal = Sampled_xToIndex (me, x); 227 | long ileft = floor (ireal), inear, ifar; 228 | double phase = ireal - ileft; 229 | if (phase < 0.5) { 230 | inear = ileft, ifar = ileft + 1; 231 | } else { 232 | ifar = ileft, inear = ileft + 1; 233 | phase = 1.0 - phase; 234 | } //±£Ö¤phase´óСÔÚ[0.0, 0.5]Ö®¼ä 235 | if (inear < 1 || inear > my nx) return NUMundefined; // x out of range? x³¬³ö·¶Î§ 236 | double fnear = my v_getValueAtSample (inear, ilevel, unit); 237 | if (fnear == NUMundefined) return NUMundefined; // function value not defined? //º¯Êýֵ䶨Òå 238 | if (ifar < 1 || ifar > my nx) return fnear; // at edge? Extrapolate //Ôڱ߽çÍâ²å 239 | double ffar = my v_getValueAtSample (ifar, ilevel, unit); 240 | if (ffar == NUMundefined) return fnear; // neighbour undefined? Extrapolate 241 | return fnear + phase * (ffar - fnear); // interpolate //ÄÚ²åÖµ 242 | } 243 | return Sampled_getValueAtSample (me, Sampled_xToNearestIndex (me, x), ilevel, unit); 244 | }*/ 245 | 246 | bool Pitch_isVoiced_i (Pitch me, long iframe) { 247 | return NUMdefined (Sampled_getValueAtSample (me, iframe, Pitch_LEVEL_FREQUENCY, kPitch_unit_HERTZ)); 248 | } 249 | 250 | double Sampled_getValueAtSample (Pitch me, long isamp, long ilevel, int unit) { /***(Sampled me, long isamp, long ilevel, int unit)***/ 251 | if (isamp < 1 || isamp > my nx) return NUMundefined; 252 | return v_getValueAtSample (me, isamp, ilevel, unit); 253 | } 254 | 255 | //Sampled.cpp 110 256 | double Sampled_getValueAtX (Pitch me, double x, long ilevel, int unit, int interpolate){ 257 | if (x < my xmin || x > my xmax) 258 | return NUMundefined; 259 | 260 | if (interpolate) { 261 | double ireal = (x - my x1) / my dx + 1; //Sampled_xToIndex (me, x); 262 | long ileft = floor (ireal), inear, ifar; 263 | double phase = ireal - ileft; 264 | if (phase < 0.5) { 265 | inear = ileft, ifar = ileft + 1; 266 | } else { 267 | ifar = ileft, inear = ileft + 1; 268 | phase = 1.0 - phase; 269 | } 270 | if (inear < 1 || inear > my nx) 271 | return NUMundefined; // x out of range? 272 | 273 | double fnear = v_getValueAtSample (me, inear, ilevel, unit); 274 | 275 | if (fnear == NUMundefined) 276 | return NUMundefined; // function value not defined?\ 277 | 278 | if (ifar < 1 || ifar > my nx) 279 | return fnear; // at edge? Extrapolate 280 | 281 | double ffar = v_getValueAtSample (me, ifar, ilevel, unit); 282 | 283 | if (ffar == NUMundefined) 284 | return fnear; // neighbour undefined? Extrapolate 285 | 286 | return fnear + phase * (ffar - fnear); // interpolate 287 | } 288 | long isamp = (long)floor((x - my x1)/my dx + 1.5); //Sampled_xToNearestIndex (me, x) 289 | return Sampled_getValueAtSample (me, isamp, ilevel, unit); 290 | } 291 | 292 | //Sampled.cpp 133 293 | long Sampled_countDefinedSamples (Pitch me, long ilevel, int unit) { 294 | long numberOfDefinedSamples = 0; 295 | for (long isamp = 1; isamp <= my nx; isamp ++) { 296 | double value = v_getValueAtSample (me, isamp, ilevel, unit); 297 | 298 | if (value == NUMundefined) 299 | continue; 300 | numberOfDefinedSamples += 1; 301 | } 302 | return numberOfDefinedSamples; 303 | } 304 | 305 | double v_getValueAtSample (Pitch me, long iframe, long ilevel, int unit) { 306 | double f = my frame[iframe].candidate[1].frequency; 307 | if (f <= 0.0 || f >= my ceiling) return NUMundefined; // frequency out of range (or NUMundefined)? Voiceless 308 | return v_convertStandardToSpecialUnit (ilevel == Pitch_LEVEL_FREQUENCY ? f : my frame[iframe].candidate[1].strength, ilevel, unit);} 309 | 310 | double v_convertStandardToSpecialUnit (double value, long ilevel, int unit) { /****structPitch :: v_convertStandardToSpecialUnit (double value, long ilevel, int unit)****/ 311 | if (ilevel == Pitch_LEVEL_FREQUENCY) { 312 | return 313 | unit == kPitch_unit_HERTZ ? value : 314 | unit == kPitch_unit_HERTZ_LOGARITHMIC ? value <= 0.0 ? NUMundefined : log10 (value) : 315 | unit == kPitch_unit_MEL ? NUMhertzToMel (value) : 316 | unit == kPitch_unit_LOG_HERTZ ? value <= 0.0 ? NUMundefined : log10 (value) : 317 | unit == kPitch_unit_SEMITONES_1 ? value <= 0.0 ? NUMundefined : 12.0 * log (value / 1.0) / NUMln2 : 318 | unit == kPitch_unit_SEMITONES_100 ? value <= 0.0 ? NUMundefined : 12.0 * log (value / 100.0) / NUMln2 : 319 | unit == kPitch_unit_SEMITONES_200 ? value <= 0.0 ? NUMundefined : 12.0 * log (value / 200.0) / NUMln2 : 320 | unit == kPitch_unit_SEMITONES_440 ? value <= 0.0 ? NUMundefined : 12.0 * log (value / 440.0) / NUMln2 : 321 | unit == kPitch_unit_ERB ? NUMhertzToErb (value) : 322 | NUMundefined; 323 | } else { 324 | return 325 | unit == Pitch_STRENGTH_UNIT_AUTOCORRELATION ? value : 326 | unit == Pitch_STRENGTH_UNIT_NOISE_HARMONICS_RATIO ? 327 | value <= 1e-15 ? 1e15 : value > 1.0 - 1e-15 ? 1e-15 : (1.0 - value) / value : /* Before losing precision. */ 328 | unit == Pitch_STRENGTH_UNIT_HARMONICS_NOISE_DB ? 329 | value <= 1e-15 ? -150.0 : value > 1.0 - 1e-15 ? 150.0 : 10 * log10 (value / (1.0 - value)) : /* Before losing precision. */ 330 | NUMundefined; 331 | } 332 | } 333 | 334 | void Pitch_scaleDuration(Pitch me, double multiplier) 335 | { 336 | if(multiplier != 1){ // keep xmin at the same value 337 | my dx *= multiplier; 338 | my x1 = my xmin + (my x1 - my xmin) * multiplier; 339 | my xmax = my xmin + (my xmax - my xmin) * multiplier; 340 | } 341 | } 342 | 343 | void Pitch_scalePitch(Pitch me, double multiplier) 344 | { 345 | for(long i = 1; i < my nx; ++ i){ 346 | double f = my frame[i].candidate[1].frequency; 347 | f *= multiplier; 348 | if(f < my ceiling) 349 | my frame[i].candidate[1].frequency = f; 350 | } 351 | } 352 | 353 | bool intersectRangeWithDomain(Pitch me, double *x1, double *x2) 354 | { 355 | if(*x1 == *x2) return false; 356 | if(*x1 < *x2){ 357 | if(*x1 < my xmin) *x1 = my xmin; 358 | if(*x2 > my xmax) *x2 = my xmax; 359 | if(*x2 <= *x1) return false; 360 | } 361 | else 362 | { 363 | if(*x2 < my xmin) *x1 = my xmin; 364 | if(*x1 > my xmax) *x2 = my xmax; 365 | if(*x1 <= *x2) return false; 366 | } 367 | return true; 368 | } 369 | 370 | 371 | long Sampled_getWindowSamples (Pitch me, double xmin, double xmax, long *ixmin, long *ixmax) { 372 | double rixmin = 1.0 + ceil ((xmin - my x1) / my dx); 373 | double rixmax = 1.0 + floor ((xmax - my x1) / my dx); 374 | *ixmin = rixmin < 1.0 ? 1 : (long) rixmin; 375 | *ixmax = rixmax > (double) my nx ? my nx : (long) rixmax; 376 | if (*ixmin > *ixmax) return 0; 377 | return *ixmax - *ixmin + 1; 378 | } 379 | 380 | double getQuantitle(Pitch me, double xmin, double xmax, double quantile, long ilevel, int unit) 381 | { //PraatÔ´ÂëÖУº Sampled.cpp 157 382 | //double Sampled_getQuantile (Sampled me, double xmin, double xmax, double quantile, long ilevel, int unit) 383 | 384 | double *values = (double *)malloc(sizeof(double) * (my nx + 1)); 385 | if(xmin >= xmax){ 386 | xmin = my xmin; 387 | xmax = my xmax; 388 | } 389 | 390 | if(!(intersectRangeWithDomain(me, & xmin, & xmax))) 391 | return NUMundefined; 392 | 393 | long imin, imax, numberOfDefinedSamples = 0; 394 | Sampled_getWindowSamples(me, xmin, xmax, & imin, & imax); 395 | 396 | for(long i = imin ; i < imax; ++ i){ 397 | double value = v_getValueAtSample(me, i, ilevel, unit); 398 | if(NUMdefined(value)) 399 | values[++ numberOfDefinedSamples] = value; 400 | } 401 | 402 | double result = NUMundefined; 403 | if(numberOfDefinedSamples >= 1){ 404 | NUMsort_d(numberOfDefinedSamples, values); 405 | result = NUMquantile (numberOfDefinedSamples, values, quantile); 406 | } 407 | return result; 408 | } 409 | 410 | //Pitch.cpp 179 411 | double Pitch_getQuantile (Pitch me, double tmin, double tmax, double quantile, int unit) 412 | { 413 | double value = getQuantitle(me, tmin, tmax, quantile, Pitch_LEVEL_FREQUENCY, unit); 414 | //PraatÔ´ÂëÖÐ: Sampled_getQuantile 415 | if(value <= 0.0 && !doesUnitAllowNegativeValues(unit)) 416 | value = NUMundefined; 417 | return value; 418 | } 419 | 420 | //Sound_extension.cpp 1501 421 | Pitch Pitch_scaleTime_old (Pitch me, double scaleFactor){ 422 | double dx = my dx, x1 = my x1, xmax = my xmax; 423 | if (scaleFactor != 1) { 424 | dx = my dx * scaleFactor; 425 | x1 = my xmin + 0.5 * dx; 426 | xmax = my xmin + my nx * dx; 427 | } 428 | 429 | Pitch thee = Pitch_create (my xmin, xmax, my nx, dx, x1, my ceiling, 2); 430 | for (long i = 1; i <= my nx; i++) { 431 | double f = my frame[i].candidate[1].frequency; 432 | thy frame[i].candidate[1].strength = my frame[i].candidate[1].strength; 433 | f /= scaleFactor; 434 | if (f < my ceiling) 435 | thy frame[i].candidate[1].frequency = f; 436 | } 437 | 438 | return thee; 439 | } 440 | 441 | //Pitch.cpp 227 442 | double Pitch_getMinimum (Pitch me, double tmin, double tmax, int unit, int interpolate){ 443 | double minimum; 444 | Pitch_getMinimumAndTime(me, tmin, tmax, unit, interpolate, & minimum, NULL); 445 | return minimum; 446 | } 447 | 448 | //Pitch.cpp 217 449 | void Pitch_getMinimumAndTime (Pitch me, double tmin, double tmax, int unit, int interpolate, 450 | double *return_minimum, double *return_timeOfMinimum){ 451 | 452 | Sampled_getMinimumAndX (me, tmin, tmax, Pitch_LEVEL_FREQUENCY, unit, interpolate, return_minimum, return_timeOfMinimum); 453 | if (!doesUnitAllowNegativeValues(unit) && return_minimum && *return_minimum <= 0.0) 454 | *return_minimum = NUMundefined; /* Not so unlikely. */ 455 | } 456 | 457 | void Sampled_getMinimumAndX (Pitch me, double xmin, double xmax, long ilevel, int unit, int interpolate, 458 | double *return_minimum, double *return_xOfMinimum){ 459 | long imin, imax, i; 460 | double minimum = 1e301, xOfMinimum = 0.0; 461 | if (xmin == NUMundefined || xmax == NUMundefined) { 462 | minimum = xOfMinimum = NUMundefined; 463 | goto end; 464 | } 465 | 466 | 467 | if (xmin >= xmax) { 468 | xmin = my xmin; 469 | xmax = my xmax; 470 | }//Ô´ÂëÖÐΪ£º Function_unidirectionalAutowindow (me, & xmin, & xmax); 471 | 472 | if (!IntersectRangeWithDomain(me, &xmin, &xmax) ) { //Ô´ÂëÖУº Function_intersectRangeWithDomain (me, & xmin, & xmax) 473 | minimum = xOfMinimum = NUMundefined; //requested range and logical domain do not intersect 474 | goto end; 475 | } 476 | if (! Sampled_getWindowSamples (me, xmin, xmax, & imin, & imax)) { 477 | /* 478 | * No sample centres between xmin and xmax. 479 | * Try to return the lesser of the values at these two points. 480 | */ 481 | double fleft = Sampled_getValueAtX (me, xmin, ilevel, unit, interpolate); 482 | double fright = Sampled_getValueAtX (me, xmax, ilevel, unit, interpolate); 483 | if (NUMdefined (fleft) && fleft < minimum) minimum = fleft, xOfMinimum = xmin; 484 | if (NUMdefined (fright) && fright < minimum) minimum = fright, xOfMinimum = xmax; 485 | } else { 486 | for (i = imin; i <= imax; i ++) { 487 | double fmid = v_getValueAtSample (me, i, ilevel, unit); 488 | if (fmid == NUMundefined) 489 | continue; 490 | 491 | if (interpolate == FALSE) { 492 | if (fmid < minimum) 493 | minimum = fmid, xOfMinimum = i; 494 | } else { 495 | //Try an interpolation, possibly even taking into account a sample just outside the selection. 496 | double fleft = i <= 1 ? NUMundefined : v_getValueAtSample (me, i - 1, ilevel, unit); 497 | double fright = i >= my nx ? NUMundefined : v_getValueAtSample (me, i + 1, ilevel, unit); 498 | if (fleft == NUMundefined || fright == NUMundefined) { 499 | if (fmid < minimum) 500 | minimum = fmid, xOfMinimum = i; 501 | } else if (fmid < fleft && fmid <= fright) { 502 | double y [4], i_real, localMinimum; 503 | y [1] = fleft, y [2] = fmid, y [3] = fright; 504 | localMinimum = NUMimproveMinimum (y, 3, 2, NUM_PEAK_INTERPOLATE_PARABOLIC, & i_real); 505 | if (localMinimum < minimum) 506 | minimum = localMinimum, xOfMinimum = i_real + i - 2; 507 | } 508 | } 509 | } 510 | xOfMinimum = my x1 + (xOfMinimum - 1) * my dx; /* From index plus phase to time. */ 511 | /* Check boundary values. */ 512 | if (interpolate) { 513 | double fleft = Sampled_getValueAtX (me, xmin, ilevel, unit, TRUE); 514 | double fright = Sampled_getValueAtX (me, xmax, ilevel, unit, TRUE); 515 | if (NUMdefined (fleft) && fleft < minimum) 516 | minimum = fleft, xOfMinimum = xmin; 517 | if (NUMdefined (fright) && fright < minimum) 518 | minimum = fright, xOfMinimum = xmax; 519 | } 520 | if (xOfMinimum < xmin) 521 | xOfMinimum = xmin; 522 | if (xOfMinimum > xmax) 523 | xOfMinimum = xmax; 524 | } 525 | if (minimum == 1e301) 526 | minimum = xOfMinimum = NUMundefined; 527 | 528 | end: 529 | if (return_minimum) 530 | *return_minimum = minimum; 531 | if (return_xOfMinimum) 532 | *return_xOfMinimum = xOfMinimum; 533 | } 534 | 535 | //Function.cpp 165 536 | bool IntersectRangeWithDomain (Pitch me, double *x1, double *x2){ 537 | //Ô´ÂëÖÐ bool Function_intersectRangeWithDomain (Function me, double *x1, double *x2) 538 | if (*x1 == *x2) 539 | return false; 540 | 541 | if (*x1 < *x2) { 542 | if (*x1 < my xmin) 543 | *x1 = my xmin; // intersect requested range with logical domain 544 | if (*x2 > my xmax) 545 | *x2 = my xmax; 546 | if (*x2 <= *x1) 547 | return false; // requested range and logical domain do not intersect 548 | } else { 549 | if (*x2 < my xmin) 550 | *x2 = my xmin; // intersect requested range with logical domain 551 | if (*x1 > my xmax) 552 | *x1 = my xmax; 553 | if (*x1 <= *x2) 554 | return false; // requested range and logical domain do not intersect 555 | } 556 | 557 | return true; 558 | } 559 | --------------------------------------------------------------------------------