示例#1
0
        public static decimal GetLoudness(string fileName, Action <double, double> updateProgress = null)
        {
            if (Path.GetExtension(fileName) != ".wav")
            {
                return(defaultLoadness);
            }

            try {
                WavReader wavReader;

                using (FileStream fileStream = new FileStream(fileName, FileMode.Open, FileAccess.Read, FileShare.Read))
                {
                    wavReader = new WavReader(fileStream, Encoding.Default);
                }

                WavReader.FmtChunk fmt    = (WavReader.FmtChunk)wavReader.Riff.Chunks["fmt "];
                double[][]         buffer = wavReader.GetSampleData();

                R128LufsMeter r128LufsMeter = new R128LufsMeter();
                r128LufsMeter.Prepare(fmt.SampleRate, buffer.Length);
                r128LufsMeter.StartIntegrated();
                r128LufsMeter.ProcessBuffer(buffer,
                                            (double current, double total) => { updateProgress?.Invoke(current, total); });
                r128LufsMeter.StopIntegrated();

                // Report input loudness
                return(-16 - Convert.ToDecimal(r128LufsMeter.IntegratedLoudness));
            }
            catch (Exception ex) {
                return(defaultLoadness);
            }
        }
示例#2
0
        private double Loudness(byte[] pcmData)
        {
            List <double> data = new List <double>();

            for (int i = 0; i < pcmData.Length; i += 2)
            {
                data.Add((double)BitConverter.ToInt16(pcmData, i) / (short.MaxValue + 1));
            }
            R128LufsMeter r128LufsMeter = new R128LufsMeter();

            r128LufsMeter.Prepare(AudioSampleRate, 1);
            r128LufsMeter.StartIntegrated();
            r128LufsMeter.ProcessBuffer(new double[][] { data.ToArray() }, null);
            r128LufsMeter.StopIntegrated();

            double loudness = r128LufsMeter.IntegratedLoudness;

            if (double.IsNaN(loudness))
            {
                return(0);
            }
            if (loudness <= -70.0)
            {
                return(0);
            }
            if (loudness >= 0.0)
            {
                return(100.0);
            }
            return((loudness + 70.0) * LUFSToPercent);
        }
        /// <summary>
        /// Normalize a buffer
        /// </summary>
        /// <param name="buffer">The buffer need to be normalize</param>
        /// <param name="sampleRate">The sample rate of the sample data</param>
        /// <returns>Normalized buffer</returns>
        public static double[][] Normalize(double[][] buffer, double sampleRate)
        {
            // Calc input loudness
            R128LufsMeter r128LufsMeter = new R128LufsMeter();

            r128LufsMeter.Prepare(sampleRate, buffer.Length);
            Console.Write("Calculating input loudness...");
            r128LufsMeter.StartIntegrated();
            r128LufsMeter.ProcessBuffer(buffer,
                                        (double current, double total) => { AppendConsoleProgressBar($"Calculating input loudness : {current:N0}/{total:N0}", (double)current / total); });
            r128LufsMeter.StopIntegrated();

            // Report input loudness
            double integratedLoudness = r128LufsMeter.IntegratedLoudness;

            ConsoleClearLine();
            Console.WriteLine("Input integrated loudness : {0:N} LU", integratedLoudness);

            // Normalization to -23 LU
            double targetLoudness = TargetIntegratedLufs;
            double gain           = targetLoudness - integratedLoudness;
            int    count          = 0;

            double[][] clone = null;
            while (Math.Abs(targetLoudness - integratedLoudness) > 0.5)
            {
                count++;

                // Clone buffer
                clone = new double[buffer.Length][];
                for (int i = 0; i < buffer.Length; i++)
                {
                    clone[i] = (double[])buffer[i].Clone();
                }

                // Apply gain to normalize
                Console.Write("Applying gain...");
                Gain.ApplyGain(clone, gain);
                ConsoleClearLine();
                Console.WriteLine($"Gain applyed : {gain:N} dB");

                // Limit the True Peak
                StreamWriter streamWriter = new StreamWriter("limiter.csv");
                int          c            = 0;
                TruePeakLimiter.ProcessBuffer(clone, MaximumTruePeak, sampleRate, LimiterAttack, LimiterRelease, LimiterAttackCurve, LimiterReleaseCurve,
                                              (double current, double total) => { if (current % 10000 == 0)
                                                                                  {
                                                                                      AppendConsoleProgressBar($"Limiting : {current:N0}/{total:N0}", (double)current / total);
                                                                                  }
                                              });
                ConsoleClearLine();
                Console.WriteLine("Limiting finished!");
                streamWriter.Close();

                // Calc output loudness
                Console.Write("Verifying output loudness...");
                r128LufsMeter.StartIntegrated();
                r128LufsMeter.ProcessBuffer(clone,
                                            (double current, double total) => { AppendConsoleProgressBar($"Verifying output loudness : {current:N0}/{total:N0}", (double)current / total); });
                r128LufsMeter.StopIntegrated();

                // Report output loudness
                integratedLoudness = r128LufsMeter.IntegratedLoudness;
                ConsoleClearLine();
                Console.WriteLine("Output integrated loudness {0} : {1:N} LU", count, integratedLoudness);
                gain += targetLoudness - integratedLoudness;

                if (!LoopVerify)
                {
                    break;
                }
            }

            if (clone != null)
            {
                return(clone);
            }
            return(buffer);
        }