Quantcast
Channel: NAudio
Viewing all articles
Browse latest Browse all 5831

New Post: Is possible use this code with Naudio

$
0
0
Hello I want just do a simple tool can meter Dynamic Range in AUDIO FILE
I haveexperience with NAUDIO only with MIDI, never work with audio.

Can this be implemented, if somebody can complete the code I can provide some money reward.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using System.Runtime.InteropServices;
using FMOD;
using System.Text.RegularExpressions;
using System.IO;

namespace DR_Meter
{
    class Program
    {
        static void Main(string[] args)
        {
            if (args.Length > 0)
            {
                Console.WriteLine("Scanning files...");

                Directory.SetCurrentDirectory(GetDirectoryName(args[0]));

                string[] files = Directory.GetFiles(Directory.GetCurrentDirectory(), GetFileName(args[0]));

                double dr = 0.0;
                int count = 0;

                foreach (string path in files)
                {
                    string name = GetFileName(path);

                    Console.WriteLine();
                    Console.WriteLine("File: " + name);

                    double result = CalculateDR(name);

                    if (result != -1.0)
                    {
                        dr += result;
                        count++;
                    }
                }

                if (count > 1)
                {
                    dr = dr / (double)count;

                    Console.WriteLine();
                    Console.WriteLine("Folder:");
                    Console.WriteLine("DR: " + Math.Round(dr));
                }
            }
            else
            {
                Console.WriteLine("No arguments specified.");
            }
        }

        static string GetDirectoryName(string path)
        {
            string result = Directory.GetCurrentDirectory();

            try
            {
                result = Directory.GetParent(path).ToString();
            }
            catch (Exception)
            {
            }

            return result;
        }

        static string GetFileName(string path)
        {
            string[] parts = path.Split(Path.DirectorySeparatorChar);
            return parts[parts.Length - 1];
        }

