public Specular_Path(Hare.Geometry.Point[] Path, int[] Seq_planes, int[] Seq_Polys, Scene Room, Source Src, double C_Sound, double[] Trans_Mod, ref double Direct_Time, int thread, int Rnd) { PathEnergy = new double[8]; ValidPath = Path; //Build an Identifier Sequence = Seq_planes; Hare.Geometry.Point Pt; for (int q = 1; q < ValidPath.Length; q++) { Pt = ValidPath[q] - ValidPath[q - 1]; Length += Math.Sqrt(Pt.x * Pt.x + Pt.y * Pt.y + Pt.z * Pt.z); } Time = Length / C_Sound + Src.Delay; Vector DIR = ValidPath[1] - ValidPath[0]; DIR.Normalize(); Random rnd = new Random(Rnd); float time = (float)(Length / C_Sound); double[] phase = Src.Phase(DIR, ref rnd); ///Energy based formulation double[] Power = Src.DirPower(thread, Rnd, DIR); Identify(Src.Source_ID(), Direct_Time); for (int oct = 0; oct < 8; oct++) { PathEnergy[oct] = (Power[oct] * Math.Pow(10,-.1 * Room.Attenuation(0)[oct] * Length) / (4 * Math.PI * Length * Length)); PathEnergy[oct] *= Trans_Mod[oct]; } foreach (int q in Seq_Polys) { if (!(Room.AbsorptionValue[q] is Basic_Material)) continue; double[] AbsorptionData = Room.AbsorptionValue[q].Coefficient_A_Broad(); double[] ScatteringData = Room.ScatteringValue[q].Coefficient(); for (int t = 0; t <= 7; t++) { PathEnergy[t] *= (1 - AbsorptionData[t]) * (1 - ScatteringData[t]); } } prms = new double[8]; for (int i = 0; i < 8; i++) prms[i] = Math.Sqrt(PathEnergy[i] * Room.Rho_C(Path[0])); //System.Numerics.Complex[] Pspec = Audio.Pach_SP.Mirror_Spectrum(Audio.Pach_SP.Magnitude_Spectrum(prms, 44100, 4096, thread)); //System.Numerics.Complex[] Pspec = Audio.Pach_SP.Mirror_Spectrum(Audio.Pach_SP.Magnitude_Spectrum(prms, 88200, 4096, thread)); Special_Filter = new System.Numerics.Complex[4096]; for (int i = 0; i < Special_Filter.Length; i++) Special_Filter[i] = 1; foreach (int q in Seq_Polys) { if (Room.AbsorptionValue[q] is Basic_Material) continue; //Pressure based formulation of materials for (int i = 0; i < Seq_Polys.Length; i++) { Hare.Geometry.Vector d = Path[i + 1] - Path[i + 2]; d.Normalize(); if (!(Room.AbsorptionValue[Seq_Polys[i]] is Basic_Material)) { System.Numerics.Complex[] Ref = Room.AbsorptionValue[Seq_Polys[i]].Reflection_Spectrum(44100, 4096, Room.Normal(Seq_Polys[i]), d, thread); //System.Numerics.Complex[] Ref = Room.AbsorptionValue[Seq_Polys[i]].Reflection_Spectrum(88200, 4096, Room.Normal(Seq_Polys[i]), d, thread); //for (int j = 0; j < Pspec.Length; j++) Pspec[j] *= Ref[j]; for (int j = 0; j < Special_Filter.Length; j++) Special_Filter[j] *= Ref[j]; } } } Create_pressure(44100, 4096, thread); //double[] tank = new double[Pspec.Length]; //for (int i = 0; i < tank.Length; i++) tank[i] = Pspec[i].Real; //P = Audio.Pach_SP.Minimum_Phase_Response(tank, 44100, thread); //TODO: Investigate phase propoerties of this for special materials filters... //double[] pre = Audio.Pach_SP.IFFT_Real4096(Pspec, thread); //P = new double[pre.Length]; //double scale = Math.Sqrt(P.Length); //int hw = P.Length / 2; //for (int i = 0; i < pre.Length; i++) P[i] = pre[(i + hw) % pre.Length] / scale; ///////////////////////////////// //Audio.Pach_SP.resample(ref P); /////////////////////////////// //Audio.Pach_SP.Raised_Cosine_Window(ref P); }