<transform>#

A constant transform can be simply added to a <clip> element, like the pos attribute in minimal.asd:

<asdf version="0.4">
  <clip file="audio/ukewave.ogg" pos="1 2" />
</asdf>

Such attributes (pos, rot etc.) can be added to <clip> and <channel>, as well as <source> and <reference>.

These attributes can be seen as shorthand notation to avoid using <transform> elements for such simple cases. Of course, explicit <transform> elements can also be used, as shown in minimal-expanded-with-explicit-transform.asd:

<?xml version="1.0"?>
<asdf version="0.4">
  <head>
    <source id="src1" />
  </head>
  <body>
    <par>
      <clip file="audio/ukewave.ogg">
        <channel id="channel1" source="src1" />
      </clip>
      <transform apply-to="channel1" pos="1 2 0" />
    </par>
  </body>
</asdf>

apply-to#

The required attribute apply-to defines the target(s) for the transform. This is a space-separated list of IDs of any <source>, <clip> and <channel> elements, as well as other <transform> elements. The special ID "reference" can be used to target the <reference>.

A <transform> element can apply to multiple objects. An object can be the target of multiple transforms, as long as at most one of them contains a rotation.

pos#

This is named after position, but technically, the term translation would be more appropriate. The final position of a sound source – or the <reference> – can be the result of multiple translations (and maybe rotations as well, see below) applied to the default position (0, 0, 0).

The pos attribute contains a space-separated list of two or three coordinate values (in meters). If only two values are given, the third one is assumed to be zero. For coordinate system conventions, see Position and Orientation.

rot#

Unlike pos, this is aptly named after rotation. The final orientation of a sound source – or the <reference> – can be the result of multiple rotations, applied to the default orientation (0, 0, 0).

The rot attribute contains a space-separated list of up to three angles (in degrees) called azimuth, elevation and roll. Only azimuth is required, the others default to zero if not specified. For angle conventions, see Position and Orientation.

The range of angle values is not limited, but the represented rotations are cyclically repeating and the number of turns is irrelevant. This means that the angles -90 and 270 both specify the same rotation. When using a sequence of rotations to define a rotation spline (see the <o> element below), the smallest possible angular difference between neighboring rotations is used. For example, an angle of 270 degrees followed by an angle of 0 degrees will lead to a rotation of 90 degrees. An angle of 180 degrees followed by -180 degrees will lead to no rotation at all.

The order of applying translations and rotations matters: within a <transform> element, pos is applied after rot. This means that the target of a <transform> is first rotated around the (local) origin and then translated to its final position.

vol#

A (linear) volume change can be specified as a non-negative decimal value. Using vol="0" results in silence, vol="0.5" corresponds to an attenuation of about 6 decibels, vol="1" doesn’t change the volume and vol="2" corresponds to a boost of about 6 decibels.

<o>#

A <transform> element can contain zero, one or more <o> elements. Let’s call them transform nodes. A <transform> with a single <o> element is able to describe a constant transform. If we specify two transform nodes, we can define a linear movement between two points. This is shown in two-pos.asd:

<asdf version="0.4">
  <par>
    <clip id="ukulele" file="audio/ukewave.ogg" />
    <transform apply-to="ukulele">
      <o pos="-2 2" />
      <o pos="2 2" />
    </transform>
  </par>
</asdf>

You can also specify two rotations, which leads to a (spherical) linear interpolation between them. See two-rot.asd:

<asdf version="0.4">
  <par>
    <clip id="marimba" file="audio/marimba.ogg">
      <channel pos="-1 2" />
      <channel pos="1 2" />
    </clip>
    <transform apply-to="marimba">
      <o rot="45" />
      <o rot="-45" />
    </transform>
  </par>
</asdf>

In fact, two nodes are not a special case. As soon as there is more than one node, a spline is constructed that passes through all the nodes. In the case of two nodes, this leads to a linear path, but with more than two nodes, curved trajectories can be created, as for example in minimal-spline.asd:

<asdf version="0.4">
  <par>
    <clip id="ukulele" file="audio/ukewave.ogg" />
    <transform apply-to="ukulele">
      <o pos="-2 -2" />
      <o pos="-2 2" />
      <o pos="2 2" />
      <o pos="2 -2" />
    </transform>
  </par>
</asdf>

In addition to pos and rot, the vol attribute can also be animated, see transform-vol.asd:

<asdf version="0.4">
  <par>
    <clip id="ukulele" file="audio/ukewave.ogg" pos="0 1.5" />
    <transform apply-to="ukulele">
      <o vol="0" />
      <o vol="1" />
      <o vol="0" />
      <o vol="1.5" />
      <o vol="0" />
    </transform>
  </par>
</asdf>

Note

This should only be used for relatively slow volume changes, because the renderer might only apply them on a block-by-block basis. If you need fast envelopes, those should be applied by modifying the audio file in a waveform editor.

time#

By default, sources move with a constant speed along trajectories, but if desired, time values can be assigned to any node. The speed will be varied such that the source passes those nodes at the given times. The first node always implicitly has time="0". See spline-time.asd:

<asdf version="0.4">
  <par>
    <clip id="ukulele" file="audio/ukewave.ogg" />
    <transform apply-to="ukulele">
      <o pos="-2 -2" />
      <o pos="-2 2" />
      <o pos="2 2" time="5" />
      <o pos="2 -2" />
    </transform>
  </par>
</asdf>

If not specified otherwise, time values are interpreted as seconds. Hours and minutes can be spelled in HH:MM:SS.sss format (where hours and fractions of seconds are optional) or using the h and min suffixes. For an example, see spline-time-hh-mm-ss.asd:

<asdf version="0.4">
  <par>
    <clip id="ukulele" file="audio/ukewave.ogg" />
    <transform apply-to="ukulele">
      <o pos="-2 -2" />
      <o pos="-2 2" time="0:10" />
      <o pos="2 2" time="0.5 min" />
      <o pos="2 -2" />
    </transform>
  </par>
</asdf>

Time values can also be given in percent, where 100% is the total duration of (one repetition of) the <transform>. See spline-time-percent.asd:

<asdf version="0.4">
  <par>
    <clip id="ukulele" file="audio/ukewave.ogg" />
    <transform apply-to="ukulele">
      <o pos="-2 -2" />
      <o pos="-2 2" time="10%" />
      <o pos="2 2" time="50%" />
      <o pos="2 -2" />
    </transform>
  </par>
</asdf>

If the <transform> doesn’t have a dur attribute (see below), the last node can have an explicit time value, but a percentage is not allowed. If unspecified, time="100%" is implied, i.e. the <transform> always ends with the last transform node.

If the time value of a node is not specified, it is deduced from the surrounding nodes.

speed#

In addition to time values, concrete speed values can also be specified. However, not all speed values are allowed. In order to provide smooth movements, the possible speed values are limited to a certain range. The speed is given in meters per second.

For an example, see spline-speed.asd:

<asdf version="0.4">
  <par>
    <clip id="ukulele" file="audio/ukewave.ogg" />
    <transform apply-to="ukulele">
      <o pos="-2 -2" speed="0" />
      <o pos="-2 2" />
      <o pos="2 2" time="15" speed="0.5" />
      <o pos="2 -2" />
    </transform>
  </par>
</asdf>

tension/continuity/bias#

The ASDF uses Kochanek–Bartels Splines, which means that the so-called TCB attributes tension, continuity and bias (each ranging from -1.0 to 1.0 with a default of 0.0) can be used. These attributes can be applied to individual transform nodes or to the whole <transform>, as shown in spline-tcb.asd:

<asdf version="0.4">
  <par>
    <clip file="audio/marimba.ogg">
      <channel id="left" />
      <channel id="right" />
    </clip>
    <transform apply-to="left" tension="-0.5">
      <o pos="-2 -2" />
      <o pos="-2 2" time="33%" />
      <o pos="2 2" time="66%" />
      <o pos="2 -2" />
    </transform>
    <transform apply-to="right">
      <o pos="-2 -2" />
      <o pos="-2 2" bias="-1" time="33%" />
      <o pos="2 2" bias="1" time="66%" />
      <o pos="2 -2" />
    </transform>
  </par>
</asdf>

In most cases, specifying TCB values will not be necessary, but they can be useful for creating straight lines, sharp edges, circles and other Special Shapes.

TCB attributes can also be used for rot trajectories, leading to Kochanek–Bartels-like Rotation Splines.

Mixed Transform Attributes#

We have seen that pos, rot and vol trajectories can be created. However, they can also be combined into a single trajectory.

None of the transform attributes are required, but if one of the attributes is used in any transform node, it also has to be specified in the first and last node. In other words, missing values are interpolated but not extrapolated.

The scene mixed-transform-attributes.asd illustrates this in an example trajectory:

<asdf version="0.4">
  <par>
    <clip id="marimba" file="audio/marimba.ogg">
      <channel pos="-1 0" />
      <channel pos="1 0" />
    </clip>
    <transform apply-to="marimba">
      <o pos="0 -2" rot="-20" vol="1" />
      <o pos="0 0" time="1s" />
      <o vol="1" />
      <o rot="0" time="2s" />
      <o vol="0" />
      <o vol="1" time="65%" />
      <o pos="0 2" rot="20" vol="1"/>
    </transform>
  </par>
</asdf>

repeat#

<transform> elements can be repeated, see Repetition.

dur#

If the last transform node has its time attribute set, this will determine the duration of the <transform>. Alternatively, the duration of a <transform> can be specified with the dur attribute, which allows the same syntax as the time attribute of transform nodes. If there are repetitions, the duration is that of a single repetition. A percentage can be given, which is relative to the duration of (one repetition of) the parent element.

If no duration is given, and the <transform> is part of a <par> container, the duration is taken from the <par> container (whose duration might be provided by its first sub-element). See <seq> and <par>.

Nested <transform>#

Any <transform> that has an id attribute can be used as the target of another <transform>. The transforms can have different begin and end times. They only have an effect while they are active.

Multiple <transform> elements can target the same object, but at most one of them can specify a rotation.

An example of nested transforms can be seen in nested-transforms.asd:

<asdf version="0.4">
  <par>
    <clip id="ukulele" file="audio/ukewave.ogg" pos="-2 -2" />
    <transform id="horizontal-movement" apply-to="ukulele" repeat="10">
      <o pos="2 4" />
      <o pos="0 2" />
      <o pos="2 0" />
      <o pos="4 2" />
      <o pos="closed" />
    </transform>
    <transform apply-to="horizontal-movement">
      <o rot="0" />
      <o rot="0 0 90" />
      <o rot="0 0 180" />
    </transform>
  </par>
</asdf>

The <clip> defines a static position, which is then dynamically translated in the horizontal plane according to the <transform> named horizontal-movement. This horizontal movement is then transformed again, this time with a dynamic rotation around the roll axis.

Creating Groups With <transform>#

There is no dedicated “group” element, but a <transform> with multiple targets in the apply-to attribute is essentially defining a group. All transform attributes are optional, allowing us to create a group by using a non-transforming <transform>:

<transform id="my-group" apply-to="target1 target2 my-other-target" />

This group can then in turn be the target of further <transform> elements.