Table ERP_tabulate (ERP me, bool includeSampleNumbers, bool includeTime, int timeDecimals, int voltageDecimals, int units) { double voltageScaling = 1.0; const wchar_t *unitText = L"(V)"; if (units == 2) { voltageDecimals -= 6; voltageScaling = 1000000.0; unitText = L"(uV)"; } try { autoTable thee = Table_createWithoutColumnNames (my nx, includeSampleNumbers + includeTime + my ny); long icol = 0; if (includeSampleNumbers) Table_setColumnLabel (thee.peek(), ++ icol, L"sample"); if (includeTime) Table_setColumnLabel (thee.peek(), ++ icol, L"time(s)"); for (long ichan = 1; ichan <= my ny; ichan ++) { Table_setColumnLabel (thee.peek(), ++ icol, Melder_wcscat (my channelNames [ichan], unitText)); } for (long isamp = 1; isamp <= my nx; isamp ++) { icol = 0; if (includeSampleNumbers) Table_setNumericValue (thee.peek(), isamp, ++ icol, isamp); if (includeTime) Table_setStringValue (thee.peek(), isamp, ++ icol, Melder_fixed (my x1 + (isamp - 1) * my dx, timeDecimals)); for (long ichan = 1; ichan <= my ny; ichan ++) { Table_setStringValue (thee.peek(), isamp, ++ icol, Melder_fixed (voltageScaling * my z [ichan] [isamp], voltageDecimals)); } } return thee.transfer(); } catch (MelderError) { Melder_throw (me, ": not converted to Table."); } }
static void drawWhileDragging (FormantGridEditor me, double xWC, double yWC, long first, long last, double dt, double dy) { FormantGrid grid = (FormantGrid) my data; Ordered tiers = my editingBandwidths ? grid -> bandwidths : grid -> formants; RealTier tier = (RealTier) tiers -> item [my selectedFormant]; double ymin = my editingBandwidths ? my p_bandwidthFloor : my p_formantFloor; double ymax = my editingBandwidths ? my p_bandwidthCeiling : my p_formantCeiling; (void) xWC; (void) yWC; /* * Draw all selected points as magenta empty circles, if inside the window. */ for (long i = first; i <= last; i ++) { RealPoint point = (RealPoint) tier -> points -> item [i]; double t = point -> number + dt, y = point -> value + dy; if (t >= my d_startWindow && t <= my d_endWindow) Graphics_circle_mm (my d_graphics, t, y, 3); } if (last == first) { /* * Draw a crosshair with time and y. */ RealPoint point = (RealPoint) tier -> points -> item [first]; double t = point -> number + dt, y = point -> value + dy; Graphics_line (my d_graphics, t, ymin, t, ymax - Graphics_dyMMtoWC (my d_graphics, 4.0)); Graphics_setTextAlignment (my d_graphics, kGraphics_horizontalAlignment_CENTRE, Graphics_TOP); Graphics_text (my d_graphics, t, ymax, Melder_fixed (t, 6)); Graphics_line (my d_graphics, my d_startWindow, y, my d_endWindow, y); Graphics_setTextAlignment (my d_graphics, Graphics_LEFT, Graphics_BOTTOM); Graphics_text (my d_graphics, my d_startWindow, y, Melder_fixed (y, 6)); } }
void structOTMultiEditor :: v_draw () { OTMulti grammar = (OTMulti) data; static MelderString buffer { 0 }; double rowHeight = 0.25, tableauHeight = 2 * rowHeight; Graphics_clearWs (g); HyperPage_listItem (this, U"\t\t %%ranking value\t %disharmony\t %plasticity"); for (long icons = 1; icons <= grammar -> numberOfConstraints; icons ++) { OTConstraint constraint = & grammar -> constraints [grammar -> index [icons]]; MelderString_copy (& buffer, U"\t", ( icons == selectedConstraint ? U"♠︎ " : U" " ), U"@@", icons, U"|", constraint -> name, U"@\t ", Melder_fixed (constraint -> ranking, 3), U"\t ", Melder_fixed (constraint -> disharmony, 3), U"\t ", Melder_fixed (constraint -> plasticity, 6) ); HyperPage_listItem (this, buffer.string); } Graphics_setAtSignIsLink (g, FALSE); drawTableau_grammar = grammar; for (long icand = 1; icand <= grammar -> numberOfCandidates; icand ++) { if (OTMulti_candidateMatches (grammar, icand, form1, form2)) { tableauHeight += rowHeight; } } drawTableau_form1 = form1; drawTableau_form2 = form2; drawTableau_constraintsAreDrawnVertically = d_constraintsAreDrawnVertically; HyperPage_picture (this, 20, tableauHeight, drawTableau); Graphics_setAtSignIsLink (g, TRUE); }
void praat_reportGraphicalProperties () { MelderInfo_open (); MelderInfo_writeLine (U"Graphical properties of this edition of Praat on this computer:\n"); double x, y, width, height; Gui_getWindowPositioningBounds (& x, & y, & width, & height); MelderInfo_writeLine (U"Window positioning area: x = ", x, U", y = ", y, U", width = ", width, U", height = ", height); #if defined (macintosh) CGDirectDisplayID screen = CGMainDisplayID (); CGSize screenSize_mm = CGDisplayScreenSize (screen); double diagonal_mm = sqrt (screenSize_mm. width * screenSize_mm. width + screenSize_mm. height * screenSize_mm. height); double diagonal_inch = diagonal_mm / 25.4; MelderInfo_writeLine (U"\nScreen size: ", screenSize_mm. width, U" x ", screenSize_mm. height, U" mm (diagonal ", Melder_fixed (diagonal_mm, 1), U" mm = ", Melder_fixed (diagonal_inch, 1), U" inch)"); size_t screenWidth_pixels = CGDisplayPixelsWide (screen); size_t screenHeight_pixels = CGDisplayPixelsHigh (screen); MelderInfo_writeLine (U"Screen \"resolution\": ", screenWidth_pixels, U" x ", screenHeight_pixels, U" pixels"); double resolution = 25.4 * screenWidth_pixels / screenSize_mm. width; MelderInfo_writeLine (U"Screen resolution: ", Melder_fixed (resolution, 1), U" pixels/inch"); #elif defined (_WIN32) /*for (int i = 0; i <= 88; i ++) MelderInfo_writeLine (U"System metric ", i, U": ", GetSystemMetrics (i));*/ #endif MelderInfo_close (); }
static void IntervalTier_insertIntervalDestructively (IntervalTier me, double tmin, double tmax) { Melder_assert (tmin < tmax); Melder_assert (tmin >= my xmin); Melder_assert (tmax <= my xmax); /* * Make sure that the tier has boundaries at the edges of the interval. */ long firstIntervalNumber = IntervalTier_hasTime (me, tmin); if (! firstIntervalNumber) { long intervalNumber = IntervalTier_timeToIndex (me, tmin); if (intervalNumber == 0) Melder_throw (U"Cannot add a boundary at ", Melder_fixed (tmin, 6), U" seconds, because this is outside the time domain of the intervals."); TextInterval interval = my intervals.at [intervalNumber]; /* * Move the text to the left of the boundary. */ autoTextInterval newInterval = TextInterval_create (tmin, interval -> xmax, U""); interval -> xmax = tmin; my intervals. addItem_move (newInterval.move()); firstIntervalNumber = IntervalTier_hasTime (me, interval -> xmin); } Melder_assert (firstIntervalNumber >= 1 && firstIntervalNumber <= my intervals.size); long lastIntervalNumber = IntervalTier_hasTime (me, tmax); if (! lastIntervalNumber) { long intervalNumber = IntervalTier_timeToIndex (me, tmax); if (intervalNumber == 0) Melder_throw (U"Cannot add a boundary at ", Melder_fixed (tmin, 6), U" seconds, because this is outside the time domain of the intervals."); TextInterval interval = my intervals.at [intervalNumber]; /* * Move the text to the right of the boundary. */ autoTextInterval newInterval = TextInterval_create (interval -> xmin, tmax, U""); interval -> xmin = tmax; my intervals. addItem_move (newInterval.move()); lastIntervalNumber = IntervalTier_hasTime (me, interval -> xmax); } Melder_assert (lastIntervalNumber >= 1 && lastIntervalNumber <= my intervals.size); /* * Empty the interval in the word tier. */ trace (U"Empty interval %ld down to ", lastIntervalNumber, U".", firstIntervalNumber); for (long iinterval = lastIntervalNumber; iinterval >= firstIntervalNumber; iinterval --) { TextInterval interval = my intervals.at [iinterval]; if (interval -> xmin > tmin && interval -> xmin < tmax) { Melder_assert (iinterval > 1); TextInterval previous = my intervals.at [iinterval - 1]; previous -> xmax = tmax; // collapse left and right intervals into left interval TextInterval_setText (previous, U""); my intervals. removeItem (iinterval); // remove right interval } if (interval -> xmax == tmax) { TextInterval_setText (interval, U""); } } }
static void gui_drawingarea_cb_click (ArtwordEditor me, GuiDrawingArea_ClickEvent event) { if (! my graphics) return; Artword artword = (Artword) my data; Graphics_setWindow (my graphics.get(), 0, artword -> totalTime, -1.0, 1.0); Graphics_setInner (my graphics.get()); double xWC, yWC; Graphics_DCtoWC (my graphics.get(), event -> x, event -> y, & xWC, & yWC); Graphics_unsetInner (my graphics.get()); GuiText_setString (my time, Melder_fixed (xWC, 6)); GuiText_setString (my value, Melder_fixed (yWC, 6)); }
Table Formant_downto_Table (Formant me, bool includeFrameNumbers, bool includeTimes, int timeDecimals, bool includeIntensity, int intensityDecimals, bool includeNumberOfFormants, int frequencyDecimals, bool includeBandwidths) { try { autoTable thee = Table_createWithoutColumnNames (my nx, includeFrameNumbers + includeTimes + includeIntensity + includeNumberOfFormants + my maxnFormants * (1 + includeBandwidths)); long icol = 0; if (includeFrameNumbers) Table_setColumnLabel (thee.peek(), ++ icol, U"frame"); if (includeTimes) Table_setColumnLabel (thee.peek(), ++ icol, U"time(s)"); if (includeIntensity) Table_setColumnLabel (thee.peek(), ++ icol, U"intensity"); if (includeNumberOfFormants) Table_setColumnLabel (thee.peek(), ++ icol, U"nformants"); for (long iformant = 1; iformant <= my maxnFormants; iformant ++) { Table_setColumnLabel (thee.peek(), ++ icol, Melder_cat (U"F", iformant, U"(Hz)")); if (includeBandwidths) { Table_setColumnLabel (thee.peek(), ++ icol, Melder_cat (U"B", iformant, U"(Hz)")); } } for (long iframe = 1; iframe <= my nx; iframe ++) { icol = 0; if (includeFrameNumbers) Table_setNumericValue (thee.peek(), iframe, ++ icol, iframe); if (includeTimes) Table_setStringValue (thee.peek(), iframe, ++ icol, Melder_fixed (my x1 + (iframe - 1) * my dx, timeDecimals)); Formant_Frame frame = & my d_frames [iframe]; if (includeIntensity) Table_setStringValue (thee.peek(), iframe, ++ icol, Melder_fixed (frame -> intensity, intensityDecimals)); if (includeNumberOfFormants) Table_setNumericValue (thee.peek(), iframe, ++ icol, frame -> nFormants); for (long iformant = 1; iformant <= frame -> nFormants; iformant ++) { Formant_Formant formant = & frame -> formant [iformant]; Table_setStringValue (thee.peek(), iframe, ++ icol, Melder_fixed (formant -> frequency, frequencyDecimals)); if (includeBandwidths) Table_setStringValue (thee.peek(), iframe, ++ icol, Melder_fixed (formant -> bandwidth, frequencyDecimals)); } for (long iformant = frame -> nFormants + 1; iformant <= my maxnFormants; iformant ++) { Table_setNumericValue (thee.peek(), iframe, ++ icol, NUMundefined); if (includeBandwidths) Table_setNumericValue (thee.peek(), iframe, ++ icol, NUMundefined); } } return thee.transfer(); } catch (MelderError) { Melder_throw (me, U": not converted to Table."); } }
void structLogisticRegression :: v_info () { LogisticRegression_Parent :: v_info (); MelderInfo_writeLine2 (L"Dependent 1: ", dependent1); MelderInfo_writeLine2 (L"Dependent 2: ", dependent2); MelderInfo_writeLine1 (L"Interpretation:"); MelderInfo_write6 (L" ln (P(", dependent2, L")/P(", dependent1, L")) " UNITEXT_ALMOST_EQUAL_TO L" ", Melder_fixed (intercept, 6)); for (long ivar = 1; ivar <= parameters -> size; ivar ++) { RegressionParameter parm = static_cast<RegressionParameter> (parameters -> item [ivar]); MelderInfo_write4 (parm -> value < 0.0 ? L" - " : L" + ", Melder_fixed (fabs (parm -> value), 6), L" * ", parm -> label); } MelderInfo_writeLine1 (NULL); MelderInfo_writeLine1 (L"Log odds ratios:"); for (long ivar = 1; ivar <= parameters -> size; ivar ++) { RegressionParameter parm = static_cast<RegressionParameter> (parameters -> item [ivar]); MelderInfo_writeLine4 (L" Log odds ratio of factor ", parm -> label, L": ", Melder_fixed ((parm -> maximum - parm -> minimum) * parm -> value, 6)); } MelderInfo_writeLine1 (L"Odds ratios:"); for (long ivar = 1; ivar <= parameters -> size; ivar ++) { RegressionParameter parm = static_cast<RegressionParameter> (parameters -> item [ivar]); MelderInfo_writeLine4 (L" Odds ratio of factor ", parm -> label, L": ", Melder_double (exp ((parm -> maximum - parm -> minimum) * parm -> value))); } }
void structLogisticRegression :: v_info () { LogisticRegression_Parent :: v_info (); MelderInfo_writeLine (U"Dependent 1: ", our dependent1); MelderInfo_writeLine (U"Dependent 2: ", our dependent2); MelderInfo_writeLine (U"Interpretation:"); MelderInfo_write (U" ln (P(", dependent2, U")/P(", dependent1, U")) " UNITEXT_ALMOST_EQUAL_TO U" ", Melder_fixed (intercept, 6)); for (long ivar = 1; ivar <= parameters.size; ivar ++) { RegressionParameter parm = parameters.at [ivar]; MelderInfo_write (parm -> value < 0.0 ? U" - " : U" + ", Melder_fixed (fabs (parm -> value), 6), U" * ", parm -> label); } MelderInfo_writeLine (U""); MelderInfo_writeLine (U"Log odds ratios:"); for (long ivar = 1; ivar <= parameters.size; ivar ++) { RegressionParameter parm = parameters.at [ivar]; MelderInfo_writeLine (U" Log odds ratio of factor ", parm -> label, U": ", Melder_fixed ((parm -> maximum - parm -> minimum) * parm -> value, 6)); } MelderInfo_writeLine (U"Odds ratios:"); for (long ivar = 1; ivar <= parameters.size; ivar ++) { RegressionParameter parm = parameters.at [ivar]; MelderInfo_writeLine (U" Odds ratio of factor ", parm -> label, U": ", exp ((parm -> maximum - parm -> minimum) * parm -> value)); } }
void structSpectrumEditor :: v_draw () { Spectrum spectrum = (Spectrum) data; Graphics_setWindow (d_graphics, 0, 1, 0, 1); Graphics_setColour (d_graphics, Graphics_WHITE); Graphics_fillRectangle (d_graphics, 0, 1, 0, 1); Graphics_setColour (d_graphics, Graphics_BLACK); Graphics_rectangle (d_graphics, 0, 1, 0, 1); Spectrum_drawInside (spectrum, d_graphics, d_startWindow, d_endWindow, minimum, maximum); FunctionEditor_drawRangeMark (this, maximum, Melder_fixed (maximum, 1), L" dB", Graphics_TOP); FunctionEditor_drawRangeMark (this, minimum, Melder_fixed (minimum, 1), L" dB", Graphics_BOTTOM); if (cursorHeight > minimum && cursorHeight < maximum) FunctionEditor_drawHorizontalHair (this, cursorHeight, Melder_fixed (cursorHeight, 1), L" dB"); Graphics_setColour (d_graphics, Graphics_BLACK); /* Update buttons. */ long first, last; long selectedSamples = Sampled_getWindowSamples (spectrum, d_startSelection, d_endSelection, & first, & last); publishBandButton -> f_setSensitive (selectedSamples != 0); publishSoundButton -> f_setSensitive (selectedSamples != 0); }
void structOTGrammarEditor :: v_draw () { OTGrammar ot = (OTGrammar) data; static char32 text [1000]; Graphics_clearWs (g); if (ot -> decisionStrategy == kOTGrammar_decisionStrategy_EXPONENTIAL_HG || ot -> decisionStrategy == kOTGrammar_decisionStrategy_EXPONENTIAL_MAXIMUM_ENTROPY) { HyperPage_listItem (this, U"\t\t %%ranking value\t %disharmony\t %plasticity\t %%e^^disharmony"); } else { HyperPage_listItem (this, U"\t\t %%ranking value\t %disharmony\t %plasticity"); } for (long icons = 1; icons <= ot -> numberOfConstraints; icons ++) { OTGrammarConstraint constraint = & ot -> constraints [ot -> index [icons]]; if (ot -> decisionStrategy == kOTGrammar_decisionStrategy_EXPONENTIAL_HG || ot -> decisionStrategy == kOTGrammar_decisionStrategy_EXPONENTIAL_MAXIMUM_ENTROPY) { Melder_sprint (text,1000, U"\t", icons == selected ? U"♠︎ " : U" ", U"@@", icons, U"|", constraint -> name, U"@\t ", Melder_fixed (constraint -> ranking, 3), U"\t ", Melder_fixed (constraint -> disharmony, 3), U"\t ", Melder_fixed (constraint -> plasticity, 6), U"\t ", Melder_float (Melder_half (exp (constraint -> disharmony)))); } else { Melder_sprint (text,1000, U"\t", icons == selected ? U"♠︎ " : U" ", U"@@", icons, U"|", constraint -> name, U"@\t ", Melder_fixed (constraint -> ranking, 3), U"\t ", Melder_fixed (constraint -> disharmony, 3), U"\t ", Melder_fixed (constraint -> plasticity, 6)); } HyperPage_listItem (this, text); } Graphics_setAtSignIsLink (g, FALSE); for (long itab = 1; itab <= ot -> numberOfTableaus; itab ++) { OTGrammarTableau tableau = & ot -> tableaus [itab]; double rowHeight = 0.25; double tableauHeight = rowHeight * (tableau -> numberOfCandidates + 2); drawTableau_ot = ot; drawTableau_input = tableau -> input; drawTableau_constraintsAreDrawnVertically = d_constraintsAreDrawnVertically; HyperPage_picture (this, 20, tableauHeight, drawTableau); } Graphics_setAtSignIsLink (g, TRUE); }
void structPitchEditor :: v_draw () { Pitch pitch = (Pitch) our data; long it, it1, it2; double dyUnv, dyIntens; Graphics_setWindow (our d_graphics, 0, 1, 0, 1); Graphics_setColour (our d_graphics, Graphics_WHITE); Graphics_fillRectangle (our d_graphics, 0, 1, 0, 1); Graphics_setColour (our d_graphics, Graphics_BLACK); Graphics_rectangle (our d_graphics, 0, 1, 0, 1); dyUnv = Graphics_dyMMtoWC (our d_graphics, HEIGHT_UNV); dyIntens = Graphics_dyMMtoWC (our d_graphics, HEIGHT_INTENS); Sampled_getWindowSamples (pitch, our d_startWindow, our d_endWindow, & it1, & it2); /* * Show pitch. */ { long df = pitch -> ceiling > 10000 ? 2000 : pitch -> ceiling > 5000 ? 1000 : pitch -> ceiling > 2000 ? 500 : pitch -> ceiling > 800 ? 200 : pitch -> ceiling > 400 ? 100 : 50; double radius; Graphics_Viewport previous; previous = Graphics_insetViewport (our d_graphics, 0, 1, dyUnv, 1 - dyIntens); Graphics_setWindow (our d_graphics, our d_startWindow, our d_endWindow, 0, pitch -> ceiling); radius = Graphics_dxMMtoWC (our d_graphics, RADIUS); /* Horizontal hair at current pitch. */ if (our d_startSelection == our d_endSelection && our d_startSelection >= our d_startWindow && our d_startSelection <= our d_endWindow) { double f = Pitch_getValueAtTime (pitch, our d_startSelection, kPitch_unit_HERTZ, Pitch_LINEAR); if (NUMdefined (f)) { Graphics_setColour (our d_graphics, Graphics_RED); Graphics_line (our d_graphics, our d_startWindow - radius, f, our d_endWindow, f); Graphics_setTextAlignment (our d_graphics, Graphics_RIGHT, Graphics_HALF); Graphics_text1 (our d_graphics, our d_startWindow - radius, f, Melder_fixed (f, 2)); } } /* Horizontal scaling lines. */ Graphics_setColour (our d_graphics, Graphics_BLUE); Graphics_setLineType (our d_graphics, Graphics_DOTTED); Graphics_setTextAlignment (our d_graphics, Graphics_LEFT, Graphics_HALF); for (long f = df; f <= pitch -> ceiling; f += df) { Graphics_line (our d_graphics, our d_startWindow, f, our d_endWindow, f); Graphics_text2 (our d_graphics, our d_endWindow + radius/2, f, Melder_integer (f), L" Hz"); } Graphics_setLineType (our d_graphics, Graphics_DRAWN); /* Show candidates. */ for (it = it1; it <= it2; it ++) { Pitch_Frame frame = & pitch -> frame [it]; double t = Sampled_indexToX (pitch, it); double f = frame -> candidate [1]. frequency; if (f > 0.0 && f < pitch -> ceiling) { Graphics_setColour (our d_graphics, Graphics_MAGENTA); Graphics_fillCircle_mm (our d_graphics, t, f, RADIUS * 2); } Graphics_setColour (our d_graphics, Graphics_BLACK); Graphics_setTextAlignment (our d_graphics, Graphics_CENTRE, Graphics_HALF); for (int icand = 1; icand <= frame -> nCandidates; icand ++) { int strength = (int) floor (10 * frame -> candidate [icand]. strength + 0.5); f = frame -> candidate [icand]. frequency; if (strength > 9) strength = 9; if (f > 0 && f <= pitch -> ceiling) Graphics_text1 (our d_graphics, t, f, Melder_integer (strength)); } } Graphics_resetViewport (our d_graphics, previous); } /* * Show intensity. */ { Graphics_Viewport previous = Graphics_insetViewport (our d_graphics, 0, 1, 1 - dyIntens, 1); Graphics_setWindow (our d_graphics, our d_startWindow, our d_endWindow, 0, 1); Graphics_setColour (our d_graphics, Graphics_BLACK); Graphics_setTextAlignment (our d_graphics, Graphics_RIGHT, Graphics_HALF); Graphics_text (our d_graphics, our d_startWindow, 0.5, L"intens"); Graphics_setTextAlignment (our d_graphics, Graphics_LEFT, Graphics_HALF); Graphics_text (our d_graphics, our d_endWindow, 0.5, L"intens"); Graphics_setTextAlignment (our d_graphics, Graphics_CENTRE, Graphics_HALF); for (it = it1; it <= it2; it ++) { Pitch_Frame frame = & pitch -> frame [it]; double t = Sampled_indexToX (pitch, it); int strength = (int) floor (10 * frame -> intensity + 0.5); // map 0.0-1.0 to 0-9 if (strength > 9) strength = 9; Graphics_text1 (our d_graphics, t, 0.5, Melder_integer (strength)); } Graphics_resetViewport (our d_graphics, previous); } if (it1 > 1) it1 -= 1; if (it2 < pitch -> nx) it2 += 1; /* * Show voicelessness. */ { Graphics_Viewport previous = Graphics_insetViewport (our d_graphics, 0, 1, 0, dyUnv); Graphics_setColour (our d_graphics, Graphics_BLUE); Graphics_line (our d_graphics, our d_startWindow, 1, our d_endWindow, 1); Graphics_setTextAlignment (our d_graphics, Graphics_RIGHT, Graphics_HALF); Graphics_text (our d_graphics, our d_startWindow, 0.5, L"Unv"); Graphics_setTextAlignment (our d_graphics, Graphics_LEFT, Graphics_HALF); Graphics_text (our d_graphics, our d_endWindow, 0.5, L"Unv"); for (it = it1; it <= it2; it ++) { Pitch_Frame frame = & pitch -> frame [it]; double t = Sampled_indexToX (pitch, it), tleft = t - 0.5 * pitch -> dx, tright = t + 0.5 * pitch -> dx; double f = frame -> candidate [1]. frequency; if ((f > 0.0 && f < pitch -> ceiling) || tright <= our d_startWindow || tleft >= our d_endWindow) continue; if (tleft < our d_startWindow) tleft = our d_startWindow; if (tright > our d_endWindow) tright = our d_endWindow; Graphics_fillRectangle (our d_graphics, tleft, tright, 0, 1); } Graphics_setColour (our d_graphics, Graphics_BLACK); Graphics_resetViewport (our d_graphics, previous); } }
Sound Sound_deepenBandModulation (Sound me, double enhancement_dB, double flow, double fhigh, double slowModulation, double fastModulation, double bandSmoothing) { try { autoSound thee = Data_copy (me); double maximumFactor = pow (10, enhancement_dB / 20), alpha = sqrt (log (2.0)); double alphaslow = alpha / slowModulation, alphafast = alpha / fastModulation; for (long channel = 1; channel <= my ny; channel ++) { autoSound channelSound = Sound_extractChannel (me, channel); autoSpectrum orgspec = Sound_to_Spectrum (channelSound.peek(), true); /* * Keep the part of the sound that is outside the filter bank. */ autoSpectrum spec = Data_copy (orgspec.peek()); Spectrum_stopHannBand (spec.peek(), flow, fhigh, bandSmoothing); autoSound filtered = Spectrum_to_Sound (spec.peek()); long n = thy nx; double *amp = thy z [channel]; for (long i = 1; i <= n; i ++) amp [i] = filtered -> z [1] [i]; autoMelderProgress progress (U"Deepen band modulation..."); double fmin = flow; while (fmin < fhigh) { /* * Take a one-bark frequency band. */ double fmid_bark = NUMhertzToBark (fmin) + 0.5, ceiling; double fmax = NUMbarkToHertz (NUMhertzToBark (fmin) + 1); if (fmax > fhigh) fmax = fhigh; Melder_progress (fmin / fhigh, U"Band: ", Melder_fixed (fmin, 0), U" ... ", Melder_fixed (fmax, 0), U" Hz"); NUMmatrix_copyElements (orgspec -> z, spec -> z, 1, 2, 1, spec -> nx); Spectrum_passHannBand (spec.peek(), fmin, fmax, bandSmoothing); autoSound band = Spectrum_to_Sound (spec.peek()); /* * Compute a relative intensity contour. */ autoSound intensity = Data_copy (band.peek()); n = intensity -> nx; amp = intensity -> z [1]; for (long i = 1; i <= n; i ++) amp [i] = 10 * log10 (amp [i] * amp [i] + 1e-6); autoSpectrum intensityFilter = Sound_to_Spectrum (intensity.peek(), true); n = intensityFilter -> nx; for (long i = 1; i <= n; i ++) { double frequency = intensityFilter -> x1 + (i - 1) * intensityFilter -> dx; double slow = alphaslow * frequency, fast = alphafast * frequency; double factor = exp (- fast * fast) - exp (- slow * slow); intensityFilter -> z [1] [i] *= factor; intensityFilter -> z [2] [i] *= factor; } intensity.reset (Spectrum_to_Sound (intensityFilter.peek())); n = intensity -> nx; amp = intensity -> z [1]; for (long i = 1; i <= n; i ++) amp [i] = pow (10, amp [i] / 2); /* * Clip to maximum enhancement. */ ceiling = 1 + (maximumFactor - 1.0) * (0.5 - 0.5 * cos (NUMpi * fmid_bark / 13)); for (long i = 1; i <= n; i ++) amp [i] = 1 / (1 / amp [i] + 1 / ceiling); n = thy nx; amp = thy z [channel]; for (long i = 1; i <= n; i ++) amp [i] += band -> z [1] [i] * intensity -> z [1] [i]; fmin = fmax; } } Vector_scale (thee.peek(), 0.99); /* Truncate. */ thy xmin = my xmin; thy xmax = my xmax; thy nx = my nx; thy x1 = my x1; return thee.transfer(); } catch (MelderError) { Melder_throw (me, U": band modulation not deepened."); } }