1 /* PitchTier_to_Sound.cpp
2  *
3  * Copyright (C) 1992-2011,2016,2017 Paul Boersma
4  *
5  * This code is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License as published by
7  * the Free Software Foundation; either version 2 of the License, or (at
8  * your option) any later version.
9  *
10  * This code is distributed in the hope that it will be useful, but
11  * WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
13  * See the GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this work. If not, see <http://www.gnu.org/licenses/>.
17  */
18 
19 #include "PitchTier_to_Sound.h"
20 #include "PitchTier_to_PointProcess.h"
21 #include "PointProcess_and_Sound.h"
22 
PitchTier_to_Sound_pulseTrain(PitchTier me,double samplingFrequency,double adaptFactor,double adaptTime,integer interpolationDepth,bool hum)23 autoSound PitchTier_to_Sound_pulseTrain (PitchTier me, double samplingFrequency,
24 	 double adaptFactor, double adaptTime, integer interpolationDepth, bool hum)
25 {
26 	static double formant [1 + 6] = { 0.0, 600.0, 1400.0, 2400.0, 3400.0, 4500.0, 5500.0 };
27 	static double bandwidth [1 + 6] = { 0.0, 50.0, 100.0, 200.0, 300.0, 400.0, 500.0 };
28 	try {
29 		const autoPointProcess point = PitchTier_to_PointProcess (me);
30 		autoSound sound = PointProcess_to_Sound_pulseTrain (point.get(), samplingFrequency, adaptFactor, adaptTime, interpolationDepth);
31 		if (hum) {
32 			Sound_filterWithFormants (sound.get(), 0.0, 0.0, 6, formant, bandwidth);
33 		}
34 		return sound;
35 	} catch (MelderError) {
36 		Melder_throw (me, U": not converted to Sound (pulse train).");
37 	}
38 }
39 
PitchTier_to_Sound_phonation(PitchTier me,double samplingFrequency,double adaptFactor,double maximumPeriod,double openPhase,double collisionPhase,double power1,double power2,bool hum)40 autoSound PitchTier_to_Sound_phonation (PitchTier me, double samplingFrequency,
41 	 double adaptFactor, double maximumPeriod, double openPhase, double collisionPhase, double power1, double power2, bool hum)
42 {
43 	static double formant [1 + 6] = { 0.0, 600.0, 1400.0, 2400.0, 3400.0, 4500.0, 5500.0 };
44 	static double bandwidth [1 + 6] = { 0.0, 50.0, 100.0, 200.0, 300.0, 400.0, 500.0 };
45 	try {
46 		const autoPointProcess point = PitchTier_to_PointProcess (me);
47 		autoSound sound = PointProcess_to_Sound_phonation (point.get(), samplingFrequency, adaptFactor,
48 			maximumPeriod, openPhase, collisionPhase, power1, power2);
49 		if (hum) {
50 			Sound_filterWithFormants (sound.get(), 0.0, 0.0, 6, formant, bandwidth);
51 		}
52 		return sound;
53 	} catch (MelderError) {
54 		Melder_throw (me, U": not converted to Sound (phonation).");
55 	}
56 }
57 
PitchTier_playPart(PitchTier me,double tmin,double tmax,bool hum)58 void PitchTier_playPart (PitchTier me, double tmin, double tmax, bool hum) {
59 	try {
60 		const autoSound sound = PitchTier_to_Sound_pulseTrain (me, 44100.0, 0.7, 0.05, 30, hum);
61 		Sound_playPart (sound.get(), tmin, tmax, nullptr, nullptr);
62 	} catch (MelderError) {
63 		Melder_throw (me, U": not played.");
64 	}
65 }
66 
PitchTier_play(PitchTier me)67 void PitchTier_play (PitchTier me) {
68 	PitchTier_playPart (me, my xmin, my xmax, false);
69 }
70 
PitchTier_hum(PitchTier me)71 void PitchTier_hum (PitchTier me) {
72 	PitchTier_playPart (me, my xmin, my xmax, true);
73 }
74 
PitchTier_to_Sound_sine(PitchTier me,double tmin,double tmax,double samplingFrequency)75 autoSound PitchTier_to_Sound_sine (PitchTier me, double tmin, double tmax, double samplingFrequency) {
76 	try {
77 		Function_unidirectionalAutowindow (me, & tmin, & tmax);
78 		integer numberOfSamples = 1 + Melder_ifloor ((my xmax - my xmin) * samplingFrequency);   // >= 1
79 		double samplingPeriod = 1.0 / samplingFrequency;
80 		double tmid = (tmin + tmax) / 2.0;
81 		double t1 = tmid - 0.5 * (numberOfSamples - 1) * samplingPeriod;
82 		autoSound thee = Sound_create (1, tmin, tmax, numberOfSamples, samplingPeriod, t1);
83 		double phase = 0.0;
84 		for (integer isamp = 2; isamp <= numberOfSamples; isamp ++) {
85 			double tleft = t1 + (isamp - 1.5) * samplingPeriod;
86 			double fleft = RealTier_getValueAtTime (me, tleft);
87 			phase += fleft * thy dx;
88 			thy z [1] [isamp] = 0.5 * sin (2.0 * NUMpi * phase);
89 		}
90 		return thee;
91 	} catch (MelderError) {
92 		Melder_throw (me, U": not converted to Sound (sine).");
93 	}
94 }
95 
PitchTier_playPart_sine(PitchTier me,double tmin,double tmax)96 void PitchTier_playPart_sine (PitchTier me, double tmin, double tmax) {
97 	try {
98 		Function_unidirectionalAutowindow (me, & tmin, & tmax);
99 		autoSound sound = PitchTier_to_Sound_sine (me, tmin, tmax, 44100.0);
100 		Sound_playPart (sound.get(), tmin, tmax, nullptr, nullptr);
101 	} catch (MelderError) {
102 		Melder_throw (me, U": not played.");
103 	}
104 }
105 
106 /* End of file PitchTier_to_Sound.cpp */
107