RobinSchmidt / RS-MET

Codebase for RS-MET products (Robin Schmidt's Music Engineering Tools)
Other
56 stars 6 forks source link

rotating X/Y/Z sound with 3 knobs? & Lorenz Attractor discussion #81

Closed elanhickler closed 6 years ago

elanhickler commented 6 years ago

I have this rotation function from one of Jerobeam's algorithms:

void JerobeamBoing::rotate(double in_x, double in_y, double in_z, double z_depth, double rot_x, double rot_y, double * out_l, double * out_r)
{
    double rot_x_x_PI_x_2_sin, rot_x_x_PI_x_2_cos;
    rosic::sinCos(rot_x*PI_x_2, &rot_x_x_PI_x_2_sin, &rot_x_x_PI_x_2_cos); /*optimization*/
    double help_11 = in_x*rot_x_x_PI_x_2_cos-in_y*rot_x_x_PI_x_2_sin;
    double help_12 = in_x*rot_x_x_PI_x_2_sin+in_y*rot_x_x_PI_x_2_cos;

    double rot_y_x_PI_x_2_sin, rot_y_x_PI_x_2_cos;
    rosic::sinCos(rot_y*PI_x_2, &rot_y_x_PI_x_2_sin, &rot_y_x_PI_x_2_cos); /*optimization*/
    double help_21 = help_11*rot_y_x_PI_x_2_cos-in_z*rot_y_x_PI_x_2_sin;
    double help_22 = help_11*rot_y_x_PI_x_2_sin+in_z*rot_y_x_PI_x_2_cos;

    double x = help_21;
    double y = help_12;
    double z = help_22;

    double formula = zdepth*1.25*(in_z / 2 + 0.5);  /*optimization*/
    double L = x - formula*x;
    double R = y - formula*y;

    double m = 1 + zdepth;

    *out_l = L*m;
    *out_r = R*m;
}

Can this be used to rotate something like the X/Y/Z out of lorenz?: http://users.physics.harvard.edu/~horowitz/misc/lorenz.htm

RobinSchmidt commented 6 years ago

i think so. can be used with anything that has 3 coordinates.

elanhickler commented 6 years ago

yes, but is it the math you'd expect to see? He has several rotation functions, seem to be unique per algorithm.

Would be nice to include in your library, a general purpose rotation.

RobinSchmidt commented 6 years ago

i'd like to include into my library a general 3D-to-2D mapper that can be set up in terms of a camera position, viewing direction (point to look at) and camera orientation...and possibly zoom. i'm not sure what the most convenient parametrization of something like that is. ...and i think the mapping function above can then be seen as a special case with some restrictions/constraints of the more general setup.

the math, i'd expect to see in the general case is probably a 4x4 matrix in homogenous coordinates. depending on how you set up constraints and parameters, it may then boil down to something like the code above

RobinSchmidt commented 6 years ago

it could also (more directly) be expressed as a 3x3 matrix plus a vector addition of a 3-vector - but typically, in computer graphics, one adds a 4th dimension to the vectors. that way, shifts can also be expressed/included in a matrix-vector-multiply. you have probably seen a lot of that stuff in your OpenGL code

RobinSchmidt commented 6 years ago

then, we could set up a differential equation system in 3D - like the lorenz system - and fly around it while it does its thing :-)

RobinSchmidt commented 6 years ago

or a 3D version of my raybouncer. or a set of parametric equations, i.e. give explicit formulas for x(t), y(t), z(t) for a particle trajectory

elanhickler commented 6 years ago

I want to make a 3d lorenz RIGHT NOW.

btw I just came up with a 2d rotation function, not that you need the math since you already know it.

    void rotate(double degreesInPhase, double inX, double inY, double * outX, double * outY)
    {
        double s, c;
        rosic::sinCos(degreesInPhase, &s, &c);
        *outX = inX * c - inY * s;
        *outY = inX * s + inY * c;
    }

the interesting part about 3d to 2d though, like I keep saying, is that you can convert Z into speed instead of just mixing it down to 2D like a boring person :)

But I think this can be done inside the function rather than inside a phase incrementor. You just add a curve to the final output I think, linear to something curved?

There is a z_depth parameter in the equation I posted, no idea if it's going to actually work, since I'm just pulling it out of an algorithm that may be expecting a certain input.

elanhickler commented 6 years ago

heehee

