Esempio n. 1
0
Sound Sound_resample (Sound me, double samplingFrequency, long precision) {
	double upfactor = samplingFrequency * my dx;
	if (fabs (upfactor - 2) < 1e-6) return Sound_upsample (me);
	if (fabs (upfactor - 1) < 1e-6) return Data_copy (me);
	try {
		long numberOfSamples = lround ((my xmax - my xmin) * samplingFrequency);
		if (numberOfSamples < 1)
			Melder_throw (U"The resampled Sound would have no samples.");
		autoSound filtered = NULL;
		if (upfactor < 1.0) {   // need anti-aliasing filter?
			long nfft = 1, antiTurnAround = 1000;
			while (nfft < my nx + antiTurnAround * 2) nfft *= 2;
			autoNUMvector <double> data (1, nfft);
			filtered.reset (Sound_create (my ny, my xmin, my xmax, my nx, my dx, my x1));
			for (long channel = 1; channel <= my ny; channel ++) {
				for (long i = 1; i <= nfft; i ++) {
					data [i] = 0;
				}
				NUMvector_copyElements (my z [channel], & data [antiTurnAround], 1, my nx);
				NUMrealft (data.peek(), nfft, 1);   // go to the frequency domain
				for (long i = (long) floor (upfactor * nfft); i <= nfft; i ++) {
					data [i] = 0;   // filter away high frequencies
				}
				data [2] = 0.0;
				NUMrealft (data.peek(), nfft, -1);   // return to the time domain
				double factor = 1.0 / nfft;
				double *to = filtered -> z [channel];
				for (long i = 1; i <= my nx; i ++) {
					to [i] = data [i + antiTurnAround] * factor;
				}
			}
			me = filtered.peek();   // reference copy; remove at end
		}
		autoSound thee = Sound_create (my ny, my xmin, my xmax, numberOfSamples, 1.0 / samplingFrequency,
			0.5 * (my xmin + my xmax - (numberOfSamples - 1) / samplingFrequency));
		for (long channel = 1; channel <= my ny; channel ++) {
			double *from = my z [channel];
			double *to = thy z [channel];
			if (precision <= 1) {
				for (long i = 1; i <= numberOfSamples; i ++) {
					double x = Sampled_indexToX (thee.peek(), i);
					double index = Sampled_xToIndex (me, x);
					long leftSample = (long) floor (index);
					double fraction = index - leftSample;
					to [i] = leftSample < 1 || leftSample >= my nx ? 0.0 :
						(1 - fraction) * from [leftSample] + fraction * from [leftSample + 1];
				}
			} else {
				for (long i = 1; i <= numberOfSamples; i ++) {
					double x = Sampled_indexToX (thee.peek(), i);
					double index = Sampled_xToIndex (me, x);
					to [i] = NUM_interpolate_sinc (my z [channel], my nx, index, precision);
				}
			}
		}
		return thee.transfer();
	} catch (MelderError) {
		Melder_throw (me, U": not resampled.");
	}
}
Esempio n. 2
0
Sound Sound_resample (Sound me, double samplingFrequency, long precision) {
	double *data = NULL;
	double upfactor = samplingFrequency * my dx;
	long numberOfSamples = floor ((my xmax - my xmin) * samplingFrequency + 0.5), i;
	Sound thee = NULL, filtered = NULL;
	if (fabs (upfactor - 2) < 1e-6) return Sound_upsample (me);
	if (fabs (upfactor - 1) < 1e-6) return (structSound *)Data_copy (me);
	if (numberOfSamples < 1)
		return (structSound *)Melder_errorp ("Cannot resample to 0 samples.");
	thee = Sound_create (my ny, my xmin, my xmax, numberOfSamples, 1.0 / samplingFrequency,
		0.5 * (my xmin + my xmax - (numberOfSamples - 1) / samplingFrequency)); cherror
	if (upfactor < 1.0) {   /* Need anti-aliasing filter? */
		long nfft = 1, antiTurnAround = 1000;
		while (nfft < my nx + antiTurnAround * 2) nfft *= 2;
		data = NUMdvector (1, nfft); cherror
		filtered = Sound_create (my ny, my xmin, my xmax, my nx, my dx, my x1); cherror
		for (long channel = 1; channel <= my ny; channel ++) {
			for (long i = 1; i <= nfft; i ++) {
				data [i] = 0;
			}
			NUMdvector_copyElements (my z [channel], data + antiTurnAround, 1, my nx);
			NUMrealft (data, nfft, 1); cherror   /* Go to the frequency domain. */
			for (long i = floor (upfactor * nfft); i <= nfft; i ++) {
				data [i] = 0;   /* Filter away high frequencies. */
			}
			data [2] = 0.0;
			NUMrealft (data, nfft, -1); cherror   /* Return to the time domain. */
			double factor = 1.0 / nfft;
			double *to = filtered -> z [channel];
			for (long i = 1; i <= my nx; i ++) {
				to [i] = data [i + antiTurnAround] * factor;
			}
		}
		me = filtered;   /* Reference copy. Remove at end. */
	}
Esempio n. 3
0
static void do_write (TimeSoundEditor me, MelderFile file, int format, int numberOfBitsPerSamplePoint) {
	if (my d_startSelection >= my d_endSelection)
		Melder_throw (U"No samples selected.");
	if (my d_longSound.data) {
		LongSound_writePartToAudioFile (my d_longSound.data, format, my d_startSelection, my d_endSelection, file, numberOfBitsPerSamplePoint);
	} else if (my d_sound.data) {
		Sound sound = my d_sound.data;
		double margin = 0.0;
		long nmargin = (long) floor (margin / sound -> dx);
		long first, last, numberOfSamples = Sampled_getWindowSamples (sound,
			my d_startSelection, my d_endSelection, & first, & last) + nmargin * 2;
		first -= nmargin;
		last += nmargin;
		if (numberOfSamples) {
			autoSound save = Sound_create (sound -> ny, 0.0, numberOfSamples * sound -> dx, numberOfSamples, sound -> dx, 0.5 * sound -> dx);
			long offset = first - 1;
			if (first < 1) first = 1;
			if (last > sound -> nx) last = sound -> nx;
			for (long channel = 1; channel <= sound -> ny; channel ++) {
				for (long i = first; i <= last; i ++) {
					save -> z [channel] [i - offset] = sound -> z [channel] [i];
				}
			}
			Sound_writeToAudioFile (save.peek(), file, format, numberOfBitsPerSamplePoint);
		}
	}
}
Esempio n. 4
0
Sound Sound_createAsPureTone (long numberOfChannels, double startingTime, double endTime,
	double sampleRate, double frequency, double amplitude, double fadeInDuration, double fadeOutDuration)
{
	try {
		double numberOfSamples_f = round ((endTime - startingTime) * sampleRate);
		if (numberOfSamples_f > (double) INT32_MAX)
			Melder_throw (U"Cannot create sounds with more than ", Melder_bigInteger (INT32_MAX), U" samples, because they cannot be saved to disk.");
		autoSound me = Sound_create (numberOfChannels, startingTime, endTime, (long) numberOfSamples_f,
			1 / sampleRate, startingTime + 0.5 / sampleRate);
		for (long isamp = 1; isamp <= my nx; isamp ++) {
			double time = my x1 + (isamp - 1) * my dx;
			double value = amplitude * sin (NUM2pi * frequency * time);
			double timeFromStart = time - startingTime;
			if (timeFromStart < fadeInDuration)
				value *= 0.5 - 0.5 * cos (NUMpi * timeFromStart / fadeInDuration);
			double timeFromEnd = endTime - time;
			if (timeFromEnd < fadeOutDuration)
				value *= 0.5 - 0.5 * cos (NUMpi * timeFromEnd / fadeOutDuration);
			for (long ichan = 1; ichan <= my ny; ichan ++) {
				my z [ichan] [isamp] = value;
			}
		}
		return me.transfer();
	} catch (MelderError) {
		Melder_throw (U"Sound not created from tone complex.");
	}
}
Esempio n. 5
0
Sound Sound_upsample (Sound me) {
	double *data = NULL;
	Sound thee = NULL;

	long nfft = 1;
	while (nfft < my nx + 2000) nfft *= 2;
	thee = Sound_create (my ny, my xmin, my xmax, my nx * 2, my dx / 2, my x1); cherror
	data = NUMdvector (1, 2 * nfft); cherror
	for (long channel = 1; channel <= my ny; channel ++) {
		NUMdvector_copyElements (my z [channel], data + 1000, 1, my nx);
		NUMrealft (data, nfft, 1); cherror
		long imin = (long) (nfft * 0.95);
		for (long i = imin + 1; i <= nfft; i ++) {
			data [i] *= ((double) (nfft - i)) / (nfft - imin);
		}
		data [2] = 0.0;
		NUMrealft (data, 2 * nfft, -1); cherror
		double factor = 1.0 / nfft;
		for (long i = 1; i <= thy nx; i ++) {
			thy z [channel] [i] = data [i + 2000] * factor;
		}
	}
end:
	NUMdvector_free (data, 1);
	iferror forget (thee);
	return thee;
}
Esempio n. 6
0
Sound Sounds_combineToStereo (Sound me, Sound thee) {
	if (my ny != 1 || thy ny != 1) return (structSound *)Melder_errorp ("Can only combine mono sounds. Stereo sound not created.");
	if (my dx != thy dx) return (structSound *)Melder_errorp ("Sampling frequencies do not match. Sounds not combined.");
	double dx = my dx;   // or thy dx, which is the same
	double xmin = my xmin < thy xmin ? my xmin : thy xmin;
	double xmax = my xmax > thy xmax ? my xmax : thy xmax;
	long myInitialZeroes = floor ((my xmin - xmin) / dx);
	long thyInitialZeroes = floor ((thy xmin - xmin) / dx);
	double myx1 = my x1 - my dx * myInitialZeroes;
	double thyx1 = thy x1 - thy dx * thyInitialZeroes;
	double x1 = 0.5 * (myx1 + thyx1);
	long mynx = my nx + myInitialZeroes;
	long thynx = thy nx + thyInitialZeroes;
	long nx = mynx > thynx ? mynx : thynx;
	Sound him = Sound_create (2, xmin, xmax, nx, dx, x1); cherror
	for (long i = 1; i <= my nx; i ++) {
		his z [1] [i + myInitialZeroes] = my z [1] [i];
	}
	for (long i = 1; i <= thy nx; i ++) {
		his z [2] [i + thyInitialZeroes] = thy z [1] [i];
	}
end:
	iferror forget (him);
	return him;
}
Esempio n. 7
0
Sound Sound_upsample (Sound me) {
	try {
		long nfft = 1;
		while (nfft < my nx + 2000) nfft *= 2;
		autoSound thee = Sound_create (my ny, my xmin, my xmax, my nx * 2, my dx / 2, my x1 - my dx / 4);
		for (long channel = 1; channel <= my ny; channel ++) {
			autoNUMvector <double> data (1, 2 * nfft);   // zeroing is important...
			NUMvector_copyElements (my z [channel], & data [1000], 1, my nx);   // ...because this fills only part of the sound
			NUMrealft (data.peek(), nfft, 1);
			long imin = (long) (nfft * 0.95);
			for (long i = imin + 1; i <= nfft; i ++) {
				data [i] *= ((double) (nfft - i)) / (nfft - imin);
			}
			data [2] = 0.0;
			NUMrealft (data.peek(), 2 * nfft, -1);
			double factor = 1.0 / nfft;
			for (long i = 1; i <= thy nx; i ++) {
				thy z [channel] [i] = data [i + 2000] * factor;
			}
		}
		return thee.transfer();
	} catch (MelderError) {
		Melder_throw (me, U": not upsampled.");
	}
}
Esempio n. 8
0
Sound Sound_createSimple (long numberOfChannels, double duration, double samplingFrequency) {
	Melder_assert (duration >= 0.0);
	Melder_assert (samplingFrequency > 0.0);
	double numberOfSamples_f = round (duration * samplingFrequency);
	if (numberOfSamples_f > (double) INT32_MAX)
		Melder_throw (U"Cannot create sounds with more than ", Melder_bigInteger (INT32_MAX), U" samples, because they cannot be saved to disk.");
	return Sound_create (numberOfChannels, 0.0, duration, (long) (int32_t) numberOfSamples_f,
		1 / samplingFrequency, 0.5 / samplingFrequency);
}
Esempio n. 9
0
Sound Matrix_to_Sound_mono (Matrix me, long row) {
	Sound thee = Sound_create (1, my xmin, my xmax, my nx, my dx, my x1);
	if (! thee) return NULL;
	if (row < 0) row = my ny + 1 + row;
	if (row < 1) row = 1;
	if (row > my ny) row = my ny;
	NUMdvector_copyElements (my z [row], thy z [1], 1, my nx);
	return thee;
}
Esempio n. 10
0
autoComplexSpectrogram Sound_to_ComplexSpectrogram (Sound me, double windowLength, double timeStep) {
	try {
		double samplingFrequency = 1.0 / my dx, myDuration = my xmax - my xmin, t1;
		if (windowLength > myDuration) {
			Melder_throw (U"Your sound is too short:\nit should be at least as long as one window length.");
		}
		
		long nsamp_window = (long) floor (windowLength / my dx);
		long halfnsamp_window = nsamp_window / 2 - 1;
		nsamp_window = halfnsamp_window * 2;
		
		if (nsamp_window < 2) {
			Melder_throw (U"Your analysis window is too short: less than two samples.");
		}
		
		long numberOfFrames;
		Sampled_shortTermAnalysis (me, windowLength, timeStep, &numberOfFrames, &t1);

		// Compute sampling of the spectrum

		long numberOfFrequencies = halfnsamp_window + 1;
		double df = samplingFrequency / (numberOfFrequencies - 1);
		
		autoComplexSpectrogram thee = ComplexSpectrogram_create (my xmin, my xmax, numberOfFrames, timeStep, t1, 0.0, 0.5 * samplingFrequency, numberOfFrequencies, df, 0.0);
		// 
		autoSound analysisWindow = Sound_create (1, 0.0, nsamp_window * my dx, nsamp_window, my dx, 0.5 * my dx);
		
		for (long iframe = 1; iframe <= numberOfFrames; iframe++) {
			double t = Sampled_indexToX (thee.get(), iframe);
			long leftSample = Sampled_xToLowIndex (me, t), rightSample = leftSample + 1;
			long startSample = rightSample - halfnsamp_window;
			long endSample = leftSample + halfnsamp_window;
			Melder_assert (startSample >= 1);
			Melder_assert (endSample <= my nx);
			
			for (long j = 1; j <= nsamp_window; j++) {
				analysisWindow -> z[1][j] = my z[1][startSample - 1 + j];
			}
			// window ?
			autoSpectrum spec = Sound_to_Spectrum (analysisWindow.get(), 0);
			
			thy z[1][iframe] = spec -> z[1][1] * spec -> z[1][1];
			thy phase[1][iframe] = 0.0;
			for (long ifreq = 2; ifreq <= numberOfFrequencies - 1; ifreq++) {
				double x = spec -> z[1][ifreq], y = spec -> z[2][ifreq];
				thy z[ifreq][iframe] = x * x + y * y; // power
				thy phase[ifreq][iframe] = atan2 (y, x); // phase [-pi,+pi]
			}
			// even number of samples
			thy z[numberOfFrequencies][iframe] = spec -> z[1][numberOfFrequencies] * spec -> z[1][numberOfFrequencies];
			thy phase[numberOfFrequencies][iframe] = 0.0;
		}
		return thee;
	} catch (MelderError) {
		Melder_throw (me, U": no ComplexSpectrogram created.");
	}
}
Esempio n. 11
0
Sound Sounds_crossCorrelate_short (Sound me, Sound thee, double tmin, double tmax, int normalize) {
	try {
		if (my dx != thy dx)
			Melder_throw (U"Sampling frequencies are not equal.");
		if (my ny != thy ny)
			Melder_throw (U"Numbers of channels are not equal.");
		double dt = my dx;
		double dphase = (thy x1 - my x1) / dt;
		dphase -= floor (dphase);   // a number between 0 and 1
		long i1 = (long) ceil (tmin / dt - dphase);   // index of first sample if sample at dphase has index 0
		long i2 = (long) floor (tmax / dt - dphase);   // index of last sample if sample at dphase has index 0
		long nt = i2 - i1 + 1;
		if (nt < 1)
			Melder_throw (U"Window too small.");
		double t1 = (dphase + i1) * dt;
		autoSound him = Sound_create (1, tmin, tmax, nt, dt, t1);
		for (long i = 1; i <= nt; i ++) {
			long di = i - 1 + i1;
			for (long ime = 1; ime <= my nx; ime ++) {
				if (ime + di < 1) continue;
				if (ime + di > thy nx) break;
				for (long channel = 1; channel <= my ny; channel ++) {
					his z [1] [i] += my z [channel] [ime] * thy z [channel] [ime + di];
				}
			}
		}
		if (normalize) {
			double mypower = 0.0, thypower = 0.0;
			for (long channel = 1; channel <= my ny; channel ++) {
				for (long i = 1; i <= my nx; i ++) {
					double value = my z [channel] [i];
					mypower += value * value;
				}
				for (long i = 1; i <= thy nx; i ++) {
					double value = thy z [channel] [i];
					thypower += value * value;
				}
			}
			if (mypower != 0.0 && thypower != 0.0) {
				double factor = 1.0 / (sqrt (mypower) * sqrt (thypower));
				for (long i = 1; i <= nt; i ++) {
					his z [1] [i] *= factor;
				}
			}
		} else {
			double factor = dt / my ny;
			for (long i = 1; i <= nt; i ++) {
				his z [1] [i] *= factor;
			}
		}
		return him.transfer();
	} catch (MelderError) {
		Melder_throw (me, U": not cross-correlated.");
	}
}
Esempio n. 12
0
Sound Sounds_combineToStereo (Collection me) {
	try {
		long totalNumberOfChannels = 0;
		double sharedSamplingPeriod = 0.0;
		for (long isound = 1; isound <= my size; isound ++) {
			Sound sound = (Sound) my item [isound];
			totalNumberOfChannels += sound -> ny;
			if (sharedSamplingPeriod == 0.0) {
				sharedSamplingPeriod = sound -> dx;
			} else if (sound -> dx != sharedSamplingPeriod) {
				Melder_throw (U"To combine sounds, their sampling frequencies must be equal.\n"
						U"You could resample one or more of the sounds before combining.");
			}
		}
		double sharedMinimumTime = NUMundefined, sharedMaximumTime = NUMundefined;
		for (long isound = 1; isound <= my size; isound ++) {
			Sound sound = (Sound) my item [isound];
			if (isound == 1) {
				sharedMinimumTime = sound -> xmin;
				sharedMaximumTime = sound -> xmax;
			} else {
				if (sound -> xmin < sharedMinimumTime) sharedMinimumTime = sound -> xmin;
				if (sound -> xmax > sharedMaximumTime) sharedMaximumTime = sound -> xmax;
			}
		}
		autoNUMvector <double> numberOfInitialZeroes (1, my size);
		long sharedNumberOfSamples = 0;
		double sumOfFirstTimes = 0.0;
		for (long isound = 1; isound <= my size; isound ++) {
			Sound sound = (Sound) my item [isound];
			numberOfInitialZeroes [isound] = floor ((sound -> xmin - sharedMinimumTime) / sharedSamplingPeriod);
			double newFirstTime = sound -> x1 - sound -> dx * numberOfInitialZeroes [isound];
			sumOfFirstTimes += newFirstTime;
			long newNumberOfSamplesThroughLastNonzero = sound -> nx + (long) floor (numberOfInitialZeroes [isound]);
			if (newNumberOfSamplesThroughLastNonzero > sharedNumberOfSamples) sharedNumberOfSamples = newNumberOfSamplesThroughLastNonzero;
		}
		double sharedTimeOfFirstSample = sumOfFirstTimes / my size;   // this is an approximation
		autoSound thee = Sound_create (totalNumberOfChannels, sharedMinimumTime, sharedMaximumTime,
			sharedNumberOfSamples, sharedSamplingPeriod, sharedTimeOfFirstSample);
		long channelNumber = 0;
		for (long isound = 1; isound <= my size; isound ++) {
			Sound sound = (Sound) my item [isound];
			long offset = (long) floor (numberOfInitialZeroes [isound]);
			for (long ichan = 1; ichan <= sound -> ny; ichan ++) {
				channelNumber ++;
				for (long isamp = 1; isamp <= sound -> nx; isamp ++) {
					thy z [channelNumber] [isamp + offset] = sound -> z [ichan] [isamp];
				}
			}
		}
		return thee.transfer();
	} catch (MelderError) {
		Melder_throw (U"Sounds not combined to stereo.");
	}
}
autoSound BandFilterSpectrogram_as_Sound (BandFilterSpectrogram me, int unit) {
	try {
		autoSound thee = Sound_create (my ny, my xmin, my xmax, my nx, my dx, my x1);
		for (long i = 1; i <= my ny; i ++) {
			for (long j = 1; j <= my nx; j ++)
				thy z[i][j] = my v_getValueAtSample (j, i, unit);
		}
		return thee;
	} catch (MelderError) {
		Melder_throw (me, U": no Sound created.");
	}
}
Esempio n. 14
0
Sound Sound_extractChannel (Sound me, long ichan) {
	Sound thee = NULL;
//start:
	if (ichan <= 0 || ichan > my ny) error3 (L"Cannot extract channel ", Melder_integer (ichan), L".");
	thee = Sound_create (1, my xmin, my xmax, my nx, my dx, my x1); cherror
	for (long isamp = 1; isamp <= my nx; isamp ++) {
		thy z [1] [isamp] = my z [ichan] [isamp];
	}
end:
	iferror forget (thee);
	return thee;
}
Esempio n. 15
0
Sound FilterBank_as_Sound (FilterBank me) {
	try {
		autoSound thee = Sound_create (my ny, my xmin, my xmax, my nx, my dx, my x1);
		for (long i = 1; i <= my ny; i++) {
			for (long j = 1; j <= my nx; j++)
				thy z[i][j] = my z[i][j];
		}
		return thee.transfer();
	} catch (MelderError) {
		Melder_throw (me, ": no Sound created.");
	}
}
Esempio n. 16
0
Sound Matrix_to_Sound_mono (Matrix me, long row) {
	try {
		autoSound thee = Sound_create (1, my xmin, my xmax, my nx, my dx, my x1);
		if (row < 0) row = my ny + 1 + row;
		if (row < 1) row = 1;
		if (row > my ny) row = my ny;
		NUMvector_copyElements (my z [row], thy z [1], 1, my nx);
		return thee.transfer();
	} catch (MelderError) {
		Melder_throw (me, U": not converted to Sound.");
	}
}
Esempio n. 17
0
Sound Sound_extractChannel (Sound me, long ichan) {
	try {
		if (ichan <= 0 || ichan > my ny)
			Melder_throw (U"There is no channel ", ichan, U".");
		autoSound thee = Sound_create (1, my xmin, my xmax, my nx, my dx, my x1);
		for (long isamp = 1; isamp <= my nx; isamp ++) {
			thy z [1] [isamp] = my z [ichan] [isamp];
		}
		return thee.transfer();
	} catch (MelderError) {
		Melder_throw (me, U": channel ", ichan, U" not extracted.");
	}
}
Esempio n. 18
0
static autoSound buffer_to_Sound (int *wav, long numberOfSamples, double samplingFrequency)
{
	try {
		double dx = 1.0 / samplingFrequency;
		double xmax = numberOfSamples * dx;
		autoSound thee = Sound_create (1, 0.0, xmax, numberOfSamples, dx, dx / 2.0);
		for (long i = 1; i <= numberOfSamples; i++) {
			thy z[1][i] = wav[i] / 32768.0;
		}
		return thee;
	} catch (MelderError) {
		Melder_throw (U"Sound not created from synthesizer data.");
	}
}
Esempio n. 19
0
autoPitch Pitch_smooth (Pitch me, double bandWidth) {
	try {
		autoPitch interp = Pitch_interpolate (me);
		autoMatrix matrix1 = Pitch_to_Matrix (interp.peek());
		autoSound sound1 = Sound_create (1, 2 * matrix1->xmin - matrix1->xmax, 2 * matrix1->xmax - matrix1->xmin,
			3 * matrix1->nx, matrix1->dx, matrix1->x1 - 2 * matrix1->nx * matrix1->dx);

		long firstVoiced = 0, lastVoiced = 0;
		for (long i = 1; i <= matrix1 -> nx; i ++) {
			double f = matrix1 -> z [1] [i];
			if (f != 0.0) {
				if (! firstVoiced) firstVoiced = i;
				lastVoiced = i;
				sound1 -> z [1] [i + matrix1 -> nx] = f;
			}
		}

		/* Extrapolate. */
		double fextrap = matrix1 -> z [1] [firstVoiced];
		firstVoiced += matrix1 -> nx;
		for (long i = 1; i < firstVoiced; i ++)
			sound1 -> z [1] [i] = fextrap;
		fextrap = matrix1 -> z [1] [lastVoiced];
		lastVoiced += matrix1 -> nx;
		for (long i = lastVoiced + 1; i <= sound1 -> nx; i ++)
			sound1 -> z [1] [i] = fextrap;

		/* Smooth. */
		autoSpectrum spectrum = Sound_to_Spectrum (sound1.peek(), true);
		for (long i = 1; i <= spectrum -> nx; i ++) {
			double f = (i - 1) * spectrum -> dx, fT = f / bandWidth, factor = exp (- fT * fT);
			spectrum -> z [1] [i] *= factor;
			spectrum -> z [2] [i] *= factor;
		}
		autoSound sound2 = Spectrum_to_Sound (spectrum.peek());

		autoMatrix matrix2 = Matrix_create (my xmin, my xmax, my nx, my dx, my x1, 1, 1, 1, 1, 1);
		for (long i = 1; i <= my nx; i ++) {
			double originalF0 = my frame [i]. candidate [1]. frequency;
			matrix2 -> z [1] [i] = originalF0 > 0.0 && originalF0 < my ceiling ?
				sound2 -> z [1] [i + matrix2 -> nx] : 0.0;
		}
		autoPitch thee = Matrix_to_Pitch (matrix2.peek());
		thy ceiling = my ceiling;
		return thee;
	} catch (MelderError) {
		Melder_throw (me, U": not smoothed.");
	}
}
Esempio n. 20
0
Sound Sound_convertToStereo (Sound me) {
	if (my ny == 2) return (structSound *)Data_copy (me);
	if (my ny > 2) {
		return (structSound *)Melder_errorp ("Don't know how to convert a Sound with %ld channels to stereo.", my ny);
	}
	Sound thee = NULL;
	Melder_assert (my ny == 1);
	thee = Sound_create (2, my xmin, my xmax, my nx, my dx, my x1); cherror
	for (long i = 1; i <= my nx; i ++) {
		thy z [1] [i] = thy z [2] [i] = my z [1] [i];
	}
end:
	iferror forget (thee);
	return thee;
}
Esempio n. 21
0
Sound Sound_convertToStereo (Sound me) {
	if (my ny == 2) return Data_copy (me);
	try {
		if (my ny > 2) {
			Melder_throw (U"The Sound has ", my ny, U" channels; don't know which to choose.");
		}
		Melder_assert (my ny == 1);
		autoSound thee = Sound_create (2, my xmin, my xmax, my nx, my dx, my x1);
		for (long i = 1; i <= my nx; i ++) {
			thy z [1] [i] = thy z [2] [i] = my z [1] [i];
		}
		return thee.transfer();
	} catch (MelderError) {
		Melder_throw (me, U": not converted to stereo.");
	}
}
Esempio n. 22
0
autoSound LongSound_extractPart (LongSound me, double tmin, double tmax, int preserveTimes) {
	try {
		if (tmax <= tmin) { tmin = my xmin; tmax = my xmax; }
		if (tmin < my xmin) tmin = my xmin;
		if (tmax > my xmax) tmax = my xmax;
		long imin, imax;
		long n = Sampled_getWindowSamples (me, tmin, tmax, & imin, & imax);
		if (n < 1) Melder_throw (U"Less than 1 sample in window.");
		autoSound thee = Sound_create (my numberOfChannels, tmin, tmax, n, my dx, my x1 + (imin - 1) * my dx);
		if (! preserveTimes) thy xmin = 0.0, thy xmax -= tmin, thy x1 -= tmin;
		LongSound_readAudioToFloat (me, thy z, imin, n);
		return thee;
	} catch (MelderError) {
		Melder_throw (me, U": Sound not extracted.");
	}
}
Esempio n. 23
0
Sound Sound_extractPart (Sound me, double t1, double t2, enum kSound_windowShape windowShape, double relativeWidth, bool preserveTimes) {
	try {
		/*
		 * We do not clip to the Sound's time domain.
		 * Any samples outside it are taken to be zero.
		 */

		/*
		 * Autowindow.
		 */
		if (t1 == t2) { t1 = my xmin; t2 = my xmax; };
		/*
		 * Allow window tails outside specified domain.
		 */
		if (relativeWidth != 1.0) {
			double margin = 0.5 * (relativeWidth - 1) * (t2 - t1);
			t1 -= margin;
			t2 += margin;
		}
		/*
		 * Determine index range. We use all the real or virtual samples that fit within [t1..t2].
		 */
		long ix1 = 1 + (long) ceil ((t1 - my x1) / my dx);
		long ix2 = 1 + (long) floor ((t2 - my x1) / my dx);
		if (ix2 < ix1) Melder_throw (U"Extracted Sound would contain no samples.");
		/*
		 * Create sound, optionally shifted to [0..t2-t1].
		 */
		autoSound thee = Sound_create (my ny, t1, t2, ix2 - ix1 + 1, my dx, my x1 + (ix1 - 1) * my dx);
		if (! preserveTimes) { thy xmin = 0.0; thy xmax -= t1; thy x1 -= t1; }
		/*
		 * Copy only *real* samples into the new sound.
		 * The *virtual* samples will remain at zero.
		 */
		for (long channel = 1; channel <= my ny; channel ++) {
			NUMvector_copyElements (my z [channel], thy z [channel] + 1 - ix1,
					( ix1 < 1 ? 1 : ix1 ), ( ix2 > my nx ? my nx : ix2 ));
		}
		/*
		 * Multiply by a window that extends throughout the target domain.
		 */
		Sound_multiplyByWindow (thee.peek(), windowShape);
		return thee.transfer();
	} catch (MelderError) {
		Melder_throw (me, U": part not extracted.");
	}
}
Esempio n. 24
0
Sound Sound_createFromToneComplex (double startingTime, double endTime, double sampleRate,
	int phase, double frequencyStep, double firstFrequency, double ceiling, long numberOfComponents)
{
	try {
		if (frequencyStep == 0.0)
			Melder_throw (U"Frequency step must not be zero.");
		/*
		 * Translate default firstFrequency.
		 */
		if (firstFrequency <= 0.0) firstFrequency = frequencyStep;
		double firstOmega = 2 * NUMpi * firstFrequency;
		/*
		 * Translate default ceiling.
		 */
		double omegaStep = 2 * NUMpi * frequencyStep, nyquistFrequency = 0.5 * sampleRate;
		if (ceiling <= 0.0 || ceiling > nyquistFrequency) ceiling = nyquistFrequency;
		/*
		 * Translate number of components.
		 */
		long maximumNumberOfComponents = (long) floor ((ceiling - firstFrequency) / frequencyStep) + 1;
		if (numberOfComponents <= 0 || numberOfComponents > maximumNumberOfComponents)
			numberOfComponents = maximumNumberOfComponents;
		if (numberOfComponents < 1)
			Melder_throw (U"Zero sine waves.");
		/*
		 * Generate the Sound.
		 */
		double factor = 0.99 / numberOfComponents;
		autoSound me = Sound_create (1, startingTime, endTime, lround ((endTime - startingTime) * sampleRate),
			1 / sampleRate, startingTime + 0.5 / sampleRate);
		double *amplitude = my z [1];
		for (long isamp = 1; isamp <= my nx; isamp ++) {
			double value = 0.0, t = Sampled_indexToX (me.peek(), isamp);
			double omegaStepT = omegaStep * t, firstOmegaT = firstOmega * t;
			if (phase == Sound_TONE_COMPLEX_SINE)
				for (long icomp = 1; icomp <= numberOfComponents; icomp ++)
					value += sin (firstOmegaT + (icomp - 1) * omegaStepT);
			else
				for (long icomp = 1; icomp <= numberOfComponents; icomp ++)
					value += cos (firstOmegaT + (icomp - 1) * omegaStepT);
			amplitude [isamp] = value * factor;
		}
		return me.transfer();
	} catch (MelderError) {
		Melder_throw (U"Sound not created from tone complex.");
	}
}
Esempio n. 25
0
Sound Sounds_append (Sound me, double silenceDuration, Sound thee) {
	try {
		long nx_silence = lround (silenceDuration / my dx), nx = my nx + nx_silence + thy nx;
		if (my ny != thy ny)
			Melder_throw (U"The numbers of channels are not equal (e.g. one is mono, the other stereo).");
		if (my dx != thy dx)
			Melder_throw (U"The sampling frequencies are not equal.");
		autoSound him = Sound_create (my ny, 0, nx * my dx, nx, my dx, 0.5 * my dx);
		for (long channel = 1; channel <= my ny; channel ++) {
			NUMvector_copyElements (my z [channel], his z [channel], 1, my nx);
			NUMvector_copyElements (thy z [channel], his z [channel] + my nx + nx_silence, 1, thy nx);
		}
		return him.transfer();
	} catch (MelderError) {
		Melder_throw (me, U" & ", thee, U": not appended.");
	}
}
Spectrum Cepstrum_to_Spectrum (Cepstrum me) {
	try {
		autoSound x = Sound_create (1, my xmin, my xmax, my nx, my dx, my x1);
		NUMvector_copyElements	(my z[1], x -> z[1], 1, my nx);
		autoSpectrum thee = Sound_to_Spectrum (x.peek(), TRUE);

		for (long i = 1; i <= thy nx; i++) {
			double ar = exp (thy z[1][i]);
			double ai = thy z[2][i];

			thy z[1][i] = ar * cos (ai);
			thy z[2][i] = ar * sin (ai);
		}
		return thee.transfer();
	} catch (MelderError) {
		Melder_throw (me, ": no Spectrum created.");
	}
}
Esempio n. 27
0
Sound PointProcess_to_Sound_pulseTrain
	(PointProcess me, double samplingFrequency,
	 double adaptFactor, double adaptTime, long interpolationDepth)
{
	try {
		long sound_nt = 1 + floor ((my xmax - my xmin) * samplingFrequency);   // >= 1
		double dt = 1.0 / samplingFrequency;
		double tmid = (my xmin + my xmax) / 2;
		double t1 = tmid - 0.5 * (sound_nt - 1) * dt;
		autoSound thee = Sound_create (1, my xmin, my xmax, sound_nt, dt, t1);
		double *sound = thy z [1];
		for (long it = 1; it <= my nt; it ++) {
			double t = my t [it], amplitude = 0.9, angle, halfampsinangle;
			long mid = Sampled_xToNearestIndex (thee.peek(), t);
			if (it <= 2 || my t [it - 2] < my t [it] - adaptTime) {
				amplitude *= adaptFactor;
				if (it == 1 || my t [it - 1] < my t [it] - adaptTime)
					amplitude *= adaptFactor;
			}
			long begin = mid - interpolationDepth, end = mid + interpolationDepth;
			if (begin < 1) begin = 1;
			if (end > thy nx) end = thy nx;
			angle = NUMpi * (Sampled_indexToX (thee.peek(), begin) - t) / thy dx;
			halfampsinangle = 0.5 * amplitude * sin (angle);
			for (long j = begin; j <= end; j ++) {
				if (fabs (angle) < 1e-6)
					sound [j] += amplitude;
				else if (angle < 0.0)
					sound [j] += halfampsinangle *
						(1 + cos (angle / (mid - begin + 1))) / angle;
				else
					sound [j] += halfampsinangle *
						(1 + cos (angle / (end - mid + 1))) / angle;
				angle += NUMpi;
				halfampsinangle = - halfampsinangle;
			}
		}
		return thee.transfer();
	} catch (MelderError) {
		Melder_throw (me, ": pulse train not synthesized.");
	}
}
Esempio n. 28
0
static ERPTier EEG_PointProcess_to_ERPTier (EEG me, PointProcess events, double fromTime, double toTime) {
	try {
		autoERPTier thee = Thing_new (ERPTier);
		Function_init (thee.peek(), fromTime, toTime);
		thy numberOfChannels = my numberOfChannels - EEG_getNumberOfExtraSensors (me);
		Melder_assert (thy numberOfChannels > 0);
		thy channelNames = NUMvector <wchar_t *> (1, thy numberOfChannels);
		for (long ichan = 1; ichan <= thy numberOfChannels; ichan ++) {
			thy channelNames [ichan] = Melder_wcsdup (my channelNames [ichan]);
		}
		long numberOfEvents = events -> nt;
		thy events = SortedSetOfDouble_create ();
		double soundDuration = toTime - fromTime;
		double samplingPeriod = my sound -> dx;
		long numberOfSamples = floor (soundDuration / samplingPeriod) + 1;
		if (numberOfSamples < 1)
			Melder_throw (L"Time window too short.");
		double midTime = 0.5 * (fromTime + toTime);
		double soundPhysicalDuration = numberOfSamples * samplingPeriod;
		double firstTime = midTime - 0.5 * soundPhysicalDuration + 0.5 * samplingPeriod;   // distribute the samples evenly over the time domain
		for (long ievent = 1; ievent <= numberOfEvents; ievent ++) {
			double eegEventTime = events -> t [ievent];
			autoERPPoint event = Thing_new (ERPPoint);
			event -> number = eegEventTime;
			event -> erp = Sound_create (thy numberOfChannels, fromTime, toTime, numberOfSamples, samplingPeriod, firstTime);
			double erpEventTime = 0.0;
			double eegSample = 1 + (eegEventTime - my sound -> x1) / samplingPeriod;
			double erpSample = 1 + (erpEventTime - firstTime) / samplingPeriod;
			long sampleDifference = round (eegSample - erpSample);
			for (long ichannel = 1; ichannel <= thy numberOfChannels; ichannel ++) {
				for (long isample = 1; isample <= numberOfSamples; isample ++) {
					long jsample = isample + sampleDifference;
					event -> erp -> z [ichannel] [isample] = jsample < 1 || jsample > my sound -> nx ? 0.0 : my sound -> z [ichannel] [jsample];
				}
			}
			Collection_addItem (thy events, event.transfer());
		}
		return thee.transfer();
	} catch (MelderError) {
		Melder_throw (me, ": ERP analysis not performed.");
	}
}
Esempio n. 29
0
autoSound Sound_and_MixingMatrix_mix (Sound me, MixingMatrix thee) {
	try {
		if (my ny != thy numberOfColumns) {
			Melder_throw (U"The number of components in the MixingMatrix and the number of channels in the Sound must be equal.");
		}
		autoSound him = Sound_create (thy numberOfRows, my xmin, my xmax, my nx, my dx, my x1);
		for (long i = 1; i <= thy numberOfRows; i++) {
			for (long j = 1; j <= my nx; j++) {
				double mix = 0;
				for (long k = 1; k <= my ny; k++) {
					mix += thy data[i][k] * my z[k][j];
				}
				his z[i][j] = mix;
			}
		}
		return him;
	} catch (MelderError) {
		Melder_throw (me, U": not mixed.");
	}
}
Esempio n. 30
0
autoSound PitchTier_to_Sound_sine (PitchTier me, double tmin, double tmax, double samplingFrequency) {
	try {
		if (tmax <= tmin) tmin = my xmin, tmax = my xmax;
		long numberOfSamples = 1 + (long) floor ((my xmax - my xmin) * samplingFrequency);   // >= 1
		double samplingPeriod = 1.0 / samplingFrequency;
		double tmid = (tmin + tmax) / 2.0;
		double t1 = tmid - 0.5 * (numberOfSamples - 1) * samplingPeriod;
		autoSound thee = Sound_create (1, tmin, tmax, numberOfSamples, samplingPeriod, t1);
		double phase = 0.0;
		for (long isamp = 2; isamp <= numberOfSamples; isamp ++) {
			double tleft = t1 + (isamp - 1.5) * samplingPeriod;
			double fleft = RealTier_getValueAtTime (me, tleft);
			phase += fleft * thy dx;
			thy z [1] [isamp] = 0.5 * sin (2.0 * NUMpi * phase);
		}
		return thee;
	} catch (MelderError) {
		Melder_throw (me, U": not converted to Sound (sine).");
	}
}