Ir al contenido
Esta documentación describe la versión 4.0.0, todavía sin publicar. La versión actual en PyPI es la 3.3.0 y no incluye todo lo que se describe aquí.

electroacoustics.programme_signal

La referencia de la API se publica en inglés en los dos idiomas: se genera a partir de los docstrings del código, que son su texto original.

The simulated programme signal of IEC 60268-1:1985, Clause 7.

A loudspeaker, an amplifier or a headphone is rated with one tone at a time, but it is used with programme: speech and music, whose power is spread over the whole audio band and concentrated in its middle. IEC 60268-1:1985 Clause 7 defines a noise that stands in for that programme in a measurement, the simulated programme signal:

A signal, whose mean power spectral density closely resembles the average
of the mean power spectral densities of a wide range of programme
material, including both speech and music of several kinds, is stationary
weighted Gaussian noise without amplitude limiting, the weighted power
spectrum being in accordance with Table II and Figure 1, page 22, when
measured with third-octave filters in accordance with IEC Publication 225.

Table II gives the relative level of each one-third-octave band from 20 Hz to 20 kHz with its tolerance: 0 dB from 250 Hz to 800 Hz, falling to dB at 20 Hz and dB at 20 kHz (SIMULATED_PROGRAMME_SPECTRUM). The Note under the clause adds that the power of the whole signal is about 12,5 dB above the 0 dB of one band, which is the power sum of the 31 relative levels, 12,56 dB.

“Such a signal may be obtained from a pink-noise source by means of the filter circuit shown in Figure 2.” The circuit is a passive ladder of five capacitors driven from the e.m.f. of the pink-noise source through 430 ohm, which includes the source’s own output impedance:

  • a series 2,2 µF capacitor into a node shunted by 3,3 kohm and 91 nF;
  • a series 330 ohm and 2,2 µF into a node shunted by 3,3 kohm and 68 nF;
  • a series 0,47 µF into the 10 kohm output resistor, loaded by at least 100 kohm; “the effect of the load impedance may be taken into account by adjusting the value of the 10 kohm resistor”, so the 10 kohm is the whole shunt the network sees.

programme_signal_filter is the exact transfer function of that ladder, the voltage across the 10 kohm over the source e.m.f., from its nodal equations. The two 2,2 µF capacitors with the resistors behind them make the low-frequency roll-off and the 91 nF and 68 nF shunts the high-frequency one; the passband loss is about 4 dB. Pink noise has equal power in every one-third-octave band, so the band levels of its output are the power average of over each band, and in ideal one-third-octave bands they fall inside every tolerance of Table II once the level is set: the worst band is the 5 kHz one, 1,1 dB below its printed level against a tolerance of 1 dB when the 0 dB of the table is put on the 630 Hz band, and 0,18 dB inside it with the level that centres the whole curve in the tolerances. Figure 2 is a realisation within tolerance, not the definition: the definition is Table II.

simulated_programme_signal synthesises the signal in the frequency domain: a white Gaussian spectrum, shaped and transformed back to a record that is stationary and Gaussian, as the clause asks, at any sample rate and with no bilinear warping near the Nyquist frequency. It offers two shapes. The default puts every band on Table II itself: a power spectral density that is a straight line in decibels against the logarithm of frequency between the band centres, whose nodes are set so that the power of each band, integrated over it in closed form, is the printed level, and which carries on at the slope of its end segments below 20 Hz and above 20 kHz. Every band then keeps its whole tolerance for the fluctuation of a finite record. The other is the circuit of Figure 2, pink noise of slope in amplitude multiplied by the complex response of the ladder; at 0,18 dB from its nearest limit it leaves a short record little room, and a 20 s record at 48 kHz falls outside the tolerance of the 31,5 Hz or 40 Hz band for some seeds.

