C# FFT Troubleshooting: Sampling at 44100 Hz, 16384 Samples

  • Context: C# 
  • Thread starter Thread starter btb4198
  • Start date Start date
  • Tags Tags
    Fft
Click For Summary

Discussion Overview

The discussion revolves around troubleshooting issues with a Fast Fourier Transform (FFT) implementation in C#. Participants are examining the accuracy of FFT results when sampling audio data at a rate of 44100 Hz using 16384 samples. The conversation includes comparisons with MATLAB outputs and considerations of data handling techniques.

Discussion Character

  • Technical explanation
  • Debate/contested
  • Mathematical reasoning

Main Points Raised

  • One participant reports discrepancies between their FFT results and those obtained from MATLAB, suggesting the need for troubleshooting.
  • Questions arise about the method of comparison with MATLAB, including whether a sine wave or mixed sound source was used.
  • Another participant inquires about windowing the sample data before applying the FFT, referencing the importance of this step.
  • Concerns are raised regarding the nature of the input signal, with suggestions to test with known sine waves to verify the FFT implementation.
  • Participants discuss the potential for under-sampling issues, with one suggesting that the samples might be 8-bit instead of 16-bit or that stereo data is being captured instead of mono.
  • There are mentions of specific frequencies tested and the resulting peaks observed in the FFT output, indicating possible issues with capturing the correct signal.
  • One participant shares code snippets related to how samples are processed and questions the correctness of their frequency calculations.
  • Another participant suggests filtering out noise based on magnitude thresholds, leading to discussions about how to handle small magnitude values in the FFT results.

Areas of Agreement / Disagreement

Participants express varying opinions on the causes of the discrepancies in FFT results, with no consensus reached on the specific issues affecting the accuracy of the output. Multiple competing views regarding the handling of audio data and FFT implementation remain present throughout the discussion.

Contextual Notes

Participants mention the importance of ensuring correct data types (e.g., 16-bit vs. 8-bit samples) and the potential impact of windowing on FFT results. There are unresolved questions about the nature of the input signal and how it affects the FFT output.

Who May Find This Useful

This discussion may be useful for software developers working with audio signal processing, particularly those implementing FFT algorithms in C# or comparing results with established tools like MATLAB.

btb4198
Messages
570
Reaction score
10
I am trying to make this



but my FFT is not getting close enough to the right Values

I am Sampling at a 44100 Hz rate

and I am sending

16384 samples to the fft at a time

but it is not close

I have attach a pic

what should i do?
I know the FFT work.. because i compared it to mat lab...

so how can I troubleshoot this?
 

Attachments

  • text1.jpg
    text1.jpg
    50.8 KB · Views: 560
Last edited by a moderator:
Technology news on Phys.org
How did you compare to Matlab? By giving both a simple n cycle sine wave?
What happens if you give both the same 16k sampled mixed sound source?
In what way is the answer then not close? What does Matlab give and what does your code give?
Are you windowing your sample data before FFT? http://en.wikipedia.org/wiki/Window_function
 
I have posting on my other fft threads... but I just enter sinewaves and just buffer with samples, both in mat lab and in my program.

if you look at my picture you will see that
youtube is outputting a frequency of 117Hz

but my programs highest peek is over 60 then 70.
that is not right
 
no I am not windowing my sample before the FFT...
the FFT gets raw data

Code:
 for (int index = 0; index < 32768; index += 2)
            {

                short sample = (short)((buffer[index + 1] << 8) |
                                        buffer[index + 0]);

                float sample32 = sample / 32768f;
                buffer1[tempint] = (double)sample32;
                tempint++;

            }

I am Sampling at a 44100 Hz rate

and I am sending

16384 samples to the fft at a time
 
I presume that tempint has been initialized to zero.
Also, how did you fill that buffer? Was it with a WAV file?
 
no it is from a microphone ..
and yes tempint is.
I am writing this in C#
 
