Skip to content

Speech Intelligibility Index

Standards: ANSI S3.5Key references: French & Steinberg 1947

The Speech Intelligibility Index predicts how much of a speech signal is audible, and therefore intelligible, to a listener in a given noise and hearing condition. It reduces a speech spectrum, a noise spectrum and a hearing threshold to a single number in [0, 1]: 0 when nothing useful reaches the listener, 1 when the whole speech-bearing spectrum is audible. This page covers all four band procedures of ANSI S3.5-1997 (R2017): the one-third-octave-band method (18 bands from 160 Hz to 8000 Hz), which is the default and the one sections 1 to 4 work through, and the critical-band, equally-contributing critical-band and octave-band methods of section 5.

The SII computation flow: three equivalent-spectrum-level inputs (speech Ei', noise Ni', hearing threshold Ti') feed the self-speech masking and spread-of-masking stage (equivalent masking spectrum level Zi), then the equivalent disturbance Di, then the band-audibility function Ai clipped to [0, 1], and finally the band-importance-weighted sum SII over the 18 one-third-octave bandsThe SII computation flow: three equivalent-spectrum-level inputs (speech Ei', noise Ni', hearing threshold Ti') feed the self-speech masking and spread-of-masking stage (equivalent masking spectrum level Zi), then the equivalent disturbance Di, then the band-audibility function Ai clipped to [0, 1], and finally the band-importance-weighted sum SII over the 18 one-third-octave bands

1. Inputs and the band-importance function

Section titled “1. Inputs and the band-importance function”

All three inputs are equivalent spectrum levels (ANSI S3.5-1997 clauses 3.11 and 3.55) sampled at the 18 one-third-octave band centres: the speech spectrum level , the noise spectrum level (both in dB SPL) and the hearing threshold (in dB HL). Each band contributes to intelligibility in proportion to its band-importance function (ANSI S3.5-1997 Table 3, average speech material), which sums to one across the 18 bands.

from phonometry import speech
# The standard normal-effort speech spectrum (Table 3) in quiet, normal hearing.
result = speech.speech_intelligibility_index("normal")
print(round(result.sii, 3)) # 0.996 (nearly everything audible)
print(round(speech.sii.BAND_IMPORTANCE.sum(), 6)) # 1.0
result.plot() # per-band audibility and its weighted contribution (needs matplotlib)

With no noise and a normal hearing threshold the standard speech spectrum is almost fully audible, so the index is close to one; the small deficit is the listener’s own self-speech masking.

The importance function is where the perceptual knowledge of the standard lives. It descends from the articulation experiments behind French and Steinberg’s articulation index: listeners scored nonsense syllables heard through filters that removed one part of the spectrum at a time, and the drop in score measures how much intelligibility each band carries. The outcome is strikingly unequal, and unrelated to where the speech energy sits: the five bands from 1250 Hz to 3150 Hz carry about 43 % of intelligibility (the place and manner cues of consonants live there), while the five lowest bands, 160 Hz to 400 Hz, carry about 11 % even though they hold nearly half of the speech power. from Table 3 is the average-speech compromise; the standard’s Annex B tabulates alternative importance functions for specific test materials (nonsense syllables, monosyllabic word lists, short passages), which shift weight according to how much redundancy the material offers.

This is the trap that silently ruins an SII computed from measured data. An equivalent spectrum level is the level the band would have if its energy were spread over 1 Hz, so a one-third-octave band level from an analyser becomes a spectrum level by subtracting ten times the logarithm of the band width in hertz:

The widths need not be memorised: every procedure object carries its own band edges, so the conversion is two lines for any of the four methods.

import numpy as np
# `speech` is the import of the first snippet on this page.
proc = speech.sii_procedure("one-third-octave")
widths = np.diff(proc.band_edges) # hertz, band by band
print(np.round(10 * np.log10(widths), 1)[[0, 8, 17]]) # [15.5 23.5 32.7]
band_levels = np.full(18, 55.0) # what an analyser reports
spectrum_levels = band_levels - 10 * np.log10(widths)
print(round(float(spectrum_levels[8]), 1)) # 31.5 dB at 1 kHz

So the correction runs from 15.5 dB at 160 Hz to 32.7 dB at 8 kHz for the one-third-octave procedure, and is 28.5 dB at 1 kHz for the octave procedure — that is, a measured 55 dB band level at 1 kHz is a 31.5 dB spectrum level, not a 55 dB one. Feed band levels straight in and both the speech and the noise are 15 to 33 dB too high, band by band, and the failure is silent: the index stays inside and the audibility plot still looks plausible.