        static double CalculateDR(String filename)
        {
            Sound sound = new Sound(filename);

            if (sound.GetResult() != FMOD.RESULT.OK)
            {
                return -1.0;
            }

            int channels = sound.GetChannels();
            int chunksize = sound.GetChunksize();
            int bytes = sound.GetBytes();
            uint length = sound.GetLength();
            SOUND_FORMAT sound_format = sound.GetSoundFormat();
            FMOD.RESULT result;

            List<Block>[] blocks = new List<Block>[channels];

            for (int i = 0; i < channels; i++)
            {
                blocks[i] = new List<Block>();
            }

            IntPtr data = Marshal.AllocHGlobal(chunksize);
            byte[] buffer = new byte[chunksize];
            uint read = 0;
            uint bytesread = 0;

            do
            {
                double[] pk = new double[channels];

                for (int j = 0; j < channels; j++)
                {
                    pk[j] = 0.0;
                }

                double[] sum = new double[channels];

                for (int j = 0; j < channels; j++)
                {
                    sum[j] = 0.0;
                }

                double[] rms = new double[channels];

                result = sound.ReadData(data, (uint)chunksize, ref read);

                Marshal.Copy(data, buffer, 0, chunksize);

                for (int i = 0; i < (int)read; i += bytes)
                {
                    int channel = (i / bytes) % channels;

                    double sample = 0.0;

                    int tmp;

                    switch (sound_format)
                    {
                        case SOUND_FORMAT.PCM8:
                            tmp = buffer[i];
                            if (tmp >= 128) tmp -= 256;
                            sample = (double)tmp / 128.0;
                            break;
                        case SOUND_FORMAT.PCM16:
                            sample = (double)BitConverter.ToInt16(buffer, i) / 32768.0;
                            break;
                        case SOUND_FORMAT.PCM24:
                            tmp = BitConverter.ToInt32(new byte[4] { buffer[i], buffer[i + 1], buffer[i + 2], 0 }, 0);
                            if (tmp >= 8388608) tmp -= 16777216;
                            sample = (double)tmp / 8388608.0;
                            break;
                        case SOUND_FORMAT.PCM32:
                            sample = (double)BitConverter.ToInt32(buffer, i) / 2147483648.0;
                            break;
                        case SOUND_FORMAT.PCMFLOAT:
                            sample = (double)BitConverter.ToSingle(buffer, i);
                            break;
                        default:
                            break;
                    }

                //  rms
                //  sum[channel] += Math.Pow(sample, 2.0);
                    sum[channel] += sample * sample;

                //  pk
                    if (Math.Abs(sample) > pk[channel])
                        pk[channel] = Math.Abs(sample);
                }

                for (int i = 0; i < channels; i++)
                {
                    rms[i] = Math.Sqrt(2.0 * (sum[i] / (double)(read / (bytes * channels))));

                //  convert to dB
                    rms[i] = 20.0 * Math.Log10(rms[i]);
                    pk[i] = 20.0 * Math.Log10(pk[i]);

                //  round to 2 decimals
                    rms[i] = Math.Round(rms[i], 2);
                    pk[i] = Math.Round(pk[i], 2);

                //  restrict range
                    if (rms[i] < -100.0) rms[i] = -100.0;
                    if (rms[i] > 0.0) rms[i] = 0.0;

                    if (pk[i] < -100.0) pk[i] = -100.0;
                    if (pk[i] > 0.0) pk[i] = 0.0;

                //  convert back from dB
                    rms[i] = Math.Pow(10.0, rms[i] / 20.0);
                    pk[i] = Math.Pow(10.0, pk[i] / 20.0);

                    blocks[i].Add(new Block(rms[i], pk[i]));
                }

                bytesread += read;

                Console.Write("\rProgress: " + Math.Round(((double)bytesread / (double)length) * 100.0) + "%");
            }
            while (result == FMOD.RESULT.OK && read == chunksize);

            Console.Write("\r              \r");

            sound.Close();

        //  Calculation

            double[] dr = new double[channels];

            double dr_sum = 0.0;

            for (int i = 0; i < channels; i++)
            {
                int blocks_20;
                
                if (blocks[i].Count <= 2) // special case: tracks with only one or two blocks
                {
                    blocks_20 = 1;
                }
                else
                {
                    blocks_20 = (int)Math.Round(0.2 * blocks[i].Count);
                }

                blocks[i].Sort();

                double pk_1st = 0.0;
                double pk_2nd = 0.0;
                double rms_20 = 0.0;

                for (int j = 0; j < blocks[i].Count; j++)
                {
                    Block block = blocks[i].ElementAt(j);

                    //  PK

                    if (block.GetPeak() >= pk_1st)
                    {
                        if (blocks[i].Count == 1) // special case: track with only one block
                        {
                            pk_2nd = block.GetPeak();
                        }
                        else
                        {
                            pk_2nd = pk_1st;
                        }

                        pk_1st = block.GetPeak();
                    }
                    else if (block.GetPeak() > pk_2nd)
                    {
                        pk_2nd = block.GetPeak();
                    }

                    //  RMS

                    if (j < blocks_20)
                    {
                    //  rms_20 += Math.Pow(block.GetRMS(), 2.0);
                        rms_20 += block.GetRMS() * block.GetRMS();
                    }
                }

                rms_20 = Math.Sqrt(rms_20 / (double)blocks_20);

            //  DR

                dr[i] = -20.0 * Math.Log10(rms_20 / pk_2nd);

                dr_sum += dr[i];

                Console.WriteLine("DR["+i+"]: " + Math.Round(dr[i], 2));
            }

            double dr_final = dr_sum / (double)channels;

            Console.WriteLine("DR: " + Math.Round(dr_final));

            return dr_final;
        }
    }
}

Here some info about how calc DR
http://www.dynamicrange.de/sites/default/files/Measuring%20DR%20ENv3.pdf

Viewing all articles
Browse latest Browse all 5831

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>