Support

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

FFT-based Audio Analyzer

Post any examples or modules that you want to share here

Re: FFT-based Audio Analyzer

Postby tester » Mon Jul 08, 2013 10:13 pm

MyCo wrote:
tester wrote:MyCo - quick question about "sample and hold" and arrays (recently I noticed too, that this one is helpful for greens). When building an array - is it better to add only one S&H after array builder prim, or - multiple S&H, one per input node?


Most of the time you add it at the output. When you have modules with S&H at the output and connect them in a chain, your input automatically has the S&H from the previous modules output.



Yes, but placing S&H on all inputs (separate trigger sends values to array builder) would not stop refreshing array dozens of times in uncontrolled way? I mean - in array builder, the array is set when output is connected to something else, or is refreshed each time, when somethig comes to any input?
Need to take a break? I have something right for you.
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

Postby RJHollins » Tue Jul 09, 2013 4:09 am

ah yes ...

The Trigger Tutorial v3 from trogluddite ...


This was the post I was trying to recall. Since working with SM/FS more, some of the info presented in this tutorial are just now beginning to make some sense for me. :o
:P

I've just now gone back into my current project, and have carefully added the 'S/H/Trig Limit' to parts of my schematic. I'm trying to be careful NOT to mess up the actual works, though, in the process. :| It would seem that optimizing AFTER the fact could make a mess.

I need to read this tutorial many more times, and then use these techniques very early in the schematic design.

One thing I noticed ... even though I have been using prims like the 'Changed' for certain sections ... when I went inside the 'KNOB' module, there was a LOT of triggering going on inside. I remember reading a thread talking about this, and making a consorted effort to optimize some of these pre-built modules. Again, something I may be able to follow better.

Once again ... so much to learn :roll:

I feel like we've hijacked this thread ... maybe we should start a separate one that talks optimization. There are some common routines that I find myself using [particularly loading, editing, reading ARRAYS ... it would be great to be able to post a basic example to be looked at ... that is, IF the GURUs wouldn't mind :oops:

I vote new thread :P
RJHollins
 
Posts: 1568
Joined: Thu Mar 08, 2012 7:58 pm

Re: FFT-based Audio Analyzer

Postby MyCo » Tue Jul 09, 2013 8:48 am

tester wrote:Yes, but placing S&H on all inputs (separate trigger sends values to array builder) would not stop refreshing array dozens of times in uncontrolled way? I mean - in array builder, the array is set when output is connected to something else, or is refreshed each time, when somethig comes to any input?


A trigger passed into the array builder (no matter where) leads to a trigger on the output. So if you know, that there'll be value changes on several array builder inputs at the same time, the best solution is to add an update trigger input, that is triggered explicitly. This trigger has to do a S&H on the output of the array builder.


steph_tsf wrote:After reading it, my idea was to create a few primitives, implementing a simple realtime scheduler, kind of do_forever loop in graphical format, kind of graphical flowchart, kind of Grafcet, from where you define the sequencing, and no more back trigger propagation.


This is kind of overkill. You can't avoid all backward triggers, unless you put sample&holds after each other primitive. This would propably lead into other timing problems. The easiest thing to do is building modules and examin what happens when a trigger comes in. When there are multiple triggers coming out at the same time, you should start thinking about, how to avoid that. Sometimes it is better to include explicit update trigger inputs, so no matter how much triggers come in, only the update trigger starts processing and updates the outputs.

steph_tsf wrote:Basing on this I would like to interleave (pipeline) the processing like only allowing the GDI+ to start drawing the lines, when the FFT just got calculated.


You have nearly no influence, when GDI+ draws. You can request redraws with the "redraw" primitives or the "redraw" method in Ruby, but this is just a request. FS & Windows decide when they do the requested redraw and in the meantime, maybe there is another change on your drawing data. Also there'll be a lot of other redraws, on which you don't have influence, eg. overlapping windows, or redraws on other GUI module overlapping or nearby your module. It's easier to prepare all the data you need when a value changes, and in the draw method just paint it on screen.