Two things follow. The threshold input is not converted: it is a hearing threshold level in dB HL, a level difference rather than a per-hertz quantity. And there is a cheap sanity check: because a spectrum level is per hertz, a white noise has the same equivalent noise spectrum level in every band of every procedure, whereas its band levels rise by 3 dB per octave. If an SII comes out exactly 0 for ordinary office noise, or exactly 1 with noise present, suspect band levels entered as spectrum levels; a quick check is that the standard’s own normal-effort speech spectrum peaks at 34.8 dB near 250 Hz, so any speech input more than about 15 dB above that is a band level.

The reason the three inputs can be combined at all is that they describe the same point in space. ANSI S3.5-1997 defines the equivalent speech and noise spectrum levels at the position corresponding to the centre of the listener’s head, midway between the ears, with the listener absent — both are field quantities at an unoccupied listening position. So: measure the noise there with the talker or source of interest silent, and the speech there with the talker at the real distance and vocal effort.

Three consequences worth writing into a report. The tabulated vocal-effort spectra of section 4 are the standard’s reference speech, excellent for design and comparison but not a substitute for a measured when the real listening condition is at another distance or in a reverberant space. Levels recorded at the eardrum, in a coupler or under headphones are not equivalent free-field levels and have to be transformed back before they can be used. And threshold= is the listener’s pure-tone hearing threshold level in dB HL at the 18 band centres and belongs to one ear, so state which ear it is and how the audiogram was put onto those centres, which section 3.2 returns to.

2. Masking and the band-audibility function

Section titled “2. Masking and the band-audibility function”

The procedure (ANSI S3.5-1997 clause 5) turns the inputs into a per-band audibility. Speech masks itself downward from each band (); the larger of that and the external noise, , spreads upward in frequency with a level-dependent slope to give the equivalent masking spectrum level (clause 5.4):

The masking is combined with the equivalent internal noise (, the reference internal noise shifted by the hearing loss) into the equivalent disturbance (clause 5.6), and the band-audibility function is the speech-to-disturbance ratio scaled into (clause 5.8):

At speech levels well above normal effort a level-distortion factor of clause 5.7 (unity for the standard spectra used on this page) reduces further; phonometry applies it automatically.

Every array in that chain is on the result, so the whole of clause 5 can be drawn for a case where the spread of masking does the work — a fan or a duct that puts all its energy below 450 Hz:

The ANSI S3.5 clause 5 chain over the 18 one-third-octave bands for the standard normal-effort speech in a masker whose 60 dB spectrum level is confined below 450 Hz. The external noise drops to nothing above 400 Hz, but the equivalent masking spectrum level decays gradually instead, still 23 dB at 1 kHz where there is no noise at all; the equivalent disturbance follows it, the shaded 30 dB window from D minus 15 to D plus 15 dB is drawn around it, and the band audibility on the right-hand axis rises from zero at 500 Hz to one by 2000 Hz as the speech curve climbs out of that window. The index is 0.60The ANSI S3.5 clause 5 chain over the 18 one-third-octave bands for the standard normal-effort speech in a masker whose 60 dB spectrum level is confined below 450 Hz. The external noise drops to nothing above 400 Hz, but the equivalent masking spectrum level decays gradually instead, still 23 dB at 1 kHz where there is no noise at all; the equivalent disturbance follows it, the shaded 30 dB window from D minus 15 to D plus 15 dB is drawn around it, and the band audibility on the right-hand axis rises from zero at 500 Hz to one by 2000 Hz as the speech curve climbs out of that window. The index is 0.60

The band audibility is a position inside a 30 dB window: at the bottom edge the band is fully masked, at the top fully audible, and in between it is a straight line. The window is centred on , and follows , which is the point of the figure — there is no noise at all above 400 Hz, yet the masking at 1 kHz is 23 dB, spread upward from the low bands. That upward skirt is what makes the SII more than a band-by-band signal-to-noise ratio, and it is the term the octave procedure of section 5 drops.

Show the code for this figure
import matplotlib.pyplot as plt
# `np` and `speech` come from the snippets above.
freqs = speech.sii_procedure("one-third-octave").frequencies
noise = np.where(freqs <= 450.0, 60.0, 0.0) # all the energy below 450 Hz
res = speech.speech_intelligibility_index("normal", noise)
print(round(res.sii, 2), round(float(res.masking[8]), 1)) # 0.6 23.2
pos = np.arange(freqs.size)
fig, ax = plt.subplots(figsize=(10.4, 6.0))
ax.fill_between(pos, res.disturbance - 15, res.disturbance + 15, alpha=0.25)
ax.plot(pos, res.speech_spectrum, "o-", label="speech Ei'")
ax.plot(pos, noise, "s--", label="external noise Ni'")
ax.plot(pos, res.masking, "^-", label="equivalent masking Zi")
ax.twinx().plot(pos, res.band_audibility) # the audibility on the right
ax.legend()
plt.show()

