# .net 逆二乗積分 シュレーダー積分 - C#で波信号の残響時間を計算する方法

matlab t20 t30

``````class Program
{
static List<double> points = new List<double>();
static double maxValue = 0;
static double minValue = 1;
static int num = 0;
static int num2 = 0;
static List<double> values = new List<double>();
private static object akima;
static void Main(string[] args)
{
int count = 0;
foreach (string fileLine in fileLines)
{
if (!fileLine.Contains(";"))
{
string processLine = fileLine.Trim();
processLine = Regex.Replace(processLine, @"\s+", " ");
if (Environment.OSVersion.Platform == PlatformID.Win32NT)
{
processLine = processLine.Replace(".", ",");
}
string[] dataParts = processLine.Split(Char.Parse(" "));
double value = Math.Pow(double.Parse(dataParts[1]), 2);
if (value > maxValue)
{
maxValue = value;
num = count;
}
}
count++;
}
for (int i = num; i < values.Count; i++)
{
if (values[i] < minValue)
{
minValue = values[i];
num2 = i;
}
}
Console.WriteLine(num + " " + num2);
int between = num2 - num;
points = points.GetRange(num, between);
values = values.GetRange(num, between);
List<double> defVal = new List<double>();
List<double> defValPoints = new List<double>();
alglib.spline1dinterpolant c;
alglib.spline1dbuildakima(points.ToArray(), values.ToArray(), out c);
double baseInt = alglib.spline1dintegrate(c, points[points.Count - 1]);
List<double> defETC = new List<double>();
for (int i = 0; i < points.Count; i += 10)
{
double toVal = points[i];
defVal.Add(10 * Math.Log10((baseInt - alglib.spline1dintegrate(c, toVal)) / baseInt));
}
WriteDoubleArrayToFile(defValPoints.ToArray(), defVal.ToArray(), "test.dat");
WriteDoubleArrayToFile(defValPoints.ToArray(), defETC.ToArray(), "etc.dat");
int end = 0;
for (int i = 0; i < points.Count; i++)
{
if (defVal[i] < -10)
{
end = i;
break;
}
}
//Console.WriteLine(num + " " + end);
int beginEDT = num;
int endEDT = num + end;
double timeBetween = (defValPoints[endEDT] - defValPoints[beginEDT]) * 6;
Console.WriteLine(timeBetween);
for (int i = 0; i < points.Count; i++)
{

}
}
static void WriteDoubleArrayToFile(double[] points, double[] values, string filename)
{
string[] defStr = new string[values.Length];
for (int i = 0; i < values.Length; i++)
{
defStr[i] = String.Format("{0,10}{1,25}", points[i], values[i]);
}
File.WriteAllLines(filename, defStr);
}
}``````
1. WAVファイルからdecimal / float / double値を抽出する
2. 抽出されたデータから配列を作成する
3. ノイズ/音の減衰をデシベルのように表示するエネルギータイムカーブを作成する
4. ステップ3で作成したETCから減衰曲線を作成する
5. この減衰曲線からEarly Decay Time（EDT）、T15 / T20、RT60として計算します。
6. これらのリバーブタイムをstdoutに表示します。

1. 私はSoxを使って、オーディオファイルを数字のある.datファイルに変換しました
2. 上記のファイルの各行を分割し、TimesArrayに時間を入れ、ValuesArrayのそれらの点に値を入れるだけで、C＃を使って配列を作成します。
3. 私はこの関数で処理されたデータを使ってGNUPlot経由でグラフを表示しています：10 * Math.Log10（values [i]）; （ここで、iはforループ内の反復整数で、ValuesArray内のすべての項目を反復処理します）
4. これは私が立ち往生し始めている場所です。 つまり、このステップでは、AlglibのAkimaスプライン関数を使用して線を統合することができます。 私はこの数学的計算を介して、Schroederの積分（逆転）でそれをやっています：10 * Math.Log10（（baseInt - alglib.spline1dintegrate（c、toVal））/ baseInt）; （ここでbaseIntは完全な曲線の基底積分として計算された値なので、逆Schroeder積分の計算された底部があります）cは、関数alglib.spline1dbuildakimaを使用するときに利用できるspline1dinterpolantです.timeArrayをx値、valueArrayをy値、cを外側のスプライン1補間記号とします。tovalはpoints配列のx値です。forループを使用して特定の値が選択されます。）これらの新しく保存された値から、その行からRT60を計算しますが、その方法はわかりません。
5. 試しましたが、実際にはうまくいかなかった。
6. 上記と同じですが、実際の価値はありません。

### Tags

c#   .net   audio   signal-processing