music.localize_linear

music.localize_linear(sonic_vector=None, theta1=90, theta2=0, dist=0.1, zeta=0.215, air_temp=20, sample_rate=44100)[source]

Localize a sound along a straight path between two angles.

The source moves at a constant rate from theta1 to theta2, both at dist from the listener, over the duration of sonic_vector. Its position is computed for every sample, and from each position the interaural intensity and time differences for that sample.

Parameters:
sonic_vectorarray_like

A one-dimensional array with the PCM samples of the sound.

theta1scalar

The azimuthal angle of the starting position in degrees.

theta2scalar

The azimuthal angle of the ending position in degrees.

distscalar

The distance of the source from the listener in meters, held for both endpoints.

zetascalar

The distance between the ears in meters.

air_tempscalar

The temperature in Celsius used for calculating the speed of sound.

sample_rateinteger

The sample rate.

Returns:
sndarray

A (2, nsamples) array with the PCM samples of the stereo sound, the same length as sonic_vector.

See also

localize

the same cues for a fixed position.

music.note_with_doppler

a moving source, synthesized rather than filtered, so it also shifts pitch.

Notes

The path is a straight line between the two positions, not an arc, which is what makes it linear.

Both cues are measured against the nearer ear at each sample, as localize() measures them against the nearer ear of its one fixed position. The nearer ear is therefore heard undelayed and unattenuated, and the farther ear is delayed by the extra distance the sound travels to reach it, and attenuated by the ratio of the two distances. Only the difference between the ears is applied: the propagation delay common to both is not, so the result stays aligned with its input and keeps its length.

The delay varies by a fraction of a sample from one sample to the next, so it is applied by reading the input at interpolated positions – see _delayed(). Rounding to whole samples instead would quantize a smoothly moving source into audible steps.

This filters an existing sound and so does not model the Doppler shift that a physically moving source would produce; use music.note_with_doppler() for that.

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_stereo(localize_linear(note(duration=3)))
>>> # a pass from the left to the right and back
>>> horizontal_stack(localize_linear(note(), theta1=90, theta2=-90),
...                  localize_linear(note(), theta1=-90, theta2=90))