The Speech Intelligibility Index is the band-importance-weighted sum of the band audibilities (ANSI S3.5-1997 clause 6):

import numpy as np
from phonometry import speech
speech_spectrum = speech.standard_speech_spectrum("normal")
# A descending broadband masking noise (an office/ventilation-like spectrum).
noise = np.array([38.0, 37.0, 36.0, 34.0, 32.0, 30.0, 28.0, 26.0, 24.0,
22.0, 20.0, 18.0, 16.0, 14.0, 12.0, 10.0, 8.0, 6.0])
result = speech.speech_intelligibility_index(speech_spectrum, noise)
print(round(result.sii, 2)) # 0.46
print(result.band_audibility.round(2)) # per-band Ai
result.plot() # the figure below: Ai and the weighted contribution per band
Band audibility of the standard normal-effort speech spectrum in a descending broadband noise: the light bars are the per-band audibility Ai across the 18 one-third-octave bands from 160 Hz to 8000 Hz, the darker bars the importance-weighted contribution Ii*Ai (scaled), and the overall SII is 0.46Band audibility of the standard normal-effort speech spectrum in a descending broadband noise: the light bars are the per-band audibility Ai across the 18 one-third-octave bands from 160 Hz to 8000 Hz, the darker bars the importance-weighted contribution Ii*Ai (scaled), and the overall SII is 0.46
Show the code for this figure
import numpy as np
import matplotlib.pyplot as plt
from phonometry import speech
speech_spectrum = speech.standard_speech_spectrum("normal")
noise = np.array([38.0, 37.0, 36.0, 34.0, 32.0, 30.0, 28.0, 26.0, 24.0,
22.0, 20.0, 18.0, 16.0, 14.0, 12.0, 10.0, 8.0, 6.0])
result = speech.speech_intelligibility_index(speech_spectrum, noise)
# One line:
result.plot()
plt.show()
# By hand, mirroring what SIIResult.plot() draws:
pos = np.arange(result.frequencies.size)
weighted = result.band_audibility * result.band_importance
fig, ax = plt.subplots()
ax.bar(pos, result.band_audibility, color="#c6dbef", label=r"Band audibility $A_i$")
ax.bar(pos, weighted / weighted.max(), width=0.5, color="#1f77b4",
label=r"Importance-weighted $I_i\,A_i$ (scaled)")
ax.set_xticks(pos)
ax.set_xticklabels([f"{f:g}" for f in result.frequencies], rotation=45, ha="right")
ax.set_xlabel("One-third-octave band [Hz]")
ax.set_ylabel("Band audibility")
ax.set_title(f"SII = {result.sii:.2f}")
ax.legend()
plt.show()

Reading the number. The SII is the importance-weighted fraction of the speech spectrum that is audible, so 0.46 means that roughly half of what carries intelligibility is getting through. It is a proportion of audibility, not of words: ANSI S3.5 maps the index to intelligibility only through transfer functions specific to the speech material and the listeners, which is why the same 0.5 supports high sentence scores and much lower nonsense-syllable scores. Never quote an SII as “X % intelligible” without naming the material. As practical anchors, above about 0.75 is the design target where unfamiliar material must be understood — the same ladder that makes requirement=0.75 a reasonable value in the fiche of section 7; 0.45 to 0.75 is workable for familiar material in a known context; below about 0.3 speech communication cannot be relied on. And mind the resolution: the inputs are measured spectra with their own uncertainty, so differences of a few hundredths are noise. When two conditions score alike, the per-band audibility profile — not the scalar — is the part that tells you what to fix.

A raised hearing threshold (threshold=) lifts the equivalent internal noise and lowers the index, exactly as added masking noise does. The input is a pure-tone hearing threshold level in dB HL at the 18 band centres, for one ear. The SIIResult also carries the per-band masking , disturbance , audibility and importance , and its .plot() renders the figure above.

The same speech and noise heard by a listener with a sloping high-frequency loss shows what that costs, band by band:

