Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/21.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如何在C语言中计算波信号的混响时间#_C#_.net_Audio_Signal Processing - Fatal编程技术网

C# 如何在C语言中计算波信号的混响时间#

C# 如何在C语言中计算波信号的混响时间#,c#,.net,audio,signal-processing,C#,.net,Audio,Signal Processing,我正在尝试用C#开发一个控制台应用程序,它使用WAV文件作为输入。应用程序应该按顺序完成几件事情,如下所示。首先,完整的代码: 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&

我正在尝试用C#开发一个控制台应用程序,它使用WAV文件作为输入。应用程序应该按顺序完成几件事情,如下所示。首先,完整的代码:

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);
    }
}
类程序
{
静态列表点=新列表();
静态双maxValue=0;
静态双最小值=1;
静态int num=0;
静态int num2=0;
静态列表值=新列表();
私有静态对象akima;
静态void Main(字符串[]参数)
{
string[]fileLines=File.ReadAllLines(args[0]);
整数计数=0;
foreach(文件行中的字符串文件行)
{
如果(!fileLine.Contains(“;”)
{
字符串processLine=fileLine.Trim();
processLine=Regex.Replace(processLine,@“\s+”,“”);
if(Environment.OSVersion.PlatformID==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);
如果(值>最大值)
{
最大值=最大值;
num=计数;
}
增加(价值);
}
计数++;
}
for(int i=num;i
  • 从WAV文件中提取十进制/浮点/双精度值
  • 从提取的数据创建数组
  • 创建一条能量-时间曲线,以类似分贝的方式显示噪声/声音的衰减
  • 根据步骤3中创建的ETC创建衰减曲线
  • 根据此衰减曲线计算早期衰减时间(EDT)、T15/T20和RT60
  • 在标准输出中显示这些混响时间
  • 目前,我似乎已经完成了一半。我会解释我做了什么:

  • 我使用Sox将音频文件转换成带有数字的.dat文件
  • 我使用C#创建了一个数组,方法是简单地拆分上面文件中的每一行,并将时间放入TimeArray中,将这些点上的值放入ValuesArray中
  • 我通过GNUPlot显示一个图形,使用这个函数处理的数据:10*Math.Log10(值[I]);(其中i是for循环中的迭代整数,该循环迭代ValuesArray中的所有项)
  • 这就是我开始陷入困境的地方。我的意思是,在这一步中,我使用来自Alglib的Akima样条函数来积分一条线。我是通过Schroeder积分(反向)来实现的,通过这个数学计算:10*Math.Log10((baseInt-alglib.spline1dinintegrate(c,toVal))/baseInt;(其中baseInt是一个作为完整曲线的基积分计算的值,因此我计算了反向Schroeder积分的底部部分。c是使用函数alglib.spline1dbuildakima时可用的spline1dinterpolant,它将时间数组作为x值,valueArray作为y值,c作为向外的spline1dintoval是点数组中的一个x值。具体值是使用for循环选择的。)从这些新保存的值中,我想创建一条插值线,并从该线计算RT60,但我不知道如何做到这一点
  • 试过了,没有真正起作用
  • 和上面一样,我没有真正的价值观可以展示

  • 我现在被卡住了,因为我不确定这样做是否正确。如果有人能告诉我如何用C#快速、灵敏地计算混响时间,我很乐意听到。这样做的方式可能与我现在拥有的完全不同,没关系,只要让我知道

    也许你需要以不同的方式来处理这个问题:

  • 从基础数学开始。找出这些函数的数学公式
  • 使用一个简单的数学函数,手工计算(在excel或matlab中)应该是什么值(所有这些值,DC、EDC、T15、T20、RT60) (一个函数,如正弦波,刚好是您需要的最小点数)
  • 然后编写一个单独的程序,在C#中评估每一项,并用excel/matlab验证结果的一致性 在C#,mayb
    main(){
    
    data = new Data();
    
    //1, 2: 
    extract_data(data, filename);
    
    //3: 
    energy_time_curve(data)
    
    //...4, 5
    
    //6: 
    display_results(data);
    
    
    }