Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to calculate the reverberation time of a wave signal in C#

I am trying to develop a console application in C# which uses a WAV-file for input. The application should do a couple of things all in order, as shown below. First of all, the complete 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);
    }
}
  1. Extract the decimal/float/double value from the WAV-file
  2. Create an array from extracted data
  3. Create an Energy Time Curve that displays the decay of the noise/sound in a decibel-like way
  4. Create an Decay Curve from the ETC created in step 3
  5. Calculate things as Early Decay Time (EDT), T15/T20 and RT60 from this Decay Curve.
  6. Display these Reverb Times in stdout.

At the moment I am sort of like half way through the process. I´ll explain what I did:

  1. I used Sox to convert the audio file into a .dat file with numbers
  2. I create an array using C# by simply splitting each line in the file above and putting the times in a TimesArray and the values at those points in a ValuesArray.
  3. I am displaying a graph via GNUPlot, using the data processed with this function: 10 * Math.Log10(values[i]); (where i is an iterative integer in a for-loop iterating over all the items in the ValuesArray)
  4. This is where I'm starting to get stuck. I mean, in this step I am using an Akima Spline function from Alglib to be able to integrate a line. I am doing that with a Schroeder integration (reversed), via this mathematical calculation: 10 * Math.Log10((baseInt - alglib.spline1dintegrate(c, toVal)) / baseInt); (where baseInt is a value calculated as a base integral for the complete curve, so I have a calculated bottom part of the reversed Schroeder integration. The c is a spline1dinterpolant made available when using the function alglib.spline1dbuildakima, which takes the timeArray as x values, valueArray as the y values, and c as an outwards spline1dinterpolant. toval is an x-value from the points array. The specific value is selected using a for-loop.) From these newly saved values I want to create an interpolated line and calculate the RT60 from that line, but I do not know how to do that.
  5. Tried, did not really work out.
  6. Same as above, I have no real values to show.

I'm quite stuck now, as I'm not sure if this is the right way to do it. If anyone can tell me how I can calculate the reverberation times in a fast and responsive way in C#, I'd be pleased to hear. The way of doing it might be completely different from what I have now, that's OK, just let me know!

like image 522
Cornel van der Heiden Avatar asked Dec 23 '12 22:12

Cornel van der Heiden


People also ask

What is the formula for calculating reverberation time?

Hence, reverberation time, TR = 36 V/cA. This approximate formula is very close to the result that is derived experimentally by W. C. Sabine and later derived in more detail by W. S. Franklin. The measurements with more careful derivation yield approximately 55 V/cA.

What is the time of reverberation?

Reverberation time (RT) is the time required for the sound in a room to decay over a specific dynamic range, usually taken to be 60 dB, when a source is suddenly interrupted. The Sabine formula relates the RT to the properties of the room.

What is meant by reverberation and time of reverberation for sound waves?

Solution : The phenomenon of persistence or prolongation of sound after the source has stopped emitting sound is called reverberation. The time for which the sound persists until its becomes inaudible is called the reverberation time. Answer.

How is T60 calculated?

T60 = 0,161 * (640/57,6) = 1,78 seconds, as required.


1 Answers

Maybe you need to approach this differently:

  1. start with the underlying maths. find out the mathematical formulas for these functions.
  2. Use a simple mathematical function and calculate by hand (in excel or matlab) what the values should be (of all these things ETC, DC, EDC, T15, T20, RT60) (A function such as a sine wave of just the minimum number of points you need )
  3. then write a separate procedure to evaluate each of these in C# and verify your results for consistency with excel/matlab.

in C#, maybe store your data in a class that you pass around to each of the methods for its calculation.

your main function should end up something like this:

main(){

data = new Data();

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

//3: 
energy_time_curve(data)

//...4, 5

//6: 
display_results(data);


}
like image 140
Rhett Avatar answered Sep 27 '22 23:09

Rhett