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
The Signal Analyser prim
9 posts
• Page 1 of 1
The Signal Analyser prim
Hi guys and gurus!
Would some kind soul be prepared to do a quick tutorial on the Signal analyser prim? I never really understood what this is all about and where you can and can’t use it etc. I put one in a poly circuit once but nothing came out!
I’d really appreciate this and I bet others would too.
Cheers
Spogg
Would some kind soul be prepared to do a quick tutorial on the Signal analyser prim? I never really understood what this is all about and where you can and can’t use it etc. I put one in a poly circuit once but nothing came out!
I’d really appreciate this and I bet others would too.
Cheers
Spogg
-
Spogg - Posts: 3358
- Joined: Thu Nov 20, 2014 4:24 pm
- Location: Birmingham, England
Re: The Signal Analyser prim
There isn't really much to it. You define a number of samples and the signal analyser runs the section connected to it for that number of samples. The incoming samples are packed into a float array for further use.
This is not really useful in an exported plugin, because the component reference tells us this:
NOTE: You cannot connect an Analyser into a section of code that contains a Poly to Mono component.
That component is the very base of each (audio) plugin, therefore it is useful while developing in Flowstone. For example (and I guess that you made this post after you saw it used in my DSP code modules?), you can visualize the output of a poly section INSTEAD of listening to it. Sometimes seeing reveals more than hearing.
This is not really useful in an exported plugin, because the component reference tells us this:
NOTE: You cannot connect an Analyser into a section of code that contains a Poly to Mono component.
That component is the very base of each (audio) plugin, therefore it is useful while developing in Flowstone. For example (and I guess that you made this post after you saw it used in my DSP code modules?), you can visualize the output of a poly section INSTEAD of listening to it. Sometimes seeing reveals more than hearing.
"There lies the dog buried" (German saying translated literally)
- tulamide
- Posts: 2714
- Joined: Sat Jun 21, 2014 2:48 pm
- Location: Germany
Re: The Signal Analyser prim
Signal analyser basically lets you execute stream components as if they were green. It creates a sample buffer of specified size and then runs the stream on it to fill it with data when trigger is received. There are several uses to it:
1. testing out your stream code. Because it dumps all the data into an array you can see exact values your code produces. This is especially useful when testing parts of stream that are not sound. For, example whether the counter for your sampler/rompler outputs correct sequence of numbers for given pre-set values. You can even see whether your custom ADSR is properly sample aligned, because you can spot one-sample-delay in the output at a glance (good luck trying that by ear ).
2. it can be used to pre-compute arrays. Streams run significantly faster than regular green. Using just green code to fill array with precomputed values (which may depend on user-specified inputs) is utter madness. If you can make stream code that does the same thing, you can just hook it up to signal analyser and it will build that array with a single trigger. This is very useful for example when your synth procedurally generates waves instead of using wavetable. You can copy your oscillator, connect it to signal analyser and set frequency so that it will produce exactly one period in given float array... viola you can inspect the waveform without having to recreate your oscillator in green.
3. It can log number of CPU cycles taken to calculate each sample - it's a benchmark tool for streams. This is extremely useful when doing optimization. You connect the component you wish to test, let it produce some samples and you can see how fast it runs. Make changes to the component and see how performance changed. It also shows each sample individually - this is useful because stage(0) code is included in the performance of the 1st sample. Signal analyser is pretty much the only way you can test performance of stage(0).
Note: The numbers are not accurate and will fluctuate even when the same code is executed. This is because the analyser simply inserts instruction that dumps uses special assembly instruction to dump CPU clock number on the start of the code and at the end. This is sketchy, because the performance of the code will depend on various circumstances, which include (but are not limited to) Cache hits/misses, interrupts from operating system, branch prediction (speculative execution), block alignment of instruction cache, hyperthreading,.. Basically, trigger the component several times and average the values or look for minimum to get good estimate.
What signal analyser can't do:
It can't run at sample-rate. That also means it can't produce any sounds or signal (except for the float array it outputs). It doesn't work with poly streams, because those must be specially triggered by voice-to-poly prim. You can however analyse a single voice by replacing the voice-to-poly prim with green floats that output correct values (or even use mono4 pack to test up to 4 voices and how they interfere, though that should mostly be unnecessary unless your code specifically does something weird with switching SSE channels).
1. testing out your stream code. Because it dumps all the data into an array you can see exact values your code produces. This is especially useful when testing parts of stream that are not sound. For, example whether the counter for your sampler/rompler outputs correct sequence of numbers for given pre-set values. You can even see whether your custom ADSR is properly sample aligned, because you can spot one-sample-delay in the output at a glance (good luck trying that by ear ).
2. it can be used to pre-compute arrays. Streams run significantly faster than regular green. Using just green code to fill array with precomputed values (which may depend on user-specified inputs) is utter madness. If you can make stream code that does the same thing, you can just hook it up to signal analyser and it will build that array with a single trigger. This is very useful for example when your synth procedurally generates waves instead of using wavetable. You can copy your oscillator, connect it to signal analyser and set frequency so that it will produce exactly one period in given float array... viola you can inspect the waveform without having to recreate your oscillator in green.
3. It can log number of CPU cycles taken to calculate each sample - it's a benchmark tool for streams. This is extremely useful when doing optimization. You connect the component you wish to test, let it produce some samples and you can see how fast it runs. Make changes to the component and see how performance changed. It also shows each sample individually - this is useful because stage(0) code is included in the performance of the 1st sample. Signal analyser is pretty much the only way you can test performance of stage(0).
Note: The numbers are not accurate and will fluctuate even when the same code is executed. This is because the analyser simply inserts instruction that dumps uses special assembly instruction to dump CPU clock number on the start of the code and at the end. This is sketchy, because the performance of the code will depend on various circumstances, which include (but are not limited to) Cache hits/misses, interrupts from operating system, branch prediction (speculative execution), block alignment of instruction cache, hyperthreading,.. Basically, trigger the component several times and average the values or look for minimum to get good estimate.
What signal analyser can't do:
It can't run at sample-rate. That also means it can't produce any sounds or signal (except for the float array it outputs). It doesn't work with poly streams, because those must be specially triggered by voice-to-poly prim. You can however analyse a single voice by replacing the voice-to-poly prim with green floats that output correct values (or even use mono4 pack to test up to 4 voices and how they interfere, though that should mostly be unnecessary unless your code specifically does something weird with switching SSE channels).
- KG_is_back
- Posts: 1196
- Joined: Tue Oct 22, 2013 5:43 pm
- Location: Slovakia
Re: The Signal Analyser prim
Very good list of applications, KG!
There's just one odd point, you made:
"It doesn't work with poly streams, because those must be specially triggered by voice-to-poly prim."
That's not true. You can connect it to any poly section. I do it every time.
It has a poly in (not a stream in, or a mono in), which also shows its purpose. But reading it a second time, you probably meant a poly section that starts with an Oscillator? In that case you're right. You need to replace the voice-to-poly output by a fixed frequency from a green float.
There's just one odd point, you made:
"It doesn't work with poly streams, because those must be specially triggered by voice-to-poly prim."
That's not true. You can connect it to any poly section. I do it every time.
It has a poly in (not a stream in, or a mono in), which also shows its purpose. But reading it a second time, you probably meant a poly section that starts with an Oscillator? In that case you're right. You need to replace the voice-to-poly output by a fixed frequency from a green float.
"There lies the dog buried" (German saying translated literally)
- tulamide
- Posts: 2714
- Joined: Sat Jun 21, 2014 2:48 pm
- Location: Germany
Re: The Signal Analyser prim
Spogg, just in case (not sure if it helps):
If you have a look at the zero crossing detector example, you will see that I have a float for the frequency (here: 440). But it doesn't matter what you enter, as the following code always calculates the number of samples from that frequency value (2/[normalized frequency, with 1 = Nyquist], so that the analyser always only grabs exactly as many samples as one cycle of the waveform is made from.
The low frequency was chosen, because it needs more samples than a higher frequency (more samples = more points for the graph). 440 is around 100 samples, 1760 is already down to 25 samples, 110 would be 400 samples. (At 44.1 kHz sampling rate)
If you wanted to grab more than one cycle, you would just multiply the resulting NS value with the number of cycles.
This is already considered from the graphic code, so just make such changes and the display will update accordingly.
If you have a look at the zero crossing detector example, you will see that I have a float for the frequency (here: 440). But it doesn't matter what you enter, as the following code always calculates the number of samples from that frequency value (2/[normalized frequency, with 1 = Nyquist], so that the analyser always only grabs exactly as many samples as one cycle of the waveform is made from.
The low frequency was chosen, because it needs more samples than a higher frequency (more samples = more points for the graph). 440 is around 100 samples, 1760 is already down to 25 samples, 110 would be 400 samples. (At 44.1 kHz sampling rate)
If you wanted to grab more than one cycle, you would just multiply the resulting NS value with the number of cycles.
This is already considered from the graphic code, so just make such changes and the display will update accordingly.
"There lies the dog buried" (German saying translated literally)
- tulamide
- Posts: 2714
- Joined: Sat Jun 21, 2014 2:48 pm
- Location: Germany
Re: The Signal Analyser prim
Guys, thank you so much for your time and guidance on this.
I successfully applied the info in a test system and now I got the graph part.
But... I would like more clarification on the clock cycles array output. What format is the array and how do you use it in practice? The manual says it’s an array of cpu cycles used for each sample but I’m not too clear what to do with it.
Also I recall seeing CPU usage modules but can't lay my hands on one just now. Maybe someone could upload a module that they use themselves, so I could see a good working example.
Thanks for helping. This is a great community!
Spogg
I successfully applied the info in a test system and now I got the graph part.
But... I would like more clarification on the clock cycles array output. What format is the array and how do you use it in practice? The manual says it’s an array of cpu cycles used for each sample but I’m not too clear what to do with it.
Also I recall seeing CPU usage modules but can't lay my hands on one just now. Maybe someone could upload a module that they use themselves, so I could see a good working example.
Thanks for helping. This is a great community!
Spogg
-
Spogg - Posts: 3358
- Joined: Thu Nov 20, 2014 4:24 pm
- Location: Birmingham, England
Re: The Signal Analyser prim
A PC runs at a certain rate, expressed in (nowadays) GHz (Gigahertz). This is called a clock. The CPU clock is basically an oscillator. A quartz crytal is used that vibrates. At the peaks of those vibrations a tick goes out. The time between two ticks is called a clock cycle.
Flowstone does not support multi-cores, so we don't need to deal with that aspect. But, due to SSE and other hacks, a CPU can run several instructions per clock cycle. An instruction is what you see in Assembler code. Move, add, fill register, etc., are all instructions.
So, if your computer runs at, for example, 3 GHz, it has 3,000,000,000 clock cycles per second, and can run like 2 to 8 instructions per each of those cycles.
The format of the analyser is the amount of clock cycles used to calculate each single sample while it progressed through the poly section that you connected to the analyser. This can be used to optimise the section, by testing if other math/wiring/code results in a lower number of clock cycles.
It can also help to track down peaks. Some peaks are totally normal, since the cpu has to deal with the whole system in parallel, not just your schematic. Other peaks might be the result of aliasing or special cases for the used math.
The scale of the clock cycle array is open ended, since it is dependend on clock speed and execution speed. It will never be 0, but it might be a few thousands per sample. That makes it difficult to print a graph from them. If you set the max too high, you will barely see more than a flat line. If you set it too low, you will end with lots of peaks outside the graphs region.
I'm pretty sure that Martin used the clock cycles array from the analyser to determine the percentage of improvement of his oscillators over the stock ones.
Flowstone does not support multi-cores, so we don't need to deal with that aspect. But, due to SSE and other hacks, a CPU can run several instructions per clock cycle. An instruction is what you see in Assembler code. Move, add, fill register, etc., are all instructions.
So, if your computer runs at, for example, 3 GHz, it has 3,000,000,000 clock cycles per second, and can run like 2 to 8 instructions per each of those cycles.
The format of the analyser is the amount of clock cycles used to calculate each single sample while it progressed through the poly section that you connected to the analyser. This can be used to optimise the section, by testing if other math/wiring/code results in a lower number of clock cycles.
It can also help to track down peaks. Some peaks are totally normal, since the cpu has to deal with the whole system in parallel, not just your schematic. Other peaks might be the result of aliasing or special cases for the used math.
The scale of the clock cycle array is open ended, since it is dependend on clock speed and execution speed. It will never be 0, but it might be a few thousands per sample. That makes it difficult to print a graph from them. If you set the max too high, you will barely see more than a flat line. If you set it too low, you will end with lots of peaks outside the graphs region.
I'm pretty sure that Martin used the clock cycles array from the analyser to determine the percentage of improvement of his oscillators over the stock ones.
"There lies the dog buried" (German saying translated literally)
- tulamide
- Posts: 2714
- Joined: Sat Jun 21, 2014 2:48 pm
- Location: Germany
Re: The Signal Analyser prim
Spogg wrote:But... I would like more clarification on the clock cycles array output. What format is the array and how do you use it in practice? The manual says it’s an array of cpu cycles used for each sample but I’m not too clear what to do with it.
In practice this output is only useful for debugging and optimizing your code, because it gives you estimate of how much demanding your code is. Your CPU keeps track of how many clock cycles it underwent since it was turned on(https://en.wikipedia.org/wiki/Time_Stamp_Counter). One can readout that value using assembler instruction called RDTSC.
Basically what signal analyser does it inserts that instruction just before your code and just after it, executes your code and subtracts the two values. It does so once per each sample and logs the results in the array.
I personally mostly just connect the array to text prim and inspect the values manually (I eyeball the average). Here's an example where the analyser prim lets you see stuff that you can't on the CPU readout of flowstone or the taskmanager.
Connect these two codes to selector and then to soundcard output (to make them run in mono):
- Code: Select all
streamout out;
out=pow(1,1)-1; //1 to the power of one, minus one aka just computes value of zero
- Code: Select all
streamout out;
streamout out;
hop(8){
out=pow(1,1)-1;
out=pow(1,1)-1;
out=pow(1,1)-1;
out=pow(1,1)-1;
out=pow(1,1)-1;
out=pow(1,1)-1;
out=pow(1,1)-1;
out=pow(1,1)-1;
}
Your schematic should give roughly the same CPU use percentage (in taskmanager and flowstone's meter in bottom right corner). It makes sense - they both do the same operation the same amount of time on average. Now connect them to the analyser prim and look at the CPU clock array. Notice that the first one gives nearly constant values (because it computes "out=pow(1,5)-1;" exactly once per sample). Meanwhile the second one outputs just very small values, except for every 8th sample where it gives 8x larger readings than the previous schematic - that is because normally there is very little code running per sample, except every 8th sample it calculates "out=pow(1,5)-1;" 8 times.
- KG_is_back
- Posts: 1196
- Joined: Tue Oct 22, 2013 5:43 pm
- Location: Slovakia
Re: The Signal Analyser prim
That’s a brilliant explanation KG!
I set up a test like you said and now I get it and can use it.
Many thanks to you and tulamide for participating. VERY much appreciated.
Spogg
I set up a test like you said and now I get it and can use it.
Many thanks to you and tulamide for participating. VERY much appreciated.
Spogg
-
Spogg - Posts: 3358
- Joined: Thu Nov 20, 2014 4:24 pm
- Location: Birmingham, England
9 posts
• Page 1 of 1
Who is online
Users browsing this forum: No registered users and 60 guests