Exemplo n.º 1
0
        /// <summary>Reads a wave file and keep reporting the progress.</summary>
        /// <param name="sender">The control that the action is for</param>
        /// <param name="e">The arguments of the event</param>
        /// <returns></returns>
        public void ReadWaveFile()
        {
            // Read WAV file and write FFT file
            using (BinaryReader reader = new BinaryReader(new FileStream(filename, FileMode.Open)))
                using (BinaryWriter fft = new BinaryWriter(File.Open(filename + ".fft.dat", FileMode.Create)))
                {
                    this.format = ReadHeader(reader);
                    if (format.BitsPerSample != 8 && format.BitsPerSample != 16)
                    {
                        return;
                    }

                    int bytesPerSample = format.BitsPerSample / 8;
                    int dataLength     = reader.ReadInt32();
                    int countSamples   = dataLength / bytesPerSample;

                    // Throw interlude before recording
                    int di  = 5; // every second, take 2205 data or every 5 data take 1 data
                    int b   = reader.ReadByte();
                    int adv = 1;
                    while (b > 120 && b < 140)
                    {
                        reader.ReadBytes(di - 1);
                        b    = reader.ReadByte();
                        adv += di;
                    }
                    countSamples = countSamples - adv;

                    float[] channelSamples16 = new float[framelen]; //buffer data per 1 frame

                    int si = countSamples / (samples.Length * di);
                    if (countSamples % (si * (samples.Length * di)) != 0)
                    {
                        si++;
                    }

                    int overlap = (int)(0 * framelen);

                    float[] sampelOverlap = null;
                    if (overlap > 0)
                    {
                        sampelOverlap = new float[overlap];
                    }
                    int nbsi = (framelen - overlap) / si;
                    while (nbsi == 0)
                    {
                        si   = si - framelen;
                        nbsi = (framelen - overlap) / si;
                    }
                    if ((framelen - overlap) % (nbsi * si) != 0)
                    {
                        nbsi++;
                    }
                    countSamples = countSamples - (overlap * di);
                    nbframe      = countSamples / ((framelen - overlap) * di);
                    // (countSamples-overlap) because at the begining we already read the data before entering region 'Read Data'
                    if (countSamples % ((framelen - overlap) * di) != 0)
                    {
                        nbframe += 1;
                    }
                    A = new float[fftPoint / 2]; //buffer hasil fft 1 frame (output applyFFT)
                    int   channelSamplesIndex = 0;
                    int   endloop             = 0;
                    byte  channelSample8;
                    Int16 sample16;
                    int   endfft = 0;
                    firFilter.FreqFrom = 500;
                    firFilter.FreqTo   = 4000;
                    firFilter.CalculateCoefficients(FFT.Algorithm.Blackman, FFT.FilterType.BandPass);

                    // Read overlapped sample
                    channelSamplesIndex = 0;
                    if (format.BitsPerSample == 8)
                    {
                        for (int sampleIndex = 0; sampleIndex < overlap; sampleIndex++)
                        {
                            channelSample8 = reader.ReadByte();
                            sampelOverlap[channelSamplesIndex] = (short)((a[(short)(channelSample8)]) << 8);
                            channelSamplesIndex++;
                            reader.ReadBytes(di - 1);
                            sampleIndex += di - 1;
                        }
                    }
                    else
                    {
                        for (int sampleIndex = 0; sampleIndex < overlap; sampleIndex++)
                        {
                            sample16 = reader.ReadInt16();
                            sampelOverlap[channelSamplesIndex] = reader.ReadInt16();
                            channelSamplesIndex++;
                            reader.ReadBytes(2 * (di - 1));
                            sampleIndex += di - 1;
                        }
                    }

                    // Set the progress value
                    int   factor         = 100;
                    float dprogressvalue = (float)factor / (float)nbframe;
                    while ((int)dprogressvalue >= 100 || (int)dprogressvalue == 0)
                    {
                        factor        *= 10;
                        dprogressvalue = factor / nbframe;
                    }

                    for (int i = 0; i < nbframe; i++)
                    {
                        // Get overlapped component
                        for (int sampleIndex = 0; sampleIndex < overlap; sampleIndex++)
                        {
                            channelSamples16[sampleIndex] = sampelOverlap[sampleIndex];
                        }
                        endloop = di * (channelSamples16.Length - overlap);
                        if (i == (nbframe - 1)) // if it's the last loop, the buffer may not be used as a whole
                        {
                            endloop = countSamples % endloop;
                        }
                        channelSamplesIndex = overlap;

                        #region Read Data

                        if (format.BitsPerSample == 8)
                        {
                            try
                            {
                                for (int sampleIndex = overlap; sampleIndex < (endloop + overlap) && channelSamplesIndex < framelen; sampleIndex++)
                                {
                                    channelSample8 = reader.ReadByte();
                                    channelSamples16[channelSamplesIndex] = (short)((a[(short)(channelSample8)]) << 8);
                                    channelSamplesIndex++;
                                    reader.ReadBytes(di - 1);
                                    sampleIndex += di - 1;
                                }
                            }
                            catch { }
                        }
                        else
                        {
                            try
                            {
                                for (int sampleIndex = 0; sampleIndex < countSamples && channelSamplesIndex < (framelen); sampleIndex++)
                                {
                                    sample16 = reader.ReadInt16();
                                    channelSamples16[channelSamplesIndex] = reader.ReadInt16();
                                    channelSamplesIndex++;
                                    reader.ReadBytes(2 * (di - 1));
                                    sampleIndex += di - 1;
                                }
                            }
                            catch { }
                        }

                        #endregion // Read Data

                        // Get data to be displayed
                        for (int j = 0; j < nbsi && (j + i * nbsi) < samples.Length; j++)
                        {
                            samples[j + i * nbsi] = (short)channelSamples16[j * si];
                        }

                        if (i != (nbframe - 1))
                        {
                            // Update overlapped component
                            for (int sampleIndex = framelen - overlap; sampleIndex < framelen; sampleIndex++)
                            {
                                sampelOverlap[sampleIndex - (framelen - overlap)] = channelSamples16[sampleIndex];
                            }
                        }

                        // Band pass the signal filter
                        FilterCalculation(ref channelSamples16, FFT.FilterType.BandPass);

                        ApplyFFT(channelSamples16);

                        endfft = fftPoint / 2;

                        if (channelSamplesIndex != 0)
                        {
                            if (endfft > channelSamplesIndex / 2)
                            {
                                endfft = channelSamplesIndex / 2;
                            }
                        }
                        for (int j = 1; j < endfft; j++)
                        {
                            fft.Write((Int16)A[j]);
                        }
                        fft.Write(-9999);
                    }

                    reader.Close();
                    fft.Close();
                }
        }