steph_tsf wrote:Honestly speaking, I think this is mandatory in case you are in competion with other software and platforms, more or less deterministic. There should be the beginning of a "deterministic" library, as huge bonus, containing a few primitives towards such direction. What do you think about such idea?


Well, I haven't seen any other FS-Like software that is so powerfull in GUI Design as FlowStone itself. When you know the rules, you can achieve anything. Just take a look at this:
http://www.synthmaker.co.uk/forum/viewt ... 210#p73485
(you have to enable an audio output in the schematic)

I don't know what you mean with "deterministic" library. Most of the time you need custom solutions for GUI Elements.

steph_tsf wrote:I had the exact same idea. I need to check if one can exploit the v.width and v. height coming out of the MGUI primitive that's hooked on the Ruby Draw Component. If this is the case, those two values can act as Green math coefficients.


That's not necessary, you can request the size of the view inside Ruby, with the "getViewSize" method, you can see it in action in the knobs from the toolbox. You can also react on module resize events by implementing "def viewSize(x,y,w,h)". There are those comment boxes with arrows in the "example.fsm" that comes with FS, they demonstrate the viewSize method.

steph_tsf wrote:I had another idea which is to determine if the GDI+ is smart enough, detecting when the lines that you ask to plot, are so close that they merge in the same screen pixel, in which case ideally speaking the GDI+ would omit drawing consecutive lines that nobody could see, and replace them by a grand "area plot". Have you checked this yet?


Not really, because you have to implement code to do that, and this can be overkill because GDI isn't very slow in drawing lines. But you can optimize the array that is being drawn, to only contain 2*Width_of_view*Pixels_Per_Grid Items. So there won't be much overpainting on the same pixels.

steph_tsf wrote:Actually I'm thinking redrawing the whole app, into "trenches" that I can stack, possibly using buses.


Buses can be very handy, but I try to avoid them, because you can't see directly what elements are in the bus. It doesn't increase readability.

steph_tsf wrote:This way the layout doesn't change, being 2 channels (like today), or being 4 or 66 channels (like tomorrow). Is there a performance penalty using buses? What programming style would you advise, for systems needing to process 20 identical channels, like rendering 20 channels on the screen ? Is it possible to multi-instantiate a "trench", creating N channels by only writing a few lines of code?


