electroacoustics.programme_signal
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 averageof the mean power spectral densities of a wide range of programmematerial, including both speech and music of several kinds, is stationaryweighted Gaussian noise without amplitude limiting, the weighted powerspectrum being in accordance with Table II and Figure 1, page 22, whenmeasured 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.
The filter of Figure 2
Section titled “The filter of Figure 2”“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.
The generator
Section titled “The generator”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.
The verdict
Section titled “The verdict”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
Section titled “check_programme_signal”check_programme_signal( frequencies_hz: ArrayLike, band_levels_db: ArrayLike,) -> ProgrammeSignalCheckIs 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
| Name | Description |
|---|---|
frequencies_hz | Band centre frequencies, in Hz, nominal or exact, each a band of Table II (20 Hz to 20 kHz) and none repeated. |
band_levels_db | The band levels, in dB, on any reference. |
Returns: A ProgrammeSignalCheck.
Raises
| Exception | When |
|---|---|
| ValueError | If 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
Section titled “programme_signal_filter”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
| Name | Description |
|---|---|
frequencies_hz | Frequencies, in Hz, any shape; each must be positive. |
Returns: The complex response, dimensionless, with the shape of frequencies_hz.
Raises
| Exception | When |
|---|---|
| ValueError | If a frequency is not a positive finite number. |
ProgrammeSignalCheck
Section titled “ProgrammeSignalCheck”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
| Name | Description |
|---|---|
frequencies_hz | The nominal frequencies of the bands judged, in Hz, ascending. |
band_levels_db | The 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.
ProgrammeSignalCheck.binding_bands_hz
Section titled “ProgrammeSignalCheck.binding_bands_hz”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.
ProgrammeSignalCheck.deviations_db
Section titled “ProgrammeSignalCheck.deviations_db”property
Each band’s level, referred by offset_db, minus Table II, in dB.
ProgrammeSignalCheck.margin_db
Section titled “ProgrammeSignalCheck.margin_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.
ProgrammeSignalCheck.offset_db
Section titled “ProgrammeSignalCheck.offset_db”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.
ProgrammeSignalCheck.passes
Section titled “ProgrammeSignalCheck.passes”property
Whether some level places every band inside its tolerance.
ProgrammeSignalCheck.plot()
Section titled “ProgrammeSignalCheck.plot()”ProgrammeSignalCheck.plot( ax: Axes | None = None, *, language: str = 'en', **kwargs: Any,) -> AxesDraw the referred band levels inside the tolerances of Table II.
Requires matplotlib (pip install phonometry[plot]).
Parameters
| Name | Description |
|---|---|
ax | Existing axes, or None to create a figure. |
language | Label language, "en" (default) or "es". |
kwargs | Forwarded to the band levels’ Axes.plot. |
Returns: The axes.
ProgrammeSignalCheck.relative_levels_db
Section titled “ProgrammeSignalCheck.relative_levels_db”property
Table II’s relative levels at the bands, in dB.
ProgrammeSignalCheck.tolerance_minus_db
Section titled “ProgrammeSignalCheck.tolerance_minus_db”property
The lower tolerances of Table II at the bands, in dB.
ProgrammeSignalCheck.tolerance_plus_db
Section titled “ProgrammeSignalCheck.tolerance_plus_db”property
The upper tolerances of Table II at the bands, in dB.
ProgrammeSpectrumBand
Section titled “ProgrammeSpectrumBand”ProgrammeSpectrumBand( relative_level_db: float, tolerance_plus_db: float, tolerance_minus_db: float,)One row of IEC 60268-1:1985 Table II.
Attributes
| Name | Description |
|---|---|
relative_level_db | The relative level of the one-third-octave band, in dB. |
tolerance_plus_db | The upper tolerance, in dB, as printed (a positive number). |
tolerance_minus_db | The lower tolerance, in dB, as printed (a positive number). |
simulated_programme_signal
Section titled “simulated_programme_signal”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
| Name | Description |
|---|---|
fs | Sample rate, in hertz. |
seconds | Duration, in seconds. |
rms | RMS 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_rms | The 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. |
seed | Seed for numpy.random.default_rng; the same seed reproduces the same record. |
Returns: The signal, round(fs * seconds) samples.
Raises
| Exception | When |
|---|---|
| ValueError | If an input is invalid, or peak_to_rms is not below the ratio of the unclipped record. |
SIMULATED_PROGRAMME_SPECTRUM
Section titled “SIMULATED_PROGRAMME_SPECTRUM”Constant (mapping).