double Matrix_getStandardDeviation (Matrix me, double xmin, double xmax, double ymin, double ymax) { if (xmax <= xmin) { xmin = my xmin; xmax = my xmax; } if (ymax <= ymin) { ymin = my ymin; ymax = my ymax; } long ixmin, ixmax, iymin, iymax; if ((Matrix_getWindowSamplesX (me, xmin, xmax, & ixmin, & ixmax) == 0) || (Matrix_getWindowSamplesY (me, ymin, ymax, & iymin, & iymax) == 0)) { return NUMundefined; } long nx = ixmax - ixmin + 1, ny = iymax - iymin + 1; if (nx == 1 && ny == 1) { return NUMundefined; } double mean = Matrix_getMean (me, xmin, xmax, ymin, ymax), sum = 0; for (long row = iymin; row <= iymax; row++) { for (long col = ixmin; col <= ixmax; col++) { double val = my z[row][col] - mean; sum += val * val; } } return sqrt (sum / (nx * ny - 1)); }
void FilterBank_paint (FilterBank me, Graphics g, double xmin, double xmax, double ymin, double ymax, double minimum, double maximum, int garnish) { if (xmax <= xmin) { xmin = my xmin; xmax = my xmax; } if (ymax <= ymin) { ymin = my ymin; ymax = my ymax; } long ixmin, ixmax, iymin, iymax; (void) Matrix_getWindowSamplesX (me, xmin - 0.49999 * my dx, xmax + 0.49999 * my dx, &ixmin, &ixmax); (void) Matrix_getWindowSamplesY (me, ymin - 0.49999 * my dy, ymax + 0.49999 * my dy, &iymin, &iymax); if (maximum <= minimum) { (void) Matrix_getWindowExtrema (me, ixmin, ixmax, iymin, iymax, &minimum, &maximum); } if (maximum <= minimum) { minimum -= 1.0; maximum += 1.0; } if (xmin >= xmax || ymin >= ymax) { return; } Graphics_setInner (g); Graphics_setWindow (g, xmin, xmax, ymin, ymax); Graphics_image (g, my z, ixmin, ixmax, Sampled_indexToX (me, ixmin - 0.5), Sampled_indexToX (me, ixmax + 0.5), iymin, iymax, SampledXY_indexToY (me, iymin - 0.5), SampledXY_indexToY (me, iymax + 0.5), minimum, maximum); Graphics_unsetInner (g); if (garnish) { Graphics_drawInnerBox (g); Graphics_marksLeft (g, 2, 1, 1, 0); Graphics_textLeft (g, 1, GetFreqScaleText (my v_getFrequencyScale ())); Graphics_marksBottom (g, 2, 1, 1, 0); Graphics_textBottom (g, 1, U"Time (s)"); } }
static void cellArrayOrImage (Matrix me, Graphics g, double xmin, double xmax, double ymin, double ymax, double minimum, double maximum, bool interpolate) { if (xmax <= xmin) { xmin = my xmin; xmax = my xmax; } if (ymax <= ymin) { ymin = my ymin; ymax = my ymax; } long ixmin, ixmax, iymin, iymax; (void) Matrix_getWindowSamplesX (me, xmin - 0.49999 * my dx, xmax + 0.49999 * my dx, & ixmin, & ixmax); (void) Matrix_getWindowSamplesY (me, ymin - 0.49999 * my dy, ymax + 0.49999 * my dy, & iymin, & iymax); if (maximum <= minimum) (void) Matrix_getWindowExtrema (me, ixmin, ixmax, iymin, iymax, & minimum, & maximum); if (maximum <= minimum) { minimum -= 1.0; maximum += 1.0; } if (xmin >= xmax || ymin >= ymax) return; Graphics_setInner (g); Graphics_setWindow (g, xmin, xmax, ymin, ymax); if (interpolate) Graphics_image (g, my z, ixmin, ixmax, Sampled_indexToX (me, ixmin - 0.5), Sampled_indexToX (me, ixmax + 0.5), iymin, iymax, SampledXY_indexToY (me, iymin - 0.5), SampledXY_indexToY (me, iymax + 0.5), minimum, maximum); else Graphics_cellArray (g, my z, ixmin, ixmax, Sampled_indexToX (me, ixmin - 0.5), Sampled_indexToX (me, ixmax + 0.5), iymin, iymax, SampledXY_indexToY (me, iymin - 0.5), SampledXY_indexToY (me, iymax + 0.5), minimum, maximum); Graphics_rectangle (g, xmin, xmax, ymin, ymax); Graphics_unsetInner (g); }
void Spectrum_drawInside (Spectrum me, Graphics g, double fmin, double fmax, double minimum, double maximum) { int autoscaling = minimum >= maximum; if (fmax <= fmin) { fmin = my xmin; fmax = my xmax; } long ifmin, ifmax; if (! Matrix_getWindowSamplesX (me, fmin, fmax, & ifmin, & ifmax)) return; autoNUMvector <double> yWC (ifmin, ifmax); /* * First pass: compute power density. */ if (autoscaling) maximum = -1e30; for (long ifreq = ifmin; ifreq <= ifmax; ifreq ++) { double y = my v_getValueAtSample (ifreq, 0, 2); if (autoscaling && y > maximum) maximum = y; yWC [ifreq] = y; } if (autoscaling) minimum = maximum - 60; /* Default dynamic range is 60 dB. */ /* * Second pass: clip. */ for (long ifreq = ifmin; ifreq <= ifmax; ifreq ++) { if (yWC [ifreq] < minimum) yWC [ifreq] = minimum; else if (yWC [ifreq] > maximum) yWC [ifreq] = maximum; } Graphics_setWindow (g, fmin, fmax, minimum, maximum); Graphics_function (g, yWC.peek(), ifmin, ifmax, Matrix_columnToX (me, ifmin), Matrix_columnToX (me, ifmax)); }
void Sound_playPart (Sound me, double tmin, double tmax, int (*callback) (void *closure, int phase, double tmin, double tmax, double t), void *closure) { try { long ifsamp = lround (1.0 / my dx), bestSampleRate = MelderAudio_getOutputBestSampleRate (ifsamp); if (ifsamp == bestSampleRate) { struct SoundPlay *thee = (struct SoundPlay *) & thePlayingSound; double *fromLeft = my z [1], *fromRight = my ny > 1 ? my z [2] : NULL; MelderAudio_stopPlaying (MelderAudio_IMPLICIT); long i1, i2; if ((thy numberOfSamples = Matrix_getWindowSamplesX (me, tmin, tmax, & i1, & i2)) < 1) return; thy tmin = tmin; thy tmax = tmax; thy dt = my dx; thy t1 = my x1; thy callback = callback; thy closure = closure; thy silenceBefore = (long) (ifsamp * MelderAudio_getOutputSilenceBefore ()); thy silenceAfter = (long) (ifsamp * MelderAudio_getOutputSilenceAfter ()); int numberOfChannels = my ny; NUMvector_free (thy buffer, 1); // just in case thy buffer = NUMvector <short> (1, (i2 - i1 + 1 + thy silenceBefore + thy silenceAfter) * numberOfChannels); thy i1 = i1; thy i2 = i2; short *to = thy buffer + thy silenceBefore * numberOfChannels; if (numberOfChannels > 2) { for (long i = i1; i <= i2; i ++) { for (long chan = 1; chan <= my ny; chan ++) { long value = (long) round (my z [chan] [i] * 32768.0); * ++ to = value < -32768 ? -32768 : value > 32767 ? 32767 : value; } } } else if (numberOfChannels == 2) { for (long i = i1; i <= i2; i ++) { long valueLeft = (long) round (fromLeft [i] * 32768.0); * ++ to = valueLeft < -32768 ? -32768 : valueLeft > 32767 ? 32767 : valueLeft; long valueRight = (long) round (fromRight [i] * 32768.0); * ++ to = valueRight < -32768 ? -32768 : valueRight > 32767 ? 32767 : valueRight; } } else { for (long i = i1; i <= i2; i ++) { long value = (long) round (fromLeft [i] * 32768.0); * ++ to = value < -32768 ? -32768 : value > 32767 ? 32767 : value; } } if (thy callback) thy callback (thy closure, 1, tmin, tmax, tmin); MelderAudio_play16 (thy buffer + 1, ifsamp, thy silenceBefore + thy numberOfSamples + thy silenceAfter, numberOfChannels, melderPlayCallback, thee); } else { autoSound resampled = Sound_resample (me, bestSampleRate, 1); Sound_playPart (resampled.peek(), tmin, tmax, callback, closure); // recursively } } catch (MelderError) { Melder_throw (me, U": not played."); } }
void PowerCepstrogram_paint (PowerCepstrogram me, Graphics g, double tmin, double tmax, double qmin, double qmax, double dBmaximum, int autoscaling, double dynamicRangedB, double dynamicCompression, int garnish) { if (tmax <= tmin) { tmin = my xmin; tmax = my xmax; } if (qmax <= qmin) { qmin = my ymin; qmax = my ymax; } long itmin, itmax, ifmin, ifmax; if (! Matrix_getWindowSamplesX (me, tmin - 0.49999 * my dx, tmax + 0.49999 * my dx, & itmin, & itmax) || ! Matrix_getWindowSamplesY (me, qmin - 0.49999 * my dy, qmax + 0.49999 * my dy, & ifmin, & ifmax)) { return; } autoMatrix thee = Data_copy (me); double min = 1e308, max = -min; for (long i = 1; i <= my ny; i++) { for (long j = 1; j <= my nx; j++) { double val = TO10LOG (my z[i][j]); min = val < min ? val : min; max = val > max ? val : max; thy z[i][j] = val; } } double dBminimum = dBmaximum - dynamicRangedB; if (autoscaling) { dBminimum = min; dBmaximum = max; } for (long j = 1; j <= my nx; j++) { double lmax = thy z[1][j]; for (long i = 2; i <= my ny; i++) { if (thy z[i][j] > lmax) { lmax = thy z[i][j]; } } double factor = dynamicCompression * (max - lmax); for (long i = 1; i <= my ny; i++) { thy z[i][j] += factor; } } Graphics_setInner (g); Graphics_setWindow (g, tmin, tmax, qmin, qmax); Graphics_image (g, thy z, itmin, itmax, Matrix_columnToX (thee.get(), itmin - 0.5), Matrix_columnToX (thee.get(), itmax + 0.5), ifmin, ifmax, Matrix_rowToY (thee.get(), ifmin - 0.5), Matrix_rowToY (thee.get(), ifmax + 0.5), dBminimum, dBmaximum); Graphics_unsetInner (g); if (garnish) { Graphics_drawInnerBox (g); Graphics_textBottom (g, true, U"Time (s)"); Graphics_marksBottom (g, 2, true, true, false); Graphics_marksLeft (g, 2, true, true, false); Graphics_textLeft (g, true, U"Quefrency (s)"); } }
void Intensity_drawInside (Intensity me, Graphics g, double tmin, double tmax, double minimum, double maximum) { if (tmax <= tmin) { tmin = my xmin; tmax = my xmax; } // autowindow long itmin, itmax; Matrix_getWindowSamplesX (me, tmin, tmax, & itmin, & itmax); if (maximum <= minimum) Matrix_getWindowExtrema (me, itmin, itmax, 1, 1, & minimum, & maximum); // autoscale if (maximum <= minimum) { minimum -= 10; maximum += 10; } Graphics_setWindow (g, tmin, tmax, minimum, maximum); Graphics_function (g, my z [1], itmin, itmax, Matrix_columnToX (me, itmin), Matrix_columnToX (me, itmax)); }
/* Fit line y = ax+b (lineType ==1) or y = a log(x) + b (lineType == 2) on interval [qmin,qmax] * method == 1 : Least squares fit * method == 2 : Theil's partial robust fit */ void PowerCepstrum_fitTiltLine (PowerCepstrum me, double qmin, double qmax, double *p_a, double *p_intercept, int lineType, int method) { try { double a, intercept; if (qmax <= qmin) { qmin = my xmin; qmax = my xmax; } long imin, imax; if (! Matrix_getWindowSamplesX (me, qmin, qmax, & imin, & imax)) { return; } imin = (lineType == 2 && imin == 1) ? 2 : imin; // log(0) is undefined! long numberOfPoints = imax - imin + 1; if (numberOfPoints < 2) { Melder_throw (U"Not enough points for fit."); } autoNUMvector<double> y (1, numberOfPoints); autoNUMvector<double> x (1, numberOfPoints); for (long i = 1; i <= numberOfPoints; i++) { long isamp = imin + i - 1; x[i] = my x1 + (isamp - 1) * my dx; if (lineType == 2) { x[i] = log (x[i]); } y[i] = my v_getValueAtSample (isamp, 1, 0); } if (method == 3) { // try local maxima first autoNUMvector<double> ym (1, numberOfPoints / 2 + 1); autoNUMvector<double> xm (1, numberOfPoints / 2 + 1); long numberOfLocalPeaks = 0; // forget y[1] if y[2]<y[1] and y[n] if y[n-1]<y[n] ! for (long i = 2; i <= numberOfPoints; i++) { if (y[i - 1] <= y[i] && y[i] > y[i + 1]) { ym[++numberOfLocalPeaks] = y[i]; xm[numberOfLocalPeaks] = x[i]; } } if (numberOfLocalPeaks > numberOfPoints / 10) { for (long i = 1; i <= numberOfLocalPeaks; i++) { x[i] = xm[i]; y[i] = ym[i]; } numberOfPoints = numberOfLocalPeaks; } method = 2; // robust fit of peaks } // fit a straight line through (x,y)'s NUMlineFit (x.peek(), y.peek(), numberOfPoints, & a, & intercept, method); if (p_intercept) { *p_intercept = intercept; } if (p_a) { *p_a = a; } } catch (MelderError) { Melder_throw (me, U": couldn't fit a line."); } }
void Matrix_drawAsSquares (Matrix me, Graphics g, double xmin, double xmax, double ymin, double ymax, int garnish) { Graphics_Colour colour = Graphics_inqColour (g); long ixmin, ixmax, iymin, iymax; if (xmax <= xmin) { xmin = my xmin; xmax = my xmax; } long nx = Matrix_getWindowSamplesX (me, xmin, xmax, &ixmin, &ixmax); if (ymax <= ymin) { ymin = my ymin; ymax = my ymax; } long ny = Matrix_getWindowSamplesY (me, ymin, ymax, &iymin, &iymax); double min, max = nx > ny ? nx : ny; double dx = (xmax - xmin) / max, dy = (ymax - ymin) / max; Graphics_setInner (g); Graphics_setWindow (g, xmin, xmax, ymin, ymax); Matrix_getWindowExtrema (me, ixmin, ixmax, iymin, iymax, & min, & max); double wAbsMax = fabs (max) > fabs (min) ? fabs (max) : fabs (min); for (long i = iymin; i <= iymax; i++) { double y = Matrix_rowToY (me, i); for (long j = ixmin; j <= ixmax; j++) { double x = Matrix_columnToX (me, j); double d = 0.95 * sqrt (fabs (my z[i][j]) / wAbsMax); if (d > 0) { double x1WC = x - d * dx / 2, x2WC = x + d * dx / 2; double y1WC = y - d * dy / 2, y2WC = y + d * dy / 2; if (my z[i][j] > 0) { Graphics_setColour (g, Graphics_WHITE); } Graphics_fillRectangle (g, x1WC, x2WC, y1WC, y2WC); Graphics_setColour (g, colour); Graphics_rectangle (g, x1WC, x2WC , y1WC, y2WC); } } } Graphics_setGrey (g, 0.0); Graphics_unsetInner (g); if (garnish) { Graphics_drawInnerBox (g); Graphics_marksLeft (g, 2, true, true, false); if (ymin * ymax < 0.0) { Graphics_markLeft (g, 0.0, true, true, true, nullptr); } Graphics_marksBottom (g, 2, true, true, false); if (xmin * xmax < 0.0) { Graphics_markBottom (g, 0.0, true, true, true, nullptr); } } }
void Spectrogram_paintInside (Spectrogram me, Graphics g, double tmin, double tmax, double fmin, double fmax, double maximum, int autoscaling, double dynamic, double preemphasis, double dynamicCompression) { if (tmax <= tmin) { tmin = my xmin; tmax = my xmax; } if (fmax <= fmin) { fmin = my ymin; fmax = my ymax; } long itmin, itmax, ifmin, ifmax; if (! Matrix_getWindowSamplesX (me, tmin - 0.49999 * my dx, tmax + 0.49999 * my dx, & itmin, & itmax) || ! Matrix_getWindowSamplesY (me, fmin - 0.49999 * my dy, fmax + 0.49999 * my dy, & ifmin, & ifmax)) return; Graphics_setWindow (g, tmin, tmax, fmin, fmax); autoNUMvector <double> preemphasisFactor (ifmin, ifmax); autoNUMvector <double> dynamicFactor (itmin, itmax); /* Pre-emphasis in place; also compute maximum after pre-emphasis. */ for (long ifreq = ifmin; ifreq <= ifmax; ifreq ++) { preemphasisFactor [ifreq] = (preemphasis / NUMln2) * log (ifreq * my dy / 1000.0); for (long itime = itmin; itime <= itmax; itime ++) { double value = my z [ifreq] [itime]; /* Power. */ value = (10.0/NUMln10) * log ((value + 1e-30) / 4.0e-10) + preemphasisFactor [ifreq]; /* dB */ if (value > dynamicFactor [itime]) dynamicFactor [itime] = value; /* Local maximum. */ my z [ifreq] [itime] = value; } } /* Compute global maximum. */ if (autoscaling) { maximum = 0.0; for (long itime = itmin; itime <= itmax; itime ++) if (dynamicFactor [itime] > maximum) maximum = dynamicFactor [itime]; } /* Dynamic compression in place. */ for (long itime = itmin; itime <= itmax; itime ++) { dynamicFactor [itime] = dynamicCompression * (maximum - dynamicFactor [itime]); for (long ifreq = ifmin; ifreq <= ifmax; ifreq ++) my z [ifreq] [itime] += dynamicFactor [itime]; } Graphics_image (g, my z, itmin, itmax, Matrix_columnToX (me, itmin - 0.5), Matrix_columnToX (me, itmax + 0.5), ifmin, ifmax, Matrix_rowToY (me, ifmin - 0.5), Matrix_rowToY (me, ifmax + 0.5), maximum - dynamic, maximum); for (long ifreq = ifmin; ifreq <= ifmax; ifreq ++) for (long itime = itmin; itime <= itmax; itime ++) { double value = 4.0e-10 * exp ((my z [ifreq] [itime] - dynamicFactor [itime] - preemphasisFactor [ifreq]) * (NUMln10 / 10.0)) - 1e-30; my z [ifreq] [itime] = value > 0.0 ? value : 0.0; } }
void ERP_drawChannel_number (ERP me, Graphics graphics, long channelNumber, double tmin, double tmax, double vmin, double vmax, bool garnish) { if (channelNumber < 1 || channelNumber > my ny) return; /* * Automatic domain. */ if (tmin == tmax) { tmin = my xmin; tmax = my xmax; } /* * Domain expressed in sample numbers. */ long ixmin, ixmax; Matrix_getWindowSamplesX (me, tmin, tmax, & ixmin, & ixmax); /* * Automatic vertical range. */ if (vmin == vmax) { Matrix_getWindowExtrema (me, ixmin, ixmax, channelNumber, channelNumber, & vmin, & vmax); if (vmin == vmax) { vmin -= 1.0; vmax += 1.0; } } /* * Set coordinates for drawing. */ Graphics_setInner (graphics); Graphics_setWindow (graphics, tmin, tmax, vmin, vmax); Graphics_function (graphics, my z [channelNumber], ixmin, ixmax, Matrix_columnToX (me, ixmin), Matrix_columnToX (me, ixmax)); Graphics_unsetInner (graphics); if (garnish) { Graphics_drawInnerBox (graphics); Graphics_textTop (graphics, true, Melder_wcscat (L"Channel ", my channelNames [channelNumber])); Graphics_textBottom (graphics, true, L"Time (s)"); Graphics_marksBottom (graphics, 2, true, true, false); if (0.0 > tmin && 0.0 < tmax) Graphics_markBottom (graphics, 0.0, true, true, true, NULL); Graphics_markLeft (graphics, vmin, true, true, false, NULL); Graphics_markLeft (graphics, vmax, true, true, false, NULL); Graphics_markBottom (graphics, 0.0, true, true, true, NULL); if (vmin != 0.0 && vmax != 0.0 && (vmin > 0.0) != (vmax > 0.0)) { Graphics_markLeft (graphics, 0.0, true, true, true, NULL); } } }
void Cepstrum_draw (Cepstrum me, Graphics g, double qmin, double qmax, double minimum, double maximum, int garnish) { int autoscaling = minimum >= maximum; Graphics_setInner (g); if (qmax <= qmin) { qmin = my xmin; qmax = my xmax; } long imin, imax; if (! Matrix_getWindowSamplesX (me, qmin, qmax, & imin, & imax)) { return; } autoNUMvector<double> y (imin, imax); double *z = my z[1]; for (long i = imin; i <= imax; i++) { y[i] = z[i]; } if (autoscaling) { NUMvector_extrema (y.peek(), imin, imax, & minimum, & maximum); } for (long i = imin; i <= imax; i ++) { if (y[i] > maximum) { y[i] = maximum; } else if (y[i] < minimum) { y[i] = minimum; } } Graphics_setWindow (g, qmin, qmax, minimum, maximum); Graphics_function (g, y.peek(), imin, imax, Matrix_columnToX (me, imin), Matrix_columnToX (me, imax)); Graphics_unsetInner (g); if (garnish) { Graphics_drawInnerBox (g); Graphics_textBottom (g, 1, L"Quefrency"); Graphics_marksBottom (g, 2, TRUE, TRUE, FALSE); Graphics_textLeft (g, 1, L"Amplitude"); } }
void Matrix_paintSurface (Matrix me, Graphics g, double xmin, double xmax, double ymin, double ymax, double minimum, double maximum, double elevation, double azimuth) { if (xmax <= xmin) { xmin = my xmin; xmax = my xmax; } if (ymax <= ymin) { ymin = my ymin; ymax = my ymax; } long ixmin, ixmax, iymin, iymax; (void) Matrix_getWindowSamplesX (me, xmin, xmax, & ixmin, & ixmax); (void) Matrix_getWindowSamplesY (me, ymin, ymax, & iymin, & iymax); if (maximum <= minimum) (void) Matrix_getWindowExtrema (me, ixmin, ixmax, iymin, iymax, & minimum, & maximum); if (maximum <= minimum) { minimum -= 1.0; maximum += 1.0; } Graphics_setInner (g); Graphics_setWindow (g, -1.0, 1.0, minimum, maximum); Graphics_surface (g, my z, ixmin, ixmax, Matrix_columnToX (me, ixmin), Matrix_columnToX (me, ixmax), iymin, iymax, Matrix_rowToY (me, iymin), Matrix_rowToY (me, iymax), minimum, maximum, elevation, azimuth); Graphics_unsetInner (g); }
static void _Cepstrum_draw (Cepstrum me, Graphics g, double qmin, double qmax, double minimum, double maximum, int power, int garnish) { int autoscaling = minimum >= maximum; Graphics_setInner (g); if (qmax <= qmin) { qmin = my xmin; qmax = my xmax; } long imin, imax; if (! Matrix_getWindowSamplesX (me, qmin, qmax, & imin, & imax)) { return; } autoNUMvector<double> y (imin, imax); for (long i = imin; i <= imax; i++) { y[i] = my v_getValueAtSample (i, (power ? 1 : 0), 0); } if (autoscaling) { NUMvector_extrema (y.peek(), imin, imax, & minimum, & maximum); } else { for (long i = imin; i <= imax; i ++) { if (y[i] > maximum) { y[i] = maximum; } else if (y[i] < minimum) { y[i] = minimum; } } } Graphics_setWindow (g, qmin, qmax, minimum, maximum); Graphics_function (g, y.peek(), imin, imax, Matrix_columnToX (me, imin), Matrix_columnToX (me, imax)); Graphics_unsetInner (g); if (garnish) { Graphics_drawInnerBox (g); Graphics_textBottom (g, true, U"Quefrency (s)"); Graphics_marksBottom (g, 2, true, true, false); Graphics_textLeft (g, true, power ? U"Amplitude (dB)" : U"Amplitude"); Graphics_marksLeft (g, 2, true, true, false); } }
double Matrix_getMean (Matrix me, double xmin, double xmax, double ymin, double ymax) { if (xmax <= xmin) { xmin = my xmin; xmax = my xmax; } if (ymax <= ymin) { ymin = my ymin; ymax = my ymax; } long ixmin, ixmax, iymin, iymax; if ((Matrix_getWindowSamplesX (me, xmin, xmax, & ixmin, & ixmax) == 0) || (Matrix_getWindowSamplesY (me, ymin, ymax, & iymin, & iymax) == 0)) { return NUMundefined; } double sum = 0.0; for (long row = iymin; row <= iymax; row++) { for (long col = ixmin; col <= ixmax; col++) { sum += my z[row][col]; } } return sum / ((iymax - iymin + 1) * (ixmax - ixmin + 1)); }
void PowerCepstrogram_paint (PowerCepstrogram me, Graphics g, double tmin, double tmax, double qmin, double qmax, double dBminimum, double dBmaximum, int garnish) { if (tmax <= tmin) { tmin = my xmin; tmax = my xmax; } if (qmax <= qmin) { qmin = my ymin; qmax = my ymax; } long itmin, itmax, ifmin, ifmax; if (! Matrix_getWindowSamplesX (me, tmin - 0.49999 * my dx, tmax + 0.49999 * my dx, & itmin, & itmax) || ! Matrix_getWindowSamplesY (me, qmin - 0.49999 * my dy, qmax + 0.49999 * my dy, & ifmin, & ifmax)) { return; } autoMatrix thee = (Matrix) Data_copy (me); double min = 1e38, max = -min; for (long i = 1; i <= my ny; i++) { for (long j = 1; j <= my nx; j++) { double val = TO10LOG (my z[i][j]); min = val < min ? val : min; max = val > max ? val : max; thy z[i][j] = val; } } if (dBmaximum <= dBminimum) { dBminimum = min; dBmaximum = max; } Graphics_setInner (g); Graphics_setWindow (g, tmin, tmax, qmin, qmax); Graphics_image (g, thy z, itmin, itmax, Matrix_columnToX (thee.peek(), itmin - 0.5), Matrix_columnToX (thee.peek(), itmax + 0.5), ifmin, ifmax, Matrix_rowToY (thee.peek(), ifmin - 0.5), Matrix_rowToY (thee.peek(), ifmax + 0.5), dBminimum, dBmaximum); Graphics_unsetInner (g); if (garnish) { Graphics_drawInnerBox (g); Graphics_textBottom (g, 1, L"Time (s)"); Graphics_marksBottom (g, 2, 1, 1, 0); Graphics_marksLeft (g, 2, 1, 1, 0); Graphics_textLeft (g, 1, L"Quefrency (s)"); } }
void Matrix_drawOneContour (Matrix me, Graphics g, double xmin, double xmax, double ymin, double ymax, double height) { bool xreversed = xmin > xmax, yreversed = ymin > ymax; if (xmax == xmin) { xmin = my xmin; xmax = my xmax; } if (ymax == ymin) { ymin = my ymin; ymax = my ymax; } if (xreversed) { double temp = xmin; xmin = xmax; xmax = temp; } if (yreversed) { double temp = ymin; ymin = ymax; ymax = temp; } long ixmin, ixmax, iymin, iymax; (void) Matrix_getWindowSamplesX (me, xmin, xmax, & ixmin, & ixmax); (void) Matrix_getWindowSamplesY (me, ymin, ymax, & iymin, & iymax); if (xmin == xmax || ymin == ymax) return; Graphics_setInner (g); Graphics_setWindow (g, xreversed ? xmax : xmin, xreversed ? xmin : xmax, yreversed ? ymax : ymin, yreversed ? ymin : ymax); Graphics_contour (g, my z, ixmin, ixmax, Matrix_columnToX (me, ixmin), Matrix_columnToX (me, ixmax), iymin, iymax, Matrix_rowToY (me, iymin), Matrix_rowToY (me, iymax), height); Graphics_rectangle (g, xmin, xmax, ymin, ymax); Graphics_unsetInner (g); }
void Spectrum_drawLogFreq (Spectrum me, Graphics g, double fmin, double fmax, double minimum, double maximum, int garnish) { int autoscaling = minimum >= maximum; if (fmax <= fmin) { fmin = my xmin; fmax = my xmax; } long ifmin, ifmax; if (! Matrix_getWindowSamplesX (me, fmin, fmax, & ifmin, & ifmax)) return; if(ifmin==1)ifmin=2; /* BUG */ autoNUMvector <double> xWC (ifmin, ifmax); autoNUMvector <double> yWC (ifmin, ifmax); /* * First pass: compute power density. */ if (autoscaling) maximum = -1e6; for (long ifreq = ifmin; ifreq <= ifmax; ifreq ++) { xWC [ifreq] = log10 (my x1 + (ifreq - 1) * my dx); yWC [ifreq] = my v_getValueAtSample (ifreq, 0, 2); if (autoscaling && yWC [ifreq] > maximum) maximum = yWC [ifreq]; } if (autoscaling) minimum = maximum - 60; /* Default dynamic range is 60 dB. */ /* * Second pass: clip. */ for (long ifreq = ifmin; ifreq <= ifmax; ifreq ++) { if (yWC [ifreq] < minimum) yWC [ifreq] = minimum; else if (yWC [ifreq] > maximum) yWC [ifreq] = maximum; } Graphics_setInner (g); Graphics_setWindow (g, log10 (fmin), log10 (fmax), minimum, maximum); Graphics_polyline (g, ifmax - ifmin + 1, & xWC [ifmin], & yWC [ifmin]); Graphics_unsetInner (g); if (garnish) { Graphics_drawInnerBox (g); Graphics_textBottom (g, 1, L"Frequency (Hz)"); Graphics_marksBottomLogarithmic (g, 3, TRUE, TRUE, FALSE); Graphics_textLeft (g, 1, L"Sound pressure level (dB/Hz)"); Graphics_marksLeftEvery (g, 1.0, 20.0, TRUE, TRUE, FALSE); } }
void Excitation_draw (Excitation me, Graphics g, double fmin, double fmax, double minimum, double maximum, int garnish) { if (fmax <= fmin) { fmin = my xmin; fmax = my xmax; } long ifmin, ifmax; Matrix_getWindowSamplesX (me, fmin, fmax, & ifmin, & ifmax); if (maximum <= minimum) Matrix_getWindowExtrema (me, ifmin, ifmax, 1, 1, & minimum, & maximum); if (maximum <= minimum) { minimum -= 20; maximum += 20; } Graphics_setInner (g); Graphics_setWindow (g, fmin, fmax, minimum, maximum); Graphics_function (g, my z [1], ifmin, ifmax, Matrix_columnToX (me, ifmin), Matrix_columnToX (me, ifmax)); Graphics_unsetInner (g); if (garnish) { Graphics_drawInnerBox (g); Graphics_textBottom (g, 1, L"Frequency (Bark)"); Graphics_textLeft (g, 1, L"Excitation (phon)"); Graphics_marksBottomEvery (g, 1, 5, 1, 1, 0); Graphics_marksLeftEvery (g, 1, 20, 1, 1, 0); } }
void Matrix_formula_part (Matrix me, double xmin, double xmax, double ymin, double ymax, const char32 *expression, Interpreter interpreter, Matrix target) { try { if (xmax <= xmin) { xmin = my xmin; xmax = my xmax; } if (ymax <= ymin) { ymin = my ymin; ymax = my ymax; } long ixmin, ixmax, iymin, iymax; (void) Matrix_getWindowSamplesX (me, xmin, xmax, & ixmin, & ixmax); (void) Matrix_getWindowSamplesY (me, ymin, ymax, & iymin, & iymax); struct Formula_Result result; Formula_compile (interpreter, me, expression, kFormula_EXPRESSION_TYPE_NUMERIC, true); if (! target) target = me; for (long irow = iymin; irow <= iymax; irow ++) { for (long icol = ixmin; icol <= ixmax; icol ++) { Formula_run (irow, icol, & result); target -> z [irow] [icol] = result. result.numericResult; } } } catch (MelderError) { Melder_throw (me, U": formula not completed."); } }
double PowerCepstrum_getRNR (PowerCepstrum me, double pitchFloor, double pitchCeiling, double f0fractionalWidth) { double rnr = NUMundefined; double qmin = 1.0 / pitchCeiling, qmax = 1.0 / pitchFloor, peakdB, qpeak; PowerCepstrum_getMaximumAndQuefrency (me, pitchFloor, pitchCeiling, 2, &peakdB, &qpeak); long imin, imax; if (! Matrix_getWindowSamplesX (me, qmin, qmax, & imin, & imax)) { return rnr; } long ndata = imax - imin + 1; if (ndata < 2) { return rnr; } // how many peaks in interval ? long npeaks = 2; while (qpeak > 0 && qpeak * npeaks <= qmax) { npeaks++; } npeaks--; double sum = 0, sumr = 0; for (long i = imin; i <= imax; i++) { double val = my v_getValueAtSample (i, 0, 0); double qx = my x1 + (i - 1) * my dx; sum += val; // is qx within an interval around a multiple of the peak's q ? for (long j = 1; j <= npeaks; j ++) { double f0c = 1.0 / (j * qpeak); double f0clow = f0c * (1.0 - f0fractionalWidth); double f0chigh = f0c * (1.0 + f0fractionalWidth); double qclow = 1.0 / f0chigh; double qchigh = ( f0fractionalWidth >= 1 ? qmax : 1.0 / f0clow ); if (qx >= qclow && qx <= qchigh) { // yes in rahmonic interval sumr += val; break; } } } rnr = sumr >= sum ? 1000000 : sumr / (sum - sumr); return rnr; }
void Matrix_drawRows (Matrix me, Graphics g, double xmin, double xmax, double ymin, double ymax, double minimum, double maximum) { if (xmax <= xmin) { xmin = my xmin; xmax = my xmax; } if (ymax <= ymin) { ymin = my ymin; ymax = my ymax; } long ixmin, ixmax, iymin, iymax; (void) Matrix_getWindowSamplesX (me, xmin, xmax, & ixmin, & ixmax); (void) Matrix_getWindowSamplesY (me, ymin, ymax, & iymin, & iymax); if (maximum <= minimum) (void) Matrix_getWindowExtrema (me, ixmin, ixmax, iymin, iymax, & minimum, & maximum); if (maximum <= minimum) { minimum -= 1.0; maximum += 1.0; } if (xmin >= xmax) return; Graphics_setInner (g); for (long iy = iymin; iy <= iymax; iy ++) { Graphics_setWindow (g, xmin, xmax, minimum - (iy - iymin) * (maximum - minimum), maximum + (iymax - iy) * (maximum - minimum)); Graphics_function (g, my z [iy], ixmin, ixmax, Matrix_columnToX (me, ixmin), Matrix_columnToX (me, ixmax)); } Graphics_unsetInner (g); if (iymin < iymax) Graphics_setWindow (g, xmin, xmax, my y1 + (iymin - 1.5) * my dy, my y1 + (iymax - 0.5) * my dy); }
void BandFilterSpectrogram_paintImage (BandFilterSpectrogram me, Graphics g, double xmin, double xmax, double ymin, double ymax, double minimum, double maximum, int garnish) { if (xmax <= xmin) { xmin = my xmin; xmax = my xmax; } if (ymax <= ymin) { ymin = my ymin; ymax = my ymax; } long ixmin, ixmax, iymin, iymax; (void) Matrix_getWindowSamplesX (me, xmin - 0.49999 * my dx, xmax + 0.49999 * my dx, &ixmin, &ixmax); (void) Matrix_getWindowSamplesY (me, ymin - 0.49999 * my dy, ymax + 0.49999 * my dy, &iymin, &iymax); autoMatrix thee = Spectrogram_to_Matrix_dB ((Spectrogram) me, 4e-10, 10, -100); if (maximum <= minimum) { (void) Matrix_getWindowExtrema (thee.peek(), ixmin, ixmax, iymin, iymax, &minimum, &maximum); } if (maximum <= minimum) { minimum -= 1.0; maximum += 1.0; } if (xmin >= xmax || ymin >= ymax) { return; } Graphics_setInner (g); Graphics_setWindow (g, xmin, xmax, ymin, ymax); Graphics_image (g, thy z, ixmin, ixmax, Sampled_indexToX (thee.peek(), ixmin - 0.5), Sampled_indexToX (thee.peek(), ixmax + 0.5), iymin, iymax, SampledXY_indexToY (thee.peek(), iymin - 0.5), SampledXY_indexToY (thee.peek(), iymax + 0.5), minimum, maximum); Graphics_unsetInner (g); if (garnish) { Graphics_drawInnerBox (g); Graphics_marksLeft (g, 2, 1, 1, 0); Graphics_textLeft (g, 1, Melder_cat (U"Frequency (", my v_getFrequencyUnit (), U")")); Graphics_marksBottom (g, 2, 1, 1, 0); Graphics_textBottom (g, 1, U"Time (s)"); } }
void Matrix_paintContours (Matrix me, Graphics g, double xmin, double xmax, double ymin, double ymax, double minimum, double maximum) { double border [1 + 30]; if (xmax <= xmin) { xmin = my xmin; xmax = my xmax; } if (ymax <= ymin) { ymin = my ymin; ymax = my ymax; } long ixmin, ixmax, iymin, iymax, iborder; (void) Matrix_getWindowSamplesX (me, xmin, xmax, & ixmin, & ixmax); (void) Matrix_getWindowSamplesY (me, ymin, ymax, & iymin, & iymax); if (maximum <= minimum) (void) Matrix_getWindowExtrema (me, ixmin, ixmax, iymin, iymax, & minimum, & maximum); if (maximum <= minimum) { minimum -= 1.0; maximum += 1.0; } for (iborder = 1; iborder <= 30; iborder ++) border [iborder] = minimum + iborder * (maximum - minimum) / (30 + 1); if (xmin >= xmax || ymin >= ymax) return; Graphics_setInner (g); Graphics_setWindow (g, xmin, xmax, ymin, ymax); Graphics_grey (g, my z, ixmin, ixmax, Matrix_columnToX (me, ixmin), Matrix_columnToX (me, ixmax), iymin, iymax, Matrix_rowToY (me, iymin), Matrix_rowToY (me, iymax), 30, border); Graphics_rectangle (g, xmin, xmax, ymin, ymax); Graphics_unsetInner (g); }
void Formant_formula (Formant me, double tmin, double tmax, long formantmin, long formantmax, Interpreter interpreter, wchar_t *expression) { try { long numberOfPossibleFormants = my maxnFormants; if (tmax <= tmin) { tmin = my xmin; tmax = my xmax; } if (formantmax >= formantmin) { formantmin = 1; formantmax = numberOfPossibleFormants; } formantmin = formantmin < 1 ? 1 : formantmin; formantmax = formantmax > numberOfPossibleFormants ? numberOfPossibleFormants : formantmax; autoMatrix fb = Matrix_create (my xmin, my xmax, my nx, my dx, my x1, 1.0, 2 * numberOfPossibleFormants, 2 * numberOfPossibleFormants, 1.0, 1.0); for (long iframe = 1; iframe <= my nx; iframe ++) { Formant_Frame frame = & my d_frames [iframe]; int numberOfFormants = frame -> nFormants < numberOfPossibleFormants ? frame -> nFormants : numberOfPossibleFormants; for (long iformant = 1; iformant <= numberOfFormants; iformant++) { if (iformant <= frame -> nFormants) { fb -> z[2 * iformant - 1][iframe] = frame -> formant[iformant].frequency; fb -> z[2 * iformant ][iframe] = frame -> formant[iformant].bandwidth; } } } // Apply formula double ymin = 2 * formantmin - 1, ymax = 2 * formantmax; Matrix_formula_part (fb.peek(), tmin, tmax, ymin, ymax, expression, interpreter, NULL); // Put results back in Formant long ixmin, ixmax, iymin, iymax; (void) Matrix_getWindowSamplesX (fb.peek(), tmin, tmax, & ixmin, & ixmax); (void) Matrix_getWindowSamplesY (fb.peek(), ymin, ymax, & iymin, & iymax); for (long iframe = ixmin; iframe <= ixmax; iframe++) { // if some of the formant frequencies are set to zero => remove the formant Formant_Frame frame = & my d_frames [iframe]; int numberOfFormants = frame -> nFormants < formantmax ? frame -> nFormants : formantmax; int iformantto = formantmin > 1 ? formantmin - 1 : 0; for (long iformant = formantmin; iformant <= numberOfFormants; iformant++) { double frequency = fb -> z[2 * iformant - 1][iframe]; double bandWidth = fb -> z[2 * iformant ][iframe]; if (frequency > 0 && bandWidth > 0) { iformantto++; frame -> formant[iformantto].frequency = frequency; frame -> formant[iformantto].bandwidth = bandWidth; } else { frame -> formant[iformant].frequency = frame -> formant[iformant].bandwidth = 0; } } // shift the (higher) formants down if necessary. for (long iformant = formantmax + 1; iformant <= frame -> nFormants; iformant++) { double frequency = fb -> z[2 * iformant - 1][iframe]; double bandWidth = fb -> z[2 * iformant ][iframe]; if (frequency > 0 && bandWidth > 0) { iformantto++; frame -> formant[iformantto].frequency = frequency; frame -> formant[iformantto].bandwidth = bandWidth; } else { frame -> formant[iformant].frequency = frame -> formant[iformant].bandwidth = 0; } } frame -> nFormants = iformantto; } } catch (MelderError) { Melder_throw (me, ": not filtered."); } }
Cochleagram Sound_to_Cochleagram_edb (Sound me, double dtime, double dfreq, int hasSynapse, double replenishmentRate, double lossRate, double returnRate, double reprocessingRate) { try { double duration_seconds = my xmax; if (dtime < my dx) dtime = my dx; long ntime = floor (duration_seconds / dtime + 0.5); if (ntime < 2) return NULL; long nfreq = floor (25.6 / dfreq + 0.5); // 25.6 Bark = highest frequency autoCochleagram thee = Cochleagram_create (my xmin, my xmax, ntime, dtime, 0.5 * dtime, dfreq, nfreq); /* Stages 1 and 2: outer- and middle-ear filtering. */ /* From acoustic sound to oval window. */ for (long ifreq = 1; ifreq <= nfreq; ifreq ++) { double *response = thy z [ifreq]; /* Stage 3: basilar membrane filtering by gammatones. */ /* From oval window to basilar membrane response. */ double midFrequency_Bark = (ifreq - 0.5) * dfreq; double midFrequency_Hertz = Excitation_barkToHertz (midFrequency_Bark); autoSound gammatone = createGammatone (midFrequency_Hertz, 1 / my dx); autoSound basil = Sounds_convolve (me, gammatone.peek(), kSounds_convolve_scaling_SUM, kSounds_convolve_signalOutsideTimeDomain_ZERO); /* Stage 4: detection = rectify + integrate + low-pass 500 Hz. */ /* From basilar membrane response to firing rate. */ if (hasSynapse) { double dt = my dx; double M = 1; /* Maximum free transmitter. */ double A = 5, B = 300, g = 2000; /* Determine permeability. */ double y = replenishmentRate; /* Meddis: 5.05 */ double l = lossRate, r = returnRate; /* Meddis: 2500, 6580 */ double x = reprocessingRate; /* Meddis: 66.31 */ double h = 50000; /* Convert cleft contents to firing rate. */ double gdt = 1 - exp (- g * dt), ydt = 1 - exp (- y * dt), ldt = (1 - exp (- (l + r) * dt)) * l / (l + r), rdt = (1 - exp (- (l + r) * dt)) * r / (l + r), xdt = 1 - exp (- x * dt); double kt = g * A / (A + B); /* Membrane permeability. */ double c = M * y * kt / (l * kt + y * (l + r)); /* Cleft contents. */ double q = c * (l + r) / kt; /* Free transmitter. */ double w = c * r / x; /* Reprocessing store. */ for (long itime = 1; itime <= basil -> nx; itime ++) { double splusA = basil -> z [1] [itime] * 10 + A; double replenish = M > q ? ydt * (M - q) : 0; double eject, loss, reuptake, reprocess; kt = splusA > 0 ? gdt * splusA / (splusA + B) : 0; eject = kt * q; loss = ldt * c; reuptake = rdt * c; reprocess = xdt * w; q = q + replenish - eject + reprocess; c = c + eject - loss - reuptake; w = w + reuptake - reprocess; basil -> z [1] [itime] = h * c; } } if (dtime == my dx) { for (long itime = 1; itime <= ntime; itime ++) response [itime] = basil -> z [1] [itime]; } else { double d = dtime / basil -> dx / 2; double factor = -6 / d / d; double area = d * sqrt (NUMpi / 6); double expmin6 = exp (-6), onebyoneminexpmin6 = 1 / (1 - expmin6); for (long itime = 1; itime <= ntime; itime ++) { double t1 = (itime - 1) * dtime, t2 = t1 + dtime, mean = 0; long i1, i2; long n = Matrix_getWindowSamplesX (basil.peek(), t1, t2, & i1, & i2); Melder_assert (n >= 1); if (n <= 2) { for (long isamp = i1; isamp <= i2; isamp ++) mean += basil -> z [1] [isamp]; mean /= n; } else { double mu = floor ((i1 + i2) / 2.0); long muint = mu, dint = d; for (long isamp = muint - dint; isamp <= muint + dint; isamp ++) { double y = 0; if (isamp < 1 || isamp > basil -> nx) Melder_casual ("isamp %ld", isamp); else y = basil -> z [1] [isamp]; mean += y * onebyoneminexpmin6 * (exp (factor * (isamp - muint) * (isamp - muint)) - expmin6); } mean /= area; } response [itime] = mean; } } } return thee.transfer(); } catch (MelderError) { Melder_throw (me, ": not converted to Cochleagram (edb)."); } }
void Vector_draw (Vector me, Graphics g, double *pxmin, double *pxmax, double *pymin, double *pymax, double defaultDy, const char32 *method) { bool xreversed = *pxmin > *pxmax, yreversed = *pymin > *pymax; if (xreversed) { double temp = *pxmin; *pxmin = *pxmax; *pxmax = temp; } if (yreversed) { double temp = *pymin; *pymin = *pymax; *pymax = temp; } long ixmin, ixmax, ix; /* * Automatic domain. */ if (*pxmin == *pxmax) { *pxmin = my xmin; *pxmax = my xmax; } /* * Domain expressed in sample numbers. */ Matrix_getWindowSamplesX (me, *pxmin, *pxmax, & ixmin, & ixmax); /* * Automatic vertical range. */ if (*pymin == *pymax) { Matrix_getWindowExtrema (me, ixmin, ixmax, 1, 1, pymin, pymax); if (*pymin == *pymax) { *pymin -= defaultDy; *pymax += defaultDy; } } /* * Set coordinates for drawing. */ Graphics_setInner (g); Graphics_setWindow (g, xreversed ? *pxmax : *pxmin, xreversed ? *pxmin : *pxmax, yreversed ? *pymax : *pymin, yreversed ? *pymin : *pymax); if (str32str (method, U"bars") || str32str (method, U"Bars")) { for (ix = ixmin; ix <= ixmax; ix ++) { double x = Sampled_indexToX (me, ix); double y = my z [1] [ix]; double left = x - 0.5 * my dx, right = x + 0.5 * my dx; if (y > *pymax) y = *pymax; if (left < *pxmin) left = *pxmin; if (right > *pxmax) right = *pxmax; if (y > *pymin) { Graphics_line (g, left, y, right, y); Graphics_line (g, left, y, left, *pymin); Graphics_line (g, right, y, right, *pymin); } } } else if (str32str (method, U"poles") || str32str (method, U"Poles")) { for (ix = ixmin; ix <= ixmax; ix ++) { double x = Sampled_indexToX (me, ix); Graphics_line (g, x, 0, x, my z [1] [ix]); } } else if (str32str (method, U"speckles") || str32str (method, U"Speckles")) { for (ix = ixmin; ix <= ixmax; ix ++) { double x = Sampled_indexToX (me, ix); Graphics_speckle (g, x, my z [1] [ix]); } } else { /* * The default: draw as a curve. */ Graphics_function (g, my z [1], ixmin, ixmax, Matrix_columnToX (me, ixmin), Matrix_columnToX (me, ixmax)); } Graphics_unsetInner (g); }
void Sound_draw (Sound me, Graphics g, double tmin, double tmax, double minimum, double maximum, bool garnish, const char32 *method) { long ixmin, ixmax; bool treversed = tmin > tmax; if (treversed) { double temp = tmin; tmin = tmax; tmax = temp; } /* * Automatic domain. */ if (tmin == tmax) { tmin = my xmin; tmax = my xmax; } /* * Domain expressed in sample numbers. */ Matrix_getWindowSamplesX (me, tmin, tmax, & ixmin, & ixmax); /* * Automatic vertical range. */ if (minimum == maximum) { Matrix_getWindowExtrema (me, ixmin, ixmax, 1, my ny, & minimum, & maximum); if (minimum == maximum) { minimum -= 1.0; maximum += 1.0; } } /* * Set coordinates for drawing. */ Graphics_setInner (g); for (long channel = 1; channel <= my ny; channel ++) { Graphics_setWindow (g, treversed ? tmax : tmin, treversed ? tmin : tmax, minimum - (my ny - channel) * (maximum - minimum), maximum + (channel - 1) * (maximum - minimum)); if (str32str (method, U"bars") || str32str (method, U"Bars")) { for (long ix = ixmin; ix <= ixmax; ix ++) { double x = Sampled_indexToX (me, ix); double y = my z [channel] [ix]; double left = x - 0.5 * my dx, right = x + 0.5 * my dx; if (y > maximum) y = maximum; if (left < tmin) left = tmin; if (right > tmax) right = tmax; Graphics_line (g, left, y, right, y); Graphics_line (g, left, y, left, minimum); Graphics_line (g, right, y, right, minimum); } } else if (str32str (method, U"poles") || str32str (method, U"Poles")) { for (long ix = ixmin; ix <= ixmax; ix ++) { double x = Sampled_indexToX (me, ix); Graphics_line (g, x, 0, x, my z [channel] [ix]); } } else if (str32str (method, U"speckles") || str32str (method, U"Speckles")) { for (long ix = ixmin; ix <= ixmax; ix ++) { double x = Sampled_indexToX (me, ix); Graphics_speckle (g, x, my z [channel] [ix]); } } else { /* * The default: draw as a curve. */ Graphics_function (g, my z [channel], ixmin, ixmax, Matrix_columnToX (me, ixmin), Matrix_columnToX (me, ixmax)); } } Graphics_setWindow (g, treversed ? tmax : tmin, treversed ? tmin : tmax, minimum, maximum); if (garnish && my ny == 2) Graphics_line (g, tmin, 0.5 * (minimum + maximum), tmax, 0.5 * (minimum + maximum)); Graphics_unsetInner (g); if (garnish) { Graphics_drawInnerBox (g); Graphics_textBottom (g, 1, U"Time (s)"); Graphics_marksBottom (g, 2, 1, 1, 0); Graphics_setWindow (g, tmin, tmax, minimum - (my ny - 1) * (maximum - minimum), maximum); Graphics_markLeft (g, minimum, 1, 1, 0, NULL); Graphics_markLeft (g, maximum, 1, 1, 0, NULL); if (minimum != 0.0 && maximum != 0.0 && (minimum > 0.0) != (maximum > 0.0)) { Graphics_markLeft (g, 0.0, 1, 1, 1, NULL); } if (my ny == 2) { Graphics_setWindow (g, treversed ? tmax : tmin, treversed ? tmin : tmax, minimum, maximum + (my ny - 1) * (maximum - minimum)); Graphics_markRight (g, minimum, 1, 1, 0, NULL); Graphics_markRight (g, maximum, 1, 1, 0, NULL); if (minimum != 0.0 && maximum != 0.0 && (minimum > 0.0) != (maximum > 0.0)) { Graphics_markRight (g, 0.0, 1, 1, 1, NULL); } } } }
void PowerCepstrum_drawTiltLine (PowerCepstrum me, Graphics g, double qmin, double qmax, double dBminimum, double dBmaximum, double qstart, double qend, int lineType, int method) { Graphics_setInner (g); if (qmax <= qmin) { qmin = my xmin; qmax = my xmax; } if (dBminimum >= dBmaximum) { // autoscaling long imin, imax; if (! Matrix_getWindowSamplesX (me, qmin, qmax, & imin, & imax)) { return; } long numberOfPoints = imax - imin + 1; dBminimum = dBmaximum = my v_getValueAtSample (imin, 1, 0); for (long i = 2; i <= numberOfPoints; i++) { long isamp = imin + i - 1; double y = my v_getValueAtSample (isamp, 1, 0); dBmaximum = y > dBmaximum ? y : dBmaximum; dBminimum = y < dBminimum ? y : dBminimum; } } Graphics_setWindow (g, qmin, qmax, dBminimum, dBmaximum); qend = qend == 0 ? my xmax : qend; if (qend <= qstart) { qend = my xmax; qstart = my xmin; } qstart = qstart < my xmin ? my xmin : qstart; qend = qend > my xmax ? my xmax : qend; double a, intercept; PowerCepstrum_fitTiltLine (me, qstart, qend, &a, &intercept, lineType, method); /* * Don't draw part outside window */ double lineWidth = Graphics_inqLineWidth (g); Graphics_setLineWidth (g, 2); if (lineType == 2) { long n = 500; double dq = (qend - qstart) / (n + 1); double q1 = qstart; if (qstart <= 0) { qstart = 0.1 * dq; // some small offset to avoid log(0) n--; } autoNUMvector<double> y (1, n); for (long i = 1; i <= n; i++) { double q = q1 + (i - 1) * dq; y[i] = a * log (q) + intercept; } Graphics_function (g, y.peek(), 1, n, qstart, qend); } else { double y1 = a * qstart + intercept, y2 = a * qend + intercept; if (y1 >= dBminimum && y2 >= dBminimum) { Graphics_line (g, qstart, y1, qend, y2); } else if (y1 < dBminimum) { qstart = (dBminimum - intercept) / a; Graphics_line (g, qstart, dBminimum, qend, y2); } else if (y2 < dBminimum) { qend = (dBminimum - intercept) / a; Graphics_line (g, qstart, y1, qend, dBminimum); } else { // don't draw anything below lower limit? } } Graphics_setLineWidth (g, lineWidth); Graphics_unsetInner (g); }
void Matrix_drawDistribution (Matrix me, Graphics g, double xmin, double xmax, double ymin, double ymax, double minimum, double maximum, long nBins, double freqMin, double freqMax, bool cumulative, bool garnish) { if (nBins <= 0) { return; } if (xmax <= xmin) { xmin = my xmin; xmax = my xmax; } if (ymax <= ymin) { ymin = my ymin; ymax = my ymax; } long ixmin, ixmax, iymin, iymax; if ((Matrix_getWindowSamplesX (me, xmin, xmax, & ixmin, & ixmax) == 0) || (Matrix_getWindowSamplesY (me, ymin, ymax, & iymin, & iymax) == 0)) { return; } if (maximum <= minimum) { Matrix_getWindowExtrema (me, ixmin, ixmax, iymin, iymax, & minimum, & maximum); } if (maximum <= minimum) { minimum -= 1.0; maximum += 1.0; } // Count the numbers per bin and the total if (nBins < 1) { nBins = 10; } autoNUMvector<long> freq (1, nBins); double binWidth = (maximum - minimum) / nBins; long nxy = 0; for (long i = iymin; i <= iymax; i++) { for (long j = ixmin; j <= ixmax; j++) { long bin = 1 + (long) floor ( (my z[i][j] - minimum) / binWidth); if (bin <= nBins && bin > 0) { freq[bin]++; nxy ++; } } } if (freqMax <= freqMin) { if (cumulative) { freqMin = 0; freqMax = 1.0; } else { NUMvector_extrema (freq.peek(), 1, nBins, & freqMin, & freqMax); if (freqMax <= freqMin) { freqMin = freqMin > 1.0 ? freqMin - 1.0 : 0.0; freqMax += 1.0; } } } Graphics_setInner (g); Graphics_setWindow (g, minimum, maximum, freqMin, freqMax); double fi = 0.0; for (long i = 1; i <= nBins; i++) { double ftmp = freq[i]; fi = cumulative ? fi + freq[i] / nxy : freq[i]; ftmp = fi; if (ftmp > freqMax) { ftmp = freqMax; } if (ftmp > freqMin) { Graphics_rectangle (g, minimum + (i - 1) * binWidth, minimum + i * binWidth, freqMin, ftmp); } } Graphics_unsetInner (g); if (garnish) { Graphics_drawInnerBox (g); Graphics_marksBottom (g, 2, true, true, false); Graphics_marksLeft (g, 2, true, true, false); if (! cumulative) { Graphics_textLeft (g, true, U"Number/bin"); } } }