Exemplo n.º 1
0
 /// <summary>
 /// Direct sound constructor. This prepares the simulation to run. 
 /// </summary>
 /// <param name="Src_in">The sound source</param>
 /// <param name="Rec_in">The collection of receivers</param>
 /// <param name="Room_in">The acoustical scene to render</param>
 /// <param name="RayCount">The number of rays which will be used </param>
 public Direct_Sound(Source Src_in, Receiver_Bank Rec_in, Scene Room_in, int[] Octaves)
 {
     type = Src_in.Type();
     Validity = new bool[Rec_in.Count];//[Rec_in.Count];
     Io = new double[Rec_in.Count][][];//[Rec_in.Count][t,8];
     Time_Pt = new double[Rec_in.Count];//[Rec_in.Count];
     Dir_Rec_Pos = new float[Rec_in.Count][][][];
     Dir_Rec_Neg = new float[Rec_in.Count][][][];
     Room = Room_in;
     C_Sound = Room_in.Sound_speed(0);
     SampleFreq = Rec_in.SampleRate;
     Src = Src_in;
     this.CO_Time = Rec_in.CO_Time;
     Receiver = new List<Point>();
     Rho_C = new double[Rec_in.Count];
     for(int i = 0; i < Rec_in.Count; i++)
     {
         Rho_C[i] = Room.Rho_C(Rec_in.H_Origin(i));
         Receiver.Add(Rec_in.H_Origin(i));
     }
     SWL = new double[8] { Src_in.SWL(0), Src_in.SWL(1), Src_in.SWL(2), Src_in.SWL(3), Src_in.SWL(4), Src_in.SWL(5), Src_in.SWL(6), Src_in.SWL(7) };
     Delay_ms = Src.Delay;
     Oct_choice = Octaves;
 }
        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);
        }