The clause asks for the noise “without amplitude limiting”. IEC 60268-7:2010 8.3.2 asks for the opposite when it rates the long-term maximum source e.m.f. of a headphone: the programme signal “with additional clipping”, with “a peak-to-r.m.s ratio between 1,8 and 2,2”. peak_to_rms clips the record at the level that gives the requested ratio after clipping and rescales it. Clipping spreads power into the weak upper bands: at a ratio of 2,0 it lifts the 20 kHz band by about half a decibel against the middle of the spectrum, inside its tolerance of 3 dB.

check_programme_signal judges one-third-octave band levels against Table II. The table is a relative spectrum: its 0 dB is not a level the signal has to reach, it is where the bands are referred to. The check therefore looks for the level that places every band inside its tolerance. Each band allows a window of levels, , and the spectrum conforms when the windows overlap; the level reported is the middle of the overlap, where the smallest margin is largest. Bands that are not given are not judged, so a record sampled at 44,1 kHz, which cannot hold the 20 kHz band, is judged on the other 30.

Neither amendment of 1988 touches Clause 7: Amendment 1 replaces Table AII, the tone-burst response of the quasi-peak meter of Appendix A, and Amendment 2 replaces 12.1, the three coils that make a uniform magnetic field.

Auto-generated from the source docstrings by scripts/generate_api_docs.py (make api-docs). Do not edit by hand.

check_programme_signal(
frequencies_hz: ArrayLike,
band_levels_db: ArrayLike,
) -> ProgrammeSignalCheck

Is this one-third-octave spectrum the programme signal of IEC 60268-1?

Clause 7 asks for a weighted power spectrum “in accordance with Table II and Figure 1 […] when measured with third-octave filters”. Table II is a relative spectrum, so the band levels are judged up to a constant: the spectrum conforms when one level places every band inside its tolerance (see the module docstring). Only the bands given are judged.

The band levels can come from any one-third-octave analyser, for instance phonometry.filters.octave_filter with fraction=3, whose exact band centres (19,95 Hz, 25,12 Hz, …) are read as the nominal ones of the table.

Parameters

NameDescription
frequencies_hzBand centre frequencies, in Hz, nominal or exact, each a band of Table II (20 Hz to 20 kHz) and none repeated.
band_levels_dbThe band levels, in dB, on any reference.

Returns: A ProgrammeSignalCheck.

Raises

ExceptionWhen
ValueErrorIf the inputs differ in length, a frequency is not a band of Table II or appears twice, a level is not finite, or fewer than two bands are given.
programme_signal_filter(frequencies_hz: ArrayLike) -> NDArray[np.complex128]

The transfer function of the filter of IEC 60268-1:1985 Figure 2.

The voltage across the 10 kohm output resistor over the e.m.f. of the pink-noise source, from the nodal equations of the ladder (see the module docstring for the circuit). The source’s output impedance is part of the first 430 ohm and the 10 kohm is the whole output shunt, the two conventions the figure’s notes state.

Parameters

NameDescription
frequencies_hzFrequencies, in Hz, any shape; each must be positive.

Returns: The complex response, dimensionless, with the shape of frequencies_hz.

Raises

ExceptionWhen
ValueErrorIf a frequency is not a positive finite number.
ProgrammeSignalCheck(
frequencies_hz: NDArray[np.float64],
band_levels_db: NDArray[np.float64],
)

A one-third-octave spectrum judged against IEC 60268-1:1985 Table II.

Attributes

NameDescription
frequencies_hzThe nominal frequencies of the bands judged, in Hz, ascending.
band_levels_dbThe band levels as given, in dB, in the order of frequencies_hz.

Table II’s relative levels and tolerances at the bands, and the offset that refers the levels to them, are read from the table, so a check cannot be built against other tolerances.

property

The bands at the smallest margin, in Hz.

The level is placed in the middle of the window every band allows, so the smallest margin is reached by at least two bands, one against its upper limit and one against its lower; those are the bands that fix the verdict.

property