btb4198 said:
no it is from a microphone ..
and yes tempint is.
I am writing this in C#
What evidence do you have that you are successfully sampling amplitude information from the microphone, and that it contains a sine waveform of significant amplitude.

As a test, have you tried putting samples into array that are generated from the sin() function?
 
it is not a sine waveform... should it be ?

if you send me you email
I can send you my program
 
btb4198 said:
it is not a sine waveform... should it be ?

if you send me you email
I can send you my program
I didn't look at the youtube video, but the frame gram you showed as an attachment showed a sine wave. Also, a sine wave is a good test pattern for an FFT exercise since it should show a single spike at the corresponding wavelength.

I guessing that you played the youtube video, picked up the sound with the mic, and tried to capture a segment of it at 44.1KHz.

If that's about what you did, then I would definitely put a known sine wave (computed from the sin() function) into your FFT subroutine or tool to verify that you have that part of the problem working. Then work on getting good data from your microphone to "buffer".

I don't want to look at that much of your code. You get to do all the real work.
 
  • #10
sorry I miss understood you.

yes the youtube video is a sinewave
if you go to youtube and look up "high frequency" you will see it
 
  • #11
also I have tested the fft by enter in a know sinewave and out putting the answered...
that works,
I have also compared my fft to MATLAB and my fft works for 2^n number of samples
 
  • #12
btb4198 said:
also I have tested the fft by enter in a know sinewave and out putting the answered...
that works,
I have also compared my fft to MATLAB and my fft works for 2^n number of samples
So it's really looking as though the problem is getting the signal you want through the microphone to "buffer".
 
  • #13
yeah I guess
 
  • #14
btb4198 said:
yeah I guess
Supposedly your collecting at 44.1KHz. So find a tone that's about 5KHz, capture that sound with you mic, and then print out the first 20 values in buffer. If all is working well, you will see about two full sine waves.

If you see something else, you're not capturing correctly.

For example:
onlinetonegenerator.com/?freq=5000

In general, you want to be able to test isolated parts of your code so that you can determine where the problem is.
 
  • #15
ok i can't add the right picture on here... the forum will not let me ...

but this is how it looks
the highest peek is 2500
which is haft of 5000
 

Attachments

  • picnow.jpg
    picnow.jpg
    47.7 KB · Views: 642
  • #16
this is how the sample input looks

it repeats
 

Attachments

  • test.jpg
    test.jpg
    22 KB · Views: 625
  • #17
I saw this one too :
test2.jpg
 
  • #18
also this
test3.jpg
 
  • #19
I'm guessing there's something wrong with the raw data charts - probably some sort of under-sampling issue.

The fact that you're getting a spike at 2500Hz, with harmonics at 2500Hz intervals is very encouraging. It means that some rendition of the sound is making to your buffer.

My guess is that the samples are actually 8-bit samples, not 16-bit - or that you are capturing stereo instead on mono.
 
  • #20
well this is weird : I use that same site you sent to me and I did 4000 Hz
and the highest point is 2000Hz

I also did 3000Hz from that same site
and the highest point I get is 1499.249

I also did 10,000
but this is what i got :
test4.jpg


any ideas as to why?
 
  • #21
Code:
            PointPairList list = new PointPairList();
            PointPairList list2 = new PointPairList();
            byte[] buffer = e.Buffer;
            int bytesRecorded = e.BytesRecorded;
            points = new RollingPointPairList(32768 / 2);
            buffer1 = new double[(32768 / 2)];
            int tempint = 0;
            for (int index = 0; index < 32768; index += 2)
            {

                buffer1[tempint] = ((buffer[index + 1] << 8) |
                                        buffer[index + 0]);
                tempint++;

            }

            DSP = new DSPclass(buffer1, 44100);
            DSP.FFT1();
is it a 16 bit sample and I break into one double
 
  • #22
ok
here is my code to print out the fft as a frequency
N ( the number of samples) = 16384
Fs ( the sampling frequency) = 44100 Hz
R( R is a int) = 16384



