public WaveFileObject[] ToWaveChunksWithOverlaps(int ms)
        {
            double secs         = ms / 1000d;
            long   chunkSamples = (long)(header.sampleRate * secs);
            long   chunkCount   = (((header.dataSize / header.blockSize) / chunkSamples) * 2) - 2;

            WaveFileObject[] waves = new WaveFileObject[chunkCount];

            int osIndex = 0;

            // Even indexes are the original chunks
            // Odd indexes are the overlaps

            for (int i = 0; i < chunkCount / 2; i++)
            {
                for (int j = 0; j < chunkSamples; j++)
                {
                    waves[i].soundData[j] = soundData[osIndex];

                    if (i == 1)
                    {
                        waves[i].soundData[j] = soundData[osIndex - (int)(chunkSamples * .5)];
                    }

                    if (i > 1 && i < chunkCount - 2)
                    {
                        waves[i].soundData[j] = soundData[osIndex - (int)(chunkSamples * .5)];
                    }
                    osIndex++;
                }

                waves[i].header.dataSize = (uint)chunkSamples * 4;
            }
            return(waves);
        }
            public WFOTransporter(WaveFileObject obj)
            {
                this.header = obj.header;

                switch (obj.header.bit)
                {
                case 16:
                    arrShort = new short[obj.soundData.Count];
                    for (int i = 0; i < obj.soundData.Count; i++)
                    {
                        arrShort[i] = (short)obj.soundData[i];
                    }
                    break;

                case 32:
                    arrInt = new uint[obj.soundData.Count];
                    for (int i = 0; i < obj.soundData.Count; i++)
                    {
                        arrInt[i] = (uint)obj.soundData[i];
                    }
                    break;

                case 64:
                    arrDouble = new double[obj.soundData.Count];
                    for (int i = 0; i < obj.soundData.Count; i++)
                    {
                        arrDouble[i] = (double)obj.soundData[i];
                    }
                    break;

                default:
                    break;
                }
            }
        private static string ProcessMessage(string s, PinnedArray <double> pin, FftwArrayComplex com, FftwPlanRC fft)
        {
            //Deserialize and then FFTW then return datasample as json string
            WFOTransporter wav    = JsonConvert.DeserializeObject <WFOTransporter>(s);
            WaveFileObject obj    = new WaveFileObject(wav);
            DataSample     sample = new DataSample(FFT(obj, pin, com, fft));
            string         json   = JsonConvert.SerializeObject(sample);

            return(json);
        }
        static double[] FFT(WaveFileObject obj, PinnedArray <double> pin, FftwArrayComplex com, FftwPlanRC fft)
        {
            Console.WriteLine("FFT");
            double[] magnitudes;
            Console.WriteLine(obj.soundData.Count);
            double[] input = new double[obj.soundData.Count + 20286];
            Array.Clear(input, 0, input.Length);
            obj.soundData.CopyTo(input, 0);

            switch (obj.header.channels)
            {
            case 1:
                for (int i = 0; i < pin.Length; i++)
                {
                    pin[i] = input[i];
                    //Console.Write(pin[i] + " : ");
                }
                break;

            case 2:
                for (int i = 0; i < pin.Length; i++)
                {
                    pin[i] = input[i + i];
                    //Console.WriteLine(pin[i]);
                }
                break;

            default:
                break;
            }

            fft.Execute();

            magnitudes = new double[com.Length];
            for (int i = 0; i < 4000; i++)
            {
                magnitudes[i] = 10 * Math.Log10((com[i].Magnitude / inputSize) * (com[i].Magnitude / inputSize));

                /*
                 * if (10 * Math.Log10((com[i].Magnitude / inputSize) * (com[i].Magnitude / inputSize)) > 10)
                 * {
                 *  Console.WriteLine("Bin: " + i * sampleRate / com.Length + " " + 10 * Math.Log10((com[i].Magnitude / inputSize) * (com[i].Magnitude / inputSize)));
                 * }
                 */
            }

            Console.WriteLine(com.Length);
            Console.WriteLine();

            Console.WriteLine("Returning magnitudes");
            return(magnitudes);
        }
        public WaveFileObject[] ToWaveChunks(int ms)
        {
            double secs         = ms / 1000d;
            long   chunkSamples = (long)(header.sampleRate * secs);
            long   chunkCount   = (header.dataSize / header.blockSize) / chunkSamples;

            WaveFileObject[] waves = new WaveFileObject[chunkCount];

            int osIndex = 0;

            for (int i = 0; i < chunkCount; i++)
            {
                for (int j = 0; j < chunkSamples; j++)
                {
                    waves[i].soundData[j] = soundData[osIndex];
                    osIndex++;
                }

                waves[i].header.dataSize = (uint)chunkSamples * 4;
            }

            return(waves);
        }
        public static void WriteWaveFile(WaveFileObject obj, string path)
        {
            using (FileStream fs = new FileStream(path, FileMode.Create, FileAccess.Write))
                using (BinaryWriter bw = new BinaryWriter(fs))
                {
                    try
                    {
                        bw.Write(obj.header.riff);
                        bw.Write(obj.header.size);
                        bw.Write(obj.header.wavID);
                        bw.Write(obj.header.fmtID);
                        bw.Write(obj.header.fmtSize);
                        bw.Write(obj.header.format);
                        bw.Write(obj.header.channels);
                        bw.Write(obj.header.sampleRate);
                        bw.Write(obj.header.bytePerSec);
                        bw.Write(obj.header.blockSize);
                        bw.Write(obj.header.bit);
                        bw.Write(obj.header.dataID);
                        bw.Write(obj.header.dataSize);

                        if (obj.header.bit == 16)
                        {
                            for (int i = 0; i < obj.header.dataSize / obj.header.blockSize; i++)
                            {
                                if (i < obj.soundData.Count)
                                {
                                    bw.Write((short)obj.soundData[i]);
                                }
                                else
                                {
                                    bw.Write(0);
                                }
                            }
                        }

                        if (obj.header.bit == 32)
                        {
                            for (int i = 0; i < obj.header.dataSize / obj.header.blockSize; i++)
                            {
                                if (i < obj.soundData.Count)
                                {
                                    bw.Write((int)obj.soundData[i]);
                                }
                                else
                                {
                                    bw.Write(0);
                                }
                            }
                        }

                        if (obj.header.bit == 64)
                        {
                            for (int i = 0; i < obj.header.dataSize / obj.header.blockSize; i++)
                            {
                                if (i < obj.soundData.Count)
                                {
                                    bw.Write((double)obj.soundData[i]);
                                }
                                else
                                {
                                    bw.Write(0);
                                }
                            }
                        }
                    }
                    finally
                    {
                        if (bw != null)
                        {
                            bw.Close();
                        }
                        if (fs != null)
                        {
                            fs.Close();
                        }
                    }
                }
            return;
        }
        public static WaveFileObject ReadWaveFile(string path)
        {
            WaveFileObject tempObj = new WaveFileObject();

            using (FileStream fs = new FileStream(path, FileMode.Open))
                using (BinaryReader br = new BinaryReader(fs))
                {
                    try
                    {
                        tempObj.header.riff  = br.ReadBytes(4);
                        tempObj.header.size  = br.ReadUInt32();
                        tempObj.header.wavID = br.ReadBytes(4);
                        byte[] temp  = br.ReadBytes(4);
                        string chunk = System.Text.Encoding.UTF8.GetString(temp);
                        if (chunk != "fmt ")
                        {
                            byte[] junk = br.ReadBytes(36);
                        }
                        else
                        {
                            tempObj.header.fmtID = temp;
                        }
                        tempObj.header.fmtSize    = br.ReadUInt32();
                        tempObj.header.format     = br.ReadUInt16();
                        tempObj.header.channels   = br.ReadUInt16();
                        tempObj.header.sampleRate = br.ReadUInt32();
                        tempObj.header.bytePerSec = br.ReadUInt32();
                        tempObj.header.blockSize  = br.ReadUInt16();
                        tempObj.header.bit        = br.ReadUInt16();
                        tempObj.header.dataID     = br.ReadBytes(4);
                        tempObj.header.dataSize   = br.ReadUInt32();

                        if (tempObj.header.bit == 16)
                        {
                            tempObj.soundData = new List <short>();

                            for (int i = 0; i < tempObj.header.dataSize / tempObj.header.blockSize; i++)
                            {
                                tempObj.soundData.Add(br.ReadInt16());
                            }
                        }

                        if (tempObj.header.bit == 32)
                        {
                            tempObj.soundData = new List <int>();

                            for (int i = 0; i < tempObj.header.dataSize / tempObj.header.blockSize; i++)
                            {
                                tempObj.soundData.Add(br.ReadInt32());
                            }
                        }

                        if (tempObj.header.bit == 64)
                        {
                            tempObj.soundData = new List <double>();

                            for (int i = 0; i < tempObj.header.dataSize / tempObj.header.blockSize; i++)
                            {
                                tempObj.soundData.Add(br.ReadDouble());
                            }
                        }
                    }
                    catch (Exception e)
                    {
                        Console.WriteLine(e.Message);
                        throw;
                    }
                    finally
                    {
                        if (br != null)
                        {
                            br.Close();
                        }
                        if (fs != null)
                        {
                            fs.Close();
                        }
                    }
                }
            return(tempObj);
        }