Each band’s level, referred by offset_db, minus Table II, in dB.

property

The smallest distance of a band from its nearer limit, in dB.

Negative when the spectrum cannot be placed inside the tolerances: its magnitude is then the excursion of the worst band.

property

The level added to the band levels to refer them to Table II, in dB.

The middle of the window of levels that keeps every band inside its tolerance, or, when no level does, the level that shares the worst excursion equally between the two sides.

property

Whether some level places every band inside its tolerance.

ProgrammeSignalCheck.plot(
ax: Axes | None = None,
*,
language: str = 'en',
**kwargs: Any,
) -> Axes

Draw the referred band levels inside the tolerances of Table II.

Requires matplotlib (pip install phonometry[plot]).

Parameters

NameDescription
axExisting axes, or None to create a figure.
languageLabel language, "en" (default) or "es".
kwargsForwarded to the band levels’ Axes.plot.

Returns: The axes.

property

Table II’s relative levels at the bands, in dB.

property

The lower tolerances of Table II at the bands, in dB.

property

The upper tolerances of Table II at the bands, in dB.

ProgrammeSpectrumBand(
relative_level_db: float,
tolerance_plus_db: float,
tolerance_minus_db: float,
)

One row of IEC 60268-1:1985 Table II.

Attributes

NameDescription
relative_level_dbThe relative level of the one-third-octave band, in dB.
tolerance_plus_dbThe upper tolerance, in dB, as printed (a positive number).
tolerance_minus_dbThe lower tolerance, in dB, as printed (a positive number).
simulated_programme_signal(
fs: int,
seconds: float,
*,
rms: float = 1.0,
spectrum: Literal['table', 'figure_2'] = 'table',
peak_to_rms: float | None = None,
seed: int | None = None,
) -> NDArray[np.float64]

The simulated programme signal of IEC 60268-1:1985 Clause 7.

Stationary Gaussian noise whose one-third-octave spectrum follows Table II, synthesised in the frequency domain (see the module docstring). The record is zero-mean and scaled to rms exactly.

Two realisations are offered. "table" (default) puts every band of Table II on its printed level: the power spectral density is linear in decibels against the logarithm of frequency between the band centres, continued at the slope of the end segments below 20 Hz and above 20 kHz, and its nodes are set so that each band’s power, integrated over the band in closed form, is the printed level. Every band then has its whole tolerance for the random fluctuation of a finite record. "figure_2" is pink noise through the filter of Figure 2 (programme_signal_filter), the circuit the clause offers: inside the tolerances, but only 0,18 dB inside at its worst band, so a short record can fall outside them.

The clause asks for the noise “without amplitude limiting”, and so does this by default. peak_to_rms clips it instead, for the limiting voltages of IEC 60268-7:2010 8.3.2, which drive a headphone with the programme signal “with additional clipping” and a peak-to-r.m.s. ratio between 1,8 and 2,2: the record is clipped symmetrically at the level that leaves exactly that ratio after clipping, then rescaled to rms.

A one-third-octave band at 20 Hz is 4,6 Hz wide, so its level fluctuates by about dB over a record of seconds: 0,4 dB in 30 s. Table II allows 3 dB there; the 0,5 dB bands of the middle need a few seconds.

Parameters

NameDescription
fsSample rate, in hertz.
secondsDuration, in seconds.
rmsRMS value of the record, in whatever unit it is scaled to.
spectrum"table" (default) for the band levels of Table II, "figure_2" for pink noise through the filter of Figure 2.
peak_to_rmsThe ratio of the peak value to the RMS value after clipping, or None (default) for no clipping. It must be above 1 and below the ratio the unclipped record already has.
seedSeed for numpy.random.default_rng; the same seed reproduces the same record.

Returns: The signal, round(fs * seconds) samples.

Raises

ExceptionWhen
ValueErrorIf an input is invalid, or peak_to_rms is not below the ratio of the unclipped record.

Constant (mapping).