Old 25th June 2012, 18:07   #1
Donone
Junior Member
 
Join Date: Nov 2011
Posts: 39
Frequency bands for bass, mid & treb

I understand that Bass, Mid & Treb are in effect the volume values. Is there any way to filter the frequency ranges of each?

My thinking is that it might be useful to be able to set the bands and even have a gap between them in order to better isolate each.
Donone is offline   Reply With Quote
Old 25th June 2012, 19:39   #2
Nitorami
Major Dude
 
Join Date: Mar 2008
Location: Erlangen
Posts: 862
That can be done using the spectrum data in the waves section and is fairly easy, but you need to understand first how milkdrop is organised.
Nitorami is offline   Reply With Quote
Old 25th June 2012, 19:55   #3
Donone
Junior Member
 
Join Date: Nov 2011
Posts: 39
Thank you, at least it is possible, so I will try to investigate.
Donone is offline   Reply With Quote
Old 27th June 2012, 18:40   #4
Donone
Junior Member
 
Join Date: Nov 2011
Posts: 39
I must confess to not solving this. I can only find bSpectrum which seems not to be related.
I would be grateful for a pointer from somebody please.
Donone is offline   Reply With Quote
Old 27th June 2012, 21:57   #5
Nitorami
Major Dude
 
Join Date: Mar 2008
Location: Erlangen
Posts: 862
1. The spectral data are only available in the wave sections. In wave1 section, store the data (I used 128 values) into gmegabuf, which is a universal array, useable in both directions (from per frame to wave/shape code AND the other way round - except shaders).

2. The best way to further process gmegabuf is in the per frame section, which is called only once per frame. In the attached sample, I store fractions of the spectrum into the variables mybass, mymid, mytreb, and copy them to one-way-registers q1, q2, q3.

3. Just to see something, we display q1, q2 and q3 as 3 shapes in the shapes section.

That's all.

All that's additionally required to make it useful, would be some kind of simple gain control, to make it independant of the overall volume.
Attached Files
File Type: milk spectrum demo.milk (5.8 KB, 316 views)
Nitorami is offline   Reply With Quote
Old 28th June 2012, 07:30   #6
Donone
Junior Member
 
Join Date: Nov 2011
Posts: 39
Thank you Nitorami for that invaluable help and especially useful having an example. It seems odd to me that I could find no documentation.

A busy weekend ahead methinks.
Donone is offline   Reply With Quote
Old 28th June 2012, 09:06   #7
Donone
Junior Member
 
Join Date: Nov 2011
Posts: 39
@:Nitorami
I have read your interesting post #22 http://forums.winamp.com/showthread.php?t=315268 but could not find the example which I would like to see.
Do you have it available please?
Donone is offline   Reply With Quote
Old 28th June 2012, 17:00   #8
Nitorami
Major Dude
 
Join Date: Mar 2008
Location: Erlangen
Posts: 862
Yes, many of the older attachments were lost during an upgrade of the forum software. I think it was this here
Attached Files
File Type: milk martin - test of real volume variable.milk (5.7 KB, 293 views)
Nitorami is offline   Reply With Quote
Old 28th June 2012, 17:49   #9
Donone
Junior Member
 
Join Date: Nov 2011
Posts: 39
Thank you Nitorami, that is indeed the one and it is very interesting.
Donone is offline   Reply With Quote
Old 28th June 2012, 18:45   #10
Donone
Junior Member
 
Join Date: Nov 2011
Posts: 39
Probably a stupid question but is there any way of displaying running values of chosen variables, on screen in a corner, perhaps also showing max/min values achieved?
Donone is offline   Reply With Quote
Old 28th June 2012, 23:14   #11
Nitorami
Major Dude
 
Join Date: Mar 2008
Location: Erlangen
Posts: 862
You can only monitor one variable, and only in the per frame section: Use "monitor=..." and press N during preset runtime. It is described in the tutorials. You can only monitor ONE variable at a time.
Nitorami is offline   Reply With Quote
Old 29th June 2012, 11:18   #12
Donone
Junior Member
 
