music.stretches

music.stretches(x, durations=(1, 4, 8, 12), sample_rate=None)[source]

Makes a sequence of squeezes of the fragment in x.

Parameters:
xarray_like

The mono samples to repeat, or two-channel stereo samples in the form (2, samples); for stereo, x[1][120] is the 120th sample of the second channel.

durationsiterable of numbers

Durations in seconds for each repeat of x.

sample_rateinteger or None

The sample rate in Hertz, used to read the length of x as a duration and so to work out how much each repeat is squeezed. None, the default, is the rate music.get_sample_rate() returns.

Returns:
ndarray

The repeats concatenated, mono or (2, nsamples) stereo according to x, each as many samples as its duration lasts at sample_rate. An empty x gives an empty result.

Raises:
ValueError

If any entry of durations is zero or negative. A duration of zero squeezes the fragment into no samples and a negative one reverses the step, so neither produces the repeat the caller asked for. Also if sample_rate is not positive, or x is not mono or two-channel stereo.

Notes

Each repeat is the whole fragment read faster or slower, as a tape played at another speed, so its pitch rises as it is squeezed and falls as it is stretched. Each sample is taken from the nearest position of the fragment, with neither interpolation nor filtering: a squeeze can fold partials past the Nyquist frequency back into the band, and a stretch holds each sample for several. It makes a rhythm, or a melody of speeds, out of any material.

Examples

>>> asound = horizontal_stack(*[note_with_vibrato(freq=i, vibrato_freq=j)
...                           for i, j in zip([220,440,330,440,330],
...                                           [.5,15,6,5,30])])
>>> s = stretches(asound)
>>> s = stretches(asound,
...               durations=[.2, .3] * 10 + [.1, .2, .3, .4] * 8 +
...               [.5, 1.5, .5, 1., 5., .5, .25, .25, .5, 1., .5] * 2)
>>> write_wav_mono(s, 'stretches.wav')