Tutorial 5: Audio musaicking parameters

One of the main advantages of the Mosaic class, is that it allows to generate different audio mosaic versions from the same instance, or corpus-target pairing. In other words, a Mosaic instance works as a virtual representation, or blueprint of an audio mosaic, rather than the audio mosaic itself.

This allows to play and experiment with different settings, hear the results, all without having to rebuild the Corpus and/or the Mosaic from scratch everytime. Thus, the resulting audio will depend on the many audio parameters one can pass to the to_audio() method.

To demonstrate this, let’s consider different cases with the same Mosaic instance.

from gamut.features import Mosaic

# first load .gamut mosaic from disk
mosaic = Mosaic().read('/path/to/my_mosaic.gamut')

Now, let’s generate audio using the default arguments:

# convert to audio mosaic using arguments and play it.
mosaic.to_audio().play()

Optionally, we can pass different arguments to fine-tune the final output. For instance, setting the grain duration:

# set grain duration to 0.5 seconds
mosaic.to_audio(grain_dur=0.5).play()

As with most of arguments in the to_audio() method, we can use a list of values to dynamically (i.e., over time) change the parameter.

# set grain duration, gradually changing from 0.1 to 0.5 seconds, over the duration of the audio file
mosaic.to_audio(grain_dur=[0.1, 0.5]).play()

Similarly we can customize the grain envelope:

env = [0, 1, 0.25, 0.25, 0]
mosaic.to_audio(grain_env=env).play

This would result in the following grain envelope:

../_images/grain-env-1.png

Warning

When specifying envelopes as a list, make sure that the envelope starts and ends in 0. Otherwise, you’ll likely get unintended audio clicks in the audio output with every grain.

Another convenient way of specifying time-varying or dynamic parameters, is through a list of tuples, here each tuple is the (x, y) coordinates of the parameter — x being time, and y being the parameter value.

env = [
    (0, 0),
    (1, 1),
    (2, 0.25),
    (10, 0),
]
mosaic.to_audio(grain_env=env).play

This results is the following grain envelope:

../_images/grain-env-2.png

Warning

When specifying a control parameter as a list of tuples, make sure the x values appear in incremental order. For instance, these lists would all throw an error:

  • [(0, 0), (0, 1)]`

  • [(0, 0), (1, 1), (0, 1)]`

  • [(0, 0), (1, 1), (50, 0.5), (10, 0)]`

Finally, let’s consider a more complex version, changing more than a single parameter.

In this case, we’ll change:

  • corpus_weights: This controls the likelihood of using the corpus (instead of the original audio target) for a given segment or grain. By default, this is set to 1. Although it’s not quite the same, this is somewhat equivalent to controlling the dry-wet mix between corpus and target.

  • grain_env: grain envelope.

  • grain_dur: grain duration, in seconds.

  • stretch_factor: inverse playback rate, where 2 is twice as slow, 0.5 is twice as fast, and so on.

# gradual change, from only using grains in corpus, to only using grains in original audio target
corpus_weights = [1, 0]

# a somewhat sharp and percussive grain envelope
grain_env = [
    (0, 0),
    (1, 1),
    (2, 0.5),
    (15, 0),
]

# playback at original speed (1.0), and half way gradually slow down to twice the speed (2.0)
stretch_factor = [1, 1, 2]

# convert to audio
audio = mosaic.to_audio(
    grain_env=grain_env,
    corpus_weights=corpus_weights,
    stretch_factor=stretch_factor,
)

# playback audio mosaic
audio.play()

# write audio mosaic to disk
audio.write('./my_cool_audio_mosaic.wav')

Note

To learn more about all available audio parameters, see the documentation: gamut.features.Mosaic.to_audio.