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); }
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); } }
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); } }
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); } }
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."); } }
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); }