Join Date: Nov 2011
Posts: 39
That is fine and thank you. I have now, since your comment, found it in the Per Frame instructions as I should have been able to in the first place.
Donone is offline   Reply With Quote
Old 30th June 2012, 23:25   #13
Flexi
wellspring of milk
Major Dude
 
Flexi's Avatar
 
Join Date: Apr 2007
Location: 54.089866,12.11168,18.75
Posts: 2,058
Send a message via ICQ to Flexi
this preset is a more advanced prototype for interactive agents. the only interaction for now is turning to the nearest neighbor and take the separated frequency band's volume data as energy for forward motion. (+a bouncing circles animation).
The spectrum curve that you see at the bottom of the screen is used to fetch the data and it is already passed into the 'gmegabuf' global memory array. read the init code section for more information:

http://forums.winamp.com/showpost.ph...&postcount=190
Flexi is offline   Reply With Quote
Old 1st July 2012, 08:24   #14
Donone
Junior Member
 
Join Date: Nov 2011
Posts: 39
That is very impressive despite being out of my depth. It reminds me of neuron connections as memory is formed. This will keep me busy for weeks searching for new techniques and how things work.
It of course raises questions. Unfortunately in asking them your name disappears and nobody can see that you have posted this.

1. Can shapes be enabled after the preset is running? I have not found any answer; except probably not.
However I note that there are formulae within various disabled shape per frame sections.

2.The waveform at the bottom is off screen but has peaks that encroach periodically. There are no scrollbars. What can I alter to remove those peaks without upsetting the preset?
Donone is offline   Reply With Quote
Old 1st July 2012, 09:34   #15
Nitorami
Major Dude
 
Join Date: Mar 2008
Location: Erlangen
Posts: 862
1. No, but you can make them invisible by setting rad = 0; e.g. from within the per-frame code, also selectively, using an if-condition: if (instance >= 20, rad = 0, 0);
Code in disabled shape section are remainders of experiments or mashups.

2. You can change the scaling in wave 2 per-point section (x= ..., y= ...) or set a= 0 to not show the wave at all
Nitorami is offline   Reply With Quote
Old 1st July 2012, 09:45   #16
Donone
Junior Member
 
Join Date: Nov 2011
Posts: 39
Thank you very much for that very specific help.
Beginning to get the hang of this. The biggest problem is the number of variations in millions means that life is spent tweaking and never being quite satisfied that there isn't another better tweak left. Time consuming.

[Edit] Using that new found knowledge I turned on a shape that was off in Flexi's recent post. Wow, the -fish?.
Donone is offline   Reply With Quote
Old 1st July 2012, 11:38   #17
Donone
Junior Member
 
Join Date: Nov 2011
Posts: 39
I noted what Nitorami said in an earlier post regarding gmegabuf.
I notice that Flexi uses gmegabuf and megabuf.

There seems to be no documentation.
I would be grateful for guidance with the following.

1. Are these built in and specific in their use?
2. can one create these arrays as required and with any name?
3. can functions be created and called?

Thank you
Donone is offline   Reply With Quote
Old 1st July 2012, 14:41   #18
Nitorami
Major Dude
 
Join Date: Mar 2008
Location: Erlangen
Posts: 862
1. Yes, they are both array of unlimited size. gmegabuf is global while megabuf is local only (local to the code section - which makes only sense in the MD internal editor)
2. No. You can only use them as such.
3. No. Only in the shader sections but that is something entirely different.

Apart from megabuf, there is also reg00 ... reg99 to store up to 100 values and transfer them between the code sections. The reg variables are also global.
Nitorami is offline   Reply With Quote
Old 1st July 2012, 17:23   #19
Donone
Junior Member
 
Join Date: Nov 2011
Posts: 39
I am grateful again.
If my questions get too much, just don't answer and I will get the message.

I have one final question... for now and hopefully a while.
I still cannot get the hang of the spectral data and would like an example if at all possible, sometime convenient.

If I want to limit base to say 200Hz; mid from 400Hz to 1KHz and treb from say 1.3KHz how might I go about that?

Thank you in anticipation
Donone is offline   Reply With Quote
Old 1st July 2012, 18:02   #20
Flexi
wellspring of milk
Major Dude
 
