How to calculate wave reverb time in C #

I am trying to develop a console application in C # that uses a WAV file for input. The application should do everything in order, as shown below. First of all, the full code:

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); } } 
  • Extract decimal / float / double value from WAV file
  • Creating an array from the extracted data
  • Create an energy time curve that displays the decay of noise / sound using the decibel method.
  • Create the decay curve from ETC created in step 3
  • Calculate the time as the early decay time (EDT), T15 / T20 and RT60 from this decay curve.
  • Display these reverb times in standard mode.

At the moment, I kind of halfway through the process. I will explain what I did:

  • I used Sox to convert the audio file to a .dat file with numbers
  • I create an array using C #, simply breaking each line in the file above and putting the time in TimesArray and the values ​​at these points in ValuesArray.
  • I show the graph through GNUPlot, using data processed using this function: 10 * Math.Log10 (values ​​[i]); (where I am an iterative integer in cyclic repetition over all elements in a ValuesArray)
  • This is where I get stuck. I mean, at this point I am using the Akima spline function from Alglib to be able to integrate the line. I do this with Schroeder integration (inverse) through this mathematical calculation: 10 * Math.Log10 ((baseInt - alglib.spline1dintegrate (c, toVal)) / baseInt); (where baseInt is the value computed as the base integral for the full curve, so I have the calculated bottom of the Schroeder inverse. c is spline1dinterpolant, available by using the alglib.spline1dbuildakima function, which takes timeArray as x values, valueArray as y values ​​and c as an external spline1dinterpolant. toval is the x-value from the array of points. The special value is selected using the for loop.) From these newly saved values, I want to create an interpolated row and calculate RT60 from this row, but I don’t know how to do it.
  • I tried, in fact, it did not work.
  • As above, I have no real values ​​to show.

I'm stuck right now because I'm not sure if this is the right way to do this. If someone tells me how I can calculate the reverberation time in a fast and responsive way in C #, I would be happy to hear. The way to do this may be completely different from what I have now, it's fine, just let me know!

+8
c # audio signal-processing
source share
1 answer

Perhaps you need to approach in a different way:

  • start with basic math calculations. find mathematical formulas for these functions.
  • Use a simple math function and manually calculate (in excel or matlab) which values ​​should be (of all these elements ETC, DC, EDC, T15, T20, RT60) (Function such as a sine wave of the total minimum number of points you need )
  • then write a separate procedure for evaluating each of them in C # and check your results against excel / matlab.

in C #, maybe save your data in the class that you pass to each of its calculation methods.

your main function should end up with something like this:

 main(){ data = new Data(); //1, 2: extract_data(data, filename); //3: energy_time_curve(data) //...4, 5 //6: display_results(data); } 
+1
source share

All Articles