Buses have nearly no penalties, it is just connection grouping. The triggers on each connection through a bus has to run through to additional primitives (that actually don't do much), that's all. For the multichannel stuff I would use drawing loops and any data would be store in an array. This can be done with "draw loop" primitive or just with Ruby.

steph_tsf wrote:Meanwhile, I'm willing to keep the schematic as flat as possible, avoiding sub-modules, sub-sub-modules, etc. The optimal trade-off depends on the the screen you are using. I'm developing using a 40 inch 1920x1080 screen, and I am test-running using a 15 inch 1280x800 screen. I think we need screens, as big as possible both in pixels count, and in dimensions. Creating and debugging Flowstone schematics using a 50 inch 4K screen : that should be quite standard quite shortly.


I'm using a 2x 27" Monitor setup, but I don't like big schematics. I keep everything very modular and synchronize as much as possible to ease future changes.

steph_tsf wrote:By the way, I just created a dedicated thread about the NGX LPC4330-Xplorer you were referring. Last year I bought a few NGX LPC4330-Xplorer boards for evaluation. The issue is the ARM Cortex-M0 used as coprocessor. Last year you could not find commercially available developments systems and debuggers, easy to install, easy to configure, able to program and debug both cores together.


I've posted in the thread already. I've checked for IDEs, nearly all of them support the LPC4300. AFAIK it's just like having a M0 and another M4. I would try to use LPCXpresso, the free version has a relativly high code size limit.

steph_tsf wrote:I don't know if the situation is better now. Last year, Paul Beckman from DSP Concepts was relying on a LPC4330 for porting AudioWeaver on the Cortex-M4 platform. The DSP Concepts team managed to use the SGPIOs for outputting four emulated I2S lanes for feeding a 8-channel audio DAC. In their implementation, the SGPIO was generating the MCLK, a setup that I don't like. I prefear the Codec having its local quartz, querying the data from the DSP.


They basically used the demo setup from the example repository:
http://www.lpcware.com/content/project/ ... rted-guide

I don't know how accurate the audio clock in an LPC is (it has a dedicated one), but the error rate on an STM32F4 isn't that bad. There is an Excel sheet from ST, where you can calculate that.
On my FPGA board I used a crystal for the codec, but it was connected to the FPGA and then passed through it to the Codec. But on an FPGA this is just as easy as assigning an input to an output.
BTW: When you require many codecs, learn FPGA. With a spartan6 you could drive hundreds of codecs at the same time.

steph_tsf wrote:Let's not forget the good (old?) PIC32. Most people don't know that the newest PIC32MX1 and PIC32MX2 feature two I2S ports, bidirectional.


I don't like PICs at all. You only have 2 IDEs to choose from and none of them has a free version with acceptable code limits. I prefere Atmel, the chips are a little bit more expensive, but the IDE has no limits and is free for all AVR8,AVR32 and even ARM.
User avatar
MyCo
 
Posts: 718
Joined: Tue Jul 13, 2010 12:33 pm
Location: Germany

Re: FFT-based Audio Analyzer

Postby MegaHurtz » Tue Jul 09, 2013 11:32 am

MyCo wrote:I don't know how accurate the audio clock in an LPC is (it has a dedicated one), but the error rate on an STM32F4 isn't that bad. There is an Excel sheet from ST, where you can calculate that.


Would assume it`s just an el cheepo oscillator crystal beats the pants off.

Not shure about PIC too, can build pretty solid led and midi controllers with it. But then you`d be happy with a decade old 16F.
192k @ 8ms
User avatar
MegaHurtz
 
Posts: 105
Joined: Mon Aug 11, 2008 6:29 pm
Location: Eindhoven/Nederland

Re: FFT-based Audio Analyzer

Postby steph_tsf » Wed Jul 10, 2013 2:55 am

MyCo wrote:The easiest thing to do is building modules and examin what happens when a trigger comes in. When there are multiple triggers coming out at the same time, you should start thinking about, how to avoid that. Sometimes it is better to include explicit update trigger inputs, so no matter how much triggers come in, only the update trigger starts processing and updates the outputs.
Indeed. For this application (the FFT-based Audio Analyzer) I would feel more comfortable, elaborating a single "master sync" properly sequencing the two FFTs, the two BiQuad IIRs, and the iFFT (for the impulse response). Following such idea, an other important trigger would be elaborated, asking the Draw. Is it possible to know when the GDI+ has completed his job? This would be useful, for explicitly blocking any new timebase trigger during those computations, avoiding a sort of queue buildup in Windows. A possibility is to provide an option like a timebase that's not fixed (500ms, 200ms, 100ms, ...), but instead a timebase that's adaptative like allocating 50% of the CPU time to the pipeline consisting of the two FFTs, the two BiQuad IIRs, the iFFT (for the impulse response), and the GDI+ execution.

By the way I just endured a Sync galore syndrom, after replacing the good old FS knobs (static with gauge) by some more ambitious knobs, that I modified (wiping out MIDI), appearing to work nicely when tested in isolation. Now guess what : if I replace all 7 old knobs by new ones, the schematic takes a lot of time for loading. Moreover, just after the load gets completed, the CPU usage is about 50% continuous, with the audio disabled and everything supposed to be idling in the schematic. I guess you are going to scream, realizing what's going on. Unfortunately I'm new with FS, and unable to deal with that otherwise than reverting back to the old FS knobs. I'm attaching the .fsm, just in case.
Attachments
Trigger galore caused by new knobs.png
Trigger galore caused by new knobs.png (98.77 KiB) Viewed 25432 times
FFT-based Audio Analyzer (LV xover) 102 (many new knobs).fsm
(318.27 KiB) Downloaded 1186 times
steph_tsf
 
Posts: 249
Joined: Sun Aug 15, 2010 10:26 pm

Re: FFT-based Audio Analyzer

Postby Tronic » Wed Jul 10, 2013 5:31 am

nice job,
but you are looking at the ruby code, you're using $foo, so not suitable, it's intended as global variable.
when used that way the value is shared in all ruby instance,
then, I think opt for a simple assignment @foo is preferable for local variable,
then I noticed that many pieces of code, in draw part, can be executed only when certain values ​​change,
not each time the values ​​of the array change, this could save a lot.
Tronic
 
Posts: 539
Joined: Wed Dec 21, 2011 12:59 pm

Re: FFT-based Audio Analyzer

Postby MyCo » Wed Jul 10, 2013 9:51 am

steph_tsf wrote:if I replace all 7 old knobs by new ones, the schematic takes a lot of time for loading. Moreover, just after the load gets completed, the CPU usage is about 50% continuous, with the audio disabled and everything supposed to be idling in the schematic.


I can't confirm this. CPU is as low as always ~7% (when audio is off, and the ticker is not running). I haven't seen anything in the knobs code that could cause higher CPU usage.

Edit: OK, just found out the ~7% isn't normal on my machine... 0% is normal ;) I think I've found the problem, I've posted it in the knob thread.

Tronic wrote:you're using $foo, so not suitable, it's intended as global variable. when used that way the value is shared in all ruby instance, then, I think opt for a simple assignment @foo is preferable for local variable


Good point. This should be changed indeed, or you can run into problems when using this in several VST instances at the same time.
User avatar
MyCo
 
Posts: 718
Joined: Tue Jul 13, 2010 12:33 pm
Location: Germany

Re: FFT-based Audio Analyzer

Postby Tronic » Wed Jul 10, 2013 6:12 pm

even if I am not clear why the developer uses it, with the global variable
$intern_this
$inten_ins
$intern_outs
$intern_in
$intern_out
$intern_fout

I believe that they are part of the pre-routine, the composition of CustomModule, with classes RubyEdit, and RubyEditConnector, but
would not have the problems of multi-instance?
Tronic
 
Posts: 539
Joined: Wed Dec 21, 2011 12:59 pm

Re: FFT-based Audio Analyzer

Postby steph_tsf » Wed Jul 10, 2013 6:36 pm

I'm not sure I understand the points about the global variables. I'll come back with this.

The new compact knobs feature a "double click" reset to a "default" value.
I managed to eradicate the new knobs Trigger Galore, by redesigning them.
The CPU is now at 0% when the schematic is idling - same as the old standard FS knobs.
See the attached .fsm
The "double click" feature is handy, but dangerous when the default value is zero.
Look the red-green-blue knobs. Double click on them, make sure they all display a zero value.
Doing so we ask the D.U.T. (the BiQuad) to mute completely, generating a zero audio signal at the BiQuad output.

Clearly FS can't cope with this. The program appears to block.

There may be two different issues with such zero audio signal.
- denormalization (within the BiQuad, or later on, like causing an extremely slow FFT execution?)
- divide by zero somewhere in the data processing

Can you please tell me what is the acid test or generic toolkit for knowing :
- if the issue is denormalization - and where
- if the issue is a divide by zero - and where

Thanks
Steph
Attachments
FFT-based Audio Analyzer (new knobs).fsm
(266.8 KiB) Downloaded 1156 times
steph_tsf
 
Posts: 249
Joined: Sun Aug 15, 2010 10:26 pm

Re: FFT-based Audio Analyzer

Postby MyCo » Wed Jul 10, 2013 6:53 pm

Tronic wrote:I believe that they are part of the pre-routine, the composition of CustomModule, with classes RubyEdit, and RubyEditConnector, but
would not have the problems of multi-instance?

I don't know, haven't tested it. But maybe it is just for RubyEdit, that you currently edit?
User avatar
MyCo
 
Posts: 718
Joined: Tue Jul 13, 2010 12:33 pm
Location: Germany

PreviousNext

Return to User Examples

Who is online

Users browsing this forum: No registered users and 32 guests