Flexi's Avatar
 
Join Date: Apr 2007
Location: 54.089866,12.11168,18.75
Posts: 2,058
Send a message via ICQ to Flexi
the short answer is: only empirical. In this case i would start with a spectrum curve and some color markers for the individual intervals. When you have successfully defined your bands it's time to integrate. that means, you've got to sum up the volume values and divide by the number of points. you store those values each in one of the regXX values, and don't forget to reset them to zero in the wave init code section.
You will also need a soundtrack where you know the frequencies to tune your spectrum separation manually.
Flexi is offline   Reply With Quote
Old 1st July 2012, 18:36   #21
Nitorami
Major Dude
 
Join Date: Mar 2008
Location: Erlangen
Posts: 862
This is what "spectrum demo" does, except I did not bother about Hz.

I guess you understood that in the wave section, value1 and value2 contain the signal of the left and right audio channel: The time values, if spectrum is OFF, the fourier coefficients, if spectrum is ON. Assume you set spectrum = ON.

The spectral data are rather lousy, starting (first wave point) somewhere undefined below 1kHz, and ending at I think, 22 kHz (last wave point). The frequency span does not depend on the number of wave points, only the resolution becomes higher with more points. I found no advantage beyond 128 points.

To some extent, the lower and upper frequency limit also depend on the "L/R separation". The only way to find out how frequency and spectrum data match is to run a few sound files with sine tones of known frequency. You can use audacity to generate such files.

Not sure if it is worth the effort, though. I found that for the purpose of visualising music, clever algorithms to analyse the spectrum further than using the simple bass,mid and treb variables don't pay off. It may be a good way to learn milkdrop but don't let this become an obsession. In the end, the visual effect is important, and the eye won't discriminate between a bass signal from 0...400Hz and one from 0...800Hz.

I just remember one guy her on the forum, who was obsessed by getting the perfect beat detection, and produced a number of always the same preset just with different beat detection. To me, they all looked the same, and none of them responded perfectly, simply because this is not possible and would require significantly more intelligence than can possibly be put into MD. But who cares ? For a visualisation, a perfect equal beat signal would also be perfectly boring. It is simply not required. We discussed this but he was so keen on his stupid beat detection that when he found out it does not work he gave up MD completely....lame.
Just telling you this so hopefully you won't go down the same path.

As to your questions: It does not annoy me, and I am happy to explain things as long as I feel that somebody is really interested and won't piss off after a week.

Edit - Hey, Flexi ! Nice to see you back here !
Nitorami is offline   Reply With Quote
Old 1st July 2012, 20:22   #22
Flexi
wellspring of milk
Major Dude
 
Flexi's Avatar
 
Join Date: Apr 2007
Location: 54.089866,12.11168,18.75
Posts: 2,058
Send a message via ICQ to Flexi
speaking of band processing, as for example in multi channel beat detection, my preset above gives a really good starting point. Naturally there are no structs or objects in the MD script language, only the two arrays (one global, one closed, where only the global one is really interesting). What i have built is an indexing system over the buffer and a lambda function that can be used to perform actions on every pair of two indexed "particles". I used this first only for the verlet integration animation and collision detection. Then i had extended it to a more general system that first constructs a list of the n nearest neighbor's indexes for more complex logic to perform the collision detection only on the very nearest two particles. That means the first values per quasi-object are position, orientation and velocities and the last indexes are used for the list. But there are more free indexes for further attributes. For example for input data from the spectrum wave, colors, or ...and now comes the clue: residual energy values per band to compare to the current volume...
The whole lambda collision checklist could also be thrown out... But hey, there are fishies to distract!

Welcome Martin! I wasn't away, only busy. I'm still regularly visiting the forum, but when I'm not at work, I'm using my Macbook most of the times where I'm not able to run Milkdrop. Lately I've been doodling with spectrum separation and beat detection algorithms in Java, respective Javascript, together with "Shadowharlequin" for some sort of a sound-driven shooter for Android and HTML5...
Flexi is offline   Reply With Quote
Old 2nd July 2012, 07:40   #23
Donone
Junior Member
 