Band audibility of the standard normal-effort speech spectrum in the same broadband noise, for a listener with a sloping high-frequency hearing loss: the bands up to 800 Hz keep much of their audibility, the bands from 4000 Hz up fall to zero, and the resulting SII is 0.36 against the 0.46 of a normal-hearing listenerBand audibility of the standard normal-effort speech spectrum in the same broadband noise, for a listener with a sloping high-frequency hearing loss: the bands up to 800 Hz keep much of their audibility, the bands from 4000 Hz up fall to zero, and the resulting SII is 0.36 against the 0.46 of a normal-hearing listener
Show the code for this figure
import numpy as np
import matplotlib.pyplot as plt
from phonometry import speech
# The same speech and office noise as above, heard through a sloping
# high-frequency loss (hearing threshold levels at the 18 band centres).
speech_spectrum = speech.standard_speech_spectrum("normal")
noise = np.array([38.0, 37.0, 36.0, 34.0, 32.0, 30.0, 28.0, 26.0, 24.0,
22.0, 20.0, 18.0, 16.0, 14.0, 12.0, 10.0, 8.0, 6.0])
threshold = np.array([5.0, 5.0, 5.0, 5.0, 8.0, 10.0, 12.0, 15.0, 18.0,
22.0, 28.0, 35.0, 42.0, 48.0, 55.0, 60.0, 65.0, 70.0])
res = speech.speech_intelligibility_index(speech_spectrum, noise, threshold=threshold)
print(round(res.sii, 3)) # 0.358 (0.458 with normal hearing)
# One line: the same audibility bars, now limited by the hearing threshold.
res.plot()
plt.show()

The loss removes the bands that carry the consonant cues, which is why the index falls by a fifth while the level of the speech has not changed at all. This is the practical use of the SII in audiology and in noise control for occupied spaces: a target index can be met either by lowering the noise or by restoring audibility (amplification), and the band profile says which bands the effort has to go into.

Getting a threshold array onto the SII grid. The age-related thresholds of ISO 7029 are a convenient population input, but the two standards are tabulated on different grids and the transfer is the caller’s decision, not an automatic one. ISO 7029 returns eleven audiometric frequencies (125 to 8000 Hz) while the one-third-octave SII procedure needs eighteen values at 160 Hz to 8000 Hz, and ANSI S3.5 defines no interpolation — the page’s own “Not covered” block says no resampling between band sets is provided. So make the choice explicit: interpolate the audiometric thresholds on a logarithmic frequency axis onto the SII band centres, or take the nearest audiometric frequency for each band, and say which in the report. There is a second mismatch: age_threshold returns the deviation from the median 18-year-old, which is a hearing threshold level in dB HL only if that baseline is taken as 0 dB HL — an assumption worth stating, and one to drop entirely when a real audiogram exists, since measured dB HL values can be fed directly. Finally, mind the direction of the error: a coarse interpolation smooths away the 3 kHz to 6 kHz notch that a noise-exposed audiogram carries, and those are bands with high importance weight, so the SII comes out optimistic.

Talkers raise their voice in noise, and the standard gives four standard speech spectra for the vocal efforts normal, raised, loud and shout (ANSI S3.5-1997 Table 3). Passing the effort name selects the corresponding spectrum; speaking louder lifts the whole spectrum and, in a fixed noise, raises the index.

import numpy as np
from phonometry import speech
# The same broadband noise, four vocal efforts.
noise = np.array([48.0, 47.0, 46.0, 44.0, 42.0, 40.0, 38.0, 36.0, 34.0,
32.0, 30.0, 28.0, 26.0, 24.0, 22.0, 20.0, 18.0, 16.0])
for effort in speech.sii.VOCAL_EFFORTS:
print(effort, round(speech.speech_intelligibility_index(effort, noise).sii, 2))
# normal 0.12 | raised 0.36 | loud 0.59 | shout 0.79
print(speech.standard_speech_spectrum("loud")[8]) # 42.16 dB SPL at 1 kHz

The four spectra are also available as one plottable result: standard_speech_spectra() returns a StandardSpeechSpectrum carrying the band centre frequencies and the per-effort band levels, and its .plot() draws them as one labelled family on the one-third-octave band axis.

The four ANSI S3.5-1997 standard speech spectra (normal, raised, loud, shout) as one labelled family: the standard speech spectrum level in dB SPL over 160 Hz to 8000 Hz, each higher effort lifting the whole spectrumThe four ANSI S3.5-1997 standard speech spectra (normal, raised, loud, shout) as one labelled family: the standard speech spectrum level in dB SPL over 160 Hz to 8000 Hz, each higher effort lifting the whole spectrum
Show the code for this figure
import numpy as np
import matplotlib.pyplot as plt
from phonometry import speech
# One line: the whole ANSI S3.5-1997 Table 3 family.
speech.standard_speech_spectra().plot()
plt.show()
# By hand, mirroring what StandardSpeechSpectrum.plot() draws:
res = speech.standard_speech_spectra()
pos = np.arange(res.frequencies.size)
fig, ax = plt.subplots()
for effort, levels in zip(res.vocal_efforts, res.levels):
ax.plot(pos, levels, "o-", label=effort.capitalize())
ax.set_xticks(pos)
ax.set_xticklabels([f"{f:g}" for f in res.frequencies], rotation=45, ha="right")
ax.set_xlabel("One-third-octave band [Hz]")
ax.set_ylabel("Speech spectrum level [dB SPL]")
ax.legend()
plt.show()

