mirror of
https://git.femboyfinancial.jp/james/lipsync.git
synced 2024-11-24 19:51:59 -08:00
274 lines
9.7 KiB
C#
274 lines
9.7 KiB
C#
/*
|
|
* math.cs
|
|
* Copyright (c) 2008-2009 kbinani
|
|
*
|
|
* This file is part of bocoree.
|
|
*
|
|
* bocoree is free software; you can redistribute it and/or
|
|
* modify it under the terms of the BSD License.
|
|
*
|
|
* bocoree is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
|
*/
|
|
using System;
|
|
using System.Collections.Generic;
|
|
|
|
namespace bocoree {
|
|
|
|
public partial class math {
|
|
private const double _PI2 = 2.0 * Math.PI;
|
|
private const double _PI4 = 4.0 * Math.PI;
|
|
private const double _PI6 = 6.0 * Math.PI;
|
|
private const double _PI8 = 8.0 * Math.PI;
|
|
|
|
public enum WindowFunctionType {
|
|
Hamming,
|
|
rectangular,
|
|
Gauss,
|
|
Hann,
|
|
Blackman,
|
|
Bartlett,
|
|
Nuttall,
|
|
Blackman_Harris,
|
|
Blackman_Nattall,
|
|
flap_top,
|
|
Parzen,
|
|
Akaike,
|
|
Welch,
|
|
Kaiser,
|
|
}
|
|
|
|
public static double window_func( WindowFunctionType type, double x ) {
|
|
switch ( type ) {
|
|
case WindowFunctionType.Akaike:
|
|
return wnd_akaike( x );
|
|
case WindowFunctionType.Bartlett:
|
|
return wnd_bartlett( x );
|
|
case WindowFunctionType.Blackman:
|
|
return wnd_blackman( x );
|
|
case WindowFunctionType.Blackman_Harris:
|
|
return wnd_blackman_harris( x );
|
|
case WindowFunctionType.Blackman_Nattall:
|
|
return wnd_blackman_nattall( x );
|
|
case WindowFunctionType.flap_top:
|
|
return wnd_flap_top( x );
|
|
case WindowFunctionType.Gauss:
|
|
throw new ApplicationException( "too few argument for Gauss window function" );
|
|
case WindowFunctionType.Hamming:
|
|
return wnd_hamming( x );
|
|
case WindowFunctionType.Hann:
|
|
return wnd_hann( x );
|
|
case WindowFunctionType.Kaiser:
|
|
throw new ApplicationException( "too few argument for Kaiser window function" );
|
|
case WindowFunctionType.Nuttall:
|
|
return wnd_nuttall( x );
|
|
case WindowFunctionType.Parzen:
|
|
return wnd_parzen( x );
|
|
case WindowFunctionType.rectangular:
|
|
return wnd_rectangular( x );
|
|
case WindowFunctionType.Welch:
|
|
return wnd_welch( x );
|
|
}
|
|
return 0.0;
|
|
}
|
|
|
|
public static double window_func( WindowFunctionType type, double x, params double[] param ) {
|
|
switch ( type ) {
|
|
case WindowFunctionType.Akaike:
|
|
return wnd_akaike( x );
|
|
case WindowFunctionType.Bartlett:
|
|
return wnd_bartlett( x );
|
|
case WindowFunctionType.Blackman:
|
|
return wnd_blackman( x );
|
|
case WindowFunctionType.Blackman_Harris:
|
|
return wnd_blackman_harris( x );
|
|
case WindowFunctionType.Blackman_Nattall:
|
|
return wnd_blackman_nattall( x );
|
|
case WindowFunctionType.flap_top:
|
|
return wnd_flap_top( x );
|
|
case WindowFunctionType.Gauss:
|
|
return wnd_gauss( x, param[0] );
|
|
case WindowFunctionType.Hamming:
|
|
return wnd_hamming( x );
|
|
case WindowFunctionType.Hann:
|
|
return wnd_hann( x );
|
|
case WindowFunctionType.Kaiser:
|
|
return wnd_kaiser( x, param[0] );
|
|
case WindowFunctionType.Nuttall:
|
|
return wnd_nuttall( x );
|
|
case WindowFunctionType.Parzen:
|
|
return wnd_parzen( x );
|
|
case WindowFunctionType.rectangular:
|
|
return wnd_rectangular( x );
|
|
case WindowFunctionType.Welch:
|
|
return wnd_welch( x );
|
|
}
|
|
return 0.0;
|
|
}
|
|
|
|
public static double wnd_kaiser( double x, double alpha ) {
|
|
if ( 0.0 <= x && x <= 1.0 ) {
|
|
double t = 2.0 * x - 1.0;
|
|
return besi0( Math.PI * alpha * Math.Sqrt( 1.0 - t * t ) ) / besi0( Math.PI * alpha );
|
|
} else {
|
|
return 0.0;
|
|
}
|
|
}
|
|
|
|
public static double wnd_welch( double x ) {
|
|
if ( 0.0 <= x && x <= 1.0 ) {
|
|
return 4.0 * x * (1.0 - x);
|
|
} else {
|
|
return 0.0;
|
|
}
|
|
}
|
|
|
|
public static double wnd_akaike( double x ) {
|
|
if ( 0.0 <= x && x <= 1.0 ) {
|
|
return 0.625 - 0.5 * Math.Cos( _PI2 * x )
|
|
- 0.125 * Math.Cos( _PI4 * x );
|
|
} else {
|
|
return 0.0;
|
|
}
|
|
}
|
|
|
|
public static double wnd_parzen( double x ) {
|
|
double x0 = Math.Abs( x );
|
|
if ( x0 <= 1.0 ) {
|
|
return (0.75 * x0 - 1.5) * x0 * x0 + 1.0;
|
|
} else {
|
|
x0 = 2.0 - x0;
|
|
return 0.25 * x0 * x0 * x0;
|
|
}
|
|
}
|
|
|
|
public static double wnd_flap_top( double x ) {
|
|
if ( 0.0 <= x && x <= 1.0 ) {
|
|
return 1.0 - 1.93 * Math.Cos( _PI2 * x )
|
|
+ 1.29 * Math.Cos( _PI4 * x )
|
|
- 0.388 * Math.Cos( _PI6 * x )
|
|
+ 0.032 * Math.Cos( _PI8 * x );
|
|
} else {
|
|
return 0.0;
|
|
}
|
|
}
|
|
|
|
public static double wnd_blackman_nattall( double x ) {
|
|
if ( 0.0 <= x && x <= 1.0 ) {
|
|
return 0.3635819 - 0.4891775 * Math.Cos( _PI2 * x )
|
|
+ 0.1365995 * Math.Cos( _PI4 * x )
|
|
- 0.0106411 * Math.Cos( _PI6 * x );
|
|
} else {
|
|
return 0.0;
|
|
}
|
|
}
|
|
|
|
public static double wnd_blackman_harris( double x ) {
|
|
if ( 0.0 <= x && x <= 1.0 ) {
|
|
return 0.35875 - 0.48829 * Math.Cos( _PI2 * x )
|
|
+ 0.14128 * Math.Cos( _PI4 * x )
|
|
- 0.01168 * Math.Cos( _PI6 * x );
|
|
} else {
|
|
return 0.0;
|
|
}
|
|
}
|
|
|
|
public static double wnd_nuttall( double x ) {
|
|
if ( 0.0 <= x && x <= 1.0 ) {
|
|
return 0.355768 - 0.487396 * Math.Cos( _PI2 * x )
|
|
+ 0.144232 * Math.Cos( _PI4 * x )
|
|
- 0.012604 * Math.Cos( _PI6 * x );
|
|
} else {
|
|
return 0.0;
|
|
}
|
|
}
|
|
|
|
public static double wnd_bartlett( double x ) {
|
|
if ( 0.0 <= x && x <= 1.0 ) {
|
|
return 1.0 - 2.0 * Math.Abs( x - 0.5 );
|
|
} else {
|
|
return 0.0;
|
|
}
|
|
}
|
|
|
|
public static double wnd_blackman( double x ) {
|
|
if ( 0.0 <= x && x <= 1.0 ) {
|
|
return 0.42 - 0.5 * Math.Cos( _PI2 * x ) + 0.08 * Math.Cos( _PI4 * x );
|
|
} else {
|
|
return 0.0;
|
|
}
|
|
}
|
|
|
|
public static double wnd_hann( double x ) {
|
|
if ( 0.0 <= x && x <= 1.0 ) {
|
|
return 0.5 - 0.5 * Math.Cos( _PI2 * x );
|
|
} else {
|
|
return 0.0;
|
|
}
|
|
}
|
|
|
|
public static double wnd_gauss( double x, double sigma ) {
|
|
return Math.Exp( -x * x / (sigma * sigma) );
|
|
}
|
|
|
|
public static double wnd_rectangular( double x ) {
|
|
if ( 0.0 <= x && x <= 1.0 ) {
|
|
return 1.0;
|
|
} else {
|
|
return 0.0;
|
|
}
|
|
}
|
|
|
|
public static double wnd_hamming( double x ) {
|
|
if ( 0.0 <= x && x <= 1.0 ) {
|
|
return 0.54 - 0.46 * Math.Cos( _PI2 * x );
|
|
} else {
|
|
return 0.0;
|
|
}
|
|
}
|
|
|
|
public static double besi0( double x ) {
|
|
int i;
|
|
double w, wx375;
|
|
double[] a = { 1.0, 3.5156229, 3.0899424,
|
|
1.2067492, 0.2659732, 0.0360768};
|
|
double[] b = { 0.39894228, 0.013285917, 0.002253187,
|
|
-0.001575649, 0.009162808, -0.020577063,
|
|
0.026355372, -0.016476329};
|
|
if ( x < 0.0 ) {
|
|
return 0.0;
|
|
}
|
|
if ( x <= 3.75 ) {
|
|
wx375 = x * x / 14.0625;
|
|
w = 0.0045813;
|
|
for ( i = 5; i >= 0; i-- ) {
|
|
w = w * wx375 + a[i];
|
|
}
|
|
return w;
|
|
}
|
|
wx375 = 3.75 / x;
|
|
w = 0.003923767;
|
|
for ( i = 7; i >= 0; i-- ) {
|
|
w = w * wx375 + b[i];
|
|
}
|
|
return w / Math.Sqrt( x ) * Math.Exp( x );
|
|
}
|
|
|
|
public static double erfcc( double x ) {
|
|
double t, z, res;
|
|
z = Math.Abs( x );
|
|
t = 1.0 / (1.0 + 0.5 * z);
|
|
res = t * Math.Exp( -z * z - 1.26551223 + t * (1.00002368 + t * (0.37409196
|
|
+ t * (0.09678418 + t * (-0.18628806 + t * (0.27886807
|
|
+ t * (-1.13520398 + t * (1.48851587 + t * (-0.82215223
|
|
+ t * 0.17087277)))))))) );
|
|
if ( x < 0.0 ) {
|
|
res = 2.0 - res;
|
|
}
|
|
return res;
|
|
}
|
|
}
|
|
|
|
}
|