Join Date: Nov 2011
Posts: 39
Ah! The crux of the matter seems to be the explanation. I could not understand where the frequency cut-off points were. I think my post was wrong, I needed the explanation.
I accept that I could be banging my head against the wall for no discernible improvement and should concentrate on the visual effects. The only really definite beat in music seems to be military bands with a bass drum suggesting that attempts at beat detection should remain with that music.
Also it is clear that a good preset for one 'type' or 'piece' of music is lousy for another.
What I think is needed is a way to link multiple presets to particular 'pieces' or genre and have just those cycle or randomly select when going through a playlist. i.e. controlled by a lookup table which is periodically tweaked.

@:Flexi. I do like the wiggle on the fishes and their clever construction. They do explode on loud passages and then reconstruct.
Donone is offline   Reply With Quote
Old 2nd July 2012, 09:03   #24
Flexi
wellspring of milk
Major Dude
 
Flexi's Avatar
 
Join Date: Apr 2007
Location: 54.089866,12.11168,18.75
Posts: 2,058
Send a message via ICQ to Flexi
there is another version without the targeting behavior (which can also be easily deactivated in the other version). Here's a more elaborate visualization: http://forums.winamp.com/showpost.ph...&postcount=181
there was a simplistic version too, but i couldn't find it right now.

or another animation method that relies on the preemptive bass/mid/treb values and a custom verlet integration that eventually resonates with the rythms:
http://forums.winamp.com/showpost.ph...&postcount=183

the idea for the swimmer actually came from this older preset with one fractal entity:
http://forums.winamp.com/showpost.ph...&postcount=105

you might also enjoy or revive this thread:
http://forums.winamp.com/showthread.php?t=291963

cheers!
Felix
Flexi is offline   Reply With Quote
Old 2nd July 2012, 14:38   #25
Donone
Junior Member
 
Join Date: Nov 2011
Posts: 39
Thank you Felix, very grateful for this interesting stuff.
I am going to need some time to both enjoy and study these along with Nitorami's.
Donone is offline   Reply With Quote
Old 3rd July 2012, 11:26   #26
Donone
Junior Member
 
Join Date: Nov 2011
Posts: 39
Trouble with something simple.
I am assuming that for say 2 instances of a shape, the shape per frame is repeated twice.
If I wish to vary x of each instance I could say x=(instance+1)*0.25;

To put them in unrelated places I tried the following but only the first works the other is zero.
x=equal(instance,0)*0.75;
x=equal(instance,1)*0.27;

1. Why do they not both work on successive repeats of shape per frame per instance?

Or have I misunderstood the sequence...?
shapecode n
shape n init
shape n per frame (1st instance)
shape n per frame (2nd instance)
Donone is offline   Reply With Quote
Old 3rd July 2012, 16:48   #27
Amandio C
Senior Member
 
Join Date: Dec 2008
Posts: 400
The variable sample provides the more convenient way to write equations.
Sample is pre-defined in the wave section, not in the shape section.
So, we write in the beginning, for the shapes:

sample (or sa, or whatever) = instance/num_inst;

Then we can write:

x=sa; defines a line

x= .5 + .3*cos(6.28*sa);
y= .5 + .3*sin(6.28*sa); defines a circle
Amandio C is offline   Reply With Quote
Old 3rd July 2012, 17:57   #28
Nitorami
Major Dude
 
Join Date: Mar 2008
Location: Erlangen
Posts: 862
Donone

That cannot work. Both lines x= .... are always executed but the second overwrites the first one. Use something like

x = instance * 0.25 + 0.25;

or (tedious)

if (instance == 0, x = 0.27, 0);
if (instance == 1, x = 0.75, 0);

or, in the per frame Init part, fill gmegabuf with the desired x-values and then use

x = gmegabuf(instance);

Edit: a==b is the C-style synonym for equal(a,b)
Nitorami is offline   Reply With Quote
Old 3rd July 2012, 18:29   #29
Donone
Junior Member
 
Join Date: Nov 2011
Posts: 39
Understood; thank you.
Donone is offline   Reply With Quote
Old 3rd July 2012, 19:32   #30
Nitorami
Major Dude
 
