Код

Предыдущая  Содержание  Следующая  V*D*V

/**

* Шумы голосового тракта.

* по материалам:

* Сорокин, Синтез речи

* Сорокин, Артикуляторный ресинтез гласных

* Сорокин, Артикуляторный ресинтез фрикативных

*

* для синтеза шипящих достаточно 2 дипольных источника:

* 1-ый в месте с наибольшим числом Рейнольдса

* 2-ой на выходе голосовой щели

*

* использование:

* calculateParams( W, L, S )

* F1 = getF1()

* F2 = getF2()

* A1 = getA1()

* A2 = getA2()

*/

public class NoisingSource {

 /**

  * критическое число Рейнольдса для возникновения турбулентного шума

  */

 public static final int ReCr = 1800;

 private static final int ReCr2 = 3240000;//ReCr^2

 //

 private int m_F1 = 1;//частота 1-го обертона

 private double m_A1 = 0;//амплитуда 1-го обертона

 private int m_Re = 0;//число Рейнольдса

 //

 public NoisingSource() {}

 /**

  * @return частота 1-го обертона

  */

 public int getF1() { return m_F1; }

 /**

  * @return амплитуда 1-го обертона

  */

 public double getA1() { return m_A1; }

 /**

  * @return полоса 1-го обертона

  */

 public int getW1() { return m_F1 / 2; }

 /**

  * @return частота 2-го обертона

  */

 public int getF2() { return m_F1 * 2; }

 /**

  * @return амплитуда 2-го обертона

  */

 public double getA2() { return m_A1 * 0.1; }

 /**

  * @return полоса 2-го обертона

  */

 public int getW2() { return m_F1; }

 /**

  * @return число Рейнольдса

  */

 public int getRe() { return m_Re; }

 /**

  * @return случайные числа с распределением по гауссовскому закону

  */

 public static double getNormalRandom() {

         double n = -8.0;

         for( int i = 0; i < 16; i++ )

         {

                 n += Math.random();//0...1

         }

         return n;

 }

 /**

  * расчет числа Рейнольдса

  * 1 вариант Re = Ro*v*h/u -> 12.25*w*sqrt(1/pi/s)?????

  * 2 вариант Re = 12.25*w/L

  * @param W - sm^3/s, объемная скорость, 0...500

  * @param L - sm, ширина щели, 1.5

  * @return - число Рейнольдса, 0...4200

  */

 public static int calculateRe(double W, double L) {

         return (int)(12.5 * W / L);

 }

 /**

  * расчет частоты 1-го обертона шума при Re > ReCr и при Re > 100

  * для дипольного источника шума

  * при ReCr > Re > 100 W = 0.11*pi*v/h -> F = 0.055*w/(sqrt(s*s*s*4/pi))

  * @param W - sm^3/s, объемная скорость, 0...500

  * @param S - sm^2, площадь щели 0.1...0.4

  * @param L - sm, ширина щели, 1.5

  * @param Re - число Рейнольдса, 0...4200

  * @return - частота

  */

 public static int calculateFrequency(double W, double S, double L, int Re) {

         if ( Re < 100 ) return 0;//при малом Re шума нет

         if( S < 0.1 ) return 0;//минимальное сужение в тракте

         if ( Re <= ReCr ) return (int)(0.0487 * W / S / Math.sqrt( S ));//докритический

         return (int)(0.085 * W * L / S / S);//турбулентный

 }

 /**

  * расчет амплитуды 1-го обертона шума

  * если Re > ReCr - турбулентный

  * если Re > 100 - просто шум

  * амплитуда 1-го обертона A1 = k1*(Re^2 - ReCr^2), k1~1^10-5...1^10-6

  * амплитуда 2-го обертона A2 = 0.1 * A1

  * @param Re - число Рейнольдса

  * @return - амплитуда обертона???? sm^3/s ? единица измерения непонятна

  */

 public static double calculateAmplitude(int Re) {

         if( Re < 100 ) return 0.0;

         double a = 0.01;//наугад

         if( Re <= ReCr ) return a;

         return a + (double)(Re * Re - ReCr2) * 0.000001;

 }

 /**

  * расчет параметров шума: частота, амплитуда, число Рейнольдса

  * @param W - sm^3/s, объемная скорость, 0...500

  * @param S - sm^2, площадь щели 0.1...0.4

  * @param L - sm, ширина щели, 1.5

  */

 public void calculateParams(double W, double S, double L) {

         m_Re = calculateRe( W, L );

         m_F1 = calculateFrequency( W, S, L, m_Re );

         m_A1 = calculateAmplitude( m_Re );

 }

}

Предыдущая  Содержание  Следующая