Friday, June 6, 2025

yessssss too important very fast hermite operator multiple channels 44100 32 bits to mono 8000 sps 16 bits PCM RIFF AND THE REPORTS

        private void button_TO_HANDLE_WAVS_WITH_1800_BUCKETS_Click(object sender, EventArgs e)

        {

            try

            {

                ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

                System.Windows.Forms.MessageBox.Show("1800 BUCKETS ANALYSIS\r\n\r\n\r\nit loads the WAV FILES  | *.WAV ");

                ///FOR REFERENCES  openFileDialogForDXFFiles.Filter = "dstv/nc1 Files (.nc1)|*.nc1|AdvanceSteels dstv/nc1 Files (.nc)|*.nc|All Files (*.*)|*.*";

                // Open file dialog to select PDF file

                OpenFileDialog openFileDialog = new OpenFileDialog();

                openFileDialog.Filter = "wav Files|*.wav";

                string CURRENT_WAV_FILE_CHOSEN = "";

                string SAANS_STANDARD_OUTPUT_WAV_FILE_FIRST_RAW_MATERIAL_TO_PROCEED_8000_SPS_16BITS_PCM_RIFF_WAV_FILES = "";

                if (openFileDialog.ShowDialog() == DialogResult.OK)

                {

                    CURRENT_WAV_FILE_CHOSEN = openFileDialog.FileName;

                    SAANS_STANDARD_OUTPUT_WAV_FILE_FIRST_RAW_MATERIAL_TO_PROCEED_8000_SPS_16BITS_PCM_RIFF_WAV_FILES

                        =

                       CURRENT_WAV_FILE_CHOSEN + "_8000SPS_16BIT_PCMRIFF.WAV";

                    //////////////////////////////

                    SAAN_IS_TRYING_TO_DO_WAVS_ANALYSIS_WITH_1800_BUCKETS

                        .WavMetadata

                        .Read(CURRENT_WAV_FILE_CHOSEN);

                    //////////////////////////////////////////////////////////////////    

                    SAAN_IS_TRYING_TO_DO_WAVS_ANALYSIS_WITH_1800_BUCKETS

                       // .DEEPER_CHECKS___SAAN_IS_TRYING_TO_DO_WAVS_ANALYSIS_WITH_1800_BUCKETS

                        .WavResampler

                       .ConvertToStandardFormat

                       (CURRENT_WAV_FILE_CHOSEN

                       ,

                      SAANS_STANDARD_OUTPUT_WAV_FILE_FIRST_RAW_MATERIAL_TO_PROCEED_8000_SPS_16BITS_PCM_RIFF_WAV_FILES

                      ,

                      ref this.progressBarFOR_ANIMATIONS_SAVING

                       );

                    //////////////////////////////////////////////////////////////////////

                    //WE HAVE TO USE WaitUntilFileIsReady___TOO_IMPORTANT_TO_CHECK

                    System.Windows.Forms.MessageBox.Show("Completes ConvertToStandardFormat");

                    ////////////////////////////////////////////////////////////////////////////////////////

                    SAAN_IS_TRYING_TO_DO_WAVS_ANALYSIS_WITH_1800_BUCKETS

                    .WavResampler

                        .WaitUntilFileIsReady___TOO_IMPORTANT_TO_CHECK

                        (

                        SAANS_STANDARD_OUTPUT_WAV_FILE_FIRST_RAW_MATERIAL_TO_PROCEED_8000_SPS_16BITS_PCM_RIFF_WAV_FILES

                    );

                    ////////////////////////////////////////////////////////////////////////////////

                    /////////WHO WILL CONSTRUCT monoSamples?????????????

                    //////int sps_found = 8000; // hardcoded now because it's our standard format

                    //////float[] monoSamples 

                    //////    =

                    //////    SAAN_IS_TRYING_TO_DO_WAVS_ANALYSIS_WITH_1800_BUCKETS

                    //////    .ThetaRotationBucketer

                    //////    //.ThetaRotationBucketer

                    //////    //.ReadWavMonoAsFloats

                    //////    (

                    //////    SAANS_STANDARD_OUTPUT_WAV_FILE_FIRST_RAW_MATERIAL_TO_PROCEED_8000_SPS_16BITS_PCM_RIFF_WAV_FILES,

                    //////    out sps_found,

                    //////    ref progressBarFOR_ANIMATIONS_SAVING

                    //////);

                    int sps_found = 8000;

                    float[] monoSamples =

                        SAAN_IS_TRYING_TO_DO_WAVS_ANALYSIS_WITH_1800_BUCKETS

                        .WavResampler

                        .ReadWavMonoAsFloats_Chunked

                        //.ReadWavMonoAsFloats

                        (

                            SAANS_STANDARD_OUTPUT_WAV_FILE_FIRST_RAW_MATERIAL_TO_PROCEED_8000_SPS_16BITS_PCM_RIFF_WAV_FILES,

                            out sps_found,

                            ref progressBarFOR_ANIMATIONS_SAVING

                        );

                    //////                    int sps_found = 8000;

                    //////                    float[] monoSamples

                    //////                        =

                    //////SAAN_IS_TRYING_TO_DO_WAVS_ANALYSIS_WITH_1800_BUCKETS

                    //////                        .WavResampler

                    //////                        .ReadWavMonoAsFloats_Chunked

                    //////                        //.ReadWavMonoAsFloats

                    //////                        (

                    //////                        SAANS_STANDARD_OUTPUT_WAV_FILE_FIRST_RAW_MATERIAL_TO_PROCEED_8000_SPS_16BITS_PCM_RIFF_WAV_FILES,

                    //////                        out sps_found,

                    //////                        ref progressBarFOR_ANIMATIONS_SAVING

                    //////                    );

                    ////////////////////////////////////////////////////////////////////////////////////////

                    SAAN_IS_TRYING_TO_DO_WAVS_ANALYSIS_WITH_1800_BUCKETS

                        .ThetaRotationBucketer

                     //ThetaRotationBucketer

                        bucketer

                        =

                        new

                        SAAN_IS_TRYING_TO_DO_WAVS_ANALYSIS_WITH_1800_BUCKETS

                        .ThetaRotationBucketer

                        (monoSamples, sps_found);

                    bucketer.Process___ThetaRotationBucketer

                        (ref progressBarFOR_ANIMATIONS_SAVING);

                    ////////////////////////////////////////////////////////////////////////////////////////

                    List<SAAN_IS_TRYING_TO_DO_WAVS_ANALYSIS_WITH_1800_BUCKETS.ThetaFeature>[] 

                        all1800Buckets 

                        = bucketer

                        .GetBuckets();

                    ////////////////////////////////////////////////////////////////////////////////////////

                    SAAN_IS_TRYING_TO_DO_WAVS_ANALYSIS_WITH_1800_BUCKETS

                    .WavResampler

                        .WaitUntilFileIsReady___TOO_IMPORTANT_TO_CHECK

                        (SAANS_STANDARD_OUTPUT_WAV_FILE_FIRST_RAW_MATERIAL_TO_PROCEED_8000_SPS_16BITS_PCM_RIFF_WAV_FILES);

                    ////////////////////////////////////////////////////////////////////////////////////////

                    ////////////////////////////////////////////////////////////////////////////////////////

                    System.Windows.Forms.MessageBox.Show("DONES");

                    ////////////////////////////////////////////////////////////////////////////////////////

                }//if (openFileDialog.ShowDialog() == DialogResult.OK)

            }

            catch(Exception ___EXCP_FOR_BUTTONS_LEVEL)

            {

                System.Windows.Forms.MessageBox.Show("___EXCP_FOR_BUTTONS_LEVEL = " + ___EXCP_FOR_BUTTONS_LEVEL.Message + "  " + ___EXCP_FOR_BUTTONS_LEVEL.StackTrace.ToString());

                Console.WriteLine("___EXCP_FOR_BUTTONS_LEVEL = " + ___EXCP_FOR_BUTTONS_LEVEL.Message + "  " + ___EXCP_FOR_BUTTONS_LEVEL.StackTrace.ToString());

            }//catch(Exception ___EXCP_FOR_BUTTONS_LEVEL)

        }//private void button_TO_HANDLE_WAVS_WITH_1800_BUCKETS_Click(object sender, EventArgs e)

//////////////////////////

namespace SAAN_IS_TRYING_TO_DO_WAVS_ANALYSIS_WITH_1800_BUCKETS

{

    //////public class ThetaFeature

    //////{

    //////    // I HAVE TO INCORPORATE SEVERAL MORE THINGS HERE

    //////    public int SampleIndex;

    //////    public double TimeMs;

    //////    public double SumLeft;

    //////    public double SumRight;

    //////    public double DeltaGap;

    //////    public double DotProduct;

    //////    public double ThetaDeg;

    //////}//public class ThetaFeature

    public class ThetaFeature

    {

        public int SampleIndex;

        public double TimeMilliseconds;

        public double SumLeft;

        public double SumRight;

        public double GapMilliseconds;

        public double SumDifference;

        public double DotProduct;

        public double ThetaDegrees;

    }//public class ThetaFeature

    public class ThetaRotationBucketer

    {

        private List<ThetaFeature>[] buckets;

        private int sampleRate;

        private float[] samples;

        private int k;

        public ThetaRotationBucketer(float[] monoSamples, int sampleRate)

        {

            this.samples = monoSamples;

            this.sampleRate = sampleRate;

            this.buckets = new List<ThetaFeature>[1801];

            for (int i = 0; i <= 1800; i++)

            {

                buckets[i] = new List<ThetaFeature>();

            }

            this.k = sampleRate / 200; // 100 ms window (k/2 on each side)

        }//public ThetaRotationBucketer(float[] monoSamples, int sampleRate)

        public void Process___ThetaRotationBucketer(ref System.Windows.Forms.ProgressBar progressBar)

        {

            int total = samples.Length;

            int start = k;

            int end = total - k;

            double millisPerSample = 1000.0 / sampleRate;

            progressBar.Maximum = 100;

            for (int i = start; i < end; i++)

            {

                double sumLeft = 0;

                double sumRight = 0;

                double dotProduct = 0;

                for (int j = 1; j <= k; j++)

                {

                    float left = samples[i - j];

                    float right = samples[i + j];

                    sumLeft += left;

                    sumRight += right;

                    dotProduct += left * right;

                }//for (int j = 1; j <= k; j++)

                double dGap = k * 2 * millisPerSample;

                double delta = sumRight - sumLeft;

                double thetaRad = Math.Atan2(delta, dGap);

                double thetaDeg = (180.0 / Math.PI) * thetaRad;

                double absTheta = Math.Abs(thetaDeg);

                int bucketIndex = Math.Min(1800, (int)Math.Round(absTheta * 10));

                ThetaFeature feature = new ThetaFeature()

                {

                    SampleIndex = i,

                    TimeMilliseconds = i * millisPerSample,

                    SumLeft = sumLeft,

                    SumRight = sumRight,

                    GapMilliseconds = dGap,

                    SumDifference = delta,

                    DotProduct = dotProduct,

                    ThetaDegrees = thetaDeg

                };

                buckets[bucketIndex].Add(feature);

                if (i % 10000 == 0)

                {

                    progressBar.Value = (int)((i * 100.0) / total);

                    progressBar.Invalidate();

                    progressBar.Refresh();

                }//if (i % 10000 == 0)

            }//for (int i = start; i < end; i++)

            progressBar.Value = 100;

            progressBar.Invalidate();

            progressBar.Refresh();

        }// public void Process___ThetaRotationBucketer(ref System.Windows.Forms.ProgressBar progressBar)

        public List<ThetaFeature>[] GetBuckets()

        {

            return buckets;

        }//public List<ThetaFeature>[] GetBuckets()

    }//public class ThetaRotationBucketer

    public class WavMetadata

    {

        public static long PUBLIC_STATIC_LONG_TOTAL_SAMPLES_FOUND___TO_CHECK_IF_ALL_SAMPLES_PROCESSING_COMPLETE_OR_NOT = 0;

        public static long PUBLIC_STATIC_LONG_NUMBER_OF_SAMPLES_PROCESSED___TO_CHECK_IF_ALL_SAMPLES_PROCESSING_COMPLETE_OR_NOT = 0;

        public static bool PUBLIC_STATIC_BOOL___IS_THE_RESAMPLING_COMPLETE = false;

        public static bool PUBLIC_STATIC_BOOL___IS_THE_STANDARD_FILE_WRITING_COMPLETE = false;

        public int SampleRate { get; set; }

        public int Channels { get; set; }

        public int BitsPerSample { get; set; }

        public static WavMetadata Read(string path)

        {

            WavMetadata meta = new WavMetadata();

            using (BinaryReader br = new BinaryReader(File.OpenRead(path)))

            {

                br.ReadBytes(12); // RIFF header

                while (br.BaseStream.Position < br.BaseStream.Length)

                {

                    string chunkID = new string(br.ReadChars(4));

                    int chunkSize = br.ReadInt32();

                    if (chunkID == "fmt ")

                    {

                        br.ReadInt16(); // Audio format

                        meta.Channels = br.ReadInt16();

                        meta.SampleRate = br.ReadInt32();

                        br.ReadInt32(); // Byte rate

                        br.ReadInt16(); // Block align

                        meta.BitsPerSample = br.ReadInt16();

                        if (chunkSize > 16) br.ReadBytes(chunkSize - 16);

                    }

                    else

                    {

                        br.BaseStream.Position += chunkSize;

                    }//END OF ELSE OF if (chunkID == "fmt ")

                }//while (br.BaseStream.Position < br.BaseStream.Length)

            }//using (BinaryReader br = new BinaryReader(File.OpenRead(path)))

            return meta;

        }//public static WavMetadata Read(string path)

    }//public class WavMetadata

    public static class WavResampler

    {

        public static void ConvertToStandardFormat(string inputPath, string outputPath, ref System.Windows.Forms.ProgressBar progressbartotrack)

        {

            int originalSps, channels, bits;

            WavMetadata metadata = WavMetadata.Read(inputPath);

            originalSps = metadata.SampleRate;

            channels = metadata.Channels;

            bits = metadata.BitsPerSample;

            float[] samples = ReadWavMonoAsFloats_Chunked(inputPath, out originalSps, ref progressbartotrack);

            double durationInSeconds = (double)samples.Length / originalSps;

            int targetSampleCount = (int)(durationInSeconds * 8000);

            float[] resampled = ResampleHermite_Chunked(samples, targetSampleCount, ref progressbartotrack);

            WriteMonoPcmWav(outputPath, resampled, 8000, 16, ref progressbartotrack);

        }//public static void ConvertToStandardFormat(...)

        public static float[] ResampleHermite_Chunked(float[] input, int targetLength, ref System.Windows.Forms.ProgressBar progressbartotrack)

        {

            float[] result = new float[targetLength];

            double step = (double)(input.Length - 1) / (targetLength - 1);

            int chunkSize = 8192;

            WavMetadata.PUBLIC_STATIC_LONG_TOTAL_SAMPLES_FOUND___TO_CHECK_IF_ALL_SAMPLES_PROCESSING_COMPLETE_OR_NOT = targetLength;

            progressbartotrack.Maximum = 100;

            for (int start = 0; start < targetLength; start += chunkSize)

            {

                int end = Math.Min(start + chunkSize, targetLength);

                for (int i = start; i < end; i++)

                {

                    double pos = i * step;

                    int idx = (int)Math.Floor(pos);

                    double frac = pos - idx;

                    float y0 = idx > 0 ? input[idx - 1] : input[0];

                    float y1 = input[idx];

                    float y2 = (idx + 1 < input.Length) ? input[idx + 1] : input[input.Length - 1];

                    float y3 = (idx + 2 < input.Length) ? input[idx + 2] : input[input.Length - 1];

                    result[i] = HermiteInterpolate(y0, y1, y2, y3, (float)frac);

                }

                progressbartotrack.Value = (int)((start * 100.0) / targetLength);

                progressbartotrack.Invalidate();

                progressbartotrack.Refresh();

            }

            WavMetadata.PUBLIC_STATIC_BOOL___IS_THE_RESAMPLING_COMPLETE = true;

            return result;

        }//public static float[] ResampleHermite_Chunked(...)

        private static float HermiteInterpolate(float y0, float y1, float y2, float y3, float mu)

        {

            float mu2 = mu * mu;

            float a0 = -0.5f * y0 + 1.5f * y1 - 1.5f * y2 + 0.5f * y3;

            float a1 = y0 - 2.5f * y1 + 2f * y2 - 0.5f * y3;

            float a2 = -0.5f * y0 + 0.5f * y2;

            float a3 = y1;

            return a0 * mu * mu2 + a1 * mu2 + a2 * mu + a3;

        }//private static float HermiteInterpolate(...)

        public static void WriteMonoPcmWav(string path, float[] samples, int sampleRate, int bits, ref System.Windows.Forms.ProgressBar progressbartotrack)

        {

            using (BinaryWriter bw = new BinaryWriter(File.Create(path)))

            {

                int dataSize = samples.Length * (bits / 8);

                bw.Write(System.Text.Encoding.ASCII.GetBytes("RIFF"));

                bw.Write(36 + dataSize);

                bw.Write(System.Text.Encoding.ASCII.GetBytes("WAVE"));

                bw.Write(System.Text.Encoding.ASCII.GetBytes("fmt "));

                bw.Write(16);

                bw.Write((short)1);

                bw.Write((short)1);

                bw.Write(sampleRate);

                bw.Write(sampleRate * bits / 8);

                bw.Write((short)(bits / 8));

                bw.Write((short)bits);

                bw.Write(System.Text.Encoding.ASCII.GetBytes("data"));

                bw.Write(dataSize);

                int chunkSize = 8192;

                for (int i = 0; i < samples.Length; i += chunkSize)

                {

                    int blockEnd = Math.Min(i + chunkSize, samples.Length);

                    for (int j = i; j < blockEnd; j++)

                    {

                        short val = (short)(Math.Max(-1f, Math.Min(1f, samples[j])) * short.MaxValue);

                        bw.Write(val);

                    }

                    progressbartotrack.Value = (int)((i * 100.0) / samples.Length);

                    progressbartotrack.Invalidate();

                    progressbartotrack.Refresh();

                }

                WavMetadata.PUBLIC_STATIC_BOOL___IS_THE_STANDARD_FILE_WRITING_COMPLETE = true;

            }

        }//public static void WriteMonoPcmWav(...)

        public static float[] ReadWavMonoAsFloats_Chunked(string path, out int sampleRate, ref System.Windows.Forms.ProgressBar progressbartotrack)

        {

            sampleRate = 8000;

            using (BinaryReader br = new BinaryReader(File.OpenRead(path)))

            {

                br.BaseStream.Seek(0, SeekOrigin.Begin);

                br.ReadBytes(12);

                int channels = 1, bits = 16;

                while (br.BaseStream.Position < br.BaseStream.Length)

                {

                    string chunkID = new string(br.ReadChars(4));

                    int chunkSize = br.ReadInt32();

                    if (chunkID == "fmt ")

                    {

                        br.ReadInt16();

                        channels = br.ReadInt16();

                        sampleRate = br.ReadInt32();

                        br.ReadInt32();

                        br.ReadInt16();

                        bits = br.ReadInt16();

                        if (chunkSize > 16) br.ReadBytes(chunkSize - 16);

                    }

                    else if (chunkID == "data")

                    {

                        int bytesPerSample = bits / 8;

                        int totalSamples = chunkSize / bytesPerSample;

                        float[] samples = new float[totalSamples / channels];

                        byte[] buffer = new byte[chunkSize];

                        br.Read(buffer, 0, chunkSize);

                        int index = 0;

                        for (int i = 0; i < buffer.Length; i += channels * bytesPerSample)

                        {

                            short sample = BitConverter.ToInt16(buffer, i);

                            samples[index++] = sample / 32768f;

                        }

                        return samples;

                    }

                    else

                    {

                        br.BaseStream.Position += chunkSize;

                    }

                }

            }

            return new float[0];

        }//public static float[] ReadWavMonoAsFloats_Chunked(...)

        public static void WaitUntilFileIsReady___TOO_IMPORTANT_TO_CHECK(string path, int timeoutMs = 5000)

        {

            DateTime start = DateTime.Now;

            while (true)

            {

                try

                {

                    using (FileStream fs = File.Open(path, FileMode.Open, FileAccess.Read, FileShare.None))

                    {

                        if (fs.Length > 0) return;

                    }

                }

                catch (IOException) { }

                if ((DateTime.Now - start).TotalMilliseconds > timeoutMs)

                    throw new TimeoutException("File was not ready within timeout.");

                System.Threading.Thread.Sleep(100);

            }//while (true)

        }//public static void WaitUntilFileIsReady___TOO_IMPORTANT_TO_CHECK(...)

    }//public static class WavResampler

    //////public static class WavResampler

    //////{

    //////    public static void ConvertToStandardFormat(string inputPath, string outputPath, ref System.Windows.Forms.ProgressBar progressbartotrack)

    //////    {

    //////        int originalSps, channels, bits;

    //////        WavMetadata metadata = WavMetadata.Read(inputPath);

    //////        originalSps = metadata.SampleRate;

    //////        channels = metadata.Channels;

    //////        bits = metadata.BitsPerSample;

    //////        float[] samples = ReadWavMonoAsFloats(inputPath, out originalSps, ref progressbartotrack);

    //////        double durationInSeconds = (double)samples.Length / originalSps;

    //////        int targetSampleCount = (int)(durationInSeconds * 8000);

    //////        NormalizeSamples(ref samples);

    //////        float[] resampled = Resample(samples, targetSampleCount, ref progressbartotrack);

    //////        WriteMonoPcmWav(outputPath, resampled, 8000, 16, ref progressbartotrack);

    //////    }

    //////    public static float[] Resample(float[] input, int targetLength, ref System.Windows.Forms.ProgressBar progressbartotrack)

    //////    {

    //////        float[] result = new float[targetLength];

    //////        double step = (double)(input.Length - 1) / (targetLength - 1);

    //////        WavMetadata.PUBLIC_STATIC_LONG_TOTAL_SAMPLES_FOUND___TO_CHECK_IF_ALL_SAMPLES_PROCESSING_COMPLETE_OR_NOT = targetLength;

    //////        progressbartotrack.Maximum = 100;

    //////        for (int i = 0; i < targetLength; i++)

    //////        {

    //////            double pos = i * step;

    //////            int idx = (int)pos;

    //////            double frac = pos - idx;

    //////            if (idx + 1 >= input.Length)

    //////            {

    //////                result[i] = input[input.Length - 1];

    //////            }

    //////            else

    //////            {

    //////                result[i] = (float)((1 - frac) * input[idx] + frac * input[idx + 1]);

    //////            }

    //////            WavMetadata.PUBLIC_STATIC_LONG_NUMBER_OF_SAMPLES_PROCESSED___TO_CHECK_IF_ALL_SAMPLES_PROCESSING_COMPLETE_OR_NOT = i;

    //////            progressbartotrack.Value = Math.Min(100, (int)((i * 100.0) / targetLength));

    //////            progressbartotrack.Invalidate();

    //////            progressbartotrack.Refresh();

    //////        }

    //////        WavMetadata.PUBLIC_STATIC_BOOL___IS_THE_RESAMPLING_COMPLETE = true;

    //////        return result;

    //////    }

    //////    public static void WriteMonoPcmWav(string path, float[] samples, int sampleRate, int bits, ref System.Windows.Forms.ProgressBar progressbartotrack)

    //////    {

    //////        using (BinaryWriter bw = new BinaryWriter(File.Create(path)))

    //////        {

    //////            int dataSize = samples.Length * (bits / 8);

    //////            bw.Write(System.Text.Encoding.ASCII.GetBytes("RIFF"));

    //////            bw.Write(36 + dataSize);

    //////            bw.Write(System.Text.Encoding.ASCII.GetBytes("WAVE"));

    //////            bw.Write(System.Text.Encoding.ASCII.GetBytes("fmt "));

    //////            bw.Write(16);

    //////            bw.Write((short)1);

    //////            bw.Write((short)1);

    //////            bw.Write(sampleRate);

    //////            bw.Write(sampleRate * bits / 8);

    //////            bw.Write((short)(bits / 8));

    //////            bw.Write((short)bits);

    //////            bw.Write(System.Text.Encoding.ASCII.GetBytes("data"));

    //////            bw.Write(dataSize);

    //////            WavMetadata.PUBLIC_STATIC_LONG_TOTAL_SAMPLES_FOUND___TO_CHECK_IF_ALL_SAMPLES_PROCESSING_COMPLETE_OR_NOT = samples.LongLength;

    //////            progressbartotrack.Maximum = 100;

    //////            for (long i = 0; i < samples.LongLength; i++)

    //////            {

    //////                float s = samples[i];

    //////                short val = (short)(Math.Max(-1f, Math.Min(1f, s)) * short.MaxValue);

    //////                bw.Write(val);

    //////                WavMetadata.PUBLIC_STATIC_LONG_NUMBER_OF_SAMPLES_PROCESSED___TO_CHECK_IF_ALL_SAMPLES_PROCESSING_COMPLETE_OR_NOT = i;

    //////                progressbartotrack.Value = Math.Min(100, (int)((i * 100.0) / samples.LongLength));

    //////                progressbartotrack.Invalidate();

    //////                progressbartotrack.Refresh();

    //////            }

    //////            WavMetadata.PUBLIC_STATIC_BOOL___IS_THE_STANDARD_FILE_WRITING_COMPLETE = true;

    //////        }

    //////    }

    //////    public static void NormalizeSamples(ref float[] samples)

    //////    {

    //////        float max = samples.Max(s => Math.Abs(s));

    //////        if (max < 0.00001f) return; // prevent divide by near-zero

    //////        for (int i = 0; i < samples.Length; i++)

    //////        {

    //////            samples[i] /= max;

    //////        }

    //////    }

    //////    public static float[] ReadWavMonoAsFloats(string path, out int sampleRate, ref System.Windows.Forms.ProgressBar progressbartotrack)

    //////    {

    //////        sampleRate = 8000;

    //////        using (BinaryReader br = new BinaryReader(File.OpenRead(path)))

    //////        {

    //////            br.BaseStream.Seek(0, SeekOrigin.Begin);

    //////            br.ReadBytes(12);

    //////            int channels = 1, bits = 16;

    //////            while (br.BaseStream.Position < br.BaseStream.Length)

    //////            {

    //////                string chunkID = new string(br.ReadChars(4));

    //////                int chunkSize = br.ReadInt32();

    //////                if (chunkID == "fmt ")

    //////                {

    //////                    br.ReadInt16();

    //////                    channels = br.ReadInt16();

    //////                    sampleRate = br.ReadInt32();

    //////                    br.ReadInt32();

    //////                    br.ReadInt16();

    //////                    bits = br.ReadInt16();

    //////                    if (chunkSize > 16) br.ReadBytes(chunkSize - 16);

    //////                }

    //////                else if (chunkID == "data")

    //////                {

    //////                    int bytesPerSample = bits / 8;

    //////                    int totalSamples = chunkSize / bytesPerSample;

    //////                    float[] samples = new float[totalSamples / channels];

    //////                    int j = 0;

    //////                    for (int i = 0; i < totalSamples; i++)

    //////                    {

    //////                        if (br.BaseStream.Position + 2 > br.BaseStream.Length) break;

    //////                        short sample = br.ReadInt16();

    //////                        if (channels == 1 || i % channels == 0)

    //////                        {

    //////                            samples[j++] = sample / 32768f;

    //////                        }

    //////                        if (channels == 2) { br.ReadInt16(); }

    //////                    }

    //////                    return samples;

    //////                }

    //////                else

    //////                {

    //////                    br.BaseStream.Position += chunkSize;

    //////                }

    //////            }

    //////        }

    //////        return new float[0];

    //////    }

    //////    public static void WaitUntilFileIsReady___TOO_IMPORTANT_TO_CHECK(string path, int timeoutMs = 5000)

    //////    {

    //////        DateTime start = DateTime.Now;

    //////        while (true)

    //////        {

    //////            try

    //////            {

    //////                using (FileStream fs = File.Open(path, FileMode.Open, FileAccess.Read, FileShare.None))

    //////                {

    //////                    if (fs.Length > 0) return;

    //////                }

    //////            }

    //////            catch (IOException) { }

    //////            if ((DateTime.Now - start).TotalMilliseconds > timeoutMs)

    //////                throw new TimeoutException("File was not ready within timeout.");

    //////            System.Threading.Thread.Sleep(100);

    //////        }

    //////    }

    //////}//public static class WavResampler

    //////    public static class WavResampler

    //////    {

    //////        public static void ConvertToStandardFormat(string inputPath, string outputPath, ref System.Windows.Forms.ProgressBar progressbartotrack)

    //////        {

    //////            int originalSps, channels, bits;

    //////            WavMetadata metadata = WavMetadata.Read(inputPath);

    //////            originalSps = metadata.SampleRate;

    //////            channels = metadata.Channels;

    //////            bits = metadata.BitsPerSample;

    //////            float[] samples = ReadWavMonoAsFloats(inputPath, out originalSps, ref progressbartotrack);

    //////            double durationInSeconds = (double)samples.Length / originalSps;

    //////            int targetSampleCount = (int)(durationInSeconds * 8000);

    //////            NormalizeSamples(ref samples);

    //////            float[] resampled = Resample(samples, targetSampleCount, ref progressbartotrack);

    //////            WriteMonoPcmWav(outputPath, resampled, 8000, 16, ref progressbartotrack);

    //////    }//public static void ConvertToStandardFormat(string inputPath, string outputPath, ref System.Windows.Forms.ProgressBar progressbartotrack)

    //////    private static float HermiteInterpolate(float y0, float y1, float y2, float y3, float mu)

    //////    {

    //////        float mu2 = mu * mu;

    //////        float a0 = -0.5f * y0 + 1.5f * y1 - 1.5f * y2 + 0.5f * y3;

    //////        float a1 = y0 - 2.5f * y1 + 2f * y2 - 0.5f * y3;

    //////        float a2 = -0.5f * y0 + 0.5f * y2;

    //////        float a3 = y1;

    //////        return a0 * mu * mu2 + a1 * mu2 + a2 * mu + a3;

    //////    }//private static float HermiteInterpolate(float y0, float y1, float y2, float y3, float mu)

    //////    public static float[] Resample(float[] input, int targetLength, ref System.Windows.Forms.ProgressBar progressbartotrack)

    //////        {

    //////            float[] result = new float[targetLength];

    //////            double step = (double)(input.Length - 1) / (targetLength - 1);

    //////            WavMetadata.PUBLIC_STATIC_LONG_TOTAL_SAMPLES_FOUND___TO_CHECK_IF_ALL_SAMPLES_PROCESSING_COMPLETE_OR_NOT = targetLength;

    //////            progressbartotrack.Maximum = 100;

    //////            for (int i = 0; i < targetLength; i++)

    //////            {

    //////                double pos = i * step;

    //////                int idx = (int)pos;

    //////                double frac = pos - idx;

    //////                if (idx + 1 >= input.Length)

    //////                {

    //////                    result[i] = input[input.Length - 1];

    //////                }

    //////                else

    //////                {

    //////                    result[i] = (float)((1 - frac) * input[idx] + frac * input[idx + 1]);

    //////            }//end of else of if (idx + 1 >= input.Length)

    //////            WavMetadata.PUBLIC_STATIC_LONG_NUMBER_OF_SAMPLES_PROCESSED___TO_CHECK_IF_ALL_SAMPLES_PROCESSING_COMPLETE_OR_NOT = i;

    //////                progressbartotrack.Value = Math.Min(100, (int)((i * 100.0) / targetLength));

    //////                progressbartotrack.Invalidate();

    //////                progressbartotrack.Refresh();

    //////        }//for (int i = 0; i < targetLength; i++)

    //////        WavMetadata.PUBLIC_STATIC_BOOL___IS_THE_RESAMPLING_COMPLETE = true;

    //////            return result;

    //////    }//public static float[] Resample(float[] input, int targetLength, ref System.Windows.Forms.ProgressBar progressbartotrack)

    //////    public static void WriteMonoPcmWav(string path, float[] samples, int sampleRate, int bits, ref System.Windows.Forms.ProgressBar progressbartotrack)

    //////        {

    //////            using (BinaryWriter bw = new BinaryWriter(File.Create(path)))

    //////            {

    //////                int dataSize = samples.Length * (bits / 8);

    //////                bw.Write(System.Text.Encoding.ASCII.GetBytes("RIFF"));

    //////                bw.Write(36 + dataSize);

    //////                bw.Write(System.Text.Encoding.ASCII.GetBytes("WAVE"));

    //////                bw.Write(System.Text.Encoding.ASCII.GetBytes("fmt "));

    //////                bw.Write(16);

    //////                bw.Write((short)1);

    //////                bw.Write((short)1);

    //////                bw.Write(sampleRate);

    //////                bw.Write(sampleRate * bits / 8);

    //////                bw.Write((short)(bits / 8));

    //////                bw.Write((short)bits);

    //////                bw.Write(System.Text.Encoding.ASCII.GetBytes("data"));

    //////                bw.Write(dataSize);

    //////                WavMetadata.PUBLIC_STATIC_LONG_TOTAL_SAMPLES_FOUND___TO_CHECK_IF_ALL_SAMPLES_PROCESSING_COMPLETE_OR_NOT = samples.LongLength;

    //////                progressbartotrack.Maximum = 100;

    //////                for (long i = 0; i < samples.LongLength; i++)

    //////                {

    //////                    float s = samples[i];

    //////                    short val = (short)(Math.Max(-1f, Math.Min(1f, s)) * short.MaxValue);

    //////                    bw.Write(val);

    //////                    WavMetadata.PUBLIC_STATIC_LONG_NUMBER_OF_SAMPLES_PROCESSED___TO_CHECK_IF_ALL_SAMPLES_PROCESSING_COMPLETE_OR_NOT = i;

    //////                    progressbartotrack.Value = Math.Min(100, (int)((i * 100.0) / samples.LongLength));

    //////                    progressbartotrack.Invalidate();

    //////                    progressbartotrack.Refresh();

    //////            }//for (long i = 0; i < samples.LongLength; i++)

    //////            WavMetadata.PUBLIC_STATIC_BOOL___IS_THE_STANDARD_FILE_WRITING_COMPLETE = true;

    //////        }//using (BinaryWriter bw = new BinaryWriter(File.Create(path)))

    //////    }//public static void WriteMonoPcmWav(string path, float[] samples, int sampleRate, int bits, ref System.Windows.Forms.ProgressBar progressbartotrack)

    //////    public static void NormalizeSamples(ref float[] samples)

    //////        {

    //////            float max = samples.Max(s => Math.Abs(s));

    //////            if (max < 0.00001f) return; // prevent divide by near-zero

    //////            for (int i = 0; i < samples.Length; i++)

    //////            {

    //////                samples[i] /= max;

    //////            }

    //////        }

    //////        public static float[] ReadWavMonoAsFloats(string path, out int sampleRate, ref System.Windows.Forms.ProgressBar progressbartotrack)

    //////        {

    //////            sampleRate = 8000;

    //////            using (BinaryReader br = new BinaryReader(File.OpenRead(path)))

    //////            {

    //////                br.BaseStream.Seek(0, SeekOrigin.Begin);

    //////                br.ReadBytes(12);

    //////                int channels = 1, bits = 16;

    //////                while (br.BaseStream.Position < br.BaseStream.Length)

    //////                {

    //////                    string chunkID = new string(br.ReadChars(4));

    //////                    int chunkSize = br.ReadInt32();

    //////                    if (chunkID == "fmt ")

    //////                    {

    //////                        br.ReadInt16();

    //////                        channels = br.ReadInt16();

    //////                        sampleRate = br.ReadInt32();

    //////                        br.ReadInt32();

    //////                        br.ReadInt16();

    //////                        bits = br.ReadInt16();

    //////                        if (chunkSize > 16) br.ReadBytes(chunkSize - 16);

    //////                    }

    //////                    else if (chunkID == "data")

    //////                    {

    //////                        int bytesPerSample = bits / 8;

    //////                        int totalSamples = chunkSize / bytesPerSample;

    //////                        float[] samples = new float[totalSamples / channels];

    //////                        int j = 0;

    //////                        for (int i = 0; i < totalSamples; i++)

    //////                        {

    //////                            if (br.BaseStream.Position + 2 > br.BaseStream.Length) break;

    //////                            short sample = br.ReadInt16();

    //////                            if (channels == 1 || i % channels == 0)

    //////                            {

    //////                                samples[j++] = sample / 32768f;

    //////                            }

    //////                            if (channels == 2) { br.ReadInt16(); }

    //////                        }

    //////                        return samples;

    //////                    }

    //////                    else

    //////                    {

    //////                        br.BaseStream.Position += chunkSize;

    //////                    }

    //////                }

    //////            }

    //////            return new float[0];

    //////    }// public static float[] ReadWavMonoAsFloats(string path, out int sampleRate, ref System.Windows.Forms.ProgressBar progressbartotrack)

    //////    public static void WaitUntilFileIsReady___TOO_IMPORTANT_TO_CHECK(string path, int timeoutMs = 5000)

    //////        {

    //////            DateTime start = DateTime.Now;

    //////            while (true)

    //////            {

    //////                try

    //////                {

    //////                    using (FileStream fs = File.Open(path, FileMode.Open, FileAccess.Read, FileShare.None))

    //////                    {

    //////                        if (fs.Length > 0) return;

    //////                    }

    //////                }

    //////                catch (IOException) { }

    //////                if ((DateTime.Now - start).TotalMilliseconds > timeoutMs)

    //////                    throw new TimeoutException("File was not ready within timeout.");

    //////                System.Threading.Thread.Sleep(100);

    //////        }//while (true)

    //////    }// public static void WaitUntilFileIsReady___TOO_IMPORTANT_TO_CHECK(string path, int timeoutMs = 5000)

    //////}//public static class WavResampler

    // this above is also bad not at par to audacity

    /// below is also bad 

    //////    public static class WavResampler

    //////    {

    //////        public static void discarding___ConvertToStandardFormat(string inputPath, string outputPath,ref System.Windows.Forms.ProgressBar progressbartotrack)

    //////        {

    //////            int originalSps, channels, bits;

    //////            WavMetadata metadata = WavMetadata.Read(inputPath);

    //////            originalSps = metadata.SampleRate;

    //////            channels = metadata.Channels;

    //////            bits = metadata.BitsPerSample;

    //////            //ref System.Windows.Forms.ProgressBar progressbartotrack

    //////            float[] samples = ReadWavMonoAsFloats(inputPath, out _ , ref progressbartotrack);

    //////            int newSampleCount = (int)((8000.0 / originalSps) * samples.Length);

    //////            //ref System.Windows.Forms.ProgressBar progressbartotrack

    //////            float[] resampled = Resample(samples, newSampleCount,ref  progressbartotrack);

    //////            //ref System.Windows.Forms.ProgressBar progressbartotrack

    //////            WriteMonoPcmWav(outputPath, resampled, 8000, 16, ref progressbartotrack);

    //////        }//public static void ConvertToStandardFormat(string inputPath, string outputPath)

    //////        public static void ConvertToStandardFormat(string inputPath, string outputPath, ref System.Windows.Forms.ProgressBar progressbartotrack)

    //////        {

    //////            int originalSps, channels, bits;

    //////            WavMetadata metadata = WavMetadata.Read(inputPath);

    //////            originalSps = metadata.SampleRate;

    //////            channels = metadata.Channels;

    //////            bits = metadata.BitsPerSample;

    //////            // Read original WAV samples with progress

    //////            float[] samples = ReadWavMonoAsFloats(inputPath, out originalSps, ref progressbartotrack);

    //////            // New logic: compute original duration based on full file's actual sample count & sample rate

    //////            double durationInSeconds = (double)samples.Length / originalSps;

    //////            //  Target sample count based on duration to match Audacity behavior

    //////            int targetSampleCount = (int)(durationInSeconds * 8000);

    //////            // Resample to exact length, tracking progress

    //////            float[] resampled = Resample(samples, targetSampleCount, ref progressbartotrack);

    //////            // Write to 8000 SPS, 16-bit mono file

    //////            WriteMonoPcmWav(outputPath, resampled, 8000, 16, ref progressbartotrack);

    //////        }//public static void ConvertToStandardFormat(string inputPath, string outputPath)

    //////        //ref System.Windows.Forms.ProgressBar progressbartotrack

    //////        public static float[] Resample(float[] input, int targetLength, ref System.Windows.Forms.ProgressBar progressbartotrack)

    //////        {

    //////            float[] result = new float[targetLength];

    //////            double step = (double)(input.Length - 1) / (targetLength - 1);

    //////            long ___long___total_samples = 0;

    //////            ___long___total_samples = targetLength;// samples.LongCount();

    //////            long __long_number_of_items_processed = 0;

    //////            WavMetadata

    //////            .PUBLIC_STATIC_LONG_TOTAL_SAMPLES_FOUND___TO_CHECK_IF_ALL_SAMPLES_PROCESSING_COMPLETE_OR_NOT

    //////                =

    //////                ___long___total_samples;

    //////            progressbartotrack.Maximum = 100;

    //////            progressbartotrack.Value = 0;

    //////            progressbartotrack.Invalidate();

    //////            progressbartotrack.Refresh();

    //////            //////FOR REFERENCES   public static long PUBLIC_STATIC_LONG_TOTAL_SAMPLES_FOUND___TO_CHECK_IF_ALL_SAMPLES_PROCESSING_COMPLETE_OR_NOT = 0;

    //////            //////FOR REFERENCES   public static long PUBLIC_STATIC_LONG_NUMBER_OF_SAMPLES_PROCESSED___TO_CHECK_IF_ALL_SAMPLES_PROCESSING_COMPLETE_OR_NOT = 0;

    //////            //////FOR REFERENCES   public static bool PUBLIC_STATIC_BOOL___IS_THE_RESAMPLING_COMPLETE = false;

    //////            //////FOR REFERENCES   public static bool PUBLIC_STATIC_BOOL___IS_THE_STANDARD_FILE_WRITING_COMPLETE = false;

    //////            for (int i = 0; i < targetLength; i++)

    //////            {

    //////                WavMetadata

    //////               .PUBLIC_STATIC_LONG_NUMBER_OF_SAMPLES_PROCESSED___TO_CHECK_IF_ALL_SAMPLES_PROCESSING_COMPLETE_OR_NOT

    //////               = i;

    //////                progressbartotrack.Value = (int)((i/ targetLength))*100;

    //////                progressbartotrack.Invalidate();

    //////                progressbartotrack.Refresh();

    //////                double pos = i * step;

    //////                int idx = (int)pos;

    //////                double frac = pos - idx;

    //////                result[i] = (idx + 1 < input.Length)

    //////                    ? (float)((1 - frac) * input[idx] + frac * input[idx + 1])

    //////                    : input[idx];

    //////            }// for (int i = 0; i < targetLength; i++)

    //////            if (

    //////            WavMetadata

    //////            .PUBLIC_STATIC_LONG_TOTAL_SAMPLES_FOUND___TO_CHECK_IF_ALL_SAMPLES_PROCESSING_COMPLETE_OR_NOT

    //////            ==

    //////            WavMetadata

    //////            .PUBLIC_STATIC_LONG_NUMBER_OF_SAMPLES_PROCESSED___TO_CHECK_IF_ALL_SAMPLES_PROCESSING_COMPLETE_OR_NOT

    //////            )

    //////            {

    //////                WavMetadata

    //////                .PUBLIC_STATIC_BOOL___IS_THE_RESAMPLING_COMPLETE = true;

    //////            }

    //////            //////if (

    //////            //////WavMetadata

    //////            //////.PUBLIC_STATIC_LONG_TOTAL_SAMPLES_FOUND___TO_CHECK_IF_ALL_SAMPLES_PROCESSING_COMPLETE_OR_NOT

    //////            //////==

    //////            //////WavMetadata

    //////            //////.PUBLIC_STATIC_LONG_NUMBER_OF_SAMPLES_PROCESSED___TO_CHECK_IF_ALL_SAMPLES_PROCESSING_COMPLETE_OR_NOT

    //////            //////)

    //////            return result;

    //////        }//public static float[] Resample(float[] input, int targetLength)

    //////        public static void WaitUntilFileIsReady___TOO_IMPORTANT_TO_CHECK(string path, int timeoutMs = 5000)

    //////        {

    //////            DateTime start = DateTime.Now;

    //////            while (true)

    //////            {

    //////                try

    //////                {

    //////                    using (FileStream fs = File.Open(path, FileMode.Open, FileAccess.Read, FileShare.None))

    //////                    {

    //////                        if (fs.Length > 0)

    //////                            return; // File is ready

    //////                    }//using (FileStream fs = File.Open(path, FileMode.Open, FileAccess.Read, FileShare.None))

    //////                }

    //////                catch (IOException)

    //////                {

    //////                    // File is still locked or being written

    //////                }

    //////                if ((DateTime.Now - start).TotalMilliseconds > timeoutMs)

    //////                    throw new TimeoutException("File was not ready within timeout.");

    //////                System.Threading.Thread.Sleep(100); // small wait before retrying

    //////            }//while (true)

    //////        }//public static void WaitUntilFileIsReady___TOO_IMPORTANT_TO_CHECK(string path, int timeoutMs = 5000)

    //////        //ref System.Windows.Forms.ProgressBar progressbartotrack

    //////        public static void WriteMonoPcmWav(string path, float[] samples, int sampleRate, int bits, ref System.Windows.Forms.ProgressBar progressbartotrack)

    //////        {

    //////            using (BinaryWriter bw = new BinaryWriter(File.Create(path)))

    //////            {

    //////                int dataSize = samples.Length * (bits / 8);

    //////                // Header

    //////                bw.Write(Encoding.ASCII.GetBytes("RIFF"));

    //////                bw.Write(36 + dataSize);

    //////                bw.Write(Encoding.ASCII.GetBytes("WAVE"));

    //////                bw.Write(Encoding.ASCII.GetBytes("fmt "));

    //////                bw.Write(16);

    //////                bw.Write((short)1); // PCM

    //////                bw.Write((short)1); // Mono

    //////                bw.Write(sampleRate);

    //////                bw.Write(sampleRate * bits / 8);

    //////                bw.Write((short)(bits / 8));

    //////                bw.Write((short)bits);

    //////                bw.Write(Encoding.ASCII.GetBytes("data"));

    //////                bw.Write(dataSize);

    //////                int total_samples_counter = (int)samples.LongCount();

    //////                int number_of_samples_processed = 0;

    //////                //////FOR REFERENCES   public static long PUBLIC_STATIC_LONG_TOTAL_SAMPLES_FOUND___TO_CHECK_IF_ALL_SAMPLES_PROCESSING_COMPLETE_OR_NOT = 0;

    //////                //////FOR REFERENCES   public static long PUBLIC_STATIC_LONG_NUMBER_OF_SAMPLES_PROCESSED___TO_CHECK_IF_ALL_SAMPLES_PROCESSING_COMPLETE_OR_NOT = 0;

    //////                //////FOR REFERENCES   public static bool PUBLIC_STATIC_BOOL___IS_THE_RESAMPLING_COMPLETE = false;

    //////                //////FOR REFERENCES   public static bool PUBLIC_STATIC_BOOL___IS_THE_STANDARD_FILE_WRITING_COMPLETE = false;

    //////                long ___long___total_samples = 0;

    //////                ___long___total_samples = samples.LongCount();

    //////                long __long_number_of_items_processed = 0;

    //////                progressbartotrack.Maximum = 100;

    //////                progressbartotrack.Value = 0;

    //////                progressbartotrack.Invalidate();

    //////                progressbartotrack.Refresh();

    //////                WavMetadata

    //////              .PUBLIC_STATIC_LONG_TOTAL_SAMPLES_FOUND___TO_CHECK_IF_ALL_SAMPLES_PROCESSING_COMPLETE_OR_NOT

    //////              = ___long___total_samples;

    //////                //WE HAVE TO USE WaitUntilFileIsReady___TOO_IMPORTANT_TO_CHECK

    //////                foreach (float s in samples)

    //////                {

    //////                    number_of_samples_processed++;

    //////                    __long_number_of_items_processed++;

    //////                    progressbartotrack.Value = ((int)((__long_number_of_items_processed / ___long___total_samples) * 100));

    //////                    progressbartotrack.Invalidate();

    //////                    progressbartotrack.Refresh();

    //////                    WavMetadata

    //////                    .PUBLIC_STATIC_LONG_NUMBER_OF_SAMPLES_PROCESSED___TO_CHECK_IF_ALL_SAMPLES_PROCESSING_COMPLETE_OR_NOT

    //////                    = __long_number_of_items_processed;

    //////                    short val = (short)(Math.Max(-1f, Math.Min(1f, s)) * short.MaxValue);

    //////                    bw.Write(val);

    //////                }//foreach (float s in samples)

    //////if(

    //////WavMetadata

    //////.PUBLIC_STATIC_LONG_TOTAL_SAMPLES_FOUND___TO_CHECK_IF_ALL_SAMPLES_PROCESSING_COMPLETE_OR_NOT

    //////==

    //////WavMetadata

    //////.PUBLIC_STATIC_LONG_NUMBER_OF_SAMPLES_PROCESSED___TO_CHECK_IF_ALL_SAMPLES_PROCESSING_COMPLETE_OR_NOT

    //////)

    //////{

    //////                    WavMetadata

    //////                    .PUBLIC_STATIC_BOOL___IS_THE_STANDARD_FILE_WRITING_COMPLETE = true;

    //////}

    ////////////if (

    ////////////WavMetadata

    ////////////.PUBLIC_STATIC_LONG_TOTAL_SAMPLES_FOUND___TO_CHECK_IF_ALL_SAMPLES_PROCESSING_COMPLETE_OR_NOT

    ////////////==

    ////////////WavMetadata

    ////////////.PUBLIC_STATIC_LONG_NUMBER_OF_SAMPLES_PROCESSED___TO_CHECK_IF_ALL_SAMPLES_PROCESSING_COMPLETE_OR_NOT

    ////////////)

    //////            }//using (BinaryWriter bw = new BinaryWriter(File.Create(path)))

    //////        }//public static void WriteMonoPcmWav(string path, float[] samples, int sampleRate, int bits)

    //////        /// THERE WAS ERRORS WHILE HANDLING HEAVY FILES

    //////        //////public static float[] ReadWavMonoAsFloats(string path, out int sampleRate)

    //////        //////{

    //////        //////    sampleRate = 8000;

    //////        //////    using (BinaryReader br = new BinaryReader(File.OpenRead(path)))

    //////        //////    {

    //////        //////        br.BaseStream.Seek(0, SeekOrigin.Begin);

    //////        //////        br.ReadBytes(12);

    //////        //////        int channels = 1, bits = 16;

    //////        //////        while (br.BaseStream.Position < br.BaseStream.Length)

    //////        //////        {

    //////        //////            string chunkID = new string(br.ReadChars(4));

    //////        //////            int chunkSize = br.ReadInt32();

    //////        //////            if (chunkID == "fmt ")

    //////        //////            {

    //////        //////                br.ReadInt16();

    //////        //////                channels = br.ReadInt16();

    //////        //////                sampleRate = br.ReadInt32();

    //////        //////                br.ReadInt32(); br.ReadInt16();

    //////        //////                bits = br.ReadInt16();

    //////        //////                if (chunkSize > 16) br.ReadBytes(chunkSize - 16);

    //////        //////            }

    //////        //////            else if (chunkID == "data")

    //////        //////            {

    //////        //////                int totalSamples = chunkSize / (bits / 8);

    //////        //////                float[] samples = new float[totalSamples / channels];

    //////        //////                for (int i = 0, j = 0; i < totalSamples; i++)

    //////        //////                {

    //////        //////                    short sample = br.ReadInt16();

    //////        //////                    if (channels == 1 || i % channels == 0)

    //////        //////                        samples[j++] = sample / 32768f;

    //////        //////                    if (channels == 2) br.ReadInt16(); // skip right

    //////        //////                }//for (int i = 0, j = 0; i < totalSamples; i++)

    //////        //////                return samples;

    //////        //////            }//END OF ELSE OF if (chunkID == "fmt ")

    //////        //////            else br.BaseStream.Position += chunkSize;

    //////        //////        }//while (br.BaseStream.Position < br.BaseStream.Length)

    //////        //////    }//using (BinaryReader br = new BinaryReader(File.OpenRead(path)))

    //////        //////    return new float[0];

    //////        //////}//public static float[] ReadWavMonoAsFloats(string path, out int sampleRate)

    //////       // ref System.Windows.Forms.ProgressBar progressbartotrack

    //////        public static float[] ReadWavMonoAsFloats(string path, out int sampleRate, ref System.Windows.Forms.ProgressBar progressbartotrack)

    //////        {

    //////            sampleRate = 8000;

    //////            using (BinaryReader br = new BinaryReader(File.OpenRead(path)))

    //////            {

    //////                br.BaseStream.Seek(0, SeekOrigin.Begin);

    //////                br.ReadBytes(12);// Skip RIFF header

    //////                int channels = 1, bits = 16;

    //////                while (br.BaseStream.Position < br.BaseStream.Length)

    //////                {

    //////                    string chunkID = new string(br.ReadChars(4));

    //////                    int chunkSize = br.ReadInt32();

    //////                    if (chunkID == "fmt ")

    //////                    {

    //////                        br.ReadInt16(); // Audio format

    //////                        channels = br.ReadInt16();

    //////                        sampleRate = br.ReadInt32();

    //////                        br.ReadInt32(); // Byte rate

    //////                        br.ReadInt16(); // Block align

    //////                        bits = br.ReadInt16();

    //////                        if (chunkSize > 16) br.ReadBytes(chunkSize - 16);

    //////                    }//END OF if (chunkID == "fmt ")

    //////                    else if (chunkID == "data")

    //////                    {

    //////                        int bytesPerSample = bits / 8;

    //////                        int totalBytes = chunkSize;

    //////                        int totalSamples = totalBytes / bytesPerSample;

    //////                        float[] samples = new float[totalSamples / channels];

    //////                        int j = 0;

    //////                        for (int i = 0; i < totalSamples; i++)

    //////                        {

    //////                            if (br.BaseStream.Position + 2 > br.BaseStream.Length)

    //////                                break;

    //////                            short sample = br.ReadInt16();

    //////                            if (channels == 1 || i % channels == 0)

    //////                            {

    //////                                samples[j++] = sample / 32768f;

    //////                            }//END OF if (channels == 1 || i % channels == 0)

    //////                            if (channels == 2)

    //////                            {

    //////                                if (br.BaseStream.Position + 2 > br.BaseStream.Length)

    //////                                    break;

    //////                                br.ReadInt16(); // skip right

    //////                            }//END OF if (channels == 2)

    //////                        }//for (int i = 0; i < totalSamples; i++)

    //////                        return samples;

    //////                    }//END OF else if (chunkID == "data")

    //////                    else

    //////                    {

    //////                        br.BaseStream.Position += chunkSize;

    //////                    }//END OF ELSE OF chunkID checks

    //////                }//while (br.BaseStream.Position < br.BaseStream.Length)

    //////            }//using (BinaryReader br = new BinaryReader(File.OpenRead(path)))

    //////            return new float[0];

    //////        }//public static float[] ReadWavMonoAsFloats(string path, out int sampleRate)

    //////    }//public static class WavResampler

}//namespace SAAN_IS_TRYING_TO_DO_WAVS_ANALYSIS_WITH_1800_BUCKETS

/////////////////////////////

///////////////////////////////////////////// COMPLETES namespace SAAN_IS_TRYING_TO_DO_WAVS_ANALYSIS_WITH_1800_BUCKETS

///////////////////////////////////////////// STARTS namespace SAAN_FRESH___RAW_NON_APIS_WAVES_TO_SHRUTIES_COPIER_GPTS

///////////////////////////////////////////// COMPLETES namespace SAAN_IS_TRYING_TO_DO_WAVS_ANALYSIS_WITH_1800_BUCKETS

///////////////////////////////////////////// STARTS namespace SAAN_FRESH___RAW_NON_APIS_WAVES_TO_SHRUTIES_COPIER_GPTS

///////////////////////////////////////////// COMPLETES namespace SAAN_IS_TRYING_TO_DO_WAVS_ANALYSIS_WITH_1800_BUCKETS

///////////////////////////////////////////// STARTS namespace SAAN_FRESH___RAW_NON_APIS_WAVES_TO_SHRUTIES_COPIER_GPTS

///////////////////////////////////////////// COMPLETES namespace SAAN_IS_TRYING_TO_DO_WAVS_ANALYSIS_WITH_1800_BUCKETS

///////////////////////////////////////////// STARTS namespace SAAN_FRESH___RAW_NON_APIS_WAVES_TO_SHRUTIES_COPIER_GPTS

///////////////////////////////////////////// COMPLETES namespace SAAN_IS_TRYING_TO_DO_WAVS_ANALYSIS_WITH_1800_BUCKETS

///////////////////////////////////////////// STARTS namespace SAAN_FRESH___RAW_NON_APIS_WAVES_TO_SHRUTIES_COPIER_GPTS

///////////////////////////////////////////// COMPLETES namespace SAAN_IS_TRYING_TO_DO_WAVS_ANALYSIS_WITH_1800_BUCKETS

///////////////////////////////////////////// STARTS namespace SAAN_FRESH___RAW_NON_APIS_WAVES_TO_SHRUTIES_COPIER_GPTS

///////////////////////////////////////////// COMPLETES namespace SAAN_IS_TRYING_TO_DO_WAVS_ANALYSIS_WITH_1800_BUCKETS

///////////////////////////////////////////// STARTS namespace SAAN_FRESH___RAW_NON_APIS_WAVES_TO_SHRUTIES_COPIER_GPTS

///////////////////////////////////////////// COMPLETES namespace SAAN_IS_TRYING_TO_DO_WAVS_ANALYSIS_WITH_1800_BUCKETS

///////////////////////////////////////////// STARTS namespace SAAN_FRESH___RAW_NON_APIS_WAVES_TO_SHRUTIES_COPIER_GPTS

///////////////////////////////////////////// COMPLETES namespace SAAN_IS_TRYING_TO_DO_WAVS_ANALYSIS_WITH_1800_BUCKETS

///////////////////////////////////////////// STARTS namespace SAAN_FRESH___RAW_NON_APIS_WAVES_TO_SHRUTIES_COPIER_GPTS

///////////////////////////////////////////// COMPLETES namespace SAAN_IS_TRYING_TO_DO_WAVS_ANALYSIS_WITH_1800_BUCKETS

///////////////////////////////////////////// STARTS namespace SAAN_FRESH___RAW_NON_APIS_WAVES_TO_SHRUTIES_COPIER_GPTS

///////////////////////////////////////////// COMPLETES namespace SAAN_IS_TRYING_TO_DO_WAVS_ANALYSIS_WITH_1800_BUCKETS

///////////////////////////////////////////// STARTS namespace SAAN_FRESH___RAW_NON_APIS_WAVES_TO_SHRUTIES_COPIER_GPTS

///////////////////////////////////////////// COMPLETES namespace SAAN_IS_TRYING_TO_DO_WAVS_ANALYSIS_WITH_1800_BUCKETS

///////////////////////////////////////////// STARTS namespace SAAN_FRESH___RAW_NON_APIS_WAVES_TO_SHRUTIES_COPIER_GPTS

///////////////////////////////////////////// COMPLETES namespace SAAN_IS_TRYING_TO_DO_WAVS_ANALYSIS_WITH_1800_BUCKETS

///////////////////////////////////////////// STARTS namespace SAAN_FRESH___RAW_NON_APIS_WAVES_TO_SHRUTIES_COPIER_GPTS

///////////////////////////////////////////// COMPLETES namespace SAAN_IS_TRYING_TO_DO_WAVS_ANALYSIS_WITH_1800_BUCKETS

///////////////////////////////////////////// STARTS namespace SAAN_FRESH___RAW_NON_APIS_WAVES_TO_SHRUTIES_COPIER_GPTS

///////////////////////////////////////////// COMPLETES namespace SAAN_IS_TRYING_TO_DO_WAVS_ANALYSIS_WITH_1800_BUCKETS

///////////////////////////////////////////// STARTS namespace SAAN_FRESH___RAW_NON_APIS_WAVES_TO_SHRUTIES_COPIER_GPTS

///////////////////////////////////////////// COMPLETES namespace SAAN_IS_TRYING_TO_DO_WAVS_ANALYSIS_WITH_1800_BUCKETS

///////////////////////////////////////////// STARTS namespace SAAN_FRESH___RAW_NON_APIS_WAVES_TO_SHRUTIES_COPIER_GPTS

///////////////////////////////////////////// COMPLETES namespace SAAN_IS_TRYING_TO_DO_WAVS_ANALYSIS_WITH_1800_BUCKETS

///////////////////////////////////////////// STARTS namespace SAAN_FRESH___RAW_NON_APIS_WAVES_TO_SHRUTIES_COPIER_GPTS

///////////////////////////////////////////// COMPLETES namespace SAAN_IS_TRYING_TO_DO_WAVS_ANALYSIS_WITH_1800_BUCKETS

///////////////////////////////////////////// STARTS namespace SAAN_FRESH___RAW_NON_APIS_WAVES_TO_SHRUTIES_COPIER_GPTS

///////////////////////////////////////////// COMPLETES namespace SAAN_IS_TRYING_TO_DO_WAVS_ANALYSIS_WITH_1800_BUCKETS

///////////////////////////////////////////// STARTS namespace SAAN_FRESH___RAW_NON_APIS_WAVES_TO_SHRUTIES_COPIER_GPTS

///////////////////////////////////////////// COMPLETES namespace SAAN_IS_TRYING_TO_DO_WAVS_ANALYSIS_WITH_1800_BUCKETS

///////////////////////////////////////////// STARTS namespace SAAN_FRESH___RAW_NON_APIS_WAVES_TO_SHRUTIES_COPIER_GPTS

///////////////////////////////////////////// COMPLETES namespace SAAN_IS_TRYING_TO_DO_WAVS_ANALYSIS_WITH_1800_BUCKETS

///////////////////////////////////////////// STARTS namespace SAAN_FRESH___RAW_NON_APIS_WAVES_TO_SHRUTIES_COPIER_GPTS

///////////////////////////////////////////// COMPLETES namespace SAAN_IS_TRYING_TO_DO_WAVS_ANALYSIS_WITH_1800_BUCKETS

///////////////////////////////////////////// STARTS namespace SAAN_FRESH___RAW_NON_APIS_WAVES_TO_SHRUTIES_COPIER_GPTS

///////////////////////////////////////////// COMPLETES namespace SAAN_IS_TRYING_TO_DO_WAVS_ANALYSIS_WITH_1800_BUCKETS

///////////////////////////////////////////// STARTS namespace SAAN_FRESH___RAW_NON_APIS_WAVES_TO_SHRUTIES_COPIER_GPTS

///////////////////////////////////////////// COMPLETES namespace SAAN_IS_TRYING_TO_DO_WAVS_ANALYSIS_WITH_1800_BUCKETS

///////////////////////////////////////////// STARTS namespace SAAN_FRESH___RAW_NON_APIS_WAVES_TO_SHRUTIES_COPIER_GPTS

///////////////////////////////////////////// COMPLETES namespace SAAN_IS_TRYING_TO_DO_WAVS_ANALYSIS_WITH_1800_BUCKETS

///////////////////////////////////////////// STARTS namespace SAAN_FRESH___RAW_NON_APIS_WAVES_TO_SHRUTIES_COPIER_GPTS

///////////////////////////////////////////// COMPLETES namespace SAAN_IS_TRYING_TO_DO_WAVS_ANALYSIS_WITH_1800_BUCKETS

///////////////////////////////////////////// STARTS namespace SAAN_FRESH___RAW_NON_APIS_WAVES_TO_SHRUTIES_COPIER_GPTS

///////////////////////////////////////////// COMPLETES namespace SAAN_IS_TRYING_TO_DO_WAVS_ANALYSIS_WITH_1800_BUCKETS

///////////////////////////////////////////// STARTS namespace SAAN_FRESH___RAW_NON_APIS_WAVES_TO_SHRUTIES_COPIER_GPTS

///////////////////////////////////////////// COMPLETES namespace SAAN_IS_TRYING_TO_DO_WAVS_ANALYSIS_WITH_1800_BUCKETS

///////////////////////////////////////////// STARTS namespace SAAN_FRESH___RAW_NON_APIS_WAVES_TO_SHRUTIES_COPIER_GPTS

///////////////////////////////////////////// COMPLETES namespace SAAN_IS_TRYING_TO_DO_WAVS_ANALYSIS_WITH_1800_BUCKETS

///////////////////////////////////////////// STARTS namespace SAAN_FRESH___RAW_NON_APIS_WAVES_TO_SHRUTIES_COPIER_GPTS

///////////////////////////////////////////// COMPLETES namespace SAAN_IS_TRYING_TO_DO_WAVS_ANALYSIS_WITH_1800_BUCKETS

///////////////////////////////////////////// STARTS namespace SAAN_FRESH___RAW_NON_APIS_WAVES_TO_SHRUTIES_COPIER_GPTS

///////////////////////////////////////////// COMPLETES namespace SAAN_IS_TRYING_TO_DO_WAVS_ANALYSIS_WITH_1800_BUCKETS

///////////////////////////////////////////// STARTS namespace SAAN_FRESH___RAW_NON_APIS_WAVES_TO_SHRUTIES_COPIER_GPTS

///////////////////////////////////////////// COMPLETES namespace SAAN_IS_TRYING_TO_DO_WAVS_ANALYSIS_WITH_1800_BUCKETS

///////////////////////////////////////////// STARTS namespace SAAN_FRESH___RAW_NON_APIS_WAVES_TO_SHRUTIES_COPIER_GPTS

///////////////////////////////////////////// COMPLETES namespace SAAN_IS_TRYING_TO_DO_WAVS_ANALYSIS_WITH_1800_BUCKETS

///////////////////////////////////////////// STARTS namespace SAAN_FRESH___RAW_NON_APIS_WAVES_TO_SHRUTIES_COPIER_GPTS

///////////////////////////////////////////// COMPLETES namespace SAAN_IS_TRYING_TO_DO_WAVS_ANALYSIS_WITH_1800_BUCKETS

///////////////////////////////////////////// STARTS namespace SAAN_FRESH___RAW_NON_APIS_WAVES_TO_SHRUTIES_COPIER_GPTS

///////////////////////////////////////////// COMPLETES namespace SAAN_IS_TRYING_TO_DO_WAVS_ANALYSIS_WITH_1800_BUCKETS

///////////////////////////////////////////// STARTS namespace SAAN_FRESH___RAW_NON_APIS_WAVES_TO_SHRUTIES_COPIER_GPTS

///////////////////////////////////////////// COMPLETES namespace SAAN_IS_TRYING_TO_DO_WAVS_ANALYSIS_WITH_1800_BUCKETS

///////////////////////////////////////////// STARTS namespace SAAN_FRESH___RAW_NON_APIS_WAVES_TO_SHRUTIES_COPIER_GPTS

///////////////////////////////////////////// COMPLETES namespace SAAN_IS_TRYING_TO_DO_WAVS_ANALYSIS_WITH_1800_BUCKETS

///////////////////////////////////////////// STARTS namespace SAAN_FRESH___RAW_NON_APIS_WAVES_TO_SHRUTIES_COPIER_GPTS

///////////////////////////////////////////// COMPLETES namespace SAAN_IS_TRYING_TO_DO_WAVS_ANALYSIS_WITH_1800_BUCKETS

///////////////////////////////////////////// STARTS namespace SAAN_FRESH___RAW_NON_APIS_WAVES_TO_SHRUTIES_COPIER_GPTS

///////////////////////////////////////////// COMPLETES namespace SAAN_IS_TRYING_TO_DO_WAVS_ANALYSIS_WITH_1800_BUCKETS

///////////////////////////////////////////// STARTS namespace SAAN_FRESH___RAW_NON_APIS_WAVES_TO_SHRUTIES_COPIER_GPTS

///////////////////////////////////////////// COMPLETES namespace SAAN_IS_TRYING_TO_DO_WAVS_ANALYSIS_WITH_1800_BUCKETS

///////////////////////////////////////////// STARTS namespace SAAN_FRESH___RAW_NON_APIS_WAVES_TO_SHRUTIES_COPIER_GPTS

///////////////////////////////////////////// COMPLETES namespace SAAN_IS_TRYING_TO_DO_WAVS_ANALYSIS_WITH_1800_BUCKETS

///////////////////////////////////////////// STARTS namespace SAAN_FRESH___RAW_NON_APIS_WAVES_TO_SHRUTIES_COPIER_GPTS

///////////////////////////////////////////// COMPLETES namespace SAAN_IS_TRYING_TO_DO_WAVS_ANALYSIS_WITH_1800_BUCKETS

///////////////////////////////////////////// STARTS namespace SAAN_FRESH___RAW_NON_APIS_WAVES_TO_SHRUTIES_COPIER_GPTS

///////////////////////////////////////////// COMPLETES namespace SAAN_IS_TRYING_TO_DO_WAVS_ANALYSIS_WITH_1800_BUCKETS

///////////////////////////////////////////// STARTS namespace SAAN_FRESH___RAW_NON_APIS_WAVES_TO_SHRUTIES_COPIER_GPTS

///////////////////////////////////////////// COMPLETES namespace SAAN_IS_TRYING_TO_DO_WAVS_ANALYSIS_WITH_1800_BUCKETS

///////////////////////////////////////////// STARTS namespace SAAN_FRESH___RAW_NON_APIS_WAVES_TO_SHRUTIES_COPIER_GPTS

///////////////////////////////////////////// COMPLETES namespace SAAN_IS_TRYING_TO_DO_WAVS_ANALYSIS_WITH_1800_BUCKETS

///////////////////////////////////////////// STARTS namespace SAAN_FRESH___RAW_NON_APIS_WAVES_TO_SHRUTIES_COPIER_GPTS

///////////////////////////////////////////// COMPLETES namespace SAAN_IS_TRYING_TO_DO_WAVS_ANALYSIS_WITH_1800_BUCKETS

///////////////////////////////////////////// STARTS namespace SAAN_FRESH___RAW_NON_APIS_WAVES_TO_SHRUTIES_COPIER_GPTS

///////////////////////////////////////////// COMPLETES namespace SAAN_IS_TRYING_TO_DO_WAVS_ANALYSIS_WITH_1800_BUCKETS

///////////////////////////////////////////// STARTS namespace SAAN_FRESH___RAW_NON_APIS_WAVES_TO_SHRUTIES_COPIER_GPTS

///////////////////////////////////////////// COMPLETES namespace SAAN_IS_TRYING_TO_DO_WAVS_ANALYSIS_WITH_1800_BUCKETS

///////////////////////////////////////////// STARTS namespace SAAN_FRESH___RAW_NON_APIS_WAVES_TO_SHRUTIES_COPIER_GPTS

///////////////////////////////////////////// COMPLETES namespace SAAN_IS_TRYING_TO_DO_WAVS_ANALYSIS_WITH_1800_BUCKETS

///////////////////////////////////////////// STARTS namespace SAAN_FRESH___RAW_NON_APIS_WAVES_TO_SHRUTIES_COPIER_GPTS

///////////////////////////////////////////// COMPLETES namespace SAAN_IS_TRYING_TO_DO_WAVS_ANALYSIS_WITH_1800_BUCKETS

///////////////////////////////////////////// STARTS namespace SAAN_FRESH___RAW_NON_APIS_WAVES_TO_SHRUTIES_COPIER_GPTS

///////////////////////////////////////////// COMPLETES namespace SAAN_IS_TRYING_TO_DO_WAVS_ANALYSIS_WITH_1800_BUCKETS

///////////////////////////////////////////// STARTS namespace SAAN_FRESH___RAW_NON_APIS_WAVES_TO_SHRUTIES_COPIER_GPTS

///////////////////////////////////////////// COMPLETES namespace SAAN_IS_TRYING_TO_DO_WAVS_ANALYSIS_WITH_1800_BUCKETS

///////////////////////////////////////////// STARTS namespace SAAN_FRESH___RAW_NON_APIS_WAVES_TO_SHRUTIES_COPIER_GPTS

///////////////////////////////////////////// COMPLETES namespace SAAN_IS_TRYING_TO_DO_WAVS_ANALYSIS_WITH_1800_BUCKETS

///////////////////////////////////////////// STARTS namespace SAAN_FRESH___RAW_NON_APIS_WAVES_TO_SHRUTIES_COPIER_GPTS

namespace SAAN_FRESH___RAW_NON_APIS_WAVES_TO_SHRUTIES_COPIER_GPTS

{

    //////////////////////////////////////////////////////////////////////////

    ///

    /// 

    /// 

    /// 

    /// 

    /// 

    /// 

    /// 

    /// 

    /// 

    /// 

    /// 

    /// 

    /// 

    /// 

    /// 

    public class special___180_wav_files_generator___to__check_______theta_rotations_transitions___ShrutiTheta180WavExporter

    {

        public static void Export180ThetaWavs(string inputWavPath)

        {

            string outputFolder = Path.GetDirectoryName(Path.GetFullPath(inputWavPath));

            float[] samples = ReadWavMonoAsFloats(inputWavPath, out int sampleRate);

            double dtMs = 1000.0 / sampleRate;

            int totalSamples = samples.Length;

            List<int>[] thetaSampleBins = new List<int>[180];

            for (int i = 0; i < 180; i++)

                thetaSampleBins[i] = new List<int>();

            for (int i = 1; i < samples.Length; i++)

            {

                float amp1 = samples[i - 1];

                float amp2 = samples[i];

                double dAmp = amp2 - amp1;

                double thetaRad = Math.Atan2(dAmp, dtMs);

                double thetaDeg = thetaRad * 180.0 / Math.PI;

                if (thetaDeg < 0) thetaDeg += 180;

                int bin = (int)Math.Floor(thetaDeg);

                if (bin >= 0 && bin < 180)

                    thetaSampleBins[bin].Add(i);

            }

            Directory.CreateDirectory(outputFolder);

            for (int i = 0; i < 180; i++)

            {

                string outPath = Path.Combine(outputFolder, $"theta_{i:D3}.wav");

                using (FileStream fs = new FileStream(outPath, FileMode.Create))

                using (BinaryWriter bw = new BinaryWriter(fs))

                {

                    WriteWavHeaderPlaceholder(bw, sampleRate, 1);

                    HashSet<int> binIndices = new HashSet<int>(thetaSampleBins[i]);

                    for (int s = 0; s < totalSamples; s++)

                    {

                        float val = binIndices.Contains(s) ? samples[s] : 0f;

                        short sampleVal = (short)(Math.Max(-1f, Math.Min(1f, val)) * 32767);

                        bw.Write(sampleVal);

                    }

                    long dataSize = fs.Position - 44;

                    PatchWavHeader(bw, sampleRate, 1, (int)dataSize);

                }

            }

            Console.WriteLine("180 theta-based full-length WAVs (with silence elsewhere) exported.");

        }

        public static float[] ReadWavMonoAsFloats(string path, out int sampleRate)

        {

            using (BinaryReader br = new BinaryReader(File.OpenRead(path)))

            {

                br.BaseStream.Seek(0, SeekOrigin.Begin);

                br.ReadBytes(12);

                int channels = 1;

                sampleRate = 44100;

                int bitsPerSample = 16;

                while (br.BaseStream.Position < br.BaseStream.Length)

                {

                    string chunkID = new string(br.ReadChars(4));

                    int chunkSize = br.ReadInt32();

                    if (chunkID == "fmt ")

                    {

                        br.ReadInt16();

                        channels = br.ReadInt16();

                        sampleRate = br.ReadInt32();

                        br.ReadInt32();

                        br.ReadInt16();

                        bitsPerSample = br.ReadInt16();

                        if (chunkSize > 16) br.ReadBytes(chunkSize - 16);

                    }

                    else if (chunkID == "data")

                    {

                        int bytesPerSample = bitsPerSample / 8;

                        int totalSamples = chunkSize / bytesPerSample;

                        float[] samples = new float[totalSamples / channels];

                        for (int i = 0, j = 0; i < totalSamples; i++)

                        {

                            short sample = br.ReadInt16();

                            if (channels == 1 || i % channels == 0)

                                samples[j++] = sample / 32768f;

                            if (channels == 2) br.ReadInt16();

                        }

                        return samples;

                    }

                    else br.ReadBytes(chunkSize);

                }

            }

            sampleRate = 44100;

            return new float[0];

        }

        public static void WriteWavHeaderPlaceholder(BinaryWriter bw, int sampleRate, int channels)

        {

            bw.Write(Encoding.ASCII.GetBytes("RIFF"));

            bw.Write(0);

            bw.Write(Encoding.ASCII.GetBytes("WAVE"));

            bw.Write(Encoding.ASCII.GetBytes("fmt "));

            bw.Write(16);

            bw.Write((short)1);

            bw.Write((short)channels);

            bw.Write(sampleRate);

            int byteRate = sampleRate * channels * 2;

            short blockAlign = (short)(channels * 2);

            bw.Write(byteRate);

            bw.Write(blockAlign);

            bw.Write((short)16);

            bw.Write(Encoding.ASCII.GetBytes("data"));

            bw.Write(0);

        }

        public static void PatchWavHeader(BinaryWriter bw, int sampleRate, int channels, int dataSize)

        {

            bw.Seek(4, SeekOrigin.Begin);

            bw.Write(36 + dataSize);

            bw.Seek(40, SeekOrigin.Begin);

            bw.Write(dataSize);

        }

    }//public class special___180_wav_files_generator___to__check_______theta_rotations_transitions___ShrutiTheta180WavExporter

    public class DISCARDED_SINCE_IT_WAS_SELECTING_ONLY_ONE_AMPLITUDE_AT_THE_LOCATIONS___special___180_wav_files_generator___to__check_______theta_rotations_transitions___ShrutiTheta180WavExporter

    {

        // public static void Export180ThetaWavs(string inputWavPath, string outputFolder)

        public static void Export180ThetaWavs(string inputWavPath)

        {

            string outputFolder = Path.GetDirectoryName(Path.GetFullPath(inputWavPath));

            float[] samples = ReadWavMonoAsFloats(inputWavPath, out int sampleRate);

            double dtMs = 1000.0 / sampleRate;

            List<int>[] thetaSampleBins = new List<int>[180];

            for (int i = 0; i < 180; i++)

                thetaSampleBins[i] = new List<int>();

            for (int i = 1; i < samples.Length; i++)

            {

                float amp1 = samples[i - 1];

                float amp2 = samples[i];

                double dAmp = amp2 - amp1;

                double thetaRad = Math.Atan2(dAmp, dtMs);

                double thetaDeg = thetaRad * 180.0 / Math.PI;

                if (thetaDeg < 0) thetaDeg += 180;

                int bin = (int)Math.Floor(thetaDeg);

                if (bin >= 0 && bin < 180)

                    thetaSampleBins[bin].Add(i);

            }

            Directory.CreateDirectory(outputFolder);

            for (int i = 0; i < 180; i++)

            {

                string outPath = Path.Combine(outputFolder, $"theta_{i:D3}.wav");

                using (FileStream fs = new FileStream(outPath, FileMode.Create))

                using (BinaryWriter bw = new BinaryWriter(fs))

                {

                    WriteWavHeaderPlaceholder(bw, sampleRate, 1);

                    foreach (int index in thetaSampleBins[i])

                    {

                        float sample = samples[index];

                        short s = (short)(Math.Max(-1f, Math.Min(1f, sample)) * 32767);

                        bw.Write(s);

                    }

                    long dataSize = fs.Position - 44;

                    PatchWavHeader(bw, sampleRate, 1, (int)dataSize);

                }

            }

            Console.WriteLine("180 theta-based filtered WAV files exported.");

        }

        public static float[] ReadWavMonoAsFloats(string path, out int sampleRate)

        {

            using (BinaryReader br = new BinaryReader(File.OpenRead(path)))

            {

                br.BaseStream.Seek(0, SeekOrigin.Begin);

                br.ReadBytes(12);

                int channels = 1;

                sampleRate = 44100;

                int bitsPerSample = 16;

                while (br.BaseStream.Position < br.BaseStream.Length)

                {

                    string chunkID = new string(br.ReadChars(4));

                    int chunkSize = br.ReadInt32();

                    if (chunkID == "fmt ")

                    {

                        br.ReadInt16();

                        channels = br.ReadInt16();

                        sampleRate = br.ReadInt32();

                        br.ReadInt32();

                        br.ReadInt16();

                        bitsPerSample = br.ReadInt16();

                        if (chunkSize > 16) br.ReadBytes(chunkSize - 16);

                    }

                    else if (chunkID == "data")

                    {

                        int bytesPerSample = bitsPerSample / 8;

                        int totalSamples = chunkSize / bytesPerSample;

                        float[] samples = new float[totalSamples / channels];

                        for (int i = 0, j = 0; i < totalSamples; i++)

                        {

                            short sample = br.ReadInt16();

                            if (channels == 1 || i % channels == 0)

                                samples[j++] = sample / 32768f;

                            if (channels == 2) br.ReadInt16();

                        }

                        return samples;

                    }

                    else br.ReadBytes(chunkSize);

                }

            }

            sampleRate = 44100;

            return new float[0];

        }//public static float[] ReadWavMonoAsFloats(string path, out int sampleRate)

        public static void WriteWavHeaderPlaceholder(BinaryWriter bw, int sampleRate, int channels)

        {

            bw.Write(Encoding.ASCII.GetBytes("RIFF"));

            bw.Write(0);

            bw.Write(Encoding.ASCII.GetBytes("WAVE"));

            bw.Write(Encoding.ASCII.GetBytes("fmt "));

            bw.Write(16);

            bw.Write((short)1);

            bw.Write((short)channels);

            bw.Write(sampleRate);

            int byteRate = sampleRate * channels * 2;

            short blockAlign = (short)(channels * 2);

            bw.Write(byteRate);

            bw.Write(blockAlign);

            bw.Write((short)16);

            bw.Write(Encoding.ASCII.GetBytes("data"));

            bw.Write(0);

        }//public static void WriteWavHeaderPlaceholder(BinaryWriter bw, int sampleRate, int channels)

        public static void PatchWavHeader(BinaryWriter bw, int sampleRate, int channels, int dataSize)

        {

            bw.Seek(4, SeekOrigin.Begin);

            bw.Write(36 + dataSize);

            bw.Seek(40, SeekOrigin.Begin);

            bw.Write(dataSize);

        }

    }//public class special___180_wav_files_generator___to__check_______theta_rotations_transitions___ShrutiTheta180WavExporter

    //specially written SAAN to generate the singles samples 80000 sps 16 bits input to PAN with preaccumulated odd even zero crossings

    public static class WavWriter_with_left_right_samples_pan_list_supplied

    {

        public static void WriteStereoWav(string outputPath, List<float> left, List<float> right, int sampleRate, int bitsPerSample)

        {

            if (left.Count != right.Count)

            {

                Console.WriteLine("Left and right channel sample counts do not match. Padding shorter list.");

                int minLength = Math.Min(left.Count, right.Count);

                while (left.Count < minLength) left.Add(0);

                while (right.Count < minLength) right.Add(0);

            }//if (left.Count != right.Count)

            int numSamples = left.Count;

            int numChannels = 2;

            //    int byteRate = sampleRate * numChannels * bitsPerSample / 8;

            //saan checking

            int byteRate = (sampleRate/2) * numChannels * bitsPerSample / 8;

            int blockAlign = numChannels * bitsPerSample / 8;

            int dataSize = numSamples * blockAlign;

            int fileSize = 44 + dataSize;

            using (BinaryWriter writer = new BinaryWriter(File.Create(outputPath)))

            {

                // Write RIFF header

                writer.Write(System.Text.Encoding.ASCII.GetBytes("RIFF"));

                writer.Write(fileSize - 8); // File size minus RIFF and size fields

                writer.Write(System.Text.Encoding.ASCII.GetBytes("WAVE"));

                // Format chunk

                writer.Write(System.Text.Encoding.ASCII.GetBytes("fmt "));

                writer.Write(16); // PCM header size

                writer.Write((short)1); // PCM format

                writer.Write((short)numChannels);

                writer.Write(sampleRate);

                writer.Write(byteRate);

                writer.Write((short)blockAlign);

                writer.Write((short)bitsPerSample);

                // Data chunk

                writer.Write(System.Text.Encoding.ASCII.GetBytes("data"));

                writer.Write(dataSize);

                //////for (int i = 0; i < numSamples; i++)

                //////{

                //////    short leftSample = ConvertToPcmSample(left[i], bitsPerSample);

                //////    short rightSample = ConvertToPcmSample(right[i], bitsPerSample);

                //////    writer.Write(leftSample);

                //////    writer.Write(rightSample);

                //////}//for (int i = 0; i < numSamples; i++)

                ///

                //////for (int i = 0; i < numSamples; i++)

                //////{

                //////    WriteSample(writer, left[i], bitsPerSample);

                //////    WriteSample(writer, right[i], bitsPerSample);

                //////}//for (int i = 0; i < numSamples; i++)

                //this is also bad output

                int numSamples_Mins_Taken = Math.Min(left.Count, right.Count); // Prevent index out of bounds

                for (int i = 0; i < numSamples_Mins_Taken; i++)

                {

                    WriteSample(writer, left[i], bitsPerSample);

                    WriteSample(writer, right[i], bitsPerSample);

                }//for (int i = 0; i < numSamples_Mins_Taken; i++)

                //           Optional: Balance lists

                //If you want to pad the shorter list with silence, you can also do this:

                ////////very bad output       no output

                //////int maxSamples = Math.Max(left.Count, right.Count);

                //////while (left.Count < maxSamples) left.Add(0f);

                //////while (right.Count < maxSamples) right.Add(0f);

                //     Then loop using maxSamples.

                //      But if preserving your original logic is critical, prefer Math.Min.

                ////////very bad output

                //////for (int i = 0; i < maxSamples; i++)

                //////{

                //////    WriteSample(writer, left[i], bitsPerSample);

                //////    WriteSample(writer, right[i], bitsPerSample);

                //////}//for (int i = 0; i < maxSamples; i++)

            }//using (BinaryWriter writer = new BinaryWriter(File.Create(outputPath)))

        }//public static void WriteStereoWav(string outputPath, List<float> left, List<float> right, int sampleRate, int bitsPerSample)

        private static void WriteSample(BinaryWriter writer, float sample, int bitsPerSample)

        {

            sample = Math.Max(-1f, Math.Min(1f, sample)); // Clamp to [-1,1]

            switch (bitsPerSample)

            {

                case 8:

                    byte val8 = (byte)((sample + 1f) * 127.5f); // 0 to 255

                    writer.Write(val8);

                    break;

                case 16:

                    short val16 = (short)(sample * short.MaxValue);

                    writer.Write(val16);

                    break;

                case 24:

                    int val24 = (int)(sample * 8388607); // 2^23 - 1

                    writer.Write((byte)(val24 & 0xFF));

                    writer.Write((byte)((val24 >> 8) & 0xFF));

                    writer.Write((byte)((val24 >> 16) & 0xFF));

                    break;

                case 32:

                    int val32 = (int)(sample * int.MaxValue);

                    writer.Write(val32);

                    break;

                default:

                    throw new NotSupportedException($"Bit depth {bitsPerSample} not supported.");

            }//switch (bitsPerSample)

        }//private static void WriteSample(BinaryWriter writer, float sample, int bitsPerSample)

        private static short ConvertToPcmSample(float sample, int bitsPerSample)

        {

            // Clamp [-1, 1] and scale to 16-bit PCM range

            sample = Math.Max(-1f, Math.Min(1f, sample));

            if (bitsPerSample == 16)

            {

                return (short)(sample * short.MaxValue);

            }

            else

            {

                throw new NotSupportedException("Only 16-bit PCM supported in this implementation.");

            }

        }//private static short ConvertToPcmSample(float sample, int bitsPerSample)

    }//public static class WavWriter_with_left_right_samples_pan_list_supplied

    /// <summary>

    /// //////////////////////////////////////////////////////////////////////////////////////////////////////

    /// </summary>

    public class StereoWavWriter___READS_TEXT_FILES___TWO_COLUMNS_THE_LEFT_RIGHT_ODD_EVEN_GTAMPS

    {

        public static void process_text_file_with___StereoWavWriter___READS_TEXT_FILES___TWO_COLUMNS_THE_LEFT_RIGHT_ODD_EVEN_GTAMPS___Main(string filename___TWO_COLUMNS_THE_LEFT_RIGHT_ODD_EVEN_GTAMPS)

        {

            string inputPath = filename___TWO_COLUMNS_THE_LEFT_RIGHT_ODD_EVEN_GTAMPS;//"input_samples.txt"; // Update this path as needed

            string outputWavPath = filename___TWO_COLUMNS_THE_LEFT_RIGHT_ODD_EVEN_GTAMPS + "_saans_left_right_odd_even_zero_crossings_pan.wav";//"output.wav";

            List<float> leftSamples = new List<float>();

            List<float> rightSamples = new List<float>();

            foreach (string line in File.ReadLines(inputPath))

            {

                if (string.IsNullOrWhiteSpace(line)) continue;

                string[] parts = line.Split(new[] { ',', '\t' }, StringSplitOptions.RemoveEmptyEntries);

                if (parts.Length < 2) continue;

                if (float.TryParse(parts[0], NumberStyles.Float, CultureInfo.InvariantCulture, out float left) &&

                    float.TryParse(parts[1], NumberStyles.Float, CultureInfo.InvariantCulture, out float right))

                {

                    leftSamples.Add(left);

                    rightSamples.Add(right);

                }

            }//foreach (string line in File.ReadLines(inputPath))

            if (leftSamples.Count != rightSamples.Count)

            {

                Console.WriteLine("Mismatch in sample count between left and right channels.");

                return;

            }//if (leftSamples.Count != rightSamples.Count)

            //  WriteStereoWav(outputWavPath, leftSamples, rightSamples, 44100, 16);

            //actual is 8000

            WriteStereoWav(outputWavPath, leftSamples, rightSamples, 8000, 16);

            Console.WriteLine("Stereo WAV written to: " + outputWavPath);

        }

        public static void WriteStereoWav(string path, List<float> left, List<float> right, int sampleRate, int bitsPerSample)

        {

            int bytesPerSample = bitsPerSample / 8;

            int numChannels = 2;

            int blockAlign = bytesPerSample * numChannels;

            int byteRate = sampleRate * blockAlign;

           // int byteRate = (sampleRate/2) * blockAlign;

            int dataSize = left.Count * blockAlign;

            int fileSize = 44 + dataSize - 8;

            using (BinaryWriter writer = new BinaryWriter(File.Create(path)))

            {

                // RIFF header

                writer.Write(Encoding.ASCII.GetBytes("RIFF"));

                writer.Write(fileSize);

                writer.Write(Encoding.ASCII.GetBytes("WAVE"));

                // fmt chunk

                writer.Write(Encoding.ASCII.GetBytes("fmt "));

                writer.Write(16); // Subchunk1Size for PCM

                writer.Write((short)1); // AudioFormat = PCM

                writer.Write((short)numChannels);

                writer.Write(sampleRate);

                writer.Write(byteRate);

                writer.Write((short)blockAlign);

                writer.Write((short)bitsPerSample);

                // data chunk

                writer.Write(Encoding.ASCII.GetBytes("data"));

                writer.Write(dataSize);

                for (int i = 0; i < left.Count; i++)

                {

                    short leftSample = ConvertFloatToPcm16(left[i]);

                    short rightSample = ConvertFloatToPcm16(right[i]);

                    writer.Write(leftSample);

                    writer.Write(rightSample);

                }//for (int i = 0; i < left.Count; i++)

            }//using (BinaryWriter writer = new BinaryWriter(File.Create(path)))

        }//public static void WriteStereoWav(string path, List<float> left, List<float> right, int sampleRate, int bitsPerSample)

        public static short ConvertFloatToPcm16(float value)

        {

            // Clamp to [-1.0f, 1.0f]

            if (value > 1.0f) value = 1.0f;

            if (value < -1.0f) value = -1.0f;

            return (short)(value * 32767);

        }//public static short ConvertFloatToPcm16(float value)

    }//public class StereoWavWriter___READS_TEXT_FILES___TWO_COLUMNS_THE_LEFT_RIGHT_ODD_EVEN_GTAMPS

    /////////////////////////////////////////////////////////////////////////////

    public class ShrutiResamplerAnalyzer___WITH_BITMAPS____DETAILED_SWINGS_OF______DEEP___PANNING__________RECALCULATED___66_COPIES_SHRUTIS_PANNED_WITH_STATISTICS

    {

        public static Dictionary<int, int> ThetaCounts = new Dictionary<int, int>();

        public static int ThetaCountMedian = 0;

        public static double PUBLIC_STATIC_DOUBLES_ZERO_CROSSING_NEGATIVES_TO_POSITIVES_COUNTER = 0;

        public static double PUBLIC_STATIC_DOUBLES_ZERO_CROSSING_POSITIVES_TO_NEGATIVES_COUNTER = 0;

        public static double PUBLIC_STATIC_DOUBLES_ZERO_CROSSING_ANY_KIND_OF_ZERO_CROSSINGS_COUNTER = 0;

        public static List<float> PUBLIC_STATIC_LIST_OF_FLOATS_TO_STORE_LEFT_PANS_SAMPLES = new List<float>();

        public static List<float> PUBLIC_STATIC_LIST_OF_FLOATS_TO_STORE_RIGHT_PANS_SAMPLES = new List<float>();

        public static void FirstScanThetaBinning(string inputWavPath)

        {

            StringBuilder ___temp_StringBuilder_for_leftPan_right_pan = new StringBuilder();

            ___temp_StringBuilder_for_leftPan_right_pan.Clear();

            PUBLIC_STATIC_LIST_OF_FLOATS_TO_STORE_LEFT_PANS_SAMPLES.Clear();

            PUBLIC_STATIC_LIST_OF_FLOATS_TO_STORE_RIGHT_PANS_SAMPLES.Clear();

            float[] samples = ReadWavMonoAsFloats(inputWavPath, out int sampleRate);

            double dtMs = 1000.0 / sampleRate;

            List<double>[] thetaBins = new List<double>[180];

            for (int i = 0; i < 180; i++)

            {

                thetaBins[i] = new List<double>();

                ThetaCounts[i] = 0;

            }

            for (int i = 1; i < samples.Length; i++)

            {

                float amp1 = samples[i - 1];

                float amp2 = samples[i];

                double dAmp = amp2 - amp1;

                if(amp2>0 && amp1 <=0)

                {

                    PUBLIC_STATIC_DOUBLES_ZERO_CROSSING_NEGATIVES_TO_POSITIVES_COUNTER ++;

                    PUBLIC_STATIC_DOUBLES_ZERO_CROSSING_ANY_KIND_OF_ZERO_CROSSINGS_COUNTER++;

                }// if(amp2>0 && amp1 <=0)

                else if (amp2 <= 0 && amp1 > 0)

                {

                    PUBLIC_STATIC_DOUBLES_ZERO_CROSSING_POSITIVES_TO_NEGATIVES_COUNTER++;

                    PUBLIC_STATIC_DOUBLES_ZERO_CROSSING_ANY_KIND_OF_ZERO_CROSSINGS_COUNTER++;

                }//if (amp2 <= 0 && amp1 >= 0)

                else

                {

                    // i was getting sufficient less number of samples

                   // PUBLIC_STATIC_DOUBLES_ZERO_CROSSING_NEGATIVES_TO_POSITIVES_COUNTER++;

                    PUBLIC_STATIC_DOUBLES_ZERO_CROSSING_ANY_KIND_OF_ZERO_CROSSINGS_COUNTER++;

                }//i had to add this to accumulate all the samples

                if(PUBLIC_STATIC_DOUBLES_ZERO_CROSSING_ANY_KIND_OF_ZERO_CROSSINGS_COUNTER%2 ==0)

                {

                    PUBLIC_STATIC_LIST_OF_FLOATS_TO_STORE_RIGHT_PANS_SAMPLES.Add(amp2);

                    ___temp_StringBuilder_for_leftPan_right_pan

                        .AppendLine("0.000000 , " + amp2.ToString("F8"));

                }

                else

                {

                    PUBLIC_STATIC_LIST_OF_FLOATS_TO_STORE_LEFT_PANS_SAMPLES.Add(amp1);

                    ___temp_StringBuilder_for_leftPan_right_pan

                        .AppendLine( amp1.ToString("F8")+",0.000000");

                }//end of else of  if(PUBLIC_STATIC_DOUBLES_ZERO_CROSSING_ANY_KIND_OF_ZERO_CROSSINGS_COUNTER%2 ==0)

                double thetaRad = Math.Atan2(dAmp, dtMs);

                double thetaDeg = thetaRad * 180.0 / Math.PI;

                if (thetaDeg < 0) thetaDeg += 180;

                int bin = (int)Math.Floor(thetaDeg);

                if (bin >= 0 && bin < 180)

                {

                    double timeMs = i * dtMs;

                    thetaBins[bin].Add(timeMs);

                    ThetaCounts[bin]++;

                }

            }//for (int i = 1; i < samples.Length; i++)

            ThetaCountMedian = ThetaCounts.Values.OrderBy(x => x).ElementAt(ThetaCounts.Count / 2);

            SaveBitmapAndDxf(thetaBins, samples.Length, dtMs, inputWavPath);

            ExportThetaStats(thetaBins, inputWavPath);

            try

            {

                //////////////////////////////////////////////////////////////////////////////

                System.IO.File.WriteAllText

                    (

                    inputWavPath + "_saans_RAW_GRABBINGS_FILTERED_left_pan_right_pan_odd_even_zero_count.THE_LEFT_RIGHT_ODD_EVEN_GTAMPS"

                    ,

                    ___temp_StringBuilder_for_leftPan_right_pan.ToString()

                    );

                //////////////////////////////////////////////////////////////////////////////

            WavWriter_with_left_right_samples_pan_list_supplied

            .WriteStereoWav

                (

                outputPath: inputWavPath.Replace(".wav", "_saans_pan_accumulated_from_the_odd_evens_listsstereo.wav"),

                left: PUBLIC_STATIC_LIST_OF_FLOATS_TO_STORE_LEFT_PANS_SAMPLES,

                right: PUBLIC_STATIC_LIST_OF_FLOATS_TO_STORE_RIGHT_PANS_SAMPLES,

                sampleRate: sampleRate,

                bitsPerSample: 16 // Assuming 16-bit input. Update if different.

            );

                /////////////////////////////////////////////////////////////////////

                System.Windows.Forms.MessageBox.Show("Wait\r\n\r\n\r\n writing the double columns odds evens left pans right pans GTAMS FILES FIRST THEN WE WILL READ \r\n\r\n\r\n\r\n\r\n\r\n\r\n StereoWavWriter___READS_TEXT_FILES___TWO_COLUMNS_THE_LEFT_RIGHT_ODD_EVEN_GTAMPS");

                //tricky calls

                WaitUntilFileIsReady(inputWavPath + "_saans_RAW_GRABBINGS_FILTERED_left_pan_right_pan_odd_even_zero_count.THE_LEFT_RIGHT_ODD_EVEN_GTAMPS");

                System.Windows.Forms.MessageBox.Show("FILE IS READY\r\n\r\n\r\n writing the double columns odds evens left pans right pans GTAMS FILES FIRST THEN WE WILL READ \r\n\r\n\r\n\r\n\r\n\r\n\r\n StereoWavWriter___READS_TEXT_FILES___TWO_COLUMNS_THE_LEFT_RIGHT_ODD_EVEN_GTAMPS");

                StereoWavWriter___READS_TEXT_FILES___TWO_COLUMNS_THE_LEFT_RIGHT_ODD_EVEN_GTAMPS

                    .process_text_file_with___StereoWavWriter___READS_TEXT_FILES___TWO_COLUMNS_THE_LEFT_RIGHT_ODD_EVEN_GTAMPS___Main

                    (

                    inputWavPath + "_saans_RAW_GRABBINGS_FILTERED_left_pan_right_pan_odd_even_zero_count.THE_LEFT_RIGHT_ODD_EVEN_GTAMPS"

                    );

            }

            catch (Exception ___excp___saan_styles_leftpans_right_pans_files_writings)

            {

                System.Windows.Forms.MessageBox.Show("___excp___saan_styles_leftpans_right_pans_files_writings = " + ___excp___saan_styles_leftpans_right_pans_files_writings.Message + "   " + ___excp___saan_styles_leftpans_right_pans_files_writings.StackTrace.ToString());

            }//catch(Exception ___excp___saan_styles_leftpans_right_pans_files_writings)

        }//public static void FirstScanThetaBinning(string inputWavPath)

        public static void WaitUntilFileIsReady(string path, int timeoutMs = 5000)

        {

            DateTime start = DateTime.Now;

            while (true)

            {

                try

                {

                    using (FileStream fs = File.Open(path, FileMode.Open, FileAccess.Read, FileShare.None))

                    {

                        if (fs.Length > 0)

                            return; // File is ready

                    }//using (FileStream fs = File.Open(path, FileMode.Open, FileAccess.Read, FileShare.None))

                }

                catch (IOException)

                {

                    // File is still locked or being written

                }

                if ((DateTime.Now - start).TotalMilliseconds > timeoutMs)

                    throw new TimeoutException("File was not ready within timeout.");

                System.Threading.Thread.Sleep(100); // small wait before retrying

            }//while (true)

        }//public static void WaitUntilFileIsReady(string path, int timeoutMs = 5000)

        public static double GetPanningFactorFromThetaStats(int bin)

        {

            if (!ThetaCounts.ContainsKey(bin)) return 0.5;

            int count = ThetaCounts[bin];

            return Math.Min(1.0, count / (double)(ThetaCountMedian * 2));

        }

        public static void GenerateShrutiVariants___GPT(string inputWavPath, string outputWavPath)

        {

            float[] sourceSamples = ReadWavMonoAsFloats(inputWavPath, out int sourceRate);

            int outputRate = 8000;

            double originalFrequency = 440.0;

            double durationSec = sourceSamples.Length / (double)sourceRate;

            double totalCycleProduct = originalFrequency * durationSec;

            using (FileStream fs = new FileStream(outputWavPath, FileMode.Create))

            using (BinaryWriter bw = new BinaryWriter(fs))

            {

                WriteWavHeaderPlaceholder(bw, outputRate, 2);

                for (int i = -33; i <= 32; i++)

                {

                    double semitoneShift = i * (1.0 / 3);

                    double freqMultiplier = Math.Pow(2, semitoneShift / 12.0);

                    double newFreq = originalFrequency * freqMultiplier;

                    double newDuration = totalCycleProduct / newFreq;

                    int newSampleCount = (int)(newDuration * outputRate);

                    float[] resampled = ResampleWithFactor(sourceSamples, newSampleCount);

                    int start = 0;

                    for (int j = 1; j < resampled.Length; j++)

                    {

                        if ((resampled[j - 1] >= 0 && resampled[j] < 0) || (resampled[j - 1] < 0 && resampled[j] >= 0))

                        {

                            float amp1 = resampled[Math.Max(start, j - 2)];

                            float amp2 = resampled[Math.Max(start + 1, j - 1)];

                            double dAmp = amp2 - amp1;

                            double dt = 1.0 / outputRate * 1000.0;

                            double thetaRad = Math.Atan2(dAmp, dt);

                            double thetaDeg = thetaRad * 180.0 / Math.PI;

                            if (thetaDeg < 0) thetaDeg += 180;

                            int bin = (int)Math.Floor(thetaDeg);

                            double panFactor = GetPanningFactorFromThetaStats(bin);

                            for (int k = start; k < j; k++)

                            {

                                float amp = resampled[k];

                                float l = (float)((1.0 - panFactor) * amp * 1.2f); // increase gain to avoid suppression

                                float r = (float)(panFactor * amp * 1.2f);

                                WriteStereoSample(bw, l, r);

                            }

                            start = j;

                        }

                    }

                    for (int k = start; k < resampled.Length; k++)

                    {

                        float amp = resampled[k];

                        float l = amp * 0.7f;

                        float r = amp * 0.7f;

                        WriteStereoSample(bw, l, r);

                    }

                }

                long fileLength = fs.Position;

                PatchWavHeader(bw, outputRate, 2, (int)(fileLength - 44));

            }

        }

        public static void SaveBitmapAndDxf(List<double>[] thetaBins, int totalSamples, double dtMs, string basePath)

        {

            int maxX = (int)(totalSamples * dtMs);

            double ___double___dxf_width_is_actiual_millis = maxX;

            double ___double___y_scale_for_dxf = maxX / 180; ;

            int maxBitmapWidth = 10000;

            double scale = 1.0;

            if (maxX > maxBitmapWidth)

            {

                scale = (double)maxBitmapWidth / maxX;

                maxX = maxBitmapWidth;

            }

            int height = 1800;

            Bitmap bmp = new Bitmap(maxX, height);

            using (Graphics g = Graphics.FromImage(bmp))

            {

                g.Clear(Color.White);

                for (int i = 0; i < 180; i++)

                {

                    int y = i * height / 180;

                    Brush brush = new SolidBrush(GetHeatmapColor(ThetaCounts[i], 0, 1000));

                    foreach (double t in thetaBins[i])

                    {

                        int x = (int)(t * scale);

                        if (x >= 0 && x < maxX) g.FillEllipse(brush, x, y, 2, 2);

                    }

                }

            }

            bmp.Save(Path.ChangeExtension(basePath, "_STATISTIKALLY_COLORED_rotations_colored.bmp"));

            using (StreamWriter sw = new StreamWriter(Path.ChangeExtension(basePath, ".STATISTIKALLY_COLORED_colored.dxf")))

            {

                sw.WriteLine("0\nSECTION\n2\nENTITIES");

                int durationInSeconds = (int)Math.Ceiling(totalSamples * dtMs / 1000.0);

                for (int sec = 0; sec <= durationInSeconds; sec++)

                {

                    double x = sec * 1000.0; // time in milliseconds

                    // Vertical green line (color index 3 = green)

                    sw.WriteLine("0\nLINE");

                    sw.WriteLine("8\nTimeMarkers");

                    sw.WriteLine("62\n3"); // green

                    sw.WriteLine($"10\n{x:F3}");

                    sw.WriteLine("20\n0.0");

                    sw.WriteLine("30\n0.0");

                    sw.WriteLine($"11\n{x:F3}");

                    sw.WriteLine($"21\n{180 * ___double___y_scale_for_dxf:F3}");

                    sw.WriteLine("31\n0.0");

                    // Text on top of the line

                    sw.WriteLine("0\nTEXT");

                    sw.WriteLine("8\nTimeLabels");

                    sw.WriteLine("62\n3"); // green

                    sw.WriteLine($"10\n{x + 2:F3}");  // small offset to the right

                    sw.WriteLine($"20\n{(180 * ___double___y_scale_for_dxf) + 2:F3}");  // small offset above

                    sw.WriteLine("30\n0.0");

                    sw.WriteLine("40\n5"); // height of text

                    sw.WriteLine("1\n" + sec.ToString() + "s");

                }//for (int sec = 0; sec <= durationInSeconds; sec++)

                for (int i = 0; i < 180; i++)

                {

                    double y = i* ___double___y_scale_for_dxf;

                    string layer = $"Theta_{i:D3}_Count_{ThetaCounts[i]}";

                    foreach (double t in thetaBins[i])

                    {

                        int colorIndex = i % 30;

                        sw.WriteLine("0\nCIRCLE");

                        sw.WriteLine($"8\n{layer}");

                        sw.WriteLine($"62\n{colorIndex}"); // DXF color

                        sw.WriteLine("10\n" + t.ToString("F3"));//true scales

                        sw.WriteLine("20\n" + (y ).ToString("F3"));//true scales

                        sw.WriteLine("30\n0.0\n40\n0.1");

                    }//foreach (double t in thetaBins[i])

                }//for (int i = 0; i < 180; i++)

                sw.WriteLine("0\nENDSEC\n0\nEOF");

            }

        }

        //////sw.WriteLine("0\nCIRCLE");

        //////sw.WriteLine($"8\n{layer}");

        //////sw.WriteLine($"62\n{colorIndex}"); // DXF color

        //////sw.WriteLine($"10\n{t:F3}");

        //////sw.WriteLine($"20\n{y:F3}");

        //////sw.WriteLine("30\n0.0");

        //////sw.WriteLine("40\n0.1"); // radius

        public static Color GetHeatmapColor(int value, int min, int max)

        {

            double ratio = Math.Min(1.0, Math.Max(0.0, (value - min) / (double)(max - min)));

            int r = (int)(255 * ratio);

            int b = 255 - r;

            return Color.FromArgb(r, 0, b);

        }

        public static void ExportThetaStats(List<double>[] thetaBins, string basePath)

        {

            using (StreamWriter sw = new StreamWriter(Path.ChangeExtension(basePath, ".theta_analysis.txt")))

            {

                for (int i = 0; i < 180; i++)

                {

                    var times = thetaBins[i];

                    sw.WriteLine($"Theta {i}° ({times.Count} entries)");

                    if (times.Count > 0)

                    {

                        double percentile25 = times[(int)(0.25 * times.Count)];

                        double percentile50 = times[(int)(0.50 * times.Count)];

                        double percentile75 = times[(int)(0.75 * times.Count)];

                        sw.WriteLine($"25th %ile: {percentile25} ms, 50th: {percentile50} ms, 75th: {percentile75} ms");

                    }

                }

            }

        }

        public static float[] ResampleWithFactor(float[] input, int targetLength)

        {

            float[] result = new float[targetLength];

            double step = (double)(input.Length - 1) / (targetLength - 1);

            for (int i = 0; i < targetLength; i++)

            {

                double pos = i * step;

                int idx = (int)pos;

                double frac = pos - idx;

                result[i] = (idx + 1 < input.Length)

                    ? (float)((1 - frac) * input[idx] + frac * input[idx + 1])

                    : input[idx];

            }

            return result;

        }

        public static float[] ReadWavMonoAsFloats(string path, out int sampleRate)

        {

            using (BinaryReader br = new BinaryReader(File.OpenRead(path)))

            {

                br.BaseStream.Seek(0, SeekOrigin.Begin);

                br.ReadBytes(12);

                int channels = 1;

                sampleRate = 8000;// 44100;

                int bitsPerSample = 16;

                while (br.BaseStream.Position < br.BaseStream.Length)

                {

                    string chunkID = new string(br.ReadChars(4));

                    int chunkSize = br.ReadInt32();

                    if (chunkID == "fmt ")

                    {

                        br.ReadInt16();

                        channels = br.ReadInt16();

                        sampleRate = br.ReadInt32();

                        br.ReadInt32();

                        br.ReadInt16();

                        bitsPerSample = br.ReadInt16();

                        if (chunkSize > 16) br.ReadBytes(chunkSize - 16);

                    }

                    else if (chunkID == "data")

                    {

                        int bytesPerSample = bitsPerSample / 8;

                        int totalSamples = chunkSize / bytesPerSample;

                        float[] samples = new float[totalSamples / channels];

                        for (int i = 0, j = 0; i < totalSamples; i++)

                        {

                            short sample = br.ReadInt16();

                            if (channels == 1 || i % channels == 0)

                                samples[j++] = sample / 32768f;

                            if (channels == 2) br.ReadInt16();

                        }

                        return samples;

                    }

                    else br.ReadBytes(chunkSize);

                }

            }

            sampleRate = 44100;

            return new float[0];

        }

        public static void WriteStereoSample(BinaryWriter bw, float left, float right)

        {

            short l = (short)(Math.Max(-1f, Math.Min(1f, left)) * 32767);

            short r = (short)(Math.Max(-1f, Math.Min(1f, right)) * 32767);

            bw.Write(l);

            bw.Write(r);

        }

        public static void WriteWavHeaderPlaceholder(BinaryWriter bw, int sampleRate, int channels)

        {

            bw.Write(Encoding.ASCII.GetBytes("RIFF"));

            bw.Write(0);

            bw.Write(Encoding.ASCII.GetBytes("WAVE"));

            bw.Write(Encoding.ASCII.GetBytes("fmt "));

            bw.Write(16);

            bw.Write((short)1);

            bw.Write((short)channels);

            bw.Write(sampleRate);

            int byteRate = sampleRate * channels * 2;

            short blockAlign = (short)(channels * 2);

            bw.Write(byteRate);

            bw.Write(blockAlign);

            bw.Write((short)16);

            bw.Write(Encoding.ASCII.GetBytes("data"));

            bw.Write(0);

        }

        public static void PatchWavHeader(BinaryWriter bw, int sampleRate, int channels, int dataSize)

        {

            bw.Seek(4, SeekOrigin.Begin);

            bw.Write(36 + dataSize);

            bw.Seek(40, SeekOrigin.Begin);

            bw.Write(dataSize);

        }

    }//public class ShrutiResamplerAnalyzer___WITH_BITMAPS____DETAILED_SWINGS_OF______DEEP___PANNING__________RECALCULATED___66_COPIES_SHRUTIS_PANNED_WITH_STATISTICS

    public class VOLUMES__SUPPRESSED____ShrutiResamplerAnalyzer___WITH_BITMAPS____DETAILED_SWINGS_OF______DEEP___PANNING__________RECALCULATED___66_COPIES_SHRUTIS_PANNED_WITH_STATISTICS

    {

        public static Dictionary<int, int> ThetaCounts = new Dictionary<int, int>();

        public static int ThetaCountMedian = 0;

        public static void FirstScanThetaBinning(string inputWavPath)

        {

            float[] samples = ReadWavMonoAsFloats(inputWavPath, out int sampleRate);

            double dtMs = 1000.0 / sampleRate;

            List<double>[] thetaBins = new List<double>[180];

            for (int i = 0; i < 180; i++)

            {

                thetaBins[i] = new List<double>(); // I NEED THE (STRICTKY ADDITIONAL 180 FILES)  8000 SAMPLES PER SECOND PCM RIFF 16 BITS DEPTH WAV FILES KEEPING THE SAME SAMPLES PER SECOND AS ORIGINAL INPUT FILE AND NO CHANGE IN FREQUENCIES ) FILTERED ONLY WITH THESE LIST VALUES AMPLITUDES CASES TO UNDERSTAND HOW THESE PLAYS ) I NEED TO EXAMINE ALL THESE 180 DIFFERENT WAV FILES SUCH THAT IT WILL HELP ME TO UNDERSTAND THE LISTENING OF WAVE FORMS BEHAVIORS DUE TO 180 DIFFERENT WAV FILES (NOT 66 COPIES FOR THESE 180 CASES OF SAME SAMPLES 

                ThetaCounts[i] = 0;

            }

            for (int i = 1; i < samples.Length; i++)

            {

                float amp1 = samples[i - 1];

                float amp2 = samples[i];

                double dAmp = amp2 - amp1;

                double thetaRad = Math.Atan2(dAmp, dtMs);

                double thetaDeg = (thetaRad * 180.0 / Math.PI);

                if (thetaDeg < 0) thetaDeg += 180;

                int bin = (int)Math.Floor(thetaDeg);

                if (bin >= 0 && bin < 180)

                {

                    double timeMs = i * dtMs;

                    thetaBins[bin].Add(timeMs);

                    ThetaCounts[bin]++;

                }

            }

            ThetaCountMedian = ThetaCounts.Values.OrderBy(x => x).ElementAt(ThetaCounts.Count / 2);

            SaveBitmapAndDxf(thetaBins, samples.Length, dtMs, inputWavPath);

            ExportThetaStats(thetaBins, inputWavPath);

        }

        public static double GetPanningFactorFromThetaStats(int bin)

        {

            if (!ThetaCounts.ContainsKey(bin)) return 0.5;

            int count = ThetaCounts[bin];

            return Math.Min(1.0, count / (double)(ThetaCountMedian * 2));

        }//public static double GetPanningFactorFromThetaStats(int bin)

        public static void GenerateShrutiVariants___GPT(string inputWavPath, string outputWavPath)

        {

            float[] sourceSamples = ReadWavMonoAsFloats(inputWavPath, out int sourceRate);

            int outputRate = 8000;

            double originalFrequency = 440.0;

            double durationSec = sourceSamples.Length / (double)sourceRate;

            double totalCycleProduct = originalFrequency * durationSec;

            using (FileStream fs = new FileStream(outputWavPath, FileMode.Create))

            using (BinaryWriter bw = new BinaryWriter(fs))

            {

                WriteWavHeaderPlaceholder(bw, outputRate, 2);

                for (int i = -33; i <= 32; i++)

                {

                    double semitoneShift = i * (1.0 / 3);

                    double freqMultiplier = Math.Pow(2, semitoneShift / 12.0);

                    double newFreq = originalFrequency * freqMultiplier;

                    double newDuration = totalCycleProduct / newFreq;

                    int newSampleCount = (int)(newDuration * outputRate);

                    float[] resampled = ResampleWithFactor(sourceSamples, newSampleCount);

                    int start = 0;

                    for (int j = 1; j < resampled.Length; j++)

                    {

                        if ((resampled[j - 1] >= 0 && resampled[j] < 0) || (resampled[j - 1] < 0 && resampled[j] >= 0))

                        {

                            float amp1 = resampled[Math.Max(start, j - 2)];

                            float amp2 = resampled[Math.Max(start + 1, j - 1)];

                            double dAmp = amp2 - amp1;

                            double dt = 1.0 / outputRate * 1000.0;

                            double thetaRad = Math.Atan2(dAmp, dt);

                            double thetaDeg = thetaRad * 180.0 / Math.PI;

                            if (thetaDeg < 0) thetaDeg += 180;

                            int bin = (int)Math.Floor(thetaDeg);

                            double panFactor = GetPanningFactorFromThetaStats(bin);

                            for (int k = start; k < j; k++)

                            {

                                float l = (float)((1.0 - panFactor) * resampled[k]);

                                float r = (float)(panFactor * resampled[k]);

                                WriteStereoSample(bw, l, r);

                            }

                            start = j;

                        }

                    }

                    for (int k = start; k < resampled.Length; k++)

                    {

                        float l = resampled[k] * 0.5f;

                        float r = resampled[k] * 0.5f;

                        WriteStereoSample(bw, l, r);

                    }

                }

                long fileLength = fs.Position;

                PatchWavHeader(bw, outputRate, 2, (int)(fileLength - 44));

            }

        }

        public static void SaveBitmapAndDxf(List<double>[] thetaBins, int totalSamples, double dtMs, string basePath)

        {

            int maxX = (int)(totalSamples * dtMs);

            int maxBitmapWidth = 10000;

            double scale = 1.0;

            if (maxX > maxBitmapWidth)

            {

                scale = (double)maxBitmapWidth / maxX;

                maxX = maxBitmapWidth;

            }

            int height = 1800;

            Bitmap bmp = new Bitmap(maxX, height);

            using (Graphics g = Graphics.FromImage(bmp))

            {

                g.Clear(Color.White);

                for (int i = 0; i < 180; i++)

                {

                    int y = i * height / 180;

                    Brush brush = new SolidBrush(GetHeatmapColor(ThetaCounts[i], 0, 1000));

                    foreach (double t in thetaBins[i])

                    {

                        int x = (int)(t * scale);

                        if (x >= 0 && x < maxX) g.FillEllipse(brush, x, y, 2, 2);

                    }

                }

            }

            bmp.Save(Path.ChangeExtension(basePath, "_STATISTIKALLY_COLORED_rotations_colored.bmp"));

            using (StreamWriter sw = new StreamWriter(Path.ChangeExtension(basePath, ".STATISTIKALLY_COLORED_colored.dxf")))

            {

                sw.WriteLine("0\nSECTION\n2\nENTITIES");

                for (int i = 0; i < 180; i++)

                {

                    double y = i;

                    string layer = $"Theta_{i:D3}_Count_{ThetaCounts[i]}";

                    foreach (double t in thetaBins[i])

                    {

                        sw.WriteLine("0\nCIRCLE");

                        sw.WriteLine($"8\n{layer}");

                        sw.WriteLine("10\n" + t.ToString("F3"));

                        sw.WriteLine("20\n" + y.ToString("F3"));

                        sw.WriteLine("30\n0.0\n40\n0.1");

                    }

                }

                sw.WriteLine("0\nENDSEC\n0\nEOF");

            }

        }

        public static Color GetHeatmapColor(int value, int min, int max)

        {

            double ratio = Math.Min(1.0, Math.Max(0.0, (value - min) / (double)(max - min)));

            int r = (int)(255 * ratio);

            int b = 255 - r;

            return Color.FromArgb(r, 0, b);

        }

        public static void ExportThetaStats(List<double>[] thetaBins, string basePath)

        {

            using (StreamWriter sw = new StreamWriter(Path.ChangeExtension(basePath, ".theta_analysis.txt")))

            {

                for (int i = 0; i < 180; i++)

                {

                    var times = thetaBins[i];

                    sw.WriteLine($"Theta {i}° ({times.Count} entries)");

                    if (times.Count > 0)

                    {

                        double percentile25 = times[(int)(0.25 * times.Count)];

                        double percentile50 = times[(int)(0.50 * times.Count)];

                        double percentile75 = times[(int)(0.75 * times.Count)];

                        sw.WriteLine($"25th %ile: {percentile25} ms, 50th: {percentile50} ms, 75th: {percentile75} ms");

                    }

                }

            }

        }

        public static float[] ResampleWithFactor(float[] input, int targetLength)

        {

            float[] result = new float[targetLength];

            double step = (double)(input.Length - 1) / (targetLength - 1);

            for (int i = 0; i < targetLength; i++)

            {

                double pos = i * step;

                int idx = (int)pos;

                double frac = pos - idx;

                result[i] = (idx + 1 < input.Length)

                    ? (float)((1 - frac) * input[idx] + frac * input[idx + 1])

                    : input[idx];

            }

            return result;

        }

        public static float[] ReadWavMonoAsFloats(string path, out int sampleRate)

        {

            using (BinaryReader br = new BinaryReader(File.OpenRead(path)))

            {

                br.BaseStream.Seek(0, SeekOrigin.Begin);

                br.ReadBytes(12);

                int channels = 1;

                sampleRate = 44100;

                int bitsPerSample = 16;

                while (br.BaseStream.Position < br.BaseStream.Length)

                {

                    string chunkID = new string(br.ReadChars(4));

                    int chunkSize = br.ReadInt32();

                    if (chunkID == "fmt ")

                    {

                        br.ReadInt16();

                        channels = br.ReadInt16();

                        sampleRate = br.ReadInt32();

                        br.ReadInt32();

                        br.ReadInt16();

                        bitsPerSample = br.ReadInt16();

                        if (chunkSize > 16) br.ReadBytes(chunkSize - 16);

                    }

                    else if (chunkID == "data")

                    {

                        int bytesPerSample = bitsPerSample / 8;

                        int totalSamples = chunkSize / bytesPerSample;

                        float[] samples = new float[totalSamples / channels];

                        for (int i = 0, j = 0; i < totalSamples; i++)

                        {

                            short sample = br.ReadInt16();

                            if (channels == 1 || i % channels == 0)

                                samples[j++] = sample / 32768f;

                            if (channels == 2) br.ReadInt16();

                        }

                        return samples;

                    }

                    else br.ReadBytes(chunkSize);

                }

            }

            sampleRate = 44100;

            return new float[0];

        }

        public static void WriteStereoSample(BinaryWriter bw, float left, float right)

        {

            short l = (short)(Math.Max(-1f, Math.Min(1f, left)) * 32767);

            short r = (short)(Math.Max(-1f, Math.Min(1f, right)) * 32767);

            bw.Write(l);

            bw.Write(r);

        }

        public static void WriteWavHeaderPlaceholder(BinaryWriter bw, int sampleRate, int channels)

        {

            bw.Write(Encoding.ASCII.GetBytes("RIFF"));

            bw.Write(0);

            bw.Write(Encoding.ASCII.GetBytes("WAVE"));

            bw.Write(Encoding.ASCII.GetBytes("fmt "));

            bw.Write(16);

            bw.Write((short)1);

            bw.Write((short)channels);

            bw.Write(sampleRate);

            int byteRate = sampleRate * channels * 2;

            short blockAlign = (short)(channels * 2);

            bw.Write(byteRate);

            bw.Write(blockAlign);

            bw.Write((short)16);

            bw.Write(Encoding.ASCII.GetBytes("data"));

            bw.Write(0);

        }

        public static void PatchWavHeader(BinaryWriter bw, int sampleRate, int channels, int dataSize)

        {

            bw.Seek(4, SeekOrigin.Begin);

            bw.Write(36 + dataSize);

            bw.Seek(40, SeekOrigin.Begin);

            bw.Write(dataSize);

        }

    }// public class ShrutiResamplerAnalyzer___WITH_BITMAPS____DETAILED_SWINGS_OF______DEEP___PANNING__________RECALCULATED___66_COPIES_SHRUTIS_PANNED_WITH_STATISTICS

    public class ShrutiResamplerAnalyzer___WITH_BITMAPS____PANNING__________RECALCULATED___66_COPIES_SHRUTIS_PANNED_WITH_STATISTICS

    {

        public static Dictionary<int, int> ThetaCounts = new Dictionary<int, int>();

        public static int ThetaCountMedian = 0;

        public static void FirstScanThetaBinning(string inputWavPath)

        {

            float[] samples = ReadWavMonoAsFloats(inputWavPath, out int sampleRate);

            double dtMs = 1000.0 / sampleRate;

            List<double>[] thetaBins = new List<double>[180];

            for (int i = 0; i < 180; i++)

            {

                thetaBins[i] = new List<double>();

                ThetaCounts[i] = 0;

            }

            for (int i = 1; i < samples.Length; i++)

            {

                float amp1 = samples[i - 1];

                float amp2 = samples[i];

                double dAmp = amp2 - amp1;

                double thetaRad = Math.Atan2(dAmp, dtMs);

                double thetaDeg = (thetaRad * 180.0 / Math.PI);

                if (thetaDeg < 0) thetaDeg += 180;

                int bin = (int)Math.Floor(thetaDeg);

                if (bin >= 0 && bin < 180)

                {

                    double timeMs = i * dtMs;

                    thetaBins[bin].Add(timeMs);

                    ThetaCounts[bin]++;

                }

            }

            ThetaCountMedian = ThetaCounts.Values.OrderBy(x => x).ElementAt(ThetaCounts.Count / 2);

            SaveBitmapAndDxf(thetaBins, samples.Length, dtMs, inputWavPath);

            ExportThetaStats(thetaBins, inputWavPath);

           // no need to call heres (double copies generates) GenerateShrutiVariants___GPT(inputWavPath, inputWavPath + "_STATISTIKALLY_COLORED_66_COPIES_PANNED.WAV");

        }//public static void FirstScanThetaBinning(string inputWavPath)

        public static void GenerateShrutiVariants___GPT(string inputWavPath, string outputWavPath)

        {

            //_STATISTIKALLY_COLORED_

            float[] sourceSamples = ReadWavMonoAsFloats(inputWavPath, out int sourceRate);

            int outputRate = 8000;

            double originalFrequency = 440.0;

            double durationSec = sourceSamples.Length / (double)sourceRate;

            double totalCycleProduct = originalFrequency * durationSec;

            using (FileStream fs = new FileStream(outputWavPath, FileMode.Create))

            using (BinaryWriter bw = new BinaryWriter(fs))

            {

                WriteWavHeaderPlaceholder(bw, outputRate, 2);

                for (int i = -33; i <= 32; i++)

                {

                    double semitoneShift = i * (1.0 / 3);

                    double freqMultiplier = Math.Pow(2, semitoneShift / 12.0);

                    double newFreq = originalFrequency * freqMultiplier;

                    double newDuration = totalCycleProduct / newFreq;

                    int newSampleCount = (int)(newDuration * outputRate);

                    float[] resampled = ResampleWithFactor(sourceSamples, newSampleCount);

                    int start = 0;

                    for (int j = 1; j < resampled.Length; j++)

                    {

                        if ((resampled[j - 1] >= 0 && resampled[j] < 0) || (resampled[j - 1] < 0 && resampled[j] >= 0))

                        {

                            float amp1 = resampled[Math.Max(start, j - 2)];

                            float amp2 = resampled[Math.Max(start + 1, j - 1)];

                            double dAmp = amp2 - amp1;

                            double dt = 1.0 / outputRate * 1000.0;

                            double thetaRad = Math.Atan2(dAmp, dt);

                            double thetaDeg = thetaRad * 180.0 / Math.PI;

                            if (thetaDeg < 0) thetaDeg += 180;

                            int bin = (int)Math.Floor(thetaDeg);

                            int pan = (ThetaCounts.ContainsKey(bin) && ThetaCounts[bin] > ThetaCountMedian) ? 1 : 0;

                            for (int k = start; k < j; k++)

                            {

                                float l = pan == 0 ? resampled[k] : 0;

                                float r = pan == 1 ? resampled[k] : 0;

                                WriteStereoSample(bw, l, r);

                            }

                            start = j;

                        }

                    }

                    for (int k = start; k < resampled.Length; k++)

                    {

                        WriteStereoSample(bw, resampled[k], resampled[k]);

                    }

                }

                long fileLength = fs.Position;

                PatchWavHeader(bw, outputRate, 2, (int)(fileLength - 44));

            }

        }

        public static void SaveBitmapAndDxf(List<double>[] thetaBins, int totalSamples, double dtMs, string basePath)

        {

            int maxX = (int)(totalSamples * dtMs);

            int maxBitmapWidth = 10000;

            double scale = 1.0;

            if (maxX > maxBitmapWidth)

            {

                scale = (double)maxBitmapWidth / maxX;

                maxX = maxBitmapWidth;

            }

            int height = 1800;

            Bitmap bmp = new Bitmap(maxX, height);

            using (Graphics g = Graphics.FromImage(bmp))

            {

                g.Clear(Color.White);

                for (int i = 0; i < 180; i++)

                {

                    int y = i * height / 180;

                    Brush brush = new SolidBrush(GetHeatmapColor(ThetaCounts[i], 0, 1000));

                    foreach (double t in thetaBins[i])

                    {

                        int x = (int)(t * scale);

                        if (x >= 0 && x < maxX) g.FillEllipse(brush, x, y, 2, 2);

                    }

                }

            }

            bmp.Save(Path.ChangeExtension(basePath, "_STATISTIKALLY_COLORED_rotations_colored.bmp"));

            using (StreamWriter sw = new StreamWriter(Path.ChangeExtension(basePath, "._STATISTIKALLY_COLORED_colored.dxf")))

            {

                sw.WriteLine("0\nSECTION\n2\nENTITIES");

                for (int i = 0; i < 180; i++)

                {

                    double y = i;

                    string layer = $"Theta_{i:D3}_Count_{ThetaCounts[i]}";

                    foreach (double t in thetaBins[i])

                    {

                        sw.WriteLine("0\nCIRCLE");

                        sw.WriteLine($"8\n{layer}");

                        sw.WriteLine("10\n" + t.ToString("F3"));

                        sw.WriteLine("20\n" + y.ToString("F3"));

                        sw.WriteLine("30\n0.0\n40\n0.1");

                    }

                }

                sw.WriteLine("0\nENDSEC\n0\nEOF");

            }

        }

        public static Color GetHeatmapColor(int value, int min, int max)

        {

            double ratio = Math.Min(1.0, Math.Max(0.0, (value - min) / (double)(max - min)));

            int r = (int)(255 * ratio);

            int b = 255 - r;

            return Color.FromArgb(r, 0, b);

        }

        public static void ExportThetaStats(List<double>[] thetaBins, string basePath)

        {

            using (StreamWriter sw = new StreamWriter(Path.ChangeExtension(basePath, ".theta_analysis.txt")))

            {

                for (int i = 0; i < 180; i++)

                {

                    var times = thetaBins[i];

                    sw.WriteLine($"Theta {i}° ({times.Count} entries)");

                    if (times.Count > 0)

                    {

                        double percentile25 = times[(int)(0.25 * times.Count)];

                        double percentile50 = times[(int)(0.50 * times.Count)];

                        double percentile75 = times[(int)(0.75 * times.Count)];

                        sw.WriteLine($"25th %ile: {percentile25} ms, 50th: {percentile50} ms, 75th: {percentile75} ms");

                    }

                }

            }

        }

        public static float[] ResampleWithFactor(float[] input, int targetLength)

        {

            float[] result = new float[targetLength];

            double step = (double)(input.Length - 1) / (targetLength - 1);

            for (int i = 0; i < targetLength; i++)

            {

                double pos = i * step;

                int idx = (int)pos;

                double frac = pos - idx;

                result[i] = (idx + 1 < input.Length)

                    ? (float)((1 - frac) * input[idx] + frac * input[idx + 1])

                    : input[idx];

            }

            return result;

        }

        public static float[] ReadWavMonoAsFloats(string path, out int sampleRate)

        {

            using (BinaryReader br = new BinaryReader(File.OpenRead(path)))

            {

                br.BaseStream.Seek(0, SeekOrigin.Begin);

                br.ReadBytes(12);

                int channels = 1;

                sampleRate = 44100;

                int bitsPerSample = 16;

                while (br.BaseStream.Position < br.BaseStream.Length)

                {

                    string chunkID = new string(br.ReadChars(4));

                    int chunkSize = br.ReadInt32();

                    if (chunkID == "fmt ")

                    {

                        br.ReadInt16();

                        channels = br.ReadInt16();

                        sampleRate = br.ReadInt32();

                        br.ReadInt32();

                        br.ReadInt16();

                        bitsPerSample = br.ReadInt16();

                        if (chunkSize > 16) br.ReadBytes(chunkSize - 16);

                    }

                    else if (chunkID == "data")

                    {

                        int bytesPerSample = bitsPerSample / 8;

                        int totalSamples = chunkSize / bytesPerSample;

                        float[] samples = new float[totalSamples / channels];

                        for (int i = 0, j = 0; i < totalSamples; i++)

                        {

                            short sample = br.ReadInt16();

                            if (channels == 1 || i % channels == 0)

                                samples[j++] = sample / 32768f;

                            if (channels == 2) br.ReadInt16();

                        }

                        return samples;

                    }

                    else br.ReadBytes(chunkSize);

                }

            }

            sampleRate = 44100;

            return new float[0];

        }

        public static void WriteStereoSample(BinaryWriter bw, float left, float right)

        {

            short l = (short)(Math.Max(-1f, Math.Min(1f, left)) * 32767);

            short r = (short)(Math.Max(-1f, Math.Min(1f, right)) * 32767);

            bw.Write(l);

            bw.Write(r);

        }

        public static void WriteWavHeaderPlaceholder(BinaryWriter bw, int sampleRate, int channels)

        {

            bw.Write(Encoding.ASCII.GetBytes("RIFF"));

            bw.Write(0);

            bw.Write(Encoding.ASCII.GetBytes("WAVE"));

            bw.Write(Encoding.ASCII.GetBytes("fmt "));

            bw.Write(16);

            bw.Write((short)1);

            bw.Write((short)channels);

            bw.Write(sampleRate);

            int byteRate = sampleRate * channels * 2;

            short blockAlign = (short)(channels * 2);

            bw.Write(byteRate);

            bw.Write(blockAlign);

            bw.Write((short)16);

            bw.Write(Encoding.ASCII.GetBytes("data"));

            bw.Write(0);

        }

        public static void PatchWavHeader(BinaryWriter bw, int sampleRate, int channels, int dataSize)

        {

            bw.Seek(4, SeekOrigin.Begin);

            bw.Write(36 + dataSize);

            bw.Seek(40, SeekOrigin.Begin);

            bw.Write(dataSize);

        }

    }//public class ShrutiResamplerAnalyzer___WITH_BITMAPS____PANNING__________RECALCULATED___66_COPIES_SHRUTIS_PANNED_WITH_STATISTICS

    //////////////////////////////////////////////////////////////////////////

    public class TO_DO_THE_MULTIPLE_SCANNING_ON_SUPPLIED_SAMPLES_PAN_WITH_FREQUENCY_CHANGES_44100_SPS_2_CHANNELS___NEW_KIND_OF_ShrutiResamplerGenerator___33_PLUS_33_66_COPIES_PLAYING_ALL_SAMPLES___GPT

    {

        public static void FirstScanThetaBinning(string inputWavPath)

        {

            float[] samples = ReadWavMonoAsFloats(inputWavPath, out int sampleRate);

            double dtMs = 1000.0 / sampleRate;

            List<double>[] thetaBins = new List<double>[180];

            for (int i = 0; i < 180; i++) thetaBins[i] = new List<double>();

            for (int i = 1; i < samples.Length; i++)

            {

                float amp1 = samples[i - 1];

                float amp2 = samples[i];

                double dAmp = amp2 - amp1;

                double thetaRad = Math.Atan2(dAmp, dtMs);

                double thetaDeg = (thetaRad * 180.0 / Math.PI);

                if (thetaDeg < 0) thetaDeg += 180;

                int bin = (int)Math.Floor(thetaDeg);

                if (bin >= 0 && bin < 180)

                {

                    double timeMs = i * dtMs;

                    thetaBins[bin].Add(timeMs);

                }

            }

            SaveBitmapAndDxf(thetaBins, samples.Length, dtMs, inputWavPath);

            ExportThetaStats(thetaBins, inputWavPath);

        }

        public static void SaveBitmapAndDxf(List<double>[] thetaBins, int totalSamples, double dtMs, string basePath)

        {

            int maxX = (int)(totalSamples * dtMs);

            int maxBitmapWidth = 10000;

            double scale = 1.0;

            if (maxX > maxBitmapWidth)

            {

                scale = (double)maxBitmapWidth / maxX;

                maxX = maxBitmapWidth;

            }

            int height = 1800; // 10 px per degree

            Bitmap bmp = new Bitmap(maxX, height);

            using (Graphics g = Graphics.FromImage(bmp))

            {

                g.Clear(Color.White);

                for (int i = 0; i < 180; i++)

                {

                    int y = i * height / 180;

                    foreach (double t in thetaBins[i])

                    {

                        int x = (int)(t * scale);

                        if (x >= 0 && x < maxX) g.FillEllipse(Brushes.Black, x, y, 2, 2);

                    }

                }

            }

            string bmpPath = Path.ChangeExtension(basePath, "_180_degrees_rotations_arrays_with_Lists.bmp");

            bmp.Save(bmpPath);

            Console.WriteLine("Bitmap saved to: " + bmpPath);

            // Also generate DXF

            string dxfPath = Path.ChangeExtension(basePath, ".rotations.dxf");

            using (StreamWriter sw = new StreamWriter(dxfPath))

            {

                sw.WriteLine("0\nSECTION\n2\nENTITIES");

                for (int i = 0; i < 180; i++)

                {

                    double y = i; // preserve true theta scale

                    foreach (double t in thetaBins[i])

                    {

                        sw.WriteLine("0\nCIRCLE");

                        sw.WriteLine("8\n0");

                        sw.WriteLine("10\n" + t.ToString("F3"));

                        sw.WriteLine("20\n" + y.ToString("F3"));

                        sw.WriteLine("30\n0.0");

                        sw.WriteLine("40\n0.1");

                    }

                }

                sw.WriteLine("0\nENDSEC\n0\nEOF");

            }

            Console.WriteLine("DXF saved to: " + dxfPath);

        }

        public static void ExportThetaStats(List<double>[] thetaBins, string basePath)

        {

            string txtPath = Path.ChangeExtension(basePath, ".theta_analysis.txt");

            using (StreamWriter sw = new StreamWriter(txtPath))

            {

                for (int i = 0; i < 180; i++)

                {

                    var times = thetaBins[i];

                    sw.WriteLine($"Theta {i}° ({times.Count} entries)");

                    if (times.Count > 0)

                    {

                        double percentile25 = times[(int)(0.25 * times.Count)];

                        double percentile50 = times[(int)(0.50 * times.Count)];

                        double percentile75 = times[(int)(0.75 * times.Count)];

                        sw.WriteLine($"25th %ile: {percentile25} ms, 50th: {percentile50} ms, 75th: {percentile75} ms");

                    }

                }

            }

            Console.WriteLine("Theta statistics exported to: " + txtPath);

        }

        public static float[] ReadWavMonoAsFloats(string path, out int sampleRate)

        {

            using (BinaryReader br = new BinaryReader(File.OpenRead(path)))

            {

                br.BaseStream.Seek(0, SeekOrigin.Begin);

                br.ReadBytes(12);

                int channels = 1;

                sampleRate = 44100;

                int bitsPerSample = 16;

                while (br.BaseStream.Position < br.BaseStream.Length)

                {

                    string chunkID = new string(br.ReadChars(4));

                    int chunkSize = br.ReadInt32();

                    if (chunkID == "fmt ")

                    {

                        br.ReadInt16();

                        channels = br.ReadInt16();

                        sampleRate = br.ReadInt32();

                        br.ReadInt32();

                        br.ReadInt16();

                        bitsPerSample = br.ReadInt16();

                        if (chunkSize > 16)

                            br.ReadBytes(chunkSize - 16);

                    }

                    else if (chunkID == "data")

                    {

                        int bytesPerSample = bitsPerSample / 8;

                        int totalSamples = chunkSize / bytesPerSample;

                        float[] samples = new float[totalSamples / channels];

                        for (int i = 0, j = 0; i < totalSamples; i++)

                        {

                            short sample = br.ReadInt16();

                            if (channels == 1 || i % channels == 0)

                                samples[j++] = sample / 32768f;

                            if (channels == 2) br.ReadInt16();

                        }

                        return samples;

                    }

                    else

                    {

                        br.ReadBytes(chunkSize);

                    }

                }

            }

            sampleRate = 44100;

            return new float[0];

        }

    }//public class TO_DO_THE_MULTIPLE_SCANNING_ON_SUPPLIED_SAMPLES_PAN_WITH_FREQUENCY_CHANGES_44100_SPS_2_CHANNELS___NEW_KIND_OF_ShrutiResamplerGenerator___33_PLUS_33_66_COPIES_PLAYING_ALL_SAMPLES___GPT

    //////public class TO_DO_THE_BMP_SAVING_MULTIPLE_SCANNING_ON_SUPPLIED_SAMPLES_PAN_WITH_FREQUENCY_CHANGES_44100_SPS_2_CHANNELS___NEW_KIND_OF_ShrutiResamplerGenerator___33_PLUS_33_66_COPIES_PLAYING_ALL_SAMPLES___GPT

    //////{

    //////    public static void FirstScanThetaBinning(string inputWavPath)

    //////    {

    //////        float[] samples = ReadWavMonoAsFloats(inputWavPath, out int sampleRate);

    //////        double dtMs = 1000.0 / sampleRate;

    //////        List<double>[] thetaBins = new List<double>[180];

    //////        for (int i = 0; i < 180; i++) thetaBins[i] = new List<double>();

    //////        for (int i = 1; i < samples.Length; i++)

    //////        {

    //////            float amp1 = samples[i - 1];

    //////            float amp2 = samples[i];

    //////            double dAmp = amp2 - amp1;

    //////            double thetaRad = Math.Atan2(dAmp, dtMs);

    //////            double thetaDeg = (thetaRad * 180.0 / Math.PI);

    //////            if (thetaDeg < 0) thetaDeg += 180;

    //////            int bin = (int)Math.Floor(thetaDeg);

    //////            if (bin >= 0 && bin < 180)

    //////            {

    //////                double timeMs = i * dtMs;

    //////                thetaBins[bin].Add(timeMs);

    //////            }//if (bin >= 0 && bin < 180)

    //////        }//for (int i = 1; i < samples.Length; i++)

    //////        SaveBitmap(thetaBins, samples.Length, dtMs, inputWavPath);

    //////        ExportThetaStats(thetaBins, inputWavPath);

    //////    }//public static void FirstScanThetaBinning(string inputWavPath)

    //////    public static void SaveBitmap(List<double>[] thetaBins, int totalSamples, double dtMs, string basePath)

    //////    {

    //////       // int size = (int)Math.Ceiling(totalSamples * dtMs);

    //////        int size = (int)Math.Ceiling(totalSamples * dtMs * 0.001);//saan changed this to avoid the parameters errors

    //////        Bitmap bmp = new Bitmap(size, size);

    //////        using (Graphics g = Graphics.FromImage(bmp))

    //////        {

    //////            g.Clear(Color.White);

    //////            for (int i = 0; i < 180; i++)

    //////            {

    //////                int y = i * size / 180;

    //////                foreach (double t in thetaBins[i])

    //////                {

    //////                  //  int x = (int)t;

    //////                    int x = (int)(t * 0.001 ); // there is some bitmaps parameters errors

    //////                    if (x >= 0 && x < size) g.FillEllipse(Brushes.Black, x, y, 2, 2);

    //////                }//foreach (double t in thetaBins[i])

    //////            }//for (int i = 0; i < 180; i++)

    //////        }//using (Graphics g = Graphics.FromImage(bmp))

    //////        string bmpPath = Path.ChangeExtension(basePath, "_180_degrees_rotations_arrays_with_Lists.bmp");

    //////        bmp.Save(bmpPath);

    //////        Console.WriteLine("Bitmap saved to: " + bmpPath);

    //////    }//public static void SaveBitmap(List<double>[] thetaBins, int totalSamples, double dtMs, string basePath)

    //////    public static void ExportThetaStats(List<double>[] thetaBins, string basePath)

    //////    {

    //////        string txtPath = Path.ChangeExtension(basePath, "._180_degrees_rotations_arrays_with_Lists_theta_analysis.txt");

    //////        using (StreamWriter sw = new StreamWriter(txtPath))

    //////        {

    //////            for (int i = 0; i < 180; i++)

    //////            {

    //////                var times = thetaBins[i];

    //////                sw.WriteLine($"Theta {i}° ({times.Count} entries)");

    //////                if (times.Count > 0)

    //////                {

    //////                    double percentile25 = times[(int)(0.25 * times.Count)];

    //////                    double percentile50 = times[(int)(0.50 * times.Count)];

    //////                    double percentile75 = times[(int)(0.75 * times.Count)];

    //////                    sw.WriteLine($"25th %ile: {percentile25} ms, 50th: {percentile50} ms, 75th: {percentile75} ms");

    //////                }

    //////            }

    //////        }

    //////        Console.WriteLine("Theta statistics exported to: " + txtPath);

    //////    }// public static void ExportThetaStats(List<double>[] thetaBins, string basePath)

    //////    public static float[] ReadWavMonoAsFloats(string path, out int sampleRate)

    //////    {

    //////        using (BinaryReader br = new BinaryReader(File.OpenRead(path)))

    //////        {

    //////            br.BaseStream.Seek(0, SeekOrigin.Begin);

    //////            br.ReadBytes(12);

    //////            int channels = 1;

    //////            sampleRate = 44100;

    //////            int bitsPerSample = 16;

    //////            while (br.BaseStream.Position < br.BaseStream.Length)

    //////            {

    //////                string chunkID = new string(br.ReadChars(4));

    //////                int chunkSize = br.ReadInt32();

    //////                if (chunkID == "fmt ")

    //////                {

    //////                    br.ReadInt16();

    //////                    channels = br.ReadInt16();

    //////                    sampleRate = br.ReadInt32();

    //////                    br.ReadInt32();

    //////                    br.ReadInt16();

    //////                    bitsPerSample = br.ReadInt16();

    //////                    if (chunkSize > 16)

    //////                        br.ReadBytes(chunkSize - 16);

    //////                }

    //////                else if (chunkID == "data")

    //////                {

    //////                    int bytesPerSample = bitsPerSample / 8;

    //////                    int totalSamples = chunkSize / bytesPerSample;

    //////                    float[] samples = new float[totalSamples / channels];

    //////                    for (int i = 0, j = 0; i < totalSamples; i++)

    //////                    {

    //////                        short sample = br.ReadInt16();

    //////                        if (channels == 1 || i % channels == 0)

    //////                            samples[j++] = sample / 32768f;

    //////                        if (channels == 2) br.ReadInt16();

    //////                    }

    //////                    return samples;

    //////                }

    //////                else

    //////                {

    //////                    br.ReadBytes(chunkSize);

    //////                }

    //////            }

    //////        }

    //////        sampleRate = 44100;

    //////        return new float[0];

    //////    }//public static float[] ReadWavMonoAsFloats(string path, out int sampleRate)

    //////}//public class TO_DO_THE_BMP_SAVING_MULTIPLE_SCANNING_ON_SUPPLIED_SAMPLES_PAN_WITH_FREQUENCY_CHANGES_44100_SPS_2_CHANNELS___NEW_KIND_OF_ShrutiResamplerGenerator___33_PLUS_33_66_COPIES_PLAYING_ALL_SAMPLES___GPT

    public class TO_DO_PAN_WITH_FREQUENCY_CHANGES_44100_SPS_2_CHANNELS___NEW_KIND_OF_ShrutiResamplerGenerator___33_PLUS_33_66_COPIES_PLAYING_ALL_SAMPLES___GPT

    {

        public static void GenerateShrutiVariants___GPT(string inputWavPath, string outputWavPath)

        {

            float[] sourceSamples = ReadWavMonoAsFloats(inputWavPath, out int sourceRate);

            int outputRate = 8000;//THE OUTPUT IS OK BUT TOO HEAVY FILES  44100;

            double originalFrequency = 440.0;

            double durationSec = sourceSamples.Length / (double)sourceRate;

            double totalCycleProduct = originalFrequency * durationSec;

            using (FileStream fs = new FileStream(outputWavPath, FileMode.Create))

            using (BinaryWriter bw = new BinaryWriter(fs))

            {

                WriteWavHeaderPlaceholder(bw, outputRate, 2);

                for (int i = -33; i <= 32; i++)

                {

                    double semitoneShift = i * (1.0 / 3);

                    double freqMultiplier = Math.Pow(2, semitoneShift / 12.0);

                    double newFreq = originalFrequency * freqMultiplier;

                    double newDuration = totalCycleProduct / newFreq;

                    int newSampleCount = (int)(newDuration * outputRate);

                    float[] resampled = ResampleWithFactor(sourceSamples, newSampleCount);

                    int lastPan = 0;

                    int start = 0;

                    for (int j = 1; j < resampled.Length; j++)

                    {

                        if ((resampled[j - 1] >= 0 && resampled[j] < 0) || (resampled[j - 1] < 0 && resampled[j] >= 0))

                        {

                            for (int k = start; k < j; k++)

                            {

                                float l = lastPan == 0 ? resampled[k] : 0;

                                float r = lastPan == 1 ? resampled[k] : 0;

                                WriteStereoSample(bw, l, r);

                            }

                            lastPan = 1 - lastPan;

                            start = j;

                        }

                    }

                    for (int k = start; k < resampled.Length; k++)

                    {

                        float l = lastPan == 0 ? resampled[k] : 0;

                        float r = lastPan == 1 ? resampled[k] : 0;

                        WriteStereoSample(bw, l, r);

                    }

                }

                long fileLength = fs.Position;

                PatchWavHeader(bw, outputRate, 2, (int)(fileLength - 44));

            }

            Console.WriteLine("Stereo 66 shruti-pitched variants with ear-swing effect generated.");

            MessageBox.Show("Done: Stereo shruti variants created\n" + outputWavPath);

        }

        public static float[] ResampleWithFactor(float[] input, int targetLength)

        {

            float[] result = new float[targetLength];

            double step = (double)(input.Length - 1) / (targetLength - 1);

            for (int i = 0; i < targetLength; i++)

            {

                double pos = i * step;

                int idx = (int)pos;

                double frac = pos - idx;

                result[i] = (idx + 1 < input.Length)

                    ? (float)((1 - frac) * input[idx] + frac * input[idx + 1])

                    : input[idx];

            }

            return result;

        }

        public static float[] ReadWavMonoAsFloats(string path, out int sampleRate)

        {

            using (BinaryReader br = new BinaryReader(File.OpenRead(path)))

            {

                br.BaseStream.Seek(0, SeekOrigin.Begin);

                br.ReadBytes(12);

                int channels = 1;

                sampleRate = 44100;

                int bitsPerSample = 16;

                while (br.BaseStream.Position < br.BaseStream.Length)

                {

                    string chunkID = new string(br.ReadChars(4));

                    int chunkSize = br.ReadInt32();

                    if (chunkID == "fmt ")

                    {

                        br.ReadInt16();

                        channels = br.ReadInt16();

                        sampleRate = br.ReadInt32();

                        br.ReadInt32();

                        br.ReadInt16();

                        bitsPerSample = br.ReadInt16();

                        if (chunkSize > 16)

                            br.ReadBytes(chunkSize - 16);

                    }

                    else if (chunkID == "data")

                    {

                        int bytesPerSample = bitsPerSample / 8;

                        int totalSamples = chunkSize / bytesPerSample;

                        float[] samples = new float[totalSamples / channels];

                        for (int i = 0, j = 0; i < totalSamples; i++)

                        {

                            short sample = br.ReadInt16();

                            if (channels == 1 || i % channels == 0)

                                samples[j++] = sample / 32768f;

                            if (channels == 2) br.ReadInt16();

                        }

                        return samples;

                    }

                    else

                    {

                        br.ReadBytes(chunkSize);

                    }

                }

            }

            sampleRate = 44100;

            return new float[0];

        }

        public static void WriteStereoSample(BinaryWriter bw, float left, float right)

        {

            short l = (short)(Math.Max(-1f, Math.Min(1f, left)) * 32767);

            short r = (short)(Math.Max(-1f, Math.Min(1f, right)) * 32767);

            bw.Write(l);

            bw.Write(r);

        }

        public static void WriteWavHeaderPlaceholder(BinaryWriter bw, int sampleRate, int channels)

        {

            bw.Write(Encoding.ASCII.GetBytes("RIFF"));

            bw.Write(0); // Placeholder for file size

            bw.Write(Encoding.ASCII.GetBytes("WAVE"));

            bw.Write(Encoding.ASCII.GetBytes("fmt "));

            bw.Write(16);

            bw.Write((short)1);

            bw.Write((short)channels);

            bw.Write(sampleRate);

            int byteRate = sampleRate * channels * 2;

            short blockAlign = (short)(channels * 2);

            bw.Write(byteRate);

            bw.Write(blockAlign);

            bw.Write((short)16);

            bw.Write(Encoding.ASCII.GetBytes("data"));

            bw.Write(0); // Placeholder for data chunk size

        }

        public static void PatchWavHeader(BinaryWriter bw, int sampleRate, int channels, int dataSize)

        {

            bw.Seek(4, SeekOrigin.Begin);

            bw.Write(36 + dataSize);

            bw.Seek(40, SeekOrigin.Begin);

            bw.Write(dataSize);

        }

        public static float[] StretchToLength(float[] input, int targetLength)

        {

            return ResampleWithFactor(input, targetLength);

        }

    }//public class TO_DO_PAN_WITH_FREQUENCY_CHANGES_44100_SPS_2_CHANNELS___NEW_KIND_OF_ShrutiResamplerGenerator___33_PLUS_33_66_COPIES_PLAYING_ALL_SAMPLES___GPT

    //////using System;

    //////using System.Collections.Generic;

    //////using System.IO;

    //////using System.Text;

    //////using System.Windows.Forms;

    ////////////namespace ShrutiResampler

    ////////////{

    //////    public class TO_DO_PAN_WITH_FREQUENCY_CHANGES_44100_SPS_2_CHANNELS___NEW_KIND_OF_ShrutiResamplerGenerator___33_PLUS_33_66_COPIES_PLAYING_ALL_SAMPLES___GPT

    //////    {

    //////        public static void GenerateShrutiVariants___GPT(string inputWavPath, string outputWavPath)

    //////        {

    //////            float[] sourceSamples = ReadWavMonoAsFloats(inputWavPath, out int sourceRate);

    //////            int outputRate = 44100;

    //////            double originalFrequency = 440.0;

    //////            double durationSec = sourceSamples.Length / (double)sourceRate;

    //////            double totalCycleProduct = originalFrequency * durationSec;

    //////            List<float> stereoSamples = new List<float>();

    //////            Random rand = new Random();

    //////            for (int i = -33; i <= 32; i++)

    //////            {

    //////                double semitoneShift = i * (1.0 / 3);

    //////                double freqMultiplier = Math.Pow(2, semitoneShift / 12.0);

    //////                double newFreq = originalFrequency * freqMultiplier;

    //////                double newDuration = totalCycleProduct / newFreq;

    //////                int newSampleCount = (int)(newDuration * outputRate);

    //////                float[] resampled = ResampleWithFactor(sourceSamples, newSampleCount);

    //////                // Stereo panning: swing left/right on zero-crossings

    //////                int lastPan = 0; // 0 = left, 1 = right

    //////                int start = 0;

    //////                for (int j = 1; j < resampled.Length; j++)

    //////                {

    //////                    if ((resampled[j - 1] >= 0 && resampled[j] < 0) || (resampled[j - 1] < 0 && resampled[j] >= 0))

    //////                    {

    //////                        for (int k = start; k < j; k++)

    //////                        {

    //////                            float l = lastPan == 0 ? resampled[k] : 0;

    //////                            float r = lastPan == 1 ? resampled[k] : 0;

    //////                            stereoSamples.Add(l);

    //////                            stereoSamples.Add(r);

    //////                        }

    //////                        lastPan = 1 - lastPan;

    //////                        start = j;

    //////                    }

    //////                }

    //////                // Copy remaining samples

    //////                for (int k = start; k < resampled.Length; k++)

    //////                {

    //////                    float l = lastPan == 0 ? resampled[k] : 0;

    //////                    float r = lastPan == 1 ? resampled[k] : 0;

    //////                    stereoSamples.Add(l);

    //////                    stereoSamples.Add(r);

    //////                }

    //////            }

    //////            SaveWav(outputWavPath, stereoSamples.ToArray(), outputRate, 2);

    //////            Console.WriteLine("Stereo 66 shruti-pitched variants with ear-swing effect generated.");

    //////            MessageBox.Show("Done: Stereo shruti variants created\n" + outputWavPath);

    //////        }

    //////        public static float[] ResampleWithFactor(float[] input, int targetLength)

    //////        {

    //////            float[] result = new float[targetLength];

    //////            double step = (double)(input.Length - 1) / (targetLength - 1);

    //////            for (int i = 0; i < targetLength; i++)

    //////            {

    //////                double pos = i * step;

    //////                int idx = (int)pos;

    //////                double frac = pos - idx;

    //////                result[i] = (idx + 1 < input.Length)

    //////                    ? (float)((1 - frac) * input[idx] + frac * input[idx + 1])

    //////                    : input[idx];

    //////            }

    //////            return result;

    //////        }

    //////        public static float[] ReadWavMonoAsFloats(string path, out int sampleRate)

    //////        {

    //////            using (BinaryReader br = new BinaryReader(File.OpenRead(path)))

    //////            {

    //////                br.BaseStream.Seek(0, SeekOrigin.Begin);

    //////                br.ReadBytes(12);

    //////                int channels = 1;

    //////                sampleRate = 44100;

    //////                int bitsPerSample = 16;

    //////                while (br.BaseStream.Position < br.BaseStream.Length)

    //////                {

    //////                    string chunkID = new string(br.ReadChars(4));

    //////                    int chunkSize = br.ReadInt32();

    //////                    if (chunkID == "fmt ")

    //////                    {

    //////                        br.ReadInt16();

    //////                        channels = br.ReadInt16();

    //////                        sampleRate = br.ReadInt32();

    //////                        br.ReadInt32();

    //////                        br.ReadInt16();

    //////                        bitsPerSample = br.ReadInt16();

    //////                        if (chunkSize > 16)

    //////                            br.ReadBytes(chunkSize - 16);

    //////                    }

    //////                    else if (chunkID == "data")

    //////                    {

    //////                        int bytesPerSample = bitsPerSample / 8;

    //////                        int totalSamples = chunkSize / bytesPerSample;

    //////                        float[] samples = new float[totalSamples / channels];

    //////                        for (int i = 0, j = 0; i < totalSamples; i++)

    //////                        {

    //////                            short sample = br.ReadInt16();

    //////                            if (channels == 1 || i % channels == 0)

    //////                                samples[j++] = sample / 32768f;

    //////                            if (channels == 2) br.ReadInt16();

    //////                        }

    //////                        return samples;

    //////                    }

    //////                    else

    //////                    {

    //////                        br.ReadBytes(chunkSize);

    //////                    }

    //////                }

    //////            }

    //////            sampleRate = 44100;

    //////            return new float[0];

    //////        }

    //////        public static void SaveWav(string path, float[] samples, int sampleRate, int channels)

    //////        {

    //////            int bitsPerSample = 16;

    //////            int byteRate = sampleRate * channels * bitsPerSample / 8;

    //////            int blockAlign = channels * bitsPerSample / 8;

    //////            int dataSize = samples.Length * 2;

    //////            using (BinaryWriter bw = new BinaryWriter(File.Create(path)))

    //////            {

    //////                bw.Write(Encoding.ASCII.GetBytes("RIFF"));

    //////                bw.Write(36 + dataSize);

    //////                bw.Write(Encoding.ASCII.GetBytes("WAVE"));

    //////                bw.Write(Encoding.ASCII.GetBytes("fmt "));

    //////                bw.Write(16);

    //////                bw.Write((short)1);

    //////                bw.Write((short)channels);

    //////                bw.Write(sampleRate);

    //////                bw.Write(byteRate);

    //////                bw.Write((short)blockAlign);

    //////                bw.Write((short)bitsPerSample);

    //////                bw.Write(Encoding.ASCII.GetBytes("data"));

    //////                bw.Write(dataSize);

    //////                foreach (float sample in samples)

    //////                {

    //////                    short s = (short)(sample * 32767);

    //////                    bw.Write(s);

    //////                }

    //////            }

    //////        }

    //////        public static float[] StretchToLength(float[] input, int targetLength)

    //////        {

    //////            return ResampleWithFactor(input, targetLength);

    //////        }

    //////    }

    ///////////////////////  }//NAMESPACES

    //THE MEMORY OVERFLOW ARRAY SIZES

    //////public class TO_DO_PAN_WITH_FREQUENCY_CHANGES_44100_SPS_2_CHANNELS___NEW_KIND_OF_ShrutiResamplerGenerator___33_PLUS_33_66_COPIES_PLAYING_ALL_SAMPLES___GPT

    //////{

    //////    public static void GenerateShrutiVariants___GPT(string inputWavPath, string outputWavPath)

    //////    {

    //////        float[] sourceSamples = ReadWavMonoAsFloats(inputWavPath, out int sourceRate);

    //////        int outputRate = 44100;

    //////        double originalFrequency = 440.0;

    //////        double durationSec = sourceSamples.Length / (double)sourceRate;

    //////        double totalCycleProduct = originalFrequency * durationSec;

    //////        List<float> stereoSamples = new List<float>();

    //////        Random rand = new Random();

    //////        for (int i = -33; i <= 32; i++)

    //////        {

    //////            double semitoneShift = i * (1.0 / 3);

    //////            double freqMultiplier = Math.Pow(2, semitoneShift / 12.0);

    //////            double newFreq = originalFrequency * freqMultiplier;

    //////            double newDuration = totalCycleProduct / newFreq;

    //////            int newSampleCount = (int)(newDuration * outputRate);

    //////            float[] resampled = ResampleWithFactor(sourceSamples, newSampleCount);

    //////            // Stereo panning: swing left/right on zero-crossings

    //////            int lastPan = 0; // 0 = left, 1 = right

    //////            int start = 0;

    //////            for (int j = 1; j < resampled.Length; j++)

    //////            {

    //////                if ((resampled[j - 1] >= 0 && resampled[j] < 0) || (resampled[j - 1] < 0 && resampled[j] >= 0))

    //////                {

    //////                    for (int k = start; k < j; k++)

    //////                    {

    //////                        float l = lastPan == 0 ? resampled[k] : 0;

    //////                        float r = lastPan == 1 ? resampled[k] : 0;

    //////                        stereoSamples.Add(l);

    //////                        stereoSamples.Add(r);

    //////                    }

    //////                    lastPan = 1 - lastPan;

    //////                    start = j;

    //////                }

    //////            }

    //////            // Copy remaining samples

    //////            for (int k = start; k < resampled.Length; k++)

    //////            {

    //////                float l = lastPan == 0 ? resampled[k] : 0;

    //////                float r = lastPan == 1 ? resampled[k] : 0;

    //////                stereoSamples.Add(l);

    //////                stereoSamples.Add(r);

    //////            }

    //////        }

    //////        SaveWav(outputWavPath, stereoSamples.ToArray(), outputRate, 2);

    //////        Console.WriteLine("Stereo 66 shruti-pitched variants with ear-swing effect generated.");

    //////        MessageBox.Show("Done: Stereo shruti variants created\n" + outputWavPath);

    //////    }

    //////    public static float[] ResampleWithFactor(float[] input, int targetLength)

    //////    {

    //////        float[] result = new float[targetLength];

    //////        double step = (double)(input.Length - 1) / (targetLength - 1);

    //////        for (int i = 0; i < targetLength; i++)

    //////        {

    //////            double pos = i * step;

    //////            int idx = (int)pos;

    //////            double frac = pos - idx;

    //////            result[i] = (idx + 1 < input.Length)

    //////                ? (float)((1 - frac) * input[idx] + frac * input[idx + 1])

    //////                : input[idx];

    //////        }

    //////        return result;

    //////    }

    //////    public static float[] ReadWavMonoAsFloats(string path, out int sampleRate)

    //////    {

    //////        using (BinaryReader br = new BinaryReader(File.OpenRead(path)))

    //////        {

    //////            br.BaseStream.Seek(0, SeekOrigin.Begin);

    //////            br.ReadBytes(12);

    //////            int channels = 1;

    //////            sampleRate = 44100;

    //////            int bitsPerSample = 16;

    //////            while (br.BaseStream.Position < br.BaseStream.Length)

    //////            {

    //////                string chunkID = new string(br.ReadChars(4));

    //////                int chunkSize = br.ReadInt32();

    //////                if (chunkID == "fmt ")

    //////                {

    //////                    br.ReadInt16();

    //////                    channels = br.ReadInt16();

    //////                    sampleRate = br.ReadInt32();

    //////                    br.ReadInt32();

    //////                    br.ReadInt16();

    //////                    bitsPerSample = br.ReadInt16();

    //////                    if (chunkSize > 16)

    //////                        br.ReadBytes(chunkSize - 16);

    //////                }

    //////                else if (chunkID == "data")

    //////                {

    //////                    int bytesPerSample = bitsPerSample / 8;

    //////                    int totalSamples = chunkSize / bytesPerSample;

    //////                    float[] samples = new float[totalSamples / channels];

    //////                    for (int i = 0, j = 0; i < totalSamples; i++)

    //////                    {

    //////                        short sample = br.ReadInt16();

    //////                        if (channels == 1 || i % channels == 0)

    //////                            samples[j++] = sample / 32768f;

    //////                        if (channels == 2) br.ReadInt16();

    //////                    }

    //////                    return samples;

    //////                }

    //////                else

    //////                {

    //////                    br.ReadBytes(chunkSize);

    //////                }

    //////            }

    //////        }

    //////        sampleRate = 44100;

    //////        return new float[0];

    //////    }

    //////    public static void SaveWav(string path, float[] samples, int sampleRate, int channels)

    //////    {

    //////        int bitsPerSample = 16;

    //////        int byteRate = sampleRate * channels * bitsPerSample / 8;

    //////        int blockAlign = channels * bitsPerSample / 8;

    //////        int dataSize = samples.Length * 2;

    //////        using (BinaryWriter bw = new BinaryWriter(File.Create(path)))

    //////        {

    //////            bw.Write(Encoding.ASCII.GetBytes("RIFF"));

    //////            bw.Write(36 + dataSize);

    //////            bw.Write(Encoding.ASCII.GetBytes("WAVE"));

    //////            bw.Write(Encoding.ASCII.GetBytes("fmt "));

    //////            bw.Write(16);

    //////            bw.Write((short)1);

    //////            bw.Write((short)channels);

    //////            bw.Write(sampleRate);

    //////            bw.Write(byteRate);

    //////            bw.Write((short)blockAlign);

    //////            bw.Write((short)bitsPerSample);

    //////            bw.Write(Encoding.ASCII.GetBytes("data"));

    //////            bw.Write(dataSize);

    //////            foreach (float sample in samples)

    //////            {

    //////                short s = (short)(sample * 32767);

    //////                bw.Write(s);

    //////            }

    //////        }

    //////    }

    //////    public static float[] StretchToLength(float[] input, int targetLength)

    //////    {

    //////        return ResampleWithFactor(input, targetLength);

    //////    }

    //////}//public class PAN_WITH_FREQUENCY_CHANGES_44100_SPS_2_CHANNELS___NEW_KIND_OF_ShrutiResamplerGenerator___33_PLUS_33_66_COPIES_PLAYING_ALL_SAMPLES___GPT

    public class ShrutiResampler___Revised_GPT_NEW_KIND_OF_ShrutiResamplerGenerator___33_PLUS_33_66_COPIES_PLAYING_ALL_SAMPLES___GPT

    {

        public static void GenerateShrutiVariants___GPT___YESSSSSS_PROPER_66_ShrutiResampler___66_DIFFERENT_FREQUENCIES_NO_TRUNCATIONS(string inputWavPath, string outputWavPath)

        {

            float[] sourceSamples = ReadWavMonoAsFloats(inputWavPath, out int sourceRate);

            int outputRate = 8000;

            double originalFrequency = 440.0; // Assume input sample is A4 (for calculation)

            double durationSec = sourceSamples.Length / (double)sourceRate;

            double totalCycleProduct = originalFrequency * durationSec;

            List<float> allVariants = new List<float>();

            for (int i = -33; i <= 32; i++) // 66 shrutis: -33 to +32

            {

                double semitoneShift = i * (1.0 / 3);

                double freqMultiplier = Math.Pow(2, semitoneShift / 12.0);

                double newFreq = originalFrequency * freqMultiplier;

                double newDuration = totalCycleProduct / newFreq;

                int newSampleCount = (int)(newDuration * outputRate);

                float[] pitchShifted = ResampleWithFactor(sourceSamples, newSampleCount);

                allVariants.AddRange(pitchShifted);

            }

            SaveWav(outputWavPath, allVariants.ToArray(), outputRate, 1);

            Console.WriteLine("66 shruti-pitched variants generated with frequency-duration relationship preserved.");

            MessageBox.Show("Generated 66 shruti-pitched variants: \n" + outputWavPath);

        }

        public static float[] ResampleWithFactor(float[] input, int targetLength)

        {

            float[] result = new float[targetLength];

            double step = (double)(input.Length - 1) / (targetLength - 1);

            for (int i = 0; i < targetLength; i++)

            {

                double pos = i * step;

                int idx = (int)pos;

                double frac = pos - idx;

                result[i] = (idx + 1 < input.Length)

                    ? (float)((1 - frac) * input[idx] + frac * input[idx + 1])

                    : input[idx];

            }

            return result;

        }

        public static float[] ReadWavMonoAsFloats(string path, out int sampleRate)

        {

            using (BinaryReader br = new BinaryReader(File.OpenRead(path)))

            {

                br.BaseStream.Seek(0, SeekOrigin.Begin);

                br.ReadBytes(12);

                int channels = 1;

                sampleRate = 8000;

                int bitsPerSample = 16;

                while (br.BaseStream.Position < br.BaseStream.Length)

                {

                    string chunkID = new string(br.ReadChars(4));

                    int chunkSize = br.ReadInt32();

                    if (chunkID == "fmt ")

                    {

                        br.ReadInt16();

                        channels = br.ReadInt16();

                        sampleRate = br.ReadInt32();

                        br.ReadInt32();

                        br.ReadInt16();

                        bitsPerSample = br.ReadInt16();

                        if (chunkSize > 16)

                            br.ReadBytes(chunkSize - 16);

                    }

                    else if (chunkID == "data")

                    {

                        int bytesPerSample = bitsPerSample / 8;

                        int totalSamples = chunkSize / bytesPerSample;

                        float[] samples = new float[totalSamples / channels];

                        for (int i = 0, j = 0; i < totalSamples; i++)

                        {

                            short sample = br.ReadInt16();

                            if (channels == 1 || i % channels == 0)

                                samples[j++] = sample / 32768f;

                            if (channels == 2) br.ReadInt16();

                        }

                        return samples;

                    }

                    else

                    {

                        br.ReadBytes(chunkSize);

                    }

                }

            }

            sampleRate = 8000;

            return new float[0];

        }

        public static void SaveWav(string path, float[] samples, int sampleRate, int channels)

        {

            int bitsPerSample = 16;

            int byteRate = sampleRate * channels * bitsPerSample / 8;

            int blockAlign = channels * bitsPerSample / 8;

            int dataSize = samples.Length * channels * 2;

            using (BinaryWriter bw = new BinaryWriter(File.Create(path)))

            {

                bw.Write(Encoding.ASCII.GetBytes("RIFF"));

                bw.Write(36 + dataSize);

                bw.Write(Encoding.ASCII.GetBytes("WAVE"));

                bw.Write(Encoding.ASCII.GetBytes("fmt "));

                bw.Write(16);

                bw.Write((short)1);

                bw.Write((short)channels);

                bw.Write(sampleRate);

                bw.Write(byteRate);

                bw.Write((short)blockAlign);

                bw.Write((short)bitsPerSample);

                bw.Write(Encoding.ASCII.GetBytes("data"));

                bw.Write(dataSize);

                foreach (float sample in samples)

                {

                    short s = (short)(sample * 32767);

                    for (int c = 0; c < channels; c++)

                        bw.Write(s);

                }

            }

        }

        public static float[] StretchToLength(float[] input, int targetLength)

        {

            return ResampleWithFactor(input, targetLength);

        }

    }//public class ShrutiResampler___Revised_GPT_NEW_KIND_OF_ShrutiResamplerGenerator___33_PLUS_33_66_COPIES_PLAYING_ALL_SAMPLES___GPT

    /////////////////////////////////////////////////////////////////////////////////////

    public class NEW_KIND_OF_ShrutiResamplerGenerator___33_PLUS_33_66_COPIES_PLAYING_ALL_SAMPLES___GPT

    {

        public static void GenerateShrutiVariants___GPT(string inputWavPath, string outputWavPath)

        {

            float[] sourceSamples = ReadWavMonoAsFloats(inputWavPath, out int sourceRate);

            int outputRate = 8000;

            double durationSec = sourceSamples.Length / (double)sourceRate;

            int targetSamplesPerVariant = (int)(durationSec * outputRate);

            List<float> allVariants = new List<float>();

            for (int i = -33; i <= 32; i++) // 66 shrutis: -33 to +32

            {

                double semitoneShift = i * (1.0 / 3); // 22 shrutis per octave

                double resampleFactor = Math.Pow(2, semitoneShift / 12.0);

                int resampledLength = (int)(sourceSamples.Length / resampleFactor);

                float[] pitchShifted = ResampleWithFactor(sourceSamples, resampledLength);

                float[] durationMatched = StretchToLength(pitchShifted, targetSamplesPerVariant);

                allVariants.AddRange(durationMatched);

            }//for (int i = -33; i <= 32; i++) // 66 shrutis: -33 to +32

            SaveWav(outputWavPath, allVariants.ToArray(), outputRate, 1);

            Console.WriteLine("66 shruti-pitched variants generated.");

            MessageBox.Show("Generated 66 shruti-pitched variants: \n" + outputWavPath);

        }//public static void GenerateShrutiVariants(string inputWavPath, string outputWavPath)

        public static float[] ResampleWithFactor(float[] input, int targetLength)

        {

            // after doing this all the samples are getting same durations and same frequencies exact copies

            // we know when the frequency changes then the duration for the sample also change because the total samples are fixed

            // we need the resampling logic to change    Total_Frequency * Total_Duration = fixed   which means          F1*T1 = F2*T2=Sample_Count fixed

            // We need the sample count to vary as per necessary conditions and interpolate the samples (as required) in the 66 copies of samples in same file where these copies are all having different frequencies and different durations     because the frequencies in every copy and durations are also changing in every copy but all the copies are on same file (the output file has same sample rate 8000 samples per second while playing the ear will listen different frequencies for different copies 

            //all copies are changing the frequencies and durations so all copies dont have same number of samples now after resampling     but the  current program is not doing that (current program is doing the resampling for frequency and then resetting that  to fixed durations and so the whole effect nullifies at the end of double transformations)

            // say the original sample has n1 samples s1 samples per second f1 frequency T1 duration then the next copy will have n2 samples f2 frequency T2 time s2 samples per second and the total things are stored in a single file with fixed samples per second so we need proper calculations for these readjustments but different number of samples but whole 

            float[] result = new float[targetLength];

            double step = (double)(input.Length - 1) / (targetLength - 1);

            for (int i = 0; i < targetLength; i++)

            {

                double pos = i * step;

                int idx = (int)pos;

                double frac = pos - idx;

                result[i] = (idx + 1 < input.Length)

                    ? (float)((1 - frac) * input[idx] + frac * input[idx + 1])

                    : input[idx];

            }//for (int i = 0; i < targetLength; i++)

            return result;

        }//public static float[] ResampleWithFactor(float[] input, int targetLength)

        public static float[] ReadWavMonoAsFloats(string path, out int sampleRate)

        {

            using (BinaryReader br = new BinaryReader(File.OpenRead(path)))

            {

                br.BaseStream.Seek(0, SeekOrigin.Begin);

                br.ReadBytes(12); // Skip RIFF header

                int channels = 1;

                sampleRate = 8000;

                int bitsPerSample = 16;

                while (br.BaseStream.Position < br.BaseStream.Length)

                {

                    string chunkID = new string(br.ReadChars(4));

                    int chunkSize = br.ReadInt32();

                    if (chunkID == "fmt ")

                    {

                        br.ReadInt16(); // audio format

                        channels = br.ReadInt16();

                        sampleRate = br.ReadInt32();

                        br.ReadInt32(); // byte rate

                        br.ReadInt16(); // block align

                        bitsPerSample = br.ReadInt16();

                        if (chunkSize > 16)

                            br.ReadBytes(chunkSize - 16);

                    }

                    else if (chunkID == "data")

                    {

                        int bytesPerSample = bitsPerSample / 8;

                        int totalSamples = chunkSize / bytesPerSample;

                        float[] samples = new float[totalSamples / channels];

                        for (int i = 0, j = 0; i < totalSamples; i++)

                        {

                            short sample = br.ReadInt16();

                            if (channels == 1 || i % channels == 0)

                                samples[j++] = sample / 32768f;

                            if (channels == 2) br.ReadInt16();

                        }

                        return samples;

                    }

                    else

                    {

                        br.ReadBytes(chunkSize);

                    }

                }//while (br.BaseStream.Position < br.BaseStream.Length)

            }//using (BinaryReader br = new BinaryReader(File.OpenRead(path)))

            sampleRate = 8000;

            return new float[0];

        }//public static float[] ReadWavMonoAsFloats(string path, out int sampleRate)

        public static void SaveWav(string path, float[] samples, int sampleRate, int channels)

        {

            int bitsPerSample = 16;

            int byteRate = sampleRate * channels * bitsPerSample / 8;

            int blockAlign = channels * bitsPerSample / 8;

            int dataSize = samples.Length * channels * 2;

            using (BinaryWriter bw = new BinaryWriter(File.Create(path)))

            {

                bw.Write(Encoding.ASCII.GetBytes("RIFF"));

                bw.Write(36 + dataSize);

                bw.Write(Encoding.ASCII.GetBytes("WAVE"));

                bw.Write(Encoding.ASCII.GetBytes("fmt "));

                bw.Write(16);

                bw.Write((short)1);

                bw.Write((short)channels);

                bw.Write(sampleRate);

                bw.Write(byteRate);

                bw.Write((short)blockAlign);

                bw.Write((short)bitsPerSample);

                bw.Write(Encoding.ASCII.GetBytes("data"));

                bw.Write(dataSize);

                foreach (float sample in samples)

                {

                    short s = (short)(sample * 32767);

                    for (int c = 0; c < channels; c++)

                        bw.Write(s);

                }

            }

        }//public static void SaveWav(string path, float[] samples, int sampleRate, int channels)

        public static float[] StretchToLength(float[] input, int targetLength)

        {

            return ResampleWithFactor(input, targetLength);

        }//public static float[] StretchToLength(float[] input, int targetLength)

    }//public class NEW_KIND_OF_ShrutiResamplerGenerator___33_PLUS_33_66_COPIES_PLAYING_ALL_SAMPLES

    /// <summary>

    /// //////////////////////////////////////////////////////////////////////////////////////////

    /// </summary>

    public class SwaralipiConcatenator_ResampleAware

    {

        public static void SwaralipiConcatenator___Main(string swaralipiFile)

        {

            int durationMs = 220;//default

            string wavFolder = Path.GetDirectoryName(swaralipiFile);

            int outputSampleRate = 8000;

            string outputStereo = swaralipiFile + "_(yesssss)_merged_trimmed_RESAMPLED_8000_stereo.wav";

            string outputMono = swaralipiFile + "_(yesssss)_merged_trimmed_RESAMPLED_8000_mono.wav";

            var lines = File.ReadAllLines(swaralipiFile)

                            .Where(l => !string.IsNullOrWhiteSpace(l)).ToList();

            var allSegments = new List<float>();

            foreach (var line in lines)

            {

                var parts = line.Split(new[] { ' ', '\t', ',' }, StringSplitOptions.RemoveEmptyEntries);

                if (parts.Length < 2) { durationMs = 220;  continue; }

                string symbol = parts[0].Trim()

                                      .Replace(".", "_DOT_")

                                      .Replace("-", "dash")

                                      .Replace("#", "hash");

                //    if (!int.TryParse(parts[1], out int durationMs)) continue;

                if (!int.TryParse(parts[1], out durationMs)) { continue; }

                if(durationMs==0)

                {

                    durationMs = 220;//default

                }//if(durationMs==0)

                string wavPath = Path.Combine(wavFolder, symbol + ".wav");

                float[] originalSamples = ReadWavMonoAsFloats(wavPath, out int originalSampleRate);

                // Step 1: Resample from originalSampleRate → outputSampleRate

                float[] resampled = ResampleToRate(originalSamples, originalSampleRate, outputSampleRate);

                // Step 2: Extract only as many samples as needed for desired duration

                int neededSamples = (int)((durationMs / 1000.0) * outputSampleRate);

                neededSamples = Math.Min(neededSamples, resampled.Length);

                float[] trimmed = new float[neededSamples];

                Array.Copy(resampled, trimmed, neededSamples);

                allSegments.AddRange(trimmed);

            }// foreach (var line in lines)

            float[] final = allSegments.ToArray();

            SaveWav(outputStereo, final, outputSampleRate, 2);

            SaveWav(outputMono, final, outputSampleRate, 1);

            Console.WriteLine("Done writing merged WAV with preserved pitches.");

            System.Windows.Forms.MessageBox.Show("Done writing WAV:\n" + outputStereo + "\n" + outputMono);

        }//public static void SwaralipiConcatenator___Main(string swaralipiFile)

        public static float[] ResampleToRate(float[] input, int fromRate, int toRate)

        {

            if (fromRate == toRate) return input;

            int newLength = (int)(input.Length * (toRate / (double)fromRate));

            float[] result = new float[newLength];

            Array.Clear(result, 0, result.Length);

            double step = (double)(input.Length - 1) / (newLength - 1);

            for (int i = 0; i < newLength; i++)

            {

                double idx = i * step;

                int index = (int)idx;

                double frac = idx - index;

                float interpolated = (  (index + 1) < input.Length)

                    ? (float)((1 - frac) * input[index] + frac * input[index + 1])

                    : input[index];

                result[i] = interpolated;

            }//for (int i = 0; i < newLength; i++)

            return result;

        }// public static float[] ResampleToRate(float[] input, int fromRate, int toRate)

        static float[] ReadWavMonoAsFloats(string path, out int sampleRate)

        {

            using (BinaryReader br = new BinaryReader(File.OpenRead(path)))

            {

                string riff = new string(br.ReadChars(4));

                br.ReadInt32();

                string wave = new string(br.ReadChars(4));

                int channels = 1;

                sampleRate = 8000;

                int bitsPerSample = 16;

                while (true)

                {

                    string chunkID = new string(br.ReadChars(4));

                    int chunkSize = br.ReadInt32();

                    if (chunkID == "fmt ")

                    {

                        br.ReadInt16(); // format

                        channels = br.ReadInt16();

                        sampleRate = br.ReadInt32();

                        br.ReadInt32();

                        br.ReadInt16();

                        bitsPerSample = br.ReadInt16();

                        if (chunkSize > 16) br.ReadBytes(chunkSize - 16);

                        break;

                    }

                    else br.ReadBytes(chunkSize);

                }// while (true)

                while (true)

                {

                    string chunkID = new string(br.ReadChars(4));

                    int chunkSize = br.ReadInt32();

                    if (chunkID == "data")

                    {

                        int bytesPerSample = bitsPerSample / 8;

                        int totalSamples = chunkSize / bytesPerSample;

                        float[] samples = new float[totalSamples / channels];

                        for (int i = 0, j = 0; i < totalSamples; i++)

                        {

                            short s = br.ReadInt16();

                            if (channels == 1 || (i % channels == 0))

                                samples[j++] = s / 32768f;

                            if (channels == 2) br.ReadInt16(); // skip right

                        }// for (int i = 0, j = 0; i < totalSamples; i++)

                        return samples;

                    }

                    else br.ReadBytes(chunkSize);

                }// while (true)

            }// using (BinaryReader br = new BinaryReader(File.OpenRead(path)))

        }//static float[] ReadWavMonoAsFloats(string path, out int sampleRate)

        //need to try to implement this also

        public static float[] ResampleWithPitchBend

        (

            float[] input, int fromRate, int toRate, int targetLength, double bendSemitones

            )

        {

            float[] output = new float[targetLength];

            // Compute shift range

            double shiftStart = 1.0;

            double shiftEnd = Math.Pow(2, bendSemitones / 12.0);

            // Resample with time-varying rate

            double inputPos = 0.0;

            for (int i = 0; i < targetLength; i++)

            {

                double t = i / (double)(targetLength - 1); // [0,1]

                double currentShift = shiftStart + t * (shiftEnd - shiftStart);

                double step = (fromRate * currentShift) / toRate;

                int idx = (int)inputPos;

                double frac = inputPos - idx;

                float sample = 0;

                if (idx + 1 < input.Length)

                    sample = (float)((1 - frac) * input[idx] + frac * input[idx + 1]);

                else if (idx < input.Length)

                    sample = input[idx];

                output[i] = sample;

                inputPos += step;

                if (inputPos >= input.Length - 1) break; // stop if overshoot

            }//for (int i = 0; i < targetLength; i++)

            return output;

        }// public static float[] ResampleWithPitchBend

        static void SaveWav(string path, float[] samples, int sampleRate, int channels)

        {

            int bitsPerSample = 16;

            int byteRate = sampleRate * channels * bitsPerSample / 8;

            int blockAlign = channels * bitsPerSample / 8;

            int dataSize = samples.Length * channels * 2;

            using (BinaryWriter bw = new BinaryWriter(File.Create(path)))

            {

                bw.Write(Encoding.ASCII.GetBytes("RIFF"));

                bw.Write(36 + dataSize);

                bw.Write(Encoding.ASCII.GetBytes("WAVE"));

                bw.Write(Encoding.ASCII.GetBytes("fmt "));

                bw.Write(16);

                bw.Write((short)1);

                bw.Write((short)channels);

                bw.Write(sampleRate);

                bw.Write(byteRate);

                bw.Write((short)blockAlign);

                bw.Write((short)bitsPerSample);

                bw.Write(Encoding.ASCII.GetBytes("data"));

                bw.Write(dataSize);

                foreach (float sample in samples)

                {

                    short s = (short)(sample * 32767);

                    for (int c = 0; c < channels; c++) bw.Write(s);

                }//foreach (float sample in samples)

            }// using (BinaryWriter bw = new BinaryWriter(File.Create(path)))

        }// static void SaveWav(string path, float[] samples, int sampleRate, int channels)

    }// public class SwaralipiConcatenator_ResampleAware

    /// <summary>

    /// ////////////////////////////////////////// the above resampler code looks like it is working properly

    /// </summary>

    public class SwaralipiConcatenator_DurationAware

    {

        public static void SwaralipiConcatenator___Main(string swaralipiFile)

        {

            string wavFolder = Path.GetDirectoryName(swaralipiFile);

            string outputStereo = swaralipiFile + "_(durationwise)_NOT_GOOD_output_8000_stereo.wav"; ;// "_output_44100_stereo.wav";

            string outputMono = swaralipiFile + "_(durationwise)_NOT_GOOD_output_8000_mono.wav";

            var lines = File.ReadAllLines(swaralipiFile)

                            .Where(l => !string.IsNullOrWhiteSpace(l)).ToList();

            var allSegments = new List<float>();

            foreach (var line in lines)

            {

                int durationMs = 220;

                var parts = line.Split(new[] { ' ', '\t', ',' }, StringSplitOptions.RemoveEmptyEntries);

                if (parts.Length < 2) { durationMs = 220; continue; }

                string symbol = parts[0].Trim();

               // if (!int.TryParse(parts[1], out int durationMs)) continue;

                if (!int.TryParse(parts[1], out durationMs)) continue;

                symbol = symbol.Replace(".", "_DOT_").Replace("-", "dash").Replace("#", "hash");

                //.Replace("#", "hash").Replace(".", "_DOT_");

                string wavPath = Path.Combine(wavFolder, symbol + ".wav");

                float[] fullSamples = { };

                Array.Clear(fullSamples, 0, fullSamples.Length);

                fullSamples = ReadWavMonoAsFloats(wavPath, out int sampleRate);

                int requiredSamples = (int)((durationMs / 1000.0) * sampleRate);

                requiredSamples = Math.Min(requiredSamples, fullSamples.Length);

                float[] trimmed = new float[requiredSamples];

                Array.Copy(fullSamples, trimmed, requiredSamples);

                allSegments.AddRange(trimmed);

            }

            float[] final = allSegments.ToArray();

            SaveWav(outputStereo, final, 44100, 2);

            SaveWav(outputStereo, final, 8000, 2);

            SaveWav(outputMono, final, 8000, 1);

            Console.WriteLine("WAVs written with trimmed durations.");

            System.Windows.Forms.MessageBox.Show("Done writing WAVs with duration control:\n" + outputStereo + "\n" + outputMono);

        }

        static float[] ReadWavMonoAsFloats(string path, out int sampleRate)

        {

            using (BinaryReader br = new BinaryReader(File.OpenRead(path)))

            {

                string riff = new string(br.ReadChars(4));

                br.ReadInt32();

                string wave = new string(br.ReadChars(4));

                int channels = 1;

                sampleRate = 8000;// 44100;

                int bitsPerSample = 16;

                while (true)

                {

                    string chunkID = new string(br.ReadChars(4));

                    int chunkSize = br.ReadInt32();

                    if (chunkID == "fmt ")

                    {

                        br.ReadInt16(); // format

                        channels = br.ReadInt16();

                        sampleRate = br.ReadInt32();

                        br.ReadInt32(); // byte rate

                        br.ReadInt16(); // block align

                        bitsPerSample = br.ReadInt16();

                        if (chunkSize > 16) br.ReadBytes(chunkSize - 16);

                        break;

                    }

                    else

                    {

                        br.ReadBytes(chunkSize);

                    }

                }

                while (true)

                {

                    string chunkID = new string(br.ReadChars(4));

                    int chunkSize = br.ReadInt32();

                    if (chunkID == "data")

                    {

                        int bytesPerSample = bitsPerSample / 8;

                        int totalSamples = chunkSize / bytesPerSample;

                        float[] samples = { };

                        samples =

                            new float[totalSamples / channels];

                        Array.Clear(samples, 0, samples.Length);

                        for (int i = 0, j = 0; i < totalSamples; i++)

                        {

                            short sample = br.ReadInt16();

                            if (channels == 1 || (i % channels == 0))

                                samples[j++] = sample / 32768f;

                            if (channels == 2) br.ReadInt16(); // skip R

                        }

                        return samples;

                    }

                    else

                    {

                        br.ReadBytes(chunkSize);

                    }

                }

            }

        }

        static void SaveWav(string path, float[] samples, int sampleRate, int channels)

        {

            int bitsPerSample = 16;

            int byteRate = sampleRate * channels * bitsPerSample / 8;

            int blockAlign = channels * bitsPerSample / 8;

            int dataSize = samples.Length * channels * 2;

            using (BinaryWriter bw = new BinaryWriter(File.Create(path)))

            {

                bw.Write(Encoding.ASCII.GetBytes("RIFF"));

                bw.Write(36 + dataSize);

                bw.Write(Encoding.ASCII.GetBytes("WAVE"));

                bw.Write(Encoding.ASCII.GetBytes("fmt "));

                bw.Write(16);

                bw.Write((short)1);

                bw.Write((short)channels);

                bw.Write(sampleRate);

                bw.Write(byteRate);

                bw.Write((short)blockAlign);

                bw.Write((short)bitsPerSample);

                bw.Write(Encoding.ASCII.GetBytes("data"));

                bw.Write(dataSize);

                foreach (float sample in samples)

                {

                    short s = (short)(sample * 32767);

                    for (int c = 0; c < channels; c++)

                    {

                        bw.Write(s);

                    }//for (int c = 0; c < channels; c++)

                }//foreach (float sample in samples)

            }//using (BinaryWriter bw = new BinaryWriter(File.Create(path)))

        }

    }

    /// <summary>

    /// //////////////////////////////////////////////////////////////////////////////////////////////////

    /// </summary>

    public class SwaralipiConcatenator___all_same_durations

    {

        public static void SwaralipiConcatenator___Main(string swaralipifile)

        {

            string swaralipiFile = swaralipifile;// "swaralipi.txt"; // path to your text file

            string wavFolder 

                //= string folderPath =

                =Path.GetDirectoryName(swaralipifile); ;// "."; // directory containing all the 66 wavs

            string outputStereo = swaralipiFile + "_all_sames_durs_NOT_GOOD_output_8000_stereo.wav";// "_output_44100_stereo.wav";

            string outputMono = swaralipiFile + "_all_sames_durs_NOT_GOOD_output_8000_mono.wav";

            var symbols = File.ReadAllLines(swaralipiFile).Where(l => !string.IsNullOrWhiteSpace(l)).ToList();

            var allSamples = new List<float[]>();

            int maxSamples = 0;

            // Step 1: Load all WAVs and store sample data

            foreach (var symbol in symbols)

            {

                // var parts = line.Split(new[] { ' ', '\t', ',' }, StringSplitOptions.RemoveEmptyEntries);

                string[] splitted_durations_notes= symbol.Split(new[] { ' ', '\t', ',' }, StringSplitOptions.RemoveEmptyEntries);

               // splitted_durations_notes

                string newsymbol = splitted_durations_notes[0].Replace(".", "_DOT_").Replace("-", "dash").Replace("#", "hash");

                //   string wavPath = Path.Combine(wavFolder, $"{symbol}.wav");

                string wavPath = "";

                wavPath= Path.Combine(wavFolder, $"{newsymbol}.wav");

                // List<float> samples = new List<float>();// null;

                float[] samples = { };// new List<float>();// null;

                //samples.Clear();

                Array.Clear(samples, 0, samples.Length);

                samples

                    =

                    ReadWavMonoAsFloats(wavPath, out int sourceRate);

                if (samples.Length > maxSamples) maxSamples = samples.Length;

                allSamples.Add(samples);

            }//foreach (var symbol in symbols)

            // Step 2: Resample all to maxSamples length

            var normalized = allSamples.Select(s => StretchToLength(s, maxSamples)).ToList();

            // Step 3: Concatenate all

            var finalFloat = normalized.SelectMany(s => s).ToList();

            // Step 4a: Save as 44100Hz stereo

            //  SaveWav(outputStereo+"_output_44100_stereo.wav", finalFloat.ToArray(), 44100, 2);

            SaveWav(outputStereo + "_output_8000_stereo.wav", finalFloat.ToArray(), 8000, 2);

            //SwaralipiConcatenator___all_same_durations

            // Step 4b: Save as 8000Hz mono

            SaveWav(outputMono+"_output_8000_mono.wav", finalFloat.ToArray(), 8000, 1);

            Console.WriteLine("Done writing output WAVs.");

            System.Windows.Forms.MessageBox.Show("Done writing output WAVs." + outputStereo +"   " + outputMono);

        }//public static void SwaralipiConcatenator___Main(string swaralipifile)

        static float[] ReadWavMonoAsFloats(string path, out int sampleRate)

        {

            using (BinaryReader br = new BinaryReader(File.OpenRead(path)))

            {

                string riff = new string(br.ReadChars(4));

                br.ReadInt32(); // file size

                string wave = new string(br.ReadChars(4));

                int channels = 1;

                sampleRate = 8000;// 44100;

                int bitsPerSample = 16;

                // Read fmt chunk

                while (true)

                {

                    string chunkID = new string(br.ReadChars(4));

                    int chunkSize = br.ReadInt32();

                    if (chunkID == "fmt ")

                    {

                        br.ReadInt16(); // audio format

                        channels = br.ReadInt16();

                        sampleRate = br.ReadInt32();

                        br.ReadInt32(); // byte rate

                        br.ReadInt16(); // block align

                        bitsPerSample = br.ReadInt16();

                        if (chunkSize > 16) br.ReadBytes(chunkSize - 16);

                        break;

                    }

                    else

                    {

                        br.ReadBytes(chunkSize); // skip unknown chunk

                    }

                }

                // Read data chunk

                while (true)

                {

                    string chunkID = new string(br.ReadChars(4));

                    int chunkSize = br.ReadInt32();

                    if (chunkID == "data")

                    {

                        int bytesPerSample = bitsPerSample / 8;

                        int totalSamples = chunkSize / bytesPerSample;

                        float[] samples = new float[totalSamples / channels];

                        for (int i = 0, j = 0; i < totalSamples; i++)

                        {

                            short sample = br.ReadInt16();

                            if (channels == 1 || (i % channels == 0))

                                samples[j++] = sample / 32768f;

                            if (channels == 2) br.ReadInt16(); // skip right channel

                        }

                        return samples;

                    }

                    else

                    {

                        br.ReadBytes(chunkSize); // skip unknown chunk

                    }

                }

            } // using BinaryReader

        }// static float[] ReadWavMonoAsFloats(string path, out int sampleRate)

        static float[] StretchToLength(float[] original, int targetLength)

        {

            float[] result = new float[targetLength];

            double step = (double)(original.Length - 1) / (targetLength - 1);

            for (int i = 0; i < targetLength; i++)

            {

                double index = i * step;

                int idx = (int)index;

                double frac = index - idx;

                result[i] = (idx + 1 < original.Length)

                    ? (float)((1 - frac) * original[idx] + frac * original[idx + 1])

                    : original[idx];

            }

            return result;

        }//static float[] StretchToLength(float[] original, int targetLength)

        static void SaveWav(string path, float[] samples, int sampleRate, int channels)

        {

            int bitsPerSample = 16;

            int byteRate = sampleRate * channels * bitsPerSample / 8;

            int blockAlign = channels * bitsPerSample / 8;

            int dataSize = samples.Length * channels * 2;

            using (BinaryWriter bw = new BinaryWriter(File.Create(path)))

            {

                // RIFF header

                bw.Write(Encoding.ASCII.GetBytes("RIFF"));

                bw.Write(36 + dataSize);

                bw.Write(Encoding.ASCII.GetBytes("WAVE"));

                // fmt chunk

                bw.Write(Encoding.ASCII.GetBytes("fmt "));

                bw.Write(16); // Subchunk1Size for PCM

                bw.Write((short)1); // Audio format = PCM

                bw.Write((short)channels);

                bw.Write(sampleRate);

                bw.Write(byteRate);

                bw.Write((short)blockAlign);

                bw.Write((short)bitsPerSample);

                // data chunk

                bw.Write(Encoding.ASCII.GetBytes("data"));

                bw.Write(dataSize);

                foreach (float sample in samples)

                {

                    short s = (short)(sample * 32767);

                    for (int c = 0; c < channels; c++)

                    {

                        bw.Write(s);

                    }

                }

            } // end using

        }//static void SaveWav(string path, float[] samples, int sampleRate, int channels)

    }//public class SwaralipiConcatenator

    public class CLUBBING_CONTINUOUS_SAME_NOTES_AND_DURATIONS___PitchMidiExtractor_YinLegacyCompatible

    {

        public static void ExtractNotes(string wavPath)

        {

            float[] samples = ReadWavMonoAsFloats(wavPath, out int sampleRate);

            double frameDurationMs = 10;

            int frameSize = (int)(sampleRate * frameDurationMs / 1000);

            List<double> freqs = YinDetect(samples, sampleRate, frameSize);

            using (StreamWriter sw = new StreamWriter(wavPath + ".SEPERATES_NON_CLUBBED_raw_notes.csv"))

            {

                sw.WriteLine("Time(ms),Freq,Note,Bend");

                for (int i = 0; i < freqs.Count; i++)

                {

                    double freq = freqs[i];

                    if (freq <= 0) continue;

                    int midiNote = (int)Math.Round(69 + 12 * Math.Log(freq / 440.0, 2));

                    double exactMidi = 69 + 12 * Math.Log(freq / 440.0, 2);

                    double pitchBend = exactMidi - midiNote;

                    double timeMs = i * frameDurationMs;

                    sw.WriteLine($"{timeMs:F1},{freq:F2},{midiNote},{pitchBend:F3}");

                }

            }

            using (StreamWriter sw = new StreamWriter(wavPath + ".SEPERATES_clubbed.csv"))

            {

                sw.WriteLine("Note,Start(ms),Duration(ms),PitchBend");

                int? prevNote = null;

                double prevTime = 0;

                double duration = 0;

                double bend = 0;

                for (int i = 0; i < freqs.Count; i++)

                {

                    double freq = freqs[i];

                    if (freq <= 0) continue;

                    int midiNote = (int)Math.Round(69 + 12 * Math.Log(freq / 440.0, 2));

                    double exactMidi = 69 + 12 * Math.Log(freq / 440.0, 2);

                    double pitchBend = exactMidi - midiNote;

                    double time = i * frameDurationMs;

                    if (prevNote == null)

                    {

                        prevNote = midiNote;

                        prevTime = time;

                        duration = frameDurationMs;

                        bend = pitchBend;

                    }

                    else if (prevNote == midiNote)

                    {

                        duration += frameDurationMs;

                    }

                    else

                    {

                        sw.WriteLine($"{prevNote},{prevTime:F1},{duration:F1},{bend:F3}");

                        prevNote = midiNote;

                        prevTime = time;

                        duration = frameDurationMs;

                        bend = pitchBend;

                    }

                }

                if (prevNote != null)

                    sw.WriteLine($"{prevNote},{prevTime:F1},{duration:F1},{bend:F3}");

            }

        }

        public static List<double> YinDetect(float[] samples, int sampleRate, int frameSize)

        {

            List<double> freqs = new List<double>();

            for (int i = 0; i + frameSize < samples.Length; i += frameSize)

            {

                double freq = DetectPitchYinFrame(samples, i, frameSize, sampleRate);

                freqs.Add(freq);

            }

            return freqs;

        }

        public static double DetectPitchYinFrame(float[] buffer, int start, int size, int sampleRate)

        {

            int tauMax = size / 2;

            double[] diff = new double[tauMax];

            for (int tau = 1; tau < tauMax; tau++)

            {

                double sum = 0;

                for (int i = 0; i < tauMax; i++)

                {

                    double d = buffer[start + i] - buffer[start + i + tau];

                    sum += d * d;

                }

                diff[tau] = sum;

            }

            double[] cmnd = new double[tauMax];

            cmnd[0] = 1;

            double runningSum = 0;

            for (int tau = 1; tau < tauMax; tau++)

            {

                runningSum += diff[tau];

                cmnd[tau] = diff[tau] / ((runningSum / tau) + 1e-6);

            }

            for (int tau = 2; tau < tauMax - 1; tau++)

            {

                if (cmnd[tau] < 0.1 && cmnd[tau] < cmnd[tau - 1] && cmnd[tau] <= cmnd[tau + 1])

                {

                    return sampleRate / (double)tau;

                }

            }

            return -1;

        }

        public static float[] ReadWavMonoAsFloats(string path, out int sampleRate)

        {

            using (var br = new BinaryReader(File.OpenRead(path)))

            {

                br.BaseStream.Seek(0, SeekOrigin.Begin);

                br.ReadBytes(12);

                int channels = 1;

                sampleRate = 44100;

                int bitsPerSample = 16;

                while (br.BaseStream.Position < br.BaseStream.Length)

                {

                    string chunkID = new string(br.ReadChars(4));

                    int chunkSize = br.ReadInt32();

                    if (chunkID == "fmt ")

                    {

                        br.ReadInt16();

                        channels = br.ReadInt16();

                        sampleRate = br.ReadInt32();

                        br.ReadInt32();

                        br.ReadInt16();

                        bitsPerSample = br.ReadInt16();

                        if (chunkSize > 16) br.ReadBytes(chunkSize - 16);

                    }

                    else if (chunkID == "data")

                    {

                        int bytesPerSample = bitsPerSample / 8;

                        int totalSamples = chunkSize / bytesPerSample;

                        float[] samples = new float[totalSamples / channels];

                        for (int i = 0, j = 0; i < totalSamples; i++)

                        {

                            short sample = br.ReadInt16();

                            if (channels == 1 || i % channels == 0)

                                samples[j++] = sample / 32768f;

                            if (channels == 2) br.ReadInt16();

                        }

                        return samples;

                    }

                    else

                    {

                        br.ReadBytes(chunkSize);

                    }

                }

            }

            sampleRate = 44100;

            return new float[0];

        }

    }//public class CLUBBING_CONTINUOUS_SAME_NOTES_AND_DURATIONS___PitchMidiExtractor_YinLegacyCompatible

    public class WAVS_TO_MIDS_DYNAMIK_THRESHOLDS_YinPitchDetector___from_wav_files_8000_samples_per_seconds_16_bitsdepth_pcm_riff_files

    {

        const int SampleRate = 8000;

        const int FrameSize = 1024;

        const int StepSize = 512;

        public static List<FrameStats> public_static___List_of___FrameStats__stats__pure_notes_nonzero_pitches = new List<FrameStats>();

        public static List<FrameStats> public_static___List_of___CLUBBED_CONTIGUOUS_NOTES___DURATIONS_SUMMED___FrameStats__stats__pure_notes_nonzero_pitches = new List<FrameStats>();

        public class FrameStats

        {

            public double TimeMs;

            public double RMS;

            public double MinCMND;

            public double Frequency;

            public double ThresholdUsed;

            public int midsnotesnum;

            public double durations_millis;

            public int velocity;

            public List<double> public_list_of_doubles_simples_durations_gaps_millis_for_for_pitchbends = new List<double>();

            public List<int> public_list_of_ints_0_8192_16384_vals_for_pitchbends = new List<int>();

            public List<double> public_list_of_percentages_of_doubles_simples_durations_gaps_0_to_100_for_for_pitchbends = new List<double>();

            public string leftsideof_slash_in_indinotes_found = "";

            public bool ALREADY_DONES_DURATIONS_CLUBBED_FOR_CONTINUOUS_SAMES_NOTES = false;

        }//public class FrameStats

        public static int FrequencyToMidiNote(double frequency)

        {

            if (frequency <= 0) return 0;

          //  return (int)Math.Round(69 + 12 * Math.Log(frequency / 440.0, 2));

           int note_number_found_from_the_nearest_frequency_Hertz

                =

             SAANAUDS.PUBLIC_STATIC_CLASS_TO_GENERATE_CSVMIDI_LIKE_SAANDATA

          // . PUBLIC_STATIC_STRING_ARRAY_FOR_SAAN_NOTES_MAPPER

          //  .public_static_global_list______ACCUMULATED_AFTER_ALL_DATA_READING_DONE___INSIDE___FUNCTION___SAAN_Log_tracks_channels_events_______BETTER_SCALES____STILL___NOT_GETTING_PROPER_PATCH_NUMBERS___SAAN_CLASS_FOR_MIDI_DATA_TO_LINE_SEGMENT_DATA_HOLDING

          //  .public_static_int_get_note_number_from_frequency_Hertz

          .public_static_int_get_note_number_from_frequency_Hertz

                (

                frequency

                );

            return note_number_found_from_the_nearest_frequency_Hertz;

        }// public static int FrequencyToMidiNote(double frequency)

        public static void ToProcess_with___inPitchDetector___from_wav_files_8000_samples_per_seconds_16_bitsdepth_pcm_riff_files___Main(string wav_filename)

        {

             ////string _returned_notes_number_string 

             ////   =

//////         SAANS_ROUGH_BEATS_COMPOSER_FOR_ON_SELECTIONS_LOOP_CYCLES

//////.PUBLIC_STATIC_CLASS_TO_PRELISTEN_HANDLING

//////.

//DO_POPULATE_INDIANIZED_NOTES___AND_RETURN_NOTENUMBER_FROM_THE_FILLED_NOTES_NAMES("");

            var samples = ReadWavFile(wav_filename);

            var frameStats = DetectPitchWithStats(samples);

            string csvPath = wav_filename + "_dynamik_thresholds_YinPitchDetector___Deep_Stats___csv";

            ExportDeepCsv(frameStats, csvPath);

            Console.WriteLine("Pitch + Stats saved to: " + csvPath);

            MessageBox.Show("Pitch + Stats saved to: " + csvPath);

        }//public static void ToProcess_with___inPitchDetector___from_wav_files_8000_samples_per_seconds_16_bitsdepth_pcm_riff_files___Main(string wav_filename)

        public static List<double> ReadWavFile(string filePath)

        {

            var samples = new List<double>();

            using (var reader = new BinaryReader(File.OpenRead(filePath)))

            {

                reader.BaseStream.Seek(44, SeekOrigin.Begin);

                while (reader.BaseStream.Position < reader.BaseStream.Length)

                {

                    short s = reader.ReadInt16();

                    samples.Add(s / 32768.0);

                }//while (reader.BaseStream.Position < reader.BaseStream.Length)

            }//using (var reader = new BinaryReader(File.OpenRead(filePath)))

            return samples;

        }//public static List<double> ReadWavFile(string filePath)

        public static List<FrameStats> DetectPitchWithStats(List<double> samples)

        {

            List<FrameStats> stats = new List<FrameStats>();

            stats.Clear();

            public_static___List_of___FrameStats__stats__pure_notes_nonzero_pitches.Clear();

            public_static___List_of___CLUBBED_CONTIGUOUS_NOTES___DURATIONS_SUMMED___FrameStats__stats__pure_notes_nonzero_pitches.Clear();

            for (int i = 0; i + FrameSize < samples.Count; i += StepSize)

            {

                double[] frame = samples.GetRange(i, FrameSize).ToArray();

                double rms = Math.Sqrt(frame.Sum(x => x * x) / frame.Length);

                double threshold = EstimateDynamicThreshold(rms);

                double pitch = YinWithStats(frame, SampleRate, threshold, out double minCMND);

                int notes_number = FrequencyToMidiNote(pitch);

                //CALLING CONVENTIONS   SAANS_ROUGH_BEATS_COMPOSER_FOR_ON_SELECTIONS_LOOP_CYCLES.PUBLIC_STATIC_CLASS_TO_PRELISTEN_HANDLING.___TEMP_STRING_INDIAN_NOTES_NAME___________PUBLIC_STATIC_STRING_FOR_GLOBAL_ACCESS

                //CALLING CONVENTIONS   SAANS_ROUGH_BEATS_COMPOSER_FOR_ON_SELECTIONS_LOOP_CYCLES.PUBLIC_STATIC_CLASS_TO_PRELISTEN_HANDLING.___TEMP_INT_INDIAN_NOTES_NUMBER___________PUBLIC_STATIC_INT_FOR_GLOBAL_ACCESS

                ///  THESE WILL GET FILLED  SAANS_ROUGH_BEATS_COMPOSER_FOR_ON_SELECTIONS_LOOP_CYCLES.PUBLIC_STATIC_CLASS_TO_PRELISTEN_HANDLING.___TEMP_STRING_INDIAN_NOTES_NAME___________PUBLIC_STATIC_STRING_FOR_GLOBAL_ACCESS = ___TEMP_STRING_INDIAN_NOTES_NAME;

                ///  THESE WILL GET FILLED   SAANS_ROUGH_BEATS_COMPOSER_FOR_ON_SELECTIONS_LOOP_CYCLES.PUBLIC_STATIC_CLASS_TO_PRELISTEN_HANDLING.___TEMP_INT_INDIAN_NOTES_NUMBER___________PUBLIC_STATIC_INT_FOR_GLOBAL_ACCESS = ___TEMP_INT_INDIAN_NOTES_NUMBER;

                string ___TEMP_STRING_INDIAN_NOTES_NAME

                    = SAANS_ROUGH_BEATS_COMPOSER_FOR_ON_SELECTIONS_LOOP_CYCLES.PUBLIC_STATIC_CLASS_TO_PRELISTEN_HANDLING.___TEMP_STRING_INDIAN_NOTES_NAME___________PUBLIC_STATIC_STRING_FOR_GLOBAL_ACCESS;

                int ___TEMP_INT_INDIAN_NOTES_NUMBER

                    = SAANS_ROUGH_BEATS_COMPOSER_FOR_ON_SELECTIONS_LOOP_CYCLES.PUBLIC_STATIC_CLASS_TO_PRELISTEN_HANDLING.___TEMP_INT_INDIAN_NOTES_NUMBER___________PUBLIC_STATIC_INT_FOR_GLOBAL_ACCESS;

                string filled_notes_name = "";

                string ___report_for_populations

                    =

                SAANS_ROUGH_BEATS_COMPOSER_FOR_ON_SELECTIONS_LOOP_CYCLES

                    .PUBLIC_STATIC_CLASS_TO_PRELISTEN_HANDLING

                   .PUBLIC_STATIC_STRING___return_NOTES_NUMBER_STRING_FROM_PRECONFIGURED_KEY_NAMES_TO_NUMBER______FROM___PUBLIC_STATIC_STRING_ARRAY_FOR_36_NOTES___50_X_3

                   (___TEMP_STRING_INDIAN_NOTES_NAME, ___TEMP_INT_INDIAN_NOTES_NUMBER, notes_number.ToString());//saan has changed this code with notes number checking also includes

                //////returned_note_number = ___report_for_populations;

                string found_leftsidepart_of_indinote_slash =

SAANS_ROUGH_BEATS_COMPOSER_FOR_ON_SELECTIONS_LOOP_CYCLES

.PUBLIC_STATIC_CLASS_TO_PRELISTEN_HANDLING

.

//PUBLIC_STATIC_STRING_GET_INDINOTESNAME_FIRST_OCCURANCES___from_____PUBLIC_STATIC_STRING_ARRAY_FOR_36_NOTES___50_X_3____FOR_GIVENS_MIDSNOTESNUMBER

PUBLIC_STATIC_STRING_GET_INDINOTESNAME_ONLY_LEFT_SIDES___FIRST_OCCURANCES___from_____PUBLIC_STATIC_STRING_ARRAY_FOR_36_NOTES___50_X_3____FOR_GIVENS_MIDSNOTESNUMBER

(notes_number);

                found_leftsidepart_of_indinote_slash

                    =

                    found_leftsidepart_of_indinote_slash

                    .Replace("-", "dash")

                    .Replace("(", "dhin")

                    .Replace(")", "dhoom")

                    ;

                if (pitch > 0)

                {

                    //to take care for the pitch>0 cases seperately

                    stats.Add

                            (new FrameStats

                            {

                                TimeMs = i * 1000.0 / SampleRate,

                                RMS = rms,

                                MinCMND = minCMND,

                                Frequency = pitch,

                                ThresholdUsed = threshold,

                                midsnotesnum = notes_number,

                                velocity = 127,

                                leftsideof_slash_in_indinotes_found = found_leftsidepart_of_indinote_slash

                            }

                            );

                }else

                {

                    try

                    {

                        stats.Last().velocity = 0;

                        /////////////////////////////////////////////////////////////////////////////////////

                    stats.Last()

                        .public_list_of_ints_0_8192_16384_vals_for_pitchbends

                        .Add

                        (

                             8192 + (int)((Math.Max(stats.Last().MinCMND, stats.Last().RMS)) * 16384)

                        );

                    //

                    stats.Last()

                        .public_list_of_doubles_simples_durations_gaps_millis_for_for_pitchbends

                        .Add

                        (

                        (i * 1000.0 / SampleRate) - (stats.Last().TimeMs)

                        );

                    }

                    catch (Exception ___excp_to_fill_pitchbends)

                    {

                    }//catch(Exception ___excp_to_fill_pitchbends)

                }//end of else of if (pitch > 0)

                if (pitch > 0)

                {

                    public_static___List_of___FrameStats__stats__pure_notes_nonzero_pitches

                        .Add

                        (new FrameStats

                        {

                            TimeMs = i * 1000.0 / SampleRate,

                            RMS = rms,

                            MinCMND = minCMND,

                            Frequency = pitch,

                            ThresholdUsed = threshold,

                            midsnotesnum = notes_number,

                            velocity=127,

                            leftsideof_slash_in_indinotes_found = found_leftsidepart_of_indinote_slash

                        }

                        );

                }// if(pitch > 0)

                else

                {

                    try

                    { 

                    public_static___List_of___FrameStats__stats__pure_notes_nonzero_pitches

                            .Last()

                        .public_list_of_ints_0_8192_16384_vals_for_pitchbends

                        .Add

                        (

                             8192 + (int)((Math.Max(stats.Last().MinCMND, stats.Last().RMS)) * 16384)

                        );

                    //

                    public_static___List_of___FrameStats__stats__pure_notes_nonzero_pitches

                        .Last()

                        .public_list_of_doubles_simples_durations_gaps_millis_for_for_pitchbends

                        .Add

                        (

                        (i * 1000.0 / SampleRate) - (stats.Last().TimeMs)

                        );

                    }

                    catch (Exception ___excp_to_fill_pitchbends)

                    {

                    }//catch(Exception ___excp_to_fill_pitchbends)

                }//end of else of if (pitch > 0)

            }//for (int i = 0; i + FrameSize < samples.Count; i += StepSize)

            //WE WILL NOW CLUB THE DURATIONS FOR CONTIGUOUS NOTES

            //////public_static___List_of___FrameStats__stats__pure_notes_nonzero_pitches.Reverse();

            //////for(int reversecrawler = 0; reversecrawler<public_static___List_of___FrameStats__stats__pure_notes_nonzero_pitches)

            //////public_static___List_of___CLUBBED_CONTIGUOUS_NOTES___DURATIONS_SUMMED___FrameStats__stats__pure_notes_nonzero_pitches

            //////    //DOING THE REVERSING AGAIN TO KEEP THAT STRAIGHT

            //////    public_static___List_of___FrameStats__stats__pure_notes_nonzero_pitches.Reverse();

            ///

            public_static___List_of___CLUBBED_CONTIGUOUS_NOTES___DURATIONS_SUMMED___FrameStats__stats__pure_notes_nonzero_pitches

                .

                Add

                (public_static___List_of___FrameStats__stats__pure_notes_nonzero_pitches.First());

            public_static___List_of___FrameStats__stats__pure_notes_nonzero_pitches.First()

                .ALREADY_DONES_DURATIONS_CLUBBED_FOR_CONTINUOUS_SAMES_NOTES = true;

            ///////////////////////////////////////////////////////////////////////////////////////////////////////

            for (int durations_clubbing_Crawler=1; durations_clubbing_Crawler< public_static___List_of___FrameStats__stats__pure_notes_nonzero_pitches.Count; durations_clubbing_Crawler++)

            {

                for(int lookforwardcrawler= durations_clubbing_Crawler+1; lookforwardcrawler< public_static___List_of___FrameStats__stats__pure_notes_nonzero_pitches.Count; lookforwardcrawler++)

                {

                        if

                        (

                            ( !

                            public_static___List_of___FrameStats__stats__pure_notes_nonzero_pitches

                            .ElementAt(lookforwardcrawler).ALREADY_DONES_DURATIONS_CLUBBED_FOR_CONTINUOUS_SAMES_NOTES

                            )

&&

public_static___List_of___FrameStats__stats__pure_notes_nonzero_pitches

.ElementAt(lookforwardcrawler).midsnotesnum

==

public_static___List_of___CLUBBED_CONTIGUOUS_NOTES___DURATIONS_SUMMED___FrameStats__stats__pure_notes_nonzero_pitches

.Last().midsnotesnum

                        )

                    {

                        public_static___List_of___CLUBBED_CONTIGUOUS_NOTES___DURATIONS_SUMMED___FrameStats__stats__pure_notes_nonzero_pitches

                            .Last()

                            .durations_millis

                            =

                        public_static___List_of___CLUBBED_CONTIGUOUS_NOTES___DURATIONS_SUMMED___FrameStats__stats__pure_notes_nonzero_pitches

                            .Last()

                            .durations_millis

                            +

                            public_static___List_of___FrameStats__stats__pure_notes_nonzero_pitches

                            .ElementAt(lookforwardcrawler)

                            .durations_millis;

                        /////////////////////////////////////////////////////////////////////////////////////

                        public_static___List_of___FrameStats__stats__pure_notes_nonzero_pitches

                            .ElementAt(lookforwardcrawler)

                            .ALREADY_DONES_DURATIONS_CLUBBED_FOR_CONTINUOUS_SAMES_NOTES

                            = true;

                    }

                        else

                    {

                        public_static___List_of___CLUBBED_CONTIGUOUS_NOTES___DURATIONS_SUMMED___FrameStats__stats__pure_notes_nonzero_pitches

                            .

                            Add

                            (

                        public_static___List_of___FrameStats__stats__pure_notes_nonzero_pitches

                            .ElementAt(lookforwardcrawler)

                            );

                        ///////////////////////////////////////////////////////////////////////////////////////////////

                        public_static___List_of___FrameStats__stats__pure_notes_nonzero_pitches

                            .ElementAt(lookforwardcrawler)

                            .ALREADY_DONES_DURATIONS_CLUBBED_FOR_CONTINUOUS_SAMES_NOTES

                            = true;

                        public_static___List_of___CLUBBED_CONTIGUOUS_NOTES___DURATIONS_SUMMED___FrameStats__stats__pure_notes_nonzero_pitches

                            .Last()

                            .TimeMs

                            =

                        public_static___List_of___FrameStats__stats__pure_notes_nonzero_pitches

                            .ElementAt(lookforwardcrawler)

                             .TimeMs;

                        durations_clubbing_Crawler = lookforwardcrawler;

                      //  goto gotohere_since_new_notes_number_found;

                    }/////////////////////////////// else case completes 

                }//for(int lookforwardcrawler= durations_clubbing_Crawler; lookforwardcrawler< public_static___List_of___FrameStats__stats__pure_notes_nonzero_pitches.Count; lookforwardcrawler++)

            gotohere_since_new_notes_number_found:;

            }//for(int durations_clubbing_Crawler=0; durations_clubbing_Crawler< public_static___List_of___FrameStats__stats__pure_notes_nonzero_pitches.Count; durations_clubbing_Crawler++)

            return stats;

        }//public static List<FrameStats> DetectPitchWithStats(List<double> samples)

        public static double EstimateDynamicThreshold(double rms)

        {

            if (rms < 0.02) return 0.30;

            if (rms < 0.05) return 0.20;

            return 0.10;

        }//public static double EstimateDynamicThreshold(double rms)

        public static double YinWithStats(double[] buffer, int sampleRate, double threshold, out double minCMND)

        {

            int tauMax = buffer.Length / 2;

            double[] difference = new double[tauMax];

            double[] cmnd = new double[tauMax];

            for (int tau = 1; tau < tauMax; tau++)

            {

                double sum = 0;

                for (int i = 0; i < tauMax; i++)

                {

                    double delta = buffer[i] - buffer[i + tau];

                    sum += delta * delta;

                }//for (int i = 0; i < tauMax; i++)

                difference[tau] = sum;

            }//for (int tau = 1; tau < tauMax; tau++)

            cmnd[0] = 1;

            double runningSum = 0;

            minCMND = 1.0;

            for (int tau = 1; tau < tauMax; tau++)

            {

                runningSum += difference[tau];

                cmnd[tau] = difference[tau] / ((runningSum / tau) + 1e-10);

                if (cmnd[tau] < minCMND) minCMND = cmnd[tau];

            }//for (int tau = 1; tau < tauMax; tau++)

            int tauEstimate = -1;

            for (int tau = 2; tau < tauMax; tau++)

            {

                if (cmnd[tau] < threshold)

                {

                    while (tau + 1 < tauMax && cmnd[tau + 1] < cmnd[tau])

                        tau++;

                    tauEstimate = tau;

                    break;

                }//if (cmnd[tau] < threshold)

            }//for (int tau = 2; tau < tauMax; tau++)

            if (tauEstimate != -1)

            {

                double betterTau = tauEstimate;

                if (tauEstimate > 0 && tauEstimate < tauMax - 1)

                {

                    double s0 = cmnd[tauEstimate - 1];

                    double s1 = cmnd[tauEstimate];

                    double s2 = cmnd[tauEstimate + 1];

                    betterTau = tauEstimate + (s2 - s0) / (2 * (2 * s1 - s2 - s0));

                }//if (tauEstimate > 0 && tauEstimate < tauMax - 1)

                return sampleRate / betterTau;

            }//if (tauEstimate != -1)

            return 0;

        }// public static double YinWithStats(double[] buffer, int sampleRate, double threshold, out double minCMND)

        public static void ExportDeepCsv(List<FrameStats> stats, string csvPath)

        {

            StringBuilder _strbldr = new StringBuilder();

            _strbldr.Clear();

            StringBuilder strbld______for_dot_dataGridView___COMPOSER = new StringBuilder();

            strbld______for_dot_dataGridView___COMPOSER.Clear();

            StringBuilder strbld______for_CLUBBED_DURATIONS___dot_dataGridView___COMPOSER = new StringBuilder();

            strbld______for_CLUBBED_DURATIONS___dot_dataGridView___COMPOSER.Clear();

            //////            LYRSYLLS   ######      INDINOTES   ######      TRYS_NOTES_NOS   ######      MILLISECOND   ######      CURR_NOTES_VELOCITY   ######      CURR_NOTES_PATCH   ######      PERCENTAGES_DURATIONS_COMMASEPS_PTCHBNDS   ######      WITHIN_NOTES_PTCHBENDS_VALUES   ######      CHANNEL   ######      TRACK   ######      NOTES_NUMBERS   ######      NOTES_FREQUENCYS   ######      JERK_MILLIS_GAP   ######      JERK_UP_PITCHBEND   ######      JERK_DOWN_PITCH_BEND   ######      FORCED_DECORATIONS_START_TIMES_MILLIS   ######      START_MILLIS_PERCUSSIONS   ######      START_MILLIS_FOR_PUREMELODYNOTES   ######      REFERENCE_CUMULATIVE_START_MILLIS   ######      PITCHBENDRANGE_2X2_DEFAULT   ######      PAN_0_TO_127   ######      

            //////   ######      S   ######      56   ######      220   ######      127   ######         ######      0;100   ######      8192;8192   ######         ######         ######         ######         ######      30   ######      30   ######      30   ######         ######         ######      220   ######      220   ######         ######         ######         ROW_NUMBER=0

            //////   ######      r   ######      57   ######      220   ######      127   ######         ######      0;100   ######      8192;8192   ######         ######         ######         ######         ######      30   ######      30   ######      30   ######         ######         ######      440   ######      440   ######         ######         ######         ROW_NUMBER=1

            //////   ######      g   ######      58   ######      220   ######      127   ######         ######      0;100   ######      8192;8192   ######         ######         ######         ######         ######      30   ######      30   ######      30   ######         ######         ######      660   ######      660   ######         ######         ######         ROW_NUMBER=2

            strbld______for_dot_dataGridView___COMPOSER

                .AppendLine

                (

          "LYRSYLLS   ######      INDINOTES   ######      TRYS_NOTES_NOS   ######      MILLISECOND   ######      CURR_NOTES_VELOCITY   ######      CURR_NOTES_PATCH   ######      PERCENTAGES_DURATIONS_COMMASEPS_PTCHBNDS   ######      WITHIN_NOTES_PTCHBENDS_VALUES   ######      CHANNEL   ######      TRACK   ######      NOTES_NUMBERS   ######      NOTES_FREQUENCYS   ######      JERK_MILLIS_GAP   ######      JERK_UP_PITCHBEND   ######      JERK_DOWN_PITCH_BEND   ######      FORCED_DECORATIONS_START_TIMES_MILLIS   ######      START_MILLIS_PERCUSSIONS   ######      START_MILLIS_FOR_PUREMELODYNOTES   ######      REFERENCE_CUMULATIVE_START_MILLIS   ######      PITCHBENDRANGE_2X2_DEFAULT   ######      PAN_0_TO_127   ######      "

                );

            strbld______for_CLUBBED_DURATIONS___dot_dataGridView___COMPOSER

                .AppendLine

                (

          "LYRSYLLS   ######      INDINOTES   ######      TRYS_NOTES_NOS   ######      MILLISECOND   ######      CURR_NOTES_VELOCITY   ######      CURR_NOTES_PATCH   ######      PERCENTAGES_DURATIONS_COMMASEPS_PTCHBNDS   ######      WITHIN_NOTES_PTCHBENDS_VALUES   ######      CHANNEL   ######      TRACK   ######      NOTES_NUMBERS   ######      NOTES_FREQUENCYS   ######      JERK_MILLIS_GAP   ######      JERK_UP_PITCHBEND   ######      JERK_DOWN_PITCH_BEND   ######      FORCED_DECORATIONS_START_TIMES_MILLIS   ######      START_MILLIS_PERCUSSIONS   ######      START_MILLIS_FOR_PUREMELODYNOTES   ######      REFERENCE_CUMULATIVE_START_MILLIS   ######      PITCHBENDRANGE_2X2_DEFAULT   ######      PAN_0_TO_127   ######      "

                );

            using (var writer = new StreamWriter(csvPath))

            {

              //  writer.WriteLine("Time (ms),Frequency (Hz),RMS,MinCMND,ThresholdUsed");

                // writer.WriteLine($"{s.TimeMs:F2},{s.Frequency:F2},{s.midsnotesnum:F2},{ s.durations_millis:F2},{s.velocity:F2},{s.RMS:F4},{s.MinCMND:F4},{s.ThresholdUsed:F3}");

                writer.WriteLine("Time (ms),Frequency (Hz),Midsnotes ,Indinotes, dursmillis , velocity , RMS,MinCMND,ThresholdUsed");

                _strbldr.AppendLine("Time (ms),Frequency (Hz),Midsnotes ,IndiNotes, dursmillis , velocity , RMS,MinCMND,ThresholdUsed");

                for (int rrr=0;rrr< (stats.Count-1);rrr++)

                {

                    stats.ElementAt(rrr).durations_millis

                        =

                  (stats.ElementAt(rrr + 1).TimeMs

                   -

                   stats.ElementAt(rrr ).TimeMs

                   );

                    /////////////////////////////// to avoid divisions with zeros for pitch bends ///////////////////////////////////////////

                    stats.ElementAt(rrr).durations_millis = Math.Max(1, stats.ElementAt(rrr).durations_millis);

                    /////////////////////////////// to avoid divisions with zeros for pitch bends ///////////////////////////////////////////

                    // stats.ElementAt(rrr).midsnotesnum =

                    stats.ElementAt(rrr).velocity = 127;// (int)((stats.ElementAt(rrr).MinCMND) * 127);        //(int)((stats.ElementAt(rrr).RMS) * 127);

                    try

                    {

                    //////////////////////////////////////////////////////////////////////

                    ///

                    for (int countptchbnds=0; countptchbnds < stats.ElementAt(rrr).public_list_of_ints_0_8192_16384_vals_for_pitchbends.Count; countptchbnds++)

                    {

                        stats.ElementAt(rrr)

                            .public_list_of_percentages_of_doubles_simples_durations_gaps_0_to_100_for_for_pitchbends

                            .

                            Add

                            (

                            (

                            (

                            stats.ElementAt(rrr).public_list_of_ints_0_8192_16384_vals_for_pitchbends.ElementAt(countptchbnds)

                            -

                            stats.ElementAt(rrr).TimeMs

                            )

                            / stats.ElementAt(rrr).durations_millis

                            )*100

                            );

                    }// for(int countptchbnds=0; countptchbnds < stats.ElementAt(rrr).public_list_of_ints_0_8192_16384_vals_for_pitchbends.Count; countptchbnds++)

                    }

                    catch (Exception ___excp_to_fill_pitchbends)

                    {

                    }//catch(Exception ___excp_to_fill_pitchbends)

                }// for(int rrr=0;rrr< (stats.Count-1);rrr++)

                for (int ggg = 0; ggg < (public_static___List_of___FrameStats__stats__pure_notes_nonzero_pitches.Count - 1); ggg++)

                {

                    public_static___List_of___FrameStats__stats__pure_notes_nonzero_pitches.ElementAt(ggg).durations_millis

                        =

                  (public_static___List_of___FrameStats__stats__pure_notes_nonzero_pitches.ElementAt(ggg + 1).TimeMs

                   -

                   public_static___List_of___FrameStats__stats__pure_notes_nonzero_pitches.ElementAt(ggg).TimeMs

                   );

                    /////////////////////////////// to avoid divisions with zeros for pitch bends ///////////////////////////////////////////

                    public_static___List_of___FrameStats__stats__pure_notes_nonzero_pitches.ElementAt(ggg).durations_millis 

                        = Math.Max(1, public_static___List_of___FrameStats__stats__pure_notes_nonzero_pitches.ElementAt(ggg).durations_millis);

                    /////////////////////////////// to avoid divisions with zeros for pitch bends ///////////////////////////////////////////

                    //  public_static___List_of___FrameStats__stats__pure_notes_nonzero_pitches.ElementAt(ggg).midsnotesnum = midsnotesnum

                    public_static___List_of___FrameStats__stats__pure_notes_nonzero_pitches.ElementAt(ggg).velocity = 127;// (int)((public_static___List_of___FrameStats__stats__pure_notes_nonzero_pitches.ElementAt(ggg).MinCMND) * 127);        //(int)((stats.ElementAt(rrr).RMS) * 127);

                    try

                    { 

                    for (int countptchbnds = 0; countptchbnds < public_static___List_of___FrameStats__stats__pure_notes_nonzero_pitches.ElementAt(ggg).public_list_of_ints_0_8192_16384_vals_for_pitchbends.Count; countptchbnds++)

                    {

                        stats.ElementAt(ggg)

                            .public_list_of_percentages_of_doubles_simples_durations_gaps_0_to_100_for_for_pitchbends

                            .

                            Add

                            (

                            (

                            (

                            public_static___List_of___FrameStats__stats__pure_notes_nonzero_pitches

                            .ElementAt(ggg).public_list_of_ints_0_8192_16384_vals_for_pitchbends.ElementAt(countptchbnds)

                            -

                            public_static___List_of___FrameStats__stats__pure_notes_nonzero_pitches

                            .ElementAt(ggg).TimeMs

                            )

                            / public_static___List_of___FrameStats__stats__pure_notes_nonzero_pitches

                            .ElementAt(ggg).durations_millis

                            )*100

                            );

                    }// for (int countptchbnds = 0; countptchbnds < public_static___List_of___FrameStats__stats__pure_notes_nonzero_pitches.ElementAt(ggg).public_list_of_ints_0_8192_16384_vals_for_pitchbends.Count; countptchbnds++)

                    }

                    catch (Exception ___excp_to_fill_pitchbends)

                    {

                    }//catch(Exception ___excp_to_fill_pitchbends)

                }// for(int ggg=0;ggg< (public_static___List_of___FrameStats__stats__pure_notes_nonzero_pitches.Count-1);ggg++)

                /////////////////////////////////////////////////////////////////////////////

                foreach (var s in stats)

                {

                    writer.WriteLine($"{s.TimeMs:F2},{s.Frequency:F2},{s.midsnotesnum:F2},{s.leftsideof_slash_in_indinotes_found},{ s.durations_millis:F2},{s.velocity:F2},{s.RMS:F4},{s.MinCMND:F4},{s.ThresholdUsed:F3}");

                }//foreach (var s in stats)

                string PERCENTAGES_DURATIONS_COMMASEPS_PTCHBNDS = "";

                string WITHIN_NOTES_PTCHBENDS_VALUES = "";

                string ___indinotefound___firstoccurances_before_slash 

                    = "";

                foreach (var s_mids in public_static___List_of___FrameStats__stats__pure_notes_nonzero_pitches)

                {

                    _strbldr.AppendLine($"{s_mids.TimeMs:F2},{s_mids.Frequency:F2},{s_mids.midsnotesnum:F2},{s_mids.leftsideof_slash_in_indinotes_found},{ s_mids.durations_millis:F2},{s_mids.velocity:F2},{s_mids.RMS:F4},{s_mids.MinCMND:F4},{s_mids.ThresholdUsed:F3}");

                    //////___indinotefound___firstoccurances_before_slash

                    //////    =

                    //////SAANS_ROUGH_BEATS_COMPOSER_FOR_ON_SELECTIONS_LOOP_CYCLES

                    //////    .PUBLIC_STATIC_CLASS_TO_PRELISTEN_HANDLING

                    //////    .

                    //////PUBLIC_STATIC_STRING_GET_INDINOTESNAME_FIRST_OCCURANCES___from_____PUBLIC_STATIC_STRING_ARRAY_FOR_36_NOTES___50_X_3____FOR_GIVENS_MIDSNOTESNUMBER

                    //////(s_mids.midsnotesnum);

                    if (s_mids.public_list_of_percentages_of_doubles_simples_durations_gaps_0_to_100_for_for_pitchbends.Count== s_mids.public_list_of_ints_0_8192_16384_vals_for_pitchbends.Count)

                    {

                        PERCENTAGES_DURATIONS_COMMASEPS_PTCHBNDS = "0";

                        WITHIN_NOTES_PTCHBENDS_VALUES = "8192";

                        foreach (double perc in s_mids.public_list_of_percentages_of_doubles_simples_durations_gaps_0_to_100_for_for_pitchbends)

                        {

                            PERCENTAGES_DURATIONS_COMMASEPS_PTCHBNDS

                                =

                                PERCENTAGES_DURATIONS_COMMASEPS_PTCHBNDS

                                +

                               ";"+ perc.ToString("F2");

                        }//foreach (double perc in s_mids.public_list_of_percentages_of_doubles_simples_durations_gaps_0_to_100_for_for_pitchbends)

                        foreach(int ptchbnd in s_mids.public_list_of_ints_0_8192_16384_vals_for_pitchbends)

                        {

                            WITHIN_NOTES_PTCHBENDS_VALUES

                                =

                                WITHIN_NOTES_PTCHBENDS_VALUES

                                + ";" + ((int)ptchbnd).ToString();

                        }//foreach(int ptchbnd in s_mids.public_list_of_ints_0_8192_16384_vals_for_pitchbends)

                    }//if(s_mids.public_list_of_percentages_of_doubles_simples_durations_gaps_0_to_100_for_for_pitchbends.Count== s_mids.public_list_of_ints_0_8192_16384_vals_for_pitchbends.Count)

                    else

                    {

                        PERCENTAGES_DURATIONS_COMMASEPS_PTCHBNDS = "0;100";

                        WITHIN_NOTES_PTCHBENDS_VALUES = "8192;8192";

                    }//filling the lists

                    ///////////////////////////////////////////////////////////////////////////////////////////

                    strbld______for_dot_dataGridView___COMPOSER

                        .AppendLine

                        (

                      //  "######"

                       // +

                        "LYRSYLLS  " 

                        +   "   ######   "+

                      // INDINOTES  

                      // ""

                      s_mids.leftsideof_slash_in_indinotes_found

                      + " ######   " +

                       // TRYS_NOTES_NOS

                       s_mids.midsnotesnum

                       + " ######   " +

                       // MILLISECOND

                       s_mids.durations_millis

                       + " ######   " +

                       // CURR_NOTES_VELOCITY

                       +s_mids.velocity

                        + " ######   " +

                      //  CURR_NOTES_PATCH

                      "73"

                        + " ######   " +

                      //  PERCENTAGES_DURATIONS_COMMASEPS_PTCHBNDS

                      //"0;100"

                      PERCENTAGES_DURATIONS_COMMASEPS_PTCHBNDS

                       + " ######   " +

                      //  WITHIN_NOTES_PTCHBENDS_VALUES

                      //"8192;8192"

                      WITHIN_NOTES_PTCHBENDS_VALUES

                       + " ######   " +

                       // CHANNEL

                       6

                        + " ######   " +

                      //  TRACK

                      6

                       + " ######   " +

                      //  NOTES_NUMBERS  names

                      "to_fill"

                       + " ######   " +

                      //  NOTES_FREQUENCYS

                      s_mids.Frequency

                       + " ######   " +

                       // JERK_MILLIS_GAP

                       6

                        + " ######   " +

                      //  JERK_UP_PITCHBEND

                      6

                        + " ######   " +

                      //  JERK_DOWN_PITCH_BEND

                      6

                        + " ######   " +

                     //   FORCED_DECORATIONS_START_TIMES_MILLIS

                     s_mids.TimeMs

                        + " ######   " +

                       // START_MILLIS_PERCUSSIONS

                       s_mids.TimeMs

                        + " ######   " +

                     //   START_MILLIS_FOR_PUREMELODYNOTES

                     s_mids.TimeMs

                        + " ######   " +

                      //  REFERENCE_CUMULATIVE_START_MILLIS  

                      +s_mids.TimeMs

                       +" ######    " + 

                      //  PITCHBENDRANGE_2X2_DEFAULT

                      "6"

                        + " ######   " +

                       // PAN_0_TO_127

                       "64"

                        + " ######   " 

                        );

                }// foreach (var s_mids in public_static___List_of___FrameStats__stats__pure_notes_nonzero_pitches)

            }//using (var writer = new StreamWriter(csvPath))

            /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

            System.IO.File.WriteAllText

                (

                csvPath+"_midsnotesfromwavs.csvs_dat"

                ,

                _strbldr.ToString()

                );

            /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

            /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

            System.IO.File.WriteAllText

                (

                csvPath + "___combined_wavstomids.dataGridView___COMPOSER"

                ,

                strbld______for_dot_dataGridView___COMPOSER.ToString()

                );

            /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

            foreach (var s_CONTINUED in public_static___List_of___CLUBBED_CONTIGUOUS_NOTES___DURATIONS_SUMMED___FrameStats__stats__pure_notes_nonzero_pitches)

            {

                //outside the writer streams

                string PERCENTAGES_DURATIONS_COMMASEPS_PTCHBNDS = "0";

                string WITHIN_NOTES_PTCHBENDS_VALUES = "8192";

                //_strbldr.AppendLine($"{s_mids.TimeMs:F2},{s_mids.Frequency:F2},{s_mids.midsnotesnum:F2},{s_mids.leftsideof_slash_in_indinotes_found},{ s_mids.durations_millis:F2},{s_mids.velocity:F2},{s_mids.RMS:F4},{s_mids.MinCMND:F4},{s_mids.ThresholdUsed:F3}");

                //////___indinotefound___firstoccurances_before_slash

                //////    =

                //////SAANS_ROUGH_BEATS_COMPOSER_FOR_ON_SELECTIONS_LOOP_CYCLES

                //////    .PUBLIC_STATIC_CLASS_TO_PRELISTEN_HANDLING

                //////    .

                //////PUBLIC_STATIC_STRING_GET_INDINOTESNAME_FIRST_OCCURANCES___from_____PUBLIC_STATIC_STRING_ARRAY_FOR_36_NOTES___50_X_3____FOR_GIVENS_MIDSNOTESNUMBER

                //////(s_mids.midsnotesnum);

                if (s_CONTINUED.public_list_of_percentages_of_doubles_simples_durations_gaps_0_to_100_for_for_pitchbends.Count == s_CONTINUED.public_list_of_ints_0_8192_16384_vals_for_pitchbends.Count)

                {

                    PERCENTAGES_DURATIONS_COMMASEPS_PTCHBNDS = "0";

                    WITHIN_NOTES_PTCHBENDS_VALUES = "8192";

                    foreach (double perc in s_CONTINUED.public_list_of_percentages_of_doubles_simples_durations_gaps_0_to_100_for_for_pitchbends)

                    {

                        PERCENTAGES_DURATIONS_COMMASEPS_PTCHBNDS

                            =

                            PERCENTAGES_DURATIONS_COMMASEPS_PTCHBNDS

                            +

                           ";" + perc.ToString("F2");

                    }//foreach (double perc in s_CONTINUED.public_list_of_percentages_of_doubles_simples_durations_gaps_0_to_100_for_for_pitchbends)

                    foreach (int ptchbnd in s_CONTINUED.public_list_of_ints_0_8192_16384_vals_for_pitchbends)

                    {

                        WITHIN_NOTES_PTCHBENDS_VALUES

                            =

                            WITHIN_NOTES_PTCHBENDS_VALUES

                            + ";" + ((int)ptchbnd).ToString();

                    }//foreach(int ptchbnd in s_CONTINUED.public_list_of_ints_0_8192_16384_vals_for_pitchbends)

                }//if(s_CONTINUED.public_list_of_percentages_of_doubles_simples_durations_gaps_0_to_100_for_for_pitchbends.Count== s_CONTINUED.public_list_of_ints_0_8192_16384_vals_for_pitchbends.Count)

                else

                {

                    PERCENTAGES_DURATIONS_COMMASEPS_PTCHBNDS = "0;100";

                    WITHIN_NOTES_PTCHBENDS_VALUES = "8192;8192";

                }//filling the lists

                 ///////////////////////////////////////////////////////////////////////////////////////////

                strbld______for_CLUBBED_DURATIONS___dot_dataGridView___COMPOSER

                    .AppendLine

                    (

                    //  "######"

                    // +

                    "LYRSYLLS  "

                    + "   ######   " +

                  // INDINOTES  

                  // ""

                  s_CONTINUED.leftsideof_slash_in_indinotes_found

                  + " ######   " +

                   // TRYS_NOTES_NOS

                   s_CONTINUED.midsnotesnum

                   + " ######   " +

                   // MILLISECOND

                   s_CONTINUED.durations_millis

                   + " ######   " +

                   // CURR_NOTES_VELOCITY

                   +s_CONTINUED.velocity

                    + " ######   " +

                  //  CURR_NOTES_PATCH

                  "73"

                    + " ######   " +

                  //  PERCENTAGES_DURATIONS_COMMASEPS_PTCHBNDS

                  //"0;100"

                  PERCENTAGES_DURATIONS_COMMASEPS_PTCHBNDS

                   + " ######   " +

                  //  WITHIN_NOTES_PTCHBENDS_VALUES

                  //"8192;8192"

                  WITHIN_NOTES_PTCHBENDS_VALUES

                   + " ######   " +

                   // CHANNEL

                   6

                    + " ######   " +

                  //  TRACK

                  6

                   + " ######   " +

                  //  NOTES_NUMBERS  names

                  "to_fill"

                   + " ######   " +

                  //  NOTES_FREQUENCYS

                  s_CONTINUED.Frequency

                   + " ######   " +

                   // JERK_MILLIS_GAP

                   6

                    + " ######   " +

                  //  JERK_UP_PITCHBEND

                  6

                    + " ######   " +

                  //  JERK_DOWN_PITCH_BEND

                  6

                    + " ######   " +

                 //   FORCED_DECORATIONS_START_TIMES_MILLIS

                 s_CONTINUED.TimeMs

                    + " ######   " +

                   // START_MILLIS_PERCUSSIONS

                   s_CONTINUED.TimeMs

                    + " ######   " +

                 //   START_MILLIS_FOR_PUREMELODYNOTES

                 s_CONTINUED.TimeMs

                    + " ######   " +

                  //  REFERENCE_CUMULATIVE_START_MILLIS  

                  +s_CONTINUED.TimeMs

                   + " ######    " +

                  //  PITCHBENDRANGE_2X2_DEFAULT

                  "6"

                    + " ######   " +

                   // PAN_0_TO_127

                   "64"

                    + " ######   "

                    );

            }// foreach (var s_CONTINUED in public_static___List_of___CLUBBED_CONTIGUOUS_NOTES___DURATIONS_SUMMED___FrameStats__stats__pure_notes_nonzero_pitches)

            /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

            System.IO.File.WriteAllText

                (

                csvPath + "___CLUBBED_DURATIONS_FOR_SAMES_NOTES_combined_wavstomids.dataGridView___COMPOSER"

                ,

                strbld______for_CLUBBED_DURATIONS___dot_dataGridView___COMPOSER.ToString()

                );

            /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

        }//public static void ExportDeepCsv(List<FrameStats> stats, string csvPath)

    }//public class WAVS_TO_MIDS_DYNAMIK_THRESHOLDS_YinPitchDetector___from_wav_files_8000_samples_per_seconds_16_bitsdepth_pcm_riff_files

    public class YinPitchDetector___from_wav_files_8000_samples_per_seconds_16_bitsdepth_pcm_riff_files

{

    const int SampleRate = 8000;

    const int FrameSize = 1024;

    const int StepSize = 512;

    const double Threshold = 0.15;

        public static int FrequencyToMidiNote(double frequency)

        {

            if (frequency <= 0) return 0;

            return (int)Math.Round(69 + 12 * Math.Log(frequency / 440.0, 2));

        }

        public static void ToProcess_with___inPitchDetector___from_wav_files_8000_samples_per_seconds_16_bitsdepth_pcm_riff_files___Main(string wav_filename)

    {

        string filePath = wav_filename;//"your_file.wav";

        var samples = ReadWavFile(filePath);

        var pitchTrack = DetectPitch(samples);

        ////Console.WriteLine("Time (ms) | Frequency (Hz)");

        ////for (int i = 0; i < pitchTrack.Count; i++)

        ////{

        ////    double timeMs = i * StepSize * 1000.0 / SampleRate;

        ////    Console.WriteLine($"{timeMs:F1}\t| {pitchTrack[i]:F2}");

        ////}//for (int i = 0; i < pitchTrack.Count; i++)

            string csvPath = filePath + "_YinPitchDetector_pitch.times_freqs___csv";

            using (var writer = new StreamWriter(csvPath))

            {

                writer.WriteLine("Time (ms),Frequency (Hz)");

                for (int i = 0; i < pitchTrack.Count; i++)

                {

                    double timeMs = i * StepSize * 1000.0 / SampleRate;

                    double frequency = pitchTrack[i];

                    writer.WriteLine($"{timeMs:F2},{frequency:F2}");

                }//for (int i = 0; i < pitchTrack.Count; i++)

            }//using (var writer = new StreamWriter(csvPath))

            Console.WriteLine("Pitch data saved to: " + csvPath);

            System.Windows.Forms.MessageBox.Show("Times Freqs_Pitch data saved to: " + csvPath);

        }//public static void ToProcess_with___inPitchDetector___from_wav_files_8000_samples_per_seconds_16_bitsdepth+pcm_riff_files___Main(string wav_filename)

    // Reads 16-bit PCM mono WAV

    public static List<double> ReadWavFile(string filePath)

    {

        var samples = new List<double>();

        using (var reader = new BinaryReader(File.OpenRead(filePath)))

        {

            // Skip header (44 bytes)

            reader.BaseStream.Seek(44, SeekOrigin.Begin);

            while (reader.BaseStream.Position < reader.BaseStream.Length)

            {

                short s = reader.ReadInt16();

                samples.Add(s / 32768.0);

            }//while (reader.BaseStream.Position < reader.BaseStream.Length)

        }//using (var reader = new BinaryReader(File.OpenRead(filePath)))

        return samples;

    }//public static List<double> ReadWavFile(string filePath)

    // Main YIN pitch detection

    public static List<double> DetectPitch(List<double> samples)

    {

        var pitchList = new List<double>();

        for (int i = 0; i + FrameSize < samples.Count; i += StepSize)

        {

            double[] frame = samples.GetRange(i, FrameSize).ToArray();

            double pitch = Yin(frame, SampleRate, Threshold);

            pitchList.Add(pitch);

        }//for (int i = 0; i + FrameSize < samples.Count; i += StepSize)

        return pitchList;

    }//public static List<double> DetectPitch(List<double> samples)

    // YIN algorithm implementation

    public static double Yin(double[] buffer, int sampleRate, double threshold)

    {

        int tauMax = buffer.Length / 2;

        double[] difference = new double[tauMax];

        double[] cumulativeMeanNormalizedDifference = new double[tauMax];

        // Step 1: Difference function

        for (int tau = 1; tau < tauMax; tau++)

        {

            double sum = 0;

            for (int i = 0; i < tauMax; i++)

            {

                double delta = buffer[i] - buffer[i + tau];

                sum += delta * delta;

            }//for (int i = 0; i < tauMax; i++)

            difference[tau] = sum;

        }//for (int tau = 1; tau < tauMax; tau++)

        // Step 2: Cumulative mean normalized difference

        cumulativeMeanNormalizedDifference[0] = 1;

        double runningSum = 0;

        for (int tau = 1; tau < tauMax; tau++)

        {

            runningSum += difference[tau];

            cumulativeMeanNormalizedDifference[tau] = difference[tau] / ((runningSum / tau) + 1e-10); // avoid divide by zero

        }//for (int tau = 1; tau < tauMax; tau++)

        // Step 3: Absolute threshold

        int tauEstimate = -1;

        for (int tau = 2; tau < tauMax; tau++)

        {

            if (cumulativeMeanNormalizedDifference[tau] < threshold)

            {

                while (tau + 1 < tauMax && cumulativeMeanNormalizedDifference[tau + 1] < cumulativeMeanNormalizedDifference[tau])

                {

                    tau++;

                }//while (tau + 1 < tauMax && cumulativeMeanNormalizedDifference[tau + 1] < cumulativeMeanNormalizedDifference[tau])

                tauEstimate = tau;

                break;

            }//if (cumulativeMeanNormalizedDifference[tau] < threshold)

        }//for (int tau = 2; tau < tauMax; tau++)

        // Step 4: Parabolic interpolation

        if (tauEstimate != -1)

        {

            double betterTau = tauEstimate;

            if (tauEstimate > 0 && tauEstimate < tauMax - 1)

            {

                double s0 = cumulativeMeanNormalizedDifference[tauEstimate - 1];

                double s1 = cumulativeMeanNormalizedDifference[tauEstimate];

                double s2 = cumulativeMeanNormalizedDifference[tauEstimate + 1];

                betterTau = tauEstimate + (s2 - s0) / (2 * (2 * s1 - s2 - s0));

            }//if (tauEstimate > 0 && tauEstimate < tauMax - 1)

            return sampleRate / betterTau;

        }

        else

        {

            return 0; // unvoiced or no pitch detected

        }//end of else of if (tauEstimate != -1)

    } // public static double Yin(double[] buffer, int sampleRate, double threshold)

    }//YinPitchDetector___from_wav_files_8000_samples_per_seconds_16_bitsdepth_pcm_riff_files

    /// <summary>

    /// ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

    /// </summary>

    public class SAANS_NO_3RD_PARTY_GPT_STYLES_WAV_FILES_READER_TO_GENERATE_8000_HZ_16_BIT_PCMS_GTAMPS

    {

        //////public static void Write_SPLITTED_WavFile(string path, List<float> normalizedSamples, int sampleRate)

        //////{

        //////    short bitsPerSample = 16;

        //////    short channels = 1;

        //////    int byteRate = sampleRate * channels * bitsPerSample / 8;

        //////    int dataSize = normalizedSamples.Count * 2;

        //////    using (var writer = new BinaryWriter(File.Create(path)))

        //////    {

        //////        writer.Write(Encoding.ASCII.GetBytes("RIFF"));

        //////        writer.Write(36 + dataSize);

        //////        writer.Write(Encoding.ASCII.GetBytes("WAVE"));

        //////        writer.Write(Encoding.ASCII.GetBytes("fmt "));

        //////        writer.Write(16);

        //////        writer.Write((short)1); // PCM

        //////        writer.Write((short)channels);

        //////        writer.Write(sampleRate);

        //////        writer.Write(byteRate);

        //////        writer.Write((short)(channels * bitsPerSample / 8));

        //////        writer.Write(bitsPerSample);

        //////        writer.Write(Encoding.ASCII.GetBytes("data"));

        //////        writer.Write(dataSize);

        //////        foreach (float sample in normalizedSamples)

        //////            writer.Write((short)(sample * 32767));

        //////    }//using (var writer = new BinaryWriter(File.Create(path)))

        //////}//public static void Write_SPLITTED_WavFile(string path, List<float> normalizedSamples, int sampleRate)

        public static double PUBLIC_STATIC_DOUBLE___CLASS_LEVEL_VARIABLE_TO_STORE_TOTAL_SAMPLES_FOUND = 0;

        public static void SplitWavByAmplitudePercentilewith_dynamik_thresholds(string wavPath)

        {

            string fileNameOnly = Path.GetFileNameWithoutExtension(wavPath);

            string folder = Path.GetDirectoryName(wavPath);

            short channels = 1;

            int sampleRate = 8000;

            short bitsPerSample = 16;

            List<float> amplitudes = new List<float>();

            // ---- Read WAV and extract normalized amplitudes ----

            using (var reader = new BinaryReader(File.OpenRead(wavPath)))

            {

                if (new string(reader.ReadChars(4)) != "RIFF") throw new Exception("Invalid RIFF");

                reader.ReadInt32(); // size

                if (new string(reader.ReadChars(4)) != "WAVE") throw new Exception("Invalid WAVE");

                while (reader.BaseStream.Position < reader.BaseStream.Length)

                {

                    string chunkId = new string(reader.ReadChars(4));

                    int chunkSize = reader.ReadInt32();

                    if (chunkId == "fmt ")

                    {

                        reader.ReadInt16(); // audioFormat

                        channels = reader.ReadInt16();

                        sampleRate = reader.ReadInt32();

                        reader.ReadInt32(); // byteRate

                        reader.ReadInt16(); // blockAlign

                        bitsPerSample = reader.ReadInt16();

                        if (chunkSize > 16) reader.ReadBytes(chunkSize - 16);

                    }

                    else if (chunkId == "data")

                    {

                        int bytesPerSample = bitsPerSample / 8;

                        int totalSamples = chunkSize / bytesPerSample;

                        for (int i = 0; i < totalSamples; i++)

                        {

                            if (reader.BaseStream.Position + bytesPerSample > reader.BaseStream.Length)

                                break;

                            short sample = reader.ReadInt16();

                            float norm = sample / 32768f;

                            amplitudes.Add(norm);

                            if (channels == 2) reader.ReadInt16(); // skip right channel

                        }

                        break;

                    }

                    else reader.ReadBytes(chunkSize); // skip unknown

                }

            }

            // ---- Calculate 20th percentile of absolute amplitudes ----

            var absSorted = amplitudes.Select(Math.Abs).OrderBy(v => v).ToList();

            float percentile20 = absSorted[(int)(absSorted.Count * 0.2)];

            Console.WriteLine($"Using 20th Percentile Amplitude as Threshold: {percentile20:F6}");

            // ---- Detect rising/falling threshold crossings ----

            List<(int Start, int End)> regions = new List<(int, int)>();

            bool inRegion = false;

            int regionStart = 0;

            int minSegmentSamples = 800; // ~100 ms

            for (int i = 0; i < amplitudes.Count; i++)

            {

                float absAmp = Math.Abs(amplitudes[i]);

                if (!inRegion && absAmp >= percentile20)

                {

                    inRegion = true;

                    regionStart = i;

                }

                else if (inRegion && absAmp < percentile20)

                {

                    int regionEnd = i;

                    if (regionEnd - regionStart >= minSegmentSamples)

                        regions.Add((regionStart, regionEnd));

                    inRegion = false;

                }

            }

            // Handle edge case if region reaches file end

            if (inRegion && amplitudes.Count - regionStart >= minSegmentSamples)

                regions.Add((regionStart, amplitudes.Count - 1));

            // ---- Save split WAVs ----

            for (int i = 0; i < regions.Count; i++)

            {

                int start = regions[i].Start;

                int end = regions[i].End;

                var segment = amplitudes.GetRange(start, end - start);

                string outputFile = Path.Combine(folder,

                    $"{fileNameOnly}_piece_{i + 1}_samples_{segment.Count}_ms_{(int)(segment.Count / (float)sampleRate * 1000)}.wav");

                Write_SPLITTED_WavFile(outputFile, segment, sampleRate);

                Console.WriteLine($"Saved: {outputFile}");

            }

            if (regions.Count == 0)

                Console.WriteLine("No regions above the 20th percentile threshold were long enough to save.");

        }//public static void SplitWavByAmplitudePercentilewith_dynamik_thresholds(string wavPath)

        public static void SplitWavByRisingAbove20dBRegions(string wavPath)

        {

            string fileNameOnly = Path.GetFileNameWithoutExtension(wavPath);

            string folder = Path.GetDirectoryName(wavPath);

            short channels = 1;

            int sampleRate = 8000;

            short bitsPerSample = 16;

            List<float> amplitudes = new List<float>();

            // ---- Read WAV and extract normalized amplitudes ----

            using (var reader = new BinaryReader(File.OpenRead(wavPath)))

            {

                // Read RIFF/WAVE

                if (new string(reader.ReadChars(4)) != "RIFF") throw new Exception("Invalid RIFF");

                reader.ReadInt32(); // size

                if (new string(reader.ReadChars(4)) != "WAVE") throw new Exception("Invalid WAVE");

                while (reader.BaseStream.Position < reader.BaseStream.Length)

                {

                    string chunkId = new string(reader.ReadChars(4));

                    int chunkSize = reader.ReadInt32();

                    if (chunkId == "fmt ")

                    {

                        reader.ReadInt16(); // audioFormat

                        channels = reader.ReadInt16();

                        sampleRate = reader.ReadInt32();

                        reader.ReadInt32(); // byteRate

                        reader.ReadInt16(); // blockAlign

                        bitsPerSample = reader.ReadInt16();

                        if (chunkSize > 16) reader.ReadBytes(chunkSize - 16);

                    }

                    else if (chunkId == "data")

                    {

                        int bytesPerSample = bitsPerSample / 8;

                        int totalSamples = chunkSize / bytesPerSample;

                        for (int i = 0; i < totalSamples; i++)

                        {

                            if (reader.BaseStream.Position + bytesPerSample > reader.BaseStream.Length)

                                break;

                            short sample = reader.ReadInt16();

                            float norm = sample / 32768f;

                            amplitudes.Add(norm);

                            if (channels == 2) reader.ReadInt16(); // skip right

                        }

                        break;

                    }

                    else reader.ReadBytes(chunkSize);

                }

            }

            // ---- SPLITTING BASED ON AMPLITUDE THRESHOLD ----

            float threshold = 0.1f; // ~ -20 dB

            bool inRegion = false;

            int regionStart = 0;

            int minSegmentSamples = 800; // = 100ms worth (8000Hz)

            List<(int Start, int End)> regions = new List<(int, int)>();

            for (int i = 0; i < amplitudes.Count; i++)

            {

                float absAmp = Math.Abs(amplitudes[i]);

                if (!inRegion && absAmp >= threshold)

                {

                    inRegion = true;

                    regionStart = i;

                }

                else if (inRegion && absAmp < threshold)

                {

                    // End of region

                    int regionEnd = i;

                    if (regionEnd - regionStart >= minSegmentSamples)

                        regions.Add((regionStart, regionEnd));

                    inRegion = false;

                }

            }//for (int i = 0; i < amplitudes.Count; i++)

            // Edge case: still in region at end

            if (inRegion && amplitudes.Count - regionStart >= minSegmentSamples)

                regions.Add((regionStart, amplitudes.Count - 1));

            // ---- SAVE SPLIT WAVS ----

            for (int i = 0; i < regions.Count; i++)

            {

                int start = regions[i].Start;

                int end = regions[i].End;

                var segment = amplitudes.GetRange(start, end - start);

                string outputFile = Path.Combine(folder,

                    $"{fileNameOnly}_piece_{i + 1}_samples_{segment.Count}_ms_{(int)(segment.Count / (float)sampleRate * 1000)}.wav");

                Write_SPLITTED_WavFile(outputFile, segment, sampleRate);

                Console.WriteLine($"Saved: {outputFile}");

            }//for (int i = 0; i < regions.Count; i++)

        }//public static void SplitWavByRisingAbove20dBRegions(string wavPath)

        public static void DISCARDING___THIS_GENERATES_LARGE_NUMBER_OF_SPLITTED_FILES______SplitWavByLocalMinimals_Of_Amplitudes(string wavPath)

        {

            string fileNameOnly = Path.GetFileNameWithoutExtension(wavPath);

            string folder = Path.GetDirectoryName(wavPath);

            short channels = 1;

            int sampleRate = 8000;

            short bitsPerSample = 16;

            List<float> amplitudes = new List<float>();

            // ---- Read WAV and extract normalized amplitudes ----

            using (var reader = new BinaryReader(File.OpenRead(wavPath)))

            {

                // Validate RIFF and WAVE

                if (new string(reader.ReadChars(4)) != "RIFF") throw new Exception("Invalid RIFF");

                reader.ReadInt32(); // size

                if (new string(reader.ReadChars(4)) != "WAVE") throw new Exception("Invalid WAVE");

                while (reader.BaseStream.Position < reader.BaseStream.Length)

                {

                    string chunkId = new string(reader.ReadChars(4));

                    int chunkSize = reader.ReadInt32();

                    if (chunkId == "fmt ")

                    {

                        reader.ReadInt16(); // audioFormat

                        channels = reader.ReadInt16();

                        sampleRate = reader.ReadInt32();

                        reader.ReadInt32(); // byteRate

                        reader.ReadInt16(); // blockAlign

                        bitsPerSample = reader.ReadInt16();

                        if (chunkSize > 16) reader.ReadBytes(chunkSize - 16);

                    }

                    else if (chunkId == "data")

                    {

                        int bytesPerSample = bitsPerSample / 8;

                        int totalSamples = chunkSize / bytesPerSample;

                        for (int i = 0; i < totalSamples; i++)

                        {

                            if (reader.BaseStream.Position + bytesPerSample > reader.BaseStream.Length)

                                break;

                            short sample = reader.ReadInt16();

                            float norm = sample / 32768f;

                            amplitudes.Add(norm);

                            if (channels == 2) reader.ReadInt16(); // skip right

                        }

                        break;

                    }

                    else reader.ReadBytes(chunkSize); // skip unknown chunk

                }

            }

            // ---- Analyze: average and percentiles ----

            float avgAmp = amplitudes.Average(a => Math.Abs(a));

            float percentile20 = amplitudes.OrderBy(Math.Abs).ElementAt((int)(amplitudes.Count * 0.2f));

            float percentile50 = amplitudes.OrderBy(Math.Abs).ElementAt((int)(amplitudes.Count * 0.5f));

            Console.WriteLine($"Average Amplitude: {avgAmp:F4}");

            Console.WriteLine($"20th Percentile: {percentile20:F4}, 50th Percentile: {percentile50:F4}");

            // ---- Detect local minima ----

            List<int> minimaIndexes = new List<int>();

            for (int i = 1; i < amplitudes.Count - 1; i++)

            {

                if (Math.Abs(amplitudes[i]) < Math.Abs(amplitudes[i - 1]) &&

                    Math.Abs(amplitudes[i]) < Math.Abs(amplitudes[i + 1]))

                {

                    if (Math.Abs(amplitudes[i]) < percentile20)

                        minimaIndexes.Add(i);

                }

            }//for (int i = 1; i < amplitudes.Count - 1; i++)

            // ---- Extract segments between minima and save WAVs ----

            for (int i = 0; i < minimaIndexes.Count - 1; i++)

            {

                int start = minimaIndexes[i];

                int end = minimaIndexes[i + 1];

                var segment = amplitudes.GetRange(start, end - start);

                string outputFile = Path.Combine(folder,

                    $"{fileNameOnly}_piece_{i + 1}_samples_{segment.Count}_ms_{(int)(segment.Count / (float)sampleRate * 1000)}.wav");

                Write_SPLITTED_WavFile(outputFile, segment, sampleRate);

                Console.WriteLine($"Saved: {outputFile}");

            }//for (int i = 0; i < minimaIndexes.Count - 1; i++)

        }//public static void DISCARDING___THIS_GENERATES_LARGE_NUMBER_OF_SPLITTED_FILES______SplitWavByLocalMinimals_Of_Amplitudes(string wavPath)

        public static void Write_SPLITTED_WavFile(string path, List<float> normalizedSamples, int sampleRate)

        {

            short bitsPerSample = 16;

            short channels = 1;

            int byteRate = sampleRate * channels * bitsPerSample / 8;

            int dataSize = normalizedSamples.Count * 2;

            using (var writer = new BinaryWriter(File.Create(path)))

            {

                // RIFF header

                writer.Write(Encoding.ASCII.GetBytes("RIFF"));

                writer.Write(36 + dataSize);

                writer.Write(Encoding.ASCII.GetBytes("WAVE"));

                // fmt chunk

                writer.Write(Encoding.ASCII.GetBytes("fmt "));

                writer.Write(16);

                writer.Write((short)1); // PCM

                writer.Write((short)channels);

                writer.Write(sampleRate);

                writer.Write(byteRate);

                writer.Write((short)(channels * bitsPerSample / 8));

                writer.Write(bitsPerSample);

                // data chunk

                writer.Write(Encoding.ASCII.GetBytes("data"));

                writer.Write(dataSize);

                foreach (float sample in normalizedSamples)

                    writer.Write((short)(sample * 32767));

            }

        }//public static void Write_SPLITTED_WavFile(string path, List<float> normalizedSamples, int sampleRate)

        public static double PrintWavDurationAndSampleCount(string wavPath)

        {

            double durationMs = 0;

            string ___report = "";

            using (var reader = new BinaryReader(File.OpenRead(wavPath)))

            {

                // Skip RIFF header

                reader.ReadChars(4);

                reader.ReadInt32();

                reader.ReadChars(4);

                int sampleRate = 0;

                short channels = 1;

                short bitsPerSample = 16;

                int dataSize = 0;

                // Read chunks

                while (reader.BaseStream.Position < reader.BaseStream.Length)

                {

                    string chunkId = new string(reader.ReadChars(4));

                    int chunkSize = reader.ReadInt32();

                    if (chunkId == "fmt ")

                    {

                        short audioFormat = reader.ReadInt16();

                        channels = reader.ReadInt16();

                        sampleRate = reader.ReadInt32();

                        reader.ReadInt32(); // byteRate

                        reader.ReadInt16(); // blockAlign

                        bitsPerSample = reader.ReadInt16();

                        if (chunkSize > 16)

                            reader.ReadBytes(chunkSize - 16);

                    }

                    else if (chunkId == "data")

                    {

                        dataSize = chunkSize;

                        break;

                    }

                    else

                    {

                        reader.ReadBytes(chunkSize); // skip unknown chunk

                    }

                }//while (reader.BaseStream.Position < reader.BaseStream.Length)

                if (sampleRate == 0 || dataSize == 0)

                {

                    Console.WriteLine("Failed to read sample rate or data size.");

                    return 0;

                }//if (sampleRate == 0 || dataSize == 0)

                int bytesPerSample = bitsPerSample / 8 * channels;

                int totalSamples = dataSize / bytesPerSample;

                 durationMs = (totalSamples / (double)sampleRate) * 1000;

                Console.WriteLine($"Sample Rate      : {sampleRate} Hz");

                Console.WriteLine($"Channels         : {channels}");

                Console.WriteLine($"Bits Per Sample  : {bitsPerSample}");

                Console.WriteLine($"Total Samples    : {totalSamples}");

                Console.WriteLine($"Total Duration   : {durationMs:F2} ms");

                 ___report= ___report + "\r\n"+ ($"Sample Rate      : {sampleRate} Hz");

                ___report = ___report + "\r\n" + ($"Channels         : {channels}");

                ___report = ___report + "\r\n" + ($"Bits Per Sample  : {bitsPerSample}");

                ___report = ___report + "\r\n" + ($"Total Samples    : {totalSamples}");

                ___report = ___report + "\r\n" + ($"Total Duration   : {durationMs:F2} ms");

                PUBLIC_STATIC_DOUBLE___CLASS_LEVEL_VARIABLE_TO_STORE_TOTAL_SAMPLES_FOUND

                    = totalSamples;

                System.IO.File.WriteAllText(wavPath + "_reportfor_gtsmps.txt", ___report);

            }//using (var reader = new BinaryReader(File.OpenRead(wavPath)))

            return durationMs;

        }//public static void PrintWavDurationAndSampleCount(string wavPath)

        public static void ConvertWavToGTAMPS___with_corrections_GPT(string wavPath, string outputGtampsPath)

        {

            short channels = 1;

            int sampleRate = 8000;

            short bitsPerSample = 16;

            using (var reader = new BinaryReader(File.OpenRead(wavPath)))

            {

                // 1. Read RIFF header

                if (new string(reader.ReadChars(4)) != "RIFF")

                    throw new Exception("Not a valid RIFF file.");

                reader.ReadInt32(); // File size

                if (new string(reader.ReadChars(4)) != "WAVE")

                    throw new Exception("Not a valid WAVE file.");

                // 2. Find 'fmt ' subchunk

                 channels = 1;

                 sampleRate = 8000;

                 bitsPerSample = 16;

                while (true)

                {

                    string chunkId = new string(reader.ReadChars(4));

                    int chunkSize = reader.ReadInt32();

                    if (chunkId == "fmt ")

                    {

                        short audioFormat = reader.ReadInt16();

                        channels = reader.ReadInt16();

                        sampleRate = reader.ReadInt32();

                        reader.ReadInt32(); // byteRate

                        reader.ReadInt16(); // blockAlign

                        bitsPerSample = reader.ReadInt16();

                        if (chunkSize > 16)

                            reader.ReadBytes(chunkSize - 16); // skip extra fmt bytes

                        break;

                    }

                    else

                    {

                        reader.ReadBytes(chunkSize); // skip unknown chunk

                    }

                }

                // 3. Find 'data' subchunk

                while (true)

                {

                    string chunkId = new string(reader.ReadChars(4));

                    int chunkSize = reader.ReadInt32();

                    if (chunkId == "data")

                    {

                        int bytesPerSample = bitsPerSample / 8;

                        int totalSamples = chunkSize / bytesPerSample;

                        // var amplitudes = new List<float>();

                        List<float> amplitudes = new List<float>();

                        for (int i = 0; i < totalSamples; i++)

                        {

                            if (reader.BaseStream.Position + bytesPerSample > reader.BaseStream.Length)

                                break;

                            short sample = reader.ReadInt16();

                            float norm = sample / 32768f;

                            amplitudes.Add(norm);

                            if (channels == 2)

                                reader.ReadInt16(); // skip right channel

                        }//for (int i = 0; i < totalSamples; i++)

                        // 4. Resample if needed

                        if (sampleRate != 8000)

                        {

                            var resampled = new List<float>();

                            double factor = sampleRate / 8000.0;

                            for (int i = 0; i < amplitudes.Count / factor; i++)

                            {

                                double idx = i * factor;

                                int i0 = (int)idx;

                                double frac = idx - i0;

                                float val = (i0 + 1 < amplitudes.Count)

                                    ? (float)((1 - frac) * amplitudes[i0] + frac * amplitudes[i0 + 1])

                                    : amplitudes[i0];

                                resampled.Add(val);

                            }//for (int i = 0; i < amplitudes.Count / factor; i++)

                            amplitudes = resampled;

                        }//if (sampleRate != 8000)

                        // 5. Save GTAMPS

                        File.WriteAllLines(outputGtampsPath, amplitudes.Select(a => a.ToString("F8")));

                           Console.WriteLine($"Saved GTAMPS: {outputGtampsPath}");

                        System.Windows.Forms.MessageBox.Show($"Saved GTAMPS: {outputGtampsPath}   amplitudes =  {amplitudes.Count}");

                        int necessary_repeats_of_samples_count = 1;

                        StringBuilder _strbldr = new StringBuilder();

                        _strbldr.Clear();

                        //////////////////////////////////////////////////////////// at least 6 seconds data 

                        if ( PUBLIC_STATIC_DOUBLE___CLASS_LEVEL_VARIABLE_TO_STORE_TOTAL_SAMPLES_FOUND < 48000)

                        {

                             necessary_repeats_of_samples_count

                                = (int)(48000 / PUBLIC_STATIC_DOUBLE___CLASS_LEVEL_VARIABLE_TO_STORE_TOTAL_SAMPLES_FOUND) + 1;

                            for (int repeater=0;repeater<= necessary_repeats_of_samples_count; repeater++)

                            {

                               foreach(float fltamps in amplitudes)

                                {

                                    _strbldr.AppendLine(fltamps.ToString("F8"));

                                }// foreach(float fltamps in amplitudes)

                            }// for (int repeater=0;repeater<= necessary_repeats_of_samples_count; repeater++)

                        }// if( PUBLIC_STATIC_DOUBLE___CLASS_LEVEL_VARIABLE_TO_STORE_TOTAL_SAMPLES_FOUND < 48000)

                        string outputGtampsPath_generated = wavPath + "_actual_sampleRate=" + sampleRate + "_actual_bps=" + bitsPerSample + "_rpt="+ necessary_repeats_of_samples_count +"_act_numSamples=" + amplitudes.Count + "_readjusted_smpls=" + (amplitudes.Count * necessary_repeats_of_samples_count) + "_8000Hz_16_bits_pcms_" + ".GTAMPS";

                        System.IO.File.WriteAllText

                            (

                            outputGtampsPath_generated

                            ,

                            _strbldr.ToString()

                            );

                        //     string outputGtampsPath_generated = wavPath + "_actual_sampleRate=" + sampleRate + "_actual_bps=" + bitsPerSample + "_numSamples=" + numSamples + "_smpls=" + samples + "_8000Hz_16_bits_pcms_" + ".GTAMPS";

                        //samples

                        // Save as .GTAMPS

                        //   File.WriteAllLines(outputGtampsPath_generated, samples.Select(s => s.ToString("F8")));

                        return;

                    }

                    else

                    {

                        reader.ReadBytes(chunkSize); // skip unknown chunk

                    }

                }

                throw new Exception("Data chunk not found.");

            }

        }//public static void ConvertWavToGTAMPS___with_corrections_GPT(string wavPath, string outputGtampsPath)

        //////    public static void ConvertWavToGTAMPS___with_corrections_GPT(string wavPath, string outputGtampsPath)

        //////    {

        //////        using (var reader = new BinaryReader(File.OpenRead(wavPath)))

        //////        {

        //////            // 1. Read RIFF header

        //////            if (new string(reader.ReadChars(4)) != "RIFF")

        //////                throw new Exception("Not a valid RIFF file.");

        //////            reader.ReadInt32(); // File size

        //////            if (new string(reader.ReadChars(4)) != "WAVE")

        //////                throw new Exception("Not a valid WAVE file.");

        //////            // 2. Find 'fmt ' subchunk

        //////            short channels = 1;

        //////            int sampleRate = 8000;

        //////            short bitsPerSample = 16;

        //////            while (true)

        //////            {

        //////                string chunkId = new string(reader.ReadChars(4));

        //////                int chunkSize = reader.ReadInt32();

        //////                if (chunkId == "fmt ")

        //////                {

        //////                    short audioFormat = reader.ReadInt16();

        //////                    channels = reader.ReadInt16();

        //////                    sampleRate = reader.ReadInt32();

        //////                    reader.ReadInt32(); // byteRate

        //////                    reader.ReadInt16(); // blockAlign

        //////                    bitsPerSample = reader.ReadInt16();

        //////                    if (chunkSize > 16)

        //////                        reader.ReadBytes(chunkSize - 16); // skip extra fmt bytes

        //////                    break;

        //////                }

        //////                else

        //////                {

        //////                    reader.ReadBytes(chunkSize); // skip unknown chunk

        //////                }

        //////            }

        //////            // 3. Find 'data' subchunk

        //////            while (true)

        //////            {

        //////                string chunkId = new string(reader.ReadChars(4));

        //////                int chunkSize = reader.ReadInt32();

        //////                if (chunkId == "data")

        //////                {

        //////                    int bytesPerSample = bitsPerSample / 8;

        //////                    int totalSamples = chunkSize / bytesPerSample;

        //////                    var amplitudes = new List<float>();

        //////                    for (int i = 0; i < totalSamples; i++)

        //////                    {

        //////                        if (reader.BaseStream.Position + bytesPerSample > reader.BaseStream.Length)

        //////                        { break; }

        //////                        short sample = reader.ReadInt16();

        //////                        float norm = sample / 32768f;

        //////                        amplitudes.Add(norm);

        //////                        if (channels == 2)

        //////                        {

        //////                            reader.ReadInt16(); // skip right channel}

        //////                        }// for (int i = 0; i < totalSamples; i++)

        //////                        // 4. Resample if needed

        //////                        if (sampleRate != 8000)

        //////                    {

        //////                        var resampled = new List<float>();

        //////                        double factor = sampleRate / 8000.0;

        //////                        for (int rrr = 0; rrr < amplitudes.Count / factor; rrr++)

        //////                        {

        //////                            double idx = rrr * factor;

        //////                            int i0 = (int)idx;

        //////                            double frac = idx - i0;

        //////                            float val = (i0 + 1 < amplitudes.Count)

        //////                                ? (float)((1 - frac) * amplitudes[i0] + frac * amplitudes[i0 + 1])

        //////                                : amplitudes[i0];

        //////                            resampled.Add(val);

        //////                        }//for (int rrr = 0; rrr < amplitudes.Count / factor; rrr++)

        //////                        amplitudes = resampled;

        //////                    }//if (sampleRate != 8000)

        //////                    // 5. Save GTAMPS

        //////                    //   File.WriteAllLines(outputGtampsPath, amplitudes.Select(a => a.ToString("F8")));

        //////                    //   Console.WriteLine($"Saved GTAMPS: {outputGtampsPath}");

        //////                    string outputGtampsPath_generated = wavPath + "_actual_sampleRate=" + sampleRate + "_actual_bps=" + bitsPerSample + "_numSamples=" + numSamples + "_smpls=" + samples + "_8000Hz_16_bits_pcms_" + ".GTAMPS";

        //////                    //samples

        //////                    // Save as .GTAMPS

        //////                    File.WriteAllLines(outputGtampsPath_generated, samples.Select(s => s.ToString("F8")));

        //////                    return;

        //////                }

        //////                else

        //////                {

        //////                    reader.ReadBytes(chunkSize); // skip unknown chunk

        //////                }

        //////            }

        //////            throw new Exception("Data chunk not found.");

        //////        }

        //////    }//public static void ConvertWavToGTAMPS___with_corrections_GPT(string wavPath, string outputGtampsPath)

        //////    public static void ConvertANY_KIND_OF_WavToGTAMPS(string wavPath, string outputGtampsPath)

        //////    {

        //////        using (var reader = new BinaryReader(File.OpenRead(wavPath)))

        //////        {

        //////            // Read RIFF header

        //////            string riff = new string(reader.ReadChars(4));

        //////            int fileSize = reader.ReadInt32();

        //////            string wave = new string(reader.ReadChars(4));

        //////            // Read format chunk

        //////            string fmt = new string(reader.ReadChars(4));

        //////            int fmtSize = reader.ReadInt32();

        //////            short audioFormat = reader.ReadInt16();

        //////            short channels = reader.ReadInt16();

        //////            int sampleRate = reader.ReadInt32();

        //////            int byteRate = reader.ReadInt32();

        //////            short blockAlign = reader.ReadInt16();

        //////            short bitsPerSample = reader.ReadInt16();

        //////            // Skip any extra bytes if fmt chunk > 16

        //////            if (fmtSize > 16)

        //////            { reader.ReadBytes(fmtSize - 16); }

        //////            // Seek to data chunk

        //////            while (new string(reader.ReadChars(4)) != "data")

        //////            {

        //////                reader.BaseStream.Position -= 3;

        //////            }//while (new string(reader.ReadChars(4)) != "data")

        //////            int dataSize = reader.ReadInt32();

        //////            int numSamples = dataSize / (bitsPerSample / 8);

        //////            var samples = new List<float>(numSamples);

        //////            for (int i = 0; i < numSamples; i++)

        //////            {

        //////                short sample16 = reader.ReadInt16();

        //////                float normalized = sample16 / 32768f;

        //////                samples.Add(normalized);

        //////                if (channels == 2) reader.ReadInt16(); // Skip second channel if stereo

        //////            }//for (int i = 0; i < numSamples; i++)

        //////            // Resample if needed (e.g., from 44100Hz to 8000Hz)

        //////            if (sampleRate != 8000)

        //////            {

        //////                var resampled = new List<float>();

        //////                double factor = sampleRate / 8000.0;

        //////                for (int i = 0; i < samples.Count / factor; i++)

        //////                {

        //////                    double index = i * factor;

        //////                    int idx = (int)index;

        //////                    double frac = index - idx;

        //////                    float sample = (idx + 1 < samples.Count)

        //////                        ? (float)((1 - frac) * samples[idx] + frac * samples[idx + 1])

        //////                        : samples[idx];

        //////                    resampled.Add(sample);

        //////                }//for (int i = 0; i < samples.Count / factor; i++)

        //////                samples = resampled;

        //////            }//if (sampleRate != 8000)

        //////           string  outputGtampsPath_generated= wavPath+ "_actual_sampleRate=" + sampleRate + "_actual_bps="+ bitsPerSample + "_numSamples=" + numSamples + "_smpls="+ samples+ "_8000Hz_16_bits_pcms_" + ".GTAMPS";

        //////            //samples

        //////            // Save as .GTAMPS

        //////            File.WriteAllLines(outputGtampsPath_generated, samples.Select(s => s.ToString("F8")));

        //////            // Console.WriteLine($"Saved GTAMPS to: {outputGtampsPath}");

        //////            System.Windows.Forms.MessageBox.Show($"Saved GTAMPS to: {outputGtampsPath}");

        //////        }//using (var reader = new BinaryReader(File.OpenRead(wavPath)))

        //////    }//public static void ConvertWavToGTAMPS(string wavPath, string outputGtampsPath)

    }// public class SAANS_NO_3RD_PARTY_GPT_STYLES_WAV_FILES_READER_TO_GENERATE_8000_HZ_16_BIT_PCMS_GTAMPS

    // this changes speed when frequencies changes

    public class WavGenerator___44_SHRUTIS_BACKWARD_TO_FORWARDS_Reads_GTAMPS_MONO_8000_Hz_Samples_16_bits_no_3rd_party_apis

    {

        const int SampleRate = 8000;

        const int BitsPerSample = 16;

        const int Channels = 1;

        const double Pi = Math.PI;

        public static void SAANS___44_SAMPLES_WavGenerator___Reads_GTAMPS_MONO_8000_Hz_Samples_16_bits_no_3rd_party_apis___Main(string gtamps_filesnames)

        {

            string inputPath = gtamps_filesnames;// "your_file_path_here.txt";

            // Read float samples

            var samples = File.ReadLines(inputPath)

                              .Where(line => double.TryParse(line, out _))

                              .Select(double.Parse)

                              .ToList();

            var allShifted = new List<short>();

            for (int r = 1; r <= 22; r++)

            {

                double shiftFactor = Math.Pow(2, r / 22.0);

                var shifted = ResampleWithFrequencyShift(samples, shiftFactor);

                allShifted.AddRange(shifted);

            }//for (int r = 1; r <= 22; r++)

            for (int r = -22; r <= 0; r++)

            {

                double shiftFactor = Math.Pow(2, r / 22.0);

                var shifted = ResampleWithFrequencyShift(samples, shiftFactor);

                allShifted.AddRange(shifted);

            }//for (int r = -22; r <= 0; r++)

            string outputPath = inputPath + "___44_SCALES_8000hZ_16_BITS_PCMS_" + allShifted.Count.ToString() + "_output.wav";

            WriteWavFile(outputPath, allShifted);

            Console.WriteLine("WAV file written to: " + outputPath);

        }//public static void SAANS___44_SAMPLES_WavGenerator___Reads_GTAMPS_MONO_8000_Hz_Samples_16_bits_no_3rd_party_apis___Main(STRING gtamps_filesnames)

        public static List<short> ResampleWithFrequencyShift(List<double> samples, double shiftFactor)

        {

            int newLength = (int)(samples.Count / shiftFactor);

            var shifted = new List<short>(newLength);

            for (int i = 0; i < newLength; i++)

            {

                double srcIndex = i * shiftFactor;

                int idx = (int)srcIndex;

                double frac = srcIndex - idx;

                double value = 0;

                if (idx + 1 < samples.Count)

                    value = (1 - frac) * samples[idx] + frac * samples[idx + 1];

                else if (idx < samples.Count)

                    value = samples[idx];

                short pcmVal = (short)(value * short.MaxValue);

                shifted.Add(pcmVal);

            }//for (int i = 0; i < newLength; i++)

            return shifted;

        }//public static List<short> ResampleWithFrequencyShift(List<double> samples, double shiftFactor)

        public static void WriteWavFile(string filePath, List<short> samples)

        {

            using (var stream = new FileStream(filePath, FileMode.Create))

            using (var writer = new BinaryWriter(stream))

            {

                int byteRate = SampleRate * Channels * BitsPerSample / 8;

                int dataSize = samples.Count * BitsPerSample / 8;

                // RIFF header

                writer.Write(Encoding.ASCII.GetBytes("RIFF"));

                writer.Write(36 + dataSize);

                writer.Write(Encoding.ASCII.GetBytes("WAVE"));

                // fmt subchunk

                writer.Write(Encoding.ASCII.GetBytes("fmt "));

                writer.Write(16); // PCM

                writer.Write((short)1); // AudioFormat = PCM

                writer.Write((short)Channels);

                writer.Write(SampleRate);

                writer.Write(byteRate);

                writer.Write((short)(Channels * BitsPerSample / 8));

                writer.Write((short)BitsPerSample);

                // data subchunk

                writer.Write(Encoding.ASCII.GetBytes("data"));

                writer.Write(dataSize);

                foreach (short s in samples)

                { writer.Write(s); }

            }//using (var writer = new BinaryWriter(stream))

        }//public static void WriteWavFile(string filePath, List<short> samples)

    }// public class WavGenerator___44_SHRUTIS_BACKWARD_TO_FORWARDS_Reads_GTAMPS_MONO_8000_Hz_Samples_16_bits_no_3rd_party_apis

    public class WavGeneratorFixedDuration___with_resamplers

    {

        const int SampleRate = 8000;

        const int BitsPerSample = 16;

        const int Channels = 1;

        public static void Process_WavGeneratorFixedDuration___with_resamplers(string inputFilePath)

        {

            var samples = File.ReadLines(inputFilePath)

                              .Where(line => double.TryParse(line, out _))

                              .Select(double.Parse)

                              .ToList();

            int originalSampleCount = samples.Count;

            var allShiftedSamples = new List<short>();

            // Positive shrutis (r = 1 to 22)

            for (int r = 1; r <= 22; r++)

            {

                double shiftFactor = Math.Pow(2, r / 22.0); // e.g., r=12 -> pitch up by ~1 semitone

                var shifted = PitchShiftPreserveDuration(samples, shiftFactor, originalSampleCount);

                allShiftedSamples.AddRange(shifted);

            }// for (int r = 1; r <= 22; r++)

            // Negative shrutis (r = -22 to 0)

            for (int r = -22; r <= 0; r++)

            {

                double shiftFactor = Math.Pow(2, r / 22.0); // pitch down

                var shifted = PitchShiftPreserveDuration(samples, shiftFactor, originalSampleCount);

                allShiftedSamples.AddRange(shifted);

            }// for (int r = -22; r <= 0; r++)

            string outputPath = inputFilePath + "_(44_COPIES_PITCH_CHANGED_)RESAMPLER_USED_FixedDur_ShiftedPitches.wav";

            WriteWavFile(outputPath, allShiftedSamples);

            Console.WriteLine("WAV file written to: " + outputPath);

            MessageBox.Show("WAV file written to: " + outputPath);

        }// public static void Process_WavGeneratorFixedDuration___with_resamplers(string inputFilePath)

        public static T Clamp<T>(T val, T min, T max) where T : IComparable<T>

        {

            if (val.CompareTo(min) < 0) return min;

            if (val.CompareTo(max) > 0) return max;

            return val;

        }// public static T Clamp<T>(T val, T min, T max) where T : IComparable<T>

        // Pitch shifts and resamples to preserve original duration

        public static List<short> PitchShiftPreserveDuration(List<double> samples, double shiftFactor, int targetLength)

        {

            var output = new List<short>(targetLength);

            double position = 0.0;

            double step = shiftFactor;

            for (int i = 0; i < targetLength; i++)

            {

                int idx = (int)position;

                double frac = position - idx;

                double value = 0;

                if (idx + 1 < samples.Count)

                    value = (1 - frac) * samples[idx] + frac * samples[idx + 1];

                else if (idx < samples.Count)

                    value = samples[idx];

                // Normalize and convert to 16-bit PCM

              //  short pcmVal = (short)(Math.Clamp(value, -1.0, 1.0) * short.MaxValue);

                     short pcmVal = (short)(Clamp(value, -1.0, 1.0) * short.MaxValue);

                output.Add(pcmVal);

                position += step;

                if (position >= samples.Count - 1)

                    position = 0; // Loop if needed to fill up

            }// for (int i = 0; i < targetLength; i++)

            return output;

        }// public static List<short> PitchShiftPreserveDuration(List<double> samples, double shiftFactor, int targetLength)

        public static void WriteWavFile(string filePath, List<short> samples)

        {

            using (var stream = new FileStream(filePath, FileMode.Create))

            {

                using (var writer = new BinaryWriter(stream))

                {

                    int byteRate = SampleRate * Channels * BitsPerSample / 8;

                    int dataSize = samples.Count * BitsPerSample / 8;

                    // RIFF Header

                    writer.Write(Encoding.ASCII.GetBytes("RIFF"));

                    writer.Write(36 + dataSize);

                    writer.Write(Encoding.ASCII.GetBytes("WAVE"));

                    // fmt chunk

                    writer.Write(Encoding.ASCII.GetBytes("fmt "));

                    writer.Write(16); // Subchunk1Size for PCM

                    writer.Write((short)1); // AudioFormat = PCM

                    writer.Write((short)Channels);

                    writer.Write(SampleRate);

                    writer.Write(byteRate);

                    writer.Write((short)(Channels * BitsPerSample / 8)); // BlockAlign

                    writer.Write((short)BitsPerSample);

                    // data chunk

                    writer.Write(Encoding.ASCII.GetBytes("data"));

                    writer.Write(dataSize);

                    foreach (short s in samples)

                        writer.Write(s);

                }// using (var writer = new BinaryWriter(stream))

            }// using (var stream = new FileStream(filePath, FileMode.Create))

        }// public static void WriteWavFile(string filePath, List<short> samples)

    }// public class WavGeneratorFixedDuration___with_resamplers

    // this dont change speed when frequencies changes

    public class WavGenerator___44_KEEPING_SHRUTIS_FIXED_DURATION

    {

        const int SampleRate = 8000;

        const int BitsPerSample = 16;

        const int Channels = 1;

        public static void function_to___WavGenerator___44_KEEPING_SHRUTIS_FIXED_DURATION___Main(string gtampsFilePath)

        {

            var samples = File.ReadLines(gtampsFilePath)

                              .Where(line => double.TryParse(line, out _))

                              .Select(double.Parse)

                              .ToList();

            int originalLength = samples.Count;

            var allShifted = new List<short>();

            // Positive shrutis

            for (int r = 1; r <= 22; r++)

            {

                double shiftFactor = Math.Pow(2, r / 22.0);

                var shifted = PitchShiftPreserveDuration(samples, shiftFactor, originalLength);

                allShifted.AddRange(shifted);

            }//for (int r = 1; r <= 22; r++)

            // Negative shrutis

            for (int r = -22; r <= 0; r++)

            {

                double shiftFactor = Math.Pow(2, r / 22.0);

                var shifted = PitchShiftPreserveDuration(samples, shiftFactor, originalLength);

                allShifted.AddRange(shifted);

            }//for (int r = -22; r <= 0; r++)

            string outputPath = gtampsFilePath + "(speed_intact)___44_FIXEDDUR_SCALES_8000Hz_16bit_" + allShifted.Count + "_output.wav";

            // WriteWavFile(outputPath, allShifted);

            WriteWavFile___another_keeping_speed_same(outputPath, allShifted);

            Console.WriteLine("WAV file written to: " + outputPath);

            System.Windows.Forms.MessageBox.Show("(Speeds intact)WAV file written to: " + outputPath);

        }//public static void function_to___WavGenerator___44_KEEPING_SHRUTIS_FIXED_DURATION___Main(string gtampsFilePath)

        // Shifts pitch and then stretches result back to original duration

        //////public static List<short> PitchShiftPreserveDuration(List<double> samples, double shiftFactor, int targetLength)

        //////{

        //////    // Step 1: Resample with frequency shift (changes duration)

        //////    int shiftedLength = (int)(samples.Count / shiftFactor);

        //////    var shifted = new List<double>(shiftedLength);

        //////    for (int i = 0; i < shiftedLength; i++)

        //////    {

        //////        double srcIndex = i * shiftFactor;

        //////        int idx = (int)srcIndex;

        //////        double frac = srcIndex - idx;

        //////        double value = 0;

        //////        if (idx + 1 < samples.Count)

        //////        { value = (1 - frac) * samples[idx] + frac * samples[idx + 1]; }

        //////        else if (idx < samples.Count)

        //////        { value = samples[idx]; }

        //////        shifted.Add(value);

        //////    }//for (int i = 0; i < shiftedLength; i++)

        //////    // Step 2: Time-stretch to match original length

        //////    var stretched = new List<short>(targetLength);

        //////    double step = (double)(shifted.Count - 1) / (targetLength - 1);

        //////    for (int i = 0; i < targetLength; i++)

        //////    {

        //////        double index = i * step;

        //////        int idx = (int)index;

        //////        double frac = index - idx;

        //////        double val = 0;

        //////        if (idx + 1 < shifted.Count)

        //////        { val = (1 - frac) * shifted[idx] + frac * shifted[idx + 1]; }

        //////        else if (idx < shifted.Count)

        //////        { val = shifted[idx]; }

        //////        short pcmVal = (short)(val * short.MaxValue);

        //////        stretched.Add(pcmVal);

        //////    }//for (int i = 0; i < targetLength; i++)

        //////    return stretched;

        //////}//public static List<short> PitchShiftPreserveDuration(List<double> samples, double shiftFactor, int targetLength)

        public static List<short> PitchShiftPreserveDuration(List<double> samples, double shiftFactor, int targetLength)

        {

            var output = new List<short>(targetLength);

            double position = 0.0;

            double positionStep = shiftFactor;

            for (int i = 0; i < targetLength; i++)

            {

                int idx = (int)position;

                double frac = position - idx;

                double value = 0;

                if (idx + 1 < samples.Count)

                    value = (1 - frac) * samples[idx] + frac * samples[idx + 1];

                else if (idx < samples.Count)

                    value = samples[idx];

                short pcmVal = (short)(value * short.MaxValue);

                output.Add(pcmVal);

                position += positionStep;

                if (position >= samples.Count - 1)

                    position = 0; // loop back if needed to keep filling output

            }//for (int i = 0; i < targetLength; i++)

            return output;

        }// public static List<short> PitchShiftPreserveDuration(List<double> samples, double shiftFactor, int targetLength)

        public static void WriteWavFile___another_keeping_speed_same(string filePath, List<short> samples)

        {

            using (var stream = new FileStream(filePath, FileMode.Create))

            {

                using (var writer = new BinaryWriter(stream))

                {

                    int byteRate = SampleRate * Channels * BitsPerSample / 8;

                    int dataSize = samples.Count * BitsPerSample / 8;

                    // RIFF header

                    writer.Write(Encoding.ASCII.GetBytes("RIFF"));

                    writer.Write(36 + dataSize);

                    writer.Write(Encoding.ASCII.GetBytes("WAVE"));

                    // fmt chunk

                    writer.Write(Encoding.ASCII.GetBytes("fmt "));

                    writer.Write(16);

                    writer.Write((short)1); // PCM

                    writer.Write((short)Channels);

                    writer.Write(SampleRate);

                    writer.Write(byteRate);

                    writer.Write((short)(Channels * BitsPerSample / 8));

                    writer.Write((short)BitsPerSample);

                    // data chunk

                    writer.Write(Encoding.ASCII.GetBytes("data"));

                    writer.Write(dataSize);

                    foreach (short s in samples)

                    { writer.Write(s); }

                }//using (var writer = new BinaryWriter(stream))

            }//using (var stream = new FileStream(filePath, FileMode.Create))

        }//public static void WriteWavFile___another_keeping_speed_same(string filePath, List<short> samples)

    }//public class WavGenerator___44_KEEPING_SHRUTIS_FIXED_DURATION

  public class WavGenerator___44_KEEPING_DURATION_VARIABLE_SAMPLE_RATE

    {

        const int BaseSampleRate = 8000;

        const int BitsPerSample = 16;

        const int Channels = 1;

        public static void function_to___WavGenerator___44_KEEPING_DURATION_VARIABLE_SAMPLE_RATE___Main(string gtampsFilePath)

        {

            var samples = File.ReadLines(gtampsFilePath)

                              .Where(line => double.TryParse(line, out _))

                              .Select(double.Parse)

                              .ToList();

            int totalSamples = samples.Count;

            for (int r = 1; r <= 22; r++)

            {

                double shiftFactor = Math.Pow(2, r / 22.0);

                int newSampleRate = (int)(BaseSampleRate * shiftFactor);

                string outputPath = gtampsFilePath + $"___shruti_up_{r}_samplerate_{newSampleRate}.wav";

                WriteWavFile_WithCustomSampleRate(outputPath, samples, newSampleRate);

            }//for (int r = 1; r <= 22; r++)

            for (int r = -22; r <= 0; r++)

            {

                double shiftFactor = Math.Pow(2, r / 22.0);

                int newSampleRate = (int)(BaseSampleRate * shiftFactor);

                string outputPath = gtampsFilePath + $"___shruti_down_{Math.Abs(r)}_samplerate_{newSampleRate}.wav";

                WriteWavFile_WithCustomSampleRate(outputPath, samples, newSampleRate);

            }//for (int r = -22; r <= 0; r++)

            Console.WriteLine("44 pitch-shifted files written with variable sample rates (durations preserved).");

            System.Windows.Forms.MessageBox.Show("WAVs written: duration preserved, pitch changed, sample rates varied.");

        }//public static void function_to___WavGenerator___44_KEEPING_DURATION_VARIABLE_SAMPLE_RATE___Main(string gtampsFilePath)

        public static void WriteWavFile_WithCustomSampleRate(string filePath, List<double> samples, int sampleRate)

        {

            using (var stream = new FileStream(filePath, FileMode.Create))

            {

                using (var writer = new BinaryWriter(stream))

                {

                    int byteRate = sampleRate * Channels * BitsPerSample / 8;

                    int dataSize = samples.Count * BitsPerSample / 8;

                    // RIFF header

                    writer.Write(Encoding.ASCII.GetBytes("RIFF"));

                    writer.Write(36 + dataSize);

                    writer.Write(Encoding.ASCII.GetBytes("WAVE"));

                    // fmt chunk

                    writer.Write(Encoding.ASCII.GetBytes("fmt "));

                    writer.Write(16);

                    writer.Write((short)1); // PCM

                    writer.Write((short)Channels);

                    writer.Write(sampleRate); // <-- variable sample rate here

                    writer.Write(byteRate);

                    writer.Write((short)(Channels * BitsPerSample / 8));

                    writer.Write((short)BitsPerSample);

                    // data chunk

                    writer.Write(Encoding.ASCII.GetBytes("data"));

                    writer.Write(dataSize);

                    foreach (double sample in samples)

                    {

                        short s = (short)(sample * short.MaxValue);

                        writer.Write(s);

                    }

                }//using writer

            }//using stream

        }//public static void WriteWavFile_WithCustomSampleRate(...)

    }//class WavGenerator___44_KEEPING_DURATION_VARIABLE_SAMPLE_RATE

    /// <summary>

    /// /////////////////////////////////////////////////////////////////////////////////////

    /// </summary>

    public class WavGenerator___12x3_ChromaticShrutis_From_SAA_GTAMPS

    {

        const int BaseSampleRate = 8000;

        const int BitsPerSample = 16;

        const int Channels = 1;

        public static StringBuilder ___combined_all_gtamps = new StringBuilder();

        public static void function_to___Generate_All_12x3_SemitoneNotes_From_SAA_GTAMPS(string gtampsFilePath)

        {

            ___combined_all_gtamps.Clear();

            var samples = File.ReadLines(gtampsFilePath)

                              .Where(line => double.TryParse(line, out _))

                              .Select(double.Parse)

                              .ToList();

            // These 36 labels are expected exactly from your shruti table

            string[] noteLabels = new string[]

            {

            ".S", ".R", ".R#", ".G", ".G#", ".M", ".M#", ".P", ".D", ".D#", ".N", ".N#",

            "S", "R", "R#", "G", "G#", "M", "M#", "P", "D", "D#", "N", "N#",

            "S.", "R.", "R#.", "G.", "G#.", "M.", "M#.", "P.", "D.", "D#.", "N.", "N#.","dash"

            };

            for (int i = 0; i < noteLabels.Length; i++)

            {

                double semitoneShift = i - 12; // Make "S" (index 12) the base reference (0)

                double shiftFactor = Math.Pow(2.0, semitoneShift / 12.0);

                int newSampleRate = (int)(BaseSampleRate * shiftFactor);

                string fileName = noteLabels[i].Replace("#", "hash").Replace(".", "_DOT_");

                string outputPath = Path.Combine(Path.GetDirectoryName(gtampsFilePath), fileName + ".wav");

                WriteWavFile_WithCustomSampleRate(outputPath, samples, newSampleRate, fileName);

            }//for (int i = 0; i < noteLabels.Length; i++)

            // Save the entire concatenated GTAMPS (optional master file)

            File.WriteAllText(gtampsFilePath + "_36_notes_combined.gtamps", ___combined_all_gtamps.ToString());

            Console.WriteLine("36 chromatic notes across 3 octaves generated.");

            System.Windows.Forms.MessageBox.Show("36 chromatic WAVs written from Sa sample.");

        }//public static void function_to___Generate_All_12x3_SemitoneNotes_From_SAA_GTAMPS(string gtampsFilePath)

        public static void WriteWavFile_WithCustomSampleRate(string filePath, List<double> samples, int sampleRate, string noteLabel)

        {

            using (var stream = new FileStream(filePath, FileMode.Create))

            using (var writer = new BinaryWriter(stream))

            {

                int byteRate = sampleRate * Channels * BitsPerSample / 8;

                int dataSize = samples.Count * BitsPerSample / 8;

                // RIFF header

                writer.Write(Encoding.ASCII.GetBytes("RIFF"));

                writer.Write(36 + dataSize);

                writer.Write(Encoding.ASCII.GetBytes("WAVE"));

                // fmt chunk

                writer.Write(Encoding.ASCII.GetBytes("fmt "));

                writer.Write(16);

                writer.Write((short)1); // PCM

                writer.Write((short)Channels);

                writer.Write(sampleRate);

                writer.Write(byteRate);

                writer.Write((short)(Channels * BitsPerSample / 8));

                writer.Write((short)BitsPerSample);

                // data chunk

                writer.Write(Encoding.ASCII.GetBytes("data"));

                writer.Write(dataSize);

                var sb = new StringBuilder();

                foreach (double sample in samples)

                {

                    short s = (short)(sample * short.MaxValue);

                    if(filePath.Contains("dash"))

                    {

                        writer.Write((short)0.0000001);

                        string textVal = "0.0000001";// s.ToString("F8");

                        sb.AppendLine(textVal);

                        ___combined_all_gtamps.AppendLine(textVal);

                    }

                    else

                    {

                        writer.Write(s);

                        string textVal = s.ToString("F8");

                        sb.AppendLine(textVal);

                        ___combined_all_gtamps.AppendLine(textVal);

                    }//end of else of if(filePath.Contains("dash"))

                }//foreach (double sample in samples)

                File.WriteAllText(filePath + ".gtamps", sb.ToString());

            }//using (var writer = new BinaryWriter(stream))

        } //public static void WriteWavFile_WithCustomSampleRate(string filePath, List<double> samples, int sampleRate, string noteLabel)

    }//public class WavGenerator___12x3_ChromaticShrutis_From_SAA_GTAMPS

    /// <summary>

    /// //////////////////////////////////////////////////////////////////////////////

    /// </summary>

    public class WavGenerator___ShrutiLibrary_From_SAA_Sample

    {

        const int BaseSampleRate = 8000;

        const int BitsPerSample = 16;

        const int Channels = 1;

       public static StringBuilder ___public_static_combined_for_88_shrutis_in_one_gtamps_stringBuilder = new StringBuilder();

        public static void function_to___Generate_All_Shrutis_From_SAA_GTAMPS(string gtampsFilePath)

        {

            ___public_static_combined_for_88_shrutis_in_one_gtamps_stringBuilder = new StringBuilder();

            ___public_static_combined_for_88_shrutis_in_one_gtamps_stringBuilder.Clear();

            var samples = File.ReadLines(gtampsFilePath)

                              .Where(line => double.TryParse(line, out _))

                              .Select(double.Parse)

                              .ToList();

            // All shruti names mapped to their shift positions (-22 to +22)

            string[] shrutiNames = new string[]

            {

            "L_Re1", "L_Re2", "L_Ma2S", "L_Pa2", "M_Sa", "M_Re1", "M_Re2", "M_Re", "M_Ga1", "M_Ga2", "M_Ga",

            "M_Ma", "M_Ma1", "M_Ma2", "M_Pa", "M_Dha1", "M_Dha2", "L_Re", "L_Ga1", "L_Ga2", "L_Ga", "L_Ma",

            "L_Ma1", "L_Ma2", "L_Pa", "L_Dha1", "L_Dha2", "L_Dha", "L_Ni1", "L_Ni2", "L_Ni2", "L_Re2S",

            "L_Ga2S", "M_Dha", "M_Ni1", "M_Ni2", "M_Ni", "M_Sa2", "M_Re2S", "M_Ga2S", "M_Ma2S", "M_Pa2",

            "U_Sa", "U_Re1", "U_Re2", "U_Re", "L_Ma2S", "L_Pa2", "M_Sa", "M_Re1", "M_Re2", "M_Re", "M_Ga1",

            "M_Ga2", "M_Ga", "M_Ma", "M_Ma1", "M_Ma2", "M_Pa", "M_Dha1", "M_Dha2", "L_Re", "L_Ga1", "L_Ga2",

            "L_Ga", "L_Ma", "L_Ma1", "L_Ma2", "L_Pa", "L_Dha1", "U_Ga1", "U_Ga2", "U_Ga", "U_Ma", "U_Ma1",

            "U_Ma2", "U_Pa", "U_Dha1", "U_Dha2", "U_Dha", "U_Ni1", "U_Ni2", "U_Ni", "U_Sa2", "U_Re2S",

            "U_Ga2S", "U_Ma2S", "U_Pa2","dash"

            };

            int totalShrutis = shrutiNames.Length;

            for (int r = 0; r < totalShrutis; r++)

            {

                int shrutiIndex = r - 22;

                double shiftFactor = Math.Pow(2, shrutiIndex / 22.0);

                int newSampleRate = (int)(BaseSampleRate * shiftFactor);

                string fileName = shrutiNames[r];

                //////string outputPath = Path.Combine(Path.GetDirectoryName(gtampsFilePath),

                //////                                 fileName + "_shruti.wav");

                ///

                string outputPath = Path.Combine(Path.GetDirectoryName(gtampsFilePath),

                                                 fileName + ".wav");

                WriteWavFile_WithCustomSampleRate(outputPath, samples, newSampleRate);

            }//for (int r = 0; r < totalShrutis; r++)

            System.IO.File.WriteAllText

                (

                gtampsFilePath+"_combined_88_shrutis.GTAMPS"

                ,

                ___public_static_combined_for_88_shrutis_in_one_gtamps_stringBuilder.ToString()

                );

            Console.WriteLine($"{totalShrutis} shruti files written using sample rate modulation.");

            System.Windows.Forms.MessageBox.Show($"{totalShrutis} shruti WAVs written from SAA sample.");

        }//public static void function_to___Generate_All_Shrutis_From_SAA_GTAMPS

        public static void WriteWavFile_WithCustomSampleRate(string filePath, List<double> samples, int sampleRate)

        {

            using (var stream = new FileStream(filePath, FileMode.Create))

            {

            using (var writer = new BinaryWriter(stream))

            {

                int byteRate = sampleRate * Channels * BitsPerSample / 8;

                int dataSize = samples.Count * BitsPerSample / 8;

                // RIFF header

                writer.Write(Encoding.ASCII.GetBytes("RIFF"));

                writer.Write(36 + dataSize);

                writer.Write(Encoding.ASCII.GetBytes("WAVE"));

                // fmt chunk

                writer.Write(Encoding.ASCII.GetBytes("fmt "));

                writer.Write(16);

                writer.Write((short)1); // PCM

                writer.Write((short)Channels);

                writer.Write(sampleRate);

                writer.Write(byteRate);

                writer.Write((short)(Channels * BitsPerSample / 8));

                writer.Write((short)BitsPerSample);

                // data chunk

                writer.Write(Encoding.ASCII.GetBytes("data"));

                writer.Write(dataSize);

                    StringBuilder ___temp_stringbuilder_for_current_shrutis_GTAMPS = new StringBuilder();

                    ___temp_stringbuilder_for_current_shrutis_GTAMPS.Clear();

                    foreach (double sample in samples)

                {

                    short s = (short)(sample * short.MaxValue);

                        if(filePath.Contains("dash"))

                            {

                            writer.Write((short)0.000001);

                            ___public_static_combined_for_88_shrutis_in_one_gtamps_stringBuilder

                                .AppendLine("0.000001");

                            ___temp_stringbuilder_for_current_shrutis_GTAMPS

                                  .AppendLine("0.000001");

                        }

                        else

                        {

                            writer.Write(s);

                            ___public_static_combined_for_88_shrutis_in_one_gtamps_stringBuilder

                                .AppendLine(s.ToString("F8"));

                            ___temp_stringbuilder_for_current_shrutis_GTAMPS

                                 .AppendLine(s.ToString("F8"));

                        }//endof else of  if(filePath.Contains("dash"))

                    }//foreach (double sample in samples)

                ///////////////////////////////////////////////////////////////////////////////////////////

                    System.IO.File.WriteAllText

                            (

                        filePath + "_bytrts_" + byteRate+"_sps_"+ sampleRate+ "_dtsizes_"+ dataSize + "_samples_" + samples.Count + "_" + ".gtamps"

                          ,

                        ___temp_stringbuilder_for_current_shrutis_GTAMPS.ToString()

                        );

                }// using (var writer = new BinaryWriter(stream))

            }//using (var stream = new FileStream(filePath, FileMode.Create))

        }//public static void WriteWavFile_WithCustomSampleRate

    }//public class WavGenerator___ShrutiLibrary_From_SAA_Sample

    //////public class WavGenerator___MultiPitch_SingleFile_FixedDurations

    //////{

    //////    const int BaseSampleRate = 44100;// 8000; // can be increased for higher resolution

    //////    const int BitsPerSample = 16;

    //////    const int Channels = 1;

    //////    public static void function_to___ApplyPerRegionPitchShift_AND_SaveUnifiedWav(string gtampsFilePath, int numRegions)

    //////    {

    //////        var originalSamples = File.ReadLines(gtampsFilePath)

    //////                                  .Where(line => double.TryParse(line, out _))

    //////                                  .Select(double.Parse)

    //////                                  .ToList();

    //////        // Apply pitch shifts to each region

    //////        List<short> finalPcm = ApplyPerRegionPitchShift(originalSamples, numRegions);

    //////        // Save to single WAV

    //////        string outputPath = gtampsFilePath + $"CONCATENATED____{numRegions}_Regions_MultiPitch_FixedDuration_output.wav";

    //////        WriteWavFile___SingleFile_ConstantSampleRate(outputPath, finalPcm, BaseSampleRate);

    //////        Console.WriteLine("Unified WAV written with pitch-shifted segments (duration preserved).");

    //////        System.Windows.Forms.MessageBox.Show("Unified WAV written with pitch-shifted segments (duration preserved): " + outputPath);

    //////    }//public static void function_to___ApplyPerRegionPitchShift_AND_SaveUnifiedWav(...)

    //////    public static List<short> ApplyPerRegionPitchShift(List<double> original, int numRegions)

    //////    {

    //////        //////int totalSamples = original.Count;

    //////        //////int segmentLength = totalSamples / numRegions;

    //////        //////List<short> output = new List<short>();

    //////        int totalSamples = original.Count * numRegions;//SAAN CHANGES THIS SINCE I THINK IF I NEED 44 COPIES THEN THERE NEEDS 44 TIMES ORIGINAL DURATION IN CONCATENATED FILES PLAY TIMES

    //////        int segmentLength = totalSamples / numRegions;

    //////        List<short> output = new List<short>();// OBVIOUSLY IF I AM GENERATING N NUMBERS OF PITCH CHANGED COPIES THEN ATLEAST N NUMBER OF TIMES ORIGINAL SAMPLES COUNT TO REPEAT

    //////        Random rnd = new Random();//??? WHY IS THIS??????????

    //////        for (int region = 0; region < numRegions; region++)

    //////        {

    //////            var segment = original.Skip(region * segmentLength).Take(segmentLength).ToList();

    //////            // Choose a shift factor (shruti-style): use 2^(r/22.0), r from -22 to +22

    //////            int shrutiStep = -22 + (44 * region / numRegions); // evenly spaced across shruti scale

    //////            // ALL OF THESE    COPIED REGIONS NEED SAME DURATION OF PLAY TIME AS ACTUAL totalSamples PLAY TIME FREQUENCIES ARE TO CHANGE

    //////            double shiftFactor = Math.Pow(2, shrutiStep / 22.0);

    //////            var regionPcm = PitchShift_PreserveDuration(segment, shiftFactor, segmentLength);

    //////            output.AddRange(regionPcm);

    //////        }

    //////        return output;

    //////    }//public static List<short> ApplyPerRegionPitchShift(List<double> original, int numRegions)

    //////    public static List<short> PitchShift_PreserveDuration(List<double> input, double shiftFactor, int outputLength)

    //////    {

    //////        var result = new List<short>(outputLength);

    //////        double pos = 0.0;

    //////        double posStep = shiftFactor;

    //////        for (int i = 0; i < outputLength; i++)

    //////        {

    //////            int idx = (int)pos;

    //////            double frac = pos - idx;

    //////            double value = 0;

    //////            if (idx + 1 < input.Count)

    //////                value = (1 - frac) * input[idx] + frac * input[idx + 1];

    //////            else if (idx < input.Count)

    //////                value = input[idx];

    //////            short pcmVal = (short)(value * short.MaxValue);

    //////            result.Add(pcmVal);

    //////            pos += posStep;

    //////            if (pos >= input.Count - 1)

    //////                pos = 0; // loop or clamp, depending on preference

    //////        }

    //////        return result;

    //////    }//public static List<short> PitchShift_PreserveDuration(...)

    //////    public static void WriteWavFile___SingleFile_ConstantSampleRate(string filePath, List<short> samples, int sampleRate)

    //////    {

    //////        using (var stream = new FileStream(filePath, FileMode.Create))

    //////        using (var writer = new BinaryWriter(stream))

    //////        {

    //////            int byteRate = sampleRate * Channels * BitsPerSample / 8;

    //////            int dataSize = samples.Count * BitsPerSample / 8;

    //////            // RIFF header

    //////            writer.Write(Encoding.ASCII.GetBytes("RIFF"));

    //////            writer.Write(36 + dataSize);

    //////            writer.Write(Encoding.ASCII.GetBytes("WAVE"));

    //////            // fmt chunk

    //////            writer.Write(Encoding.ASCII.GetBytes("fmt "));

    //////            writer.Write(16);

    //////            writer.Write((short)1); // PCM

    //////            writer.Write((short)Channels);

    //////            writer.Write(sampleRate);

    //////            writer.Write(byteRate);

    //////            writer.Write((short)(Channels * BitsPerSample / 8));

    //////            writer.Write((short)BitsPerSample);

    //////            // data chunk

    //////            writer.Write(Encoding.ASCII.GetBytes("data"));

    //////            writer.Write(dataSize);

    //////            foreach (short s in samples)

    //////                writer.Write(s);

    //////        }

    //////    }//public static void WriteWavFile___SingleFile_ConstantSampleRate(...)

    //////}//class WavGenerator___MultiPitch_SingleFile_FixedDurations

    //////public class WavGenerator___MultiPitch_SingleFile_FixedDurations

    //////{

    //////    const int BaseSampleRate = 44100;

    //////    const int BitsPerSample = 16;

    //////    const int Channels = 1;

    //////    public static void function_to___ApplyPerRegionPitchShift_AND_SaveUnifiedWav(string gtampsFilePath, int numRegions)

    //////    {

    //////        var originalSamples = File.ReadLines(gtampsFilePath)

    //////                                  .Where(line => double.TryParse(line, out _))

    //////                                  .Select(double.Parse)

    //////                                  .ToList();

    //////        // Generate shifted versions

    //////        List<short> finalPcm = new List<short>();

    //////        for (int region = 0; region < numRegions; region++)

    //////        {

    //////            // Shruti step evenly from -22 to +22

    //////            int shrutiStep = -22 + (44 * region / numRegions);

    //////            double shiftFactor = Math.Pow(2, shrutiStep / 22.0);

    //////            var pitchShifted = ResamplePitchShift(originalSamples, shiftFactor);

    //////            // Now stretch/truncate pitch-shifted to same duration as original (i.e., same sample count)

    //////            var fixedDuration = StretchToLength(pitchShifted, originalSamples.Count);

    //////            finalPcm.AddRange(fixedDuration);

    //////        }

    //////        // Save to WAV

    //////        string outputPath = gtampsFilePath + $"__{numRegions}_Regions_MultiPitch_FIXED_T_Duration_output.wav";

    //////        WriteWavFile(outputPath, finalPcm, BaseSampleRate);

    //////        Console.WriteLine("Saved WAV: pitch-shifted regions, each fixed to original duration.");

    //////        System.Windows.Forms.MessageBox.Show("Output WAV: multi-pitch, all segments same duration.");

    //////    }

    //////    public static List<double> ResamplePitchShift(List<double> input, double shiftFactor)

    //////    {

    //////        int newLength = (int)(input.Count / shiftFactor);

    //////        List<double> result = new List<double>(newLength);

    //////        for (int i = 0; i < newLength; i++)

    //////        {

    //////            double srcIndex = i * shiftFactor;

    //////            int idx = (int)srcIndex;

    //////            double frac = srcIndex - idx;

    //////            double val = 0;

    //////            if (idx + 1 < input.Count)

    //////                val = (1 - frac) * input[idx] + frac * input[idx + 1];

    //////            else if (idx < input.Count)

    //////                val = input[idx];

    //////            result.Add(val);

    //////        }

    //////        return result;

    //////    }

    //////    public static List<short> StretchToLength(List<double> input, int targetLength)

    //////    {

    //////        List<short> output = new List<short>(targetLength);

    //////        double step = (double)(input.Count - 1) / (targetLength - 1);

    //////        for (int i = 0; i < targetLength; i++)

    //////        {

    //////            double srcIndex = i * step;

    //////            int idx = (int)srcIndex;

    //////            double frac = srcIndex - idx;

    //////            double val = 0;

    //////            if (idx + 1 < input.Count)

    //////                val = (1 - frac) * input[idx] + frac * input[idx + 1];

    //////            else if (idx < input.Count)

    //////                val = input[idx];

    //////            output.Add((short)(val * short.MaxValue));

    //////        }

    //////        return output;

    //////    }

    //////    public static void WriteWavFile(string filePath, List<short> samples, int sampleRate)

    //////    {

    //////        using (var stream = new FileStream(filePath, FileMode.Create))

    //////        using (var writer = new BinaryWriter(stream))

    //////        {

    //////            int byteRate = sampleRate * Channels * BitsPerSample / 8;

    //////            int dataSize = samples.Count * BitsPerSample / 8;

    //////            // RIFF header

    //////            writer.Write(Encoding.ASCII.GetBytes("RIFF"));

    //////            writer.Write(36 + dataSize);

    //////            writer.Write(Encoding.ASCII.GetBytes("WAVE"));

    //////            // fmt chunk

    //////            writer.Write(Encoding.ASCII.GetBytes("fmt "));

    //////            writer.Write(16);

    //////            writer.Write((short)1); // PCM

    //////            writer.Write((short)Channels);

    //////            writer.Write(sampleRate);

    //////            writer.Write(byteRate);

    //////            writer.Write((short)(Channels * BitsPerSample / 8));

    //////            writer.Write((short)BitsPerSample);

    //////            // data chunk

    //////            writer.Write(Encoding.ASCII.GetBytes("data"));

    //////            writer.Write(dataSize);

    //////            foreach (short s in samples)

    //////                writer.Write(s);

    //////        }

    //////    }

    //////}//public class WavGenerator___MultiPitch_SingleFile_FixedDurations

    public class WavGenerator___MultiPitch___IT_GENERATES_SAME_PITCH_COPIES_ONLY____SingleFile_FixedDurations

    {

        //WE CANNOT CHANGE THE SAMPLE RATE FROM THE ORIGINAL GTAMPS SAMPLE RATES

        const int BaseSampleRate = 8000;//44100;//8000;// 16000;//8000;//44100; // or 8000, if desired

        const int BitsPerSample = 16;

        const int Channels = 1;

        public static void function_to___ApplyPerRegionPitchShift_AND_SaveUnifiedWav(string gtampsFilePath, int numRegions)

        {

            var originalSamples = File.ReadLines(gtampsFilePath)

                                      .Where(line => double.TryParse(line, out _))

                                      .Select(double.Parse)

                                      .ToList();

            List<short> finalPcm = ApplyPerRegionPitchShift(originalSamples, numRegions);

            //  string outputPath = gtampsFilePath + $"___{numRegions}_Regions_MultiPitch_FIXED_T_Duration_output.wav";

            string outputPath = gtampsFilePath + $"___{numRegions}_Regions_SAMEPitchCOPY_FIXED_T_Duration_output.wav";

            WriteWavFile(outputPath, finalPcm, BaseSampleRate);

            Console.WriteLine("Unified WAV written with pitch-shifted regions (duration preserved).");

            System.Windows.Forms.MessageBox.Show("WAV with multiple pitches and fixed durations saved:\n" + outputPath);

        }//public static void function_to___ApplyPerRegionPitchShift_AND_SaveUnifiedWav

        public static List<short> ApplyPerRegionPitchShift(List<double> original, int numRegions)

        {

            //  double segmentDurationSec = original.Count / (double)BaseSampleRate;

            // double segmentDurationSec = (original.Count* numRegions) / (double)BaseSampleRate;

            double segmentDurationSec = original.Count / (double)BaseSampleRate; //WHEN I DO THIS THEN ALL ARE PLAYING WITH SAME FREWQUENCY

            List<short> output = new List<short>();

            for (int region = 0; region < numRegions; region++)

            {

//int shrutiStep = -22 + (44 * region / numRegions);

                int shrutiStep = -(int)(numRegions/2) + (44 * region / numRegions);

                double shiftFactor = Math.Pow(2, shrutiStep / 22.0);

                var pitchShifted = ResamplePitchShift(original, shiftFactor);

                int desiredSampleCount = (int)(segmentDurationSec * BaseSampleRate);

                var adjusted = StretchToLength(pitchShifted, desiredSampleCount);

                output.AddRange(adjusted);

            }//for (int region = 0; region < numRegions; region++)

            return output;

        }//public static List<short> ApplyPerRegionPitchShift

        public static List<double> ResamplePitchShift(List<double> input, double shiftFactor)

        {

            int newLength = (int)(input.Count / shiftFactor);

            var result = new List<double>(newLength);

            for (int i = 0; i < newLength; i++)

            {

                double srcIndex = i * shiftFactor;

                int idx = (int)srcIndex;

                double frac = srcIndex - idx;

                double val = 0;

                if (idx + 1 < input.Count)

                    val = (1 - frac) * input[idx] + frac * input[idx + 1];

                else if (idx < input.Count)

                    val = input[idx];

                result.Add(val);

            }//for (int i = 0; i < newLength; i++)

            return result;

        }//public static List<double> ResamplePitchShift

        public static List<short> StretchToLength(List<double> input, int targetLength)

        {

            var output = new List<short>(targetLength);

            double step = (double)(input.Count - 1) / (targetLength - 1);

            for (int i = 0; i < targetLength; i++)

            {

                double srcIndex = i * step;

                int idx = (int)srcIndex;

                double frac = srcIndex - idx;

                double val = 0;

                if (idx + 1 < input.Count)

                {

                    val = (1 - frac) * input[idx] + frac * input[idx + 1];

                }

                else if (idx < input.Count)

                {

                    val = input[idx];

                }

                short pcm = (short)(val * short.MaxValue);

                output.Add(pcm);

            }

            return output;

        }//public static List<short> StretchToLength

        public static void WriteWavFile(string filePath, List<short> samples, int sampleRate)

        {

            using (var stream = new FileStream(filePath, FileMode.Create))

            using (var writer = new BinaryWriter(stream))

            {

                int byteRate = sampleRate * Channels * BitsPerSample / 8;

                int dataSize = samples.Count * BitsPerSample / 8;

                // RIFF header

                writer.Write(Encoding.ASCII.GetBytes("RIFF"));

                writer.Write(36 + dataSize);

                writer.Write(Encoding.ASCII.GetBytes("WAVE"));

                // fmt chunk

                writer.Write(Encoding.ASCII.GetBytes("fmt "));

                writer.Write(16);

                writer.Write((short)1); // PCM

                writer.Write((short)Channels);

                writer.Write(sampleRate);

                writer.Write(byteRate);

                writer.Write((short)(Channels * BitsPerSample / 8));

                writer.Write((short)BitsPerSample);

                // data chunk

                writer.Write(Encoding.ASCII.GetBytes("data"));

                writer.Write(dataSize);

                foreach (short s in samples)

                    writer.Write(s);

            }

        }//public static void WriteWavFile

    }//public class WavGenerator___MultiPitch_SingleFile_FixedDurations

    public class WavGenerator___Reads_GTAMPS_MONO_8000_Hz_Samples_16_bits_no_3rd_party_apis

    {

        const int SampleRate = 8000;

        const int BitsPerSample = 16;

        const int Channels = 1;

        const double Pi = Math.PI;

        public static void SAANS___WavGenerator___Reads_GTAMPS_MONO_8000_Hz_Samples_16_bits_no_3rd_party_apis___Main(string gtamps_filesnames)

        {

            string inputPath = gtamps_filesnames;// "your_file_path_here.txt";

            // Read float samples

            var samples = File.ReadLines(inputPath)

                              .Where(line => double.TryParse(line, out _))

                              .Select(double.Parse)

                              .ToList();

            var allShifted = new List<short>();

            for (int r = 1; r <= 22; r++)

            {

                double shiftFactor = Math.Pow(2, r / 22.0);

                var shifted = ResampleWithFrequencyShift(samples, shiftFactor);

                allShifted.AddRange(shifted);

            }//for (int r = 1; r <= 22; r++)

            string outputPath = inputPath + "___22_times_8000hZ_16_BITS_PCMS_"+allShifted.Count.ToString() + "_output.wav";

            WriteWavFile(outputPath, allShifted);

            Console.WriteLine("WAV file written to: " + outputPath);

        }//public static void SAANS___WavGenerator___Reads_GTAMPS_MONO_8000_Hz_Samples_16_bits_no_3rd_party_apis___Main(STRING gtamps_filesnames)

        public static List<short> ResampleWithFrequencyShift(List<double> samples, double shiftFactor)

        {

            int newLength = (int)(samples.Count / shiftFactor);

            var shifted = new List<short>(newLength);

            for (int i = 0; i < newLength; i++)

            {

                double srcIndex = i * shiftFactor;

                int idx = (int)srcIndex;

                double frac = srcIndex - idx;

                double value = 0;

                if (idx + 1 < samples.Count)

                    value = (1 - frac) * samples[idx] + frac * samples[idx + 1];

                else if (idx < samples.Count)

                    value = samples[idx];

                short pcmVal = (short)(value * short.MaxValue);

                shifted.Add(pcmVal);

            }//for (int i = 0; i < newLength; i++)

            return shifted;

        }//public static List<short> ResampleWithFrequencyShift(List<double> samples, double shiftFactor)

        public static void WriteWavFile(string filePath, List<short> samples)

        {

            using (var stream = new FileStream(filePath, FileMode.Create))

            using (var writer = new BinaryWriter(stream))

            {

                int byteRate = SampleRate * Channels * BitsPerSample / 8;

                int dataSize = samples.Count * BitsPerSample / 8;

                // RIFF header

                writer.Write(Encoding.ASCII.GetBytes("RIFF"));

                writer.Write(36 + dataSize);

                writer.Write(Encoding.ASCII.GetBytes("WAVE"));

                // fmt subchunk

                writer.Write(Encoding.ASCII.GetBytes("fmt "));

                writer.Write(16); // PCM

                writer.Write((short)1); // AudioFormat = PCM

                writer.Write((short)Channels);

                writer.Write(SampleRate);

                writer.Write(byteRate);

                writer.Write((short)(Channels * BitsPerSample / 8));

                writer.Write((short)BitsPerSample);

                // data subchunk

                writer.Write(Encoding.ASCII.GetBytes("data"));

                writer.Write(dataSize);

                foreach (short s in samples)

                { writer.Write(s); }

            }//using (var writer = new BinaryWriter(stream))

        }//public static void WriteWavFile(string filePath, List<short> samples)

    }//public class WavGenerator___Reads_GTAMPS_MONO_8000_Hz_Samples_16_bits_no_3rd_party_apis

}//namespace SAAN_FRESH___RAW_NON_APIS_WAVES_TO_SHRUTIES_COPIER_GPTS

namespace bards_wavshandlingsdontuse

{

    /// <summary>

    /// Contains utility methods for reading and writing WAV files.

    /// </summary>

    public static class WavUtils___ShrutiPitchShifterApp___BARDS___66_SHRUTIS_COPIER

    {

        // Represents the WAV file header structure.

        public struct WavHeader

        {

            public byte[] RiffId;         // "RIFF"

            public uint FileSize;         // Total file size minus 8 bytes

            public byte[] WaveId;         // "WAVE"

            public byte[] FmtId;          // "fmt "

            public uint FmtSize;          // Size of the format chunk (usually 16)

            public ushort AudioFormat;    // Audio format (1 for PCM)

            public ushort NumChannels;    // Number of channels (1 for mono, 2 for stereo)

            public uint SampleRate;       // Samples per second (e.g., 44100, 8000)

            public uint ByteRate;         // SampleRate * NumChannels * BitsPerSample / 8

            public ushort BlockAlign;     // NumChannels * BitsPerSample / 8

            public ushort BitsPerSample;  // Bits per sample (e.g., 8, 16, 24)

            public byte[] DataId;         // "data"

            public uint DataSize;         // Size of the data chunk

        }

        /// <summary>

        /// Reads a WAV file and returns its audio data as mono float samples [-1.0, 1.0].

        /// </summary>

        /// <param name="filePath">Path to the WAV file.</param>

        /// <param name="header">Output: The read WAV header.</param>

        /// <returns>A float array of mono samples, or null if an error occurs.</returns>

        public static float[] ReadWav(string filePath, out WavHeader header)

        {

            header = new WavHeader();

            byte[] wavBytes = File.ReadAllBytes(filePath);

            using (MemoryStream ms = new MemoryStream(wavBytes))

            using (BinaryReader reader = new BinaryReader(ms))

            {

                try

                {

                    // Read RIFF Chunk

                    header.RiffId = reader.ReadBytes(4);

                    if (Encoding.ASCII.GetString(header.RiffId) != "RIFF") throw new FormatException("Not a RIFF file.");

                    header.FileSize = reader.ReadUInt32();

                    header.WaveId = reader.ReadBytes(4);

                    if (Encoding.ASCII.GetString(header.WaveId) != "WAVE") throw new FormatException("Not a WAVE file.");

                    // Find and Read "fmt " Chunk

                    bool fmtChunkFound = false;

                    while (reader.BaseStream.Position < reader.BaseStream.Length)

                    {

                        byte[] chunkIdBytes = reader.ReadBytes(4);

                        string chunkId = Encoding.ASCII.GetString(chunkIdBytes);

                        uint chunkSize = reader.ReadUInt32();

                        if (chunkId == "fmt ")

                        {

                            header.FmtId = chunkIdBytes;

                            header.FmtSize = chunkSize;

                            header.AudioFormat = reader.ReadUInt16();

                            header.NumChannels = reader.ReadUInt16();

                            header.SampleRate = reader.ReadUInt32();

                            header.ByteRate = reader.ReadUInt32();

                            header.BlockAlign = reader.ReadUInt16();

                            header.BitsPerSample = reader.ReadUInt16();

                            if (header.FmtSize > 16) // Skip extra format bytes

                            {

                                reader.ReadBytes((int)(header.FmtSize - 16));

                            }

                            fmtChunkFound = true;

                            break;

                        }

                        else

                        {

                            reader.BaseStream.Seek(chunkSize, SeekOrigin.Current); // Skip other chunks

                        }

                    }

                    if (!fmtChunkFound) throw new FormatException("fmt chunk not found.");

                    if (header.AudioFormat != 1) throw new NotSupportedException("Only PCM audio format is supported.");

                    // Find and Read "data" Chunk

                    bool dataChunkFound = false;

                    while (reader.BaseStream.Position < reader.BaseStream.Length)

                    {

                        byte[] chunkIdBytes = reader.ReadBytes(4);

                        string chunkId = Encoding.ASCII.GetString(chunkIdBytes);

                        uint chunkSize = reader.ReadUInt32();

                        if (chunkId == "data")

                        {

                            header.DataId = chunkIdBytes;

                            header.DataSize = chunkSize;

                            int numSamples = (int)(header.DataSize / header.BlockAlign);

                            List<float> monoSamples = new List<float>(numSamples);

                            for (int i = 0; i < numSamples; i++)

                            {

                                float leftSample = 0;

                                float rightSample = 0;

                                if (header.BitsPerSample == 16)

                                {

                                    leftSample = reader.ReadInt16() / 32768.0f;

                                    if (header.NumChannels == 2)

                                        rightSample = reader.ReadInt16() / 32768.0f;

                                }

                                else if (header.BitsPerSample == 8)

                                {

                                    leftSample = (reader.ReadByte() - 128) / 128.0f;

                                    if (header.NumChannels == 2)

                                        rightSample = (reader.ReadByte() - 128) / 128.0f;

                                }

                                else if (header.BitsPerSample == 24)

                                {

                                    byte[] sampleBytes = reader.ReadBytes(3);

                                    int val = (sampleBytes[2] << 16) | (sampleBytes[1] << 8) | sampleBytes[0];

                                    if ((val & 0x800000) > 0) val |= ~0xFFFFFF; // Sign extend

                                    leftSample = val / 8388608.0f; // 2^23

                                    if (header.NumChannels == 2)

                                    {

                                        sampleBytes = reader.ReadBytes(3);

                                        val = (sampleBytes[2] << 16) | (sampleBytes[1] << 8) | sampleBytes[0];

                                        if ((val & 0x800000) > 0) val |= ~0xFFFFFF;

                                        rightSample = val / 8388608.0f;

                                    }

                                }

                                else if (header.BitsPerSample == 32 && header.AudioFormat == 1) // PCM 32-bit int

                                {

                                    leftSample = reader.ReadInt32() / 2147483648.0f; // 2^31

                                    if (header.NumChannels == 2)

                                        rightSample = reader.ReadInt32() / 2147483648.0f;

                                }

                                else if (header.BitsPerSample == 32 && header.AudioFormat == 3) // PCM 32-bit float

                                {

                                    leftSample = reader.ReadSingle();

                                    if (header.NumChannels == 2)

                                        rightSample = reader.ReadSingle();

                                }

                                else

                                {

                                    throw new NotSupportedException($"BitsPerSample {header.BitsPerSample} not supported for PCM.");

                                }

                                monoSamples.Add(header.NumChannels == 2 ? (leftSample + rightSample) * 0.5f : leftSample);

                            }

                            dataChunkFound = true;

                            return monoSamples.ToArray();

                        }

                        else

                        {

                            // Ensure we don't read past the end of the stream if chunkSize is too large

                            if (reader.BaseStream.Position + chunkSize > reader.BaseStream.Length)

                            {

                                break;

                            }

                            reader.BaseStream.Seek(chunkSize, SeekOrigin.Current);

                        }

                    }

                    if (!dataChunkFound) throw new FormatException("data chunk not found.");

                    return null; // Should be unreachable if logic is correct

                }

                catch (Exception ex)

                {

                    Console.WriteLine($"Error reading WAV: {ex.Message}");

                    return null;

                }

            }

        }

        /// <summary>

        /// Writes a list of float samples to a WAV file.

        /// </summary>

        /// <param name="filePath">Path to save the WAV file.</param>

        /// <param name="samples">List of float samples (expected to be mono for this application).</param>

        /// <param name="sampleRate">The sample rate for the output WAV.</param>

        /// <param name="bitsPerSample">The bit depth for the output WAV (typically 16).</param>

        public static void WriteWav(string filePath, IEnumerable<float> samples, uint sampleRate, ushort bitsPerSample)

        {

            using (FileStream fs = new FileStream(filePath, FileMode.Create))

            using (BinaryWriter writer = new BinaryWriter(fs))

            {

                ushort numChannels = 1; // Output is always mono

                int dataLength = samples.Count() * numChannels * (bitsPerSample / 8);

                // RIFF Header

                writer.Write(Encoding.ASCII.GetBytes("RIFF"));

                writer.Write(36 + dataLength); // FileSize

                writer.Write(Encoding.ASCII.GetBytes("WAVE"));

                // Format Chunk ("fmt ")

                writer.Write(Encoding.ASCII.GetBytes("fmt "));

                writer.Write(16); // FmtSize (PCM)

                writer.Write((ushort)1); // AudioFormat (PCM)

                writer.Write(numChannels);

                writer.Write(sampleRate);

                writer.Write(sampleRate * numChannels * (bitsPerSample / 8)); // ByteRate

                writer.Write((ushort)(numChannels * (bitsPerSample / 8))); // BlockAlign

                writer.Write(bitsPerSample);

                // Data Chunk ("data")

                writer.Write(Encoding.ASCII.GetBytes("data"));

                writer.Write(dataLength);

                // Write audio data

                foreach (float sampleFloat in samples)

                {

                    // Clamp sample to [-1.0, 1.0] before conversion

                    float clampedSample = Math.Max(-1.0f, Math.Min(1.0f, sampleFloat));

                    if (bitsPerSample == 16)

                    {

                        short pcmSample = (short)(clampedSample * short.MaxValue);

                        writer.Write(pcmSample);

                    }

                    else if (bitsPerSample == 8)

                    {

                        byte pcmSample = (byte)((clampedSample * 127.0f) + 128);

                        writer.Write(pcmSample);

                    }

                    // Add other bit depths if necessary

                }

            }

        }

    }

    /// <summary>

    /// Handles the core logic of pitch shifting and resampling.

    /// </summary>

    public class ShrutiPitchProcessor___bards_copier_66

    {

        private const int OutputSampleRate = 8000;

        private const ushort OutputBitsPerSample = 16; // As per requirement

        /// <summary>

        /// Processes the input WAV file to generate 66 pitch-shifted versions,

        /// concatenated into a single output WAV file.

        /// </summary>

        /// <param name="inputWavPath">Path to the input WAV file.</param>

        /// <param name="outputWavPath">Path to save the resulting WAV file.</param>

        public static void CreateShrutiVariations(string inputWavPath, string outputWavPath)

        {

            Console.WriteLine($"Reading input WAV: {inputWavPath}");

            WavUtils___ShrutiPitchShifterApp___BARDS___66_SHRUTIS_COPIER.WavHeader inputHeader;

            float[] monoInputSamples = WavUtils___ShrutiPitchShifterApp___BARDS___66_SHRUTIS_COPIER.ReadWav(inputWavPath, out inputHeader);

            if (monoInputSamples == null || monoInputSamples.Length == 0)

            {

                Console.WriteLine("Failed to read input WAV file or the file is empty.");

                return;

            }

            Console.WriteLine($"Input WAV: {inputHeader.SampleRate} Hz, {inputHeader.BitsPerSample}-bit, {(inputHeader.NumChannels == 1 ? "Mono" : "Stereo")}, Length: {monoInputSamples.Length} samples.");

            // Calculate the original duration of the input audio.

            // This duration will be maintained for each pitch-shifted segment.

            double originalDurationSeconds = (double)monoInputSamples.Length / inputHeader.SampleRate;

            // Calculate the number of samples each shifted segment should have to maintain the original duration at the OutputSampleRate.

            int targetSegmentLengthSamples = (int)(originalDurationSeconds * OutputSampleRate);

            if (targetSegmentLengthSamples == 0 && originalDurationSeconds > 0)

            {

                Console.WriteLine("Warning: Target segment length is 0, possibly due to very short input or rounding. Output might be empty or unexpected.");

            }

            else if (targetSegmentLengthSamples == 0 && originalDurationSeconds == 0)

            {

                Console.WriteLine("Input audio has zero duration. Output will be empty.");

                WavUtils___ShrutiPitchShifterApp___BARDS___66_SHRUTIS_COPIER.WriteWav(outputWavPath, new List<float>(), OutputSampleRate, OutputBitsPerSample);

                Console.WriteLine($"Empty output WAV file created at: {outputWavPath}");

                return;

            }

            List<float> allShiftedAudioSamples = new List<float>();

            Console.WriteLine($"Original duration: {originalDurationSeconds:F3} seconds.");

            Console.WriteLine($"Target segment length for each shruti: {targetSegmentLengthSamples} samples at {OutputSampleRate} Hz.");

            // Generate 66 shruti versions.

            // We'll iterate shruti offsets from -33 to +32 (inclusive), giving 66 distinct shifts.

            // shrutiOffset = -33 will be the lowest pitch (most "up" in user's description of lower frequency).

            // shrutiOffset = +32 will be the highest pitch (most "down" in user's description of higher frequency).

            int totalShrutisGenerated = 0;

            for (int shrutiOffset = -33; shrutiOffset <= 32; shrutiOffset++)

            {

                // Calculate the pitch shift factor.

                // 22.0 represents the number of shrutis in one octave.

                double pitchShiftFactor = Math.Pow(2.0, (double)shrutiOffset / 22.0);

                Console.WriteLine($"Processing shruti offset: {shrutiOffset,3} (Factor: {pitchShiftFactor:F4})...");

                // Perform resampling to achieve pitch shift while preserving duration.

                float[] shiftedSegment = ResampleAndShiftPitch(

                    monoInputSamples,

                    (int)inputHeader.SampleRate,

                    pitchShiftFactor,

                    targetSegmentLengthSamples

                );

                allShiftedAudioSamples.AddRange(shiftedSegment);

                totalShrutisGenerated++;

            }

            Console.WriteLine($"Total {totalShrutisGenerated} shruti versions generated.");

            Console.WriteLine($"Writing concatenated output WAV: {outputWavPath}");

            WavUtils___ShrutiPitchShifterApp___BARDS___66_SHRUTIS_COPIER.WriteWav(outputWavPath, allShiftedAudioSamples, OutputSampleRate, OutputBitsPerSample);

            Console.WriteLine("Processing complete.");

        }

        /// <summary>

        /// Resamples the input audio to a new pitch while attempting to preserve its original perceived duration.

        /// The output will have 'targetOutputLengthSamples' samples.

        /// </summary>

        /// <param name="inputSamples">The original mono audio samples (float -1.0 to 1.0).</param>

        /// <param name="inputSampleRate">Sample rate of the inputSamples.</param>

        /// <param name="pitchShiftFactor">Factor to shift pitch by (>1.0 higher, <1.0 lower).</param>

        /// <param name="targetOutputLengthSamples">The desired number of samples for the output segment.</param>

        /// <returns>A new float array containing the pitch-shifted and resampled audio.</returns>

        private static float[] ResampleAndShiftPitch(

            float[] inputSamples,

            int inputSampleRate,

            double pitchShiftFactor,

            int targetOutputLengthSamples)

        {

            if (inputSamples == null || inputSamples.Length == 0) return new float[0];

            if (targetOutputLengthSamples == 0) return new float[0];

            float[] outputSamples = new float[targetOutputLengthSamples];

            // Calculate the step for advancing through the input samples for each output sample.

            // This 'readStep' determines how quickly we "read" through the input audio.

            // If pitchShiftFactor > 1 (higher pitch), readStep is larger, so we move through input faster.

            // If pitchShiftFactor < 1 (lower pitch), readStep is smaller, so we move through input slower.

            // The ratio (inputSampleRate / OutputSampleRate) accounts for any difference in native sample rates.

            double readStep = pitchShiftFactor * ((double)inputSampleRate / OutputSampleRate);

            for (int i = 0; i < targetOutputLengthSamples; i++)

            {

                // Calculate the floating-point index in the input samples array.

                double currentInputIndexFloat = i * readStep;

                // Handle looping: if currentInputIndexFloat exceeds input length, it should wrap around.

                // This ensures that the output segment is filled to its targetOutputLengthSamples,

                // effectively looping the input if it's "consumed" too quickly (e.g., high pitch shift).

                currentInputIndexFloat = currentInputIndexFloat % inputSamples.Length;

                // Ensure positivity if modulo result is negative (can happen if readStep or i is negative, though not in this loop)

                if (currentInputIndexFloat < 0)

                {

                    currentInputIndexFloat += inputSamples.Length;

                }

                // Get integer indices for interpolation.

                int indexBefore = (int)Math.Floor(currentInputIndexFloat);

                int indexAfter = (indexBefore + 1);

                // Ensure indexAfter also wraps around correctly.

                if (indexAfter >= inputSamples.Length)

                {

                    indexAfter = indexAfter % inputSamples.Length;

                }

                // Handle edge case for single sample input to avoid out of bounds with indexAfter

                if (inputSamples.Length == 1)

                {

                    indexBefore = 0;

                    indexAfter = 0;

                }

                // Get the fraction for linear interpolation.

                double fraction = currentInputIndexFloat - indexBefore;

                float sampleBefore = inputSamples[indexBefore];

                // If input has only one sample, sampleAfter is the same as sampleBefore.

                float sampleAfter = (inputSamples.Length > 1) ? inputSamples[indexAfter] : sampleBefore;

                // Linear interpolation.

                outputSamples[i] = (float)(sampleBefore * (1.0 - fraction) + sampleAfter * fraction);

            }

            return outputSamples;

        }

    }//public class ShrutiPitchProcessor___bards_copier_66

    /// <summary>

    /// Main program class.

    /// </summary>

    public class Program_bards_66_copier_for_shrutis

    {

        public static void CreateShrutiVariations___Main(string wavfilesnames)

        {

            Console.WriteLine("Shruti Pitch Shifter Application");

            Console.WriteLine("---------------------------------");

            //////if (args.Length < 2)

            //////{

            //////    Console.WriteLine("Usage: ShrutiPitchShifterApp.exe <input_wav_file> <output_wav_file>");

            //////    Console.WriteLine("Example: ShrutiPitchShifterApp.exe input.wav output_shrutis.wav");

            //////    return;

            //////}

            string inputFilePath = wavfilesnames;// args[0];

            string outputFilePath = wavfilesnames + "_66_copies_bards_shrutis_copier.wav";// args[1];

            if (!File.Exists(inputFilePath))

            {

                Console.WriteLine($"Error: Input file not found: {inputFilePath}");

                return;

            }

            try

            {

                ShrutiPitchProcessor___bards_copier_66.CreateShrutiVariations(inputFilePath, outputFilePath);

            }

            catch (Exception ex)

            {

                Console.WriteLine($"An unexpected error occurred: {ex.Message}");

                Console.WriteLine($"Stack Trace: {ex.StackTrace}");

            }

        }

    }//public static class WavUtils___ShrutiPitchShifterApp___BARDS___66_SHRUTIS_COPIER

    /// 

    /////////////////////////////////////////////////////////////////////////////////////////////

    ///

}//namespace bards_wavshandlingsdontuse

No comments:

Post a Comment