Join Date: Mar 2008
Location: Erlangen
Posts: 862
Obviously, you may also use

x = equal(instance,0)*0.75 + equal(instance,1)*0.27;

"if" can also return a value, such as

x = if ( instance==0, 0.75, 0.27);

or, if you like nested statements (I don't)


x = if (instance==0, 0.75, if (instance==1, 0.27, if (instance== 2, 0.15, 0.1)));


There is many possibilities and I suggest you stick to one style, whatever suits you.
Nitorami is offline   Reply With Quote
Old 4th July 2012, 09:37   #31
Donone
Junior Member
 
Join Date: Nov 2011
Posts: 39
Thank you as always for your assistance.
What you suggest is familiar. My problem was that I presumed that per frame cycled as many times as there are instances, perhaps building a buffer, before finally displaying the frame.
Thus the first cycle would have set instance 0 at its x, (by the equality test) the second cycle setting instance 1 at its x and so on.

How it actually does it, taking your original comment about over writing into account, is now not clear and I would actually like to know how the sequence is carried out.
That is a hint!
Donone is offline   Reply With Quote
Old 4th July 2012, 13:18   #32
Amandio C
Senior Member
 
Join Date: Dec 2008
Posts: 400
The shape per-instance code is read n times, being n the number of instances. The variable "instance" is replaced by an integer: 0,1,2, etc until a maximum of 1023, if we use 1024 instances.
If we define a variable sa=instance/num_inst, it will always be in the interval [0,1[, no matter num_inst (number of instances) which is convenient to write the equations.
Amandio C is offline   Reply With Quote
Old 4th July 2012, 15:52   #33
Nitorami
Major Dude
 
Join Date: Mar 2008
Location: Erlangen
Posts: 862
Let me add some detail. It is in fact difficult to identify MD's loops.

preset initialization code is run once at preset start
preset per frame code is run once per frame. See below for frame. This is more or less the central code section.
per vertex equations are run m*n per frame, where m,n is the mesh size (MD config)

custom wave init code is run once at preset start
custom wave per frame code is run once per frame
custom wave per point code is run (num points) times per frame (max 512). During that, the variable sample runs from 0...1 (***)

custom shape init code is run once at preset start
custom shape per frame code has no own codes section. This is because the original MD could only handle one shape per custom shape section, 4 in total. "per frame" was the same as "per instance". This was upgraded later to 1024 x 4, but compatibility had to be maintained.
custom shape per instance code is run (num instances) times per frame (max 1024). During that, the variable instance is incremented by one per instance. (***)

"Frame" is a complete screen update. Depending on your settings, video card and complexity of the preset, you'll usually get between 15 and 90 frames per second (fps). Display the actual figure by pressing F5. It is also available in the code as variable fps.

(***) x,y, rad, a, r,g,b etc. and all the other output variables determine the position, colour etc. of the individual point (shape) on the screen. You cannot see the loop, but actually the per point / per instance code is run num points / num instances times per frame, with different x,y, etc. outputs per cycle. All you need to understand is when you define x = instance * 0.1; for a total of 8 shapes, the code will generate 8 different values of x for the 8 shapes, although you see only one equation and not the underlying loop... You cannot therefore use "monitor" in this code section.
Nitorami is offline   Reply With Quote
Old 4th July 2012, 18:35   #34
Donone
Junior Member
 
Join Date: Nov 2011
Posts: 39
It is clear now how I went wrong. Very clear and thank you.
Donone is offline   Reply With Quote
Old 5th July 2012, 19:31   #35
Nitorami
Major Dude
 
Join Date: Mar 2008
Location: Erlangen
Posts: 862
No questions today ?
Nitorami is offline   Reply With Quote
Old 5th July 2012, 22:15   #36
Flexi
wellspring of milk
Major Dude
 
Flexi's Avatar
 
Join Date: Apr 2007
Location: 54.089866,12.11168,18.75
Posts: 2,058
Send a message via ICQ to Flexi
Flexi is offline   Reply With Quote
Old 6th July 2012, 06:41   #37
Donone
Junior Member
 
Join Date: Nov 2011
Posts: 39
Yet another day... I am not dead! I am thinking.
Donone is offline   Reply With Quote
Old 6th July 2012, 15:49   #38
Flexi
wellspring of milk
Major Dude
 
Flexi's Avatar
 
Join Date: Apr 2007
Location: 54.089866,12.11168,18.75
Posts: 2,058
Send a message via ICQ to Flexi
what about your background in other programming languages, are you familiar with Java and/or Javascript? I've got this little sketch using Processing for a web-based music visualization. Feel free to use anything from it: www.cake23.de/pjs-soundcloud-bridge
I wanted to include this thing next: https://github.com/cjcliffe/beatdete...eatdetektor.js
Flexi is offline   Reply With Quote
Old 6th July 2012, 16:25   #39
Donone
Junior Member
 
Join Date: Nov 2011
Posts: 39
If you get bored with no questions for a few days perhaps you could answer them in advance,
.
Seriously after 12 years in the UK RAF, I started with the Digital PDP8 with 4Kb magnetic core memory using machine code (can't get much in that). The first program I wrote was NIM, keying in the binary code with the front panel key switches. No screens or keyboards then just a teletype for input/output. Then the first Microprocessor the intel 8008 (not 8080) in 1971-ish, then 6502 etc using machine code eventually moving up to assembler. Most of this at the same time as building and designing the hardware.

Higher up & later, Delphi up to 5, Javascript a little with web sites, B4PPC and just starting with B4Android and have played with Processing and Arduino, Dialect and earlier, Lisp and Forth. No C or C++ which would have been more universally useful.
I will have a look at your link after the weekend when I stop thinking.

My first visualiser was a hardware one back in about 197x or 198x. It was built into a large wooden frame with coloured 12v bulbs behind cottonwool and other materials, thyristors and filters on 4 channels. Totally different to today's. The filters were extremely accurate at isolating frequencies, hence the title of my post and trying to resurrect the same or similar so that the mid tones didn't light the other colours too much. With MD2 they do overlap a lot spoiling the effect.
Back to thinking for now. Meanwhile perhaps some background from your end.
Donone is offline   Reply With Quote
Old 6th July 2012, 19:59   #40
Nitorami
Major Dude
 
Join Date: Mar 2008
Location: Erlangen
Posts: 862
Hey, a hardware man. Reminds me when I built thyristor-controlled lightshows for school friends ages ago....1978ish.

And yes, I am bored and try to anticipate your next question - how can adequate filtering be done in MD, and the answer is - it can't, for physical reasons.
It may be an old hat for you but nevermind: The FFT is an extremely sharp means of filtering but it cannot defeat the physical rules that apply to every method of filtering, the inverse relation between time and frequency domain, delta f = 1 / delta T. Selective filtering requires a signal of long duration and hence is slow in response. If you want a fast response, you need to sacrifice selectivity.

MD uses chunks of music data max. ca. 10ms in length, you can see this when you run a 1kHz signal and display it as standard oscilloscope in the waves section with "use spectrum" set to OFF and a length of 512 points. You might build your own FFT on it ( certainly possible, I started on that but lost interest), and the lowest frequency you can discriminate would be 100Hz, followed by 200 etc. 100Hz resolution = 1/10ms.

The same is true for the inbuilt FFT ("use spectrum" = ON) except I don't know what length of data it uses but probably the same, logically below 1/fps, but likely to be shorter, maybe the same 10ms. That is reasonable because visuals must react quickly, and can't wait and collect 200ms of data just to perform sharp filtering at 5Hz resolution.

You can also not collect the chunks from several frames and combine them to a continuous data flow in order to apply filtering, because the chunks are not continuous. For fps = 30, MD gives us at best 10ms of music data, then follows a 20ms gap.... that does not work for filtering.
Nitorami is offline   Reply With Quote
Reply
Go Back   Winamp & Shoutcast Forums > Visualizations > MilkDrop > MilkDrop Presets

Thread Tools Search this Thread
Search this Thread:

Advanced Search
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off

Forum Jump