예제 #1
0
static autoSpectrum Cepstrum_to_Spectrum2 (Cepstrum me) { //TODO power cepstrum
	try {
		autoNUMfft_Table fftTable;
		long numberOfSamples = 2 * my nx - 2;

		autoNUMvector<double> fftbuf (1, numberOfSamples);
		autoSpectrum thee = Spectrum_create (0.5 / my dx, my nx);
		fftbuf[1] = sqrt (my z[1][1]);
		for (long i = 2; i <= my nx; i++) {
			fftbuf[i] = 2.0 * sqrt (my z[1][i]);
		}
		// fftbuf[my nx+1 ... numberOfSamples] = 0
		NUMfft_Table_init (&fftTable, numberOfSamples);
		NUMfft_forward (&fftTable, fftbuf.peek());
		
		thy z[1][1] = fabs (fftbuf[1]);
		for (long i = 2; i < my nx; i++) {
			double br = fftbuf[i + i - 2], bi = fftbuf[i + i - 1];
			thy z[1][i] = sqrt (br * br + bi * bi);
		}
		thy z[1][my nx] = fabs (fftbuf[numberOfSamples]);
		for (long i = 1; i <= my nx; i++) {
			thy z[1][i] = exp (NUMln10 * thy z[1][i] / 20.0) * 2e-5 / sqrt (2 * thy dx);
			thy z[2][i] = 0.0;
		}
		return thee;
	} catch (MelderError) {
		Melder_throw (me, U": no Spectrum created.");
	}
}
예제 #2
0
autoSpectrum Spectrum_compressFrequencyDomain (Spectrum me, double fmax, long interpolationDepth, int freqscale, int method) {
	try {
		double fdomain = my xmax - my xmin, factor = fdomain / fmax ;
		//long numberOfFrequencies = 1.0 + fmax / my dx; // keep dx the same, otherwise the "duration" changes
		double xmax = my xmax / factor;
		long numberOfFrequencies = (long) floor (my nx / factor); // keep dx the same, otherwise the "duration" changes
		autoSpectrum thee = Spectrum_create (xmax, numberOfFrequencies);
		thy z[1][1] = my z[1][1]; thy z[2][1] = my z[2][1];
		double df = freqscale == 1 ? factor * my dx : log10 (fdomain) / (numberOfFrequencies - 1);
		for (long i = 2; i <= numberOfFrequencies; i++) {
			double f = my xmin + (freqscale == 1 ? (i - 1) * df : pow (10.0, (i - 1) * df));
			double x, y, index = (f - my x1) / my dx + 1;
			if (index > my nx) {
				break;
			}
			if (method == 1) {
				x = NUM_interpolate_sinc (my z[1], my nx, index, interpolationDepth);
				y = NUM_interpolate_sinc (my z[2], my nx, index, interpolationDepth);
			} else {
				x = NUMundefined;   // ppgb: better than data from random memory
				y = NUMundefined;
			}
			thy z[1][i] = x; thy z[2][i] = y;
		}
		return thee;
	} catch (MelderError) {
		Melder_throw (me, U": not compressed.");
	}
}
예제 #3
0
파일: FilterBank.cpp 프로젝트: psibre/praat
Spectrum FormantFilter_to_Spectrum_slice (FormantFilter me, double t) {
	try {
		double sqrtref = sqrt (FilterBank_DBREF);
		double factor2 = 2 * 10 * FilterBank_DBFAC;
		autoSpectrum thee = Spectrum_create (my ymax, my ny);

		thy xmin = my ymin;
		thy xmax = my ymax;
		thy x1 = my y1;
		thy dx = my dy;   /* Frequency step. */

		long frame = Sampled_xToNearestIndex (me, t);
		if (frame < 1) {
			frame = 1;
		}
		if (frame > my nx) {
			frame = my nx;
		}

		for (long i = 1; i <= my ny; i++) {
			/*
				power = ref * 10 ^ (value / 10)
				sqrt(power) = sqrt(ref) * 10 ^ (value / (2*10))
			*/
			thy z[1][i] = sqrtref * pow (10, my z[i][frame] / factor2);
			thy z[2][i] = 0.0;
		}
		return thee.transfer();
	} catch (MelderError) {
		Melder_throw (me, U": Spectral slice not created.");
	}
}
예제 #4
0
autoSpectrum Spectrum_shiftFrequencies (Spectrum me, double shiftBy, double newMaximumFrequency, long interpolationDepth) {
	try {
		double xmax = my xmax;
		long numberOfFrequencies = my nx;
		if (newMaximumFrequency != 0) {
			numberOfFrequencies = (long) floor (newMaximumFrequency / my dx) + 1;
			xmax = newMaximumFrequency;
		}
		autoSpectrum thee = Spectrum_create (xmax, numberOfFrequencies);
		// shiftBy >= 0
		for (long i = 1; i <= thy nx; i++) {
			double thyf = thy x1 + (i - 1) * thy dx;
			double myf = thyf - shiftBy;
			if (myf >= my xmin && myf <= my xmax) {
				double index = Sampled_xToIndex (me, myf);
				thy z[1][i] = NUM_interpolate_sinc (my z[1], my nx, index, interpolationDepth);
				thy z[2][i] = NUM_interpolate_sinc (my z[2], my nx, index, interpolationDepth);
			}
		}
		// Make imaginary part of first and last sample zero
		// so Spectrum_to_Sound uses FFT if numberOfSamples was power of 2!
		double amp = sqrt (thy z[1][1] * thy z[1][1] + thy z[2][1] * thy z[2][1]);
		thy z[1][1] = amp; thy z[2][1] = 0;
		amp = sqrt (thy z[1][thy nx] * thy z[1][thy nx] + thy z[2][thy nx] * thy z[2][thy nx]);
		thy z[1][thy nx] = amp; thy z[2][thy nx] = 0;
		return thee;
	} catch (MelderError) {
		Melder_throw (me, U": not shifted.");
	}
}
예제 #5
0
autoSpectrum Spectrum_resample (Spectrum me, long numberOfFrequencies) {
	try {
		double newSamplingFrequency = (1 / my dx) * numberOfFrequencies / my nx;
		// resample real and imaginary part !
		autoSound thee = Sound_resample ((Sound) me, newSamplingFrequency, 50);
		autoSpectrum him = Spectrum_create (my xmax, numberOfFrequencies);
		NUMmatrix_copyElements<double> (thy z, his z, 1, 2, 1, numberOfFrequencies);
		return him;
	} catch (MelderError) {
		Melder_throw (me, U": not resampled.");
	}
}
예제 #6
0
autoSpectrum ComplexSpectrogram_to_Spectrum (ComplexSpectrogram me, double time) {
	try {
		long iframe = Sampled_xToLowIndex (me, time);   // ppgb: geen Sampled_xToIndex gebruiken voor integers (afrondingen altijd expliciet maken)
		iframe = iframe < 1 ? 1 : (iframe > my nx ? my nx : iframe);
		autoSpectrum thee = Spectrum_create (my ymax, my ny);
		for (long ifreq = 1; ifreq <= my ny; ifreq++) {
			double a = sqrt (my z[ifreq][iframe]);
			double phi = my phase[ifreq][iframe];
			thy z[1][ifreq] = a * cos (phi);
			thy z[2][ifreq] = a * sin (phi);
		}
		return thee;
	} catch (MelderError) {
		Melder_throw (me, U": no Spectrum created.");
	}
}
예제 #7
0
static autoSound ComplexSpectrogram_to_Sound2 (ComplexSpectrogram me, double stretchFactor) {
	try {
		/* original number of samples is odd: imaginary part of last spectral value is zero -> 
		 * phase is either zero or pi
		 */
		double pi = atan2 (0.0, - 0.5);
		double samplingFrequency = 2.0 * my ymax;
		double lastFrequency = my y1 + (my ny - 1) * my dy;
		int originalNumberOfSamplesProbablyOdd = (my phase [my ny][1] != 0.0 && my phase[my ny][1] != pi) || my ymax - lastFrequency > 0.25 * my dx;
		if (my y1 != 0.0) {
			Melder_throw (U"A Fourier-transformable Spectrum must have a first frequency of 0 Hz, not ", my y1, U" Hz.");
		}
		long numberOfSamples = 2 * my ny - (originalNumberOfSamplesProbablyOdd ? 1 : 2 );
		double synthesisWindowDuration = numberOfSamples / samplingFrequency;
		autoSpectrum spectrum = Spectrum_create (my ymax, my ny);
		autoSound synthesisWindow = Sound_createSimple (1, synthesisWindowDuration, samplingFrequency);
		long stepSizeSamples = my dx * samplingFrequency * stretchFactor;
		double newDuration = (my xmax - my xmin) * stretchFactor + 0.05;
		autoSound thee = Sound_createSimple (1, newDuration, samplingFrequency); //TODO
		long istart = 1, iend = istart + stepSizeSamples - 1;
		for (long iframe = 1; iframe <= my nx; iframe++) {
			spectrum -> z[1][1] = sqrt (my z[1][iframe]);
			for (long ifreq = 2; ifreq <= my ny; ifreq++) {
				double f = my y1 + (ifreq - 1) * my dy;
				double a = sqrt (my z[ifreq][iframe]);
				double phi = my phase[ifreq][iframe];
				double extraPhase = 2.0 * pi * (stretchFactor - 1.0) * my dx * f;
				phi += extraPhase;
				spectrum -> z[1][ifreq] = a * cos (phi);
				spectrum -> z[2][ifreq] = a * sin (phi);
			}
			autoSound synthesis = Spectrum_to_Sound (spectrum.get());
			for (long j = istart; j <= iend; j++) {
				thy z[1][j] = synthesis -> z[1][j - istart + 1];
			}
			istart = iend + 1; iend = istart + stepSizeSamples - 1;
		}
		return thee;
	} catch (MelderError) {
		Melder_throw (me, U": no Sound created.");
	}
}
예제 #8
0
double VocalTract_and_LPC_Frame_getMatchingLength (VocalTract me, LPC_Frame thee, double glottalDamping, bool radiationDamping, bool internalDamping) {
	try {
		// match the average distance between the first two formants in the VocaTract and the LPC spectrum
		long numberOfFrequencies = 1000;
		double maximumFrequency = 5000.0;
		autoSpectrum vts = VocalTract_to_Spectrum (me, numberOfFrequencies, maximumFrequency, glottalDamping, radiationDamping, internalDamping);
		double samplingFrequency =  1000.0 * my nx;
		autoSpectrum lps = Spectrum_create (0.5 * samplingFrequency, numberOfFrequencies);
		LPC_Frame_into_Spectrum (thee, lps.peek(), 0, 50);
		autoSpectrumTier vtst = Spectrum_to_SpectrumTier_peaks (vts.peek());
		autoSpectrumTier lpst = Spectrum_to_SpectrumTier_peaks (lps.peek());
		double vt_f1 = vtst -> points.at [1] -> number, vt_f2 = vtst -> points.at [2] -> number;
		double lp_f1 = lpst -> points.at [1] -> number, lp_f2 = lpst -> points.at [2] -> number;
		double df1 = lp_f1 - vt_f1, df2 =  lp_f2 - vt_f2, df = 0.5 * (df1 + df2);
		double dl = - df / lp_f2;
		return my dx * my nx * (1 + dl);
	} catch (MelderError) {
		Melder_throw (U"Length could not be determined from VocalTract and LPC_Frame.");
	}
}
예제 #9
0
autoSpectrum Sound_to_Spectrum (Sound me, int fast) {
	try {
		long numberOfSamples = my nx;
		if (fast) {
			numberOfSamples = 2;
			while (numberOfSamples < my nx) numberOfSamples *= 2;
		}
		long numberOfFrequencies = numberOfSamples / 2 + 1;   // 4 samples -> cos0 cos1 sin1 cos2; 5 samples -> cos0 cos1 sin1 cos2 sin2
		autoNUMvector <double> data (1, numberOfSamples);
		autoNUMfft_Table fourierTable;
		NUMfft_Table_init (& fourierTable, numberOfSamples);

		for (long i = 1; i <= my nx; i ++)
			data [i] = my ny == 1 ? my z [1] [i] : 0.5 * (my z [1] [i] + my z [2] [i]);
		NUMfft_forward (& fourierTable, data.peek());
		autoSpectrum thee = Spectrum_create (0.5 / my dx, numberOfFrequencies);
		thy dx = 1.0 / (my dx * numberOfSamples);   // override
		double *re = thy z [1];
		double *im = thy z [2];
		double scaling = my dx;
		re [1] = data [1] * scaling;
		im [1] = 0.0;
		for (long i = 2; i < numberOfFrequencies; i ++) {
			re [i] = data [i + i - 2] * scaling;
			im [i] = data [i + i - 1] * scaling;
		}
		if ((numberOfSamples & 1) != 0) {
			if (numberOfSamples > 1) {
				re [numberOfFrequencies] = data [numberOfSamples - 1] * scaling;
				im [numberOfFrequencies] = data [numberOfSamples] * scaling;
			}
		} else {
			re [numberOfFrequencies] = data [numberOfSamples] * scaling;
			im [numberOfFrequencies] = 0.0;
		}
		return thee;
	} catch (MelderError) {
		Melder_throw (me, U": not converted to Spectrum.");
	}
}
예제 #10
0
Spectrum Spectrogram_to_Spectrum (I, double tim) {
	iam (Spectrogram);
	try {
		autoSpectrum thee = Spectrum_create (my ymax, my ny);
		/* Override stupid Spectrum values. */
		thy xmin = my ymin;
		thy xmax = my ymax;
		thy x1 = my y1;   // centre of first band, instead of 0 (makes it unFFTable)
		thy dx = my dy;   // frequency step
		long itime = Sampled_xToNearestIndex (me, tim);
		if (itime < 1 ) itime = 1;
		if (itime > my nx) itime = my nx;
		for (long ifreq = 1; ifreq <= my ny; ifreq ++) {
			double value = my z [ifreq] [itime];
			if (value < 0.0)
				Melder_throw (U"Negative values in spectrogram.");
			thy z [1] [ifreq] = sqrt (value);
			thy z [2] [ifreq] = 0.0;
		}
		return thee.transfer();
	} catch (MelderError) {
		Melder_throw (me, U": spectral slice not extracted.");
	}
}
예제 #11
0
Spectrum LPC_to_Spectrum (LPC me, double t, double dfMin, double bandwidthReduction, double deEmphasisFrequency) {
	try {
		double samplingFrequency = 1.0 / my samplingPeriod;
		long nfft = 2, index = Sampled_xToNearestIndex (me, t);

		if (index < 1) {
			index = 1;
		}
		if (index > my nx) {
			index = my nx;
		}
		if (dfMin <= 0) {
			nfft = 512; dfMin = samplingFrequency / nfft;
		}
		while (samplingFrequency / nfft > dfMin || nfft <= my d_frames[index].nCoefficients) {
			nfft *= 2;
		}
		autoSpectrum thee = Spectrum_create (samplingFrequency / 2, nfft / 2 + 1);
		LPC_Frame_into_Spectrum (& my d_frames[index], thee.peek(), bandwidthReduction, deEmphasisFrequency);
		return thee.transfer();
	} catch (MelderError) {
		Melder_throw (me, ": no Spectrum created.");
	}
}
예제 #12
0
static autoSpectrum Spectrum_shiftFrequencies2 (Spectrum me, double shiftBy, bool changeMaximumFrequency) {
	try {
		double xmax = my xmax;
		long numberOfFrequencies = my nx, interpolationDepth = 50;
		if (changeMaximumFrequency) {
			xmax += shiftBy;
			numberOfFrequencies += (xmax - my xmax) / my dx;
		}
		autoSpectrum thee = Spectrum_create (xmax, numberOfFrequencies);
		// shiftBy >= 0
		for (long i = 1; i <= thy nx; i++) {
			double thyf = thy x1 + (i - 1) * thy dx;
			double myf = thyf - shiftBy;
			if (myf >= my xmin && myf <= my xmax) {
				double index = Sampled_xToIndex (me, myf);
				thy z[1][i] = NUM_interpolate_sinc (my z[1], my nx, index, interpolationDepth);
				thy z[2][i] = NUM_interpolate_sinc (my z[2], my nx, index, interpolationDepth);
			}
		}
		return thee;
	} catch (MelderError) {
		Melder_throw (me, U": not shifted.");
	}
}
예제 #13
0
autoSpectrum Sound_to_Spectrum (Sound me, int fast) {
	try {
		long numberOfSamples = my nx;
		const long numberOfChannels = my ny;
		if (fast) {
			numberOfSamples = 2;
			while (numberOfSamples < my nx) numberOfSamples *= 2;
		}
		long numberOfFrequencies = numberOfSamples / 2 + 1;   // 4 samples -> cos0 cos1 sin1 cos2; 5 samples -> cos0 cos1 sin1 cos2 sin2

		autoNUMvector <double> data (1, numberOfSamples);
		if (numberOfChannels == 1) {
			const double *channel = my z [1];
			for (long i = 1; i <= my nx; i ++) {
				data [i] = channel [i];
			}
			/*
				All samples from `my nx + 1` through `numberOfSamples`
				should be set to zero, but they are already zero.
			*/
			// so do nothing
		} else {
			for (long ichan = 1; ichan <= numberOfChannels; ichan ++) {
				const double *channel = my z [ichan];
				for (long i = 1; i <= my nx; i ++) {
					data [i] += channel [i];
				}
			}
			for (long i = 1; i <= my nx; i ++) {
				data [i] /= numberOfChannels;
			}
		}

		autoNUMfft_Table fourierTable;
		NUMfft_Table_init (& fourierTable, numberOfSamples);
		NUMfft_forward (& fourierTable, data.peek());

		autoSpectrum thee = Spectrum_create (0.5 / my dx, numberOfFrequencies);
		thy dx = 1.0 / (my dx * numberOfSamples);   // override
		double *re = thy z [1];
		double *im = thy z [2];
		double scaling = my dx;
		re [1] = data [1] * scaling;
		im [1] = 0.0;
		for (long i = 2; i < numberOfFrequencies; i ++) {
			re [i] = data [i + i - 2] * scaling;   // data [2], data [4], ...
			im [i] = data [i + i - 1] * scaling;   // data [3], data [5], ...
		}
		if ((numberOfSamples & 1) != 0) {
			if (numberOfSamples > 1) {
				re [numberOfFrequencies] = data [numberOfSamples - 1] * scaling;
				im [numberOfFrequencies] = data [numberOfSamples] * scaling;
			}
		} else {
			re [numberOfFrequencies] = data [numberOfSamples] * scaling;
			im [numberOfFrequencies] = 0.0;
		}
		return thee;
	} catch (MelderError) {
		Melder_throw (me, U": not converted to Spectrum.");
	}
}
예제 #14
0
autoSound ComplexSpectrogram_to_Sound (ComplexSpectrogram me, double stretchFactor) {
	try {
		/* original number of samples is odd: imaginary part of last spectral value is zero -> 
		 * phase is either zero or +/-pi
		 */
		double pi = atan2 (0.0, - 0.5);
		double samplingFrequency = 2.0 * my ymax;
		double lastFrequency = my y1 + (my ny - 1) * my dy, lastPhase = my phase[my ny][1];
		int originalNumberOfSamplesProbablyOdd = (lastPhase != 0.0 && lastPhase != pi && lastPhase != -pi) || 
			my ymax - lastFrequency > 0.25 * my dx;
		if (my y1 != 0.0) {
			Melder_throw (U"A Fourier-transformable ComplexSpectrogram must have a first frequency of 0 Hz, not ", my y1, U" Hz.");
		}
		long nsamp_window = 2 * my ny - (originalNumberOfSamplesProbablyOdd ? 1 : 2 );
		long halfnsamp_window = nsamp_window / 2;
		double synthesisWindowDuration = nsamp_window / samplingFrequency;
		autoSpectrum spectrum = Spectrum_create (my ymax, my ny);
		autoSound synthesisWindow = Sound_createSimple (1, synthesisWindowDuration, samplingFrequency);
		double newDuration = (my xmax - my xmin) * stretchFactor;
		autoSound thee = Sound_createSimple (1, newDuration, samplingFrequency); //TODO
		double thyStartTime;
		for (long iframe = 1; iframe <= my nx; iframe++) {
			// "original" sound :
			double tmid = Sampled_indexToX (me, iframe);
			long leftSample = Sampled_xToLowIndex (thee.get(), tmid);
			long rightSample = leftSample + 1;
			long startSample = rightSample - halfnsamp_window;
			double startTime = Sampled_indexToX (thee.get(), startSample);
			if (iframe == 1) {
				thyStartTime = Sampled_indexToX (thee.get(), startSample);
			}
			//long endSample = leftSample + halfnsamp_window;
			// New Sound with stretch
			long thyStartSample = Sampled_xToLowIndex (thee.get(),thyStartTime);
			double thyEndTime = thyStartTime + my dx * stretchFactor;
			long thyEndSample = Sampled_xToLowIndex (thee.get(), thyEndTime);
			long stretchedStepSizeSamples = thyEndSample - thyStartSample + 1;
			//double extraTime = (thyStartSample - startSample + 1) * thy dx;
			double extraTime = (thyStartTime - startTime);
			spectrum -> z[1][1] = sqrt (my z[1][iframe]);
			for (long ifreq = 2; ifreq <= my ny; ifreq++) {
				double f = my y1 + (ifreq - 1) * my dy;
				double a = sqrt (my z[ifreq][iframe]);
				double phi = my phase[ifreq][iframe], intPart;
				double extraPhase = 2.0 * pi * modf (extraTime * f, &intPart); // fractional part
				phi += extraPhase;
				spectrum -> z[1][ifreq] = a * cos (phi);
				spectrum -> z[2][ifreq] = a * sin (phi);
			}

			autoSound synthesis = Spectrum_to_Sound (spectrum.get());

			// Where should the sound be placed?

			long thyEndSampleP = (long) floor (fmin (thyStartSample + synthesis -> nx - 1, thyStartSample + stretchedStepSizeSamples - 1)); // guard against extreme stretches
			if (iframe == my nx) {
				thyEndSampleP = (long) floor (fmin (thy nx, thyStartSample + synthesis -> nx - 1));   // ppgb: waarom naar beneden afgerond?
			}
			for (long j = thyStartSample; j <= thyEndSampleP; j++) {
				thy z[1][j] = synthesis -> z[1][j - thyStartSample + 1];
			}
			thyStartTime += my dx * stretchFactor;
		}
		return thee;
	} catch (MelderError) {
		Melder_throw (me, U": no Sound created.");
	}
}