Go to bottom

8 note slide as f(t)

category: code [glöplog]
Let's say you want to slide through 8 notes procedurally with only f(t) like they have on Shadertoy .... and avoid clicks.

A simple smoothstep between the frequencies of notes won't help because the phase of the signal does not connect properly and that causes really unexpected (at first!) tone drops or raises.

Working with the phase, which is the integral of the frequency slide curve (linear raise or drop)
Code:float k = f1-f0; f = slideTime*f0 + slideSpeed*k*slideTime*slideTime/2.0;

works as expected and avoids a click when the slide begins but I struggle to find a solution for all 8 notes with no break between them - and no clicks.

Maybe the only solution is to go through all notes and add up the phases accordingly. But then exactly, I can not figure out how. This seems to be such a simple task but it turns nasty really fast - for me.

Is it possible to do something like anti-aliasing in image processing to audio to iron-out misconnected audio signals by calculating 2 or more samples of the master signal? Averaging out too high jumps could help.... but this is just speculation here.

Was wondering if any tracker coders had to solve this issue and might have a solution they'd love to share or brag about - please take this as an invitation!

It would also help me to sleep more.
added on the 2014-08-21 04:00:24 by movAX13h movAX13h
There are some examples on wavepot.com that had a slide function, maybe you can check that out.
added on the 2014-08-21 06:48:54 by potasmic potasmic
movAX13h, one simple way is to make sure that in every note interval you fit an integer amonut of wave cycles. I made this shader showing the idea: https://www.shadertoy.com/view/4sSXRh

Code:float hash( float n ) { return fract(sin(n)*43758.5453); } vec2 mainSound( float time ) { float i = floor( time ); // interval float n = floor( 24.0*hash( i ) ); // note float f = 220.0 * pow( 2.0, n/12.0 ); // frequency // avoid click f = floor( f ); return vec2( sin(6.2831*f*time) ); }
added on the 2014-08-21 09:02:31 by iq iq
Okay. I'm gonna quote the code in wavepot.

Code: function slide(measure, seq, speed){ var pos = (t / measure / 2) % seq.length; var now = pos | 0; var next = now + 1; var alpha = pos - now; if (next == seq.length) next = 0; return seq[now] + ((seq[next] - seq[now]) * Math.pow(alpha, speed)); } var melody = [2, 9, 5, 8]; //This array is converted to its frequency correspondence which I have removed that code. var mod_melody = slide(1/8, melody, 12);
added on the 2014-08-21 13:34:37 by potasmic potasmic
potasmic, thank you. a lovely application that is. wavepot - did not know of it before. Thx for the code but I don't see how it would avoid clicks because it is not considering the previous notes, only the current and the next one. So when the next note will play, it jumps from one phase to the next (by ignoring the phase of the previous note(s)).
Code:return seq[now] + ((seq[next] - seq[now]) * Math.pow(alpha, speed));

is almost the same as my code from above
Code:f = slideTime*f0 + slideSpeed*(f1-f0)*slideTime*slideTime/2.0;

iq, thank you. maybe that could help somewhere.
added on the 2014-08-21 15:06:07 by movAX13h movAX13h
<rant>First the web, then graphics... can we please keep the hipster disease that is statelessness out of audio? Pretty please?</rant>
added on the 2014-08-21 15:11:13 by kb_ kb_
added on the 2014-08-21 15:16:36 by MsK` MsK`
Exploring new ways of solving problems (=new perspective) can never be hipster.
added on the 2014-08-21 15:18:46 by movAX13h movAX13h
Or new ways of creating problems :)
added on the 2014-08-21 15:22:04 by Gargaj Gargaj
1) Post the solution when you find it, Movax?

2) I'm curious to hear more about how statelessness is utilized by coding hipsters. That isn't sarcasm, it's genuine curiosity. But my request is perhaps OT for this thread.

