예제 #1
0
static void menu_cb_MoveCursorToZero (SoundEditor me, EDITOR_ARGS_DIRECT) {
	double zero = Sound_getNearestZeroCrossing ((Sound) my data, 0.5 * (my d_startSelection + my d_endSelection), 1);   // STEREO BUG
	if (NUMdefined (zero)) {
		my d_startSelection = my d_endSelection = zero;
		FunctionEditor_marksChanged (me, true);
	}
}
static void menu_cb_moveCursorToPeak (EDITOR_ARGS) {
	EDITOR_IAM (SpectrumEditor);
	double frequencyOfMaximum, heightOfMaximum;
	Spectrum_getNearestMaximum ((Spectrum) my data, 0.5 * (my d_startSelection + my d_endSelection), & frequencyOfMaximum, & heightOfMaximum);
	my d_startSelection = my d_endSelection = frequencyOfMaximum;
	my cursorHeight = heightOfMaximum;
	FunctionEditor_marksChanged (me, true);
}
예제 #3
0
static void menu_cb_MoveEtoZero (SoundEditor me, EDITOR_ARGS_DIRECT) {
	double zero = Sound_getNearestZeroCrossing ((Sound) my data, my d_endSelection, 1);   // STEREO BUG
	if (NUMdefined (zero)) {
		my d_endSelection = zero;
		if (my d_startSelection > my d_endSelection) {
			double dummy = my d_startSelection;
			my d_startSelection = my d_endSelection;
			my d_endSelection = dummy;
		}
		FunctionEditor_marksChanged (me, true);
	}
}
예제 #4
0
void SoundEditor_init (SoundEditor me, const char32 *title, Sampled data) {
	/*
	 * my longSound.data or my sound.data have to be set before we call FunctionEditor_init,
	 * because createMenus expects that one of them is not null.
	 */
	TimeSoundAnalysisEditor_init (me, title, data, data, false);
	if (my d_longSound.data && my d_endWindow - my d_startWindow > 30.0) {
		my d_endWindow = my d_startWindow + 30.0;
		if (my d_startWindow == my tmin)
			my d_startSelection = my d_endSelection = 0.5 * (my d_startWindow + my d_endWindow);
		FunctionEditor_marksChanged (me, false);
	}
}
예제 #5
0
void structSoundEditor :: f_init (const wchar_t *title, Sampled data) {
	/*
	 * my longSound.data or my sound.data have to be set before we call FunctionEditor_init,
	 * because createMenus expect that one of them is not NULL.
	 */
	structTimeSoundAnalysisEditor :: f_init (title, data, data, false);
	if (d_longSound.data && d_endWindow - d_startWindow > 30.0) {
		d_endWindow = d_startWindow + 30.0;
		if (d_startWindow == d_tmin)
			d_startSelection = d_endSelection = 0.5 * (d_startWindow + d_endWindow);
		FunctionEditor_marksChanged (this);
	}
}
예제 #6
0
static void menu_cb_Cut (SoundEditor me, EDITOR_ARGS_DIRECT) {
	try {
		Sound sound = (Sound) my data;
		long first, last, selectionNumberOfSamples = Sampled_getWindowSamples (sound,
			my d_startSelection, my d_endSelection, & first, & last);
		long oldNumberOfSamples = sound -> nx;
		long newNumberOfSamples = oldNumberOfSamples - selectionNumberOfSamples;
		if (newNumberOfSamples < 1)
			Melder_throw (U"You cannot cut all of the signal away,\n"
				U"because you cannot create a Sound with 0 samples.\n"
				U"You could consider using Copy instead.");
		if (selectionNumberOfSamples) {
			double **oldData = sound -> z;
			/*
			 * Create without change.
			 */
			autoSound publish = Sound_create (sound -> ny, 0.0, selectionNumberOfSamples * sound -> dx,
							selectionNumberOfSamples, sound -> dx, 0.5 * sound -> dx);
			for (long channel = 1; channel <= sound -> ny; channel ++) {
				long j = 0;
				for (long i = first; i <= last; i ++) {
					publish -> z [channel] [++ j] = oldData [channel] [i];
				}
			}
			autoNUMmatrix <double> newData (1, sound -> ny, 1, newNumberOfSamples);
			for (long channel = 1; channel <= sound -> ny; channel ++) {
				long j = 0;
				for (long i = 1; i < first; i ++) {
					newData [channel] [++ j] = oldData [channel] [i];
				}
				for (long i = last + 1; i <= oldNumberOfSamples; i ++) {
					newData [channel] [++ j] = oldData [channel] [i];
				}
			}
			Editor_save (me, U"Cut");
			/*
			 * Change without error.
			 */
			NUMmatrix_free <double> (oldData, 1, 1);
			sound -> xmin = 0.0;
			sound -> xmax = newNumberOfSamples * sound -> dx;
			sound -> nx = newNumberOfSamples;
			sound -> x1 = 0.5 * sound -> dx;
			sound -> z = newData.transfer();
			Sound_clipboard = publish.move();

			/* Start updating the markers of the FunctionEditor, respecting the invariants. */

			my tmin = sound -> xmin;
			my tmax = sound -> xmax;

			/* Collapse the selection, */
			/* so that the Cut operation can immediately be undone by a Paste. */
			/* The exact position will be half-way in between two samples. */

			my d_startSelection = my d_endSelection = sound -> xmin + (first - 1) * sound -> dx;

			/* Update the window. */
			{
				double t1 = (first - 1) * sound -> dx;
				double t2 = last * sound -> dx;
				double windowLength = my d_endWindow - my d_startWindow;   // > 0
				if (t1 > my d_startWindow)
					if (t2 < my d_endWindow)
						my d_startWindow -= 0.5 * (t2 - t1);
					else
						(void) 0;
				else if (t2 < my d_endWindow)
					my d_startWindow -= t2 - t1;
				else   /* Cut overlaps entire window: centre. */
					my d_startWindow = my d_startSelection - 0.5 * windowLength;
				my d_endWindow = my d_startWindow + windowLength;   // first try
				if (my d_endWindow > my tmax) {
					my d_startWindow -= my d_endWindow - my tmax;   // second try
					if (my d_startWindow < my tmin)
						my d_startWindow = my tmin;   // third try
					my d_endWindow = my tmax;   // second try
				} else if (my d_startWindow < my tmin) {
					my d_endWindow -= my d_startWindow - my tmin;   // second try
					if (my d_endWindow > my tmax)
						my d_endWindow = my tmax;   // third try
					my d_startWindow = my tmin;   // second try
				}
			}

			/* Force FunctionEditor to show changes. */

			Matrix_getWindowExtrema (sound, 1, sound -> nx, 1, sound -> ny, & my d_sound.minimum, & my d_sound.maximum);
			my v_reset_analysis ();
			FunctionEditor_ungroup (me);
			FunctionEditor_marksChanged (me, false);
			Editor_broadcastDataChanged (me);
		} else {
			Melder_warning (U"No samples selected.");
		}
	} catch (MelderError) {
		Melder_throw (U"Sound selection not cut to clipboard.");
	}
}
예제 #7
0
static void menu_cb_Paste (SoundEditor me, EDITOR_ARGS_DIRECT) {
	Sound sound = (Sound) my data;
	long leftSample = Sampled_xToLowIndex (sound, my d_endSelection);
	long oldNumberOfSamples = sound -> nx, newNumberOfSamples;
	double **oldData = sound -> z;
	if (! Sound_clipboard) {
		Melder_warning (U"Clipboard is empty; nothing pasted.");
		return;
	}
	if (Sound_clipboard -> ny != sound -> ny)
		Melder_throw (U"Cannot paste, because\n"
			U"the number of channels of the clipboard is not equal to\n"
			U"the number of channels of the edited sound.");
	if (Sound_clipboard -> dx != sound -> dx)
		Melder_throw (U"Cannot paste, because\n"
			U"the sampling frequency of the clipboard is not equal to\n"
			U"the sampling frequency of the edited sound.");
	if (leftSample < 0) leftSample = 0;
	if (leftSample > oldNumberOfSamples) leftSample = oldNumberOfSamples;
	newNumberOfSamples = oldNumberOfSamples + Sound_clipboard -> nx;
	/*
	 * Check without change.
	 */
	autoNUMmatrix <double> newData (1, sound -> ny, 1, newNumberOfSamples);
	for (long channel = 1; channel <= sound -> ny; channel ++) {
		long j = 0;
		for (long i = 1; i <= leftSample; i ++) {
			newData [channel] [++ j] = oldData [channel] [i];
		}
		for (long i = 1; i <= Sound_clipboard -> nx; i ++) {
			newData [channel] [++ j] = Sound_clipboard -> z [channel] [i];
		}
		for (long i = leftSample + 1; i <= oldNumberOfSamples; i ++) {
			newData [channel] [++ j] = oldData [channel] [i];
		}
	}
	Editor_save (me, U"Paste");
	/*
	 * Change without error.
	 */
	NUMmatrix_free <double> (oldData, 1, 1);
	sound -> xmin = 0.0;
	sound -> xmax = newNumberOfSamples * sound -> dx;
	sound -> nx = newNumberOfSamples;
	sound -> x1 = 0.5 * sound -> dx;
	sound -> z = newData.transfer();

	/* Start updating the markers of the FunctionEditor, respecting the invariants. */

	my tmin = sound -> xmin;
	my tmax = sound -> xmax;
	my d_startSelection = leftSample * sound -> dx;
	my d_endSelection = (leftSample + Sound_clipboard -> nx) * sound -> dx;

	/* Force FunctionEditor to show changes. */

	Matrix_getWindowExtrema (sound, 1, sound -> nx, 1, sound -> ny, & my d_sound.minimum, & my d_sound.maximum);
	my v_reset_analysis ();
	FunctionEditor_ungroup (me);
	FunctionEditor_marksChanged (me, false);
	Editor_broadcastDataChanged (me);
}