namespace waveshape2D
{   
    void rotate(double degreesOfPhase, double inX, double inY, double * outX, double * outY)
    {
        double s, c;
        rosic::sinCos(degreesOfPhase, &s, &c);
        *outX = inX * c - inY * s;
        *outY = inX * s + inY * c;
    }

    void circle(double phase, double * outX, double * outY)
    {
        rosic::sinCos(phase, outX, outY);
    }

    void diamond(double phase, double * outX, double * outY)
    {
        *outX = waveshape::tri(phase);
        *outY = waveshape::tri(phase+phase90degrees);
    }

    void square(double phase, double * outX, double * outY)
    {

        diamond(phase, outX, outY);
        rotate(phase45degrees, *outX, *outY, outX, outY);
    }

    void squarepoint(double phase, double * outX, double * outY)
    {
        waveshape::square(phase);
        waveshape::square(phase+phase90degrees);
    }
}
RobinSchmidt commented 6 years ago

I want to make a 3d lorenz RIGHT NOW.

rosic::LorentzSystem ...but i think, you have your own anyway

elanhickler commented 6 years ago

https://www.youtube.com/watch?v=z53qA25_8sc

done.

im bored, what's next?

heehee :)

RobinSchmidt commented 6 years ago

next? how about a sound generator module for chainer where you can enter the differential equations like in func shaper. i certainly want to do this someday

elanhickler commented 6 years ago

Your LorentzSystem had a few problems though.

  1. values explode to inf, requiring plugin restart. I wonder if clipping all the state values to reasonable ranges would fix that.
  2. I think you misspelled Lorenz (makes it unusable)
  3. At 8x oversampling you get a more smooth sound, but I remember you saying there's a better way to interpolate chaos? More oversampling sounded better, but after x4 it stopped improving. I think the graininess is due to sampling limit, but I wouldn't know without listening to an analog synth. I know that chaos seems to sound better on an analog synth.
RobinSchmidt commented 6 years ago

ah - soo this youtube demo was my code? i did not really test it very much. seems like i tend to confuse lorenz with lorentz:

https://en.wikipedia.org/wiki/Lorentz_transformation

hmmm...yeah....maybe i should include a saturation/clipping to prevent it from exploding?

as for improving the quality without oversampling: oversampling actually lowers the stepsize for the numerical ode-solver (which, in this case, is the simple forward euler method - which is the simplest).

https://en.wikipedia.org/wiki/Numerical_methods_for_ordinary_differential_equations

maybe higher order methods such as runge-kutta could improve things

RobinSchmidt commented 6 years ago

this one: https://en.wikipedia.org/wiki/Runge%E2%80%93Kutta_methods#The_Runge.E2.80.93Kutta_method

RobinSchmidt commented 6 years ago

in the video, it seems like as you increase frequency, there's a threshold above which it goes into noise. at low frequencies, it's fairly periodic - you get a bam bam bam bam....but if you increase the freq, you don't get a periodic waveform

elanhickler commented 6 years ago

I just did some hours of testing Lorenz to prove whether I am getting an accurate sound or whether it's not accurate due to existing in the digital domain (and not being produced by an analog synth).

It's confusing because it sounds "quantizy" and digital as if locking onto aliasing harmonics. But here are some things that prove it's not because of digital domain:

  1. Oversampling stopped improving results after x4. I even tried up to x64 oversampling.
  2. I tried various filter curves in the feedback path in attempt to remove spikiness in the signal. Didn't do anything useful, it just made the chaos more stable at higher frequencies.
  3. I tried recording a low frequency signal then playing it back really fast. Quantizy sound again!
  4. I listened to some analog chaos and it too sounds quantizy at times.

https://soundcloud.com/elanhickler/oh-my-little-chaos-generator

To know if you're getting digital distortion of the chaos, just use no oversampling and sweep the frequency (looking at FFT graph helps) and if there's any aliasing harmonics, you will hear and see it locking on to those harmonics. Then turn up oversampling (and maybe retune the chaos frequency) and that behavior will disappear

I think the reason it sounds digital by nature is because it's locking and unlocking onto itself at various multiples and divisions of is harmonics. It makes sense. The less stable the chaos, the more range of locking it has, and therefore the more noisy it is. Maybe that is the fundamental nature of chaos, it's how many related frequencies it locks on to and how fast that locking changes. It can be so fast it is pure white noise or it can be so slow that you get a tone.