mandelbrot

Oscillator based on the Mandelbrot fractal iteration (z' = z^2 + c), where z is the variable of iteration (meaning that the output of each iteration is the input of the next one) and c a user defined complex number (in the form Re + Im*i) This object does not model faithfully the actual function, which has an extreme dynamic range, but it tries to "tame the beast" and make it somewhat usable for sound generation. Neither the parameters map exactly 1 to 1 the points of the complex plane, they're scaled differently. Parameter list: re : the real part of the complex number im : the imaginary part ' ' ' ' ' ' ' ' pitch : the pitch of the oscillator. Notice that in some zones of the complex plane the function iterates at multiples of the pitch. Use autoadjust to overcome this problem limit : the size of the bailout window. Basically, any iteration that escapes from this window will reset the oscillator to 0. This parameter also adjusts the output gain of the osc. If a complex number does not produce any sound you might try lowering this number 3oct : pitch the oscillator down 3 octaves (might be useful) autoadjust : try to pitch the oscillator correctly (this won't work properly if the current iteration does not diverge. interp: interpolate between values.
Author: Sputnki
License: BSD
Github: sptnk/osc/mandelbrot.axo

Inlets

frac32 pitch

frac32 Re

frac32 Im

Outlets

frac32buffer Re

frac32buffer Im

int32.bipolar iterations

Parameters

frac32.s.map.pitch pitch

int32 limit

bool32.tgl 3oct

bool32.tgl autoadjust

bool32.tgl interp

frac32.s.map re

frac32.s.map im

Declaration
int32_t re;
int32_t im;

int32_t re_old;
int32_t im_old;

int32_t re_interp;
int32_t im_interp;

int32_t c_re;
int32_t c_im;

int i_number;
int iterations;

int shift;

uint32_t Phase;
uint32_t Phase_old;
Init
re = 0;
im = 0;
re_old = 0;
im_old = 0;
re_interp = 0;
im_interp = 0;

c_re = 0;
c_im = 0;

Phase = 0;
Phase_old = 0;

shift = 0;

i_number = 1;
iterations = 1;
Control Rate
c_re = param_re + inlet_Re >> 5;
c_im = param_im + inlet_Im >> 5;

uint32_t freq;
MTOFEXTENDED(param_pitch + inlet_pitch - (param_3oct * 36 << 21), freq);

if (param_autoadjust)
  freq *= iterations;

int limit = param_limit;

outlet_iterations = iterations;

shift = 30 - limit;
Audio Rate
Phase += (freq >> 0); // this phasor is used as a counter, when it resets a new
                      // iteration is calculated.

if (Phase < Phase_old) // if the phasor has reset -> calculate a new iteration
{
  if (re_old > (1 << limit) || re_old < -(1 << limit) ||
      im_old > (1 << limit) ||
      im_old < -(1 << limit)) // reset to z'=(0,0) if the current z has exceded
                              // the limit size
  {
    re = 0;
    im = 0;
    iterations = i_number;
    i_number = 1;
  } else // iterate z' = z^2 + c if the current z is smaller than the limit size
  {
    re = ___SMMUL(re_old << 6, re_old << 6) -
         ___SMMUL(im_old << 6, im_old << 6) + c_re;
    im = c_im + (___SMMUL(re_old << 6, im_old << 6) << 1);
    i_number += 1;
  }
  re_interp = re_old; // these two are for the interpolation (basically it keeps
                      // track of the old value outside the iteration cycle)
  im_interp = im_old;

  re_old = re;
  im_old = im;
}

Phase_old = Phase; // this is needed for the  "if () then () " above

if (!param_interp) // output w/o interpolation
{
  outlet_Re = (re << shift) >> 4;
  outlet_Im = (im << shift) >> 4;
} else // output with interpolation, i need some help here!
{
  int32_t phase_t =
      Phase >> 4; // make the phase variable signed int (so i can use it inside
                  // SMMUL) - Also, i'm making it smaller
  int32_t temp = (re >> 2) - (re_interp >> 2);
  outlet_Re = ((___SMMUL(temp, phase_t) << 6) + (re_interp) << shift) >> 4;
  temp = (im >> 2) - (im_interp >> 2);
  outlet_Im = ((___SMMUL(temp, phase_t) << 6) + (im_interp) << shift) >>
              4; // AIUTO PLEASE
}

Privacy

© 2024 Zrna Research