Code:
        public int frequencies(double[] freq, double [] Ctemp)
        {
            
            int counter = 0;
            for (int i = 0; i < R; i++)
                    {
                        if (((i / N) * Fs) >= (Fs / 2)) // nyquist 
                        {
                            return counter;

                        }
                        if (Math.Abs(F[i].Magnitude) > 100)
                        {
                            freq[counter] = (i / N) * Fs;
                            Ctemp[counter] = F[i].Magnitude;
                            counter++;

                        }
                    }
            return counter;  
        }
is that right ?
Frequency = (bin / N) * Fs?
and I should be using the Magnitude right ?
oh this is all c#
 
  • #23
If the magnitude is less than 100, you skip the frequency value?
I'm guessing that you are trying to treat all small magnitudes as noise. If that's the case, you should set Ctemp[counter] to 0.

Since both i and N are integers and i<N, i/N will always be zero. So freq[counter] is always zero.
 
  • #24
yes i am treating all the small magnitudes as Noise .
should it be higher than 100?

no , I get values for my counter
but is Frequency = (bin / N) * Fs?
is that right ?
 
  • #25
so I just tried this :
Code:
 for (int index = 0; index < 32768; index++)
            {
                buffer1[tempint] = buffer[index]; 
                tempint++;
            }
and the fft is off
so maybe it really is 16bits

do anyone know anything that might help me?
 
  • #26
ok if I just do * 2 to my out put it works...
I just do not know why...
 
  • #27
It's okay to filter noise, but this is how you would do it:

Code:
    public int frequencies(double[] freq, double [] Ctemp)
    {
        int counter = 0;
        for (int i = 0; i < R; i++)
        {
            freq[counter] = (i / N) * Fs;
            if (Math.Abs(F[i].Magnitude) > 100)
            {
                Ctemp[counter] = F[i].Magnitude;
            } else {
                Ctemp[counter] = 0;
            }
            counter++;
        }
        return counter;
    }
 
  • #28
the way I am going is...
I do not keep the once with a magnitude > 100
but I am thinking about making it 1000
 
  • #29
btb4198 said:
I also did 10,000
but this is what i got :
View attachment 66066


btb4198 said:
Code:
            int tempint = 0;
            for (int index = 0; index < 32768; index += 2)
            {

                buffer1[tempint] = ((buffer[index + 1] << 8) |
                                        buffer[index + 0]);
                tempint++;

            }

I think the problem is that the audio data is signed 16 bit integers (between -32768 and +32767) but your code is converting them to unsigned integers between 0 and 65535.

Try this:
Code:
            int tempint = 0;
            for (int index = 0; index < 32768; index += 2)
            {

                buffer1[tempint] = ((buffer[index + 1] << 8) |
                                        buffer[index + 0]);
                if (buffer1[tempint] > 32767)
                    buffer1[tempint] = buffer1[tempint] - 65536;
                tempint++;

            }

If would be better just to declare buffer as an array of 16-bit signed ints instead of unsigned 8-bit bytes, then you can just copy the data from buffer to your double array buffer1.
 
  • #30
ok you where right about between -32768 and +32767
the ftt is a lot less noisy...
and the print out of the samples look a lot better ...

however, I am still getting half the Frequencies...
I can just do * by 2 at the very end and get the right Frequencies but I really want to know why it is doing this
 

Similar threads

  • · Replies 6 ·
Replies
6
Views
2K
Replies
3
Views
3K
  • · Replies 3 ·
Replies
3
Views
4K
  • · Replies 1 ·
Replies
1
Views
3K
  • · Replies 10 ·
Replies
10
Views
3K
  • · Replies 0 ·
Replies
0
Views
2K
  • · Replies 6 ·
Replies
6
Views
2K
  • · Replies 10 ·
Replies
10
Views
3K
  • · Replies 4 ·
Replies
4
Views
2K
  • · Replies 12 ·
Replies
12
Views
2K