DrumSequenceEngine

The DrumSequenceEngine is a SequenceEngine that can be used to produce drums like a drum computer, based on patterns. Only absolute (non-transposable) notes are produced by this SequenceEngine.

The DrumSequenceEngine supports an interesting feature: conditional patterns. These patterns are applied on each chord section boundary if the activity changes from a specified activity to a specified activity. For example, you can create a snare crescendo if the base drum was inactive before and now becomes active or if the base and clap were active and now only the base is active. Applying a pattern means that the notes of the last ticks of the previous chord section (or a longer pattern crossing several chord sections) of a specified sequence are replaced by or added from the given conditional pattern.

In the first phase, for each "pattern" tag a sequence is generated using the given base pitch. The pitches supplied in the pattern will be added to the base pitch. For example, if the base pitch is 36, a "0" means pitch 36, "1" means pitch 37, etc. This is helpful for loop players, where each pitch is mapped to a different part of the loop.

In the second phase, the DrumSequenceEngine sweeps through the chord sections (starting with the second one) and checks for each conditional pattern if it can be applied. This is done by iterating through the conditional patterns one by one, checking if the condition is true; if not, the conditional pattern is ignored. If the condition is true, the random generator is asked if the pattern should be applied; if yes, the given pattern will be used to change the already generated sequence of the first phase by replacing parts of the sequence or adding to the sequence. A conditional pattern can replace notes that were already replaced by a previous conditional pattern.

Starting with version 0.3, for all chord boundaries crossed by the pattern the precondition is checked. This happens if the pattern is longer than the previous chord section. For example, suppose that the precondition is chosen so that the base drum is not active and the postcondition is that the base is active. Then at the current chord section (and all previous chord sections crossed by the conditional pattern) the precondition has to be true, i.e., in the previous chord section(s) (depending on the pattern length) the base drum must be inactive. In addition, the postcondition has to be true at the current chord section, i.e., the base drum must become active. Before version 0.3, the precondition was only checked at the current chord section, which sometimes lead to strange situations if the pattern was longer than the previous chord section.

Some nice tricks are possible with the DrumSequenceEngine:

  • using an additional drum pitch for conditional patterns - if you are not using a certain drum pitch in the normal patterns but want to be able to use it as a target for a conditional pattern, simply add an arbitrary activity vector to the list of activity vectors for the DrumSequenceEngine, create an empty pattern in a new "pattern" section (which contains a 1-tick pause) and then use that as the target
  • using non-drum activity vectors for conditional patterns - if you want a condition based on an additional activity vector that is not used for drums (for example, the "melody" activity vector), simply add this activity vector to the list of activity vectors for the DrumSequenceEngine and use an empty pattern in an additional "pattern" tag; you can then reference this ActivityVector in conditions - note: this workaround is not needed anymore since version 0.9, as you are allowed to use all of the song's ActivityVectors in a condition

Starting with version 0.2, more control about the conditional patterns is possible by using the "skipWhenApplied" and "skipWhenNotApplied" tags. For example, let's suppose you always want only one or the other conditional pattern (but never both) applied at each chord section and they have the same condition. You would simply set them next to each other and set the "skipWhenApplied" tag to 1 for the first pattern and the probability of the second pattern to "100", which means that the second pattern will be skipped if the first was applied, and the second pattern will always be applied if the first was not applied (unless there is an overlap as described above). It is also possible to jump backwards by providing a negative skip (-1 will repeat the check of the current conditional pattern, -2 will jump back to the previous pattern, etc.). Make sure you don't create infinite loops with this.

Starting with version 0.5, the tag "condition" has been replaced by the tags "precondition" and "postcondition" with a much simpler condition syntax.

Starting with version 0.8, SoundHelix supports conditional LFOs. This lets you create an LFO sequence upon conditions similar to the ones for conditional patterns. This allows, for example, to slowly open/close a filter when a certain condition arises. Creating the LFO sequence is done via the "conditionalLFO" tag. The created LFO sequence can then be mapped to a MIDI controller in the MidiPlayer configuration.

Configuration

