c# - t60 - tiempo de reverberacion pdf
Cómo calcular el tiempo de reverberación de una señal de onda en C# (1)
Estoy tratando de desarrollar una aplicación de consola en C # que utiliza un archivo WAV para la entrada. La aplicación debe hacer un par de cosas en orden, como se muestra a continuación. Primero que todo, el código completo:
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);
}
}
- Extraiga el valor decimal / flotante / doble del archivo WAV
- Crear una matriz a partir de datos extraídos
- Cree una curva de tiempo de energía que muestre la disminución del ruido / sonido de una manera similar a un decibelio
- Cree una curva de decaimiento del ETC creado en el paso 3
- Calcule las cosas como Tiempo de Decaimiento Temprano (EDT), T15 / T20 y RT60 de esta Curva de Decaimiento.
- Muestra estos tiempos de reverberación en stdout.
Por el momento, estoy algo así como en la mitad del proceso. Explicaré lo que hice:
- Usé Sox para convertir el archivo de audio en un archivo .dat con números
- Creo una matriz usando C # simplemente dividiendo cada línea en el archivo anterior y poniendo los tiempos en TimesArray y los valores en esos puntos en un ValuesArray.
- Estoy visualizando un gráfico a través de GNUPlot, usando los datos procesados con esta función: 10 * Math.Log10 (valores [i]); (donde i es un número entero iterativo en un bucle for que itera sobre todos los elementos en ValuesArray)
- Aquí es donde estoy empezando a estancarme. Quiero decir, en este paso estoy usando una función Akima Spline de Alglib para poder integrar una línea. Estoy haciendo eso con una integración de Schroeder (invertida), a través de este cálculo matemático: 10 * Math.Log10 ((baseInt - alglib.spline1dintegrate (c, toVal)) / baseInt); (donde baseInt es un valor calculado como una base integral para la curva completa, entonces tengo una parte inferior calculada de la integración inversa de Schroeder. c es un spline1dinterpolant disponible cuando se usa la función alglib.spline1dbuildakima, que toma timeArray como x valores, valorArray como los valores y, y c como un spline1dinterpolant hacia afuera. toval es un valor x de la matriz de puntos. El valor específico se selecciona usando un for-loop.) A partir de estos valores recién guardados, quiero crear una línea interpolada y calcule el RT60 desde esa línea, pero no sé cómo hacer eso.
- Intenté, realmente no funcionó.
- Igual que arriba, no tengo valores reales para mostrar.
Estoy bastante atascado ahora, ya que no estoy seguro de si esta es la manera correcta de hacerlo. Si alguien puede decirme cómo puedo calcular los tiempos de reverberación de una manera rápida y receptiva en C #, me gustaría escucharlo. La forma de hacerlo podría ser completamente diferente a la que tengo ahora, está bien, ¡házmelo saber!
Quizás necesites acercarte a esto de otra manera:
- Comience con las matemáticas subyacentes. Descubre las fórmulas matemáticas para estas funciones.
- Utilice una función matemática simple y calcule a mano (en Excel o Matlab) cuáles deberían ser los valores (de todas estas cosas ETC, DC, EDC, T15, T20, RT60) (Una función como una onda sinusoidal de solo el número mínimo de puntos que necesitas)
- luego, escriba un procedimiento por separado para evaluar cada uno de estos en C # y verifique la concordancia de los resultados con Excel / Matlab.
en C #, tal vez almacene sus datos en una clase que pase a cada uno de los métodos para su cálculo.
tu función principal debería terminar algo como esto:
main(){
data = new Data();
//1, 2:
extract_data(data, filename);
//3:
energy_time_curve(data)
//...4, 5
//6:
display_results(data);
}