The same four spectra feed the index: in a fixed broadband noise, each higher vocal effort lifts the speech spectrum and raises the SII.

Left: the four ANSI S3.5-1997 standard speech spectra (normal, raised, loud, shout) over 160 Hz to 8000 Hz, each higher effort lifting the whole spectrum. Right: the resulting SII in a fixed broadband noise, rising from 0.12 (normal) to 0.79 (shout)Left: the four ANSI S3.5-1997 standard speech spectra (normal, raised, loud, shout) over 160 Hz to 8000 Hz, each higher effort lifting the whole spectrum. Right: the resulting SII in a fixed broadband noise, rising from 0.12 (normal) to 0.79 (shout)
Show the code for this figure
import numpy as np
import matplotlib.pyplot as plt
from matplotlib.ticker import NullFormatter
from phonometry import speech
# The four ANSI S3.5-1997 Table 3 spectra and the fixed broadband noise above.
noise = np.array([48.0, 47.0, 46.0, 44.0, 42.0, 40.0, 38.0, 36.0, 34.0,
32.0, 30.0, 28.0, 26.0, 24.0, 22.0, 20.0, 18.0, 16.0])
efforts = speech.sii.VOCAL_EFFORTS # ("normal", "raised", "loud", "shout")
freqs = speech.sii.BAND_CENTERS # the 18 one-third-octave band centres
fig, (ax_s, ax_i) = plt.subplots(1, 2, figsize=(12, 5))
# Left: each higher vocal effort lifts the whole speech spectrum.
for effort in efforts:
ax_s.plot(freqs, speech.standard_speech_spectrum(effort), "o-",
label=effort.capitalize())
ax_s.set_xscale("log")
ax_s.set_xticks(list(freqs))
ax_s.set_xticklabels([f"{f:g}" for f in freqs], rotation=45, ha="right")
ax_s.xaxis.set_minor_formatter(NullFormatter())
ax_s.set_xlabel("One-third-octave band [Hz]")
ax_s.set_ylabel("Speech spectrum level [dB SPL]")
ax_s.legend()
# Right: the SII each spectrum reaches in the fixed noise.
sii = [speech.speech_intelligibility_index(e, noise).sii for e in efforts]
pos = np.arange(len(efforts))
ax_i.bar(pos, sii)
ax_i.set_xticks(pos)
ax_i.set_xticklabels([e.capitalize() for e in efforts])
ax_i.set_ylim(0.0, 1.0)
ax_i.set_ylabel("Speech Intelligibility Index")
plt.show()

The vocal-effort names work anywhere a speech spectrum is expected, including as the first argument to speech_intelligibility_index.

The standard’s own title is plural, and so is the standard: ANSI S3.5-1997 defines four band procedures. They differ only in the band table and in how the upward spread of masking is expressed, and method= selects one. The default is the one-third-octave procedure used above.

method=BandsBand centresBand limitsConstantsSpread of masking
"critical-band"21150 Hz to 8500 Hz100 Hz to 9500 HzTable 1between tabulated band limits
"equally-contributing"17350 Hz to 5800 Hz300 Hz to 6400 HzTable 2between tabulated band limits
"one-third-octave"18160 Hz to 8000 Hz143 Hz to 8980 Hz (computed)Table 3between band centre frequencies
"octave"6250 Hz to 8000 Hz177 Hz to 11314 HzTable 4none

The two columns are sii_procedure(method).frequencies and .band_edges; only the one-third-octave limits are computed from the centres rather than tabulated.

Every procedure runs the same chain as section 2: self-speech masking, the upward spread of masking, the equivalent internal noise and disturbance, the level-distortion factor and the band-audibility function, weighted by that procedure’s own band-importance function. The masking slope is one formula throughout, with the band width in hertz. The critical-band and equally-contributing procedures spread the masking from the upper limit of the masker band up to the centre frequency of the masked band; the one-third-octave procedure writes that same geometry in terms of the band centres, which is where its printed and dB come from. The octave-band procedure carries no spread of masking at all: an octave band is already wider than the spread being modelled, so its equivalent masking spectrum level is the equivalent noise spectrum level itself.

The four band-importance functions are one underlying distribution sampled at four resolutions, so the wider the bands, the larger each . Each function sums to one, except Table 2’s, which prints 0.0588 in each of its 17 bands and so sums to 0.9996.