Tag Attribute Type # Example Description
patternRestartMode - string 0-1 chordSection The restart mode to use for all patterns in addition to restarting them at the end. Allowed values are "chord" (restart patterns at each new chord), "chordSection" (restart patterns at each new chord section), "song" (never restart patterns). Defaults to "song" for backwards compatibility. Available since version 0.9.
pattern - - 1-n - The container for the pattern.
pattern/pitch - int 1 36 The absolute pitch to use.
pattern/patternEngine class class 1 StringPatternEngine The name of the PatternEngine implementation to use.
pattern/patternEngine - - 1-n - The configuration of the PatternEngine implementation.
conditionalPattern - - 0-n - The container for the conditional pattern.
conditionalPattern/target - list of ints 1 0,1 The target sequences to apply the conditional pattern to. Sequences are numbered from 0 in the order of the activity vectors.
conditionalPattern/condition - string 1 0-10>0--0 The condition when to apply the pattern. On the left of the ">" (called the precondition), provide the activity condition of the previous chord section, on the right (called the postcondition) provide the one of the current chord section. For each activity vector provided to the DrumSequenceEngine, each of the two conditions contains "0", "1" and "-" characters, where "0" means off, "1" means on and "-" means don't care, in the order of the activity vectors. Whenever there is a transition from the left-hand activity to the right-hand activity, the conditional pattern can be applied. This syntax has been deprecated since version 0.5. Use the tags "precondition" and "postcondition" instead.
conditionalPattern/precondition - string 1 +base,-snare The before condition when to apply the pattern. The condition is a comma-separated list of ActivityVector names, which are each prefixed by either "+" (meaning active) or "-" (meaning inactive). Not mentioning an ActivityVector means that its state is not relevant for the condition. Any of the song's ActivityVectors can be used (prior to version 0.9 only AVs fed into the DrumSequenceEngine could be used). Available since version 0.5.
conditionalPattern/postcondition - string 1 +base,+snare The after condition when to apply the pattern. The condition is a comma-separated list of ActivityVector names, which are each prefixed by either "+" (meaning active) or "-" (meaning inactive). Not mentioning an ActivityVector means that its state is not relevant for the condition. Any of the song's ActivityVectors can be used (prior to version 0.9 only AVs fed into the DrumSequenceEngine could be used). Available since version 0.5.
conditionalPattern/mode - string 1 replace Specifies, the mode, which can be either "replace" or "add". The mode "replace" replaces the existing notes and pauses with the conditional pattern's notes and pauses, the mode "add" adds the conditional pattern's notes to the existing notes and pauses.
conditionalPattern/probability - double 1 60 The probability (in percent) to apply the conditional pattern if the condition is met.
conditionalPattern/skipWhenApplied - int 0/1 1 How many following conditional patterns should be skipped if the conditional pattern was applied. Available since version 0.2.
conditionalPattern/skipWhenNotApplied - int 0/1 1 How many following conditional patterns should be skipped if the conditional pattern was not applied even though it was allowed to be applied, according to the condition (either the random generator didn't agree or there would be an overlap). Available since version 0.2.
conditionalPattern/patternEngine class class 1 StringPatternEngine The name of the PatternEngine implementation to use.
conditionalPattern/patternEngine - - 1-n - The configuration of the PatternEngine implementation.
conditionalLFO - - 0-n - The container for the conditional LFO. Available since version 0.8.
conditionalLFO/name - string 1 bassLFO The name of the LFO. The combination of instrument name and LFO name must be unique. The name can be referenced in the Player later.
conditionalLFO/ticks - int 1 32 The number of ticks for the LFO when the condition is met.
conditionalLFO/speed - double 1 0.5 The number of full rotations to perform within one rotation unit.
conditionalLFO/rotationUnit - string 1 beat The rotation (a.k.a. period) unit to use for the LFO. These rotation units are allowed:
  • beat - speed and phase are set so that one full rotation from the beginning to the end of a beat is made
  • range - speed and phase are set so that one full rotation from the first to the last tick (based on the "ticks" tag) is made when the condition is met.
conditionalLFO/phase - double 1 0.25 The phase shift of the LFO in number of rotations. 0.25 is a shift by 90 degrees, 0.5 by 180 degrees, etc.
conditionalLFO/defaultValue - double 1 0 The default value of the LFO when the condition is not triggered. Must be between 0 and 1.
conditionalLFO/precondition - string 1 +base,-snare The before condition when to apply the pattern. The condition is a comma-separated list of ActivityVector names, which are each prefixed by either "+" (meaning active) or "-" (meaning inactive). Not mentioning an ActivityVector means that its state is not relevant for the condition. Any of the song's ActivityVectors can be used (prior to version 0.9 only AVs fed into the DrumSequenceEngine could be used).
conditionalLFO/postcondition - string 1 +base,+snare The after condition when to apply the pattern. The condition is a comma-separated list of ActivityVector names, which are each prefixed by either "+" (meaning active) or "-" (meaning inactive). Not mentioning an ActivityVector means that its state is not relevant for the condition. Any of the song's ActivityVectors can be used (prior to version 0.9 only AVs fed into the DrumSequenceEngine could be used).
conditionalLFO/probability - double 1 60 The probability (in percent) to apply the conditional pattern if the condition is met.
conditionalLFO/skipWhenApplied - int 0/1 1 How many following conditional patterns should be skipped if the conditional pattern was applied.
conditionalLFO/skipWhenNotApplied - int 0/1 1 How many following conditional patterns should be skipped if the conditional pattern was not applied even though it was allowed to be applied, according to the condition (either the random generator didn't agree or there would be an overlap).
conditionalLFO/lfo class class 1 TriangleLFO The name of the LFO implementation to use.
conditionalLFO/lfo - - 1-n - The configuration of the LFO implementation.

Configuration example


<sequenceEngine class="DrumSequenceEngine">
  <pattern>
    <pitch>36</pitch>
    <patternEngine class="RandomFragmentPatternEngine">
      <patternTicks>16</patternTicks>
      <patternString>A1,B1,A1,B2,A1,B1,A1,B3</patternString>
      <pattern group="A">0,-,-,-,-,-,-,-,0,-,-,-,-,-,-,-</pattern>
      <pattern group="B">0,-,-,0,-,-,-,-,0,-,-,-,-,-,-,-|0,-,-,-,-,-,-,-,0,-,-,-,-,-,0,-|0,-,-,-,-,-,-,-,0,-,-,-,-,-,-,0|0,-,-,-,-,-,-,-,0,-,-,-,-,-,0,0</pattern>
    </patternEngine>
  </pattern>
  <pattern>
    <pitch>38</pitch>
    <patternEngine class="RandomFragmentPatternEngine">
      <patternTicks>8</patternTicks>
      <patternString>A1,A1,A1,B1,A1,A1,A1,C1,A1,A1,A1,B1,A1,A1,A1,C2</patternString>
      <pattern group="A">-,-,-,-,0,-,-,-</pattern>
      <pattern group="B">-,-,-,-,0,-,-,-|-,-,-,-,0,-,-,0</pattern>
      <pattern group="C">-,-,-,-,0,-,-,0|-,-,-,0,0,-,0,-|-,-,-,0,0,0,-,0|-,-,-,0,0,0,0,-</pattern>
    </patternEngine>
  </pattern>
  <pattern>
    <pitch>42</pitch>
    <patternEngine class="RandomFragmentPatternEngine">
      <patternTicks>4</patternTicks>
      <patternString>A1,A2,A1,A3,A1,A2,A1,A4</patternString>
      <pattern group="A">0:26000,0:26000,0:26000,0:26000|0:26000,0:26000,-,0:26000|0:26000,-,-,-|0:26000,-,0:26000,-|0:26000,0:26000,0:26000,-</pattern>
    </patternEngine>
  </pattern>
  <pattern>
    <pitch>46</pitch>
    <patternEngine class="RandomFragmentPatternEngine">
      <patternTicks>8</patternTicks>
      <patternString>A1,B1,A1,B2,A1,B1,A1,B3</patternString>
      <pattern group="A">-,-,0:20000,-,-,-,0:20000,-</pattern>
      <pattern group="B">-,-,0:20000,-,-,-,0:20000,-|-,-,0:20000,-,-,-,-,0:20000|-,-,0:20000,-,-,0:20000,-,0:20000</pattern>
    </patternEngine>
  </pattern>
  <conditionalPattern>
    <target>1</target>
    <condition before="-base" after="+base"/>
    <mode>replace</mode>
    <probability>40</probability>
    <patternEngine class="StringPatternEngine">
      <string><random list="0:6,0:32,0:89,0:182,0:317,0:499,0:734,0:1024,0:1375,0:1789,0:2271,0:2822,0:3447,0:4149,0:4930,0:5793,0:6741,0:7776,0:8901,0:10119,0:11432,0:12842,0:14351,0:15962,0:17677,0:19498,0:21427,0:23467,0:25618,0:27884,0:30266,0:32767|0:1,0:6,0:16,0:32,0:56,0:89,0:130,0:182,0:243,0:317,0:402,0:499,0:610,0:734,0:872,0:1024,0:1192,0:1375,0:1574,0:1789,0:2021,0:2271,0:2537,0:2822,0:3125,0:3447,0:3788,0:4149,0:4529,0:4930,0:5351,0:5793,0:6256,0:6741,0:7247,0:7776,0:8327,0:8901,0:9499,0:10119,0:10763,0:11432,0:12124,0:12842,0:13584,0:14351,0:15144,0:15962,0:16806,0:17677,0:18574,0:19498,0:20449,0:21427,0:22433,0:23467,0:24528,0:25618,0:26737,0:27884,0:29061,0:30266,0:31502,0:32767"/></string>
    </patternEngine>
  </conditionalPattern>
  <conditionalPattern>
    <target>0</target>
    <condition before="+base" after="-base"/>
    <mode>add</mode>
    <probability>40</probability>
    <patternEngine class="StringPatternEngine">
      <string><random list="0,0,0,0|0,0,0,0,0,0,0,0"/></string>
    </patternEngine>
  </conditionalPattern>
</sequenceEngine>

Add new comment