8

入力にWAVファイルを使用するコンソールアプリケーションをC#で開発しようとしています。以下に示すように、アプリケーションはいくつかのことをすべて順番に実行する必要があります。まず第一に、完全なコード:

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)
{
    string[] fileLines = File.ReadAllLines(args[0]);
    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(" "));
            points.Add(double.Parse(dataParts[0]));
            double value = Math.Pow(double.Parse(dataParts[1]), 2);
            if (value > maxValue)
            {
                maxValue = value;
                num = count;
            }
            values.Add(value);
        }
        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];
        defETC.Add(10 * Math.Log10(values[i]));
        defVal.Add(10 * Math.Log10((baseInt - alglib.spline1dintegrate(c, toVal)) / baseInt));
        defValPoints.Add(points[i]);
    }
    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++)
    {

    }
    Console.ReadLine();
}
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. この崩壊曲線から、初期崩壊時間(EDT)、T15 / T20、およびRT60として計算します。
  6. これらのリバーブタイムをstdoutで表示します。

現時点では、私はプロセスの途中のようなものです。私がしたことを説明します:

  1. Soxを使用して、オーディオファイルを番号付きの.datファイルに変換しました
  2. 上記のファイルの各行を分割し、TimesArrayに時刻を入れ、ValuesArrayにそれらのポイントの値を入れるだけで、C#を使用して配列を作成します。
  3. この関数で処理されたデータを使用して、GNUPlotを介してグラフを表示しています。10* Math.Log10(values [i]); (ここで、iは、ValuesArray内のすべての項目を反復するforループ内の反復整数です)
  4. これは私が行き詰まり始めているところです。つまり、このステップでは、AlglibのAkimaスプライン関数を使用してラインを統合できるようにしています。私は、この数学的計算を介して、シュローダー積分(逆)でそれを行っています:10 * Math.Log10((baseInt --alglib.spline1dintegrate(c、toVal))/ baseInt); (ここで、baseIntは完全な曲線の基本積分として計算された値であるため、逆シュローダー積分の下部が計算されます。cは、関数alglib.spline1dbuildakimaを使用するときに使用できるspline1dinterpolantであり、timeArrayをxとして取ります。値、y値としてのvalueArray、および外向きのspline1dinterpolantとしてのc。tovalはポイント配列からのx値です。特定の値は、forループを使用して選択されます。
  5. 試してみましたが、実際にはうまくいきませんでした。
  6. 上記と同じように、表示する実際の値はありません。

これが正しい方法かどうかわからないので、今はかなり行き詰まっています。C#で高速かつ応答性の高い方法で残響時間を計算する方法を誰かに教えてもらえれば幸いです。それを行う方法は、私が今持っているものとは完全に異なるかもしれません、それは大丈夫です、ただ私に知らせてください!

4

1 に答える 1

1

おそらく、これに別の方法でアプローチする必要があります。

  1. 基礎となる数学から始めます。これらの関数の数式を見つけます。
  2. 単純な数学関数を使用して、(Excel または Matlab で) 値がどうあるべきか (ETC、DC、EDC、T15、T20、RT60) を手で計算します (最小数の正弦波などの関数必要なポイント数)
  3. 次に、C# でこれらのそれぞれを評価するための個別の手順を記述し、Excel/Matlab との一貫性について結果を検証します。

C# では、計算のために各メソッドに渡すクラスにデータを格納することができます。

メイン関数は次のようになります。

main(){

data = new Data();

//1, 2: 
extract_data(data, filename);

//3: 
energy_time_curve(data)

//...4, 5

//6: 
display_results(data);


}
于 2013-05-04T23:03:49.470 に答える