Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Setting axis limits in 3rd party visualizers for FFT Plot and changing FFT Size #120

Closed
BryanT423 opened this issue Apr 2, 2021 · 5 comments

Comments

@BryanT423
Copy link

Hello all, I have 2 relatively, basic questions regarding an FFT plot:

How can I change the FFT size instead of using the default 512? I see the private readonly int fftSize in the FastFourierTransform.cs class, but how can I manually set this value?

Also, how do I change the x-axis limits for my 3rd party visualizer chart? I’ve been going through the inheritance hierarchy starting from the CartesianChartVisualizationObject.cs class but I can’t seem to find what I need to set the x-axis limits. If someone could point me to where these controls are and explain how they figured out where the location is, I would greatly appreciate it.

@BryanT423 BryanT423 changed the title Setting axis limits in 3rd party visualizers for FFT Plot and changing FFT Size. Setting axis limits in 3rd party visualizers for FFT Plot and changing FFT Size Apr 2, 2021
@sandrist
Copy link
Contributor

sandrist commented Apr 6, 2021

For your first question, take a look inside the constructor for AcousticFeatureExtractor. Under the hood, this class instantiates and wires together a number of audio processing components, but the FFT component specifically is instantiated on line 86. It takes in fftSize and frameSize as parameters. The quickest way to move ahead could be to simply change the code on that line and pass in whatever parameter you'd like, rather than using the one computed earlier in the constructor (lines 49-55). It's up to you of course to ensure that the parameter is a sensible one.

Another solution would be to just use the FFT component in your program, rather than AcousticFeatureExtractor. However, you will have to also invoke the right set of components and operators to convert your audio stream (IProducer<AudioBuffer>) into a stream of float arrays (IProducer<float[]>) to pass to the FFT. You can again look to what AcousticFeatureExtractor does for inspiration (line 60 - 72), where the input audio stream is converted to byte array, then frame shifted, then converted to float array, then dithered (optional), and then a Hanning window is applied.

@danbohus will follow up on your second question.

@danbohus
Copy link
Contributor

danbohus commented Apr 6, 2021

Re: axis limits, to separate out this topic from the fftSize parameter question above, and also because it represents a good opportunity for community contributions, I've created another issue - see #122 and labeled it help-wanted. Please have a look, and if you have additional questions re: how to go about setting xmin, xmax, please add them to that topic. If you decide to pursue this extension of the existing visualizer with the goal of creating a pull request, also please let us know on that thread.

@BryanT423
Copy link
Author

Hello, I tried to increase the fftSize and frameSize within the AcousticFeaturesExtractor constructor but it did not change anything. So I am trying to write use the FFT.cs directly in my main program.

How do I set my audio as the input data to perform the FFT on? It is not taking the FFT with my current code.

            // Call an audio file
            var source = new WaveFileAudioSource(p, "6250Hz.wav");
            source.Write("Audio", store);
            
            // Perform FFT
            var ffTransform = new FFT(p, 1024, 1000)                    
                .Select(t =>
                {
                    var Values = new List<(string, double)>();
                    for (int i = 0; i < t.Length; i++)
                    {
                        Values.Add((i.ToString(), Math.Abs(t[i])));
                    }
                    Console.WriteLine("Length = " + Values.Count);
                    return Values;

                })
                .Write("FFT", store);

@sandrist
Copy link
Contributor

I'm curious why changing the code in that constructor didn't result in any actual change...

But if you'd like to use the FFT operator directly, for now, look at how the audio stream is transformed in the AcousticFeaturesExtractor component before being passed to the FFT operator. You'll need to copy those transformations up into your app. Basically the audio stream needs to be transformed to a float array. It looks like we first transform to a byte array, then do a frame shift, then convert to float, then apply a hanning window, in this case I would copy this code into your app and then set the parameters in whatever way makes sense for your audio stream (e.g., look at how bytesPerFrame, bytesPerFrameShift, AvgBytesPerSec, etc., get set). You can of course choose to copy which steps in this transformation make the most sense for your scenario.

// Construct overlapping frames of audio samples to operate on
var windowedFrame = this.inAudio.ToByteArray().FrameShift(bytesPerFrame, bytesPerFrameShift, configuration.InputFormat.AvgBytesPerSec);

// Convert the frame to floating point
var frame = windowedFrame.ToFloat(configuration.InputFormat);

// Apply Hanning window
frame = frame.HanningWindow(frameSize);

@BryanT423
Copy link
Author

I finally got it to work, thank you. I basically imported the AcousticFeaturesExtractor lines 43 - 57, as well as what you mentioned above, to my main program and manually changed the int frameSize to a value that I wanted.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants