-4

I have to make a simple module where I'm getting a .wav file of at most 3 seconds in length, then I have to first extract Amplitudes & then Frequency from this file. I'm doing this by creating a stream of the wave file, then reading & simultaneously adding the data into a List (but named it arr) as follows:

    do                                                                                          
    { i = wav.ReadByte(); if (i != -1) { arr.Add(i); } }                                         
    while (i != -1); Console.WriteLine(arr.Count); Console.ReadLine();   

Then starting from 44th position I'm either printing this info on the console or dumping it into a text file. Right now I'm seeing integers in the range of 0-255. I know in order to get the frequency I have to convert data from time domain to frequency domain using Fast Fourier Transform (FFT). Right now my confusions are:

  1. What does the data in my List is representing in its current form?
  2. I read a lot about Sampling the signal first, but since the file is already in a digital format so should I be worried about sampling because I think it is done during ADC only. On the other hand if it is still needed to be done, then why should I be doing that as I'm already using the whole file.
  3. Is the data in its current form is ready to for the FFT?
  4. What are the things I'm missing right now for preparing the data for FFT?

Right now I required just a naive approach for getting frequencies. Later I will add more detailed extraction of data if asked to do so.

I'm researching on the theoretical parts of sound processing for a long time now. But no book or article exactly shows the preparation of the data for the FFT. Some useful links that I found out are:
Importing a .wav file in c# and extracting the signal an array of doubles
How to get sound data sample value in c#
Storing a wav file in an array

This article supports my logic that sampling is required during ADC only
http://www.relisoft.com/science/physics/sampling.html

THE CODE BELOW WAS NOT INTENDED FOR THE PUBLIC VIEWING as right now it contains a lot of redundancies that I introduced at various points in order to get visualize the output of every step.

class MyClass
{
  static void Main(string[] args)
  {
    string path = @"C:\wav_samples\"; 
    Console.WriteLine("Select a song between 1 to 10");
    string choice = Console.ReadLine();
    string finalpath = path + choice+".wav";
    //Creating a Stream for my .WAV File
    FileStream wav = new FileStream(finalpath , FileMode.Open);

    /*Declaring the ints & the list for the storage of bytes from the Stream for FFT */
    int i;
    List<double> arr = new List<double>();



    ///////////////////////////////////////////////////////////////////////////////////////////////
    /*Reading Bytes from the .WAV File & then printing out the corresponding integer values */
    do                                                                                          
    { i = wav.ReadByte(); 
        if (i != -1)                                                                                            
        { arr.Add(i); } }                                                                       
    while (i != -1); Console.WriteLine(arr.Count); Console.ReadLine();                          
    ////////////////////////////////////////////////////////////////////////////////

    //*Removing first 44 bytes of data as they include header information & other metadata*/
    arr.RemoveRange(0, 44);

    /*No method to find the size of list hence copying the data of list to a new array*/
    double[] storage = new double[arr.Count];
    arr.CopyTo(storage);
    Console.WriteLine(storage.LongLength);

    //Dumping results on screen or in a text file
    Console.WriteLine("Do you want to get results on the screen, press 1 for yes or 2 for dumping this in a text_file in wav_sample folder");
    int a = Convert.ToInt16(Console.ReadLine());
    if (a == 1) 
    {
        for (int limit = 0; limit < storage.LongLength; limit++ )
            Console.WriteLine(arr[limit]);
    }
    if (a == 2)
    {
        System.IO.StreamWriter file = new System.IO.StreamWriter(path +            "Results.txt", true);
        for (int limit = 0; limit < storage.LongLength; limit++ )
        { file.WriteLine( storage[limit] ); }
    }
    Console.ReadLine();
  }
}
Community
  • 1
  • 1
Htaank
  • 21
  • 3
  • 1
    Can you at least give us the hexadecimal representation of the bytes you're seeing, what you're expecting to see, and what you want done with it? Because of how it's written, it's very vague. And you keep saying "FFT", but not defining what that is; if you want someone from Google to find this, you may have to actually spell out "Fast Fourier Transform" at least once." – George Stocker Oct 30 '15 at 14:08
  • 2
    *"Why are the numbers between 0 and 255"* Isn't it obvious from the `wav.ReadByte()` call? – Ron Beyer Oct 30 '15 at 14:10
  • Okay it's my bad (I guess) as I was unable to convey the clear questions. Is it okay now @GeorgeStocker. I'm editing the question & including the entire code right away. – Htaank Oct 30 '15 at 14:22

1 Answers1

0
  1. What does the data in my List is representing in its current form?

In its current form, you are getting the raw byte sequence from the file, except from the header which you are removing explicitly. The mapping between raw bytes and the corresponding data sample value is in general non-trivial, and varies according to the selected encoding scheme. See this wave file specification for more details.

  1. I read a lot about Sampling the signal first, but since the file is already in a digital format so should I be worried about sampling because I think it is done during ADC only. On the other hand if it is still needed to be done, then why should I be doing that as I'm already using the whole file.

Indeed wavefiles contain digitally sampled data, so you do not need to be worried about sampling this data. You will however very likely need to know how this data was sampled, and in particular the sampling rate used. That information is contained in the wav file header.

  1. Is the data in its current form ready for the FFT?

Simply put, no. As I indicated above, the data is still in raw byte form and using CopyTo to try and convert the raw bytes to an array of double just doesn't cut it.

  1. What are the things I'm missing right now for preparing the data for FFT?

You would need to convert the raw byte sequence into data sample values. If you were to do this yourself, you'd have to take into account the number of bits per sample, the number of channels (to deinterleave the channels if you are not dealing with mono) and the encoding format (PCM, IEEE float, etc.). Fortunately there are several libraries (such as NAudio) which can perform this decoding for you. Alternatively you may want to have a look at answers this post.

Community
  • 1
  • 1
SleuthEye
  • 14,379
  • 2
  • 32
  • 61
  • Yours is the most point2point answer & you helped me a lot to understand the missing links & clear the misconceptions as well. My module is fully ready now & is already accepted by the other members of the team. I waited for a better answer but I think not many respects the learning curve of others & behaves like they were born boys genius. Thanks to @SleuthEye for his answers & others for not answering constructively cos this tell us that decency is a rare trait. – Htaank Nov 04 '15 at 20:10