The band-importance function of the four ANSI S3.5-1997 band procedures overlaid on one logarithmic frequency axis: the 21 critical bands, the 17 equally-contributing critical bands, the 18 one-third-octave bands and the 6 octave bands, each drawn as a step across its own band limits. All four trace the same rise to a maximum around 2 kHz, and the wider the bands the higher the step, the octave function peaking at 0.265 against 0.090 for the one-third-octave functionThe band-importance function of the four ANSI S3.5-1997 band procedures overlaid on one logarithmic frequency axis: the 21 critical bands, the 17 equally-contributing critical bands, the 18 one-third-octave bands and the 6 octave bands, each drawn as a step across its own band limits. All four trace the same rise to a maximum around 2 kHz, and the wider the bands the higher the step, the octave function peaking at 0.265 against 0.090 for the one-third-octave function
Show the code for this figure
import numpy as np
import matplotlib.pyplot as plt
from phonometry import SII_METHODS, sii_procedure
# One line: each procedure's own .plot() steps its Ii over its band limits.
fig, ax = plt.subplots(figsize=(10, 6))
for method in SII_METHODS:
sii_procedure(method).plot(ax=ax, linewidth=1.8)
plt.show()
# By hand, mirroring what SIIProcedure.plot() draws:
fig, ax = plt.subplots()
for method in SII_METHODS:
proc = sii_procedure(method)
ii = proc.band_importance
ax.plot(proc.band_edges, np.append(ii, ii[-1]), drawstyle="steps-post",
label=method)
ax.set_xscale("log")
ax.set_xlabel("Frequency [Hz]")
ax.set_ylabel(r"Band importance $I_i$")
ax.set_ylim(bottom=0.0)
ax.legend()
plt.show()

Because an equivalent spectrum level is a per-hertz quantity, a white noise has the same equivalent noise spectrum level in every band of every procedure, which makes the four directly comparable:

import numpy as np
from phonometry import speech
for method in speech.SII_METHODS:
n_bands = speech.sii_procedure(method).frequencies.size
result = speech.speech_intelligibility_index(
"normal", np.full(n_bands, 25.0), method=method
)
print(method, n_bands, round(result.sii, 3))
# critical-band 21 0.343
# equally-contributing 17 0.333
# one-third-octave 18 0.350
# octave 6 0.369

The four agree to within about 0.04 on the same listening situation. The octave procedure reads highest because it drops the spread of masking, which is exactly the risk it carries: feed it a strong low-frequency noise and it will not see that noise reaching up into the speech-bearing bands.

SII computed by all four band procedures against the spectrum level of a low-frequency noise confined below 450 Hz, swept from 45 to 80 dB. The critical-band, equally-contributing and one-third-octave curves fall together from about 0.75 to below 0.07, while the octave curve stays flat at 0.87 throughout; at the loudest point the two are annotated as 0.81 index units apartSII computed by all four band procedures against the spectrum level of a low-frequency noise confined below 450 Hz, swept from 45 to 80 dB. The critical-band, equally-contributing and one-third-octave curves fall together from about 0.75 to below 0.07, while the octave curve stays flat at 0.87 throughout; at the loudest point the two are annotated as 0.81 index units apart

The agreement above is a property of the stimulus, not of the procedures. On white noise all four track each other; on a masker that lives below 450 Hz the three procedures that carry the upward spread of masking collapse together while the octave procedure does not move at all — 0.81 index units apart at the loudest point, which is most of the scale. An octave-band SII under low-frequency-dominated noise is an upper bound, not an estimate.

Show the code for this figure
levels = np.arange(45.0, 80.1, 1.0)
for method in ("critical-band", "equally-contributing", "one-third-octave",
"octave"):
proc = speech.sii_procedure(method)
curve = [speech.speech_intelligibility_index(
proc.speech_spectrum,
np.where(np.asarray(proc.frequencies) <= 450.0, x, 0.0),
method=method).sii for x in levels]
print(method, round(curve[0], 3), round(curve[-1], 3))
# critical-band 0.736 0.03
# equally-contributing 0.753 0.026
# one-third-octave 0.777 0.067
# octave 0.882 0.872

Which procedure to use.

  • "one-third-octave" is the working default: the finest resolution the standard offers, the only table that carries all four vocal-effort speech spectra, and the resolution measurement data usually arrives in.
  • "critical-band" follows the auditory filter. Its 21 bands are the classical critical bands, so it is the procedure to pair with critical-band models of masking or loudness, and the only one that reaches down to 100 Hz.
  • "equally-contributing" gives all 17 of its bands the same importance over 300 Hz to 6400 Hz, so the index reads directly as the fraction of equally-important bands that are audible. That makes it fast to check by hand, and it is the presentation closest to the articulation-index tradition the SII grew out of.
  • "octave" is for octave-band data, which is what sound level meters, HVAC selections and building-acoustics reports routinely give. Use it when that is all you have, and read it knowing the spread of masking is missing.

