music.note_with_glissando

music.note_with_glissando(start_freq=220, end_freq=440, duration=2, alpha=1, waveform_table=array([0., 0.0003835, 0.00076699, ..., -0.00115049, -0.00076699, -0.0003835], shape=(16384,)), method='exp', number_of_samples=None, sample_rate=None)[source]

A note with a pitch transition: a glissando.

Parameters:
start_freqscalar

The starting frequency.

end_freqscalar

The final frequency.

durationscalar

The duration of the sound in seconds.

alphascalar

An index to begin the transition faster or slower. If alpha != 1, the transition is not of linear pitch.

waveform_tablearray_like

The table with the waveform to synthesize the sound.

methodstr

“exp” or “exponential” for an exponential transition of frequency (linear pitch); “lin” or “linear” for a linear transition of frequency.

number_of_samplesinteger or None

The number of samples of the sound. If given, duration is not used, and zero is no samples.

sample_rateinteger or None

The sample rate. None, the default, is the rate music.get_sample_rate() returns.

Returns:
sndarray

A numpy array where each value is a PCM sample of the sound.

Raises:
ValueError

If an exponential glissando is asked to start or end at a frequency that is not positive. It sweeps by a constant ratio, and there is no ratio from zero: a start of zero divided, and a negative frequency raised to a fractional power gave NaN, which was then cast to an integer table index and read as a sound. A linear glissando has no such restriction.

Also if method is not one of the four names above. Anything but "exp" used to sweep linearly, "exponential" included.

If alpha is negative: it bends a transition through zero, where a negative power has no finite value, and the render came back holding infinity behind a warning.

Parameters:
  • start_freq (float)

  • end_freq (float)

  • duration (float)

  • alpha (float)

  • waveform_table (ArrayLike)

  • method (str)

  • number_of_samples (int | None)

  • sample_rate (int | None)

Return type:

NDArray[float64]

See also

note

A basic musical note without vibrato or pitch transition.

note_with_vibrato

A musical note with an oscillation of pitch.

tremolo

A tremolo, an oscillation of loudness.

loud

A transition of loudness.

fade

Fade in or out.

Notes

The frequency moves from \(f_0\), start_freq, to \(f_{\Lambda-1}\), end_freq, by a constant ratio – linearly in pitch – or by a constant step, as the article writes them [1]:

\[f_i = f_0 \left(\frac{f_{\Lambda-1}}{f_0}\right)^{\left( \frac{i}{\Lambda-1}\right)^{\alpha}} \quad \text{or} \quad f_i = f_0 + (f_{\Lambda-1} - f_0) \frac{i}{\Lambda - 1},\]

the first bent by alpha, which the second does not read. The table is read where those frequencies accumulate, so the phase follows the frequency rather than jumping with it:

\[t_i = \tilde{l}_{\gamma_i \bmod \tilde{\Lambda}}, \qquad \gamma_i = \left\lfloor \sum_{j=0}^{i} f_j \frac{\tilde{\Lambda}}{f_s} \right\rfloor,\]

with the table and its length as in note().

Cite the following article whenever you use this function.

References

[1]

Fabbri, Renato, et al. “Musical elements in the discrete-time representation of sound.” arXiv preprint arXiv:abs/1412.6853 (2017)

Examples

>>> write_wav_mono(note_with_glissando())  # writes file with a glissando
>>> s = horizontal_stack(
...     *[note_with_glissando(i, j) for i, j in zip([220, 440, 4000],
... [440, 220, 220])])
>>> write_wav_mono(s)  # writes a file with glissandi