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 GaussianMixture_drawMarginalPdf (GaussianMixture me, Graphics g, long d, double xmin, double xmax, double ymin, double ymax, long npoints, long nbins, int garnish) { if (d < 1 || d > my dimension) { Melder_warning1 (L"Dimension doesn't agree."); return;} if (npoints <= 1) npoints = 1000; double *p = NUMdvector (1, npoints); if (p == 0) return; double nsigmas = 2, *v = NUMdvector (1, my dimension); if (v == NULL) goto end; if (xmax <= xmin && ! GaussianMixture_getIntervalAlongDirection (me, d, nsigmas, &xmin, &xmax)) goto end; { double pmax = 0, dx = (xmax - xmin) / (npoints - 1); double scalef = nbins <= 0 ? 1 : 1; // TODO for (long i = 1; i <= npoints; i++) { double x = xmin + (i - 1) * dx; for (long k = 1; k <= my dimension; k++) v[k] = k == d ? 1 : 0; p[i] = scalef * GaussianMixture_getMarginalProbabilityAtPosition (me, v, x); if (p[i] > pmax) pmax = p[i]; } if (ymin >= ymax) { ymin = 0; ymax = pmax; } Graphics_setInner (g); Graphics_setWindow (g, xmin, xmax, ymin, ymax); Graphics_function (g, p, 1, npoints, xmin, xmax); Graphics_unsetInner (g); if (garnish) { Graphics_drawInnerBox (g); Graphics_markBottom (g, xmin, 1, 1, 0, NULL); Graphics_markBottom (g, xmax, 1, 1, 0, NULL); Graphics_markLeft (g, ymin, 1, 1, 0, NULL); Graphics_markLeft (g, ymax, 1, 1, 0, NULL); } } end: NUMdvector_free (p, 1); NUMdvector_free (v, 1); }
void TextGrid_Pitch_drawSeparately (TextGrid grid, Pitch pitch, Graphics g, double tmin, double tmax, double fmin, double fmax, int showBoundaries, int useTextStyles, int garnish, int speckle, int unit) { int ntier = grid -> tiers -> size; if (tmax <= tmin) tmin = grid -> xmin, tmax = grid -> xmax; if (Function_isUnitLogarithmic (pitch, Pitch_LEVEL_FREQUENCY, unit)) { fmin = Function_convertStandardToSpecialUnit (pitch, fmin, Pitch_LEVEL_FREQUENCY, unit); fmax = Function_convertStandardToSpecialUnit (pitch, fmax, Pitch_LEVEL_FREQUENCY, unit); } if (unit == kPitch_unit_HERTZ_LOGARITHMIC) Pitch_draw (pitch, g, tmin, tmax, pow (10, fmin - 0.25 * (fmax - fmin) * ntier), pow (10, fmax), FALSE, speckle, unit); else Pitch_draw (pitch, g, tmin, tmax, fmin - 0.25 * (fmax - fmin) * ntier, fmax, FALSE, speckle, unit); TextGrid_Sound_draw (grid, NULL, g, tmin, tmax, showBoundaries, useTextStyles, FALSE); /* * Restore window for the sake of margin drawing. */ Graphics_setWindow (g, tmin, tmax, fmin - 0.25 * (fmax - fmin) * ntier, fmax); if (unit == kPitch_unit_HERTZ_LOGARITHMIC) fmin = pow (10, fmin), fmax = pow (10, fmax); if (garnish) { Graphics_drawInnerBox (g); if (unit == kPitch_unit_HERTZ_LOGARITHMIC) { Graphics_markLeftLogarithmic (g, fmin, TRUE, TRUE, FALSE, NULL); Graphics_markLeftLogarithmic (g, fmax, TRUE, TRUE, FALSE, NULL); autoMarks_logarithmic (g, fmin, fmax, FALSE); } else if (unit == kPitch_unit_SEMITONES_100) { Graphics_markLeft (g, fmin, TRUE, TRUE, FALSE, NULL); Graphics_markLeft (g, fmax, TRUE, TRUE, FALSE, NULL); autoMarks_semitones (g, fmin, fmax, FALSE); } else { Graphics_markLeft (g, fmin, TRUE, TRUE, FALSE, NULL); Graphics_markLeft (g, fmax, TRUE, TRUE, FALSE, NULL); autoMarks (g, fmin, fmax, FALSE); } static MelderString buffer = { 0 }; MelderString_empty (& buffer); MelderString_append (& buffer, L"Pitch (", Function_getUnitText (pitch, Pitch_LEVEL_FREQUENCY, unit, Function_UNIT_TEXT_GRAPHICAL), L")"); Graphics_textLeft (g, true, buffer.string); Graphics_textBottom (g, true, L"Time (s)"); Graphics_marksBottom (g, 2, true, true, true); } }
static void autoMarks_semitones (Graphics g, double ymin, double ymax, bool haveDottedLines) { double dy = ymax - ymin; if (dy < 16) { long imin = ceil ((ymin + 1.2) / 3.0), imax = floor ((ymax - 1.2) / 3.0); for (long i = imin; i <= imax; i ++) Graphics_markLeft (g, i * 3, TRUE, TRUE, haveDottedLines, NULL); } else if (dy < 32) { long imin = ceil ((ymin + 2.4) / 6.0), imax = floor ((ymax - 2.4) / 6.0); for (long i = imin; i <= imax; i ++) Graphics_markLeft (g, i * 6, TRUE, TRUE, haveDottedLines, NULL); } else if (dy < 64) { long imin = ceil ((ymin + 4.8) / 12.0), imax = floor ((ymax - 4.8) / 12.0); for (long i = imin; i <= imax; i ++) Graphics_markLeft (g, i * 12, TRUE, TRUE, haveDottedLines, NULL); } else if (dy < 128) { long imin = ceil ((ymin + 9.6) / 24.0), imax = floor ((ymax - 9.6) / 24.0); for (long i = imin; i <= imax; i ++) Graphics_markLeft (g, i * 24, TRUE, TRUE, haveDottedLines, NULL); } }
static void autoMarks (Graphics g, double ymin, double ymax, bool haveDottedLines) { double dy = ymax - ymin; if (dy < 26.0) { long imin = (long) ceil ((ymin + 2.0) / 5.0), imax = (long) floor ((ymax - 2.0) / 5.0); for (long i = imin; i <= imax; i ++) Graphics_markLeft (g, i * 5.0, true, true, haveDottedLines, nullptr); } else if (dy < 110.0) { long imin = (long) ceil ((ymin + 8.0) / 20.0), imax = (long) floor ((ymax - 8.0) / 20.0); for (long i = imin; i <= imax; i ++) Graphics_markLeft (g, i * 20.0, true, true, haveDottedLines, nullptr); } else if (dy < 260.0) { long imin = (long) ceil ((ymin + 20.0) / 50.0), imax = (long) floor ((ymax - 20.0) / 50.0); for (long i = imin; i <= imax; i ++) Graphics_markLeft (g, i * 50.0, true, true, haveDottedLines, nullptr); } else if (dy < 510.0) { long imin = (long) ceil ((ymin + 40.0) / 100.0), imax = (long) floor ((ymax - 40.0) / 100.0); for (long i = imin; i <= imax; i ++) Graphics_markLeft (g, i * 100.0, true, true, haveDottedLines, nullptr); } }
static void autoMarks (Graphics g, double ymin, double ymax, bool haveDottedLines) { double dy = ymax - ymin; if (dy < 26) { long imin = ceil ((ymin + 2.0) / 5.0), imax = floor ((ymax - 2.0) / 5.0); for (long i = imin; i <= imax; i ++) Graphics_markLeft (g, i * 5, TRUE, TRUE, haveDottedLines, NULL); } else if (dy < 110) { long imin = ceil ((ymin + 8.0) / 20.0), imax = floor ((ymax - 8.0) / 20.0); for (long i = imin; i <= imax; i ++) Graphics_markLeft (g, i * 20, TRUE, TRUE, haveDottedLines, NULL); } else if (dy < 260) { long imin = ceil ((ymin + 20.0) / 50.0), imax = floor ((ymax - 20.0) / 50.0); for (long i = imin; i <= imax; i ++) Graphics_markLeft (g, i * 50, TRUE, TRUE, haveDottedLines, NULL); } else if (dy < 510) { long imin = ceil ((ymin + 40.0) / 100.0), imax = floor ((ymax - 40.0) / 100.0); for (long i = imin; i <= imax; i ++) Graphics_markLeft (g, i * 100, TRUE, TRUE, haveDottedLines, NULL); } }
void GaussianMixture_and_PCA_drawMarginalPdf (GaussianMixture me, PCA thee, Graphics g, long d, double xmin, double xmax, double ymin, double ymax, long npoints, long nbins, int garnish) { if (my dimension != thy dimension || d < 1 || d > my dimension) { Melder_warning1 (L"Dimensions don't agree."); return;} if (npoints <= 1) npoints = 1000; double *p = NUMdvector (1, npoints); if (p == 0) return; double nsigmas = 2; if (xmax <= xmin && ! GaussianMixture_and_PCA_getIntervalAlongDirection (me, thee, d, nsigmas, &xmin, &xmax)) goto end; { double pmax = 0, dx = (xmax - xmin) / npoints, x1 = xmin + 0.5 * dx; double scalef = nbins <= 0 ? 1 : 1; // TODO for (long i = 1; i <= npoints; i++) { double x = x1 + (i - 1) * dx; p[i] = scalef * GaussianMixture_getMarginalProbabilityAtPosition (me, thy eigenvectors[d], x); if (p[i] > pmax) pmax = p[i]; } if (ymin >= ymax) { ymin = 0; ymax = pmax; } Graphics_setInner (g); Graphics_setWindow (g, xmin, xmax, ymin, ymax); Graphics_function (g, p, 1, npoints, x1, xmax - 0.5 * dx); Graphics_unsetInner (g); if (garnish) { Graphics_drawInnerBox (g); Graphics_markBottom (g, xmin, 1, 1, 0, NULL); Graphics_markBottom (g, xmax, 1, 1, 0, NULL); Graphics_markLeft (g, ymin, 1, 1, 0, NULL); Graphics_markLeft (g, ymax, 1, 1, 0, NULL); } } end: NUMdvector_free (p, 1); }
void TextGrid_Pitch_drawSeparately (TextGrid grid, Pitch pitch, Graphics g, double tmin, double tmax, double fmin, double fmax, bool showBoundaries, bool useTextStyles, bool garnish, bool speckle, int unit) { int ntier = grid -> tiers->size; if (tmax <= tmin) tmin = grid -> xmin, tmax = grid -> xmax; if (Function_isUnitLogarithmic (pitch, Pitch_LEVEL_FREQUENCY, unit)) { fmin = Function_convertStandardToSpecialUnit (pitch, fmin, Pitch_LEVEL_FREQUENCY, unit); fmax = Function_convertStandardToSpecialUnit (pitch, fmax, Pitch_LEVEL_FREQUENCY, unit); } if (unit == kPitch_unit_HERTZ_LOGARITHMIC) Pitch_draw (pitch, g, tmin, tmax, pow (10.0, fmin - 0.25 * (fmax - fmin) * ntier), pow (10.0, fmax), false, speckle, unit); else Pitch_draw (pitch, g, tmin, tmax, fmin - 0.25 * (fmax - fmin) * ntier, fmax, false, speckle, unit); TextGrid_Sound_draw (grid, nullptr, g, tmin, tmax, showBoundaries, useTextStyles, false); /* * Restore window for the sake of margin drawing. */ Graphics_setWindow (g, tmin, tmax, fmin - 0.25 * (fmax - fmin) * ntier, fmax); if (unit == kPitch_unit_HERTZ_LOGARITHMIC) fmin = pow (10, fmin), fmax = pow (10.0, fmax); if (garnish) { Graphics_drawInnerBox (g); if (unit == kPitch_unit_HERTZ_LOGARITHMIC) { Graphics_markLeftLogarithmic (g, fmin, true, true, false, nullptr); Graphics_markLeftLogarithmic (g, fmax, true, true, false, nullptr); autoMarks_logarithmic (g, fmin, fmax, false); } else if (unit == kPitch_unit_SEMITONES_100) { Graphics_markLeft (g, fmin, true, true, false, nullptr); Graphics_markLeft (g, fmax, true, true, false, nullptr); autoMarks_semitones (g, fmin, fmax, false); } else { Graphics_markLeft (g, fmin, true, true, false, nullptr); Graphics_markLeft (g, fmax, true, true, false, nullptr); autoMarks (g, fmin, fmax, false); } Graphics_textLeft (g, true, Melder_cat (U"Pitch (", Function_getUnitText (pitch, Pitch_LEVEL_FREQUENCY, unit, Function_UNIT_TEXT_GRAPHICAL), U")")); Graphics_textBottom (g, true, U"Time (s)"); Graphics_marksBottom (g, 2, true, true, false); } }
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 Matrix_scatterPlot (Matrix me, Graphics g, long icx, long icy, double xmin, double xmax, double ymin, double ymax, double size_mm, const char32 *mark, int garnish) { long ix = labs (icx), iy = labs (icy); if (ix < 1 || ix > my nx || iy < 1 || iy > my nx) { return; } if (xmax <= xmin) { (void) Matrix_getWindowExtrema (me, ix, ix, 1, my ny, & xmin, & xmax); if (xmax <= xmin) { xmin -= 0.5; xmax += 0.5; } } if (ymax <= ymin) { (void) Matrix_getWindowExtrema (me, iy, iy, 1, my ny, & ymin, & ymax); if (ymax <= ymin) { ymin -= 0.5; ymax += 0.5; } } Graphics_setInner (g); if (icx < 0) { double t = xmin; xmin = xmax; xmax = t; } if (icy < 0) { double t = ymin; ymin = ymax; ymax = t; } Graphics_setWindow (g, xmin, xmax, ymin, ymax); for (long i = 1; i <= my ny; i++) { if (my z[i][ix] >= xmin && my z[i][ix] <= xmax && my z[i][iy] >= ymin && my z[i][iy] <= ymax) { Graphics_mark (g, my z[i][ix], my z[i][iy], size_mm, mark); } } 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 Polygon_Categories_draw (Polygon me, thou, Graphics graphics, double xmin, double xmax, double ymin, double ymax, int garnish) { thouart (Categories); double min, max, tmp; if (my numberOfPoints != thy size) { return; } if (xmax == xmin) { NUMvector_extrema (my x, 1, my numberOfPoints, & min, & max); tmp = max - min == 0 ? 0.5 : 0.0; xmin = min - tmp; xmax = max + tmp; } if (ymax == ymin) { NUMvector_extrema (my y, 1, my numberOfPoints, & min, & max); tmp = max - min == 0 ? 0.5 : 0.0; ymin = min - tmp; ymax = max + tmp; } Graphics_setInner (graphics); Graphics_setWindow (graphics, xmin, xmax, ymin, ymax); Graphics_setTextAlignment (graphics, Graphics_CENTRE, Graphics_HALF); for (long i = 1; i <= my numberOfPoints; i++) { OrderedOfString_drawItem (thee, graphics, i, my x[i], my y[i]); } Graphics_unsetInner (graphics); if (garnish) { Graphics_drawInnerBox (graphics); Graphics_marksLeft (graphics, 2, 1, 1, 0); if (ymin * ymax < 0.0) { Graphics_markLeft (graphics, 0.0, 1, 1, 1, NULL); } Graphics_marksBottom (graphics, 2, 1, 1, 0); if (xmin * xmax < 0.0) { Graphics_markBottom (graphics, 0.0, 1, 1, 1, NULL); } } }
void TableOfReal_drawAsSquares (TableOfReal me, Graphics graphics, long rowmin, long rowmax, long colmin, long colmax, int garnish) { double dx = 1, dy = 1; Graphics_Colour colour = Graphics_inqColour (graphics); fixRows (me, & rowmin, & rowmax); fixColumns (me, & colmin, & colmax); Graphics_setInner (graphics); Graphics_setWindow (graphics, colmin - 0.5, colmax + 0.5, rowmin - 0.5, rowmax + 0.5); double datamax = my data [rowmin] [colmin]; for (long irow = 1; irow <= my numberOfRows; irow ++) for (long icol = 1; icol <= my numberOfColumns; icol ++) if (fabs (my data [irow] [icol]) > datamax) datamax = fabs (my data [irow] [icol]); for (long irow = rowmin; irow <= rowmax; irow ++) { double y = rowmax + rowmin - irow; for (long icol = colmin; icol <= colmax; icol ++) { double x = icol; /* two neighbouring squares should not touch -> 0.95 */ double d = 0.95 * sqrt (fabs (my data [irow] [icol]) / datamax); double x1WC = x - d * dx / 2, x2WC = x + d * dx / 2; double y1WC = y - d * dy / 2, y2WC = y + d * dy / 2; if (my data [irow] [icol] > 0) Graphics_setColour (graphics, Graphics_WHITE); Graphics_fillRectangle (graphics, x1WC, x2WC, y1WC, y2WC); Graphics_setColour (graphics, colour); Graphics_rectangle (graphics, x1WC, x2WC , y1WC, y2WC); } } Graphics_setGrey (graphics, 0.0); Graphics_unsetInner (graphics); if (garnish) { for (long irow = rowmin; irow <= rowmax; irow ++) if (my rowLabels [irow]) Graphics_markLeft (graphics, rowmax + rowmin - irow, 0, 0, 0, my rowLabels [irow]); for (long icol = colmin; icol <= colmax; icol ++) if (my columnLabels [icol]) Graphics_markTop (graphics, icol, 0, 0, 0, my columnLabels [icol]); } }
void Confusion_Matrix_draw (Confusion me, Matrix thee, Graphics g, long index, double lowerPercentage, double xmin, double xmax, double ymin, double ymax, int garnish) { long ib = 1, ie = my numberOfRows; if (index > 0 && index <= my numberOfColumns) { ib = ie = index; } if (thy ny != my numberOfRows) { Melder_throw (U"Wrong number of positions."); } if (xmax <= xmin) { (void) Matrix_getWindowExtrema (thee, 1, 1, 1, thy ny, &xmin, &xmax); } if (xmax <= xmin) { return; } if (ymax <= ymin) { (void) Matrix_getWindowExtrema (thee, 2, 2, 1, thy ny, &ymin, &ymax); } if (ymax <= ymin) { return; } double rmax = fabs (xmax - xmin) / 10.0; double rmin = rmax / 10; Graphics_setInner (g); Graphics_setWindow (g, xmin - rmax, xmax + rmax, ymin - rmax, ymax + rmax); Graphics_setTextAlignment (g, Graphics_CENTRE, Graphics_HALF); for (long i = 1; i <= my numberOfRows; i++) { Graphics_text (g, thy z[i][1], thy z[i][2], my rowLabels[i]); } for (long i = ib; i <= ie; i++) { double xSum = 0.0; for (long j = 1; j <= my numberOfColumns; j++) { xSum += my data[i][j]; } if (xSum <= 0.0) { continue; /* no confusions */ } double x1 = thy z[i][1]; double y1 = thy z[i][2]; double r = rmax * my data[i][i] / xSum; Graphics_circle (g, x1, y1, r > rmin ? r : rmin); for (long j = 1; j <= my numberOfColumns; j++) { double x2 = thy z[j][1], y2 = thy z[j][2]; double perc = 100.0 * my data[i][j] / xSum; double dx = x2 - x1, dy = y2 - y1; double alpha = atan2 (dy, dx); if (perc == 0.0 || perc < lowerPercentage || j == i) { continue; } xmin = x1; xmax = x2; if (x2 < x1) { xmin = x2; xmax = x1; } ymin = y1; xmax = y2; if (y2 < y1) { ymin = y2; ymax = y1; } autoPolygon p = Polygon_createPointer(); double xs = sqrt (dx * dx + dy * dy) - 2.2 * r; if (xs < 0.0) { xs = 0.0; } double ys = perc * rmax / 100.0; Polygon_scale (p.get(), xs, ys); Polygon_translate (p.get(), x1, y1 - ys / 2); Polygon_rotate (p.get(), alpha, x1, y1); Polygon_translate (p.get(), 1.1 * r * cos (alpha), 1.1 * r * sin (alpha)); Polygon_drawInside (p.get(), g); } } Graphics_unsetInner (g); if (garnish) { Graphics_drawInnerBox (g); Graphics_marksBottom (g, 2, true, true, false); if (ymin * ymax < 0.0) { Graphics_markLeft (g, 0.0, true, true, true, nullptr); } Graphics_marksLeft (g, 2, true, true, false); if (xmin * xmax < 0.0) { Graphics_markBottom (g, 0.0, true, true, true, nullptr); } } }
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); } } } }