An alternative band-importance function. band_importance= replaces the procedure’s tabulated with one of your own, which is how the standard’s Annex B functions for particular speech test materials (nonsense syllables, monosyllabic word lists, short passages) are applied. It changes the weighting only: the audibility chain, and therefore result.band_audibility, is untouched.

res = speech.speech_intelligibility_index(
"normal", np.full(6, 25.0), method="octave",
band_importance=[0.0, 0.0, 1.0, 0.0, 0.0, 0.0], # all the weight at 1 kHz
)
print(round(res.sii, 3)) # 0.5 (the 1 kHz octave band alone)

The tabulated constants. sii_procedure(method) returns an SIIProcedure carrying that procedure’s band centre frequencies, band limits, band-importance function, reference internal noise spectrum level and normal-effort standard speech spectrum level; its .plot() draws the band-importance function as a step over the band limits, which is the figure above. Tables 1, 2 and 4 print all four vocal-effort columns in the standard, but only their normal-effort column is carried here, so "raised", "loud" and "shout" are available on the one-third-octave procedure alone.

octave = speech.sii_procedure("octave")
print(octave.frequencies) # [ 250. 500. 1000. 2000. 4000. 8000.]
print(octave.band_importance) # [0.0617 0.1671 0.2373 0.2648 0.2142 0.0549]
# Table 2 is critical bands 3 to 19 of Table 1, weighted equally.
equal = speech.sii_procedure("equally-contributing")
print(equal.band_edges[0], equal.band_edges[-1]) # 300.0 6400.0
print(equal.band_importance.sum().round(4)) # 0.9996

The two speech metrics answer different questions from different measurements, and each is blind to what the other captures:

SII (ANSI S3.5)STI (IEC 60268-16)
Question answeredIs enough of the speech spectrum audible at the listener’s ear?How much of the speech envelope does the transmission channel preserve?
InputsSpeech, noise and hearing-threshold spectra (18 one-third-octave equivalent spectrum levels)An impulse response (indirect) or a STIPA recording through the channel (direct)
Band machineryBand-importance weighting applied to the band audibility Modulation transfer function per octave band, converted to an effective SNR
CapturesSteady noise, upward spread of masking, hearing loss, vocal effort, level distortionReverberation, echoes, noise and (measured directly) non-linear processing
Blind toReverberation and any time-domain smearing: a fully audible but hopelessly reverberant channel still scores highIndividual hearing status: hearing-impaired listeners need specific corrections
Typical useAudiology, hearing aids and protectors, noise-control targets at a listener positionPA systems, intercoms and rooms: rating a transmission channel end to end

The same space can pass one and fail the other. A quiet, highly reverberant atrium is an SII near 1 with a poor STI; a dry office flooded by ventilation noise can rate an acceptable STI from its impulse response while the SII (and the noise-aware STI, via snr= or level=) reveals that little of the speech spectrum clears the noise. When both mechanisms are in play, compute both; the inputs are cheap once the room and the noise have been measured. See the Speech Transmission Index guide for the STI side.

SIIResult.report(path) renders a one-page PDF fiche laid out like a speech-audibility report: a standard-basis line, an optional metadata header block, a per-one-third-octave-band table of the equivalent speech spectrum , the Table 3 band-importance function and the band-audibility function beside the audibility and importance-weighted contribution bars (the result’s own .plot()), the boxed SII = X single number, an optional verdict row and a footer with the fixed disclaimer. It uses the same ReportMetadata container and rendering engine as the ISO 717 insulation fiche; a supplied requirement is read as the minimum required SII (a higher SII passes). verbose=True adds the equivalent disturbance spectrum level column. Rendering needs reportlab and, for the figure the fiche embeds, matplotlib (pip install "phonometry[report,plot]"); only engine="reportlab" is supported. Pass language="es" for a Spanish fiche.

from phonometry import ReportMetadata, speech
res = speech.speech_intelligibility_index(speech_spectrum, noise, threshold=threshold)
res.report(
"sii_fiche.pdf",
metadata=ReportMetadata(
specimen="Conversational speech in low-frequency ambient noise",
measurement_standard="ANSI S3.5-1997",
laboratory="Phonometry Reference Laboratory",
requirement=0.75, # minimum required SII (a higher SII passes)
),
)

The example fiche is regenerated with make reports and kept rendered in the repository; click the preview to open the PDF.

ANSI S3.5-1997 SII example report (PDF)

One-page speech-intelligibility-index fiche: a metadata header, a one-third-octave-band table of the equivalent speech spectrum, band importance and band audibility, the audibility bars, the boxed SII = 0.851 single-number result and a PASS verdict against a 0.75 minimum.

