If you have a problem or need to report a bug please email : support@dsprobotics.com
There are 3 sections to this support area:
DOWNLOADS: access to product manuals, support files and drivers
HELP & INFORMATION: tutorials and example files for learning or finding pre-made modules for your projects
USER FORUMS: meet with other users and exchange ideas, you can also get help and assistance here
NEW REGISTRATIONS - please contact us if you wish to register on the forum
Users are reminded of the forum rules they sign up to which prohibits any activity that violates any laws including posting material covered by copyright
FFT-based Audio Analyzer
Re: FFT-based Audio Analyzer
I've fixed the label issue in your schematic and set the knobs to zero, but it's still running without problems her. See Attachment.
- Attachments
-
- FFT-based Audio Analyzer (new knobs +MyCo2).fsm
- (246.09 KiB) Downloaded 1260 times
-
MyCo - Posts: 718
- Joined: Tue Jul 13, 2010 12:33 pm
- Location: Germany
Re: FFT-based Audio Analyzer
Looks we need wait for public FS update, to talk about issues on-the-go.
Need to take a break? I have something right for you.
Feel free to donate. Thank you for your contribution.
Feel free to donate. Thank you for your contribution.
- tester
- Posts: 1786
- Joined: Wed Jan 18, 2012 10:52 pm
- Location: Poland, internet
Re: FFT-based Audio Analyzer
@ MyCo : Thus, you fixed the "double click" knobs unreliability, and it magically appears that the schematic doesn't crash anymore when the red/green/blue pots are reset to default, outputting zero values. That's very interesting.
Was I wrong, assuming the crash was coming from "zero" audio generated within the BiQuad? Should we investigate further?
For fixing the "double click" knobs unreliability, you added a [def event i,v / redraw / end] section in the Ruby Draw Component dealing with the Readout and the Label.
This makes me realize that after one month with Flowstone, I'm still misunderstanding the Ruby Draw Component.
Let us consider the Ruby Draw Component dealing with the Readout/Label Draw.
Over there, inside the [def draw v / ... / end] section, we have the instructions for rendering the Readout field and the Label field, on screen. OK, that's s evident, isn't?
However, the important question is : when will such code execute? What are the triggers?
Seeing no explicit triggers in the above code, I would assume that the triggers are all the variables connected as input, on that particular Ruby Draw Component. The triggers should thus be : the View itself (??), the color supplied as external parameter, the float containing the Readout value, and the String containing the Label text. Am I right ?
So, you added that [def event i,v / redraw / end] section. Again, there is no trigger, explicitly named. So again, what is the trigger for such redraw? What makes it "better" or "more reliable" ?
Was I wrong, assuming the crash was coming from "zero" audio generated within the BiQuad? Should we investigate further?
For fixing the "double click" knobs unreliability, you added a [def event i,v / redraw / end] section in the Ruby Draw Component dealing with the Readout and the Label.
This makes me realize that after one month with Flowstone, I'm still misunderstanding the Ruby Draw Component.
Let us consider the Ruby Draw Component dealing with the Readout/Label Draw.
Over there, inside the [def draw v / ... / end] section, we have the instructions for rendering the Readout field and the Label field, on screen. OK, that's s evident, isn't?
However, the important question is : when will such code execute? What are the triggers?
Seeing no explicit triggers in the above code, I would assume that the triggers are all the variables connected as input, on that particular Ruby Draw Component. The triggers should thus be : the View itself (??), the color supplied as external parameter, the float containing the Readout value, and the String containing the Label text. Am I right ?
So, you added that [def event i,v / redraw / end] section. Again, there is no trigger, explicitly named. So again, what is the trigger for such redraw? What makes it "better" or "more reliable" ?
- steph_tsf
- Posts: 249
- Joined: Sun Aug 15, 2010 10:26 pm
Re: FFT-based Audio Analyzer
I haven't fixed the problem that you noticed when the 3 knobs are zero. I tried it here, and it never happened... so I can't fix a problem, that I've never seen. Maybe you PC or FS was in a weird state as you've seen the problem?
The "draw" method is executed when windows tells FlowStone that a section of it's body has to be redrawn. When your modules view is in that section, the "draw" method is called. "draw" is also called from flowstone, when the schematic is changed, or when there is an animation near the modules view, or when another module near the module view requests a redraw. And you can force a call to "draw" by calling "redraw" or by triggering a "redraw" primitive in the modules view.
"event" is called when an input receives a trigger. In "event" you can check the "i" parameter to only react on specific triggers.
This code calls "redraw" everytime an input is triggered. "redraw" tells FlowStone "Hey it's time that you call draw again" and FlowStone then calls "draw", when it has time for it.
The "draw" method is executed when windows tells FlowStone that a section of it's body has to be redrawn. When your modules view is in that section, the "draw" method is called. "draw" is also called from flowstone, when the schematic is changed, or when there is an animation near the modules view, or when another module near the module view requests a redraw. And you can force a call to "draw" by calling "redraw" or by triggering a "redraw" primitive in the modules view.
"event" is called when an input receives a trigger. In "event" you can check the "i" parameter to only react on specific triggers.
- Code: Select all
def event(i,v)
redraw
end
This code calls "redraw" everytime an input is triggered. "redraw" tells FlowStone "Hey it's time that you call draw again" and FlowStone then calls "draw", when it has time for it.
-
MyCo - Posts: 718
- Joined: Tue Jul 13, 2010 12:33 pm
- Location: Germany
Re: FFT-based Audio Analyzer
Hello MyCo, thanks for the explanation, very clear. There is indeed a huge difference between Flowstone imposing a redraw to Windows (event), and Windows deciding to (re)draw the View (windows overlap, resize, etc). Now I understand the importance of that little "event" section, triggered by any signal that's connected to the Ruby Draw Component as input, and imposing the redraw. Thanks, again.
- steph_tsf
- Posts: 249
- Joined: Sun Aug 15, 2010 10:26 pm
Re: FFT-based Audio Analyzer
I'm posting a small update, featuring the three rendering methods (True Segments, True Bars, Lines) for the Impulse Response plot. Using the "True Bars" rendering, one can better see what's happening.
There appears to be a serious issue with the iFFT primitive.
What's the exact specification of the iFFT primitive?
Can you provide this?
In order to explain the issue, I need to start from the beginning, from the FFT that's done on the time-domain signal. Say N = 32. We thus have 32 time-domain samples, that we enter into the FFT primitive. Those samples are considered as (real). The (imag) are not provided to the FFT primitive. I guess Flowstone considers all (imag) time-domain samples to equal zero. As we better do not guess at this stage, a nice helps would be that you publish the exact FFT specification of the FFT primitive. Actually in Flowstone there are two different FFT primitives. We need both specifications, as solid start.
At the output of the FFT, we get (N/2)+1 magnitude samples, and (N/2)+1 phase samples.
Actually it is a little bit more complicated than this.
In the magnitude vector, the first (DC) and last (Fs/2) data represent half the nominal bandwidth, and in the phase vector, the first (DC) data is always equal to zero. Thus, physically speaking, at the output of the FFT we only get (N/2)+ 1 - 1/2 -1/2 +(N/2)+1 - 1 = N elements of information that are guaranteed to be fluctuating, and independent.
That's a reassuring fact, as it would have been strange to observe spontaneous information generation, through a FFT computation.
Now let's face the iFFT issue.
Take the magnitude vector and the phase vector from above, and enter them into the iFFT Flowstone primitive. What would you expect as output? Same rule as above : N guaranteed independent elements of information.
Well, here is the clash : the iFFT primitive only delivers N/2 elements of information, instead of N elements of information.
The FFT-based Audio Analyzer illustrates this fully.
If you open the attached .fsm, and play with the delays, you will realize that sometimes you can see the big time-domain pulse at the beginning of the impulse response, and sometimes such pulse dissapears.
This is not a random artifact. This is not caused by Flowstone having computing speed issues.
Actually if you setup both delays to an odd value (like 15), you will always see the big time-domain pulse at the beginning of the impulse response.
On the other hand, if you introduce even numbers in the delays (like 14 or 16), the pulse you just looked at, won't be rendered anymore.
Any idea ?
There appears to be a serious issue with the iFFT primitive.
What's the exact specification of the iFFT primitive?
Can you provide this?
In order to explain the issue, I need to start from the beginning, from the FFT that's done on the time-domain signal. Say N = 32. We thus have 32 time-domain samples, that we enter into the FFT primitive. Those samples are considered as (real). The (imag) are not provided to the FFT primitive. I guess Flowstone considers all (imag) time-domain samples to equal zero. As we better do not guess at this stage, a nice helps would be that you publish the exact FFT specification of the FFT primitive. Actually in Flowstone there are two different FFT primitives. We need both specifications, as solid start.
At the output of the FFT, we get (N/2)+1 magnitude samples, and (N/2)+1 phase samples.
Actually it is a little bit more complicated than this.
In the magnitude vector, the first (DC) and last (Fs/2) data represent half the nominal bandwidth, and in the phase vector, the first (DC) data is always equal to zero. Thus, physically speaking, at the output of the FFT we only get (N/2)+ 1 - 1/2 -1/2 +(N/2)+1 - 1 = N elements of information that are guaranteed to be fluctuating, and independent.
That's a reassuring fact, as it would have been strange to observe spontaneous information generation, through a FFT computation.
Now let's face the iFFT issue.
Take the magnitude vector and the phase vector from above, and enter them into the iFFT Flowstone primitive. What would you expect as output? Same rule as above : N guaranteed independent elements of information.
Well, here is the clash : the iFFT primitive only delivers N/2 elements of information, instead of N elements of information.
The FFT-based Audio Analyzer illustrates this fully.
If you open the attached .fsm, and play with the delays, you will realize that sometimes you can see the big time-domain pulse at the beginning of the impulse response, and sometimes such pulse dissapears.
This is not a random artifact. This is not caused by Flowstone having computing speed issues.
Actually if you setup both delays to an odd value (like 15), you will always see the big time-domain pulse at the beginning of the impulse response.
On the other hand, if you introduce even numbers in the delays (like 14 or 16), the pulse you just looked at, won't be rendered anymore.
Any idea ?
- Attachments
-
- FFT-based Audio Analyzer.fsm
- (61.87 KiB) Downloaded 1337 times
- steph_tsf
- Posts: 249
- Joined: Sun Aug 15, 2010 10:26 pm
Re: FFT-based Audio Analyzer
The iFFT primitive requires a full FFT signal as input not only the real frequencies part. At the moment you do:
audio -> FFT -> toPhase&toMag -> lower half section -> fromPhase&fromMag -> iFFT
The problem is the part "lower half section", it removes the non-real frequencies (the mirrored image) from the array. The FFT/iFFT is as I said earlier a very straight forward implementation. It doesn't fill the mirrored part itself and also doesn't zero pad. So the user has to provide a valid input.
audio -> FFT -> toPhase&toMag -> lower half section -> fromPhase&fromMag -> iFFT
The problem is the part "lower half section", it removes the non-real frequencies (the mirrored image) from the array. The FFT/iFFT is as I said earlier a very straight forward implementation. It doesn't fill the mirrored part itself and also doesn't zero pad. So the user has to provide a valid input.
-
MyCo - Posts: 718
- Joined: Tue Jul 13, 2010 12:33 pm
- Location: Germany
Re: FFT-based Audio Analyzer
Hi MyCo, okay, this is the usual garbage in / garbage out phenomenon. I'll rewire the inputs of the complex FFT, and reconsider the useful array lenghts deliverd by the complex FFT. Doing so I hope to get the 100% time-domain info at the iFFT output, instead of the 50% I'm getting now. Thanks.
- steph_tsf
- Posts: 249
- Joined: Sun Aug 15, 2010 10:26 pm
Re: FFT-based Audio Analyzer
This is the update following MyCo advice, exploiting the full FFT data for feeding the iFFT that's needed for computing all time-domain samples of the impulse response. This time, providing N (real) time-domain samples to the FFT, we get again N (real) time-domain samples after the iFFT.
By the way, that issue with zero audio is still there.
It was difficult to spot, as it only happened when Auto gain is selected (impulse response).
I went looking the min/max detection code.
The imp array contains the time-domain response.
We need to apply Auto gain on it.
I'm using Ruby .minmax for determining the extremes.
I'm using Ruby .abs for taking the absolute value of the min and the max found above.
I'm using Ruby .max, for electing the big value, and such value drives the Autogain, as denominator.
There may be an issue with Ruby .minmax or Ruby .max when comparing two values that are the same. This is the case when the audio equals zero. I have the impression that in such case, Ruby is issuing a soft non-blocking warning. Or perhaps a warning gets issued in .abs when taking the absolute value of zero?
Amazing to realize that after doing FFTs, iFFTs, graphing, sequencing, etc. a remaining difficulty is to search the maximum absolute value in a vector, without triggering warnings in some particular cases.
By the way, I used here and there quite randomly in the .fsm a few global variables without realizing potential consequences of this. Can you tell me as general rule in Flowstone, when local variables (starting with @) are better compared to global variables(starting with $), and what are the limitations of simple variables (without any prefix)?
Thanks
Steph
By the way, that issue with zero audio is still there.
It was difficult to spot, as it only happened when Auto gain is selected (impulse response).
I went looking the min/max detection code.
The imp array contains the time-domain response.
We need to apply Auto gain on it.
I'm using Ruby .minmax for determining the extremes.
I'm using Ruby .abs for taking the absolute value of the min and the max found above.
I'm using Ruby .max, for electing the big value, and such value drives the Autogain, as denominator.
There may be an issue with Ruby .minmax or Ruby .max when comparing two values that are the same. This is the case when the audio equals zero. I have the impression that in such case, Ruby is issuing a soft non-blocking warning. Or perhaps a warning gets issued in .abs when taking the absolute value of zero?
- Code: Select all
if @imp_autogain then
return if (@imp.nil?)
tmp = []
tmp = @imp.minmax
tmp[0] = tmp[0].abs + 0.0000001
tmp[1] = tmp[1].abs + 0.0000001
max = tmp.max
if max <= 0.000001 then max = 0.000001 end
fillfactor = 0.75
$y_gain = fillfactor / max
end
Amazing to realize that after doing FFTs, iFFTs, graphing, sequencing, etc. a remaining difficulty is to search the maximum absolute value in a vector, without triggering warnings in some particular cases.
By the way, I used here and there quite randomly in the .fsm a few global variables without realizing potential consequences of this. Can you tell me as general rule in Flowstone, when local variables (starting with @) are better compared to global variables(starting with $), and what are the limitations of simple variables (without any prefix)?
Thanks
Steph
- Attachments
-
- FFT-based Audio Analyzer.fsm
- (368.93 KiB) Downloaded 1243 times
- steph_tsf
- Posts: 249
- Joined: Sun Aug 15, 2010 10:26 pm
Re: FFT-based Audio Analyzer
The reason for the problem is because the @imp array contains non-real numbers. In FS it is called #IND and in Ruby it is called NaN.
You have to validate @imp array first, like this:
and after that you have to use "newimp" instead of @imp. This is not very elegant, though... but it's the shortest solution, else you have to check everytime you read from @imp, if the value you read is valid.
Maybe you also need a fix for infinite and -infinite... but don't know if that could crash your code.
You have to validate @imp array first, like this:
- Code: Select all
newimp = @imp.map{|x| x.nan? ? 0 : x}
and after that you have to use "newimp" instead of @imp. This is not very elegant, though... but it's the shortest solution, else you have to check everytime you read from @imp, if the value you read is valid.
Maybe you also need a fix for infinite and -infinite... but don't know if that could crash your code.
-
MyCo - Posts: 718
- Joined: Tue Jul 13, 2010 12:33 pm
- Location: Germany
Who is online
Users browsing this forum: No registered users and 37 guests