Fb1_MSD:
Filter:
Classes (extension) | Libraries > miSCellaneous > Nonlinear

Fb1_MSD : UGen : AbstractFunction : Object
ExtensionExtension

mass spring damper model pseudo ugen
Source: Fb1_ODE.sc

Description

Fb1_ODE wrapper for the mass spring damper equation of motion:

y''(t) * mass = f(t) - (dampen * y'(t)) - (spring * y(t))

It returns a 2-channel signal with position and velocity. Fb1_SD with unified mass is slightly more efficient than Fb1_MSD and you can always rewrite. See Fb1_ODE for general information about Fb1 ODE integrator UGens and further MSD examples.

HISTORY AND CREDITS: Big credit to David Pirrò from IEM Graz for pointing me to the symplectic integration methods, which are essential for audifying ODEs, as they help to ensure numeric stability in the long run (e.g. to avoid drifts of oscillations that are mathematically expected to be regular). See the chapter on integration in his dissertation [2], pp 135-146. You might also want check David Pirròs optimized ODE compiler named Henri [3]. Big credit also to Nathaniel Virgo who brought up the buffering strategy used in Fb1, which is Fb1_ODE's working horse.

WARNING: Especially with self-defined ODEs the usage of this class is – inherently – highly experimental. Be careful with amplitudes, as always with feedback it can become loud! Sudden blowups might result form the mathematical characteristics of the ODE systems or they might come from parameter changes on which ODEs can react extremely sensitive to, they can also stem from numerical accumulation effects. It is highly recommended to take precautionary measures, e.g. by limiting/distorting operators (tanh, clip, softclip, distort) with the compose option (See Fb1_ODE Examples 5) and/or external limiting and/or using MasterFX from the JITLibExtensions quark.
NOTE: The convenience of direct definition of the ODE relation comes with the price of a large number of UGens involved. You might want to allow a higher number of UGens with the server option numWireBufs. For a nice workflow I'd recommended to take reduced blockSizes (e.g. 1, 2, 4, 8, 16) while experimenting as compile time is shorter, but once you have finished the design of a SynthDef it might pay going back to blocksize 32 or 64 for runtime efficiency, especially if many kr UGens are involved.

   

References

  1. Trefethen, Lloyd N.; Birkisson Ásgeir; Driscoll, Tobin A. (2017): Exploring ODEs. SIAM - Society for Industrial and Applied Mathematics. Free download from: https://people.maths.ox.ac.uk/trefethen/Exploring.pdf
  2. Pirrò, David (2017). Composing Interactions. Dissertation. Institute of Electronic Music and Acoustics, University of Music and Performing Arts Graz. Free download from: https://pirro.mur.at/media/pirro_david_composing_interactions_print.pdf
  3. https://git.iem.at/davidpirro/henri

Class Methods

Fb1_MSD.new(f: 0, mass: 1, spring: 1, dampen: 0, tMul: 1, t0: 0, y0: [ 0, 0 ], intType: 'sym2', compose, composeArIn, dt0, argList0, init_intType: 'sym8', withDiffChannels: false, withTimeChannel: false, blockSize, graphOrderType: 1, leakDC: true, leakCoef: 0.995)

Creates a new Fb1_MSD ar object.

Arguments:

f

External force. Defaults to 0.

mass

Mass. Defaults to 1.

spring

Spring stiffness. Defaults to 1.

dampen

Dampening factor. Defaults to 0.

tMul

Time multiplier, which determines velocity of proceeding in the dynamic system. The default value 1 means that the step delta of time equals 1 / sample duration. For getting audible oscillations you might, depending on the ODE definition, have to pass much higher values. Can also be a kr / ar UGen and might also be negative.

t0

Initial time. Expects Number. Defaults to 0.

y0

Initial value of the ODE. Expects array of size 2. Defaults to #[0, 0].

intType

Integration type. Expects one of the Symbols, for which procedures are stored with Fb1_ODEintdef. The use of symplectic procedures (with prefix 'sym') is highly recommended. Defaults to \sym2. For more accurate integration you can try symplectic procedures of higher order like \sym4, \sym8 etc. Families of integration procedures:

  • Symplectic: \sym2, \sym2_d, \sym4, \sym4_d, \sym6, \sym6_d, \sym8, \sym8_d, \sym12, \sym12_d, \sym16, \sym16_d, \sym32, \sym32_d, \sym64, \sym64_d
  • Euler: \eu, \eu_d, \eum, \eum_d, \eui, \eui_d
  • Prediction-Evaluation-Correction: \pec, \pece, \pecec, \pecece
  • Runge-Kutta: \rk3, \rk3_d, \rk3h, \rk3h_d, \rk4, \rk4_d
  • Adams-Bashforth: \ab2, \ab3, \ab4, \ab5, \ab6
  • Adams-Bashforth-Moulton: \abm21, \abm22, \abm32, \abm33, \abm43, \abm44, \abm54, \abm55, \abm65, \abm66
compose

Operator(s) / Function(s) to be applied to the system value on a per-sample base. This of course blurs the numeric procedure but can be used for containing or in a creative way. Can be an operator Symbol, a Function or an arbitrarily mixed SequenceableCollection thereof. The Functions are in any case expected to take an array (the system state) as first argument. If only one Function is given it must output an array of same (system) size. Within a SequenceableCollection a Function must output a value of size 0. Within a SequenceableCollection an operator Symbol is applied only to the corresponding component. A Function can optionally take a second argument which is for ar UGens passed via composeArIn.

composeArIn

ar UGen or SequenceableCollection thereof or a SequenceableCollection that can contain both. This is the way to use ar UGens within a Function passed to compose. UGens are passed to the Function's second argument.

dt0

First time delta in seconds to be used for the language-side calculation of first values of a multi-step intType procedure. This will mostly be irrelevant as (single-step) symplectic procedures are to be preferred. In case of a multi-step procedure a dt0 value will be derived from the default server's properties (sample duration * tMul).

argList0

Initial argList value(s) to be used for the language-side calculation of first values of a multi-step intType procedure. This will mostly be irrelevant as (single-step) symplectic procedures are to be preferred. If no UGens are passed to argList, values will be assumed from passed argList Numbers.

init_intType

Integration type for language-side calculation of first values of a multi-step intType procedure. This will mostly be irrelevant as (single-step) symplectic procedures are to be preferred. Defaults to \sym8.

withDiffChannels

Boolean. Determines if channel(s) with differential value(s) should be returned. This is only applicable with integration types with a sizeFactor == 2, which means that for every sample the values of the differential are buffered. As by default this is not the case for all predefined numeric procedures, there exist variants with appendix '_d', e.g. \sym2_d. Defaults to false.

withTimeChannel

Boolean. Determines if accumulated time is output in an additional channel.

WARNING: with constant tMul it produces an ascending DC which is not affected by leakDC if this is set to true. Might especially be of interest if time is modulated. Defaults to false.
blockSize

Integer, this should be the server blockSize. If no Integer is passed, the current default server's blockSize is assumed (in contrast to Fb1). So explicitely passing a blockSize should only be necessary in special cases, e.g. when compiling before booting. However for a pleasant workflow for ar usage it's recommended to use Fb1_ODE with a reduced server blockSize in order to reduce SynthDef compile time.

graphOrderType

0, 1 or 2. Determines if topological order of generated BufRd and BufWr instances in the SynthDef graph is forced by additional UGens.

  • Type 0: forced graph order is turned off.
  • Type 1 (default): graph order is forced by summation and <!.
  • Type 2: graph order is forced by <! operators only.

Default 1 is recommended, but with CPU-intense SynthDefs it might be worth trying it with the value 0. This saves a lot of UGens though there might be exceptional cases with different results. Type 2 can shorten the SynthDef compilation time for certain graphs with a large number of UGens, which can be lengthy with type 1. However, CPU usage doesn't directly correspond to the number of UGens.

leakDC

Boolean. Determines if a LeakDC is applied to the output (except time channel). Defaults to true.

leakCoef

Number, the leakDC coefficient. Defaults to 0.995.

Fb1_MSD.ar(f: 0, mass: 1, spring: 1, dampen: 0, tMul: 1, t0: 0, y0: [ 0, 0 ], intType: 'sym2', compose, composeArIn, dt0, argList0, init_intType: 'sym8', withDiffChannels: false, withTimeChannel: false, blockSize, graphOrderType: 1, leakDC: true, leakCoef: 0.995)

Equivalent to *new.

Fb1_MSD.kr(f: 0, mass: 1, spring: 1, dampen: 0, tMul: 1, t0: 0, y0: [ 0, 0 ], intType: 'sym4', compose, dt0, argList0, init_intType: 'sym8', withDiffChannels: false, withTimeChannel: false, graphOrderType: 1, leakDC: true, leakCoef: 0.995)

Creates a new Fb1_MSD kr object.

Arguments:

f

External force. Defaults to 0.

mass

Mass. Defaults to 1.

spring

Spring stiffness. Defaults to 1.

dampen

Dampening factor. Defaults to 0.

tMul

Time multiplier, which determines velocity of proceeding in the dynamic system. The default value 1 means that the step delta of time equals 1 / control duration. For getting audible oscillations you might, depending on the ODE definition, have to pass much higher values. Can also be a kr UGen and might also be negative.

t0

Initial time. Expects Number. Defaults to 0.

y0

Initial value of the ODE. Expects array of size 2. Defaults to #[0, 0].

intType

Integration type. Expects one of the Symbols, for which procedures are stored with Fb1_ODEintdef. The use of symplectic procedures (with prefix 'sym') is highly recommended. Defaults to \sym4. For more accurate integration you can try symplectic procedures of higher order like \sym6, \sym8 etc. Families of integration procedures:

  • Symplectic: \sym2, \sym2_d, \sym4, \sym4_d, \sym6, \sym6_d, \sym8, \sym8_d, \sym12, \sym12_d, \sym16, \sym16_d, \sym32, \sym32_d, \sym64, \sym64_d
  • Euler: \eu, \eu_d, \eum, \eum_d, \eui, \eui_d
  • Prediction-Evaluation-Correction: \pec, \pece, \pecec, \pecece
  • Runge-Kutta: \rk3, \rk3_d, \rk3h, \rk3h_d, \rk4, \rk4_d
  • Adams-Bashforth: \ab2, \ab3, \ab4, \ab5, \ab6
  • Adams-Bashforth-Moulton: \abm21, \abm22, \abm32, \abm33, \abm43, \abm44, \abm54, \abm55, \abm65, \abm66
compose

Operator(s) / Function(s) to be applied to the system value on a per-control-block base. This of course blurs the numeric procedure but can be used for containing or in a creative way. Can be an operator Symbol, a Function or an arbitrarily mixed SequenceableCollection thereof. The Functions are in any case expected to take an array (the system state) as first argument. If only one Function is given it must output an array of same (system) size. Within a SequenceableCollection a Function must output a value of size 0. Within a SequenceableCollection an operator Symbol is applied only to the corresponding component.

dt0

First time delta in seconds to be used for the language-side calculation of first values of a multi-step intType procedure. This will mostly be irrelevant as (single-step) symplectic procedures are to be preferred. In case of a multi-step procedure a dt0 value will be derived from the default server's properties (control duration * tMul).

argList0

Initial argList value(s) to be used for the language-side calculation of first values of a multi-step intType procedure. This will mostly be irrelevant as (single-step) symplectic procedures are to be preferred. If no UGens are passed to argList, values will be assumed from passed argList Numbers.

init_intType

Integration type for language-side calculation of first values of a multi-step intType procedure. This will mostly be irrelevant as (single-step) symplectic procedures are to be preferred. Defaults to \sym8.

withDiffChannels

Boolean. Determines if channel(s) with differential value(s) should be returned. This is only applicable with integration types with a sizeFactor == 2, which means that for every sample the values of the differential are buffered. As by default this is not the case for all predefined numeric procedures, there exist variants with appendix '_d', e.g. \sym2_d. Defaults to false.

withTimeChannel

Boolean. Determines if accumulated time is output in an additional channel.

WARNING: with constant tMul it produces an ascending DC which is not affected by leakDC if this is set to true. Might especially be of interest if time is modulated. Defaults to false.
graphOrderType

0, 1 or 2. Determines if topological order of generated BufRd and BufWr instances in the SynthDef graph is forced by additional UGens.

  • Type 0: forced graph order is turned off.
  • Type 1 (default): graph order is forced by summation and <!.
  • Type 2: graph order is forced by <! operators only.

Default 1 is recommended, but with CPU-intense SynthDefs it might be worth trying it with the value 0. This saves a lot of UGens though there might be exceptional cases with different results. Type 2 can shorten the SynthDef compilation time for certain graphs with a large number of UGens, which can be lengthy with type 1. However, CPU usage doesn't directly correspond to the number of UGens.

leakDC

Boolean. Determines if a LeakDC is applied to the output (except time channel). Defaults to true.

leakCoef

Number, the leakDC coefficient. Defaults to 0.995.

Inherited class methods

Instance Methods

Inherited instance methods

Examples