3) Pouet is all about news ways of creating problems (flashbacks to the pouet.net talk at Revision, which I finally got to see afterwards)
*new ways. gah.
Yes, I will post a solution but be assured that non-hipsters like iq (or kb obviously) would easily write that code/math down in the matter of minutes if not seconds. Hipsters like me are just here to entertain by talking about things we don't fully understand and thus depend on exchange of knowledge. Curiosity is what got me into all of this.
added on the 2014-08-21 17:10:14 by movAX13h movAX13h
what is this statelessness thing you all talk about?
added on the 2014-08-21 17:20:29 by Navis Navis
I'd say: A system that does not allow sharing variables between updates. So everything has to be calculated everytime. Fragment shaders on the GPU for example. Since the GPU is optimized for mathematical operations, it makes it very attractive to do things this way and it also involves a change of perspective in many aspects.
added on the 2014-08-21 17:44:19 by movAX13h movAX13h
It's that thing about imperative VS functional languages.
Something I still don't have a good grasp of. I am still not sure what means to be a functional language, so functional is like trying to use only functions that get input and return output without changing data of the given object or variable? And for some reason you must not make loops, but use recursion to make a for loop for example? I am not getting it exactly, there is a lot of disagreement of what is and what is not functional language. I was reading various explanations on internet for hours but still not sure. Also, if I follow these practices in pure C, then I write C like a functional language? Isn't this though like you code in imperative language, but by restricting yourself more?
added on the 2014-08-21 17:52:22 by Optimus Optimus
I do understand though this would be considered more safe maybe (some global variable that accidentally changed state, will not skew your correct function return value for example), and they say it's better for multithreading, which makes sense. But not sure, every time I see some example in haskell or whatever else, it takes me time to read and understand.
added on the 2014-08-21 17:54:38 by Optimus Optimus
re "A system that does not allow sharing variables between updates"
Ok, that was what I thought it meant, but I wasn't sure I was right.

Why is it hot right now, something about memory utilization?

I mean, safety is useful in terms of having code that doesn't bork itself globally when you tweak one thing as Optimus said, but it has to be more than that which made it catch on . . . if it did catch on.
I feel myself making some mental tie between statelessness and the combined recent popularity of barebones platforms like the RP and of approaches to certain unusual oldskool platforms . . . but I'm not sure if that is a spurious tie. Would explain the hipster component (insert Arduino joke here, although at least one very awesome person did a 'duino demo . . .)

And Movax, yay! I look forward to seeing what you find out. I don't know anything much yet either, hence why I wanna learn (:
hm, also portability between platforms, cf ShaderToy . . .
I think the main reason for statelessness of a shader is that 4 pixels are processed in parallel (even if there is only 1 pixel of a poly visible; thats why dfdx and dfdy are possible). This is done for performance reasons. I don't know other stateless systems.

To me it is the "straightforwardness" and the forced "reversedness" of the resulting implementations that totally got me into more difficult mathematics (unusual for me) and various techniques to try and develop.

You go from 2D screen coordinates to a 3D domain, to modelling and shading in just a few lines of code.

As an example I'd like to use the definition of a circle in a distance based framework for a stateless system like a plain fragment shader which as input has only x and y of the currently drawn pixel and some constants like screen resolution and time (=constant for each frame):
Code:distance = length(currentPixelPos.xy-circlePos.xy)-circleRadius;

Amazingly that is also the definition of a 3D sphere (using .xyz) in a distance based framework very convenient to have on a stateless system. In a polygon-based engine, you'd have to do A LOT more for a simple sphere and all of the mathematics would be about triangles - very unnatural.
A limitation (no control over x and y of the pixel to draw) led to new solutions, in this case and in my opinion to a very different approach in many ways - even a new branch maybe and that makes it so interesting.
added on the 2014-08-21 21:24:56 by movAX13h movAX13h
stateless allows out-of-order and/or parallel execution of the code, because frame n+1 does not need to wait for the side effects of frame n to be ready. In the world of GPUs where there is a lot of potential for paralellizing stuff, this is nice. On recent 4 or 8-core CPUs there is some use to it, but maybe not enough to use a pure functional language just yet.
in that sense, pretty muh everything i try to do is stateless- including particle systems. This allows me to play demos backwards, jump to x etc without hassle (at least thats how i understand this).
added on the 2014-08-22 10:16:02 by Navis Navis
How do you do stateless particle emitters?
added on the 2014-08-22 10:20:15 by Preacher Preacher
Particles don't necessarily have to be a physics simulation I guess, they can just follow a path.
added on the 2014-08-22 10:22:11 by Gargaj Gargaj
No emitters. A rain effect for example, is simulated by fmod(time). The demo "butterfly effect" is all stateless (function of time).
added on the 2014-08-22 10:40:22 by Navis Navis


Go to top