void structPointEditor :: v_draw () { PointProcess point = (PointProcess) data; Sound sound = d_sound.data; Graphics_setColour (d_graphics, Graphics_WHITE); Graphics_setWindow (d_graphics, 0, 1, 0, 1); Graphics_fillRectangle (d_graphics, 0, 1, 0, 1); double minimum = -1.0, maximum = +1.0; if (sound != NULL && (d_sound.scalingStrategy == kTimeSoundEditor_scalingStrategy_BY_WINDOW || d_sound.scalingStrategy == kTimeSoundEditor_scalingStrategy_BY_WINDOW_AND_CHANNEL)) { long first, last; if (Sampled_getWindowSamples (sound, d_startWindow, d_endWindow, & first, & last) >= 1) { Matrix_getWindowExtrema (sound, first, last, 1, 1, & minimum, & maximum); } } Graphics_setWindow (d_graphics, d_startWindow, d_endWindow, minimum, maximum); Graphics_setColour (d_graphics, Graphics_BLACK); if (sound != NULL) { long first, last; if (Sampled_getWindowSamples (sound, d_startWindow, d_endWindow, & first, & last) > 1) { Graphics_setLineType (d_graphics, Graphics_DOTTED); Graphics_line (d_graphics, d_startWindow, 0.0, d_endWindow, 0.0); Graphics_setLineType (d_graphics, Graphics_DRAWN); Graphics_function (d_graphics, sound -> z [1], first, last, Sampled_indexToX (sound, first), Sampled_indexToX (sound, last)); } } Graphics_setColour (d_graphics, Graphics_BLUE); Graphics_setWindow (d_graphics, d_startWindow, d_endWindow, -1.0, +1.0); for (long i = 1; i <= point -> nt; i ++) { double t = point -> t [i]; if (t >= d_startWindow && t <= d_endWindow) Graphics_line (d_graphics, t, -0.9, t, +0.9); } Graphics_setColour (d_graphics, Graphics_BLACK); v_updateMenuItems_file (); }
void structTimeSoundEditor :: v_updateMenuItems_file () { Sampled sound; if (d_sound.data) { sound = d_sound.data; } else { sound = d_longSound.data; } if (! sound) return; long first, last, selectedSamples = Sampled_getWindowSamples (sound, d_startSelection, d_endSelection, & first, & last); if (drawButton) { GuiThing_setSensitive (drawButton, selectedSamples != 0); GuiThing_setSensitive (publishButton, selectedSamples != 0); GuiThing_setSensitive (publishPreserveButton, selectedSamples != 0); if (publishWindowButton) GuiThing_setSensitive (publishWindowButton, selectedSamples != 0); if (publishOverlapButton) GuiThing_setSensitive (publishOverlapButton, selectedSamples != 0); } GuiThing_setSensitive (writeWavButton, selectedSamples != 0); if (d_saveAs24BitWavButton) GuiThing_setSensitive (d_saveAs24BitWavButton, selectedSamples != 0); if (d_saveAs32BitWavButton) GuiThing_setSensitive (d_saveAs32BitWavButton, selectedSamples != 0); GuiThing_setSensitive (writeAiffButton, selectedSamples != 0); GuiThing_setSensitive (writeAifcButton, selectedSamples != 0); GuiThing_setSensitive (writeNextSunButton, selectedSamples != 0); GuiThing_setSensitive (writeNistButton, selectedSamples != 0); GuiThing_setSensitive (writeFlacButton, selectedSamples != 0); }
double Vector_getStandardDeviation (Vector me, double xmin, double xmax, long ilevel) { if (xmax <= xmin) { xmin = my xmin; xmax = my xmax; } long imin, imax, n = Sampled_getWindowSamples (me, xmin, xmax, & imin, & imax); if (n < 2) return NUMundefined; if (ilevel == Vector_CHANNEL_AVERAGE) { double sum2 = 0.0; for (long channel = 1; channel <= my ny; channel ++) { double mean = Vector_getMean (me, xmin, xmax, channel); for (long i = imin; i <= imax; i ++) { double diff = my z [channel] [i] - mean; sum2 += diff * diff; } } return sqrt (sum2 / (n * my ny - my ny)); // The number of constraints equals the number of channels, // because from every channel its own mean was subtracted. // Corollary: a two-channel mono sound will have the same stdev as the corresponding one-channel sound. } double mean = Vector_getMean (me, xmin, xmax, ilevel); double sum2 = 0.0; for (long i = imin; i <= imax; i ++) { double diff = my z [ilevel] [i] - mean; sum2 += diff * diff; } return sqrt (sum2 / (n - 1)); }
void Formant_drawTracks (Formant me, Graphics g, double tmin, double tmax, double fmax, int garnish) { long itmin, itmax, ntrack = Formant_getMinNumFormants (me); if (tmax <= tmin) { tmin = my xmin; tmax = my xmax; } if (! Sampled_getWindowSamples (me, tmin, tmax, & itmin, & itmax)) return; Graphics_setInner (g); Graphics_setWindow (g, tmin, tmax, 0.0, fmax); for (long itrack = 1; itrack <= ntrack; itrack ++) { for (long iframe = itmin; iframe < itmax; iframe ++) { Formant_Frame curFrame = & my d_frames [iframe], nextFrame = & my d_frames [iframe + 1]; double x1 = Sampled_indexToX (me, iframe), x2 = Sampled_indexToX (me, iframe + 1); double f1 = curFrame -> formant [itrack]. frequency; double f2 = nextFrame -> formant [itrack]. frequency; if (NUMdefined (x1) && NUMdefined (f1) && NUMdefined (x2) && NUMdefined (f2)) Graphics_line (g, x1, f1, x2, f2); } } Graphics_unsetInner (g); if (garnish) { Graphics_drawInnerBox (g); Graphics_textBottom (g, 1, U"Time (s)"); Graphics_textLeft (g, 1, U"Formant frequency (Hz)"); Graphics_marksBottom (g, 2, 1, 1, 0); Graphics_marksLeftEvery (g, 1.0, 1000.0, 1, 1, 1); } }
void CC_drawC0 (I, Graphics g, double xmin, double xmax, double ymin, double ymax, int garnish) { iam (CC); (void) garnish; if (xmin >= xmax) { xmin = my xmin; xmax = my xmax; } long bframe, eframe; (void) Sampled_getWindowSamples (me, xmin, xmax, &bframe, &eframe); autoNUMvector<double> c (bframe, eframe); for (long i = bframe; i <= eframe; i++) { CC_Frame cf = & my frame[i]; c[i] = cf -> c0; } if (ymin >= ymax) { NUMvector_extrema (c.peek(), bframe, eframe, &ymin, &ymax); if (ymax <= ymin) { ymin -= 1.0; ymax += 1.0; } } else { NUMvector_clip (c.peek(), bframe, eframe, ymin, ymax); } Graphics_setInner (g); Graphics_setWindow (g, xmin, xmax, ymin, ymax); Graphics_function (g, c.peek(), bframe, eframe, xmin, xmax); Graphics_unsetInner (g); }
void Formant_drawSpeckles_inside (Formant me, Graphics g, double tmin, double tmax, double fmin, double fmax, double suppress_dB) { long itmin, itmax; double maximumIntensity = 0.0, minimumIntensity; if (tmax <= tmin) { tmin = my xmin; tmax = my xmax; } if (! Sampled_getWindowSamples (me, tmin, tmax, & itmin, & itmax)) return; Graphics_setWindow (g, tmin, tmax, fmin, fmax); for (long iframe = itmin; iframe <= itmax; iframe ++) { Formant_Frame frame = & my d_frames [iframe]; if (frame -> intensity > maximumIntensity) maximumIntensity = frame -> intensity; } if (maximumIntensity == 0.0 || suppress_dB <= 0.0) minimumIntensity = 0.0; /* Ignore. */ else minimumIntensity = maximumIntensity / pow (10.0, suppress_dB / 10.0); for (long iframe = itmin; iframe <= itmax; iframe ++) { Formant_Frame frame = & my d_frames [iframe]; double x = Sampled_indexToX (me, iframe); if (frame -> intensity < minimumIntensity) continue; for (long iformant = 1; iformant <= frame -> nFormants; iformant ++) { double frequency = frame -> formant [iformant]. frequency; if (frequency >= fmin && frequency <= fmax) Graphics_speckle (g, x, frequency); } } }
void Formant_scatterPlot (Formant me, Graphics g, double tmin, double tmax, int iformant1, double fmin1, double fmax1, int iformant2, double fmin2, double fmax2, double size_mm, const char32 *mark, int garnish) { if (iformant1 < 1 || iformant2 < 1) return; if (tmax <= tmin) { tmin = my xmin; tmax = my xmax; } long itmin, itmax; if (! Sampled_getWindowSamples (me, tmin, tmax, & itmin, & itmax)) return; if (fmax1 == fmin1) Formant_getExtrema (me, iformant1, tmin, tmax, & fmin1, & fmax1); if (fmax1 == fmin1) return; if (fmax2 == fmin2) Formant_getExtrema (me, iformant2, tmin, tmax, & fmin2, & fmax2); if (fmax2 == fmin2) return; Graphics_setInner (g); Graphics_setWindow (g, fmin1, fmax1, fmin2, fmax2); for (long iframe = itmin; iframe <= itmax; iframe ++) { Formant_Frame frame = & my d_frames [iframe]; if (iformant1 > frame -> nFormants || iformant2 > frame -> nFormants) continue; double x = frame -> formant [iformant1]. frequency; double y = frame -> formant [iformant2]. frequency; if (x == 0.0 || y == 0.0) continue; Graphics_mark (g, x, y, size_mm, mark); } Graphics_unsetInner (g); if (garnish) { Graphics_drawInnerBox (g); Graphics_textBottom (g, 1, Melder_cat (U"%%F_", iformant1, U" (Hz)")); Graphics_textLeft (g, 1, Melder_cat (U"%%F_", iformant2, U" (Hz)")); Graphics_marksBottom (g, 2, 1, 1, 0); Graphics_marksLeft (g, 2, 1, 1, 0); } }
void Pitch_step (Pitch me, double step, double precision, double tmin, double tmax) { Melder_assert (precision >= 0.0 && precision < 1.0); long imin, imax; if (! Sampled_getWindowSamples (me, tmin, tmax, & imin, & imax)) return; for (long i = imin; i <= imax; i ++) { Pitch_Frame frame = & my frame [i]; double currentFrequency = frame -> candidate [1]. frequency; if (currentFrequency > 0.0 && currentFrequency < my ceiling) { double targetFrequency = currentFrequency * step; double fmin = (1 - precision) * targetFrequency; double fmax = (1 + precision) * targetFrequency; int icand, nearestCandidate = 0; double nearestDistance = my ceiling; if (fmax > my ceiling) fmax = my ceiling; for (icand = 2; icand <= frame -> nCandidates; icand ++) { double f = frame -> candidate [icand]. frequency; if (f > fmin && f < fmax) { double localDistance = fabs (f - targetFrequency); if (localDistance < nearestDistance) { nearestCandidate = icand; nearestDistance = localDistance; } } } if (nearestCandidate) { /* Swap candidates. */ struct structPitch_Candidate candidate = frame -> candidate [nearestCandidate]; frame -> candidate [nearestCandidate] = frame -> candidate [1]; frame -> candidate [1] = candidate; } } } }
bool LongSound_haveWindow (LongSound me, double tmin, double tmax) { long imin, imax; long n = Sampled_getWindowSamples (me, tmin, tmax, & imin, & imax); if ((1.0 + 2 * MARGIN) * n + 1 > my nmax) return false; _LongSound_haveSamples (me, imin, imax); return true; }
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); } } }
void Ltas_fitTiltLine (Ltas me, double fmin, double fmax, bool lnf, int method, double *a, double *b) { try { if (fmax <= fmin) { fmin = my xmin; fmax = my xmax; } long ifmin, ifmax, numberOfSamples = Sampled_getWindowSamples (me, fmin, fmax, &ifmin, &ifmax); if (numberOfSamples < 2) { Melder_throw ("There must be at least two data points to fit a line."); } autoNUMvector<double> x (1, numberOfSamples); autoNUMvector<double> y (1, numberOfSamples); for (long i = ifmin; i <= ifmax; i++) { long ixy = i - ifmin + 1; x[ixy] = my x1 + (i - 1) * my dx; if (lnf) { // For Ltas always x1 > 0 x[ixy] = log10 (x[ixy]); } y[ixy] = my z[1][i]; } NUMlineFit (x.peek(), y.peek(), numberOfSamples, a, b, method); } catch (MelderError) { Melder_throw ("Tilt line not determined."); } }
void Sound_reverse (Sound me, double tmin, double tmax) { if (tmax <= tmin) { tmin = my xmin; tmax = my xmax; } // autowindowing long itmin, itmax; long n = Sampled_getWindowSamples (me, tmin, tmax, & itmin, & itmax) / 2; for (long channel = 1; channel <= my ny; channel ++) { double *amp = my z [channel]; for (long i = 0; i < n; i ++) { double dummy = amp [itmin + i]; amp [itmin + i] = amp [itmax - i]; amp [itmax - i] = dummy; } } }
static void menu_cb_SetSelectionToZero (SoundEditor me, EDITOR_ARGS_DIRECT) { Sound sound = (Sound) my data; long first, last; Sampled_getWindowSamples (sound, my d_startSelection, my d_endSelection, & first, & last); Editor_save (me, U"Set to zero"); for (long channel = 1; channel <= sound -> ny; channel ++) { for (long i = first; i <= last; i ++) { sound -> z [channel] [i] = 0.0; } } my v_reset_analysis (); FunctionEditor_redraw (me); Editor_broadcastDataChanged (me); }
void structPointEditor :: v_draw () { PointProcess point = static_cast <PointProcess> (our data); Sound sound = d_sound.data; Graphics_setColour (our graphics.get(), Graphics_WHITE); Graphics_setWindow (our graphics.get(), 0.0, 1.0, 0.0, 1.0); Graphics_fillRectangle (our graphics.get(), 0.0, 1.0, 0.0, 1.0); double minimum = -1.0, maximum = +1.0; if (sound && (p_sound_scalingStrategy == kTimeSoundEditor_scalingStrategy_BY_WINDOW || p_sound_scalingStrategy == kTimeSoundEditor_scalingStrategy_BY_WINDOW_AND_CHANNEL)) { long first, last; if (Sampled_getWindowSamples (sound, our startWindow, our endWindow, & first, & last) >= 1) { Matrix_getWindowExtrema (sound, first, last, 1, 1, & minimum, & maximum); if (minimum == maximum) minimum -= 1.0, maximum += 1.0; } } Graphics_setWindow (our graphics.get(), our startWindow, our endWindow, minimum, maximum); Graphics_setColour (our graphics.get(), Graphics_BLACK); if (sound) { long first, last; if (Sampled_getWindowSamples (sound, our startWindow, our endWindow, & first, & last) > 1) { Graphics_setLineType (our graphics.get(), Graphics_DOTTED); Graphics_line (our graphics.get(), our startWindow, 0.0, our endWindow, 0.0); Graphics_setLineType (our graphics.get(), Graphics_DRAWN); Graphics_function (our graphics.get(), sound -> z [1], first, last, Sampled_indexToX (sound, first), Sampled_indexToX (sound, last)); } } Graphics_setColour (our graphics.get(), Graphics_BLUE); Graphics_setWindow (our graphics.get(), our startWindow, our endWindow, -1.0, +1.0); for (long i = 1; i <= point -> nt; i ++) { double t = point -> t [i]; if (t >= our startWindow && t <= our endWindow) Graphics_line (our graphics.get(), t, -0.9, t, +0.9); } Graphics_setColour (our graphics.get(), Graphics_BLACK); v_updateMenuItems_file (); }
static double getSumOfSquares (Sound me, double xmin, double xmax, long *n) { if (xmax <= xmin) { xmin = my xmin; xmax = my xmax; } long imin, imax; *n = Sampled_getWindowSamples (me, xmin, xmax, & imin, & imax); if (*n < 1) return NUMundefined; double sum2 = 0.0; for (long channel = 1; channel <= my ny; channel ++) { double *amplitude = my z [channel]; for (long i = imin; i <= imax; i ++) { double value = amplitude [i]; sum2 += value * value; } } return sum2; }
/* static double Sound_getPeak (Sound me, double tmin, double tmax, long channel) { double minimum, timeOfMinimum, maximum, timeOfMaximum; double *y = my z [channel]; long i, imin, imax, sampleOfMinimum, sampleOfMaximum; if (Sampled_getWindowSamples (me, tmin, tmax, & imin, & imax) < 3) return NUMundefined; maximum = minimum = y [imin]; sampleOfMaximum = sampleOfMinimum = imin; for (i = imin + 1; i <= imax; i ++) { if (y [i] < minimum) { minimum = y [i]; sampleOfMinimum = i; } if (y [i] > maximum) { maximum = y [i]; sampleOfMaximum = i; } } timeOfMinimum = my x1 + (sampleOfMinimum - 1) * my dx; timeOfMaximum = my x1 + (sampleOfMaximum - 1) * my dx; Vector_getMinimumAndX (me, timeOfMinimum - my dx, timeOfMinimum + my dx, NUM_PEAK_INTERPOLATE_SINC70, & minimum, & timeOfMinimum); Vector_getMaximumAndX (me, timeOfMaximum - my dx, timeOfMaximum + my dx, NUM_PEAK_INTERPOLATE_SINC70, & maximum, & timeOfMaximum); return maximum - minimum; } */ static double Sound_getHannWindowedRms (Sound me, double tmid, double widthLeft, double widthRight) { double sumOfSquares = 0.0, windowSumOfSquares = 0.0; long imin, imax; if (Sampled_getWindowSamples (me, tmid - widthLeft, tmid + widthRight, & imin, & imax) < 3) return NUMundefined; for (long i = imin; i <= imax; i ++) { double t = my x1 + (i - 1) * my dx; double width = t < tmid ? widthLeft : widthRight; double windowPhase = (t - tmid) / width; /* in [-1 .. 1] */ double window = 0.5 + 0.5 * cos (NUMpi * windowPhase); /* Hann */ double windowedValue = ( my ny == 1 ? my z [1] [i] : 0.5 * (my z [1] [i] + my z [2] [i]) ) * window; sumOfSquares += windowedValue * windowedValue; windowSumOfSquares += window * window; } return sqrt (sumOfSquares / windowSumOfSquares); }
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."); } }
int SoundEditor::menu_cb_SetSelectionToZero (EDITOR_ARGS) { SoundEditor *editor = (SoundEditor *)editor_me; Sound sound = (Sound) editor->_data; long first, last; Sampled_getWindowSamples (sound, editor->_startSelection, editor->_endSelection, & first, & last); editor->save (L"Set to zero"); for (long channel = 1; channel <= sound -> ny; channel ++) { for (long i = first; i <= last; i ++) { sound -> z [channel] [i] = 0.0; } } editor->destroy_analysis (); editor->redraw (); editor->broadcastChange (); return 1; }
void Formant_getExtrema (Formant me, int iformant, double tmin, double tmax, double *fmin, double *fmax) { long itmin, itmax, iframe; if (fmin) *fmin = 0.0; if (fmax) *fmax = 0.0; if (iformant < 1) return; if (tmax <= tmin) { tmin = my xmin; tmax = my xmax; } if (! Sampled_getWindowSamples (me, tmin, tmax, & itmin, & itmax)) return; for (iframe = itmin; iframe <= itmax; iframe ++) { Formant_Frame frame = & my d_frames [iframe]; double f; if (iformant > frame -> nFormants) continue; f = frame -> formant [iformant]. frequency; if (f == 0.0) continue; if (fmin) if (f < *fmin || *fmin == 0.0) *fmin = f; if (fmax) if (f > *fmax) *fmax = f; } }
void LongSound_savePartAsAudioFile (LongSound me, int audioFileType, double tmin, double tmax, MelderFile file, int numberOfBitsPerSamplePoint) { 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 selected."); autoMelderFile mfile = MelderFile_create (file); MelderFile_writeAudioFileHeader (file, audioFileType, my sampleRate, n, my numberOfChannels, numberOfBitsPerSamplePoint); writePartToOpenFile (me, audioFileType, imin, n, file, 0, numberOfBitsPerSamplePoint); MelderFile_writeAudioFileTrailer (file, audioFileType, my sampleRate, n, my numberOfChannels, numberOfBitsPerSamplePoint); mfile.close (); } catch (MelderError) { Melder_throw (me, U": not written to sound file ", file, U"."); } }
Ltas Ltas_subtractTrendLine (Ltas me, double fmin, double fmax) { try { /* * Find the first and last bin. */ long imin, imax, n; if ((n = Sampled_getWindowSamples (me, fmin, fmax, & imin, & imax)) < 2) Melder_throw ("Number of bins too low (", n, "). Should be at least 2."); autoLtas thee = Data_copy (me); /* * Compute average amplitude and frequency. */ double sum = 0.0, amean, fmean, numerator = 0.0, denominator = 0.0, slope; for (long i = imin; i <= imax; i ++) { sum += thy z [1] [i]; } amean = sum / n; fmean = thy x1 + (0.5 * (imin + imax) - 1) * thy dx; /* * Compute slope. */ for (long i = imin; i <= imax; i ++) { double da = thy z [1] [i] - amean, df = thy x1 + (i - 1) * thy dx - fmean; numerator += da * df; denominator += df * df; } slope = numerator / denominator; /* * Modify bins. */ for (long i = 1; i < imin; i ++) { thy z [1] [i] = 0.0; } for (long i = imin; i <= imax; i ++) { double df = thy x1 + (i - 1) * thy dx - fmean; thy z [1] [i] -= amean + slope * df; } for (long i = imax + 1; i <= thy nx; i ++) { thy z [1] [i] = 0.0; } return thee.transfer(); } catch (MelderError) { Melder_throw (me, ": trend line not subtracted."); } }
void LineSpectralFrequencies_drawFrequencies (LineSpectralFrequencies me, Graphics g, double tmin, double tmax, double fmin, double fmax, bool garnish) { if (tmax <= tmin) { tmin = my xmin; tmax = my xmax; } long itmin, itmax; if (! Sampled_getWindowSamples (me, tmin, tmax, & itmin, & itmax)) { return; } if (fmax <= fmin) { double f1max, f2min; autoNUMvector<double> f1 (itmin, itmax), f2 (itmin, itmax); for (long iframe = itmin; iframe <= itmax; iframe++) { f1[iframe] = my d_frames[iframe].frequencies[1]; f2[iframe] = my d_frames[iframe].frequencies[my d_frames[iframe].numberOfFrequencies]; } NUMvector_extrema (f1.peek(), itmin, itmax, & fmin, & f1max); NUMvector_extrema (f2.peek(), itmin, itmax, & f2min, & fmax); } if (fmax == fmin) { fmin = 0; fmax += 0.5; } Graphics_setInner (g); Graphics_setWindow (g, tmin, tmax, fmin, fmax); for (long iframe = itmin; iframe <= itmax; iframe++) { LineSpectralFrequencies_Frame lsf = & my d_frames[iframe]; double x = Sampled_indexToX (me, iframe); for (long ifreq = 1; ifreq <= lsf -> numberOfFrequencies; ifreq++) { double y = lsf -> frequencies [ifreq]; if (y >= fmin && y <= fmax) { Graphics_speckle (g, x, y); } } } Graphics_unsetInner (g); if (garnish) { Graphics_drawInnerBox (g); Graphics_textBottom (g, true, U"Time (seconds)"); Graphics_textLeft (g, true, U"Frequency (Hz)"); Graphics_marksBottom (g, 2, true, true, false); Graphics_marksLeft (g, 2, true, true, false); } }
void Sound_setZero (Sound me, double tmin_in, double tmax_in, int roundTimesToNearestZeroCrossing) { Function_unidirectionalAutowindow (me, & tmin_in, & tmax_in); Function_intersectRangeWithDomain (me, & tmin_in, & tmax_in); for (long channel = 1; channel <= my ny; channel ++) { double tmin = tmin_in, tmax = tmax_in; if (roundTimesToNearestZeroCrossing) { if (tmin > my xmin) tmin = Sound_getNearestZeroCrossing (me, tmin_in, channel); if (tmax < my xmax) tmax = Sound_getNearestZeroCrossing (me, tmax_in, channel); } if (tmin == NUMundefined) tmin = my xmin; if (tmax == NUMundefined) tmax = my xmax; long imin, imax; Sampled_getWindowSamples (me, tmin, tmax, & imin, & imax); for (long i = imin; i <= imax; i ++) { my z [channel] [i] = 0.0; } } }
void structSpectrogramEditor :: v_draw () { Spectrogram spectrogram = (Spectrogram) our data; Graphics_setWindow (our d_graphics.get(), 0.0, 1.0, 0.0, 1.0); Graphics_setColour (our d_graphics.get(), Graphics_WHITE); Graphics_fillRectangle (our d_graphics.get(), 0.0, 1.0, 0.0, 1.0); Graphics_setColour (our d_graphics.get(), Graphics_BLACK); Graphics_rectangle (our d_graphics.get(), 0.0, 1.0, 0.0, 1.0); long itmin, itmax; Sampled_getWindowSamples (spectrogram, our d_startWindow, our d_endWindow, & itmin, & itmax); /* * Autoscale frequency axis. */ our maximum = spectrogram -> ymax; Graphics_setWindow (our d_graphics.get(), our d_startWindow, our d_endWindow, 0.0, our maximum); Spectrogram_paintInside (spectrogram, our d_graphics.get(), our d_startWindow, our d_endWindow, 0, 0, 0.0, true, 60, 6.0, 0); /* * Horizontal scaling lines. */ Graphics_setWindow (our d_graphics.get(), 0.0, 1.0, 0.0, our maximum); Graphics_setTextAlignment (our d_graphics.get(), Graphics_RIGHT, Graphics_HALF); Graphics_setColour (our d_graphics.get(), Graphics_RED); long df = 1000; for (long f = df; f <= our maximum; f += df) { Graphics_line (our d_graphics.get(), 0.0, f, 1.0, f); Graphics_text (our d_graphics.get(), -0.01, f, f, U" Hz"); } /* * Vertical cursor lines. */ Graphics_setWindow (our d_graphics.get(), our d_startWindow, our d_endWindow, 0.0, our maximum); if (our d_startSelection > our d_startWindow && our d_startSelection < our d_endWindow) Graphics_line (our d_graphics.get(), our d_startSelection, 0, our d_startSelection, our maximum); if (our d_endSelection > our d_startWindow && d_endSelection < d_endWindow) Graphics_line (our d_graphics.get(), our d_endSelection, 0, our d_endSelection, our maximum); Graphics_setColour (our d_graphics.get(), Graphics_BLACK); }
Ltas Ltas_subtractTrendLine (Ltas me, double fmin, double fmax) { Ltas thee = NULL; long imin, imax, n, i; double sum = 0.0, amean, fmean, numerator = 0.0, denominator = 0.0, slope; /* * Find the first and last bin. */ if ((n = Sampled_getWindowSamples (me, fmin, fmax, & imin, & imax)) < 2) { return (structLtas *)Melder_errorp ("(Ltas_subtractTrendLine:) Number of bins too low (%ld). Should be at least 2.", n); } thee = (structLtas *)Data_copy (me); /* * Compute average amplitude and frequency. */ for (i = imin; i <= imax; i ++) { sum += thy z [1] [i]; } amean = sum / n; fmean = thy x1 + (0.5 * (imin + imax) - 1) * thy dx; /* * Compute slope. */ for (i = imin; i <= imax; i ++) { double da = thy z [1] [i] - amean, df = thy x1 + (i - 1) * thy dx - fmean; numerator += da * df; denominator += df * df; } slope = numerator / denominator; /* * Modify bins. */ for (i = 1; i < imin; i ++) { thy z [1] [i] = 0.0; } for (i = imin; i <= imax; i ++) { double df = thy x1 + (i - 1) * thy dx - fmean; thy z [1] [i] -= amean + slope * df; } for (i = imax + 1; i <= thy nx; i ++) { thy z [1] [i] = 0.0; } return thee; }
void LongSound_getWindowExtrema (LongSound me, double tmin, double tmax, int channel, double *minimum, double *maximum) { long imin, imax; (void) Sampled_getWindowSamples (me, tmin, tmax, & imin, & imax); *minimum = 1.0; *maximum = -1.0; try { LongSound_haveWindow (me, tmin, tmax); } catch (MelderError) { Melder_clearError (); return; } long minimum_int = 32767, maximum_int = -32768; for (long i = imin; i <= imax; i ++) { long value = my buffer [(i - my imin) * my numberOfChannels + channel - 1]; if (value < minimum_int) minimum_int = value; if (value > maximum_int) maximum_int = value; } *minimum = minimum_int / 32768.0; *maximum = maximum_int / 32768.0; }
double Formant_getStandardDeviation (Formant me, int iformant, double tmin, double tmax, int bark) { if (iformant < 1 || tmin == NUMundefined || tmax == NUMundefined) return NUMundefined; if (tmax <= tmin) { tmin = my xmin; tmax = my xmax; } long itmin, itmax; if (! Sampled_getWindowSamples (me, tmin, tmax, & itmin, & itmax)) return NUMundefined; double mean = Formant_getMean (me, iformant, tmin, tmax, bark); double sum = 0.0; long n = 0; for (long iframe = itmin; iframe <= itmax; iframe ++) { Formant_Frame frame = & my d_frames [iframe]; if (iformant > frame -> nFormants) continue; double f = frame -> formant [iformant]. frequency; if (f == 0.0) continue; if (bark) f = NUMhertzToBark (f); n += 1; sum += (f - mean) * (f - mean); } if (n > 1) return sqrt (sum / (n - 1)); return NUMundefined; }
double Sampled_getQuantile (I, double xmin, double xmax, double quantile, long ilevel, int unit) { iam (Sampled); long i, imin, imax, numberOfDefinedSamples = 0; double *values = NUMdvector (1, my nx), result = NUMundefined; iferror return NUMundefined; Function_unidirectionalAutowindow (me, & xmin, & xmax); if (! Function_intersectRangeWithDomain (me, & xmin, & xmax)) return NUMundefined; Sampled_getWindowSamples (me, xmin, xmax, & imin, & imax); for (i = imin; i <= imax; i ++) { double value = our getValueAtSample (me, i, ilevel, unit); if (NUMdefined (value)) { values [++ numberOfDefinedSamples] = value; } } if (numberOfDefinedSamples >= 1) { NUMsort_d (numberOfDefinedSamples, values); result = NUMquantile (numberOfDefinedSamples, values, quantile); } NUMdvector_free (values, 1); return result; }
static void Sound_into_MelSpectrogram_frame (Sound me, MelSpectrogram thee, long frame) { autoSpectrum him = Sound_to_Spectrum_power (me); for (long ifilter = 1; ifilter <= thy ny; ifilter ++) { double power = 0; double fc_mel = thy y1 + (ifilter - 1) * thy dy; double fc_hz = thy v_frequencyToHertz (fc_mel); double fl_hz = thy v_frequencyToHertz (fc_mel - thy dy); double fh_hz = thy v_frequencyToHertz (fc_mel + thy dy); long ifrom, ito; Sampled_getWindowSamples (him.get(), fl_hz, fh_hz, &ifrom, &ito); for (long i = ifrom; i <= ito; i++) { // Bin with a triangular filter the power (=amplitude-squared) double f = his x1 + (i - 1) * his dx; double a = NUMtriangularfilter_amplitude (fl_hz, fc_hz, fh_hz, f); power += a * his z[1][i]; } thy z[ifilter][frame] = power; } }
void Sound_filterWithFormants (Sound me, double tmin, double tmax, int numberOfFormants, double formant [], double bandwidth []) { try { for (long channel = 1; channel <= my ny; channel ++) { if (tmax <= tmin) { tmin = my xmin; tmax = my xmax; } // autowindowing long itmin, itmax; long n = Sampled_getWindowSamples (me, tmin, tmax, & itmin, & itmax); if (n <= 2) Melder_throw (U"Sound too short."); double *amplitude = my z [channel] + itmin - 1; // base 1 NUMdeemphasize_f (amplitude, n, my dx, 50.0); for (int iformant = 1; iformant <= numberOfFormants; iformant ++) { NUMfilterSecondOrderSection_fb (amplitude, n, my dx, formant [iformant], bandwidth [iformant]); } } Matrix_scaleAbsoluteExtremum (me, 0.99); } catch (MelderError) { Melder_throw (me, U": not filtered."); } }