music.note_with_vibrato

music.note_with_vibrato(freq=220, duration=2, vibrato_freq=4, max_pitch_dev=2, waveform_table=array([-1., -0.99975586, -0.99951172, ..., -0.99926758, -0.99951172, -0.99975586], shape=(16384,)), vibrato_waveform_table=array([0., 0.0003835, 0.00076699, ..., -0.00115049, -0.00076699, -0.0003835], shape=(16384,)), alpha=1, number_of_samples=None, sample_rate=None)[source]

Synthesize a musical note with a vibrato.

A vibrato is an oscillatory pattern of pitch [1]. A max_pitch_dev of zero is a note without one.

Parameters:
freqscalar

The frequency of the note in Hertz.

durationscalar

The duration of the note in seconds.

vibrato_freqscalar

The frequency of the vibrato oscillations in Hertz.

max_pitch_devscalar

The maximum deviation of pitch in the vibrato in semitones.

waveform_tablearray_like

The table with the waveform to synthesize the sound.

vibrato_waveform_tablearray_like

The table with the waveform for the vibrato oscillatory pattern.

alphascalar

An index to distort the vibrato [1]. If alpha != 1, the vibrato is not of linear pitch.

number_of_samplesinteger or None

The number of samples in the sound. If given, duration is ignored, and zero is no samples.

sample_rateinteger or None

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

Returns:
resultndarray

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

Raises:
ValueError

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

Parameters:
  • freq (float)

  • duration (float)

  • vibrato_freq (float)

  • max_pitch_dev (float)

  • waveform_table (ArrayLike)

  • vibrato_waveform_table (ArrayLike)

  • alpha (float)

  • number_of_samples (int | None)

  • sample_rate (int | None)

Return type:

NDArray[float64]

See also

note

A basic musical note without vibrato.

tremolo

A tremolo, an oscillation of loudness.

note_with_fm

A linear oscillation of the frequency (not linear pitch).

am

A linear oscillation of amplitude (not linear loudness).

Notes

The vibrato’s pattern is read from its own table at its own frequency, as note() reads a table; it sets the note’s frequency at each sample, and the note’s table is read where those frequencies accumulate. In the article’s terms [1]:

\[ \begin{align}\begin{aligned}t'_i = \tilde{m}_{\gamma'_i \bmod \tilde{\Lambda}_M}, \qquad \gamma'_i = \left\lfloor i f' \frac{\tilde{\Lambda}_M}{f_s} \right\rfloor,\\f_i = f \, 2^{t'_i \nu / 12}, \qquad 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,\end{aligned}\end{align} \]

where \(\tilde{m}\) is vibrato_waveform_table, of length \(\tilde{\Lambda}_M\), \(f'\) is vibrato_freq, \(\nu\) is max_pitch_dev and the rest is as in note(). A pattern between -1 and 1 takes the pitch \(\nu\) semitones either way. With alpha other than 1 the exponent \(x = t'_i \nu / 12\) is bent to \(\operatorname{sgn}(x) |x|^{\alpha}\), an index the article gives transitions but not vibratos; see DISCREPANCIES.md.

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_vibrato())  # writes a WAV file of a note
>>> s = horizontal_stack(
...     *[note_with_vibrato(i, j) for i, j in zip([200, 500, 100],
... [2, 1, 2])])
>>> s2 = note_with_vibrato(440, 1.5, 6, 1)