Download the report (PDF)

Speech intelligibility index fiche (SIIResult.report), the SII with its per-band audibility.
  • Covered

    All four band procedures of ANSI S3.5-1997 (R2017): the critical-band method (21 bands, Table 1), the equally-contributing critical-band method (17 bands, Table 2), the one-third-octave-band method (18 bands, Table 3, the default) and the octave-band method (6 bands, Table 4). For each: the equivalent speech, noise and hearing-threshold spectrum levels, the band-importance function and standard speech spectrum level, the self-speech masking, upward spread of masking, level-distortion factor and band-audibility function of clause 5, and the index of clause 6. speech_intelligibility_index (with method= and band_importance=), sii_procedure, standard_speech_spectrum and standard_speech_spectra implement these, and SIIResult.report(path) renders the ANSI S3.5-1997 fiche for whichever procedure was used.

  • Not covered

    The standard speech spectra for raised, loud and shout vocal effort are carried for the one-third-octave procedure only; Tables 1, 2 and 4 are implemented with their normal-effort column, which is the column the level-distortion factor of clause 5.7 needs. The tabulated band-importance functions are the average-speech compromise of each table; Annex B’s alternative importance functions for specific test materials (nonsense syllables, monosyllabic word lists, short passages) are not shipped as constants, but any importance function can be applied with band_importance=. No resampling between the four band sets is provided: each procedure is fed spectra on its own bands. The Speech Transmission Index, a different metric for a transmission channel rather than listener audibility, is covered separately in the Speech Transmission Index guide.

Which frequency bands matter most for speech intelligibility?

Section titled “Which frequency bands matter most for speech intelligibility?”

In the one-third-octave-band method of ANSI S3.5-1997, the band-importance function (Table 3, average speech material) sums to one across 18 bands from 160 Hz to 8000 Hz. The five bands from 1250 Hz to 3150 Hz carry about 43 % of intelligibility (the consonant cues), while the five lowest bands, 160 Hz to 400 Hz, carry about 11 % despite holding nearly half of the speech power.

How is the Speech Intelligibility Index calculated?

Section titled “How is the Speech Intelligibility Index calculated?”

The SII of ANSI S3.5-1997 clause 6 is the band-importance-weighted sum of the band audibilities, , over 18 one-third-octave bands. Each band audibility is (clause 5.8), where is the equivalent speech spectrum level and the equivalent disturbance combining external noise, upward spread of masking and the equivalent internal noise. The index lies in .

Which of the four ANSI S3.5 band procedures should I use?

Section titled “Which of the four ANSI S3.5 band procedures should I use?”

ANSI S3.5-1997 defines four, quoted here by band centre: critical band (21 bands, centres 150 Hz to 8500 Hz), equally-contributing critical band (17 bands, centres 350 Hz to 5800 Hz), one-third octave (18 bands, centres 160 Hz to 8000 Hz) and octave (6 bands, centres 250 Hz to 8000 Hz). Use method="one-third-octave" by default: it is the finest resolution and the only procedure whose table carries the raised, loud and shout speech spectra. Use method="critical-band" to align the index with a critical-band (Bark) masking or loudness model, method="equally-contributing" when the index should read as the fraction of equally-important bands that are audible, and method="octave" when octave-band data is all that was measured, remembering that the octave procedure carries no upward spread of masking and so reads high under strong low-frequency noise.

When should I use the SII instead of the STI?

Section titled “When should I use the SII instead of the STI?”

Use the SII (ANSI S3.5) when the question is whether enough of the speech spectrum is audible at the listener’s ear: it captures steady noise, upward spread of masking, hearing loss and vocal effort, but it is blind to reverberation. The STI (IEC 60268-16) rates a transmission channel, how much of the speech modulation a room or sound system preserves. When both mechanisms are in play, compute both.

  • American National Standards Institute. (1997). American National Standard Methods for the Calculation of the Speech Intelligibility Index (ANSI S3.5-1997 (R2017)). Acoustical Society of America. The four band procedures: critical band (21 bands, Table 1), equally-contributing critical band (17 bands, Table 2), one-third octave (18 bands, Table 3) and octave (6 bands, Table 4), each with its band-importance function, standard speech spectrum level and reference internal noise; the masking, disturbance and band-audibility procedure (clause 5) and the index (clause 6).
  • French, N. R., & Steinberg, J. C. (1947). Factors governing the intelligibility of speech sounds. The Journal of the Acoustical Society of America, 19(1), 90-119. https://doi.org/10.1121/1.1916407The articulation-band experiments that the band-importance function of section 1 descends from.